Source file: /~heha/hsn/dlo/DLO_PowerSwitch.zip/src/DLO_PowerSwitch.c

/* Discolitez plugin, for controlling eight channels via
 * www.obdev.at's AVR-USB PowerSwitch example
 *
+080921	Uses the first PowerSwitch adapter found, but if DLL file name
	has a number after a blank, that number is used (0-based).
	Here, no editor facility is implemented, in opposite to DLO_Parallel
 */

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shlwapi.h>
#include "libusb-win32-device-bin-0.1.12.1/include/usb.h"	// requires _cdecl

// Opens the <n>th device (zero-based) that matches to
// Vendor, Product, Revision, Manufacturer string, and Product string.
// Zeroes given skip the match.
// Returns NULL when no match available
static usb_dev_handle* _stdcall usb_findA(int Vid, int Pid, int Rev,
  const char *sManufacturer, const char *sProduct, int n) {
 struct usb_bus		*bus;
 struct usb_device	*dev;
 usb_dev_handle		*handle;
 char			string[64];

 usb_init();
 usb_find_busses();
 usb_find_devices();
 for (bus=usb_get_busses(); bus; bus=bus->next) {
  for (dev=bus->devices; dev; dev=dev->next) {
   if (Vid && dev->descriptor.idVendor!=Vid) continue;
   if (Pid && dev->descriptor.idProduct!=Pid) continue;
   if (Rev && dev->descriptor.bcdDevice!=Rev) continue;
   handle = usb_open(dev);	/* we need to open the device in order to query strings */
   if (!handle) continue;	/* now check whether the names match: */
   if (sManufacturer) {
    if (usb_get_string_simple(handle,dev->descriptor.iManufacturer,string,sizeof(string))<=0) goto closehandle;
    if (lstrcmp(string,sManufacturer)) goto closehandle;
   }
   if (sProduct) {
    if (usb_get_string_simple(handle,dev->descriptor.iProduct,string,sizeof(string))<=0) goto closehandle;
    if (lstrcmp(string,sProduct)) goto closehandle;
   }
   if (n) {			/* found, but take next match! */
    n--;
closehandle:
    usb_close(handle);    
    continue;
   }
   return handle;
  }
 }
 return NULL;
}

static int DevNum;

// Opens the first PowerSwitch device, returns NULL when none available
static usb_dev_handle* OpenPowerSwitch(void) {
 return usb_findA(0x16C0/*VOTI*/,0x05DC/*Obdev*/,0,"www.obdev.at","PowerSwitch",DevNum);
}

static usb_dev_handle *handle;
static HINSTANCE hInst;

static BOOL CALLBACK ConfigDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 switch (Msg) {
  case WM_INITDIALOG: {
// Show current state of PowerSwitch found
   CheckDlgButton(Wnd,11,(UINT)handle);
  }return TRUE;

  case WM_COMMAND: switch (LOWORD(wParam)) {
   case 1:
   case 2: EndDialog(Wnd,wParam); break;
   case 10: {	// re-open PowerSwitch (in case of some disconnection meanwhile)
    if (handle) usb_close(handle);
    handle=OpenPowerSwitch();
    CheckDlgButton(Wnd,11,(UINT)handle);
   }break;
  }break;
 }
 return FALSE;
}

static BYTE laststate;


/**********************
 * exported functions *
 **********************/
BYTE _declspec(dllexport) DLO_getnch(void) {
 return 8;
}

LPSTR _declspec(dllexport) DLO_getname(void) {
 if (DevNum) {
  static char buf[32];
  wnsprintf(buf,sizeof(buf),"USB PowerSwitch #%d",DevNum);
  return buf;
 }
 return "USB PowerSwitch";
}

void _declspec(dllexport) DLO_datain(BYTE ch, BYTE val) {
 BYTE mask;
 if (!handle) return;
// avoid too many calls to usb_control_msg()
 mask = 1 << (ch-1);
 if (val) {
  if (laststate&mask) return;
 }else{
  if (!(laststate&mask)) return;
 }
 laststate ^= mask;
 usb_control_msg(handle,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,
   val ? 2/*PSCMD_ON*/ : 3/*PSCMD_OFF*/, 0/*duration*/, ch-1,
   NULL,0,200);
}

void _declspec(dllexport) DLO_init(void) {
 handle=OpenPowerSwitch();
 if (handle) {
  int i;
  for (i=0; i<8; i++) usb_control_msg(handle,
    USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,3,0,i,NULL,0,200);
  laststate=0;
 }
}

void _declspec(dllexport) DLO_done(void) {
 if (handle) usb_close(handle);
}

void _declspec(dllexport) DLO_about(void) {
 DialogBox(hInst,MAKEINTRESOURCE(100),0,ConfigDlgProc);
}

/********************
 * main entry point *
 ********************/
void CALLBACK _DllMainCRTStartup(HINSTANCE hInstDll,DWORD fdwReason,LPVOID lpReserved) {
 if (fdwReason==DLL_PROCESS_ATTACH) {
  char DllName[MAX_PATH], *p;
  hInst = hInstDll;	// Where the (dialog) resource comes from - and the file name
  if (GetModuleFileName(hInstDll,DllName,sizeof(DllName))
  && (p=StrChr(PathFindFileName(DllName),' ')))
    DevNum = StrToInt(p);
  DisableThreadLibraryCalls(hInstDll);	// returns TRUE to continue DLL loading
 }
}
Detected encoding: ASCII (7 bit)2