📄 usbd.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:
usbd.cpp
Abstract:
Functions:
Notes:
--*/
#pragma warning (3 : 4100 4101 4705 4706)
#include <windows.h>
#include "usbdi.h"
#include "hcdi.h"
#include "usbdinc.hpp"
#include "usbdobj.hpp"
#include "usbd.hpp"
#undef DEBUGMSG
#define DEBUGMSG(x,y) NKDbgPrintfW y
#undef SETFNAME
#define SETFNAME(name) LPCTSTR pszFname = (name)
LPCWSTR gcszUsbRegKey = L"Drivers\\USB";
LPCWSTR gcszDriverIDs = L"ClientDrivers";
LPCWSTR gcszLoadClients = L"LoadClients";
LPCWSTR gcszDefaultDriver = L"Default";
LPCWSTR gcszDllName = L"DLL";
LPCWSTR gcszUSBDeviceAttach = L"USBDeviceAttach";
LPCWSTR gcszUSBInstallDriver = L"USBInstallDriver";
static USB_FUNCS gc_UsbFuncs =
{
sizeof(USB_FUNCS), //DWORD dwCount;
&GetUSBDVersion, // LPGET_USBD_VERSION
&OpenClientRegistryKey, // LPOPEN_CLIENT_REGISTRY_KEY
&RegisterNotificationRoutine, // LPREGISTER_NOTIFICATION_ROUTINE
&UnRegisterNotificationRoutine, // LPUN_REGISTER_NOTIFICATION_ROUTINE
&LoadGenericInterfaceDriver, // LPLOAD_GENERIC_INTERFACE_DRIVER
&TranslateStringDescr, // LPTRANSLATE_STRING_DESCR
&FindInterface, // LPFIND_INTERFACE
&GetFrameNumber, // LPGET_FRAME_NUMBER
&GetFrameLength, // LPGET_FRAME_LENGTH
&TakeFrameLengthControl, // LPTAKE_FRAME_LENGTH_CONTROL
&ReleaseFrameLengthControl, // LPRELEASE_FRAME_LENGTH_CONTROL
&SetFrameLength, // LPSET_FRAME_LENGTH
&GetDeviceInfo, // LPGET_DEVICE_INFO
&IssueVendorTransfer, // LPISSUE_VENDOR_TRANSFER
&GetInterface, // LPGET_INTERFACE
&SetInterface, // LPSET_INTERFACE
&GetDescriptor, // LPGET_DESCRIPTOR
&SetDescriptor, // LPSET_DESCRIPTOR
&SetFeature, // LPSET_FEATURE
&ClearFeature, // LPCLEAR_FEATURE
&GetStatus, // LPGET_STATUS
&SyncFrame, // LPSYNC_FRAME
&OpenPipe, // LPOPEN_PIPE
&AbortPipeTransfers, // LPABORT_PIPE_TRANSFERS
&ResetPipe, // LPRESET_PIPE
&ClosePipe, // LPCLOSE_PIPE
&IsPipeHalted, // LPIS_PIPE_HALTED
&IssueControlTransfer, // LPISSUE_CONTROL_TRANSFER
&IssueBulkTransfer, // LPISSUE_BULK_TRANSFER
&IssueInterruptTransfer, // LPISSUE_INTERRUPT_TRANSFER
&IssueIsochTransfer, // LPISSUE_ISOCH_TRANSFER
&IsTransferComplete, // LPIS_TRANSFER_COMPLETE
&GetTransferStatus, // LPGET_TRANSFER_STATUS
&GetIsochResults, // LPGET_ISOCH_RESULTS
&AbortTransfer, // LPABORT_TRANSFER
&CloseTransfer, // LPCLOSE_TRANSFER
// These functions were added with USBDI version 1.1
&ResetDefaultPipe, // LPRESET_DEFAULT_PIPE
&IsDefaultPipeHalted // LPIS_DEFAULT_PIPE_HALTED
};
BOOL AddTransfer(SPipe * pPipe, STransfer * pTransfer)
{
EnterCriticalSection(&pPipe->csTransferLock);
// Check if we're being removed
if (pPipe->dwSig != VALID_PIPE_SIG)
{
LeaveCriticalSection(&pPipe->csTransferLock);
return FALSE;
}
for(UINT iTransfer = 0 ; iTransfer < pPipe->cAllocatedTransfers ;
++iTransfer)
{
if(pPipe->apTransfers[iTransfer] == NULL)
break;
}
if(iTransfer == pPipe->cAllocatedTransfers)
{
STransfer * * apNewTransfers;
UINT cAllocated =
pPipe->cAllocatedTransfers + gcTransferAllocateChunk;
apNewTransfers = new STransfer * [cAllocated];
if (apNewTransfers == NULL)
{
LeaveCriticalSection(&pPipe->csTransferLock);
return FALSE;
}
for(UINT iCopy = 0 ; iCopy < pPipe->cAllocatedTransfers ; ++iCopy)
apNewTransfers[iCopy] = pPipe->apTransfers[iCopy];
for(iCopy += 1 ; iCopy < cAllocated ; ++iCopy)
apNewTransfers[iCopy] = NULL;
if(pPipe->apTransfers)
delete [] pPipe->apTransfers;
pPipe->apTransfers = apNewTransfers;
pPipe->cAllocatedTransfers = cAllocated;
}
pTransfer->iTransfer = iTransfer;
pPipe->apTransfers[iTransfer] = pTransfer;
LeaveCriticalSection(&pPipe->csTransferLock);
return TRUE;
}
void GetSettingString(PWCHAR szString, DWORD dw1, DWORD dw2, DWORD dw3)
{
szString[0] = 0; // an empty string
if(dw1 == USB_NO_INFO && dw2 == USB_NO_INFO && dw3 == USB_NO_INFO)
{
// if there are no specific settings then return a default setting
lstrcpy(szString, gcszDefaultDriver);
return;
}
if(dw1 != USB_NO_INFO)
{
szString += swprintf(szString, L"%u_", dw1);
}
if(dw2 != USB_NO_INFO)
{
szString += swprintf(szString, L"%u_", dw2);
}
if(dw3 != USB_NO_INFO)
{
szString += swprintf(szString, L"%u_", dw3);
}
--szString; // go back to last underscore
*szString = 0; // and remove the last underscore
return;
}
BOOL AddDriverLib(SDevice * pDev, HINSTANCE hDriver)
{
EnterCriticalSection(&pDev->csLibList);
SDriverLibs * * ppLib = &pDev->pDriverLibs;
while(*ppLib)
ppLib = &((*ppLib)->pNext);
*ppLib = new SDriverLibs;
if (*ppLib == NULL) {
LeaveCriticalSection(&pDev->csLibList);
return FALSE;
}
(*ppLib)->hDriver = hDriver;
(*ppLib)->pNext = NULL;
LeaveCriticalSection(&pDev->csLibList);
return TRUE;
}
BOOL
InstallClientDriver(LPCWSTR szDriverName)
{
BOOL fRet = FALSE;
HINSTANCE hClientInstance = LoadLibrary(szDriverName);
if (hClientInstance) {
LPCLIENT_INSTALL_PROC pInstallProc =
(LPCLIENT_INSTALL_PROC) GetProcAddress(hClientInstance,gcszUSBInstallDriver);
if (pInstallProc) {
__try {
if ((*pInstallProc)(szDriverName)) {
DEBUGMSG(ZONE_LOADER,(TEXT("USBD:InstallClientDriver(%s), Install completed successfully\r\n"),szDriverName));
fRet = TRUE;
} else {
DEBUGMSG(ZONE_ERROR,(TEXT("!USBD:InstallClientDriver(%s), error in client driver install\r\n"),szDriverName));
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR,(TEXT("!USBD: Exception in install proc\r\n")));
}
} else {
DEBUGMSG(ZONE_ERROR,(TEXT("!USBD:InstallClientDriver, GetProcAddr(%s,%s) failed: %u\r\n"),
szDriverName,gcszUSBInstallDriver,GetLastError()));
}
}
else {
DEBUGMSG(ZONE_ERROR,(TEXT("!USBD:InstallClientDriver, error in LoadLibrary(%s): %u\r\n"),
szDriverName,GetLastError()));
}
if (hClientInstance) {
FreeLibrary(hClientInstance);
}
return fRet;
}
BOOL LoadRegisteredDriver(HKEY hkReg, SDevice * pDev,
LPCUSB_INTERFACE lpInterface, LPBOOL pfLoaded,
LPCUSB_DRIVER_SETTINGS lpDriverSettings)
{
UINT iSubKey = 0;
DWORD cchDriverId;
WCHAR szDriverId[gcMaxDriverIdSize];
HKEY hkSetting;
cchDriverId = sizeof(szDriverId) / sizeof(szDriverId[0]);
while(RegEnumKeyEx(hkReg, iSubKey++, szDriverId, &cchDriverId, NULL,
NULL, NULL, NULL) == ERROR_SUCCESS)
{
if(RegOpenKeyEx(hkReg, szDriverId, 0, 0, &hkSetting) == ERROR_SUCCESS)
{
WCHAR szDll[USB_MAX_LOAD_STRING];
DWORD cbDll = sizeof(szDll);
DWORD dwType;
RegQueryValueEx(hkSetting, gcszDllName, NULL, &dwType,
(LPBYTE)szDll, &cbDll);
if(cbDll && dwType == REG_SZ)
{
// We use LoadDriver here instead of LoadLibrary so that client drivers will
// be locked into RAM. This is in case a client wishes to register with device
// to receive power notifications - you cannot take a page fault in a power handler
// routine.
HINSTANCE hClientInstance = LoadDriver(szDll);
if(hClientInstance)
{
LPCLIENT_ATTACH_PROC pAttachProc = (LPCLIENT_ATTACH_PROC)
GetProcAddress(hClientInstance,
gcszUSBDeviceAttach);
if(pAttachProc)
{
DEBUGMSG(ZONE_LOADER,(TEXT("USBD: Calling client attach proc for %s\r\n"),szDriverId));
__try {
(*pAttachProc)((USB_HANDLE)pDev, &gc_UsbFuncs,
lpInterface, szDriverId, pfLoaded,
lpDriverSettings, 0);
} __except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR,(TEXT("!USBD: Exception in attach proc\r\n")));
*pfLoaded = FALSE;
}
DEBUGMSG(ZONE_LOADER,(TEXT("USBD: Client %s control of device\r\n"),
(*pfLoaded)? TEXT("accepted"):TEXT("did not accept")));
}
else
DEBUGMSG(ZONE_ERROR,(TEXT("!LoadRegisteredDriver: No attach proc for client driver %s\r\n"),szDriverId));
if(!*pfLoaded)
FreeLibrary(hClientInstance);
}
else {
DEBUGMSG(ZONE_ERROR,(TEXT("!USBD: Error in LoadDriver(%s): %u\r\n"),
szDll,GetLastError()));
}
if(*pfLoaded)
AddDriverLib(pDev, hClientInstance);
}
RegCloseKey(hkSetting);
}
cchDriverId = sizeof(szDriverId) / sizeof(szDriverId[0]);
}
return TRUE;
}
BOOL LoadGroupDriver(HKEY hkBase, SDevice * pDev, PBOOL pfLoaded,
LPCUSB_INTERFACE lpInterface, PCUSB_DRIVER_SETTINGS pDriverSettings,
BOOL fGroup1, BOOL fGroup2, BOOL fGroup3)
{
*pfLoaded = FALSE;
BOOL fRet = TRUE;
BOOL fWork1;
BOOL fWork2;
BOOL fWork3;
USB_DRIVER_SETTINGS CurSettings;
CurSettings.dwCount = sizeof(CurSettings);
CurSettings.dwVendorId = USB_NO_INFO;
CurSettings.dwProductId = USB_NO_INFO;
CurSettings.dwReleaseNumber = USB_NO_INFO;
CurSettings.dwDeviceClass = USB_NO_INFO;
CurSettings.dwDeviceSubClass = USB_NO_INFO;
CurSettings.dwDeviceProtocol = USB_NO_INFO;
CurSettings.dwInterfaceClass = USB_NO_INFO;
CurSettings.dwInterfaceSubClass = USB_NO_INFO;
CurSettings.dwInterfaceProtocol = USB_NO_INFO;
WCHAR szTemp[gcMaxDriverString];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -