ntdll / kernel32: #43

Eric Pouech pouech-eric at wanadoo.fr
Wed Feb 4 14:55:16 CST 2004


Changes for device & VxD management (kernel)
- remove server/device.c and all the associated hacks
- opening a device is now implemented as opening a unix file
   (either a real unix device, or an empty file for VxDs & TSRs)

Notes: server/device.c has to be removed
-------------- next part --------------
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel42/device.c dlls/kernel/device.c
--- dlls/kernel42/device.c	2004-01-16 19:58:25.000000000 +0100
+++ dlls/kernel/device.c	2004-01-18 21:11:05.000000000 +0100
@@ -24,6 +24,7 @@
 #include "wine/port.h"
 
 #include <stdlib.h>
+#include <stdio.h>
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
@@ -40,19 +41,23 @@
 #include <string.h>
 #include <stdarg.h>
 #include <time.h>
+#include <dirent.h>
 
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
 #include "ntstatus.h"
 #include "windef.h"
 #include "winbase.h"
 #include "winreg.h"
 #include "winerror.h"
 #include "winnls.h"
-#include "file.h"
 #include "winioctl.h"
 #include "winnt.h"
 #include "iphlpapi.h"
+#include "wine/winbase16.h"
 #include "kernel_private.h"
 #include "wine/server.h"
