NullReferenceException при запросе резервирования dhcp через API управления сервером Microsoft dhcp

Я хочу перечислить все записи резервирования dhcp нашего dhcp-сервера Microsoft с API-интерфейсом управления dhcp-сервером Microsoft в C#.

Это мой код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Windows.Forms;
using System.Collections;

namespace Sequence
{
    [StructLayout(LayoutKind.Sequential)]
    public struct DHCP_CLIENT_INFO_ARRAY
    {
        public uint NumElements;
        public IntPtr Clients;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DHCP_CLIENT_UID
    {
        public uint DataLength;
        public IntPtr Data;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct DHCP_CLIENT_INFO
    {
        public uint ip;
        public uint subnet;
        public DHCP_CLIENT_UID mac;

        [MarshalAs(UnmanagedType.LPWStr)]
        public string ClientName;

        [MarshalAs(UnmanagedType.LPWStr)]
        public string ClientComment;
    }

    class CDHCP
    {
        public static ArrayList findDhcpClients(string server, string subnet)
        {
            ArrayList foundClients = new ArrayList();

            uint parsedMask = StringIPAddressToUInt32(subnet);
            uint resumeHandle = 0;
            uint numClientsRead = 0;
            uint totalClients = 0;

            IntPtr info_array_ptr;

            uint response = DhcpEnumSubnetClients(
                server,
                parsedMask,
                ref resumeHandle,
                65536,
                out info_array_ptr,
                ref numClientsRead,
                ref totalClients
                );

            DHCP_CLIENT_INFO_ARRAY rawClients = (DHCP_CLIENT_INFO_ARRAY)Marshal.PtrToStructure(info_array_ptr, typeof(DHCP_CLIENT_INFO_ARRAY));

            IntPtr current = rawClients.Clients;

            for (int i = 0; i < (int)rawClients.NumElements; i++)
            {
                DHCP_CLIENT_INFO rawMachine = (DHCP_CLIENT_INFO)Marshal.PtrToStructure(Marshal.ReadIntPtr(current), typeof(DHCP_CLIENT_INFO));

                CDHCPCLIENT thisClient = new CDHCPCLIENT();
                thisClient.ip = UInt32IPAddressToString(rawMachine.ip);
                thisClient.hostname = rawMachine.ClientName;
                thisClient.mac = string.Format("{0:x2}-{1:x2}-{2:x2}-{3:x2}-{4:x2}-{5:x2}",
                        Marshal.ReadByte(rawMachine.mac.Data, 0),
                        Marshal.ReadByte(rawMachine.mac.Data, 1),
                        Marshal.ReadByte(rawMachine.mac.Data, 2),
                        Marshal.ReadByte(rawMachine.mac.Data, 3),
                        Marshal.ReadByte(rawMachine.mac.Data, 4),
                        Marshal.ReadByte(rawMachine.mac.Data, 5));

                foundClients.Add(thisClient);

                current = (IntPtr)((int)current + (int)Marshal.SizeOf(typeof(IntPtr)));
            }

            return foundClients;
        }

        public static uint StringIPAddressToUInt32(string ip)
        {
            IPAddress i = IPAddress.Parse(ip);
            byte[] ipByteArray = i.GetAddressBytes();

            uint ipUint = (uint)ipByteArray[0] << 24;
            ipUint += (uint)ipByteArray[1] << 16;
            ipUint += (uint)ipByteArray[2] << 8;
            ipUint += (uint)ipByteArray[3];

            return ipUint;
        }

        public static string UInt32IPAddressToString(uint ip)
        {
            IPAddress i = new IPAddress(ip);
            string[] ipArray = i.ToString().Split('.');

            return ipArray[3] + "." + ipArray[2] + "." + ipArray[1] + "." + ipArray[0];
        }

        [DllImport("C:\\Windows\\System32\\dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern uint DhcpEnumSubnetClients(
            string ServerIpAddress,
            uint SubnetAddress,
            ref uint ResumeHanle,
            uint PreferredMaximum,
            out IntPtr ClientInfo,
            ref uint ElementsRead,
            ref uint ElementsTotal);
    }
}

К сожалению, я получаю исключение NullReferenceException в этой строке:

DHCP_CLIENT_INFO_ARRAY rawClients = (DHCP_CLIENT_INFO_ARRAY)Marshal.PtrToStructure(info_array_ptr, typeof(DHCP_CLIENT_INFO_ARRAY));

Я вызываю функцию следующим образом:

public void GetDHCPReservation()
    {
        ArrayList clients = CDHCP.findDhcpClients("192.168.1.3", "192.168.1.5");

        foreach (CDHCPCLIENT c in clients)
        {
            MessageBox.Show(string.Format("(0,-35}{1,-15}{2,-15}", c.hostname, c.ip, c.mac));
        }
    }

Кто-нибудь может мне помочь? Заранее спасибо.

1 ответ

Решение

Я думаю, что я только что решил свою проблему.

Причина, по которой я получал исключение NullReferenceException, заключалась в том, что IntPtr info_array_ptr всегда указывал на 0 (ноль). Это было из-за нехватки прав пользователя на сервере DHCP. После того, как я добавил пользователя, с которым я запускаю свое приложение, к администраторам домена, все работало хорошо.

Другие вопросы по тегам