Mega Code Archive

 
Categories / Delphi / Examples
 

NT Native API

Title: NT Native API Question: 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 rcSTATUS_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 ResultSTATUS_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 Result0 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 (ParamCount2) 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.