+#include "wine/library.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(file);
@@ -132,190 +137,182 @@
 struct VxDInfo
 {
     LPCSTR  name;
-    WORD    id;
     BOOL  (*deviceio)(DWORD, LPVOID, DWORD,
-                        LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
+                      LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
 };
 
 static const struct VxDInfo VxDList[] =
 {
     /* Standard VxD IDs */
-    { "VMM",      0x0001, NULL },
-    { "DEBUG",    0x0002, NULL },
-    { "VPICD",    0x0003, NULL },
-    { "VDMAD",    0x0004, NULL },
-    { "VTD",      0x0005, NULL },
-    { "V86MMGR",  0x0006, NULL },
-    { "PAGESWAP", 0x0007, NULL },
-    { "PARITY",   0x0008, NULL },
-    { "REBOOT",   0x0009, NULL },
-    { "VDD",      0x000A, NULL },
-    { "VSD",      0x000B, NULL },
-    { "VMD",      0x000C, NULL },
-    { "VKD",      0x000D, NULL },
-    { "VCD",      0x000E, DeviceIo_VCD },
-    { "VPD",      0x000F, NULL },
-    { "BLOCKDEV", 0x0010, NULL },
-    { "VMCPD",    0x0011, NULL },
-    { "EBIOS",    0x0012, NULL },
-    { "BIOSXLAT", 0x0013, NULL },
-    { "VNETBIOS", 0x0014, DeviceIo_NetBIOS },
-    { "DOSMGR",   0x0015, NULL },
-    { "WINLOAD",  0x0016, NULL },
-    { "SHELL",    0x0017, NULL },
-    { "VMPOLL",   0x0018, NULL },
-    { "VPROD",    0x0019, NULL },
-    { "DOSNET",   0x001A, NULL },
-    { "VFD",      0x001B, NULL },
-    { "VDD2",     0x001C, NULL },
-    { "WINDEBUG", 0x001D, NULL },
-    { "TSRLOAD",  0x001E, NULL },
-    { "BIOSHOOK", 0x001F, NULL },
-    { "INT13",    0x0020, NULL },
-    { "PAGEFILE", 0x0021, NULL },
-    { "SCSI",     0x0022, NULL },
-    { "MCA_POS",  0x0023, NULL },
-    { "SCSIFD",   0x0024, NULL },
-    { "VPEND",    0x0025, NULL },
-    { "VPOWERD",  0x0026, NULL },
-    { "VXDLDR",   0x0027, NULL },
-    { "NDIS",     0x0028, NULL },
-    { "BIOS_EXT", 0x0029, NULL },
-    { "VWIN32",   0x002A, DeviceIo_VWin32 },
-    { "VCOMM",    0x002B, NULL },
-    { "SPOOLER",  0x002C, NULL },
-    { "WIN32S",   0x002D, NULL },
-    { "DEBUGCMD", 0x002E, NULL },
-
-    { "VNB",      0x0031, DeviceIo_VNB },
-    { "SERVER",   0x0032, NULL },
-    { "CONFIGMG", 0x0033, NULL },
-    { "DWCFGMG",  0x0034, NULL },
-    { "SCSIPORT", 0x0035, NULL },
-    { "VFBACKUP", 0x0036, NULL },
-    { "ENABLE",   0x0037, NULL },
-    { "VCOND",    0x0038, NULL },
-
-    { "EFAX",     0x003A, NULL },
-    { "DSVXD",    0x003B, NULL },
-    { "ISAPNP",   0x003C, NULL },
-    { "BIOS",     0x003D, NULL },
-    { "WINSOCK",  0x003E, NULL },
-    { "WSOCK",    0x003E, NULL },
-    { "WSIPX",    0x003F, NULL },
-    { "IFSMgr",   0x0040, DeviceIo_IFSMgr },
-    { "VCDFSD",   0x0041, NULL },
-    { "MRCI2",    0x0042, NULL },
-    { "PCI",      0x0043, NULL },
-    { "PELOADER", 0x0044, NULL },
-    { "EISA",     0x0045, NULL },
-    { "DRAGCLI",  0x0046, NULL },
-    { "DRAGSRV",  0x0047, NULL },
-    { "PERF",     0x0048, NULL },
-    { "AWREDIR",  0x0049, NULL },
-
+    { "VMM",      NULL },
+    { "DEBUG",    NULL },
+    { "VPICD",    NULL },
+    { "VDMAD",    NULL },
+    { "VTD",      NULL },
+    { "V86MMGR",  NULL },
+    { "PAGESWAP", NULL },
+    { "PARITY",   NULL },
+    { "REBOOT",   NULL },
+    { "VDD",      NULL },
+    { "VSD",      NULL },
+    { "VMD",      NULL },
+    { "VKD",      NULL },
+    { "VCD",      DeviceIo_VCD },
+    { "VPD",      NULL },
+    { "BLOCKDEV", NULL },
+    { "VMCPD",    NULL },
+    { "EBIOS",    NULL },
+    { "BIOSXLAT", NULL },
+    { "VNETBIOS", DeviceIo_NetBIOS },
+    { "DOSMGR",   NULL },
+    { "WINLOAD",  NULL },
+    { "SHELL",    NULL },
+    { "VMPOLL",   NULL },
+    { "VPROD",    NULL },
+    { "DOSNET",   NULL },
+    { "VFD",      NULL },
+    { "VDD2",     NULL },
+    { "WINDEBUG", NULL },
+    { "TSRLOAD",  NULL },
+    { "BIOSHOOK", NULL },
+    { "INT13",    NULL },
+    { "PAGEFILE", NULL },
+    { "SCSI",     NULL },
+    { "MCA_POS",  NULL },
+    { "SCSIFD",   NULL },
+    { "VPEND",    NULL },
+    { "VPOWERD",  NULL },
+    { "VXDLDR",   NULL },
+    { "NDIS",     NULL },
+    { "BIOS_EXT", NULL },
+    { "VWIN32",   DeviceIo_VWin32 },
+    { "VCOMM",    NULL },
+    { "SPOOLER",  NULL },
+    { "WIN32S",   NULL },
+    { "DEBUGCMD", NULL },
+
+    { "VNB",      DeviceIo_VNB },
+    { "SERVER",   NULL },
+    { "CONFIGMG", NULL },
+    { "DWCFGMG",  NULL },
+    { "SCSIPORT", NULL },
+    { "VFBACKUP", NULL },
+    { "ENABLE",   NULL },
+    { "VCOND",    NULL },
+
+    { "EFAX",     NULL },
+    { "DSVXD",    NULL },
+    { "ISAPNP",   NULL },
+    { "BIOS",     NULL },
+    { "WINSOCK",  NULL },
+    { "WSOCK",    NULL },
+    { "WSIPX",    NULL },
+    { "IFSMgr",   DeviceIo_IFSMgr },
+    { "VCDFSD",   NULL },
+    { "MRCI2",    NULL },
+    { "PCI",      NULL },
+    { "PELOADER", NULL },
+    { "EISA",     NULL },
+    { "DRAGCLI",  NULL },
+    { "DRAGSRV",  NULL },
+    { "PERF",     NULL },
+    { "AWREDIR",  NULL },
+    
     /* Far East support */
-    { "ETEN",     0x0060, NULL },
-    { "CHBIOS",   0x0061, NULL },
-    { "VMSGD",    0x0062, NULL },
-    { "VPPID",    0x0063, NULL },
-    { "VIME",     0x0064, NULL },
-    { "VHBIOSD",  0x0065, NULL },
+    { "ETEN",     NULL },
+    { "CHBIOS",   NULL },
+    { "VMSGD",    NULL },
+    { "VPPID",    NULL },
+    { "VIME",     NULL },
+    { "VHBIOSD",  NULL },
 
     /* Multimedia OEM IDs */
-    { "VTDAPI",   0x0442, DeviceIo_VTDAPI },
-    { "MMDEVLDR", 0x044A, DeviceIo_MMDEVLDR },
+    { "VTDAPI",   DeviceIo_VTDAPI },
+    { "MMDEVLDR", DeviceIo_MMDEVLDR },
 
     /* Network Device IDs */
-    { "VNetSup",  0x0480, NULL },
-    { "VRedir",   0x0481, NULL },
-    { "VBrowse",  0x0482, NULL },
-    { "VSHARE",   0x0483, NULL },
-    { "IFSMgr",   0x0484, NULL },
-    { "MEMPROBE", 0x0485, NULL },
-    { "VFAT",     0x0486, NULL },
-    { "NWLINK",   0x0487, NULL },
-    { "VNWLINK",  0x0487, NULL },
-    { "NWSUP",    0x0487, NULL },
-    { "VTDI",     0x0488, NULL },
-    { "VIP",      0x0489, NULL },
-    { "VTCP",     0x048A, NULL },
-    { "VCache",   0x048B, NULL },
-    { "VUDP",     0x048C, NULL },
-    { "VAsync",   0x048D, NULL },
-    { "NWREDIR",  0x048E, NULL },
-    { "STAT80",   0x048F, NULL },
-    { "SCSIPORT", 0x0490, NULL },
-    { "FILESEC",  0x0491, NULL },
-    { "NWSERVER", 0x0492, NULL },
-    { "SECPROV",  0x0493, NULL },
-    { "NSCL",     0x0494, NULL },
-    { "WSTCP",    0x0495, NULL },
-    { "NDIS2SUP", 0x0496, NULL },
-    { "MSODISUP", 0x0497, NULL },
-    { "Splitter", 0x0498, NULL },
-    { "PPP",      0x0499, NULL },
-    { "VDHCP",    0x049A, DeviceIo_DHCP },
-    { "VNBT",     0x049B, NULL },
-    { "LOGGER",   0x049D, NULL },
-    { "EFILTER",  0x049E, NULL },
-    { "FFILTER",  0x049F, NULL },
-    { "TFILTER",  0x04A0, NULL },
-    { "AFILTER",  0x04A1, NULL },
-    { "IRLAMP",   0x04A2, NULL },
-
-    { "PCCARD",   0x097C, DeviceIo_PCCARD },
-    { "HASP95",   0x3721, DeviceIo_HASP },
+    { "VNetSup",  NULL },
+    { "VRedir",   NULL },
+    { "VBrowse",  NULL },
+    { "VSHARE",   NULL },
+    { "IFSMgr",   NULL },
+    { "MEMPROBE", NULL },
+    { "VFAT",     NULL },
+    { "NWLINK",   NULL },
+    { "VNWLINK",  NULL },
+    { "NWSUP",    NULL },
+    { "VTDI",     NULL },
+    { "VIP",      NULL },
+    { "VTCP",     NULL },
+    { "VCache",   NULL },
+    { "VUDP",     NULL },
+    { "VAsync",   NULL },
+    { "NWREDIR",  NULL },
+    { "STAT80",   NULL },
+    { "SCSIPORT", NULL },
+    { "FILESEC",  NULL },
+    { "NWSERVER", NULL },
+    { "SECPROV",  NULL },
+    { "NSCL",     NULL },
+    { "WSTCP",    NULL },
+    { "NDIS2SUP", NULL },
+    { "MSODISUP", NULL },
+    { "Splitter", NULL },
+    { "PPP",      NULL },
+    { "VDHCP",    DeviceIo_DHCP },
+    { "VNBT",     NULL },
+    { "LOGGER",   NULL },
+    { "EFILTER",  NULL },
+    { "FFILTER",  NULL },
+    { "TFILTER",  NULL },
+    { "AFILTER",  NULL },
+    { "IRLAMP",   NULL },
+    
+    
+    { "PCCARD",   DeviceIo_PCCARD },
+    { "HASP95",   DeviceIo_HASP },
 
     /* WINE additions, ids unknown */
-    { "MONODEBG.VXD", 0x4242, DeviceIo_MONODEBG },
+    { "MONODEBG.VXD", DeviceIo_MONODEBG },
 
-    { NULL,       0,      NULL }
+    { NULL,       NULL }
 };
 
-HANDLE DEVICE_Open( LPCWSTR filenameW, DWORD access, LPSECURITY_ATTRIBUTES sa )
+static  const struct VxDInfo* lookup_vxd(HANDLE hDevice)
 {
-    const struct VxDInfo *info;
-    char filename[MAX_PATH];
-
-    if (!WideCharToMultiByte(CP_ACP, 0, filenameW, -1, filename, MAX_PATH, NULL, NULL))
-    {
-        SetLastError( ERROR_FILE_NOT_FOUND );
-        return 0;
-    }
-
-    for (info = VxDList; info->name; info++)
-        if (!strncasecmp( info->name, filename, strlen(info->name) ))
-            return FILE_CreateDevice( info->id | 0x10000, access, sa );
-
-    FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n",
-           filename);
-
-    SetLastError( ERROR_FILE_NOT_FOUND );
-    return 0;
-}
-
-static DWORD DEVICE_GetClientID( HANDLE handle )
-{
-    DWORD       ret = 0;
-    SERVER_START_REQ( get_device_id )
-    {
-        req->handle = handle;
-        if (!wine_server_call( req )) ret = reply->id;
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-static const struct VxDInfo *DEVICE_GetInfo( DWORD clientID )
-{
-    const struct VxDInfo *info = NULL;
-
-    if (clientID & 0x10000)
-    {
-        for (info = VxDList; info->name; info++)
-            if (info->id == LOWORD(clientID)) break;
+    struct stat         st_ref, st;
+    int                 fd;
+    char                p[MAX_PATH], *l;
+    DIR*                dir;
+    struct dirent*      de;
+    const struct VxDInfo*info = NULL;
+
+    wine_server_handle_to_fd( hDevice, GENERIC_READ, &fd, NULL, NULL );
+    if (fd == -1) return NULL;
+
+    if (fstat(fd, &st_ref) != -1)
+    {
+        sprintf(p, "%s/DosDevices/", wine_get_config_dir());
+        l = p + strlen(p);
+        dir = opendir(p);
+        if (dir)
+        {
+            while ((de = readdir(dir)))
+            {
+                strcpy(l, de->d_name);
+                if (stat(p, &st) != -1 && st.st_dev == st_ref.st_dev &&
+                    st.st_ino == st_ref.st_ino)
+                {
+                    for (info = VxDList; info->name; info++)
+                        if (!strcmp(info->name, de->d_name))
+                            break;
+                    break;
+                }
+            }
+            closedir(dir);
+        }
     }
+    close(fd);
     return info;
 }
 
@@ -329,78 +326,65 @@
  * GetLastError can decipher.
  */
 BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
-			      LPVOID lpvInBuffer, DWORD cbInBuffer,
-			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
-			      LPDWORD lpcbBytesReturned,
-			      LPOVERLAPPED lpOverlapped)
-{
-        DWORD clientID;
+                            LPVOID lpvInBuffer, DWORD cbInBuffer,
+                            LPVOID lpvOutBuffer, DWORD cbOutBuffer,
+                            LPDWORD lpcbBytesReturned, LPOVERLAPPED lpOverlapped)
+{
+    TRACE( "(%p,%ld,%p,%ld,%p,%ld,%p,%p)\n",
+           hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer,
+           lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped	);
 
-        TRACE( "(%p,%ld,%p,%ld,%p,%ld,%p,%p)\n",
-               hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer,
-               lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped	);
-
-	if (!(clientID = DEVICE_GetClientID( hDevice )))
-	{
-		SetLastError( ERROR_INVALID_PARAMETER );
-		return FALSE;
-	}
-
-	/* Check if this is a user defined control code for a VxD */
-	if( HIWORD( dwIoControlCode ) == 0 )
-	{
-                const struct VxDInfo *info;
-                if (!(info = DEVICE_GetInfo( clientID )))
-                {
-                        FIXME( "No device found for id %lx\n", clientID);
-                }
-                else if ( info->deviceio )
-		{
-			return info->deviceio( dwIoControlCode,
-                                        lpvInBuffer, cbInBuffer,
-                                        lpvOutBuffer, cbOutBuffer,
-                                        lpcbBytesReturned, lpOverlapped );
-		}
-		else
-		{
-			FIXME( "Unimplemented control %ld for VxD device %s\n",
-                               dwIoControlCode, info->name ? info->name : "???" );
-			/* FIXME: this is for invalid calls on W98SE,
-			 * but maybe we should use ERROR_CALL_NOT_IMPLEMENTED
-			 * instead ? */
-			SetLastError( ERROR_INVALID_FUNCTION );
-		}
-	}
-	else
-	{       
-            NTSTATUS            status;
-
-            if (lpOverlapped)
-            {
-                status = NtDeviceIoControlFile(hDevice, lpOverlapped->hEvent, 
-                                               NULL, NULL, 
-                                               (PIO_STATUS_BLOCK)lpOverlapped,
-                                               dwIoControlCode, 
-                                               lpvInBuffer, cbInBuffer,
-                                               lpvOutBuffer, cbOutBuffer);
-                if (status) SetLastError(RtlNtStatusToDosError(status));
-                if (lpcbBytesReturned) *lpcbBytesReturned = lpOverlapped->InternalHigh;
-                return !status;
-            }
-            else
-            {
-                IO_STATUS_BLOCK     iosb;
+    /* Check if this is a user defined control code for a VxD */
+    if ( HIWORD( dwIoControlCode ) == 0 )
+    {
+        const struct VxDInfo *info;
+        if (!(info = lookup_vxd(hDevice)))
+        {
+            FIXME( "No device found for hDevice %p\n", hDevice);
+            SetLastError( ERROR_FILE_NOT_FOUND );
+            return FALSE;
+        }
+        else if ( !info->deviceio )
+        {
+            FIXME( "Unimplemented ioproc for VxD device %s, control=%lx\n",
+                   info->name ? info->name : "???", dwIoControlCode );
+            /* FIXME: this is for invalid calls on W98SE,
+             * but maybe we should use ERROR_CALL_NOT_IMPLEMENTED
+             * instead ? */
+            SetLastError( ERROR_INVALID_FUNCTION );
+            return FALSE;
+        }
+        return info->deviceio( dwIoControlCode,
+                               lpvInBuffer, cbInBuffer,
+                               lpvOutBuffer, cbOutBuffer,
+                               lpcbBytesReturned, lpOverlapped );
+    }
+    if (lpOverlapped)
+    {
+        NTSTATUS            status;
+
+        status = NtDeviceIoControlFile(hDevice, lpOverlapped->hEvent, 
+                                       NULL, NULL, 
+                                       (PIO_STATUS_BLOCK)lpOverlapped,
+                                       dwIoControlCode, 
+                                       lpvInBuffer, cbInBuffer,
+                                       lpvOutBuffer, cbOutBuffer);
+        if (status) SetLastError(RtlNtStatusToDosError(status));
+        if (lpcbBytesReturned) *lpcbBytesReturned = lpOverlapped->InternalHigh;
+        return !status;
+    }
+    else
+    {
+        IO_STATUS_BLOCK     iosb;
 
-                status = NtDeviceIoControlFile(hDevice, NULL, NULL, NULL, &iosb,
-                                               dwIoControlCode, 
-                                               lpvInBuffer, cbInBuffer,
-                                               lpvOutBuffer, cbOutBuffer);
-                if (status) SetLastError(RtlNtStatusToDosError(status));
-                if (lpcbBytesReturned) *lpcbBytesReturned = iosb.Information;
-                return !status;
-            }
-	}
-   	return FALSE;
+        NtDeviceIoControlFile(hDevice, NULL, NULL, NULL, &iosb,
+                              dwIoControlCode, 
+                              lpvInBuffer, cbInBuffer,
+                              lpvOutBuffer, cbOutBuffer);
+        if (iosb.u.Status) SetLastError(RtlNtStatusToDosError(iosb.u.Status));
+        if (lpcbBytesReturned) *lpcbBytesReturned = iosb.Information;
+        return !iosb.u.Status;
+    }
 }
 
 /***********************************************************************
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel42/kernel32.spec dlls/kernel/kernel32.spec
--- dlls/kernel42/kernel32.spec	2004-02-01 14:10:48.000000000 +0100
+++ dlls/kernel/kernel32.spec	2004-02-01 14:27:38.000000000 +0100
@@ -1154,7 +1154,6 @@
 ################################################################
 # Wine dll separation hacks, these will go away, don't use them
 #
-@ cdecl DOSFS_GetDeviceByHandle(long)
 @ cdecl DOSMEM_AllocSelector(long)
 @ cdecl DOSMEM_Available()
 @ cdecl DOSMEM_FreeBlock(ptr)
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll42/cdrom.c dlls/ntdll/cdrom.c
--- dlls/ntdll42/cdrom.c	2004-01-23 22:21:08.000000000 +0100
+++ dlls/ntdll/cdrom.c	2004-02-02 22:01:27.000000000 +0100
@@ -2,7 +2,7 @@
 /* Main file for CD-ROM support
  *
  * Copyright 1994 Martin Ayotte
- * Copyright 1999, 2001,2003 Eric Pouech
+ * Copyright 1999, 2001, 2003 Eric Pouech
  * Copyright 2000 Andreas Mohr
  *
  * This library is free software; you can redistribute it and/or
@@ -83,6 +83,9 @@
 #include "ntddstor.h"
 #include "ntddcdrm.h"
 #include "ntddscsi.h"
+#include "ntdll_misc.h"
+#include "wine/server.h"
+#include "wine/library.h"
 #include "wine/debug.h"
 
 /* Non-Linux systems do not have linux/cdrom.h and the like, and thus
@@ -182,13 +185,20 @@
  * for toc inquiries.
  */
 struct cdrom_cache {
-    int fd;
-    int count;
-    char toc_good; /* if false, will reread TOC from disk */
-    CDROM_TOC toc;
+    int         fd;
+    HANDLE      hDevice;
+    dev_t       device;
+    ino_t       inode;
+    int         count;
+    char        toc_good; /* if false, will reread TOC from disk */
+    CDROM_TOC   toc;
     SUB_Q_CURRENT_POSITION CurrentPosition;
-    const char *device;
 };
+/* who has more than 5 cdroms on his/her machine ?? */
+/* FIXME: this should grow depending on the number of cdroms we install/configure 
+ * at startup
+ */
+#define MAX_CACHE_ENTRIES       5
 static struct cdrom_cache cdrom_cache[26];
 
 /* Proposed media change function: not really needed at this time */
@@ -201,7 +211,7 @@
    struct cdrom_tochdr	hdr;
    struct cdrom_tocentry entry;
 
-   if (dev < 0 || dev >= 26)
+   if (dev < 0 || dev >= MAX_CACHE_ENTRIES)
       return 0;
    if ( ioctl(cdrom_cache[dev].fd, CDROMREADTOCHDR, &hdr) == -1 )
       return 0;
@@ -365,71 +375,70 @@
 static int CDROM_GetInterfaceInfo(int fd, int* port, int* iface, int* device,int* lun)
 {
 #if defined(linux)
+    struct stat st;
+    if ( fstat(fd, &st) == -1 || ! S_ISBLK(st.st_mode))
     {
-        struct stat st;
-        if ( fstat(fd, &st) == -1 || ! S_ISBLK(st.st_mode)) {
-            FIXME("cdrom not a block device!!!\n");
-            return 0;
-        }
-        *port = 0;
-        *iface = 0;
-        *device = 0;
-        *lun = 0;
-        switch (major(st.st_rdev)) {
-            case IDE0_MAJOR: *iface = 0; break;
-            case IDE1_MAJOR: *iface = 1; break;
-            case IDE2_MAJOR: *iface = 2; break;
-            case IDE3_MAJOR: *iface = 3; break;
-            case IDE4_MAJOR: *iface = 4; break;
-            case IDE5_MAJOR: *iface = 5; break;
-            case IDE6_MAJOR: *iface = 6; break;
-            case IDE7_MAJOR: *iface = 7; break;
-            default: *port = 1; break;
-        }
+        FIXME("cdrom not a block device!!!\n");
+        return 0;
+    }
+    *port = 0;
+    *iface = 0;
+    *device = 0;
+    *lun = 0;
+    switch (major(st.st_rdev)) {
+    case IDE0_MAJOR: *iface = 0; break;
+    case IDE1_MAJOR: *iface = 1; break;
+    case IDE2_MAJOR: *iface = 2; break;
+    case IDE3_MAJOR: *iface = 3; break;
+    case IDE4_MAJOR: *iface = 4; break;
+    case IDE5_MAJOR: *iface = 5; break;
+    case IDE6_MAJOR: *iface = 6; break;
+    case IDE7_MAJOR: *iface = 7; break;
+    default: *port = 1; break;
+    }
 
-        if (*port == 0)
-                *device = (minor(st.st_rdev) >> 6);
+    if (*port == 0)
+        *device = (minor(st.st_rdev) >> 6);
+    else
+    {
+#ifdef SCSI_IOCTL_GET_IDLUN
+        UINT32 idlun[2];
+        if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun) != -1)
+        {
+            *port = ((idlun[0] >> 24) & 0xff) + 1;
+            *iface = (idlun[0] >> 16) & 0xff;
+            *device = idlun[0] & 0xff;
+            *lun = (idlun[0] >> 8) & 0xff;
+        }
         else
+#endif
         {
-#ifdef SCSI_IOCTL_GET_IDLUN
-                UINT32 idlun[2];
-                if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun) != -1)
-                {
-                        *port = ((idlun[0] >> 24) & 0xff) + 1;
-                        *iface = (idlun[0] >> 16) & 0xff;
-                        *device = idlun[0] & 0xff;
-                        *lun = (idlun[0] >> 8) & 0xff;
-                }
-                else
-#endif
-                {
-                        FIXME("CD-ROM device (%d, %d) not supported\n",
-                              major(st.st_rdev), minor(st.st_rdev));
-                        return 0;
-                }
+            FIXME("CD-ROM device (%d, %d) not supported\n",
+                  major(st.st_rdev), minor(st.st_rdev));
+            return 0;
         }
