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

📄 testapp.c

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

Copyright (c) Microsoft Corporation.  All rights reserved.

    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
    PURPOSE.

Module Name: testapp.c


Abstract:


Author:

     Eliyas Yakub   Dec 15, 2002

Environment:

    User mode only.

Revision History:

    
--*/

#define UNICODE 1
#define INITGUID

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <setupapi.h>
#include <dbt.h>
#include <winioctl.h>
#include <ntddndis.h> // for IOCTL_NDIS_QUERY_GLOBAL_STATS
#include <ndisguid.h> // for GUID_NDIS_LAN_CLASS
#include <strsafe.h>
#include "testapp.h"
#include "public.h" // for IOCTL_NETVMINI_HELLO
    
//
// Global variables
//
HINSTANCE   hInst;
HWND        hWndList;
TCHAR       szTitle[]=TEXT("NETVMINI's IOCTL Test Application");
LIST_ENTRY  ListHead;
HDEVNOTIFY  hInterfaceNotification;
TCHAR       OutText[500];
UINT        ListBoxIndex = 0;
GUID        InterfaceGuid;// = GUID_NDIS_LAN_CLASS;


_inline VOID Display(PWCHAR Format, PWCHAR Str) 
{
    HRESULT hr;
    
    if(Str) {
        hr = StringCchPrintf(OutText, sizeof(OutText)/sizeof(WCHAR), Format, Str);
    } else {
        hr = StringCchCopy(OutText, sizeof(OutText)/sizeof(WCHAR), Format);
    }
    if(FAILED(hr)){
        return;
    }
    SendMessage(hWndList, LB_INSERTSTRING, ListBoxIndex++, (LPARAM)OutText);
}


int PASCAL WinMain (HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR     lpszCmdParam,
                    int       nCmdShow)
{
    static    TCHAR szAppName[]=TEXT("NETVMINI TESTAPP");
    HWND      hWnd;
    MSG       msg;
    WNDCLASS  wndclass;

    InterfaceGuid = GUID_NDIS_LAN_CLASS;
    hInst=hInstance;

    if (!hPrevInstance)
       {
         wndclass.style        =  CS_HREDRAW | CS_VREDRAW;
         wndclass.lpfnWndProc  =  WndProc;
         wndclass.cbClsExtra   =  0;
         wndclass.cbWndExtra   =  0;
         wndclass.hInstance    =  hInstance;
         wndclass.hIcon        =  LoadIcon (NULL, IDI_APPLICATION);
         wndclass.hCursor      =  LoadCursor(NULL, IDC_ARROW);
         wndclass.hbrBackground=  GetStockObject(WHITE_BRUSH);
         wndclass.lpszMenuName =  TEXT("GenericMenu");
         wndclass.lpszClassName=  szAppName;

         RegisterClass(&wndclass);
       }

    hWnd = CreateWindow (szAppName,
                         szTitle,
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         NULL,
                         NULL,
                         hInstance,
                         NULL);

    ShowWindow (hWnd,nCmdShow);
    UpdateWindow(hWnd);

    while (GetMessage (&msg, NULL, 0,0))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }

    return (0);
}


