sysutils.pp 26 KB

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