Esempio n. 1
0
int HID_API_EXPORT hid_init(void)
{
#ifndef HIDAPI_USE_DDK
	if (!initialized) {
//        DebugClearText ();
        if (lookup_functions() < 0) {
			hid_exit();
            DebugAppendText ("initialized FAILED\n");

            return -1;
		}
		initialized = TRUE;
        DebugAppendText ("initialized = TRUE;\n");
	}
#endif
	return 0;
}
Esempio n. 2
0
HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
{
	// TODO: Merge this functions with the Linux version. This function should be platform independent.
	struct hid_device_info *devs, *cur_dev;
	const char *path_to_open = NULL;
    hid_device *handle = NULL;

#ifdef STICK20_DEBUG
{ // For debugging
    char text[1000];
    sprintf(text,"hid_open: VID %04x PID %04x\n", vendor_id,product_id);
    DebugAppendText (text);
}
#endif

	devs = hid_enumerate(vendor_id, product_id);
	cur_dev = devs;
	while (cur_dev) {
		if (cur_dev->vendor_id == vendor_id &&
		    cur_dev->product_id == product_id) {
			if (serial_number) {
				if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
					path_to_open = cur_dev->path;
					break;
				}
			}
			else {
				path_to_open = cur_dev->path;
				break;
			}
		}
		cur_dev = cur_dev->next;
	}

	if (path_to_open) {
		/* Open the device */
		handle = hid_open_path(path_to_open);
	}

	hid_free_enumeration(devs);
	
	return handle;
}
Esempio n. 3
0
void Response::DebugResponse()
{
    char text[1000];
    char text1[1000];
    int i;
    static int Counter = 0;

    sprintf(text,"%6d :getResponse : ",Counter);
    Counter++;
    DebugAppendText (text);
    for (i=0;i<=64;i++)
    {
        sprintf(text,"%02x ",(unsigned char)reportBuffer[i]);
        DebugAppendText (text);
    }
    sprintf(text,"\n");
    DebugAppendText (text);

// Check device status =     deviceStatus = reportBuffer[1]
    switch (deviceStatus)
    {
        case CMD_STATUS_OK :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_OK\n");
            break;
        case CMD_STATUS_WRONG_CRC :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_WRONG_CRC\n");
            break;
        case CMD_STATUS_WRONG_SLOT :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_WRONG_SLOT\n");
            break;
        case CMD_STATUS_SLOT_NOT_PROGRAMMED :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_SLOT_NOT_PROGRAMMED\n");
            break;
        case CMD_STATUS_WRONG_PASSWORD :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_WRONG_PASSWORD\n");
            break;
        case CMD_STATUS_NOT_AUTHORIZED :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_NOT_AUTHORIZED\n");
            break;
        case CMD_STATUS_TIMESTAMP_WARNING :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_TIMESTAMP_WARNING\n");
            break;
        case CMD_STATUS_NO_NAME_ERROR :
            DebugAppendText ((char *)"         Device status       : CMD_STATUS_NO_NAME_ERROR\n");
            break;

        default:
                DebugAppendText ((char *)"         Device status       : Unknown\n");
                break;
    }


// Check last command =     lastCommandType   = reportBuffer[2]
    switch (lastCommandType)
    {
        case CMD_GET_STATUS :
            DebugAppendText ((char *)"         Last command        : CMD_GET_STATUS\n");
            break;
        case CMD_WRITE_TO_SLOT :
            DebugAppendText ((char *)"         Last command        : CMD_WRITE_TO_SLOT\n");
            break;
        case CMD_READ_SLOT_NAME :
            strncpy (text1,data,15);
            text1[15] = 0;
            sprintf(text,"         Last command        : CMD_READ_SLOT_NAME -%s-\n",text1);
            DebugAppendText (text);
            break;
        case CMD_READ_SLOT :
            DebugAppendText ((char *)"         Last command        : CMD_READ_SLOT\n");
            break;
        case CMD_GET_CODE :
            DebugAppendText ((char *)"         Last command        : CMD_GET_CODE\n");
            break;
        case CMD_WRITE_CONFIG :
            DebugAppendText ((char *)"         Last command        : CMD_WRITE_CONFIG\n");
            break;
        case CMD_ERASE_SLOT :
            DebugAppendText ((char *)"         Last command        : CMD_ERASE_SLOT\n");
            break;
        case CMD_FIRST_AUTHENTICATE :
            DebugAppendText ((char *)"         Last command        : CMD_FIRST_AUTHENTICATE\n");
            break;
        case CMD_AUTHORIZE :
            DebugAppendText ((char *)"         Last command        : CMD_AUTHORIZE\n");
            break;
        case CMD_GET_PASSWORD_RETRY_COUNT :
            DebugAppendText ((char *)"         Last command        : CMD_GET_PASSWORD_RETRY_COUNT\n");
            break;
        case CMD_CLEAR_WARNING :
            DebugAppendText ((char *)"         Last command        : CMD_CLEAR_WARNING\n");
            break;


        case CMD_GET_PW_SAFE_SLOT_STATUS :
            DebugAppendText ((char *)"         Last command        : CMD_GET_PW_SAFE_SLOT_STATUS\n");
            break;
        case CMD_GET_PW_SAFE_SLOT_NAME :
            DebugAppendText ((char *)"         Last command        : CMD_GET_PW_SAFE_SLOT_NAME\n");
            break;
        case CMD_GET_PW_SAFE_SLOT_PASSWORD :
            DebugAppendText ((char *)"         Last command        : CMD_GET_PW_SAFE_SLOT_PASSWORD\n");
            break;

        case CMD_GET_PW_SAFE_SLOT_LOGINNAME :
            DebugAppendText ((char *)"         Last command        : CMD_GET_PW_SAFE_SLOT_LOGINNAME\n");
            break;
        case CMD_SET_PW_SAFE_SLOT_DATA_1 :
            DebugAppendText ((char *)"         Last command        : CMD_SET_PW_SAFE_SLOT_DATA_1\n");
            break;
        case CMD_SET_PW_SAFE_SLOT_DATA_2 :
            DebugAppendText ((char *)"         Last command        : CMD_SET_PW_SAFE_SLOT_DATA_2\n");
            break;
        case CMD_PW_SAFE_ERASE_SLOT :
            DebugAppendText ((char *)"         Last command        : CMD_PW_SAFE_ERASE_SLOT\n");
            break;
        case CMD_PW_SAFE_ENABLE :
            DebugAppendText ((char *)"         Last command        : CMD_PW_SAFE_ENABLE\n");
            break;
        case CMD_PW_SAFE_INIT_KEY :
            DebugAppendText ((char *)"         Last command        : CMD_PW_SAFE_INIT_KEY\n");
            break;
        case CMD_PW_SAFE_SEND_DATA :
            DebugAppendText ((char *)"         Last command        : CMD_PW_SAFE_SEND_DATA");
            break;
        case CMD_SD_CARD_HIGH_WATERMARK :
            DebugAppendText ((char *)"         Last command        : CMD_SD_CARD_HIGH_WATERMARK");
            break;

        case CMD_SET_TIME :
            DebugAppendText ((char *)"         Last command        : CMD_SET_TIME\n");
            break;
        case CMD_TEST_COUNTER :
            DebugAppendText ((char *)"         Last command        : CMD_TEST_COUNTER\n");
            break;
        case CMD_TEST_TIME :
            DebugAppendText ((char *)"         Last command        : CMD_TEST_TIME\n");
            break;
        case CMD_USER_AUTHENTICATE :
            DebugAppendText ((char *)"         Last command        : CMD_USER_AUTHENTICATE\n");
            break;
        case CMD_GET_USER_PASSWORD_RETRY_COUNT :
            DebugAppendText ((char *)"         Last command        : CMD_GET_USER_PASSWORD_RETRY_COUNT\n");
            break;
        case CMD_USER_AUTHORIZE :
            DebugAppendText ((char *)"         Last command        : CMD_USER_AUTHORIZE\n");
            break;
        case CMD_UNLOCK_USER_PASSOWRD :
            DebugAppendText ((char *)"         Last command        : CMD_UNLOCK_USER_PASSOWRD\n");
            break;
        case CMD_LOCK_DEVICE :
            DebugAppendText ((char *)"         Last command        : CMD_LOCK_DEVICE");
            break;

        case STICK20_CMD_ENABLE_CRYPTED_PARI            :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_ENABLE_CRYPTED_PARI           \n");         break;
        case STICK20_CMD_DISABLE_CRYPTED_PARI           :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_DISABLE_CRYPTED_PARI          \n");         break;
        case STICK20_CMD_ENABLE_HIDDEN_CRYPTED_PARI     :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_ENABLE_HIDDEN_CRYPTED_PARI    \n");         break;
        case STICK20_CMD_DISABLE_HIDDEN_CRYPTED_PARI    :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_DISABLE_HIDDEN_CRYPTED_PARI   \n");         break;
        case STICK20_CMD_ENABLE_FIRMWARE_UPDATE         :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_ENABLE_FIRMWARE_UPDATE        \n");         break;
        case STICK20_CMD_EXPORT_FIRMWARE_TO_FILE        :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_EXPORT_FIRMWARE_TO_FILE       \n");         break;
        case STICK20_CMD_GENERATE_NEW_KEYS              :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_GENERATE_NEW_KEYS             \n");         break;
        case STICK20_CMD_FILL_SD_CARD_WITH_RANDOM_CHARS :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_FILL_SD_CARD_WITH_RANDOM_CHARS\n");         break;
        case STICK20_CMD_WRITE_STATUS_DATA              :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_WRITE_STATUS_DATA             \n");         break;
        case STICK20_CMD_ENABLE_READONLY_UNCRYPTED_LUN  :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_ENABLE_READONLY_UNCRYPTED_LUN \n");         break;
        case STICK20_CMD_ENABLE_READWRITE_UNCRYPTED_LUN :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_ENABLE_READWRITE_UNCRYPTED_LUN\n");         break;
        case STICK20_CMD_SEND_PASSWORD_MATRIX           :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_PASSWORD_MATRIX          \n");         break;
        case STICK20_CMD_SEND_PASSWORD_MATRIX_PINDATA   :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_PASSWORD_MATRIX_PINDATA  \n");         break;
        case STICK20_CMD_SEND_PASSWORD_MATRIX_SETUP     :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_PASSWORD_MATRIX_SETUP    \n");         break;
        case STICK20_CMD_GET_DEVICE_STATUS              :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_GET_DEVICE_STATUS             \n");         break;
        case STICK20_CMD_SEND_DEVICE_STATUS             :    DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_DEVICE_STATUS            \n");         break;

        case STICK20_CMD_SEND_HIDDEN_VOLUME_PASSWORD :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_HIDDEN_VOLUME_PASSWORD\n");
            break;
        case STICK20_CMD_SEND_HIDDEN_VOLUME_SETUP :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_HIDDEN_VOLUME_SETUP\n");
            break;
        case STICK20_CMD_SEND_PASSWORD :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_PASSWORD\n");
            break;
        case STICK20_CMD_SEND_NEW_PASSWORD :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_NEW_PASSWORD\n");
            break;
        case STICK20_CMD_CLEAR_NEW_SD_CARD_FOUND :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_CLEAR_NEW_SD_CARD_FOUND\n");
            break;
        case STICK20_CMD_SEND_STARTUP :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_STARTUP\n");
            break;
        case STICK20_CMD_SEND_CLEAR_STICK_KEYS_NOT_INITIATED :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_CLEAR_STICK_KEYS_NOT_INITIATED\n");
            break;
        case STICK20_CMD_SEND_LOCK_STICK_HARDWARE :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_SEND_LOCK_STICK_HARDWARE\n");
            break;
        case STICK20_CMD_PRODUCTION_TEST :
            DebugAppendText ((char *)"         Last command        : STICK20_CMD_PRODUCTION_TEST\n");
            break;
        default:
            DebugAppendText ((char *)"         Last command        : Unknown\n");
            break;
    }


// Check last command status =     lastCommandStatus = reportBuffer[7]
    switch (lastCommandStatus)
    {
        case CMD_STATUS_OK :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_OK\n");
            break;
        case CMD_STATUS_WRONG_CRC :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_WRONG_CRC\n");
            break;
        case CMD_STATUS_WRONG_SLOT :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_WRONG_SLOT\n");
            break;
        case CMD_STATUS_SLOT_NOT_PROGRAMMED :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_SLOT_NOT_PROGRAMMED\n");
            break;
        case CMD_STATUS_WRONG_PASSWORD :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_WRONG_PASSWORD\n");
            break;
        case CMD_STATUS_NOT_AUTHORIZED :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_NOT_AUTHORIZED\n");
            break;
        case CMD_STATUS_TIMESTAMP_WARNING :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_TIMESTAMP_WARNING\n");
            break;
        case CMD_STATUS_NO_NAME_ERROR :
            DebugAppendText ((char *)"         Last command status : CMD_STATUS_NO_NAME_ERROR\n");
            break;
        default:
            DebugAppendText ((char *)"         Last command status : Unknown\n");
            break;
    }

//    lastCommandCRC     = ((uint32_t *)(reportBuffer+3))[0];
//    responseCRC       = ((uint32_t *)(reportBuffer+61))[0];


}
void Response::DebugResponse()
{
    char text[1000];
    char text1[1000];
    int i;
    static int Counter = 0;

    sprintf(text,"%6d :getResponse: ",Counter);
    Counter++;
    DebugAppendText (text);
    for (i=0;i<=64;i++)
    {
        sprintf(text,"%02x ",(unsigned char)reportBuffer[i]);
        DebugAppendText (text);
    }
    sprintf(text,"\n");
    DebugAppendText (text);

// Check device status =     deviceStatus = reportBuffer[1]
    switch (deviceStatus)
    {
        case CMD_STATUS_OK :
            DebugAppendText ("         Device status       : CMD_STATUS_OK\n");
            break;
        case CMD_STATUS_WRONG_CRC :
            DebugAppendText ("         Device status       : CMD_STATUS_WRONG_CRC\n");
            break;
        case CMD_STATUS_WRONG_SLOT :
            DebugAppendText ("         Device status       : CMD_STATUS_WRONG_SLOT\n");
            break;
        case CMD_STATUS_SLOT_NOT_PROGRAMMED :
            DebugAppendText ("         Device status       : CMD_STATUS_SLOT_NOT_PROGRAMMED\n");
            break;
        case CMD_STATUS_WRONG_PASSWORD :
            DebugAppendText ("         Device status       : CMD_STATUS_WRONG_PASSWORD\n");
            break;
        case CMD_STATUS_NOT_AUTHORIZED :
            DebugAppendText ("         Device status       : CMD_STATUS_NOT_AUTHORIZED\n");
            break;
        default:
            DebugAppendText ("         Device status       : Unknown\n");
            break;
    }


// Check last command =     lastCommandType   = reportBuffer[2]
    switch (lastCommandType)
    {
        case CMD_GET_STATUS :
            DebugAppendText ("         Last command        : CMD_GET_STATUS\n");
            break;
        case CMD_WRITE_TO_SLOT :
            DebugAppendText ("         Last command        : CMD_WRITE_TO_SLOT\n");
            break;
        case CMD_READ_SLOT_NAME :
            strncpy (text1,data,15);
            text1[15] = 0;
            sprintf(text,"         Last command        : CMD_READ_SLOT_NAME -%s-\n",text1);
            DebugAppendText (text);
            break;
        case CMD_READ_SLOT :
            DebugAppendText ("         Last command        : CMD_READ_SLOT\n");
            break;
        case CMD_GET_CODE :
            DebugAppendText ("         Last command        : CMD_GET_CODE\n");
            break;
        case CMD_WRITE_CONFIG :
            DebugAppendText ("         Last command        : CMD_WRITE_CONFIG\n");
            break;
        case CMD_ERASE_SLOT :
            DebugAppendText ("         Last command        : CMD_ERASE_SLOT\n");
            break;
        case CMD_FIRST_AUTHENTICATE :
            DebugAppendText ("         Last command        : CMD_FIRST_AUTHENTICATE\n");
            break;
        case CMD_AUTHORIZE :
            DebugAppendText ("         Last command        : CMD_AUTHORIZE\n");
            break;
        case CMD_GET_PASSWORD_RETRY_COUNT :
            DebugAppendText ("         Last command        : CMD_GET_PASSWORD_RETRY_COUNT\n");
            break;
        default:
            DebugAppendText ("         Last command        : Unknown\n");
            break;
    }




// Check last command status =     lastCommandStatus = reportBuffer[7]
    switch (lastCommandStatus)
    {
        case CMD_STATUS_OK :
            DebugAppendText ("         Last command status : CMD_STATUS_OK\n");
            break;
        case CMD_STATUS_WRONG_CRC :
            DebugAppendText ("         Last command status : CMD_STATUS_WRONG_CRC\n");
            break;
        case CMD_STATUS_WRONG_SLOT :
            DebugAppendText ("         Last command status : CMD_STATUS_WRONG_SLOT\n");
            break;
        case CMD_STATUS_SLOT_NOT_PROGRAMMED :
            DebugAppendText ("         Last command status : CMD_STATUS_SLOT_NOT_PROGRAMMED\n");
            break;
        case CMD_STATUS_WRONG_PASSWORD :
            DebugAppendText ("         Last command status : CMD_STATUS_WRONG_PASSWORD\n");
            break;
        case CMD_STATUS_NOT_AUTHORIZED :
            DebugAppendText ("         Last command status : CMD_STATUS_NOT_AUTHORIZED\n");
            break;
        default:
            DebugAppendText ("         Last command status : Unknown\n");
            break;
    }

//    lastCommandCRC     = ((uint32_t *)(reportBuffer+3))[0];
//    responseCRC       = ((uint32_t *)(reportBuffer+61))[0];



}
Esempio n. 5
0
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	BOOL res;
	struct hid_device_info *root = NULL; // return object
	struct hid_device_info *cur_dev = NULL;

	// Windows objects for interacting with the driver.
	GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
	SP_DEVINFO_DATA devinfo_data;
	SP_DEVICE_INTERFACE_DATA device_interface_data;
	SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
	HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
	int device_index = 0;
	int i;
#ifdef STICK20_DEBUG
    { // For debugging
        char text[1000];
        sprintf(text,"hid_enumerate: Start VID %04x PID %04x\n", vendor_id,product_id);
        DebugAppendText (text);
    }
#endif
	if (hid_init() < 0)
		return NULL;

//    DebugAppendText ("hid_enumerate: 2\n");

	// Initialize the Windows objects.
	memset(&devinfo_data, 0x0, sizeof(devinfo_data));
	devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
	device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	// Get information for all the devices belonging to the HID class.
    device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
//    device_info_set = SetupDiGetClassDevsA(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);



	// Iterate over each device in the HID class, looking for the right one.
	
	for (;;) {
		HANDLE write_handle = INVALID_HANDLE_VALUE;
		DWORD required_size = 0;
		HIDD_ATTRIBUTES attrib;

		res = SetupDiEnumDeviceInterfaces(device_info_set,
			NULL,
			&InterfaceClassGuid,
			device_index,
			&device_interface_data);
		
		if (!res) {
			// A return of FALSE from this function means that
			// there are no more devices.
			break;
		}

		// Call with 0-sized detail size, and let the function
		// tell us how long the detail struct needs to be. The
		// size is put in &required_size.
		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
			&device_interface_data,
			NULL,
			0,
			&required_size,
			NULL);

		// Allocate a long enough structure for device_interface_detail_data.
		device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
		device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);

		// Get the detailed data for this device. The detail data gives us
		// the device path for this device, which is then passed into
		// CreateFile() to get a handle to the device.
		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
			&device_interface_data,
			device_interface_detail_data,
			required_size,
			NULL,
			NULL);

		if (!res) {
			//register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
			// Continue to the next device.
			goto cont;
		}

		// Make sure this device is of Setup Class "HIDClass" and has a
		// driver bound to it.
		for (i = 0; ; i++) {
			char driver_name[256];

			// Populate devinfo_data. This function will return failure
			// when there are no more interfaces left.

			res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
			if (!res)
				goto cont;

			res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
			               SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
			if (!res)
				goto cont;
#ifdef STICK20_DEBUG_ALL
            {
                    char text[1000];
                sprintf(text,"HandleName: 4c %s\n", driver_name);
                 DebugAppendText (text);
            }
#endif
            if ((strcmp(driver_name, "HIDClass") == 0) || (strcmp(driver_name, "Keyboard") == 0)) {
				// See if there's a driver bound.
				res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
				           SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
				if (res)
                {
					break;
                }
			}
        }
