1 ESIMERKKIAJURI Tehdään virtuaalinen portti COM7, jota eri sovellukset voivat käyttää. Oletuksena tässä projektissa on, että olet asentanut PC:hen Microsoft embedded Visual C++ 3:n Windowsiin sekä Platform SDK:n siihen alustaan, johon haluat tehdä ajurin (H/PC 2000, H/PC Professional, Palmsize PC, Pocket PC). Saat ne Microsoftilta. Aina kuitenkin kannattaa asentaa ko. ohjelmistosta se uusin versio. Tällä hetkellä löytyy Microsoftilta jo kokeiluversio Windows CE 6:een (Windows Embedded CE 6.0), jossa on jopa Platform Builder mukana. Silloin sinun pitää kuitenkin asentaa myös Visual Studio 2005. Tässä materiaalissa esimerkkikoodi on tehty Pocket PC 2002 ympäristöön ARM prosesoriin. Toiseksi kone pitää olla yhteydessä Pocket PC:hen esim. Microsoftin ActiveSync:lla (esim. USB-liitännän kautta). Aloita embedded Visual C++:sta valitsemalla File, New, Projects. Valitse seuraava projektityyppi: Nimeä projekti nimelle Demo, kuten kuvassa. Valitse itsellesi sopiva CPU.
2 Seuraavaksi valitse kuten alla: Syntyneessä projektissa on tiedostossa Demo.cpp seuraavanlainen pääohjelma : #include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hmodule, DWORD ul_reason_for_call, LPVOID lpreserved ) return TRUE;
3 Lisää ennen DllMain funktiota seuraavat funktioiden esittelyt: #include "stdafx.h" declspec(dllexport) DWORD COM_Init(LPCTSTR pcontext, LPCVOID lpvbuscontext); declspec(dllexport) BOOL COM_Deinit( DWORD hdevicecontext ); declspec(dllexport) DWORD COM_Open( DWORD hdevicecontext, DWORD AccessCode, DWORD ShareMode ); declspec(dllexport) BOOL COM_Close( DWORD hopencontext ); declspec(dllexport) BOOL COM_IOControl( DWORD hopencontext, DWORD dwcode, PBYTE pbufin, DWORD dwlenin, PBYTE pbufout, DWORD dwlenout, PDWORD pdwactualout ); declspec(dllexport) void COM_PowerUp( DWORD hdevicecontext ); declspec(dllexport) void COM_PowerDown( DWORD hdevicecontext ); declspec(dllexport) DWORD COM_Read( DWORD hopencontext, LPVOID pbuffer, DWORD Count ); declspec(dllexport) DWORD COM_Write( DWORD hopencontext, LPCVOID pbuffer, DWORD Count ); declspec(dllexport) DWORD COM_Seek( DWORD hopencontext, long Amount, WORD Type ); BOOL APIENTRY DllMain( HANDLE hmodule, DWORD ul_reason_for_call, LPVOID lpreserved ) return TRUE; Muokkaa DllMain funktiota seuraavanlaiseksi: BOOL APIENTRY DllMain( HANDLE hmodule, DWORD ul_reason_for_call, LPVOID lpreserved ) switch ( ul_reason_for_call ) case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; return TRUE;
4 Seuraavaksi lisää seuraavan function toteutus DllMain funktion alapuolelle: declspec(dllexport) DWORD COM_Init( LPCTSTR pcontext, LPCVOID lpvbuscontext) DWORD dwport = 0; HKEY hkey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pcontext, 0, 0, &hkey) == ERROR_SUCCESS) TCHAR szdriverkey[255]; DWORD dwsize = 255; DWORD dwtype; if (RegQueryValueEx(hKey, L"Key", 0, &dwtype, (BYTE *)szdriverkey, &dwsize) == ERROR_SUCCESS) RegCloseKey(hKey); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szdriverkey, 0, 0, &hkey) == ERROR_SUCCESS) dwsize=4; if (RegQueryValueEx(hKey, L"ManagePort", 0, &dwtype, (BYTE *)&dwport, &dwsize)!= ERROR_SUCCESS) dwport = 0; RegCloseKey(hKey); if (dwport!= 0) dwmanageport = dwport; return DRV_CONTEXT; Lisää myös seuraavat vakiot ennen DllMain:ia: #define DRV_CONTEXT 0x1450 #define OPEN_CONTEXT 0x1451 HANDLE hcomm = INVALID_HANDLE_VALUE; DWORD dwmanageport = 1; Seuraavaksi lisää funktion COM_Deinit -toteutus: declspec(dllexport) BOOL COM_Deinit( DWORD hdevicecontext ) if (hdevicecontext!= DRV_CONTEXT) return FALSE; return TRUE;
5 Funktion COM_Open -toteutus: declspec(dllexport) DWORD COM_Open( DWORD hdevicecontext, DWORD AccessCode, DWORD ShareMode ) if (hdevicecontext!= DRV_CONTEXT) TCHAR szport[255]; swprintf(szport, L"COM%u", dwmanageport); hcomm = CreateFile( szport, AccessCode, ShareMode, NULL, OPEN_EXISTING, 0, NULL); MessageBox(NULL,szPort,L"Portti auki", MB_OK); if (hcomm == INVALID_HANDLE_VALUE) else return OPEN_CONTEXT; Funktion COM_Close toteutus: declspec(dllexport) BOOL COM_Close( DWORD hopencontext ) if (hopencontext!= OPEN_CONTEXT) BOOL bret = CloseHandle(hComm); hcomm = INVALID_HANDLE_VALUE; return bret;
6 Funktion COM_IOCOntrol toteutus: declspec(dllexport) BOOL COM_IOControl( DWORD hopencontext, DWORD dwcode, PBYTE pbufin, DWORD dwlenin, PBYTE pbufout, DWORD dwlenout, PDWORD pdwactualout ) if (hopencontext!= OPEN_CONTEXT) BOOL bret=deviceiocontrol( hcomm, dwcode, pbufin, dwlenin, pbufout, dwlenout, pdwactualout, NULL); return bret; Funktioiden COM_PowerUp ja COM_PowerDown toteutukset: declspec(dllexport) void COM_PowerUp( DWORD hdevicecontext ) declspec(dllexport) void COM_PowerDown( DWORD hdevicecontext ) Funktion COM_Read toteutus: declspec(dllexport) DWORD COM_Read( DWORD hopencontext, LPVOID pbuffer, DWORD Count ) if (hopencontext!= OPEN_CONTEXT) DWORD dwbytes = 0; ReadFile(hComm, pbuffer, Count, &dwbytes, NULL); return dwbytes;
7 Funktion COM_Write toteutus: declspec(dllexport) DWORD COM_Write( DWORD hopencontext, LPCVOID pbuffer, DWORD Count ) if (hopencontext!= OPEN_CONTEXT) DWORD dwbytes = 0; WriteFile(hComm, pbuffer, Count, &dwbytes, NULL); return dwbytes; Funktion COM_Seek toteutus: declspec(dllexport) DWORD COM_Seek( DWORD hopencontext, long Amount, WORD Type ) Lisää tiedosto Demo.def projektiisi. Sen sisältö on seuraavanlainen: LIBRARY EXPORTS Demo COM_Init COM_Deinit COM_Open COM_Close COM_Read COM_Write COM_Seek COM_IOControl COM_PowerDown COM_PowerUp Käännä ja linkitä projekti. Syntynyt Demo.dll pitää kopioida kohdelaitteen (tässä Pocket PC 2002) windows hakemistoon. Jos sinulla on ActiveSync yhteydessä sopivat asetukset ja myös kohdelaite on auki, tiedosto kopioituu automaattisesti (jos oikeat asetukset ovat päällä). Sen lisäksi sinun pitää jotenkin pystyä rekisteröimään kohdelaitteeseen vapaaseen rekisterin paikkaan esim. seuraavat arvot (laitteessa COM7 vapaa): HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial7 Dll = DemoDriver.dll FriendlyName = Demo Driver Index = 7 Order = 2 Prefix = COM ManagePort = 1
8 BuiltIn avaimen alle voidaan tehdä ladattavia omia ajureita. Tässä siis tehty avain Serial7, koska se ei ollut vielä kohdelaitteessa käytössä. Muistiin latautuneet ajurit näkyvät avaimen Active alla. Katso rekisteristä montako laitetta on kohdassa HKEY_LOCAL_MACHINE\Drivers\Active latautuneena (laske montako aliavainta siellä on). Kun ajuri on lisätty kohdelaitteen Windows hakemistoon ja em. Serial7 avaimen arvot on lisätty, buuttaa laite. Katso nyt HKEY_LOCAL_MACHINE\Drivers\Active kohdan aliavaimet. Tuliko yksi lisää? Voit tutkia myös embedded Visual C++:lla seuraavasta valikosta laitteesi rekisteriä, jos sinulla on laitteeseen ActiveSync yhteys: Valitse Connection, Add Connection rekisterieditorissa ja etsi sieltä laitteesi, jonka rekisteriä tutkit. Onko siellä seuraava aktiivinen avain?: Jos avain, näkyy, ajurisi on latautunut muistiin.
9 Alla vielä BuiltIn- avaimen arvot: