⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testapp.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:

         CloseDeviceHandles(deviceInfo);
         
        //
        // Unlink this deviceInfo from the list and free the memory
        //
         RemoveEntryList(&deviceInfo->ListEntry);
         HeapFree (GetProcessHeap(), 0, deviceInfo);
         
        break;
        
    case DBT_DEVICEREMOVEPENDING:
 
        Display(TEXT("Remove Pending (Handle Notification):%ws"),
                                        deviceInfo->DeviceName);
        //
        // Device is removed so close the handle if it's there
        // and unregister the notification
        //
        if (deviceInfo->hHandleNotification) {
            UnregisterDeviceNotification(deviceInfo->hHandleNotification);
            deviceInfo->hHandleNotification = NULL;
            deviceInfo->hDevice = INVALID_HANDLE_VALUE;
        }
        //
        // Unlink this deviceInfo from the list and free the memory
        //
         RemoveEntryList(&deviceInfo->ListEntry);
         HeapFree (GetProcessHeap(), 0, deviceInfo);

        break;

    case DBT_DEVICEQUERYREMOVEFAILED :
        Display(TEXT("Remove failed (Handle Notification):%ws"),
                                    deviceInfo->DeviceName);
        //
        // Remove failed. So reopen the device and register for
        // notification on the new handle. But first we should unregister
        // the previous notification.
        //
        if (deviceInfo->hHandleNotification) {
            UnregisterDeviceNotification(deviceInfo->hHandleNotification);
            deviceInfo->hHandleNotification = NULL;
         }
        deviceInfo->hDevice = CreateFile(deviceInfo->DevicePath, 
                                GENERIC_READ | GENERIC_WRITE, 
                                0, NULL, OPEN_EXISTING, 0, NULL);
        if(deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
            Display(TEXT("Failed to reopen the device: %ws"), 
                    deviceInfo->DeviceName);
            //
            // Unlink this deviceInfo from the list and free the memory
            //
            RemoveEntryList(&deviceInfo->ListEntry);
            HeapFree (GetProcessHeap(), 0, deviceInfo);
            break;
        }

        //
        // Register handle based notification to receive pnp 
        // device change notification on the handle.
        //
        memset (&filter, 0, sizeof(filter)); //zero the structure
        filter.dbch_size = sizeof(filter);
        filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
        filter.dbch_handle = deviceInfo->hDevice;
 
        deviceInfo->hHandleNotification = 
                            RegisterDeviceNotification(hWnd, &filter, 0);
        Display(TEXT("Reopened device %ws"), deviceInfo->DeviceName);        
        break;
        
    default:
        Display(TEXT("Unknown (Handle Notification)"),
                                    deviceInfo->DeviceName);
        break;
 
    }
    return TRUE;
}


