下面是源代码:
(1)头文件
// USBDriverApp.h
#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <process.h> #include <commctrl.h> #include <tchar.h> #include <setupapi.h> #include <initguid.h> #include <winioctl.h> #include <process.h>
#include <assert.h> #include <dbt.h> #include "resource.h" #include "..\intrface.h"
#define MAX_STRING_LENGTH 500
typedef VOID (*USBDRIVER_IO_CALLBACK)(PVOID Context);
typedef struct _USBDRIVER_LIST_ITEM
{
struct _USBDRIVER_LIST_ITEM* Next;
struct _USBDRIVER_LIST_ITEM* Previous;
OVERLAPPED IoOverlapped;
PCHAR InBuffer;
PCHAR OutBuffer;
ULONG InSize;
ULONG OutSize;
ULONG ReturnLength;
ULONG Error;
USBDRIVER_IO_CALLBACK Callback;
} USBDRIVER_LIST_ITEM, *PUSBDRIVER_LIST_ITEM;
extern HANDLE g_hDevice;
extern USBDRIVER_LIST_ITEM g_IoList;
extern CRITICAL_SECTION g_IoListLock;
ULONG USBDriverExecuteIo(HWND hDlg);
UINT __stdcall USBDriverIoCompletionThread(PVOID Context);
VOID USBDriverOutputText(LPCTSTR Format, ...);
VOID USBDriverOutputBuffer(PVOID Buffer, ULONG Size);
(2)源文件
// USBDriverApp.cpp
#include "USBDriverApp.h"
PTCHAR g_TransferTypeArray[] =
{
_T("ReadFile"),
_T("WriteFile"),
_T("IOCTL_BULK_READ"),
_T("IOCTL_BULK_WRITE"),
_T("")
};
HANDLE g_hDevice = INVALID_HANDLE_VALUE;
HDEVNOTIFY g_hInterfaceNotification = NULL;
USBDRIVER_LIST_ITEM g_IoList;
CRITICAL_SECTION g_IoListLock;
HANDLE g_hIoCompletionThreadTerminationEvent;
HANDLE g_hIoCompletionThread;
// USBDriverOpenDevice
// Opens the nth device found with the given interface class
HANDLE USBDriverOpenDevice(HWND hDlg)
{
HWND hList;
HANDLE hDev;
TCHAR path[MAX_STRING_LENGTH];
DWORD itemIndex;
// Open handle to device
hDev = CreateFile(
path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0
); if (hDev == INVALID_HANDLE_VALUE)
{
USBDriverOutputText(_T("Error: CreateFile failed for device %s (%d)\n"), path, GetLastError());
return INVALID_HANDLE_VALUE;
}
USBDriverOutputText(_T("Opened device %s"), path);
return hDev;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// USBDriverMainDlgProc
// Message loop
LRESULT CALLBACK USBDriverMainDlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
HWND hWnd;
TCHAR str[MAX_STRING_LENGTH];
DWORD itemIndex;
DWORD error = ERROR_SUCCESS;
DWORD ii;
BOOL bInBufferEnable = TRUE;
BOOL bOutBufferEnable = TRUE;
DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
PDEV_BROADCAST_HDR pHdr;
switch (uMsg)
{
case IDC_EXECUTE_BUTTON:
USBDriverExecuteIo(hDlg);
break;
case WM_CLOSE:
if (g_hDevice != INVALID_HANDLE_VALUE)
{
CloseHandle(g_hDevice);
g_hDevice = INVALID_HANDLE_VALUE;
} // Terminate our I/O completion thread
SetEvent(g_hIoCompletionThreadTerminationEvent);
WaitForSingleObject(g_hIoCompletionThread, INFINITE);
UnregisterDeviceNotification(g_hInterfaceNotification);
EndDialog(hDlg, 0);
PostQuitMessage(0);
// Clean up window-specific data objects.
return 0;
// Process other messages.
default:
return 0;
}
return 0;
}
(3)我的问题是:那个回调函数是如何起作用的?
在函数ULONG USBDriverExecuteIo(HWND hDlg)中有这样的代码
if ((!ReadFile(
g_hDevice,
ioItem->OutBuffer,
ioItem->OutSize,
NULL,
&ioItem->IoOverlapped)) &&
(GetLastError() != ERROR_IO_PENDING))
{
error = GetLastError();
USBDriverOutputText(_T("ReadFile failed with error (%d)"), error);
break;
}
ioItem->Callback = USBDriverReadCompleteCallback;
可见上面这句中的USBDriverReadCompleteCallback是一个回调函数,可是异步访问驱动能设置回调函数?这个是什么机制?通常我们异步IO是用WaitForSingleObject来等待IO结束的,倒还没见过有回调方式的吧?
请高手指点!
(1)头文件
// USBDriverApp.h
#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <process.h> #include <commctrl.h> #include <tchar.h> #include <setupapi.h> #include <initguid.h> #include <winioctl.h> #include <process.h>
#include <assert.h> #include <dbt.h> #include "resource.h" #include "..\intrface.h"
#define MAX_STRING_LENGTH 500
typedef VOID (*USBDRIVER_IO_CALLBACK)(PVOID Context);
typedef struct _USBDRIVER_LIST_ITEM
{
struct _USBDRIVER_LIST_ITEM* Next;
struct _USBDRIVER_LIST_ITEM* Previous;
OVERLAPPED IoOverlapped;
PCHAR InBuffer;
PCHAR OutBuffer;
ULONG InSize;
ULONG OutSize;
ULONG ReturnLength;
ULONG Error;
USBDRIVER_IO_CALLBACK Callback;
} USBDRIVER_LIST_ITEM, *PUSBDRIVER_LIST_ITEM;
extern HANDLE g_hDevice;
extern USBDRIVER_LIST_ITEM g_IoList;
extern CRITICAL_SECTION g_IoListLock;
ULONG USBDriverExecuteIo(HWND hDlg);
UINT __stdcall USBDriverIoCompletionThread(PVOID Context);
VOID USBDriverOutputText(LPCTSTR Format, ...);
VOID USBDriverOutputBuffer(PVOID Buffer, ULONG Size);
(2)源文件
// USBDriverApp.cpp
#include "USBDriverApp.h"
PTCHAR g_TransferTypeArray[] =
{
_T("ReadFile"),
_T("WriteFile"),
_T("IOCTL_BULK_READ"),
_T("IOCTL_BULK_WRITE"),
_T("")
};
HANDLE g_hDevice = INVALID_HANDLE_VALUE;
HDEVNOTIFY g_hInterfaceNotification = NULL;
USBDRIVER_LIST_ITEM g_IoList;
CRITICAL_SECTION g_IoListLock;
HANDLE g_hIoCompletionThreadTerminationEvent;
HANDLE g_hIoCompletionThread;
// USBDriverOpenDevice
// Opens the nth device found with the given interface class
HANDLE USBDriverOpenDevice(HWND hDlg)
{
HWND hList;
HANDLE hDev;
TCHAR path[MAX_STRING_LENGTH];
DWORD itemIndex;
// Open handle to device
hDev = CreateFile(
path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0
); if (hDev == INVALID_HANDLE_VALUE)
{
USBDriverOutputText(_T("Error: CreateFile failed for device %s (%d)\n"), path, GetLastError());
return INVALID_HANDLE_VALUE;
}
USBDriverOutputText(_T("Opened device %s"), path);
return hDev;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// USBDriverMainDlgProc
// Message loop
LRESULT CALLBACK USBDriverMainDlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
HWND hWnd;
TCHAR str[MAX_STRING_LENGTH];
DWORD itemIndex;
DWORD error = ERROR_SUCCESS;
DWORD ii;
BOOL bInBufferEnable = TRUE;
BOOL bOutBufferEnable = TRUE;
DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
PDEV_BROADCAST_HDR pHdr;
switch (uMsg)
{
case IDC_EXECUTE_BUTTON:
USBDriverExecuteIo(hDlg);
break;
case WM_CLOSE:
if (g_hDevice != INVALID_HANDLE_VALUE)
{
CloseHandle(g_hDevice);
g_hDevice = INVALID_HANDLE_VALUE;
} // Terminate our I/O completion thread
SetEvent(g_hIoCompletionThreadTerminationEvent);
WaitForSingleObject(g_hIoCompletionThread, INFINITE);
UnregisterDeviceNotification(g_hInterfaceNotification);
EndDialog(hDlg, 0);
PostQuitMessage(0);
// Clean up window-specific data objects.
return 0;
// Process other messages.
default:
return 0;
}
return 0;
}
(3)我的问题是:那个回调函数是如何起作用的?
在函数ULONG USBDriverExecuteIo(HWND hDlg)中有这样的代码
if ((!ReadFile(
g_hDevice,
ioItem->OutBuffer,
ioItem->OutSize,
NULL,
&ioItem->IoOverlapped)) &&
(GetLastError() != ERROR_IO_PENDING))
{
error = GetLastError();
USBDriverOutputText(_T("ReadFile failed with error (%d)"), error);
break;
}
ioItem->Callback = USBDriverReadCompleteCallback;
可见上面这句中的USBDriverReadCompleteCallback是一个回调函数,可是异步访问驱动能设置回调函数?这个是什么机制?通常我们异步IO是用WaitForSingleObject来等待IO结束的,倒还没见过有回调方式的吧?
请高手指点!
{
TCHAR str[MAX_STRING_LENGTH];
HWND hWnd;
ULONG error = ERROR_SUCCESS;
DWORD inPattern;
DWORD outPattern;
DWORD ii;
DWORD itemIndex;
PUSBDRIVER_LIST_ITEM ioItem;
······
if ((!ReadFile(
g_hDevice,
ioItem->OutBuffer,
ioItem->OutSize,
NULL,
&ioItem->IoOverlapped)) &&
(GetLastError() != ERROR_IO_PENDING))
{
error = GetLastError();
USBDriverOutputText(_T("ReadFile failed with error (%d)"), error);
break;
} // Setup the entry
ioItem->Callback = USBDriverReadCompleteCallback;
return error;
······
}