[Wine-patches] [eterhack] [0021/0021] Implement {READ, WRITE}_PORT_UCHAR for parallel port registers.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Ср Янв 28 21:10:18 MSK 2009


---
 dlls/hal/Makefile.in              |    2 +-
 dlls/hal/hal.c                    |   10 ++++--
 dlls/parport.sys/Makefile.in      |    1 +
 dlls/parport.sys/parport.c        |   68 +++++++++++++++++++++++++++++++++++++
 dlls/parport.sys/parport.sys.spec |    9 ++++-
 include/ddk/parallel.h            |    4 ++
 6 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/dlls/hal/Makefile.in b/dlls/hal/Makefile.in
index 026268a..7d2754c 100644
--- a/dlls/hal/Makefile.in
+++ b/dlls/hal/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = hal.dll
-IMPORTS   = kernel32 ntdll
+IMPORTS   = kernel32 ntdll parport.sys
 
 C_SRCS = \
 	hal.c
diff --git a/dlls/hal/hal.c b/dlls/hal/hal.c
index eab8e12..c9fc920 100644
--- a/dlls/hal/hal.c
+++ b/dlls/hal/hal.c
@@ -54,6 +54,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
 #endif
 
 
+extern UCHAR CDECL __wine_read_parport( UCHAR *port );
+extern void CDECL __wine_write_parport( UCHAR *port, UCHAR value );
+
 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
 DEFINE_FASTCALL1_ENTRYPOINT( ExAcquireFastMutex )
 VOID WINAPI __regs_ExAcquireFastMutex(PFAST_MUTEX FastMutex)
@@ -153,11 +156,12 @@ void WINAPI KeStallExecutionProcessor(ULONG MicroSeconds)
 
 UCHAR WINAPI READ_PORT_UCHAR(PUCHAR Port)
 {
-    FIXME( "(%p) stub!\n", Port );
-    return 0xff;
+    TRACE( "(%p)\n", Port );
+    return __wine_read_parport( Port );
 }
 
 void WINAPI WRITE_PORT_UCHAR(PUCHAR Port, UCHAR Value)
 {
-    FIXME( "(%p %u) stub!\n", Port, Value );
+    TRACE( "(%p %u)\n", Port, Value );
+    __wine_write_parport( Port, Value );
 }
diff --git a/dlls/parport.sys/Makefile.in b/dlls/parport.sys/Makefile.in
index 2cae1a8..f9a4cde 100644
--- a/dlls/parport.sys/Makefile.in
+++ b/dlls/parport.sys/Makefile.in
@@ -3,6 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = parport.sys
+IMPORTLIB = parport.sys
 IMPORTS   = ntoskrnl.exe
 EXTRADLLFLAGS = -Wb,--subsystem,native
 EXTRALIBS = @IEEE1284LIBS@
diff --git a/dlls/parport.sys/parport.c b/dlls/parport.sys/parport.c
index b1f25bb..d84abcb 100644
--- a/dlls/parport.sys/parport.c
+++ b/dlls/parport.sys/parport.c
@@ -49,6 +49,8 @@ struct ParPortExtension
 
 struct parport_list pp_list = {0, NULL};
 
+DRIVER_OBJECT *parport_driver;
+
 static BOOLEAN WINAPI parport_try( void *context )
 {
     struct ParPortExtension *ppe = context;
@@ -165,8 +167,73 @@ static void enum_par_devices( DRIVER_OBJECT *driver )
         create_parport_device( driver, k, pp );
     }
 }
+
+static struct ParPortExtension *get_parport_ext( UCHAR *port, ULONG *offset )
+{
+    DEVICE_OBJECT *device = parport_driver->DeviceObject;
+    struct ParPortExtension *ppe;
+
+    while (device)
+    {
+        ppe = device->DeviceExtension;
+        *offset = (ULONG)port - ppe->pp->base_addr;
+        if (*offset <= DCR_OFFSET) return ppe;
+        device = device->NextDevice;
+    }
+    return NULL;
+}
+
+static int read_parport( struct parport *pp, ULONG offset )
+{
+    if (DATA_OFFSET == offset) return ieee1284_read_data( pp );
+    if (DSR_OFFSET == offset) return ieee1284_read_status( pp ) ^ S1284_INVERTED;
+    if (DCR_OFFSET == offset) return ieee1284_read_control( pp ) ^ C1284_INVERTED;
+    return -1;
+}
+
+static void write_parport( struct parport *pp, UCHAR value, ULONG offset )
+{
+    if (DATA_OFFSET == offset) ieee1284_write_data( pp, value );
+    /* FIXME: see NOTE in ieee1284.h */
+    else if (DCR_OFFSET == offset) ieee1284_write_control( pp, value ^ C1284_INVERTED );
+}
 #endif  /* HAVE_LIBIEEE1284 */
 
+UCHAR CDECL __wine_read_parport( UCHAR *port )
+{
+#ifdef HAVE_LIBIEEE1284
+    int ret = -1;
+    ULONG offset;
+    struct ParPortExtension *ppe = get_parport_ext( port, &offset );
+
+    if (!ppe) return 0xff;
+    if (ppe->claimed) ret = read_parport( ppe->pp, offset );
+    else if (parport_try( ppe ))
+    {
+        ret = read_parport( ppe->pp, offset );
+        parport_free( ppe );
+    }
+    if (ret >= 0) return ret;
+#endif
+    return 0xff;
+}
+
+void CDECL __wine_write_parport( UCHAR *port, UCHAR value )
+{
+#ifdef HAVE_LIBIEEE1284
+    ULONG offset;
+    struct ParPortExtension *ppe = get_parport_ext( port, &offset );
+
+    if (!ppe) return;
+    if (ppe->claimed) write_parport( ppe->pp, value, offset );
+    else if (parport_try( ppe ))
+    {
+        write_parport( ppe->pp, value, offset );
+        parport_free( ppe );
+    }
+#endif
+}
+
 static void WINAPI parport_unload( DRIVER_OBJECT *driver )
 {
 #ifdef HAVE_LIBIEEE1284
@@ -187,6 +254,7 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
     driver->DriverUnload = parport_unload;
 #ifdef HAVE_LIBIEEE1284
     driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = parport_ioctl;
+    parport_driver = driver;
     enum_par_devices( driver );
 #endif
     return STATUS_SUCCESS;
diff --git a/dlls/parport.sys/parport.sys.spec b/dlls/parport.sys/parport.sys.spec
index 76421d7..4848c4a 100644
--- a/dlls/parport.sys/parport.sys.spec
+++ b/dlls/parport.sys/parport.sys.spec
@@ -1 +1,8 @@
-# nothing to export
+################################################################
+# Wine internal extensions
+#
+# All functions must be prefixed with '__wine_' (for internal functions)
+# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
+
+@ cdecl __wine_read_parport(ptr)
+@ cdecl __wine_write_parport(ptr long)
diff --git a/include/ddk/parallel.h b/include/ddk/parallel.h
index da5ec2a..bcde4bf 100644
--- a/include/ddk/parallel.h
+++ b/include/ddk/parallel.h
@@ -34,4 +34,8 @@ typedef struct _PARALLEL_PORT_INFORMATION {
     PVOID                           Context;
 } PARALLEL_PORT_INFORMATION, *PPARALLEL_PORT_INFORMATION;
 
+#define DATA_OFFSET         0
+#define DSR_OFFSET          1
+#define DCR_OFFSET          2
+
 #endif /* _PARALLEL_ */
-- 
1.6.0.2.GIT



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