From f873af4b21d440cae02c25349c5fadcc0189837c Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Mon, 15 Feb 2016 20:15:54 +0000 Subject: [PATCH] [MPR] 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 | 468 ++++++++++++++--------------- reactos/dll/win32/mpr/wnet.c | 40 +-- 2 files changed, 256 insertions(+), 252 deletions(-) diff --git a/reactos/dll/win32/mpr/mpr_ros.diff b/reactos/dll/win32/mpr/mpr_ros.diff index 95b5ca4c7f9..4d82fe021fe 100644 --- a/reactos/dll/win32/mpr/mpr_ros.diff +++ b/reactos/dll/win32/mpr/mpr_ros.diff @@ -3,237 +3,237 @@ Index: mpr.spec --- mpr.spec (revision 49877) +++ mpr.spec (working copy) @@ -1,23 +1,23 @@ - # 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 +- 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) +@@ -1553,6 +1553,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.@] + */ +@@ -1561,12 +1588,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; + } + + /***************************************************************** +@@ -1577,12 +1659,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; + } + + /********************************************************************* diff --git a/reactos/dll/win32/mpr/wnet.c b/reactos/dll/win32/mpr/wnet.c index 4c6f9299f59..fa96dcf274c 100644 --- a/reactos/dll/win32/mpr/wnet.c +++ b/reactos/dll/win32/mpr/wnet.c @@ -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 {