下面是源代码:
(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.   

    ULONG USBDriverExecuteIo(HWND hDlg)
    {
        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;
    ······
    }