sysutils.pp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2005 by Florian Klaempfl and Yury Sidorov
  4. members of the Free Pascal development team
  5. Sysutils unit for wince
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit sysutils;
  13. interface
  14. {$MODE objfpc}
  15. {$MODESWITCH OUT}
  16. { force ansistrings }
  17. {$H+}
  18. uses
  19. dos,
  20. windows;
  21. {$DEFINE HAS_SLEEP}
  22. {$DEFINE HAS_OSERROR}
  23. {$DEFINE HAS_OSCONFIG}
  24. {$DEFINE HAS_TEMPDIR}
  25. {$DEFINE HAS_LOCALTIMEZONEOFFSET}
  26. { Include platform independent interface part }
  27. {$i sysutilh.inc}
  28. type
  29. TSystemTime = Windows.TSystemTime;
  30. EWinCEError = class(Exception)
  31. public
  32. ErrorCode : DWORD;
  33. end;
  34. Var
  35. WinCEPlatform : Longint;
  36. WinCEMajorVersion,
  37. WinCEMinorVersion,
  38. WinCEBuildNumber : dword;
  39. WinCECSDVersion : ShortString; // CSD record is 128 bytes only?
  40. implementation
  41. uses
  42. sysconst;
  43. {$DEFINE FPC_NOGENERICANSIROUTINES}
  44. {$define HASEXPANDUNCFILENAME}
  45. {$DEFINE FPC_FEXPAND_NO_DEFAULT_PATHS}
  46. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  47. { Include platform independent implementation part }
  48. {$i sysutils.inc}
  49. procedure PWideCharToString(const str: PWideChar; out Result: string; strlen: longint = -1);
  50. var
  51. len: longint;
  52. begin
  53. if (strlen < 1) and (str^ = #0) then
  54. Result:=''
  55. else
  56. begin
  57. while True do begin
  58. if strlen <> -1 then
  59. len:=strlen + 1
  60. else
  61. len:=WideToAnsiBuf(str, -1, nil, 0);
  62. if len > 0 then
  63. begin
  64. SetLength(Result, len - 1);
  65. if (WideToAnsiBuf(str, strlen, @Result[1], len) = 0) and (strlen <> -1) then
  66. begin
  67. strlen:=-1;
  68. continue;
  69. end;
  70. end
  71. else
  72. Result:='';
  73. break;
  74. end;
  75. end;
  76. end;
  77. function ExpandUNCFileName (const filename:string) : string;
  78. { returns empty string on errors }
  79. var
  80. s : widestring;
  81. size : dword;
  82. rc : dword;
  83. buf : pwidechar;
  84. begin
  85. s := ExpandFileName (filename);
  86. size := max_path*SizeOf(WideChar);
  87. getmem(buf,size);
  88. try
  89. rc := WNetGetUniversalName (pwidechar(s), UNIVERSAL_NAME_INFO_LEVEL, buf, @size);
  90. if rc=ERROR_MORE_DATA then
  91. begin
  92. buf:=reallocmem(buf,size);
  93. rc := WNetGetUniversalName (pwidechar(s), UNIVERSAL_NAME_INFO_LEVEL, buf, @size);
  94. end;
  95. if rc = NO_ERROR then
  96. Result := PRemoteNameInfo(buf)^.lpUniversalName
  97. else if rc = ERROR_NOT_CONNECTED then
  98. Result := filename
  99. else
  100. Result := '';
  101. finally
  102. freemem(buf);
  103. end;
  104. end;
  105. {****************************************************************************
  106. File Functions
  107. ****************************************************************************}
  108. Function FileOpen (Const FileName : string; Mode : Integer) : THandle;
  109. const
  110. AccessMode: array[0..2] of Cardinal = (
  111. GENERIC_READ,
  112. GENERIC_WRITE,
  113. GENERIC_READ or GENERIC_WRITE);
  114. ShareMode: array[0..4] of Integer = (
  115. 0,
  116. 0,
  117. FILE_SHARE_READ,
  118. FILE_SHARE_WRITE,
  119. FILE_SHARE_READ or FILE_SHARE_WRITE);
  120. var
  121. fn: PWideChar;
  122. begin
  123. fn:=StringToPWideChar(FileName);
  124. result := CreateFile(fn, dword(AccessMode[Mode and 3]),
  125. dword(ShareMode[(Mode and $F0) shr 4]), nil, OPEN_EXISTING,
  126. FILE_ATTRIBUTE_NORMAL, 0);
  127. //if fail api return feInvalidHandle (INVALIDE_HANDLE=feInvalidHandle=-1)
  128. FreeMem(fn);
  129. end;
  130. Function FileCreate (Const FileName : String) : THandle;
  131. var
  132. fn: PWideChar;
  133. begin
  134. fn:=StringToPWideChar(FileName);
  135. Result := CreateFile(fn, GENERIC_READ or GENERIC_WRITE,
  136. 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  137. FreeMem(fn);
  138. end;
  139. Function FileCreate (Const FileName : String; Rights:longint) : THandle;
  140. begin
  141. FileCreate:=FileCreate(FileName);
  142. end;
  143. Function FileCreate (Const FileName : String; ShareMode:longint; Rights:longint) : THandle;
  144. begin
  145. FileCreate:=FileCreate(FileName);
  146. end;
  147. Function FileRead (Handle : THandle; Out Buffer; Count : longint) : Longint;
  148. Var
  149. res : dword;
  150. begin
  151. if ReadFile(Handle, Buffer, Count, res, nil) then
  152. FileRead:=Res
  153. else
  154. FileRead:=-1;
  155. end;
  156. Function FileWrite (Handle : THandle; const Buffer; Count : Longint) : Longint;
  157. Var
  158. Res : dword;
  159. begin
  160. if WriteFile(Handle, Buffer, Count, Res, nil) then
  161. FileWrite:=Res
  162. else
  163. FileWrite:=-1;
  164. end;
  165. Function FileSeek (Handle : THandle;FOffset,Origin : Longint) : Longint;
  166. begin
  167. Result := longint(SetFilePointer(Handle, FOffset, nil, Origin));
  168. end;
  169. Function FileSeek (Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
  170. begin
  171. Result := SetFilePointer(Handle, longint(FOffset), nil, longint(Origin));
  172. end;
  173. Procedure FileClose (Handle : THandle);
  174. begin
  175. if Handle<=4 then
  176. exit;
  177. CloseHandle(Handle);
  178. end;
  179. Function FileTruncate (Handle : THandle;Size: Int64) : boolean;
  180. begin
  181. if FileSeek (Handle, Size, FILE_BEGIN) = Size then
  182. Result:=SetEndOfFile(handle)
  183. else
  184. Result := false;
  185. end;
  186. Function DosToWinTime (DTime:longint; out Wtime : TFileTime):longbool;
  187. begin
  188. DosToWinTime:=dos.DosToWinTime(DTime, Wtime);
  189. end;
  190. Function WinToDosTime (Const Wtime : TFileTime; out DTime:longint):longbool;
  191. begin
  192. WinToDosTime:=dos.WinToDosTime(Wtime, DTime);
  193. end;
  194. Function FileAge (Const FileName : String): Longint;
  195. var
  196. Handle: THandle;
  197. FindData: TWin32FindData;
  198. fn: PWideChar;
  199. begin
  200. fn:=StringToPWideChar(FileName);
  201. Handle := FindFirstFile(fn, FindData);
  202. FreeMem(fn);
  203. if Handle <> INVALID_HANDLE_VALUE then
  204. begin
  205. Windows.FindClose(Handle);
  206. if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
  207. If WinToDosTime(FindData.ftLastWriteTime,Result) then
  208. exit;
  209. end;
  210. Result := -1;
  211. end;
  212. Function FileExists (Const FileName : String) : Boolean;
  213. var
  214. Attr:Dword;
  215. begin
  216. Attr:=FileGetAttr(FileName);
  217. if Attr <> $ffffffff then
  218. Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) = 0
  219. else
  220. Result:=False;
  221. end;
  222. Function DirectoryExists (Const Directory : String) : Boolean;
  223. var
  224. Attr:Dword;
  225. begin
  226. Attr:=FileGetAttr(Directory);
  227. if Attr <> $ffffffff then
  228. Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) <> 0
  229. else
  230. Result:=False;
  231. end;
  232. Function FindMatch(var f: TSearchRec) : Longint;
  233. begin
  234. { Find file with correct attribute }
  235. While (F.FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
  236. begin
  237. if not FindNextFile (F.FindHandle,F.FindData) then
  238. begin
  239. Result:=GetLastError;
  240. exit;
  241. end;
  242. end;
  243. { Convert some attributes back }
  244. WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
  245. f.size:=F.FindData.NFileSizeLow;
  246. f.attr:=F.FindData.dwFileAttributes;
  247. PWideCharToString(@F.FindData.cFileName[0], f.Name);
  248. Result:=0;
  249. end;
  250. Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
  251. var
  252. fn: PWideChar;
  253. begin
  254. fn:=StringToPWideChar(Path);
  255. Rslt.Name:=Path;
  256. Rslt.Attr:=attr;
  257. Rslt.ExcludeAttr:=(not Attr) and ($1e);
  258. { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
  259. { FindFirstFile is a WinCE Call }
  260. Rslt.FindHandle:=FindFirstFile (fn, Rslt.FindData);
  261. FreeMem(fn);
  262. If Rslt.FindHandle=Invalid_Handle_value then
  263. begin
  264. Result:=GetLastError;
  265. exit;
  266. end;
  267. { Find file with correct attribute }
  268. Result:=FindMatch(Rslt);
  269. end;
  270. Function FindNext (Var Rslt : TSearchRec) : Longint;
  271. begin
  272. if FindNextFile(Rslt.FindHandle, Rslt.FindData) then
  273. Result := FindMatch(Rslt)
  274. else
  275. Result := GetLastError;
  276. end;
  277. Procedure FindClose (Var F : TSearchrec);
  278. begin
  279. if F.FindHandle <> INVALID_HANDLE_VALUE then
  280. Windows.FindClose(F.FindHandle);
  281. end;
  282. Function FileGetDate (Handle : THandle) : Longint;
  283. Var
  284. FT : TFileTime;
  285. begin
  286. If GetFileTime(Handle,nil,nil,@ft) and
  287. WinToDosTime(FT, Result) then
  288. exit;
  289. Result:=-1;
  290. end;
  291. Function FileSetDate (Handle : THandle;Age : Longint) : Longint;
  292. Var
  293. FT: TFileTime;
  294. begin
  295. Result := 0;
  296. if DosToWinTime(Age, FT) and SetFileTime(Handle, FT, FT, FT) then
  297. Exit;
  298. Result := GetLastError;
  299. end;
  300. Function FileGetAttr (Const FileName : String) : Longint;
  301. var
  302. fn: PWideChar;
  303. begin
  304. fn:=StringToPWideChar(FileName);
  305. Result:=GetFileAttributes(fn);
  306. FreeMem(fn);
  307. end;
  308. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  309. var
  310. fn: PWideChar;
  311. begin
  312. fn:=StringToPWideChar(FileName);
  313. if not SetFileAttributes(fn, Attr) then
  314. Result := GetLastError
  315. else
  316. Result:=0;
  317. FreeMem(fn);
  318. end;
  319. Function DeleteFile (Const FileName : String) : Boolean;
  320. var
  321. fn: PWideChar;
  322. begin
  323. fn:=StringToPWideChar(FileName);
  324. DeleteFile:=Windows.DeleteFile(fn);
  325. FreeMem(fn);
  326. end;
  327. Function RenameFile (Const OldName, NewName : String) : Boolean;
  328. var
  329. fold, fnew: PWideChar;
  330. begin
  331. fold:=StringToPWideChar(OldName);
  332. fnew:=StringToPWideChar(NewName);
  333. Result := MoveFile(fold, fnew);
  334. FreeMem(fnew);
  335. FreeMem(fold);
  336. end;
  337. {****************************************************************************
  338. Disk Functions
  339. ****************************************************************************}
  340. function diskfree(drive : byte) : int64;
  341. begin
  342. Result := Dos.diskfree(drive);
  343. end;
  344. function disksize(drive : byte) : int64;
  345. begin
  346. Result := Dos.disksize(drive);
  347. end;
  348. Function GetCurrentDir : String;
  349. begin
  350. GetDir(0, result);
  351. end;
  352. Function SetCurrentDir (Const NewDir : String) : Boolean;
  353. begin
  354. {$I-}
  355. ChDir(NewDir);
  356. {$I+}
  357. result := (IOResult = 0);
  358. end;
  359. Function CreateDir (Const NewDir : String) : Boolean;
  360. begin
  361. {$I-}
  362. MkDir(NewDir);
  363. {$I+}
  364. result := (IOResult = 0);
  365. end;
  366. Function RemoveDir (Const Dir : String) : Boolean;
  367. begin
  368. {$I-}
  369. RmDir(Dir);
  370. {$I+}
  371. result := (IOResult = 0);
  372. end;
  373. {****************************************************************************
  374. Time Functions
  375. ****************************************************************************}
  376. Procedure GetLocalTime(var SystemTime: TSystemTime);
  377. begin
  378. windows.Getlocaltime(SystemTime);
  379. end;
  380. function GetLocalTimeOffset: Integer;
  381. var
  382. TZInfo: TTimeZoneInformation;
  383. begin
  384. case GetTimeZoneInformation(TZInfo) of
  385. TIME_ZONE_ID_UNKNOWN:
  386. Result := TZInfo.Bias;
  387. TIME_ZONE_ID_STANDARD:
  388. Result := TZInfo.Bias + TZInfo.StandardBias;
  389. TIME_ZONE_ID_DAYLIGHT:
  390. Result := TZInfo.Bias + TZInfo.DaylightBias;
  391. else
  392. Result := 0;
  393. end;
  394. end;
  395. {****************************************************************************
  396. Misc Functions
  397. ****************************************************************************}
  398. procedure SysBeep;
  399. begin
  400. MessageBeep(0);
  401. end;
  402. {****************************************************************************
  403. Locale Functions
  404. ****************************************************************************}
  405. function GetLocaleStr(LID, LT: Longint; const Def: string): ShortString;
  406. var
  407. L: Integer;
  408. Buf: array[0..255] of WideChar;
  409. s: widestring;
  410. begin
  411. L := GetLocaleInfo(LID, LT, Buf, SizeOf(Buf) div SizeOf(WideChar));
  412. if L > 0 then
  413. begin
  414. SetString(s, Buf, L - 1);
  415. Result:=s;
  416. end
  417. else
  418. Result := Def;
  419. end;
  420. function GetLocaleChar(LID, LT: Longint; Def: Char): Char;
  421. var
  422. Buf: array[0..1] of WideChar;
  423. Buf2: array[0..1] of Char;
  424. begin
  425. if GetLocaleInfo(LID, LT, Buf, 2) > 0 then
  426. begin
  427. WideToAnsiBuf(Buf, 1, Buf2, SizeOf(Buf2));
  428. Result := Buf2[0];
  429. end
  430. else
  431. Result := Def;
  432. end;
  433. Function GetLocaleInt(LID,TP,Def: LongInt): LongInt;
  434. Var
  435. S: String;
  436. C: Integer;
  437. Begin
  438. S:=GetLocaleStr(LID,TP,'0');
  439. Val(S,Result,C);
  440. If C<>0 Then
  441. Result:=Def;
  442. End;
  443. procedure GetFormatSettings;
  444. var
  445. HF : Shortstring;
  446. LID : LCID;
  447. I,Day,DateOrder : longint;
  448. begin
  449. LID := GetUserDefaultLCID;
  450. { Date stuff }
  451. for I := 1 to 12 do
  452. begin
  453. ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
  454. LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
  455. end;
  456. for I := 1 to 7 do
  457. begin
  458. Day := (I + 5) mod 7;
  459. ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
  460. LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
  461. end;
  462. DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
  463. DateOrder := GetLocaleInt(LID, LOCALE_IDate, 0);
  464. Case DateOrder Of
  465. 1: Begin
  466. ShortDateFormat := 'dd/mm/yyyy';
  467. LongDateFormat := 'dddd, d. mmmm yyyy';
  468. End;
  469. 2: Begin
  470. ShortDateFormat := 'yyyy/mm/dd';
  471. LongDateFormat := 'dddd, yyyy mmmm d.';
  472. End;
  473. else
  474. // Default american settings...
  475. ShortDateFormat := 'mm/dd/yyyy';
  476. LongDateFormat := 'dddd, mmmm d. yyyy';
  477. End;
  478. { Time stuff }
  479. TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
  480. TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
  481. TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
  482. if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
  483. HF:='h'
  484. else
  485. HF:='hh';
  486. // No support for 12 hour stuff at the moment...
  487. ShortTimeFormat := HF+':nn';
  488. LongTimeFormat := HF + ':nn:ss';
  489. { Currency stuff }
  490. CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
  491. CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
  492. NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
  493. { Number stuff }
  494. ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
  495. DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
  496. CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
  497. end;
  498. Procedure InitInternational;
  499. begin
  500. InitInternationalGeneric;
  501. SysLocale.MBCS:=GetSystemMetrics(SM_DBCSENABLED)<>0;
  502. SysLocale.RightToLeft:=GetSystemMetrics(SM_MIDEASTENABLED)<>0;
  503. GetFormatSettings;
  504. end;
  505. {****************************************************************************
  506. Target Dependent
  507. ****************************************************************************}
  508. function SysErrorMessage(ErrorCode: Integer): String;
  509. var
  510. MsgBuffer: PWideChar;
  511. len: longint;
  512. begin
  513. MsgBuffer:=nil;
  514. len:=FormatMessage(
  515. FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
  516. nil,
  517. ErrorCode,
  518. 0,
  519. @MsgBuffer, { This function allocs the memory (in this case you pass a PPwidechar)}
  520. 0,
  521. nil);
  522. if MsgBuffer <> nil then begin
  523. while (len > 0) and (MsgBuffer[len - 1] <= #32) do
  524. Dec(len);
  525. MsgBuffer[len]:=#0;
  526. PWideCharToString(MsgBuffer, Result);
  527. LocalFree(HLOCAL(MsgBuffer));
  528. end
  529. else
  530. Result:='';
  531. end;
  532. {****************************************************************************
  533. Initialization code
  534. ****************************************************************************}
  535. // WinCE does not have environment. It can be emulated via registry or file. (YS)
  536. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  537. begin
  538. Result := '';
  539. end;
  540. Function GetEnvironmentVariableCount : Integer;
  541. begin
  542. Result := 0;
  543. end;
  544. Function GetEnvironmentString(Index : Integer) : String;
  545. begin
  546. Result := '';
  547. end;
  548. function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString;Flags:TExecuteFlags=[]):integer;
  549. var
  550. PI: TProcessInformation;
  551. Proc : THandle;
  552. l : DWord;
  553. e : EOSError;
  554. begin
  555. DosError := 0;
  556. if not CreateProcess(PWideChar(widestring(Path)), PWideChar(widestring(ComLine)),
  557. nil, nil, FALSE, 0, nil, nil, nil, PI) then
  558. begin
  559. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  560. e.ErrorCode:=GetLastError;
  561. raise e;
  562. end;
  563. Proc:=PI.hProcess;
  564. CloseHandle(PI.hThread);
  565. if WaitForSingleObject(Proc, dword($ffffffff)) <> $ffffffff then
  566. begin
  567. GetExitCodeProcess(Proc,l);
  568. CloseHandle(Proc);
  569. result:=l;
  570. end
  571. else
  572. begin
  573. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  574. e.ErrorCode:=GetLastError;
  575. CloseHandle(Proc);
  576. raise e;
  577. end;
  578. end;
  579. function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array of AnsiString;Flags:TExecuteFlags=[]):integer;
  580. var
  581. CommandLine: AnsiString;
  582. I: integer;
  583. begin
  584. Commandline := '';
  585. for I := 0 to High (ComLine) do
  586. if Pos (' ', ComLine [I]) <> 0 then
  587. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  588. else
  589. CommandLine := CommandLine + ' ' + Comline [I];
  590. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  591. end;
  592. Procedure Sleep(Milliseconds : Cardinal);
  593. begin
  594. Windows.Sleep(MilliSeconds)
  595. end;
  596. Function GetLastOSError : Integer;
  597. begin
  598. Result:=GetLastError;
  599. end;
  600. {****************************************************************************
  601. Initialization code
  602. ****************************************************************************}
  603. Procedure LoadVersionInfo;
  604. Var
  605. versioninfo : TOSVERSIONINFO;
  606. i : Integer;
  607. begin
  608. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  609. GetVersionEx(versioninfo);
  610. WinCEPlatform:=versionInfo.dwPlatformId;
  611. WinCEMajorVersion:=versionInfo.dwMajorVersion;
  612. WinCEMinorVersion:=versionInfo.dwMinorVersion;
  613. WinCEBuildNumber:=versionInfo.dwBuildNumber;
  614. i:=WideToAnsiBuf(@versioninfo.szCSDVersion[0], -1, @WinCECSDVersion[1], SizeOf(WinCECSDVersion) - 1);
  615. if i <> 0 then
  616. WinCECSDVersion[0]:=chr(i - 1);
  617. end;
  618. Function GetSpecialDir(ID: Integer) : String;
  619. Var
  620. APath : array[0..MAX_PATH] of WideChar;
  621. begin
  622. if SHGetSpecialFolderPath(0, APath, ID, True) then
  623. begin
  624. PWideCharToString(APath, Result);
  625. Result:=IncludeTrailingPathDelimiter(Result);
  626. end
  627. else
  628. Result:='';
  629. end;
  630. Function GetAppConfigDir(Global : Boolean) : String;
  631. begin
  632. If Global then
  633. Result:=GetSpecialDir(CSIDL_WINDOWS)
  634. else
  635. Result:=GetSpecialDir(CSIDL_APPDATA);
  636. If (Result<>'') then
  637. begin
  638. if VendorName<>'' then
  639. Result:=IncludeTrailingPathDelimiter(Result+VendorName);
  640. Result:=IncludeTrailingPathDelimiter(Result+ApplicationName);
  641. end
  642. else
  643. Result:=IncludeTrailingPathDelimiter(DGetAppConfigDir(Global));
  644. end;
  645. Function GetAppConfigFile(Global : Boolean; SubDir : Boolean) : String;
  646. begin
  647. result:=DGetAppConfigFile(Global,SubDir);
  648. end;
  649. Function GetTempDir(Global : Boolean) : String;
  650. var
  651. buf: widestring;
  652. begin
  653. SetLength(buf, MAX_PATH);
  654. SetLength(buf, GetTempPath(Length(buf) + 1, PWideChar(buf)));
  655. Result:=buf;
  656. Result := IncludeTrailingPathDelimiter(Result);
  657. end;
  658. {****************************************************************************
  659. Target Dependent WideString stuff
  660. ****************************************************************************}
  661. function DoCompareString(P1, P2: PWideChar; L1, L2: PtrUInt; Flags: DWORD): PtrInt;
  662. begin
  663. SetLastError(0);
  664. Result:=CompareString(LOCALE_USER_DEFAULT,Flags,P1,L1,P2,L2)-2;
  665. if GetLastError<>0 then
  666. RaiseLastOSError;
  667. end;
  668. function WinCECompareWideString(const s1, s2 : WideString) : PtrInt;
  669. begin
  670. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
  671. end;
  672. function WinCECompareTextWideString(const s1, s2 : WideString) : PtrInt;
  673. begin
  674. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  675. end;
  676. function WinCECompareUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
  677. begin
  678. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
  679. end;
  680. function WinCECompareTextUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
  681. begin
  682. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  683. end;
  684. function WinCEAnsiUpperCase(const s: string): string;
  685. var
  686. buf: PWideChar;
  687. len: longint;
  688. begin
  689. if s <> '' then
  690. begin
  691. buf:=StringToPWideChar(s, @len);
  692. CharUpperBuff(buf, len-1);
  693. PWideCharToString(buf, Result, len-1);
  694. FreeMem(buf);
  695. end
  696. else
  697. Result:='';
  698. end;
  699. function WinCEAnsiLowerCase(const s: string): string;
  700. var
  701. buf: PWideChar;
  702. len: longint;
  703. begin
  704. if s <> '' then
  705. begin
  706. buf:=StringToPWideChar(s, @len);
  707. CharLowerBuff(buf, len-1);
  708. PWideCharToString(buf, Result, len-1);
  709. FreeMem(buf);
  710. end
  711. else
  712. Result:='';
  713. end;
  714. function WinCEAnsiCompareStr(const S1, S2: string): PtrInt;
  715. var
  716. ws1, ws2: PWideChar;
  717. begin
  718. ws1:=StringToPWideChar(S1);
  719. ws2:=StringToPWideChar(S2);
  720. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, Length(S1), ws2, Length(S2)) - 2;
  721. FreeMem(ws2);
  722. FreeMem(ws1);
  723. end;
  724. function WinCEAnsiCompareText(const S1, S2: string): PtrInt;
  725. var
  726. ws1, ws2: PWideChar;
  727. begin
  728. ws1:=StringToPWideChar(S1);
  729. ws2:=StringToPWideChar(S2);
  730. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, Length(S1), ws2, Length(S2)) - 2;
  731. FreeMem(ws2);
  732. FreeMem(ws1);
  733. end;
  734. function WinCEAnsiStrComp(S1, S2: PChar): PtrInt;
  735. var
  736. ws1, ws2: PWideChar;
  737. begin
  738. ws1:=PCharToPWideChar(S1);
  739. ws2:=PCharToPWideChar(S2);
  740. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, -1, ws2, -1) - 2;
  741. FreeMem(ws2);
  742. FreeMem(ws1);
  743. end;
  744. function WinCEAnsiStrIComp(S1, S2: PChar): PtrInt;
  745. var
  746. ws1, ws2: PWideChar;
  747. begin
  748. ws1:=PCharToPWideChar(S1);
  749. ws2:=PCharToPWideChar(S2);
  750. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, -1, ws2, -1) - 2;
  751. FreeMem(ws2);
  752. FreeMem(ws1);
  753. end;
  754. function WinCEAnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  755. var
  756. ws1, ws2: PWideChar;
  757. len1, len2: longint;
  758. begin
  759. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  760. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  761. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, len1, ws2, len2) - 2;
  762. FreeMem(ws2);
  763. FreeMem(ws1);
  764. end;
  765. function WinCEAnsiStrLIComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  766. var
  767. ws1, ws2: PWideChar;
  768. len1, len2: longint;
  769. begin
  770. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  771. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  772. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, len1, ws2, len2) - 2;
  773. FreeMem(ws2);
  774. FreeMem(ws1);
  775. end;
  776. function WinCEAnsiStrLower(Str: PChar): PChar;
  777. var
  778. buf: PWideChar;
  779. len: longint;
  780. begin
  781. buf:=PCharToPWideChar(Str, -1, @len);
  782. CharLowerBuff(buf, len - 1);
  783. Result:=Str;
  784. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  785. FreeMem(buf);
  786. end;
  787. function WinCEAnsiStrUpper(Str: PChar): PChar;
  788. var
  789. buf: PWideChar;
  790. len: longint;
  791. begin
  792. buf:=PCharToPWideChar(Str, -1, @len);
  793. CharUpperBuff(buf, len - 1);
  794. Result:=Str;
  795. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  796. FreeMem(buf);
  797. end;
  798. { there is a similiar procedure in the system unit which inits the fields which
  799. are relevant already for the system unit }
  800. procedure InitWinCEWidestrings;
  801. begin
  802. widestringmanager.CompareWideStringProc:=@WinCECompareWideString;
  803. widestringmanager.CompareTextWideStringProc:=@WinCECompareTextWideString;
  804. widestringmanager.CompareUnicodeStringProc:=@WinCECompareUnicodeString;
  805. widestringmanager.CompareTextUnicodeStringProc:=@WinCECompareTextUnicodeString;
  806. widestringmanager.UpperAnsiStringProc:=@WinCEAnsiUpperCase;
  807. widestringmanager.LowerAnsiStringProc:=@WinCEAnsiLowerCase;
  808. widestringmanager.CompareStrAnsiStringProc:=@WinCEAnsiCompareStr;
  809. widestringmanager.CompareTextAnsiStringProc:=@WinCEAnsiCompareText;
  810. widestringmanager.StrCompAnsiStringProc:=@WinCEAnsiStrComp;
  811. widestringmanager.StrICompAnsiStringProc:=@WinCEAnsiStrIComp;
  812. widestringmanager.StrLCompAnsiStringProc:=@WinCEAnsiStrLComp;
  813. widestringmanager.StrLICompAnsiStringProc:=@WinCEAnsiStrLIComp;
  814. widestringmanager.StrLowerAnsiStringProc:=@WinCEAnsiStrLower;
  815. widestringmanager.StrUpperAnsiStringProc:=@WinCEAnsiStrUpper;
  816. end;
  817. Initialization
  818. InitWinCEWidestrings;
  819. InitExceptions; { Initialize exceptions. OS independent }
  820. InitInternational; { Initialize internationalization settings }
  821. LoadVersionInfo;
  822. OnBeep:=@SysBeep;
  823. SysConfigDir:='\Windows';
  824. Finalization
  825. DoneExceptions;
  826. end.