Click here to Skip to main content
15,888,733 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
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?

C#
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;
}


[EDIT]

C#
[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
     );


C#
[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;
}


C#
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;
}
Posted
Updated 14-Apr-11 10:43am
v5

1 solution

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
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 14-Apr-11 16:26pm    
OP commented:

Going to look into what you said. Here's what you asked for in the mean time.
Sergey Alexandrovich Kryukov 14-Apr-11 16:30pm    
@majortool161: thank you for extra information, but next time please post it properly (not as "solution"). I've just fixed it.
--SA
[no name] 14-Apr-11 16:34pm    
Good point. I'm just getting the hang of Code Project. Great community! Time for home!
Sergey Alexandrovich Kryukov 14-Apr-11 16:46pm    
I think it is :-).
I had to fix some formatting in your code.
Try to resolve the problem yourself first; I pointed our some suspect items.
--SA
Espen Harlinn 14-Apr-11 16:45pm    
Good points, my 5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900