Zdroj: http://prochazka.clanweb.eu/index.php?a=programy/wwio_dll • Vydáno: 13.4.2009 17:45 • Autor: hacesoft
Knihovna pro přístup na LPT porty pod WinXP a WinVista
Tak po delší odmlce tu máme novou verzi knihovny pro přístup na LPT port. Tato verze je určena pro WinXP a nove pro WinVista. U WinVista se to mírně komplikuje diky UAE. Tento problém prozatím musíte řešit, že zakážete, ve WinVista řízení učtu (UAE) a nebo ve svém projektu (v *.exe) nastavíte ve vlastnostech linkeru ->manifest file -> UAC execution level na reqire Administrator. Popřípadě v ikoně *.exe souboru ve vlastnostech nastavíte zaškrtávání políčko spouštět jako administrátor.
Nová verze knihovny KNIHOVNA.DLL se už jmenuje wwio.dll je napsána v cecku a částečně s podporou technologie .NET. Ta je použita na funkce kde není potřeba maximální rychlost. Jedna se o funkce UnLock_ a nalezeni adresy LPT portu. Od této verzi už není využíváno služeb knihovny AdresaPortu.dll, ta je teďka přímo integrována do wwio.dll. Ale nadále je využíváno služeb ovladače GiveIO.sys. Který musí bejt ve stejném adresáři jako wwio.dll.
wwio.dll je testována na WinXP servisní baliček 3 a .NET Framework 3.5, taktéž její funkčnost je ověřena na WinVista SP1.
Knihovny DLL prostředí Visuál C++ jsou zavaděný na adresu 0x10000000. Dovoluji si tvrdit, že se na jednu adresu snaží zavést polovina všech DLL na světě. Musí-li operační systém přesměrovat adresu DLL, musí každé místo v kódu, které s příslušnou adresou DLL knihovny pracuje najít a změnit odkazovou adresu, protože se DLL už nenachází na své výchozí adrese. Kvůli přesměrování nemůže operační systém swapovat příslušný modul paměti. Je-li modul zaveden na svoji výchozí adresu, může jej operační systém načíst přímo z disku, byl-li modul swapován. Pokud je modul přesměrován, mění se adresa paměti modulu pro daný proces a operační systém musí tuto paměť stale udržovat, což počítač zpomaluje. Proto knihovna wwio.dll se zavadí na adresu 0x63000000.
Pomocí této knihovny můžete ve Visuál Basicu a Céčku pracovat s LPT porty. V Biosu nastavte LPT port na ECP + EPP. Toto nastavení není nikterak důležité pro funkci DLL wwio.dll ale s tímto nastavením funguje LPT port obousměrně. Například nastavení režimu portu na SPP znamená že datová sběrnice D0 – D7 je jen výstupní. Podrobnosti ohledně LPT portu v češtině naleznete zde: hw.cz/lpt
Další nastavení jako DMA a adresa portu, muže bejt libovolná.
Tento program, wwio.dll můžete používat neomezeně pro NEKOMERČNÍ účely.
Funkce UnLock_ :
C++ code
int WINAPI UnLock_
(void);
Nainstaluje ovladač Giveio.sys a spustí ho. Pokud už tak neučinila jiná aplikace využívající služeb knihovny wwio.dll. Tato funkce se provede vždy jednou a to na začátku programu. Návratová hodnota je nula, když funkce uspěla. V případě chyby je vracena hodnota -1 a pomoci funkce Error_ se dá zjistit proč funkce neuspěla. V případe že návratová hodnota je nula a použijete funkci Error_ , muže se stát že nevrátí hodnotu nula ale nějakou hodnotu, která indikuje co se při instalaci a spouštění giveio.sys ovladače pokazilo, ale to neznamená, že nelze v programu úspěšně pokračovat. Toto muže nastat pokud ovladač giveio.sys je už nainstalován jiným programem ale to neznamená, že ho nelze úspěšně používat. Funkce jen upozorňuje, že tato situace nastala.
Pro další zjištěni použijte funkci Error_, která vrátí jednu z následujících možností:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = -1 -- Funkce selhala.
- ErrorKod = 1 -- Nelze najit soubor GiveIO.sys.
- ErrorKod = 2 -- Nejde nainstalovat giveio.sys ovladač.
- ErrorKod = 3 -- Nejde spustit giveio.sys ovladač.
- ErrorKod = 4 -- Nejde otevřít OpenSCManager.
- ErrorKod = 183 – Nelze vytvořit soubor, který již existuje. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále.
- ErrorKod = 1072 – Zadané zařízení je určeno na odstranění. Zkuste po chvilce použit tuto funkci znovu.
- ErrorKod = 1073 – Zadaná služba již existuje. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále.
- ErrorKod = 1056 - Instance této služby je již spuštěna. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále.
Funkce Lock_ :
C++ code
unsigned int WINAPI Lock_
(RETURN_CODE
* ReturnCode
= NULL);
Zastaví ovladač Giveio.sys a odstraní ho ze systému, uklidí po sobě v registrech. Tato funkce se vola na konci programu. Nepovinny parametr je struktura, která lépe informuje, co se vše stalo.
C++ code
typedef struct {//Registr provedeni funkcí při ukončení práce s ovladačem giveio.sys
unsigned r_OpenSCManager
: 1; /*bit 0 --> */
unsigned r_DriverStop
: 1; /*bit 1 --> */
unsigned r_DriverRemove
: 1; /*bit 2 --> */
unsigned r_RegDeleteKey
: 1; /*bit 3 --> */
unsigned r_Existing_Driver
: 1; /*bit 4 --> */
unsigned r_UnLock
: 1; /*bit 5 --> */
unsigned r_Lock
: 1; /*bit 6 --> */
}RETURN_CODE
;
- Bit 0 -> Nejde otevřít servisní kontrolní manažer.
- Bit 1 -> Nejde zastavit služba giveio.sys, pravděpodobné tuto službu využívá další program.
- Bit 2 -> Nejde Odstranit služba giveio.sys, pravděpodobné tuto službu využívá další program.
- Bit 3 -> Nejde uklidit registry.
- Bit 4 -> Selhala funkce Existing_Driver.
- Bit 5 -> Nebyla provedena před voláním funkce Lock_ funkce UnLock_
- Bit 6 -> Funkce Lock_ lze volat jen jednou a to na konci programu.
Návratový parametr funkce je to samé co vrátí struktura RETURN_CODE ale už se nejedná o strukturu ale datový typ unsigned int.
Funkce Existing_Driver :
C++ code
int WINAPI Existing_Driver
(strucEXISTING_DRIVER
*ExistingDriver
);
Po provedení funkce UnLock_ lze zavolat funkci Existing_Driver, která lépe informuje jak se podařila nainstalovat služba ovladače giveio.sys. Jednotlivé položky jsou přímo návratové hodnoty Win API funkcí CreateService a StartService
C++ code
typedef struct {//Existing_Driver
unsigned int DriverInstall
; //CreateService
unsigned int DriverStart
; //StartService
}strucEXISTING_DRIVER
;
Pokud funkce selže nebo program havaruje, tyto informace lze většinou zjistit z Win registru:
HKEY_CURRENT_USER\Control Panel\HaCeSOFT\AddressPort\Ovladac_Existuje
Po zavolání funkce Lock_ tyto informace už nejsou k dispozici.
Funkce OpenPort :
C++ code
int WINAPI OpenPort
(PORT_CONFIG
*PortConfig
);
typedef struct {//konfigurace portu
int DMA
; //out
int IRQ
; //out
int Type_Port
; //out
int adress
; //out
int range
; //in
PCHAR port
; //in
}PORT_CONFIG
;
Pomoci této funkce zjistíte fyzickou adresu zjišťovaného portu. Funkce OpenPort používá strukturu PORT_CONFIG, kde je patrné že jsou pouze dva parametry vstupní a zbytek funkce po úspěšném provedení dodá. Jako velice důležitý vstupní parametr je název portu, kde můžete se dotazovat na LPT1 až LPT 9 a COM1 až COM9. Názvy portu není třeba psát jen velkýma písmeny ale můžete použit jakoukoliv kombinaci velkých a malých písmen. Za tímto názvem je číslo požadovaného portu. Knihovna wwio.dll je určena pro práci s LPT porty počítače, to že dokáže zjistit fyzickou adresu COM portu je pouze vedlejší efekt, na komunikaci s COM porty existuje slušná sada API funkcí systému, proto tato knihovna wwio.dll nikterak nekomunikuje s COM porty. I když dokáže zjistit jeho fyzickou adresu.
Jako další vstupní parametr je funkce OpenPort v datové struktuře PORT_CONFIG je integer range, pro normální čínnost používejte hodnotu 0. Při zadání hodnoty 1 se vrátí jiná adresa portu, kde by se měly nacházet další konfigurační registry LPT portu.
Ostatní položky datové struktury PORT_CONFIG jsou už zjištěny funkcí OpenPort:
- DMA – hodnota dma kanálu.
- IRQ – číslo přerušení portu.
- Adress – je adresa LPT/COM portu.
- Type_Port
- – pokud obsahuje hodnotu 2, jedná se o port SPP nebo EPP.
- - pokud obsahuje hodnotu 4, jedna se o port ECP a jeho kombinace.
Funkce přímo vrací následující hodnoty:
- ErrorKod = 0 -- Vše je ok.
- ErrorKod = 1 -- Parametr range mimo rozsah.
- ErrorKod = 2 -- Požadovaný port NEEXISTUJE.
- ErrorKod = 3 -- Neplatné označení portu.
- ErrorKod = 4 -- Je indikována chyba z předchozí činnosti funkce OpenPort.
- ErrorKod = 5 -- Není provedena funkce UnLock.
Tytéž hodnoty dostanete při použiti funkce: Error_
Poznámka: funkce OpenPort není párová funkce, neexistuje něco jako ClosePort. Při ukončení programu se pouze provede funkce Lock();.
Funkce Error_ :
C++ code
int WINAPI Error_
(void);
Vrátí chybovou hlásku po právě provedené funkce z knihovny wwio.dll. U každé funkce je vyčet všech možných chyb, které můžou nastat.
Funkce ErrorEx :
C++ code
void WINAPI ErrorEx
(LPCWSTR text
);
Jako vstupní parametr je řetězec, který popisuje, co se vlastně stalo. Funkce ErrorEx() je pouze vylepšená API funkce: GetLastError(), která vrátí po jakékoliv provedení API funkce systému Windows jak funkce uspěla. Vylepšení se tyká toho, že se objeví okno kde je číslo chyby a navíc v jazyku systému i popsána tato chyba. Velmi to pomáhá ladit kód, když ihned vidíte, co se vlastně pokazilo. Ale doporučuji toto používat jen pro ladící účely, tak jak je tomu u makra _ASSERT, které existuje v kódu jen pro debugovací účely. Funkci ErrorEx ještě musíte doplnit podmínkami pro podmíněnou kompilaci. Případně si nesledující kód upravte. Zde je plný výpis funkce ErrorEx:
C++ code
void WINAPI ErrorEx
(LPCWSTR text
){
LPVOID lpMsgBuf
;
CAtlString sBuffer
;
int nGetLastError
;
_ASSERT
(NULL != text
);
FormatMessage
( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError
(),
MAKELANGID
(LANG_NEUTRAL, SUBLANG_DEFAULT
),
// Default language
(LPTSTR
) &lpMsgBuf,
0,
NULL);
nGetLastError
= GetLastError
();
sBuffer
= (LPCWSTR
)lpMsgBuf
;
sBuffer
= sBuffer
+ TEXT
("GetLastError Code: ");
sBuffer
= sBuffer
+ nGetLastError.
ToString();
MessageBox
(NULL, sBuffer, text, MB_OK
|MB_ICONSTOP
);
LocalFree
( lpMsgBuf
);
}
Funkce Wait, WaitEx :
C++ code
int WINAPI Wait
(unsigned int delka
);
int WINAPI WaitEx
(unsigned int delka
);
Jsou tu použity jen z historického důvodu, při další revizi kódu, budou pravděpodobné odstraněny.
Jak už sám název napovídá, jedná se o čekací funkce, kde čas zadáte v milisekundách. A podle toho funkce čeká.
Funkce Wait pracuje na principu počítaní strojového času, kde neustále cykluje ve smyčce a při zadání dlouhého času, se systém může neúměrně zpomalit. Ale na krátké časy v řádově desítek milisekund je funkce extrémně přesná, použijte tuto funkci na časování kritických úseků komunikace LPT portu. Funkce vrátí jak přesně dlouho čekala v milisekundách a nebo vrátí hodnotu 0, pokud selhala.
Funkce WaitEx je postavena na multimediálním časovači, který není tak přesný ale zato při čekání vrací zdroje systému. Funkce minimálně čeká jak je zadáno v parametru. A nejdéle jak potřebuje systém. Proto tato funkce není přesná. Ale zaleží a aktuálním stavu operačního systému, zda už předá po uplynutí stanoveného času prostředky programu zpět, který použil funkci WaitEx. Tato funkce vrátí hodnotu jak dlouho čekala. A nebo hodnotu 0 pokud neuspěla.
Funkce Write :
C++ code
int WINAPI Write
(unsigned short AdresaPortu,
int hodnota
);
Funkce zapíše hodnotu (byte) na adresu uvedenou v prvním parametru.
Sice druhy vstupní parametr je definován jako int, uvnitř funkce je konvertován na datový typ: byte.
Povolený rozsah druhého parametru je 0 až 255.
Při úspěšném zapsání hodnoty na požadovanou adresu, funkce vrátí, adresu kam skutečně zapsala nebo hodnotu -1, pokud selhala.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Zápis se neprovedl, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
Funkce Write_Data :
C++ code
int WINAPI Write_Data
(int hodnota
);
Zapíše hodnotu 0 až 255 do registru DATA, LPT portu který se otevřel pomocí funkce OpenPort.
Funkce v případě úspěchu vrátí adresu, kam zapsala, nebo -1 pokud selhala.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Zápis se neprovedl, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
- ErrorKod = 2 -- Zápis se neprovedl, je spatná adresa. Chyba ve funkci OpenPort. Zkuste použít range 1.
- ErrorKod = 3 -- Je indikována chyba z předchozí činnosti funkce OpenPort.
Funkce Write_Status :
C++ code
int WINAPI Write_Status
(int hodnota
);
Zapíše hodnotu 0 až 255 do registru STATUS, LPT portu který se otevřel pomocí funkce OpenPort.
Funkce v případě úspěchu vrátí adresu, kam zapsala, nebo -1 pokud selhala.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Zápis se neprovedl, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
- ErrorKod = 2 -- Zápis se neprovedl, je spatná adresa. Chyba ve funkci OpenPort. Zkuste použít range 1.
- ErrorKod = 3 -- Je indikována chyba z předchozí činnosti funkce OpenPort.
Funkce Write_Control :
C++ code
int WINAPI Write_Control
(int hodnota
);
Zapíše hodnotu 0 až 255 do registru CONTROL, LPT portu který se otevřel pomocí funkce OpenPort.
Funkce v případě úspěchu vrátí adresu, kam zapsala, nebo -1 pokud selhala.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Zápis se neprovedl, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
- ErrorKod = 2 -- Zápis se neprovedl, je spatná adresa. Chyba ve funkci OpenPort. Zkuste použít range 1.
- ErrorKod = 3 -- Je indikována chyba z předchozí činnosti funkce OpenPort.
Funkce Read :
C++ code
int WINAPI Read
(unsigned short AdresaPortu
);
Z adresy přečte hodnotu (byte) –> 0 až 255.
Funkce vždy vrátí, co přečetla. Pokud funkce neuspěla, vrátí hodnotu 0.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Čtení se nezdařilo, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
Funkce Read_Data :
C++ code
int WINAPI Read_Data
(void);"
Přečte hodnotu 0 až 255 do registru DATA, LPT portu který se otevřel pomocí funkce OpenPort.
Funkce v případě úspěchu vrátí, co přečetla, nebo 0 pokud neuspěla.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Čtení se nezdařilo, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
- ErrorKod = 2 -- Čtení se nezdařilo, je spatná adresa.
- ErrorKod = 3 -- Je indikována chyba z předchozí činnosti funkce OpenPort.
Funkce Read_Status :
C++ code
int WINAPI Read_Status
(void);
Přečte hodnotu 0 až 255 do registru STATUS, LPT portu který se otevřel pomocí funkce OpenPort.
Funkce v případě úspěchu vrátí, co přečetla, nebo 0 pokud neuspěla.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Čtení se nezdařilo, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
- ErrorKod = 2 -- Čtení se nezdařilo, je spatná adresa.
- ErrorKod = 3 -- Je indikována chyba z předchozí činnosti funkce OpenPort.
Funkce Read_Control :
C++ code
int WINAPI Read_Control
(void);
Přečte hodnotu 0 až 255 do registru CONTROL, LPT portu který se otevřel pomocí funkce OpenPort.
Funkce v případě úspěchu vrátí, co přečetla, nebo 0 pokud neuspěla.
Při použití funkce Error_ vrátí následující hodnoty:
- ErrorKod = 0 -- Vše je OK.
- ErrorKod = 1 -- Čtení se nezdařilo, nelze otevřít giveio.sys ovladač. Pravděpodobně jste neprovedli funkci UnLock();
- ErrorKod = 2 -- Čtení se nezdařilo, je spatná adresa.
- ErrorKod = 3 -- Je indikována chyba z předchozí činnosti funkce OpenPort.
Deklarace funkci v cecku:
C++ code
//************************************************************
#define DllImport __declspec(dllimport)
extern "C"
{
DllImport
unsigned int WINAPI Lock_
(__out RETURN_CODE
* ReturnCode
= NULL);
DllImport
int WINAPI Existing_Driver
(__out EXISTING_DRIVER
* ExistingDriver
);
DllImport
int WINAPI UnLock_
(void);
DllImport
int WINAPI Error_
(void);
DllImport
int WINAPI Write_Data
(__in
int hodnota
);
DllImport
int WINAPI Write_Status
(__in
int hodnota
);
DllImport
int WINAPI Write_Control
(__in
int hodnota
);
DllImport
int WINAPI Write
(__in
int AdresaPortu,__in
int hodnota
);
DllImport
int WINAPI Read
(__out
int AdresaPortu
);
DllImport
int WINAPI Read_Data
(void);
DllImport
int WINAPI Read_Status
(void);
DllImport
int WINAPI Read_Control
(void);
DllImport
int WINAPI OpenPort
(__inout CONFIG_PORT
* Port_Config
);
DllImport
void WINAPI ErrorEx
(__in LPCWSTR text
);
DllImport
int WINAPI Wait
(unsigned int delka
);
DllImport
int WINAPI WaitEx
(unsigned int delka
);
}
//************************************************************
Deklarace struktur v Cecku:
C++ code
//************************************************************
typedef struct {
int DMA
; //out
int IRQ
; //out
int Type_Port
; //out
int adress
; //out
int range
; //in
PCHAR port
; //in
}CONFIG_PORT
;
typedef struct {//Existing_Driver
unsigned int DriverInstall
; //out
unsigned int DriverStart
; //out
}EXISTING_DRIVER
;
typedef struct {//Registr provedeni funkci pri ukoncovani prace s ovladacem giveio.sys
unsigned r_OpenSCManager
: 1; /*bit 0 --> */
unsigned r_DriverStop
: 1; /*bit 1 --> */
unsigned r_DriverRemove
: 1; /*bit 2 --> */
unsigned r_RegDeleteKey
: 1; /*bit 3 --> */
unsigned r_Existing_Driver
: 1; /*bit 4 --> */
unsigned r_UnLock
: 1; /*bit 5 --> */
unsigned r_Lock
: 1; /*bit 6 --> */
}RETURN_CODE
;
//************************************************************
Deklarace funkci ve Visual Basicu Net:
vb.net code
Private Declare Function Lock_
Lib "wwio.dll" (ByRef ReturnCode
As RETURN_CODE
) As UInteger 'Zavre giveio.sys ovladac.
Private Declare Function UnLock_
Lib "wwio.dll" () As Integer 'Otevre giveio.sys ovladac.
Private Declare Function Existing_Driver
Lib "wwio.dll" (ByRef ExistingDriver
As strucEXISTING_DRIVER
) As Integer
Private Declare Function OpenPort
Lib "wwio.dll" (ByRef Port_Config
As PORT_CONFIG
) As Integer REM zjisti parametry dotazovaneho portu
Private Declare Function Write
Lib "wwio.dll" (ByVal Port
As Integer,
ByVal Data
As Byte) As Integer
Private Declare Function Write_Data
Lib "wwio.dll" (ByVal Data
As Byte) As Integer
Private Declare Function Write_Status
Lib "wwio.dll" (ByVal Data
As Byte) As Integer
Private Declare Function Write_Control
Lib "wwio.dll" (ByVal Data
As Byte) As Integer
Private Declare Function Read
Lib "wwio.dll" (ByVal Port
As Short) As Integer
Private Declare Function Read_Data
Lib "wwio.dll" () As Integer
Private Declare Function Read_Status
Lib "wwio.dll" () As Integer
Private Declare Function Read_Control
Lib "wwio.dll" () As Integer
Private Declare Function ErrorEx
Lib "wwio.dll" (ByVal text
As String) As Integer
Private Declare Function Error_
Lib "wwio.dll" () As Integer
Private Declare Function Wait
Lib "wwio.dll" (ByVal delka
As Short) As Integer
Private Declare Function WaitEx
Lib "wwio.dll" (ByVal delka
As Short) As Integer
Deklarace struktur ve Visual Basic Net:
vb.net code
Public Structure PORT_CONFIG
Dim DMA
As Integer
Dim IRQ
As Integer
Dim Type_Port
As Integer
Dim adress
As Integer
Dim range
As Integer
Dim port
As String
End Structure
Private Structure strucEXISTING_DRIVER
Dim DriverInstall
As UInteger
Dim DriverStart
As UInteger
End Structure
Private Structure RETURN_CODE
Dim r_OpenSCManager
As Boolean
Dim r_DriverStop
As Boolean
Dim r_DriverRemove
As Boolean
Dim r_RegDeleteKey
As Boolean
Dim r_Existing_Driver
As Boolean
Dim r_UnLock
As Boolean
Dim r_Lock
As Boolean
End Structure
Ukazkový kód ve Visual Basicu Net:
vb.net code
Option Strict Off
Option Explicit
On
Module Demo_wwio
' Dne 28.3.2009
' By HaCeSOFT
' Pavel Prochazka
' hacesoft@mujmail.cz
' www.prochazka.zde.cz
Public Structure PORT_CONFIG
Dim DMA
As Integer
Dim IRQ
As Integer
Dim Type_Port
As Integer
Dim adress
As Integer
Dim range
As Integer
Dim port
As String
End Structure
Private Structure strucEXISTING_DRIVER
Dim DriverInstall
As UInteger
Dim DriverStart
As UInteger
End Structure
Private Structure RETURN_CODE
Dim r_OpenSCManager
As Boolean
Dim r_DriverStop
As Boolean
Dim r_DriverRemove
As Boolean
Dim r_RegDeleteKey
As Boolean
Dim r_Existing_Driver
As Boolean
Dim r_UnLock
As Boolean
Dim r_Lock
As Boolean
End Structure
Private Declare Function Lock_
Lib "wwio.dll" (ByRef ReturnCode
As RETURN_CODE
) As UInteger 'Zavre giveio.sys ovladac.
Private Declare Function UnLock_
Lib "wwio.dll" () As Integer 'Otevre giveio.sys ovladac.
Private Declare Function Existing_Driver
Lib "wwio.dll" (ByRef ExistingDriver
As strucEXISTING_DRIVER
) As Integer
Private Declare Function OpenPort
Lib "wwio.dll" (ByRef Port_Config
As PORT_CONFIG
) As Integer REM zjisti parametry dotazovaneho portu
Private Declare Function Write
Lib "wwio.dll" (ByVal Port
As Integer,
ByVal Data
As Byte) As Integer
Private Declare Function Write_Data
Lib "wwio.dll" (ByVal Data
As Byte) As Integer
Private Declare Function Write_Status
Lib "wwio.dll" (ByVal Data
As Byte) As Integer
Private Declare Function Write_Control
Lib "wwio.dll" (ByVal Data
As Byte) As Integer
Private Declare Function Read
Lib "wwio.dll" (ByVal Port
As Short) As Integer
Private Declare Function Read_Data
Lib "wwio.dll" () As Integer
Private Declare Function Read_Status
Lib "wwio.dll" () As Integer
Private Declare Function Read_Control
Lib "wwio.dll" () As Integer
Private Declare Function ErrorEx
Lib "wwio.dll" (ByVal text
As String) As Integer
Private Declare Function Error_
Lib "wwio.dll" () As Integer
Private Declare Function Wait
Lib "wwio.dll" (ByVal delka
As Short) As Integer
Private Declare Function WaitEx
Lib "wwio.dll" (ByVal delka
As Short) As Integer
Sub Main
()
Dim rnt
As Integer
Dim rnt1
As Integer
Dim Port_Config
As PORT_CONFIG
Dim ExistingDriver
As strucEXISTING_DRIVER
Dim Reg
As String = 255
Dim Data
As Integer
Dim k
As Integer
Dim title
As String
Dim adresa
As Integer
Port_Config
.range = 0
Port_Config
.port = "LPT1"
REM title
= My
.Application.Info.Title
title
= "Demo WwIo.Dll"
k
= UnLock_
()
rnt
= Unlock_Hlaseni
(Error_
(), title
)
rnt1
= Existing_Driver
(ExistingDriver
)
If k
= 0 Then
If rnt1
= 1 Then REM fnkce se provedla v spravne
If rnt
= 1 Then
REM zde se vypise presny stav ovladace giveio
.sys
MsgBox("Zde se podívejte do MSDN libraty na funkci CreateService která vrátila tuto hodnotu:" & ExistingDriver
.DriverInstall, MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
MsgBox("Zde se podívejte do MSDN libraty na funkci StartService která vrátila tuto hodnotu:" & ExistingDriver
.DriverStart, MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
End If
If k
= 0 Then
'rnt = Cekat(10000) 'Cekat 10s - Jedna se o přesnou čekací rutinu, která zatíží procesor na 100%!
'rnt = CekatEx(10000) 'Cekat 10s - Tato funkce používá multimediální časovač, po celou dobu čekání se nezatěžuje procesor.
'********************************************************************************
'Zapise hodnotu 1 na adresu LPT1 + Base0.
rnt
= OpenPort
(Port_Config
)
OpenPort_hlaseni
(rnt, Port_Config, title
)
If rnt
= 0 Then REM vse je ok
.
Data = 1
adresa
= Write_Data
(Data
)
WriteRead_Hlaseni
(Error_
(), title
)
If Error_
() = 0 Then
MsgBox("Hodnotu: $" & Hex(Data
) & " jsem zapsal na adresu: $" & Hex(adresa
), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
'Zjisti typ portu:
'return 2 -> jednase o port SPP nebo EPP
'return 4 -> jedna se o port ECP a jeho kombinace
rnt
= Port_Config
.Type_Port
If rnt
<> -1 Then
If rnt
= 2 Then
MsgBox("Port " & Port_Config
.port & " je typu SPP nebo EPP.", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
If rnt
= 4 Then
MsgBox("Port " & Port_Config
.port & " je typu ECP.", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
End If
'Zjisti IRQ portu.
rnt
= Port_Config
.IRQ
If rnt
<> -1 Then
MsgBox("Port " & Port_Config
.port & " používá IRQ číslo: " & Hex(rnt
), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
'Zjisti DMA portu.
'pokud je port typu SPP nebo EPP tak DMA prenosy nejdou uskutecnit!
rnt
= Port_Config
.DMA
If rnt
<> -1 Then
MsgBox("Port " & Port_Config
.port & " používá DMA číslo: " & Hex(rnt
), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
Else
MsgBox("Port " & Port_Config
.port & " je typu SPP nebo EPP a tudiz neexistuje DMA!!!", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
'Precte hodnotu z adresy LPT1 + Base0 a ulozi do promenne k.
k
= Read_Data
()
WriteRead_Hlaseni
(Error_
(), title
)
If Error_
= 0 Then
MsgBox("Z požadované adresy ($" & Hex(adresa
) & ") jsem přečetl hodnotu: $" & Hex(k
), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
End If
'********************************************************************************
Port_Config
.range = 0
Port_Config
.port = "Com1"
rnt
= OpenPort
(Port_Config
)
OpenPort_hlaseni
(rnt, Port_Config, title
)
If rnt
= 0 Then
MsgBox("Port " & Port_Config
.port & " má adresu: $" & Hex(Port_Config
.adress), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
'********************************************************************************
' Ted budem pracovat s portem LPT2!!!.
Port_Config
.range = 0
Port_Config
.port = "Lpt2"
rnt
= OpenPort
(Port_Config
)
OpenPort_hlaseni
(rnt, Port_Config, title
)
'Standartne na PC LPT2 neni, tudis vrati hodnotu -1.
If rnt
= 0 Then
MsgBox("Port " & Port_Config
.port & " má adresu: $" & Hex(rnt
), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
'Zapise hodnotu 255 na adresu LPT2 + Base0.
Data
= 255
adresa
= Write_Data
(Data
)
WriteRead_Hlaseni
(Error_
(), title
)
If Error_
() = 0 Then
MsgBox("Hodnotu: $" & Hex(Data
) & " jsem zapsal na adresu: $" & Hex(adresa
), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
'Precte hodnotu z adresy LPT2 + Base0 a ulozi do promenne k.
' nasledujici prikaz precte hodnotu 255 z LPT1!
k
= Read_Data
()
WriteRead_Hlaseni
(Error_
(), title
)
If Error_
() = 0 Then
MsgBox("Z požadované adresy (" & adresa
& "+ Base0) jsem přečetl hodnotu: $" & Hex(k
), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
End If
'********************************************************************************
'Po ukonceni prace s porty.
Dim ReturnCode
As RETURN_CODE
k
= Lock_
(ReturnCode
)
REM k
= Lock_
()
Lock_Hlaseni
(k, title
)
End If
End If
End Sub
Sub OpenPort_hlaseni
(ByVal rnt
As Integer,
ByRef Port_Config
As PORT_CONFIG,
ByRef title
As String)
REM // ErrorKod
= 0 -- Vse je ok
.
REM // ErrorKod
= 1 -- Paramet range mimo rozsah
.
REM // ErrorKod
= 2 -- Pozadovaný port NEEXISTUJE
.
REM // ErrorKod
= 3 -- Neplatne oznaceni portu
.
REM // ErrorKod
= 4 -- Je indikovana chyba z predchozi cinnosti funkce OpenPort
.
REM // ErrorKod
= 5 -- Neni provedena funkce UnLock
.
If rnt
= 1 Then
MsgBox("Parametr range Portu " & Port_Config
.port & " je mimo dovolený rozsah!", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
ElseIf rnt
= 2 Then
MsgBox("Požadovaný port " & Port_Config
.port & " neexistuje!", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
ElseIf rnt
= 3 Then
MsgBox("Parametr " & Port_Config
.port & " není platné označení fyzického portu!", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
ElseIf rnt
= 4 Then
MsgBox("Je indikována chyba z předchozí činnosti funkce OpenPort", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
ElseIf rnt
= 5 Then
MsgBox("Před použitím funkce OpenPort prosím nejprve použijte funkci UnLock", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
End If
End Sub
Function Unlock_Hlaseni
(ByVal rnt
As Integer,
ByRef title
As String)
REM //ErrorKod
= 0 -- Vše je OK
.
REM //ErrorKod
= -1 -- Funkce selhala
.
REM //ErrorKod
= 1 -- Nelze najit soubor GiveIO
.sys.
REM //ErrorKod
= 2 -- Nejde nainstalovat giveio
.sys ovladač
.
REM //ErrorKod
= 3 -- Nejde spustit giveio
.sys ovladač
.
REM //ErrorKod
= 4 -- Nejde otevrit OpenSCManager
.
REM //ErrorKod
= 12 -- ERROR_FILE_NOT_FOUND, toto je chyba funkce DriverStart, provedte restart pc a smazte v registrech retezec giveio
REM //ErrorKod
= 13 -- ERROR_PATH_NOT_FOUND, toto je chyba funkce DriverStart, provedte restart pc a smazte v registrech retezec giveio
REM //ErrorKod
= 183 – Nelze vytvořit soubor, který již existuje
. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále
.
REM //ErrorKod
= 1072 – Zadané zařízení je určeno na odstranění
. Zkuste to znovu
.
REM //ErrorKod
= 1073 – Zadaná služba již existuje
. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále
.
REM //ErrorKod
= 1056 - Instance té
to služ
by je již spuštěna
. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále
.
Unlock_Hlaseni = 0
Select Case rnt
Case -1
MsgBox("Funkce UnLock selhala", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
Case 1
MsgBox("Nelze najít soubor GiveIo.sys", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Case 2
MsgBox("Nejde nainstalovat GiveIo.sys", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Case 3
MsgBox("Nejde spustit GiveIo.sys", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
Case 4
MsgBox("Nejde otevrit OpenSCManager" + Chr(13) _
+ "V UAC nastavte execution level na reqire Administrator, toto se hlavně týká WinVista " + Chr(13) _
, MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Case 12
MsgBox("Funkce DriverStart hlasi: ERROR_FILE_NOT_FOUND" + Chr(13) _
+ "toto je chyba funkce DriverStart, provedte restart pc a smazte v registrech retezec giveio" _
, MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
Case 13
MsgBox("Funkce DriverStart hlasi: ERROR_PATH_NOT_FOUND" + Chr(13) _
+ "toto je chyba funkce DriverStart, provedte restart pc a smazte v registrech retezec giveio" _
, MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
Case 183
MsgBox("Nelze vytvořit soubor, který již existuje. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále.", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
Case 1072
MsgBox("Zadané zařízení je určeno na odstranění. Zkuste to znovu", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
Case 1073
MsgBox("Zadaná služba již existuje. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále.", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
Case 1056
MsgBox("Instance této služby je již spuštěna. Nejedna se o chybu ale o upozorněni, program muže pokračovat dále.", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Unlock_Hlaseni
= 1
End Select
End Function
Sub WriteRead_Hlaseni
(ByVal rnt
As Integer,
ByRef title
As String)
REM //ErrorKod
= 0 -- Vše je OK
.
REM //ErrorKod
= 1 -- Zápis se neprovedl, nelze otevřít giveio
.sys ovladač
. Selhala funkce CreateFile, nebo jse neprovedli funkci UnLock
();
REM //ErrorKod
= 2 -- Zápis se neprovedl, je spatná adresa
.
REM //ErrorKod
= 3 -- Je indikovana chyba z predchozi cinnosti funkce OpenPort
Select Case rnt
Case 1
MsgBox("Zápis se neprovedl, nelze otevřít giveio.sys ovladač. Selhala funkce CreateFile, nebo jse neprovedli funkci UnLock()", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Case 2
MsgBox("Zápis se neprovedl, je spatná adresa.", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
Case 3
MsgBox("Je indikovana chyba z predchozi cinnosti funkce OpenPort", MsgBoxStyle
.OkOnly + MsgBoxStyle
.Critical, title
)
End Select
End Sub
Sub Lock_Hlaseni
(ByVal rnt
As Integer,
ByRef title
As String)
REM typedef struct
{//Registr provedeni funkci pri ukoncovani prace s ovladacem giveio
.sys
REM unsigned r_OpenSCManager :
1;
/*bit
0 --> */
REM unsigned r_DriverStop :
1;
/*bit
1 --> */
REM unsigned r_DriverRemove :
1;
/*bit
2 --> */
REM unsigned r_RegDeleteKey :
1;
/*bit
3 --> */
REM unsigned r_Existing_Driver :
1;
/*bit
4 --> */
REM unsigned r_UnLock :
1;
/*bit
5 --> */
REM unsigned r_Lock :
1;
/*bit
6 --> */
REM }RETURN_CODE;
REM rc_OpenSCManager 0x1
//hodnota je
true, kdyz nelze uspesbě použít funkci OpenSCManager
REM rc_DriverStop 0x2
//hodnota je
true, když nelze zastavit giveio
.sys ovladač
(nejaký další program ho používá
)
REM rc_DriverRemove 0x4
//hodnota je
true, když nelze odstranit giveio
.sys ovladač
(nejaký další program ho používá
)
REM rc_RegDeleteKey 0x8
//hodnota je
true, když nelze uklidit systemové registry
REM rc_Existing_Driver 0x10
//hodnota je
true, když selhala funkce Existing_Driver
REM rc_UnLock 0x20
//hodnota je
true, když není provedena funkce Unlock
REM rc_Lock 0x40
//hodnota je
true, když už jednou jste použily funkci Lock
If rnt
<> 0 Then
MsgBox("Když návratová hodnota není nula neznamená že se něco pokazilo" + Chr(13) _
+ "Hodnotu " & rnt
& " je potřeba analyzovat na binární úrovni:" + Chr(13) _
+ "typedef struct {//Registr provedeni funkci při ukončení komunikace s ovladačem giveio.sys" + Chr(13) _
+ "unsigned r_OpenSCManager : 1; /*bit 0 --> hodnota je true, když nelze úspěšně použít funkci OpenSCManager *" + Chr(13) _
+ "unsigned r_DriverStop : 1; /*bit 1 --> hodnota je true, když nelze zastavit giveio.sys ovladač (nějaký další program ho používá) *" + Chr(13) _
+ "unsigned r_DriverRemove : 1; /*bit 2 --> hodnota je true, když nelze odstranit giveio.sys ovladač (nějaký další program ho používá) *" + Chr(13) _
+ "unsigned r_RegDeleteKey : 1; /*bit 3 --> hodnota je true, když nelze uklidit systémové registry *" + Chr(13) _
+ "unsigned r_Existing_Driver : 1; /*bit 4 --> hodnota je true, když selhala funkce Existing_Driver *" + Chr(13) _
+ "unsigned r_UnLock : 1; /*bit 5 --> hodnota je true, když není provedena funkce Unlock *" + Chr(13) _
+ "unsigned r_Lock : 1; /*bit 6 --> hodnota je true, když už jednou jste použily funkci Lock *" + Chr(13) _
+ "}RETURN_CODE;" + Chr(13), MsgBoxStyle
.OkOnly + MsgBoxStyle
.Information, title
)
End If
End Sub
End Module
Dále je třeba k projektu v C nebo C++ přilinkovat tento wwio.lib soubor.
Stáhnout soubor wwio_dll.zip
Archív wwio.dll obsahuje tři adresáře: Debug, Release a Test.
Knihovna wwio.dll je dodávána kromě finální verze v adresáři release, tak i pro testovací účely (adresář debug). Toto testovací knihovnu opravdu nepoužívejte ve finálních verzích projektu. Obsahuje nadbytečný testovací kód a všechny vstupní parametru se kontroluji makrem _ASSERT. Pokud program se chová divně a nevíte, kde se nachází problém, použijte knihovnu z adresáře debug a pokud Váš program dodává špatně parametry, knihovna wwio.dll vám to dá patřičně najevo že něco je špatně.
Kromě samotné knihovny v obou adresářů se nacházejí i zkompilované testovací projekty.
Adresář test: obsahuje dva testovací projekty jak pro céčko tak i visuál basic. Projekt pro céčko je opravdu velice hrubý testovací kód. Když ho spustíte plnou rychlostí, tak nic zajímavého neuvidíte. Doporučuji v souboru DemoKnihovnaDll.cpp přidat na vhodné místo breakpoint a potom kód krokovat. Když se podíváte jak je testovací aplikace napsaná, tak opravdu slouží jen pro hrubé zjištění zda a jak knihovna wwio.dll funguje. Sami se můžete přesvědčit že tak jak je kód napsaný se opravdu program nepíše. Napsal jsem to pravě tak, abych našel potenciální chyby. Testovací program pro visuál basic je ukázkový program jak korektně pracovat s knihovnu wwio.dll. Visuál basic vždy používám pro svou jednoduchost pro grafický interface a testovací účely. Knihovny potom už píšu v cecku. To jen pro ty co nenávidí visuál basic a divíse proč jsem zbastlil něco tak odporného v céčku.
Prozatím programy pracující s LPT portem používají starou verzi knihovny pro přístup na paralelní port. A nelze použít knihovnu wwio.dll bez úpravy stávajícího programu. Nemluvně o tom že se cely projekt musí předělat na platformu NET.
Ujednání:
Tento archív můžete neomezeně šířit pouze kompletní!
Tento archív se nesmí za úplatu kopírovat a šířit.
Nesmí být použit v KOMERČNÍCH projektech bez souhlasu autora.
Pokud používáte tyto knihovny ve svém programu, už nemusíte přikládat kompletní archív ani dokumentaci. Postačí, ze uvedete zdroj a odkaz na server www.prochazka.zde.cz těchto knihoven v dokumentaci o vašem programu nebo aboutu (O Aplikaci ...).
Děkuji, že používáte tyto produkty.
Autor ovladaču Giveio.SYS je:
Dale Roberts, Direct I/O and Windows NT.
ftp://ftp.mfi.com/pub/windev/1995/may95.zip