CORE_Driver/deepfreeze.c
#define INITGUID
#include <ntifs.h>
#include <ntddk.h>
#include <ntdddisk.h>
#include "stdarg.h"
#include "stdio.h"
#include <ntddvol.h>
#include <ntiologc.h>
#include <mountdev.h>
#include "sector.h"
#include "driver.h"
#include "main.h"
PVOID saved_major[IRP_MJ_MAXIMUM_FUNCTION+1];
WCHAR mdev_name[] = DEEPUNFREEZE_DEVICE;
WCHAR mdev_uniq[] = DEEPUNFREEZE_UNIQUE_ID;
WCHAR mdev_mask[] = L"\\DosDevices\\%c:";
WCHAR mdev_link[64];
INT mounted = 0;
PDEVICE_OBJECT freezed_device;
PDEVICE_OBJECT thawed_device;
typedef NTSTATUS (* DispFunc_t)(IN PDEVICE_OBJECT dobj, IN PIRP Irp);
// Suspend current thread for a number of milliseconds
void KSleep (int milliSeconds)
{
#define malloc(size) ((void *) ExAllocatePoolWithTag( NonPagedPool, size, 'MMRD' ))
#define free(memblock) ExFreePoolWithTag( memblock, 'MMRD' )
PKTIMER timer = (PKTIMER) malloc(sizeof (KTIMER));
LARGE_INTEGER duetime;
if (!timer)
return;
duetime.QuadPart = (__int64) milliSeconds * -10000;
KeInitializeTimerEx(timer, NotificationTimer);
KeSetTimerEx(timer, duetime, 0, NULL);
KeWaitForSingleObject (timer, Executive, KernelMode, FALSE, NULL);
free(timer);
}
NTSTATUS DrvDeviceIOControl(PWSTR deviceName, ULONG IoControlCode,
void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
{
IO_STATUS_BLOCK ioStatusBlock;
NTSTATUS ntStatus;
PIRP irp;
PFILE_OBJECT fileObject;
PDEVICE_OBJECT deviceObject;
KEVENT event;
UNICODE_STRING name;
RtlInitUnicodeString(&name, deviceName);
ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
if (ntStatus != STATUS_SUCCESS)
return ntStatus;
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest (IoControlCode,
deviceObject,
InputBuffer, InputBufferSize,
OutputBuffer, OutputBufferSize,
FALSE,
&event,
&ioStatusBlock);
if (irp == NULL) {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ret;
}
ntStatus = IoCallDriver (deviceObject, irp);
if (ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
ntStatus = ioStatusBlock.Status;
}
ret:
ObDereferenceObject (fileObject);
DTRACE("DrvDeviceIOControl returned %X", ntStatus);
return ntStatus;
}
NTSTATUS MountManagerMount (WCHAR *NTName, WCHAR *DOSName)
{
NTSTATUS ntStatus;
WCHAR arrVolume[256];
char buf[400];
PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
UNICODE_STRING symName, devName;
ULONG i;
int count = 0;
wcscpy(arrVolume, NTName);
in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
wcscpy(in->DeviceName, arrVolume);
ntStatus = DrvDeviceIOControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);
DTRACE("IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION returned %X", ntStatus);
#if 0
memset (buf, 0, sizeof buf);
DTRACE("DOSName: [%x] [%S] ", wcslen(DOSName), DOSName);
wcscpy((PWSTR) &point[1], DOSName);
point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));
point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
DTRACE("NTName: [%x] [%S] ", wcslen(NTName), NTName);
wcscpy ((PWSTR) (buf + point->DeviceNameOffset), NTName);
point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;
RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));
DTRACE("CREATE_MOUNT_POINT: [%x] [%S][%x]", point->SymbolicLinkNameLength, &point[1], wcslen(&point[1]));
DTRACE("CREATE_MOUNT_POINT: [%x] [%S][%x]", point->DeviceNameLength, (buf + point->DeviceNameOffset), wcslen(buf + point->DeviceNameOffset));
DumpMemory((PVOID)buf, 64);
ntStatus = DrvDeviceIOControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
point->DeviceNameOffset + point->DeviceNameLength, 0, 0);
DTRACE("IOCTL_MOUNTMGR_CREATE_POINT returned %X", ntStatus);
#endif
return ntStatus;
}
NTSTATUS MountManagerUnMount (WCHAR *DosName)
{
NTSTATUS ntStatus;
char buf[256], out[300];
PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;
memset (buf, 0, sizeof buf);
wcscpy((PWSTR) &in[1], DosName);
in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;
ntStatus = DrvDeviceIOControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);
DTRACE("MountManagerUnMount returned %X", ntStatus);
return ntStatus;
}
NTSTATUS DrvFsctl (PFILE_OBJECT fileObject, LONG IoControlCode,
void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
{
IO_STATUS_BLOCK ioStatusBlock;
NTSTATUS ntStatus;
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION stack;
PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest (IoControlCode,
deviceObject,
InputBuffer, InputBufferSize,
OutputBuffer, OutputBufferSize,
FALSE,
&event,
&ioStatusBlock);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
stack = IoGetNextIrpStackLocation(irp);
stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
stack->FileObject = fileObject;
ntStatus = IoCallDriver (deviceObject, irp);
if (ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
ntStatus = ioStatusBlock.Status;
}
return ntStatus;
}
// Opens a mounted volume on filesystem level
NTSTATUS DrvOpenFsVolume (WCHAR *volumeName, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
{
NTSTATUS ntStatus;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING fullFileName;
IO_STATUS_BLOCK ioStatus;
RtlInitUnicodeString (&fullFileName, volumeName);
InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
ntStatus = ZwCreateFile (volumeHandle,
SYNCHRONIZE | GENERIC_READ,
&objectAttributes,
&ioStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
ntStatus = ObReferenceObjectByHandle (*volumeHandle, FILE_READ_DATA, NULL, KernelMode, fileObject, NULL);
if (!NT_SUCCESS (ntStatus)) {
ZwClose(*volumeHandle);
return ntStatus;
}
return ntStatus;
}
NTSTATUS HookFunc(IN PDEVICE_OBJECT dobj, IN PIRP Irp)
{
PVOID Buf;
ULONG BufLen; //Buffer length for user provided buffer
PIO_STACK_LOCATION currIrp;
DispFunc_t pDispFunc;
currIrp = IoGetCurrentIrpStackLocation(Irp);
if (Irp->Flags & 0x80000000) {
Irp->Flags &= (~0x80000000);
IoSkipCurrentIrpStackLocation(Irp);
// manda l'IRP al device sotto a deepfreeze (che e' il disco fisico)
return IoCallDriver(IoGetLowerDeviceObject(dobj), Irp);
}
if (currIrp->MajorFunction > IRP_MJ_MAXIMUM_FUNCTION) {
DTRACE("OOOPPSS MajorFunction greater than IRP_MJ_MAXIMUM_FUNCTION !!!");
return STATUS_UNSUCCESSFUL;
}
pDispFunc = (DispFunc_t) saved_major[currIrp->MajorFunction];
return pDispFunc(dobj, Irp);
}
NTSTATUS FindAvailDriveLetter(WCHAR *letter)
{
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING objectName;
WCHAR link[128];
HANDLE handle;
for (*letter = L'Z'; *letter > L'A'; (*letter)--) {
DTRACE("Trying drive %c", *letter);
swprintf(link, mdev_mask, *letter);
RtlInitUnicodeString (&objectName, link);
InitializeObjectAttributes (&objectAttributes, &objectName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
if (NT_SUCCESS (ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes))) {
ZwClose (handle);
continue;
}
DTRACE("Letter found: %c", *letter);
return STATUS_SUCCESS;
}
// special value if not found
*letter = L'!';
return STATUS_UNSUCCESSFUL;
}
NTSTATUS CreateMountPoint(IN PDRIVER_OBJECT dobj, WCHAR freezedletter, WCHAR *thawedletter)
{
NTSTATUS ntStatus;
PDRIVER_OBJECT pDiskObject;
PDEVICE_OBJECT pDevice;
UNICODE_STRING deviceName, symLink;
UNICODE_STRING driver_name;
HANDLE hFile;
OBJECT_ATTRIBUTES objAttr;
IO_STATUS_BLOCK ioStatus;
PDEVICE_OBJECT pDevicePtr;
PFILE_OBJECT pFileObj;
WCHAR freezed_link[64];
WCHAR thawedletter_tmp;
int i;
// special case when failed
*thawedletter = L'!';
if (mounted)
return STATUS_UNSUCCESSFUL;
/************************************************************************/
/* CERCA UNA LETTERA DISPONIBILE per thawedletter */
/************************************************************************/
if (FindAvailDriveLetter(&thawedletter_tmp) != STATUS_SUCCESS)
return STATUS_UNSUCCESSFUL;
swprintf(mdev_link, mdev_mask, thawedletter_tmp);
RtlInitUnicodeString (&symLink, mdev_link);
/************************************************************************/
/* CERCA IL VOLUME DATA LA LETTERA freezedletter */
/************************************************************************/
swprintf(freezed_link, mdev_mask, freezedletter);
RtlInitUnicodeString(&driver_name, freezed_link);
InitializeObjectAttributes (&objAttr, &driver_name, OBJ_CASE_INSENSITIVE, NULL, NULL);
freezed_device = NULL;
ntStatus = ZwCreateFile(&hFile, SYNCHRONIZE | FILE_ANY_ACCESS, &objAttr, &ioStatus, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, NULL, 0);
if (NT_SUCCESS(ntStatus)) {
ntStatus = ObReferenceObjectByHandle(hFile, FILE_READ_DATA, NULL, KernelMode, &pFileObj, NULL);
if (NT_SUCCESS(ntStatus)) {
pDevicePtr = IoGetRelatedDeviceObject(pFileObj);
while (pDevicePtr) {
pDevicePtr = IoGetLowerDeviceObject(pDevicePtr);
if (pDevicePtr != NULL)
freezed_device = pDevicePtr;
}
ObDereferenceObject(pFileObj);
}
ZwClose(hFile);
}
if (!freezed_device || freezed_device->DeviceType != FILE_DEVICE_DISK)
return STATUS_UNSUCCESSFUL;
DTRACE("freezed_device %x\n", freezed_device);
/************************************************************************/
/* HOOK SUL DRIVER DI DEEPFREEZ */
/************************************************************************/
RtlInitUnicodeString(&driver_name, L"\\Driver\\DeepFrz");
if (ObReferenceObjectByName(&driver_name, 64, 0, 0, *IoDriverObjectType, KernelMode, 0, &pDiskObject) < 0) {
return STATUS_UNSUCCESSFUL;
}
for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++) {
saved_major[i] = pDiskObject->MajorFunction[i];
if (pDiskObject->MajorFunction[i]) {
//DTRACE("HOOKING MJ_%.2X %.8X with %.8X", i, pDiskObject->MajorFunction[i], HookFunc);
pDiskObject->MajorFunction[i] = HookFunc;
}
}
ObDereferenceObject(pDiskObject);
pDiskObject = NULL;
/************************************************************************/
/* CREA IL NOSTRO DEVICE */
/************************************************************************/
RtlInitUnicodeString(&deviceName, mdev_name);
ntStatus = IoCreateDevice(dobj, 0, &deviceName, freezed_device->DeviceType, freezed_device->Characteristics, FALSE, &thawed_device );
if (!NT_SUCCESS(ntStatus))
return ntStatus;
thawed_device->Flags &= ~DO_DEVICE_INITIALIZING;
thawed_device->Flags |= (freezed_device->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO));
thawed_device->StackSize += 4; // Reduce occurrence of NO_MORE_IRP_STACK_LOCATIONS bug check caused by buggy drivers
DTRACE("thawed_device %x\n", thawed_device);
ntStatus = MountManagerMount(mdev_name, mdev_link);
if (NT_SUCCESS(ntStatus)) {
mounted = 1;
*thawedletter = thawedletter_tmp;
}
ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
DTRACE("IoCreateSymbolicLink returned %X\n", ntStatus);
return ntStatus;
}
NTSTATUS do_ioctl_thaw(IN PDEVICE_OBJECT dobj, IN PIRP Irp, IN PIO_STACK_LOCATION irpSp)
{
NTSTATUS ntstatus;
// INPUT: lettera del drive freezed
// OUTPUT: lettere del drive thawed, trovata partendo dal basso (Z:)
if (irpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(WCHAR) ) {
WCHAR freezedletter = *((WCHAR *)Irp->AssociatedIrp.SystemBuffer);
WCHAR thawedletter = L'!';
ntstatus = CreateMountPoint(dobj->DriverObject, freezedletter, &thawedletter);
if (ntstatus == STATUS_SUCCESS) {
memcpy(Irp->AssociatedIrp.SystemBuffer, &thawedletter, sizeof(WCHAR));
Irp->IoStatus.Information = sizeof(WCHAR);
}
}
return ntstatus;
}
NTSTATUS do_ioctl_freeze(IN PDEVICE_OBJECT dobj, IN PIRP Irp, IN PIO_STACK_LOCATION irpSp)
{
int i;
PDRIVER_OBJECT pDiskObject;
UNICODE_STRING fname_u;
NTSTATUS ntStatus;
HANDLE volumeHandle;
PFILE_OBJECT volumeFileObject;
UNICODE_STRING symLink;
if (!mounted)
return STATUS_UNSUCCESSFUL;
/************************************************************************/
/* UNHOOK DI DEEPFREEZE */
/************************************************************************/
RtlInitUnicodeString(&fname_u, L"\\Driver\\DeepFrz");
if (ObReferenceObjectByName(&fname_u, 64, 0, 0, *IoDriverObjectType, KernelMode, 0, &pDiskObject) < 0) {
return STATUS_UNSUCCESSFUL;
}
for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++) {
//DTRACE("DEHOOKING MJ_%.2X %.8X with %.8X", i, pDiskObject->MajorFunction[i], saved_major[i]);
pDiskObject->MajorFunction[i] = saved_major[i];
}
ObDereferenceObject( pDiskObject );
DTRACE("UnHook effettuato\n");
/************************************************************************/
/* UNMOUNT DI NTFS E DISTRUZIONE DEVICE */
/************************************************************************/
ntStatus = DrvOpenFsVolume(mdev_link, &volumeHandle, &volumeFileObject);
DTRACE("DrvOpenFsVolume returned %X", ntStatus);
if (NT_SUCCESS (ntStatus)) {
// Lock volume
ntStatus = DrvFsctl (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
DTRACE("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);
KSleep(100);
// Dismount volume
for (i = 0; i < 50; ++i) {
ntStatus = DrvFsctl(volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
DTRACE("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);
if (NT_SUCCESS (ntStatus) || ntStatus == STATUS_VOLUME_DISMOUNTED)
break;
KSleep(100);
}
// UnLock volume
ntStatus = DrvFsctl (volumeFileObject, FSCTL_UNLOCK_VOLUME, 0, 0, 0, 0);
DTRACE("FSCTL_UNLOCK_VOLUME returned %X\n", ntStatus);
}
MountManagerUnMount(mdev_link);
RtlInitUnicodeString (&symLink, mdev_link);
ntStatus = IoDeleteSymbolicLink (&symLink);
DTRACE("IoDeleteSymbolicLink returned %X\n", ntStatus);
ObDereferenceObject (volumeFileObject);
ZwClose (volumeHandle);
IoDeleteDevice(thawed_device);
DTRACE("Dismount volume effettuato\n");
mounted = 0;
return STATUS_SUCCESS;
}
NTSTATUS DispatchDeepFreeze(IN PDEVICE_OBJECT dobj, IN PIRP Irp)
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
irpSp = IoGetCurrentIrpStackLocation (Irp);
status = STATUS_INVALID_DEVICE_REQUEST;
switch (irpSp->MajorFunction) {
case IRP_MJ_DEVICE_CONTROL:
{
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_MOUNTDEV_LINK_CREATED:
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
break;
case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
{
ULONG outLength;
UNICODE_STRING ntUnicodeString;
PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer;
RtlInitUnicodeString (&ntUnicodeString, mdev_name);
outputBuffer->NameLength = ntUnicodeString.Length;
outLength = ntUnicodeString.Length + sizeof(USHORT);
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) {
Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME);
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = outLength;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
break;
case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
{
ULONG outLength;
UNICODE_STRING ntUnicodeString;
PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer;
RtlInitUnicodeString (&ntUnicodeString, mdev_uniq);
outputBuffer->NameLength = ntUnicodeString.Length;
outLength = ntUnicodeString.Length + sizeof(USHORT);
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) {
Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = outLength;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
break;
case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
{
ULONG outLength;
UNICODE_STRING ntUnicodeString;
PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer;
RtlInitUnicodeString (&ntUnicodeString, mdev_link);
outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE;
outputBuffer->NameLength = ntUnicodeString.Length;
if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
{
Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME);
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = outLength;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
break;
case IOCTL_DISK_IS_WRITABLE:
case IOCTL_DISK_GET_PARTITION_INFO_EX:
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
case IOCTL_DISK_GET_LENGTH_INFO:
case IOCTL_DISK_CHECK_VERIFY: // this is needed for FAT filesystems
{
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(freezed_device, Irp);
return status;
}
break;
default:
{
DTRACE("UNSUPPORTED_IOCTL: %.8X", irpSp->Parameters.DeviceIoControl.IoControlCode);
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
}
}
break;
case IRP_MJ_WRITE:
case IRP_MJ_READ:
case IRP_MJ_FLUSH_BUFFERS:
{
IoSkipCurrentIrpStackLocation(Irp);
// mark our irp with special flag used in the HookFunc
Irp->Flags |= 0x80000000;
status = IoCallDriver(freezed_device, Irp);
return status;
}
break;
case IRP_MJ_CREATE:
case IRP_MJ_CLEANUP:
case IRP_MJ_CLOSE:
case IRP_MJ_SHUTDOWN:
case IRP_MJ_PNP:
{
status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
break;
default:
{
DTRACE("UNSUPPORTED_MJ: %.8X", irpSp->MajorFunction);
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
break;
}
}
NTSTATUS DriverEntryDeepFreeze( IN PDRIVER_OBJECT dobj, IN PUNICODE_STRING regpath)
{
DTRACE("DriverEntryDeepFreeze");
return STATUS_SUCCESS;
}
void OnUnloadDeepFreeze(IN PDRIVER_OBJECT dobj)
{
DTRACE("OnUnloadDeepFreeze");
do_ioctl_freeze(NULL, NULL, NULL);
}