--- mpr.spec (revision 49877)\r
+++ mpr.spec (working copy)\r
@@ -1,23 +1,23 @@\r
- # ordinal exports
-- 1 stub @
-- 2 stub @
-- 3 stub @
-- 4 stub @
-- 5 stub @
-- 6 stub @
-- 7 stub @
-- 8 stub @
-- 9 stub @
--12 stub @
--13 stub @
--14 stub @
--15 stub @
--16 stub @
--17 stub @
--18 stub @
--19 stub @
--20 stub @
--21 stub @
-+ 1 stub MPR_1
-+ 2 stub MPR_2
-+ 3 stub MPR_3
-+ 4 stub MPR_4
-+ 5 stub MPR_5
-+ 6 stub MPR_6
-+ 7 stub MPR_7
-+ 8 stub MPR_8
-+ 9 stub MPR_9
-+12 stub MPR_12
-+13 stub MPR_13
-+14 stub MPR_14
-+15 stub MPR_15
-+16 stub MPR_16
-+17 stub MPR_17
-+18 stub MPR_18
-+19 stub MPR_19
-+20 stub MPR_20
-+21 stub MPR_21
- 22 stdcall @(long) MPR_Alloc
- 23 stdcall @(ptr long) MPR_ReAlloc
- 24 stdcall @(ptr) MPR_Free
+ # ordinal exports\r
+- 1 stub @\r
+- 2 stub @\r
+- 3 stub @\r
+- 4 stub @\r
+- 5 stub @\r
+- 6 stub @\r
+- 7 stub @\r
+- 8 stub @\r
+- 9 stub @\r
+-12 stub @\r
+-13 stub @\r
+-14 stub @\r
+-15 stub @\r
+-16 stub @\r
+-17 stub @\r
+-18 stub @\r
+-19 stub @\r
+-20 stub @\r
+-21 stub @\r
++ 1 stub MPR_1\r
++ 2 stub MPR_2\r
++ 3 stub MPR_3\r
++ 4 stub MPR_4\r
++ 5 stub MPR_5\r
++ 6 stub MPR_6\r
++ 7 stub MPR_7\r
++ 8 stub MPR_8\r
++ 9 stub MPR_9\r
++12 stub MPR_12\r
++13 stub MPR_13\r
++14 stub MPR_14\r
++15 stub MPR_15\r
++16 stub MPR_16\r
++17 stub MPR_17\r
++18 stub MPR_18\r
++19 stub MPR_19\r
++20 stub MPR_20\r
++21 stub MPR_21\r
+ 22 stdcall @(long) MPR_Alloc\r
+ 23 stdcall @(ptr long) MPR_ReAlloc\r
+ 24 stdcall @(ptr) MPR_Free\r
+Index: wnet.c\r
+===================================================================\r
+--- wnet.c (revision 71983)\r
++++ wnet.c (working copy)\r
+@@ -60,6 +50,9 @@\r
+ PF_NPAddConnection addConnection;\r
+ PF_NPAddConnection3 addConnection3;\r
+ PF_NPCancelConnection cancelConnection;\r
++#ifdef __REACTOS__\r
++ PF_NPGetConnection getConnection;\r
++#endif\r
+ } WNetProvider, *PWNetProvider;\r
+ \r
+ typedef struct _WNetProviderTable\r
+@@ -214,6 +207,9 @@\r
+ provider->addConnection = MPR_GETPROC(NPAddConnection);\r
+ provider->addConnection3 = MPR_GETPROC(NPAddConnection3);\r
+ provider->cancelConnection = MPR_GETPROC(NPCancelConnection);\r
++#ifdef __REACTOS__\r
++ provider->getConnection = MPR_GETPROC(NPGetConnection);\r
++#endif\r
+ TRACE("NPAddConnection %p\n", provider->addConnection);\r
+ TRACE("NPAddConnection3 %p\n", provider->addConnection3);\r
+ TRACE("NPCancelConnection %p\n", provider->cancelConnection);\r
+@@ -251,6 +247,85 @@\r
+ debugstr_w(provider));\r
+ }\r
+ \r
++#ifdef __REACTOS__\r
++static void _restoreSavedConnection(HKEY connection, WCHAR * local)\r
++{\r
++ NETRESOURCEW net;\r
++ DWORD type, prov, index, size;\r
++\r
++ net.lpProvider = NULL;\r
++ net.lpRemoteName = NULL;\r
++ net.lpLocalName = NULL;\r
++\r
++ TRACE("Restoring: %S\n", local);\r
++\r
++ size = sizeof(DWORD);\r
++ if (RegQueryValueExW(connection, L"ConnectionType", NULL, &type, (BYTE *)&net.dwType, &size) != ERROR_SUCCESS)\r
++ return;\r
++\r
++ if (type != REG_DWORD || size != sizeof(DWORD))\r
++ return;\r
++\r
++ if (RegQueryValueExW(connection, L"ProviderName", NULL, &type, NULL, &size) != ERROR_SUCCESS)\r
++ return;\r
++\r
++ if (type != REG_SZ)\r
++ return;\r
++\r
++ net.lpProvider = HeapAlloc(GetProcessHeap(), 0, size);\r
++ if (!net.lpProvider)\r
++ return;\r
++\r
++ if (RegQueryValueExW(connection, L"ProviderName", NULL, NULL, (BYTE *)net.lpProvider, &size) != ERROR_SUCCESS)\r
++ goto cleanup;\r
++\r
++ size = sizeof(DWORD);\r
++ if (RegQueryValueExW(connection, L"ProviderType", NULL, &type, (BYTE *)&prov, &size) != ERROR_SUCCESS)\r
++ goto cleanup;\r
++\r
++ if (type != REG_DWORD || size != sizeof(DWORD))\r
++ goto cleanup;\r
++\r
++ index = _findProviderIndexW(net.lpProvider);\r
++ if (index == BAD_PROVIDER_INDEX)\r
++ goto cleanup;\r
++\r
++ if (providerTable->table[index].dwNetType != prov)\r
++ goto cleanup;\r
++\r
++ if (RegQueryValueExW(connection, L"RemotePath", NULL, &type, NULL, &size) != ERROR_SUCCESS)\r
++ goto cleanup;\r
++\r
++ if (type != REG_SZ)\r
++ goto cleanup;\r
++\r
++ net.lpRemoteName = HeapAlloc(GetProcessHeap(), 0, size);\r
++ if (!net.lpRemoteName)\r
++ goto cleanup;\r
++\r
++ if (RegQueryValueExW(connection, L"RemotePath", NULL, NULL, (BYTE *)net.lpRemoteName, &size) != ERROR_SUCCESS)\r
++ goto cleanup;\r
++\r
++ size = strlenW(local);\r
++ net.lpLocalName = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR) + 2 * sizeof(WCHAR));\r
++ if (!net.lpLocalName)\r
++ goto cleanup;\r
++\r
++ strcpyW(net.lpLocalName, local);\r
++ net.lpLocalName[size] = ':';\r
++ net.lpLocalName[size + 1] = 0;\r
++\r
++ TRACE("Attempting connection\n");\r
++\r
++ WNetAddConnection2W(&net, NULL, NULL, 0);\r
++\r
++cleanup:\r
++ HeapFree(GetProcessHeap(), 0, net.lpProvider);\r
++ HeapFree(GetProcessHeap(), 0, net.lpRemoteName);\r
++ HeapFree(GetProcessHeap(), 0, net.lpLocalName);\r
++}\r
++#endif\r
++\r
+ void wnetInit(HINSTANCE hInstDll)\r
+ {\r
+ static const WCHAR providerOrderKey[] = { 'S','y','s','t','e','m','\\',\r
+@@ -329,6 +404,64 @@\r
+ }\r
+ RegCloseKey(hKey);\r
+ }\r
++\r
++#ifdef __REACTOS__\r
++ if (providerTable)\r
++ {\r
++ HKEY user_profile;\r
++\r
++ if (RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS)\r
++ {\r
++ HKEY network;\r
++ WCHAR subkey[8] = {'N', 'e', 't', 'w', 'o', 'r', 'k', 0};\r
++\r
++ if (RegOpenKeyExW(user_profile, subkey, 0, KEY_READ, &network) == ERROR_SUCCESS)\r
++ {\r
++ DWORD size, max;\r
++\r
++ TRACE("Enumerating remembered connections\n");\r
++\r
++ if (RegQueryInfoKey(network, NULL, NULL, NULL, &max, &size, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)\r
++ {\r
++ WCHAR *local;\r
++\r
++ TRACE("There are %lu connections\n", max);\r
++\r
++ local = HeapAlloc(GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR));\r
++ if (local)\r
++ {\r
++ DWORD index;\r
++\r
++ for (index = 0; index < max; ++index)\r
++ {\r
++ DWORD len = size + 1;\r
++ HKEY connection;\r
++\r
++ TRACE("Trying connection %lu\n", index);\r
++\r
++ if (RegEnumKeyExW(network, index, local, &len, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)\r
++ continue;\r
++\r
++ TRACE("It is %S\n", local);\r
++\r
++ if (RegOpenKeyExW(network, local, 0, KEY_READ, &connection) != ERROR_SUCCESS)\r
++ continue;\r
++\r
++ _restoreSavedConnection(connection, local);\r
++ RegCloseKey(connection);\r
++ }\r
++\r
++ HeapFree(GetProcessHeap(), 0, local);\r
++ }\r
++ }\r
++\r
++ RegCloseKey(network);\r
++ }\r
++\r
++ RegCloseKey(user_profile);\r
++ }\r
++ }\r
++#endif\r
+ }\r
+ \r
+ void wnetFree(void)\r
+@@ -1870,6 +2003,43 @@\r
+ }\r
+ }\r
+ \r
++#ifdef __REACTOS__\r
++ if (ret == WN_SUCCESS && ctxt->flags & CONNECT_UPDATE_PROFILE)\r
++ {\r
++ HKEY user_profile;\r
++\r
++ if (netres.dwType == RESOURCETYPE_PRINT)\r
++ {\r
++ FIXME("Persistent connection are not supported for printers\n");\r
++ return ret;\r
++ }\r
++\r
++ if (RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS)\r
++ {\r
++ HKEY network;\r
++ WCHAR subkey[10] = {'N', 'e', 't', 'w', 'o', 'r', 'k', '\\', netres.lpLocalName[0], 0};\r
++\r
++ if (RegCreateKeyExW(user_profile, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &network, NULL) == ERROR_SUCCESS)\r
++ {\r
++ DWORD dword_arg = RESOURCETYPE_DISK;\r
++ DWORD len = (strlenW(provider->name) + 1) * sizeof(WCHAR);\r
++\r
++ RegSetValueExW(network, L"ConnectionType", 0, REG_DWORD, (const BYTE *)&dword_arg, sizeof(DWORD));\r
++ RegSetValueExW(network, L"ProviderName", 0, REG_SZ, (const BYTE *)provider->name, len);\r
++ dword_arg = provider->dwNetType;\r
++ RegSetValueExW(network, L"ProviderType", 0, REG_DWORD, (const BYTE *)&dword_arg, sizeof(DWORD));\r
++ len = (strlenW(netres.lpRemoteName) + 1) * sizeof(WCHAR);\r
++ RegSetValueExW(network, L"RemotePath", 0, REG_SZ, (const BYTE *)netres.lpRemoteName, len);\r
++ len = 0;\r
++ RegSetValueExW(network, L"UserName", 0, REG_SZ, (const BYTE *)netres.lpRemoteName, len);\r
++ RegCloseKey(network);\r
++ }\r
++\r
++ RegCloseKey(user_profile);\r
++ }\r
++ }\r
++#endif\r
++\r
+ return ret;\r
+ }\r
+ \r
+@@ -2061,6 +2231,37 @@\r
+ }\r
+ }\r
+ }\r
++#ifdef __REACTOS__\r
++\r
++ if (dwFlags & CONNECT_UPDATE_PROFILE)\r
++ {\r
++ HKEY user_profile;\r
++ WCHAR *coma = strchrW(lpName, ':');\r
++\r
++ if (coma && RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS)\r
++ {\r
++ WCHAR *subkey;\r
++ DWORD len;\r
++\r
++ len = (ULONG_PTR)coma - (ULONG_PTR)lpName + sizeof(L"Network\\");\r
++ subkey = HeapAlloc(GetProcessHeap(), 0, len);\r
++ if (subkey)\r
++ {\r
++ strcpyW(subkey, L"Network\\");\r
++ memcpy(subkey + (sizeof(L"Network\\") / sizeof(WCHAR)) - 1, lpName, (ULONG_PTR)coma - (ULONG_PTR)lpName);\r
++ subkey[len / sizeof(WCHAR) - 1] = 0;\r
++\r
++ TRACE("Removing: %S\n", subkey);\r
++\r
++ RegDeleteKeyW(user_profile, subkey);\r
++ HeapFree(GetProcessHeap(), 0, subkey);\r
++ }\r
++\r
++ RegCloseKey(user_profile);\r
++ }\r
++ }\r
++\r
++#endif\r
+ return ret;\r
+ }\r
+ \r
+@@ -2188,6 +2389,7 @@\r
+ /* find the network connection for a given drive; helper for WNetGetConnection */\r
+ static DWORD get_drive_connection( WCHAR letter, LPWSTR remote, LPDWORD size )\r
+ {\r
++#ifndef __REACTOS__\r
+ char buffer[1024];\r
+ struct mountmgr_unix_drive *data = (struct mountmgr_unix_drive *)buffer;\r
+ HANDLE mgr;\r
+@@ -2230,6 +2432,32 @@\r
+ }\r
+ CloseHandle( mgr );\r
+ return ret;\r
++#else\r
++ DWORD ret = WN_NO_NETWORK;\r
++ DWORD index;\r
++ WCHAR local[3] = {letter, ':', 0};\r
++\r
++ if (providerTable != NULL)\r
++ {\r
++ for (index = 0; index < providerTable->numProviders; index++)\r
++ {\r
++ if(providerTable->table[index].getCaps(WNNC_CONNECTION) &\r
++ WNNC_CON_GETCONNECTIONS)\r
++ {\r
++ if (providerTable->table[index].getConnection)\r
++ ret = providerTable->table[index].getConnection(\r
++ local, remote, size);\r
++ else\r
++ ret = WN_NO_NETWORK;\r
++ if (ret == WN_SUCCESS || ret == WN_MORE_DATA)\r
++ break;\r
++ }\r
++ }\r
++ }\r
++ if (ret)\r
++ SetLastError(ret);\r
++ return ret;\r
++#endif\r
+ }\r
+ \r
+ /**************************************************************************\r