#ifdef STICK20_DEBUG_ALL
    {
            char text[1000];
        sprintf(text,"HandleName: %s\n", device_interface_detail_data->DevicePath);
        DebugAppendText (text);
    }
#endif
		// Open a handle to the device
		write_handle = open_device(device_interface_detail_data->DevicePath, TRUE);

		// Check validity of write_handle.
		if (write_handle == INVALID_HANDLE_VALUE) {
			// Unable to open the device.
			//register_error(dev, "CreateFile");
			goto cont_close;
		}		


		// Get the Vendor ID and Product ID for this device.
		attrib.Size = sizeof(HIDD_ATTRIBUTES);
		HidD_GetAttributes(write_handle, &attrib);
		//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
#ifdef STICK20_DEBUG
        { // For debugging
            char text[1000];
//            sprintf(text,"Check Product-Vendor: Start VID %04x PID %04x\n",attrib.ProductID, attrib.VendorID);
//            DebugAppendText (text);
            if ((attrib.VendorID == 0x20A0) && (attrib.ProductID == 0x4109) && (attrib.ProductID == product_id))
            {
                sprintf(text,"*** STICK FOUND\n");
                DebugAppendText (text);
            }
        }
#endif


		// Check the VID/PID to see if we should add this
		// device to the enumeration list.
		if ((vendor_id == 0x0 && product_id == 0x0) || 
			(attrib.VendorID == vendor_id && attrib.ProductID == product_id)) {

			#define WSTR_LEN 512
			const char *str;
			struct hid_device_info *tmp;
			PHIDP_PREPARSED_DATA pp_data = NULL;
			HIDP_CAPS caps;
			BOOLEAN res;
			NTSTATUS nt_res;
			wchar_t wstr[WSTR_LEN]; // TODO: Determine Size
			size_t len;

			/* VID/PID match. Create the record. */
			tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;

			// Get the Usage Page and Usage for this device.
			res = HidD_GetPreparsedData(write_handle, &pp_data);
			if (res) {
				nt_res = HidP_GetCaps(pp_data, &caps);
				if (nt_res == HIDP_STATUS_SUCCESS) {
					cur_dev->usage_page = caps.UsagePage;
					cur_dev->usage = caps.Usage;
				}

				HidD_FreePreparsedData(pp_data);
			}
			
			/* Fill out the record */
			cur_dev->next = NULL;
			str = device_interface_detail_data->DevicePath;
			if (str) {
				len = strlen(str);
				cur_dev->path = (char*) calloc(len+1, sizeof(char));
				strncpy(cur_dev->path, str, len+1);
				cur_dev->path[len] = '\0';
			}
			else
				cur_dev->path = NULL;

			/* Serial Number */
			res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->serial_number = _wcsdup(wstr);
			}

			/* Manufacturer String */
			res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->manufacturer_string = _wcsdup(wstr);
			}

			/* Product String */
			res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->product_string = _wcsdup(wstr);
			}

			/* VID/PID */
			cur_dev->vendor_id = attrib.VendorID;
			cur_dev->product_id = attrib.ProductID;

			/* Release Number */
			cur_dev->release_number = attrib.VersionNumber;

			/* Interface Number. It can sometimes be parsed out of the path
			   on Windows if a device has multiple interfaces. See
			   http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
			   search for "Hardware IDs for HID Devices" at MSDN. If it's not
			   in the path, it's set to -1. */
			cur_dev->interface_number = -1;
			if (cur_dev->path) {
				char *interface_component = strstr(cur_dev->path, "&mi_");
				if (interface_component) {
					char *hex_str = interface_component + 4;
					char *endptr = NULL;
					cur_dev->interface_number = strtol(hex_str, &endptr, 16);
					if (endptr == hex_str) {
						/* The parsing failed. Set interface_number to -1. */
						cur_dev->interface_number = -1;
					}
				}
			}
		}

cont_close:
		CloseHandle(write_handle);
cont:
		// We no longer need the detail data. It can be freed
		free(device_interface_detail_data);

		device_index++;

	}

	// Close the device information handle.
	SetupDiDestroyDeviceInfoList(device_info_set);

	return root;

}