windows nt driverek fejlesztése: virtuális lemezegység driver

31
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 10 2006

Upload: halla-rodriquez

Post on 04-Jan-2016

19 views

Category:

Documents


3 download

DESCRIPTION

Windows NT driverek fejlesztése: Virtuális lemezegység driver. 10. előadás dr. Robu Judit szeminárium drd. Lukács Sándor. 2006. 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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

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 Juditszeminárium

drd. Lukács Sándor

10

2006

Page 2: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

2A 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

Page 3: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

3A 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

Page 4: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

WIN32, ALKALMAZÁSOK

VDISK driverDRV DEVOBJ VOL DEVOBJ VOL DEVOBJ

dev ext, IMAGE dev ext, IMAGEdev ext

VDCONF

MOUNT kérés

NTFS, FASTFAT stb.VOL DEVOBJ

dev ext

merevlemez

IMGISO

IRP_MJ_READIRP_MJ_WRITE

ZwReadFile ZwWriteFile

Page 5: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

5Image 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;

Page 6: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

6Image 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;

Page 7: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

7Globá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;

Page 8: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

8DriverEntry 1

// initialize the dispatch entry pointsDriverObject->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 objectRtlInitUnicodeString(&(DrvGlobalData.DeviceName), DEVICE_NAME);

Status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), &DrvGlobalData.DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DrvGlobalData.DeviceObject );

Page 9: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

9DriverEntry 2

DevExt = (PDEVICE_EXTENSION)DrvGlobalData.DeviceObject->DeviceExtension;

DevExt->DeviceObject = DrvGlobalData.DeviceObject;

// no image is mounted yetDrvGlobalData.DevCounter = 0;DrvGlobalData.MountedCount = 0;DrvGlobalData.DevNumber = 0x1000;...

// create symbolic linkRtlInitUnicodeString(&(DrvGlobalData.DosDeviceName), L"\\dosdevices\\vdiskdev");if (NT_SUCCESS(IoCreateSymbolicLink(&(DrvGlobalData.DosDeviceName), &DrvGlobalData.DeviceName))){ ExKdPrint((" DriverEntry - symbolic link %S created\n", DrvGlobalData.DosDeviceName.Buffer));}

Page 10: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

10IRP_MJ_CREATE

// request to open the deviceif (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; }}

Page 11: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

11IRP_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;...

Page 12: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

12IRP_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;...

Page 13: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

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; }

Page 14: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

14IOCTL_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; }

Page 15: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

15IOCTL_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; }

Page 16: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

16IOCTL_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; }

Page 17: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

17A 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;

Page 18: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

18IOCTL_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);...

Page 19: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

19IOCTL_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);...

Page 20: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

20IOCTL_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);...

Page 21: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

21IOCTL_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));...

Page 22: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

22IOCTL_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; } }

Page 23: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

23IRP_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;...

Page 24: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

24IRP_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...

Page 25: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

25IRP_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;}

Page 26: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

26Win32 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; }...

Page 27: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

27Win32 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;...

Page 28: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

28Win32 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;}

Page 29: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

29DEMO...

Page 30: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

30Mi 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

Page 31: Windows NT  driverek fejlesztése: Virtuális lemezegység driver

2006BBTE, Alkalmazások és operációs rendszerek optimizálása

31

Köszönöm a figyelmet!