⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.cpp

📁 Intel PXA270 Wince5.0 BSP
💻 CPP
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

Module Name:  

driver.cpp

Abstract:  
    USB Human Interface Device (HID) class driver sample.

Functions:

Notes: 

--*/

// There are four warnings that I like from Warning level 4.  Since we build
// at warning level 3, I'm setting these four down to level 3 so I still get
// them.
// C4101 unrefrenced local variable
// C4705 statement has no effect
// C4706 assignment in conditional
#pragma warning (3 : 4101 4705 4706)

#include <windows.h>
#include <usbdi.h>
#include <hiddi.hpp>

#include "hid.hpp"

/* 
 * Debug Zones.
 */
#ifdef DEBUG

#define DBG_INIT                0x0001
#define DBG_ATTACH              0x0002
#define DBG_CONFIG              0x0004
#define DBG_REPORT              0x0008
#define DBG_MOUSE               0x0010
#define DBG_KEYBD               0x0020
#define DBG_JOYSTICK            0x0040
#define DBG_EVENTS              0x0080
#define DBG_FUNCTION            0x2000
#define DBG_WARNING             0x4000
#define DBG_ERROR               0x8000

DBGPARAM dpCurSettings = {
        TEXT("Hid"), {
        TEXT("Init"), TEXT("Attach"), TEXT("Config"), TEXT("Report"),
        TEXT("Mouse"), TEXT("Keyboard"), TEXT("Joystick"), TEXT("Events"),
        TEXT(""), TEXT(""), TEXT(""), TEXT(""),
        TEXT(""), TEXT("Function"), TEXT("Warnings"), TEXT("Errors") },
        DBG_INIT | DBG_ATTACH | DBG_ERROR };
#endif

extern CHid *gpobHid;


const WCHAR gcszRegisterClientDriverId[] = L"RegisterClientDriverID";
const WCHAR gcszRegisterClientSettings[] = L"RegisterClientSettings";

const WCHAR gcszUnRegisterClientDriverId[] = L"UnRegisterClientDriverID";
const WCHAR gcszUnRegisterClientSettings[] = L"UnRegisterClientSettings";

const WCHAR gcszHidDriverId[] = L"Generic_Sample_Hid_Class_Driver";


/*
 * DLL entry point
 */
extern "C" BOOL
DllEntry( HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved) 
{
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            DEBUGREGISTER((HINSTANCE)hDllHandle);

            DEBUGMSG(ZONE_INIT, (TEXT("+Hid DriverEntry\r\n")));
            break;
        case DLL_PROCESS_DETACH:
            DEBUGMSG(ZONE_INIT, (TEXT("-Hid DriverEntry\r\n")));
        default:
            break;
    }
    return TRUE ;
}

/* 
 * Routine to initialize driver settings structure that determines how this
 * driver is to be loaded.  As specified in the HID spec, HID class devices
 * are identified in the interface descriptor, so we only need to specify
 * the dwInterfaceClass field.
 */
static void
SetupHIDDriverSettings(USB_DRIVER_SETTINGS *pDriverSettings)
{
    pDriverSettings->dwCount = sizeof(USB_DRIVER_SETTINGS);

    pDriverSettings->dwVendorId          = USB_NO_INFO;
    pDriverSettings->dwProductId         = USB_NO_INFO;
    pDriverSettings->dwReleaseNumber     = USB_NO_INFO;

    pDriverSettings->dwDeviceClass       = USB_NO_INFO;
    pDriverSettings->dwDeviceSubClass    = USB_NO_INFO;
    pDriverSettings->dwDeviceProtocol    = USB_NO_INFO;

    pDriverSettings->dwInterfaceClass    = USB_DEVICE_CLASS_HUMAN_INTERFACE;
    pDriverSettings->dwInterfaceSubClass = USB_NO_INFO;
    pDriverSettings->dwInterfaceProtocol = USB_NO_INFO;
}

/*
 * USBInstallDriver
 *
 *   USB driver install routine - set up client registry settings so we will be loaded
 *   by USBD for HID devices.  This function should not be called for systems in which the
 *   OEM ships the HID driver.
 *
 * Return value:
 *   Return TRUE if install succeeds, or FALSE if there is some error.
 */
