none
How to obtain data from WDM(WMI) by C application RRS feed

  • Question

  • I'm practicing WMI and want to get a variable by C programming

    I find an useful sample code from this website:

    https://stackoverflow.com/questions/1431103/how-to-obtain-data-from-wmi-using-a-c-application

    but I don't know how to modify the const variable "resource", "query" and second parameter in Get()

    Here is my .mof:

    [WMI, Dynamic, Provider("WMIProv"),
     Description("IOCTL information"),
     guid("{097ee7c3-4482-49f6-8709-a1f21ab1e622}"),
     locale("MS\\0x409")]

    class IOCTL_Information
    {
    [key, read]
    string InstanceName;
    [read]
    boolean Active;
    [WmiDataId(1),
    read,
    Description("wcl Data")
    ]
    boolean wcl_variable;
    };

    ////////////////////////////////////////////////////////////

    my QueryWmiDataBlock routine, I wand to get boolean value "1"

           

    NTSTATUS 
    QueryWmiDataBlock(
    IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
    IN ULONG GuidIndex, 
    IN ULONG InstanceIndex,
    IN ULONG InstanceCount,
    IN OUT PULONG InstanceLengthArray,
    IN ULONG OutBufferSize,
    OUT PUCHAR PBuffer)
    {
    PLOCAL_DEVICE_EXTENSION dx;
    NTSTATUS status;
    ULONG size = 0;
    ULONG SymLinkNameLen;
    ULONG FirstWord = 0;

    dx = (PLOCAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    switch(GuidIndex)
    {
    case wcl_WMI_GUID_INDEX:
    {
            size = sizeof(BOOLEAN);

            if (OutBufferSize < size) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

    *(PBOOLEAN) PBuffer = 1;
            *InstanceLengthArray = size;
            status = STATUS_SUCCESS;

    break;
    }

    default:
    DebugPrint(("QueryWmiDataBlock: Bad GUID index"));
    status = STATUS_WMI_GUID_NOT_FOUND;
    break;
    }

    return WmiCompleteRequest( DeviceObject, Irp, status, size, IO_NO_INCREMENT);
    }




    • Edited by _Wayne56 Thursday, July 12, 2018 7:38 AM
    Thursday, July 12, 2018 7:32 AM

Answers

  • While this can be done in C it is painful to use it versus something like C#.   Unless you have a large block of code that needs to directly access WMI you should look at C#.   If it is the case it is your driver and your user code, you can also look at using an IOCTL to gather the data, and not WMI.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    • Marked as answer by _Wayne56 Friday, July 13, 2018 6:44 AM
    Thursday, July 12, 2018 10:32 AM

All replies

  • While this can be done in C it is painful to use it versus something like C#.   Unless you have a large block of code that needs to directly access WMI you should look at C#.   If it is the case it is your driver and your user code, you can also look at using an IOCTL to gather the data, and not WMI.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    • Marked as answer by _Wayne56 Friday, July 13, 2018 6:44 AM
    Thursday, July 12, 2018 10:32 AM
  • While this can be done in C it is painful to use it versus something like C#.   Unless you have a large block of code that needs to directly access WMI you should look at C#.   If it is the case it is your driver and your user code, you can also look at using an IOCTL to gather the data, and not WMI.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    thanks for your suggestion.

    I try to use C#, and find a sample from here

            private void button1_Click(object sender, EventArgs e)
            {
                var dskQuery = new SelectQuery("Win32_LogicalDisk", "DriveType=3");
                var mgmtScope = new ManagementScope("\\\\****\\root\\cimv2");
                mgmtScope.Connect();
                var mgmtSrchr = new ManagementObjectSearcher(mgmtScope, dskQuery);
                foreach (var disk in mgmtSrchr.Get())
                {
                    var devId = disk.GetPropertyValue("DeviceID").ToString();
                    if (!string.IsNullOrEmpty(devId) && devId == "C:")
                    {
                        var freeWmi = disk.GetPropertyValue("FreeSpace").ToString();
                        var freeInt = 0;
                        if (!string.IsNullOrEmpty(freeWmi) && int.TryParse(freeWmi, out freeInt))
                        {
                            // Console.WriteLine("Free Space on " + devId + " Drive: " + freeInt.ToString());
                            MessageBox.Show("Free Space on " + devId + " Drive: " + freeInt.ToString());
                        }
                    }
                }
            }

    but I still don't know how to modify the code to obtain data from my WMI provider...

    Could anyone give me some advice or sample?

    Friday, July 13, 2018 3:34 AM
  • solved

    private void WMI(object sender, EventArgs e)
            {
                try
                {
                    ManagementScope scope = new ManagementScope("root\\wmi");
                    scope.Connect();
                    ManagementClass mc = new ManagementClass(@"IOCTL_Information");
                    mc.Scope = scope;
                    ManagementObjectCollection moc = mc.GetInstances();
                    if (moc.Count == 0)
                    {
                        Console.Write("Object Count:{0}", moc.Count);
                    }
                    foreach (ManagementObject mo in moc)
                    {
                        Console.WriteLine(mo["wcl_variable"]);
                    }
                }
                catch (Exception err)
                {
                    Console.WriteLine("IOCTL_Information:{0}", err.Message.ToString());
                }
            }

    Friday, July 13, 2018 6:44 AM
  • solved

    private void WMI(object sender, EventArgs e)
            {
                try
                {
                    ManagementScope scope = new ManagementScope("root\\wmi");
                    scope.Connect();
                    ManagementClass mc = new ManagementClass(@"IOCTL_Information");
                    mc.Scope = scope;
                    ManagementObjectCollection moc = mc.GetInstances();
                    if (moc.Count == 0)
                    {
                        Console.Write("Object Count:{0}", moc.Count);
                    }
                    foreach (ManagementObject mo in moc)
                    {
                        Console.WriteLine(mo["wcl_variable"]);
                    }
                }
                catch (Exception err)
                {
                    Console.WriteLine("IOCTL_Information:{0}", err.Message.ToString());
                }
            }

    P.S. The program needs UAC
    • Edited by _Wayne56 Friday, July 13, 2018 6:46 AM
    Friday, July 13, 2018 6:45 AM
  • While this can be done in C it is painful to use it versus something like C#.   Unless you have a large block of code that needs to directly access WMI you should look at C#.   If it is the case it is your driver and your user code, you can also look at using an IOCTL to gather the data, and not WMI.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    I can read data from my WMI Provider

    Do you know how to write data to my driver by C#?

    Friday, July 13, 2018 9:19 AM