123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2010 by Sven Barth
- member of the Free Pascal development team
- Sysutils unit for NativeNT
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit sysutils;
- interface
- {$MODE objfpc}
- {$MODESWITCH OUT}
- { force ansistrings }
- {$H+}
- uses
- ndk;
- {$DEFINE HAS_SLEEP}
- {$DEFINE HAS_CREATEGUID}
- { Include platform independent interface part }
- {$i sysutilh.inc}
- implementation
- uses
- sysconst, ndkutils;
- {$DEFINE FPC_NOGENERICANSIROUTINES}
- { Include platform independent implementation part }
- {$i sysutils.inc}
- {****************************************************************************
- File Functions
- ****************************************************************************}
- function FileOpen(const FileName : string; Mode : Integer) : THandle;
- const
- AccessMode: array[0..2] of ACCESS_MASK = (
- GENERIC_READ,
- GENERIC_WRITE,
- GENERIC_READ or GENERIC_WRITE);
- ShareMode: array[0..4] of ULONG = (
- 0,
- 0,
- FILE_SHARE_READ,
- FILE_SHARE_WRITE,
- FILE_SHARE_READ or FILE_SHARE_WRITE);
- var
- ntstr: UNICODE_STRING;
- objattr: OBJECT_ATTRIBUTES;
- iostatus: IO_STATUS_BLOCK;
- begin
- AnsiStrToNtStr(FileName, ntstr);
- InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
- NtCreateFile(@Result, AccessMode[Mode and 3] or NT_SYNCHRONIZE, @objattr,
- @iostatus, Nil, FILE_ATTRIBUTE_NORMAL, ShareMode[(Mode and $F0) shr 4],
- FILE_OPEN, FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT, Nil, 0);
- FreeNtStr(ntstr);
- end;
- function FileCreate(const FileName : String) : THandle;
- var
- ntstr: UNICODE_STRING;
- objattr: OBJECT_ATTRIBUTES;
- iostatus: IO_STATUS_BLOCK;
- res: NTSTATUS;
- begin
- AnsiStrToNTStr(FileName, ntstr);
- InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
- NtCreateFile(@Result, GENERIC_READ or GENERIC_WRITE or NT_SYNCHRONIZE,
- @objattr, @iostatus, Nil, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
- FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT, Nil, 0);
- FreeNtStr(ntstr);
- end;
- function FileCreate(const FileName : String; Mode: longint) : THandle;
- begin
- FileCreate := FileCreate(FileName);
- end;
- function FileRead(Handle : THandle; out Buffer; Count : longint) : Longint;
- var
- iostatus: IO_STATUS_BLOCK;
- res: NTSTATUS;
- begin
- res := NtReadFile(Handle, 0, Nil, Nil, @iostatus, @Buffer, Count, Nil, Nil);
- if res = STATUS_PENDING then begin
- res := NtWaitForSingleObject(Handle, False, Nil);
- if NT_SUCCESS(res) then
- res := iostatus.union1.Status;
- end;
- if NT_SUCCESS(res) then
- Result := LongInt(iostatus.Information)
- else
- Result := -1;
- end;
- function FileWrite(Handle : THandle; const Buffer; Count : Longint) : Longint;
- var
- iostatus: IO_STATUS_BLOCK;
- res: NTSTATUS;
- begin
- res := NtWriteFile(Handle, 0, Nil, Nil, @iostatus, @Buffer, Count, Nil,
- Nil);
- if res = STATUS_PENDING then begin
- res := NtWaitForSingleObject(Handle, False, Nil);
- if NT_SUCCESS(res) then
- res := iostatus.union1.Status;
- end;
- if NT_SUCCESS(res) then
- Result := LongInt(iostatus.Information)
- else
- Result := -1;
- end;
- function FileSeek(Handle : THandle;FOffset,Origin : Longint) : Longint;
- begin
- Result := longint(FileSeek(Handle, Int64(FOffset), Origin));
- end;
- function FileSeek(Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
- const
- ErrorCode = $FFFFFFFFFFFFFFFF;
- var
- position: FILE_POSITION_INFORMATION;
- standard: FILE_STANDARD_INFORMATION;
- iostatus: IO_STATUS_BLOCK;
- res: NTSTATUS;
- begin
- { determine the new position }
- case Origin of
- fsFromBeginning:
- position.CurrentByteOffset.QuadPart := FOffset;
- fsFromCurrent: begin
- res := NtQueryInformationFile(Handle, @iostatus, @position,
- SizeOf(FILE_POSITION_INFORMATION), FilePositionInformation);
- if res < 0 then begin
- Result := ErrorCode;
- Exit;
- end;
- position.CurrentByteOffset.QuadPart :=
- position.CurrentByteOffset.QuadPart + FOffset;
- end;
- fsFromEnd: begin
- res := NtQueryInformationFile(Handle, @iostatus, @standard,
- SizeOf(FILE_STANDARD_INFORMATION), FileStandardInformation);
- if res < 0 then begin
- Result := ErrorCode;
- Exit;
- end;
- position.CurrentByteOffset.QuadPart := standard.EndOfFile.QuadPart +
- FOffset;
- end;
- else begin
- Result := ErrorCode;
- Exit;
- end;
- end;
- { set the new position }
- res := NtSetInformationFile(Handle, @iostatus, @position,
- SizeOf(FILE_POSITION_INFORMATION), FilePositionInformation);
- if res < 0 then
- Result := ErrorCode
- else
- Result := position.CurrentByteOffset.QuadPart;
- end;
- procedure FileClose(Handle : THandle);
- begin
- NtClose(Handle);
- end;
- function FileTruncate(Handle : THandle;Size: Int64) : boolean;
- var
- endoffileinfo: FILE_END_OF_FILE_INFORMATION;
- allocinfo: FILE_ALLOCATION_INFORMATION;
- iostatus: IO_STATUS_BLOCK;
- res: NTSTATUS;
- begin
- // based on ReactOS' SetEndOfFile
- endoffileinfo.EndOfFile.QuadPart := Size;
- res := NtSetInformationFile(Handle, @iostatus, @endoffileinfo,
- SizeOf(FILE_END_OF_FILE_INFORMATION), FileEndOfFileInformation);
- if NT_SUCCESS(res) then begin
- allocinfo.AllocationSize.QuadPart := Size;
- res := NtSetInformationFile(handle, @iostatus, @allocinfo,
- SizeOf(FILE_ALLOCATION_INFORMATION), FileAllocationInformation);
- Result := NT_SUCCESS(res);
- end else
- Result := False;
- end;
- function NTToDosTime(const NtTime: LARGE_INTEGER): LongInt;
- var
- userdata: PKUSER_SHARED_DATA;
- local, bias: LARGE_INTEGER;
- fields: TIME_FIELDS;
- zs: LongInt;
- begin
- userdata := SharedUserData;
- repeat
- bias.u.HighPart := userdata^.TimeZoneBias.High1Time;
- bias.u.LowPart := userdata^.TimeZoneBias.LowPart;
- until bias.u.HighPart = userdata^.TimeZoneBias.High2Time;
- local.QuadPart := NtTime.QuadPart - bias.QuadPart;
- RtlTimeToTimeFields(@local, @fields);
- { from objpas\datutil.inc\DateTimeToDosDateTime }
- Result := - 1980;
- Result := Result + fields.Year and 127;
- Result := Result shl 4;
- Result := Result + fields.Month;
- Result := Result shl 5;
- Result := Result + fields.Day;
- Result := Result shl 16;
- zs := fields.Hour;
- zs := zs shl 6;
- zs := zs + fields.Minute;
- zs := zs shl 5;
- zs := zs + fields.Second div 2;
- Result := Result + (zs and $ffff);
- end;
- function DosToNtTime(aDTime: LongInt; var aNtTime: LARGE_INTEGER): Boolean;
- var
- fields: TIME_FIELDS;
- local, bias: LARGE_INTEGER;
- userdata: PKUSER_SHARED_DATA;
- begin
- { from objpas\datutil.inc\DosDateTimeToDateTime }
- fields.Second := (aDTime and 31) * 2;
- aDTime := aDTime shr 5;
- fields.Minute := aDTime and 63;
- aDTime := aDTime shr 6;
- fields.Hour := aDTime and 31;
- aDTime := aDTime shr 5;
- fields.Day := aDTime and 31;
- aDTime := aDTime shr 5;
- fields.Month := aDTime and 15;
- aDTime := aDTime shr 4;
- fields.Year := aDTime + 1980;
- Result := RtlTimeFieldsToTime(@fields, @local);
- if not Result then
- Exit;
- userdata := SharedUserData;
- repeat
- bias.u.HighPart := userdata^.TimeZoneBias.High1Time;
- bias.u.LowPart := userdata^.TimeZoneBias.LowPart;
- until bias.u.HighPart = userdata^.TimeZoneBias.High2Time;
- aNtTime.QuadPart := local.QuadPart + bias.QuadPart;
- end;
- function FileAge(const FileName: String): Longint;
- begin
- Result := -1;
- end;
- function FileExists(const FileName: String): Boolean;
- var
- ntstr: UNICODE_STRING;
- objattr: OBJECT_ATTRIBUTES;
- res: NTSTATUS;
- iostatus: IO_STATUS_BLOCK;
- h: THandle;
- begin
- AnsiStrToNtStr(FileName, ntstr);
- InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
- res := NtOpenFile(@h, 0, @objattr, @iostatus,
- FILE_SHARE_READ or FILE_SHARE_WRITE,
- FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT);
- Result := NT_SUCCESS(res);
- if Result then
- NtClose(h);
- FreeNtStr(ntstr);
- end;
- function DirectoryExists(const Directory : String) : Boolean;
- var
- ntstr: UNICODE_STRING;
- objattr: OBJECT_ATTRIBUTES;
- res: NTSTATUS;
- iostatus: IO_STATUS_BLOCK;
- h: THandle;
- begin
- AnsiStrToNtStr(Directory, ntstr);
- InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
- { first test wether this is a object directory }
- res := NtOpenDirectoryObject(@h, 0, @objattr);
- if NT_SUCCESS(res) then
- Result := True
- else begin
- if res = STATUS_OBJECT_TYPE_MISMATCH then begin
- { this is a file object! }
- res := NtOpenFile(@h, 0, @objattr, @iostatus,
- FILE_SHARE_READ or FILE_SHARE_WRITE,
- FILE_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT);
- Result := NT_SUCCESS(res);
- end else
- Result := False;
- end;
- if Result then
- NtClose(h);
- FreeNtStr(ntstr);
- end;
- function FindMatch(var f: TSearchRec): Longint;
- begin
- Result := -1;
- end;
- function FindFirst(const Path: String; Attr: Longint; out Rslt: TSearchRec): Longint;
- begin
- Result := -1;
- end;
- function FindNext(var Rslt: TSearchRec): Longint;
- begin
- Result := -1;
- end;
- procedure FindClose(var F: TSearchrec);
- begin
- { empty }
- end;
- function FileGetDate(Handle: THandle): Longint;
- var
- res: NTSTATUS;
- basic: FILE_BASIC_INFORMATION;
- iostatus: IO_STATUS_BLOCK;
- begin
- res := NtQueryInformationFile(Handle, @iostatus, @basic,
- SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
- if NT_SUCCESS(res) then
- Result := NtToDosTime(basic.LastWriteTime)
- else
- Result := -1;
- end;
- function FileSetDate(Handle: THandle;Age: Longint): Longint;
- var
- res: NTSTATUS;
- basic: FILE_BASIC_INFORMATION;
- iostatus: IO_STATUS_BLOCK;
- begin
- res := NtQueryInformationFile(Handle, @iostatus, @basic,
- SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
- if NT_SUCCESS(res) then begin
- if not DosToNtTime(Age, basic.LastWriteTime) then begin
- Result := -1;
- Exit;
- end;
- res := NtSetInformationFile(Handle, @iostatus, @basic,
- SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
- if NT_SUCCESS(res) then
- Result := 0
- else
- Result := res;
- end else
- Result := res;
- end;
- function FileGetAttr(const FileName: String): Longint;
- var
- objattr: OBJECT_ATTRIBUTES;
- info: FILE_NETWORK_OPEN_INFORMATION;
- res: NTSTATUS;
- ntstr: UNICODE_STRING;
- begin
- AnsiStrToNtStr(FileName, ntstr);
- InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
- res := NtQueryFullAttributesFile(@objattr, @info);
- if NT_SUCCESS(res) then
- Result := info.FileAttributes
- else
- Result := 0;
- FreeNtStr(ntstr);
- end;
- function FileSetAttr(const Filename: String; Attr: LongInt): Longint;
- var
- h: THandle;
- objattr: OBJECT_ATTRIBUTES;
- ntstr: UNICODE_STRING;
- basic: FILE_BASIC_INFORMATION;
- res: NTSTATUS;
- iostatus: IO_STATUS_BLOCK;
- begin
- AnsiStrToNtStr(Filename, ntstr);
- InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
- res := NtOpenFile(@h,
- NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES or FILE_WRITE_ATTRIBUTES,
- @objattr, @iostatus,
- FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- FreeNtStr(ntstr);
- if NT_SUCCESS(res) then begin
- res := NtQueryInformationFile(h, @iostatus, @basic,
- SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
- if NT_SUCCESS(res) then begin
- basic.FileAttributes := Attr;
- Result := NtSetInformationFile(h, @iostatus, @basic,
- SizeOf(FILE_BASIC_INFORMATION), FileBasicInformation);
- end;
- NtClose(h);
- end else
- Result := res;
- end;
- function DeleteFile(const FileName: String): Boolean;
- var
- h: THandle;
- objattr: OBJECT_ATTRIBUTES;
- ntstr: UNICODE_STRING;
- dispinfo: FILE_DISPOSITION_INFORMATION;
- res: NTSTATUS;
- iostatus: IO_STATUS_BLOCK;
- begin
- AnsiStrToNtStr(Filename, ntstr);
- InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
- res := NtOpenFile(@h, NT_DELETE, @objattr, @iostatus,
- FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
- FILE_NON_DIRECTORY_FILE);
- FreeNtStr(ntstr);
- if NT_SUCCESS(res) then begin
- dispinfo.DeleteFile := True;
- res := NtSetInformationFile(h, @iostatus, @dispinfo,
- SizeOf(FILE_DISPOSITION_INFORMATION), FileDispositionInformation);
- Result := NT_SUCCESS(res);
- NtClose(h);
- end else
- Result := False;
- end;
- function RenameFile(const OldName, NewName: String): Boolean;
- var
- h: THandle;
- objattr: OBJECT_ATTRIBUTES;
- iostatus: IO_STATUS_BLOCK;
- dest, src: UNICODE_STRING;
- renameinfo: PFILE_RENAME_INFORMATION;
- res: LongInt;
- begin
- { check whether the destination exists first }
- AnsiStrToNtStr(NewName, dest);
- InitializeObjectAttributes(objattr, @dest, 0, 0, Nil);
- res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0,
- FILE_SHARE_READ or FILE_SHARE_WRITE, FILE_OPEN,
- FILE_NON_DIRECTORY_FILE, Nil, 0);
- if NT_SUCCESS(res) then begin
- { destination already exists => error }
- NtClose(h);
- Result := False;
- end else begin
- AnsiStrToNtStr(OldName, src);
- InitializeObjectAttributes(objattr, @src, 0, 0, Nil);
- res := NtCreateFile(@h,
- GENERIC_ALL or NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES,
- @objattr, @iostatus, Nil, 0, FILE_SHARE_READ or FILE_SHARE_WRITE,
- FILE_OPEN, FILE_OPEN_FOR_BACKUP_INTENT or FILE_OPEN_REMOTE_INSTANCE
- or FILE_NON_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT, Nil,
- 0);
- if NT_SUCCESS(res) then begin
- renameinfo := GetMem(SizeOf(FILE_RENAME_INFORMATION) + dest.Length);
- with renameinfo^ do begin
- ReplaceIfExists := False;
- RootDirectory := 0;
- FileNameLength := dest.Length;
- Move(dest.Buffer^, renameinfo^.FileName, dest.Length);
- end;
- res := NtSetInformationFile(h, @iostatus, renameinfo,
- SizeOf(FILE_RENAME_INFORMATION) + dest.Length,
- FileRenameInformation);
- if not NT_SUCCESS(res) then begin
- { this could happen if src and destination reside on different drives,
- so we need to copy the file manually }
- {$message warning 'RenameFile: Implement file copy!'}
- Result := False;
- end else
- Result := True;
- NtClose(h);
- end else
- Result := False;
- FreeNtStr(src);
- end;
- FreeNtStr(dest);
- end;
- {****************************************************************************
- Disk Functions
- ****************************************************************************}
- function diskfree(drive: byte): int64;
- begin
- { here the mount manager needs to be queried }
- Result := -1;
- end;
- function disksize(drive: byte): int64;
- begin
- { here the mount manager needs to be queried }
- Result := -1;
- end;
- function GetCurrentDir: String;
- begin
- GetDir(0, result);
- end;
- function SetCurrentDir(const NewDir: String): Boolean;
- begin
- {$I-}
- ChDir(NewDir);
- {$I+}
- Result := IOResult = 0;
- end;
- function CreateDir(const NewDir: String): Boolean;
- begin
- {$I-}
- MkDir(NewDir);
- {$I+}
- Result := IOResult = 0;
- end;
- function RemoveDir(const Dir: String): Boolean;
- begin
- {$I-}
- RmDir(Dir);
- {$I+}
- Result := IOResult = 0;
- end;
- {****************************************************************************
- Time Functions
- ****************************************************************************}
- procedure GetLocalTime(var SystemTime: TSystemTime);
- var
- bias, syst: LARGE_INTEGER;
- fields: TIME_FIELDS;
- userdata: PKUSER_SHARED_DATA;
- begin
- // get UTC time
- userdata := SharedUserData;
- repeat
- syst.u.HighPart := userdata^.SystemTime.High1Time;
- syst.u.LowPart := userdata^.SystemTime.LowPart;
- until syst.u.HighPart = userdata^.SystemTime.High2Time;
- // adjust to local time
- repeat
- bias.u.HighPart := userdata^.TimeZoneBias.High1Time;
- bias.u.LowPart := userdata^.TimeZoneBias.LowPart;
- until bias.u.HighPart = userdata^.TimeZoneBias.High2Time;
- syst.QuadPart := syst.QuadPart - bias.QuadPart;
- RtlTimeToTimeFields(@syst, @fields);
- SystemTime.Year := fields.Year;
- SystemTime.Month := fields.Month;
- SystemTime.Day := fields.Day;
- SystemTime.Hour := fields.Hour;
- SystemTime.Minute := fields.Minute;
- SystemTime.Second := fields.Second;
- SystemTime.Millisecond := fields.MilliSeconds;
- end;
- {****************************************************************************
- Misc Functions
- ****************************************************************************}
- procedure sysbeep;
- begin
- { empty }
- end;
- procedure InitInternational;
- begin
- InitInternationalGeneric;
- end;
- {****************************************************************************
- Target Dependent
- ****************************************************************************}
- function SysErrorMessage(ErrorCode: Integer): String;
- begin
- Result := 'NT error code: 0x' + IntToHex(ErrorCode, 8);
- end;
- {****************************************************************************
- Initialization code
- ****************************************************************************}
- function wstrlen(p: PWideChar): LongInt; external name 'FPC_PWIDECHAR_LENGTH';
- function GetEnvironmentVariable(const EnvVar: String): String;
- var
- s : string;
- i : longint;
- hp: pwidechar;
- len: sizeint;
- begin
- { TODO : test once I know how to execute processes }
- Result:='';
- hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
- while hp^<>#0 do
- begin
- len:=UnicodeToUTF8(Nil, hp, 0);
- SetLength(s,len);
- UnicodeToUTF8(PChar(s), hp, len);
- //s:=strpas(hp);
- i:=pos('=',s);
- if uppercase(copy(s,1,i-1))=upcase(envvar) then
- begin
- Result:=copy(s,i+1,length(s)-i);
- break;
- end;
- { next string entry}
- hp:=hp+wstrlen(hp)+1;
- end;
- end;
- function GetEnvironmentVariableCount: Integer;
- var
- hp : pwidechar;
- begin
- Result:=0;
- hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
- If (Hp<>Nil) then
- while hp^<>#0 do
- begin
- Inc(Result);
- hp:=hp+wstrlen(hp)+1;
- end;
- end;
- function GetEnvironmentString(Index: Integer): String;
- var
- hp : pwidechar;
- len: sizeint;
- begin
- Result:='';
- hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
- If (Hp<>Nil) then
- begin
- while (hp^<>#0) and (Index>1) do
- begin
- Dec(Index);
- hp:=hp+wstrlen(hp)+1;
- end;
- If (hp^<>#0) then
- begin
- len:=UnicodeToUTF8(Nil, hp, 0);
- SetLength(Result, len);
- UnicodeToUTF8(PChar(Result), hp, len);
- end;
- end;
- end;
- function ExecuteProcess(const Path: AnsiString; const ComLine: AnsiString;
- Flags: TExecuteFlags = []): Integer;
- begin
- { TODO : implement }
- Result := 0;
- end;
- function ExecuteProcess(const Path: AnsiString;
- const ComLine: Array of AnsiString; Flags:TExecuteFlags = []): Integer;
- var
- CommandLine: AnsiString;
- I: integer;
- begin
- Commandline := '';
- for I := 0 to High (ComLine) do
- if Pos (' ', ComLine [I]) <> 0 then
- CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
- else
- CommandLine := CommandLine + ' ' + Comline [I];
- ExecuteProcess := ExecuteProcess (Path, CommandLine,Flags);
- end;
- procedure Sleep(Milliseconds: Cardinal);
- const
- DelayFactor = 10000;
- var
- interval: LARGE_INTEGER;
- begin
- interval.QuadPart := - Milliseconds * DelayFactor;
- NtDelayExecution(False, @interval);
- end;
- {****************************************************************************
- Initialization code
- ****************************************************************************}
- initialization
- InitExceptions; { Initialize exceptions. OS independent }
- InitInternational; { Initialize internationalization settings }
- OnBeep := @SysBeep;
- finalization
- DoneExceptions;
- end.
|