sysutils.pp 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  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. begin
  205. Handle := FindFirstFile(PWideChar(FileName), FindData);
  206. if Handle <> INVALID_HANDLE_VALUE then
  207. begin
  208. Windows.FindClose(Handle);
  209. if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
  210. If WinToDosTime(FindData.ftLastWriteTime,Result) then
  211. exit;
  212. end;
  213. Result := -1;
  214. end;
  215. function FileGetSymLinkTarget(const FileName: UnicodeString; out SymLinkRec: TUnicodeSymLinkRec): Boolean;
  216. begin
  217. Result := False;
  218. end;
  219. Function FileExists (Const FileName : UnicodeString; FollowLink : Boolean) : Boolean;
  220. var
  221. Attr:Dword;
  222. begin
  223. Attr:=FileGetAttr(FileName);
  224. if Attr <> $ffffffff then
  225. Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) = 0
  226. else
  227. Result:=False;
  228. end;
  229. Function DirectoryExists (Const Directory : UnicodeString; FollowLink : Boolean) : Boolean;
  230. var
  231. Attr:Dword;
  232. begin
  233. Attr:=FileGetAttr(Directory);
  234. if Attr <> $ffffffff then
  235. Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) <> 0
  236. else
  237. Result:=False;
  238. end;
  239. Function FindMatch(var f: TAbstractSearchRec; var Name: UnicodeString) : Longint;
  240. begin
  241. { Find file with correct attribute }
  242. While (F.FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
  243. begin
  244. if not FindNextFile (F.FindHandle,F.FindData) then
  245. begin
  246. Result:=GetLastError;
  247. exit;
  248. end;
  249. end;
  250. { Convert some attributes back }
  251. WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
  252. f.size:=F.FindData.NFileSizeLow;
  253. f.attr:=F.FindData.dwFileAttributes;
  254. Name:=F.FindData.cFileName;
  255. Result:=0;
  256. end;
  257. Function InternalFindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name : UnicodeString) : Longint;
  258. var
  259. fn: PWideChar;
  260. begin
  261. fn:=PWideChar(Path);
  262. Name:=Path;
  263. Rslt.Attr:=attr;
  264. Rslt.ExcludeAttr:=(not Attr) and ($1e);
  265. { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
  266. { FindFirstFile is a WinCE Call }
  267. Rslt.FindHandle:=FindFirstFile (fn, Rslt.FindData);
  268. If Rslt.FindHandle=Invalid_Handle_value then
  269. begin
  270. Result:=GetLastError;
  271. exit;
  272. end;
  273. { Find file with correct attribute }
  274. Result:=FindMatch(Rslt, Name);
  275. end;
  276. Function InternalFindNext (Var Rslt : TAbstractSearchRec; var Name: UnicodeString) : Longint;
  277. begin
  278. if FindNextFile(Rslt.FindHandle, Rslt.FindData) then
  279. Result := FindMatch(Rslt, Name)
  280. else
  281. Result := GetLastError;
  282. end;
  283. Procedure InternalFindClose (var Handle: THandle; var FindData: TFindData);
  284. begin
  285. if Handle <> INVALID_HANDLE_VALUE then
  286. Windows.FindClose(Handle);
  287. end;
  288. Function FileGetDate (Handle : THandle) : Longint;
  289. Var
  290. FT : TFileTime;
  291. begin
  292. If GetFileTime(Handle,nil,nil,@ft) and
  293. WinToDosTime(FT, Result) then
  294. exit;
  295. Result:=-1;
  296. end;
  297. Function FileSetDate (Handle : THandle;Age : Int64) : Longint;
  298. Var
  299. FT: TFileTime;
  300. begin
  301. Result := 0;
  302. if DosToWinTime(Age, FT) and SetFileTime(Handle, FT, FT, FT) then
  303. Exit;
  304. Result := GetLastError;
  305. end;
  306. Function FileGetAttr (Const FileName : UnicodeString) : Longint;
  307. var
  308. fn: PWideChar;
  309. begin
  310. fn:=StringToPWideChar(FileName);
  311. Result:=GetFileAttributes(fn);
  312. FreeMem(fn);
  313. end;
  314. Function FileSetAttr (Const Filename : UnicodeString; Attr: longint) : Longint;
  315. begin
  316. if not SetFileAttributes(PWideChar(FileName), Attr) then
  317. Result := GetLastError
  318. else
  319. Result:=0;
  320. end;
  321. Function DeleteFile (Const FileName : UnicodeString) : Boolean;
  322. begin
  323. DeleteFile:=Windows.DeleteFile(PWideChar(FileName));
  324. end;
  325. Function RenameFile (Const OldName, NewName : UnicodeString) : Boolean;
  326. begin
  327. Result := MoveFile(PWideChar(OldName), PWideChar(NewName));
  328. end;
  329. {****************************************************************************
  330. Disk Functions
  331. ****************************************************************************}
  332. function diskfree(drive : byte) : int64;
  333. begin
  334. Result := Dos.diskfree(drive);
  335. end;
  336. function disksize(drive : byte) : int64;
  337. begin
  338. Result := Dos.disksize(drive);
  339. end;
  340. {****************************************************************************
  341. Time Functions
  342. ****************************************************************************}
  343. Procedure GetLocalTime(var SystemTime: TSystemTime);
  344. begin
  345. windows.Getlocaltime(SystemTime);
  346. end;
  347. function GetUniversalTime(var SystemTime: TSystemTime): Boolean;
  348. begin
  349. windows.GetSystemTime(SystemTime);
  350. Result:=True;
  351. end;
  352. function GetLocalTimeOffset: Integer;
  353. var
  354. TZInfo: TTimeZoneInformation;
  355. begin
  356. case GetTimeZoneInformation(TZInfo) of
  357. TIME_ZONE_ID_UNKNOWN:
  358. Result := TZInfo.Bias;
  359. TIME_ZONE_ID_STANDARD:
  360. Result := TZInfo.Bias + TZInfo.StandardBias;
  361. TIME_ZONE_ID_DAYLIGHT:
  362. Result := TZInfo.Bias + TZInfo.DaylightBias;
  363. else
  364. Result := 0;
  365. end;
  366. end;
  367. function GetLocalTimeOffset(const DateTime: TDateTime; const InputIsUTC: Boolean; out Offset: Integer): Boolean;
  368. begin
  369. Result := False; // not supported
  370. end;
  371. {****************************************************************************
  372. Misc Functions
  373. ****************************************************************************}
  374. procedure SysBeep;
  375. begin
  376. MessageBeep(0);
  377. end;
  378. {****************************************************************************
  379. Locale Functions
  380. ****************************************************************************}
  381. function GetLocaleStr(LID, LT: Longint; const Def: string): ShortString;
  382. var
  383. L: Integer;
  384. Buf: array[0..255] of WideChar;
  385. s: widestring;
  386. begin
  387. L := GetLocaleInfo(LID, LT, Buf, SizeOf(Buf) div SizeOf(WideChar));
  388. if L > 0 then
  389. begin
  390. SetString(s, Buf, L - 1);
  391. Result:=s;
  392. end
  393. else
  394. Result := Def;
  395. end;
  396. function GetLocaleChar(LID, LT: Longint; Def: Char): Char;
  397. var
  398. Buf: array[0..1] of WideChar;
  399. Buf2: array[0..1] of Char;
  400. begin
  401. if GetLocaleInfo(LID, LT, Buf, 2) > 0 then
  402. begin
  403. WideToAnsiBuf(Buf, 1, Buf2, SizeOf(Buf2));
  404. Result := Buf2[0];
  405. end
  406. else
  407. Result := Def;
  408. end;
  409. Function GetLocaleInt(LID,TP,Def: LongInt): LongInt;
  410. Var
  411. S: String;
  412. C: Integer;
  413. Begin
  414. S:=GetLocaleStr(LID,TP,'0');
  415. Val(S,Result,C);
  416. If C<>0 Then
  417. Result:=Def;
  418. End;
  419. procedure GetFormatSettings;
  420. var
  421. HF : Shortstring;
  422. LID : LCID;
  423. I,Day,DateOrder : longint;
  424. begin
  425. LID := GetUserDefaultLCID;
  426. { Date stuff }
  427. for I := 1 to 12 do
  428. begin
  429. ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
  430. LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
  431. end;
  432. for I := 1 to 7 do
  433. begin
  434. Day := (I + 5) mod 7;
  435. ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
  436. LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
  437. end;
  438. DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
  439. DateOrder := GetLocaleInt(LID, LOCALE_IDate, 0);
  440. Case DateOrder Of
  441. 1: Begin
  442. ShortDateFormat := 'dd/mm/yyyy';
  443. LongDateFormat := 'dddd, d. mmmm yyyy';
  444. End;
  445. 2: Begin
  446. ShortDateFormat := 'yyyy/mm/dd';
  447. LongDateFormat := 'dddd, yyyy mmmm d.';
  448. End;
  449. else
  450. // Default american settings...
  451. ShortDateFormat := 'mm/dd/yyyy';
  452. LongDateFormat := 'dddd, mmmm d. yyyy';
  453. End;
  454. { Time stuff }
  455. TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
  456. TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
  457. TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
  458. if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
  459. HF:='h'
  460. else
  461. HF:='hh';
  462. // No support for 12 hour stuff at the moment...
  463. ShortTimeFormat := HF+':nn';
  464. LongTimeFormat := HF + ':nn:ss';
  465. { Currency stuff }
  466. CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
  467. CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
  468. NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
  469. { Number stuff }
  470. ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
  471. DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
  472. CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
  473. end;
  474. Procedure InitInternational;
  475. begin
  476. InitInternationalGeneric;
  477. SysLocale.MBCS:=GetSystemMetrics(SM_DBCSENABLED)<>0;
  478. SysLocale.RightToLeft:=GetSystemMetrics(SM_MIDEASTENABLED)<>0;
  479. GetFormatSettings;
  480. end;
  481. {****************************************************************************
  482. Target Dependent
  483. ****************************************************************************}
  484. function SysErrorMessage(ErrorCode: Integer): String;
  485. var
  486. MsgBuffer: PWideChar;
  487. len: longint;
  488. begin
  489. MsgBuffer:=nil;
  490. len:=FormatMessage(
  491. FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
  492. nil,
  493. ErrorCode,
  494. 0,
  495. @MsgBuffer, { This function allocs the memory (in this case you pass a PPwidechar)}
  496. 0,
  497. nil);
  498. if MsgBuffer <> nil then begin
  499. while (len > 0) and (MsgBuffer[len - 1] <= #32) do
  500. Dec(len);
  501. MsgBuffer[len]:=#0;
  502. PWideCharToString(MsgBuffer, Result);
  503. LocalFree(HLOCAL(MsgBuffer));
  504. end
  505. else
  506. Result:='';
  507. end;
  508. {****************************************************************************
  509. Initialization code
  510. ****************************************************************************}
  511. // WinCE does not have environment. It can be emulated via registry or file. (YS)
  512. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  513. begin
  514. Result := '';
  515. end;
  516. Function GetEnvironmentVariableCount : Integer;
  517. begin
  518. Result := 0;
  519. end;
  520. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  521. begin
  522. Result := '';
  523. end;
  524. function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
  525. begin
  526. result:=ExecuteProcess(UnicodeString(Path),UnicodeString(ComLine),Flags);
  527. end;
  528. function ExecuteProcess(Const Path: UnicodeString; Const ComLine: UnicodeString;Flags:TExecuteFlags=[]):integer;
  529. var
  530. PI: TProcessInformation;
  531. Proc : THandle;
  532. l : DWord;
  533. e : EOSError;
  534. begin
  535. DosError := 0;
  536. if not CreateProcess(PWideChar(Path), PWideChar(ComLine),
  537. nil, nil, FALSE, 0, nil, nil, nil, PI) then
  538. begin
  539. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  540. e.ErrorCode:=GetLastError;
  541. raise e;
  542. end;
  543. Proc:=PI.hProcess;
  544. CloseHandle(PI.hThread);
  545. if WaitForSingleObject(Proc, dword($ffffffff)) <> $ffffffff then
  546. begin
  547. GetExitCodeProcess(Proc,l);
  548. CloseHandle(Proc);
  549. result:=l;
  550. end
  551. else
  552. begin
  553. e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,GetLastError]);
  554. e.ErrorCode:=GetLastError;
  555. CloseHandle(Proc);
  556. raise e;
  557. end;
  558. end;
  559. function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
  560. var
  561. CommandLine: UnicodeString;
  562. I: integer;
  563. begin
  564. Commandline := '';
  565. for I := 0 to High (ComLine) do
  566. if Pos (' ', ComLine [I]) <> 0 then
  567. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  568. else
  569. CommandLine := CommandLine + ' ' + Comline [I];
  570. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  571. end;
  572. function ExecuteProcess(Const Path: RawByteString; Const ComLine: Array of RawByteString;Flags:TExecuteFlags=[]):integer;
  573. var
  574. CommandLine: UnicodeString;
  575. I: integer;
  576. begin
  577. Commandline := '';
  578. for I := 0 to High (ComLine) do
  579. if Pos (' ', ComLine [I]) <> 0 then
  580. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  581. else
  582. CommandLine := CommandLine + ' ' + Comline [I];
  583. ExecuteProcess := ExecuteProcess (UnicodeString(Path), CommandLine,Flags);
  584. end;
  585. Procedure Sleep(Milliseconds : Cardinal);
  586. begin
  587. Windows.Sleep(MilliSeconds)
  588. end;
  589. Function GetLastOSError : Integer;
  590. begin
  591. Result:=GetLastError;
  592. end;
  593. {****************************************************************************
  594. Initialization code
  595. ****************************************************************************}
  596. Procedure LoadVersionInfo;
  597. Var
  598. versioninfo : TOSVERSIONINFO;
  599. i : Integer;
  600. begin
  601. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  602. GetVersionEx(versioninfo);
  603. WinCEPlatform:=versionInfo.dwPlatformId;
  604. WinCEMajorVersion:=versionInfo.dwMajorVersion;
  605. WinCEMinorVersion:=versionInfo.dwMinorVersion;
  606. WinCEBuildNumber:=versionInfo.dwBuildNumber;
  607. i:=WideToAnsiBuf(@versioninfo.szCSDVersion[0], -1, @WinCECSDVersion[1], SizeOf(WinCECSDVersion) - 1);
  608. if i <> 0 then
  609. WinCECSDVersion[0]:=chr(i - 1);
  610. end;
  611. Function GetSpecialDir(ID: Integer) : String;
  612. Var
  613. APath : array[0..MAX_PATH] of WideChar;
  614. begin
  615. if SHGetSpecialFolderPath(0, APath, ID, True) then
  616. begin
  617. PWideCharToString(APath, Result);
  618. Result:=IncludeTrailingPathDelimiter(Result);
  619. end
  620. else
  621. Result:='';
  622. end;
  623. Function GetAppConfigDir(Global : Boolean) : String;
  624. begin
  625. If Global then
  626. Result:=GetSpecialDir(CSIDL_WINDOWS)
  627. else
  628. Result:=GetSpecialDir(CSIDL_APPDATA);
  629. If (Result<>'') then
  630. begin
  631. if VendorName<>'' then
  632. Result:=IncludeTrailingPathDelimiter(Result+VendorName);
  633. Result:=IncludeTrailingPathDelimiter(Result+ApplicationName);
  634. end
  635. else
  636. Result:=IncludeTrailingPathDelimiter(DGetAppConfigDir(Global));
  637. end;
  638. Function GetAppConfigFile(Global : Boolean; SubDir : Boolean) : String;
  639. begin
  640. result:=DGetAppConfigFile(Global,SubDir);
  641. end;
  642. Function GetTempDir(Global : Boolean) : String;
  643. var
  644. buf: widestring;
  645. begin
  646. SetLength(buf, MAX_PATH);
  647. SetLength(buf, GetTempPath(Length(buf) + 1, PWideChar(buf)));
  648. Result:=buf;
  649. Result := IncludeTrailingPathDelimiter(Result);
  650. end;
  651. {****************************************************************************
  652. Target Dependent WideString stuff
  653. ****************************************************************************}
  654. function DoCompareString(P1, P2: PWideChar; L1, L2: PtrUInt; Flags: DWORD): PtrInt;
  655. begin
  656. SetLastError(0);
  657. Result:=CompareString(LOCALE_USER_DEFAULT,Flags,P1,L1,P2,L2)-2;
  658. if GetLastError<>0 then
  659. RaiseLastOSError;
  660. end;
  661. function WinCECompareWideString(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
  662. begin
  663. if coIgnoreCase in Options then
  664. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE)
  665. else
  666. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
  667. end;
  668. function WinCECompareTextWideString(const s1, s2 : WideString) : PtrInt;
  669. begin
  670. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  671. end;
  672. function WinCECompareUnicodeString(const s1, s2 : UnicodeString; 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 WinCECompareTextUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
  680. begin
  681. Result:=DoCompareString(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), NORM_IGNORECASE);
  682. end;
  683. function WinCEAnsiUpperCase(const s: string): string;
  684. var
  685. buf: PWideChar;
  686. len: longint;
  687. begin
  688. if s <> '' then
  689. begin
  690. buf:=StringToPWideChar(s, @len);
  691. CharUpperBuff(buf, len-1);
  692. PWideCharToString(buf, Result, len-1);
  693. FreeMem(buf);
  694. end
  695. else
  696. Result:='';
  697. end;
  698. function WinCEAnsiLowerCase(const s: string): string;
  699. var
  700. buf: PWideChar;
  701. len: longint;
  702. begin
  703. if s <> '' then
  704. begin
  705. buf:=StringToPWideChar(s, @len);
  706. CharLowerBuff(buf, len-1);
  707. PWideCharToString(buf, Result, len-1);
  708. FreeMem(buf);
  709. end
  710. else
  711. Result:='';
  712. end;
  713. function WinCEAnsiCompareStr(const S1, S2: string): PtrInt;
  714. var
  715. ws1, ws2: PWideChar;
  716. begin
  717. ws1:=StringToPWideChar(S1);
  718. ws2:=StringToPWideChar(S2);
  719. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, Length(S1), ws2, Length(S2)) - 2;
  720. FreeMem(ws2);
  721. FreeMem(ws1);
  722. end;
  723. function WinCEAnsiCompareText(const S1, S2: string): PtrInt;
  724. var
  725. ws1, ws2: PWideChar;
  726. begin
  727. ws1:=StringToPWideChar(S1);
  728. ws2:=StringToPWideChar(S2);
  729. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, Length(S1), ws2, Length(S2)) - 2;
  730. FreeMem(ws2);
  731. FreeMem(ws1);
  732. end;
  733. function WinCEAnsiStrComp(S1, S2: PChar): PtrInt;
  734. var
  735. ws1, ws2: PWideChar;
  736. begin
  737. ws1:=PCharToPWideChar(S1);
  738. ws2:=PCharToPWideChar(S2);
  739. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, -1, ws2, -1) - 2;
  740. FreeMem(ws2);
  741. FreeMem(ws1);
  742. end;
  743. function WinCEAnsiStrIComp(S1, S2: PChar): PtrInt;
  744. var
  745. ws1, ws2: PWideChar;
  746. begin
  747. ws1:=PCharToPWideChar(S1);
  748. ws2:=PCharToPWideChar(S2);
  749. Result:=CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ws1, -1, ws2, -1) - 2;
  750. FreeMem(ws2);
  751. FreeMem(ws1);
  752. end;
  753. function WinCEAnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  754. var
  755. ws1, ws2: PWideChar;
  756. len1, len2: longint;
  757. begin
  758. ws1:=PCharToPWideChar(S1, MaxLen, @len1);
  759. ws2:=PCharToPWideChar(S2, MaxLen, @len2);
  760. Result:=CompareString(LOCALE_USER_DEFAULT, 0, ws1, len1, ws2, len2) - 2;
  761. FreeMem(ws2);
  762. FreeMem(ws1);
  763. end;
  764. function WinCEAnsiStrLIComp(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, NORM_IGNORECASE, ws1, len1, ws2, len2) - 2;
  772. FreeMem(ws2);
  773. FreeMem(ws1);
  774. end;
  775. function WinCEAnsiStrLower(Str: PChar): PChar;
  776. var
  777. buf: PWideChar;
  778. len: longint;
  779. begin
  780. buf:=PCharToPWideChar(Str, -1, @len);
  781. CharLowerBuff(buf, len - 1);
  782. Result:=Str;
  783. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  784. FreeMem(buf);
  785. end;
  786. function WinCEAnsiStrUpper(Str: PChar): PChar;
  787. var
  788. buf: PWideChar;
  789. len: longint;
  790. begin
  791. buf:=PCharToPWideChar(Str, -1, @len);
  792. CharUpperBuff(buf, len - 1);
  793. Result:=Str;
  794. WideToAnsiBuf(buf, -1, Result, StrLen(Str));
  795. FreeMem(buf);
  796. end;
  797. { there is a similiar procedure in the system unit which inits the fields which
  798. are relevant already for the system unit }
  799. procedure InitWinCEWidestrings;
  800. begin
  801. widestringmanager.CompareWideStringProc:=@WinCECompareWideString;
  802. widestringmanager.CompareUnicodeStringProc:=@WinCECompareUnicodeString;
  803. widestringmanager.UpperAnsiStringProc:=@WinCEAnsiUpperCase;
  804. widestringmanager.LowerAnsiStringProc:=@WinCEAnsiLowerCase;
  805. widestringmanager.CompareStrAnsiStringProc:=@WinCEAnsiCompareStr;
  806. widestringmanager.CompareTextAnsiStringProc:=@WinCEAnsiCompareText;
  807. widestringmanager.StrCompAnsiStringProc:=@WinCEAnsiStrComp;
  808. widestringmanager.StrICompAnsiStringProc:=@WinCEAnsiStrIComp;
  809. widestringmanager.StrLCompAnsiStringProc:=@WinCEAnsiStrLComp;
  810. widestringmanager.StrLICompAnsiStringProc:=@WinCEAnsiStrLIComp;
  811. widestringmanager.StrLowerAnsiStringProc:=@WinCEAnsiStrLower;
  812. widestringmanager.StrUpperAnsiStringProc:=@WinCEAnsiStrUpper;
  813. end;
  814. Initialization
  815. InitWinCEWidestrings;
  816. InitExceptions; { Initialize exceptions. OS independent }
  817. InitInternational; { Initialize internationalization settings }
  818. LoadVersionInfo;
  819. OnBeep:=@SysBeep;
  820. SysConfigDir:='\Windows';
  821. Finalization
  822. FreeTerminateProcs;
  823. DoneExceptions;
  824. end.