sysutils.pp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  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: Longint) : boolean;
  173. begin
  174. Result:=longint(SetFilePointer(handle,Size,nil,FILE_BEGIN))<>-1;
  175. If Result then
  176. Result:=SetEndOfFile(handle);
  177. end;
  178. Function DosToWinTime (DTime:longint; out Wtime : TFileTime):longbool;
  179. begin
  180. DosToWinTime:=dos.DosToWinTime(DTime, Wtime);
  181. end;
  182. Function WinToDosTime (Const Wtime : TFileTime; out DTime:longint):longbool;
  183. begin
  184. WinToDosTime:=dos.WinToDosTime(Wtime, DTime);
  185. end;
  186. Function FileAge (Const FileName : String): Longint;
  187. var
  188. Handle: THandle;
  189. FindData: TWin32FindData;
  190. fn: PWideChar;
  191. begin
  192. fn:=StringToPWideChar(FileName);
  193. Handle := FindFirstFile(fn, FindData);
  194. FreeMem(fn);
  195. if Handle <> INVALID_HANDLE_VALUE then
  196. begin
  197. Windows.FindClose(Handle);
  198. if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
  199. If WinToDosTime(FindData.ftLastWriteTime,Result) then
  200. exit;
  201. end;
  202. Result := -1;
  203. end;
  204. Function FileExists (Const FileName : String) : Boolean;
  205. var
  206. Attr:Dword;
  207. begin
  208. Attr:=FileGetAttr(FileName);
  209. if Attr <> $ffffffff then
  210. Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) = 0
  211. else
  212. Result:=False;
  213. end;
  214. Function DirectoryExists (Const Directory : String) : Boolean;
  215. var
  216. Attr:Dword;
  217. begin
  218. Attr:=FileGetAttr(Directory);
  219. if Attr <> $ffffffff then
  220. Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) <> 0
  221. else
  222. Result:=False;
  223. end;
  224. Function FindMatch(var f: TSearchRec) : Longint;
  225. begin
  226. { Find file with correct attribute }
  227. While (F.FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
  228. begin
  229. if not FindNextFile (F.FindHandle,F.FindData) then
  230. begin
  231. Result:=GetLastError;
  232. exit;
  233. end;
  234. end;
  235. { Convert some attributes back }
  236. WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
  237. f.size:=F.FindData.NFileSizeLow;
  238. f.attr:=F.FindData.dwFileAttributes;
  239. PWideCharToString(@F.FindData.cFileName[0], f.Name);
  240. Result:=0;
  241. end;
  242. Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
  243. var
  244. fn: PWideChar;
  245. begin
  246. fn:=StringToPWideChar(Path);
  247. Rslt.Name:=Path;
  248. Rslt.Attr:=attr;
  249. Rslt.ExcludeAttr:=(not Attr) and ($1e);
  250. { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
  251. { FindFirstFile is a WinCE Call }
  252. Rslt.FindHandle:=FindFirstFile (fn, Rslt.FindData);
  253. FreeMem(fn);
  254. If Rslt.FindHandle=Invalid_Handle_value then
  255. begin
  256. Result:=GetLastError;
  257. exit;
  258. end;
  259. { Find file with correct attribute }
  260. Result:=FindMatch(Rslt);
  261. end;
  262. Function FindNext (Var Rslt : TSearchRec) : Longint;
  263. begin
  264. if FindNextFile(Rslt.FindHandle, Rslt.FindData) then
  265. Result := FindMatch(Rslt)
  266. else
  267. Result := GetLastError;
  268. end;
  269. Procedure FindClose (Var F : TSearchrec);
  270. begin
  271. if F.FindHandle <> INVALID_HANDLE_VALUE then
  272. Windows.FindClose(F.FindHandle);
  273. end;
  274. Function FileGetDate (Handle : THandle) : Longint;
  275. Var
  276. FT : TFileTime;
  277. begin
  278. If GetFileTime(Handle,nil,nil,@ft) and
  279. WinToDosTime(FT, Result) then
  280. exit;
  281. Result:=-1;
  282. end;
  283. Function FileSetDate (Handle : THandle;Age : Longint) : Longint;
  284. Var
  285. FT: TFileTime;
  286. begin
  287. Result := 0;
  288. if DosToWinTime(Age, FT) and SetFileTime(Handle, FT, FT, FT) then
  289. Exit;
  290. Result := GetLastError;
  291. end;
  292. Function FileGetAttr (Const FileName : String) : Longint;
  293. var
  294. fn: PWideChar;
  295. begin
  296. fn:=StringToPWideChar(FileName);
  297. Result:=GetFileAttributes(fn);
  298. FreeMem(fn);
  299. end;
  300. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  301. var
  302. fn: PWideChar;
  303. begin
  304. fn:=StringToPWideChar(FileName);
  305. if not SetFileAttributes(fn, Attr) then
  306. Result := GetLastError
  307. else
  308. Result:=0;
  309. FreeMem(fn);
  310. end;
  311. Function DeleteFile (Const FileName : String) : Boolean;
  312. var
  313. fn: PWideChar;
  314. begin
  315. fn:=StringToPWideChar(FileName);
  316. DeleteFile:=Windows.DeleteFile(fn);
  317. FreeMem(fn);
  318. end;
  319. Function RenameFile (Const OldName, NewName : String) : Boolean;
  320. var
  321. fold, fnew: PWideChar;
  322. begin
  323. fold:=StringToPWideChar(OldName);
  324. fnew:=StringToPWideChar(NewName);
  325. Result := MoveFile(fold, fnew);
  326. FreeMem(fnew);
  327. FreeMem(fold);
  328. end;
  329. {****************************************************************************
  330. Disk Functions
  331. ****************************************************************************}
  332. function diskfree(drive : byte) : int64;
  333. begin
  334. Result := Dos.diskfree(drive);
  335. end;
  336. function disksize(drive : byte) : int64;
  337. begin
  338. Result := Dos.disksize(drive);
  339. end;
  340. Function GetCurrentDir : String;
  341. begin
  342. GetDir(0, result);
  343. end;
  344. Function SetCurrentDir (Const NewDir : String) : Boolean;
  345. begin
  346. {$I-}
  347. ChDir(NewDir);
  348. {$I+}
  349. result := (IOResult = 0);
  350. end;
  351. Function CreateDir (Const NewDir : String) : Boolean;
  352. begin
  353. {$I-}
  354. MkDir(NewDir);
  355. {$I+}
  356. result := (IOResult = 0);
  357. end;
  358. Function RemoveDir (Const Dir : String) : Boolean;
  359. begin
  360. {$I-}
  361. RmDir(Dir);
  362. {$I+}
  363. result := (IOResult = 0);
  364. end;
  365. {****************************************************************************
  366. Time Functions
  367. ****************************************************************************}
  368. Procedure GetLocalTime(var SystemTime: TSystemTime);
  369. Var
  370. Syst : Windows.TSystemtime;
  371. begin
  372. windows.Getlocaltime(@syst);
  373. SystemTime.year:=syst.wYear;
  374. SystemTime.month:=syst.wMonth;
  375. SystemTime.day:=syst.wDay;
  376. SystemTime.hour:=syst.wHour;
  377. SystemTime.minute:=syst.wMinute;
  378. SystemTime.second:=syst.wSecond;
  379. SystemTime.millisecond:=syst.wMilliSeconds;
  380. end;
  381. {****************************************************************************
  382. Misc Functions
  383. ****************************************************************************}
  384. procedure Beep;
  385. begin
  386. MessageBeep(0);
  387. end;
  388. {****************************************************************************
  389. Locale Functions
  390. ****************************************************************************}
  391. Procedure InitAnsi;
  392. Var
  393. i : longint;
  394. begin
  395. { Fill table entries 0 to 127 }
  396. for i := 0 to 96 do
  397. UpperCaseTable[i] := chr(i);
  398. for i := 97 to 122 do
  399. UpperCaseTable[i] := chr(i - 32);
  400. for i := 123 to 191 do
  401. UpperCaseTable[i] := chr(i);
  402. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  403. for i := 0 to 64 do
  404. LowerCaseTable[i] := chr(i);
  405. for i := 65 to 90 do
  406. LowerCaseTable[i] := chr(i + 32);
  407. for i := 91 to 191 do
  408. LowerCaseTable[i] := chr(i);
  409. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  410. end;
  411. function GetLocaleStr(LID, LT: Longint; const Def: string): ShortString;
  412. var
  413. L: Integer;
  414. Buf: array[0..255] of WideChar;
  415. s: widestring;
  416. begin
  417. L := GetLocaleInfo(LID, LT, Buf, SizeOf(Buf) div SizeOf(WideChar));
  418. if L > 0 then
  419. begin
  420. SetString(s, Buf, L - 1);
  421. Result:=s;
  422. end
  423. else
  424. Result := Def;
  425. end;
  426. function GetLocaleChar(LID, LT: Longint; Def: Char): Char;
  427. var
  428. Buf: array[0..1] of WideChar;
  429. Buf2: array[0..1] of Char;
  430. begin
  431. if GetLocaleInfo(LID, LT, Buf, 2) > 0 then
  432. begin
  433. WideToAnsiBuf(Buf, -1, Buf2, SizeOf(Buf2));
  434. Result := Buf2[0];
  435. end
  436. else
  437. Result := Def;
  438. end;
  439. Function GetLocaleInt(LID,TP,Def: LongInt): LongInt;
  440. Var
  441. S: String;
  442. C: Integer;
  443. Begin
  444. S:=GetLocaleStr(LID,TP,'0');
  445. Val(S,Result,C);
  446. If C<>0 Then
  447. Result:=Def;
  448. End;
  449. procedure GetFormatSettings;
  450. var
  451. HF : Shortstring;
  452. LID : LCID;
  453. I,Day,DateOrder : longint;
  454. begin
  455. LID := GetUserDefaultLCID;
  456. { Date stuff }
  457. for I := 1 to 12 do
  458. begin
  459. ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
  460. LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
  461. end;
  462. for I := 1 to 7 do
  463. begin
  464. Day := (I + 5) mod 7;
  465. ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
  466. LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
  467. end;
  468. DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
  469. DateOrder := GetLocaleInt(LID, LOCALE_IDate, 0);
  470. Case DateOrder Of
  471. 1: Begin
  472. ShortDateFormat := 'dd/mm/yyyy';
  473. LongDateFormat := 'dddd, d. mmmm yyyy';
  474. End;
  475. 2: Begin
  476. ShortDateFormat := 'yyyy/mm/dd';
  477. LongDateFormat := 'dddd, yyyy mmmm d.';
  478. End;
  479. else
  480. // Default american settings...
  481. ShortDateFormat := 'mm/dd/yyyy';
  482. LongDateFormat := 'dddd, mmmm d. yyyy';
  483. End;
  484. { Time stuff }
  485. TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
  486. TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
  487. TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
  488. if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
  489. HF:='h'
  490. else
  491. HF:='hh';
  492. // No support for 12 hour stuff at the moment...
  493. ShortTimeFormat := HF+':nn';
  494. LongTimeFormat := HF + ':nn:ss';
  495. { Currency stuff }
  496. CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
  497. CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
  498. NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
  499. { Number stuff }
  500. ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
  501. DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
  502. CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
  503. end;
  504. Procedure InitInternational;
  505. begin
  506. InitInternationalGeneric;
  507. SysLocale.MBCS:=GetSystemMetrics(SM_DBCSENABLED)<>0;
  508. SysLocale.RightToLeft:=GetSystemMetrics(SM_MIDEASTENABLED)<>0;
  509. InitAnsi;
  510. GetFormatSettings;
  511. end;
  512. {****************************************************************************
  513. Target Dependent
  514. ****************************************************************************}
  515. function SysErrorMessage(ErrorCode: Integer): String;
  516. var
  517. MsgBuffer: PWideChar;
  518. len: longint;
  519. begin
  520. len:=FormatMessage(
  521. FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
  522. nil,
  523. ErrorCode,
  524. 0,
  525. PWideChar(@MsgBuffer), { This function allocs the memory (in this case you pass a PPwidechar)}
  526. 0,
  527. nil);
  528. while (len > 0) and (MsgBuffer[len - 1] <= #32) do
  529. Dec(len);
  530. MsgBuffer[len]:=#0;
  531. PWideCharToString(PWideChar(MsgBuffer), Result);
  532. LocalFree(HLOCAL(MsgBuffer));
  533. end;
  534. {****************************************************************************
  535. Initialization code
  536. ****************************************************************************}
  537. // WinCE does not have environment. It can be emulated via registry or file. (YS)
  538. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  539. begin
  540. Result := '';
  541. end;
  542. Function GetEnvironmentVariableCount : Integer;
  543. begin
  544. Result := 0;
  545. end;
  546. Function GetEnvironmentString(Index : Integer) : String;
  547. begin
  548. Result := '';
  549. end;
  550. function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString):integer;
  551. var
  552. PI: TProcessInformation;
  553. Proc : THandle;
  554. l : DWord;
  555. e : EOSError;
  556. begin
  557. DosError := 0;
  558. if not CreateProcess(PWideChar(widestring(Path)), PWideChar(widestring(ComLine)),
  559. nil, nil, FALSE, 0, nil, nil, nil, PI) then
  560. begin
  561. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  562. e.ErrorCode:=GetLastError;
  563. raise e;
  564. end;
  565. Proc:=PI.hProcess;
  566. CloseHandle(PI.hThread);
  567. if WaitForSingleObject(Proc, dword($ffffffff)) <> $ffffffff then
  568. begin
  569. GetExitCodeProcess(Proc,l);
  570. CloseHandle(Proc);
  571. result:=l;
  572. end
  573. else
  574. begin
  575. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  576. e.ErrorCode:=GetLastError;
  577. CloseHandle(Proc);
  578. raise e;
  579. end;
  580. end;
  581. function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array of AnsiString):integer;
  582. Var
  583. CommandLine : AnsiString;
  584. i : Integer;
  585. Begin
  586. Commandline:='';
  587. For i:=0 to high(ComLine) Do
  588. Commandline:=CommandLine+' '+Comline[i];
  589. ExecuteProcess:=ExecuteProcess(Path,CommandLine);
  590. End;
  591. Procedure Sleep(Milliseconds : Cardinal);
  592. begin
  593. Windows.Sleep(MilliSeconds)
  594. end;
  595. Function GetLastOSError : Integer;
  596. begin
  597. Result:=GetLastError;
  598. end;
  599. {****************************************************************************
  600. Initialization code
  601. ****************************************************************************}
  602. Procedure LoadVersionInfo;
  603. Var
  604. versioninfo : TOSVERSIONINFO;
  605. i : Integer;
  606. begin
  607. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  608. GetVersionEx(versioninfo);
  609. WinCEPlatform:=versionInfo.dwPlatformId;
  610. WinCEMajorVersion:=versionInfo.dwMajorVersion;
  611. WinCEMinorVersion:=versionInfo.dwMinorVersion;
  612. WinCEBuildNumber:=versionInfo.dwBuildNumber;
  613. i:=WideToAnsiBuf(@versioninfo.szCSDVersion[0], -1, @WinCECSDVersion[1], SizeOf(WinCECSDVersion) - 1);
  614. if i <> 0 then
  615. WinCECSDVersion[0]:=chr(i - 1);
  616. end;
  617. Function GetSpecialDir(ID: Integer) : String;
  618. Var
  619. APath : array[0..MAX_PATH] of WideChar;
  620. begin
  621. if SHGetSpecialFolderPath(0, APath, ID, True) then
  622. begin
  623. PWideCharToString(APath, Result);
  624. Result:=IncludeTrailingPathDelimiter(Result);
  625. end
  626. else
  627. Result:='';
  628. end;
  629. Function GetAppConfigDir(Global : Boolean) : String;
  630. begin
  631. If Global then
  632. Result:=DGetAppConfigDir(Global) // or use windows dir ??
  633. else
  634. begin
  635. Result:=GetSpecialDir(CSIDL_APPDATA)+ApplicationName;
  636. If (Result='') then
  637. Result:=DGetAppConfigDir(Global);
  638. end;
  639. end;
  640. Function GetAppConfigFile(Global : Boolean; SubDir : Boolean) : String;
  641. begin
  642. if Global then
  643. begin
  644. Result:=IncludeTrailingPathDelimiter(DGetAppConfigDir(Global));
  645. if SubDir then
  646. Result:=IncludeTrailingPathDelimiter(Result+'Config');
  647. Result:=Result+ApplicationName+ConfigExtension;
  648. end
  649. else
  650. begin
  651. Result:=IncludeTrailingPathDelimiter(GetAppConfigDir(False));
  652. if SubDir then
  653. Result:=Result+'Config\';
  654. Result:=Result+ApplicationName+ConfigExtension;
  655. end;
  656. end;
  657. {****************************************************************************
  658. Target Dependent WideString stuff
  659. ****************************************************************************}
  660. function WinCECompareWideString(const s1, s2 : WideString) : PtrInt;
  661. begin
  662. SetLastError(0);
  663. Result:=CompareString(LOCALE_USER_DEFAULT,0,pwidechar(s1),
  664. length(s1),pwidechar(s2),length(s2))-2;
  665. if GetLastError<>0 then
  666. RaiseLastOSError;
  667. end;
  668. function WinCECompareTextWideString(const s1, s2 : WideString) : PtrInt;
  669. begin
  670. SetLastError(0);
  671. Result:=CompareString(LOCALE_USER_DEFAULT,NORM_IGNORECASE,pwidechar(s1),
  672. length(s1),pwidechar(s2),length(s2))-2;
  673. if GetLastError<>0 then
  674. RaiseLastOSError;
  675. end;
  676. function WinCEAnsiUpperCase(const s: string): string;
  677. var
  678. buf: PWideChar;
  679. len: longint;
  680. begin
  681. if s <> '' then
  682. begin
  683. buf:=StringToPWideChar(s, @len);
  684. CharUpperBuff(buf, len);
  685. PWideCharToString(buf, Result, len);
  686. FreeMem(buf);
  687. end
  688. else
  689. Result:='';
  690. end;
  691. function WinCEAnsiLowerCase(const s: string): string;
  692. var
  693. buf: PWideChar;
  694. len: longint;
  695. begin
  696. if s <> '' then
  697. begin
  698. buf:=StringToPWideChar(s, @len);
  699. CharLowerBuff(buf, len);
  700. PWideCharToString(buf, Result, len);
  701. FreeMem(buf);
  702. end
  703. else
  704. Result:='';
  705. end;
  706. function WinCEAnsiCompareStr(const S1, S2: string): PtrInt;
  707. var
  708. ws1, ws2: PWideChar;
  709. begin
  710. ws1:=StringToPWideChar(S1);
  711. ws2:=StringToPWideChar(S2);
  712. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, Length(S1), ws2, Length(S2)) - 2;
  713. FreeMem(ws2);
  714. FreeMem(ws1);
  715. end;
  716. function WinCEAnsiCompareText(const S1, S2: string): PtrInt;
  717. var
  718. ws1, ws2: PWideChar;
  719. begin
  720. ws1:=StringToPWideChar(S1);
  721. ws2:=StringToPWideChar(S2);
  722. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, Length(S1), ws2, Length(S2)) - 2;
  723. FreeMem(ws2);
  724. FreeMem(ws1);
  725. end;
  726. function WinCEAnsiStrComp(S1, S2: PChar): PtrInt;
  727. var
  728. ws1, ws2: PWideChar;
  729. begin
  730. ws1:=PCharToPWideChar(S1);
  731. ws2:=PCharToPWideChar(S2);
  732. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, -1, ws2, -1) - 2;
  733. FreeMem(ws2);
  734. FreeMem(ws1);
  735. end;
  736. function WinCEAnsiStrIComp(S1, S2: PChar): PtrInt;
  737. var
  738. ws1, ws2: PWideChar;
  739. begin
  740. ws1:=PCharToPWideChar(S1);
  741. ws2:=PCharToPWideChar(S2);
  742. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, -1, ws2, -1) - 2;
  743. FreeMem(ws2);
  744. FreeMem(ws1);
  745. end;
  746. function WinCEAnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  747. var
  748. ws1, ws2: PWideChar;
  749. len1, len2: longint;
  750. begin
  751. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  752. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  753. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, len1, ws2, len2) - 2;
  754. FreeMem(ws2);
  755. FreeMem(ws1);
  756. end;
  757. function WinCEAnsiStrLIComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  758. var
  759. ws1, ws2: PWideChar;
  760. len1, len2: longint;
  761. begin
  762. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  763. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  764. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, len1, ws2, len2) - 2;
  765. FreeMem(ws2);
  766. FreeMem(ws1);
  767. end;
  768. function WinCEAnsiStrLower(Str: PChar): PChar;
  769. var
  770. buf: PWideChar;
  771. len: longint;
  772. begin
  773. buf:=PCharToPWideChar(Str, -1, @len);
  774. CharLowerBuff(buf, len);
  775. Result:=Str;
  776. WideToAnsiBuf(buf, -1, Result, len + 1);
  777. FreeMem(buf);
  778. end;
  779. function WinCEAnsiStrUpper(Str: PChar): PChar;
  780. var
  781. buf: PWideChar;
  782. len: longint;
  783. begin
  784. buf:=PCharToPWideChar(Str, -1, @len);
  785. CharUpperBuff(buf, len);
  786. Result:=Str;
  787. WideToAnsiBuf(buf, -1, Result, len + 1);
  788. FreeMem(buf);
  789. end;
  790. { there is a similiar procedure in the system unit which inits the fields which
  791. are relevant already for the system unit }
  792. procedure InitWinCEWidestrings;
  793. begin
  794. widestringmanager.CompareWideStringProc:=@WinCECompareWideString;
  795. widestringmanager.CompareTextWideStringProc:=@WinCECompareTextWideString;
  796. widestringmanager.UpperAnsiStringProc:=@WinCEAnsiUpperCase;
  797. widestringmanager.LowerAnsiStringProc:=@WinCEAnsiLowerCase;
  798. widestringmanager.CompareStrAnsiStringProc:=@WinCEAnsiCompareStr;
  799. widestringmanager.CompareTextAnsiStringProc:=@WinCEAnsiCompareText;
  800. widestringmanager.StrCompAnsiStringProc:=@WinCEAnsiStrComp;
  801. widestringmanager.StrICompAnsiStringProc:=@WinCEAnsiStrIComp;
  802. widestringmanager.StrLCompAnsiStringProc:=@WinCEAnsiStrLComp;
  803. widestringmanager.StrLICompAnsiStringProc:=@WinCEAnsiStrLIComp;
  804. widestringmanager.StrLowerAnsiStringProc:=@WinCEAnsiStrLower;
  805. widestringmanager.StrUpperAnsiStringProc:=@WinCEAnsiStrUpper;
  806. end;
  807. Initialization
  808. InitWinCEWidestrings;
  809. InitExceptions; { Initialize exceptions. OS independent }
  810. InitInternational; { Initialize internationalization settings }
  811. LoadVersionInfo;
  812. SysConfigDir:='\Windows';
  813. Finalization
  814. DoneExceptions;
  815. end.