sysutils.pp 26 KB

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