1

我正在尝试使用调用netapi32.dll来操作 DFS 共享的 Windows API .dll。我们在 Windows Server 2008 R2 上使用 DFS,而我使用的是 .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条线。

有时会收到一条错误消息:

运行时遇到致命错误。错误地址位于线程 0x1d44 上的 0x626ac91c。错误代码为 0xc0000005。此错误可能是 CLR 中的错​​误或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM 互操作或 PInvoke 的用户封送错误,这可能会损坏堆栈。

错误类型是fatalExecutionEngineError,它不是 .NET 异常,所以我无法捕捉到它。它不会每次都发生,但我会说大约 50% 的时间会出现此错误。查找Windows 错误代码,我看到 5 是“拒绝访问”。由于只精通介绍级 Comp Sci,我对指针(IntPtr对象是什么)有所了解,并且指针可能已经溢出到它不应该的结果中?我仍然不明白为什么这个错误只会在某些时候发生。

我如何理解/避免这个错误?

4

1 回答 1

2

你的定义DFS_STORAGE_INFO不正确。在 .NET 中 along/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 个字节 - 这可能会或可能不会工作,具体取决于结构之后的内容。

于 2012-07-09T16:07:22.297 回答