extern "C" BOOL 
USBInstallDriver(
    LPCWSTR szDriverLibFile)  // Contains client driver DLL name
{
    BOOL fRet = FALSE;
    HINSTANCE hInst = LoadLibrary(L"USBD.DLL");
    DEBUGMSG(ZONE_INIT,(TEXT("HID: Install function called (driver: %s)\r\n"),szDriverLibFile));
    
    // This is the install routine for the HID sample driver.
    if(hInst)
    {
        LPREGISTER_CLIENT_DRIVER_ID pRegisterId = 
        (LPREGISTER_CLIENT_DRIVER_ID) GetProcAddress(hInst, gcszRegisterClientDriverId);

        LPREGISTER_CLIENT_SETTINGS pRegisterSettings =
        (LPREGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,gcszRegisterClientSettings);

        if (pRegisterId && pRegisterSettings) {
            USB_DRIVER_SETTINGS DriverSettings;

            SetupHIDDriverSettings(&DriverSettings);

            fRet = (*pRegisterId)(gcszHidDriverId);

            if(fRet)
            {
                fRet = (*pRegisterSettings)(szDriverLibFile,gcszHidDriverId, NULL, &DriverSettings);

                if(!fRet)
                {
                    LPUN_REGISTER_CLIENT_DRIVER_ID pUnregisterId =
                        (LPUN_REGISTER_CLIENT_DRIVER_ID) GetProcAddress(hInst,gcszUnRegisterClientDriverId);
                    if (pUnregisterId) 
                        (*pUnregisterId)(gcszHidDriverId);
                }
            }
        }
        else 
        {
            RETAILMSG(1,(TEXT("!Hid: Error getting USBD function pointers\r\n")));
        }
        FreeLibrary(hInst);
    }
    return fRet;
}

/*
 * USBUnInstallDriver
 *
 *   This function can be called by a client driver to deregister itself
 *   with USBD.
 */
extern "C" BOOL 
USBUnInstallDriver()
{
    BOOL fRet = FALSE;
    HINSTANCE hInst = LoadLibrary(L"USBD.DLL");

    if(hInst)
    {
        LPUN_REGISTER_CLIENT_DRIVER_ID pUnRegisterId =
                (LPUN_REGISTER_CLIENT_DRIVER_ID) GetProcAddress(hInst, gcszUnRegisterClientDriverId);

        LPUN_REGISTER_CLIENT_SETTINGS pUnRegisterSettings =
                (LPUN_REGISTER_CLIENT_SETTINGS) GetProcAddress(hInst, gcszUnRegisterClientSettings);

        if(pUnRegisterSettings)
        {
            USB_DRIVER_SETTINGS DriverSettings;

            // This structure must be filled out the same as we registered with
            SetupHIDDriverSettings(&DriverSettings);

            fRet = (*pUnRegisterSettings)(gcszHidDriverId, NULL,&DriverSettings);
        }

        if(pUnRegisterId)
        {
            BOOL fRetTemp = (*pUnRegisterId)(gcszHidDriverId);
            fRet = fRet ? fRetTemp : fRet;
        }
        FreeLibrary(hInst);
    }
    return fRet;
}

/*
 * USBDeviceNotifications
 *
 *    Process notifications from USBD.  Currently, the only notification
 *    supported is a device removal.  Unused parameters are reserved for
 *    future use.
 */
extern "C" BOOL USBDeviceNotifications(LPVOID lpvNotifyParameter, DWORD dwCode,
        LPDWORD * dwInfo1, LPDWORD * dwInfo2, LPDWORD * dwInfo3,
        LPDWORD * dwInfo4)
{
    SHidDevice *pHidDevice = (SHidDevice *)lpvNotifyParameter;

    switch(dwCode)
    {
        case USB_CLOSE_DEVICE:
            gpobHid->HidCloseDevice(pHidDevice);
            if (gpobHid->m_curDevices == 0)
            {
                // If this is the last device, clean up
                delete gpobHid;
                gpobHid = NULL;
            }
        return TRUE;
    }
    return FALSE;
}

