NT Native API (Views: 719)
Problem/Question/Abstract: NT Native API is basic API in Windows NT/2000. All other API (Win32 is included) are use this API. But functions from ntdll.dll are poorely documented. Answer: You can download full source code (ntdll.pas is included): http://homepages.mtgroup.ru/alexk/files/NativeApp.zip Unit ntdll.pas contains only definitions for some functions and structures from NT Native API. program NativeApp; // PURPOSE: Simple Windows NT/2000 console application that calls // Native API functions {$APPTYPE CONSOLE} uses Windows, SysUtils, ntdll; type TEnumNtObjectCallBack = function( pusObjectName: PNtUnicodeString; ObjectTypeName: string; DirectoryHandle: THandle; UserData: Pointer ): Boolean; // False => stop //------------------------------------------------------------- function NtUnicodeStringToString(pusString: PNtUnicodeString): string; var asString: TNtAnsiString; begin Result := ''; if (pusString = nil) or (pusString^.Length = 0) then Exit; // convert with allocating RtlUnicodeStringToAnsiString(@asString, pusString, True); try SetString(Result, asString.Buffer, asString.Length); finally RtlFreeAnsiString(@asString); // free allocated memory end; end; //------------------------------------------------------------- // Open any named NT object. // If DirectoryHandle=0 then ObjectName must be full qualified name // (start with backslash symbol), // otherwise ObjectName specify relative path from this directory // You must call CloseHandle to free obtained handle. function OpenObject(ObjectName: PNtUnicodeString; DirectoryHandle: THandle; DesireAccess: ACCESS_MASK): THandle; var ObjectAttributes: TNtObjectAttributes; IoStatus: TIoStatusBlock; doserr: DWORD; rc: NTSTATUS; begin InitializeObjectAttributes(@ObjectAttributes, ObjectName, OBJ_CASE_INSENSITIVE, DirectoryHandle, nil); rc := NtOpenFile(Result, DesireAccess, ObjectAttributes, IoStatus, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, 0); if rc <> STATUS_SUCCESS then begin doserr := RtlNtStatusToDosError(rc); SetLastError(doserr); Result := INVALID_HANDLE_VALUE; end; end; //------------------------------------------------------------- // Open directory and call Treate function for all objects // in this directory. function EnumNtObjects(Path: string; Treate: TEnumNtObjectCallBack; UserData: Pointer): NTSTATUS; const BufferSize = 2048; var hDir: THandle; doserr: DWORD; DirObject: TNtObjectAttributes; asDirName: TNtAnsiString; usDirName: TNtUnicodeString; cbBytesReturned: DWORD; dwIndex: DWORD; Buffer: array[0..BufferSize - 1] of Byte; DirInfo: TDirectoryInformationTYpe1 absolute Buffer; FileNameInfo: TFileNameInformation absolute Buffer; begin if not Assigned(Treate) or (Path = '') then begin Result := STATUS_INVALID_PARAMETER; Exit; end; RtlInitAnsiString(@asDirName, PChar(Path)); RtlAnsiStringToUnicodeString(@usDirName, @asDirName, True); try InitializeObjectAttributes(@DirObject, @usDirName, OBJ_CASE_INSENSITIVE, 0, nil); hDir := 0; Result := NtOpenDirectoryObject(hDir, DIRECTORY_TRAVERSE or DIRECTORY_QUERY, DirObject); if Result <> STATUS_SUCCESS then begin doserr := RtlNtStatusToDosError(Result); SetLastError(doserr); end else try dwIndex := 0; repeat Result := NtQueryDirectoryObject(hDir, @Buffer, BufferSize, TDirectoryInformationClass(1), // ??? False, dwIndex, cbBytesReturned); if Result <> 0 then begin if Result = STATUS_NO_MORE_DATA then begin Result := STATUS_SUCCESS; Break; end; doserr := RtlNtStatusToDosError(Result); SetLastError(doserr); Break; end; until not Treate(@DirInfo.ObjectName, NtUnicodeStringToString(@DirInfo.ObjectTypeName), hDir, UserData); finally CloseHandle(hDir); end; finally RtlFreeUnicodeString(@usDirName); end; end; //============================================================= // Sample for EnumNtObjects callback function type TUserData = record DesireObjectType: PChar; DesireAccess: ACCESS_MASK; end; PUserData = ^TUserData; function EnumNtObjectsCallBack(pusObjectName: PNtUnicodeString; ObjectTypeName: string; DirectoryHandle: THandle; UserData: Pointer): Boolean; var sObjectName: string; hObject: THandle; begin Result := True; sObjectName := NtUnicodeStringToString(pusObjectName); with PUserData(UserData)^ do if (DesireObjectType <> '*') and (CompareText(ObjectTypeName, DesireObjectType) <> 0) then Exit; if (CompareText(ObjectTypeName, 'Directory') = 0) //NtOpenDirectoryObject or (CompareText(ObjectTypeName, 'Type') = 0) or (CompareText(ObjectTypeName, 'Port') = 0) or (CompareText(ObjectTypeName, 'Key') = 0) // NtOpenKey or (CompareText(ObjectTypeName, 'Event') = 0) // OpenEvent or (CompareText(ObjectTypeName, 'Semaphore') = 0) // OpenSemaphore or (CompareText(ObjectTypeName, 'Mutant') = 0) // OpenMutex or (CompareText(ObjectTypeName, 'Timer') = 0) // NtOpenTimer or (CompareText(ObjectTypeName, 'Section') = 0) // NtOpenSection or (CompareText(ObjectTypeName, 'SymbolicLink') = 0) {// NtOpenSymbolicLinkObject } then begin WriteLn(ObjectTypeName, ' ', sObjectName); Exit; end; hObject := OpenObject(pusObjectName, DirectoryHandle, PUserData(UserData)^.DesireAccess); if hObject = INVALID_HANDLE_VALUE then begin Write(' NtOpenObject failed for ', sObjectName, ': '); WriteLn(SysErrorMessage(GetLastError)); Exit; end; try WriteLn(ObjectTypeName, ' ', sObjectName, ' is opened successfully'); // do something with object here finally CloseHandle(hObject); end; end; //============================================================= // Application var sObjectType, sPath: string; rUserData: TUserData; begin if (ParamCount = 0) or (ParamCount > 2) then begin WriteLn('(c) 20 jul 2000 Alex Konshin mailto:alexk@mtgroup.ru'); WriteLn; WriteLn('Sample console application that use NT Native API.'); WriteLn; WriteLn('Using:'); WriteLn; WriteLn(' NativeApp ObjectType [Path]'); WriteLn; WriteLn('Where:'); WriteLn; WriteLn(' ObjectType = *(all objects), Directory, Type, Device, Mutant,'); WriteLn(' Section, Semaphore,...'); WriteLn(' (use NativeApp Type \ObjectTypes to list NT object types)'); WriteLn; WriteLn(' Path = NT objects directory name.'); WriteLn; WriteLn('Examples:'); WriteLn; WriteLn(' NativeApp Device \Device'); WriteLn(' NativeApp Mutant \BaseNamedObjects'); WriteLn; Exit; end; sObjectType := ParamStr(1); sPath := ParamStr(2); if sPath = '' then sPath := '\'; with rUserData do begin DesireObjectType := PChar(sObjectType); DesireAccess := FILE_READ_DATA; // GENERIC_READ or GENERIC_WRITE; end; EnumNtObjects(sPath, EnumNtObjectsCallBack, @rUserData); end. Links for more informations: http://www.sysinternals.com/ntdll.htm http://www.sysinternals.com/winobj.htm Books: http://www.amazon.com/exec/obidos/ASIN/1578701996/systemsinternals See also Zw*, Rtl* functions descriptions in Win2000 DDK. |