fatalExecutionEngineError при использовании Windows API

Я пытаюсь использовать Windows API .dll под названием netapi32.dll манипулировать акциями DFS. Мы используем DFS в Windows Server 2008 R2, а я использую.NET 4.0. Я никогда не использовал что-то подобное в.NET, но у меня проблемы с пониманием того, что не работает.

я использую DllImport вызвать NetDfsGetInfo для проверки получения информации об общей папке DFS. Я должен был создать структуры для уровня информации, которую я хотел получить от функции.

public struct DFS_INFO_3
{
    [MarshalAs(UnmanagedType.LPWStr)]
    public string EntryPath;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string Comment;
    public UInt32 State;
    public UInt32 NumberOfStorages;
    public IntPtr Storage;
}

public struct DFS_STORAGE_INFO
{
    public ulong State;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ServerName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ShareName;
}

Я использовал следующий код, чтобы получить и прочитать результат:

[DllImport("netapi32", CallingConvention = CallingConvention.Winapi)]
public static extern int NetDfsGetInfo(
                    [MarshalAs(UnmanagedType.LPWStr)] string DfsEntryPath,
                    [MarshalAs(UnmanagedType.LPWStr)]string ServerName, 
                    [MarshalAs(UnmanagedType.LPWStr)]string ShareName, 
                    int Level, 
                    out IntPtr Buffer);

public void GetInfo() {
    IntPtr buffer;
    string dfsPath = "\\\\server\\share";

    int result = NetDfsGetInfo(EntryPath, null, null, 3, out buffer);

    if (result == 0) { //0 is Success
        DFS_INFO_3 info = (DFS_INFO_3)Marshal.PtrToStructure(buffer, typeof(DFS_INFO_3));
        DFS_STORAGE_INFO storage = (DFS_STORAGE_INFO)Marshal.PtrToStructure(info.Storage, typeof(DFS_STORAGE_INFO)); //Error
        Console.WriteLine("{0}, {1}, {2} ", storage.ServerName, storage.ShareName, storage.State);
    }
}

Все идет хорошо, пока не идет читать storage линия.

Иногда я получаю сообщение об ошибке:

Во время выполнения произошла фатальная ошибка. Адрес ошибки был 0x626ac91c, в потоке 0x1d44. Код ошибки 0xc0000005. Эта ошибка может быть ошибкой в ​​CLR или в небезопасных или не поддающихся проверке частях пользовательского кода. Распространенными источниками этой ошибки являются ошибки пользовательского маршалинга для COM-взаимодействия или PInvoke, которые могут повредить стек.

Тип ошибки - fatalExecutionEngineError, который не является исключением.NET, поэтому я не могу его перехватить. Это происходит не каждый раз, но я бы сказал, что в 50% случаев я получаю эту ошибку. Просматривая коды ошибок Windows, я вижу, что 5 - "Отказано в доступе". Будучи только начинающим специалистом по Comp Sci, я немного разбираюсь в указателях (что IntPtr объект есть), и что указатель, возможно, перетек в часть результата, который он не должен был? Я до сих пор не понимаю, почему эта ошибка возникает только иногда.

Как я понимаю / избежать этой ошибки?

1 ответ

Решение

Ваше определение DFS_STORAGE_INFO это неверно. В.NET long/ulong составляет 64 бита, в то время как в неуправляемом Win32 это только 32 бита (то же самое, что int/uint)

public struct DFS_STORAGE_INFO
{
    public UInt32 State;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ServerName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string ShareName;
}

Когда вы соберете DFS_STORAGE_INFO Вы будете читать 4 байта после конца структуры - что может работать или не работать в зависимости от того, что находится после структуры.

Другие вопросы по тегам