zoukankan      html  css  js  c++  java
  • .net 深入系统编程(二)

    转载自:http://www.codeproject.com/KB/system/divingsysprog2.aspx

    /Files/kk1230/.net Diving into System Programming/DevInfo.zip

    Introduction

    In Part 1, I have demonstrated how to enumerate device classes. Now let us see how to enumerate devices of the class.

    Device enumeration

    First of all, let us look again at the picture with Device Manager information. It is easy - Device Manager enumerate devices when we expand the tree for device class.

    DevMan2

    The idea of device enumeration is not difficult for understanding:

    • Get class Guid using device class name (SetupDiClassGuidsFromNameA function)
    • Get device info set for device class (SetupDiGetClassDevsA function)
    • Get device info data for every device (SetupDiGetClassDevsA function, second parameters for this function is sequential device index in the device class, so call this function in circle with device index = 0, 1, etc.).
    • Get device name from Registry via SetupDiGetDeviceRegistryPropertyA function.

    Below you see code in C# that will enumerate devices for selected device class for PC.

     

    using System;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace DevInfo
    {
    
        class DeviceInfo
        {
    
            public const int DIGCF_PRESENT    = (0x00000002);
            public const int MAX_DEV_LEN = 1000;
            public const int SPDRP_FRIENDLYNAME = (0x0000000C);  
              // FriendlyName (R/W)
            public const int SPDRP_DEVICEDESC = (0x00000000);    
              // DeviceDesc (R/W)
    
            [StructLayout(LayoutKind.Sequential)]
                public class SP_DEVINFO_DATA
                    {
                     public int cbSize;
                     public Guid  ClassGuid;
                     public int DevInst;    // DEVINST handle
                     public ulong Reserved;
                    };
    
            [DllImport("setupapi.dll")]//
            public static extern Boolean
              SetupDiClassGuidsFromNameA(string ClassN, ref Guid guids, 
                UInt32 ClassNameSize, ref UInt32 ReqSize);
    
            [DllImport("setupapi.dll")]
            public static extern IntPtr                //result HDEVINFO
              SetupDiGetClassDevsA(ref Guid ClassGuid, UInt32 Enumerator,
                IntPtr     hwndParent,  UInt32 Flags);
    
            [DllImport("setupapi.dll")]
            public static extern Boolean
              SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 MemberIndex,
                SP_DEVINFO_DATA     DeviceInfoData);
    
            [DllImport("setupapi.dll")]
            public static extern Boolean
              SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
    
            [DllImport("setupapi.dll")]
            public static extern Boolean
              SetupDiGetDeviceRegistryPropertyA(IntPtr DeviceInfoSet,
              SP_DEVINFO_DATA     DeviceInfoData, UInt32 Property,
              UInt32   PropertyRegDataType, StringBuilder  PropertyBuffer,
              UInt32 PropertyBufferSize, IntPtr RequiredSize);
    
    
    
            public static int EnumerateDevices(UInt32 DeviceIndex, 
                    string ClassName,
                    StringBuilder DeviceName)
            {
             UInt32 RequiredSize = 0;
             Guid guid=Guid.Empty;
             Guid[] guids=new Guid[1];
             IntPtr NewDeviceInfoSet;
             SP_DEVINFO_DATA DeviceInfoData= new SP_DEVINFO_DATA();
    
    
             bool res=SetupDiClassGuidsFromNameA(ClassName,
                        ref guids[0],RequiredSize,
                        ref RequiredSize);
    
             if(RequiredSize==0)
                   {
                    //incorrect class name:
                    DeviceName=new StringBuilder("");
                    return -2;
                   }
    
             if(!res)
              {
               guids=new Guid[RequiredSize];
               res=SetupDiClassGuidsFromNameA(ClassName,ref guids[0],RequiredSize,
                    ref RequiredSize);
    
               if(!res || RequiredSize==0)
                   {
               //incorrect class name:
                    DeviceName=new StringBuilder("");
                    return -2;
                   }
              }
    
             //get device info set for our device class
             NewDeviceInfoSet=SetupDiGetClassDevsA(ref guids[0],0,IntPtr.Zero,
                         DIGCF_PRESENT);
             if( NewDeviceInfoSet.ToInt32() == -1 )
             if(!res)
                   {
              //device information is unavailable:
                    DeviceName=new StringBuilder("");
                    return -3;
                   }
    
                DeviceInfoData.cbSize = 28;
                //is devices exist for class
                DeviceInfoData.DevInst=0;
                DeviceInfoData.ClassGuid=System.Guid.Empty;
                DeviceInfoData.Reserved=0;
    
                res=SetupDiEnumDeviceInfo(NewDeviceInfoSet,
                       DeviceIndex,DeviceInfoData);
                if(!res) {
             //no such device:
                    SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);
                    DeviceName=new StringBuilder("");
                    return -1;
                }
    
    
    
            DeviceName.Capacity=MAX_DEV_LEN;
            if(!SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet,
              DeviceInfoData,
            SPDRP_FRIENDLYNAME,0,DeviceName,MAX_DEV_LEN,IntPtr.Zero) )
            {
             res = SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet,
              DeviceInfoData,SPDRP_DEVICEDESC,0,DeviceName,MAX_DEV_LEN, 
                IntPtr.Zero);
             if(!res){
             //incorrect device name:
                    SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);
                    DeviceName=new StringBuilder("");
                    return -4;
                }
            }
             return 0;
            }
    
            [STAThread]
            static void Main(string[] args)
            {
             StringBuilder devices=new StringBuilder("");
             UInt32 Index=0;
             int result=0;
    
             if(args.Length != 1)
              {
                Console.WriteLine("command line format:");
                Console.WriteLine("DevInfo <CLASSNAME>");
                return;
              }
    
             while(true)
              {
                result=EnumerateDevices(Index, args[0], devices);
                Index++;
                if(result == -2)
                        {
                         Console.WriteLine("Incorrect name of Class = {0}",
                           args[0]);
                         break;
                        }
                if(result == -1)break;
                if(result == 0)Console.WriteLine("Device{0} is {1}", 
                  Index, devices);
            }
    
            }
        }
    }
    

    The command line for this console application - DevInfo classname

    classname - the name of device class. You can use application from previous article to find correct device class name. After running application you can see devices for any device class on your PC.

    Console2

    Summary

    Now we can join code from the first article and this article, add information about devices (for example, resources like IRQs, ports, etc) and put it in the Windows Forms application. But it is a subject for Part 3.

    License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  • 相关阅读:
    hdu:2222:Keywords Search(AC自动机模板题)
    3400: [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队
    bzoj:1026: [SCOI2009]windy数(数位dp)
    poj:1985:Cow Marathon(求树的直径)
    RQNOJ:PID30 / [stupid]愚蠢的矿工☆(树形背包)
    002 Android 系统特有的类介绍及使用
    001 Android TextUtils工具类的使用
    java 常用模块代码
    045 Android Studio 常用应用
    Android Studio 常用技巧
  • 原文地址:https://www.cnblogs.com/kk1230/p/1610760.html
Copyright © 2011-2022 走看看