内存损坏pinvoke调用

内存损坏pinvoke调用

问题描述:

有时,我在这里遇到一个讨厌的错误,说我在API调用方面做得很顽皮.我得到SID长度和元帅后出现错误.将脚本复制到托管内存中.该错误实际上在Marshal.Copy行上.我想念这里的把手关闭吗?这是怎么回事?!当SID副本做坏事并且不会崩溃时,它还会随机给出错误87(在底部注释).这些问题肯定是相关的.有帮助吗?

Occasionally I''m getting a nasty error here saying that I''ve been doing something naughty with the API calls. The error comes after I get the SID length and Marshal.Copy the scruct into managed memory. The error is actually on the Marshal.Copy line. Am I missing the closing of a handle here? What''s going on?! It''s also randomly giving error 87(commented in the bottom) when the SID copy does bad things and doesn''t crash. These issues are definitely related. Any help?

public static Shares GetRemoteShares(string ip_address, string username, string password)
{
    var shares = new Shares();
    var entriesread = 0;
    var totalentries = 0;
    var resume_handle = 0;
    var n_struct_size = Marshal.SizeOf(typeof(SHARE_INFO_502));
    var share_buf_ptr = IntPtr.Zero;
    var server = new StringBuilder(ip_address);
    Int32 share_enum_ret;
    do
    {
        share_enum_ret =
            PInvoke.NetShareEnum(server, 502, ref share_buf_ptr, 0xFFFFFFFF,
                 ref entriesread, ref totalentries, ref resume_handle);
        for (var i = 0; i < entriesread; ++i)
        {
            var share_info =
                 (SHARE_INFO_502)Marshal.PtrToStructure(share_buf_ptr + n_struct_size * i,
                      typeof(SHARE_INFO_502));
            if (share_info.shi502_type != SHARE_TYPE.STYPE_DISKTREE &&
                      share_info.shi502_type != SHARE_TYPE.STYPE_SPECIAL) continue;
            var share_permissions = GetSharePermissions(share_info, ip_address);
            var ntfs_permissions = GetNTFSPermissions(share_info, ip_address, username, password);
            //if (share_ret !=
            //PInvoke.ERROR_SUCCESS && share_ret != PInvoke.ERROR_SESSION_CREDENTIAL_CONFLICT) continue;
            shares.Add(new Share(share_info.shi502_netname,
                share_info.shi502_path, ntfs_permissions, share_permissions));
        }
    } while (share_enum_ret == PInvoke.ERROR_MORE_DATA);
    PInvoke.NetApiBufferFree(share_buf_ptr);
    return shares;
}









[DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
public static extern int NetShareEnum(
     StringBuilder server_name,
     int level,
     ref IntPtr buf_ptr,
     uint prefmaxlen,
     ref int entriesread,
     ref int totalentries,
     ref int resume_handle
     );





[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_502
{
    public string shi502_netname;
    [MarshalAs(UnmanagedType.U4)]
    public SHARE_TYPE shi502_type;
    public string shi502_remark;
    [MarshalAs(UnmanagedType.U4)]
    public int shi502_permissions;        // used w/ share level security only
    [MarshalAs(UnmanagedType.U4)]
    public int shi502_max_uses;
    [MarshalAs(UnmanagedType.U4)]
    public int shi502_current_uses;
    public string shi502_path;
    public string shi502_passwd;        // used w/ share level security only
    [MarshalAs(UnmanagedType.U4)]
    public int shi502_reserved;
    public IntPtr shi502_security_descriptor;
}





public static Shares GetRemoteShares(string ip_address, string username, string password)
{
    var shares = new Shares();
    var entriesread = 0;
    var totalentries = 0;
    var resume_handle = 0;
    var n_struct_size = Marshal.SizeOf(typeof(SHARE_INFO_502));
    var share_buf_ptr = IntPtr.Zero;
    var server = new StringBuilder(ip_address);
    Int32 share_enum_ret;
    do
    {
        share_enum_ret =
            PInvoke.NetShareEnum(server, 502, ref share_buf_ptr,
                 0xFFFFFFFF, ref entriesread, ref totalentries, ref resume_handle);
        for (var i = 0; i < entriesread; ++i)
        {
            var share_info =
                 (SHARE_INFO_502)Marshal.PtrToStructure(share_buf_ptr +
                        n_struct_size * i, typeof(SHARE_INFO_502));
            if (share_info.shi502_type != SHARE_TYPE.STYPE_DISKTREE &&
                        share_info.shi502_type != SHARE_TYPE.STYPE_SPECIAL) continue;
            var share_permissions = GetSharePermissions(share_info, ip_address);
            var ntfs_permissions = GetNTFSPermissions(share_info, ip_address, username, password);
            //if (share_ret != PInvoke.ERROR_SUCCESS &&
            //    share_ret != PInvoke.ERROR_SESSION_CREDENTIAL_CONFLICT) continue;
            shares.Add(new Share(share_info.shi502_netname,
                share_info.shi502_path, ntfs_permissions, share_permissions));
        }
    } while (share_enum_ret == PInvoke.ERROR_MORE_DATA);
    PInvoke.NetApiBufferFree(share_buf_ptr);
    return shares;
}

您需要显示您的课程PInvoke. Windows API方法NetShareEnumNetApiBufferFreeSHARE_INFO_0的声明中很有可能是您的问题.第一个函数通过指向非托管内存的指针返回三个值(顺便说一句,使用<code> out代替ref,只是为了更好的可维护性),这些值应该自动编组为通过out进行引用传递的参数. > 您需要显式声明这些变量,而不是通过var声明为System.UInt32.
—SA
You need to show your class PInvoke. Your problem is most likely in the declarations of the Windows API methods NetShareEnum, NetApiBufferFree and SHARE_INFO_0. First functions returns three values by pointers to the unmanaged memory (by the way, use <code>out instead of ref, just for better maintainability) which should be marshaled automatically as passing parameters by reference via out.
You need to declare those variable explicitly, not through var as System.UInt32.

—SA