sysutils.pp 25 KB

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