3

シーケンスは次のようになります。

これらはすべて機能し、最後のものを除いて、期待される適切な値を返します。呼び出す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);
4

1 に答える 1

1

まず、完全なコードではないので、コンパイルできません。policyHandle関数で開くコードはありませんLsaOpenPolicy。のようないくつかの構造体の宣言AUDIT_POLICY_INFORMATIONLSA_OBJECT_ATTRIBUTESおよびLSA_UNICODE_STRING存在しないものもあります。

それにもかかわらず、あなたのコードに少なくとも 1 つのエラーが見つかりました。の最後のパラメータの使い方がAuditLookupCategoryGuidFromCategoryId間違っているようです。関数AuditLookupCategoryGuidFromCategoryIdにはプロトタイプがあります

BOOLEAN WINAPI AuditLookupCategoryGuidFromCategoryId(
  __in   POLICY_AUDIT_EVENT_TYPE AuditCategoryId,
  __out  GUID *pAuditCategoryGuid
);

つまり、保持するためにアンマネージメモリを割り当て、GUIDへのポインタを取得する必要がありますAuditLookupCategoryGuidFromCategoryId。メモリは で埋められAuditLookupCategoryGuidFromCategoryIdます。だから代わりに

GUID audCatGuid = new GUID();
if (!AuditLookupCategoryGuidFromCategoryId((POLICY_AUDIT_EVENT_TYPE)audCat,
                                           new IntPtr(&audCatGuid)))
// ...
if (!AuditEnumerateSubCategories(new IntPtr(&audCatGuid), true, out subCats,
                                 out nSubCats))
// ...

私は次のように正しいようです

IntPtr pAuditCatGuid = Marshal.AllocHGlobal (Marshal.SizeOf(GUID));
if (!AuditLookupCategoryGuidFromCategoryId((POLICY_AUDIT_EVENT_TYPE)audCat,
                                           pAuditCatGuid))
// ...
if (!AuditEnumerateSubCategories(pAuditCatGuid, true, out subCats,
                                 out nSubCats))
// ...
于 2010-06-11T23:02:58.847 に答える