sysutils.pp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  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. function GetLocalTimeOffset(const DateTime: TDateTime; out Offset: Integer): Boolean;
  363. begin
  364. Result := False; // not supported
  365. end;
  366. {****************************************************************************
  367. Misc Functions
  368. ****************************************************************************}
  369. procedure SysBeep;
  370. begin
  371. MessageBeep(0);
  372. end;
  373. {****************************************************************************
  374. Locale Functions
  375. ****************************************************************************}
  376. function GetLocaleStr(LID, LT: Longint; const Def: string): ShortString;
  377. var
  378. L: Integer;
  379. Buf: array[0..255] of WideChar;
  380. s: widestring;
  381. begin
  382. L := GetLocaleInfo(LID, LT, Buf, SizeOf(Buf) div SizeOf(WideChar));
  383. if L > 0 then
  384. begin
  385. SetString(s, Buf, L - 1);
  386. Result:=s;
  387. end
  388. else
  389. Result := Def;
  390. end;
  391. function GetLocaleChar(LID, LT: Longint; Def: Char): Char;
  392. var
  393. Buf: array[0..1] of WideChar;
  394. Buf2: array[0..1] of Char;
  395. begin
  396. if GetLocaleInfo(LID, LT, Buf, 2) > 0 then
  397. begin
  398. WideToAnsiBuf(Buf, 1, Buf2, SizeOf(Buf2));
  399. Result := Buf2[0];
  400. end
  401. else
  402. Result := Def;
  403. end;
  404. Function GetLocaleInt(LID,TP,Def: LongInt): LongInt;
  405. Var
  406. S: String;
  407. C: Integer;
  408. Begin
  409. S:=GetLocaleStr(LID,TP,'0');
  410. Val(S,Result,C);
  411. If C<>0 Then
  412. Result:=Def;
  413. End;
  414. procedure GetFormatSettings;
  415. var
  416. HF : Shortstring;
  417. LID : LCID;
  418. I,Day,DateOrder : longint;
  419. begin
  420. LID := GetUserDefaultLCID;
  421. { Date stuff }
  422. for I := 1 to 12 do
  423. begin
  424. ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
  425. LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
  426. end;
  427. for I := 1 to 7 do
  428. begin
  429. Day := (I + 5) mod 7;
  430. ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
  431. LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
  432. end;
  433. DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
  434. DateOrder := GetLocaleInt(LID, LOCALE_IDate, 0);
  435. Case DateOrder Of
  436. 1: Begin
  437. ShortDateFormat := 'dd/mm/yyyy';
  438. LongDateFormat := 'dddd, d. mmmm yyyy';
  439. End;
  440. 2: Begin
  441. ShortDateFormat := 'yyyy/mm/dd';
  442. LongDateFormat := 'dddd, yyyy mmmm d.';
  443. End;
  444. else
  445. // Default american settings...
  446. ShortDateFormat := 'mm/dd/yyyy';
  447. LongDateFormat := 'dddd, mmmm d. yyyy';
  448. End;
  449. { Time stuff }
  450. TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
  451. TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
  452. TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
  453. if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
  454. HF:='h'
  455. else
  456. HF:='hh';
  457. // No support for 12 hour stuff at the moment...
  458. ShortTimeFormat := HF+':nn';
  459. LongTimeFormat := HF + ':nn:ss';
  460. { Currency stuff }
  461. CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
  462. CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
  463. NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
  464. { Number stuff }
  465. ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
  466. DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
  467. CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
  468. end;
  469. Procedure InitInternational;
  470. begin
  471. InitInternationalGeneric;
  472. SysLocale.MBCS:=GetSystemMetrics(SM_DBCSENABLED)<>0;
  473. SysLocale.RightToLeft:=GetSystemMetrics(SM_MIDEASTENABLED)<>0;
  474. GetFormatSettings;
  475. end;
  476. {****************************************************************************
  477. Target Dependent
  478. ****************************************************************************}
  479. function SysErrorMessage(ErrorCode: Integer): String;
  480. var
  481. MsgBuffer: PWideChar;
  482. len: longint;
  483. begin
  484. MsgBuffer:=nil;
  485. len:=FormatMessage(
  486. FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
  487. nil,
  488. ErrorCode,
  489. 0,
  490. @MsgBuffer, { This function allocs the memory (in this case you pass a PPwidechar)}
  491. 0,
  492. nil);
  493. if MsgBuffer <> nil then begin
  494. while (len > 0) and (MsgBuffer[len - 1] <= #32) do
  495. Dec(len);
  496. MsgBuffer[len]:=#0;
  497. PWideCharToString(MsgBuffer, Result);
  498. LocalFree(HLOCAL(MsgBuffer));
  499. end
  500. else
  501. Result:='';
  502. end;
  503. {****************************************************************************
  504. Initialization code
  505. ****************************************************************************}
  506. // WinCE does not have environment. It can be emulated via registry or file. (YS)
  507. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  508. begin
  509. Result := '';
  510. end;
  511. Function GetEnvironmentVariableCount : Integer;
  512. begin
  513. Result := 0;
  514. end;
  515. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  516. begin
  517. Result := '';
  518. end;
  519. function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
  520. begin
  521. result:=ExecuteProcess(UnicodeString(Path),UnicodeString(ComLine),Flags);
  522. end;
  523. function ExecuteProcess(Const Path: UnicodeString; Const ComLine: UnicodeString;Flags:TExecuteFlags=[]):integer;
  524. var
  525. PI: TProcessInformation;
  526. Proc : THandle;
  527. l : DWord;
  528. e : EOSError;
  529. begin
  530. DosError := 0;
  531. if not CreateProcess(PWideChar(Path), PWideChar(ComLine),
  532. nil, nil, FALSE, 0, nil, nil, nil, PI) then
  533. begin
  534. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  535. e.ErrorCode:=GetLastError;
  536. raise e;
  537. end;
  538. Proc:=PI.hProcess;
  539. CloseHandle(PI.hThread);
  540. if WaitForSingleObject(Proc, dword($ffffffff)) <> $ffffffff then
  541. begin
  542. GetExitCodeProcess(Proc,l);
  543. CloseHandle(Proc);
  544. result:=l;
  545. end
  546. else
  547. begin
  548. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  549. e.ErrorCode:=GetLastError;
  550. CloseHandle(Proc);
  551. raise e;
  552. end;
  553. end;
  554. function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
  555. var
  556. CommandLine: UnicodeString;
  557. I: integer;
  558. begin
  559. Commandline := '';
  560. for I := 0 to High (ComLine) do
  561. if Pos (' ', ComLine [I]) <> 0 then
  562. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  563. else
  564. CommandLine := CommandLine + ' ' + Comline [I];
  565. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  566. end;
  567. function ExecuteProcess(Const Path: RawByteString; Const ComLine: Array of RawByteString;Flags:TExecuteFlags=[]):integer;
  568. var
  569. CommandLine: UnicodeString;
  570. I: integer;
  571. begin
  572. Commandline := '';
  573. for I := 0 to High (ComLine) do
  574. if Pos (' ', ComLine [I]) <> 0 then
  575. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  576. else
  577. CommandLine := CommandLine + ' ' + Comline [I];
  578. ExecuteProcess := ExecuteProcess (UnicodeString(Path), CommandLine,Flags);
  579. end;
  580. Procedure Sleep(Milliseconds : Cardinal);
  581. begin
  582. Windows.Sleep(MilliSeconds)
  583. end;
  584. Function GetLastOSError : Integer;
  585. begin
  586. Result:=GetLastError;
  587. end;
  588. {****************************************************************************
  589. Initialization code
  590. ****************************************************************************}
  591. Procedure LoadVersionInfo;
  592. Var
  593. versioninfo : TOSVERSIONINFO;
  594. i : Integer;
  595. begin
  596. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  597. GetVersionEx(versioninfo);
  598. WinCEPlatform:=versionInfo.dwPlatformId;
  599. WinCEMajorVersion:=versionInfo.dwMajorVersion;
  600. WinCEMinorVersion:=versionInfo.dwMinorVersion;
  601. WinCEBuildNumber:=versionInfo.dwBuildNumber;
  602. i:=WideToAnsiBuf(@versioninfo.szCSDVersion[0], -1, @WinCECSDVersion[1], SizeOf(WinCECSDVersion) - 1);
  603. if i <> 0 then
  604. WinCECSDVersion[0]:=chr(i - 1);
  605. end;
  606. Function GetSpecialDir(ID: Integer) : String;
  607. Var
  608. APath : array[0..MAX_PATH] of WideChar;
  609. begin
  610. if SHGetSpecialFolderPath(0, APath, ID, True) then
  611. begin
  612. PWideCharToString(APath, Result);
  613. Result:=IncludeTrailingPathDelimiter(Result);
  614. end
  615. else
  616. Result:='';
  617. end;
  618. Function GetAppConfigDir(Global : Boolean) : String;
  619. begin
  620. If Global then
  621. Result:=GetSpecialDir(CSIDL_WINDOWS)
  622. else
  623. Result:=GetSpecialDir(CSIDL_APPDATA);
  624. If (Result<>'') then
  625. begin
  626. if VendorName<>'' then
  627. Result:=IncludeTrailingPathDelimiter(Result+VendorName);
  628. Result:=IncludeTrailingPathDelimiter(Result+ApplicationName);
  629. end
  630. else
  631. Result:=IncludeTrailingPathDelimiter(DGetAppConfigDir(Global));
  632. end;
  633. Function GetAppConfigFile(Global : Boolean; SubDir : Boolean) : String;
  634. begin
  635. result:=DGetAppConfigFile(Global,SubDir);
  636. end;
  637. Function GetTempDir(Global : Boolean) : String;
  638. var
  639. buf: widestring;
  640. begin
  641. SetLength(buf, MAX_PATH);
  642. SetLength(buf, GetTempPath(Length(buf) + 1, PWideChar(buf)));
  643. Result:=buf;
  644. Result := IncludeTrailingPathDelimiter(Result);
  645. end;
  646. {****************************************************************************
  647. Target Dependent WideString stuff
  648. ****************************************************************************}
  649. function DoCompareString(P1, P2: PWideChar; L1, L2: PtrUInt; Flags: DWORD): PtrInt;
  650. begin
  651. SetLastError(0);
  652. Result:=CompareString(LOCALE_USER_DEFAULT,Flags,P1,L1,P2,L2)-2;
  653. if GetLastError<>0 then
  654. RaiseLastOSError;
  655. end;
  656. function WinCECompareWideString(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
  657. begin
  658. if coIgnoreCase in Options then
  659. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE)
  660. else
  661. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
  662. end;
  663. function WinCECompareTextWideString(const s1, s2 : WideString) : PtrInt;
  664. begin
  665. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  666. end;
  667. function WinCECompareUnicodeString(const s1, s2 : UnicodeString; Options : TCompareOptions) : PtrInt;
  668. begin
  669. if coIgnoreCase in Options then
  670. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE)
  671. else
  672. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
  673. end;
  674. function WinCECompareTextUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
  675. begin
  676. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  677. end;
  678. function WinCEAnsiUpperCase(const s: string): string;
  679. var
  680. buf: PWideChar;
  681. len: longint;
  682. begin
  683. if s <> '' then
  684. begin
  685. buf:=StringToPWideChar(s, @len);
  686. CharUpperBuff(buf, len-1);
  687. PWideCharToString(buf, Result, len-1);
  688. FreeMem(buf);
  689. end
  690. else
  691. Result:='';
  692. end;
  693. function WinCEAnsiLowerCase(const s: string): string;
  694. var
  695. buf: PWideChar;
  696. len: longint;
  697. begin
  698. if s <> '' then
  699. begin
  700. buf:=StringToPWideChar(s, @len);
  701. CharLowerBuff(buf, len-1);
  702. PWideCharToString(buf, Result, len-1);
  703. FreeMem(buf);
  704. end
  705. else
  706. Result:='';
  707. end;
  708. function WinCEAnsiCompareStr(const S1, S2: string): PtrInt;
  709. var
  710. ws1, ws2: PWideChar;
  711. begin
  712. ws1:=StringToPWideChar(S1);
  713. ws2:=StringToPWideChar(S2);
  714. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, Length(S1), ws2, Length(S2)) - 2;
  715. FreeMem(ws2);
  716. FreeMem(ws1);
  717. end;
  718. function WinCEAnsiCompareText(const S1, S2: string): PtrInt;
  719. var
  720. ws1, ws2: PWideChar;
  721. begin
  722. ws1:=StringToPWideChar(S1);
  723. ws2:=StringToPWideChar(S2);
  724. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, Length(S1), ws2, Length(S2)) - 2;
  725. FreeMem(ws2);
  726. FreeMem(ws1);
  727. end;
  728. function WinCEAnsiStrComp(S1, S2: PChar): PtrInt;
  729. var
  730. ws1, ws2: PWideChar;
  731. begin
  732. ws1:=PCharToPWideChar(S1);
  733. ws2:=PCharToPWideChar(S2);
  734. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, -1, ws2, -1) - 2;
  735. FreeMem(ws2);
  736. FreeMem(ws1);
  737. end;
  738. function WinCEAnsiStrIComp(S1, S2: PChar): PtrInt;
  739. var
  740. ws1, ws2: PWideChar;
  741. begin
  742. ws1:=PCharToPWideChar(S1);
  743. ws2:=PCharToPWideChar(S2);
  744. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, -1, ws2, -1) - 2;
  745. FreeMem(ws2);
  746. FreeMem(ws1);
  747. end;
  748. function WinCEAnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  749. var
  750. ws1, ws2: PWideChar;
  751. len1, len2: longint;
  752. begin
  753. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  754. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  755. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, len1, ws2, len2) - 2;
  756. FreeMem(ws2);
  757. FreeMem(ws1);
  758. end;
  759. function WinCEAnsiStrLIComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  760. var
  761. ws1, ws2: PWideChar;
  762. len1, len2: longint;
  763. begin
  764. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  765. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  766. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, len1, ws2, len2) - 2;
  767. FreeMem(ws2);
  768. FreeMem(ws1);
  769. end;
  770. function WinCEAnsiStrLower(Str: PChar): PChar;
  771. var
  772. buf: PWideChar;
  773. len: longint;
  774. begin
  775. buf:=PCharToPWideChar(Str, -1, @len);
  776. CharLowerBuff(buf, len - 1);
  777. Result:=Str;
  778. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  779. FreeMem(buf);
  780. end;
  781. function WinCEAnsiStrUpper(Str: PChar): PChar;
  782. var
  783. buf: PWideChar;
  784. len: longint;
  785. begin
  786. buf:=PCharToPWideChar(Str, -1, @len);
  787. CharUpperBuff(buf, len - 1);
  788. Result:=Str;
  789. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  790. FreeMem(buf);
  791. end;
  792. { there is a similiar procedure in the system unit which inits the fields which
  793. are relevant already for the system unit }
  794. procedure InitWinCEWidestrings;
  795. begin
  796. widestringmanager.CompareWideStringProc:=@WinCECompareWideString;
  797. widestringmanager.CompareUnicodeStringProc:=@WinCECompareUnicodeString;
  798. widestringmanager.UpperAnsiStringProc:=@WinCEAnsiUpperCase;
  799. widestringmanager.LowerAnsiStringProc:=@WinCEAnsiLowerCase;
  800. widestringmanager.CompareStrAnsiStringProc:=@WinCEAnsiCompareStr;
  801. widestringmanager.CompareTextAnsiStringProc:=@WinCEAnsiCompareText;
  802. widestringmanager.StrCompAnsiStringProc:=@WinCEAnsiStrComp;
  803. widestringmanager.StrICompAnsiStringProc:=@WinCEAnsiStrIComp;
  804. widestringmanager.StrLCompAnsiStringProc:=@WinCEAnsiStrLComp;
  805. widestringmanager.StrLICompAnsiStringProc:=@WinCEAnsiStrLIComp;
  806. widestringmanager.StrLowerAnsiStringProc:=@WinCEAnsiStrLower;
  807. widestringmanager.StrUpperAnsiStringProc:=@WinCEAnsiStrUpper;
  808. end;
  809. Initialization
  810. InitWinCEWidestrings;
  811. InitExceptions; { Initialize exceptions. OS independent }
  812. InitInternational; { Initialize internationalization settings }
  813. LoadVersionInfo;
  814. OnBeep:=@SysBeep;
  815. SysConfigDir:='\Windows';
  816. Finalization
  817. FreeTerminateProcs;
  818. DoneExceptions;
  819. end.