[MPR]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 15 Feb 2016 20:15:54 +0000 (20:15 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 15 Feb 2016 20:15:54 +0000 (20:15 +0000)
Import Wine commit (by Nikolay Sivov):
164fe0470ccf7cb3c0946cbb52d4139aec0c4a03, Query for NPAddConnection and NPAddConnection3 when loading a provider.

CORE-10032

svn path=/trunk/; revision=70754

reactos/dll/win32/mpr/mpr_ros.diff
reactos/dll/win32/mpr/wnet.c

index 95b5ca4..4d82fe0 100644 (file)
@@ -3,237 +3,237 @@ Index: mpr.spec
 --- 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
-Index: wnet.c
-===================================================================
---- wnet.c     (rĂ©vision 70645)
-+++ wnet.c     (copie de travail)
-@@ -1549,6 +1549,33 @@
-                               dwFlags, NULL, 0, NULL);
- }
-+/* Convert an ANSI string to wide */
-+static LPWSTR strdupAtoW( LPCSTR str )
-+{
-+    LPWSTR ret;
-+    INT len;
-+
-+    if (!str) return NULL;
-+    len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
-+    ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
-+    if (ret) MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
-+    return ret;
-+}
-+
-+/* Convert ANSI NETRESOURCE struct to wide structure */
-+static VOID convert_netresourcea_to_w( LPNETRESOURCEA lpNetResourceA,
-+                                       LPNETRESOURCEW lpNetResourceW )
-+{
-+    lpNetResourceW->dwScope = lpNetResourceA->dwScope;
-+    lpNetResourceW->dwType = lpNetResourceA->dwType;
-+    lpNetResourceW->dwDisplayType = lpNetResourceA->dwDisplayType;
-+    lpNetResourceW->dwUsage = lpNetResourceA->dwUsage;
-+    lpNetResourceW->lpLocalName = strdupAtoW(lpNetResourceA->lpLocalName);
-+    lpNetResourceW->lpRemoteName = strdupAtoW(lpNetResourceA->lpRemoteName);
-+    lpNetResourceW->lpComment = strdupAtoW(lpNetResourceA->lpComment);
-+    lpNetResourceW->lpProvider = strdupAtoW(lpNetResourceA->lpProvider);
-+}
-+
- /*****************************************************************
-  *  WNetUseConnectionA [MPR.@]
-  */
-@@ -1557,12 +1584,67 @@
-                                  LPSTR lpAccessName, LPDWORD lpBufferSize,
-                                  LPDWORD lpResult )
- {
--    FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",
--           hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags,
--           debugstr_a(lpAccessName), lpBufferSize, lpResult );
-+    NETRESOURCEW resourcesW, *pRes = NULL;
-+    PWSTR passW, userIDW, accessNameW = NULL;
-+    DWORD ret = WN_MORE_DATA;
-+    DWORD bufferSize = 1;
-+    int len;
--    SetLastError(WN_NO_NETWORK);
--    return WN_NO_NETWORK;
-+    if (lpNetResource)
-+    {
-+        convert_netresourcea_to_w(lpNetResource, &resourcesW);
-+        pRes = &resourcesW;
-+    }
-+
-+    passW = strdupAtoW(lpPassword);
-+    userIDW = strdupAtoW(lpUserID);
-+
-+    if (lpAccessName && lpBufferSize && *lpBufferSize)
-+    {
-+        WCHAR probe;
-+
-+        ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
-+                                 &probe, &bufferSize, lpResult);
-+        if (ret == WN_MORE_DATA)
-+            accessNameW = HeapAlloc(GetProcessHeap(), 0, bufferSize * sizeof(WCHAR));
-+    }
-+
-+    if (ret == WN_MORE_DATA)
-+    {
-+        ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
-+                                 accessNameW, &bufferSize, lpResult);
-+        if (ret == WN_SUCCESS)
-+        {
-+            if (lpAccessName && lpBufferSize && *lpBufferSize && accessNameW)
-+            {
-+                len = WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, NULL, 0, NULL, NULL);
-+                if (len)
-+                {
-+                    if (len <= *lpBufferSize)
-+                        WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, lpAccessName, len, NULL, NULL);
-+                    else
-+                    {
-+                        WNetCancelConnectionW(accessNameW, TRUE);
-+                        *lpBufferSize = len;
-+                       ret = WN_MORE_DATA;
-+                    }
-+                }
-+            }
-+        }
-+    }
-+
-+    if (lpNetResource)
-+    {
-+        HeapFree(GetProcessHeap(), 0, resourcesW.lpLocalName);
-+        HeapFree(GetProcessHeap(), 0, resourcesW.lpRemoteName);
-+        HeapFree(GetProcessHeap(), 0, resourcesW.lpComment);
-+        HeapFree(GetProcessHeap(), 0, resourcesW.lpProvider);
-+    }
-+    HeapFree(GetProcessHeap(), 0, passW);
-+    HeapFree(GetProcessHeap(), 0, userIDW);
-+    HeapFree(GetProcessHeap(), 0, accessNameW);
-+
-+    return ret;
- }
- /*****************************************************************
-@@ -1573,12 +1655,75 @@
-                                  LPWSTR lpAccessName, LPDWORD lpBufferSize,
-                                  LPDWORD lpResult )
- {
--    FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",
--           hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags,
--           debugstr_w(lpAccessName), lpBufferSize, lpResult );
-+    DWORD provider;
-+    DWORD cap;
-+    char id;
-+    DWORD drives;
-+    DWORD ret;
-+    PF_NPAddConnection3 addConn3;
-+    PF_NPAddConnection addConn;
--    SetLastError(WN_NO_NETWORK);
--    return WN_NO_NETWORK;
-+    if (!providerTable || providerTable->numProviders == 0) {
-+        SetLastError(WN_NO_NETWORK);
-+        return WN_NO_NETWORK;
-+    }
-+
-+    if (!lpNetResource) {
-+        SetLastError(ERROR_INVALID_PARAMETER);
-+        return ERROR_INVALID_PARAMETER;
-+    }
-+
-+    if (!lpNetResource->lpProvider || !*lpNetResource->lpProvider) {
-+        SetLastError(ERROR_BAD_PROVIDER);
-+        return ERROR_BAD_PROVIDER;
-+    }
-+
-+    if (!lpNetResource->lpLocalName || !*lpNetResource->lpLocalName) {
-+        SetLastError(ERROR_BAD_DEVICE);
-+        return ERROR_BAD_DEVICE;
-+    }
-+
-+    if ((!(lpNetResource->lpLocalName[0] >= 'a' && lpNetResource->lpLocalName[0] <= 'z') &&
-+        !(lpNetResource->lpLocalName[0] >= 'A' && lpNetResource->lpLocalName[0] <= 'Z')) ||
-+        lpNetResource->lpLocalName[1] != ':' || lpNetResource->lpLocalName[2]) {
-+        SetLastError(ERROR_BAD_DEVICE);
-+        return ERROR_BAD_DEVICE;
-+    }
-+
-+    id = (lpNetResource->lpLocalName[0] >= 'a') ? lpNetResource->lpLocalName[0] - 'a' : lpNetResource->lpLocalName[0] - 'A';
-+    drives = GetLogicalDrives();
-+    if (drives & (1 << id)) {
-+        SetLastError(ERROR_ALREADY_ASSIGNED);
-+        return ERROR_ALREADY_ASSIGNED;
-+    }
-+
-+    provider = _findProviderIndexW(lpNetResource->lpProvider);
-+    if (provider == BAD_PROVIDER_INDEX) {
-+        SetLastError(ERROR_BAD_PROVIDER);
-+        return ERROR_BAD_PROVIDER;
-+    }
-+
-+    cap = providerTable->table[provider].getCaps(WNNC_CONNECTION);
-+    if (!(cap & WNNC_CON_ADDCONNECTION) && !(cap & WNNC_CON_ADDCONNECTION3)) {
-+        SetLastError(ERROR_BAD_PROVIDER);
-+        return ERROR_BAD_PROVIDER;
-+    }
-+
-+    ret = WN_ACCESS_DENIED;
-+    if (cap & WNNC_CON_ADDCONNECTION3) {
-+        addConn3 = (PF_NPAddConnection3)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection3");
-+        if (addConn3) {
-+            ret = addConn3(hwndOwner, lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID, dwFlags);
-+        }
-+    }
-+    else if (cap & WNNC_CON_ADDCONNECTION) {
-+        addConn = (PF_NPAddConnection)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection");
-+        if (addConn) {
-+            ret = addConn(lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID);
-+        }
-+    }
-+
-+    return ret;
- }
- /*********************************************************************
+ # 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     (rĂ©vision 70645)\r
++++ wnet.c     (copie de travail)\r
+@@ -1553,6 +1553,33 @@\r
+                               dwFlags, NULL, 0, NULL);\r
+ }\r
\r
++/* Convert an ANSI string to wide */\r
++static LPWSTR strdupAtoW( LPCSTR str )\r
++{\r
++    LPWSTR ret;\r
++    INT len;\r
++\r
++    if (!str) return NULL;\r
++    len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );\r
++    ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );\r
++    if (ret) MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );\r
++    return ret;\r
++}\r
++\r
++/* Convert ANSI NETRESOURCE struct to wide structure */\r
++static VOID convert_netresourcea_to_w( LPNETRESOURCEA lpNetResourceA,\r
++                                       LPNETRESOURCEW lpNetResourceW )\r
++{\r
++    lpNetResourceW->dwScope = lpNetResourceA->dwScope;\r
++    lpNetResourceW->dwType = lpNetResourceA->dwType;\r
++    lpNetResourceW->dwDisplayType = lpNetResourceA->dwDisplayType;\r
++    lpNetResourceW->dwUsage = lpNetResourceA->dwUsage;\r
++    lpNetResourceW->lpLocalName = strdupAtoW(lpNetResourceA->lpLocalName);\r
++    lpNetResourceW->lpRemoteName = strdupAtoW(lpNetResourceA->lpRemoteName);\r
++    lpNetResourceW->lpComment = strdupAtoW(lpNetResourceA->lpComment);\r
++    lpNetResourceW->lpProvider = strdupAtoW(lpNetResourceA->lpProvider);\r
++}\r
++\r
+ /*****************************************************************\r
+  *  WNetUseConnectionA [MPR.@]\r
+  */\r
+@@ -1561,12 +1588,67 @@\r
+                                  LPSTR lpAccessName, LPDWORD lpBufferSize,\r
+                                  LPDWORD lpResult )\r
+ {\r
+-    FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",\r
+-           hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags,\r
+-           debugstr_a(lpAccessName), lpBufferSize, lpResult );\r
++    NETRESOURCEW resourcesW, *pRes = NULL;\r
++    PWSTR passW, userIDW, accessNameW = NULL;\r
++    DWORD ret = WN_MORE_DATA;\r
++    DWORD bufferSize = 1;\r
++    int len;\r
\r
+-    SetLastError(WN_NO_NETWORK);\r
+-    return WN_NO_NETWORK;\r
++    if (lpNetResource)\r
++    {\r
++        convert_netresourcea_to_w(lpNetResource, &resourcesW);\r
++        pRes = &resourcesW;\r
++    }\r
++\r
++    passW = strdupAtoW(lpPassword);\r
++    userIDW = strdupAtoW(lpUserID);\r
++\r
++    if (lpAccessName && lpBufferSize && *lpBufferSize)\r
++    {\r
++        WCHAR probe;\r
++\r
++        ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,\r
++                                 &probe, &bufferSize, lpResult);\r
++        if (ret == WN_MORE_DATA)\r
++            accessNameW = HeapAlloc(GetProcessHeap(), 0, bufferSize * sizeof(WCHAR));\r
++    }\r
++\r
++    if (ret == WN_MORE_DATA)\r
++    {\r
++        ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,\r
++                                 accessNameW, &bufferSize, lpResult);\r
++        if (ret == WN_SUCCESS)\r
++        {\r
++            if (lpAccessName && lpBufferSize && *lpBufferSize && accessNameW)\r
++            {\r
++                len = WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, NULL, 0, NULL, NULL);\r
++                if (len)\r
++                {\r
++                    if (len <= *lpBufferSize)\r
++                        WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, lpAccessName, len, NULL, NULL);\r
++                    else\r
++                    {\r
++                        WNetCancelConnectionW(accessNameW, TRUE);\r
++                        *lpBufferSize = len;\r
++                       ret = WN_MORE_DATA;\r
++                    }\r
++                }\r
++            }\r
++        }\r
++    }\r
++\r
++    if (lpNetResource)\r
++    {\r
++        HeapFree(GetProcessHeap(), 0, resourcesW.lpLocalName);\r
++        HeapFree(GetProcessHeap(), 0, resourcesW.lpRemoteName);\r
++        HeapFree(GetProcessHeap(), 0, resourcesW.lpComment);\r
++        HeapFree(GetProcessHeap(), 0, resourcesW.lpProvider);\r
++    }\r
++    HeapFree(GetProcessHeap(), 0, passW);\r
++    HeapFree(GetProcessHeap(), 0, userIDW);\r
++    HeapFree(GetProcessHeap(), 0, accessNameW);\r
++\r
++    return ret;\r
+ }\r
\r
+ /*****************************************************************\r
+@@ -1577,12 +1659,75 @@\r
+                                  LPWSTR lpAccessName, LPDWORD lpBufferSize,\r
+                                  LPDWORD lpResult )\r
+ {\r
+-    FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",\r
+-           hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags,\r
+-           debugstr_w(lpAccessName), lpBufferSize, lpResult );\r
++    DWORD provider;\r
++    DWORD cap;\r
++    char id;\r
++    DWORD drives;\r
++    DWORD ret;\r
++    PF_NPAddConnection3 addConn3;\r
++    PF_NPAddConnection addConn;\r
\r
+-    SetLastError(WN_NO_NETWORK);\r
+-    return WN_NO_NETWORK;\r
++    if (!providerTable || providerTable->numProviders == 0) {\r
++        SetLastError(WN_NO_NETWORK);\r
++        return WN_NO_NETWORK;\r
++    }\r
++\r
++    if (!lpNetResource) {\r
++        SetLastError(ERROR_INVALID_PARAMETER);\r
++        return ERROR_INVALID_PARAMETER;\r
++    }\r
++\r
++    if (!lpNetResource->lpProvider || !*lpNetResource->lpProvider) {\r
++        SetLastError(ERROR_BAD_PROVIDER);\r
++        return ERROR_BAD_PROVIDER;\r
++    }\r
++\r
++    if (!lpNetResource->lpLocalName || !*lpNetResource->lpLocalName) {\r
++        SetLastError(ERROR_BAD_DEVICE);\r
++        return ERROR_BAD_DEVICE;\r
++    }\r
++\r
++    if ((!(lpNetResource->lpLocalName[0] >= 'a' && lpNetResource->lpLocalName[0] <= 'z') &&\r
++        !(lpNetResource->lpLocalName[0] >= 'A' && lpNetResource->lpLocalName[0] <= 'Z')) ||\r
++        lpNetResource->lpLocalName[1] != ':' || lpNetResource->lpLocalName[2]) {\r
++        SetLastError(ERROR_BAD_DEVICE);\r
++        return ERROR_BAD_DEVICE;\r
++    }\r
++\r
++    id = (lpNetResource->lpLocalName[0] >= 'a') ? lpNetResource->lpLocalName[0] - 'a' : lpNetResource->lpLocalName[0] - 'A';\r
++    drives = GetLogicalDrives();\r
++    if (drives & (1 << id)) {\r
++        SetLastError(ERROR_ALREADY_ASSIGNED);\r
++        return ERROR_ALREADY_ASSIGNED;\r
++    }\r
++\r
++    provider = _findProviderIndexW(lpNetResource->lpProvider);\r
++    if (provider == BAD_PROVIDER_INDEX) {\r
++        SetLastError(ERROR_BAD_PROVIDER);\r
++        return ERROR_BAD_PROVIDER;\r
++    }\r
++\r
++    cap = providerTable->table[provider].getCaps(WNNC_CONNECTION);\r
++    if (!(cap & WNNC_CON_ADDCONNECTION) && !(cap & WNNC_CON_ADDCONNECTION3)) {\r
++        SetLastError(ERROR_BAD_PROVIDER);\r
++        return ERROR_BAD_PROVIDER;\r
++    }\r
++\r
++    ret = WN_ACCESS_DENIED;\r
++    if (cap & WNNC_CON_ADDCONNECTION3) {\r
++        addConn3 = (PF_NPAddConnection3)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection3");\r
++        if (addConn3) {\r
++            ret = addConn3(hwndOwner, lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID, dwFlags);\r
++        }\r
++    }\r
++    else if (cap & WNNC_CON_ADDCONNECTION) {\r
++        addConn = (PF_NPAddConnection)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection");\r
++        if (addConn) {\r
++            ret = addConn(lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID);\r
++        }\r
++    }\r
++\r
++    return ret;\r
+ }\r
\r
+ /*********************************************************************\r
index 4c6f929..fa96dcf 100644 (file)
@@ -46,6 +46,8 @@ typedef struct _WNetProvider
     PF_NPEnumResource enumResource;
     PF_NPCloseEnum    closeEnum;
     PF_NPGetResourceInformation getResourceInformation;
+    PF_NPAddConnection addConnection;
+    PF_NPAddConnection3 addConnection3;
 } WNetProvider, *PWNetProvider;
 
 typedef struct _WNetProviderTable
@@ -152,8 +154,9 @@ static void _tryLoadProvider(PCWSTR provider)
 
                 if (hLib)
                 {
-                    PF_NPGetCaps getCaps = (PF_NPGetCaps)GetProcAddress(hLib,
-                     "NPGetCaps");
+#define MPR_GETPROC(proc) ((PF_##proc)GetProcAddress(hLib, #proc))
+
+                    PF_NPGetCaps getCaps = MPR_GETPROC(NPGetCaps);
 
                     TRACE("loaded lib %p\n", hLib);
                     if (getCaps)
@@ -172,22 +175,17 @@ static void _tryLoadProvider(PCWSTR provider)
                         if (provider->dwEnumScopes)
                         {
                             TRACE("supports enumeration\n");
-                            provider->openEnum = (PF_NPOpenEnum)
-                             GetProcAddress(hLib, "NPOpenEnum");
-                            TRACE("openEnum is %p\n", provider->openEnum);
-                            provider->enumResource = (PF_NPEnumResource)
-                             GetProcAddress(hLib, "NPEnumResource");
-                            TRACE("enumResource is %p\n",
-                             provider->enumResource);
-                            provider->closeEnum = (PF_NPCloseEnum)
-                             GetProcAddress(hLib, "NPCloseEnum");
-                            TRACE("closeEnum is %p\n", provider->closeEnum);
-                            provider->getResourceInformation = (PF_NPGetResourceInformation)
-                                    GetProcAddress(hLib, "NPGetResourceInformation");
-                            TRACE("getResourceInformation is %p\n",
-                                  provider->getResourceInformation);
-                            if (!provider->openEnum || !provider->enumResource
-                             || !provider->closeEnum)
+                            provider->openEnum = MPR_GETPROC(NPOpenEnum);
+                            TRACE("NPOpenEnum %p\n", provider->openEnum);
+                            provider->enumResource = MPR_GETPROC(NPEnumResource);
+                            TRACE("NPEnumResource %p\n", provider->enumResource);
+                            provider->closeEnum = MPR_GETPROC(NPCloseEnum);
+                            TRACE("NPCloseEnum %p\n", provider->closeEnum);
+                            provider->getResourceInformation = MPR_GETPROC(NPGetResourceInformation);
+                            TRACE("NPGetResourceInformation %p\n", provider->getResourceInformation);
+                            if (!provider->openEnum ||
+                                !provider->enumResource ||
+                                !provider->closeEnum)
                             {
                                 provider->openEnum = NULL;
                                 provider->enumResource = NULL;
@@ -196,6 +194,10 @@ static void _tryLoadProvider(PCWSTR provider)
                                 WARN("Couldn't load enumeration functions\n");
                             }
                         }
+                        provider->addConnection = MPR_GETPROC(NPAddConnection);
+                        provider->addConnection3 = MPR_GETPROC(NPAddConnection3);
+                        TRACE("NPAddConnection %p\n", provider->addConnection);
+                        TRACE("NPAddConnection3 %p\n", provider->addConnection3);
                         providerTable->numProviders++;
                     }
                     else
@@ -205,6 +207,8 @@ static void _tryLoadProvider(PCWSTR provider)
                         HeapFree(GetProcessHeap(), 0, name);
                         FreeLibrary(hLib);
                     }
+
+#undef MPR_GETPROC
                 }
                 else
                 {