WNetAddConnection2 returns Error 1200 - Local name is valid

半世苍凉 提交于 2019-12-12 10:44:51

问题


I'm trying to connect a share (let's say \server\folder) to my local device X:

[DllImport("Mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern int WNetAddConnection2(
            [In] NetResource lpNetResource,
            string lpPassword,
            string lpUsername,
            int flags
        );

public static bool Connect(string remoteName, string localName, bool persistent) {
            if (!IsLocalPathValid(localName)) return false;
            var r = new NetResource
            {
                dwScope = ResourceScope.RESOURCE_GLOBALNET,
                dwType = ResourceType.RESOURCETYPE_ANY,
                dwDisplayType = ResourceDisplayType.RESOURCEDISPLAYTYPE_SHARE,
                dwUsage = ResourceUsage.RESOURCEUSAGE_CONNECTABLE,
                lpRemoteName = remoteName,
                lpLocalName = localName
            };
            return WNetAddConnection2(r, null, null, persistent ? 1 : 0) == 0;
        }

[StructLayout(LayoutKind.Sequential)]
    public class NetResource {
        public ResourceScope dwScope;
        public ResourceType dwType;
        public ResourceDisplayType dwDisplayType;
        public ResourceUsage dwUsage;
        public string lpLocalName;
        public string lpRemoteName;
        public string lpComment;
        public string lpProvider;
    }

When calling

Connect(@"\\server\folder", "X:", true);

the function just returns false - the Error says 1200 (BAD_DEVICE). The NetResource looks like this:

lpRemoteName = "\\\\server\\folder"; 
lpProvider = null;
lpLocalName = "X:";
lpComment = null;
dwUsage = Connectable; 
dwType = Any; 
dwScope = GlobalNet; 
dwDisplayType = Share;

I already checked with several snippets (PInvoke) put i can't see any difference. Maybe you can solve this mystery...

EDIT1


回答1:


[StructLayout(LayoutKind.Sequential)]

That is where the problem started, the attribute does not specify the CharSet property. The default is CharSet.Ansi, a bewildering choice that requires a trip in a time machine to make sense of, taking you back to 1998. So the code passes a struct with strings that get translated to 8-bit characters to a function that is explicitly uses the Unicode flavor of the function. Inevitably the implementation sees garbage.

You can force the marshaling of each individual string member with [MarshalAs]. But it is just simpler and logical to make the character types match. Fix:

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



回答2:


I finally did it.

I solved the issue by adding

[MarshalAs(UnmanagedType.LPWStr)] 

Attribute to every string field inside my NetResource class. Unfortunately I don't know why this is solving the issue...



来源:https://stackoverflow.com/questions/45342437/wnetaddconnection2-returns-error-1200-local-name-is-valid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!