www.pudn.com > liuqudong.zip > GenDriver.cpp
//====================================================================== // GenDriver - Generic stream device driver for Windows CE // // Written for the book Programming Windows CE // Copyright (C) 2003 Douglas Boling //====================================================================== #include// For all that Windows stuff #include "GenDriver.h" // Local program includes // // Globals // HINSTANCE hInst; // DLL instance handle // // Debug zone support // #ifdef DEBUG // Used as a prefix string for all debug zone messages. #define DTAG TEXT ("GENDrv: ") // Debug zone constants #define ZONE_ERROR DEBUGZONE(0) #define ZONE_WARNING DEBUGZONE(1) #define ZONE_FUNC DEBUGZONE(2) #define ZONE_INIT DEBUGZONE(3) #define ZONE_DRVCALLS DEBUGZONE(4) #define ZONE_EXENTRY (ZONE_FUNC | ZONE_DRVCALLS) // Debug zone structure DBGPARAM dpCurSettings = { TEXT("GenDriver"), { TEXT("Errors"),TEXT("Warnings"),TEXT("Functions"), TEXT("Init"),TEXT("Driver Calls"),TEXT("Undefined"), TEXT("Undefined"),TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"), TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"), TEXT("Undefined") }, 0x0003 }; #endif //DEBUG //====================================================================== // DllMain - DLL initialization entry point // BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved) { hInst = (HINSTANCE)hinstDLL; switch (dwReason) { case DLL_PROCESS_ATTACH: DEBUGREGISTER(hInst); // Improve performance by passing on thread attach calls DisableThreadLibraryCalls (hInst); break; case DLL_PROCESS_DETACH: DEBUGMSG(ZONE_INIT, (DTAG TEXT("DLL_PROCESS_DETACH\r\n"))); break; } return TRUE; } //====================================================================== // GEN_Init - Driver initialization function // #if (_WIN32_WCE_ > 300) DWORD GEN_Init (DWORD dwContext, LPCVOID lpvBusContext) { #else DWORD GEN_Init (DWORD dwContext) { #endif PDRVCONTEXT pDrv; DEBUGMSG (ZONE_INIT | ZONE_EXENTRY, (DTAG TEXT("GEN_Init++ dwContex:%x\r\n"), dwContext)); // Allocate a drive instance structure. pDrv = (PDRVCONTEXT)LocalAlloc (LPTR, sizeof (DRVCONTEXT)); if (pDrv) { // Initialize structure. memset ((PBYTE) pDrv, 0, sizeof (DRVCONTEXT)); pDrv->dwSize = sizeof (DRVCONTEXT); // Read registry to determine the size of the disk. GetConfigData (dwContext); } else DEBUGMSG (ZONE_INIT | ZONE_ERROR, (DTAG TEXT("GEN_Init failure. Out of memory\r\n"))); DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GEN_Init-- pDrv: %x\r\n"), pDrv)); return (DWORD)pDrv; } //====================================================================== // GEN_Deinit - Driver de-initialization function // BOOL GEN_Deinit (DWORD dwContext) { PDRVCONTEXT pDrv = (PDRVCONTEXT) dwContext; DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("GEN_Deinit++ dwContex:%x\r\n"), dwContext)); if (pDrv && (pDrv->dwSize == sizeof (DRVCONTEXT))) { // Free the driver state buffer. LocalFree ((PBYTE)pDrv); } DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GEN_Deinit--\r\n"))); return TRUE; } //====================================================================== // GEN_Open - Called when driver opened // DWORD GEN_Open (DWORD dwContext, DWORD dwAccess, DWORD dwShare) { PDRVCONTEXT pDrv = (PDRVCONTEXT) dwContext; DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("GEN_Open++ dwContext: %x\r\n"), dwContext)); // Verify that the context handle is valid. if (pDrv && (pDrv->dwSize != sizeof (DRVCONTEXT))) { DEBUGMSG (ZONE_ERROR, (DTAG TEXT("GEN_Open failed\r\n"))); return 0; } // Count the number of opens. InterlockedIncrement ((long *)&pDrv->nNumOpens); DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GEN_Open--\r\n"))); return (DWORD)pDrv; } //====================================================================== // GEN_Close - Called when driver closed // BOOL GEN_Close (DWORD dwOpen) { PDRVCONTEXT pDrv = (PDRVCONTEXT) dwOpen; DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("GEN_Close++ dwOpen: %x\r\n"), dwOpen)); if (pDrv && (pDrv->dwSize != sizeof (DRVCONTEXT))) { DEBUGMSG (ZONE_FUNC | ZONE_ERROR, (DTAG TEXT("GEN_Close failed\r\n"))); return 0; } if (pDrv->nNumOpens) pDrv->nNumOpens--; DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GEN_Close--\r\n"))); return TRUE; } //====================================================================== // GEN_Read - Called when driver read // DWORD GEN_Read (DWORD dwOpen, LPVOID pBuffer, DWORD dwCount) { DWORD dwBytesRead = 0; DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("GEN_Read++ dwOpen: %x\r\n"), dwOpen)); DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GEN_Read--\r\n"))); return dwBytesRead; } //====================================================================== // GEN_Write - Called when driver written // DWORD GEN_Write (DWORD dwOpen, LPVOID pBuffer, DWORD dwCount) { DWORD dwBytesWritten = 0; DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("GEN_Write++ dwOpen: %x\r\n"), dwOpen)); DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GEN_Write--\r\n"))); return dwBytesWritten; } //====================================================================== // GEN_Seek - Called when SetFilePtr called // DWORD GEN_Seek (DWORD dwOpen, long lDelta, WORD wType) { DEBUGMSG (ZONE_EXENTRY,(DTAG TEXT("GEN_Seek++ dwOpen:%x %d %d\r\n"), dwOpen, lDelta, wType)); DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("GEN_Seek--\r\n"))); return 0; } //====================================================================== // GEN_IOControl - Called when DeviceIOControl called // DWORD GEN_IOControl (DWORD dwOpen, DWORD dwCode, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut, DWORD *pdwBytesWritten) { PDRVCONTEXT pState; DWORD err = ERROR_INVALID_PARAMETER; DEBUGMSG (ZONE_EXENTRY, (DTAG TEXT("GEN_IOControl++ dwOpen: %x dwCode: %x\r\n"), dwOpen, dwCode)); pState = (PDRVCONTEXT) dwOpen; switch (dwCode) { // Insert IOCTL codes here. default: DEBUGMSG (ZONE_ERROR, (DTAG TEXT("GEN_IOControl: unknown code %x\r\n"), dwCode)); return FALSE; } SetLastError (err); DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GEN_IOControl--\r\n"))); return TRUE; } //====================================================================== // GEN_PowerDown - Called when system suspends // // NOTE: No kernel calls, including debug messages, can be made from // this call. // void GEN_PowerDown (DWORD dwContext) { return; } //====================================================================== // GEN_PowerUp - Called when resumes // // NOTE: No kernel calls, including debug messages, can be made from // this call. // void GEN_PowerUp (DWORD dwContext) { return; } //---------------------------------------------------------------------- // GetConfigData - Get the configuration data from the registry. // DWORD GetConfigData (DWORD dwContext) { int nLen, rc; DWORD dwLen, dwType, dwSize = 0; HKEY hKey; TCHAR szKeyName[256], szPrefix[8]; DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetConfigData++\r\n"))); nLen = 0; // If ptr < 65K, it's a value, not a pointer. if (dwContext < 0x10000) { return -1; } else { __try { nLen = lstrlen ((LPTSTR)dwContext); } __except (EXCEPTION_EXECUTE_HANDLER) { nLen = 0; } } if (!nLen) { DEBUGMSG (ZONE_ERROR, (DTAG TEXT("dwContext not a ptr\r\n"))); return -2; } // Open the Active key for the driver. rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPTSTR)dwContext,0, 0, &hKey); if (rc == ERROR_SUCCESS) { // Read the key value. dwLen = sizeof(szKeyName); rc = RegQueryValueEx (hKey, TEXT("Key"), NULL, &dwType, (PBYTE)szKeyName, &dwLen); RegCloseKey(hKey); if (rc == ERROR_SUCCESS) rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE, (LPTSTR) dwContext, 0, 0, &hKey); if (rc == ERROR_SUCCESS) { // This driver doesn't need any data from the key, so as // an example, it just reads the Prefix value, which // identifies the three-char prefix (GEN) of this driver. dwLen = sizeof (szPrefix); rc = RegQueryValueEx (hKey, TEXT("Prefix"), NULL, &dwType, (PBYTE)szPrefix, &dwLen); RegCloseKey(hKey); } else DEBUGMSG (ZONE_ERROR, (TEXT("Error opening key\r\n"))); } else DEBUGMSG (ZONE_ERROR, (TEXT("Error opening Active key\r\n"))); DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetConfigData--\r\n"))); return 0; }