}\r
else\r
ret = WN_NOT_SUPPORTED;\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
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.@]
- */
-DWORD WINAPI WNetUseConnectionA( HWND hwndOwner, LPNETRESOURCEA lpNetResource,
- LPCSTR lpPassword, LPCSTR lpUserID, DWORD dwFlags,
- LPSTR lpAccessName, LPDWORD lpBufferSize,
- LPDWORD lpResult )
-{
- NETRESOURCEW resourcesW, *pRes = NULL;
- PWSTR passW, userIDW, accessNameW = NULL;
- DWORD ret = WN_MORE_DATA;
- DWORD bufferSize = 1;
- int len;
-
- if (lpNetResource)
- {
- convert_netresourcea_to_w(lpNetResource, &resourcesW);
- pRes = &resourcesW;
- }
-
- passW = strdupAtoW(lpPassword);
- userIDW = strdupAtoW(lpUserID);
-
- if (lpAccessName && lpBufferSize && *lpBufferSize)
+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)
{
- WCHAR probe;
+ DWORD len;
- ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
- &probe, &bufferSize, lpResult);
- if (ret == WN_MORE_DATA)
- accessNameW = HeapAlloc(GetProcessHeap(), 0, bufferSize * sizeof(WCHAR));
- }
+ if (ctxt->resource->lpLocalName)
+ len = strlenW(ctxt->resource->lpLocalName);
+ else
+ len = strlenW(ctxt->resource->lpRemoteName);
- if (ret == WN_MORE_DATA)
- {
- ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
- accessNameW, &bufferSize, lpResult);
- if (ret == WN_SUCCESS)
+ if (++len > *ctxt->buffer_size)
{
- 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;
- }
- }
- }
+ *ctxt->buffer_size = len;
+ return ERROR_MORE_DATA;
}
}
+ else
+ ctxt->accessname = NULL;
- 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 ERROR_SUCCESS;
+}
- return ret;
+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);
}
-/*****************************************************************
- * WNetUseConnectionW [MPR.@]
- */
-DWORD WINAPI WNetUseConnectionW( HWND hwndOwner, NETRESOURCEW *resource, LPCWSTR password,
- LPCWSTR userid, DWORD flags, LPWSTR accessname, DWORD *buffer_size, DWORD *result )
+static DWORD wnet_use_connection( struct use_connection_context *ctxt )
{
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)
+ if (!ctxt->resource)
return ERROR_INVALID_PARAMETER;
- if (!resource->lpProvider)
+ if (!ctxt->resource->lpProvider)
{
FIXME("Networking provider selection is not implemented.\n");
return WN_NO_NETWORK;
}
- if (!resource->lpLocalName && (flags & CONNECT_REDIRECT))
+ if (!ctxt->resource->lpLocalName && (ctxt->flags & CONNECT_REDIRECT))
{
FIXME("Locale device selection is not implemented.\n");
return WN_NO_NETWORK;
}
- if (flags & CONNECT_INTERACTIVE)
+ if (ctxt->flags & CONNECT_INTERACTIVE)
return ERROR_BAD_NET_NAME;
- index = _findProviderIndexW(resource->lpProvider);
+ index = _findProviderIndexW(ctxt->resource->lpProvider);
if (index == BAD_PROVIDER_INDEX)
return ERROR_BAD_PROVIDER;
if (!(caps & (WNNC_CON_ADDCONNECTION | WNNC_CON_ADDCONNECTION3)))
return ERROR_BAD_PROVIDER;
- if (accessname && buffer_size && *buffer_size)
+ 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 (resource->lpLocalName)
- len = strlenW(resource->lpLocalName);
+ if (ctxt->resourceA->lpLocalName)
+ len = strlen(ctxt->resourceA->lpLocalName);
else
- len = strlenW(resource->lpRemoteName);
+ len = strlen(ctxt->resourceA->lpRemoteName);
- if (++len > *buffer_size)
+ if (++len > *ctxt->buffer_size)
{
- *buffer_size = len;
+ *ctxt->buffer_size = len;
return ERROR_MORE_DATA;
}
}
else
- accessname = NULL;
+ ctxt->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);
+ return ERROR_SUCCESS;
+}
- if (ret == WN_SUCCESS && accessname)
- {
- if (resource->lpLocalName)
- strcpyW(accessname, resource->lpLocalName);
- else
- strcpyW(accessname, resource->lpRemoteName);
- }
+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;
+ 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;
+}
+
+static void netresource_a_to_w( NETRESOURCEA *resourceA, NETRESOURCEW *resourceW )
+{
+ 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, NETRESOURCEA *resource,
+ LPCSTR password, LPCSTR userid, DWORD flags, LPSTR accessname,
+ DWORD *buffer_size, DWORD *result )
+{
+ struct use_connection_context ctxt;
+ NETRESOURCEW resourceW;
+ DWORD ret;
+
+ TRACE( "(%p, %p, %p, %s, 0x%08X, %p, %p, %p)\n", hwndOwner, resource, password, debugstr_a(userid), flags,
+ accessname, buffer_size, result );
+
+ netresource_a_to_w(resource, &resourceW);
+
+ 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 = wnet_use_connection(&ctxt);
+
+ free_netresourceW(&resourceW);
+ HeapFree(GetProcessHeap(), 0, ctxt.password);
+ HeapFree(GetProcessHeap(), 0, ctxt.userid);
return ret;
}