c++ - DeviceIoControl for SCSI INQUIRY command returns error 50 -
i trying access usb scanner through ioctl commands. on windows 7. did not deal ioctl coding before, first tried following snippet based on find quick search.
#include "stdafx.h" #include <stddef.h> #include <windows.h> #include <ntddscsi.h> #include <usbscan.h> typedef struct { scsi_pass_through spt; byte sense[18]; byte data[36]; } sptsd; lptstr errormessage(dword error) { lptstr errortext = null; formatmessage( format_message_from_system |format_message_allocate_buffer |format_message_ignore_inserts, null, error, makelangid(lang_neutral, sublang_default), (lptstr)&errortext, 0, null); return errortext; } int _tmain(int argc, _tchar* argv[]) { handle h = createfile(l"\\\\.\\usbscan0", generic_read|generic_write, file_share_read|file_share_write, null, open_existing, file_attribute_normal, null); if (invalid_handle_value != h) { sptsd sptsd={0}; sptsd.spt.length = sizeof (sptsd.spt); sptsd.spt.senseinfolength = sizeof(sptsd.sense); sptsd.spt.datatransferlength = sizeof(sptsd.data); sptsd.spt.senseinfooffset = offsetof (sptsd, sense); sptsd.spt.databufferoffset = offsetof (sptsd, data); sptsd.spt.timeoutvalue = 30; sptsd.spt.datain = scsi_ioctl_data_in; sptsd.spt.cdblength = 6; sptsd.spt.cdb[0] = 0x12; // scsi inquiry command sptsd.spt.cdb[1] = 0; sptsd.spt.cdb[2] = 0; sptsd.spt.cdb[3] = 0; sptsd.spt.cdb[4] = sizeof(sptsd.data); sptsd.spt.cdb[5] = 0; dword dwreturnedbytes; bool b; b = deviceiocontrol(h, ioctl_scsi_pass_through, &sptsd, sizeof(sptsd), &sptsd, sizeof(sptsd), &dwreturnedbytes, null); if (b == 0) { lptstr errortext = errormessage(getlasterror()); wprintf(l"deviceiocontrol(ioctl_scsi_pass_through-inquiry) failed error %d : %s\r\n", getlasterror(), errortext); localfree(errortext); } else { wprintf(l"deviceiocontrol(ioctl_scsi_pass_through-inquiry) succeeded\r\n"); (int i=0; i<dwreturnedbytes; i++) { wprintf(l"%02x ", sptsd.data[i]); } wprintf(l"\r\nend of returned data\r\n"); } device_descriptor dd; b = deviceiocontrol(h, ioctl_get_device_descriptor, &dd, sizeof(dd), &dd, sizeof(dd), &dwreturnedbytes, null); if (b == 0) { lptstr errortext = errormessage(getlasterror()); wprintf(l"deviceiocontrol(ioctl_get_device_descriptor) failed error %d : %s\r\n", getlasterror(), errortext); localfree(errortext); } else { wprintf(l"deviceiocontrol(ioctl_get_device_descriptor) succeeded\r\n"); wprintf(l"vendorid = %x, productid = %x, version = %x\r\n", dd.usvendorid, dd.usproductid, dd.usbcddevice); wprintf(l"end of returned data\r\n"); } closehandle(h); } return 0; }
i tried both 32-bit , 64-bit versions of windows 7 result same on both (error 50 : request not supported.). interestingly, second deviceiocontrol call works , returns vid/pid of device, along firmware version.
based on error message, think ioctl not supported. however, looked , found out ioctl code mandatory devices, there must doing wrong. how should code modified inquiry command succeed?
according http://msdn.microsoft.com/en-us/library/ff548569%28v=vs.85%29.aspx, these ioctl codes recognized kernel-mode still image driver usb buses.
- ioctl_cancel_io
- ioctl_get_channel_align_rqst
- ioctl_get_device_descriptor
- ioctl_get_pipe_configuration
- ioctl_get_usb_descriptor
- ioctl_get_version
- ioctl_read_registers
- ioctl_reset_pipe
- ioctl_send_usb_request
- ioctl_set_timeout
- ioctl_wait_on_device_event ioctl_write_registers
my understanding other ioctl code should sent via ioctl_send_usb_request control code. explains why trying send inqury command using above code not work.
edit: matter of using writefile send inquiry command , readfile read response. however, there seems additional issue not understand: device wants byte after 6 bytes of inquiry command send response. otherwise, readfile return single byte (0x3). update reply again if figure out happening here.
Comments
Post a Comment