********************************LoongEmbedded********************************
作者:LoongEmbedded(kandi)
时间:2012.05.04
类别:WINCE驱动开发
********************************LoongEmbedded********************************
根据客户的要求,希望我们WINCE设备可以作为PC机器的可移动磁盘,并且可以通过应用软件能够实现mass storage和ActiveSync的切换,那怎么实现这个功能呢:
1. 系统组件
选择ActiveSync、mass storage和serial组件,如下图所示:
图1
我们先来看USB客户端驱动的注册表信息
IF BSP_USBFNCLASS == MASS_STORAGE
[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers]
"DefaultClientDriver"=- ; erase prevIoUs default
"DefaultClientDriver"="Mass_Storage_Class"
ENDIF BSP_USBFNCLASS
[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers\Mass_Storage_Class]
"Dll"="usbmsfn.dll"
"InterfaceSubClass"=dword:06
"InterfaceProtocol"=dword:50
"DeviceName"="DSK1:" ; 被映射为U盘的存储设备的设备名
"FriendlyName"="Mass Storage";显示设备名
"idvendor"=dword:045E; vendor ID,应该向USB组织申请
"Manufacturer"="Generic Manufacturer (PROTOTYPE--Remember to change idvendor)";厂商命
"idProduct"=dword:FFFF; Product ID,由厂商定义
"Product"="Generic Mass Storage (PROTOTYPE--Remember to change idvendor)";产品名
"bcdDevice"=dword:0;设备的版本号
[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers\RNdis]
"idvendor"=dword:0547
"Manufacturer"=LOC_USBFN_RNdis_MANUFACTURER
"idProduct"=dword:2c2d
"Product"=LOC_USBFN_RNdis_PRODUCT
[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers\Serial_Class]
"FriendlyName"=LOC_USBFN_SERIAL_NAME
"idvendor"=dword:045E
"Manufacturer"=LOC_USBFN_SERIAL_MANUFACTURER
"idProduct"=dword:00CE
"Product"=LOC_USBFN_SERIAL_PRODUCT
"Index"=dword:5
[HKEY_CURRENT_USER\ControlPanel\Comm]
"Cnct"="`USB"
在上面的注册表信息中,如果要把SD卡或是flash分区作为PC机的可移动盘,一定要让"DeviceName"="DSK1:"中的1和SD卡驱动或是flash驱动的index一致,这样就可以实现这个功能了。
3. mass storage和ActiveSync切换
⑴基于GUID调用FindFirstDevice函数获取到USB控制器驱动(比如s3c2450_usbfn.dll)的句柄。
⑵通过上面获取的驱动句柄,以控制码IOCTL_UFN_GET_CURRENT_CLIENT调用DeviceIoControl函数来获取当前已经加载的USB客户端驱动,然后以控制码IOCTL_UFN_CHANGE_CURRENT_CLIENT调用DeviceIoControl函数来切换USB客户端驱动(比如由mass storage切换为ActiveSync)。
⑶修改注册表信息,比如把"DefaultClientDriver"="Mass_Storage_Class"改为"DefaultClientDriver"="serial"
具体的代码如下:
#define FILE_DEVICE_UNKNowN 0x00000022
#define METHOD_BUFFERED 0
#define FILE_ANY_ACCESS 0
#define CTL_CODE( DeviceType,Function,Method,Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
#define _UFN_ACCESS_CTL_CODE(_Function) \
CTL_CODE(FILE_DEVICE_UNKNowN,_Function,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_UFN_GET_CURRENT_CLIENT _UFN_ACCESS_CTL_CODE(3)
#define IOCTL_UFN_CHANGE_CURRENT_CLIENT _UFN_ACCESS_CTL_CODE(4)
#define UFN_CLIENT_NAME_MAX_CHARS 128
#define UFN_CLIENT_DESCRIPTION_MAX_CHARS 250
typedef struct _UFN_CLIENT_INFO {
TCHAR szName[UFN_CLIENT_NAME_MAX_CHARS];
TCHAR szDescription[UFN_CLIENT_DESCRIPTION_MAX_CHARS];
} UFN_CLIENT_INFO,*PUFN_CLIENT_INFO;
typedef struct _UFN_CLIENT_NAME {
TCHAR szName[UFN_CLIENT_NAME_MAX_CHARS];
} UFN_CLIENT_NAME,*PUFN_CLIENT_NAME;
static HKEY hOpenKey=NULL;
#define DRIVER_USB_KEY TEXT("Drivers\\USB\\FunctionDrivers")
#define DRIVER_USB_NAME TEXT("DefaultClientDriver")
#define DRIVER_USB_VALUE_SERIAL TEXT("Serial_Class")
#define DRIVER_USB_VALUE_STORAGE TEXT("Mass_Storage_Class")
HANDLE GetUfncontroller()
{
HANDLE hUfn = NULL;
DEVMGR_DEVICE_informatION di;
memset(&di,sizeof(di));
di.dwSize = sizeof(di);
GUID guidUsbFn = { 0xE2BDC372,0x598F,0x4619,0xBC,0x50,0x54,0xB3,0xF7,0x84,0x8D,0x35 };
HANDLE hf = FindFirstDevice(DeviceSearchByGuid,&guidUsbFn,&di);
if (hf != INVALID_HANDLE_VALUE)
{
hUfn = CreateFile(di.szBusName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL);
CloseHandle(hf);
}
else
{
hUfn = INVALID_HANDLE_VALUE;
}
return hUfn;
}
void CusbfunctionswitchDlg::OnBnClickedStorageActivesyncSwitch()
{
// Todo: Add your control notification handler code here
HANDLE hdisk = NULL;
BOOL fnTypestorage = TRUE;
UFN_CLIENT_NAME uname;
UFN_CLIENT_INFO uinfo;
DWORD dwReturn = 0;
_tcscpy(uname.szName,L"Mass_Storage_Class");
hdisk = GetUfncontroller();
if (hdisk == INVALID_HANDLE_VALUE)
{
RETAILMSG(1,(TEXT("invalid usb handle,error = %d/r/n"),GetLastError()));
}
if (DeviceIoControl(hdisk,IOCTL_UFN_GET_CURRENT_CLIENT,&uinfo,sizeof(uinfo),&dwReturn,0) && (dwReturn == sizeof(uinfo)))
{
if (_tcscmp(L"Mass_Storage_Class",uinfo.szName) == 0)
{
_tcscpy(uname.szName,L"Serial_Class");
fnTypestorage = FALSE;
}
else
{
fnTypestorage = TRUE;
}
}
if (!DeviceIoControl(hdisk,IOCTL_UFN_CHANGE_CURRENT_CLIENT,&uname,sizeof(uname),NULL))
{
RETAILMSG(1,(TEXT("deviceiocontrol Failed,GetLastError()));
}
else
{
LONG lResult = 0;
if(fnTypestorage)
{
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,DRIVER_USB_KEY,&hOpenKey );
if(ERROR_SUCCESS == lResult)
{
lResult = RegSetValueEx(hOpenKey,DRIVER_USB_NAME,REG_SZ,(BYTE *)DRIVER_USB_VALUE_STORAGE,sizeof(DRIVER_USB_VALUE_STORAGE));
}
}
else
{
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,&hOpenKey );
if(ERROR_SUCCESS == lResult)
{
lResult = RegSetValueEx(hOpenKey,(BYTE *)DRIVER_USB_VALUE_SERIAL,sizeof(DRIVER_USB_VALUE_SERIAL));
}
}
RegCloseKey( hOpenKey );
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。