sysutils.pp 25 KB

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