1

I'm having a problem building an array of structs from an IntPtr in another struct.

This structure is returned by a Windows API I'm using:

public struct DFS_INFO_9 {
    [MarshalAs(UnmanagedType.LPWStr)]
    public string EntryPath;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string Comment;
    public DFS_VOLUME_STATE State;
    public UInt32 Timeout;
    public Guid Guid;
    public UInt32 PropertyFlags;
    public UInt32 MetadataSize;
    public UInt32 SdLengthReserved;
    public IntPtr pSecurityDescriptor;
    public UInt32 NumberOfStorages;
    public IntPtr Storage;
}

[DllImport("netapi32", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int NetDfsEnum([MarshalAs(UnmanagedType.LPWStr)]string DfsName, int Level, int PrefMaxLen, out IntPtr Buffer, [MarshalAs(UnmanagedType.I4)]out int EntriesRead, [MarshalAs(UnmanagedType.I4)]ref int ResumeHandle);

I'm trying to get the array of DFS_STORAGE_INFO_1s referenced by IntPtr Storage.

Here's that structure (if it matters):

public struct DFS_STORAGE_INFO_1 {
    public DFS_STORAGE_STATE State;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ServerName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ShareName;
    public IntPtr TargetPriority;
}

So far this code has been working to get the DFS_INFO_9s with only one storage, but fails when trying to marshal the second item in the array.

DFS_INFO_9 info = GetInfoFromWinApi();
List<DFS_STORAGE_INFO_1> Storages = new List<DFS_STORAGE_INFO_1>();
for (int i = 0; i < info.NumberOfStorages; i++) {
    IntPtr pStorage = new IntPtr(info.Storage.ToInt64() + i * Marshal.SizeOf(typeof(DFS_STORAGE_INFO_1)));
    DFS_STORAGE_INFO_1 storage = (DFS_STORAGE_INFO_1)Marshal.PtrToStructure(pStorage, typeof(DFS_STORAGE_INFO_1));
    Storages.Add(storage);
}

I'm getting a FatalExecutionEngineError that spits out error code 0x0000005 (Access Denied). I'm assuming the size of the DFS_STORAGE_INFO_1 is being miscalculated causing the marshal to attempt to access memory outside that allocated for the array. But this is happening on i = 1, when there might be 7 storages to get through. Maybe my thinking is flawed, but I have no idea how to rectify this.

8
  • look here at some precious SO posting stackoverflow.com/questions/4550207/… also do a google search on this error code 0xc0000005 (Access Denied) Commented Apr 5, 2013 at 19:35
  • I've seen stuff like this, you can bet I googled it. The first so posts suggest the solution I'm trying to get away from, running an executable. I'm trying to use Windows Apis to better manage the code, and not have to open a command prompt and hope everything goes alright. The second post makes no sense to me. Commented Apr 5, 2013 at 19:45
  • I think I know what you are wanting I have seen an earlier post let me find it again and see if it's related Commented Apr 5, 2013 at 19:47
  • TargetPriority is wrong. It is a struct, not a pointer. Commented Apr 5, 2013 at 21:33
  • Wow, can't believe I overlooked that. Thanks @HansPassant. Could you list that as an answer? Here's the link to the structure definition that confirms it: msdn.microsoft.com/en-us/library/windows/desktop/… Commented Apr 8, 2013 at 14:11

1 Answer 1

1

The actual definition of DFS_STORAGE_INFO_1 is this:

public struct DFS_STORAGE_INFO_1 {
    public DFS_STORAGE_STATE State;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ServerName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ShareName;
    DFS_TARGET_PRIORITY TargetPriority;
}

TargetPriority is a structure, defined here:

public struct DFS_TARGET_PRIORITY {
    public DFS_TARGET_PRIORITY_CLASS TargetPriorityClass;
    public UInt16 TargetPriorityRank;
    public UInt16 Reserved;
}

public enum DFS_TARGET_PRIORITY_CLASS {
    DfsInvalidPriorityClass = -1,
    DfsSiteCostNormalPriorityClass = 0,
    DfsGlobalHighPriorityClass = 1,
    DfsSiteCostHighPriorityClass = 2,
    DfsSiteCostLowPriorityClass = 3,
    DfsGlobalLowPriorityClass = 4
}

As for the FatalExecutionEngineError, I believe that the size of the structure DFS_STORAGE_INFO_1 was being miscalculated since it was defined incorrectly. When trying to convert the pointers to the structures they referenced, the next index was wrong because the size was off. When converting the block of memory, it presumably referenced a block that shouldn't have been accessible, throwing the "Access Denied (0x0000005)" error.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.