From 7b6651a9e147b915eee98bbedb58165a67f6af4c Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Fri, 23 Apr 2004 21:36:22 +0000
Subject: [PATCH] Moved creation of the CDROM registry keys into the registry
 loading code.

---
 dlls/ntdll/cdrom.c    | 144 +----------------------------------
 dlls/ntdll/ntdll.spec |   1 -
 files/drive.c         |  12 ---
 misc/registry.c       | 173 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 174 insertions(+), 156 deletions(-)

diff --git a/dlls/ntdll/cdrom.c b/dlls/ntdll/cdrom.c
index 1d6ca236af0..59dcedfff3c 100644
--- a/dlls/ntdll/cdrom.c
+++ b/dlls/ntdll/cdrom.c
@@ -377,8 +377,6 @@ static void CDROM_ClearCacheEntry(int dev)
  * number of the device on that interface for ide cdroms (*port == 0).
  * Determines the scsi information for scsi cdroms (*port >= 1).
  * Returns false if the info cannot not be obtained.
- *
- * NOTE: this function is used in CDROM_InitRegistry and CDROM_GetAddress
  */
 static int CDROM_GetInterfaceInfo(int fd, int* port, int* iface, int* device,int* lun)
 {
@@ -421,8 +419,7 @@ static int CDROM_GetInterfaceInfo(int fd, int* port, int* iface, int* device,int
         else
 #endif
         {
-            FIXME("CD-ROM device (%d, %d) not supported\n",
-                  major(st.st_rdev), minor(st.st_rdev));
+            WARN("CD-ROM device (%d, %d) not supported\n", major(st.st_rdev), minor(st.st_rdev));
             return 0;
         }
     }
@@ -457,143 +454,6 @@ static int CDROM_GetInterfaceInfo(int fd, int* port, int* iface, int* device,int
 }
 
 
-/******************************************************************
- *		CDROM_InitRegistry
- *
- * Initializes registry to contain scsi info about the cdrom in NT.
- * All devices (even not real scsi ones) have this info in NT.
- * TODO: for now it only works for non scsi devices
- * NOTE: programs usually read these registry entries after sending the
- *       IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
- */
-void CDROM_InitRegistry(int fd)
-{
-    int portnum, busid, targetid, lun;
-    OBJECT_ATTRIBUTES attr;
-    UNICODE_STRING nameW;
-    WCHAR dataW[50];
-    DWORD lenW;
-    char buffer[40];
-    DWORD value;
-    const char *data;
-    HKEY scsiKey;
-    HKEY portKey;
-    HKEY busKey;
-    HKEY targetKey;
-    DWORD disp;
-
-    attr.Length = sizeof(attr);
-    attr.RootDirectory = 0;
-    attr.ObjectName = &nameW;
-    attr.Attributes = 0;
-    attr.SecurityDescriptor = NULL;
-    attr.SecurityQualityOfService = NULL;
-
-    if (!CDROM_GetInterfaceInfo(fd, &portnum, &busid, &targetid, &lun))
-        return;
-
-    /* Ensure there is Scsi key */
-    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) ||
-        NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0,
-                     NULL, REG_OPTION_VOLATILE, &disp ))
-    {
-        ERR("Cannot create DEVICEMAP\\Scsi registry key\n" );
-        return;
-    }
-    RtlFreeUnicodeString( &nameW );
-
-    snprintf(buffer,sizeof(buffer),"Scsi Port %d",portnum);
-    attr.RootDirectory = scsiKey;
-    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
-        NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0,
-                     NULL, REG_OPTION_VOLATILE, &disp ))
-    {
-        ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" );
-        return;
-    }
-    RtlFreeUnicodeString( &nameW );
-
-    RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" );
-    data = "atapi";
-    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
-    NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
-    RtlFreeUnicodeString( &nameW );
-    value = 10;
-    RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" );
-    NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
-    RtlFreeUnicodeString( &nameW );
-    value = 0;
-#ifdef HDIO_GET_DMA
-    {
-        int dma;
-        if (ioctl(fd,HDIO_GET_DMA, &dma) != -1) {
-            value = dma;
-            TRACE("setting dma to %lx\n", value);
-        }
-    }
-#endif
-    RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" );
-    NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
-    RtlFreeUnicodeString( &nameW );
-
-    snprintf(buffer,40,"Scsi Bus %d", busid);
-    attr.RootDirectory = portKey;
-    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
-        NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0,
-                     NULL, REG_OPTION_VOLATILE, &disp ))
-    {
-        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" );
-        return;
-    }
-    RtlFreeUnicodeString( &nameW );
-
-    attr.RootDirectory = busKey;
-    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) ||
-        NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
-                     NULL, REG_OPTION_VOLATILE, &disp ))
-    {
-        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" );
-        return;
-    }
-    RtlFreeUnicodeString( &nameW );
-    NtClose( targetKey );
-
-    snprintf(buffer,40,"Target Id %d", targetid);
-    attr.RootDirectory = busKey;
-    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
-        NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
-                     NULL, REG_OPTION_VOLATILE, &disp ))
-    {
-        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" );
-        return;
-    }
-    RtlFreeUnicodeString( &nameW );
-
-    RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
-    data = "CdRomPeripheral";
-    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
-    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
-    RtlFreeUnicodeString( &nameW );
-    /* FIXME - maybe read the real identifier?? */
-    RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" );
-    data = "Wine CDROM";
-    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
-    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
-    RtlFreeUnicodeString( &nameW );
-    /* FIXME - we always use Cdrom0 - do not know about the nt behaviour */
-    RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
-    data = "Cdrom0";
-    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
-    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
-    RtlFreeUnicodeString( &nameW );
-
-    NtClose( targetKey );
-    NtClose( busKey );
-    NtClose( portKey );
-    NtClose( scsiKey );
-}
-
-
 /******************************************************************
  *		CDROM_Open
  *
@@ -1721,7 +1581,7 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
 
     piosb->Information = 0;
 
-    if ((status = wine_server_handle_to_fd( hDevice, GENERIC_READ, &fd, NULL, NULL ))) goto error;
+    if ((status = wine_server_handle_to_fd( hDevice, 0, &fd, NULL, NULL ))) goto error;
     if ((status = CDROM_Open(fd, &dev)))
     {
         wine_server_release_fd( hDevice, fd );
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 364c872e163..a1f72a7bcfc 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1129,7 +1129,6 @@
 ################################################################
 # Wine dll separation hacks, these will go away, don't use them
 #
-@ cdecl CDROM_InitRegistry(long)
 @ cdecl MODULE_DllThreadAttach(ptr)
 @ cdecl MODULE_GetLoadOrderW(ptr wstr wstr)
 @ cdecl VERSION_Init(wstr)
diff --git a/files/drive.c b/files/drive.c
index f532dd71cfb..025f289206a 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -100,8 +100,6 @@ inline static char *heap_strdup( const char *str )
     return p;
 }
 
-extern void CDROM_InitRegistry(int dev);
-
 /***********************************************************************
  *           DRIVE_GetDriveType
  */
