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; 
}