sysutils.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2010 by Sven Barth
  4. member of the Free Pascal development team
  5. Sysutils unit for NativeNT
  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. uses
  19. ndk;
  20. {$DEFINE HAS_SLEEP}
  21. {$DEFINE HAS_CREATEGUID}
  22. { Include platform independent interface part }
  23. {$i sysutilh.inc}
  24. implementation
  25. uses
  26. sysconst, ndkutils;
  27. {$DEFINE FPC_NOGENERICANSIROUTINES}
  28. { Include platform independent implementation part }
  29. {$i sysutils.inc}
  30. {****************************************************************************
  31. File Functions
  32. ****************************************************************************}
  33. function FileOpen(const FileName : string; Mode : Integer) : THandle;
  34. const
  35. AccessMode: array[0..2] of ACCESS_MASK = (
  36. GENERIC_READ,
  37. GENERIC_WRITE,
  38. GENERIC_READ or GENERIC_WRITE);
  39. ShareMode: array[0..4] of ULONG = (
  40. 0,
  41. 0,
  42. FILE_SHARE_READ,
  43. FILE_SHARE_WRITE,
  44. FILE_SHARE_READ or FILE_SHARE_WRITE);
  45. var
  46. ntstr: UNICODE_STRING;
  47. objattr: OBJECT_ATTRIBUTES;
  48. iostatus: IO_STATUS_BLOCK;
  49. begin
  50. AnsiStrToNtStr(FileName, ntstr);
  51. InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  52. NtCreateFile(@Result, AccessMode[Mode and 3] or NT_SYNCHRONIZE, @objattr,
  53. @iostatus, Nil, FILE_ATTRIBUTE_NORMAL, ShareMode[(Mode and $F0) shr 4],
  54. FILE_OPEN, FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT, Nil, 0);
  55. FreeNtStr(ntstr);
  56. end;
  57. function FileCreate(const FileName : String) : THandle;
  58. var
  59. ntstr: UNICODE_STRING;
  60. objattr: OBJECT_ATTRIBUTES;
  61. iostatus: IO_STATUS_BLOCK;
  62. res: NTSTATUS;
  63. begin
  64. AnsiStrToNTStr(FileName, ntstr);
  65. InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  66. NtCreateFile(@Result, GENERIC_READ or GENERIC_WRITE or NT_SYNCHRONIZE,
  67. @objattr, @iostatus, Nil, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
  68. FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT, Nil, 0);
  69. FreeNtStr(ntstr);
  70. end;
  71. function FileCreate(const FileName : String; Mode: longint) : THandle;
  72. begin
  73. FileCreate := FileCreate(FileName);
  74. end;
  75. function FileRead(Handle : THandle; out Buffer; Count : longint) : Longint;
  76. var
  77. iostatus: IO_STATUS_BLOCK;
  78. res: NTSTATUS;
  79. begin
  80. res := NtReadFile(Handle, 0, Nil, Nil, @iostatus, @Buffer, Count, Nil, Nil);
  81. if res = STATUS_PENDING then begin
  82. res := NtWaitForSingleObject(Handle, False, Nil);
  83. if NT_SUCCESS(res) then
  84. res := iostatus.union1.Status;
  85. end;
  86. if NT_SUCCESS(res) then
  87. Result := LongInt(iostatus.Information)
  88. else
  89. Result := -1;
  90. end;
  91. function FileWrite(Handle : THandle; const Buffer; Count : Longint) : Longint;
  92. var
  93. iostatus: IO_STATUS_BLOCK;
  94. res: NTSTATUS;
  95. begin
  96. res := NtWriteFile(Handle, 0, Nil, Nil, @iostatus, @Buffer, Count, Nil,
  97. Nil);
  98. if res = STATUS_PENDING then begin
  99. res := NtWaitForSingleObject(Handle, False, Nil);
  100. if NT_SUCCESS(res) then
  101. res := iostatus.union1.Status;
  102. end;
  103. if NT_SUCCESS(res) then
  104. Result := LongInt(iostatus.Information)
  105. else
  106. Result := -1;
  107. end;
  108. function FileSeek(Handle : THandle;FOffset,Origin : Longint) : Longint;
  109. begin
  110. Result := longint(FileSeek(Handle, Int64(FOffset), Origin));
  111. end;
  112. function FileSeek(Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
  113. const
  114. ErrorCode = $FFFFFFFFFFFFFFFF;
  115. var
  116. position: FILE_POSITION_INFORMATION;
  117. standard: FILE_STANDARD_INFORMATION;
  118. iostatus: IO_STATUS_BLOCK;
  119. res: NTSTATUS;
  120. begin
  121. { determine the new position }
  122. case Origin of
  123. fsFromBeginning:
  124. position.CurrentByteOffset.QuadPart := FOffset;
  125. fsFromCurrent: begin
  126. res := NtQueryInformationFile(Handle, @iostatus, @position,
  127. SizeOf(FILE_POSITION_INFORMATION), FilePositionInformation);
  128. if res < 0 then begin
  129. Result := ErrorCode;
  130. Exit;
  131. end;
  132. position.CurrentByteOffset.QuadPart :=
  133. position.CurrentByteOffset.QuadPart + FOffset;
  134. end;
  135. fsFromEnd: begin
  136. res := NtQueryInformationFile(Handle, @iostatus, @standard,
  137. SizeOf(FILE_STANDARD_INFORMATION), FileStandardInformation);
  138. if res < 0 then begin
  139. Result := ErrorCode;
  140. Exit;
  141. end;
  142. position.CurrentByteOffset.QuadPart := standard.EndOfFile.QuadPart +
  143. FOffset;
  144. end;
  145. else begin
  146. Result := ErrorCode;
  147. Exit;
  148. end;
  149. end;
  150. { set the new position }
  151. res := NtSetInformationFile(Handle, @iostatus, @position,
  152. SizeOf(FILE_POSITION_INFORMATION), FilePositionInformation);
  153. if res < 0 then
  154. Result := ErrorCode
  155. else
  156. Result := position.CurrentByteOffset.QuadPart;
  157. end;
  158. procedure FileClose(Handle : THandle);
  159. begin
  160. NtClose(Handle);
  161. end;
  162. function FileTruncate(Handle : THandle;Size: Int64) : boolean;
  163. var
  164. endoffileinfo: FILE_END_OF_FILE_INFORMATION;
  165. allocinfo: FILE_ALLOCATION_INFORMATION;
  166. iostatus: IO_STATUS_BLOCK;
  167. res: NTSTATUS;
  168. begin
  169. // based on ReactOS' SetEndOfFile
  170. endoffileinfo.EndOfFile.QuadPart := Size;
  171. res := NtSetInformationFile(Handle, @iostatus, @endoffileinfo,
  172. SizeOf(FILE_END_OF_FILE_INFORMATION), FileEndOfFileInformation);
  173. if NT_SUCCESS(res) then begin
  174. allocinfo.AllocationSize.QuadPart := Size;
  175. res := NtSetInformationFile(handle, @iostatus, @allocinfo,
  176. SizeOf(FILE_ALLOCATION_INFORMATION), FileAllocationInformation);
  177. Result := NT_SUCCESS(res);
  178. end else
  179. Result := False;
  180. end;
  181. function NTToDosTime(const NtTime: LARGE_INTEGER): LongInt;
  182. var
  183. userdata: PKUSER_SHARED_DATA;
  184. local, bias: LARGE_INTEGER;
  185. fields: TIME_FIELDS;
  186. zs: LongInt;
  187. begin
  188. userdata := SharedUserData;
  189. repeat
  190. bias.u.HighPart := userdata^.TimeZoneBias.High1Time;
  191. bias.u.LowPart := userdata^.TimeZoneBias.LowPart;
  192. until bias.u.HighPart = userdata^.TimeZoneBias.High2Time;
  193. local.QuadPart := NtTime.QuadPart - bias.QuadPart;
  194. RtlTimeToTimeFields(@local, @fields);
  195. { from objpas\datutil.inc\DateTimeToDosDateTime }
  196. Result := - 1980;
  197. Result := Result + fields.Year and 127;
  198. Result := Result shl 4;
  199. Result := Result + fields.Month;
  200. Result := Result shl 5;
  201. Result := Result + fields.Day;
  202. Result := Result shl 16;
  203. zs := fields.Hour;
  204. zs := zs shl 6;
  205. zs := zs + fields.Minute;
  206. zs := zs shl 5;
  207. zs := zs + fields.Second div 2;
  208. Result := Result + (zs and $ffff);
  209. end;
  210. function DosToNtTime(aDTime: LongInt; var aNtTime: LARGE_INTEGER): Boolean;
  211. var
  212. fields: TIME_FIELDS;
  213. local, bias: LARGE_INTEGER;
  214. userdata: PKUSER_SHARED_DATA;
  215. begin
  216. { from objpas\datutil.inc\DosDateTimeToDateTime }
  217. fields.Second := (aDTime and 31) * 2;
  218. aDTime := aDTime shr 5;
  219. fields.Minute := aDTime and 63;
  220. aDTime := aDTime shr 6;
  221. fields.Hour := aDTime and 31;
  222. aDTime := aDTime shr 5;
  223. fields.Day := aDTime and 31;
  224. aDTime := aDTime shr 5;
  225. fields.Month := aDTime and 15;
  226. aDTime := aDTime shr 4;
  227. fields.Year := aDTime + 1980;
  228. Result := RtlTimeFieldsToTime(@fields, @local);
  229. if not Result then
  230. Exit;
  231. userdata := SharedUserData;
  232. repeat
  233. bias.u.HighPart := userdata^.TimeZoneBias.High1Time;
  234. bias.u.LowPart := userdata^.TimeZoneBias.LowPart;
  235. until bias.u.HighPart = userdata^.TimeZoneBias.High2Time;
  236. aNtTime.QuadPart := local.QuadPart + bias.QuadPart;
  237. end;
  238. function FileAge(const FileName: String): Longint;
  239. begin
  240. Result := -1;
  241. end;
  242. function FileExists(const FileName: String): Boolean;
  243. var
  244. ntstr: UNICODE_STRING;
  245. objattr: OBJECT_ATTRIBUTES;
  246. res: NTSTATUS;
  247. iostatus: IO_STATUS_BLOCK;
  248. h: THandle;
  249. begin
  250. AnsiStrToNtStr(FileName, ntstr);
  251. InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  252. res := NtOpenFile(@h, 0, @objattr, @iostatus,
  253. FILE_SHARE_READ or FILE_SHARE_WRITE,
  254. FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT);
  255. Result := NT_SUCCESS(res);
  256. if Result then
  257. NtClose(h);
  258. FreeNtStr(ntstr);
  259. end;
  260. function DirectoryExists(const Directory : String) : Boolean;
  261. var
  262. ntstr: UNICODE_STRING;
  263. objattr: OBJECT_ATTRIBUTES;
  264. res: NTSTATUS;
  265. iostatus: IO_STATUS_BLOCK;
  266. h: THandle;
  267. begin
  268. AnsiStrToNtStr(Directory, ntstr);
  269. InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  270. { first test wether this is a object directory }
  271. res := NtOpenDirectoryObject(@h, 0, @objattr);
  272. if NT_SUCCESS(res) then
  273. Result := True
  274. else begin
  275. if res = STATUS_OBJECT_TYPE_MISMATCH then begin
  276. { this is a file object! }
  277. res := NtOpenFile(@h, 0, @objattr, @iostatus,
  278. FILE_SHARE_READ or FILE_SHARE_WRITE,
  279. FILE_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT);
  280. Result := NT_SUCCESS(res);
  281. end else
  282. Result := False;
  283. end;
  284. if Result then
  285. NtClose(h);
  286. FreeNtStr(ntstr);
  287. end;
  288. function FindMatch(var f: TSearchRec): Longint;
  289. begin
  290. Result := -1;
  291. end;
  292. function FindFirst(const Path: String; Attr: Longint; out Rslt: TSearchRec): Longint;
  293. begin
  294. Result := -1;
  295. end;
  296. function FindNext(var Rslt: TSearchRec): Longint;
  297. begin
  298. Result := -1;
  299. end;
  300. procedure FindClose(var F: TSearchrec);
  301. begin
  302. { empty }
  303. end;
  304. function FileGetDate(Handle: THandle): Longint;
  305. var
  306. res: NTSTATUS;
  307. basic: FILE_BASIC_INFORMATION;
  308. iostatus: IO_STATUS_BLOCK;
  309. begin
  310. res := NtQueryInformationFile(Handle, @iostatus, @basic,
  311. SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
  312. if NT_SUCCESS(res) then
  313. Result := NtToDosTime(basic.LastWriteTime)
  314. else
  315. Result := -1;
  316. end;
  317. function FileSetDate(Handle: THandle;Age: Longint): Longint;
  318. var
  319. res: NTSTATUS;
  320. basic: FILE_BASIC_INFORMATION;
  321. iostatus: IO_STATUS_BLOCK;
  322. begin
  323. res := NtQueryInformationFile(Handle, @iostatus, @basic,
  324. SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
  325. if NT_SUCCESS(res) then begin
  326. if not DosToNtTime(Age, basic.LastWriteTime) then begin
  327. Result := -1;
  328. Exit;
  329. end;
  330. res := NtSetInformationFile(Handle, @iostatus, @basic,
  331. SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
  332. if NT_SUCCESS(res) then
  333. Result := 0
  334. else
  335. Result := res;
  336. end else
  337. Result := res;
  338. end;
  339. function FileGetAttr(const FileName: String): Longint;
  340. var
  341. objattr: OBJECT_ATTRIBUTES;
  342. info: FILE_NETWORK_OPEN_INFORMATION;
  343. res: NTSTATUS;
  344. ntstr: UNICODE_STRING;
  345. begin
  346. AnsiStrToNtStr(FileName, ntstr);
  347. InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  348. res := NtQueryFullAttributesFile(@objattr, @info);
  349. if NT_SUCCESS(res) then
  350. Result := info.FileAttributes
  351. else
  352. Result := 0;
  353. FreeNtStr(ntstr);
  354. end;
  355. function FileSetAttr(const Filename: String; Attr: LongInt): Longint;
  356. var
  357. h: THandle;
  358. objattr: OBJECT_ATTRIBUTES;
  359. ntstr: UNICODE_STRING;
  360. basic: FILE_BASIC_INFORMATION;
  361. res: NTSTATUS;
  362. iostatus: IO_STATUS_BLOCK;
  363. begin
  364. AnsiStrToNtStr(Filename, ntstr);
  365. InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  366. res := NtOpenFile(@h,
  367. NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES or FILE_WRITE_ATTRIBUTES,
  368. @objattr, @iostatus,
  369. FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
  370. FILE_SYNCHRONOUS_IO_NONALERT);
  371. FreeNtStr(ntstr);
  372. if NT_SUCCESS(res) then begin
  373. res := NtQueryInformationFile(h, @iostatus, @basic,
  374. SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
  375. if NT_SUCCESS(res) then begin
  376. basic.FileAttributes := Attr;
  377. Result := NtSetInformationFile(h, @iostatus, @basic,
  378. SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
  379. end;
  380. NtClose(h);
  381. end else
  382. Result := res;
  383. end;
  384. function DeleteFile(const FileName: String): Boolean;
  385. var
  386. h: THandle;
  387. objattr: OBJECT_ATTRIBUTES;
  388. ntstr: UNICODE_STRING;
  389. dispinfo: FILE_DISPOSITION_INFORMATION;
  390. res: NTSTATUS;
  391. iostatus: IO_STATUS_BLOCK;
  392. begin
  393. AnsiStrToNtStr(Filename, ntstr);
  394. InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  395. res := NtOpenFile(@h, NT_DELETE, @objattr, @iostatus,
  396. FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
  397. FILE_NON_DIRECTORY_FILE);
  398. FreeNtStr(ntstr);
  399. if NT_SUCCESS(res) then begin
  400. dispinfo.DeleteFile := True;
  401. res := NtSetInformationFile(h, @iostatus, @dispinfo,
  402. SizeOf(FILE_DISPOSITION_INFORMATION), FileDispositionInformation);
  403. Result := NT_SUCCESS(res);
  404. NtClose(h);
  405. end else
  406. Result := False;
  407. end;
  408. function RenameFile(const OldName, NewName: String): Boolean;
  409. var
  410. h: THandle;
  411. objattr: OBJECT_ATTRIBUTES;
  412. iostatus: IO_STATUS_BLOCK;
  413. dest, src: UNICODE_STRING;
  414. renameinfo: PFILE_RENAME_INFORMATION;
  415. res: LongInt;
  416. begin
  417. { check whether the destination exists first }
  418. AnsiStrToNtStr(NewName, dest);
  419. InitializeObjectAttributes(objattr, @dest, 0, 0, Nil);
  420. res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0,
  421. FILE_SHARE_READ or FILE_SHARE_WRITE, FILE_OPEN,
  422. FILE_NON_DIRECTORY_FILE, Nil, 0);
  423. if NT_SUCCESS(res) then begin
  424. { destination already exists => error }
  425. NtClose(h);
  426. Result := False;
  427. end else begin
  428. AnsiStrToNtStr(OldName, src);
  429. InitializeObjectAttributes(objattr, @src, 0, 0, Nil);
  430. res := NtCreateFile(@h,
  431. GENERIC_ALL or NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES,
  432. @objattr, @iostatus, Nil, 0, FILE_SHARE_READ or FILE_SHARE_WRITE,
  433. FILE_OPEN, FILE_OPEN_FOR_BACKUP_INTENT or FILE_OPEN_REMOTE_INSTANCE
  434. or FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT, Nil,
  435. 0);
  436. if NT_SUCCESS(res) then begin
  437. renameinfo := GetMem(SizeOf(FILE_RENAME_INFORMATION) + dest.Length);
  438. with renameinfo^ do begin
  439. ReplaceIfExists := False;
  440. RootDirectory := 0;
  441. FileNameLength := dest.Length;
  442. Move(dest.Buffer^, renameinfo^.FileName, dest.Length);
  443. end;
  444. res := NtSetInformationFile(h, @iostatus, renameinfo,
  445. SizeOf(FILE_RENAME_INFORMATION) + dest.Length,
  446. FileRenameInformation);
  447. if not NT_SUCCESS(res) then begin
  448. { this could happen if src and destination reside on different drives,
  449. so we need to copy the file manually }
  450. {$message warning 'RenameFile: Implement file copy!'}
  451. Result := False;
  452. end else
  453. Result := True;
  454. NtClose(h);
  455. end else
  456. Result := False;
  457. FreeNtStr(src);
  458. end;
  459. FreeNtStr(dest);
  460. end;
  461. {****************************************************************************
  462. Disk Functions
  463. ****************************************************************************}
  464. function diskfree(drive: byte): int64;
  465. begin
  466. { here the mount manager needs to be queried }
  467. Result := -1;
  468. end;
  469. function disksize(drive: byte): int64;
  470. begin
  471. { here the mount manager needs to be queried }
  472. Result := -1;
  473. end;
  474. function GetCurrentDir: String;
  475. begin
  476. GetDir(0, result);
  477. end;
  478. function SetCurrentDir(const NewDir: String): Boolean;
  479. begin
  480. {$I-}
  481. ChDir(NewDir);
  482. {$I+}
  483. Result := IOResult = 0;
  484. end;
  485. function CreateDir(const NewDir: String): Boolean;
  486. begin
  487. {$I-}
  488. MkDir(NewDir);
  489. {$I+}
  490. Result := IOResult = 0;
  491. end;
  492. function RemoveDir(const Dir: String): Boolean;
  493. begin
  494. {$I-}
  495. RmDir(Dir);
  496. {$I+}
  497. Result := IOResult = 0;
  498. end;
  499. {****************************************************************************
  500. Time Functions
  501. ****************************************************************************}
  502. procedure GetLocalTime(var SystemTime: TSystemTime);
  503. var
  504. bias, syst: LARGE_INTEGER;
  505. fields: TIME_FIELDS;
  506. userdata: PKUSER_SHARED_DATA;
  507. begin
  508. // get UTC time
  509. userdata := SharedUserData;
  510. repeat
  511. syst.u.HighPart := userdata^.SystemTime.High1Time;
  512. syst.u.LowPart := userdata^.SystemTime.LowPart;
  513. until syst.u.HighPart = userdata^.SystemTime.High2Time;
  514. // adjust to local time
  515. repeat
  516. bias.u.HighPart := userdata^.TimeZoneBias.High1Time;
  517. bias.u.LowPart := userdata^.TimeZoneBias.LowPart;
  518. until bias.u.HighPart = userdata^.TimeZoneBias.High2Time;
  519. syst.QuadPart := syst.QuadPart - bias.QuadPart;
  520. RtlTimeToTimeFields(@syst, @fields);
  521. SystemTime.Year := fields.Year;
  522. SystemTime.Month := fields.Month;
  523. SystemTime.Day := fields.Day;
  524. SystemTime.Hour := fields.Hour;
  525. SystemTime.Minute := fields.Minute;
  526. SystemTime.Second := fields.Second;
  527. SystemTime.Millisecond := fields.MilliSeconds;
  528. end;
  529. {****************************************************************************
  530. Misc Functions
  531. ****************************************************************************}
  532. procedure sysbeep;
  533. begin
  534. { empty }
  535. end;
  536. procedure InitInternational;
  537. begin
  538. InitInternationalGeneric;
  539. end;
  540. {****************************************************************************
  541. Target Dependent
  542. ****************************************************************************}
  543. function SysErrorMessage(ErrorCode: Integer): String;
  544. begin
  545. Result := 'NT error code: 0x' + IntToHex(ErrorCode, 8);
  546. end;
  547. {****************************************************************************
  548. Initialization code
  549. ****************************************************************************}
  550. function wstrlen(p: PWideChar): LongInt; external name 'FPC_PWIDECHAR_LENGTH';
  551. function GetEnvironmentVariable(const EnvVar: String): String;
  552. var
  553. s : string;
  554. i : longint;
  555. hp: pwidechar;
  556. len: sizeint;
  557. begin
  558. { TODO : test once I know how to execute processes }
  559. Result:='';
  560. hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
  561. while hp^<>#0 do
  562. begin
  563. len:=UnicodeToUTF8(Nil, hp, 0);
  564. SetLength(s,len);
  565. UnicodeToUTF8(PChar(s), hp, len);
  566. //s:=strpas(hp);
  567. i:=pos('=',s);
  568. if uppercase(copy(s,1,i-1))=upcase(envvar) then
  569. begin
  570. Result:=copy(s,i+1,length(s)-i);
  571. break;
  572. end;
  573. { next string entry}
  574. hp:=hp+wstrlen(hp)+1;
  575. end;
  576. end;
  577. function GetEnvironmentVariableCount: Integer;
  578. var
  579. hp : pwidechar;
  580. begin
  581. Result:=0;
  582. hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
  583. If (Hp<>Nil) then
  584. while hp^<>#0 do
  585. begin
  586. Inc(Result);
  587. hp:=hp+wstrlen(hp)+1;
  588. end;
  589. end;
  590. function GetEnvironmentString(Index: Integer): String;
  591. var
  592. hp : pwidechar;
  593. len: sizeint;
  594. begin
  595. Result:='';
  596. hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
  597. If (Hp<>Nil) then
  598. begin
  599. while (hp^<>#0) and (Index>1) do
  600. begin
  601. Dec(Index);
  602. hp:=hp+wstrlen(hp)+1;
  603. end;
  604. If (hp^<>#0) then
  605. begin
  606. len:=UnicodeToUTF8(Nil, hp, 0);
  607. SetLength(Result, len);
  608. UnicodeToUTF8(PChar(Result), hp, len);
  609. end;
  610. end;
  611. end;
  612. function ExecuteProcess(const Path: AnsiString; const ComLine: AnsiString;
  613. Flags: TExecuteFlags = []): Integer;
  614. begin
  615. { TODO : implement }
  616. Result := 0;
  617. end;
  618. function ExecuteProcess(const Path: AnsiString;
  619. const ComLine: Array of AnsiString; Flags:TExecuteFlags = []): Integer;
  620. var
  621. CommandLine: AnsiString;
  622. I: integer;
  623. begin
  624. Commandline := '';
  625. for I := 0 to High (ComLine) do
  626. if Pos (' ', ComLine [I]) <> 0 then
  627. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  628. else
  629. CommandLine := CommandLine + ' ' + Comline [I];
  630. ExecuteProcess := ExecuteProcess (Path, CommandLine,Flags);
  631. end;
  632. procedure Sleep(Milliseconds: Cardinal);
  633. const
  634. DelayFactor = 10000;
  635. var
  636. interval: LARGE_INTEGER;
  637. begin
  638. interval.QuadPart := - Milliseconds * DelayFactor;
  639. NtDelayExecution(False, @interval);
  640. end;
  641. {****************************************************************************
  642. Initialization code
  643. ****************************************************************************}
  644. initialization
  645. InitExceptions; { Initialize exceptions. OS independent }
  646. InitInternational; { Initialize internationalization settings }
  647. OnBeep := @SysBeep;
  648. finalization
  649. DoneExceptions;
  650. end.