sysutils.pp 25 KB

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