2014-07-08 22 views
6

Sto provando a chiamare le funzioni DeviceIO in modo asincrono utilizzando la struttura OVERLAPPED come descritto su MSDN. Sto usando il codice di controllo FSCTL_ENUM_USN_DATA per enumerare il MFT delle unità NTFS ma non riesco a eseguirlo in modo asincrono. L'handle del file viene creato con FILE_FLAG_OVERLAPPED ma non c'è differenza se utilizzo la struttura sovrapposta con FILE_FLAG_OVERLAPPED o no. La funzione non ritorna immediatamente. Sembra essere sincrono in entrambi i casi. L'esempio seguente mostra l'enumerazione delle prime 100.000 voci MFT sull'unità C: \. Dato che non ho familiarità con l'uso di strutture sovrapposte, forse ho fatto qualcosa di sbagliato. La mia domanda: Come posso eseguire DeviceIoControl (hDevice, FSCTL_ENUM_USN_DATA, ...) in modo asincrono? Grazie per l'aiuto.Come chiamare il codice DeviceIOControl in modo asincrono?

#include "stdafx.h" 
#include <Windows.h> 

typedef struct { 
    DWORDLONG nextusn; 
    USN_RECORD FirstUsnRecord; 
    BYTE Buffer[500]; 
}TDeviceIoControlOutputBuffer, *PTDeviceIoControlOutputBuffer; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    MFT_ENUM_DATA lInputMftData; 
    lInputMftData.StartFileReferenceNumber = 0; 
    lInputMftData.MinMajorVersion = 2; 
    lInputMftData.MaxMajorVersion = 3; 
    lInputMftData.LowUsn = 0; 
    lInputMftData.HighUsn = 0; 

    TDeviceIoControlOutputBuffer lOutputMftData; 
    DWORD lOutBytesReturned = 0; 
    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
    OVERLAPPED lOverlapped = { 0 }; 
    lOverlapped.hEvent = hEvent; 
    LPCWSTR path = L"\\\\.\\C:"; 
    HANDLE hDevice = CreateFile(path, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 
    if (hDevice != INVALID_HANDLE_VALUE) { 
     lOutputMftData.nextusn = 0; 
     while (lOutputMftData.nextusn < 100000) { 
      lInputMftData.StartFileReferenceNumber = lOutputMftData.nextusn; 
      BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped); 
     } 
    } 
} 
+0

Se driver non supporta I/O asincrono in generale o per qualche richiesta, gestisce richiesta di I/O sincrono, ignorando il parametro OVERLAPPED. Non so se questo driver supporta questa specifica richiesta in modalità I/O asincrono, però. –

+0

Grazie per la risposta. Secondo Microsoft FSCTL_ENUM_USN_DATA può essere chiamato async: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364563%28v=vs.85%29.aspx – user3816574

+0

Bene, guardando ancora il tuo codice, I non vedi che riempi il membro 'hEvent' della variabile' lOverlapped'. Questa potrebbe essere una buona ragione per eseguire questa richiesta in modo sincrono. –

risposta

0
HEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
OVERLAPPED lOverlapped = { 0 }; 
lOverlapped.hEvent = hEvent; 

... 

BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped); 

// If operation is asynchronous, wait for hEvent here or somewhere else 
+0

Grazie. Ma ancora non funziona. Nessun asincrono. La struttura sovrapposta e l'handle del dispositivo dovrebbero essere corretti: se chiamo ad es. la funzione 'readfile' con la stessa struttura sovrapposta e lo stesso handle di hdevice, ritorna immediatamente con GetalstError() = 997 (ERROR_IO_PENDING: operazione I/O sovrapposta è in corso), che indica che 'readfile' è chiamato in modo asincrono. Ma non funziona per deviceio. – user3816574