📄 usbddrv.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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.
Module Name:
usbddrv.cpp
Abstract:
This file contains code for the USBD module of the Universal Serial
Bus driver for Windows CE. The USBD driver is responsible for loading
client drivers, and providing an interface to the USB host controller
to client drivers.
+--------------+
| USB Client |
| Driver |
+--------------+
/|\
| USBDI Interface
\|/
+--------------+
| USBD |
| Driver |
+--------------+
/|\
| HCD Interface
\|/
+--------------+
| HCD (OHCD or|
| UHCD) driver|
+--------------+
/|\
| HC Interface
\|/
+--------------------+ +------------------------+
| Host controller HW | | USB Device (function) |
+--------------------+ +------------------------+
/|\ /|\
| |
+------------------------------------------+
Functions:
TranslateStringDescr
LoadGenericInterfaceDriver
OpenClientRegistryKey
FindInterface
TakeFrameLengthControl
ReleaseFrameLengthControl
SetFrameLength
GetFrameNumber
GetFrameLength
OpenPipe
ResetPipe
AbortPipeTransfers
GetInterface
SetInterface
GetDescriptor
SetDescriptor
SetFeature
ClearFeature
GetStatus
SyncFrame
IssueVendorTransfer
IssueControlTransfer
IssueBulkTransfer
IssueInterruptTransfer
IssueIsochTransfer
CloseTransfer
AbortTransfer
ClosePipe
IsTransferComplete
GetTransferError
RegisterNotificationRoutine
UnRegisterNotificationRoutine
GetTransferStatus
GetIsochResults
GetDeviceInfo
GetUSBDVersion
IsPipeHalted
Notes:
@doc DRIVERS
--*/
#pragma warning (3 : 4100 4101 4705 4706)
#include <windows.h>
#include <netui.h>
#include <windev.h>
#include "usbdi.h"
#include "hcdi.h"
#include "usbdinc.hpp"
#include "usbd.hpp"
#include "usbdinc.hpp"
#include "usbdobj.hpp"
#ifdef DEBUG
#define DBG_INIT 0x0001
#define DBG_LOADER 0x0002
#define DBG_CONFIG 0x0004
#define DBG_PIPE 0x0008
#define DBG_VENDOR 0x0010
#define DBG_CONTROL 0x0020
#define DBG_BULK 0x0040
#define DBG_INTR 0x0080
#define DBG_ISOCH 0x0100
#define DBG_API 0x0200
#define DBG_WARN 0x4000
#define DBG_ERROR 0x8000
DBGPARAM dpCurSettings = {
TEXT("USBD"), {
TEXT("Init"),TEXT("Loader"),TEXT("Config"),TEXT("Pipe"),
TEXT("Vendor"),TEXT("Control"),TEXT("Bulk"),TEXT("Interrupt"),
TEXT("Isoch"),TEXT("API"),TEXT("Unused"),TEXT("Unused"),
TEXT("Unused"),TEXT("Unused"),TEXT("Warning"),TEXT("Error")},
DBG_INIT | DBG_PIPE | DBG_ERROR
};
// For decoding endpoint descriptor attributes
static const TCHAR *aszTypeStrings[] =
{
TEXT("Control"),TEXT("Isoch"),TEXT("Bulk"),TEXT("Interrupt")
};
#endif
extern "C" BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
UnusedParameter(hinstDLL);
UnusedParameter(dwReason);
UnusedParameter(lpvReserved);
if (dwReason == DLL_PROCESS_ATTACH) {
DEBUGREGISTER((HINSTANCE)hinstDLL);
DEBUGMSG(ZONE_INIT,(TEXT("USBD: DLL attach\r\n")));
DisableThreadLibraryCalls((HMODULE) hinstDLL);
}
return TRUE;
}
extern "C" BOOL
HcdAttach(
LPVOID lpvHcd,
LPCHCD_FUNCS lpHcdFuncs,
LPLPVOID lppvContext)
{
*lppvContext = NULL;
SHcd * pHcd = new SHcd;
if (pHcd == NULL)
return FALSE;
memset(pHcd,0,sizeof(SHcd));
pHcd->pvHcd = lpvHcd;
pHcd->pHcdFuncs = lpHcdFuncs;
InitializeCriticalSection(&pHcd->csFrameLengthControl);
*lppvContext = (LPVOID)pHcd;
DEBUGMSG(ZONE_INIT,(TEXT("+USBD:HcdAttach, hcd: 0x%X\r\n"),pHcd));
return TRUE;
}
extern "C" BOOL HcdDetach(LPVOID lpvContext)
{
ASSERT(lpvContext);
SHcd * pHcd = (SHcd *)lpvContext;
DeleteCriticalSection(&pHcd->csFrameLengthControl);
delete pHcd;
return TRUE;
}
// Call dialog box in NETUI to get driver name from user. If platform doesn't
// have UI, or user cancels dialog, this will return FALSE, otherwise returns
// the driver name entered by the user.
static BOOL
GetClientDriverName(LPWSTR szDriverName, int BufSize)
{
HANDLE hEvent;
// We share dialog with PCMCIA
GETDRIVERNAMEPARMS DriverNameParms;
DriverNameParms.Socket = 0;
DriverNameParms.PCCardType = PCCARDTYPE_USB;
// In case we're booting, wait for window manager to come up
hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, (TEXT("SYSTEM/GweApiSetReady")));
if (hEvent == NULL) return FALSE;
WaitForSingleObject(hEvent, INFINITE);
wcsncpy(DriverNameParms.DriverName,szDriverName,
sizeof(DriverNameParms.DriverName)/sizeof(DriverNameParms.DriverName[0]));
BOOL fRet = CallGetDriverName(NULL,&DriverNameParms);
if (!fRet) {
DEBUGMSG(ZONE_LOADER,(TEXT("!USBD:GetClientDriverName, error in CallGetDriverName\r\n")));
return FALSE;
}
wcsncpy(szDriverName,DriverNameParms.DriverName,BufSize);
return TRUE;
}
extern "C" BOOL HcdDeviceAttached(LPVOID lpvContext, UINT iDevice,
UINT iEndpointZero, LPCUSB_DEVICE lpDeviceInfo,
LPLPVOID lppvDeviceDetach)
{
BOOL fRet = TRUE, fLoaded = FALSE;
WCHAR szDllName[USB_MAX_LOAD_STRING] = {0};
*lppvDeviceDetach = NULL;
SHcd * pHcd = (SHcd *)lpvContext;
SDevice * pDev = new SDevice;
if (pDev == NULL)
return FALSE;
memset(pDev,0,sizeof(SDevice));
pDev->dwSig = VALID_DEVICE_SIG;
pDev->pHcd = pHcd;
pDev->iDevice = iDevice;
pDev->pDeviceInfo = lpDeviceInfo;
InitializeCriticalSection(&pDev->csPipeLock);
InitializeCriticalSection(&pDev->csSerializeNotifyRoutine);
InitializeCriticalSection(&pDev->csLibList);
for(UINT iPipe = 0 ; iPipe < gcMaxPipes ; ++iPipe)
pDev->apPipes[iPipe] = NULL;
SPipe * pPipe = GetPipeObject(pDev);
if (pPipe) {
pDev->apPipes[gcEndpointZero] = pPipe;
pPipe->iEndpointIndex = iEndpointZero; //value we use to the HCD
DEBUGMSG(ZONE_LOADER,(TEXT("+USBD:HcdDeviceAttached, Interfaces:%u\r\n"),
pDev->pDeviceInfo->lpActiveConfig->Descriptor.bNumInterfaces));
// Create Activated interface flag array for LoadDeviceDrivers
DWORD dwNumInterfaces = pDev->pDeviceInfo->lpActiveConfig->Descriptor.bNumInterfaces;
PBYTE pbActivatedFlag=NULL;
if (dwNumInterfaces) {
pbActivatedFlag= new BYTE[dwNumInterfaces];
};
if (pbActivatedFlag) {
memset(pbActivatedFlag,0,dwNumInterfaces);
}
else
ASSERT(FALSE);
while (fRet && !fLoaded) {
// Attempt to load client driver based on registry settings
fRet = LoadDeviceDrivers(pDev, &fLoaded, pbActivatedFlag);
if (fRet && !fLoaded) {
// No driver found, prompt user for driver name
if (!GetClientDriverName(szDllName, USB_MAX_LOAD_STRING))
break;
// Call client install proc, then retry load procedure
else if (!InstallClientDriver(szDllName))
// "Error installing USB driver <driver name>"
CallNetMsgBox(NULL,NMB_FL_OK|NMB_FL_TITLEUSB,
NETUI_GETNETSTR_USB_INSTALL_FAILURE,szDllName);
}
}
if (!fLoaded && pbActivatedFlag) { // We does not load all the driver.
// Check at least one drivers is loaded before free everything
for (DWORD dwIndex=0;dwIndex<dwNumInterfaces;dwIndex++)
if (*(pbActivatedFlag+dwIndex)) {
fLoaded=TRUE;
break;
}
}
if (pbActivatedFlag) {
delete pbActivatedFlag;
}
// Consider it an error if we couldn't get a driver for this device
if (!fLoaded)
fRet = FALSE;
if(fRet)
{
*lppvDeviceDetach = (LPVOID)pDev;
return TRUE;
}
}
RETAILMSG(1,(TEXT("!USBD: Could not load driver for attached device\r\n")));
if (pPipe)
FreePipeObjectMem(pPipe);
DeleteCriticalSection(&pDev->csPipeLock);
DeleteCriticalSection(&pDev->csSerializeNotifyRoutine);
DeleteCriticalSection(&pDev->csLibList);
delete pDev;
return FALSE;
}
extern "C" BOOL
HcdDeviceDetached(LPVOID lpvDeviceDetach)
{
BOOL fRet;
SDevice * pDev = (SDevice *)lpvDeviceDetach;
if(!pDev)
return TRUE;
SPipe * pPipe, *pDfltPipe;
DEBUGMSG(ZONE_LOADER,(TEXT("+USBD:HcdDeviceDetached, pDev:0x%X"),pDev));
EnterCriticalSection(&pDev->csPipeLock);
pDfltPipe = pDev->apPipes[gcEndpointZero];
LeaveCriticalSection(&pDev->csPipeLock);
// Close all pipes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -