VOID MtrrDumpFixed ( IN ULONG Base, IN ULONG Size, IN ULONG Msr ) { ULONG x; ULONGLONG li; ReadMsr(Msr, &li); for (x=0; x < 8; x++) { dprintf ("%s:%05x-%05x ", MtrrType ( ((ULONG) li) & 0xff ), Base, Base + Size - 1 ); li >>= 8; Base += Size; if (x == 3) { dprintf ("\n"); } } dprintf ("\n"); }
PyObject * wipe_ReadMsr(PyObject * self, PyObject * args) { ULONG ulMsr; ULONGLONG tValue; if (!PyArg_ParseTuple(args, "k", &ulMsr)) { return NULL; } ReadMsr(ulMsr, &tValue); return Py_BuildValue("K", tValue); }
/*++ IRP_MJ_DEVICE_CONTROL dispatch routine --*/ NTSTATUS DispatchIoCtl(IN PDEVICE_OBJECT fdo, IN PIRP irp) { PDEVICE_EXTENSION device_extension; PIO_STACK_LOCATION irpStack; NTSTATUS ntStatus; //Init to default settings irp->IoStatus.Status=STATUS_SUCCESS; irp->IoStatus.Information=0; irpStack=IoGetCurrentIrpStackLocation(irp); switch (irpStack->MajorFunction) { case IRP_MJ_DEVICE_CONTROL: switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_PUSH_READ_MSR: { irp->IoStatus.Status = ReadMsr( irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, (ULONG*)&irp->IoStatus.Information ); ntStatus=irp->IoStatus.Status; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break; case IOCTL_PUSH_READ_PCI_CONFIG: { /*irp->IoStatus.Status = ReadPciConfig( irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, (ULONG*)&irp->IoStatus.Information );*/ irp->IoStatus.Status = SlReadPciConfig( irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, (ULONG*)&irp->IoStatus.Information ); ntStatus=irp->IoStatus.Status; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break; /*case IOCTL_PUSH_READ_GPU_REGISTER: { irp->IoStatus.Status = ReadGpuRegister( irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, (ULONG*)&irp->IoStatus.Information ); ntStatus=irp->IoStatus.Status; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break;*/ case IOCTL_PUSH_SET_CACHE_NAME: { irp->IoStatus.Status = SetCacheName( irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, (ULONG*)&irp->IoStatus.Information ); ntStatus=irp->IoStatus.Status; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break; case IOCTL_PUSH_TOGGLE_MONITORING: { ntStatus = ToggleProcessMonitoring(irp); irp->IoStatus.Status = ntStatus; irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break; case IOCTL_PUSH_GET_PROC_INFO: { if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PROCESS_CALLBACK_INFO)) { PPROCESS_CALLBACK_INFO pProcCallbackInfo; PDEVICE_EXTENSION extension = g_DeviceObject->DeviceExtension; pProcCallbackInfo = irp->AssociatedIrp.SystemBuffer; pProcCallbackInfo->hProcessID = extension->ProcessEvent.ProcessID; ntStatus = STATUS_SUCCESS; } irp->IoStatus.Status = ntStatus; irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break; case IOCTL_PUSH_GET_IMAGE_INFO: { IMAGE_CALLBACK_INFO *imageInfo; PDEVICE_EXTENSION extension = g_DeviceObject->DeviceExtension; imageInfo = irp->AssociatedIrp.SystemBuffer; imageInfo->processID = extension->imageEvent.processID; /*wcscpy(imageInfo->imageName, extension->imageEvent.imageName);*/ ntStatus = STATUS_SUCCESS; irp->IoStatus.Status = ntStatus; irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break; case IOCTL_PUSH_GET_THREAD_INFO: { THREAD_CALLBACK_INFO *threadInfo; DEVICE_EXTENSION *extension; extension = (DEVICE_EXTENSION*) g_DeviceObject->DeviceExtension; threadInfo = (THREAD_CALLBACK_INFO*) irp->AssociatedIrp.SystemBuffer; //threadInfo->threadOwner = extension->ThreadEvent.threadOwner; threadInfo->threadOwner = extension->threadCallbackInfo.threadOwner; threadInfo->threadID = extension->threadCallbackInfo.threadID; threadInfo->create = extension->threadCallbackInfo.create; ntStatus = STATUS_SUCCESS; irp->IoStatus.Status = ntStatus; irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } break; case IOCTL_PUSH_MAP_PHYSICAL_MEMORY: { irp->IoStatus.Status = MapPhysicalMemory( irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.InputBufferLength, irpStack->Parameters.DeviceIoControl.OutputBufferLength, (ULONG*)&irp->IoStatus.Information ); IoCompleteRequest(irp, IO_NO_INCREMENT); return irp->IoStatus.Status; } break; case IOCTL_PUSH_QUEUE_FILE: { DbgPrint("[PUSH] File request: %ws", irp->AssociatedIrp.SystemBuffer); FltQueueFile(irp->AssociatedIrp.SystemBuffer); irp->IoStatus.Status = STATUS_SUCCESS; /*if (!FltInitialized) FltFilterInstall(PushDriverObject);*/ IoCompleteRequest(irp, IO_NO_INCREMENT); return irp->IoStatus.Status; } break; } break; } ASSERT(fdo != NULL); ASSERT(irp != NULL); device_extension = (PDEVICE_EXTENSION) fdo->DeviceExtension; if (KeReadStateEvent(&device_extension->terminate_thread) != 0) { DbgPrint("ImDisk: IOCTL attempt on device that is being removed.\n"); //device_extension->device_number)); ntStatus = STATUS_NO_MEDIA_IN_DEVICE; irp->IoStatus.Status = ntStatus; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } // The control device can only receive version queries, enumeration queries // or device create requests. if (fdo == g_DeviceObject) switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_PUSH_QUERY_VERSION: case IOCTL_PUSH_CREATE_RAMDISK: case IOCTL_PUSH_QUERY_DRIVER: break; default: KdPrint(("ImDisk: Invalid IOCTL %#x for control device.\n", irpStack->Parameters.DeviceIoControl.IoControlCode)); ntStatus = STATUS_INVALID_DEVICE_REQUEST; irp->IoStatus.Status = ntStatus; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } else switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { // Invalid IOCTL codes for this driver's disk devices. case IOCTL_PUSH_CREATE_RAMDISK: KdPrint(("ImDisk: Invalid IOCTL %#x for disk device.\n", irpStack->Parameters.DeviceIoControl.IoControlCode)); ntStatus = STATUS_INVALID_DEVICE_REQUEST; irp->IoStatus.Status = ntStatus; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_PUSH_CREATE_RAMDISK: { RAMDISK_CREATE_DATA* create_data; KdPrint(("ImDisk: IOCTL_IMDISK_CREATE_DEVICE for device.\n")); //device_extension->device_number)); // This IOCTL requires work that must be done at IRQL < DISPATCH_LEVEL // but the control device has no worker thread (does not handle any // other I/O) so therefore everything is done directly here. Therefore // this IRQL check is necessary. if (KeGetCurrentIrql() >= DISPATCH_LEVEL) { ntStatus = STATUS_ACCESS_DENIED; irp->IoStatus.Information = 0; break; } if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(RAMDISK_CREATE_DATA) /*- sizeof(*create_data->FileName)*/) { KdPrint(("ImDisk: Invalid input buffer size (1). " "Got: %u Expected at least: %u.\n", irpStack->Parameters.DeviceIoControl.InputBufferLength, sizeof(RAMDISK_CREATE_DATA))); ntStatus = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } create_data = (RAMDISK_CREATE_DATA*) irp->AssociatedIrp.SystemBuffer; if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(RAMDISK_CREATE_DATA) /*+ create_data->FileNameLength - sizeof(*create_data->FileName)*/) { KdPrint(("ImDisk: Invalid input buffer size (2). " "Got: %u Expected at least: %u.\n", irpStack->Parameters.DeviceIoControl.InputBufferLength, sizeof(RAMDISK_CREATE_DATA))); ntStatus = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } ntStatus = ImDiskAddVirtualDisk(fdo->DriverObject, (RAMDISK_CREATE_DATA*) irp->AssociatedIrp.SystemBuffer, irp->Tail.Overlay.Thread); if (NT_SUCCESS(ntStatus) && (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= irpStack->Parameters.DeviceIoControl.InputBufferLength)) irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength; else irp->IoStatus.Information = 0; break; } case IOCTL_DISK_EJECT_MEDIA: case IOCTL_STORAGE_EJECT_MEDIA: KdPrint(("ImDisk: IOCTL_DISK/STORAGE_EJECT_MEDIA for device.\n")); //device_extension->device_number)); if (device_extension->special_file_count > 0) { irp->IoStatus.Information = 0; ntStatus = STATUS_ACCESS_DENIED; } else { ImDiskRemoveVirtualDisk(fdo); irp->IoStatus.Information = 0; ntStatus = STATUS_SUCCESS; } break; case IOCTL_PUSH_QUERY_RAMDISK: { RAMDISK_CREATE_DATA *create_data; KdPrint(("[PUSH] IOCTL_IMDISK_QUERY_DEVICE for device.\n")); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(RAMDISK_CREATE_DATA) /*+ device_extension->file_name.Length + sizeof(*create_data->FileName)*/) { ntStatus = STATUS_BUFFER_TOO_SMALL; irp->IoStatus.Information = 0; break; } create_data = (RAMDISK_CREATE_DATA*) irp->AssociatedIrp.SystemBuffer; //create_data->DeviceNumber = device_extension->device_number; create_data->DiskGeometry = device_extension->disk_geometry; //create_data->Flags = 0; /*if (device_extension->read_only) create_data->Flags |= IMDISK_OPTION_RO;*/ /*if (fdo->Characteristics & FILE_REMOVABLE_MEDIA) create_data->Flags |= IMDISK_OPTION_REMOVABLE;*/ /*if (fdo->DeviceType == FILE_DEVICE_CD_ROM) create_data->Flags |= IMDISK_DEVICE_TYPE_CD | IMDISK_OPTION_RO; else if (fdo->Characteristics & FILE_FLOPPY_DISKETTE) create_data->Flags |= IMDISK_DEVICE_TYPE_FD; else create_data->Flags |= IMDISK_DEVICE_TYPE_HD;*/ /*if (device_extension->vm_disk) create_data->Flags |= IMDISK_TYPE_VM; else if (device_extension->use_proxy) create_data->Flags |= IMDISK_TYPE_PROXY; else create_data->Flags |= IMDISK_TYPE_FILE;*/ /*if (device_extension->image_modified) create_data->Flags |= IMDISK_IMAGE_MODIFIED;*/ /*if (device_extension->use_set_zero_data) create_data->Flags |= IMDISK_OPTION_SPARSE_FILE;*/ //create_data->ImageOffset = device_extension->image_offset; create_data->DriveLetter = device_extension->drive_letter; //create_data->FileNameLength = device_extension->file_name.Length; /*if (device_extension->file_name.Length > 0) RtlCopyMemory(create_data->FileName, device_extension->file_name.Buffer, device_extension->file_name.Length);*/ ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = sizeof(RAMDISK_CREATE_DATA)/* + create_data->FileNameLength - sizeof(*create_data->FileName)*/; break; } case IOCTL_DISK_CHECK_VERIFY: //case IOCTL_CDROM_CHECK_VERIFY: case IOCTL_STORAGE_CHECK_VERIFY: case IOCTL_STORAGE_CHECK_VERIFY2: { KdPrint(("ImDisk: IOCTL_DISK/CDROM/STORAGE_CHECK_VERIFY/2 for " "device.\n"/*, device_extension->device_number*/)); if (device_extension->vm_disk) { KdPrint(("ImDisk: Faked verify ok on vm device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) irp->IoStatus.Information = 0; else { *(PULONG) irp->AssociatedIrp.SystemBuffer = device_extension->media_change_count; irp->IoStatus.Information = sizeof(ULONG); } ntStatus = STATUS_SUCCESS; } else ntStatus = STATUS_PENDING; break; } case IOCTL_PUSH_QUERY_VERSION: { KdPrint(("ImDisk: IOCTL_IMDISK_QUERY_VERSION for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) ntStatus = STATUS_INVALID_PARAMETER; else { *(PULONG) irp->AssociatedIrp.SystemBuffer = IMDISK_DRIVER_VERSION; irp->IoStatus.Information = sizeof(ULONG); ntStatus = STATUS_SUCCESS; } break; } case IOCTL_DISK_FORMAT_TRACKS: case IOCTL_DISK_FORMAT_TRACKS_EX: // Only several checks are done here // Actual operation is done by the device thread { PFORMAT_PARAMETERS param; PDISK_GEOMETRY geometry; KdPrint(("ImDisk: IOCTL_DISK_FORMAT_TRACKS for device.\n"/*, device_extension->device_number*/)); /* if (~fdo->Characteristics & FILE_FLOPPY_DISKETTE) { irp->IoStatus.Information = 0; ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } */ // Media is writable? if (device_extension->read_only) { KdPrint(("ImDisk: Attempt to format write-protected image.\n")); irp->IoStatus.Information = 0; ntStatus = STATUS_MEDIA_WRITE_PROTECTED; break; } // Check input parameter size if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(FORMAT_PARAMETERS)) { irp->IoStatus.Information = 0; ntStatus = STATUS_INVALID_PARAMETER; break; } // Input parameter sanity check param = (PFORMAT_PARAMETERS) irp->AssociatedIrp.SystemBuffer; geometry = ExAllocatePoolWithTag(NonPagedPool, sizeof(DISK_GEOMETRY), POOL_TAG); if (geometry == NULL) { irp->IoStatus.Information = 0; ntStatus = STATUS_INSUFFICIENT_RESOURCES; break; } RtlCopyMemory(geometry, &device_extension->disk_geometry, sizeof(DISK_GEOMETRY)); geometry->Cylinders.QuadPart /= geometry->TracksPerCylinder; geometry->Cylinders.QuadPart /= geometry->SectorsPerTrack; geometry->Cylinders.QuadPart /= geometry->BytesPerSector; if ((param->StartHeadNumber > geometry->TracksPerCylinder - 1) || (param->EndHeadNumber > geometry->TracksPerCylinder - 1) || ((LONGLONG)param->StartCylinderNumber > geometry->Cylinders.QuadPart) || ((LONGLONG)param->EndCylinderNumber > geometry->Cylinders.QuadPart) || (param->EndCylinderNumber < param->StartCylinderNumber)) { ExFreePoolWithTag(geometry, POOL_TAG); irp->IoStatus.Information = 0; ntStatus = STATUS_INVALID_PARAMETER; break; } if ((param->StartCylinderNumber * geometry->TracksPerCylinder * geometry->BytesPerSector * geometry->SectorsPerTrack + param->StartHeadNumber * geometry->BytesPerSector * geometry->SectorsPerTrack >= device_extension->disk_geometry.Cylinders.QuadPart) | (param->EndCylinderNumber * geometry->TracksPerCylinder * geometry->BytesPerSector * geometry->SectorsPerTrack + param->EndHeadNumber * geometry->BytesPerSector * geometry->SectorsPerTrack >= device_extension->disk_geometry.Cylinders.QuadPart)) { ExFreePoolWithTag(geometry, POOL_TAG); irp->IoStatus.Information = 0; ntStatus = STATUS_INVALID_PARAMETER; break; } // If this is an EX request then make a couple of extra checks if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_FORMAT_TRACKS_EX) { PFORMAT_EX_PARAMETERS exparam; ULONG paramsize; KdPrint(("ImDisk: IOCTL_DISK_FORMAT_TRACKS_EX for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(FORMAT_EX_PARAMETERS)) { ExFreePoolWithTag(geometry, POOL_TAG); irp->IoStatus.Information = 0; ntStatus = STATUS_INVALID_PARAMETER; break; } exparam = (PFORMAT_EX_PARAMETERS)irp->AssociatedIrp.SystemBuffer; paramsize = sizeof(FORMAT_EX_PARAMETERS) + exparam->SectorsPerTrack * sizeof(USHORT) - sizeof(USHORT); if (irpStack->Parameters.DeviceIoControl.InputBufferLength < paramsize || exparam->FormatGapLength > geometry->SectorsPerTrack || exparam->SectorsPerTrack != geometry->SectorsPerTrack) { ExFreePoolWithTag(geometry, POOL_TAG); irp->IoStatus.Information = 0; ntStatus = STATUS_INVALID_PARAMETER; break; } } ExFreePoolWithTag(geometry, POOL_TAG); ntStatus = STATUS_PENDING; break; } case IOCTL_DISK_GROW_PARTITION: { PDISK_GROW_PARTITION grow_partition; KdPrint(("ImDisk: IOCTL_DISK_GROW_PARTITION for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.InputBufferLength != sizeof(DISK_GROW_PARTITION)) { ntStatus = STATUS_BUFFER_TOO_SMALL; irp->IoStatus.Information = 0; break; } if (device_extension->read_only) { ntStatus = STATUS_MEDIA_WRITE_PROTECTED; irp->IoStatus.Information = 0; break; } grow_partition = (PDISK_GROW_PARTITION) irp->AssociatedIrp.SystemBuffer; // Check so we don't get a smaller disk with these parameters if ((grow_partition->PartitionNumber != 1) | (device_extension->disk_geometry.Cylinders.QuadPart + grow_partition->BytesToGrow.QuadPart < device_extension->disk_geometry.Cylinders.QuadPart)) { ntStatus = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } ntStatus = STATUS_PENDING; break; } case IOCTL_DISK_UPDATE_PROPERTIES: { ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = 0; break; } case IOCTL_DISK_GET_MEDIA_TYPES: case IOCTL_STORAGE_GET_MEDIA_TYPES: case IOCTL_DISK_GET_DRIVE_GEOMETRY: //case IOCTL_CDROM_GET_DRIVE_GEOMETRY: case IOCTL_DISK_UPDATE_DRIVE_SIZE: { PDISK_GEOMETRY geometry; KdPrint(("ImDisk: IOCTL_DISK/STORAGE_GET_MEDIA_TYPES/DRIVE_GEOMETRY " "for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(device_extension->disk_geometry)) { ntStatus = STATUS_BUFFER_TOO_SMALL; irp->IoStatus.Information = 0; break; } geometry = (PDISK_GEOMETRY) irp->AssociatedIrp.SystemBuffer; *geometry = device_extension->disk_geometry; geometry->Cylinders.QuadPart /= geometry->TracksPerCylinder; geometry->Cylinders.QuadPart /= geometry->SectorsPerTrack; geometry->Cylinders.QuadPart /= geometry->BytesPerSector; ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = sizeof(DISK_GEOMETRY); break; } case IOCTL_DISK_GET_LENGTH_INFO: { KdPrint(("ImDisk: IOCTL_DISK_GET_LENGTH_INFO for device %i.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION)) { ntStatus = STATUS_BUFFER_TOO_SMALL; irp->IoStatus.Information = 0; break; } ((PGET_LENGTH_INFORMATION) irp->AssociatedIrp.SystemBuffer)-> Length.QuadPart = device_extension->disk_geometry.Cylinders.QuadPart; ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION); break; } case IOCTL_DISK_GET_PARTITION_INFO: { PPARTITION_INFORMATION partition_information; KdPrint(("ImDisk: IOCTL_DISK_GET_PARTITION_INFO for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARTITION_INFORMATION)) { ntStatus = STATUS_BUFFER_TOO_SMALL; irp->IoStatus.Information = 0; break; } partition_information = (PPARTITION_INFORMATION) irp->AssociatedIrp.SystemBuffer; partition_information->StartingOffset.QuadPart = (LONGLONG) device_extension->disk_geometry.BytesPerSector * device_extension->disk_geometry.SectorsPerTrack; partition_information->PartitionLength = device_extension->disk_geometry.Cylinders; partition_information->HiddenSectors = 1; partition_information->PartitionNumber = 1; partition_information->PartitionType = PARTITION_HUGE; partition_information->BootIndicator = FALSE; partition_information->RecognizedPartition = FALSE; partition_information->RewritePartition = FALSE; ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = sizeof(PARTITION_INFORMATION); break; } case IOCTL_DISK_GET_PARTITION_INFO_EX: { PPARTITION_INFORMATION_EX partition_information_ex; KdPrint(("ImDisk: IOCTL_DISK_GET_PARTITION_INFO_EX for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARTITION_INFORMATION_EX)) { ntStatus = STATUS_BUFFER_TOO_SMALL; irp->IoStatus.Information = 0; break; } partition_information_ex = (PPARTITION_INFORMATION_EX) irp->AssociatedIrp.SystemBuffer; partition_information_ex->PartitionStyle = PARTITION_STYLE_MBR; partition_information_ex->StartingOffset.QuadPart = (LONGLONG) device_extension->disk_geometry.BytesPerSector * device_extension->disk_geometry.SectorsPerTrack; partition_information_ex->PartitionLength = device_extension->disk_geometry.Cylinders; partition_information_ex->PartitionNumber = 1; partition_information_ex->RewritePartition = FALSE; partition_information_ex->Mbr.PartitionType = PARTITION_HUGE; partition_information_ex->Mbr.BootIndicator = FALSE; partition_information_ex->Mbr.RecognizedPartition = FALSE; partition_information_ex->Mbr.HiddenSectors = 1; ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX); break; } case IOCTL_DISK_IS_WRITABLE: { KdPrint(("ImDisk: IOCTL_DISK_IS_WRITABLE for device.\n"/*, device_extension->device_number*/)); if (!device_extension->read_only) ntStatus = STATUS_SUCCESS; else ntStatus = STATUS_MEDIA_WRITE_PROTECTED; irp->IoStatus.Information = 0; break; } case IOCTL_DISK_MEDIA_REMOVAL: case IOCTL_STORAGE_MEDIA_REMOVAL: { KdPrint(("ImDisk: IOCTL_DISK/STORAGE_MEDIA_REMOVAL for device.\n"/*, device_extension->device_number*/)); ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = 0; break; } case IOCTL_DISK_SET_PARTITION_INFO: { KdPrint(("ImDisk: IOCTL_DISK_SET_PARTITION_INFO for device.\n"/*, device_extension->device_number*/)); if (device_extension->read_only) { KdPrint(("ImDisk: Attempt to partition read-only image.\n")); ntStatus = STATUS_MEDIA_WRITE_PROTECTED; irp->IoStatus.Information = 0; break; } if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SET_PARTITION_INFORMATION)) { ntStatus = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = 0; break; } case IOCTL_DISK_SET_PARTITION_INFO_EX: { PSET_PARTITION_INFORMATION_EX partition_information_ex; KdPrint(("ImDisk: IOCTL_DISK_SET_PARTITION_INFO_EX for device.\n"/*, device_extension->device_number*/)); if (device_extension->read_only) { KdPrint(("ImDisk: Attempt to partition read-only image.\n")); ntStatus = STATUS_MEDIA_WRITE_PROTECTED; irp->IoStatus.Information = 0; break; } if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SET_PARTITION_INFORMATION_EX)) { ntStatus = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } partition_information_ex = (PSET_PARTITION_INFORMATION_EX) irp->AssociatedIrp.SystemBuffer; if (partition_information_ex->PartitionStyle != PARTITION_STYLE_MBR) { ntStatus = STATUS_UNSUCCESSFUL; irp->IoStatus.Information = 0; } else { ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = 0; } break; } case IOCTL_DISK_VERIFY: { PVERIFY_INFORMATION verify_information; KdPrint(("ImDisk: IOCTL_DISK_VERIFY for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION)) { ntStatus = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } verify_information = (PVERIFY_INFORMATION) irp->AssociatedIrp.SystemBuffer; if (device_extension->read_only) { KdPrint(("ImDisk: Attempt to verify read-only media.\n")); ntStatus = STATUS_MEDIA_WRITE_PROTECTED; irp->IoStatus.Information = 0; break; } if (verify_information->StartingOffset.QuadPart + verify_information->Length > device_extension->disk_geometry.Cylinders.QuadPart) { KdPrint(("ImDisk: Attempt to verify beyond image size.\n")); ntStatus = STATUS_NONEXISTENT_SECTOR; irp->IoStatus.Information = 0; break; } ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = 0; break; } case IOCTL_STORAGE_GET_HOTPLUG_INFO: { PSTORAGE_HOTPLUG_INFO hotplug_info; KdPrint(("ImDisk: IOCTL_STORAGE_GET_HOTPLUG_INFO for device.\n"/*, device_extension->device_number*/)); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_HOTPLUG_INFO)) { ntStatus = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } hotplug_info = (PSTORAGE_HOTPLUG_INFO) irp->AssociatedIrp.SystemBuffer; hotplug_info->Size = sizeof(STORAGE_HOTPLUG_INFO); if (fdo->Characteristics & FILE_REMOVABLE_MEDIA) { hotplug_info->MediaRemovable = TRUE; hotplug_info->MediaHotplug = TRUE; hotplug_info->DeviceHotplug = TRUE; hotplug_info->WriteCacheEnableOverride = FALSE; } else { hotplug_info->MediaRemovable = FALSE; hotplug_info->MediaHotplug = FALSE; hotplug_info->DeviceHotplug = FALSE; hotplug_info->WriteCacheEnableOverride = FALSE; } ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO); break; } case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: { PMOUNTDEV_NAME mountDeviceName = irp->AssociatedIrp.SystemBuffer; int chars; KdPrint(("ImDisk: IOCTL_MOUNTDEV_QUERY_DEVICE_NAME for device.\n"/*, device_extension->device_number*/)); chars = _snwprintf( mountDeviceName->Name, (irpStack->Parameters.DeviceIoControl.OutputBufferLength - FIELD_OFFSET(MOUNTDEV_NAME, Name)) >> 1, PUSH_RAMDISK_DEVICE_NAME ); if (chars < 0) { if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= FIELD_OFFSET(MOUNTDEV_NAME, Name) + sizeof(mountDeviceName->NameLength)) /*mountDeviceName->NameLength = sizeof(PUSH_DEVICE_BASE_NAME) + 20;*/ mountDeviceName->NameLength = sizeof(PUSH_RAMDISK_DEVICE_NAME) + 20; KdPrint(("ImDisk: IOCTL_MOUNTDEV_QUERY_DEVICE_NAME overflow, " "buffer length %u, returned %i.\n", irpStack->Parameters.DeviceIoControl.OutputBufferLength, chars)); ntStatus = STATUS_BUFFER_OVERFLOW; if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(MOUNTDEV_NAME)) irp->IoStatus.Information = sizeof(MOUNTDEV_NAME); else irp->IoStatus.Information = 0; break; } mountDeviceName->NameLength = (USHORT) chars << 1; ntStatus = STATUS_SUCCESS; irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + mountDeviceName->NameLength; KdPrint(("[PUSH] => IOCTL_MOUNTDEV_QUERY_DEVICE_NAME => %ws, " "length %u total %u.\n", mountDeviceName->Name, mountDeviceName->NameLength, irp->IoStatus.Information)); } break; default: { KdPrint(("[PUSH] Unknown IOCTL %#x.\n", irpStack->Parameters.DeviceIoControl.IoControlCode)); ntStatus = STATUS_INVALID_DEVICE_REQUEST; irp->IoStatus.Information = 0; } } if (ntStatus == STATUS_PENDING) { IoMarkIrpPending(irp); ExInterlockedInsertTailList(&device_extension->list_head, &irp->Tail.Overlay.ListEntry, &device_extension->list_lock); KeSetEvent(&device_extension->request_event, (KPRIORITY) 0, FALSE); } else { irp->IoStatus.Status = ntStatus; IoCompleteRequest(irp, IO_NO_INCREMENT); } return ntStatus; }