sysutils.pp 24 KB

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