-        return 1;
     }
+    return 1;
 #elif defined(__NetBSD__)
+    struct scsi_addr addr;
+    if (ioctl(fd, SCIOCIDENTIFY, &addr) != -1)
     {
-       struct scsi_addr addr;
-       if (ioctl(fd, SCIOCIDENTIFY, &addr) != -1) {
-            switch (addr.type) {
-                case TYPE_SCSI:  *port = 1;
-                                 *iface = addr.addr.scsi.scbus;
-                                 *device = addr.addr.scsi.target;
-                                 *lun = addr.addr.scsi.lun;
-                                 break;
-                case TYPE_ATAPI: *port = 0;
-                                 *iface = addr.addr.atapi.atbus;
-                                 *device = addr.addr.atapi.drive;
-                                 *lun = 0;
-                                 break;
-            }
-            return 1;
-       }
-       return 0;
+        switch (addr.type) 
+        {
+        case TYPE_SCSI:  *port = 1;
+            *iface = addr.addr.scsi.scbus;
+            *device = addr.addr.scsi.target;
+            *lun = addr.addr.scsi.lun;
+            break;
+        case TYPE_ATAPI: *port = 0;
+            *iface = addr.addr.atapi.atbus;
+            *device = addr.addr.atapi.drive;
+            *lun = 0;
+            break;
+        }
+        return 1;
     }
