[Wine-patches] [eterhack 06/12] parport.sys: Create interfaces for parallel ports.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Чт Май 21 17:53:42 MSD 2009


---
 dlls/parport.sys/Makefile.in |    2 +-
 dlls/parport.sys/parport.c   |   85 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/dlls/parport.sys/Makefile.in b/dlls/parport.sys/Makefile.in
index f9a4cde..73e918b 100644
--- a/dlls/parport.sys/Makefile.in
+++ b/dlls/parport.sys/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = parport.sys
 IMPORTLIB = parport.sys
-IMPORTS   = ntoskrnl.exe
+IMPORTS   = ntoskrnl.exe setupapi kernel32
 EXTRADLLFLAGS = -Wb,--subsystem,native
 EXTRALIBS = @IEEE1284LIBS@
 
diff --git a/dlls/parport.sys/parport.c b/dlls/parport.sys/parport.c
index 20d1b3d..2b94d6b 100644
--- a/dlls/parport.sys/parport.c
+++ b/dlls/parport.sys/parport.c
@@ -25,11 +25,18 @@
 
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+#define INITGUID
 
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
+#include "windef.h"
 #include "winternl.h"
 #include "winioctl.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "setupapi.h"
+#include "ntddpar.h"
 #include "ddk/ntddk.h"
 #include "ddk/parallel.h"
 #include "wine/unicode.h"
@@ -39,10 +46,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(parport);
 
 
 #ifdef HAVE_LIBIEEE1284
+static const WCHAR device_idW[] = {'A','C','P','I','\\',
+                                   'P','N','P','0','4','0','0','\\','%','d',0};
+
 struct ParPortExtension
 {
     struct parport *pp;
     int claimed;
+    int n;
+    UNICODE_STRING interface;
 };
 
 struct parport_list pp_list = {0, NULL};
@@ -130,8 +142,7 @@ static NTSTATUS WINAPI parport_ioctl( DEVICE_OBJECT *device, IRP *irp )
 
 static NTSTATUS WINAPI parport_pnp( DEVICE_OBJECT *device, IRP *irp )
 {
-    static const WCHAR device_idW[] = {'A','C','P','I','\\',
-                                       'P','N','P','0','4','0','0',0};
+    static const WCHAR fmtW[] = {'%','d',0};
 
     IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
     NTSTATUS status;
@@ -153,10 +164,27 @@ static NTSTATUS WINAPI parport_pnp( DEVICE_OBJECT *device, IRP *irp )
                 break;
             }
             strcpyW( device_id, device_idW );
+            *strrchrW( device_id, '\\' ) = 0;
             status = STATUS_SUCCESS;
             irp->IoStatus.Information = (ULONG_PTR)device_id;
             break;
         }
+        case BusQueryInstanceID:
+        {
+            ULONG len = 16;
+            struct ParPortExtension *ppe = device->DeviceExtension;
+            WCHAR *instance_id = ExAllocatePool( PagedPool, len * sizeof(WCHAR) );
+
+            if (instance_id == NULL)
+            {
+                status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+            snprintfW( instance_id, len, fmtW, ppe->n );
+            status = STATUS_SUCCESS;
+            irp->IoStatus.Information = (ULONG_PTR)instance_id;
+            break;
+        }
         default:
             FIXME( "IRP_MN_QUERY_ID: IdType %u is not implemented\n",
                     irpsp->Parameters.QueryId.IdType );
@@ -172,6 +200,48 @@ static NTSTATUS WINAPI parport_pnp( DEVICE_OBJECT *device, IRP *irp )
     return STATUS_SUCCESS;
 }
 
+static void register_parport_device( DEVICE_OBJECT *parport_dev, int n )
+{
+    static const WCHAR acpiW[] = {'A','C','P','I',0};
+
+    struct ParPortExtension *ppe;
+    HDEVINFO set;
+    SP_DEVINFO_DATA devInfo;
+    WCHAR *devnameW;
+    ULONG size;
+    NTSTATUS status;
+
+    size = sizeof(device_idW) + 16 * sizeof(WCHAR);
+    devnameW = ExAllocatePool( PagedPool, size );
+    if (devnameW == NULL) return;
+    snprintfW( devnameW, size / sizeof(WCHAR), device_idW, n );
+
+    set = SetupDiGetClassDevsW( NULL, acpiW, 0, DIGCF_ALLCLASSES );
+    if (set == INVALID_HANDLE_VALUE) goto done;
+    devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
+    if (SetupDiCreateDeviceInfoW( set, devnameW, &GUID_SERENUM_BUS_ENUMERATOR,
+            NULL, NULL, 0, &devInfo ))
+    {
+        if (!SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL ))
+            goto done;
+    }
+    else
+    {
+        if (ERROR_DEVINST_ALREADY_EXISTS != GetLastError())
+            goto done;
+    }
+
+    ppe = parport_dev->DeviceExtension;
+    status = IoRegisterDeviceInterface( parport_dev, &GUID_DEVINTERFACE_PARALLEL,
+            NULL, &ppe->interface );
+    if (status == STATUS_SUCCESS)
+        IoSetDeviceInterfaceState( &ppe->interface, TRUE );
+done:
+    if (set != INVALID_HANDLE_VALUE)
+        SetupDiDestroyDeviceInfoList( set );
+    ExFreePool( devnameW );
+}
+
 static void create_parport_device( DRIVER_OBJECT *driver, int n, struct parport *pp )
 {
     static const WCHAR parallel_portW[] = {'\\','D','e','v','i','c','e',
@@ -191,8 +261,10 @@ static void create_parport_device( DRIVER_OBJECT *driver, int n, struct parport
     if (status == STATUS_SUCCESS)
     {
         ppe = parport_dev->DeviceExtension;
+        RtlZeroMemory( ppe, sizeof(*ppe) );
         ppe->pp = pp;
-        ppe->claimed = 0;
+        ppe->n = n;
+        register_parport_device( parport_dev, n );
         parport_dev->Flags &= ~DO_DEVICE_INITIALIZING;
     }
 }
@@ -280,10 +352,17 @@ static void WINAPI parport_unload( DRIVER_OBJECT *driver )
 {
 #ifdef HAVE_LIBIEEE1284
     DEVICE_OBJECT *device = driver->DeviceObject, *device2;
+    struct ParPortExtension *ppe;
 
     while (device)
     {
         device2 = device->NextDevice;
+        ppe = device->DeviceExtension;
+        if (ppe->interface.Buffer)
+        {
+            IoSetDeviceInterfaceState( &ppe->interface, FALSE );
+            RtlFreeUnicodeString( &ppe->interface );
+        }
         IoDeleteDevice( device );
         device = device2;
     }
-- 
1.6.2.5



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