I am trying to use the found-bits project to communicate with my STM32F103 via USB from a Windows application with no success.
The program keeps returning an error code 31 at the WinUsb_ControlTransfer function call.
I made some changes that solved the problem for receiving the data from the default end point but the issue remains when trying to send data to it.
How can I get my windows application to send and receive data from the STM32?
P.S.: I created .inf and .cat files for my device and installed the driver
BOOL SendDatatoDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, BYTE byWinUSBCommControl, BYTE *pbyData = NULL, WORD wNumBytesCount = 0)
{
if (hDeviceHandle==INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bResult = TRUE;
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
//Create the setup packet
SetupPacket.RequestType = (BMREQUEST_HOST_TO_DEVICE << 7)/* | (BMREQUEST_VENDOR << 5) | BMREQUEST_TO_INTERFACE*/;
//SetupPacket.Request = byWinUSBCommControl;
//SetupPacket.Value = 0;
SetupPacket.Index = 0; // specify WinUSBComm interface
//SetupPacket.Length = wNumBytesCount;
SetupPacket.Request = USB_REQUEST_GET_DESCRIPTOR;
SetupPacket.Value = USB_DEVICE_DESCRIPTOR_TYPE << 8;
SetupPacket.Length = sizeof(USB_DEVICE_DESCRIPTOR);
bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, pbyData, wNumBytesCount, &cbSent, 0);
if(!bResult)
{
printf("Error WinUsb_ControlTransfer: %d.\n", GetLastError());
goto done;
}
PTRACE("Data sent: %d \nActual data transferred: %d.\n", wNumBytesCount, cbSent);
done:
return bResult;
}
BOOL GetDataFromDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, BYTE byWinUSBCommControl, BYTE *pbyData, WORD wNumBytesCount)
{
if ( 0 == wNumBytesCount )
{
return TRUE;
}
if ( NULL == pbyData )
{
return FALSE;
}
if (hDeviceHandle==INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bResult = TRUE;
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
//Create the setup packet
SetupPacket.RequestType = (BMREQUEST_DEVICE_TO_HOST << 7)/* | (BMREQUEST_VENDOR << 5) | BMREQUEST_TO_DEVICE*/;
//SetupPacket.Request = byWinUSBCommControl;
//SetupPacket.Value = 0;
SetupPacket.Index = 0; // specify WinUSBComm interface
//SetupPacket.Length = wNumBytesCount;
SetupPacket.Request = USB_REQUEST_GET_DESCRIPTOR;
SetupPacket.Value = USB_DEVICE_DESCRIPTOR_TYPE << 8;
SetupPacket.Length = sizeof(USB_DEVICE_DESCRIPTOR);
bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, pbyData, wNumBytesCount, &cbSent, 0);
if(!bResult)
{
printf("Error WinUsb_ControlTransfer: %d.\n", GetLastError());
goto done;
}
PTRACE("Data get : %d \nActual data transferred: %d.\n", wNumBytesCount, cbSent);
done:
return bResult;
}
Related
I am using M5StickC, trying to use the microphone for sensing noise. I am not familiar with Arduino. I was able to connect the device to wifi. I have been looking at examples and got this :
bool InitI2SMicroPhone()
{
esp_err_t err = ESP_OK;
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM),
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // is fixed at 12bit, stereo, MSB
.channel_format = I2S_CHANNEL_FMT_ALL_RIGHT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 2,
.dma_buf_len = 128,
};
i2s_pin_config_t pin_config;
pin_config.bck_io_num = I2S_PIN_NO_CHANGE;
pin_config.ws_io_num = PIN_CLK;
pin_config.data_out_num = I2S_PIN_NO_CHANGE;
pin_config.data_in_num = PIN_DATA;
err += i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
err += i2s_set_pin(I2S_NUM_0, &pin_config);
err += i2s_set_clk(I2S_NUM_0, 44100, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
//i2s_set_clk(0)
if (err != ESP_OK)
{
return false;
}
else
{
return true;
}
}
However, I am not sure how to get amplitude data. I want to get noise info and send it over wifi. I do not see this function in Loop. How can I extract the needed info in the Loop function?
I am working with nrf52 and I made a custom service for 17 bytes data array and I want to send it but it gives fatal error while in data update (sending) function and resets the program.
Here's my custom service data update function:
uint32_t ble_cus_mydata_update(ble_cus_t * p_cus, uint8_array_t mydata, uint16_t conn_handle)
{
if (p_cus->conn_handle != BLE_CONN_HANDLE_INVALID)
{
ble_gatts_hvx_params_t params;
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_cus->mydata_char_handles.value_handle;
params.p_data = &mydata;
params.p_len = 17;
return sd_ble_gatts_hvx(conn_handle, ¶ms);
}}
and i send data with timeout_handler
static void mydata_timeout_handler(void * p_context)
{
ret_code_t err_code;
UNUSED_PARAMETER(p_context);
bsp_board_led_on(2);
nrf_delay_ms(100);
bsp_board_led_off(2);
uint8_array_t mydata_value [17] = {0x55,0x10,0x01,0x23,0x99,0xFF,0xFF,0xCC,0xBB,0x00,0x00,0x00,0x00,0x00,0x24,0x24,0x20};
err_code = ble_cus_mydata_update(&m_cus, *mydata_value , m_conn_handle);
if ((err_code != NRF_SUCCESS) &&
(err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_BUSY) &&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
)
{
APP_ERROR_HANDLER(err_code);
}
}
And here is my service char add
uint8_array_t mydata_char_init_value [17] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
memset(&add_char_params, 0, sizeof(add_char_params));
add_char_params.uuid = MYDATA_CHAR_UUID;
add_char_params.uuid_type = p_cus->uuid_type;
add_char_params.init_len = 17;
add_char_params.max_len = 17;
add_char_params.p_init_value = mydata_char_init_value;
add_char_params.char_props.read = 1;
add_char_params.char_props.notify = 1;
add_char_params.read_access = SEC_OPEN;
add_char_params.cccd_write_access = SEC_OPEN;
err_code = characteristic_add(p_cus->service_handle,
&add_char_params,
&p_cus->mydata_char_handles);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
I get an error:
nrf error_code= 0x2000310c
There is no info about this error message; it throws this fatal error and goes to nrf_breakpoint_cond after error handler and resets itself.
Please help me; I tried everything I know and I can't move forward. Thanks in advance to whomever tries to help me.
i solved it and wanted to help others who might need it its a little different this code is for sending 4 bytes of data you need to do a little changes for 17 bytes but its not that much the other codes are same you just need to change update function to something like this
uint32_t ble_cus_pres_level_update(ble_cus_t * p_cus, uint32_t presvalue)
{
// NRF_LOG_INFO("In ble_cus_presvalue_update. \r\n");
if (p_cus == NULL)
{
return NRF_ERROR_NULL;
}
uint32_t err_code = NRF_SUCCESS;
ble_gatts_value_t gatts_value;
// Initialize value struct.
memset(&gatts_value, 0, sizeof(gatts_value));
gatts_value.len = sizeof(uint32_t);
gatts_value.offset = 0;
gatts_value.p_value = &presvalue;
// Update database.
err_code = sd_ble_gatts_value_set(p_cus->conn_handle,
p_cus->bme280_presvalue_char_handles.value_handle,
&gatts_value);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Send value if connected and notifying.
if (p_cus->conn_handle != BLE_CONN_HANDLE_INVALID)
{
ble_gatts_hvx_params_t params;
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_cus->bme280_presvalue_char_handles.value_handle;
params.offset = gatts_value.offset;
params.p_data = gatts_value.p_value;
params.p_len = &gatts_value.len;
err_code = sd_ble_gatts_hvx(p_cus->conn_handle, ¶ms);
// NRF_LOG_INFO("sd_ble_gatts_hvx result: %x. \r\n", err_code);
}
else
{
err_code = NRF_ERROR_INVALID_STATE;
// NRF_LOG_INFO("sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE. \r\n");
}
return err_code;
}
Shouldn't err_code = ble_cus_mydata_update(&m_cus, *mydata_value , m_conn_handle); be err_code = ble_cus_mydata_update(&m_cus, mydata_value , m_conn_handle);?
I am working on using SChannel to build a client/server program. One of the things I would like to do is have file sharing. I found some example code of a client program using Schannel to communicate and I am wondering why the max size of a message is 32kb. Here is the example function that does the receiving
int tls_handshake(tls_ctx *c, tls_session *s) {
DWORD flags_in, flags_out;
SecBuffer ib[2], ob[1];
SecBufferDesc in, out;
int len;
// send initial hello
if (!tls_hello(c, s)) {
return 0;
}
flags_in = ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY |
ISC_RET_EXTENDED_ERROR |
ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_MANUAL_CRED_VALIDATION;
c->ss = SEC_I_CONTINUE_NEEDED;
s->buflen = 0;
while (c->ss == SEC_I_CONTINUE_NEEDED ||
c->ss == SEC_E_INCOMPLETE_MESSAGE ||
c->ss == SEC_I_INCOMPLETE_CREDENTIALS)
{
if (c->ss == SEC_E_INCOMPLETE_MESSAGE)
{
// receive data from server
len = recv(s->sck, &s->buf[s->buflen], s->maxlen - s->buflen, 0);
// socket error?
if (len == SOCKET_ERROR) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
// server disconnected?
} else if (len==0) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
}
// increase buffer position
s->buflen += len;
}
// inspect what we've received
//tls_hex_dump(s->buf, s->buflen);
// input data
ib[0].pvBuffer = s->buf;
ib[0].cbBuffer = s->buflen;
ib[0].BufferType = SECBUFFER_TOKEN;
// empty buffer
ib[1].pvBuffer = NULL;
ib[1].cbBuffer = 0;
ib[1].BufferType = SECBUFFER_VERSION;
in.cBuffers = 2;
in.pBuffers = ib;
in.ulVersion = SECBUFFER_VERSION;
// output from schannel
ob[0].pvBuffer = NULL;
ob[0].cbBuffer = 0;
ob[0].BufferType = SECBUFFER_VERSION;
out.cBuffers = 1;
out.pBuffers = ob;
out.ulVersion = SECBUFFER_VERSION;
c->ss = c->sspi->
InitializeSecurityContextA(
&s->cc, &s->ctx, NULL, flags_in, 0,
SECURITY_NATIVE_DREP, &in, 0, NULL,
&out, &flags_out, NULL);
// what have we got so far?
if (c->ss == SEC_E_OK ||
c->ss == SEC_I_CONTINUE_NEEDED ||
(FAILED(c->ss) && (flags_out & ISC_RET_EXTENDED_ERROR)))
{
// response for server?
if (ob[0].cbBuffer != 0 && ob[0].pvBuffer) {
// send response
tls_send(s->sck, ob[0].pvBuffer, ob[0].cbBuffer);
// free response
c->sspi->FreeContextBuffer(ob[0].pvBuffer);
ob[0].pvBuffer = NULL;
}
}
// incomplete message? continue reading
if (c->ss==SEC_E_INCOMPLETE_MESSAGE) continue;
// completed handshake?
if (c->ss==SEC_E_OK) {
s->established = 1;
// If the "extra" buffer contains data, this is encrypted application
// protocol layer stuff and needs to be saved. The application layer
// will decrypt it later with DecryptMessage.
if (ib[1].BufferType == SECBUFFER_EXTRA) {
DEBUG_PRINT(" [ we have extra data after handshake.\n");
memmove(s->pExtra.pvBuffer,
&s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->pExtra.cbBuffer = ib[1].cbBuffer;
s->pExtra.BufferType = SECBUFFER_TOKEN;
} else {
// no extra data encountered
s->pExtra.pvBuffer = NULL;
s->pExtra.cbBuffer = 0;
s->pExtra.BufferType = SECBUFFER_EMPTY;
}
break;
}
// some other error
if(FAILED(c->ss)) break;
// Copy any leftover data from the "extra" buffer, and go around again.
if(ib[1].BufferType == SECBUFFER_EXTRA) {
memmove(s->buf, &s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->buflen = ib[1].cbBuffer;
DEBUG_PRINT(" [ we have %i bytes of extra data.\n", s->buflen);
tls_hex_dump(s->buf, s->buflen);
} else {
s->buflen = 0;
}
}
return c->ss==SEC_E_OK ? 1 : 0;
}
The code comes from a Github I found here: https://github.com/odzhan/shells/blob/master/s6/tls.c
Inside one of his header files he defines
#define TLS_MAX_BUFSIZ 32768
I have also read in other places that this is a limit with TLS. Is it possible to increase that limit? What happens if I need to receive more then that? Like a large file?
I am using a generic write and read operations using the serial communication with R-232 connector to an external device.
For specific write operations, the readFile returns the data.
But for one command, it returns 0 bytes and GetLastError() returns 0.
I am using the application on a windows PDA.
Below is the code used:
long port = jport;
long baudrate = jbaudrate;
int cmd_length = env->GetStringLength(jcmd);
const jchar* cmd = env->GetStringChars(jcmd, 0);
zCommand = new char[cmd_length+1];
for (int j=0;j<cmd_length;j++)
zCommand[j] = (char)cmd[j];
zCommand[cmd_length]='\r';
env->ReleaseStringChars(jcmd,cmd);
WCHAR comPort[6];
wsprintf(comPort, L"COM%d:", port);
LPCTSTR pcCommPort = LPCTSTR( comPort );
hCom = CreateFile( pcCommPort,
GENERIC_READ | GENERIC_WRITE,
0, // exclusive-access
NULL, // default security attributes
OPEN_EXISTING,
0, // not overlapped I/O
NULL
);
if (hCom == INVALID_HANDLE_VALUE)
{
throw_executeCommand(env,"java/lang/Exception","INVALID_HANDLE_VALUE");
return env->NewStringUTF("");
}
//Clear all input output buffer
PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR);
//Configure DCB
DCB PortDCB;
// Initialize the DCBlength member.
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState (hCom, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = baudrate; // Zera specified baud
PortDCB.ByteSize = 8;
PortDCB.StopBits = TWOSTOPBITS;
PortDCB.Parity = PARITY_NONE;
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
PortDCB.fRtsControl = RTS_CONTROL_ENABLE | (RTS_CONTROL_TOGGLE ^ RTS_CONTROL_HANDSHAKE );
PortDCB.fAbortOnError = FALSE;
//Set Com Timeouts
COMMTIMEOUTS commTimeouts;
if(!GetCommTimeouts(hCom, &commTimeouts))
{
throw_executeCommand(env,"java/lang/Exception","Exception GetCommTimeouts");
return env->NewStringUTF("");
}
commTimeouts.ReadIntervalTimeout = 50;
commTimeouts.ReadTotalTimeoutMultiplier = 10;
commTimeouts.ReadTotalTimeoutConstant = 50;
commTimeouts.WriteTotalTimeoutConstant = 50;
commTimeouts.WriteTotalTimeoutMultiplier = 10;
if(!SetCommTimeouts(hCom, &commTimeouts))
{
throw_executeCommand(env,"java/lang/Exception","Exception SetCommTimeouts");
return env->NewStringUTF("");
}
if (!SetCommState (hCom, &PortDCB))
{
throw_executeCommand(env,"java/lang/Exception","Exception SetCommState");
return env->NewStringUTF("");
}
unsigned long numBytesWritten;
unsigned long numBytesRead;
BOOL bWriteResult;
bWriteResult = WriteFile(hCom,zCommand, sizeof (zCommand),&numBytesWritten,NULL);
if (!bWriteResult)
{
throw_executeCommand(env,"java/lang/Exception","Exception WriteFile");
return env->NewStringUTF("");
}
//Time to read
string result="";
BOOL bReadResult; //AAV,ARC,AGR1
char sBuffer[128];
BOOL datafound;
numBytesRead = 0;
while(true)
{
bReadResult = ReadFile(hCom, &sBuffer, 128, &numBytesRead, NULL);
if (numBytesRead > 0)
{
for (int i=0;i<(int)numBytesRead;i++)
{
datafound = TRUE;
if (sBuffer[i]=='\r')
{
result += '\n';
}else
{
result += sBuffer[i];
}
}
}
else
{
break;
}
}
if (datafound)
{
if (hCom != INVALID_HANDLE_VALUE)
{
cleanup_executeCommand();
return env->NewStringUTF(result.c_str());
}
}
cleanup_executeCommand();
throw_executeCommand(env,"java/lang/Exception","err");
return env->NewStringUTF("");
I'm working on creating a virtual HID device in Windows 10. To prepare myself for writing the drivers, I've been analyzing the sample provided here: https://github.com/Microsoft/Windows-driver-samples/tree/master/hid/vhidmini2.
In the file app/testvhid.c, HidD_GetAttributes is used to retrieve the attributes of the HID device. It appears that the attributes are initialized in driver/vhidmini.c (hidAttributes in the EvtDeviceAdd function). However, hidAttributes is stored inside of a DEVICE_CONTEXT structure, which (from my understanding) is defined by the driver.
If hidAttributes is a user defined attribute, then how does HidD_GetAttributes know to retrieve it from the device?
I've tried to replicate this for myself by creating a KMDF driver which is based mostly on the sample given. The relevant driver code is as follows (The majority of this was taken from the sample, with the exception of the call to WdfDeviceCreateDeviceInterface):
NTSTATUS
kmdfTest2CreateDevice(
_Inout_ PWDFDEVICE_INIT DeviceInit
)
{
WDF_OBJECT_ATTRIBUTES deviceAttributes;
PDEVICE_CONTEXT deviceContext;
WDFDEVICE device;
NTSTATUS status;
PHID_DEVICE_ATTRIBUTES hidAttributes;
WdfFdoInitSetFilter(DeviceInit);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
if (NT_SUCCESS(status)) {
deviceContext = DeviceGetContext(device);
deviceContext->Device = device;
deviceContext->DeviceData = 0;
hidAttributes = &deviceContext->HidDeviceAttributes;
RtlZeroMemory(hidAttributes, sizeof(HID_DEVICE_ATTRIBUTES));
hidAttributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);
hidAttributes->VendorID = HIDMINI_VID;
hidAttributes->ProductID = HIDMINI_PID;
hidAttributes->VersionNumber = HIDMINI_VERSION;
if (NT_SUCCESS(status)) {
status = kmdfTest2QueueInitialize(device);
}
deviceContext->HidDescriptor = G_DefaultHidDescriptor;
deviceContext->ReportDescriptor = G_DefaultReportDescriptor;
status = WdfDeviceCreateDeviceInterface(
device,
&GUID_DEVINTERFACE_HID,
NULL // ReferenceString
);
}
return status;
}
The relevant section of code in the user mode test application is as follows (this code is virtually entirely from the given sample):
BOOLEAN
CheckIfOurDevice(
HANDLE file)
{
PHIDP_PREPARSED_DATA Ppd; // The opaque parser info describing this device
HIDP_CAPS Caps; // The Capabilities of this hid device.
HIDD_ATTRIBUTES attr; // Device attributes
if (!HidD_GetAttributes(file, &attr))
{
printf("Error: HidD_GetAttributes failed \n");
return FALSE;
}
printf("Device Attributes - PID: 0x%x, VID: 0x%x \n", attr.ProductID, attr.VendorID);
if ((attr.VendorID != HIDMINI_VID) || (attr.ProductID != HIDMINI_PID))
{
printf("Device attributes doesn't match the sample \n");
return FALSE;
}
if (!HidD_GetPreparsedData(file, &Ppd))
{
printf("Error: HidD_GetPreparsedData failed \n");
return FALSE;
}
if (!HidP_GetCaps(Ppd, &Caps))
{
printf("Error: HidP_GetCaps failed \n");
HidD_FreePreparsedData(Ppd);
return FALSE;
}
if ((Caps.UsagePage == g_MyUsagePage) && (Caps.Usage == g_MyUsage)) {
printf("Success: Found my device.. \n");
return TRUE;
}
else {
printf("failed: UsagePage: %d, Usage: %d \n", Caps.UsagePage, Caps.Usage);
}
return FALSE;
}
BOOLEAN
GetHidInterface(_Out_ HANDLE* Handle) {
CONFIGRET cr = CR_SUCCESS;
*Handle = INVALID_HANDLE_VALUE;
ULONG deviceInterfaceListLength = 0;
GUID InterfaceGuid;
PSTR deviceInterfaceList = NULL;
HANDLE devHandle = INVALID_HANDLE_VALUE;
if (NULL == Handle) {
printf("Error: Invalid device handle parameter\n");
return FALSE;
}
HidD_GetHidGuid(&InterfaceGuid);
cr = CM_Get_Device_Interface_List_Size(
&deviceInterfaceListLength,
&InterfaceGuid,
NULL,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr != CR_SUCCESS) {
printf("Error 0x%x retrieving device interface list size.\n", cr);
return FALSE;
}
if (deviceInterfaceListLength <= 1) {
printf("Error: No active device interfaces found.\n"
" Is the sample driver loaded?");
return FALSE;
}
deviceInterfaceList = (PSTR)malloc(deviceInterfaceListLength * sizeof(WCHAR));
if (deviceInterfaceList == NULL) {
printf("Error allocating memory for device interface list.\n");
return FALSE;
}
ZeroMemory(deviceInterfaceList, deviceInterfaceListLength * sizeof(WCHAR));
cr = CM_Get_Device_Interface_List(
&InterfaceGuid,
NULL,
deviceInterfaceList,
deviceInterfaceListLength,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr != CR_SUCCESS) {
printf("Error 0x%x retrieving device interface list.\n", cr);
return FALSE;
}
printf("\n....looking for our HID device (with UP=0x%04X "
"and Usage=0x%02X)\n", g_MyUsagePage, g_MyUsage);
PSTR currentInterface;
for (currentInterface = deviceInterfaceList;
*currentInterface;
currentInterface += strlen(currentInterface) + 1) {
devHandle = CreateFile(currentInterface,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, // no SECURITY_ATTRIBUTES structure
OPEN_EXISTING, // No special create flags
0, // No special attributes
NULL); // No template file
if (INVALID_HANDLE_VALUE == devHandle) {
printf("Warning: CreateFile failed: %d\n", GetLastError());
continue;
}
if (CheckIfOurDevice(devHandle)) {
*Handle = devHandle;
return TRUE;
}
else {
CloseHandle(devHandle);
}
}
return FALSE;
}
The HidD_GetAttributes function passes, but the CheckIfOurDevice function fails when checking the device attributes ("Device attributes doesn't match the sample"). I've checked some of the attribute values that are being set by HidD_GetAttributes, but they don't match up with the ones set by the driver. Is the sample making some other call that I'm missing?