+    return 0;
 #elif defined(__FreeBSD__)
     FIXME("not implemented for BSD\n");
     return 0;
@@ -449,7 +458,7 @@
  * NOTE: programs usually read these registry entries after sending the
  *       IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
  */
-void CDROM_InitRegistry(int fd, int device_id, const char *device )
+void CDROM_InitRegistry(int fd)
 {
     int portnum, busid, targetid, lun;
     OBJECT_ATTRIBUTES attr;
@@ -465,8 +474,6 @@
     HKEY targetKey;
     DWORD disp;
 
-    cdrom_cache[device_id].device = device;
-
     attr.Length = sizeof(attr);
     attr.RootDirectory = 0;
     attr.ObjectName = &nameW;
@@ -474,7 +481,7 @@
     attr.SecurityDescriptor = NULL;
     attr.SecurityQualityOfService = NULL;
 
-    if ( ! CDROM_GetInterfaceInfo(fd, &portnum, &busid, &targetid, &lun))
+    if (!CDROM_GetInterfaceInfo(fd, &portnum, &busid, &targetid, &lun))
         return;
 
     /* Ensure there is Scsi key */
@@ -583,25 +590,39 @@
  *		CDROM_Open
  *
  */
-static NTSTATUS CDROM_Open(HANDLE hDevice, DWORD clientID, int* dev)
+static NTSTATUS CDROM_Open(HANDLE hDevice, int* dev)
 {
-    *dev = LOWORD(clientID);
-
-    if (*dev >= 26) return STATUS_NO_SUCH_DEVICE;
-
+    int         fd;
+    struct stat st;
+    int         empty = -1;
+
+    wine_server_handle_to_fd(hDevice, GENERIC_READ, &fd, NULL, NULL);
+    if (fd == -1 || fstat(fd, &st) == -1) return STATUS_NO_SUCH_DEVICE;
+
+    for (*dev = 0; *dev < MAX_CACHE_ENTRIES; (*dev)++)
+    {
+        if (empty == -1 &&
+            cdrom_cache[*dev].device == 0 &&
+            cdrom_cache[*dev].inode == 0)
+            empty = *dev;
+        else if (cdrom_cache[*dev].device == st.st_dev &&
+                 cdrom_cache[*dev].inode == st.st_ino)
+            break;
+    }
+    if (*dev == MAX_CACHE_ENTRIES)
+    {
+        if (empty == -1) return STATUS_NOT_IMPLEMENTED;
+        *dev = empty;
+    }
     if (!cdrom_cache[*dev].count)
     {
-        const char *device;
-
-        if (!(device = cdrom_cache[*dev].device)) return STATUS_NO_SUCH_DEVICE;
-        cdrom_cache[*dev].fd = open(device, O_RDONLY|O_NONBLOCK);
-        if (cdrom_cache[*dev].fd == -1)
-        {
-            FIXME("Can't open configured CD-ROM drive %c: (device %s): %s\n",
-                  'A' + *dev, device, strerror(errno));
-            return STATUS_NO_SUCH_DEVICE;
-        }
+        cdrom_cache[*dev].fd      = fd;
+        cdrom_cache[*dev].hDevice = hDevice;
+        cdrom_cache[*dev].device  = st.st_dev;
+        cdrom_cache[*dev].inode   = st.st_ino;
     }
+    else
+        wine_server_release_fd(hDevice, fd);
     cdrom_cache[*dev].count++;
     TRACE("%d, %d, %d\n", *dev, cdrom_cache[*dev].fd, cdrom_cache[*dev].count);
     return STATUS_SUCCESS;
@@ -612,15 +633,15 @@
  *
  *
  */
-static void CDROM_Close(DWORD clientID)
+static void CDROM_Close(int dev)
 {
-    int dev = LOWORD(clientID);
-
-    if (dev >= 26 /*|| fd != cdrom_cache[dev].fd*/) FIXME("how come\n");
     if (--cdrom_cache[dev].count == 0) 
     {
-        close(cdrom_cache[dev].fd);
-        cdrom_cache[dev].fd = -1;
+        wine_server_release_fd(cdrom_cache[dev].hDevice, cdrom_cache[dev].fd);
+        cdrom_cache[dev].fd      = -1;
+        cdrom_cache[dev].hDevice = 0;
+        cdrom_cache[dev].device  = 0;
+        cdrom_cache[dev].inode   = 0;
     }
 }
 
@@ -752,13 +773,11 @@
 {
     NTSTATUS       ret = STATUS_NOT_SUPPORTED;
 
-    if (dev < 0 || dev >= 26)
-       return STATUS_INVALID_PARAMETER;
-    if ( !cdrom_cache[dev].toc_good ) {
-       ret = CDROM_SyncCache(dev);
-       if ( ret )
-	  return ret;
-    }
+    if (dev < 0 || dev >= MAX_CACHE_ENTRIES)
+        return STATUS_INVALID_PARAMETER;
+    if ( !cdrom_cache[dev].toc_good && (ret = CDROM_SyncCache(dev))) 
+        return ret;
+
     *toc = cdrom_cache[dev].toc;
     return STATUS_SUCCESS;
 }
@@ -1686,7 +1705,7 @@
  *
  *
  */
-NTSTATUS CDROM_DeviceIoControl(DWORD clientID, HANDLE hDevice, 
+NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice, 
                                HANDLE hEvent, PIO_APC_ROUTINE UserApcRoutine,
                                PVOID UserApcContext, 
                                PIO_STATUS_BLOCK piosb, 
@@ -1698,13 +1717,13 @@
     NTSTATUS    status = STATUS_SUCCESS;
     int         dev;
 
-    TRACE("%lx[%c] %s %lx %ld %lx %ld %p\n",
-          (DWORD)hDevice, 'A' + LOWORD(clientID), iocodex(dwIoControlCode), (DWORD)lpInBuffer, nInBufferSize,
+    TRACE("%lx %s %lx %ld %lx %ld %p\n",
+          (DWORD)hDevice, iocodex(dwIoControlCode), (DWORD)lpInBuffer, nInBufferSize,
           (DWORD)lpOutBuffer, nOutBufferSize, piosb);
 
     piosb->Information = 0;
 
-    if ((status = CDROM_Open(hDevice, clientID, &dev))) goto error;
+    if ((status = CDROM_Open(hDevice, &dev))) goto error;
 
     switch (dwIoControlCode)
     {
@@ -1893,7 +1912,7 @@
         status = STATUS_INVALID_PARAMETER;
         break;
     }
-    CDROM_Close(clientID);
+    CDROM_Close(dev);
  error:
     piosb->u.Status = status;
     piosb->Information = sz;
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll42/file.c dlls/ntdll/file.c
--- dlls/ntdll42/file.c	2004-01-23 22:21:08.000000000 +0100
+++ dlls/ntdll/file.c	2004-01-23 22:24:09.000000000 +0100
@@ -665,24 +665,12 @@
                                       PVOID OutputBuffer,
                                       ULONG OutputBufferSize)
 {
-    DWORD               clientID = 0;
-
     TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n",
           DeviceHandle, hEvent, UserApcRoutine, UserApcContext,
           IoStatusBlock, IoControlCode, 
           InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize);
 
-    /* FIXME: clientID hack should disappear */
-    SERVER_START_REQ( get_device_id )
-    {
-        req->handle = DeviceHandle;
-        if (!wine_server_call( req )) clientID = reply->id;
-    }
-    SERVER_END_REQ;
-
-    if (!clientID) return STATUS_INVALID_PARAMETER;
-
-    if (CDROM_DeviceIoControl(clientID, DeviceHandle, hEvent,
+    if (CDROM_DeviceIoControl(DeviceHandle, hEvent,
                               UserApcRoutine, UserApcContext,
                               IoStatusBlock, IoControlCode,
                               InputBuffer, InputBufferSize,
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll42/ntdll_misc.h dlls/ntdll/ntdll_misc.h
--- dlls/ntdll42/ntdll_misc.h	2004-01-23 22:21:08.000000000 +0100
+++ dlls/ntdll/ntdll_misc.h	2004-01-23 22:24:09.000000000 +0100
@@ -89,7 +89,7 @@
 
 /* Device IO */
 /* ntdll/cdrom.c.c */
-extern NTSTATUS CDROM_DeviceIoControl(DWORD clientID, HANDLE hDevice, 
+extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice, 
                                       HANDLE hEvent, PIO_APC_ROUTINE UserApcRoutine,
                                       PVOID UserApcContext, 
                                       PIO_STATUS_BLOCK piosb, 
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll42/ntdll.spec dlls/ntdll/ntdll.spec
--- dlls/ntdll42/ntdll.spec	2004-01-23 22:21:08.000000000 +0100
+++ dlls/ntdll/ntdll.spec	2004-01-23 22:24:09.000000000 +0100
@@ -1084,7 +1084,7 @@
 ################################################################
 # Wine dll separation hacks, these will go away, don't use them
 #
-@ cdecl CDROM_InitRegistry(long long str)
+@ cdecl CDROM_InitRegistry(long)
 @ cdecl MODULE_DllThreadAttach(ptr)
 @ cdecl MODULE_GetLoadOrderW(ptr wstr wstr)
 @ cdecl VERSION_Init(wstr)
diff -u -N -r -x '*~' -x '.#*' -x CVS files42/directory.c files/directory.c
--- files42/directory.c	2004-01-01 09:53:52.000000000 +0100
+++ files/directory.c	2004-01-18 21:20:00.000000000 +0100
@@ -531,7 +531,7 @@
 
     TRACE_(file)("(%s,%p)\n", debugstr_w(path), lpsecattribs );
 
-    if (DOSFS_GetDevice( path ))
+    if (RtlIsDosDeviceName_U( path ))
     {
         TRACE_(file)("cannot use device %s!\n", debugstr_w(path));
         SetLastError( ERROR_ACCESS_DENIED );
@@ -630,7 +630,7 @@
 
     TRACE_(file)("%s\n", debugstr_w(path));
 
-    if (DOSFS_GetDevice( path ))
+    if (RtlIsDosDeviceName_U( path ))
     {
         TRACE_(file)("cannot remove device %s!\n", debugstr_w(path));
         SetLastError( ERROR_FILE_NOT_FOUND );
diff -u -N -r -x '*~' -x '.#*' -x CVS files42/dos_fs.c files/dos_fs.c
--- files42/dos_fs.c	2004-01-23 22:21:09.000000000 +0100
+++ files/dos_fs.c	2004-01-23 22:24:19.000000000 +0100
@@ -94,39 +94,6 @@
 /* Chars we don't want to see in DOS file names */
 #define INVALID_DOS_CHARS  "*?<>|\"+=,;[] \345"
 
-static const DOS_DEVICE DOSFS_Devices[] =
-/* name, device flags (see Int 21/AX=0x4400) */
-{
-    { {'C','O','N',0}, 0xc0d3 },
-    { {'P','R','N',0}, 0xa0c0 },
-    { {'N','U','L',0}, 0x80c4 },
-    { {'A','U','X',0}, 0x80c0 },
-    { {'L','P','T','1',0}, 0xa0c0 },
-    { {'L','P','T','2',0}, 0xa0c0 },
-    { {'L','P','T','3',0}, 0xa0c0 },
-    { {'L','P','T','4',0}, 0xc0d3 },
-    { {'C','O','M','1',0}, 0x80c0 },
-    { {'C','O','M','2',0}, 0x80c0 },
-    { {'C','O','M','3',0}, 0x80c0 },
-    { {'C','O','M','4',0}, 0x80c0 },
-    { {'S','C','S','I','M','G','R','$',0}, 0xc0c0 },
-    { {'H','P','S','C','A','N',0}, 0xc0c0 },
-    { {'E','M','M','X','X','X','X','0',0}, 0x0000 }
-};
-
-static const WCHAR devW[] = {'\\','D','e','v','i','c','e','\\',0};
-static const WCHAR dosW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
-
-static const WCHAR auxW[] = {'A','U','X',0};
-static const WCHAR comW[] = {'C','O','M',0};
-static const WCHAR lptW[] = {'L','P','T',0};
-static const WCHAR nulW[] = {'N','U','L',0};
-
-static const WCHAR nullW[] = {'N','u','l','l',0};
-static const WCHAR parW[] = {'P','a','r','a','l','l','e','l',0};
-static const WCHAR serW[] = {'S','e','r','i','a','l',0};
-static const WCHAR oneW[] = {'1',0};
-
 /*
  * Directory info for DOSFS_ReadDir
  * contains the names of *all* the files in the directory
@@ -805,189 +772,6 @@
 
 
 /***********************************************************************
- *           DOSFS_GetDevice
- *
- * Check if a DOS file name represents a DOS device and return the device.
- */
-const DOS_DEVICE *DOSFS_GetDevice( LPCWSTR name )
-{
-    unsigned int i;
-    const WCHAR *p;
-
-    if (!name) return NULL; /* if wine_server_handle_to_fd was used */
-    if (name[0] && (name[1] == ':')) name += 2;
-    if ((p = strrchrW( name, '/' ))) name = p + 1;
-    if ((p = strrchrW( name, '\\' ))) name = p + 1;
-    for (i = 0; i < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]); i++)
-    {
-        const WCHAR *dev = DOSFS_Devices[i].name;
-        if (!strncmpiW( dev, name, strlenW(dev) ))
-        {
-            p = name + strlenW( dev );
-            if (!*p || (*p == '.') || (*p == ':')) return &DOSFS_Devices[i];
-        }
-    }
-    return NULL;
-}
-
-
-/***********************************************************************
- *           DOSFS_GetDeviceByHandle
- */
-const DOS_DEVICE *DOSFS_GetDeviceByHandle( HANDLE hFile )
-{
-    const DOS_DEVICE *ret = NULL;
-    SERVER_START_REQ( get_device_id )
-    {
-        req->handle = hFile;
-        if (!wine_server_call( req ))
-        {
-            if ((reply->id >= 0) &&
-                (reply->id < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
-                ret = &DOSFS_Devices[reply->id];
-        }
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-
-/**************************************************************************
- *         DOSFS_CreateCommPort
- */
-static HANDLE DOSFS_CreateCommPort(LPCWSTR name, DWORD access, DWORD attributes, LPSECURITY_ATTRIBUTES sa)
-{
-    HANDLE ret;
-    HKEY hkey;
-    DWORD dummy;
-    OBJECT_ATTRIBUTES attr;
-    UNICODE_STRING nameW;
-    WCHAR *devnameW;
-    char tmp[128];
-    char devname[40];
-
-    static const WCHAR serialportsW[] = {'M','a','c','h','i','n','e','\\',
-                                         'S','o','f','t','w','a','r','e','\\',
-                                         'W','i','n','e','\\','W','i','n','e','\\',
-                                         'C','o','n','f','i','g','\\',
-                                         'S','e','r','i','a','l','P','o','r','t','s',0};
-
-    TRACE_(file)("%s %lx %lx\n", debugstr_w(name), access, attributes);
-
-    attr.Length = sizeof(attr);
-    attr.RootDirectory = 0;
-    attr.ObjectName = &nameW;
-    attr.Attributes = 0;
-    attr.SecurityDescriptor = NULL;
-    attr.SecurityQualityOfService = NULL;
-    RtlInitUnicodeString( &nameW, serialportsW );
-
-    if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) return 0;
-
-    RtlInitUnicodeString( &nameW, name );
-    if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
-        devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
-    else
-        devnameW = NULL;
-
-    NtClose( hkey );
-
-    if (!devnameW) return 0;
-    WideCharToMultiByte(CP_ACP, 0, devnameW, -1, devname, sizeof(devname), NULL, NULL);
-
-    TRACE("opening %s as %s\n", devname, debugstr_w(name));
-
-    SERVER_START_REQ( create_serial )
-    {
-        req->access  = access;
-        req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-        req->attributes = attributes;
-        req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
-        wine_server_add_data( req, devname, strlen(devname) );
-        SetLastError(0);
-        wine_server_call_err( req );
-        ret = reply->handle;
-    }
-    SERVER_END_REQ;
-
-    if(!ret)
-        ERR("Couldn't open device '%s' ! (check permissions)\n",devname);
-    else
-        TRACE("return %p\n", ret );
-    return ret;
-}
-
-/***********************************************************************
- *           DOSFS_OpenDevice
- *
- * Open a DOS device. This might not map 1:1 into the UNIX device concept.
- * Returns 0 on failure.
- */
-HANDLE DOSFS_OpenDevice( LPCWSTR name, DWORD access, DWORD attributes, LPSECURITY_ATTRIBUTES sa )
-{
-    unsigned int i;
-    const WCHAR *p;
-    HANDLE handle;
-
-    if (name[0] && (name[1] == ':')) name += 2;
-    if ((p = strrchrW( name, '/' ))) name = p + 1;
-    if ((p = strrchrW( name, '\\' ))) name = p + 1;
-    for (i = 0; i < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]); i++)
-    {
-        const WCHAR *dev = DOSFS_Devices[i].name;
-        if (!strncmpiW( dev, name, strlenW(dev) ))
-        {
-            p = name + strlenW( dev );
-            if (!*p || (*p == '.') || (*p == ':')) {
-		static const WCHAR nulW[] = {'N','U','L',0};
-		static const WCHAR conW[] = {'C','O','N',0};
-		static const WCHAR scsimgrW[] = {'S','C','S','I','M','G','R','$',0};
-		static const WCHAR hpscanW[] = {'H','P','S','C','A','N',0};
-		static const WCHAR emmxxxx0W[] = {'E','M','M','X','X','X','X','0',0};
-	    	/* got it */
-		if (!strcmpiW(DOSFS_Devices[i].name, nulW))
-                    return FILE_CreateFile( "/dev/null", access,
-                                            FILE_SHARE_READ|FILE_SHARE_WRITE, sa,
-                                            OPEN_EXISTING, 0, 0, TRUE, DRIVE_UNKNOWN );
-		if (!strcmpiW(DOSFS_Devices[i].name, conW)) {
-			HANDLE to_dup;
-			switch (access & (GENERIC_READ|GENERIC_WRITE)) {
-			case GENERIC_READ:
-				to_dup = GetStdHandle( STD_INPUT_HANDLE );
-				break;
-			case GENERIC_WRITE:
-				to_dup = GetStdHandle( STD_OUTPUT_HANDLE );
-				break;
-			default:
-				FIXME("can't open CON read/write\n");
-				return 0;
-			}
-			if (!DuplicateHandle( GetCurrentProcess(), to_dup, GetCurrentProcess(),
-					      &handle, 0,
-					      sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle,
-					      DUPLICATE_SAME_ACCESS ))
-			    handle = 0;
-			return handle;
-		}
-		if (!strcmpiW(DOSFS_Devices[i].name, scsimgrW) ||
-                    !strcmpiW(DOSFS_Devices[i].name, hpscanW) ||
-                    !strcmpiW(DOSFS_Devices[i].name, emmxxxx0W))
-                {
-                    return FILE_CreateDevice( i, access, sa );
-		}
-
-                if( (handle=DOSFS_CreateCommPort(DOSFS_Devices[i].name,access,attributes,sa)) )
-                    return handle;
-                FIXME("device open %s not supported (yet)\n", debugstr_w(DOSFS_Devices[i].name));
-    		return 0;
-	    }
-        }
-    }
-    return 0;
-}
-
-
-/***********************************************************************
  *           DOSFS_GetPathDrive
  *
  * Get the drive specified by a given path name (DOS or Unix format).
diff -u -N -r -x '*~' -x '.#*' -x CVS files42/drive.c files/drive.c
--- files42/drive.c	2004-01-23 22:21:09.000000000 +0100
+++ files/drive.c	2004-01-23 22:24:19.000000000 +0100
@@ -141,7 +141,7 @@
 
 #define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
 
-extern void CDROM_InitRegistry(int dev, int id, const char *device);
+extern void CDROM_InitRegistry(int dev);
 
 /***********************************************************************
  *           DRIVE_GetDriveType
@@ -334,7 +334,7 @@
                     int cd_fd;
                     if ((cd_fd = open(drive->device, O_RDONLY|O_NONBLOCK)) != -1)
                     {
-                        CDROM_InitRegistry(cd_fd, i, drive->device);
+                        CDROM_InitRegistry(cd_fd);
                         close(cd_fd);
                     }
                 }
@@ -1210,7 +1210,6 @@
     return 1;
 }
 
-
 /***********************************************************************
  *           DRIVE_GetType
  */
diff -u -N -r -x '*~' -x '.#*' -x CVS files42/file.c files/file.c
--- files42/file.c	2004-01-23 22:21:09.000000000 +0100
+++ files/file.c	2004-01-23 22:24:19.000000000 +0100
@@ -264,28 +264,6 @@
 }
 
 
-/***********************************************************************
- *           FILE_CreateDevice
- *
- * Same as FILE_CreateFile but for a device
- * Returns 0 on failure.
- */
-HANDLE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa )
-{
-    HANDLE ret;
-    SERVER_START_REQ( create_device )
-    {
-        req->access  = access;
-        req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-        req->id      = client_id;
-        SetLastError(0);
-        wine_server_call_err( req );
-        ret = reply->handle;
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
 static HANDLE FILE_OpenPipe(LPCWSTR name, DWORD access, LPSECURITY_ATTRIBUTES sa )
 {
     HANDLE ret;
@@ -390,18 +368,7 @@
             ret = FILE_OpenPipe( filename, access, sa );
             goto done;
         }
-        else if (isalphaW(filename[4]) && filename[5] == ':' && filename[6] == '\0')
-        {
-            ret = FILE_CreateDevice( (toupperW(filename[4]) - 'A') | 0x20000, access, sa );
-            goto done;
-        }
-        else if (!DOSFS_GetDevice( filename ))
-        {
-            ret = DEVICE_Open( filename+4, access, sa );
-            goto done;
-        }
-	else
-        	filename+=4; /* fall into DOSFS_Device case below */
+        filename += 4;
     }
 
     /* If the name still starts with '\\', it's a UNC name. */
@@ -425,15 +392,48 @@
         goto done;
     }
 
-    if (DOSFS_GetDevice( filename ))
+    if ((isalphaW(filename[0]) && filename[1] == ':' && !filename[2]) ||
+        RtlIsDosDeviceName_U( filename ))
     {
+        char    buffer[MAX_PATH];
+        char    tmp[MAX_PATH], *ptr;
+        LPWSTR  p;
         TRACE("opening device %s\n", debugstr_w(filename) );
 
-        if (!(ret = DOSFS_OpenDevice( filename, access, attributes, sa )))
+        if (isalphaW(filename[0]) && (filename[1] == ':') && filename[2]) filename += 2;
+        if ((p = strrchrW( filename, '/' ))) filename = p + 1;
+        if ((p = strrchrW( filename, '\\' ))) filename = p + 1;
+
+        WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, tmp, sizeof(tmp), NULL, NULL);
+        for (ptr = tmp; *ptr; ptr++) *ptr = tolower(*ptr);
+
+        sprintf(buffer, "%s/device/%s/device", wine_get_config_dir(), tmp);
+        if (tmp[0] == 'c' && tmp[1] == 'o' && tmp[2] == 'm' && isdigit(tmp[3]) &&
+            !tmp[4])
         {
-            /* Do not silence this please. It is a critical error. -MM */
-            ERR("Couldn't open device %s!\n", debugstr_w(filename));
-            SetLastError( ERROR_FILE_NOT_FOUND );
+            SERVER_START_REQ( create_serial )
+            {
+                req->access  = access;
+                req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+                req->attributes = attributes;
+                req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
+                wine_server_add_data( req, buffer, strlen(buffer) );
+                SetLastError(0);
+                wine_server_call_err( req );
+                ret = reply->handle;
+            }
+            SERVER_END_REQ;
+
+            if (!ret)
+                ERR("Couldn't open device '%s' ! (check permissions)\n", buffer);
+            else
+                TRACE("return %p\n", ret );
+        }
+        else
+        {
+            ret = FILE_CreateFile( buffer, access, sharing,
+                                   sa, creation, attributes, template,
+                                   FALSE, DRIVE_UNKNOWN );
         }
         goto done;
     }
@@ -1407,7 +1407,7 @@
         SetLastError(ERROR_PATH_NOT_FOUND);
         return FALSE;
     }
-    if (DOSFS_GetDevice( path ))
+    if (RtlIsDosDeviceName_U( path ))
     {
         WARN("cannot remove DOS device %s!\n", debugstr_w(path));
         SetLastError( ERROR_FILE_NOT_FOUND );
diff -u -N -r -x '*~' -x '.#*' -x CVS include42/file.h include/file.h
--- include42/file.h	2004-01-01 09:54:11.000000000 +0100
+++ include/file.h	2004-01-18 22:29:49.000000000 +0100
@@ -45,14 +45,6 @@
 
 #define IS_END_OF_NAME(ch)  (!(ch) || ((ch) == '/') || ((ch) == '\\'))
 
-/* DOS device descriptor */
-typedef struct
-{
-    const WCHAR name[9];
-    int flags;
-    UINT codepage;
-} DOS_DEVICE;
-
 /* locale-independent case conversion */
 inline static char FILE_tolower( char c )
 {
@@ -71,12 +63,10 @@
 extern int FILE_strncasecmp( const char *str1, const char *str2, int len );
 extern void FILE_SetDosError(void);
 extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info, BOOL *is_symlink );
-extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 );
 extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
                                LPSECURITY_ATTRIBUTES sa, DWORD creation,
                                DWORD attributes, HANDLE template, BOOL fail_read_only,
                                UINT drive_type );
-extern HANDLE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa );
 
 extern LONG WINAPI WIN16_hread(HFILE16,SEGPTR,LONG);
 
@@ -89,15 +79,9 @@
 
 /* files/dos_fs.c */
 extern BOOL DOSFS_ToDosFCBFormat( LPCWSTR name, LPWSTR buffer );
-extern const DOS_DEVICE *DOSFS_GetDevice( LPCWSTR name );
-extern const DOS_DEVICE *DOSFS_GetDeviceByHandle( HANDLE hFile );
-extern HANDLE DOSFS_OpenDevice( LPCWSTR name, DWORD access, DWORD attributes, LPSECURITY_ATTRIBUTES sa);
 extern BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf,
                                 INT long_len, LPWSTR short_buf, BOOL ignore_case );
 extern BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last,
                                  DOS_FULL_NAME *full );
 
-/* win32/device.c */
-extern HANDLE DEVICE_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa );
-
 #endif  /* __WINE_FILE_H */
