как отмечено @ eryksun мы можем удалить сопоставленный файл, если раздел (сопоставление файлов) был создан без атрибута SEC_IMAGE
двумя способами:
- открыть файл с флагом
FILE_FLAG_DELETE_ON_CLOSE
- Файл
быть удаленным сразу после того, как все его дескрипторы закрыты, что
включает указанный дескриптор и любой другой открытый или дублированный
ручки или мы можем использовать NtOpenFile
или NtCreateFile
звонок с флагом FILE_DELETE_ON_CLOSE
.
- по телефону
ZwDeleteFile
. действительно внутренний NtDeleteFile
открытый
файл с флагом FILE_DELETE_ON_CLOSE
и специальным внутренним
распоряжение DeleteOnly = TRUE
. это сделать вызов больше
Эффективно сравнить нормальный открытый файл и затем закрыть его дескриптор.
в коде это выглядит так.
#ifndef FILE_SHARE_VALID_FLAGS
#define FILE_SHARE_VALID_FLAGS 0x00000007
#endif
NTSTATUS Delete1(PCWSTR FileName)
{
HANDLE hFile = CreateFile(FileName, DELETE, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return RtlGetLastNtStatus();
}
CloseHandle(hFile);
return 0;
}
NTSTATUS Delete2(PCWSTR FileName)
{
UNICODE_STRING ObjectName;
if (RtlDosPathNameToNtPathName_U(FileName, &ObjectName, 0, 0))
{
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
NTSTATUS status = ZwDeleteFile(&oa);
RtlFreeUnicodeString(&ObjectName);
return status;
}
return STATUS_UNSUCCESSFUL;
}
обратите внимание, что вызов DeleteFileW
завершается с ошибкой со статусом - STATUS_CANNOT_DELETE
. я рекомендую позвонить RtlGetLastNtStatus()
здесь вместо GetLastError()
, потому что сопоставление win32 NTSTATUS
с кодом ошибки не является инъективным и часто теряет ценную информацию. скажем STATUS_CANNOT_DELETE
сопоставлено с ERROR_ACCESS_DENIED
. но существуют огромные другие NTSATUS
коды, которые также сопоставлены с ERROR_ACCESS_DENIED
. ERROR_ACCESS_DENIED
не только STATUS_ACCESS_DENIED
(реальный доступ запрещен). получил STATUS_CANNOT_DELETE
гораздо более информативно здесь сравнить ERROR_ACCESS_DENIED
. RtlGetLastNtStatus
имеет точно такую же подпись, что и GetLastError
и экспортируется из ntdll.dll (поэтому включите ntdll.lib или ntdllp.lib )
extern "C" NTSYSCALLAPI NTSTATUS NTAPI RtlGetLastNtStatus();