/*
 *  USBDeviceAttach 
 * 
 *    USB device attach routine.  This function is called by USBD when a device is attached
 *    to the USB, and a matching registry key is found off the  LoadClients registry key. 
 *    We must determine whether the device may be controlled by this driver, and load 
 *    drivers for any uncontrolled interfaces.
 *
 *  Return Value:
 *    Return TRUE upon success, or FALSE if an error occurs.
 */
extern "C" BOOL 
USBDeviceAttach(
    USB_HANDLE hDevice,           // USB device handle
    LPCUSB_FUNCS lpUsbFuncs,      // Pointer to USBDI function table.
    LPCUSB_INTERFACE lpInterface, // If client is being loaded as an interface driver, contains a pointer to the USB_INTERFACE
                                  // structure that contains interface information. If client is not loaded for a specific interface,
                                  // this parameter will be NULL.
    LPCWSTR szUniqueDriverId,     // Contains client driver id string.
    LPBOOL fAcceptControl,        // Filled in with TRUE if we accept control of the device, 
                                  // or FALSE if USBD should continue to try to load client drivers.
    LPCUSB_DRIVER_SETTINGS lpDriverSettings,// Contains pointer to USB_DRIVER_SETTINGS struct that indicates how we were loaded.

    DWORD dwUnused)               // Reserved for use with future versions of USBD
{
    LPCUSB_CONFIGURATION lpActiveConfig;
    LPCUSB_DEVICE lpDeviceInfo;
    int iInterface;

    *fAcceptControl = FALSE;

    if (lpInterface) {
        // If loaded as an interface driver, ignore non HID interfaces
        if (lpInterface->Descriptor.bInterfaceClass != USB_DEVICE_CLASS_HUMAN_INTERFACE) {
            DEBUGMSG(ZONE_ATTACH,(TEXT("USBHid: DeviceAttach, ignoring non HID interface class %u\r\n"),
                                  lpInterface->Descriptor.bInterfaceClass));
            return FALSE;
        }
        DEBUGMSG(ZONE_ATTACH,
                 (TEXT("USBHid: DeviceAttach, IF %u, #EP:%u, Class:%u, Sub:%u, Prot:%u\r\n"),
                  lpInterface->Descriptor.bInterfaceNumber,lpInterface->Descriptor.bNumEndpoints,
                  lpInterface->Descriptor.bInterfaceClass,lpInterface->Descriptor.bInterfaceSubClass,
                  lpInterface->Descriptor.bInterfaceProtocol));
    }
    else {
        DEBUGMSG(ZONE_ATTACH,(TEXT("USBHid: DeviceAttach, lpInterface == NULL\r\n")));
    }
    
    // If this is the first device, init our global data
    if (gpobHid == NULL)
    {
        DEBUGMSG(ZONE_INIT,(TEXT("USBHid: DeviceAttach, creating new CHid instance...\r\n")));
        gpobHid = new CHid();
        if (gpobHid == NULL)
            return FALSE;

        if (!gpobHid->Initialize(lpUsbFuncs)) {
            DEBUGMSG(ZONE_ERROR, (TEXT("HID: Error initializing driver.  Exiting.\r\n")));
            goto Error;
        }
    }

    // Retrieve device descriptor information 
    lpDeviceInfo = (*lpUsbFuncs->lpGetDeviceInfo)(hDevice);
    if (lpDeviceInfo == NULL) {
        DEBUGMSG(ZONE_ERROR,(TEXT("!HID: Error in GetDeviceInfo()\r\n")));
        goto Error;

    }

    lpActiveConfig = lpDeviceInfo->lpActiveConfig;

    if ((lpActiveConfig == NULL) || 
        (lpActiveConfig->lpInterfaces == NULL) || 
        (lpActiveConfig->lpInterfaces->lpEndpoints == NULL))
    {
        DEBUGMSG(ZONE_ERROR,(TEXT("!HID: DeviceAttach - missing descriptor information!\r\n")));
        goto Error;
    }

    // HCD should guarantee this
    ASSERT(lpDeviceInfo->Descriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE);
    ASSERT(lpActiveConfig->Descriptor.bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE);
    ASSERT(lpActiveConfig->lpInterfaces->Descriptor.bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);

    // Check all interfaces on device.  If we find at least one HID class interface, we'll accept
    // control of the device.
    for (iInterface = 0; iInterface < (int)lpActiveConfig->dwNumInterfaces; iInterface++) {
        LPCUSB_INTERFACE lpIF = &lpActiveConfig->lpInterfaces[iInterface];
        SHidDevice *pHidDevice;

        // HCD should guarantee this
        ASSERT(lpIF); 
        ASSERT(lpIF->Descriptor.bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);

        // Ignore alternate interfaces
        if (lpIF->Descriptor.bAlternateSetting != 0) {
            DEBUGMSG(ZONE_ATTACH,(TEXT("HID:DeviceAttach Skipping alternate interface %u\r\n"),iInterface));
            continue;
        }

        // We only care about HID interfaces (load drivers for other interfaces later if we decide to accept
        // control of this device).
        if (lpIF->Descriptor.bInterfaceClass != USB_DEVICE_CLASS_HUMAN_INTERFACE) {
            DEBUGMSG(ZONE_ATTACH,(TEXT("HID:DeviceAttach Skipping interface %u (class 0x%X not HID)\r\n"),
                                  iInterface,lpIF->Descriptor.bInterfaceClass));
            continue;
        }

        if ((pHidDevice = gpobHid->HidNewDevice(hDevice,lpIF,lpDeviceInfo->Descriptor.bMaxPacketSize0)) == NULL) {
            goto Error;
        }
        else {
            // Register notification routine for device status changes.
            (*lpUsbFuncs->lpRegisterNotificationRoutine)(hDevice,USBDeviceNotifications, pHidDevice);

            // Tell USBD to stop looking for drivers
            *fAcceptControl = TRUE;
        }
    }

    if (*fAcceptControl) {
        // OK, we want control of this device, let's load drivers for other interfaces
        for (iInterface = 0; iInterface < (int)lpActiveConfig->dwNumInterfaces; iInterface++) {
            LPCUSB_INTERFACE lpIF = &lpActiveConfig->lpInterfaces[iInterface];
            if ((lpIF->Descriptor.bAlternateSetting != 0) && 
                (lpIF->Descriptor.bInterfaceClass != USB_DEVICE_CLASS_HUMAN_INTERFACE)) {
                // This will go through the standard client driver search algorithm.  Note that
                // we are prevented from looping since we reject non HID interfaces immediately.
                (*lpUsbFuncs->lpLoadGenericInterfaceDriver)(hDevice,lpIF);
            }
        }
    }
    return TRUE;

Error:
    // Clean up
    RETAILMSG(1,(TEXT("!HID: Could not configure HID device\r\n")));

    if (gpobHid->m_curDevices == 0) {
        delete gpobHid;
        gpobHid = NULL;
    }
    return FALSE;

}

