Здравствуйте, zaza1, Вы писали:
Z>воможно но для этого нужно две тачки — не всегда удобно
как рядом советовали — отлаживаться удобно на виртуальной машине, а WinDbg запускать на основной, подключаясь через виртуальный com1 (через pipe).
Z>этот вариант вполне подходит) вообще софтина исключительно для личного пользования поэтому готов даже виндовый драйвер пропатчить, знать бы где) вот только вот какая проблема..
Мне попался уже готовый продукт, который позволяет писать напрямую на диск — но он, по-моему, коммерческий:
http://www.eldos.com/rawdisk/
>я почему и стал изучать этот вопрос — драйвер режима ядра не мог писать на диск.. т.е. партиция открывалась драйвером >(ZwCreateFile) в нулевом кольце и запись туда проводилась с использованием ZwWriteFile. и все это дело сваливалось со >STATUS_ACCESS_DENIED. меня эт до глубины души возмутило — все ж происходит в ядре, какие уж тут ограничения..
>в юзер моде ситуация абсолютно аналогичная. т.е. как я понимаю над драйвером непосредственно пишущим на диск висит >драйвер-фильтр, который рулит ситуацией, какой irp пакет принять и толкнуть дальше вниз по стеку, а какой обломать, >причем это не должен быть драйвер файловой системы, ведь она здесь никоем разом не завязана..
Я посмотрел отладчиком — запросы на запись обламывают в нескольких разных драйверах. Запросы на запись к волюму (если открывать как \\.\C

отклоняются непосредственно в драйверах файловых систем — Ntfs (NtfsCommonWrite) и Fastfat (FatCommonWrite). Запросы к диску (если открыть файл как \\.\PhysicalDrive0) отклоняет драйвер volmgr, к которому обращается для проверки возможности записи в конкретное место диска partmgr.
ZwWriteFile в режиме ядра ломается, так как запрос к волюму проходит через драйвер файловой системы.
>самое простое решение которое мне в голову приходит — просто отрубить этот фильтр. по моим соображениям функционал не >пострадает, а защита эта отвалится.. но вот только кто он?
Проверок несколько и в разных драйверах. Замена fastfat версией от XP может сработать, а вот насчет Ntfs — маловероятно, так как Ntfs изменился со времен XP — поддержка транзакций и т.п.
Один из возможных "универсальных" вариантов — сделать свой драйвер, в котором использовать не ZwWriteFile, а создавать IRP вручную и отправлять его не файловой системе, а непосредственно волюму, например, так:
NTSTATUS TestDirectWrite()
{
NTSTATUS status = 0;
HANDLE hDrive = 0;
OBJECT_ATTRIBUTES attrs = {0};
IO_STATUS_BLOCK iosb = {0};
char wrt_buf[512] = {0};
PFILE_OBJECT pFileObj = 0;
PIRP pIrp = 0;
LARGE_INTEGER liOffset = {0x1000000, 0};
PDEVICE_OBJECT pRelated = 0;
KEVENT event;
UNICODE_STRING usPath = {0};
RtlInitUnicodeString(&usPath, L"\\??\\E:");
KeInitializeEvent( &event, NotificationEvent, FALSE);
InitializeObjectAttributes(&attrs, &usPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, 0, 0);
status = ZwOpenFile(&hDrive, GENERIC_WRITE, &attrs, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
if(NT_SUCCESS(status))
{
status = ObReferenceObjectByHandle(hDrive, FILE_ALL_ACCESS, *IoFileObjectType, KernelMode, &pFileObj, 0);
ZwClose(hDrive);
if(NT_SUCCESS(status))
{
pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, pFileObj->DeviceObject, wrt_buf,
sizeof(wrt_buf), &liOffset, &event, &iosb);
if(!pIrp)
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
status = IoCallDriver( pFileObj->DeviceObject, pIrp );
if(status == STATUS_PENDING)
{
status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = iosb.Status;
}
}
ObDereferenceObject( pFileObj );
}
}
return status;
}