sysutils.pp 25 KB

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