[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