1Index: mpr.spec 2=================================================================== 3--- mpr.spec (revision 49877) 4+++ mpr.spec (working copy) 5@@ -1,23 +1,23 @@ 6 # ordinal exports 7- 1 stub @ 8- 2 stub @ 9- 3 stub @ 10- 4 stub @ 11- 5 stub @ 12- 6 stub @ 13- 7 stub @ 14- 8 stub @ 15- 9 stub @ 16-12 stub @ 17-13 stub @ 18-14 stub @ 19-15 stub @ 20-16 stub @ 21-17 stub @ 22-18 stub @ 23-19 stub @ 24-20 stub @ 25-21 stub @ 26+ 1 stub MPR_1 27+ 2 stub MPR_2 28+ 3 stub MPR_3 29+ 4 stub MPR_4 30+ 5 stub MPR_5 31+ 6 stub MPR_6 32+ 7 stub MPR_7 33+ 8 stub MPR_8 34+ 9 stub MPR_9 35+12 stub MPR_12 36+13 stub MPR_13 37+14 stub MPR_14 38+15 stub MPR_15 39+16 stub MPR_16 40+17 stub MPR_17 41+18 stub MPR_18 42+19 stub MPR_19 43+20 stub MPR_20 44+21 stub MPR_21 45 22 stdcall @(long) MPR_Alloc 46 23 stdcall @(ptr long) MPR_ReAlloc 47 24 stdcall @(ptr) MPR_Free 48Index: wnet.c 49=================================================================== 50--- wnet.c (revision 71983) 51+++ wnet.c (working copy) 52@@ -60,6 +50,9 @@ 53 PF_NPAddConnection addConnection; 54 PF_NPAddConnection3 addConnection3; 55 PF_NPCancelConnection cancelConnection; 56+#ifdef __REACTOS__ 57+ PF_NPGetConnection getConnection; 58+#endif 59 } WNetProvider, *PWNetProvider; 60 61 typedef struct _WNetProviderTable 62@@ -219,6 +212,10 @@ 63 provider->addConnection3 = MPR_GETPROC(NPAddConnection3); 64 if (connectCap & WNNC_CON_CANCELCONNECTION) 65 provider->cancelConnection = MPR_GETPROC(NPCancelConnection); 66+#ifdef __REACTOS__ 67+ if (connectCap & WNNC_CON_GETCONNECTIONS) 68+ provider->getConnection = MPR_GETPROC(NPGetConnection); 69+#endif 70 TRACE("NPAddConnection %p\n", provider->addConnection); 71 TRACE("NPAddConnection3 %p\n", provider->addConnection3); 72 TRACE("NPCancelConnection %p\n", provider->cancelConnection); 73@@ -256,6 +253,85 @@ 74 debugstr_w(provider)); 75 } 76 77+#ifdef __REACTOS__ 78+static void _restoreSavedConnection(HKEY connection, WCHAR * local) 79+{ 80+ NETRESOURCEW net; 81+ DWORD type, prov, index, size; 82+ 83+ net.lpProvider = NULL; 84+ net.lpRemoteName = NULL; 85+ net.lpLocalName = NULL; 86+ 87+ TRACE("Restoring: %S\n", local); 88+ 89+ size = sizeof(DWORD); 90+ if (RegQueryValueExW(connection, L"ConnectionType", NULL, &type, (BYTE *)&net.dwType, &size) != ERROR_SUCCESS) 91+ return; 92+ 93+ if (type != REG_DWORD || size != sizeof(DWORD)) 94+ return; 95+ 96+ if (RegQueryValueExW(connection, L"ProviderName", NULL, &type, NULL, &size) != ERROR_SUCCESS) 97+ return; 98+ 99+ if (type != REG_SZ) 100+ return; 101+ 102+ net.lpProvider = HeapAlloc(GetProcessHeap(), 0, size); 103+ if (!net.lpProvider) 104+ return; 105+ 106+ if (RegQueryValueExW(connection, L"ProviderName", NULL, NULL, (BYTE *)net.lpProvider, &size) != ERROR_SUCCESS) 107+ goto cleanup; 108+ 109+ size = sizeof(DWORD); 110+ if (RegQueryValueExW(connection, L"ProviderType", NULL, &type, (BYTE *)&prov, &size) != ERROR_SUCCESS) 111+ goto cleanup; 112+ 113+ if (type != REG_DWORD || size != sizeof(DWORD)) 114+ goto cleanup; 115+ 116+ index = _findProviderIndexW(net.lpProvider); 117+ if (index == BAD_PROVIDER_INDEX) 118+ goto cleanup; 119+ 120+ if (providerTable->table[index].dwNetType != prov) 121+ goto cleanup; 122+ 123+ if (RegQueryValueExW(connection, L"RemotePath", NULL, &type, NULL, &size) != ERROR_SUCCESS) 124+ goto cleanup; 125+ 126+ if (type != REG_SZ) 127+ goto cleanup; 128+ 129+ net.lpRemoteName = HeapAlloc(GetProcessHeap(), 0, size); 130+ if (!net.lpRemoteName) 131+ goto cleanup; 132+ 133+ if (RegQueryValueExW(connection, L"RemotePath", NULL, NULL, (BYTE *)net.lpRemoteName, &size) != ERROR_SUCCESS) 134+ goto cleanup; 135+ 136+ size = strlenW(local); 137+ net.lpLocalName = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR) + 2 * sizeof(WCHAR)); 138+ if (!net.lpLocalName) 139+ goto cleanup; 140+ 141+ strcpyW(net.lpLocalName, local); 142+ net.lpLocalName[size] = ':'; 143+ net.lpLocalName[size + 1] = 0; 144+ 145+ TRACE("Attempting connection\n"); 146+ 147+ WNetAddConnection2W(&net, NULL, NULL, 0); 148+ 149+cleanup: 150+ HeapFree(GetProcessHeap(), 0, net.lpProvider); 151+ HeapFree(GetProcessHeap(), 0, net.lpRemoteName); 152+ HeapFree(GetProcessHeap(), 0, net.lpLocalName); 153+} 154+#endif 155+ 156 void wnetInit(HINSTANCE hInstDll) 157 { 158 static const WCHAR providerOrderKey[] = { 'S','y','s','t','e','m','\\', 159@@ -334,6 +410,64 @@ 160 } 161 RegCloseKey(hKey); 162 } 163+ 164+#ifdef __REACTOS__ 165+ if (providerTable) 166+ { 167+ HKEY user_profile; 168+ 169+ if (RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS) 170+ { 171+ HKEY network; 172+ WCHAR subkey[8] = {'N', 'e', 't', 'w', 'o', 'r', 'k', 0}; 173+ 174+ if (RegOpenKeyExW(user_profile, subkey, 0, KEY_READ, &network) == ERROR_SUCCESS) 175+ { 176+ DWORD size, max; 177+ 178+ TRACE("Enumerating remembered connections\n"); 179+ 180+ if (RegQueryInfoKey(network, NULL, NULL, NULL, &max, &size, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) 181+ { 182+ WCHAR *local; 183+ 184+ TRACE("There are %lu connections\n", max); 185+ 186+ local = HeapAlloc(GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR)); 187+ if (local) 188+ { 189+ DWORD index; 190+ 191+ for (index = 0; index < max; ++index) 192+ { 193+ DWORD len = size + 1; 194+ HKEY connection; 195+ 196+ TRACE("Trying connection %lu\n", index); 197+ 198+ if (RegEnumKeyExW(network, index, local, &len, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) 199+ continue; 200+ 201+ TRACE("It is %S\n", local); 202+ 203+ if (RegOpenKeyExW(network, local, 0, KEY_READ, &connection) != ERROR_SUCCESS) 204+ continue; 205+ 206+ _restoreSavedConnection(connection, local); 207+ RegCloseKey(connection); 208+ } 209+ 210+ HeapFree(GetProcessHeap(), 0, local); 211+ } 212+ } 213+ 214+ RegCloseKey(network); 215+ } 216+ 217+ RegCloseKey(user_profile); 218+ } 219+ } 220+#endif 221 } 222 223 void wnetFree(void) 224@@ -1875,6 +2009,43 @@ 225 } 226 } 227 228+#ifdef __REACTOS__ 229+ if (ret == WN_SUCCESS && ctxt->flags & CONNECT_UPDATE_PROFILE) 230+ { 231+ HKEY user_profile; 232+ 233+ if (netres.dwType == RESOURCETYPE_PRINT) 234+ { 235+ FIXME("Persistent connection are not supported for printers\n"); 236+ return ret; 237+ } 238+ 239+ if (RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS) 240+ { 241+ HKEY network; 242+ WCHAR subkey[10] = {'N', 'e', 't', 'w', 'o', 'r', 'k', '\\', netres.lpLocalName[0], 0}; 243+ 244+ if (RegCreateKeyExW(user_profile, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &network, NULL) == ERROR_SUCCESS) 245+ { 246+ DWORD dword_arg = RESOURCETYPE_DISK; 247+ DWORD len = (strlenW(provider->name) + 1) * sizeof(WCHAR); 248+ 249+ RegSetValueExW(network, L"ConnectionType", 0, REG_DWORD, (const BYTE *)&dword_arg, sizeof(DWORD)); 250+ RegSetValueExW(network, L"ProviderName", 0, REG_SZ, (const BYTE *)provider->name, len); 251+ dword_arg = provider->dwNetType; 252+ RegSetValueExW(network, L"ProviderType", 0, REG_DWORD, (const BYTE *)&dword_arg, sizeof(DWORD)); 253+ len = (strlenW(netres.lpRemoteName) + 1) * sizeof(WCHAR); 254+ RegSetValueExW(network, L"RemotePath", 0, REG_SZ, (const BYTE *)netres.lpRemoteName, len); 255+ len = 0; 256+ RegSetValueExW(network, L"UserName", 0, REG_SZ, (const BYTE *)netres.lpRemoteName, len); 257+ RegCloseKey(network); 258+ } 259+ 260+ RegCloseKey(user_profile); 261+ } 262+ } 263+#endif 264+ 265 return ret; 266 } 267 268@@ -2066,6 +2237,37 @@ 269 } 270 } 271 } 272+#ifdef __REACTOS__ 273+ 274+ if (dwFlags & CONNECT_UPDATE_PROFILE) 275+ { 276+ HKEY user_profile; 277+ WCHAR *coma = strchrW(lpName, ':'); 278+ 279+ if (coma && RegOpenCurrentUser(KEY_ALL_ACCESS, &user_profile) == ERROR_SUCCESS) 280+ { 281+ WCHAR *subkey; 282+ DWORD len; 283+ 284+ len = (ULONG_PTR)coma - (ULONG_PTR)lpName + sizeof(L"Network\\"); 285+ subkey = HeapAlloc(GetProcessHeap(), 0, len); 286+ if (subkey) 287+ { 288+ strcpyW(subkey, L"Network\\"); 289+ memcpy(subkey + (sizeof(L"Network\\") / sizeof(WCHAR)) - 1, lpName, (ULONG_PTR)coma - (ULONG_PTR)lpName); 290+ subkey[len / sizeof(WCHAR) - 1] = 0; 291+ 292+ TRACE("Removing: %S\n", subkey); 293+ 294+ RegDeleteKeyW(user_profile, subkey); 295+ HeapFree(GetProcessHeap(), 0, subkey); 296+ } 297+ 298+ RegCloseKey(user_profile); 299+ } 300+ } 301+ 302+#endif 303 return ret; 304 } 305 306@@ -2193,6 +2395,7 @@ 307 /* find the network connection for a given drive; helper for WNetGetConnection */ 308 static DWORD get_drive_connection( WCHAR letter, LPWSTR remote, LPDWORD size ) 309 { 310+#ifndef __REACTOS__ 311 char buffer[1024]; 312 struct mountmgr_unix_drive *data = (struct mountmgr_unix_drive *)buffer; 313 HANDLE mgr; 314@@ -2235,6 +2438,32 @@ 315 } 316 CloseHandle( mgr ); 317 return ret; 318+#else 319+ DWORD ret = WN_NO_NETWORK; 320+ DWORD index; 321+ WCHAR local[3] = {letter, ':', 0}; 322+ 323+ if (providerTable != NULL) 324+ { 325+ for (index = 0; index < providerTable->numProviders; index++) 326+ { 327+ if(providerTable->table[index].getCaps(WNNC_CONNECTION) & 328+ WNNC_CON_GETCONNECTIONS) 329+ { 330+ if (providerTable->table[index].getConnection) 331+ ret = providerTable->table[index].getConnection( 332+ local, remote, size); 333+ else 334+ ret = WN_NO_NETWORK; 335+ if (ret == WN_SUCCESS || ret == WN_MORE_DATA) 336+ break; 337+ } 338+ } 339+ } 340+ if (ret) 341+ SetLastError(ret); 342+ return ret; 343+#endif 344 } 345 346 /************************************************************************** 347