vdkioctl.c

来自「Virtual Disk Driver」· C语言 代码 · 共 1,626 行 · 第 1/3 页

C
1,626
字号
	//	case IOCTL_VDK_DELETE_DISK:		status = STATUS_PENDING;		break;	//	// Operation:	Notifies the device that it has been dismounted	// Target:		any device	// Input:		none	// Output:		none	//	case IOCTL_VDK_NOTIFY_DISMOUNT:		if (part_extension->PartitionOrdinal == VDK_ZOMBIE) {			VDKTRACE(VDKIOCTL | VDKWARN,				("[VDK] %ws is no longer a zombie.\n",				part_extension->DeviceName.Buffer));			part_extension->PartitionOrdinal = 0;		}		status = STATUS_SUCCESS;		break;	//	// Operation:	Returnes driver information	// Target:		any device	// Input:		none	// Output:		VDK_DRIVER_INFO driver information	// Status:		STATUS_BUFFER_TOO_SMALL		output buffer too small	//	case IOCTL_VDK_DRIVER_INFO:		{			PDEVICE_OBJECT device_obj;			PVDK_DRIVER_INFO driver_info;			//			// Check output buffer length			//			if (IO_OUTPUTLEN(io_stack) < sizeof(VDK_DRIVER_INFO)) {				status = STATUS_BUFFER_TOO_SMALL;				break;			}			//			//	Initialize output buffer			//			driver_info =				(PVDK_DRIVER_INFO)Irp->AssociatedIrp.SystemBuffer;			RtlZeroMemory(driver_info, sizeof(VDK_DRIVER_INFO));			//			//	Count each type of devices			//			device_obj = DeviceObject->DriverObject->DeviceObject;			while (device_obj) {				PPART_EXTENSION part_ext =					(PPART_EXTENSION)device_obj->DeviceExtension;				if (device_obj->Vpb && device_obj->Vpb->ReferenceCount) {					driver_info->TotalReference						+= device_obj->Vpb->ReferenceCount;				}				if (part_ext) {					if (part_ext == (PPART_EXTENSION)part_ext->FirstPartition) {						driver_info->DiskDevices++;					}					else if (part_ext->FirstPartition) {						driver_info->AttachedParts++;					}					else {						driver_info->OrphanedParts++;					}#if DBG					if ((TraceFlags & (VDKIOCTL | VDKINFO)) == (VDKIOCTL | VDKINFO)) {						if (part_ext->DeviceName.Buffer) {							KdPrint(("[VDK] DeviceName: %ws\n",								part_ext->DeviceName.Buffer));						}						if (part_ext->SymbolicLink.Buffer) {							KdPrint(("[VDK] SymbolicLink: %ws\n",								part_ext->SymbolicLink.Buffer));						}						KdPrint(("[VDK] Characteristics = 0x%08x\n",							device_obj->Characteristics));						if (device_obj->Characteristics & FILE_AUTOGENERATED_DEVICE_NAME) {							KdPrint(("    FILE_AUTOGENERATED_DEVICE_NAME\n"));						}						if (device_obj->Characteristics & FILE_DEVICE_IS_MOUNTED) {							KdPrint(("    FILE_DEVICE_IS_MOUNTED\n"));						}						if (device_obj->Characteristics & FILE_DEVICE_SECURE_OPEN) {							KdPrint(("    FILE_DEVICE_SECURE_OPEN\n"));						}						if (device_obj->Characteristics & FILE_FLOPPY_DISKETTE) {							KdPrint(("    FILE_FLOPPY_DISKETTE\n"));						}						if (device_obj->Characteristics & FILE_READ_ONLY_DEVICE) {							KdPrint(("    FILE_READ_ONLY_DEVICE\n"));						}						if (device_obj->Characteristics & FILE_REMOTE_DEVICE) {							KdPrint(("    FILE_REMOTE_DEVICE\n"));						}						if (device_obj->Characteristics & FILE_REMOVABLE_MEDIA) {							KdPrint(("    FILE_REMOVABLE_MEDIA\n"));						}						if (device_obj->Characteristics & FILE_VIRTUAL_VOLUME) {							KdPrint(("    FILE_VIRTUAL_VOLUME\n"));						}						if (device_obj->Characteristics & FILE_WRITE_ONCE_MEDIA) {							KdPrint(("    FILE_WRITE_ONCE_MEDIA\n"));						}						if (device_obj->Vpb) {							KdPrint(("    Vpb->Type = %d\n",								device_obj->Vpb->Type));							KdPrint(("    Vpb->SerialNumber = %lu\n",								device_obj->Vpb->SerialNumber));							KdPrint(("    Vpb->ReferenceCount = %lu\n",								device_obj->Vpb->ReferenceCount));							if (device_obj->Vpb->Flags & VPB_MOUNTED) {								KdPrint(("    VPB_MOUNTED\n"));							}							if (device_obj->Vpb->Flags & VPB_LOCKED) {								KdPrint(("    VPB_LOCKED\n"));							}							if (device_obj->Vpb->Flags & VPB_PERSISTENT) {								KdPrint(("    VPB_PERSISTENT\n"));							}							if (device_obj->Vpb->Flags & VPB_REMOVE_PENDING) {								KdPrint(("    VPB_REMOVE_PENDING\n"));							}							if (device_obj->Vpb->Flags & VPB_RAW_MOUNT) {								KdPrint(("    VPB_RAW_MOUNT\n"));							}						}					}#endif	// DBG				}				device_obj = device_obj->NextDevice;			}			Irp->IoStatus.Information = sizeof(VDK_DRIVER_INFO);			status = STATUS_SUCCESS;			break;		}	//	// Operation:	Returns device information	// Target:		any device	// Input:		TRUE	query all devices	//				FALSE	query this device only	// Output:		VDK_DEVICE_INFO device information	// Status:		STATUS_BUFFER_TOO_SMALL	output buffer too small	//				STATUS_BUFFER_OVERFLOW	//	case IOCTL_VDK_DEVICE_INFO:		{			PDEVICE_OBJECT device_obj;			PVDK_DEVICE_INFO device_info;			ANSI_STRING ansi_str;			ULONG device_num;			//			// Check output buffer length			//			if (IO_OUTPUTLEN(io_stack) < sizeof(VDK_DEVICE_INFO)) {				status = STATUS_BUFFER_TOO_SMALL;				break;			}			//			// Check request type			//			if (IO_INPUTLEN(io_stack) >= sizeof(ULONG) &&				*(PULONG)Irp->AssociatedIrp.SystemBuffer) {				//				// Information request for all devices				//				device_obj = DeviceObject->DriverObject->DeviceObject;				device_num = 0;				while (device_obj) {					device_num++;					device_obj = device_obj->NextDevice;				}				//				// Recheck output buffer length				//				if (IO_OUTPUTLEN(io_stack) < sizeof(VDK_DEVICE_INFO) * device_num) {					device_num = IO_OUTPUTLEN(io_stack) / sizeof(VDK_DEVICE_INFO);					status = STATUS_BUFFER_OVERFLOW;				}				else {					status = STATUS_SUCCESS;				}				device_obj = DeviceObject->DriverObject->DeviceObject;			}			else {				//				// Information request for this device only				//				device_obj = DeviceObject;				device_num = 1;				status = STATUS_SUCCESS;			}			//			// Initialize output buffer			//			Irp->IoStatus.Information =				sizeof(VDK_DEVICE_INFO) * device_num;			RtlZeroMemory(				Irp->AssociatedIrp.SystemBuffer,				sizeof(VDK_DEVICE_INFO) * device_num);			device_info =				(PVDK_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;			while (device_obj && device_num) {				PPART_EXTENSION part_ext =					(PPART_EXTENSION)device_obj->DeviceExtension;				//				// Store devie type				//				if (part_ext == (PPART_EXTENSION)part_ext->FirstPartition) {					device_info->DeviceType = VDK_DEVICE_DISK;				}				else {					device_info->DeviceType = VDK_DEVICE_PART;				}				if (part_ext->PartitionOrdinal == VDK_ZOMBIE) {					device_info->Zombie = VDK_ZOMBIE;				}				//				// Store device name				//				if (part_ext->DeviceName.Buffer) {					ansi_str.Buffer = device_info->DeviceName;					ansi_str.Length = 0;					ansi_str.MaximumLength = sizeof(device_info->DeviceName);					RtlUnicodeStringToAnsiString(						&ansi_str, &part_ext->DeviceName, FALSE);				}				//				// Store symbolic link name				//				if (part_ext->SymbolicLink.Buffer) {					ansi_str.Buffer = device_info->SymbolicLink;					ansi_str.Length = 0;					ansi_str.MaximumLength = sizeof(device_info->SymbolicLink);					RtlUnicodeStringToAnsiString(						&ansi_str, &part_ext->SymbolicLink, FALSE);				}				//				// store device reference count				//				if (device_obj->Vpb) {					device_info->ReferenceCount =						device_obj->Vpb->ReferenceCount;				}				//				// next device;				//				device_obj = device_obj->NextDevice;				device_num--;				device_info++;			}			break;		}#if DBG	//	// Operation:	Set debug trace flag	// Target:		any device	// Input:		ULONG trace flags (optional)	// Output:		none	// Status:		STATUS_SUCCESS	//	case IOCTL_VDK_DEBUG_TRACE:		{			if (IO_INPUTLEN(io_stack) >= sizeof(ULONG)) {				TraceFlags = *(PULONG)Irp->AssociatedIrp.SystemBuffer;			}			KdPrint(("[VDK] Current Trace Flags = 0x%08x\n", TraceFlags));			if (IO_OUTPUTLEN(io_stack) >= sizeof(ULONG)) {				*(PULONG)Irp->AssociatedIrp.SystemBuffer = TraceFlags;				Irp->IoStatus.Information = sizeof(ULONG);			}			status = STATUS_SUCCESS;			break;		}#endif	// DBG	//	// Operation:	Return the drive geometry for the specified drive.	// Target:		active device	// Input:		none	// Output:		DISK_GEOMETRY	//	// we will return the geometry for the physical drive, regardless	// of which partition was specified for the request.	//	case IOCTL_DISK_GET_DRIVE_GEOMETRY:		{			PDISK_GEOMETRY geometry;			//			//	check device type			//			if (!disk_extension) {				VDKTRACE(VDKIOCTL,					("[VDK] %ws is an orphaned partition device\n",					part_extension->DeviceName.Buffer));				status = STATUS_INVALID_DEVICE_REQUEST;				break;			}			//			// check device state			//			if (!disk_extension->DiskInfo.DiskType ||				!part_extension->PartitionInfo.PartitionLength.QuadPart) {				status = STATUS_DEVICE_NOT_READY;				break;			}			//			// check output buffer length			//			if (IO_OUTPUTLEN(io_stack) < sizeof(DISK_GEOMETRY)) {				status = STATUS_BUFFER_TOO_SMALL;				break;			}			//			// copy DISK_GEOMETRY information			//			geometry = (PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer;			geometry->MediaType			= FixedMedia;			geometry->BytesPerSector	= VDK_BYTES_PER_SECTOR;			geometry->SectorsPerTrack	= disk_extension->DiskInfo.Sectors;			geometry->TracksPerCylinder	= disk_extension->DiskInfo.Tracks;			geometry->Cylinders.QuadPart = disk_extension->DiskInfo.Cylinders;			Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);			status = STATUS_SUCCESS;			break;		}	//	// Operation:	Return the information about the partition specified by the	// 				device object.	// Target: 		active device	// Input:		none	// Output:		PARTITION_INFORMATION	//	case IOCTL_DISK_GET_PARTITION_INFO:		{			PPARTITION_INFORMATION partition_info;			//			//	check device type			//			if (!disk_extension) {				VDKTRACE(VDKIOCTL,					("[VDK] %ws is an orphaned partition device\n",					part_extension->DeviceName.Buffer));				status = STATUS_INVALID_DEVICE_REQUEST;				break;			}			//			// check device state			//			if (!disk_extension->DiskInfo.DiskType ||				!part_extension->PartitionInfo.PartitionLength.QuadPart) {				status = STATUS_DEVICE_NOT_READY;				break;			}			//			// check output buffer length			//			if (IO_OUTPUTLEN(io_stack) < sizeof(PARTITION_INFORMATION)) {				status = STATUS_BUFFER_TOO_SMALL;				break;			}			//			// set up the PARTITION_INFORMATION to return			//			partition_info =				(PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;			RtlCopyMemory(partition_info,				&part_extension->PartitionInfo,				sizeof(PARTITION_INFORMATION));			partition_info->RecognizedPartition = TRUE;			partition_info->RewritePartition	= FALSE;			Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);			status = STATUS_SUCCESS;			break;		}	//	// Operation:	Return the information about the partition specified by the	// 				device object. (WINXP specific)	// Target: 		active device	// Input:		none	// Output:		PARTITION_INFORMATION_EX	//	case IOCTL_DISK_GET_PARTITION_INFO_EX:	// WINXP		{			PPARTITION_INFORMATION_EX partition_info;			//			//	check device type			//			if (!disk_extension) {				VDKTRACE(VDKIOCTL,					("[VDK] %ws is an orphaned partition device\n",					part_extension->DeviceName.Buffer));				status = STATUS_INVALID_DEVICE_REQUEST;				break;			}			//			// check device state			//			if (!disk_extension->DiskInfo.DiskType ||				!part_extension->PartitionInfo.PartitionLength.QuadPart) {				status = STATUS_DEVICE_NOT_READY;				break;			}			//			// check output buffer length			//			if (IO_OUTPUTLEN(io_stack) < sizeof(PARTITION_INFORMATION_EX)) {				status = STATUS_BUFFER_TOO_SMALL;				break;			}			//			// set up the PARTITION_INFORMATION_EX to return			//			partition_info =				(PPARTITION_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;			partition_info->PartitionStyle = PARTITION_STYLE_MBR;			partition_info->StartingOffset.QuadPart =				part_extension->PartitionInfo.StartingOffset.QuadPart;			partition_info->PartitionLength.QuadPart =				part_extension->PartitionInfo.PartitionLength.QuadPart;			partition_info->PartitionNumber =				part_extension->PartitionInfo.PartitionNumber;			partition_info->RewritePartition	= FALSE;			partition_info->Mbr.PartitionType =				part_extension->PartitionInfo.PartitionType;			partition_info->Mbr.BootIndicator =				part_extension->PartitionInfo.BootIndicator;			partition_info->Mbr.RecognizedPartition = TRUE;			partition_info->Mbr.HiddenSectors =				part_extension->PartitionInfo.HiddenSectors;			Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);			status = STATUS_SUCCESS;			break;		}	//	// Operation:	set the partition type.	// Target: 		active partition device	// Input:		SET_PARTITION_INFORMATION	// Output:		none	//	case IOCTL_DISK_SET_PARTITION_INFO:		{			PSET_PARTITION_INFORMATION set_info;			//			// check device type			//			if (!disk_extension) {				VDKTRACE(VDKIOCTL,					("[VDK] %ws is an orphaned partition device\n",					part_extension->DeviceName.Buffer));				status = STATUS_INVALID_DEVICE_REQUEST;				break;			}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?