@@ -270,16 +268,6 @@ int DRIVE_Init(void)
                 len = WideCharToMultiByte(CP_UNIXCP, 0, data, -1, NULL, 0, NULL, NULL);
                 drive->device = HeapAlloc(GetProcessHeap(), 0, len);
                 WideCharToMultiByte(CP_UNIXCP, 0, data, -1, drive->device, len, NULL, NULL);
-
-                if (drive->type == DRIVE_CDROM)
-                {
-                    int cd_fd;
-                    if ((cd_fd = open(drive->device, O_RDONLY|O_NONBLOCK)) != -1)
-                    {
-                        CDROM_InitRegistry(cd_fd);
-                        close(cd_fd);
-                    }
-                }
             }
 
             /* Make the first hard disk the current drive */
diff --git a/misc/registry.c b/misc/registry.c
index 18c675791b9..3835bf93b4f 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -50,6 +50,12 @@
 #ifdef HAVE_SYS_MMAN_H
 # include <sys/mman.h>
 #endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_LINUX_HDREG_H
+# include <linux/hdreg.h>
+#endif
 
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
@@ -57,6 +63,8 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
+#include "winioctl.h"
+#include "ntddscsi.h"
 
 #include "wine/winbase16.h"
 #include "wine/library.h"
@@ -1213,7 +1221,7 @@ static void load_wine_registry(HKEY hkey,LPCSTR fn)
 
     attr.Length = sizeof(attr);
     attr.RootDirectory = 0;
-    attr.Attributes = OBJ_CASE_INSENSITIVE;
+    attr.Attributes = 0;
     attr.ObjectName = &name;
     attr.SecurityDescriptor = NULL;
     attr.SecurityQualityOfService = NULL;
@@ -1666,6 +1674,165 @@ static void _load_home_registry( HKEY hkey_local_machine, HKEY hkey_current_user
 }
 
 