diff -u -N -r -x '*~' -x '.#*' -x CVS server42/Makefile.in server/Makefile.in
--- server42/Makefile.in	2004-01-01 09:54:22.000000000 +0100
+++ server/Makefile.in	2004-01-18 21:13:52.000000000 +0100
@@ -16,7 +16,6 @@
 	context_powerpc.c \
 	context_sparc.c \
 	debugger.c \
-	device.c \
 	event.c \
 	fd.c \
 	file.c \
diff -u -N -r -x '*~' -x '.#*' -x CVS server42/protocol.def server/protocol.def
--- server42/protocol.def	2004-01-14 22:29:59.000000000 +0100
+++ server/protocol.def	2004-01-18 21:11:59.000000000 +0100
@@ -1106,24 +1106,6 @@
 @END
 
 
-/* Create a device */
- at REQ(create_device)
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-    int          id;            /* client private id */
- at REPLY
-    obj_handle_t handle;        /* handle to the device */
- at END
-
-
-/* Retrieve the client private id for a device */
- at REQ(get_device_id)
-    obj_handle_t handle;        /* handle to the device */
- at REPLY
-    int          id;            /* client private id */
- at END
-
-
 #define SNAP_HEAPLIST   0x00000001
 #define SNAP_PROCESS    0x00000002
 #define SNAP_THREAD     0x00000004
