sysutils.pp 24 KB

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