Author: pschweitzer
Date: Mon Oct 31 21:27:02 2016
New Revision: 73093
URL:
http://svn.reactos.org/svn/reactos?rev=73093&view=rev
Log:
[MPR]
Implement saved connections restoration.
This is a bit hackish for now: it should only be attempted once, when the DLL is loaded on
session login. Right now, it's attempt each time the DLL is loaded (ie, even when a
program linking to it is started). This is to be fixed later on. So far, it brings the
intended feature.
Now, you can create a connection with net use, save it, and reboot: it will be restored on
the session opening.
CORE-11757
Modified:
trunk/reactos/dll/win32/mpr/mpr_ros.diff
trunk/reactos/dll/win32/mpr/wnet.c
Modified: trunk/reactos/dll/win32/mpr/mpr_ros.diff
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mpr/mpr_ros.diff…
==============================================================================
--- trunk/reactos/dll/win32/mpr/mpr_ros.diff [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mpr/mpr_ros.diff [iso-8859-1] Mon Oct 31 21:27:02 2016
@@ -69,7 +69,158 @@
TRACE("NPAddConnection %p\n",
provider->addConnection);
TRACE("NPAddConnection3 %p\n",
provider->addConnection3);
TRACE("NPCancelConnection %p\n",
provider->cancelConnection);
-@@ -1870,6 +1866,43 @@
+@@ -251,6 +247,85 @@
+ debugstr_w(provider));
+ }
+
++#ifdef __REACTOS__
++static void _restoreSavedConnection(HKEY connection, WCHAR * local)
++{
++ NETRESOURCEW net;
++ DWORD type, prov, index, size;
++
++ net.lpProvider = NULL;
++ net.lpRemoteName = NULL;
++ net.lpLocalName = NULL;
++
++ TRACE("Restoring: %S\n", local);
++
++ size = sizeof(DWORD);
++ if (RegQueryValueExW(connection, L"ConnectionType", NULL, &type, (BYTE
*)&net.dwType, &size) != ERROR_SUCCESS)
++ return;
++
++ if (type != REG_DWORD || size != sizeof(DWORD))
++ return;
++
++ if (RegQueryValueExW(connection, L"ProviderName", NULL, &type, NULL,
&size) != ERROR_SUCCESS)
++ return;
++
++ if (type != REG_SZ)
++ return;
++
++ net.lpProvider = HeapAlloc(GetProcessHeap(), 0, size);
++ if (!net.lpProvider)
++ return;
++
++ if (RegQueryValueExW(connection, L"ProviderName", NULL, NULL, (BYTE
*)net.lpProvider, &size) != ERROR_SUCCESS)
++ goto cleanup;
++
++ size = sizeof(DWORD);
++ if (RegQueryValueExW(connection, L"ProviderType", NULL, &type, (BYTE
*)&prov, &size) != ERROR_SUCCESS)
++ goto cleanup;
++
++ if (type != REG_DWORD || size != sizeof(DWORD))
++ goto cleanup;
++
++ index = _findProviderIndexW(net.lpProvider);
++ if (index == BAD_PROVIDER_INDEX)
++ goto cleanup;
++
++ if (providerTable->table[index].dwNetType != prov)
++ goto cleanup;
++
++ if (RegQueryValueExW(connection, L"RemotePath", NULL, &type, NULL,
&size) != ERROR_SUCCESS)
++ goto cleanup;
++
++ if (type != REG_SZ)
++ goto cleanup;
++
++ net.lpRemoteName = HeapAlloc(GetProcessHeap(), 0, size);
++ if (!net.lpRemoteName)
++ goto cleanup;
++
++ if (RegQueryValueExW(connection, L"RemotePath", NULL, NULL, (BYTE
*)net.lpRemoteName, &size) != ERROR_SUCCESS)
++ goto cleanup;
++
++ size = strlenW(local);
++ net.lpLocalName = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR) + 2 *
sizeof(WCHAR));
++ if (!net.lpLocalName)
++ goto cleanup;
++
++ strcpyW(net.lpLocalName, local);
++ net.lpLocalName[size] = ':';
++ net.lpLocalName[size + 1] = 0;
++
++ TRACE("Attempting connection\n");
++
++ WNetAddConnection2W(&net, NULL, NULL, 0);
++
++cleanup:
++ HeapFree(GetProcessHeap(), 0, net.lpProvider);
++ HeapFree(GetProcessHeap(), 0, net.lpRemoteName);
++ HeapFree(GetProcessHeap(), 0, net.lpLocalName);
++}
++#endif
++
+ void wnetInit(HINSTANCE hInstDll)
+ {
+ static const WCHAR providerOrderKey[] = {
'S','y','s','t','e','m','\\',
+@@ -329,6 +404,64 @@
+ }
+ RegCloseKey(hKey);
+ }
++
++#ifdef __REACTOS__
++ if (providerTable)
++ {
++ HKEY user_profile;
++
++ if (RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS)
++ {
++ HKEY network;
++ WCHAR subkey[8] = {'N', 'e', 't', 'w',
'o', 'r', 'k', 0};
++
++ if (RegOpenKeyExW(user_profile, subkey, 0, KEY_READ, &network) ==
ERROR_SUCCESS)
++ {
++ DWORD size, max;
++
++ TRACE("Enumerating remembered connections\n");
++
++ if (RegQueryInfoKey(network, NULL, NULL, NULL, &max, &size,
NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
++ {
++ WCHAR *local;
++
++ TRACE("There are %lu connections\n", max);
++
++ local = HeapAlloc(GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR));
++ if (local)
++ {
++ DWORD index;
++
++ for (index = 0; index < max; ++index)
++ {
++ DWORD len = size + 1;
++ HKEY connection;
++
++ TRACE("Trying connection %lu\n", index);
++
++ if (RegEnumKeyExW(network, index, local, &len, NULL,
NULL, NULL, NULL) != ERROR_SUCCESS)
++ continue;
++
++ TRACE("It is %S\n", local);
++
++ if (RegOpenKeyExW(network, local, 0, KEY_READ,
&connection) != ERROR_SUCCESS)
++ continue;
++
++ _restoreSavedConnection(connection, local);
++ RegCloseKey(connection);
++ }
++
++ HeapFree(GetProcessHeap(), 0, local);
++ }
++ }
++
++ RegCloseKey(network);
++ }
++
++ RegCloseKey(user_profile);
++ }
++ }
++#endif
+ }
+
+ void wnetFree(void)
+@@ -1870,6 +2003,43 @@
}
}
@@ -113,7 +264,7 @@
return ret;
}
-@@ -2061,6 +2094,37 @@
+@@ -2061,6 +2231,37 @@
}
}
}
@@ -151,7 +302,7 @@
return ret;
}
-@@ -2188,6 +2252,7 @@
+@@ -2188,6 +2389,7 @@
/* find the network connection for a given drive; helper for WNetGetConnection */
static DWORD get_drive_connection( WCHAR letter, LPWSTR remote, LPDWORD size )
{
@@ -159,7 +310,7 @@
char buffer[1024];
struct mountmgr_unix_drive *data = (struct mountmgr_unix_drive *)buffer;
HANDLE mgr;
-@@ -2230,6 +2295,32 @@
+@@ -2230,6 +2432,32 @@
}
CloseHandle( mgr );
return ret;
Modified: trunk/reactos/dll/win32/mpr/wnet.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mpr/wnet.c?rev=7…
==============================================================================
--- trunk/reactos/dll/win32/mpr/wnet.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mpr/wnet.c [iso-8859-1] Mon Oct 31 21:27:02 2016
@@ -247,6 +247,85 @@
debugstr_w(provider));
}
+#ifdef __REACTOS__
+static void _restoreSavedConnection(HKEY connection, WCHAR * local)
+{
+ NETRESOURCEW net;
+ DWORD type, prov, index, size;
+
+ net.lpProvider = NULL;
+ net.lpRemoteName = NULL;
+ net.lpLocalName = NULL;
+
+ TRACE("Restoring: %S\n", local);
+
+ size = sizeof(DWORD);
+ if (RegQueryValueExW(connection, L"ConnectionType", NULL, &type, (BYTE
*)&net.dwType, &size) != ERROR_SUCCESS)
+ return;
+
+ if (type != REG_DWORD || size != sizeof(DWORD))
+ return;
+
+ if (RegQueryValueExW(connection, L"ProviderName", NULL, &type, NULL,
&size) != ERROR_SUCCESS)
+ return;
+
+ if (type != REG_SZ)
+ return;
+
+ net.lpProvider = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!net.lpProvider)
+ return;
+
+ if (RegQueryValueExW(connection, L"ProviderName", NULL, NULL, (BYTE
*)net.lpProvider, &size) != ERROR_SUCCESS)
+ goto cleanup;
+
+ size = sizeof(DWORD);
+ if (RegQueryValueExW(connection, L"ProviderType", NULL, &type, (BYTE
*)&prov, &size) != ERROR_SUCCESS)
+ goto cleanup;
+
+ if (type != REG_DWORD || size != sizeof(DWORD))
+ goto cleanup;
+
+ index = _findProviderIndexW(net.lpProvider);
+ if (index == BAD_PROVIDER_INDEX)
+ goto cleanup;
+
+ if (providerTable->table[index].dwNetType != prov)
+ goto cleanup;
+
+ if (RegQueryValueExW(connection, L"RemotePath", NULL, &type, NULL,
&size) != ERROR_SUCCESS)
+ goto cleanup;
+
+ if (type != REG_SZ)
+ goto cleanup;
+
+ net.lpRemoteName = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!net.lpRemoteName)
+ goto cleanup;
+
+ if (RegQueryValueExW(connection, L"RemotePath", NULL, NULL, (BYTE
*)net.lpRemoteName, &size) != ERROR_SUCCESS)
+ goto cleanup;
+
+ size = strlenW(local);
+ net.lpLocalName = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR) + 2 *
sizeof(WCHAR));
+ if (!net.lpLocalName)
+ goto cleanup;
+
+ strcpyW(net.lpLocalName, local);
+ net.lpLocalName[size] = ':';
+ net.lpLocalName[size + 1] = 0;
+
+ TRACE("Attempting connection\n");
+
+ WNetAddConnection2W(&net, NULL, NULL, 0);
+
+cleanup:
+ HeapFree(GetProcessHeap(), 0, net.lpProvider);
+ HeapFree(GetProcessHeap(), 0, net.lpRemoteName);
+ HeapFree(GetProcessHeap(), 0, net.lpLocalName);
+}
+#endif
+
void wnetInit(HINSTANCE hInstDll)
{
static const WCHAR providerOrderKey[] = {
'S','y','s','t','e','m','\\',
@@ -325,6 +404,64 @@
}
RegCloseKey(hKey);
}
+
+#ifdef __REACTOS__
+ if (providerTable)
+ {
+ HKEY user_profile;
+
+ if (RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS)
+ {
+ HKEY network;
+ WCHAR subkey[8] = {'N', 'e', 't', 'w',
'o', 'r', 'k', 0};
+
+ if (RegOpenKeyExW(user_profile, subkey, 0, KEY_READ, &network) ==
ERROR_SUCCESS)
+ {
+ DWORD size, max;
+
+ TRACE("Enumerating remembered connections\n");
+
+ if (RegQueryInfoKey(network, NULL, NULL, NULL, &max, &size, NULL,
NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ WCHAR *local;
+
+ TRACE("There are %lu connections\n", max);
+
+ local = HeapAlloc(GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR));
+ if (local)
+ {
+ DWORD index;
+
+ for (index = 0; index < max; ++index)
+ {
+ DWORD len = size + 1;
+ HKEY connection;
+
+ TRACE("Trying connection %lu\n", index);
+
+ if (RegEnumKeyExW(network, index, local, &len, NULL,
NULL, NULL, NULL) != ERROR_SUCCESS)
+ continue;
+
+ TRACE("It is %S\n", local);
+
+ if (RegOpenKeyExW(network, local, 0, KEY_READ,
&connection) != ERROR_SUCCESS)
+ continue;
+
+ _restoreSavedConnection(connection, local);
+ RegCloseKey(connection);
+ }
+
+ HeapFree(GetProcessHeap(), 0, local);
+ }
+ }
+
+ RegCloseKey(network);
+ }
+
+ RegCloseKey(user_profile);
+ }
+ }
+#endif
}
void wnetFree(void)