📄 driver.cpp
字号:
// 232usb Copyright (c) 2003 Zoroyoshi, SOFTCLUB, Japan
// See source.txt for detail
#include <windows.h>
#include "usbdi.h"
#include "common.h"
#include "file.h"
#include "device.h"
BOOL APIENTRY
DllMain(
HANDLE module, DWORD code, void* resv)
{
switch (code) {
case DLL_PROCESS_ATTACH:
{ //DisableThreadLibraryCalls exists after CE3.0
HMODULE dll= GetModuleHandle(L"coredll");
BOOL (WINAPI *proc)(HMODULE)= (BOOL (WINAPI *)(HMODULE))GetProcAddress(dll, L"DisableThreadLibraryCalls");
if(proc) (*proc)((HMODULE)module);
};
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
};
return TRUE;
};
extern "C" BOOL
USBInstallDriver(
PCWCH dllname)
{
dmesg(L"installdriver\n");
WCHAR const* clientname= L"RS232_USB";
HKEY hk;
DWORD rd;
WCHAR ckey[256];
//RegisterClientSettings..
wsprintf(ckey, L"Drivers\\USB\\LoadClients\\Default\\Default\\Default\\%s", clientname);
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, ckey, 0, 0, 0, 0, 0, &hk, &rd)) hk= 0;
RegSetValueEx(hk, L"Dll", 0, REG_SZ, (BYTE*)dllname, (wcslen(dllname)+1)*2);
DWORD d= GetTickCount();
RegSetValueEx(hk, L"InstallTime", 0, REG_DWORD, (BYTE*)&d, sizeof(d));
RegCloseKey(hk);
return TRUE;
};
extern "C" BOOL
USBUnInstallDriver(void)
{
//never called
return TRUE;
};
BOOL WINAPI
USBDeviceNotify(
PVOID parm, DWORD code,
PDWORD *d1, PDWORD *d2, PDWORD *d3, PDWORD *d4)
{
dmesg(L"devicenotify\n");
device_extension *dx= (device_extension*)parm;
if(code==USB_CLOSE_DEVICE) {
if(dx==0) return FALSE;
if(dx->ud) DeactivateDevice(dx->ud);
LocalFree(dx);
dmesg(L"<free-dx%x> devicenotify close\n", dx);
return TRUE;
};
return FALSE;
};
extern "C" BOOL
USBDeviceAttach(
USB_HANDLE uh,
PCUSB_FUNCS uf,
PCUSB_INTERFACE iface,
PCWCH clientname,
PBOOL accept,
PCUSB_DRIVER_SETTINGS sets,
DWORD resv)
{
*accept= FALSE;
USB_DEVICE const* info= uf->lpGetDeviceInfo(uh); //static storage; needless to free
#ifdef DEBUG
infodump(uh, uf, info);
#endif
WCHAR ckey[256]; //vendor-specific client registry
wsprintf(ckey, L"Drivers\\USB\\LoadClients\\%d_%d_%d\\Default\\Default\\%s"
, info->Descriptor.idVendor, info->Descriptor.idProduct, info->Descriptor.bcdDevice
, clientname);
HKEY hk;
int usbmode;
DWORD classaddr, recvaddr, sendaddr;
DWORD rt, rd;
if(sets->dwVendorId==~0&&sets->dwProductId==~0&&sets->dwReleaseNumber==~0
&&sets->dwDeviceClass==~0&&sets->dwDeviceSubClass==~0&&sets->dwDeviceProtocol==~0
&&sets->dwInterfaceClass==~0&&sets->dwInterfaceSubClass==~0&&sets->dwInterfaceProtocol==~0) {
WCHAR dllname[256];
DWORD instime;
wsprintf(dllname, L"Drivers\\USB\\LoadClients\\Default\\Default\\Default\\%s", clientname);
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, dllname, 0, 0, &hk)) return FALSE;
rd= sizeof(dllname)-2;
if(RegQueryValueEx(hk, L"Dll", 0, &rt, (BYTE*)dllname, &rd)) rt= 0;
if(rt==REG_SZ) dllname[rd/2]= 0/*guard*/; else dllname[0]= 0;
rd= sizeof(instime); rt= 0;
if(RegQueryValueEx(hk, L"InstallTime", 0, &rt, (BYTE*)&instime, &rd)) rt= 0;
if(rt==REG_DWORD) instime= GetTickCount()-instime; else instime= ~0;
RegDeleteValue(hk, L"Dll");
RegDeleteValue(hk, L"InstallTime");
RegCloseKey(hk);
if(instime>=3000||dllname[0]==0) return FALSE; //not loaded
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, ckey, 0, 0, 0, 0, 0, &hk, &rd)) return FALSE; //error create
//initialize registries
RegSetValueEx(hk, L"Dll", 0, REG_SZ, (BYTE*)dllname, (wcslen(dllname)+1)*2);
WCHAR* v;
v= L"COM";
RegSetValueEx(hk, L"Prefix", 0, REG_SZ, (BYTE*)v, (wcslen(v)+1)*2);
v= L"RS232 USB Driver";
RegSetValueEx(hk, L"FriendlyName", 0, REG_SZ, (BYTE*)v, (wcslen(v)+1)*2);
v= L"Unimodem.dll";
RegSetValueEx(hk, L"Tsp", 0, REG_SZ, (BYTE*)v, (wcslen(v)+1)*2);
rd= 1;
RegSetValueEx(hk, L"DeviceType", 0, REG_DWORD, (BYTE*)&rd, sizeof(DWORD));
//analyze descriptor
int classw= 0; int recvw= 0; int sendw= 0; //probability
classaddr= 0; recvaddr= 0; sendaddr= 0; usbmode= 0x100;
USB_INTERFACE const* ua= info->lpActiveConfig->lpInterfaces;
for(UINT ia= 0; ia<info->lpActiveConfig->dwNumInterfaces; ia++, ua++) {
if(ua->Descriptor.bAlternateSetting==0) {
USB_ENDPOINT const* ue= ua->lpEndpoints;
int ee= 0; //error
DWORD ec= 0; DWORD er= 0; DWORD es= 0;
for(UINT ie= 0; ie<ua->Descriptor.bNumEndpoints; ie++, ue++) {
if((ue->Descriptor.bEndpointAddress&128) //input
&&(ue->Descriptor.bmAttributes&3)==3 //control
&&(ue->Descriptor.wMaxPacketSize&0x7ff)>=10) {
if(ec) ee++;
ec= ue->Descriptor.bEndpointAddress;
} else if((ue->Descriptor.bEndpointAddress&128) //input
&&(ue->Descriptor.bmAttributes&3)==2) {
if(er) ee++;
er= ue->Descriptor.bEndpointAddress;
} else if((ue->Descriptor.bEndpointAddress&128)==0 //output
&&(ue->Descriptor.bmAttributes&3)==2) {
if(es) ee++;
es= ue->Descriptor.bEndpointAddress;
};
};
if(ee==0) {
if(ec) {
int w= 1;
if(er&&es) {
w+= 1;
if(ua->Descriptor.bNumEndpoints==3) w+= 1;
};
if(ua->Descriptor.bNumEndpoints==1) w+= 5;
if(ua->Descriptor.bInterfaceClass==2) { //CDC
w+= 10;
if(ua->Descriptor.bInterfaceSubClass==2) { //ACM
w+= 10;
};
};
dmesg(L"ec %d %d\n", ec, w);
if(classw<w) {
classw= w;
classaddr= ec;
};
};
if(er) {
int w= 1;
if(es) {
w+= 1;
if((er^es)==128) w+= 2; //same endpoint number
if(ua->Descriptor.bNumEndpoints==2) w+= 4;
};
if(ua->Descriptor.bInterfaceClass==10) w+= 10; //CDC-data
else if(ua->Descriptor.bInterfaceClass==2) w+= 1; //CDC
dmesg(L"er %d %d\n", er, w);
if(recvw<w) {
recvw= w;
recvaddr= er;
};
};
if(es) {
int w= 1;
if(er) {
w+= 1;
if((er^es)==128) w+= 2; //same endpoint number
if(ua->Descriptor.bNumEndpoints==2) w+= 4;
};
if(ua->Descriptor.bInterfaceClass==10) w+= 10; //CDC-data
else if(ua->Descriptor.bInterfaceClass==2) w+= 1; //CDC
dmesg(L"es %d %d\n", es, w);
if(sendw<w) {
sendw= w;
sendaddr= es;
};
};
};
};
};
if(info->lpActiveConfig->dwNumInterfaces==1&&classaddr==129&&recvaddr==131&&sendaddr==2) usbmode|= 1; //pl2303?
RegSetValueEx(hk, L"ClassEndp", 0, REG_DWORD, (BYTE*)&classaddr, sizeof(DWORD));
RegSetValueEx(hk, L"ReceiveEndp", 0, REG_DWORD, (BYTE*)&recvaddr, sizeof(DWORD));
RegSetValueEx(hk, L"SendEndp", 0, REG_DWORD, (BYTE*)&sendaddr, sizeof(DWORD));
RegSetValueEx(hk, L"UsbMode", 0, REG_DWORD, (BYTE*)&usbmode, sizeof(DWORD));
RegCloseKey(hk);
return FALSE;
};
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, ckey, 0, 0, &hk)) return FALSE;
rd= sizeof(usbmode); rt= 0;
if(RegQueryValueEx(hk, L"UsbMode", 0, &rt, (BYTE*)&usbmode, &rd)) rt= 0;
rd= sizeof(classaddr); rt= 0;
if(RegQueryValueEx(hk, L"ClassEndp", 0, &rt, (BYTE*)&classaddr, &rd)) rt= 0;
if(rt!=REG_DWORD) classaddr= 0;
rd= sizeof(recvaddr); rt= 0;
if(RegQueryValueEx(hk, L"ReceiveEndp", 0, &rt, (BYTE*)&recvaddr, &rd)) rt= 0;
if(rt!=REG_DWORD) recvaddr= 0;
rd= sizeof(sendaddr); rt= 0;
if(RegQueryValueEx(hk, L"SendEndp", 0, &rt, (BYTE*)&sendaddr, &rd)) rt= 0;
if(rt!=REG_DWORD) sendaddr= 0;
RegCloseKey(hk);
if((usbmode&~0xff)!=0x100) return FALSE; //wrong version/class
dmesg(L"class=%d recv=%d send=%d\n", classaddr, recvaddr, sendaddr);
device_extension *dx= (device_extension*)LocalAlloc(0
, sizeof(device_extension)+RECVSIZE+RECVPKT);
if(dx==0) return FALSE;
dmesg(L"<alloc-dx%x>deviceattach\n", dx);
memset(dx, 0, sizeof(device_extension));
dx->uh= uh;
dx->uf= uf;
dx->uf->lpRegisterNotificationRoutine(dx->uh, USBDeviceNotify, dx);
dx->recvbuf= (BYTE*)dx+sizeof(device_extension);
{
dx->usbmode= usbmode;
dx->classif= 0;
dx->classendp= 0; dx->recvendp= 0; dx->sendendp= 0;
USB_INTERFACE const* ua= info->lpActiveConfig->lpInterfaces;
for(UINT ia= 0; ia<info->lpActiveConfig->dwNumInterfaces; ia++, ua++) {
if(ua->Descriptor.bAlternateSetting==0) {
USB_ENDPOINT const* ue= ua->lpEndpoints;
for(UINT ie= 0; ie<ua->Descriptor.bNumEndpoints; ie++, ue++) {
if(ue->Descriptor.bEndpointAddress==classaddr) {
dx->classendp= ue;
dx->classif= ua->Descriptor.bInterfaceNumber;
};
if(ue->Descriptor.bEndpointAddress==recvaddr) {
dx->recvendp= ue;
};
if(ue->Descriptor.bEndpointAddress==sendaddr) {
dx->sendendp= ue;
};
};
};
};
};
dx->ud= 0;
if(dx->classendp&&dx->recvendp&&dx->sendendp) {
dx->ud= ActivateDevice(ckey, (DWORD)dx);
// if(dx->ud==0) {
// USBDeviceNotify(dx, USB_CLOSE_DEVICE, 0, 0, 0, 0);
// return FALSE;
// };
};
*accept= TRUE;
return TRUE;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -