Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

use createfile to access usb device

2 views
Skip to first unread message

whyitbe

unread,
Apr 12, 2005, 11:19:03 AM4/12/05
to
I installed a driver for a usb device.now i need to access the device
programatically in desktop application.
Somebody told me that createfile may do the work.
But i don't know where to find the file name (the first parameter of
createfile call) for the call.
Sample codes will be great help.

Andrue Cope

unread,
Apr 12, 2005, 12:03:48 PM4/12/05
to
whyitbe wrote:

> Somebody told me that createfile may do the work.

Yes, it will.

> But i don't know where to find the file name (the first parameter of
> createfile call) for the call.

That could be problematic. TBH if it's a device that can appear as a
drive letter I suggest you use that as the path. SDK documentation for
CreateFile() indicates how but as an example for C: drive you would use:

"\\\\.\\C:"

This will only work if the account making the request has Administrator
privileges and not at all IIRC on Win9x.

This path is actually an alias to the device's real path but trust me
that you don't want to get involved with trying to determine the real
path for any device that takes your fancy. I am currently trying to do
this. See the thread titled "Devices and GUIDs". Root message
ID:<#cgtJz4O...@TK2MSFTNGP12.phx.gbl>

Andrue Cope

unread,
Apr 12, 2005, 12:08:55 PM4/12/05
to
Andrue Cope wrote:

> as an example for C: drive you would use:
>
> "\\\\.\\C:"

Important note. This is if you are programming in C or C++ where two
adjacent '\'s indicate a single '\' after compilation. The string is
therefore better expressed as "\\.\C:" - sorry for any confusion.

Peter Wieland [MSFT]

unread,
Apr 12, 2005, 2:43:41 PM4/12/05
to
there are two ways to do this.

if the USB exposes something "standard" like a COM port, or a disk or CD-ROM
drive, you can just use the normal device names (COM1, \\.\d:, etc...)

if the device exposes something custom then you'll first need to be sure the
device driver has registered a "device interface" with PnP. If that's been
done you can locate your device using the SetupDi functions to enumerate all
instances of your device's interface and get the device path to them. Once
you have the path you can pass that to CreateFile.

-p

--
This posting is provided "AS IS" with no warranties, and confers no rights.
"whyitbe" <why...@discussions.microsoft.com> wrote in message
news:034FB189-16B3-4736...@microsoft.com...

Ray Trent

unread,
Apr 12, 2005, 4:04:57 PM4/12/05
to
Or if it's a HID device, you can use DirectX and/or the user-mode HID
support routines.

Peter Wieland [MSFT] wrote:
> there are two ways to do this.
>
> if the USB exposes something "standard" like a COM port, or a disk or CD-ROM
> drive, you can just use the normal device names (COM1, \\.\d:, etc...)
>
> if the device exposes something custom then you'll first need to be sure the
> device driver has registered a "device interface" with PnP. If that's been
> done you can locate your device using the SetupDi functions to enumerate all
> instances of your device's interface and get the device path to them. Once
> you have the path you can pass that to CreateFile.
>
> -p
>

--
../ray\..

whyitbe

unread,
Apr 13, 2005, 2:48:01 AM4/13/05
to
Thanks for your reply,it's helpful.
I followed the 2nd way of your direction.becuase the 1st way is not proper
for my device.

Now,I may enumerate all devices installed on my machine,thus means that the
SetupDiGetClassDevs & SetupDiEnumDeviceInfo calls worked well.
But while i called SetupDiEnumDeviceInterfaces,i got the error of
ERROR_NO_MORE_ITEMS.
The parameters are as below:

BOOLEAN
SetupDiEnumDeviceInterfaces(
IN HDEVINFO DeviceInfoSet,//I used the hdevinfo returned by the
SetupDiGetClassDevs call
IN PSP_DEVINFO_DATA DeviceInfoData, //I used the deviceinfo returned by
the SetupDiEnumDeviceInfo here
IN LPGUID InterfaceClassGuid, // I used DeviceInfoData.ClassGuid here
IN DWORD MemberIndex,// I used ZERO here
OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
);

I enumerated all of the devices on my machine,none device inteeface
returned.I thought that's impossible,so,there must be something wrong in the
above call.
The most confusing part is the InterfaceClassGuid.Is that the Guid of the
device class,or,is there one Guid for each individual device interface?If
so,where to get the Guids of each individual interface?

Andrue Cope

unread,
Apr 13, 2005, 5:13:07 AM4/13/05
to
whyitbe wrote:

> IN PSP_DEVINFO_DATA DeviceInfoData, //I used the deviceinfo
> returned by the SetupDiEnumDeviceInfo here

Try passing NULL here.

> The most confusing part is the InterfaceClassGuid.Is that the Guid of
> the device class,or,is there one Guid for each individual device
> interface?If so,where to get the Guids of each individual interface?

A very good question and one that's probably at the heart of my problem
as well. ISTM that those functions are concerned more with device
management (installation/removal) than with actually providing access
to the devices themselves. The link between the two is provided by
SetupDiEnumDeviceInterfaces() and SetupDiGetDeviceInterfaceDetail(). We
use the following function to obtain a list of class interfaces for a
given GUID then for each member it obtains the CreateFile() compatible
path:

typedef std::vector<AnsiString> TClassDeviceList;

TClassDeviceList
doEnumSpecificClass( GUID ClassGUID,
HDEVINFO DeviceInfoSet )
{
// Added for newsgroup posting
boost::scoped_array<BYTE> wibble2( new BYTE[ 10240 ] );

TClassDeviceList result;

SP_DEVICE_INTERFACE_DATA devIntData;
devIntData.cbSize=sizeof( devIntData );
DWORD member=0;

while( SetupDiEnumDeviceInterfaces( DeviceInfoSet,
NULL,
&ClassGUID,
member,
&devIntData ) )
{
SP_DEVICE_INTERFACE_DETAIL_DATA devIntDetailData;
devIntDetailData.cbSize=sizeof( devIntDetailData );
DWORD reqdevIntDetailDataSize=0;

SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize=sizeof( deviceInfoData );

PSP_DEVICE_INTERFACE_DETAIL_DATA ptr=
reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(
wibble2.get() );

ptr->cbSize=sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );

if( SetupDiGetDeviceInterfaceDetail( DeviceInfoSet,
&devIntData,
ptr,
10240,
&reqdevIntDetailDataSize,
&deviceInfoData ) )
{
result.push_back( ptr->DevicePath ); // <<<< Success!
}

++member;
}

return result;
}

Peter Wieland [MSFT]

unread,
Apr 13, 2005, 1:05:36 PM4/13/05
to
An interface GUID describes what the interface does. There's one for
CD-ROMs, for example, that each CD-ROM device sets up. You can think of
them like COM interface IDs if that helps any.

so if you have 4 of your device in the system, each would report that they
support the GUID_DEVINTERFACE_MYINTERFACE interface.

If memory serves you'd want to do the following:

Call SetupDiGetClassDevs with
GUID_DEVINTERFACE_MYINTERFACE
NULL
???
DIGCF_DEVICEINTERFACE

that gives you a device info set with all devices that support
GUID_DEVINTERFACE_MYINTERFACE.

From there you would call

SetupDiEnumDeviceInterfaces with
devinfoset
NULL
GUID_DEVINTERFACE_MYINTERFACE
index
&deviceInterfaceData

and then for each deviceInterfaceData you get back, call

SetupDiGetDeviceInterfaceDetail
...

This gives you the path to the interface.

-p

--
This posting is provided "AS IS" with no warranties, and confers no rights.
"whyitbe" <why...@discussions.microsoft.com> wrote in message

news:5E42E601-0FFD-4274...@microsoft.com...

whyitbe

unread,
Apr 13, 2005, 9:37:06 PM4/13/05
to
Your sample code is perfect,but it seems not work well for me.The call

SetupDiEnumDeviceInterfaces( DeviceInfoSet,
NULL,
&ClassGUID,
member,
&devIntData ) )
returns false,and the GetLastError() returns ERROR_NO_MORE_ITEMS.
The ClassGUID i used is simply GUID_DEVCLASS_USB.BUt there's no interface
info returned,that drives me crazy.Because I may see my usb device when
calling SetupDiEnumDeviceInfo().
Any further suggestion?

whyitbe

unread,
Apr 13, 2005, 9:44:02 PM4/13/05
to
Thanks for your sample code,but it seems not work for me.
The call SetupDiEnumDeviceInterfaces( DeviceInfoSet,
NULL,
&ClassGUID,
member,
&devIntData )
returns false,and error is ERR_NO_MORE_ITEMS.
The ClassGUID i used is GUID_DEVCLASS_USB.
This drives me crazy,because i may see my usb device when calling
SetupDiEnumDeviceInfo.
Any further suggestion?

Doron Holan [MS]

unread,
Apr 14, 2005, 2:52:13 AM4/14/05
to
GUID_DEVCLAS_USB is a device class. think of a device class a logical
grouping. Not all USB devices have the same interface, even though they are
of the same bus type. If you don't know the device interface GUID for the
device, you need to ask the manufacturer.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.


This posting is provided "AS IS" with no warranties, and confers no rights.


"whyitbe" <why...@discussions.microsoft.com> wrote in message

news:76ABCE1F-2C60-4E07...@microsoft.com...

Andrue Cope

unread,
Apr 14, 2005, 4:37:41 AM4/14/05
to
Doron Holan [MS] wrote:

> GUID_DEVCLAS_USB is a device class. think of a device class a
> logical grouping. Not all USB devices have the same interface, even
> though they are of the same bus type.

Gosh - that's pretty much the way I'd worked it out. Nice to know I was
right.

My current problem is how to enumerate all the devices classes on the
system. At the moment I'm looking at enumerating
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\DeviceClasses\

Perhaps whyitbe could do the same - 'all' he then needs is to issue a
IOCTL_SCSI_GET_INQUIRY_DATA and compare the manufacturer ID. My only
concern is that I /think/ I remember when we were developing our IOCTL
handling class that some non-SCSI devices react badly to
IOCTL_SCSI_GET_INQUIRY_DATA requests.

Doron Holan [MS]

unread,
Apr 14, 2005, 11:18:41 AM4/14/05
to
the CM_* APIs allow you to walk the device tree. for each device in the
tree you can query for the device class. you build up the lists yourself.
walking the registry is a bad idea, the formate can change from OS to OS, SP
to SP. using the APIs guard you from these underlying changes.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"Andrue Cope" <no....@not.a.valid.address> wrote in message
news:uaak50MQ...@TK2MSFTNGP12.phx.gbl...

Andrue Cope

unread,
Apr 14, 2005, 12:29:37 PM4/14/05
to
Doron Holan [MS] wrote:

> the CM_* APIs allow you to walk the device tree. for each device in
> the tree you can query for the device class. you build up the lists
> yourself. walking the registry is a bad idea, the formate can change
> from OS to OS, SP to SP. using the APIs guard you from these
> underlying changes.

Okay, thanks. Well we've got that working this week (I've been doing
other things which is why it's taken a while) and now that Friday is
coming round again I can plan for looking at another solution next week.

As I've said to another respondee:I will concede that we are doing
something odd. Most of this code will be used in-house by data recovery
professionals so I can accept it being OS specific. The only thing I
can't accept is not being able to access a device for a customer just
because it's a bit weird :-/

whyitbe

unread,
Apr 14, 2005, 9:48:02 PM4/14/05
to
Thank Andrue,thank Doron,thank you very much!
Finally i got it worked following your directions.

sukumar

unread,
Jun 4, 2008, 1:58:01 AM6/4/08
to

"whyitbe" wrote:


hi....
i had gone through all these discussion..i need to access the uSB device
data from C++ appication with the help of win32 api's. is it possible? i
didn't findout the api's like SetupDiGetClassDev..are these kernel api's?
can u do some help to access the
USB device data fro our c++ application by using win32 api's....

Maxim S. Shatskih

unread,
Jun 4, 2008, 2:12:28 AM6/4/08
to
> didn't findout the api's like SetupDiGetClassDev..are these kernel api's?

No, SetupDiGetClassDevs is user setupapi.dll.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
ma...@storagecraft.com
http://www.storagecraft.com

sukumar

unread,
Jun 4, 2008, 2:30:00 AM6/4/08
to