BOOLEAN
EnumExistingDevices(
    HWND   hWnd
)
{
    HDEVINFO                            hardwareDeviceInfo;
    SP_DEVICE_INTERFACE_DATA            deviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA    deviceInterfaceDetailData = NULL;
    ULONG                               predictedLength = 0;
    ULONG                               requiredLength = 0, bytes=0;
    DWORD                               dwRegType, error;
    DEV_BROADCAST_HANDLE                filter;
    PDEVICE_INFO                        deviceInfo =NULL;
    UINT                                i=0;
    HRESULT                             hr;
    
    hardwareDeviceInfo = SetupDiGetClassDevs (
                       (LPGUID)&InterfaceGuid,
                       NULL, // Define no enumerator (global)
                       NULL, // Define no
                       (DIGCF_PRESENT | // Only Devices present
                       DIGCF_DEVICEINTERFACE)); // Function class devices.
    if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
    {
        goto Error;
    }
  
    //
    // Enumerate devices of toaster class
    //
    deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);

    for(i=0; SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
                                 0, // No care about specific PDOs
                                 (LPGUID)&InterfaceGuid,
                                 i, //
                                 &deviceInterfaceData); i++ ) {
                                 
        //
        // Allocate a function class device data structure to 
        // receive the information about this particular device.
        //

        //
        // First find out required length of the buffer
        //
        if(deviceInterfaceDetailData)
                HeapFree (GetProcessHeap(), 0, deviceInterfaceDetailData);
                
        if(!SetupDiGetDeviceInterfaceDetail (
                hardwareDeviceInfo,
                &deviceInterfaceData,
                NULL, // probing so no output buffer yet
                0, // probing so output buffer length of zero
                &requiredLength,
                NULL) && (error = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
        {
            goto Error;
        }
        predictedLength = requiredLength;

        deviceInterfaceDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
                                        predictedLength);
        deviceInterfaceDetailData->cbSize = 
                        sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);


        if (! SetupDiGetDeviceInterfaceDetail (
                   hardwareDeviceInfo,
                   &deviceInterfaceData,
                   deviceInterfaceDetailData,
                   predictedLength,
                   &requiredLength,
                   NULL)) {              
            goto Error;
        }

        deviceInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
                        sizeof(DEVICE_INFO));
        if(!deviceInfo)
            goto Error;
            
        InitializeListHead(&deviceInfo->ListEntry);
        InsertTailList(&ListHead, &deviceInfo->ListEntry);
        
        //
        // Get the device details such as friendly name and SerialNo
        //
        if(!GetDeviceDescription(deviceInterfaceDetailData->DevicePath, 
                                 deviceInfo->DeviceName,
                                 NULL)){
            goto Error;
        }

        Display(TEXT("Found device %ws"), deviceInfo->DeviceName );

        hr = StringCchCopy(deviceInfo->DevicePath, MAX_PATH, deviceInterfaceDetailData->DevicePath);
        if(FAILED(hr)){
            goto Error;
        }
        
        //
        // Open an handle to the device.
        //
        deviceInfo->hDevice = CreateFile ( 
                deviceInterfaceDetailData->DevicePath,
                GENERIC_READ | GENERIC_WRITE,
                0,
                NULL, // no SECURITY_ATTRIBUTES structure
                OPEN_EXISTING, // No special create flags
                0, // No special attributes
                NULL);

        if (INVALID_HANDLE_VALUE == deviceInfo->hDevice) {
            Display(TEXT("Failed to open the device: %ws"), 
                    deviceInfo->DeviceName);            
            continue;
        }
        
        Display(TEXT("Opened handled to the device: %ws"), 
                    deviceInfo->DeviceName);
        //
        // Register handle based notification to receive pnp 
        // device change notification on the handle.
        //

        memset (&filter, 0, sizeof(filter)); //zero the structure
        filter.dbch_size = sizeof(filter);
        filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
        filter.dbch_handle = deviceInfo->hDevice;

        deviceInfo->hHandleNotification = RegisterDeviceNotification(hWnd, &filter, 0);        

    } 

    if(deviceInterfaceDetailData)
        HeapFree (GetProcessHeap(), 0, deviceInterfaceDetailData);

    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
    return 0;

Error:

    error = GetLastError();
    MessageBox(hWnd, TEXT("EnumExisting Devices failed"), TEXT("Error!"), MB_OK);  
    if(deviceInterfaceDetailData)
        HeapFree (GetProcessHeap(), 0, deviceInterfaceDetailData);

    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
    Cleanup(hWnd);
    return 0;
}

BOOLEAN Cleanup(HWND hWnd)
{
    PDEVICE_INFO    deviceInfo =NULL;
    PLIST_ENTRY     thisEntry;

    while (!IsListEmpty(&ListHead)) {
        thisEntry = RemoveHeadList(&ListHead);
        deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
        if (deviceInfo->hHandleNotification) {
            UnregisterDeviceNotification(deviceInfo->hHandleNotification);
            deviceInfo->hHandleNotification = NULL;
        }
        CloseDeviceHandles(deviceInfo);
        HeapFree (GetProcessHeap(), 0, deviceInfo);
    }
    return TRUE;
}

