【问题标题】:PInvoke for DWORD-aligned handles to memoryPInvoke 用于 DWORD 对齐的内存句柄
【发布时间】:2012-07-23 17:53:35
【问题描述】:

我正在尝试为ACCESS_DENIED_ACE 结构编写一个等效的 C#,如MSDN 中定义的那样:

typedef struct _ACCESS_DENIED_ACE {
  ACE_HEADER  Header;
  ACCESS_MASK Mask;
  DWORD       SidStart;
} ACCESS_DENIED_ACE, *PACCESS_DENIED_ACE;

SidStart 是受托人 SID 的第一个 DWORD。 SID 的剩余字节存储在 SidStart 成员之后的连续内存中。

我已经看到了像 (PSID) &accessAllowedAce->SidStart 这样使用的例子,

if ( EqualSid (pSid, (PSID) &accessDeniedAce->SidStart) )
{
   //
}

现在我该如何为此编写 C# StructLayout 以及如何在 EqualSid 函数中使用它,同时解释一下您的解决方案是如何工作的。

【问题讨论】:

    标签: c# pinvoke structlayout


    【解决方案1】:

    从子结构开始。

    [StructLayout(LayoutKind.Sequential)]
    struct ACE_HEADER
    {
        byte AceType;
        byte AceFlags;
        uint AceSize;
    }
    

    DWORD = uint

    [Flags]
    enum ACCESS_MASK : uint
    {
        // ...
    }
    

    它是一个基于标志的枚举结构,表示为 32 位(即可以切换多个状态)。 您需要按照记录定义这些位。

    [StructLayout(LayoutKind.Sequential)]
    struct ACCESS_DENIED_ACE
    {
        ACE_HEADER Header;
        ACCESS_MASK Mask;
        uint SidStart;
    }
    

    现在结构简单。

    【讨论】:

    • 如何在 c# 中使用 SidStart,如果在 C++ 中它像 (PSID) &accessAllowedAce->SidStart 一样使用。将 uint (SidStart) 编组到 IntPtr 是否有效?
    • @sri:我认为你可以这样使用:var sid1 = new IntPtr((long)ace.SidStart); if ( EqualSid(sid1, sid2) ) { .... }。尝试让我知道它是否有效。
    • 我没有看到 PSID 的 typedef,但它很可能只是一个 DWORD 并且为了便于阅读而添加了它。对于您的问题,正如@Nawaz 所说, var sid = new ACCESS_DENIED_ACE(...); sid.SidStart 将为您提供 SidStart 的值,无需基于 MSDN 中该结构的定义的 IntPtr。
    • @Nawaz:我的 ace 是使用 Marshal.PtrToStructure 创建的,因此它会创建一个新副本。现在我的问题是,它会将 SID 中的所有位复制到创建的新结构中,还是仅将 SID 的第一个字节作为 SidStart 是一个 uint。如果它在编组对象中的 SidStart 成员之后将所有片段复制为连续内存,那么它在编组时如何知道该信息。
    • @sri:我认为它不会复制结构之外的其余位。这是关心合规性的 C++ 程序员认为这种 hack 不好的原因之一。但是我认为如果您知道用于 SID 的字节数,那么您可以更改ACCESS_DENIED_ACE 的定义,如下所示:@ 987654326@ ,即把它变成一个数组,这样编组就会知道它需要复制多少字节。
    【解决方案2】:

    当我获得ACCESS_DENIED_ACEIntPtr(假设deniedAceIntPtr)时,我可以通过添加SidStart 的偏移量来获得ACCESS_DENIED_ACE 中SID 的IntPtr

    IntPtr tempSid = IntPtr.Add(deniedAceIntPtr, 8);

    【讨论】:

    • +1。 (顺便说一句,在一般情况下避免在代码中使用幻数;但这里似乎没关系)。
    猜你喜欢
    • 2016-03-04
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多