title: How to pinvoke a variable-length array of structs from GetTokenInformation() safely for 32-bit and 64-bit? C#
body: <p>I'm following the pinvoke code provided <a href="https://stackoverflow.com/questions/2146153/how-to-get-the-logon-sid-in-c/2146418#2146418">here</a> but am slightly scared by the marshalling of the variable-length array as size=1 and then stepping through it by calculating an offset instead of indexing into an array. Isn't there a better way? And if not, how should I do this to make it safe for 32-bit and 64-bit? </p>
  
  <pre><code>    [StructLayout(LayoutKind.Sequential)]
      public struct SID_AND_ATTRIBUTES
      {
          public IntPtr Sid;
          public uint Attributes;
      }
  
      [StructLayout(LayoutKind.Sequential)]
      public struct TOKEN_GROUPS
      {
          public int GroupCount;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
          public SID_AND_ATTRIBUTES[] Groups;
      };
  
  
  public void SomeMethod()
  {
      IntPtr tokenInformation;
  
      // ... 
  
      string retVal = string.Empty;
      TOKEN_GROUPS groups = (TOKEN_GROUPS)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_GROUPS));
      int sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES());
      for (int i = 0; i &lt; groups.GroupCount; i++)
      {
          // *** Scary line here: 
          SID_AND_ATTRIBUTES sidAndAttributes = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(
                new IntPtr(tokenInformation.ToInt64() + i * sidAndAttrSize + IntPtr.Size), 
                typeof(SID_AND_ATTRIBUTES));
  
      // ... 
  }
  </code></pre>
  
  <p>I see <a href="https://stackoverflow.com/questions/3338297/managed-to-unmanaged-code-call-causes-access-violation-sometimes">here</a> another approach of declaring the length of the array as much bigger than it's likely to be, but that seemed to have its own problems.</p>
  
  <p>As a side question: When I step through the above code in the debugger I'm not able to evaluate <code>tokenInformation.ToInt64()</code> or <code>ToInt32()</code>. I get an ArgumentOutOfRangeException. But the line of code executes just fine!? What's going on here?</p>