sysutils.pp 23 KB

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