Search code examples
c#pinvokeunmanagednetapi32

Call unmanaged code from c#. Getting data using IntPtr


I have a strange problem with application that I'm currently writing. I'm pretty sure i haven't changed anything within the below code recently, but somehow it stopped working. To the point. I'm using:

[DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern uint NetShareGetInfo(
        string servername,
        string netname,
        int level,
        out IntPtr ppBuf
        );

To import NetApi32.dll. I need physical Path. WMI and WinRM cannot be used. Then I have enum and struct as below:

public enum ShType
    {
        DiskTree = 0,
        PrintQ = 1,
        Device = 2,
        IPC = 3,
        Temporary = 0x40000000,
        Special = unchecked((int)0x80000000)
    }
    public struct SHARE_INFO_502
    {
        public string Name;
        public ShType Type;
        public string Remark;
        public int Permissions;
        public int MaxUses;
        public int CurrentUses;
        public string Path;
        public string PassWd;
        public int reserved;
        public IntPtr SecDescriptor;
    }

all in

 [SuppressUnmanagedCodeSecurity]
public static class SafeNativeMethods

Class according to VS code analyzer. I call it with:

 IntPtr ptrGet;
 var resGetInfo = SafeNativeMethods.NetShareGetInfo("server_name", "share_name", 502, out ptrGet);             
 SafeNativeMethods.SHARE_INFO_502 siGet = (SafeNativeMethods.SHARE_INFO_502)Marshal.PtrToStructure(ptrGet, typeof(SafeNativeMethods.SHARE_INFO_502));

after running above code I do not receive any errors or exceptions, however, siGet Struct has only first letter of each property value. Where could be the problem?


Solution

  • The default character set is Ansi, and that's what the struct marshalling uses. But you opt for the Unicode version of the function. You should also specify the character set for the struct:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHARE_INFO_502
    ....
    

    Some tips when marshalling text:

    • Whenever you see only the first character of a string, you should first suspect that you have UTF-16 text interpreted as ANSI or UTF-8.
    • Whenever you see text that looks Chinese where you expected English, you should first suspect that you have ANSI or UTF-8 text interpreted as UTF-16.