/*********************************************************************
*
* MPUSBAPI Library Version 1.00
*
*********************************************************************
* FileName: _mpusbapi.cpp
* Dependencies: See #include section below.
* Compiler: Borland C++ Builder 6
* Company: Copyright (C) 2004 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 Companys 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.
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Ross Fosler 9/2/04 Implemented MPUSBGetDeviceLink()
* Rawin Rojvanit 11/19/04 Original version 1.00 completed
********************************************************************/
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <setupapi.h>
#include <initguid.h>
#include <winioctl.h>
#include "ioctls.h"
#include "_mpusbapi.h"
#define MPUSBAPI_VERSION 0x00010000L
#define MPUSB_DEV_NO_INFO 2
#define MPUSB_DEV_INVALID_INST 3
#define MPUSB_DEV_VIDPID_NOT_FOUND 4
#define MPUSB_DEV_NOT_ATTACHED 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 MMMMmmmm
//
DWORD MPUSBGetDLLVersion(void)
{
return MPUSBAPI_VERSION;
}//end MPUSBGetDLLVersion
///////////////////////////////////////////////////////////////////////////////
// MPUSBIsVidPidEqual : Compares the pVID_PID string against the DeviceInstance
// 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 calls
// 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],pDevicePath);
/* Open Key */
returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
lpSubKey,
0L,
KEY_ALL_ACCESS,
&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 calls
// 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,
i
- 1
- 2
前往页