mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 22:49:34 +02:00

* Many more RTL units are enabled now, like SysUtils, Classes, Math, FGL, etc and Text-, File- and ConsoleIO features are enabled now as well (Threading and Processes are enabled, too, but their implementations are only stubs!). ConsoleIO isn't tested though, because the processes that are started by SMSS have their Standard Handles set to 0. git-svn-id: trunk@16553 -
384 lines
11 KiB
PHP
384 lines
11 KiB
PHP
{
|
|
Basic stuff for NativeNT RTLs
|
|
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 2009-2010 by Sven Barth
|
|
|
|
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.
|
|
|
|
**********************************************************************}
|
|
|
|
const
|
|
{$ifdef kmode}
|
|
ntdll = 'ntoskrnl.exe';
|
|
{$else}
|
|
ntdll = 'ntdll.dll';
|
|
{$endif}
|
|
|
|
type
|
|
PHandle = ^THandle;
|
|
|
|
TNtUnicodeString = packed record
|
|
Length: Word; // used characters in buffer
|
|
MaximumLength: Word; // maximum characters in buffer
|
|
Buffer: PWideChar;
|
|
end;
|
|
PNtUnicodeString = ^TNtUnicodeString;
|
|
|
|
// using Int64 is an alternative (QWord might have unintended side effects)
|
|
TLargeInteger = packed record
|
|
case Boolean of
|
|
True:(LowPart: LongWord;
|
|
HighPart: LongInt);
|
|
False:(QuadPart: Int64);
|
|
end;
|
|
PLargeInteger = ^TLargeInteger;
|
|
|
|
|
|
TObjectAttributes = record
|
|
Length: LongWord;
|
|
RootDirectory: THandle;
|
|
ObjectName: PNtUnicodeString;
|
|
Attributes: LongWord;
|
|
SecurityDescriptor: Pointer; // Points to type SECURITY_DESCRIPTOR
|
|
SecurityQualityOfService: Pointer; // Points to type SECURITY_QUALITY_OF_SERVICE
|
|
end;
|
|
PObjectAttributes = ^TObjectAttributes;
|
|
|
|
TRtlDriveLetterCurDir = packed record
|
|
Flags: Word;
|
|
Length: Word;
|
|
TimeStamp: LongWord;
|
|
DosPath: TNtUnicodeString;
|
|
end;
|
|
|
|
TCurDir = packed record
|
|
DosPath: TNtUnicodeString;
|
|
Handle: THandle;
|
|
end;
|
|
|
|
TRtlUserProcessParameters = packed record
|
|
MaximumLength: LongWord;
|
|
Length: LongWord;
|
|
Flags: LongWord;
|
|
DebugFlags: LongWord;
|
|
ConsoleHandle: THandle;
|
|
ConsoleFlags: LongWord;
|
|
StandardInput: THandle;
|
|
StandardOutput: THandle;
|
|
StandardError: THandle;
|
|
CurrentDirectory: TCurDir;
|
|
DllPath: TNtUnicodeString;
|
|
ImagePathName: TNtUnicodeString;
|
|
CommandLine: TNtUnicodeString;
|
|
Environment: ^Word; // PWSTR
|
|
StartingX: LongWord;
|
|
StartingY: LongWord;
|
|
CountX: LongWord;
|
|
CountY: LongWord;
|
|
CountCharsX: LongWord;
|
|
CountCharsY: LongWord;
|
|
FillAttribute: LongWord;
|
|
WindowFlags: LongWord;
|
|
ShowWindowFlags: LongWord;
|
|
WindowTitle: TNtUnicodeString;
|
|
DesktopInfo: TNtUnicodeString;
|
|
ShellInfo: TNtUnicodeString;
|
|
RuntimeData: TNtUnicodeString;
|
|
CurrentDirectories: array[0..31] of TRtlDriveLetterCurDir;
|
|
end;
|
|
PRtlUserProcessParameters = ^TRtlUserProcessParameters;
|
|
|
|
// a simple version of the PEB that contains the common stuff
|
|
TSimplePEB = packed record
|
|
InheritedAddressSpace: Byte;
|
|
ReadImageFileExecOptions: Byte;
|
|
BeingDebugged: Byte;
|
|
SpareBool: Byte;
|
|
Mutant: THandle;
|
|
ImageBaseAddress: Pointer;
|
|
Ldr: Pointer;
|
|
ProcessParameters: PRtlUserProcessParameters;
|
|
SubSystemData: Pointer;
|
|
ProcessHeap: Pointer;
|
|
FastPebLock: Pointer;
|
|
FastPebLockRoutine: Pointer;
|
|
FastPebUnlockRoutine: Pointer;
|
|
EnvironmentUpdateCount: LongWord;
|
|
KernelCallbackTable: Pointer;
|
|
EventLogSection: Pointer;
|
|
EventLog: Pointer;
|
|
FreeList: Pointer;
|
|
TlsExpansionCounter: LongWord;
|
|
TlsBitmap: Pointer;
|
|
TlsBitmapBits: array[0..1] of LongWord;
|
|
ReadOnlySharedMemoryBase: Pointer;
|
|
ReadOnlySharedMemoryHeap: Pointer;
|
|
ReadOnlyStaticServerData: Pointer;
|
|
AnsiCodePageData: Pointer;
|
|
OemCodePageData: Pointer;
|
|
UnicodeCaseTableData: Pointer;
|
|
NumberOfProcessors: LongWord;
|
|
NtGlobalFlag: LongWord;
|
|
CriticalSectionTimeout: TLargeInteger;
|
|
HeapSegmentReserve: LongWord;
|
|
HeapSegmentCommit: LongWord;
|
|
HeapDeCommitTotalFreeThreshold: LongWord;
|
|
HeapDeCommitFreeBlockThreshold: LongWord;
|
|
NumberOfHeaps: LongWord;
|
|
MaximumNumberOfHeaps: LongWord;
|
|
ProcessHeaps: Pointer;
|
|
GdiSharedHandleTable: Pointer;
|
|
ProcessStarterHelper: Pointer;
|
|
GdiDCAttributeList: LongWord;
|
|
LoaderLock: Pointer;
|
|
OSMajorVersion: LongWord;
|
|
OSMinorVersion: LongWord;
|
|
OSBuildNumber: Word;
|
|
OSCSDVersion: Word;
|
|
OSPlatformId: LongWord;
|
|
ImageSubSystem: LongWord;
|
|
ImageSubSystemMajorVersion: LongWord;
|
|
ImageSubSystemMinorVersion: LongWord;
|
|
ImageProcessAffinityMask: LongWord;
|
|
GdiHandleBuffer: array[0..$21] of LongWord;
|
|
PostProcessInitRoutine: Pointer;
|
|
TlsExpansionBitmap: Pointer;
|
|
TlsExpansionBitmapBits: array[0..$19] of Word;
|
|
SessionId: LongWord;
|
|
end;
|
|
PSimplePEB = ^TSimplePEB;
|
|
|
|
PExceptionRegistrationRecord = ^TExceptionRegistrationRecord;
|
|
TExceptionRegistrationRecord = packed record
|
|
Next: PExceptionRegistrationRecord;
|
|
Handler: Pointer; //PExceptionRoutine;
|
|
end;
|
|
|
|
PNTTIB = ^TNTTIB;
|
|
TNTTIB = packed record
|
|
ExceptionList: PExceptionRegistrationRecord;
|
|
StackBase: Pointer;
|
|
StackLimit: Pointer;
|
|
SubSystemTib: Pointer;
|
|
union1: record
|
|
case Boolean of
|
|
True: (FiberData: Pointer);
|
|
False: (Version: DWord);
|
|
end;
|
|
ArbitraryUserPointer: Pointer;
|
|
Self: PNTTIB;
|
|
end;
|
|
|
|
TClientID = packed record
|
|
UniqueProcess: LongWord;
|
|
UniqueThread: LongWord;
|
|
end;
|
|
PClientID = ^TClientID;
|
|
|
|
TSimpleTEB = packed record
|
|
NtTib: TNTTIB;
|
|
EnvironmentPointer: Pointer;
|
|
ClientId: TClientID;
|
|
end;
|
|
PSimpleTEB = ^TSimpleTEB;
|
|
|
|
const
|
|
STATUS_SUCCESS = LongInt($00000000);
|
|
STATUS_PENDING = LongInt($00000103);
|
|
STATUS_END_OF_FILE = LongInt($C0000011);
|
|
STATUS_ACCESS_DENIED = LongInt($C0000022);
|
|
STATUS_OBJECT_TYPE_MISMATCH = LongInt($C0000024);
|
|
STATUS_PIPE_BROKEN = LongInt($C000014B);
|
|
STATUS_OBJECT_NAME_NOT_FOUND = LongInt($C0000034);
|
|
STATUS_FILE_IS_A_DIRECTORY = LongInt($C00000BA);
|
|
|
|
OBJ_INHERIT = $00000002;
|
|
OBJ_PERMANENT = $00000010;
|
|
|
|
FILE_DIRECTORY_FILE = $00000001;
|
|
FILE_NON_DIRECTORY_FILE = $00000040;
|
|
FILE_SYNCHRONOUS_IO_NONALERT = $00000020;
|
|
FILE_OPEN_FOR_BACKUP_INTENT = $00004000;
|
|
FILE_OPEN_REMOTE_INSTANCE = $00000400;
|
|
|
|
STANDARD_RIGHTS_REQUIRED = $000F0000;
|
|
|
|
FILE_SHARE_READ = $00000001;
|
|
FILE_SHARE_WRITE = $00000002;
|
|
FILE_SHARE_DELETE = $00000004;
|
|
|
|
FILE_OPEN = $00000001;
|
|
FILE_CREATE = $00000002;
|
|
FILE_OVERWRITE_IF = $00000005;
|
|
|
|
FILE_ATTRIBUTE_NORMAL = $00000080;
|
|
|
|
NT_SYNCHRONIZE = $00100000; // normally called SYNCHRONIZE
|
|
NT_DELETE = $00010000; // normally called DELETE
|
|
GENERIC_READ = LongWord($80000000);
|
|
GENERIC_WRITE = $40000000;
|
|
GENERIC_ALL = $10000000;
|
|
FILE_READ_ATTRIBUTES = $00000080;
|
|
|
|
FileStandardInformation = 5;
|
|
FileRenameInformation = 10;
|
|
FileDispositionInformation = 13;
|
|
FilePositionInformation = 14;
|
|
FileAllocationInformation = 19;
|
|
FileEndOfFileInformation = 20;
|
|
|
|
{ Share mode open }
|
|
fmShareCompat = $00000000;
|
|
fmShareExclusive = $10;
|
|
fmShareDenyWrite = $20;
|
|
fmShareDenyRead = $30;
|
|
fmShareDenyNone = $40;
|
|
|
|
type
|
|
TIoStatusBlock = record
|
|
Status: LongInt;
|
|
Information: PLongWord;
|
|
end;
|
|
PIoStatusBlock = ^TIoStatusBlock;
|
|
|
|
TFileDispositionInformation = record
|
|
DeleteFile: LongBool;
|
|
end;
|
|
|
|
TFileStandardInformation = record
|
|
AllocationSize: TLargeInteger;
|
|
EndOfFile: TLargeInteger;
|
|
NumberOfLinks: LongWord;
|
|
DeletePending: ByteBool;
|
|
Directory: ByteBool;
|
|
end;
|
|
|
|
TFilePositionInformation = record
|
|
CurrentByteOffset: TLargeInteger;
|
|
end;
|
|
|
|
TFileEndOfFileInformation = record
|
|
EndOfFile: TLargeInteger;
|
|
end;
|
|
|
|
TFileAllocationInformation = record
|
|
AllocationSize: TLargeInteger;
|
|
end;
|
|
|
|
TFileRenameInformation = record
|
|
ReplaceIfExists: ByteBool;
|
|
RootDirectory: THandle;
|
|
FileNameLength: LongWord;
|
|
FileName: array[0..0] of WideChar;
|
|
end;
|
|
PFileRenameInformation = ^TFileRenameInformation;
|
|
|
|
threadvar
|
|
errno: LongInt;
|
|
|
|
procedure Errno2InoutRes;
|
|
var
|
|
r: Word;
|
|
begin
|
|
{$message warning 'Correctly implement Errno2InoutRes'}
|
|
case errno of
|
|
STATUS_OBJECT_NAME_NOT_FOUND:
|
|
r := 2;
|
|
STATUS_OBJECT_TYPE_MISMATCH:
|
|
r := 3;
|
|
STATUS_ACCESS_DENIED:
|
|
r := 5;
|
|
STATUS_END_OF_FILE:
|
|
r := 100;
|
|
else
|
|
r := errno;
|
|
end;
|
|
errno := 0;
|
|
InOutRes := r;
|
|
end;
|
|
|
|
function NtCreateFile(FileHandle: PHandle; DesiredAccess: LongWord;
|
|
ObjectAttributes: PObjectAttributes; IoStatusBlock: PIOStatusBlock;
|
|
AllocationSize: PLargeInteger; FileAttributes: LongWord;
|
|
ShareAccess: LongWord; CreateDisposition: LongWord; CreateOptions: LongWord;
|
|
EaBuffer: Pointer; EaLength: LongWord): LongInt; stdcall; external ntdll;
|
|
function NtCreateDirectoryObject(DirectoryHandle: PHandle;
|
|
DesiredAccess: LongWord; ObjectAttributes: PObjectAttributes): LongInt;
|
|
stdcall; external ntdll;
|
|
function NtOpenDirectoryObject(DirectoryHandle: PHandle;
|
|
DesiredAccess: LongWord; ObjectAttributes: PObjectAttributes): LongInt;
|
|
stdcall; external ntdll;
|
|
function NtClose(Handle: THandle): LongInt; stdcall; external ntdll;
|
|
function NtMakeTemporaryObject(Handle: THandle): LongInt; stdcall;
|
|
external ntdll;
|
|
function NtSetInformationFile(FileHandle: THandle;
|
|
IoStatusBlock: PIoStatusBlock; FileInformation: Pointer;
|
|
FileInformationLength: LongWord; FileInformationClass: LongWord):
|
|
LongInt; stdcall; external ntdll;
|
|
function NtQueryInformationFile(FileHandle: THandle;
|
|
IoStatusBlock: PIoStatusBlock; FileInformation: Pointer;
|
|
FileInformationLength: LongWord; FileInformationClass: LongWord):
|
|
LongInt; stdcall; external ntdll;
|
|
function NtReadFile(FileHandle: THandle; Event: THandle; ApcRoutine: Pointer;
|
|
ApcContext: Pointer; IoStatusBlock: PIOStatusBlock; Buffer: Pointer;
|
|
Length: LongWord; ByteOffset: PLargeInteger; Key: PLongWord): LongInt;
|
|
stdcall; external ntdll;
|
|
function NtWriteFile(FileHandle: THandle; Event: THandle;
|
|
ApcRoutine: Pointer; ApcContext: Pointer; IoStatusBlock: PIOStatusBlock;
|
|
Buffer: Pointer; Length: LongWord; ByteOffset: PLargeInteger; Key: PLongWord):
|
|
LongInt; stdcall; external ntdll;
|
|
function NtWaitForSingleObject(Handle: THandle; Alertable: ByteBool;
|
|
Timeout: PLargeInteger): LongInt; stdcall; external ntdll;
|
|
function NtDisplayString(aString: PNtUnicodeString): LongInt; stdcall; external ntdll;
|
|
|
|
{ TODO : move to platform specific file }
|
|
function NtCurrentTEB: PSimpleTEB; assembler;
|
|
asm
|
|
movl %fs:(0x18),%eax
|
|
end;
|
|
|
|
(* from NDKUtils *)
|
|
procedure SysInitializeObjectAttributes(var aObjectAttr: TObjectAttributes;
|
|
aName: PNtUnicodeString; aAttributes: LongWord; aRootDir: THandle;
|
|
aSecurity: Pointer);
|
|
begin
|
|
with aObjectAttr do begin
|
|
Length := SizeOf(TObjectAttributes);
|
|
RootDirectory := aRootDir;
|
|
Attributes := aAttributes;
|
|
ObjectName := aName;
|
|
SecurityDescriptor := aSecurity;
|
|
SecurityQualityOfService := Nil;
|
|
end;
|
|
end;
|
|
|
|
procedure SysPCharToNtStr(var aNtStr: TNtUnicodeString; aText: PChar;
|
|
aLen: LongWord);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if (aLen = 0) and (aText <> Nil) and (aText^ <> #0) then
|
|
aLen := StrLen(aText);
|
|
aNtStr.Length := aLen * SizeOf(WideChar);
|
|
aNtStr.MaximumLength := aNtStr.Length;
|
|
aNtStr.Buffer := GetMem(aNtStr.Length);
|
|
for i := 0 to aLen do
|
|
aNtStr.Buffer[i] := aText[i];
|
|
end;
|
|
|
|
procedure SysFreeNtStr(var aNtStr: TNtUnicodeString);
|
|
begin
|
|
if aNtStr.Buffer <> Nil then begin
|
|
FreeMem(aNtStr.Buffer);
|
|
aNtStr.Buffer := Nil;
|
|
end;
|
|
aNtStr.Length := 0;
|
|
aNtStr.MaximumLength := 0;
|
|
end;
|