Alkalmazások és operációs rendszerek optimizálása „Babeş-Bolyai” Tudományegyetem, Matematika-Informatika Kar Windows NT driverek fejlesztése: Virtuális lemezegység driver előadás dr. Robu Judit szeminárium drd. Lukács Sándor
BBTE, Alkalmazások és operációs rendszerek optimizálása 2 A feladat megfogalmazása... egy virtuális lemezegység létrehozása, amely segítségével egy image állományt egy lemezegységként tudunk kezelni működjön floppy és mervelmez partíciók esetén is működjön CD és DVD ISO képek esetén is lehessen egy állomány csak egy bizonyos részét lemezegységként használni az eredei ötlet a SIMICS virtuális lemezegységeinek Windows alá történő betükrözése volt
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 3 A megoldás alapötletei virtuális lemezegység driver minden virtuális lemezegység számára egy-egy device objektum minden device objektum számára egy-egy szimbolikus link pl. „\\dosdevices\\b:” minden lemezegységnek megfelel háttérben egy-egy állomány az IRP_MJ_READ és IRP_MJ_WRITE műveleteket úgy oldjuk meg, hogy háttérben az állományból/-ba olvassuk/írjuk az adatokat implementálunk egy saját IOCTL-t a mount művelet számára minden device objektumhoz rendelünk egy-egy device extensiont ebben tároljuk a driver/device specifikus információkat, mint pl. a lemezegységnek megfelelő állomány handel-je, a lemezegység típusa (cd-rom, floppy), a lemez geometriája (CHS) etc. minimális számú standard IOCTL-t implementálunk ahhoz, hogy írható-olvasható lemezegységket tudjunk szimulálni
WIN32, ALKALMAZÁSOK VDISK driver DRV DEVOBJ VOL DEVOBJ dev ext, IMAGE dev ext VDCONF MOUNT kérés NTFS, FASTFAT stb. VOL DEVOBJ dev ext merevlemez IMG ISO IRP_MJ_READ IRP_MJ_WRITE ZwReadFile ZwWriteFile
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 5 Image információk 1 typedef struct _IMAGE { // device extension a VOLUME OBJECT-ek számára PDEVICE_OBJECT DeviceObject; UNICODE_STRING DeviceName; UNICODE_STRING DosDeviceName; // user supplied geometry and partition information DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION_EX PartInfo; // offset and length inside the file QWORD ImageOffset; QWORD ImageSize; // handle of the file image HANDLE DiskImage; BOOLEAN ReadOnly; DWORD DevNumber; } IMAGE, *PIMAGE; typedef struct _DEVICE_EXTENSION { // dev ext DRVOBJ számára PDEVICE_OBJECT DeviceObject; } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 6 Image információk 2 typedef struct _DISK_GEOMETRY { LARGE_INTEGER Cylinders; MEDIA_TYPE MediaType; DWORD TracksPerCylinder; DWORD SectorsPerTrack; DWORD BytesPerSector; } DISK_GEOMETRY, *PDISK_GEOMETRY; typedef struct _PARTITION_INFORMATION_EX { PARTITION_STYLE PartitionStyle; LARGE_INTEGER StartingOffset; LARGE_INTEGER PartitionLength; DWORD PartitionNumber; BOOLEAN RewritePartition; union { PARTITION_INFORMATION_MBR Mbr; PARTITION_INFORMATION_GPT Gpt; }; } PARTITION_INFORMATION_EX, *PPARTITION_INFORMATION_EX;
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 7 Globális adatok typedef struct _DRV_GLOBAL_DATA { DRV_SPIN_LOCK Lock; ULONG Flags; // DRV specific fields PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT DeviceObject; // driver specific string ids UNICODE_STRING DeviceName; UNICODE_STRING DosDeviceName; // device name generator DWORD DevCounter; // IMAGE-ek száma DWORD MountedCount; // a mountolt IMAGE-ek száma DWORD DevNumber; } DRV_GLOBAL_DATA, *PDRV_GLOBAL_DATA;
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 8 DriverEntry 1 // initialize the dispatch entry points DriverObject->MajorFunction[IRP_MJ_CREATE] = Drv_MJ_CREATE; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Drv_MJ_CLEANUP; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Drv_MJ_CLOSE; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Drv_MJ_DEVICE_CONTROL; DriverObject->MajorFunction[IRP_MJ_READ] = Drv_MJ_READ; DriverObject->MajorFunction[IRP_MJ_WRITE] = Drv_MJ_WRITE; // create the main device object RtlInitUnicodeString(&(DrvGlobalData.DeviceName), DEVICE_NAME); Status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), &DrvGlobalData.DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DrvGlobalData.DeviceObject );
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 9 DriverEntry 2 DevExt = (PDEVICE_EXTENSION)DrvGlobalData.DeviceObject->DeviceExtension; DevExt->DeviceObject = DrvGlobalData.DeviceObject; // no image is mounted yet DrvGlobalData.DevCounter = 0; DrvGlobalData.MountedCount = 0; DrvGlobalData.DevNumber = 0x1000;... // create symbolic link RtlInitUnicodeString(&(DrvGlobalData.DosDeviceName), L"\\dosdevices\\vdiskdev"); if (NT_SUCCESS(IoCreateSymbolicLink(&(DrvGlobalData.DosDeviceName), &DrvGlobalData.DeviceName))) { ExKdPrint((" DriverEntry - symbolic link %S created\n", DrvGlobalData.DosDeviceName.Buffer)); }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 10 IRP_MJ_CREATE // request to open the device if (DeviceObject == DrvGlobalData.DeviceObject) { ExKdPrint((" vdisk.sys device object opened\n")); Irp->IoStatus.Information = FILE_OPENED; Status = STATUS_SUCCESS; } else { // try to locate a corresponding image object device Image = (PIMAGE)DeviceObject->DeviceExtension; if (Image != NULL) { ExKdPrint((" image device %S opened\n", Image->DosDeviceName.Buffer)); Irp->IoStatus.Information = FILE_OPENED; Status = STATUS_SUCCESS; } else { ExKdPrint((" try to open an invalid object/device\n")); Irp->IoStatus.Information = FILE_DOES_NOT_EXIST; Status = STATUS_OBJECT_NAME_NOT_FOUND; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 11 IRP_MJ_DEVICE_CONTROL 1 ExKdPrint((" Drv_MJ_DEVICE_CONTROL \n")); switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_DISK_GET_PARTITION_INFO: Status = Drv_IOCTL_DISK_GET_PARTITION_INFO(DeviceObject, Irp, IrpSp); break; case IOCTL_DISK_GET_PARTITION_INFO_EX: Status = Drv_IOCTL_DISK_GET_PARTITION_INFO_EX(DeviceObject, Irp, IrpSp); break; case IOCTL_CDROM_READ_TOC: Status = Drv_IOCTL_CDROM_READ_TOC(DeviceObject, Irp, IrpSp); break; case IOCTL_DISK_GET_DRIVE_GEOMETRY: case IOCTL_CDROM_GET_DRIVE_GEOMETRY: Status = Drv_IOCTL_DISK_GET_DRIVE_GEOMETRY(DeviceObject, Irp, IrpSp); break; case IOCTL_DISK_GET_LENGTH_INFO: Status = Drv_IOCTL_DISK_GET_LENGTH_INFO(DeviceObject, Irp, IrpSp); break;...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 12 IRP_MJ_DEVICE_CONTROL 2... case IOCTL_DISK_MEDIA_REMOVAL: Status = Drv_IOCTL_DISK_MEDIA_REMOVAL(DeviceObject, Irp, IrpSp); break; case IOCTL_DISK_CHECK_VERIFY: case IOCTL_STORAGE_CHECK_VERIFY: case IOCTL_STORAGE_CHECK_VERIFY2: case IOCTL_CDROM_CHECK_VERIFY: Status = Drv_IOCTL_DISK_CHECK_VERIFY(DeviceObject, Irp, IrpSp); break; case IOCTL_DISK_IS_WRITABLE: Status = Drv_IOCTL_DISK_IS_WRITABLE(DeviceObject, Irp, IrpSp); break; case IOCTL_STORAGE_GET_DEVICE_NUMBER: Status = Drv_IOCTL_STORAGE_GET_DEVICE_NUMBER(DeviceObject, Irp, IrpSp); break; case IOCTL_DRV_MOUNT_IMAGE: Status = Drv_IOCTL_DRV_MOUNT_IMAGE(DeviceObject, Irp, IrpSp); break;...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 13 IOCTL_DISK_GET_DRIVE_GEOMETRY Image = (PIMAGE)DeviceObject->DeviceExtension; ExKdPrint((" Drv_IOCTL_DISK_GET_DRIVE_GEOMETRY\n")); if (Image == NULL) { Irp->IoStatus.Information = 0; return STATUS_INVALID_DEVICE_REQUEST; } if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) { Irp->IoStatus.Information = sizeof(DISK_GEOMETRY); Status = STATUS_BUFFER_TOO_SMALL; // inform the caller we need bigger buffer } else { PDISK_GEOMETRY Geometry; Geometry = (PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer; RtlCopyMemory(Geometry, &Image->DiskGeometry, sizeof(DISK_GEOMETRY)); Irp->IoStatus.Information = sizeof(DISK_GEOMETRY); Status = STATUS_SUCCESS; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 14 IOCTL_DISK_GET_LENGTH_INFO Image = (PIMAGE)DeviceObject->DeviceExtension; ExKdPrint((" Drv_IOCTL_DISK_GET_LENGTH_INFO\n")); if (Image == NULL) { Irp->IoStatus.Information = 0; return STATUS_INVALID_DEVICE_REQUEST; } if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION)) { Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION); Status = STATUS_BUFFER_TOO_SMALL; // Inform the caller we need bigger buffer } else { PGET_LENGTH_INFORMATION LengthInfo; LengthInfo = (PGET_LENGTH_INFORMATION)Irp->AssociatedIrp.SystemBuffer; LengthInfo->Length.QuadPart = Image->DiskGeometry.BytesPerSector * Image->DiskGeometry.SectorsPerTrack * Image->DiskGeometry.TracksPerCylinder * Image->DiskGeometry.Cylinders.QuadPart; Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION); Status = STATUS_SUCCESS; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 15 IOCTL_CDROM_READ_TOC Image = (PIMAGE)DeviceObject->DeviceExtension; ExKdPrint((" Drv_IOCTL_CDROM_READ_TOC\n")); if (Image == NULL) { Irp->IoStatus.Information = 0; return STATUS_INVALID_DEVICE_REQUEST; } if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC)) { Irp->IoStatus.Information = sizeof(CDROM_TOC); Status = STATUS_BUFFER_TOO_SMALL; // Inform the caller we need bigger buffer } else { PCDROM_TOC CdRomToc; CdRomToc = (PCDROM_TOC)Irp->AssociatedIrp.SystemBuffer; CdRomToc->FirstTrack = 1; CdRomToc->LastTrack = 1; CdRomToc->TrackData[0].Control = TOC_DATA_TRACK; Irp->IoStatus.Information = sizeof(CDROM_TOC); Status = STATUS_SUCCESS; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 16 IOCTL_DISK_IS_WRITEABLE Image = (PIMAGE)DeviceObject->DeviceExtension; ExKdPrint((" Drv_IOCTL_DISK_IS_WRITABLE\n")); if (Image == NULL) { Irp->IoStatus.Information = 0; return STATUS_INVALID_DEVICE_REQUEST; } if (Image->ReadOnly) { Status = STATUS_MEDIA_WRITE_PROTECTED; } else { Status = STATUS_SUCCESS; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 17 A mount művelet implementálása typedef struct _MOUNT { CHAR FileName[1024]; // fully qualified image name // (ex. “c:\\dir1\\dir2\\image.iso") QWORD ImageOffset; // offset and length inside the file QWORD ImageSize; CHAR DosDevName[64]; // fully qualified dos device name // (ex. "\\dosdevices\\v:") BOOLEAN ReadOnly; // mount as a ReadOnly image DISK_GEOMETRY DiskGeometry; // user supplied geometry and PARTITION_INFORMATION_EX PartInfo; // partition information BOOLEAN CdRom; // TRUE for CD-ROM images int Status; } MOUNT_IMAGE, *PMOUNT_IMAGE;
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 18 IOCTL_DRV_MOUNT_IMAGE 1... static CHAR FullFileName[1024]; static CHAR DevName[64], Hex[20]; UNREFERENCED_PARAMETER(IrpSp); ExKdPrint((" Drv_IOCTL_DRV_MOUNT_IMAGE\n")); if (DeviceObject != DrvGlobalData.DeviceObject) { ExKdPrint((" invalid device object, invalid request\n")); return STATUS_INVALID_DEVICE_REQUEST; } Params = (PMOUNT_IMAGE)(Irp->AssociatedIrp.SystemBuffer); // bytes returned Irp->IoStatus.Information = sizeof(MOUNT_IMAGE); // inialize ImageFileName #pragma warning(suppress:4995) strcpy(FullFileName, "\\??\\"); #pragma warning(suppress:4995) strcat(FullFileName, Params->FileName);...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 19 IOCTL_DRV_MOUNT_IMAGE 2... RtlInitAnsiString(&AnsiName, FullFileName); RtlAnsiStringToUnicodeString(&ImageFileName, &AnsiName, TRUE); InitializeObjectAttributes(&ObjAttribs, &ImageFileName, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&DiskImage, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjAttribs, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { ExKdPrint((" Can't open disk image %S, error %s\n", ImageFileName.Buffer, DrvNtStatusToString(Status))); RtlFreeUnicodeString(&ImageFileName); } else { RtlFreeUnicodeString(&ImageFileName);...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 20 IOCTL_DRV_MOUNT_IMAGE 3... // init device name strcpy(DevName, "\\vdimg"); DrvGlobalData.DevCounter++; Hex[4] = 0; Hex[0] = NameChars[(DrvGlobalData.DevCounter & 0xF000) >> 12]; Hex[1] = NameChars[(DrvGlobalData.DevCounter & 0x0F00) >> 8]; Hex[2] = NameChars[(DrvGlobalData.DevCounter & 0x00F0) >> 4]; Hex[3] = NameChars[(DrvGlobalData.DevCounter & 0x000F)]; strcat(DevName, Hex); RtlInitAnsiString(&AnsiName, DevName); RtlAnsiStringToUnicodeString(&DeviceName, &AnsiName, TRUE); // create device object Status = IoCreateDevice( DrvGlobalData.DriverObject, sizeof(IMAGE), &DeviceName, Params->CdRom ? FILE_DEVICE_CD_ROM : FILE_DEVICE_VIRTUAL_DISK, 0, FALSE, &NewDeviceObject);...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 21 IOCTL_DRV_MOUNT_IMAGE 4... if (!NT_SUCCESS(Status)) { ExKdPrint(("couldn't create dev object, %s\n", DrvNtStatusToString(Status))); // deinit Image ZwClose(&DiskImage); RtlFreeUnicodeString(&DeviceName); } else { ExKdPrint((" device object for image created\n")); Image = (PIMAGE)NewDeviceObject->DeviceExtension; Image->DeviceObject = NewDeviceObject; Image->DeviceName = DeviceName; if (Params->CdRom || Params->ReadOnly) { Image->DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; } // init DosDeviceName RtlInitAnsiString(&AnsiName, Params->DosDevName); RtlAnsiStringToUnicodeString(&Image->DosDeviceName, &AnsiName, TRUE); ExKdPrint((" devicename %S dosdevicename %S\n", Image->DeviceName.Buffer, Image->DosDeviceName.Buffer));...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 22 IOCTL_DRV_MOUNT_IMAGE 5... // set device flags Image->DeviceObject->Flags |= DO_DIRECT_IO; Image->DeviceObject->Flags |= DO_POWER_PAGABLE; Image->DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; // create symbolic link IoCreateSymbolicLink(&Image->DosDeviceName, &Image->DeviceName); // set image file handle Image->DiskImage = DiskImage; Image->ReadOnly = Params->ReadOnly; // set image size and offset Image->ImageSize = Params->ImageSize; Image->ImageOffset = Params->ImageOffset; ExKdPrint((" imagesize 0x%I64x imageoffset 0x%I64x\n", Image->ImageSize, Image->ImageOffset)); // copy geometry and partition info RtlCopyMemory(&Image->DiskGeometry, &Params->DiskGeometry, sizeof(DISK_GEOMETRY)); RtlCopyMemory(&Image->PartInfo, &Params->PartInfo, sizeof(PARTITION_INFORMATION_EX)); DrvGlobalData.MountedCount++; DrvGlobalData.DevNumber++; Image->DevNumber = DrvGlobalData.DevNumber; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 23 IRP_MJ_READ / IRP_MN_NORMAL 1 NTSTATUS Read_MN_NORMAL(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, PIO_STACK_LOCATION IrpSp) { NTSTATUS Status = STATUS_SUCCESS; LARGE_INTEGER ByteOffset; ULONG Length; ULONG BytesReaded; IO_STATUS_BLOCK IoStatus; PIMAGE Image; PVOID Buffer; Image = (PIMAGE)DeviceObject->DeviceExtension; if (Image == NULL) { ExKdPrint((" Read_MN_NORMAL, image object is NULL\n")); Irp->IoStatus.Information = 0; return STATUS_INVALID_DEVICE_REQUEST; } // verify parameters ByteOffset.QuadPart = IrpSp->Parameters.Read.ByteOffset.QuadPart; Length = IrpSp->Parameters.Read.Length;...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 24 IRP_MJ_READ / IRP_MN_NORMAL 2... if (ByteOffset.QuadPart + Length > (__int64)Image->ImageSize) { ExKdPrint(("Read_MN_NORMAL invalid offset / length\n")); ExKdPrint(("ByteOffset 0x%I64x Length 0x%x ImageSize 0x%I64x ImageOffset 0x%I64x\n", ByteOffset.QuadPart, Length, Image->ImageSize, Image->ImageOffset)); Irp->IoStatus.Information = 0; return STATUS_INVALID_PARAMETER; } ByteOffset.QuadPart += Image->ImageOffset; Irp->IoStatus.Information = 0; ExKdPrint(("Read_MN_NORMAL Offset %08I64d Length %08ld\n", ByteOffset.QuadPart, Length)); BytesReaded = 0; if (NULL == Image->DiskImage) { ExKdPrint((" no image to read from\n")); Status = STATUS_INVALID_DEVICE_REQUEST; } else...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 25 IRP_MJ_READ / IRP_MN_NORMAL 3... else { if (Irp->MdlAddress != NULL) { ExKdPrint((" try to read disk image, using MDL\n")); Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); Status = ZwReadFile(Image->DiskImage, NULL, NULL, NULL, &IoStatus, Buffer, Length, &ByteOffset, NULL); BytesReaded = (ULONG)IoStatus.Information; ExKdPrint((" read successfully terminated\n")); } else { Status = STATUS_INVALID_PARAMETER; ExKdPrint((" no MDL address\n")); } ExKdPrint((" Read_MN_NORMAL / bytes readed = %ld / status is %s\n", BytesReaded, DrvNtStatusToString(Status))); Irp->IoStatus.Information = BytesReaded; return Status; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 26 Win32 vezérlő alkalmazás – VDCONF 1 int MountVolume(char *image, char *drive, QWORD ImageSize, QWORD ImageOffset) { CHAR DevName[64]; HANDLE Device; MOUNT_IMAGE Mount; int ret; QWORD DiskSize; HANDLE File; // get file size File = CreateFile(image, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (File == INVALID_HANDLE_VALUE) { printf("error: can't open image\n"); return -1; } DiskSize = GetFileSize(File, NULL); CloseHandle(File); // apply predefined file size, if given if (ImageSize != 0) { DiskSize = ImageSize; } else { ImageOffset = 0; }...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 27 Win32 vezérlő alkalmazás – VDCONF 2... // open virtual disk strcpy_s(DevName, sizeof(DevName), "\\\\?\\vdiskdev"); Device = CreateFile(DevName, 0, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (Device == INVALID_HANDLE_VALUE) { printf("error: can't open virtual disk\n"); return -1; } strcpy_s(Mount.FileName, sizeof(Mount.FileName), image); strcpy_s(Mount.DosDevName, sizeof(Mount.DosDevName), "\\dosdevices\\"); strcat_s(Mount.DosDevName, sizeof(Mount.DosDevName), drive); // disk geometry Mount.DiskGeometry.MediaType = FixedMedia; Mount.DiskGeometry.BytesPerSector = 512; Mount.DiskGeometry.SectorsPerTrack = 63; Mount.DiskGeometry.TracksPerCylinder = 16; Mount.DiskGeometry.Cylinders.QuadPart = DiskSize / (512 * 63 * 16); // set offset and size Mount.ImageOffset = ImageOffset; Mount.ImageSize = DiskSize;...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 28 Win32 vezérlő alkalmazás – VDCONF 3... // partition info Mount.PartInfo.PartitionStyle = PARTITION_STYLE_MBR; Mount.PartInfo.StartingOffset.QuadPart = 0; Mount.PartInfo.PartitionLength.QuadPart = DiskSize; Mount.PartInfo.PartitionNumber = (ULONG)(-1L); Mount.PartInfo.RewritePartition = FALSE; Mount.PartInfo.Mbr.RecognizedPartition = FALSE; // not recognized partition // mount as a read-write disk Mount.ReadOnly = FALSE; Mount.CdRom = FALSE; // mount image if (DeviceIoControl(Device, IOCTL_DRV_MOUNT_IMAGE, &Mount, sizeof(MOUNT_IMAGE), &Mount, sizeof(MOUNT_IMAGE), &ret, NULL)) { printf("image successfully mounted\n"); } else { printf("can't mount image, error: %d\n", GetLastError()); } // close vdisk driver CloseHandle(Device); return Mount.Status; }
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 29 DEMO...
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 30 Mi hiányzik? Plug&Play és Power Management +75% a forráskódra van rá jó példa a Microsoft RamDisk driver-ben valódi volume unmount flush a lemezegységekre FSCTL_DISMOUNT_VOLUME DeviceTree-vel követhető, hogy a most implementált unmount esetén a device objektum megmarad csak letörli a szimbolikus linket és felszabadítja az IMAGE struktúrát CD és DVD képek esetén több session támogatása (több track) több partíciós merevlemez képek támogatása
2006BBTE, Alkalmazások és operációs rendszerek optimizálása 31 Köszönöm a figyelmet!