?? usbmsc.c
字號:
//
// 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:
usbmsc.c
Abstract:
USB Mass Storage Class.
Bulk-Only Transport 1.0 (BOT)
Control/Bulk/Interrupt Transport 1.0 (CBIT and CBT)
Functions:
Notes:
--*/
#include "usbmscp.h"
#include "bot.h"
#include "cbit.h"
#include <Pkfuncs.h> // for LoadDriver
LONG g_NumDevices = 0;
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("USBMSC"), {
TEXT("Errors"), TEXT("Warnings"), TEXT("Init"), TEXT("Trace"),
TEXT("USB_PARSE"), TEXT("USB_INIT"), TEXT("USB_CONTROL"), TEXT("USB_BULK"),
TEXT("USB_INT"), TEXT("BOT"), TEXT("CBI"), TEXT("CBIT"),
TEXT("TIME"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined")
},
0x0003 // ZONE_WRN|ZONE_ERR
};
#endif // DEBUG
//*****************************************************************************
//
// F U N C T I O N P R O T O T Y P E S
//
//*****************************************************************************
LPCUSB_INTERFACE
ParseUsbDescriptors(
USB_HANDLE hUsbDevice,
LPCUSB_FUNCS UsbFuncs,
LPCUSB_INTERFACE CurInterface,
LPUSHORT ConfigIndex
);
VOID
RemoveDeviceContext(
PUSBMSC_DEVICE pUsbDevice
);
BOOL
SetUsbInterface(
PUSBMSC_DEVICE pUsbDevice,
LPCWSTR UniqueDriverId
);
BOOL WINAPI
UsbDeviceNotify(
LPVOID lpvNotifyParameter,
DWORD dwCode,
LPDWORD *dwInfo1,
LPDWORD *dwInfo2,
LPDWORD *dwInfo3,
LPDWORD *dwInfo4
);
BOOL
UsbDeviceTest(
PUSBMSC_DEVICE pUsbDevice
);
DWORD
GetMaxLUN(HANDLE hTransport, PUCHAR pLun);
PVOID CreateBulkTransferMgr(
LPCUSB_FUNCS lpUsbFuncs, USB_PIPE hPipe, LPCUSB_ENDPOINT_DESCRIPTOR lpEndpointDesc,LPCTSTR szUniqueDriverId
);
VOID DeleteBulkTransferMgr(LPVOID lpContent);
BOOL
DllEntry(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
UNREFERENCED_PARAMETER(hDllHandle);
UNREFERENCED_PARAMETER(lpreserved);
switch (dwReason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE)hDllHandle);
DisableThreadLibraryCalls((HMODULE) hDllHandle);
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return TRUE;
}
//*****************************************************************************
//
// U S B D I N T E R F A C E
//
//*****************************************************************************
BOOL
USBInstallDriver(
LPCWSTR szDriverLibFile
)
{
HKEY hKey = NULL;
BOOL bRc;
UCHAR i;
const WCHAR wsUsbDeviceID[] = CLASS_NAME_SZ;
USB_DRIVER_SETTINGS usbDriverSettings = { USBMSC_DRIVER_SETTINGS };
// reg entries for Class driver
REG_VALUE_DESCR rdClassValues[] = {
DLL_SZ, REG_SZ, 0, (PUCHAR)(DRIVER_NAME_SZ),
NULL, 0, 0, NULL
};
// reg entries for Disk SubClass drivers
WCHAR wsSubClassRegKey[sizeof(CLIENT_REGKEY_SZ)+16] = CLIENT_REGKEY_SZ;
const ULONG index = (sizeof(CLIENT_REGKEY_SZ)-2)/2;
DWORD dwIoctl = DEFAULT_IOCTL;
REG_VALUE_DESCR rdSubClassValues[] = {
DLL_SZ, REG_SZ, 0, (PUCHAR)(DEFAULT_DISK_SZ),
PREFIX_SZ, REG_SZ, 0, (PUCHAR)(DEFAULT_PREFIX_SZ),
FSD_SZ, REG_SZ, 0, (PUCHAR)(DEFAULT_FSD_SZ),
FOLDER_SZ, REG_SZ, 0, (PUCHAR)(DEFAULT_FOLDER_SZ),
IOCTL_SZ, REG_DWORD, 0, (PUCHAR)(&dwIoctl),
NULL, 0, 0, NULL
};
DWORD dwReset = RESET_TIMEOUT;
DWORD dwCommand = COMMAND_BLOCK_TIMEOUT;
DWORD dwStatus = COMMAND_STATUS_TIMEOUT;
REG_VALUE_DESCR rdTimeouts[] = {
RESET_TIMEOUT_SZ, REG_DWORD, 0, (PUCHAR)(&dwReset),
COMMAND_BLOCK_TIMEOUT_SZ, REG_DWORD, 0, (PUCHAR)(&dwCommand),
COMMAND_STATUS_TIMEOUT_SZ, REG_DWORD, 0, (PUCHAR)(&dwStatus),
NULL, 0, 0, NULL
};
DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC>USBInstallDriver(%s)\n"), szDriverLibFile ));
//
// register with USBD
//
bRc = RegisterClientDriverID( wsUsbDeviceID );
if ( !bRc ) {
DEBUGMSG( ZONE_ERR, (TEXT("RegisterClientDriverID error:%d\n"), GetLastError()));
return FALSE;
}
bRc = RegisterClientSettings( szDriverLibFile,
wsUsbDeviceID,
NULL,
&usbDriverSettings );
if ( !bRc ) {
DEBUGMSG( ZONE_ERR, (TEXT("RegisterClientSettings error:%d\n"), GetLastError()));
return FALSE;
}
//
// Add our default Timeout values to the reg
//
if ( !GetSetKeyValues( wsSubClassRegKey,
&rdTimeouts[0],
SET,
TRUE ) ) {
DEBUGMSG( ZONE_ERR, (TEXT("GetSetKeyValues failed!\n")));
TEST_TRAP();
}
//
// Create our Disk SubClass Reg entries.
//
for (i = USBMSC_SUBCLASS_RBC; i <= USBMSC_SUBCLASS_SCSI; i++) {
swprintf( &wsSubClassRegKey[index], TEXT("\\%d"), i );
if ( !GetSetKeyValues( wsSubClassRegKey,
rdSubClassValues,
SET,
FALSE ) ) {
DEBUGMSG( ZONE_ERR, (TEXT("GetSetKeyValues failed!\n")));
TEST_TRAP();
}
}
DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC<USBInstallDriver:%d\n"), bRc ));
return bRc;
}
BOOL
USBUnInstallDriver(
VOID
)
{
BOOL bRc;
const WCHAR wsUsbDeviceID[] = CLASS_NAME_SZ;
USB_DRIVER_SETTINGS usbDriverSettings = { USBMSC_DRIVER_SETTINGS };
DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC>USBUnInstallDriver\n")));
TEST_TRAP();
bRc = UnRegisterClientSettings( wsUsbDeviceID,
NULL,
&usbDriverSettings );
bRc = bRc & UnRegisterClientDriverID( wsUsbDeviceID );
DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC<USBUnInstallDriver:%d\n"), bRc));
return bRc;
}
BOOL
USBDeviceAttach(
USB_HANDLE hDevice,
LPCUSB_FUNCS UsbFuncs,
LPCUSB_INTERFACE UsbInterface,
LPCWSTR UniqueDriverId,
LPBOOL AcceptControl,
LPCUSB_DRIVER_SETTINGS UsbDriverSettings,
DWORD Unused
)
{
BOOL bRc = TRUE;
ULONG ulConfigIndex = 0;
PUSBMSC_DEVICE pUsbDevice = NULL;
LPCUSB_INTERFACE pUsbInterface = NULL;
PUSBDISK_ATTACH DiskAttach;
UCHAR bInterfaceSubClass;
UCHAR bTempInterfaceSubClass = 0xFF; // invalid subclass
UCHAR uMaxLun;
UINT uiIndex; // Working Unit.
// reg entries for Disk SubClass drivers
WCHAR wsSubClassRegKey[sizeof(CLIENT_REGKEY_SZ)+16] = CLIENT_REGKEY_SZ;
const ULONG index = (sizeof(CLIENT_REGKEY_SZ)-2)/2;
REG_VALUE_DESCR RegVal[2] = {0};
WCHAR wsDriverName[MAX_DLL_LEN];
REG_VALUE_DESCR rdTimeouts[] = {
RESET_TIMEOUT_SZ, REG_DWORD, sizeof(DWORD), (PUCHAR)(NULL),
COMMAND_BLOCK_TIMEOUT_SZ, REG_DWORD, sizeof(DWORD), (PUCHAR)(NULL),
COMMAND_STATUS_TIMEOUT_SZ, REG_DWORD, sizeof(DWORD), (PUCHAR)(NULL),
NULL, 0, 0, NULL
};
UNREFERENCED_PARAMETER(UniqueDriverId);
UNREFERENCED_PARAMETER(Unused);
DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC>USBDeviceAttach(0x%x, %s)\n"), hDevice, UniqueDriverId));
//
// Determine if we control this USB peripheral...
//
*AcceptControl = FALSE;
do {
if ( USBMSC_INTERFACE_CLASS != UsbDriverSettings->dwInterfaceClass) {
DEBUGMSG( ZONE_ERR, (TEXT("Not our Device Class:0x%x\n"), UsbDriverSettings->dwInterfaceClass ));
bRc = FALSE;
break;
}
//
// Parse USB Descriptors
//
pUsbInterface = ParseUsbDescriptors( hDevice,
UsbFuncs,
UsbInterface,
(LPUSHORT)&ulConfigIndex );
if ( !pUsbInterface ) {
DEBUGMSG( ZONE_ERR, (TEXT("ParseUsbDescriptors failed!\n") ));
bRc = FALSE;
break;
}
//
// we found a device, interface, & protocol we can control, so create our device context
//
pUsbDevice = (PUSBMSC_DEVICE)LocalAlloc( LPTR, sizeof(USBMSC_DEVICE) );
if ( !pUsbDevice ) {
DEBUGMSG( ZONE_ERR, (TEXT("LocalAlloc error:%d\n"), GetLastError() ));
bRc = FALSE;
break;
}
pUsbDevice->Sig = USBMSC_SIG;
InitializeCriticalSection( &pUsbDevice->Lock );
pUsbDevice->hUsbDevice = hDevice;
pUsbDevice->pUsbInterface = pUsbInterface;
pUsbDevice->ConfigIndex = (USHORT)ulConfigIndex;
pUsbDevice->UsbFuncs = UsbFuncs;
pUsbDevice->Flags.AcceptIo = FALSE;
pUsbDevice->Flags.DeviceRemoved = FALSE;
pUsbDevice->dwMaxLun=0;
//
// set the USB interface/pipes
//
bRc = SetUsbInterface( pUsbDevice, UniqueDriverId );
if ( !bRc ) {
DEBUGMSG( ZONE_ERR, (TEXT("SetUsbInterface failed!\n")));
break;
}
// create endpoint 0 event
pUsbDevice->hEP0Event = CreateEvent( NULL, MANUAL_RESET_EVENT, FALSE, NULL);
if ( !pUsbDevice->hEP0Event ) {
DEBUGMSG( ZONE_ERR, (TEXT("CreateEvent error:%d\n"), GetLastError() ));
bRc = FALSE;
break;
}
//
// Read the timeout values from the registry
//
rdTimeouts[0].Data = (PUCHAR)(&pUsbDevice->Timeouts.Reset);
rdTimeouts[1].Data = (PUCHAR)(&pUsbDevice->Timeouts.CommandBlock);
rdTimeouts[2].Data = (PUCHAR)(&pUsbDevice->Timeouts.CommandStatus);
if ( !GetSetKeyValues(wsSubClassRegKey,
&rdTimeouts[0],
GET,
FALSE) ) {
//
// use defaults
//
pUsbDevice->Timeouts.Reset = RESET_TIMEOUT;
pUsbDevice->Timeouts.CommandBlock = COMMAND_BLOCK_TIMEOUT;
pUsbDevice->Timeouts.CommandStatus = COMMAND_STATUS_TIMEOUT;
}
if (!pUsbDevice->Timeouts.Reset)
pUsbDevice->Timeouts.Reset = RESET_TIMEOUT;
if (!pUsbDevice->Timeouts.Reset)
pUsbDevice->Timeouts.CommandBlock = COMMAND_BLOCK_TIMEOUT;
if (!pUsbDevice->Timeouts.Reset)
pUsbDevice->Timeouts.CommandStatus = COMMAND_STATUS_TIMEOUT;
//
// Load the USB Disk Driver based on the bInterfaceSubClass code.
// The USB Disk Driver is named by convention USBDISKxx.DLL,
// where 'xx' is a valid bInterfaceSubClass code.
//
// To override the default disk driver stuff the replacement driver subkey in the registry.
// If the named subkey does not exist then retry with SCSI as the default driver.
//
bInterfaceSubClass = pUsbDevice->pUsbInterface->Descriptor.bInterfaceSubClass;
ASSERT( (bInterfaceSubClass >= USBMSC_SUBCLASS_RBC) &&
(bInterfaceSubClass <= USBMSC_SUBCLASS_SCSI) ||
bInterfaceSubClass == USBMSC_SUBCLASS_RESERVED);
_retryDefault:
swprintf( &wsSubClassRegKey[index], TEXT("\\%d"), bInterfaceSubClass );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -