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.comuses 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 NTSTATUSend;const wsFileName : PWideChar = 'C:\GoogleLogo.png';begin _DeleteFile(wsFileName);end.