VOID CloseDeviceHandles(
    IN PDEVICE_INFO deviceInfo)
{
    if(!deviceInfo) return;
    
    if (deviceInfo->hDevice != INVALID_HANDLE_VALUE && 
            deviceInfo->hDevice != NULL) {
            
        CloseHandle(deviceInfo->hDevice);
        deviceInfo->hDevice = INVALID_HANDLE_VALUE;
        
        //
        // If there is a valid control device handle, close
        // that also. We aren't going to get any notification
        // on the control-device because it's not known to PNP
        // subsystem.
        //       
        if (deviceInfo->hControlDevice != INVALID_HANDLE_VALUE && 
                        deviceInfo->hControlDevice != NULL) {
            CloseHandle(deviceInfo->hControlDevice);
            deviceInfo->hControlDevice = INVALID_HANDLE_VALUE;                            
        }
        
        Display(TEXT("Closed handle to device %ws"), deviceInfo->DeviceName );
    }
}
BOOL 
GetDeviceDescription(
    LPTSTR DevPath, 
    LPTSTR OutBuffer,
    PULONG Unused
)
{
    HDEVINFO                            hardwareDeviceInfo;
    SP_DEVICE_INTERFACE_DATA            deviceInterfaceData;
    SP_DEVINFO_DATA                     deviceInfoData;
    DWORD                               dwRegType, error;

    hardwareDeviceInfo = SetupDiCreateDeviceInfoList(NULL, NULL);
    if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
    {
        goto Error;
    }
    
    //
    // Enumerate devices of toaster class
    //
    deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);

    SetupDiOpenDeviceInterface (hardwareDeviceInfo, DevPath,
                                 0, //
                                 &deviceInterfaceData);
                                 
    deviceInfoData.cbSize = sizeof(deviceInfoData);
    if(!SetupDiGetDeviceInterfaceDetail (
            hardwareDeviceInfo,
            &deviceInterfaceData,
            NULL, // probing so no output buffer yet
            0, // probing so output buffer length of zero
            NULL,
            &deviceInfoData) && (error = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
    {
        goto Error;
    }
    //
    // Get the friendly name for this instance, if that fails
    // try to get the device description.
    //

    if(!SetupDiGetDeviceRegistryProperty(hardwareDeviceInfo, &deviceInfoData,
                                     SPDRP_FRIENDLYNAME,
                                     &dwRegType,
                                     (BYTE*) OutBuffer,
                                     MAX_PATH,
                                     NULL))
    {
        if(!SetupDiGetDeviceRegistryProperty(hardwareDeviceInfo, &deviceInfoData,
                                     SPDRP_DEVICEDESC,
                                     &dwRegType,
                                     (BYTE*) OutBuffer,
                                     MAX_PATH,
                                     NULL)){
            goto Error;
                                     
        }
        

    }

    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
    return TRUE;

Error:

    error = GetLastError();
    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
    return FALSE;
}

BOOLEAN
SendIoctlToControlDevice(
    IN PDEVICE_INFO deviceInfo)
{
    BOOLEAN result = FALSE;
    UINT bytes;       

    //
    // Open handle to the control device, if it's not already opened. Please
    // note that even a non-admin user can open handle to the device with 
    // FILE_READ_ATTRIBUTES | SYNCHRONIZE DesiredAccess and send IOCTLs if the 
    // IOCTL is defined with FILE_ANY_ACCESS. So for better security avoid 
    // specifying FILE_ANY_ACCESS in your IOCTL defintions. 
    // If you open the device with GENERIC_READ, you can send IOCTL with 
    // FILE_READ_DATA access rights. If you open the device with GENERIC_WRITE, 
    // you can sedn ioctl with FILE_WRITE_DATA access rights.
    // 
    //
    
    if(deviceInfo->hControlDevice != INVALID_HANDLE_VALUE) {
            
        deviceInfo->hControlDevice = CreateFile ( 
            TEXT("\\\\.\\NETVMINI"),
            GENERIC_READ | GENERIC_WRITE,//FILE_READ_ATTRIBUTES | SYNCHRONIZE,
            FILE_SHARE_READ,
            NULL, // no SECURITY_ATTRIBUTES structure
            OPEN_EXISTING, // No special create flags
            FILE_ATTRIBUTE_NORMAL, // No special attributes
            NULL);

        if (INVALID_HANDLE_VALUE == deviceInfo->hControlDevice) {
            Display(TEXT("Failed to open the control device: %ws"), 
                    deviceInfo->DeviceName);
            return result;
        } 
    }        
    
    //
    // send ioclt requests
    //
    if(!DeviceIoControl (deviceInfo->hControlDevice,
          IOCTL_NETVMINI_READ_DATA,
          NULL, 0,
          NULL, 0,
          &bytes, NULL)) {
       Display(TEXT("Read IOCTL to %ws failed"), deviceInfo->DeviceName);                    
    } else {
       Display(TEXT("Read IOCTL to %ws succeeded"), deviceInfo->DeviceName); 
       result = TRUE;
    }
   
    if(!DeviceIoControl (deviceInfo->hControlDevice,
          IOCTL_NETVMINI_WRITE_DATA,
          NULL, 0,
          NULL, 0,
          &bytes, NULL)) {
       Display(TEXT("Write IOCTL to %ws failed"), deviceInfo->DeviceName);                    
    } else {
       Display(TEXT("Write IOCTL to %ws succeeded"), deviceInfo->DeviceName); 
       result = TRUE;
    }
    
    return result;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -