#include #include #include #include #include "usbdi.h" #include "devioctl.h" #include "bulkusr.h" #include #include #include #include #include "surface.h" /* declarations for functions in this file */ HANDLE open_file( char *filename); BOOL GetUsbDeviceFileName( LPGUID pGuid, char *outNameBuf); HANDLE OpenUsbDevice(LPGUID pGuid, char *outNameBuf); HANDLE OpenOneDevice(IN HDEVINFO hwDeviceInfo,IN PSP_DEVICE_INTERFACE_DATA DeviceInfoData,IN char *devName); void scanEndpoints(void *p); int surf_init(Surf *pSurf) { int k; pSurf->hDriver = OpenUsbDevice( (LPGUID)&GUID_CLASS_I82930_BULK, pSurf->completeDeviceName); if(pSurf->hDriver == INVALID_HANDLE_VALUE) { return 1; } /* default values for endpoint parameters */ for(k=0;kendpoint[k].hRead = (HANDLE)INVALID_HANDLE_VALUE; pSurf->endpoint[k].hWrite = (HANDLE)INVALID_HANDLE_VALUE; strcpy(pSurf->endpoint[k].inPipe,""); strcpy(pSurf->endpoint[k].outPipe,""); } /* get endpoint parameters */ scanEndpoints(pSurf); return 0; /* good */ } int surf_close(Surf *pSurf) { int k; /* default values for endpoint parameters */ for(k=0;kendpoint[k].hRead != INVALID_HANDLE_VALUE) CloseHandle(pSurf->endpoint[k].hRead); if(pSurf->endpoint[k].hWrite != INVALID_HANDLE_VALUE) CloseHandle(pSurf->endpoint[k].hWrite); } if(pSurf->hDriver != INVALID_HANDLE_VALUE) CloseHandle(pSurf->hDriver); return 0; /* good */ } int surf_version(Surf *pSurf) { int status, revision; ULONG nBytes; status = DeviceIoControl(pSurf->hDriver, IOCTL_SURF_GET_VERSION, NULL, 0, &revision, sizeof(revision), &nBytes, NULL); return status ? revision : -1; } int surf_send(Surf *pSurf,int whichEndpoint,void *buff,int len) { HANDLE handle; ULONG nBytes = 0; if((handle = pSurf->endpoint[whichEndpoint].hWrite) == INVALID_HANDLE_VALUE) return 0; WriteFile(handle, buff, len, &nBytes, NULL); return nBytes; } int surf_recv(Surf *pSurf,int whichEndpoint,void *buff,int len) { HANDLE handle; ULONG nBytes = 0; if((handle = pSurf->endpoint[whichEndpoint].hRead) == INVALID_HANDLE_VALUE) return 0; ReadFile(handle, buff, len, &nBytes, NULL); return nBytes; } int surf_peek_queue(Surf *pSurf) { ULONG nBytes = 0; int outBuff[4], status; status = DeviceIoControl(pSurf->hDriver, IOCTL_SURF_PEEK_QUEUE, NULL, 0, outBuff, sizeof(outBuff), &nBytes, NULL); return status ? outBuff[0] : -1; } int surf_poke_queue(Surf *pSurf, char *str) { int len, status; ULONG nBytes = 0; len = strlen(str) + 1; /* include null-termination */ status = DeviceIoControl(pSurf->hDriver, IOCTL_SURF_POKE_QUEUE, str, len, 0, 0, &nBytes, NULL); return status ? nBytes : -1; } int surf_read_queue(Surf *pSurf,char *buffer,int len) { ULONG nBytes = 0; int status; status = DeviceIoControl(pSurf->hDriver, IOCTL_SURF_READ_QUEUE, NULL, 0, buffer, len, &nBytes, NULL); return status ? nBytes : -1; } int surf_vendor(Surf *pSurf,unsigned int requestType, unsigned int request, unsigned int value, unsigned int idx, void *buff, int len) { ULONG nBytes = 0; UCHAR *ctrlBuff, *puch, ch; int ctrlSize, index, k, n, status; if((ctrlBuff = malloc(len+7)) == NULL) return -1; index = 0; ctrlBuff[index++] = (UCHAR)(requestType & 0xff); ctrlBuff[index++] = (UCHAR)(request & 0xff); ctrlBuff[index++] = (UCHAR)(value & 0xff); ctrlBuff[index++] = (UCHAR)((value >> 8) & 0xff); ctrlBuff[index++] = (UCHAR)(idx & 0xff); ctrlBuff[index++] = (UCHAR)((idx >> 8) & 0xff); ctrlBuff[index++] = len; for(k=0,puch = (UCHAR *)buff;khDriver, IOCTL_SURF_VENDOR_DEVICE, ctrlBuff, ctrlSize, ctrlBuff, ctrlSize, &nBytes, NULL); n = nBytes; for(index=0,puch = (UCHAR *)buff;index> 8) & 0xff); ctrlBuff[index++] = (UCHAR)(idx & 0xff); ctrlBuff[index++] = (UCHAR)((idx >> 8) & 0xff); ctrlBuff[index++] = len; for(k=0,puch = (UCHAR *)buff;khDriver, IOCTL_SURF_GET_DESCRIPTOR, ctrlBuff, ctrlSize, ctrlBuff, ctrlSize, &nBytes, NULL); n = nBytes; for(index=0,puch = (UCHAR *)buff;index sizeof(completeDeviceName)) { return handle; } strcat(completeDeviceName,filename); handle = CreateFile(completeDeviceName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); return handle; } /* returns string with the device name, to be used in CreateFile() */ BOOL GetUsbDeviceFileName(LPGUID pGuid,char *outNameBuf) { HANDLE hDev = OpenUsbDevice( pGuid, outNameBuf ); if(hDev != INVALID_HANDLE_VALUE) { CloseHandle(hDev); return TRUE; } return FALSE; } /* find the next available device returns the handle to the device or INVALID_HANDLE_VALUE if unsuccessful */ HANDLE OpenUsbDevice(LPGUID pGuid, char *outNameBuf) { ULONG curDev, maxDevices; HANDLE hOut; HDEVINFO hwDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInfoData; BOOLEAN done; PUSB_DEVICE_DESCRIPTOR pUsbDevDesc0, pUsbDevDesc; // PCTSTR enumerator; HWND hWndParent; DWORD flags; // enumerator = NULL; hWndParent = NULL; flags = DIGCF_PRESENT | DIGCF_DEVICEINTERFACE; /* only present devices */ /* get device information on all installed devices of a specified class */ hwDeviceInfo = SetupDiGetClassDevs(pGuid,0,hWndParent,flags); maxDevices = 8; done = FALSE; deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); hOut = INVALID_HANDLE_VALUE; pUsbDevDesc0 = (PUSB_DEVICE_DESCRIPTOR)calloc(maxDevices,sizeof (USB_DEVICE_DESCRIPTOR)); for(curDev=0;curDevcbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, DeviceInfoData, functionClassDeviceData, predictedLength, &requiredLength, NULL)) { free( functionClassDeviceData ); return hOut; } strcpy(devName,functionClassDeviceData->DevicePath) ; hOut = CreateFile(functionClassDeviceData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); free(functionClassDeviceData); return hOut; } void scanEndpoints(Surf *pSurf) { UINT j, n, status, endpointAddress; ULONG i, nBytes; char *pch, pipe[16], *pPipe; int siz, dirRead; char buf[2048]; PUSB_CONFIGURATION_DESCRIPTOR cd; PUSB_INTERFACE_DESCRIPTOR id; PUSB_ENDPOINT_DESCRIPTOR ed; HANDLE *pHnd; siz = sizeof(buf); status = DeviceIoControl(pSurf->hDriver, IOCTL_BULKUSB_GET_CONFIG_DESCRIPTOR, buf, siz, buf, siz, &nBytes, NULL); if (status) { pch = buf; n = 0; cd = (PUSB_CONFIGURATION_DESCRIPTOR) pch; pch += cd->bLength; do { id = (PUSB_INTERFACE_DESCRIPTOR) pch; pch += id->bLength; for (j=0; jbNumEndpoints; j++) { ed = (PUSB_ENDPOINT_DESCRIPTOR) pch; endpointAddress = ed->bEndpointAddress; dirRead = endpointAddress & 0x80; endpointAddress &= 0x7f; if(endpointAddress < MAXENDPOINTS) { sprintf(pipe,"Pipe%02d",j); printf("endpoint %02d. direction = %s\n", endpointAddress, dirRead ? "read" : "write"); if(dirRead) { pPipe = pSurf->endpoint[endpointAddress].inPipe; pHnd = &pSurf->endpoint[endpointAddress].hRead; } else { pPipe = pSurf->endpoint[endpointAddress].outPipe; pHnd = &pSurf->endpoint[endpointAddress].hWrite; } strcpy(pPipe,pipe); *pHnd = open_file(pPipe); } pch += ed->bLength; } i = (ULONG)(pch - buf); } while (iwTotalLength); } return; }