summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2002-07-31 00:09:33 +0000
committercliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2002-07-31 00:09:33 +0000
commite5fa3b60238db8bfe839d8bbffc4a638719f6e95 (patch)
treedd65b616d0f96163ea36951daa8087b0737087d4
parent8864126e15e73ed3e09225fde414a265a6e520da (diff)
downloadpyserial-git-e5fa3b60238db8bfe839d8bbffc4a638719f6e95.tar.gz
added giveio sources and a readme
-rw-r--r--pyparallel/src/win32/README.txt20
-rw-r--r--pyparallel/src/win32/giveio/GIVEIO.C168
-rw-r--r--pyparallel/src/win32/giveio/MAKEFILE7
-rw-r--r--pyparallel/src/win32/giveio/README.TXT92
-rw-r--r--pyparallel/src/win32/giveio/SOURCES7
5 files changed, 294 insertions, 0 deletions
diff --git a/pyparallel/src/win32/README.txt b/pyparallel/src/win32/README.txt
new file mode 100644
index 0000000..d0b3cc5
--- /dev/null
+++ b/pyparallel/src/win32/README.txt
@@ -0,0 +1,20 @@
+This extension is needed on Windows as there is no API to
+manipulate the parallel port. This Python extension exposes
+"inp()" and "outp()" that can be used to manipulate the printer
+IOs directly. It could be basicaly used to access any IO port.
+
+On Windows NT/2k/XP direct access to IOs is not possible for
+user applications (only kernel mode drivers). Because of that
+a kernel driver is needed. The sources to GIVEIO.SYS are in
+the respective directory. The loaddrv sources come from the
+archive that is mentioned in the giveio readme.
+
+The extension tries to detect if its running on an NT based
+system and activates the giveio driver to gain access to the
+IO ports.
+
+Thanks go to
+ Dale Roberts for the giveio driver and to
+ Paula Tomlinson for the loaddrv sources
+
+chris <cliechti@gmx.net>
diff --git a/pyparallel/src/win32/giveio/GIVEIO.C b/pyparallel/src/win32/giveio/GIVEIO.C
new file mode 100644
index 0000000..f752a29
--- /dev/null
+++ b/pyparallel/src/win32/giveio/GIVEIO.C
@@ -0,0 +1,168 @@
+/*********************************************************************
+
+Author: Dale Roberts
+Date: 8/30/95
+Program: GIVEIO.SYS
+Compile: Use DDK BUILD facility
+
+Purpose: Give direct port I/O access to a user mode process.
+
+*********************************************************************/
+#include <ntddk.h>
+
+/*
+ * The name of our device driver.
+ */
+#define DEVICE_NAME_STRING L"giveio"
+
+/*
+ * This is the "structure" of the IOPM. It is just a simple
+ * character array of length 0x2000.
+ *
+ * This holds 8K * 8 bits -> 64K bits of the IOPM, which maps the
+ * entire 64K I/O space of the x86 processor. Any 0 bits will give
+ * access to the corresponding port for user mode processes. Any 1
+ * bits will disallow I/O access to the corresponding port.
+ */
+#define IOPM_SIZE 0x2000
+typedef UCHAR IOPM[IOPM_SIZE];
+
+/*
+ * This will hold simply an array of 0's which will be copied
+ * into our actual IOPM in the TSS by Ke386SetIoAccessMap().
+ * The memory is allocated at driver load time.
+ */
+IOPM *IOPM_local = 0;
+
+/*
+ * These are the two undocumented calls that we will use to give
+ * the calling process I/O access.
+ *
+ * Ke386IoSetAccessMap() copies the passed map to the TSS.
+ *
+ * Ke386IoSetAccessProcess() adjusts the IOPM offset pointer so that
+ * the newly copied map is actually used. Otherwise, the IOPM offset
+ * points beyond the end of the TSS segment limit, causing any I/O
+ * access by the user mode process to generate an exception.
+ */
+void Ke386SetIoAccessMap(int, IOPM *);
+void Ke386QueryIoAccessMap(int, IOPM *);
+void Ke386IoSetAccessProcess(PEPROCESS, int);
+
+/*********************************************************************
+ Release any allocated objects.
+*********************************************************************/
+VOID GiveioUnload(IN PDRIVER_OBJECT DriverObject)
+{
+ WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
+ UNICODE_STRING uniDOSString;
+
+ if(IOPM_local)
+ MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM));
+
+ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
+ IoDeleteSymbolicLink (&uniDOSString);
+ IoDeleteDevice(DriverObject->DeviceObject);
+}
+
+/*********************************************************************
+ Set the IOPM (I/O permission map) of the calling process so that it
+is given full I/O access. Our IOPM_local[] array is all zeros, so
+the IOPM will be all zeros. If OnFlag is 1, the process is given I/O
+access. If it is 0, access is removed.
+*********************************************************************/
+VOID SetIOPermissionMap(int OnFlag)
+{
+ Ke386IoSetAccessProcess(PsGetCurrentProcess(), OnFlag);
+ Ke386SetIoAccessMap(1, IOPM_local);
+}
+
+void GiveIO(void)
+{
+ SetIOPermissionMap(1);
+}
+
+/*********************************************************************
+ Service handler for a CreateFile() user mode call.
+
+ This routine is entered in the driver object function call table by
+the DriverEntry() routine. When the user mode application calls
+CreateFile(), this routine gets called while still in the context of
+the user mode application, but with the CPL (the processor's Current
+Privelege Level) set to 0. This allows us to do kernel mode
+operations. GiveIO() is called to give the calling process I/O
+access. All the user mode application needs do to obtain I/O access
+is open this device with CreateFile(). No other operations are
+required.
+*********************************************************************/
+NTSTATUS GiveioCreateDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ GiveIO(); // give the calling process I/O access
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+/*********************************************************************
+ Driver Entry routine.
+
+ This routine is called only once after the driver is initially
+loaded into memory. It allocates everything necessary for the
+driver's operation. In our case, it allocates memory for our IOPM
+array, and creates a device which user mode applications can open.
+It also creates a symbolic link to the device driver. This allows
+a user mode application to access our driver using the \\.\giveio
+notation.
+*********************************************************************/
+NTSTATUS DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+{
+ PDEVICE_OBJECT deviceObject;
+ NTSTATUS status;
+ WCHAR NameBuffer[] = L"\\Device\\" DEVICE_NAME_STRING;
+ WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
+ UNICODE_STRING uniNameString, uniDOSString;
+
+ //
+ // Allocate a buffer for the local IOPM and zero it.
+ //
+ IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM));
+ if(IOPM_local == 0)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlZeroMemory(IOPM_local, sizeof(IOPM));
+
+ //
+ // Set up device driver name and device object.
+ //
+ RtlInitUnicodeString(&uniNameString, NameBuffer);
+ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
+
+ status = IoCreateDevice(DriverObject, 0,
+ &uniNameString,
+ FILE_DEVICE_UNKNOWN,
+ 0, FALSE, &deviceObject);
+
+ if(!NT_SUCCESS(status))
+ return status;
+
+ status = IoCreateSymbolicLink (&uniDOSString, &uniNameString);
+
+ if (!NT_SUCCESS(status))
+ return status;
+
+ //
+ // Initialize the Driver Object with driver's entry points.
+ // All we require are the Create and Unload operations.
+ //
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = GiveioCreateDispatch;
+ DriverObject->DriverUnload = GiveioUnload;
+ return STATUS_SUCCESS;
+}
+
diff --git a/pyparallel/src/win32/giveio/MAKEFILE b/pyparallel/src/win32/giveio/MAKEFILE
new file mode 100644
index 0000000..5818975
--- /dev/null
+++ b/pyparallel/src/win32/giveio/MAKEFILE
@@ -0,0 +1,7 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the driver components of the Windows NT DDK
+#
+
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/pyparallel/src/win32/giveio/README.TXT b/pyparallel/src/win32/giveio/README.TXT
new file mode 100644
index 0000000..4a6ec36
--- /dev/null
+++ b/pyparallel/src/win32/giveio/README.TXT
@@ -0,0 +1,92 @@
+The entire archive was pulled from here:
+Dr. Dobb's Journal, http://www.ddj.com/ftp/1996/1996.05/directio.zip
+It contained some other snippets too, but as they are not useful here
+I don't include them here.
+
+chris
+
+Following is the original readme of the archive:
+-----------------------------------------------------------------------------
+
+
+Author: Dale Roberts, Direct I/O and Windows NT
+
+
+Here are two helpful hints to get you going with GIVEIO. The first
+section below mentions the INSTDRV utility that is provided with the
+Microsoft DDK. If you do not have access to the DDK, you can use Paula
+Tomlinson's program LOADDRV instead. She describes it in her May 1995
+article in Windows/DOS Developer's Journal (now Windows Developer's
+Journal). You can get the program from their FTP site at:
+
+ ftp://ftp.mfi.com/pub/windev/1995/may95.zip.
+
+
+------------------------------------------------------------------
+Device Driver Installation Made Easy
+
+The Microsoft NT Device Driver Kit documentation implies in several
+places that there are several steps involved in installing a device driver
+and making it accessible to a Win32 application. It explains that you
+should edit the registry manually and then reboot the system. But
+device drivers are dynamically loadable and unloadable in NT, and the
+DDK comes with a very handy utility called INSTDRV that
+demonstrates this facility in a very practical manner.
+
+INSTDRV is a console application that will register, load, and start a
+kernel mode device driver. It does not require you to edit the registry
+manually or reboot the computer. On the command line you simply
+give the name of your device driver and the complete path to the .SYS
+file (which does not need to be in the system's DRIVERS directory).
+After this command is executed, you will find that the driver has been
+registered with the system and appears in the Devices applet in the
+control panel. If you give the word remove instead of the path, the
+driver is removed from the system and taken out of the driver database.
+
+Once the driver is loaded and started, you can use the control panel's
+Devices applet to start and stop it, or you can use the net start and net
+stop commands (these are much faster) from a console window. When
+a kernel mode device is stopped, it is in also unloaded from memory.
+The next time you start the device, a fresh copy of the driver is read
+from the hard drive, if it has been modified. This makes it very
+convenient to develop device drivers, since you can go through the
+modify, stop, start cycle repeatedly without ever needing to reboot. If
+you need your driver to load at boot time, you can go into the Devices
+applet and change its startup mode to boot.
+
+The other component that is needed to make the driver visible to user
+mode applications, so they can use CreateFile() calls to access the
+driver, is registering the name in the DOS Devices name space. This
+can be done, as documented in the DDK, by editing the registry
+manually and rebooting. Or, much more simply, the kernel mode
+driver can call the IoCreateSymbolicLink() function to register the
+name itself. The GIVEIO driver shown in Listing Four uses the later
+technique. Once the name is registered, user mode applications can get
+a file handle to the device driver by calling CreateFile() with the driver
+name as the file parameter, but preceding the driver name with the
+special cookie \\.\. The TESTIO application in Listing Five uses this
+technique.
+
+------------------------------------------------------------------
+Quick Trick: Using DEBUG With Port I/O
+
+Sometimes you just need to do a quick I/O operation to a port. In DOS,
+you could use the DEBUG program to accomplish this. In NT, once
+you have the GIVEIO device driver up and running, you can once
+again use DEBUG for port I/O. If you look at the source code for the
+test application, you'll see that all it does is open and close the GIVEIO
+device driver. It uses the special cookie \\.\ before the driver name in
+order to access it. Without modifying DEBUG, you can have it open
+this device driver by simply typing debug \\.\giveio in an NT console
+window. You will get an error message complaining that the file
+\\.\giveio is not found, but it will give DEBUG I/O access anyway.
+Subsequent DOS applications that are run from this console window
+will also have I/O access.
+
+WIN32 applications executed from this console window will still cause
+exceptions. This is because DEBUG (and any other DOS application)
+runs in the context of the VDM (Virtual DOS Machine) process of the
+console box, whereas each WIN32 application gets its own process.
+The VDM process stays active as long as the console window is open,
+but each WIN32 application creates a brand new process with the
+IOPM offset initialized to point beyond the end of the TSS.
diff --git a/pyparallel/src/win32/giveio/SOURCES b/pyparallel/src/win32/giveio/SOURCES
new file mode 100644
index 0000000..1f8abef
--- /dev/null
+++ b/pyparallel/src/win32/giveio/SOURCES
@@ -0,0 +1,7 @@
+TARGETNAME=giveio
+TARGETPATH=.
+TARGETTYPE=DRIVER
+
+INCLUDES=c:\ddk\inc
+
+SOURCES=giveio.c