extern "C" DWORD
HID_Init (DWORD dwCtx)
{
   // Unnecessary to init here; this is only so we can register ourselves to the OS for the benefit of DI.
   return 1;
}

extern "C" BOOL
HID_Deinit (DWORD dwCtx)
{
   return TRUE;
}

extern "C" BOOL
HID_Open (DWORD dwCtx, DWORD dwAccMode, DWORD dwShrMode)
{
#if 0
   // We should only open the HID for purposes of ioctl.
   if (dwAccMode || dwShrMode) {
      SetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
#endif
   return TRUE;
}

extern "C" BOOL
HID_Close (DWORD)
{
   return TRUE;
}

extern "C" DWORD
HID_Read (DWORD,LPVOID,DWORD)
{
   SetLastError(ERROR_NOT_SUPPORTED);
   return -1;
}

extern "C" DWORD
HID_Write (DWORD,LPCVOID,DWORD)
{
   SetLastError(ERROR_NOT_SUPPORTED);
   return -1;
}

extern "C" DWORD
HID_Seek (DWORD,long,DWORD)
{
   SetLastError(ERROR_NOT_SUPPORTED);
   return -1;
}

extern "C" BOOL
HID_IOControl (DWORD hCtx, DWORD dwCode,
               PBYTE pInpBuf, DWORD dwInpLen,
               PBYTE pOutBuf, DWORD dwOutLen, PDWORD pdwActualOutLen)
{
   ASSERT(gpobHid);

   return gpobHid->IOControl(dwCode, pInpBuf, dwInpLen, pOutBuf, dwOutLen, pdwActualOutLen);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -