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

📄 pnp.cpp

📁 采用tenx TMU3110开发的一个HID的示例程式 包括单片机程式 ,PC端USb接收程式
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1996    Microsoft Corporation

Module Name:

    pnp.c

Abstract:

    This module contains the code
    for finding, adding, removing, and identifying hid devices.

Environment:

    User mode

--*/

#include "stdafx.h"
#include <dbt.h>
#include "hid.h"
#include <basetyps.h>
#include <stdlib.h>
#include <wtypes.h>
#include <setupapi.h>

#define TENX_VID 0x1130
#define TENX_PID 0x0202

/*++
Routine Description:
   Do the required PnP things in order to find the 1603 HID device in
   the system at this time.
--*/

BOOLEAN FindGenericHIDDevice(PHID_DEVICE HidDevice, PHID_DEVICE HidCBWDevice, HWND hWnd) 
{
    HDEVINFO                            hardwareDeviceInfo;
    SP_INTERFACE_DEVICE_DATA            deviceInfoData;
    ULONG                               i;
    GUID                                hidGuid;
    PSP_INTERFACE_DEVICE_DETAIL_DATA    functionClassDeviceData = NULL;
    ULONG                               predictedLength = 0;
    ULONG                               requiredLength = 0;
	BOOL	bFindDevice, bFindCBWDevice, bFind; 
	
	bFindDevice = bFindCBWDevice = FALSE;


    HidD_GetHidGuid (&hidGuid);

    //
    // Open a handle to the plug and play dev node.
    //
    hardwareDeviceInfo = SetupDiGetClassDevs ( &hidGuid,
                                               NULL, // Define no enumerator (global)
                                               NULL, // Define no
                                               (DIGCF_PRESENT | // Only Devices present
                                                DIGCF_DEVICEINTERFACE)); // Function class devices.


    deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);


    for (i=0; SetupDiEnumDeviceInterfaces(hardwareDeviceInfo, 0, &hidGuid, i, &deviceInfoData); i++) {
		bFind = FALSE;

		//
        // allocate a function class device data structure to receive the
        // goods about this particular device.
        //

        SetupDiGetDeviceInterfaceDetail (
                hardwareDeviceInfo,
                &deviceInfoData,
                NULL, // probing so no output buffer yet
                0, // probing so output buffer length of zero
                &requiredLength,
                NULL); // not interested in the specific dev-node


        predictedLength = requiredLength;

        functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc (predictedLength);
        if (functionClassDeviceData)
        {
            functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
        }
        else
        {
            SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
            return FALSE;
        }

        //
        // Retrieve the information from Plug and Play.
        //

        if (! SetupDiGetDeviceInterfaceDetail (
                   hardwareDeviceInfo,
                   &deviceInfoData,
                   functionClassDeviceData,
                   predictedLength,
                   &requiredLength,
                   NULL)) 
        {
            SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
            return FALSE;
        }

        //
        // Open device with just generic query abilities to begin with
        //
              
		if(!bFindDevice) {
			bFind = bFindDevice = OpenHidDevice (functionClassDeviceData -> DevicePath, 
						   TRUE,      // ReadAccess - none
						   TRUE,      // WriteAccess - none
						   FALSE,       // Overlapped - no
						   FALSE,       // Exclusive - no
						   TRUE,        // GetDeviceInfo - yes
						   HidDevice,
						   hWnd,
						   1, 0);
		} 

		if(!bFindCBWDevice && !bFind) {
			bFindCBWDevice = OpenHidDevice (functionClassDeviceData -> DevicePath, 
						   TRUE,      // ReadAccess - none
						   TRUE,      // WriteAccess - none
						   FALSE,       // Overlapped - no
						   FALSE,       // Exclusive - no
						   TRUE,        // GetDeviceInfo - yes
						   HidCBWDevice,
						   hWnd,
						   1, 3);
		}

		if(bFindDevice && bFindCBWDevice) break;
	}

    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
    return (bFindDevice && bFindCBWDevice);
}


/*++
RoutineDescription:
    Given the HardwareDeviceInfo, representing a handle to the plug and
    play information, and deviceInfoData, representing a specific hid device,
    open that device and fill in all the relivant information in the given
    HID_DEVICE structure.

    return if the open and initialization was successfull or not.

--*/
BOOLEAN
OpenHidDevice (
    IN       PCHAR          DevicePath,
    IN       BOOL           HasReadAccess,
    IN       BOOL           HasWriteAccess,
    IN       BOOL           IsOverlapped,
    IN       BOOL           IsExclusive,
    IN       BOOL           GetDeviceInfo,
    IN OUT   PHID_DEVICE    HidDevice,
	IN		 HWND			hWnd,
	IN		 USHORT			usUsagePage,
	IN		 USHORT			usUsageID
)
{
    DWORD   accessFlags = 0;
    DWORD   sharingFlags = 0;
    
	DWORD dwLen = strlen(DevicePath);
    HidDevice -> DevicePath = (PCHAR)malloc(dwLen + 1);

    if (NULL == HidDevice -> DevicePath) 
    {
        return (FALSE);
    }

    strcpy(HidDevice -> DevicePath, DevicePath);
	HidDevice -> DevicePath[dwLen] = '\0';
    
    if (HasReadAccess)
    {
        accessFlags |= GENERIC_READ;
    }

    if (HasWriteAccess)
    {
        accessFlags |= GENERIC_WRITE;
    }

    if (!IsExclusive)
    {
        sharingFlags = FILE_SHARE_READ | FILE_SHARE_WRITE;
    }
    
    HidDevice->HidDevice = CreateFile (DevicePath,
                                       accessFlags,
                                       sharingFlags,
                                       NULL,        // no SECURITY_ATTRIBUTES structure
                                       OPEN_EXISTING, // No special create flags
                                       IsOverlapped ? FILE_FLAG_OVERLAPPED : 0, 
                                       NULL);       // No template file

    if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) 
    {
        free(HidDevice -> DevicePath);
        return FALSE;
    }

    HidDevice -> OpenedForRead = HasReadAccess;
    HidDevice -> OpenedForWrite = HasWriteAccess;
    HidDevice -> OpenedOverlapped = IsOverlapped;
    HidDevice -> OpenedExclusive = IsExclusive;
    
    //
    // If the device was not opened as overlapped, then fill in the rest of the
    //  HidDevice structure.  However, if opened as overlapped, this handle cannot
    //  be used in the calls to the HidD_ exported functions since each of these
    //  functions does synchronous I/O.
    //
 
    if (!HidD_GetAttributes (HidDevice->HidDevice, &HidDevice->Attributes)) 
    {
        free(HidDevice -> DevicePath);
        CloseHandle(HidDevice -> HidDevice);
        return FALSE;
    } else {	// Check the VID/PID
		if( (HidDevice->Attributes.VendorID != TENX_VID) || (HidDevice->Attributes.ProductID != TENX_PID) ) {
			free(HidDevice -> DevicePath);
			CloseHandle(HidDevice -> HidDevice);
			return FALSE;			
		}
	}

	
    if (GetDeviceInfo) 
    {
        if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd)) 
        {
            free(HidDevice -> DevicePath);
            CloseHandle(HidDevice -> HidDevice);
            return FALSE;
        }

        if (!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps))
        {
            free(HidDevice -> DevicePath);

            CloseHandle(HidDevice -> HidDevice);

            HidD_FreePreparsedData (HidDevice->Ppd);

            return FALSE;
        } else {	// Check the usage page and usage ID.
			if((HidDevice->Caps.UsagePage != (USAGE)usUsagePage) || (HidDevice->Caps.Usage != (USAGE)usUsageID)) {
				free(HidDevice -> DevicePath);

				CloseHandle(HidDevice -> HidDevice);

				HidD_FreePreparsedData (HidDevice->Ppd);

				return FALSE;
			}
		}


        //
        // At this point the client has a choice.  It may chose to look at the
        // Usage and Page of the top level collection found in the HIDP_CAPS
        // structure.  In this way it could just use the usages it knows about.
        // If either HidP_GetUsages or HidP_GetUsageValue return an error then
        // that particular usage does not exist in the report.
        // This is most likely the preferred method as the application can only
        // use usages of which it already knows.
        // In this case the app need not even call GetButtonCaps or GetValueCaps.
        //
        // In this example, however, we will call FillDeviceInfo to look for all
        //    of the usages in the device.
        //

        FillDeviceInfo(HidDevice);

		DEV_BROADCAST_HANDLE broadcastHandle;

		broadcastHandle.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
		broadcastHandle.dbch_devicetype = DBT_DEVTYP_HANDLE;
		broadcastHandle.dbch_handle = HidDevice->HidDevice;

		HidDevice->hDeviceNotificationHandle = RegisterDeviceNotification( 
									hWnd,
									&broadcastHandle,
									DEVICE_NOTIFY_WINDOW_HANDLE);
		HidDevice->bFound = TRUE;
    }
    
    return (TRUE);
}

VOID
FillDeviceInfo(
    IN  PHID_DEVICE HidDevice
)
{
    USHORT              numValues;
    USHORT              numCaps;
    PHIDP_BUTTON_CAPS   buttonCaps;
    PHIDP_VALUE_CAPS    valueCaps;
    PHID_DATA           data;
    ULONG               i;
    USAGE               usage;

    //
    // setup Input Data buffers.
    //

    //
    // Allocate memory to hold on input report
    //

    HidDevice->InputReportBuffer = (PCHAR) 
        calloc (HidDevice->Caps.InputReportByteLength, sizeof (CHAR));


    //
    // Allocate memory to hold the button and value capabilities.
    // NumberXXCaps is in terms of array elements.
    //
    
    HidDevice->InputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
        calloc (HidDevice->Caps.NumberInputButtonCaps, sizeof (HIDP_BUTTON_CAPS));

    HidDevice->InputValueCaps = valueCaps = (PHIDP_VALUE_CAPS)
        calloc (HidDevice->Caps.NumberInputValueCaps, sizeof (HIDP_VALUE_CAPS));

    //
    // Have the HidP_X functions fill in the capability structure arrays.
    //

    numCaps = HidDevice->Caps.NumberInputButtonCaps;

    HidP_GetButtonCaps (HidP_Input,
                        buttonCaps,
                        &numCaps,
                        HidDevice->Ppd);

    numCaps = HidDevice->Caps.NumberInputValueCaps;

    HidP_GetValueCaps (HidP_Input,
                       valueCaps,
                       &numCaps,
                       HidDevice->Ppd);


    //
    // Depending on the device, some value caps structures may represent more
    // than one value.  (A range).  In the interest of being verbose, over
    // efficient, we will expand these so that we have one and only one
    // struct _HID_DATA for each value.
    //
    // To do this we need to count up the total number of values are listed
    // in the value caps structure.  For each element in the array we test
    // for range if it is a range then UsageMax and UsageMin describe the
    // usages for this range INCLUSIVE.
    //
    
    numValues = 0;
    for (i = 0; i < HidDevice->Caps.NumberInputValueCaps; i++, valueCaps++) 
    {
        if (valueCaps->IsRange) 
        {
            numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1;
        }
        else
        {
            numValues++;
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -