Import Wine commit (by Nikolay Sivov):
- 164fe0470ccf7cb3c0946cbb52d4139aec0c4a03, Query for NPAddConnection and NPAddConnection3 when loading a provider.

CORE-10032

svn path=/trunk/; revision=70754
This commit is contained in:
Pierre Schweitzer 2016-02-15 20:15:54 +00:00
parent cf5302e3de
commit f873af4b21
2 changed files with 256 additions and 252 deletions

View file

@ -3,237 +3,237 @@ Index: mpr.spec
--- mpr.spec (revision 49877) --- mpr.spec (revision 49877)
+++ mpr.spec (working copy) +++ mpr.spec (working copy)
@@ -1,23 +1,23 @@ @@ -1,23 +1,23 @@
# ordinal exports # ordinal exports
- 1 stub @ - 1 stub @
- 2 stub @ - 2 stub @
- 3 stub @ - 3 stub @
- 4 stub @ - 4 stub @
- 5 stub @ - 5 stub @
- 6 stub @ - 6 stub @
- 7 stub @ - 7 stub @
- 8 stub @ - 8 stub @
- 9 stub @ - 9 stub @
-12 stub @ -12 stub @
-13 stub @ -13 stub @
-14 stub @ -14 stub @
-15 stub @ -15 stub @
-16 stub @ -16 stub @
-17 stub @ -17 stub @
-18 stub @ -18 stub @
-19 stub @ -19 stub @
-20 stub @ -20 stub @
-21 stub @ -21 stub @
+ 1 stub MPR_1 + 1 stub MPR_1
+ 2 stub MPR_2 + 2 stub MPR_2
+ 3 stub MPR_3 + 3 stub MPR_3
+ 4 stub MPR_4 + 4 stub MPR_4
+ 5 stub MPR_5 + 5 stub MPR_5
+ 6 stub MPR_6 + 6 stub MPR_6
+ 7 stub MPR_7 + 7 stub MPR_7
+ 8 stub MPR_8 + 8 stub MPR_8
+ 9 stub MPR_9 + 9 stub MPR_9
+12 stub MPR_12 +12 stub MPR_12
+13 stub MPR_13 +13 stub MPR_13
+14 stub MPR_14 +14 stub MPR_14
+15 stub MPR_15 +15 stub MPR_15
+16 stub MPR_16 +16 stub MPR_16
+17 stub MPR_17 +17 stub MPR_17
+18 stub MPR_18 +18 stub MPR_18
+19 stub MPR_19 +19 stub MPR_19
+20 stub MPR_20 +20 stub MPR_20
+21 stub MPR_21 +21 stub MPR_21
22 stdcall @(long) MPR_Alloc 22 stdcall @(long) MPR_Alloc
23 stdcall @(ptr long) MPR_ReAlloc 23 stdcall @(ptr long) MPR_ReAlloc
24 stdcall @(ptr) MPR_Free 24 stdcall @(ptr) MPR_Free
Index: wnet.c Index: wnet.c
=================================================================== ===================================================================
--- wnet.c (révision 70645) --- wnet.c (révision 70645)
+++ wnet.c (copie de travail) +++ wnet.c (copie de travail)
@@ -1549,6 +1549,33 @@ @@ -1553,6 +1553,33 @@
dwFlags, NULL, 0, NULL); dwFlags, NULL, 0, NULL);
} }
+/* Convert an ANSI string to wide */ +/* Convert an ANSI string to wide */
+static LPWSTR strdupAtoW( LPCSTR str ) +static LPWSTR strdupAtoW( LPCSTR str )
+{ +{
+ LPWSTR ret; + LPWSTR ret;
+ INT len; + INT len;
+ +
+ if (!str) return NULL; + if (!str) return NULL;
+ len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); + len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+ ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if (ret) MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len ); + if (ret) MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
+ return ret; + return ret;
+} +}
+ +
+/* Convert ANSI NETRESOURCE struct to wide structure */ +/* Convert ANSI NETRESOURCE struct to wide structure */
+static VOID convert_netresourcea_to_w( LPNETRESOURCEA lpNetResourceA, +static VOID convert_netresourcea_to_w( LPNETRESOURCEA lpNetResourceA,
+ LPNETRESOURCEW lpNetResourceW ) + LPNETRESOURCEW lpNetResourceW )
+{ +{
+ lpNetResourceW->dwScope = lpNetResourceA->dwScope; + lpNetResourceW->dwScope = lpNetResourceA->dwScope;
+ lpNetResourceW->dwType = lpNetResourceA->dwType; + lpNetResourceW->dwType = lpNetResourceA->dwType;
+ lpNetResourceW->dwDisplayType = lpNetResourceA->dwDisplayType; + lpNetResourceW->dwDisplayType = lpNetResourceA->dwDisplayType;
+ lpNetResourceW->dwUsage = lpNetResourceA->dwUsage; + lpNetResourceW->dwUsage = lpNetResourceA->dwUsage;
+ lpNetResourceW->lpLocalName = strdupAtoW(lpNetResourceA->lpLocalName); + lpNetResourceW->lpLocalName = strdupAtoW(lpNetResourceA->lpLocalName);
+ lpNetResourceW->lpRemoteName = strdupAtoW(lpNetResourceA->lpRemoteName); + lpNetResourceW->lpRemoteName = strdupAtoW(lpNetResourceA->lpRemoteName);
+ lpNetResourceW->lpComment = strdupAtoW(lpNetResourceA->lpComment); + lpNetResourceW->lpComment = strdupAtoW(lpNetResourceA->lpComment);
+ lpNetResourceW->lpProvider = strdupAtoW(lpNetResourceA->lpProvider); + lpNetResourceW->lpProvider = strdupAtoW(lpNetResourceA->lpProvider);
+} +}
+ +
/***************************************************************** /*****************************************************************
* WNetUseConnectionA [MPR.@] * WNetUseConnectionA [MPR.@]
*/ */
@@ -1557,12 +1584,67 @@ @@ -1561,12 +1588,67 @@
LPSTR lpAccessName, LPDWORD lpBufferSize, LPSTR lpAccessName, LPDWORD lpBufferSize,
LPDWORD lpResult ) LPDWORD lpResult )
{ {
- FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n", - FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",
- hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags, - hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags,
- debugstr_a(lpAccessName), lpBufferSize, lpResult ); - debugstr_a(lpAccessName), lpBufferSize, lpResult );
+ NETRESOURCEW resourcesW, *pRes = NULL; + NETRESOURCEW resourcesW, *pRes = NULL;
+ PWSTR passW, userIDW, accessNameW = NULL; + PWSTR passW, userIDW, accessNameW = NULL;
+ DWORD ret = WN_MORE_DATA; + DWORD ret = WN_MORE_DATA;
+ DWORD bufferSize = 1; + DWORD bufferSize = 1;
+ int len; + int len;
- SetLastError(WN_NO_NETWORK); - SetLastError(WN_NO_NETWORK);
- return WN_NO_NETWORK; - return WN_NO_NETWORK;
+ if (lpNetResource) + if (lpNetResource)
+ { + {
+ convert_netresourcea_to_w(lpNetResource, &resourcesW); + convert_netresourcea_to_w(lpNetResource, &resourcesW);
+ pRes = &resourcesW; + pRes = &resourcesW;
+ } + }
+ +
+ passW = strdupAtoW(lpPassword); + passW = strdupAtoW(lpPassword);
+ userIDW = strdupAtoW(lpUserID); + userIDW = strdupAtoW(lpUserID);
+ +
+ if (lpAccessName && lpBufferSize && *lpBufferSize) + if (lpAccessName && lpBufferSize && *lpBufferSize)
+ { + {
+ WCHAR probe; + WCHAR probe;
+ +
+ ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags, + ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
+ &probe, &bufferSize, lpResult); + &probe, &bufferSize, lpResult);
+ if (ret == WN_MORE_DATA) + if (ret == WN_MORE_DATA)
+ accessNameW = HeapAlloc(GetProcessHeap(), 0, bufferSize * sizeof(WCHAR)); + accessNameW = HeapAlloc(GetProcessHeap(), 0, bufferSize * sizeof(WCHAR));
+ } + }
+ +
+ if (ret == WN_MORE_DATA) + if (ret == WN_MORE_DATA)
+ { + {
+ ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags, + ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
+ accessNameW, &bufferSize, lpResult); + accessNameW, &bufferSize, lpResult);
+ if (ret == WN_SUCCESS) + if (ret == WN_SUCCESS)
+ { + {
+ if (lpAccessName && lpBufferSize && *lpBufferSize && accessNameW) + if (lpAccessName && lpBufferSize && *lpBufferSize && accessNameW)
+ { + {
+ len = WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, NULL, 0, NULL, NULL); + len = WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, NULL, 0, NULL, NULL);
+ if (len) + if (len)
+ { + {
+ if (len <= *lpBufferSize) + if (len <= *lpBufferSize)
+ WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, lpAccessName, len, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, accessNameW, -1, lpAccessName, len, NULL, NULL);
+ else + else
+ { + {
+ WNetCancelConnectionW(accessNameW, TRUE); + WNetCancelConnectionW(accessNameW, TRUE);
+ *lpBufferSize = len; + *lpBufferSize = len;
+ ret = WN_MORE_DATA; + ret = WN_MORE_DATA;
+ } + }
+ } + }
+ } + }
+ } + }
+ } + }
+ +
+ if (lpNetResource) + if (lpNetResource)
+ { + {
+ HeapFree(GetProcessHeap(), 0, resourcesW.lpLocalName); + HeapFree(GetProcessHeap(), 0, resourcesW.lpLocalName);
+ HeapFree(GetProcessHeap(), 0, resourcesW.lpRemoteName); + HeapFree(GetProcessHeap(), 0, resourcesW.lpRemoteName);
+ HeapFree(GetProcessHeap(), 0, resourcesW.lpComment); + HeapFree(GetProcessHeap(), 0, resourcesW.lpComment);
+ HeapFree(GetProcessHeap(), 0, resourcesW.lpProvider); + HeapFree(GetProcessHeap(), 0, resourcesW.lpProvider);
+ } + }
+ HeapFree(GetProcessHeap(), 0, passW); + HeapFree(GetProcessHeap(), 0, passW);
+ HeapFree(GetProcessHeap(), 0, userIDW); + HeapFree(GetProcessHeap(), 0, userIDW);
+ HeapFree(GetProcessHeap(), 0, accessNameW); + HeapFree(GetProcessHeap(), 0, accessNameW);
+ +
+ return ret; + return ret;
} }
/***************************************************************** /*****************************************************************
@@ -1573,12 +1655,75 @@ @@ -1577,12 +1659,75 @@
LPWSTR lpAccessName, LPDWORD lpBufferSize, LPWSTR lpAccessName, LPDWORD lpBufferSize,
LPDWORD lpResult ) LPDWORD lpResult )
{ {
- FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n", - FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",
- hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags, - hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags,
- debugstr_w(lpAccessName), lpBufferSize, lpResult ); - debugstr_w(lpAccessName), lpBufferSize, lpResult );
+ DWORD provider; + DWORD provider;
+ DWORD cap; + DWORD cap;
+ char id; + char id;
+ DWORD drives; + DWORD drives;
+ DWORD ret; + DWORD ret;
+ PF_NPAddConnection3 addConn3; + PF_NPAddConnection3 addConn3;
+ PF_NPAddConnection addConn; + PF_NPAddConnection addConn;
- SetLastError(WN_NO_NETWORK); - SetLastError(WN_NO_NETWORK);
- return WN_NO_NETWORK; - return WN_NO_NETWORK;
+ if (!providerTable || providerTable->numProviders == 0) { + if (!providerTable || providerTable->numProviders == 0) {
+ SetLastError(WN_NO_NETWORK); + SetLastError(WN_NO_NETWORK);
+ return WN_NO_NETWORK; + return WN_NO_NETWORK;
+ } + }
+ +
+ if (!lpNetResource) { + if (!lpNetResource) {
+ SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER; + return ERROR_INVALID_PARAMETER;
+ } + }
+ +
+ if (!lpNetResource->lpProvider || !*lpNetResource->lpProvider) { + if (!lpNetResource->lpProvider || !*lpNetResource->lpProvider) {
+ SetLastError(ERROR_BAD_PROVIDER); + SetLastError(ERROR_BAD_PROVIDER);
+ return ERROR_BAD_PROVIDER; + return ERROR_BAD_PROVIDER;
+ } + }
+ +
+ if (!lpNetResource->lpLocalName || !*lpNetResource->lpLocalName) { + if (!lpNetResource->lpLocalName || !*lpNetResource->lpLocalName) {
+ SetLastError(ERROR_BAD_DEVICE); + SetLastError(ERROR_BAD_DEVICE);
+ return ERROR_BAD_DEVICE; + return ERROR_BAD_DEVICE;
+ } + }
+ +
+ if ((!(lpNetResource->lpLocalName[0] >= 'a' && lpNetResource->lpLocalName[0] <= 'z') && + if ((!(lpNetResource->lpLocalName[0] >= 'a' && lpNetResource->lpLocalName[0] <= 'z') &&
+ !(lpNetResource->lpLocalName[0] >= 'A' && lpNetResource->lpLocalName[0] <= 'Z')) || + !(lpNetResource->lpLocalName[0] >= 'A' && lpNetResource->lpLocalName[0] <= 'Z')) ||
+ lpNetResource->lpLocalName[1] != ':' || lpNetResource->lpLocalName[2]) { + lpNetResource->lpLocalName[1] != ':' || lpNetResource->lpLocalName[2]) {
+ SetLastError(ERROR_BAD_DEVICE); + SetLastError(ERROR_BAD_DEVICE);
+ return ERROR_BAD_DEVICE; + return ERROR_BAD_DEVICE;
+ } + }
+ +
+ id = (lpNetResource->lpLocalName[0] >= 'a') ? lpNetResource->lpLocalName[0] - 'a' : lpNetResource->lpLocalName[0] - 'A'; + id = (lpNetResource->lpLocalName[0] >= 'a') ? lpNetResource->lpLocalName[0] - 'a' : lpNetResource->lpLocalName[0] - 'A';
+ drives = GetLogicalDrives(); + drives = GetLogicalDrives();
+ if (drives & (1 << id)) { + if (drives & (1 << id)) {
+ SetLastError(ERROR_ALREADY_ASSIGNED); + SetLastError(ERROR_ALREADY_ASSIGNED);
+ return ERROR_ALREADY_ASSIGNED; + return ERROR_ALREADY_ASSIGNED;
+ } + }
+ +
+ provider = _findProviderIndexW(lpNetResource->lpProvider); + provider = _findProviderIndexW(lpNetResource->lpProvider);
+ if (provider == BAD_PROVIDER_INDEX) { + if (provider == BAD_PROVIDER_INDEX) {
+ SetLastError(ERROR_BAD_PROVIDER); + SetLastError(ERROR_BAD_PROVIDER);
+ return ERROR_BAD_PROVIDER; + return ERROR_BAD_PROVIDER;
+ } + }
+ +
+ cap = providerTable->table[provider].getCaps(WNNC_CONNECTION); + cap = providerTable->table[provider].getCaps(WNNC_CONNECTION);
+ if (!(cap & WNNC_CON_ADDCONNECTION) && !(cap & WNNC_CON_ADDCONNECTION3)) { + if (!(cap & WNNC_CON_ADDCONNECTION) && !(cap & WNNC_CON_ADDCONNECTION3)) {
+ SetLastError(ERROR_BAD_PROVIDER); + SetLastError(ERROR_BAD_PROVIDER);
+ return ERROR_BAD_PROVIDER; + return ERROR_BAD_PROVIDER;
+ } + }
+ +
+ ret = WN_ACCESS_DENIED; + ret = WN_ACCESS_DENIED;
+ if (cap & WNNC_CON_ADDCONNECTION3) { + if (cap & WNNC_CON_ADDCONNECTION3) {
+ addConn3 = (PF_NPAddConnection3)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection3"); + addConn3 = (PF_NPAddConnection3)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection3");
+ if (addConn3) { + if (addConn3) {
+ ret = addConn3(hwndOwner, lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID, dwFlags); + ret = addConn3(hwndOwner, lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID, dwFlags);
+ } + }
+ } + }
+ else if (cap & WNNC_CON_ADDCONNECTION) { + else if (cap & WNNC_CON_ADDCONNECTION) {
+ addConn = (PF_NPAddConnection)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection"); + addConn = (PF_NPAddConnection)GetProcAddress(providerTable->table[provider].hLib, "NPAddConnection");
+ if (addConn) { + if (addConn) {
+ ret = addConn(lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID); + ret = addConn(lpNetResource, (LPWSTR)lpPassword, (LPWSTR)lpUserID);
+ } + }
+ } + }
+ +
+ return ret; + return ret;
} }
/********************************************************************* /*********************************************************************

View file

@ -46,6 +46,8 @@ typedef struct _WNetProvider
PF_NPEnumResource enumResource; PF_NPEnumResource enumResource;
PF_NPCloseEnum closeEnum; PF_NPCloseEnum closeEnum;
PF_NPGetResourceInformation getResourceInformation; PF_NPGetResourceInformation getResourceInformation;
PF_NPAddConnection addConnection;
PF_NPAddConnection3 addConnection3;
} WNetProvider, *PWNetProvider; } WNetProvider, *PWNetProvider;
typedef struct _WNetProviderTable typedef struct _WNetProviderTable
@ -152,8 +154,9 @@ static void _tryLoadProvider(PCWSTR provider)
if (hLib) if (hLib)
{ {
PF_NPGetCaps getCaps = (PF_NPGetCaps)GetProcAddress(hLib, #define MPR_GETPROC(proc) ((PF_##proc)GetProcAddress(hLib, #proc))
"NPGetCaps");
PF_NPGetCaps getCaps = MPR_GETPROC(NPGetCaps);
TRACE("loaded lib %p\n", hLib); TRACE("loaded lib %p\n", hLib);
if (getCaps) if (getCaps)
@ -172,22 +175,17 @@ static void _tryLoadProvider(PCWSTR provider)
if (provider->dwEnumScopes) if (provider->dwEnumScopes)
{ {
TRACE("supports enumeration\n"); TRACE("supports enumeration\n");
provider->openEnum = (PF_NPOpenEnum) provider->openEnum = MPR_GETPROC(NPOpenEnum);
GetProcAddress(hLib, "NPOpenEnum"); TRACE("NPOpenEnum %p\n", provider->openEnum);
TRACE("openEnum is %p\n", provider->openEnum); provider->enumResource = MPR_GETPROC(NPEnumResource);
provider->enumResource = (PF_NPEnumResource) TRACE("NPEnumResource %p\n", provider->enumResource);
GetProcAddress(hLib, "NPEnumResource"); provider->closeEnum = MPR_GETPROC(NPCloseEnum);
TRACE("enumResource is %p\n", TRACE("NPCloseEnum %p\n", provider->closeEnum);
provider->enumResource); provider->getResourceInformation = MPR_GETPROC(NPGetResourceInformation);
provider->closeEnum = (PF_NPCloseEnum) TRACE("NPGetResourceInformation %p\n", provider->getResourceInformation);
GetProcAddress(hLib, "NPCloseEnum"); if (!provider->openEnum ||
TRACE("closeEnum is %p\n", provider->closeEnum); !provider->enumResource ||
provider->getResourceInformation = (PF_NPGetResourceInformation) !provider->closeEnum)
GetProcAddress(hLib, "NPGetResourceInformation");
TRACE("getResourceInformation is %p\n",
provider->getResourceInformation);
if (!provider->openEnum || !provider->enumResource
|| !provider->closeEnum)
{ {
provider->openEnum = NULL; provider->openEnum = NULL;
provider->enumResource = NULL; provider->enumResource = NULL;
@ -196,6 +194,10 @@ static void _tryLoadProvider(PCWSTR provider)
WARN("Couldn't load enumeration functions\n"); 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++; providerTable->numProviders++;
} }
else else
@ -205,6 +207,8 @@ static void _tryLoadProvider(PCWSTR provider)
HeapFree(GetProcessHeap(), 0, name); HeapFree(GetProcessHeap(), 0, name);
FreeLibrary(hLib); FreeLibrary(hLib);
} }
#undef MPR_GETPROC
} }
else else
{ {