sysutils.pp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  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 GetUniversalTime(var SystemTime: TSystemTime): Boolean;
  359. begin
  360. windows.GetSystemTime(SystemTime);
  361. Result:=True;
  362. end;
  363. function GetLocalTimeOffset: Integer;
  364. var
  365. TZInfo: TTimeZoneInformation;
  366. begin
  367. case GetTimeZoneInformation(TZInfo) of
  368. TIME_ZONE_ID_UNKNOWN:
  369. Result := TZInfo.Bias;
  370. TIME_ZONE_ID_STANDARD:
  371. Result := TZInfo.Bias + TZInfo.StandardBias;
  372. TIME_ZONE_ID_DAYLIGHT:
  373. Result := TZInfo.Bias + TZInfo.DaylightBias;
  374. else
  375. Result := 0;
  376. end;
  377. end;
  378. function GetLocalTimeOffset(const DateTime: TDateTime; const InputIsUTC: Boolean; out Offset: Integer): Boolean;
  379. begin
  380. Result := False; // not supported
  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) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  532. begin
  533. Result := '';
  534. end;
  535. function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
  536. begin
  537. result:=ExecuteProcess(UnicodeString(Path),UnicodeString(ComLine),Flags);
  538. end;
  539. function ExecuteProcess(Const Path: UnicodeString; Const ComLine: UnicodeString;Flags:TExecuteFlags=[]):integer;
  540. var
  541. PI: TProcessInformation;
  542. Proc : THandle;
  543. l : DWord;
  544. e : EOSError;
  545. begin
  546. DosError := 0;
  547. if not CreateProcess(PWideChar(Path), PWideChar(ComLine),
  548. nil, nil, FALSE, 0, nil, nil, nil, PI) then
  549. begin
  550. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  551. e.ErrorCode:=GetLastError;
  552. raise e;
  553. end;
  554. Proc:=PI.hProcess;
  555. CloseHandle(PI.hThread);
  556. if WaitForSingleObject(Proc, dword($ffffffff)) <> $ffffffff then
  557. begin
  558. GetExitCodeProcess(Proc,l);
  559. CloseHandle(Proc);
  560. result:=l;
  561. end
  562. else
  563. begin
  564. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  565. e.ErrorCode:=GetLastError;
  566. CloseHandle(Proc);
  567. raise e;
  568. end;
  569. end;
  570. function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
  571. var
  572. CommandLine: UnicodeString;
  573. I: integer;
  574. begin
  575. Commandline := '';
  576. for I := 0 to High (ComLine) do
  577. if Pos (' ', ComLine [I]) <> 0 then
  578. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  579. else
  580. CommandLine := CommandLine + ' ' + Comline [I];
  581. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  582. end;
  583. function ExecuteProcess(Const Path: RawByteString; Const ComLine: Array of RawByteString;Flags:TExecuteFlags=[]):integer;
  584. var
  585. CommandLine: UnicodeString;
  586. I: integer;
  587. begin
  588. Commandline := '';
  589. for I := 0 to High (ComLine) do
  590. if Pos (' ', ComLine [I]) <> 0 then
  591. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  592. else
  593. CommandLine := CommandLine + ' ' + Comline [I];
  594. ExecuteProcess := ExecuteProcess (UnicodeString(Path), CommandLine,Flags);
  595. end;
  596. Procedure Sleep(Milliseconds : Cardinal);
  597. begin
  598. Windows.Sleep(MilliSeconds)
  599. end;
  600. Function GetLastOSError : Integer;
  601. begin
  602. Result:=GetLastError;
  603. end;
  604. {****************************************************************************
  605. Initialization code
  606. ****************************************************************************}
  607. Procedure LoadVersionInfo;
  608. Var
  609. versioninfo : TOSVERSIONINFO;
  610. i : Integer;
  611. begin
  612. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  613. GetVersionEx(versioninfo);
  614. WinCEPlatform:=versionInfo.dwPlatformId;
  615. WinCEMajorVersion:=versionInfo.dwMajorVersion;
  616. WinCEMinorVersion:=versionInfo.dwMinorVersion;
  617. WinCEBuildNumber:=versionInfo.dwBuildNumber;
  618. i:=WideToAnsiBuf(@versioninfo.szCSDVersion[0], -1, @WinCECSDVersion[1], SizeOf(WinCECSDVersion) - 1);
  619. if i <> 0 then
  620. WinCECSDVersion[0]:=chr(i - 1);
  621. end;
  622. Function GetSpecialDir(ID: Integer) : String;
  623. Var
  624. APath : array[0..MAX_PATH] of WideChar;
  625. begin
  626. if SHGetSpecialFolderPath(0, APath, ID, True) then
  627. begin
  628. PWideCharToString(APath, Result);
  629. Result:=IncludeTrailingPathDelimiter(Result);
  630. end
  631. else
  632. Result:='';
  633. end;
  634. Function GetAppConfigDir(Global : Boolean) : String;
  635. begin
  636. If Global then
  637. Result:=GetSpecialDir(CSIDL_WINDOWS)
  638. else
  639. Result:=GetSpecialDir(CSIDL_APPDATA);
  640. If (Result<>'') then
  641. begin
  642. if VendorName<>'' then
  643. Result:=IncludeTrailingPathDelimiter(Result+VendorName);
  644. Result:=IncludeTrailingPathDelimiter(Result+ApplicationName);
  645. end
  646. else
  647. Result:=IncludeTrailingPathDelimiter(DGetAppConfigDir(Global));
  648. end;
  649. Function GetAppConfigFile(Global : Boolean; SubDir : Boolean) : String;
  650. begin
  651. result:=DGetAppConfigFile(Global,SubDir);
  652. end;
  653. Function GetTempDir(Global : Boolean) : String;
  654. var
  655. buf: widestring;
  656. begin
  657. SetLength(buf, MAX_PATH);
  658. SetLength(buf, GetTempPath(Length(buf) + 1, PWideChar(buf)));
  659. Result:=buf;
  660. Result := IncludeTrailingPathDelimiter(Result);
  661. end;
  662. {****************************************************************************
  663. Target Dependent WideString stuff
  664. ****************************************************************************}
  665. function DoCompareString(P1, P2: PWideChar; L1, L2: PtrUInt; Flags: DWORD): PtrInt;
  666. begin
  667. SetLastError(0);
  668. Result:=CompareString(LOCALE_USER_DEFAULT,Flags,P1,L1,P2,L2)-2;
  669. if GetLastError<>0 then
  670. RaiseLastOSError;
  671. end;
  672. function WinCECompareWideString(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
  673. begin
  674. if coIgnoreCase in Options then
  675. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE)
  676. else
  677. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
  678. end;
  679. function WinCECompareTextWideString(const s1, s2 : WideString) : PtrInt;
  680. begin
  681. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  682. end;
  683. function WinCECompareUnicodeString(const s1, s2 : UnicodeString; Options : TCompareOptions) : PtrInt;
  684. begin
  685. if coIgnoreCase in Options then
  686. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE)
  687. else
  688. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
  689. end;
  690. function WinCECompareTextUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
  691. begin
  692. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  693. end;
  694. function WinCEAnsiUpperCase(const s: string): string;
  695. var
  696. buf: PWideChar;
  697. len: longint;
  698. begin
  699. if s <> '' then
  700. begin
  701. buf:=StringToPWideChar(s, @len);
  702. CharUpperBuff(buf, len-1);
  703. PWideCharToString(buf, Result, len-1);
  704. FreeMem(buf);
  705. end
  706. else
  707. Result:='';
  708. end;
  709. function WinCEAnsiLowerCase(const s: string): string;
  710. var
  711. buf: PWideChar;
  712. len: longint;
  713. begin
  714. if s <> '' then
  715. begin
  716. buf:=StringToPWideChar(s, @len);
  717. CharLowerBuff(buf, len-1);
  718. PWideCharToString(buf, Result, len-1);
  719. FreeMem(buf);
  720. end
  721. else
  722. Result:='';
  723. end;
  724. function WinCEAnsiCompareStr(const S1, S2: string): PtrInt;
  725. var
  726. ws1, ws2: PWideChar;
  727. begin
  728. ws1:=StringToPWideChar(S1);
  729. ws2:=StringToPWideChar(S2);
  730. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, Length(S1), ws2, Length(S2)) - 2;
  731. FreeMem(ws2);
  732. FreeMem(ws1);
  733. end;
  734. function WinCEAnsiCompareText(const S1, S2: string): PtrInt;
  735. var
  736. ws1, ws2: PWideChar;
  737. begin
  738. ws1:=StringToPWideChar(S1);
  739. ws2:=StringToPWideChar(S2);
  740. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, Length(S1), ws2, Length(S2)) - 2;
  741. FreeMem(ws2);
  742. FreeMem(ws1);
  743. end;
  744. function WinCEAnsiStrComp(S1, S2: PChar): PtrInt;
  745. var
  746. ws1, ws2: PWideChar;
  747. begin
  748. ws1:=PCharToPWideChar(S1);
  749. ws2:=PCharToPWideChar(S2);
  750. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, -1, ws2, -1) - 2;
  751. FreeMem(ws2);
  752. FreeMem(ws1);
  753. end;
  754. function WinCEAnsiStrIComp(S1, S2: PChar): PtrInt;
  755. var
  756. ws1, ws2: PWideChar;
  757. begin
  758. ws1:=PCharToPWideChar(S1);
  759. ws2:=PCharToPWideChar(S2);
  760. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, -1, ws2, -1) - 2;
  761. FreeMem(ws2);
  762. FreeMem(ws1);
  763. end;
  764. function WinCEAnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  765. var
  766. ws1, ws2: PWideChar;
  767. len1, len2: longint;
  768. begin
  769. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  770. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  771. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, len1, ws2, len2) - 2;
  772. FreeMem(ws2);
  773. FreeMem(ws1);
  774. end;
  775. function WinCEAnsiStrLIComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  776. var
  777. ws1, ws2: PWideChar;
  778. len1, len2: longint;
  779. begin
  780. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  781. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  782. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, len1, ws2, len2) - 2;
  783. FreeMem(ws2);
  784. FreeMem(ws1);
  785. end;
  786. function WinCEAnsiStrLower(Str: PChar): PChar;
  787. var
  788. buf: PWideChar;
  789. len: longint;
  790. begin
  791. buf:=PCharToPWideChar(Str, -1, @len);
  792. CharLowerBuff(buf, len - 1);
  793. Result:=Str;
  794. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  795. FreeMem(buf);
  796. end;
  797. function WinCEAnsiStrUpper(Str: PChar): PChar;
  798. var
  799. buf: PWideChar;
  800. len: longint;
  801. begin
  802. buf:=PCharToPWideChar(Str, -1, @len);
  803. CharUpperBuff(buf, len - 1);
  804. Result:=Str;
  805. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  806. FreeMem(buf);
  807. end;
  808. { there is a similiar procedure in the system unit which inits the fields which
  809. are relevant already for the system unit }
  810. procedure InitWinCEWidestrings;
  811. begin
  812. widestringmanager.CompareWideStringProc:=@WinCECompareWideString;
  813. widestringmanager.CompareUnicodeStringProc:=@WinCECompareUnicodeString;
  814. widestringmanager.UpperAnsiStringProc:=@WinCEAnsiUpperCase;
  815. widestringmanager.LowerAnsiStringProc:=@WinCEAnsiLowerCase;
  816. widestringmanager.CompareStrAnsiStringProc:=@WinCEAnsiCompareStr;
  817. widestringmanager.CompareTextAnsiStringProc:=@WinCEAnsiCompareText;
  818. widestringmanager.StrCompAnsiStringProc:=@WinCEAnsiStrComp;
  819. widestringmanager.StrICompAnsiStringProc:=@WinCEAnsiStrIComp;
  820. widestringmanager.StrLCompAnsiStringProc:=@WinCEAnsiStrLComp;
  821. widestringmanager.StrLICompAnsiStringProc:=@WinCEAnsiStrLIComp;
  822. widestringmanager.StrLowerAnsiStringProc:=@WinCEAnsiStrLower;
  823. widestringmanager.StrUpperAnsiStringProc:=@WinCEAnsiStrUpper;
  824. end;
  825. Initialization
  826. InitWinCEWidestrings;
  827. InitExceptions; { Initialize exceptions. OS independent }
  828. InitInternational; { Initialize internationalization settings }
  829. LoadVersionInfo;
  830. OnBeep:=@SysBeep;
  831. SysConfigDir:='\Windows';
  832. Finalization
  833. FreeTerminateProcs;
  834. DoneExceptions;
  835. end.