WNetAddConnection2 возвращает ошибку 1200 - действительное локальное имя

Я пытаюсь подключить общий ресурс (скажем, \server\folder) к моему локальному устройству 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;
    }

При звонке

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

функция просто возвращает false - ошибка говорит 1200 (BAD_DEVICE).NETResource выглядит так:

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

Я уже проверил несколько фрагментов (PInvoke), я не вижу никакой разницы. Может быть, вы можете решить эту загадку...

EDIT1

Переменные при попытке сопоставления диска

2 ответа

Решение
[StructLayout(LayoutKind.Sequential)]

Вот где проблема началась, атрибут не указывает CharSet имущество. По умолчанию используется CharSet.Ansi, изумительный выбор, для которого требуется отключение на машине времени, возвращающее вас назад к 1998 году. Таким образом, код передает структуру со строками, которые переводятся в 8-битные символы, в функцию, которая является явно использует Unicode-вариант функции. Неизбежно реализация видит мусор.

Вы можете форсировать маршалинг каждого отдельного члена строки с помощью [MarshalAs]. Но просто и логично сделать совпадение типов символов. Fix:

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

Я наконец сделал это.

Я решил проблему, добавив

[MarshalAs(UnmanagedType.LPWStr)] 

Атрибут каждого строкового поля внутри моего класса NetResource. К сожалению, я не знаю, почему это решает проблему...

Другие вопросы по тегам