1. Trang chủ
  2. » Công Nghệ Thông Tin

USB Complete fourth- P29 doc

10 151 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 205,53 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

8$ Definitions Public Structure SP_DEVICE_INTERFACE_DATA Dim cbSize As Int32 Dim InterfaceClassGuid As Guid Dim Flags As Int32 Dim Reserved As IntPtr End Structure _ Shared Function Set

Trang 1

In some cases, such as when looking for a HID-class device with a specific Ven-dor ID and Product ID, the application may need to request more information before deciding whether a retrieved device interface is the desired one

8$ Definitions

Public Structure SP_DEVICE_INTERFACE_DATA

Dim cbSize As Int32

Dim InterfaceClassGuid As Guid

Dim Flags As Int32

Dim Reserved As IntPtr

End Structure

<DllImport("setupapi.dll", SetLastError:=True)> _

Shared Function SetupDiEnumDeviceInterfaces _

(ByVal DeviceInfoSet As IntPtr, _

ByVal DeviceInfoData As IntPtr, _

ByRef InterfaceClassGuid As System.Guid, _

ByVal MemberIndex As Int32, _

ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA) _

As Boolean

End Function

Use

Dim memberIndex As Int32 = 0

Dim MyDeviceInterfaceData As SP_DEVICE_INTERFACE_DATA

Dim success As Boolean

MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData)

success = SetupDiEnumDeviceInterfaces _

(deviceInfoSet, _

IntPtr.Zero, _

myGuid, _

memberIndex, _

MyDeviceInterfaceData)

Trang 2

8% Definitions

internal struct SP_DEVICE_INTERFACE_DATA

{

internal Int32 cbSize;

internal Guid InterfaceClassGuid;

internal Int32 Flags;

internal IntPtr Reserved;

}

[DllImport("setupapi.dll", SetLastError = true)]

internal static extern Boolean SetupDiEnumDeviceInterfaces

(IntPtr DeviceInfoSet,

IntPtr DeviceInfoData,

ref System.Guid InterfaceClassGuid,

Int32 MemberIndex,

ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);

Use

Int32 memberIndex = 0;

MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();

Boolean success = false;

MyDeviceInterfaceData.cbSize = = Marshal.SizeOf( MyDeviceInterfaceData );

success = SetupDiEnumDeviceInterfaces

(deviceInfoSet,

IntPtr.Zero,

ref myGuid,

memberIndex,

ref MyDeviceInterfaceData);

&GVCKNU

In the SP_DEVICE_INTERFACE_DATA structure, the cbSize parameter is the size of the structure in bytes The Marshal.SizeOf method returns the struc-ture’s size

The myGuid and deviceInfoSet parameters are values retrieved previously The DeviceInfoData parameter can be a pointer to an SP_DEVINFO_DATA struc-ture that limits the search to a particular device instance or a null pointer The memberIndex parameter is an index to a structure in the deviceInfoSet array

T h e My D e v i c e I n t e r f a c e D a t a p a r a m e t e r i s a p o i n t e r t o t h e

Trang 3

structure identifies a device interface of the requested type The function returns true on success

4GSWGUVKPIC5VTWEVWTGYKVJVJG&GXKEG2CVJ0COG

The SetupDiGetDeviceInterfaceDetail function returns a structure that

con-t a i n s a d e v i c e p a con-t h n a m e f o r a d e v i c e i n con-t e r f a c e i d e n con-t i f i e d i n a n SP_DEVICE_INTERFACE_DATA structure

When calling this function for the first time, you don’t know the size in bytes of the DeviceInterfaceDetailData structure to pass in the DeviceInterfaceDetail-DataSize parameter Yet the function won’t return the structure unless the func-tion call passes the correct size The solufunc-tion is to call the funcfunc-tion twice The

first time, GetLastError returns the error The data area passed to a system call is

too small, but the RequiredSize parameter contains the correct value for

Device-InterfaceDetailDataSize The second call passes the returned size value, and the function returns the structure

