Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
255 views

Mpusbapi CPP

MPUSBAPI library is intended for use on Microchip microcontrollers. No warranties, express or implied, are made with respect to this software. Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil liability for the breach of the terms and conditions of this license.

Uploaded by

Jorge Araque
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
255 views

Mpusbapi CPP

MPUSBAPI library is intended for use on Microchip microcontrollers. No warranties, express or implied, are made with respect to this software. Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil liability for the breach of the terms and conditions of this license.

Uploaded by

Jorge Araque
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 19

/********************************************************************* * * MPUSBAPI Library * ********************************************************************* * FileName: _mpusbapi.cpp * Dependencies: See #include section below.

* Compiler: Borland C++ Builder 6 * Company: Copyright (C) 2008 by Microchip Technology, Inc. * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the Company ) for its PICmicro Microcontroller is intended and * supplied to you, the Company s customer, for use solely and * exclusively on Microchip PICmicro Microcontroller products. The * software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * revision Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * v0.0.0.0 9/2/04 Implemented MPUSBGetDeviceLink() * v1.0.0.0 11/19/04 Original version 1.00 completed * v1.0.1.0 03/24/08 Slight update to fix issue which * was requiring admin run level to * work correctly. * v1.1.0.0 05/22/08 Added the support for the * following functions: * MPUSBSetConfiguration() * MPUSBGetDeviceDescriptor() * MPUSBGetConfigurationDescriptor() * MPUSBGetStringDescriptor() * Modified MPUSBGetDLLVersion return * format. * v1.2.0.0 02/02/09 Fixed bugs in MPUSBRead() function ********************************************************************/ #include #include #include #include #include #include #include #include <stdio.h> <windows.h> <string.h> <setupapi.h> <initguid.h> <winioctl.h> "ioctls.h" "_mpusbapi.h" 0x00010000L 0x00010100L 0x01010000L //revision 1.0.0.0 //revision 1.0.1.0 //revision 1.1.0.0

//#define MPUSBAPI_VERSION //#define MPUSBAPI_VERSION #define MPUSBAPI_VERSION

#define #define #define #define

MPUSB_DEV_NO_INFO MPUSB_DEV_INVALID_INST MPUSB_DEV_VIDPID_NOT_FOUND MPUSB_DEV_NOT_ATTACHED

2 3 4 5

#pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved ) { return 1; } /////////////////////////////////////////////////////////////////////////////// // MPUSBGetDLLVersion : get mpusbapi.dll revision level // // Input: // None // Output: // 32-bit revision level MMmmddii // MM - Major release // mm - Minor release // dd - dot release or minor fix // ii - test release revisions // Note: // The formatting changed between revisions v1.0.1.0 of the // driver and v1.1.0.0. The output of this function was // previously MMMMmmmm and did not match the .DLL file // numbering format. The format of this fuction was changed to // match how the .DLL file number generation works. // DWORD MPUSBGetDLLVersion(void) { return MPUSBAPI_VERSION; }//end MPUSBGetDLLVersion /////////////////////////////////////////////////////////////////////////////// // MPUSBIsVidPidEqual : Compares the pVID_PID string against the DeviceInst ance // string retrieved from the registry using the DevicePath subkey. // This function should be called only from MPUSBGetDevicePath(). // // Note: // All Windows version has the DeviceClasses information stored in: // HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\DeviceClasses\\ // {GUID_DEVINTERFACE_MCHPUSB}\\<DevicePath> // Win98SE,ME have different DevicePath string format from 2K,XP. // It does not contain vid&pid information in the DevicePath. // Thus necessitating the needs to check the DeviceInstance string in the // registry. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBIsVidPidEqual(PCHAR pDevicePath, PCHAR pVID_PID) {

DWORD dwResult = MPUSB_FAIL; char lszValue[255]; char lpSubKey[512]; HKEY hKey; LONG returnStatus; DWORD dwType=REG_SZ; DWORD dwSize=255; GUID guid = GUID_DEVINTERFACE_MCHPUSB; /* Modify DevicePath to use registry format */ pDevicePath[0] = '#'; pDevicePath[1] = '#'; pDevicePath[3] = '#'; /* Form SubKey */ wsprintf(lpSubKey, "SYSTEM\\CURRENTCONTROLSET\\CONTROL\\DEVICECLASSES\\{%4.2x-%2.2x-%2.2x-%.2x% .2x-%.2x%.2x%.2x%.2x%.2x%.2x}\\%s", guid.Data1,guid.Data2,guid.Data3,guid.Data4[0],guid.Data4[1],guid.Data4[2], guid.Data4[3],guid.Data4[4],guid.Data4[5],guid.Data4[6],guid.Data4[7],pDevic ePath); /* Open Key */ returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0L, KEY_QUERY_VALUE, //Changed from v1.0. Us ed to be "KEY_ALL_ACCESS" which requires administrator logon (and application ad ministrator execution level to work in Vista). &hKey); if(returnStatus == ERROR_SUCCESS) { returnStatus = RegQueryValueEx(hKey, "DeviceInstance", NULL, &dwType, (LPBYTE)&lszValue, &dwSize); if(returnStatus == ERROR_SUCCESS) { /* * The string info stored in 'DeviceInstance' is the same * across all Windows platforms: 98SE, ME, 2K, and XP. * Upper-case in 98SE,ME. * Converts all to lower-case anyway. */ strlwr(lszValue); if(strstr(lszValue,pVID_PID) != NULL) { dwResult = MPUSB_SUCCESS; } } } RegCloseKey(hKey); /* Modify DevicePath to use the original format */ pDevicePath[0] = '\\'; pDevicePath[1] = '\\'; pDevicePath[3] = '\\';

return dwResult; }//end /////////////////////////////////////////////////////////////////////////////// // MPUSBGetDeviceLink : Returns the path to device hardware with a given // instance number. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBGetDeviceLink(DWORD instance, // Input PCHAR pVID_PID, // Input PCHAR pPath, // Output DWORD dwLen, // Input PDWORD pLength) // Output { if(pLength != NULL)*pLength = 0; // Initialization HDEVINFO info = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_MCHPUSB, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if(info==INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(info); return MPUSB_DEV_NO_INFO; }// end if // Get interface data for the requested instance SP_DEVICE_INTERFACE_DATA intf_data; intf_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if(!SetupDiEnumDeviceInterfaces(info, NULL, (LPGUID)&GUID_DEVINTERFACE_MCHPUSB, instance, &intf_data)) { SetupDiDestroyDeviceInfoList(info); return MPUSB_DEV_INVALID_INST; }// end if // Get size of symbolic link DWORD ReqLen; SetupDiGetDeviceInterfaceDetail(info, &intf_data, NULL, 0, &ReqLen, NULL ); PSP_DEVICE_INTERFACE_DETAIL_DATA intf_detail = \ (PSP_DEVICE_INTERFACE_DETAIL_DATA)(new char[ReqLen]); if( intf_detail == NULL) { SetupDiDestroyDeviceInfoList(info); delete intf_detail; return MPUSB_DEV_NO_INFO; }// end if

// Get symbolic link name intf_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) should equals 5. // In C++ Builder, go to Project/Options/Advanced Compiler/Data Alignment // and select "byte" align. if(!SetupDiGetDeviceInterfaceDetail(info, &intf_data, intf_detail, ReqLen, NULL, NULL)) { SetupDiDestroyDeviceInfoList(info); delete intf_detail; return MPUSB_DEV_NO_INFO; }// end if // Check for a valid VID&PID - if argument is not null) if(pVID_PID != NULL) { if(MPUSBIsVidPidEqual(intf_detail->DevicePath, pVID_PID) == NULL) { SetupDiDestroyDeviceInfoList(info); delete intf_detail; return MPUSB_DEV_VIDPID_NOT_FOUND; }// end if }// end if // Set the length of the path string if(pLength != NULL) *pLength = (DWORD)strlen(intf_detail->DevicePath); // Copy output string path to buffer pointed to by pPath if(pPath != NULL) { // Check that input buffer has enough room... // Use > not >= because strlen does not include null if(dwLen > strlen(intf_detail->DevicePath)) strcpy(pPath, intf_detail->DevicePath); else { SetupDiDestroyDeviceInfoList(info); delete intf_detail; return MPUSB_FAIL; }// end if }// end if // Clean up SetupDiDestroyDeviceInfoList(info); delete intf_detail; return MPUSB_SUCCESS; }// end MPUSBGetDeviceLink /////////////////////////////////////////////////////////////////////////////// // MPUSBGetDeviceCount : Returns the number of devices with matching VID & PID // // Note that "input" and "output" refer to the parameter designations in ca

lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBGetDeviceCount(PCHAR pVID_PID) { DWORD count; // Number of USB device with matching VID & PID count = 0; // Initialization for(int i = 0; i < MAX_NUM_MPUSB_DEV; i++) { if(MPUSBGetDeviceLink(i,pVID_PID,NULL,NULL,NULL) == MPUSB_SUCCESS) count++; }//end for return count; }//end MPUSBGetDeviceCount /////////////////////////////////////////////////////////////////////////////// // MPUSBOpen : Returns the handle to the endpoint pipe with matching VID & PID // // All pipes are opened with the FILE_FLAG_OVERLAPPED attribute. // This allows MPUSBRead,MPUSBWrite, and MPUSBReadInt to have a time-out value. // // Note: Time-out value has no meaning for Isochronous pipes. // // instance - An instance number of the device to open. // Typical usage is to call MPUSBGetDeviceCount first to find out // how many instances there are. // It is important to understand that the driver is shared among // different devices. The number of devices returned by // MPUSBGetDeviceCount could be equal to or less than the number // of all the devices that are currently connected & using the // generic driver. // // Example: // if there are 3 device with the following PID&VID connected: // Device Instance 0, VID 0x04d8, PID 0x0001 // Device Instance 1, VID 0x04d8, PID 0x0002 // Device Instance 2, VID 0x04d8, PID 0x0001 // // If the device of interest has VID = 0x04d8 and PID = 0x0002 // Then MPUSBGetDeviceCount will only return '1'. // The calling function should have a mechanism that attempts // to call MPUSBOpen up to the absolute maximum of MAX_NUM_MPUSB_DEV // (MAX_NUM_MPUSB_DEV is defined in _mpusbapi.h). // It should also keep track of the number of successful calls // to MPUSBOpen(). Once the number of successes equals the // number returned by MPUSBGetDeviceCount, the attempts should // be aborted because there will no more devices with // a matching vid&pid left. // // pVID_PID - A string containing the PID&VID value of the target device. // The format is "vid_xxxx&pid_yyyy". Where xxxx is the VID value // in hex and yyyy is the PID value in hex. // Example: If a device has the VID value of 0x04d8 and PID value // of 0x000b, then the input string should be: // "vid_04d8&pid_000b" // // pEP - A string of the endpoint number on the target endpoint to open.

// The format is "\\MCHP_EPz". Where z is the endpoint number in // decimal. // Example: "\\MCHP_EP1" // // This arguement can be NULL. A NULL value should be used to // create a handles for non-specific endpoint functions. // MPUSBRead, MPUSBWrite, MPUSBReadInt are endpoint specific // functions. // All others are not. // Non-specific endpoint functions will become available in the // next release of the DLL. // // Note: To use MPUSBReadInt(), the format of pEP has to be // "\\MCHP_EPz_ASYNC". This option is only available for // an IN interrupt endpoint. A data pipe opened with the // "_ASYNC" keyword would buffer the data at the interval // specified in the endpoint descriptor upto the maximum of // 100 data sets. Any data received after the driver buffer // is full will be ignored. // The user application should call MPUSBReadInt() often // enough so that the maximum limit of 100 is never reached. // // dwDir - Specifies the direction of the endpoint. // Use MP_READ for MPUSBRead, MPSUBReadInt // Use MP_WRITE for MPUSBWrite // // dwReserved Future Use // // Summary of transfer type usage: // ============================================================================ // Transfer Type Functions Time-Out Applicable? // ============================================================================ // Interrupt - IN MPUSBRead, MPUSBReadInt Yes // Interrupt - OUT MPUSBWrite Yes // Bulk - IN MPUSBRead Yes // Bulk - OUT MPUSBWrite Yes // Isochronous - IN MPUSBRead No // Isochronous - OUT MPUSBWrite No // ============================================================================ // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // HANDLE MPUSBOpen(DWORD instance, // Input PCHAR pVID_PID, // Input PCHAR pEP, // Input DWORD dwDir, // Input DWORD dwReserved) // Input <Future Use> { char path[MAX_PATH]; DWORD dwReqLen; HANDLE handle; handle = INVALID_HANDLE_VALUE; // Check arguments first if((pVID_PID != NULL) && ((dwDir == MP_WRITE) || (dwDir == MP_READ))) {

if(MPUSBGetDeviceLink(instance,pVID_PID,path,MAX_PATH,&dwReqLen)==\ MPUSB_SUCCESS) { char path_io[MAX_PATH]; strcpy(path_io,path); if(pEP != NULL) strcat(path_io,pEP); if(dwDir == MP_READ) { handle = CreateFile(path_io, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL); } else { handle = CreateFile(path_io, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL); }//end if }//end if }//end if return handle; }//end MPUSBOpen(...) /////////////////////////////////////////////////////////////////////////////// // MPUSBGetDescriptor : Returns the Requested Descriptor Data // // handle - Identifies the endpoint pipe to be read. The pipe handle must // have been created with MP_READ access attribute. // pDscParam // - pointer to a descriptor parameters object to be sent down to the // driver. This object specifies the details about the descriptor // request. // dscLen - the size of the pDscParam object // pDevDsc - pointer to where the resulting descriptor should be copied. // dwLen - the available data in the pDevDsc buffer // pLength - a pointer to a DWORD that will be updated with the amount of data // actually written to the pDevDsc buffer. This number will be // less than or equal to dwLen. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBGetDescriptor(HANDLE handle, // Input PVOID pDscParam, // Input DWORD dscLen, // Input PVOID pDevDsc, // Output DWORD dwLen, // Input PDWORD pLength) // Output {

if(pLength != NULL)*pLength = 0; if(pDevDsc == NULL) return MPUSB_FAIL; if(pDscParam == NULL) return MPUSB_FAIL; if(!DeviceIoControl(handle, IOCTL_MCHPUSB_GET_DESCRIPTOR, pDscParam, dscLen, pDevDsc, dwLen, pLength, NULL)) { printf("Get dsc error: %d",GetLastError()); return MPUSB_FAIL; }//end if return MPUSB_SUCCESS; }// MPUSBGetDeviceDescriptor /////////////////////////////////////////////////////////////////////////////// // MPUSBGetDeviceDescriptor : Returns the Device Descriptor Data // // handle - Identifies the endpoint pipe to be read. The pipe handle must // have been created with MP_READ access attribute. // pDevDsc - pointer to where the resulting descriptor should be copied. // dwLen - the available data in the pDevDsc buffer // pLength - a pointer to a DWORD that will be updated with the amount of data // actually written to the pDevDsc buffer. This number will be // less than or equal to dwLen. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBGetDeviceDescriptor(HANDLE handle, // Input PVOID pDevDsc, // Output DWORD dwLen, // Input PDWORD pLength) // Output { GET_DESCRIPTOR_PARAMETER DscParam; if(pLength != NULL)*pLength = 0; if(pDevDsc == NULL) return MPUSB_FAIL; DscParam.bType = USB_DEVICE_DESCRIPTOR_TYPE; DscParam.bIndex = 0; DscParam.wLangid = 0; if(!DeviceIoControl(handle, IOCTL_MCHPUSB_GET_DESCRIPTOR, &DscParam, sizeof(DscParam), pDevDsc, dwLen, pLength, NULL)) { printf("Get dsc error: %d",GetLastError()); return MPUSB_FAIL;

}//end if return MPUSB_SUCCESS; }// MPUSBGetDeviceDescriptor /////////////////////////////////////////////////////////////////////////////// // MPUSBGetConfigurationDescriptor : Returns the Configuration Descriptor // // handle - Identifies the endpoint pipe to be read. The pipe handle must // have been created with MP_READ access attribute. // bIndex - the index of the configuration descriptor desired. Valid input // range is 1 - 255. // pDevDsc - pointer to where the resulting descriptor should be copied. // dwLen - the available data in the pDevDsc buffer // pLength - a pointer to a DWORD that will be updated with the amount of data // actually written to the pDevDsc buffer. This number will be // less than or equal to dwLen. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBGetConfigurationDescriptor(HANDLE handle, // Input UCHAR bIndex, // Input PVOID pDevDsc, // Output DWORD dwLen, // Input PDWORD pLength) // Output { GET_DESCRIPTOR_PARAMETER DscParam; if(pLength != NULL)*pLength = 0; if(pDevDsc == NULL) return MPUSB_FAIL; if(bIndex == 0) return MPUSB_FAIL; DscParam.bType = USB_CONFIGURATION_DESCRIPTOR_TYPE; DscParam.bIndex = bIndex - 1; DscParam.wLangid = 0; if(!DeviceIoControl(handle, IOCTL_MCHPUSB_GET_DESCRIPTOR, &DscParam, sizeof(DscParam), pDevDsc, dwLen, pLength, NULL)) { printf("Get dsc error: %d",GetLastError()); return MPUSB_FAIL; }//end if return MPUSB_SUCCESS; }// MPUSBGetConfigurationDescriptor /////////////////////////////////////////////////////////////////////////////// // MPUSBGetStringDescriptor : Returns the requested string descriptor // // handle - Identifies the endpoint pipe to be read. The pipe handle must // have been created with MP_READ access attribute. // bIndex - the index of the configuration descriptor desired. Valid input // range is 0 - 255.

// wLangId - the language ID of the string that needs to be read // pDevDsc - pointer to where the resulting descriptor should be copied. // dwLen - the available data in the pDevDsc buffer // pLength - a pointer to a DWORD that will be updated with the amount of data // actually written to the pDevDsc buffer. This number will be // less than or equal to dwLen. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBGetStringDescriptor(HANDLE handle, // Input UCHAR bIndex, // Input USHORT wLangId, // Input PVOID pDevDsc, // Output DWORD dwLen, // Input PDWORD pLength) // Output { GET_DESCRIPTOR_PARAMETER DscParam; if(pLength != NULL)*pLength = 0; if(pDevDsc == NULL) return MPUSB_FAIL; DscParam.bType = USB_STRING_DESCRIPTOR_TYPE; DscParam.bIndex = bIndex; DscParam.wLangid = wLangId; if(!DeviceIoControl(handle, IOCTL_MCHPUSB_GET_DESCRIPTOR, &DscParam, sizeof(DscParam), pDevDsc, dwLen, pLength, NULL)) { printf("Get dsc error: %d",GetLastError()); return MPUSB_FAIL; }//end if return MPUSB_SUCCESS; }// MPUSBGetConfigurationDescriptor // **** INCOMPLETE **** DWORD MPUSBGetConfigInfoSize(HANDLE handle) { DWORD config_size; DWORD dwReqLen; DeviceIoControl(handle, IOCTL_MCHPUSB_GET_CONFIGURATION_INFO, NULL, 0, &config_size, sizeof(DWORD), &dwReqLen, NULL); return config_size; }//end MPUSBGetConfigInfoSize // **** INCOMPLETE ****

DWORD MPUSBGetConfigInfo(HANDLE handle, // Input PVOID pData, // Output DWORD dwLen) // Input { DWORD dwReqLen; if(!DeviceIoControl(handle, IOCTL_MCHPUSB_GET_CONFIGURATION_INFO, NULL, 0, pData, dwLen, &dwReqLen, NULL)) { printf("Get config error: %d",GetLastError()); return MPUSB_FAIL; }//end if return MPUSB_SUCCESS; }//end MPUSBGetConfigInfo // **** INCOMPLETE **** DWORD MPUSBSendControl(HANDLE handle, PVOID pData, DWORD dwLen) { return MPUSB_FAIL; } // **** INCOMPLETE **** DWORD MPUSBGetControl(HANDLE handle, PVOID pData, DWORD dwLen) { return MPUSB_FAIL; } // Input // Input // Input

// Input // Ouput // Input

/////////////////////////////////////////////////////////////////////////////// // MPUSBSetConfiguration : Sets the device configuration through a USB // SET_CONFIGURATION command. // // handle - Identifies the endpoint pipe to be written. The pipe handle must // have been created with MP_WRITE access attribute. // // bConfigSetting // - Denotes the configuration number that needs to be set. If this // number does not fall in the devices allowed configurations then // this function will return with MP_FAIL // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBSetConfiguration(HANDLE handle, // Input USHORT bConfigSetting) // Input { SET_CONFIGURATION_PARAMETER cfgParam; DWORD dwReturnData; DWORD dwReqLen;

cfgParam.bConfigurationValue = bConfigSetting; if(!DeviceIoControl(handle, IOCTL_MCHPUSB_SET_CONFIGURATION, &cfgParam, sizeof(cfgParam), &dwReturnData, sizeof(dwReturnData), &dwReqLen, NULL)) { printf("Set configuration error: %d",GetLastError()); return MPUSB_FAIL; }//end if return MPUSB_SUCCESS; } /////////////////////////////////////////////////////////////////////////////// // MPUSBRead : // // handle - Identifies the endpoint pipe to be read. The pipe handle must // have been created with MP_READ access attribute. // // pData - Points to the buffer that receives the data read from the pipe. // // dwLen - Specifies the number of bytes to be read from the pipe. // // pLength - Points to the number of bytes read. MPUSBRead sets this value to // zero before doing any work or error checking. // // dwMilliseconds // - Specifies the time-out interval, in milliseconds. The function // returns if the interval elapses, even if the operation is // incomplete. If dwMilliseconds is zero, the function tests the // data pipe and returns immediately. If dwMilliseconds is INFINITE, // the function's time-out interval never elapses. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBRead(HANDLE handle, // Input PVOID pData, // Output DWORD dwLen, // Input PDWORD pLength, // Output DWORD dwMilliseconds) // Input { BOOL bResult; DWORD nBytesRead; OVERLAPPED gOverlapped; DWORD dwResult; dwResult = MPUSB_FAIL; // set up overlapped structure fields gOverlapped.Internal = 0; gOverlapped.InternalHigh = 0;

gOverlapped.Offset gOverlapped.OffsetHigh gOverlapped.hEvent

= 0; = 0; = CreateEvent(NULL, FALSE, FALSE, NULL);

if(pLength != NULL)*pLength = 0; // attempt an asynchronous read operation bResult = ReadFile(handle,pData,dwLen,&nBytesRead,&gOverlapped); if(!bResult) { // deal with the error code switch (GetLastError()) { case ERROR_HANDLE_EOF: { // we have reached the end of the file // during the call to ReadFile break; } case ERROR_IO_PENDING: { // asynchronous i/o is still in progress switch(WaitForSingleObject(gOverlapped.hEvent, dwMilliseconds)) { case WAIT_OBJECT_0: // check on the results of the asynchronous read // and update the nBytesRead... bResult = GetOverlappedResult(handle, &gOverlapped, &nBytesRead, FALSE); if(!bResult) { printf("Error: %d", GetLastError()); } else { if(pLength != NULL) *pLength = nBytesRead; dwResult = MPUSB_SUCCESS; }//end if else break; case WAIT_TIMEOUT: CancelIo(handle); break; default: //switch(WaitForSingleObject(gOverlapped.hEvent, dw Milliseconds)) CancelIo(handle); break; }//end switch break; //switch (GetLastError()) case ERROR_IO_PENDING }//end case default: //switch (GetLastError()) CancelIo(handle); break; }//end switch } else { if(pLength != NULL) *pLength = nBytesRead;

dwResult = MPUSB_SUCCESS; }//end if else ResetEvent(gOverlapped.hEvent); CloseHandle(gOverlapped.hEvent); return dwResult; }//end MPUSBRead /////////////////////////////////////////////////////////////////////////////// // MPUSBWrite : // // handle - Identifies the endpoint pipe to be written to. The pipe handle // must have been created with MP_WRITE access attribute. // // pData - Points to the buffer containing the data to be written to the pipe . // // dwLen - Specifies the number of bytes to write to the pipe. // // pLength - Points to the number of bytes written by this function call. // MPUSBWrite sets this value to zero before doing any work or // error checking. // // dwMilliseconds // - Specifies the time-out interval, in milliseconds. The function // returns if the interval elapses, even if the operation is // incomplete. If dwMilliseconds is zero, the function tests the // data pipe and returns immediately. If dwMilliseconds is INFINITE, // the function's time-out interval never elapses. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBWrite(HANDLE handle, // Input PVOID pData, // Input DWORD dwLen, // Input PDWORD pLength, // Output DWORD dwMilliseconds) // Input { BOOL bResult; DWORD nBytesWritten; OVERLAPPED gOverlapped; DWORD dwResult; dwResult = MPUSB_FAIL; // set up overlapped structure fields gOverlapped.Internal = 0; gOverlapped.InternalHigh = 0; gOverlapped.Offset = 0; gOverlapped.OffsetHigh = 0; gOverlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(pLength != NULL)*pLength = 0; // attempt an asynchronous read operation bResult = WriteFile(handle,pData,dwLen,&nBytesWritten,&gOverlapped);

if(!bResult) { // deal with the error code switch (GetLastError()) { case ERROR_HANDLE_EOF: { // we have reached the end of the file // during the call to ReadFile break; } case ERROR_IO_PENDING: { // asynchronous i/o is still in progress switch(WaitForSingleObject(gOverlapped.hEvent, dwMilliseconds)) { case WAIT_OBJECT_0: // check on the results of the asynchronous read // and update the nBytesWritten... bResult = GetOverlappedResult(handle, &gOverlapped, &nBytesWritten, FALSE); if(!bResult) { printf("Error: %d", GetLastError()); } else { if(pLength != NULL) *pLength = nBytesWritten; dwResult = MPUSB_SUCCESS; }//end if else break; case WAIT_TIMEOUT: CancelIo(handle); break; default: CancelIo(handle); break; }//end switch break; }//end case default: CancelIo(handle); break; }//end switch } else { if(pLength != NULL) *pLength = nBytesWritten; dwResult = MPUSB_SUCCESS; }//end if else ResetEvent(gOverlapped.hEvent); CloseHandle(gOverlapped.hEvent); return dwResult; }//end MPUSBWrite

/////////////////////////////////////////////////////////////////////////////// // MPUSBReadInt : // // handle - Identifies the endpoint pipe to be read. The pipe handle must // have been created with MP_READ access attribute. // // pData - Points to the buffer that receives the data read from the pipe. // // dwLen - Specifies the number of bytes to be read from the pipe. // // pLength - Points to the number of bytes read. MPUSBRead sets this value to // zero before doing any work or error checking. // // dwMilliseconds // - Specifies the time-out interval, in milliseconds. The function // returns if the interval elapses, even if the operation is // incomplete. If dwMilliseconds is zero, the function tests the // data pipe and returns immediately. If dwMilliseconds is INFINITE, // the function's time-out interval never elapses. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // DWORD MPUSBReadInt(HANDLE handle, // Input PVOID pData, // Output DWORD dwLen, // Input PDWORD pLength, // Output DWORD dwMilliseconds)// Input { BOOL bResult; DWORD nBytesRead; OVERLAPPED gOverlapped; DWORD dwResult; dwResult = MPUSB_FAIL; // set up overlapped structure fields gOverlapped.Internal = 0; gOverlapped.InternalHigh = 0; gOverlapped.Offset = 0; gOverlapped.OffsetHigh = 0; gOverlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(pLength != NULL)*pLength = 0; if(pData == NULL) { SetLastError(ERROR_NOACCESS); return dwResult; }//end if // attempt an asynchronous read operation bResult = DeviceIoControl(handle, IOCTL_MCHPUSB_WAIT_INTERRUPT, NULL, 0, pData, dwLen,

&nBytesRead, &gOverlapped); if(!bResult) { // deal with the error code switch (GetLastError()) { case ERROR_HANDLE_EOF: { // we have reached the end of the file // during the call to ReadFile break; } case ERROR_IO_PENDING: { // asynchronous i/o is still in progress switch(WaitForSingleObject(gOverlapped.hEvent, dwMilliseconds)) { case WAIT_OBJECT_0: // check on the results of the asynchronous read // and update the nBytesRead... bResult = GetOverlappedResult(handle, &gOverlapped, &nBytesRead, FALSE); if(!bResult) { printf("Error: %d", GetLastError()); } else { if(pLength != NULL) *pLength = nBytesRead; dwResult = MPUSB_SUCCESS; }//end if else break; case WAIT_TIMEOUT: CancelIo(handle); break; default: CancelIo(handle); break; }//end switch break; }//end case default: CancelIo(handle); break; }//end switch } else { if(pLength != NULL) *pLength = nBytesRead; dwResult = MPUSB_SUCCESS; }//end if else ResetEvent(gOverlapped.hEvent); CloseHandle(gOverlapped.hEvent); return dwResult; }//end MPUSBReadInt

/////////////////////////////////////////////////////////////////////////////// // MPUSBClose : closes a given handle. // // Note that "input" and "output" refer to the parameter designations in ca lls // to this function, which are the opposite of common sense from the // perspective of an application making the calls. // BOOL MPUSBClose(HANDLE handle) { BOOL toReturn; toReturn = true; if(handle != INVALID_HANDLE_VALUE) toReturn = CloseHandle(handle); return toReturn; }//end MPUSBClose //---------------------------------------------------------------------------

You might also like