sysutils.pp 24 KB

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