initial upload, directio/giveio.sys sources still missing
diff --git a/pyparallel/src/win32/_pyparallel.c b/pyparallel/src/win32/_pyparallel.c
new file mode 100644
index 0000000..7f906c5
--- /dev/null
+++ b/pyparallel/src/win32/_pyparallel.c
@@ -0,0 +1,91 @@
+// Parallel port extension for Win32
+// "inp" and "outp" are used to access the parallelport hardware
+// needs giveio.sys driver on NT/2k/XP
+//
+// (C) 2002 Chris Liechti <cliechti@gmx.net>
+// this is distributed under a free software license, see license.txt
+
+#include <Python.h>
+#include <windows.h>
+#include <conio.h>
+#include "loaddrv.h"
+
+#define DRIVERNAME      "giveio.sys"
+#define SERVICENAME     "giveio"
+
+/* module-functions */
+
+static PyObject*
+py_outp(PyObject *self, PyObject *args)
+{
+    int port, value;
+    if(!PyArg_ParseTuple(args, "ii", &port, &value))
+        return 0;
+    _outp(port, value);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject*
+py_inp(PyObject *self, PyObject *args)
+{
+    int port, value;
+    if(!PyArg_ParseTuple(args, "i", &port))
+        return 0;
+    value = _inp(port);
+    return Py_BuildValue("i", value);
+}
+
+
+
+static PyMethodDef pypar_methods[] = {
+    {"outp",   py_outp,   METH_VARARGS},
+    {"inp",    py_inp,    METH_VARARGS},
+    {0, 0}
+};
+
+/* module entry-point (module-initialization) function */
+void init_pyparallel(void) {
+    int dwStatus;
+    //~ char buf[256];
+    OSVERSIONINFO vi;
+    
+    /* Create the module and add the functions */
+    PyObject *m = Py_InitModule("_pyparallel", pypar_methods);
+    
+    //detect OS, on NT,2k,XP the driver needs to be loaded
+    vi.dwOSVersionInfoSize = sizeof(vi);
+    GetVersionEx(&vi);
+    if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+        HANDLE h;
+        //try to open driver
+        h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL,
+                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if (h == INVALID_HANDLE_VALUE) {
+            //failed, try to load sys file fom disk
+            dwStatus = LoadDriverInit();        //init loaddriver module
+            //~ printf("init %d\n", dwStatus);
+            //driver not running, try to start it
+            //~ dwStatus = getcwd(buf, sizeof buf);
+            //~ snprintf(buf, sizeof buf, "%s\\%s", buf, SERVICENAME);
+            //~ printf("path %d %s %s\n", dwStatus, buf, SERVICENAME);
+            //~ dwStatus = DriverInstall(buf, SERVICENAME);
+            //install the driver. this returns an error if already installed
+            //but who cares?
+            dwStatus = DriverInstall(DRIVERNAME, SERVICENAME);
+            dwStatus = DriverStart(SERVICENAME);//now start the driver
+            LoadDriverCleanup();                //close loaddriver module
+            //retry to open the file
+            h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL,
+                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+            if (h == INVALID_HANDLE_VALUE) {
+                //if it fails again, then we have a problem... -> exception
+                PyErr_Format(PyExc_ImportError, "Couldn't access giveio device");
+            }
+        }
+        //close again immediately.
+        //the process is now tagged to have the rights it needs,
+        //the giveio driver remembers that
+        if (h != NULL) CloseHandle(h);          //close the driver's file
+    }
+}
diff --git a/pyparallel/src/win32/loaddrv.c b/pyparallel/src/win32/loaddrv.c
new file mode 100644
index 0000000..5149877
--- /dev/null
+++ b/pyparallel/src/win32/loaddrv.c
@@ -0,0 +1,103 @@
+// loaddrv.c - Dynamic driver install/start/stop/remove
+// original by Paula Tomlinson
+
+#include <windows.h>
+#include "loaddrv.h"
+
+SC_HANDLE hSCMan = NULL;
+
+DWORD LoadDriverInit(void) {
+    // connect to local service control manager
+    if ((hSCMan = OpenSCManager(NULL, NULL, 
+        SC_MANAGER_ALL_ACCESS)) == NULL) {
+        return -1;
+    }
+    return OKAY;
+}
+
+void LoadDriverCleanup(void) {
+    if (hSCMan != NULL) CloseServiceHandle(hSCMan);
+}
+
+DWORD DriverInstall(LPSTR lpPath, LPSTR lpDriver) {
+   BOOL dwStatus = OKAY;
+   SC_HANDLE hService = NULL;
+
+   // add to service control manager's database
+   if ((hService = CreateService(hSCMan, lpDriver, 
+      lpDriver, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
+      SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, lpPath, 
+      NULL, NULL, NULL, NULL, NULL)) == NULL) 
+   {
+         dwStatus = GetLastError();
+   } else {
+       CloseServiceHandle(hService);
+   }
+
+   return dwStatus;
+}
+
+DWORD DriverStart(LPSTR lpDriver) {
+   BOOL dwStatus = OKAY;
+   SC_HANDLE hService = NULL;
+
+   // get a handle to the service
+   if ((hService = OpenService(hSCMan, lpDriver, 
+      SERVICE_ALL_ACCESS)) != NULL) 
+   {
+      // start the driver
+      if (!StartService(hService, 0, NULL))
+         dwStatus = GetLastError();
+   } else {
+       dwStatus = GetLastError();
+   }
+
+   if (hService != NULL) {
+       CloseServiceHandle(hService);
+   }
+   return dwStatus;
+}
+
+DWORD DriverStop(LPSTR lpDriver) {
+   BOOL dwStatus = OKAY;
+   SC_HANDLE hService = NULL;
+   SERVICE_STATUS serviceStatus;
+
+   // get a handle to the service
+   if ((hService = OpenService(hSCMan, lpDriver, 
+      SERVICE_ALL_ACCESS)) != NULL) 
+   {
+      // stop the driver
+      if (!ControlService(hService, SERVICE_CONTROL_STOP,
+         &serviceStatus))
+            dwStatus = GetLastError();
+   } else {
+       dwStatus = GetLastError();
+   }
+
+   if (hService != NULL) {
+       CloseServiceHandle(hService);
+   }
+   return dwStatus;
+}
+
+DWORD DriverRemove(LPSTR lpDriver) {
+   BOOL dwStatus = OKAY;
+   SC_HANDLE hService = NULL;
+
+   // get a handle to the service
+   if ((hService = OpenService(hSCMan, lpDriver, 
+      SERVICE_ALL_ACCESS)) != NULL) 
+   {
+      // remove the driver
+      if (!DeleteService(hService))
+         dwStatus = GetLastError();
+   } else {
+       dwStatus = GetLastError();
+   }
+
+   if (hService != NULL) {
+       CloseServiceHandle(hService);
+   }
+   return dwStatus;
+}
diff --git a/pyparallel/src/win32/loaddrv.h b/pyparallel/src/win32/loaddrv.h
new file mode 100644
index 0000000..4f874da
--- /dev/null
+++ b/pyparallel/src/win32/loaddrv.h
@@ -0,0 +1,17 @@
+#ifndef LOADDRV_H
+#define LOADDRV_H
+
+#include <windows.h>
+
+#define OKAY                   0
+#define UNEXPECTED_ERROR       9999
+
+//prototypes
+DWORD LoadDriverInit(void);
+void LoadDriverCleanup(void);
+DWORD DriverInstall(LPSTR, LPSTR);
+DWORD DriverStart(LPSTR);
+DWORD DriverStop(LPSTR);
+DWORD DriverRemove(LPSTR);
+
+#endif //LOADDRV_H
\ No newline at end of file