Import Wine commit (by Nikolay Sivov):
- e920b4ecffd6387e24dd046fd7fa97d13d418d26, Implement WNetUseConnectionA().

CORE-10032

svn path=/trunk/; revision=71015
This commit is contained in:
Pierre Schweitzer
2016-03-16 18:40:14 +00:00
parent ca5647ee50
commit 02ce356779
2 changed files with 197 additions and 255 deletions
-107
View File
@@ -71,110 +71,3 @@ Index: wnet.c
}
else
ret = WN_NOT_SUPPORTED;
@@ -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;
}
/*****************************************************************
+197 -148
View File
@@ -1560,7 +1560,162 @@ DWORD WINAPI WNetAddConnection3W( HWND hwndOwner, LPNETRESOURCEW lpNetResource,
dwFlags, NULL, 0, NULL);
}
/* Convert an ANSI string to wide */
struct use_connection_context
{
HWND hwndOwner;
NETRESOURCEW *resource;
NETRESOURCEA *resourceA; /* only set for WNetUseConnectionA */
WCHAR *password;
WCHAR *userid;
DWORD flags;
void *accessname;
DWORD *buffer_size;
DWORD *result;
DWORD (*pre_set_accessname)(struct use_connection_context*);
void (*set_accessname)(struct use_connection_context*);
};
static DWORD use_connection_pre_set_accessnameW(struct use_connection_context *ctxt)
{
if (ctxt->accessname && ctxt->buffer_size && *ctxt->buffer_size)
{
DWORD len;
if (ctxt->resource->lpLocalName)
len = strlenW(ctxt->resource->lpLocalName);
else
len = strlenW(ctxt->resource->lpRemoteName);
if (++len > *ctxt->buffer_size)
{
*ctxt->buffer_size = len;
return ERROR_MORE_DATA;
}
}
else
ctxt->accessname = NULL;
return ERROR_SUCCESS;
}
static void use_connection_set_accessnameW(struct use_connection_context *ctxt)
{
WCHAR *accessname = ctxt->accessname;
if (ctxt->resource->lpLocalName)
strcpyW(accessname, ctxt->resource->lpLocalName);
else
strcpyW(accessname, ctxt->resource->lpRemoteName);
}
static DWORD wnet_use_connection( struct use_connection_context *ctxt )
{
WNetProvider *provider;
DWORD index, ret, caps;
if (!providerTable || providerTable->numProviders == 0)
return WN_NO_NETWORK;
if (!ctxt->resource)
return ERROR_INVALID_PARAMETER;
if (!ctxt->resource->lpProvider)
{
FIXME("Networking provider selection is not implemented.\n");
return WN_NO_NETWORK;
}
if (!ctxt->resource->lpLocalName && (ctxt->flags & CONNECT_REDIRECT))
{
FIXME("Locale device selection is not implemented.\n");
return WN_NO_NETWORK;
}
if (ctxt->flags & CONNECT_INTERACTIVE)
return ERROR_BAD_NET_NAME;
index = _findProviderIndexW(ctxt->resource->lpProvider);
if (index == BAD_PROVIDER_INDEX)
return ERROR_BAD_PROVIDER;
provider = &providerTable->table[index];
caps = provider->getCaps(WNNC_CONNECTION);
if (!(caps & (WNNC_CON_ADDCONNECTION | WNNC_CON_ADDCONNECTION3)))
return ERROR_BAD_PROVIDER;
if ((ret = ctxt->pre_set_accessname(ctxt)))
return ret;
ret = WN_ACCESS_DENIED;
if ((caps & WNNC_CON_ADDCONNECTION3) && provider->addConnection3)
ret = provider->addConnection3(ctxt->hwndOwner, ctxt->resource, ctxt->password, ctxt->userid, ctxt->flags);
else if ((caps & WNNC_CON_ADDCONNECTION) && provider->addConnection)
ret = provider->addConnection(ctxt->resource, ctxt->password, ctxt->userid);
if (ret == WN_SUCCESS && ctxt->accessname)
ctxt->set_accessname(ctxt);
return ret;
}
/*****************************************************************
* WNetUseConnectionW [MPR.@]
*/
DWORD WINAPI WNetUseConnectionW( HWND hwndOwner, NETRESOURCEW *resource, LPCWSTR password,
LPCWSTR userid, DWORD flags, LPWSTR accessname, DWORD *buffer_size, DWORD *result )
{
struct use_connection_context ctxt;
TRACE( "(%p, %p, %p, %s, 0x%08X, %p, %p, %p)\n",
hwndOwner, resource, password, debugstr_w(userid), flags,
accessname, buffer_size, result );
ctxt.hwndOwner = hwndOwner;
ctxt.resource = resource;
ctxt.resourceA = NULL;
ctxt.password = (WCHAR*)password;
ctxt.userid = (WCHAR*)userid;
ctxt.flags = flags;
ctxt.accessname = accessname;
ctxt.buffer_size = buffer_size;
ctxt.result = result;
ctxt.pre_set_accessname = use_connection_pre_set_accessnameW;
ctxt.set_accessname = use_connection_set_accessnameW;
return wnet_use_connection(&ctxt);
}
static DWORD use_connection_pre_set_accessnameA(struct use_connection_context *ctxt)
{
if (ctxt->accessname && ctxt->buffer_size && *ctxt->buffer_size)
{
DWORD len;
if (ctxt->resourceA->lpLocalName)
len = strlen(ctxt->resourceA->lpLocalName);
else
len = strlen(ctxt->resourceA->lpRemoteName);
if (++len > *ctxt->buffer_size)
{
*ctxt->buffer_size = len;
return ERROR_MORE_DATA;
}
}
else
ctxt->accessname = NULL;
return ERROR_SUCCESS;
}
static void use_connection_set_accessnameA(struct use_connection_context *ctxt)
{
char *accessname = ctxt->accessname;
if (ctxt->resourceA->lpLocalName)
strcpy(accessname, ctxt->resourceA->lpLocalName);
else
strcpy(accessname, ctxt->resourceA->lpRemoteName);
}
static LPWSTR strdupAtoW( LPCSTR str )
{
LPWSTR ret;
@@ -1573,165 +1728,59 @@ static LPWSTR strdupAtoW( LPCSTR str )
return ret;
}
/* Convert ANSI NETRESOURCE struct to wide structure */
static VOID convert_netresourcea_to_w( LPNETRESOURCEA lpNetResourceA,
LPNETRESOURCEW lpNetResourceW )
static void netresource_a_to_w( NETRESOURCEA *resourceA, NETRESOURCEW *resourceW )
{
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);
resourceW->dwScope = resourceA->dwScope;
resourceW->dwType = resourceA->dwType;
resourceW->dwDisplayType = resourceA->dwDisplayType;
resourceW->dwUsage = resourceA->dwUsage;
resourceW->lpLocalName = strdupAtoW(resourceA->lpLocalName);
resourceW->lpRemoteName = strdupAtoW(resourceA->lpRemoteName);
resourceW->lpComment = strdupAtoW(resourceA->lpComment);
resourceW->lpProvider = strdupAtoW(resourceA->lpProvider);
}
static void free_netresourceW( NETRESOURCEW *resource )
{
HeapFree(GetProcessHeap(), 0, resource->lpLocalName);
HeapFree(GetProcessHeap(), 0, resource->lpRemoteName);
HeapFree(GetProcessHeap(), 0, resource->lpComment);
HeapFree(GetProcessHeap(), 0, resource->lpProvider);
}
/*****************************************************************
* WNetUseConnectionA [MPR.@]
*/
DWORD WINAPI WNetUseConnectionA( HWND hwndOwner, LPNETRESOURCEA lpNetResource,
LPCSTR lpPassword, LPCSTR lpUserID, DWORD dwFlags,
LPSTR lpAccessName, LPDWORD lpBufferSize,
LPDWORD lpResult )
DWORD WINAPI WNetUseConnectionA( HWND hwndOwner, NETRESOURCEA *resource,
LPCSTR password, LPCSTR userid, DWORD flags, LPSTR accessname,
DWORD *buffer_size, DWORD *result )
{
NETRESOURCEW resourcesW, *pRes = NULL;
PWSTR passW, userIDW, accessNameW = NULL;
DWORD ret = WN_MORE_DATA;
DWORD bufferSize = 1;
int len;
struct use_connection_context ctxt;
NETRESOURCEW resourceW;
DWORD ret;
if (lpNetResource)
{
convert_netresourcea_to_w(lpNetResource, &resourcesW);
pRes = &resourcesW;
}
TRACE( "(%p, %p, %p, %s, 0x%08X, %p, %p, %p)\n", hwndOwner, resource, password, debugstr_a(userid), flags,
accessname, buffer_size, result );
passW = strdupAtoW(lpPassword);
userIDW = strdupAtoW(lpUserID);
netresource_a_to_w(resource, &resourceW);
if (lpAccessName && lpBufferSize && *lpBufferSize)
{
WCHAR probe;
ctxt.hwndOwner = hwndOwner;
ctxt.resource = &resourceW;
ctxt.resourceA = resource;
ctxt.password = strdupAtoW(password);
ctxt.userid = strdupAtoW(userid);
ctxt.flags = flags;
ctxt.accessname = accessname;
ctxt.buffer_size = buffer_size;
ctxt.result = result;
ctxt.pre_set_accessname = use_connection_pre_set_accessnameA;
ctxt.set_accessname = use_connection_set_accessnameA;
ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
&probe, &bufferSize, lpResult);
if (ret == WN_MORE_DATA)
accessNameW = HeapAlloc(GetProcessHeap(), 0, bufferSize * sizeof(WCHAR));
}
ret = wnet_use_connection(&ctxt);
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;
}
/*****************************************************************
* WNetUseConnectionW [MPR.@]
*/
DWORD WINAPI WNetUseConnectionW( HWND hwndOwner, NETRESOURCEW *resource, LPCWSTR password,
LPCWSTR userid, DWORD flags, LPWSTR accessname, DWORD *buffer_size, DWORD *result )
{
WNetProvider *provider;
DWORD index, ret, caps;
TRACE( "(%p, %p, %p, %s, 0x%08X, %p, %p, %p)\n",
hwndOwner, resource, password, debugstr_w(userid), flags,
accessname, buffer_size, result );
if (!providerTable || providerTable->numProviders == 0)
return WN_NO_NETWORK;
if (!resource)
return ERROR_INVALID_PARAMETER;
if (!resource->lpProvider)
{
FIXME("Networking provider selection is not implemented.\n");
return WN_NO_NETWORK;
}
if (!resource->lpLocalName && (flags & CONNECT_REDIRECT))
{
FIXME("Locale device selection is not implemented.\n");
return WN_NO_NETWORK;
}
if (flags & CONNECT_INTERACTIVE)
return ERROR_BAD_NET_NAME;
index = _findProviderIndexW(resource->lpProvider);
if (index == BAD_PROVIDER_INDEX)
return ERROR_BAD_PROVIDER;
provider = &providerTable->table[index];
caps = provider->getCaps(WNNC_CONNECTION);
if (!(caps & (WNNC_CON_ADDCONNECTION | WNNC_CON_ADDCONNECTION3)))
return ERROR_BAD_PROVIDER;
if (accessname && buffer_size && *buffer_size)
{
DWORD len;
if (resource->lpLocalName)
len = strlenW(resource->lpLocalName);
else
len = strlenW(resource->lpRemoteName);
if (++len > *buffer_size)
{
*buffer_size = len;
return ERROR_MORE_DATA;
}
}
else
accessname = NULL;
ret = WN_ACCESS_DENIED;
if ((caps & WNNC_CON_ADDCONNECTION3) && provider->addConnection3)
ret = provider->addConnection3(hwndOwner, resource, (LPWSTR)password, (LPWSTR)userid, flags);
else if ((caps & WNNC_CON_ADDCONNECTION) && provider->addConnection)
ret = provider->addConnection(resource, (LPWSTR)password, (LPWSTR)userid);
if (ret == WN_SUCCESS && accessname)
{
if (resource->lpLocalName)
strcpyW(accessname, resource->lpLocalName);
else
strcpyW(accessname, resource->lpRemoteName);
}
free_netresourceW(&resourceW);
HeapFree(GetProcessHeap(), 0, ctxt.password);
HeapFree(GetProcessHeap(), 0, ctxt.userid);
return ret;
}