+/******************************************************************
+ *		init_cdrom_registry
+ *
+ * Initializes registry to contain scsi info about the cdrom in NT.
+ * All devices (even not real scsi ones) have this info in NT.
+ * TODO: for now it only works for non scsi devices
+ * NOTE: programs usually read these registry entries after sending the
+ *       IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
+ */
+static void init_cdrom_registry( HANDLE handle )
+{
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING nameW;
+    WCHAR dataW[50];
+    DWORD lenW;
+    char buffer[40];
+    DWORD value;
+    const char *data;
+    HKEY scsiKey;
+    HKEY portKey;
+    HKEY busKey;
+    HKEY targetKey;
+    DWORD disp;
+    IO_STATUS_BLOCK io;
+    SCSI_ADDRESS scsi_addr;
+
+    if (NtDeviceIoControlFile( handle, 0, NULL, NULL, &io, IOCTL_SCSI_GET_ADDRESS,
+                               NULL, 0, &scsi_addr, sizeof(scsi_addr) ))
+        return;
+
+    attr.Length = sizeof(attr);
+    attr.RootDirectory = 0;
+    attr.ObjectName = &nameW;
+    attr.Attributes = 0;
+    attr.SecurityDescriptor = NULL;
+    attr.SecurityQualityOfService = NULL;
+
+    /* Ensure there is Scsi key */
+    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) ||
+        NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0,
+                     NULL, REG_OPTION_VOLATILE, &disp ))
+    {
+        ERR("Cannot create DEVICEMAP\\Scsi registry key\n" );
+        return;
+    }
+    RtlFreeUnicodeString( &nameW );
+
+    snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr.PortNumber);
+    attr.RootDirectory = scsiKey;
+    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
+        NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0,
+                     NULL, REG_OPTION_VOLATILE, &disp ))
+    {
+        ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" );
+        return;
+    }
+    RtlFreeUnicodeString( &nameW );
+
+    RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" );
+    data = "atapi";
+    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
+    NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
+    RtlFreeUnicodeString( &nameW );
+    value = 10;
+    RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" );
+    NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
+    RtlFreeUnicodeString( &nameW );
+    value = 0;
+#ifdef HDIO_GET_DMA
+    {
+        int fd, dma;
+        if (!wine_server_handle_to_fd( handle, 0, &fd, NULL, NULL ))
+        {
+            if (ioctl(fd,HDIO_GET_DMA, &dma) != -1) value = dma;
+            wine_server_release_fd( handle, fd );
+        }
+    }
+#endif
+    RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" );
+    NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
+    RtlFreeUnicodeString( &nameW );
+
+    snprintf(buffer,40,"Scsi Bus %d", scsi_addr.PathId);
+    attr.RootDirectory = portKey;
+    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
+        NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0,
+                     NULL, REG_OPTION_VOLATILE, &disp ))
+    {
+        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" );
+        return;
+    }
+    RtlFreeUnicodeString( &nameW );
+
+    attr.RootDirectory = busKey;
+    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) ||
+        NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
+                     NULL, REG_OPTION_VOLATILE, &disp ))
+    {
+        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" );
+        return;
+    }
+    RtlFreeUnicodeString( &nameW );
+    NtClose( targetKey );
+
+    snprintf(buffer,40,"Target Id %d", scsi_addr.TargetId);
+    attr.RootDirectory = busKey;
+    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
+        NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
+                     NULL, REG_OPTION_VOLATILE, &disp ))
+    {
+        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" );
+        return;
+    }
+    RtlFreeUnicodeString( &nameW );
+
+    RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
+    data = "CdRomPeripheral";
+    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
+    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
+    RtlFreeUnicodeString( &nameW );
+    /* FIXME - maybe read the real identifier?? */
+    RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" );
+    data = "Wine CDROM";
+    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
+    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
+    RtlFreeUnicodeString( &nameW );
+    /* FIXME - we always use Cdrom0 - do not know about the nt behaviour */
+    RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
+    data = "Cdrom0";
+    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
+    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
+    RtlFreeUnicodeString( &nameW );
+
+    NtClose( targetKey );
+    NtClose( busKey );
+    NtClose( portKey );
+    NtClose( scsiKey );
+}
+
+
+/* create the hardware registry branch */
+static void create_hardware_branch(void)
+{
+    int i;
+    HANDLE handle;
+    char drive[] = "\\\\.\\A:";
+
+    /* create entries for cdroms */
+    for (i = 0; i < 26; i++)
+    {
+        drive[4] = 'A' + i;
+        handle = CreateFileA( drive, 0, 0, NULL, OPEN_EXISTING, 0, 0 );
+        if (handle == INVALID_HANDLE_VALUE) continue;
+        init_cdrom_registry( handle );
+        CloseHandle( handle );
+    }
+}
+
+
 /* load all registry (native and global and home) */
 void SHELL_LoadRegistry( void )
 {
@@ -1794,6 +1961,10 @@ void SHELL_LoadRegistry( void )
     }
     if (res) _load_home_registry( hkey_local_machine, hkey_current_user, hkey_users_default );
 
+    /* create hardware registry branch */
+
+    create_hardware_branch();
+
     /* setup registry saving */
 
     all = FALSE;
-- 
GitLab