从 C# 调用 AuditQuerySystemPolicy() (advapi32.dll) 返回“参数不正确”
顺序如下:
- 使用
LsaOpenPolicy()
(未显示) - 调用
LsaQueryInformationPolicy()
获取类别数量; - 对于每个类别:
- 调用
AuditLookupCategoryGuidFromCategoryId()
将枚举值转换为 GUID;
- 调用
AuditEnumerateSubCategories()
获取所有子类别的 GUID 列表;
- 调用
AuditQuerySystemPolicy()
获取子类别的审核策略。
- 调用
除了最后一个之外,所有这些都起作用并返回预期的合理值。调用 AuditQuerySystemPolicy()
会出现“参数不正确”错误。我想一定存在一些微妙的解组问题。我可能误解了 AuditEnumerateSubCategories()
返回的内容,但我被难住了。
您会看到(已注释)我尝试将 AuditEnumerateSubCategories()
的返回指针取消引用为指针。这样做或不这样做都会产生相同的结果。
代码:
#region LSA types
public enum POLICY_INFORMATION_CLASS
{
PolicyAuditLogInformation = 1,
PolicyAuditEventsInformation,
PolicyPrimaryDomainInformation,
PolicyPdAccountInformation,
PolicyAccountDomainInformation,
PolicyLsaServerRoleInformation,
PolicyReplicaSourceInformation,
PolicyDefaultQuotaInformation,
PolicyModificationInformation,
PolicyAuditFullSetInformation,
PolicyAuditFullQueryInformation,
PolicyDnsDomainInformation
}
public enum POLICY_AUDIT_EVENT_TYPE
{
AuditCategorySystem,
AuditCategoryLogon,
AuditCategoryObjectAccess,
AuditCategoryPrivilegeUse,
AuditCategoryDetailedTracking,
AuditCategoryPolicyChange,
AuditCategoryAccountManagement,
AuditCategoryDirectoryServiceAccess,
AuditCategoryAccountLogon
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct POLICY_AUDIT_EVENTS_INFO
{
public bool AuditingMode;
public IntPtr EventAuditingOptions;
public UInt32 MaximumAuditEventCount;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct GUID
{
public UInt32 Data1;
public UInt16 Data2;
public UInt16 Data3;
public Byte Data4a;
public Byte Data4b;
public Byte Data4c;
public Byte Data4d;
public Byte Data4e;
public Byte Data4f;
public Byte Data4g;
public Byte Data4h;
public override string ToString()
{
return Data1.ToString("x8") + "-" + Data2.ToString("x4") + "-" + Data3.ToString("x4") + "-"
+ Data4a.ToString("x2") + Data4b.ToString("x2") + "-"
+ Data4c.ToString("x2") + Data4d.ToString("x2") + Data4e.ToString("x2") + Data4f.ToString("x2") + Data4g.ToString("x2") + Data4h.ToString("x2");
}
}
#endregion
#region LSA Imports
[DllImport("kernel32.dll")]
extern static int GetLastError();
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern UInt32 LsaNtStatusToWinError(
long Status);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern long LsaOpenPolicy(
ref LSA_UNICODE_STRING SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
Int32 DesiredAccess,
out IntPtr PolicyHandle );
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern long LsaClose(IntPtr PolicyHandle);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern long LsaFreeMemory(IntPtr Buffer);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern void AuditFree(IntPtr Buffer);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern long LsaQueryInformationPolicy(
IntPtr PolicyHandle, POLICY_INFORMATION_CLASS InformationClass,
out IntPtr Buffer);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern bool AuditLookupCategoryGuidFromCategoryId(
POLICY_AUDIT_EVENT_TYPE AuditCategoryId,
IntPtr pAuditCategoryGuid);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern bool AuditEnumerateSubCategories(
IntPtr pAuditCategoryGuid,
bool bRetrieveAllSubCategories,
out IntPtr ppAuditSubCategoriesArray,
out ulong pCountReturned);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern bool AuditQuerySystemPolicy(
IntPtr pSubCategoryGuids,
ulong PolicyCount,
out IntPtr ppAuditPolicy);
#endregion
Dictionary<string, UInt32> retList = new Dictionary<string, UInt32>();
long lretVal;
uint retVal;
IntPtr pAuditEventsInfo;
lretVal = LsaQueryInformationPolicy(policyHandle, POLICY_INFORMATION_CLASS.PolicyAuditEventsInformation, out pAuditEventsInfo);
retVal = LsaNtStatusToWinError(lretVal);
if (retVal != 0)
{
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception((int)retVal);
}
POLICY_AUDIT_EVENTS_INFO myAuditEventsInfo = new POLICY_AUDIT_EVENTS_INFO();
myAuditEventsInfo = (POLICY_AUDIT_EVENTS_INFO)Marshal.PtrToStructure(pAuditEventsInfo, myAuditEventsInfo.GetType());
IntPtr subCats = IntPtr.Zero;
ulong nSubCats = 0;
for (int audCat = 0; audCat < myAuditEventsInfo.MaximumAuditEventCount; audCat++)
{
GUID audCatGuid = new GUID();
if (!AuditLookupCategoryGuidFromCategoryId((POLICY_AUDIT_EVENT_TYPE)audCat, new IntPtr(&audCatGuid)))
{
int causingError = GetLastError();
LsaFreeMemory(pAuditEventsInfo);
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception(causingError);
}
if (!AuditEnumerateSubCategories(new IntPtr(&audCatGuid), true, out subCats, out nSubCats))
{
int causingError = GetLastError();
LsaFreeMemory(pAuditEventsInfo);
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception(causingError);
}
// Dereference the first pointer-to-pointer to point to the first subcategory
// subCats = (IntPtr)Marshal.PtrToStructure(subCats, subCats.GetType());
if (nSubCats > 0)
{
IntPtr audPolicies = IntPtr.Zero;
if (!AuditQuerySystemPolicy(subCats, nSubCats, out audPolicies))
{
int causingError = GetLastError();
if (subCats != IntPtr.Zero)
AuditFree(subCats);
LsaFreeMemory(pAuditEventsInfo);
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception(causingError);
}
AUDIT_POLICY_INFORMATION myAudPol = new AUDIT_POLICY_INFORMATION();
for (ulong audSubCat = 0; audSubCat < nSubCats; audSubCat++)
{
// Process audPolicies[audSubCat], turn GUIDs into names, fill retList.
// http://msdn.microsoft.com/en-us/library/aa373931%28VS.85%29.aspx
// http://msdn.microsoft.com/en-us/library/bb648638%28VS.85%29.aspx
IntPtr itemAddr = IntPtr.Zero;
IntPtr itemAddrAddr = new IntPtr(audPolicies.ToInt64() + (long)(audSubCat * (ulong)Marshal.SizeOf(itemAddr)));
itemAddr = (IntPtr)Marshal.PtrToStructure(itemAddrAddr, itemAddr.GetType());
myAudPol = (AUDIT_POLICY_INFORMATION)Marshal.PtrToStructure(itemAddr, myAudPol.GetType());
retList[myAudPol.AuditSubCategoryGuid.ToString()] = myAudPol.AuditingInformation;
}
if (audPolicies != IntPtr.Zero)
AuditFree(audPolicies);
}
if (subCats != IntPtr.Zero)
AuditFree(subCats);
subCats = IntPtr.Zero;
nSubCats = 0;
}
lretVal = LsaFreeMemory(pAuditEventsInfo);
retVal = LsaNtStatusToWinError(lretVal);
if (retVal != 0)
throw new System.ComponentModel.Win32Exception((int)retVal);
lretVal = LsaClose(policyHandle);
retVal = LsaNtStatusToWinError(lretVal);
if (retVal != 0)
throw new System.ComponentModel.Win32Exception((int)retVal);
The sequence is like follows:
- Open a policy handle with
LsaOpenPolicy()
(not shown) - Call
LsaQueryInformationPolicy()
to get the number of categories; - For each category:
- Call
AuditLookupCategoryGuidFromCategoryId()
to turn the enum value into a GUID; - Call
AuditEnumerateSubCategories()
to get a list of the GUIDs of all subcategories; - Call
AuditQuerySystemPolicy()
to get the audit policies for the subcategories.
- Call
All of these work and return expected, sensible values except the last. Calling AuditQuerySystemPolicy()
gets me a "The parameter is incorrect" error. I'm thinking there must be some subtle unmarshaling problem. I'm probably misinterpreting what exactly AuditEnumerateSubCategories()
returns, but I'm stumped.
You'll see (commented) I tried to dereference the return pointer from AuditEnumerateSubCategories()
as a pointer. Doing or not doing that gives the same result.
Code:
#region LSA types
public enum POLICY_INFORMATION_CLASS
{
PolicyAuditLogInformation = 1,
PolicyAuditEventsInformation,
PolicyPrimaryDomainInformation,
PolicyPdAccountInformation,
PolicyAccountDomainInformation,
PolicyLsaServerRoleInformation,
PolicyReplicaSourceInformation,
PolicyDefaultQuotaInformation,
PolicyModificationInformation,
PolicyAuditFullSetInformation,
PolicyAuditFullQueryInformation,
PolicyDnsDomainInformation
}
public enum POLICY_AUDIT_EVENT_TYPE
{
AuditCategorySystem,
AuditCategoryLogon,
AuditCategoryObjectAccess,
AuditCategoryPrivilegeUse,
AuditCategoryDetailedTracking,
AuditCategoryPolicyChange,
AuditCategoryAccountManagement,
AuditCategoryDirectoryServiceAccess,
AuditCategoryAccountLogon
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct POLICY_AUDIT_EVENTS_INFO
{
public bool AuditingMode;
public IntPtr EventAuditingOptions;
public UInt32 MaximumAuditEventCount;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct GUID
{
public UInt32 Data1;
public UInt16 Data2;
public UInt16 Data3;
public Byte Data4a;
public Byte Data4b;
public Byte Data4c;
public Byte Data4d;
public Byte Data4e;
public Byte Data4f;
public Byte Data4g;
public Byte Data4h;
public override string ToString()
{
return Data1.ToString("x8") + "-" + Data2.ToString("x4") + "-" + Data3.ToString("x4") + "-"
+ Data4a.ToString("x2") + Data4b.ToString("x2") + "-"
+ Data4c.ToString("x2") + Data4d.ToString("x2") + Data4e.ToString("x2") + Data4f.ToString("x2") + Data4g.ToString("x2") + Data4h.ToString("x2");
}
}
#endregion
#region LSA Imports
[DllImport("kernel32.dll")]
extern static int GetLastError();
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern UInt32 LsaNtStatusToWinError(
long Status);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern long LsaOpenPolicy(
ref LSA_UNICODE_STRING SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
Int32 DesiredAccess,
out IntPtr PolicyHandle );
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern long LsaClose(IntPtr PolicyHandle);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern long LsaFreeMemory(IntPtr Buffer);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
public static extern void AuditFree(IntPtr Buffer);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern long LsaQueryInformationPolicy(
IntPtr PolicyHandle, POLICY_INFORMATION_CLASS InformationClass,
out IntPtr Buffer);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern bool AuditLookupCategoryGuidFromCategoryId(
POLICY_AUDIT_EVENT_TYPE AuditCategoryId,
IntPtr pAuditCategoryGuid);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern bool AuditEnumerateSubCategories(
IntPtr pAuditCategoryGuid,
bool bRetrieveAllSubCategories,
out IntPtr ppAuditSubCategoriesArray,
out ulong pCountReturned);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern bool AuditQuerySystemPolicy(
IntPtr pSubCategoryGuids,
ulong PolicyCount,
out IntPtr ppAuditPolicy);
#endregion
Dictionary<string, UInt32> retList = new Dictionary<string, UInt32>();
long lretVal;
uint retVal;
IntPtr pAuditEventsInfo;
lretVal = LsaQueryInformationPolicy(policyHandle, POLICY_INFORMATION_CLASS.PolicyAuditEventsInformation, out pAuditEventsInfo);
retVal = LsaNtStatusToWinError(lretVal);
if (retVal != 0)
{
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception((int)retVal);
}
POLICY_AUDIT_EVENTS_INFO myAuditEventsInfo = new POLICY_AUDIT_EVENTS_INFO();
myAuditEventsInfo = (POLICY_AUDIT_EVENTS_INFO)Marshal.PtrToStructure(pAuditEventsInfo, myAuditEventsInfo.GetType());
IntPtr subCats = IntPtr.Zero;
ulong nSubCats = 0;
for (int audCat = 0; audCat < myAuditEventsInfo.MaximumAuditEventCount; audCat++)
{
GUID audCatGuid = new GUID();
if (!AuditLookupCategoryGuidFromCategoryId((POLICY_AUDIT_EVENT_TYPE)audCat, new IntPtr(&audCatGuid)))
{
int causingError = GetLastError();
LsaFreeMemory(pAuditEventsInfo);
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception(causingError);
}
if (!AuditEnumerateSubCategories(new IntPtr(&audCatGuid), true, out subCats, out nSubCats))
{
int causingError = GetLastError();
LsaFreeMemory(pAuditEventsInfo);
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception(causingError);
}
// Dereference the first pointer-to-pointer to point to the first subcategory
// subCats = (IntPtr)Marshal.PtrToStructure(subCats, subCats.GetType());
if (nSubCats > 0)
{
IntPtr audPolicies = IntPtr.Zero;
if (!AuditQuerySystemPolicy(subCats, nSubCats, out audPolicies))
{
int causingError = GetLastError();
if (subCats != IntPtr.Zero)
AuditFree(subCats);
LsaFreeMemory(pAuditEventsInfo);
LsaClose(policyHandle);
throw new System.ComponentModel.Win32Exception(causingError);
}
AUDIT_POLICY_INFORMATION myAudPol = new AUDIT_POLICY_INFORMATION();
for (ulong audSubCat = 0; audSubCat < nSubCats; audSubCat++)
{
// Process audPolicies[audSubCat], turn GUIDs into names, fill retList.
// http://msdn.microsoft.com/en-us/library/aa373931%28VS.85%29.aspx
// http://msdn.microsoft.com/en-us/library/bb648638%28VS.85%29.aspx
IntPtr itemAddr = IntPtr.Zero;
IntPtr itemAddrAddr = new IntPtr(audPolicies.ToInt64() + (long)(audSubCat * (ulong)Marshal.SizeOf(itemAddr)));
itemAddr = (IntPtr)Marshal.PtrToStructure(itemAddrAddr, itemAddr.GetType());
myAudPol = (AUDIT_POLICY_INFORMATION)Marshal.PtrToStructure(itemAddr, myAudPol.GetType());
retList[myAudPol.AuditSubCategoryGuid.ToString()] = myAudPol.AuditingInformation;
}
if (audPolicies != IntPtr.Zero)
AuditFree(audPolicies);
}
if (subCats != IntPtr.Zero)
AuditFree(subCats);
subCats = IntPtr.Zero;
nSubCats = 0;
}
lretVal = LsaFreeMemory(pAuditEventsInfo);
retVal = LsaNtStatusToWinError(lretVal);
if (retVal != 0)
throw new System.ComponentModel.Win32Exception((int)retVal);
lretVal = LsaClose(policyHandle);
retVal = LsaNtStatusToWinError(lretVal);
if (retVal != 0)
throw new System.ComponentModel.Win32Exception((int)retVal);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您发布的代码不完整,所以我无法编译它。没有使用
LsaOpenPolicy
函数打开policyHandle
的代码。一些结构的声明,例如AUDIT_POLICY_INFORMATION
、LSA_OBJECT_ATTRIBUTES
和LSA_UNICODE_STRING
也缺失。尽管如此,我在您的代码中至少发现了一处错误。
AuditLookupCategoryGuidFromCategoryId
最后一个参数的使用似乎是错误的。函数AuditLookupCategoryGuidFromCategoryId
具有原型,这意味着您必须分配非托管内存来保存
GUID
并获取指向AuditLookupCategoryGuidFromCategoryId
的指针。内存将由AuditLookupCategoryGuidFromCategoryId
填充。所以我似乎更正了以下内容
First of all you post not full code, so I can not compile it. There are no code to open
policyHandle
withLsaOpenPolicy
function. declaration of some structures likeAUDIT_POLICY_INFORMATION
,LSA_OBJECT_ATTRIBUTES
andLSA_UNICODE_STRING
also absent.Nevertheless I found at least one error in your code. Usage of the last parameter of
AuditLookupCategoryGuidFromCategoryId
seems me wrong. The functionAuditLookupCategoryGuidFromCategoryId
has prototypewhich means, you have to allocate unmanaged memory to hold
GUID
and get pointer toAuditLookupCategoryGuidFromCategoryId
. The memory will be filled byAuditLookupCategoryGuidFromCategoryId
. So instead ofseems me correct the following