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