From 7f44319909809d8f9532611855d8e532438c584e Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Tue, 15 Mar 2011 15:06:22 +0300 Subject: [PATCH] mountmgr.sys: Partially implement reading harddisk volume (eterbug #6942). --- dlls/mountmgr.sys/device.c | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index 1119008706..838b696647 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -752,6 +753,78 @@ NTSTATUS query_dos_device( int letter, enum device_type *type, return STATUS_NO_SUCH_DEVICE; } +/* get the volume serial number from .windows-serial */ +static NTSTATUS get_serial( const char *unix_mount, DWORD *serial ) +{ + static const char windows_serial[] = "/.windows-serial"; + + NTSTATUS status = STATUS_UNSUCCESSFUL; + char buf[17]; + char *path; + int fd, len; + + path = RtlAllocateHeap( GetProcessHeap(), 0, + strlen(unix_mount) + sizeof(windows_serial) ); + if (!path) + return STATUS_NO_MEMORY; + + strcpy( path, unix_mount ); + strcat( path, windows_serial ); + + fd = open( path, O_RDONLY ); + if (fd >= 0) + { + len = read( fd, buf, sizeof(buf) - 1 ); + buf[len] = 0; + *serial = strtoul( buf, NULL, 16 ); + close( fd ); + status = STATUS_SUCCESS; + } + RtlFreeHeap( GetProcessHeap(), 0, path ); + return status; +} + +/* handler for reading the harddisk device */ +static NTSTATUS WINAPI harddisk_read( DEVICE_OBJECT *device, IRP *irp ) +{ + static const char ntfs[] = "NTFS "; + + IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation; + struct dos_drive *drive = device->DeviceExtension; + NTSTATUS status; + DWORD len = irpsp->Parameters.Read.Length; + LARGE_INTEGER offset = irpsp->Parameters.Read.ByteOffset; + char *buf = irp->UserBuffer; + + TRACE( "len %u offset %x%08x\n", len, offset.u.HighPart, offset.u.LowPart ); + + switch (drive->type) + { + case DEVICE_HARDDISK_VOL: + { + DWORD *serial = (DWORD *)(buf + 0x48); + + if (len != 512 || offset.QuadPart) + { + FIXME( "reading first 512 bytes is implemented only\n" ); + break; + } + memset( buf, 0, len ); + memcpy( buf + 3, ntfs, strlen(ntfs) ); + buf[0x40] = 0xf6; /* eterbug #6942 */ + status = get_serial( drive->unix_mount, serial ); + irp->IoStatus.Information = len; + break; + } + default: + FIXME( "unsupported device type %u\n", drive->type ); + status = STATUS_NOT_IMPLEMENTED; + } + irp->IoStatus.u.Status = status; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return status; +} + /* handler for ioctls on the harddisk device */ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp ) { @@ -866,6 +939,7 @@ NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *pa struct dos_drive *drive; harddisk_driver = driver; + driver->MajorFunction[IRP_MJ_READ] = harddisk_read; driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = harddisk_ioctl; /* create a harddisk0 device that isn't assigned to any drive */ -- 2.33.8