LRESULT FAR PASCAL 
WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    DWORD nEventType = (DWORD)wParam; 
    PDEV_BROADCAST_HDR p = (PDEV_BROADCAST_HDR) lParam;
    DEV_BROADCAST_DEVICEINTERFACE filter;
    
    switch (message)
    {

        case WM_COMMAND:
            HandleCommands(hWnd, message, wParam, lParam);
            return 0;

        case WM_CREATE:

            hWndList = CreateWindow (TEXT("listbox"),
                         NULL,
                         WS_CHILD|WS_VISIBLE|LBS_NOTIFY |
                         WS_VSCROLL | WS_BORDER,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         hWnd,
                         (HMENU)ID_EDIT,
                         hInst,
                         NULL);
                         
            filter.dbcc_size = sizeof(filter);
            filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
            filter.dbcc_classguid = InterfaceGuid;
            hInterfaceNotification = RegisterDeviceNotification(hWnd, &filter, 0);

            InitializeListHead(&ListHead);
            EnumExistingDevices(hWnd);

            return 0;

      case WM_SIZE:

            MoveWindow(hWndList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            return 0;

      case WM_SETFOCUS:
            SetFocus(hWndList);
            return 0;
            
      case WM_DEVICECHANGE:      

            //
            // All the events we're interested in come with lParam pointing to
            // a structure headed by a DEV_BROADCAST_HDR.  This is denoted by
            // bit 15 of wParam being set, and bit 14 being clear.
            //
            if((wParam & 0xC000) == 0x8000) {
            
                if (!p)
                    return 0;
                                  
                if (p->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {

                    HandleDeviceInterfaceChange(hWnd, nEventType, (PDEV_BROADCAST_DEVICEINTERFACE) p);
                } else if (p->dbch_devicetype == DBT_DEVTYP_HANDLE) {

                    HandleDeviceChange(hWnd, nEventType, (PDEV_BROADCAST_HANDLE) p);
                }
            }
            return 0;

      case WM_CLOSE:
            Cleanup(hWnd);
            UnregisterDeviceNotification(hInterfaceNotification);
            return  DefWindowProc(hWnd,message, wParam, lParam);

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hWnd,message, wParam, lParam);
  }


LRESULT
HandleCommands(
    HWND     hWnd,
    UINT     uMsg,
    WPARAM   wParam,
    LPARAM     lParam
    )

{
    switch (wParam) {

        case IDM_OPEN:
            Cleanup(hWnd); // close all open handles
            EnumExistingDevices(hWnd);
            break;

        case IDM_CLOSE:           
            Cleanup(hWnd);
            break;
            
        case IDM_CTL_IOCTL:   
            {
                PDEVICE_INFO deviceInfo = NULL;
                PLIST_ENTRY thisEntry;
                BOOLEAN    found = FALSE;
                //
                // Find the Virtual miniport driver
                // We need the deviceInfo to get the handle to the device.
                //
                for(thisEntry = ListHead.Flink; thisEntry != &ListHead;
                    thisEntry = thisEntry->Flink)
                {
                    deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
                    if(deviceInfo && 
                        deviceInfo->hDevice != INVALID_HANDLE_VALUE &&
                        wcsstr(deviceInfo->DeviceName, TEXT("Microsoft Virtual Ethernet Adapter"))) {
                            found = TRUE;
                            SendIoctlToControlDevice(deviceInfo);
                    }
                }
                    
                if(!found) {
                    Display(TEXT("Didn't find any NETVMINI device"), NULL);                     
                }
            }                
            break;
                                    
        case IDM_CLEAR:           
            SendMessage(hWndList, LB_RESETCONTENT, 0, 0);
            ListBoxIndex = 0;
            break;
            
        case IDM_EXIT:           
            PostQuitMessage(0);
            break;
            
        default:
            break;
    }

    return TRUE;
}


BOOL 
HandleDeviceInterfaceChange(
    HWND hWnd, 
    DWORD evtype, 
    PDEV_BROADCAST_DEVICEINTERFACE dip
    )
{
    DEV_BROADCAST_HANDLE    filter;
    PDEVICE_INFO            deviceInfo = NULL;
    HRESULT                 hr;
    
    switch (evtype)
    {
        case DBT_DEVICEARRIVAL:
        //
        // New device arrived. Open handle to the device 
        // and register notification of type DBT_DEVTYP_HANDLE
        //

        deviceInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO));
        if(!deviceInfo)
            return FALSE;
            
        InitializeListHead(&deviceInfo->ListEntry);
        InsertTailList(&ListHead, &deviceInfo->ListEntry);
        

        if(!GetDeviceDescription(dip->dbcc_name, deviceInfo->DeviceName,
                                 NULL)) {
            MessageBox(hWnd, TEXT("GetDeviceDescription failed"), TEXT("Error!"), MB_OK);  
        }

        Display(TEXT("New device Arrived (Interface Change Notification): %ws"), 
                    deviceInfo->DeviceName);

        hr = StringCchCopy(deviceInfo->DevicePath, MAX_PATH, dip->dbcc_name);
        if(FAILED(hr)){
            break; // DeviceInfo will be freed later by the cleanup routine.
        }
        
        deviceInfo->hDevice = CreateFile(dip->dbcc_name, 
                                        GENERIC_READ |GENERIC_WRITE, 0, NULL, 
                                        OPEN_EXISTING, 0, NULL);
        if(deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
            Display(TEXT("Failed to open the device: %ws"), 
                    deviceInfo->DeviceName);
            break;
        }
        Display(TEXT("Opened handled to the device: %ws"), 
                    deviceInfo->DeviceName);
        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);
        break;
 
        case DBT_DEVICEREMOVECOMPLETE:
        Display(TEXT("Remove Complete (Interface Change Notification)"), NULL);
        break;    

        //
        // Device Removed.
        // 

        default:
        Display(TEXT("Unknown (Interface Change Notification)"), NULL);
        break;
    }
    return TRUE;
}
 
BOOL 
HandleDeviceChange(
    HWND hWnd, 
    DWORD evtype, 
    PDEV_BROADCAST_HANDLE dhp
    )
{
    UINT i;
    DEV_BROADCAST_HANDLE    filter;
    PDEVICE_INFO            deviceInfo = NULL;
    PLIST_ENTRY             thisEntry;
    HANDLE                  tempHandle;
    
    //
    // Walk the list to get the deviceInfo for this device
    // by matching the handle given in the notification.
    //
    for(thisEntry = ListHead.Flink; thisEntry != &ListHead;
                        thisEntry = thisEntry->Flink)
    {
        deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
        if(dhp->dbch_handle == deviceInfo->hDevice) {
            break;
        }
        deviceInfo = NULL;
    }

    if(!deviceInfo) {
        MessageBox(hWnd, TEXT("Unknown Device"), TEXT("Error"), MB_OK);  
        return FALSE;
    }

    switch (evtype)
    {
    
    case DBT_DEVICEQUERYREMOVE:

        Display(TEXT("Query Remove (Handle Notification)"),
                        deviceInfo->DeviceName);
        //
        // Close the handle so that target device can
        // get removed. Do not unregister the notification
        // at this point, because you want to know whether
        // the device is successfully removed or not.
        //

        tempHandle = deviceInfo->hDevice;
        
        CloseDeviceHandles(deviceInfo);
        //
        // Since we use the handle to locate the deviceinfo, we
        // will reset the handle to the original value and
        // clear it in the the remove_pending message callback.
        // ugly hack..
        //
        deviceInfo->hDevice = tempHandle;            
        break;
        
    case DBT_DEVICEREMOVECOMPLETE:
 
        Display(TEXT("Remove Complete (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;
         }

⌨️ 快捷键说明

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