The code below doesn’t pass a structure for the DeviceInterfaceDetailData parameter Instead, the code reserves a generic buffer, passes a pointer to the buffer, and extracts the device path name directly from the buffer The code thus doesn’t require a structure declaration, but I’ve included one to show the contents of the returned buffer

8$ Definitions

Public Structure SP_DEVICE_INTERFACE_DETAIL_DATA

Dim cbSize As Int32

Dim DevicePath As String

End Structure

<DllImport("setupapi.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _

Shared Function SetupDiGetDeviceInterfaceDetail _

(ByVal DeviceInfoSet As IntPtr, _

ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, _

ByVal DeviceInterfaceDetailData As IntPtr, _

ByVal DeviceInterfaceDetailDataSize As Int32, _

ByRef RequiredSize As Int32, _

ByVal DeviceInfoData As IntPtr) _

As Boolean

End Function

Trang 4

Dim bufferSize As Int32

Dim detailDataBuffer As IntPtr

Dim success As Boolean

success = SetupDiGetDeviceInterfaceDetail _

(deviceInfoSet, _

MyDeviceInterfaceData, _

IntPtr.Zero, _

0, _

bufferSize, _

IntPtr.Zero)

detailDataBuffer = Marshal.AllocHGlobal(bufferSize)

Marshal.WriteInt32 _

(detailDataBuffer,

ConvertToInt32(IIf((IntPtr.Size = 4), 4 + Marshal.SystemDefaultCharSize, 8))) success = SetupDiGetDeviceInterfaceDetail _

(deviceInfoSet, _

MyDeviceInterfaceData, _

detailDataBuffer, _

bufferSize, _

bufferSize, _

IntPtr.Zero)

8% Definitions

internal struct SP_DEVICE_INTERFACE_DETAIL_DATA

{

internal Int32 cbSize;

internal String DevicePath;

}

[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]

internal static extern Boolean SetupDiGetDeviceInterfaceDetail

(IntPtr DeviceInfoSet,

ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,

IntPtr DeviceInterfaceDetailData,

Int32 DeviceInterfaceDetailDataSize,

ref Int32 RequiredSize,

Trang 5

Int32 bufferSize = 0;

IntPtr detailDataBuffer;

Boolean success = false;

success = SetupDiGetDeviceInterfaceDetail

(deviceInfoSet,

ref MyDeviceInterfaceData,

IntPtr.Zero,

0,

ref bufferSize,

IntPtr.Zero);

detailDataBuffer = Marshal.AllocHGlobal( bufferSize );

Marshal.WriteInt32

(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); success = SetupDiGetDeviceInterfaceDetail

(deviceInfoSet,

ref MyDeviceInterfaceData,

detailDataBuffer,

bufferSize,

ref bufferSize,

IntPtr.Zero);

&GVCKNU

After calling SetupDiGetDeviceInterfaceDetail, bufferSize contains the value to pass in the DeviceInterfaceDetailDataSize parameter in the next call But before calling the function again, the code needs to take care of a few things

The second function call returns a pointer (detailDataBuffer) to an SP_DEVICE_INTERFACE_DETAIL_DATA structure in unmanaged mem-ory The Marshal.AllocGlobal method uses the returned bufferSize value to allocate memory for the structure

The cbSize member of the structure passed in detailDataBuffer equals four bytes for cbSize plus the width of one character for the device path name (which is empty when passed to the function) The Marshal.WriteInt32 method copies the cbSize value into the first member of detailDataBuffer The IIf function (Visual Basic) or “?” conditional operator (Visual C#) selects the correct value for 32- and 64-bit systems

Trang 6

The second call to SetupDiGetDeviceInterfaceDetail passes the pointer to detailDataBuffer and sets the deviceInterfaceDetailDataSize parameter equal to the bufferSize value returned previously in RequiredSize

When the function returns after the second call, detailDataBuffer points to a structure containing a device path name

'ZVTCEVKPIVJG&GXKEG2CVJ0COG

In detailDataBuffer, the first four bytes are the cbSize member The string con-taining the device path name begins at the fifth byte

8$ Dim devicePathName As String = ""

Dim pDevicePathName As IntPtr = New IntPtr(detailDataBuffer.ToInt32 + 4)

devicePathName = Marshal.PtrToStringAuto(pDevicePathName)

Marshal.FreeHGlobal(detailDataBuffer)

8% String devicePathName = "";

IntPtr pDevicePathName = new IntPtr( detailDataBuffer.ToInt32() + 4 );

devicePathName = Marshal.PtrToStringAuto(pDevicePathName);

Marshal.FreeHGlobal(detailDataBuffer);

&GVCKNU

The pDevicePathName variable points to the string in the buffer The Mar-shal.PtrToString method retrieves the string from the buffer When finished with the buffer, Marshal.FreeHGlobal frees the memory previously allocated for the buffer

%NQUKPI%QOOWPKECVKQPU

When finished using the DeviceInfoSet returned by SetupDiGetClassDevs, the application should call SetupDiDestroyDeviceInfoList to free resources

8$ Definitions

<DllImport("setupapi.dll", SetLastError:=True)> _

Shared Function SetupDiDestroyDeviceInfoList _

(ByVal DeviceInfoSet As IntPtr) _

Trang 7

SetupDiDestroyDeviceInfoList (deviceInfoSet)

8% Definitions

[DllImport("setupapi.dll", SetLastError = true)]

internal static extern Int32 SetupDiDestroyDeviceInfoList

(IntPtr DeviceInfoSet);

Use

SetupDiDestroyDeviceInfoList( deviceInfoSet );

1DVCKPKPIC*CPFNG

An application can use a retrieved device path name to obtain a handle that enables communicating with the device Table 10-2 shows API functions related to requesting a handle

4GSWGUVKPIC%QOOWPKECVKQPU*CPFNG

After retrieving a device path name, an application is ready to open communi-cations with the device The CreateFile function requests a handle to an object, which can be a file or another resource managed by a driver that supports han-dle-based operations For example, applications can request a handle to use in exchanging reports with HID-class devices For devices that use the WinUSB driver, CreateFile obtains a handle the application uses to obtain a WinUSB device handle for accessing a device

The call to CreateFile can pass a SECURITY_ATTRIBUTES structure that can limit access to the handle or IntPtr.Zero if the function doesn’t need to limit access

Table 10-2: Applications can use CreateFile to request a handle to a device and CloseHandle to free the resources used by a handle.

#2+(WPEVKQP & 2WTRQUG

CloseHandle kernel32 Free resources reserved by CreateFile To close handles

for the SafeHandle and derived classes, use the Close method, which calls CloseHandle internally.

CreateFile kernel32 Retrieve a handle for communicating with a device.

Trang 8

8$ Definitions

Friend Const FILE_ATTRIBUTE_NORMAL As Int32 = &H80

Friend Const FILE_FLAG_OVERLAPPED As Int32 = &H40000000

Friend Const FILE_SHARE_READ As Int32 = 1

Friend Const FILE_SHARE_WRITE As Int32 = 2

Friend Const GENERIC_READ As UInt32 = &H80000000UL

Friend Const GENERIC_WRITE As UInt32 = &H40000000

Friend Const OPEN_EXISTING As Int32 = 3

<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _

Shared Function CreateFile _

(ByVal lpFileName As String, _

ByVal dwDesiredAccess As UInt32, _

ByVal dwShareMode As Int32, _

ByVal lpSecurityAttributes As IntPtr, _

ByVal dwCreationDisposition As Int32, _

ByVal dwFlagsAndAttributes As Int32, _

ByVal hTemplateFile As Int32) _

As SafeFileHandle

End Function

Use

Dim deviceHandle As SafeFileHandle

deviceHandle = CreateFile _

(devicePathName, _

GENERIC_WRITE Or GENERIC_READ, _

FILE_SHARE_READ Or FILE_SHARE_WRITE, _

IntPtr.Zero, _

OPEN_EXISTING, _

FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_OVERLAPPED, _

0)

8% Definitions

internal const Int32 FILE_ATTRIBUTE_NORMAL = 0X80;

internal const Int32 FILE_FLAG_OVERLAPPED = 0X40000000;

internal const Int32 FILE_SHARE_READ = 1;

internal const Int32 FILE_SHARE_WRITE = 2;

internal const UInt32 GENERIC_READ = 0X80000000;

internal const UInt32 GENERIC_WRITE = 0X40000000;

internal const Int32 OPEN_EXISTING = 3;

Trang 9

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

internal static extern SafeFileHandle CreateFile

(String lpFileName,

UInt32 dwDesiredAccess,

Int32 dwShareMode,

IntPtr lpSecurityAttributes,

Int32 dwCreationDisposition,

Int32 dwFlagsAndAttributes,

Int32 hTemplateFile);

Use

internal SafeFileHandle deviceHandle;

deviceHandle = CreateFile

(devicePathName,

(GENERIC_WRITE | GENERIC_READ),

FILE_SHARE_READ | FILE_SHARE_WRITE,

IntPtr.Zero,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,

0);

&GVCKNU

The function passes a pointer to the devicePathName string returned by Setup-DiGetDeviceInterfaceDetail The dwDesiredAccess parameter requests read/write access to the device The dwShareMode parameter allows other pro-cesses to access the device while the handle is open The lpSecurityAttributes parameter is a null pointer (or a pointer to a SECURITY_ATTRIBUTES structure) The dwCreationDisposition parameter must be OPEN_EXISTING for devices For use with the WinUSB driver, the dwFlagsAndAttributes

param-e t param-e r m u s t u s param-e F I L E _ F L A G _ O V E R L A P P E D T h param-e FILE_ATTRIBUTE_NORMAL attribute indicates that no other attributes such as hidden, read-only, or encrypted are set The example passes zero for the unused hTemplate parameter The function returns a SafeFileHandle object

%NQUKPIVJG*CPFNG

When finished communicating with a device, the application should free the resources reserved by CreateFile

8$ deviceHandle.Close()

Trang 10

8% deviceHandle.Close();

&GVCKNU

SafeFileHandle objects support the Close method, which marks the handle for releasing and freeing resources The method calls the CloseHandle API func-tion internally

&GVGEVKPI#VVCEJOGPVCPF4GOQXCN

Many applications find it useful to know when a device has been attached or removed On detecting when a device is attached, the application can begin communicating with the device On detecting when a device has been removed, the application can stop attempting to communicate until detecting reattach-ment Windows provides device-notification functions for this purpose

#DQWV&GXKEG0QVKHKECVKQPU

To request to be informed when a device is attached or removed, an applica-tion’s form can register to receive notification messages for devices in a device interface class The operating system passes WM_DEVICECHANGE mes-sages to the form’s WndProc method (called WindowProc in C) An application can override WndProc in a form’s base class with a method that processes the messages and then passes them to the base class’s WndProc method (The code below shows how to do this.) Each notification contains a device path name that the application can use to identify the device that the notification applies

to Table 10-3 lists the API functions used in registering for device notifications The example that follows shows how to use the functions

4GIKUVGTKPIHQT&GXKEG0QVKHKECVKQPU

Applications use the RegisterDeviceNotification function to request to receive notification messages The function requires a handle for the window or service

t h a t w i l l r e c e i v e t h e n o t i f i c a t i o n s , a p o i n t e r t o a DEV_BROADCAST_DEVICEINTERFACE structure that holds information about the request, and flags to indicate whether the handle is for a window or service

In the DEV_BROADCAST_DEVICEINTERFACE structure passed to

Regis-t e r D e v i c e No Regis-t i f i c a Regis-t i o n , Regis-t h e d b c c _ d e v i c e Regis-t y p e m e m b e r i s s e Regis-t Regis-t o

Ngày đăng: 04/07/2014, 07:20

w