sysutils.pp 26 KB

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