sysutils.pp 24 KB

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