Index: dlls/winedos/int21.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winedos/int21.c,v
retrieving revision 1.52
diff -u -r1.52 int21.c
--- dlls/winedos/int21.c	14 Jan 2004 04:34:22 -0000	1.52
+++ dlls/winedos/int21.c	18 Jan 2004 21:24:47 -0000
@@ -31,6 +31,7 @@
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
+#include <dirent.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -38,12 +39,12 @@
 #include "winternl.h"
 #include "wine/winbase16.h"
 #include "dosexe.h"
-#include "file.h"
 #include "winerror.h"
 #include "winuser.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
 #include "wine/exception.h"
+#include "wine/server.h"
 
 /*
  * Note:
@@ -245,7 +246,6 @@
 #define EL_Serial            0x04
 #define EL_Memory            0x05
 
-
 /* Many calls translate a drive argument like this:
    drive number (00h = default, 01h = A:, etc)
    */
@@ -2444,19 +2444,45 @@
  */
 static void INT21_Ioctl_Char( CONTEXT86 *context )
 {
-    static const WCHAR emmxxxx0W[] = {'E','M','M','X','X','X','X','0',0};
-    static const WCHAR scsimgrW[] = {'S','C','S','I','M','G','R','$',0};
-
-    HANDLE handle = DosFileHandleToWin32Handle(BX_reg(context));
-    const DOS_DEVICE *dev = DOSFS_GetDeviceByHandle(handle);
-
-    if (dev && !strcmpiW( dev->name, emmxxxx0W )) 
+    HANDLE      handle;
+    struct stat st_ref, st;
+    int         fd;
+    char        p[MAX_PATH], *l;
+    DIR*        dir;
+    struct dirent* de = NULL;
+
+    handle = DosFileHandleToWin32Handle(BX_reg(context));
+    if (wine_server_handle_to_fd(handle, GENERIC_READ, &fd, NULL, NULL))
+
+    if (fstat(fd, &st_ref) != -1)
+    {
+        sprintf(p, "%s/dosdevices/", wine_get_config_dir());
+        l = p + strlen(p);
+        dir = opendir(p);
+        if (dir)
+        {
+            while ((de = readdir(dir)))
+            {
+                strcpy(l, de->d_name);
+                if (stat(p, &st) != -1 && st.st_dev == st_ref.st_dev &&
+                    st.st_ino == st_ref.st_ino)
+                {
+                    strcpy(p, de->d_name);
+                    break;
+                }
+            }
+            closedir(dir);
+        }
+    }
+    close(fd);
+ 
+    if (de && !strcasecmp( p, "EMMXXXX0"))
     {
         EMS_Ioctl_Handler(context);
         return;
     }
 
-    if (dev && !strcmpiW( dev->name, scsimgrW ) && AL_reg(context) == 2)
+    if (de && !strcasecmp( p, "SCSIMGR$" ) && AL_reg(context) == 2)
     {
         DOSVM_ASPIHandler(context);
         return;
@@ -2466,8 +2492,26 @@
     {
     case 0x00: /* GET DEVICE INFORMATION */
         TRACE( "IOCTL - GET DEVICE INFORMATION - %d\n", BX_reg(context) );
-        if (dev)
+        if (de)
         {
+            static struct {const char* name; unsigned flags;} dos_dev[] = {
+                { "CON", 0xc0d3 },
+                { "PRN", 0xa0c0 },
+                { "NUL", 0x80c4 },
+                { "AUX", 0x80c0 },
+                { "LPT1", 0xa0c0 },
+                { "LPT2", 0xa0c0 },
+                { "LPT3", 0xa0c0 },
+                { "LPT4", 0xc0d3 },
+                { "COM1", 0x80c0 },
+                { "COM2", 0x80c0 },
+                { "COM3", 0x80c0 },
+                { "COM4", 0x80c0 },
+                { "SCSIMGR$", 0xc0c0 },
+                { "HPSCAN", 0xc0c0 },
+                { "EMMXXXX0", 0x0000 }
+            };
+            int i;
             /*
              * Returns attribute word in DX: 
              *   Bit 14 - Device driver can process IOCTL requests.
@@ -2483,7 +2527,10 @@
              *   Bit  1 - Standard output.
              *   Bit  0 - Standard input.
              */
-            SET_DX( context, dev->flags );
+            for (i = sizeof(dos_dev) / sizeof(dos_dev[0]) - 1; i >= 0; i--)
+                if (!strcmp(p, dos_dev[i].name))
+                    SET_DX( context, dos_dev[i].flags );
+            if (i < 0) SET_DX( context, 0 );
         }
         else
         {
@@ -3439,7 +3486,7 @@
      * is something behind this ?
      */
     while (*p == '*' || *p == ' ') p++; /* skip wildcards and spaces */
-    return IS_END_OF_NAME(*p);
+    return *p == '\0' || *p == '/' || *p == '\\';
 }
 
 static HANDLE       INT21_FindHandle;


More information about the wine-patches mailing list