"Maxim S. Shatskih" wrote:

> can u tell me how to accee thes api's from visual c++ application

Tim Roberts

unread,
Jun 5, 2008, 2:25:48 AM6/5/08
to
sukumar <suk...@discussions.microsoft.com> wrote:
>
>"Maxim S. Shatskih" wrote:
>
>> > didn't findout the api's like SetupDiGetClassDev..are these kernel api's?
>>
>> No, SetupDiGetClassDevs is user setupapi.dll.
>
> can u tell me how to accee thes api's from visual c++ application

He just did. The SetupDi APIs are in setupapi.h and setupapi.lib. You
will need to read the documentation to figure out how to use them. They
are too complicated to describe in a newsgroup message. There are good
examples in the "devcon" app in the WDK.

As an alternative, you might create your own symbolic link in the
\DosDevices tree. If, for example you create a symbolic link called
L"\\DosDevices\\SukumarDevice", then you can open it with CreateFile using
the file name "\\\\?\\SukumarDevice".
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Maxim S. Shatskih

unread,
Jun 5, 2008, 3:01:08 AM6/5/08
to
> > can u tell me how to accee thes api's from visual c++ application

Add setupapi.lib to your lib list in the IDE's project options.

Then just type SetupDiGetClassDevs in the code, and include setupapi.h to
stdafx.h

As about the coding sample - DEVCON source in the WDK is the proper one, it is
the command-line Device Manager.

Odomae

unread,
Feb 13, 2009, 6:01:03 PM2/13/09
to
I am trying to send some SCSI commands to a USb device. In the process, I
first need to call CreateFile to get the handle.

So todo that, I called SetupDiGetClassDevs(NULL,
"USB", // Define no enumerator
(global)
NULL, // Define no
DIGCF_ALLCLASSES // Only
Devices present
); // Function class devices.

But the call fails.

Does somebody know how I can get past this?

Tim Roberts

unread,
Feb 13, 2009, 11:51:10 PM2/13/09
to
Odomae <Odo...@discussions.microsoft.com> wrote:
>
>I am trying to send some SCSI commands to a USb device. In the process, I
>first need to call CreateFile to get the handle.
>
>So todo that, I called SetupDiGetClassDevs(NULL,
> "USB", // Define no enumerator
>(global)
> NULL, // Define no
> DIGCF_ALLCLASSES // Only
>Devices present
> ); // Function class devices.
>
>But the call fails.

How do you know? When I type in that exact code and run it, I get back a
valid HDEVINFO handle.

By the way, your comments do not match your code. You HAVE defined an
enumerator, and you have NOT set the "only devices present" flag.

Odomae

unread,
Feb 26, 2009, 5:45:02 PM2/26/09
to
Hi!

I managed to get past this problem. I used the SetupDi* functions and I get
the devicename to be something like
\\?\usb#vid_0781&pid_5150#sndk3151051964709804&0.

When I call createFile() with this device name, the device says "opened
successfully".

Now to send SCSI pass through commands, I followed the spti.c code from
winDDK.

status = GetAlignmentMaskForDevice(hOut, &alignmentMask); where hout is the
handle I obtained from CreateFile()

However I am unable to send read/write or inquiry messages using this handle.

Instead, if I use something like "\\\.\E:\ as the device path to
CreateFile() - everything works fine. But I dont want to use the drive letter
since eventually I want to enumerate all USB devices , identify my device
based on VID/PID and send SCSI commands only to that...

Thanks in advance!

odomae

Maxim S. Shatskih

unread,
Feb 28, 2009, 3:38:01 AM2/28/09
to
> However I am unable to send read/write or inquiry messages using this handle.
>
> Instead, if I use something like "\\\.\E:\ as the device path to
> CreateFile() - everything works fine.

Correct, SCSI passthrough to the adapter FDO (like \\.\Scsi0) is no more supported since 2003 or so (at least if the LUN in question is claimed by the class driver, i.e. is a disk or CD or such), you must send them to LUN PDO (\\.\PhysicalDrive%d) instead.

--
Maxim S. Shatskih
Windows DDK MVP
ma...@storagecraft.com
http://www.storagecraft.com

0 new messages