DhcpEnumFilterV4 (P/Invoke) 总是报告ERROR_NO_MORE_ITEMS
本文关键字:ERROR 报告 NO ITEMS MORE Invoke DhcpEnumFilterV4 | 更新日期: 2023-09-27 18:32:16
我尝试以编程方式枚举Windows 2012 R2 DHCP服务器上的DHCP过滤器。使用 P/Invoke,代码如下所示:
public const uint ERROR_SUCCESS = 0;
public const uint ERROR_MORE_DATA = 234;
public const uint ERROR_NO_MORE_ITEMS = 259;
public const int MAX_PATTERN_LENGTH = 255;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DHCP_ADDR_PATTERN {
public bool MatchHWType;
public byte HWType;
public bool IsWildCard;
public byte Length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_PATTERN_LENGTH)]
public byte[] Pattern;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DHCP_FILTER_ENUM_INFO {
public uint NumElements;
public IntPtr pEnumRecords;
}
public enum DHCP_FILTER_LIST_TYPE : uint {
Deny = 0x1,
Allow = 0x2
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DHCP_FILTER_RECORD {
public DHCP_ADDR_PATTERN AddrPatt;
public string Comment;
}
[DllImport("dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint DhcpEnumFilterV4(string ServerIpAddress,
ref DHCP_ADDR_PATTERN ResumeHandle, uint PreferredMaximum,
DHCP_FILTER_LIST_TYPE ListType, out IntPtr EnumFilterInfo,
out uint ElementsRead, out uint ElementsTotal);
public static IEnumerable<DHCP_FILTER_RECORD> DhcpEnumFilterV4(
string serverIpAddress, DHCP_FILTER_LIST_TYPE listType,
uint preferredMaximum = 1024) {
uint cntRead = 0;
uint cntTotal = 0;
uint error = ERROR_SUCCESS;
var hResume = new DHCP_ADDR_PATTERN();
var data = IntPtr.Zero;
var size = Marshal.SizeOf(typeof(DHCP_FILTER_RECORD));
do {
error = DhcpEnumFilterV4(serverIpAddress, ref hResume,
preferredMaximum, listType, out data, out cntRead,
out cntTotal);
//
// PROBLEM OCCURS HERE: 'error' is always 259
//
if ((error == ERROR_SUCCESS) || (error == ERROR_MORE_DATA)) {
var array = data.ToStructure<DHCP_FILTER_ENUM_INFO>();
for (uint i = 0; i < array.NumElements; ++i) {
var ptr = new IntPtr((long) array.pEnumRecords + i * size);
var obj = (DHCP_FILTER_RECORD) Marshal.PtrToStructure(ptr, typeof(DHCP_FILTER_RECORD));
yield return obj;
}
DhcpRpcFreeMemory(array.pEnumRecords);
DhcpRpcFreeMemory(data);
data = IntPtr.Zero;
} else if (error != ERROR_NO_MORE_ITEMS) {
Debug.Assert(data == IntPtr.Zero);
throw new Win32Exception((int) error);
}
} while (error == ERROR_MORE_DATA);
}
[DllImport("dhcpsapi.dll", SetLastError = true)]
public static extern void DhcpRpcFreeMemory(IntPtr BufferPointer);
恕我直言,整个DHCP API的文档(http://msdn.microsoft.com/en-us/library/windows/desktop/dd897526(v=vs.85).aspx)有点粗略,所以我不完全确定我是否在做正确的事情。
问题是:我从来没有得到任何结果,DhcpEnumFilterV4
总是返回ERROR_NO_MORE_ITEMS
。有什么建议吗?
我偶然发现了一个关于MSDN中DHCP_FILTER_LIST_TYPE
的重要用户评论(http://msdn.microsoft.com/en-us/library/windows/desktop/dd897586(v=vs.85).aspx)。MSDN 中枚举的定义似乎是错误的。以下
typedef enum {
Deny = 0x1, // This is wrong!
Allow = 0x2 // This is wrong!
} DHCP_FILTER_LIST_TYPE;
应该是
typedef enum {
Deny = 0x0, // This is correct!
Allow = 0x1 // This is correct!
} DHCP_FILTER_LIST_TYPE;
使用更新的常量,我的代码可以工作。