⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.cpp

📁 HPC上的RS232 USB Driver .该软件比PL2303专用驱动强
💻 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 + -