summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2002-07-29 02:09:04 +0000
committercliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2002-07-29 02:09:04 +0000
commit8864126e15e73ed3e09225fde414a265a6e520da (patch)
tree03b78f448b9283602707e1eecac28ffbc2a64c7c
parent7bb452a4d4b72c71bad873b90b7b4b9ad0537d3f (diff)
downloadpyserial-git-8864126e15e73ed3e09225fde414a265a6e520da.tar.gz
initial upload, directio/giveio.sys sources still missing
-rw-r--r--pyparallel/CHANGES.txt2
-rw-r--r--pyparallel/LICENSE.txt61
-rw-r--r--pyparallel/MANIFEST8
-rw-r--r--pyparallel/README.txt46
-rw-r--r--pyparallel/examples/lcd.py120
-rw-r--r--pyparallel/makefile6
-rw-r--r--pyparallel/parallel/__init__.py21
-rw-r--r--pyparallel/parallel/parallelwin32.py122
-rw-r--r--pyparallel/setup.py19
-rw-r--r--pyparallel/src/win32/_pyparallel.c91
-rw-r--r--pyparallel/src/win32/loaddrv.c103
-rw-r--r--pyparallel/src/win32/loaddrv.h17
12 files changed, 616 insertions, 0 deletions
diff --git a/pyparallel/CHANGES.txt b/pyparallel/CHANGES.txt
new file mode 100644
index 0000000..9f88238
--- /dev/null
+++ b/pyparallel/CHANGES.txt
@@ -0,0 +1,2 @@
+Version 0.1 29 Jul 2002
+ added to CVS
diff --git a/pyparallel/LICENSE.txt b/pyparallel/LICENSE.txt
new file mode 100644
index 0000000..2b0e2d8
--- /dev/null
+++ b/pyparallel/LICENSE.txt
@@ -0,0 +1,61 @@
+Copyright (c) 2002 Chris Liechti <cliechti@gmx.net>;
+All Rights Reserved.
+
+This is the Python license. In short, you can use this product in
+commercial and non-commercial applications, modify it, redistribute it.
+A notification to the author when you use and/or modify it is welcome.
+
+
+TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE
+===================================================================
+
+LICENSE AGREEMENT
+-----------------
+
+1. This LICENSE AGREEMENT is between the copyright holder of this
+product, and the Individual or Organization ("Licensee") accessing
+and otherwise using this product in source or binary form and its
+associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement,
+the copyright holder hereby grants Licensee a nonexclusive,
+royalty-free, world-wide license to reproduce, analyze, test,
+perform and/or display publicly, prepare derivative works, distribute,
+and otherwise use this product alone or in any derivative version,
+provided, however, that copyright holders License Agreement and
+copyright holders notice of copyright are retained in this product
+alone or in any derivative version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates this product or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to this product.
+
+4. The copyright holder is making this product available to Licensee on
+an "AS IS" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS OR
+WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION,
+THE COPYRIGHT HOLDER MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
+THAT THE USE OF THIS PRODUCT WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER
+USERS OF THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL
+DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE
+USING THIS PRODUCT, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE
+POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between the
+copyright holder and Licensee. This License Agreement does not grant
+permission to use trademarks or trade names from the copyright holder
+in a trademark sense to endorse or promote products or services of
+Licensee, or any third party.
+
+8. By copying, installing or otherwise using this product, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
diff --git a/pyparallel/MANIFEST b/pyparallel/MANIFEST
new file mode 100644
index 0000000..72f39fd
--- /dev/null
+++ b/pyparallel/MANIFEST
@@ -0,0 +1,8 @@
+README.txt
+LICENSE.txt
+CHANGES.txt
+setup.py
+parallel\__init__.py
+parallel\_pyparallel.py
+examples\test.py
+
diff --git a/pyparallel/README.txt b/pyparallel/README.txt
new file mode 100644
index 0000000..e6e0734
--- /dev/null
+++ b/pyparallel/README.txt
@@ -0,0 +1,46 @@
+pyParallel
+--------
+This module capsulates the access for the parallel port. It provides backends
+for standard Python running on Windows, Linux, BSD and Jython.
+The module named "parallel" automaticaly selects the appropriate backend.
+
+It is released under a free software license, see LICENSE.txt for more
+details.
+
+Project Homepage: pyserial.sourceforge.net
+(C) 2002 Chris Liechti <cliechti@gmx.net>
+
+
+Features
+--------
+- same class based interface on all supported platforms
+- port numbering starts at zero, no need to know the platform dependant port
+ name in the user program
+- port name can be specified if access through numbering is inappropriate
+
+Requirements
+------------
+- Python 2.0 or newer (1.5.2 untested)
+- "Java Communications" (JavaComm) extension for Java/Jython
+
+
+Installation
+------------
+Extract files from the archive, open a shell/console in that directory and
+let Distutils do the rest: "python setup.py install"
+
+The files get installed in the "Lib/site-packages" directory in newer
+Python versions.
+
+
+Short introduction
+------------------
+>>> import parallel
+>>> p = parallel.Parallel() #open LPT1
+>>> p.setData(0x55)
+
+References
+----------
+- Python: http://www.python.org
+
+- Jython: http://www.jython.org
diff --git a/pyparallel/examples/lcd.py b/pyparallel/examples/lcd.py
new file mode 100644
index 0000000..b56c2a5
--- /dev/null
+++ b/pyparallel/examples/lcd.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+# character LCD example for pyparallel
+#
+#(C) 2002 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+import sys, time
+sys.path.append('..')
+import parallel
+
+LCDON = 0x01 #0x00000001 Switch on display
+LCDOFF = 0x08 #0x00001000 Switch off display
+LCDCLEAR = 0x01 #0x00000001
+LCDLINE1 = 0x80 #0x10000000
+LCDLINE2 = 0xc0 #0x11000000
+LCDCURSORON = 0x0f #0x00001111 turn on cursor blinking
+LCDCURSOROFF = 0x0c #0x00001100 Disable cursor blinking. The cursor is hidden.
+LCDCGADRSET = 0x40 #0b01000000
+LCDDDADRSET = 0x80 #0b10000000
+LCD2LINES = 0x28 #0b00101000 Set display mode to two lines.
+LCD8BITS = 0x30 #0b00110000 select 8 Bit interface
+LCD4BITS = 0x20 #0b00100000 select 4 Bit interface
+LCD_DATA_OFF = 0x05 #0x00000101 mask used to clear the data lines
+
+LCD_RS = 1<<1
+LCD_RW = 1<<2
+LCD_E = 1<<3
+LCD_D4 = 1<<4
+LCD_D5 = 1<<5
+LCD_D6 = 1<<6
+LCD_D7 = 1<<7
+
+
+class LCD:
+ def __init__(self):
+ self.p = parallel.Parallel()
+ self.data = 0
+
+ self.out(0) #reset pins
+ time.sleep(0.050) #wait more than 30ms
+ #send the reset sequece (3 times the same pattern)
+ self.out(LCD8BITS) #set 8 bit interface
+ self.toggleE() #toggle LCD_E, the enable pin
+ time.sleep(0.005) #wait a bit
+ self.toggleE() #toggle LCD_E, the enable pin
+ time.sleep(0.005) #wait a bit
+ self.toggleE() #toggle LCD_E, the enable pin
+ time.sleep(0.005) #wait a bit
+
+ self.out(LCD4BITS) #now set up the 4 bit interface
+ self.toggleE() #toggle LCD_E, the enable pin
+ time.sleep(0.002) #wait until instr is finished
+ self.instr(LCD2LINES) #set 2 lines display
+ self.instr(LCDCURSOROFF) #hide cursor
+ self.instr(LCDCLEAR) #clear display
+
+ #my connector has the wrong pinorder....
+ #better swap them in software than to solder ;-)
+ def reveseout(self, x):
+ r = ((x & (1<<0) and 1) << 7) |\
+ ((x & (1<<1) and 1) << 6) |\
+ ((x & (1<<2) and 1) << 5) |\
+ ((x & (1<<3) and 1) << 4) |\
+ ((x & (1<<4) and 1) << 3) |\
+ ((x & (1<<5) and 1) << 2) |\
+ ((x & (1<<6) and 1) << 1) |\
+ ((x & (1<<7) and 1) << 0)
+ #print "%02x" % r, "%02x" %x
+ self.p.setData(r)
+
+ def toggleE(self):
+ """toggle enable pin"""
+ self.data |= LCD_E; #toggle LCD_E, the enable pin
+ self.reveseout(self.data)
+ self.data &= ~LCD_E; #back to inactive position
+ self.reveseout(self.data)
+
+ def out(self, data):
+ """set data to LCD port"""
+ self.data = data
+ self.reveseout(self.data)
+
+ def instr(self, cmd):
+ """send instruction byte to LCD"""
+ self.out(cmd & 0xf0) #output upper nibble
+ self.toggleE() #toggle LCD_E, the enable pin
+ self.out((cmd << 4) & 0xf0) #and then the lower nibble
+ self.toggleE() #toggle LCD_E, the enable pin
+ time.sleep(0.001) #wait until instr is finished
+
+ def putc(self, c):
+ """send a data byte to the LCD"""
+ c = ord(c)
+ self.out((c & 0xf0) | LCD_RS) #output upper nibble
+ self.toggleE() #toggle LCD_E, the enable pin
+ self.out(((c << 4) & 0xf0) | LCD_RS) #and then the lower nibble
+ self.toggleE() #toggle LCD_E, the enable pin
+ time.sleep(0.001) #wait until instr is finished
+
+ def write(self, str):
+ """write a string to the LCD"""
+ for c in str:
+ self.putc(c) #write each character
+
+ def downloadFont(self, fontdata):
+ """Set the memory pointer and download a font"""
+ self.instr(LCDCGADRSET);
+ self.write(fontdata)
+ self.instr(LCDLINE1) #just in case, set cursor to a visible pos
+
+if __name__ == '__main__':
+ lcd = LCD()
+ lcd.write("Hello World")
+ lcd.instr(LCDLINE2)
+ lcd.write("from Python")
+## for c in map(chr,range(256)):
+## lcd.instr(LCDLINE1)
+## lcd.write(c)
+
+ \ No newline at end of file
diff --git a/pyparallel/makefile b/pyparallel/makefile
new file mode 100644
index 0000000..182cf58
--- /dev/null
+++ b/pyparallel/makefile
@@ -0,0 +1,6 @@
+all:
+ ./setup.py build --compiler=mingw32
+ cp build/lib.win32-2.2/_pyparallel.pyd ./parallel
+
+installer: all
+ ./setup.py bdist_wininst
diff --git a/pyparallel/parallel/__init__.py b/pyparallel/parallel/__init__.py
new file mode 100644
index 0000000..6bcdf49
--- /dev/null
+++ b/pyparallel/parallel/__init__.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+#portable parallel port access with python
+#this is a wrapper module for different platform implementations
+#
+# (C)2001-2002 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+import sys, os, string
+VERSION = string.split("$Revision: 1.1 $")[1] #extract CVS version
+
+#chose an implementation, depending on os
+if os.name == 'nt': #sys.platform == 'win32':
+ from parallelwin32 import *
+elif os.name == 'posix':
+ from parallelposix import *
+elif os.name == 'java':
+ from paralleljava import *
+else:
+ raise "Sorry no implementation for your platform available."
+
+#no "mac" implementation. someone want's to write it? i have no access to a mac.
diff --git a/pyparallel/parallel/parallelwin32.py b/pyparallel/parallel/parallelwin32.py
new file mode 100644
index 0000000..7c10c3f
--- /dev/null
+++ b/pyparallel/parallel/parallelwin32.py
@@ -0,0 +1,122 @@
+#pyparallel driver for win32
+#see __init__.py
+#
+#(C) 2002 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+#
+# thanks to Dincer Aydin dinceraydin@altavista.net for his work on the
+# winioport module: www.geocities.com/dinceraydin/ the graphic below is
+# borrowed form him ;-)
+
+
+# LPT1 = 0x0378 or 0x03BC
+# LPT2 = 0x0278 or 0x0378
+# LPT3 = 0x0278
+#
+# Data Register (base + 0) ........ outputs
+#
+# 7 6 5 4 3 2 1 0
+# . . . . . . . * D0 ........... (pin 2), 1=High, 0=Low (true)
+# . . . . . . * . D1 ........... (pin 3), 1=High, 0=Low (true)
+# . . . . . * . . D2 ........... (pin 4), 1=High, 0=Low (true)
+# . . . . * . . . D3 ........... (pin 5), 1=High, 0=Low (true)
+# . . . * . . . . D4 ........... (pin 6), 1=High, 0=Low (true)
+# . . * . . . . . D5 ........... (pin 7), 1=High, 0=Low (true)
+# . * . . . . . . D6 ........... (pin 8), 1=High, 0=Low (true)
+# * . . . . . . . D7 ........... (pin 9), 1=High, 0=Low (true)
+#
+# Status Register (base + 1) ...... inputs
+#
+# 7 6 5 4 3 2 1 0
+# . . . . . * * * Undefined
+# . . . . * . . . Error ........ (pin 15), high=1, low=0 (true)
+# . . . * . . . . Selected ..... (pin 13), high=1, low=0 (true)
+# . . * . . . . . No paper ..... (pin 12), high=1, low=0 (true)
+# . * . . . . . . Ack .......... (pin 10), high=1, low=0 (true)
+# * . . . . . . . Busy ......... (pin 11), high=0, low=1 (inverted)
+#
+# ctrl Register (base + 2) ..... outputs
+#
+# 7 6 5 4 3 2 1 0
+# . . . . . . . * Strobe ....... (pin 1), 1=low, 0=high (inverted)
+# . . . . . . * . Auto Feed .... (pin 14), 1=low, 0=high (inverted)
+# . . . . . * . . Initialize ... (pin 16), 1=high, 0=low (true)
+# . . . . * . . . Select ....... (pin 17), 1=low, 0=high (inverted)
+# * * * * . . . . Unused
+
+LPT1 = 0
+LPT2 = 1
+
+LPT1_base = 0x0378
+LPT2_base = 0x0278
+
+import _pyparallel
+
+class Parallel:
+ def __init__(self, port = LPT1):
+ if port == LPT1:
+ self.dataRegAdr = LPT1_base
+ elif port == LPT1:
+ self.dataRegAdr = LPT2_base
+ else:
+ raise ValueError("No such port available - expecting a number")
+ self.statusRegAdr = self.dataRegAdr + 1
+ self.ctrlRegAdr = self.dataRegAdr + 2
+
+ def setData(self, value):
+ _pyparallel.outp(self.dataRegAdr, value)
+
+ # control register output functions
+ def setDataStrobe(self, state):
+ """data strobe bit"""
+ if state == 0:
+ self.ctrlReg = self.ctrlReg | 0x01
+ else:
+ self.ctrlReg = self.ctrlReg & ~0x01
+ _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg)
+
+ def setAutoFeed(self, state):
+ """auto feed bit"""
+ if state == 0:
+ self.ctrlReg = self.ctrlReg | 0x02
+ else:
+ self.ctrlReg = self.ctrlReg & ~0x02
+ _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg)
+
+ def setInitOut(self, state):
+ """initialize bit"""
+ if state == 0:
+ self.ctrlReg = self.ctrlReg & ~0x04
+ else:
+ self.ctrlReg = self.ctrlReg | 0x04
+ _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg)
+
+ def setSelect(self, state):
+ """select bit"""
+ if state == 0:
+ self.ctrlReg = self.ctrlReg | 0x08
+ else:
+ self.ctrlReg = self.ctrlReg & ~0x08
+ _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg)
+
+ def getInError(self):
+ """Error pin"""
+ return _pyparallel.inp(self.statusRegAdr) & 0x08 and 1
+
+ def gettInSelected(self):
+ """select pin"""
+ return _pyparallel.inp(self.statusRegAdr) & 0x10 and 1
+
+ def getInPaperOut(self):
+ """paper out pin"""
+ return _pyparallel.inp(self.statusRegAdr) & 0x20 and 1
+
+ def getInAcknowledge(self):
+ """Acknowledge pin"""
+ return _pyparallel.inp(self.statusRegAdr) & 0x40 and 1
+
+ def getInBusy(self):
+ """input from busy pin"""
+ return _pyparallel.inp(self.statusRegAdr)& 0x80 and 1
+
+
diff --git a/pyparallel/setup.py b/pyparallel/setup.py
new file mode 100644
index 0000000..64bda13
--- /dev/null
+++ b/pyparallel/setup.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from distutils.core import setup, Extension
+
+setup (name = "pyparallel",
+ description="Python Parallel Port Extension",
+ version="0.1",
+ author="Chris Liechti",
+ author_email="cliechti@gmx.net",
+ url="http://pyserial.sourceforge.net/",
+ packages=['parallel'],
+ license="Python",
+ long_description="Python Parallel Port Extension for Win32, Linux, BSD",
+
+ ext_modules = [
+ Extension('_pyparallel',
+ sources=['src/win32/_pyparallel.c', 'src/win32/loaddrv.c'],
+ )
+ ]
+)
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