[Wine-patches] [eterhack] mountmgr.sys: Partially implement reading harddisk volume (eterbug #6942).

Alexander Morozov amorozov на etersoft.ru
Вт Мар 15 17:44:13 MSK 2011


----------- следующая часть -----------
From 7c74855559aad38904bca9c7d9a6bb1015aa0775 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 15 Mar 2011 15:06:22 +0300
Subject: [eterhack 1/2] mountmgr.sys: Partially implement reading harddisk volume (eterbug #6942).

---
 dlls/mountmgr.sys/device.c |   78 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 59cc68d..5393441 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -24,6 +24,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdarg.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -1006,6 +1007,82 @@ NTSTATUS query_dos_device( int letter, enum device_type *type, char **device, ch
     return status;
 }
 
+/* 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 = IoGetCurrentIrpStackLocation( irp );
+    struct disk_device *dev = 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 );
+
+    EnterCriticalSection( &device_section );
+
+    switch (dev->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( dev->unix_mount, serial );
+        irp->IoStatus.Information = len;
+        break;
+    }
+    default:
+        FIXME( "unsupported device type %u\n", dev->type );
+        status = STATUS_NOT_IMPLEMENTED;
+    }
+
+    LeaveCriticalSection( &device_section );
+    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 )
 {
@@ -1134,6 +1211,7 @@ NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *pa
     struct disk_device *device;
 
     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 */
-- 
1.7.4.1



Подробная информация о списке рассылки Wine-patches