We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Aug 4, 2011 7:27:49 PM
The native API NtDeleteFile performs the same task as the user-mode API DeleteFile, but interestingly enough, the user-mode API does not call the native API to perform it’s task. As explained here, normally files are deleted through calls to NtSetInformationFile. The main difference in behavior comes from the fact that NtDeleteFile does not wait for handles on the file to close before deleting it (note that if the file is “open for normal I/O or as a memory-mapped file”, it still can’t be deleted, so only read-only handles will be ignored).
Source:
http://vtopan.wordpress.com/2009/05/26/using-ntdeletefile-from-delphi/
The required structures (not defined in Delphi) are:
UNICODE_STRING
PUNICODE_STRING = ^UNICODE_STRING;
UNICODE_STRING = packed record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
OBJECT_ATTRIBUTES.
POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;
OBJECT_ATTRIBUTES = packed record
Length: Cardinal;
RootDirectory: THandle;
ObjectName: PUNICODE_STRING;
Attributes: Cardinal;
SecurityDescriptor: Pointer;
SecurityQualityOfService: Pointer;
end;
The steps to remove the file are:
Using the afore-linked-to type definitions, we still need to import the native APIs:
function NtDeleteFile(ObjectAttributes:POBJECT_ATTRIBUTES):DWORD; stdcall; external 'ntdll.dll';
function RtlDosPathNameToNtPathName_U(DosName:PWChar; var NtName:UNICODE_STRING; DosFilePath:PPChar; NtFilePath:PUNICODE_STRING):BOOL; stdcall; external 'ntdll.dll';
Do note that this statically links the imported functions, making the whole application unable to load if the undocumented APIs are not present on the system (at least for Windows 2000 and XP they should be).
Converting the DOS path name to a native path is done by the RtlDosPathNameToNtPathName_U API, which takes in a PWChar argument containing the DOS path and a pre-allocated UNICODE_STRING structure of MAX_PATH WideChars and returns True if it has successfully converted the path.
program NativeDelete;
//cswi - www.delphibasics.info
//Vlad Ioan Topan - http://vtopan.wordpress.com
uses
Windows;
type
PUnicodeString = ^TUnicodeString;
TUnicodeString = packed record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
PObjectAttributes = ^TObjectAttributes;
TObjectAttributes = packed record
Length: Cardinal;
RootDirectory: THandle;
ObjectName: PUnicodeString;
Attributes: Cardinal;
SecurityDescriptor: Pointer;
SecurityQualityOfService: Pointer;
end;
procedure RtlInitUnicodeString(DestinationString: PUnicodeString; SourceString: LPWSTR); stdcall; external 'ntdll.dll';
function NtDeleteFile(ObjectAttributes: PObjectAttributes): DWORD; stdcall; external 'ntdll.dll';
function RtlDosPathNameToNtPathName_U(DosName: PWChar; var NtName: TUnicodeString; DosFilePath: PPChar; NtFilePath: PUnicodeString):BOOL; stdcall; external 'ntdll.dll';
procedure InitializeObjectAttributes(var InitializedAttributes: TObjectAttributes;
ObjectName: PUnicodeString;
Attributes: ULONG;
RootDirectory: THandle;
SecurityDescriptor: Pointer;
SecurityQualityOfService : Pointer);
begin
InitializedAttributes.Length := SizeOf(TObjectAttributes);
InitializedAttributes.RootDirectory := RootDirectory;
InitializedAttributes.Attributes := Attributes;
InitializedAttributes.ObjectName := ObjectName;
InitializedAttributes.SecurityDescriptor := SecurityDescriptor;
InitializedAttributes.SecurityQualityOfService := SecurityQualityOfService;
end;
function _DeleteFile(wsFileName: WideString):DWORD;
var
ObjectAttributes: TObjectAttributes;
UnicodeString: TUnicodeString;
begin
Result := $C0000001; // STATUS_UNSUCCESSFUL, "generic" error
RtlInitUnicodeString(@UnicodeString, @wsFileName);
RtlDosPathNameToNtPathName_U(@wsFileName[1], UnicodeString, nil, nil);
InitializeObjectAttributes(ObjectAttributes, @UnicodeString, $40, 0, nil, nil);
Result := NtDeleteFile(@ObjectAttributes); // pass on the NTSTATUS
end;
const
wsFileName : PWideChar = 'C:\GoogleLogo.png';
begin
_DeleteFile(wsFileName);
end.