PF_NPGetResourceInformation getResourceInformation;
PF_NPAddConnection addConnection;
PF_NPAddConnection3 addConnection3;
+ PF_NPCancelConnection cancelConnection;
+#ifdef __REACTOS__
+ PF_NPGetConnection getConnection;
+#endif
} WNetProvider, *PWNetProvider;
typedef struct _WNetProviderTable
WNetProvider table[1];
} WNetProviderTable, *PWNetProviderTable;
-#define WNET_ENUMERATOR_TYPE_NULL 0
-#define WNET_ENUMERATOR_TYPE_GLOBAL 1
-#define WNET_ENUMERATOR_TYPE_PROVIDER 2
-#define WNET_ENUMERATOR_TYPE_CONTEXT 3
+#define WNET_ENUMERATOR_TYPE_NULL 0
+#define WNET_ENUMERATOR_TYPE_GLOBAL 1
+#define WNET_ENUMERATOR_TYPE_PROVIDER 2
+#define WNET_ENUMERATOR_TYPE_CONTEXT 3
+#define WNET_ENUMERATOR_TYPE_CONNECTED 4
/* An WNet enumerator. Note that the type doesn't correspond to the scope of
* the enumeration; it represents one of the following types:
DWORD dwScope;
DWORD dwType;
DWORD dwUsage;
- LPNETRESOURCEW lpNet;
+ LPVOID lpBuffer;
} WNetEnumerator, *PWNetEnumerator;
#define BAD_PROVIDER_INDEX (DWORD)0xffffffff
}
provider->addConnection = MPR_GETPROC(NPAddConnection);
provider->addConnection3 = MPR_GETPROC(NPAddConnection3);
+ provider->cancelConnection = MPR_GETPROC(NPCancelConnection);
+#ifdef __REACTOS__
+ provider->getConnection = MPR_GETPROC(NPGetConnection);
+#endif
TRACE("NPAddConnection %p\n", provider->addConnection);
TRACE("NPAddConnection3 %p\n", provider->addConnection3);
+ TRACE("NPCancelConnection %p\n", provider->cancelConnection);
providerTable->numProviders++;
}
else
ret->dwScope = dwScope;
ret->dwType = dwType;
ret->dwUsage = dwUsage;
- ret->lpNet = _copyNetResourceForEnumW(lpNet);
+ ret->lpBuffer = _copyNetResourceForEnumW(lpNet);
}
return ret;
}
return ret;
}
+static PWNetEnumerator _createConnectedEnumerator(DWORD dwScope, DWORD dwType,
+ DWORD dwUsage)
+{
+ PWNetEnumerator ret = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));
+
+ if (ret)
+ {
+ ret->enumType = WNET_ENUMERATOR_TYPE_CONNECTED;
+ ret->dwScope = dwScope;
+ ret->dwType = dwType;
+ ret->dwUsage = dwUsage;
+ ret->lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HANDLE) * providerTable->numProviders);
+ if (!ret->lpBuffer)
+ {
+ HeapFree(GetProcessHeap(), 0, ret);
+ ret = NULL;
+ }
+ }
+ return ret;
+}
+
/* Thunks the array of wide-string LPNETRESOURCEs lpNetArrayIn into buffer
* lpBuffer, with size *lpBufferSize. lpNetArrayIn contains *lpcCount entries
* to start. On return, *lpcCount reflects the number thunked into lpBuffer.
providerTable->table[index].dwEnumScopes & WNNC_ENUM_GLOBAL)
{
HANDLE handle;
+ PWSTR RemoteName = lpNet->lpRemoteName;
+
+ if ((lpNet->dwUsage & RESOURCEUSAGE_CONTAINER) &&
+ RemoteName && !strcmpW(RemoteName, lpNet->lpProvider))
+ lpNet->lpRemoteName = NULL;
ret = providerTable->table[index].openEnum(
dwScope, dwType, dwUsage, lpNet, &handle);
ret = *lphEnum ? WN_SUCCESS :
WN_OUT_OF_MEMORY;
}
+
+ lpNet->lpRemoteName = RemoteName;
}
else
ret = WN_NOT_SUPPORTED;
ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
break;
case RESOURCE_REMEMBERED:
- case RESOURCE_CONNECTED:
*lphEnum = _createNullEnumerator();
ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
break;
+ case RESOURCE_CONNECTED:
+ *lphEnum = _createConnectedEnumerator(dwScope, dwType, dwUsage);
+ ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
+ break;
default:
WARN("unknown scope 0x%08x\n", dwScope);
ret = WN_BAD_VALUE;
{
ret = providerTable->table[enumerator->providerIndex].
openEnum(enumerator->dwScope, enumerator->dwType,
- enumerator->dwUsage, enumerator->lpNet,
+ enumerator->dwUsage, enumerator->lpBuffer,
&enumerator->handle);
if (ret == WN_SUCCESS)
{
switch (enumerator->dwScope)
{
case RESOURCE_GLOBALNET:
- if (enumerator->lpNet)
+ if (enumerator->lpBuffer)
ret = _enumerateGlobalPassthroughW(enumerator, lpcCount,
lpBuffer, lpBufferSize);
else
return ret;
}
+static DWORD _enumerateConnectedW(PWNetEnumerator enumerator, LPDWORD lpcCount,
+ LPVOID lpBuffer, LPDWORD lpBufferSize)
+{
+ DWORD ret, index, count, size, i, len, left;
+ PVOID end;
+ LPNETRESOURCEW curr, buffer;
+ PHANDLE handles;
+
+ if (!enumerator)
+ return WN_BAD_POINTER;
+ if (enumerator->enumType != WNET_ENUMERATOR_TYPE_CONNECTED)
+ return WN_BAD_VALUE;
+ if (!lpcCount)
+ return WN_BAD_POINTER;
+ if (!lpBuffer)
+ return WN_BAD_POINTER;
+ if (!lpBufferSize)
+ return WN_BAD_POINTER;
+ if (!providerTable)
+ return WN_NO_NETWORK;
+
+ handles = enumerator->lpBuffer;
+ left = *lpBufferSize;
+ size = *lpBufferSize;
+ buffer = HeapAlloc(GetProcessHeap(), 0, *lpBufferSize);
+ if (!buffer)
+ return WN_NO_NETWORK;
+
+ curr = lpBuffer;
+ end = (PVOID)((ULONG_PTR)lpBuffer + size);
+ count = *lpcCount;
+
+
+ for (index = 0; index < providerTable->numProviders; index++)
+ {
+ if (providerTable->table[index].dwEnumScopes)
+ {
+ if (handles[index] == 0)
+ {
+ ret = providerTable->table[index].openEnum(enumerator->dwScope,
+ enumerator->dwType,
+ enumerator->dwUsage,
+ NULL, &handles[index]);
+ if (ret != WN_SUCCESS)
+ continue;
+ }
+
+ ret = providerTable->table[index].enumResource(handles[index],
+ &count,
+ buffer,
+ &size);
+
+ if (ret == WN_MORE_DATA)
+ {
+
+ break;
+ }
+
+ if (ret == WN_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ if (left < sizeof(NETRESOURCEW))
+ {
+ ret = WN_MORE_DATA;
+ break;
+ }
+
+ memcpy(curr, &buffer[i], sizeof(NETRESOURCEW));
+ left -= sizeof(NETRESOURCEW);
+
+ len = WideCharToMultiByte(CP_ACP, 0, buffer[i].lpLocalName, -1, NULL, 0, NULL, NULL);
+ len *= sizeof(WCHAR);
+ if (left < len)
+ {
+ ret = WN_MORE_DATA;
+ break;
+ }
+
+ end = (PVOID)((ULONG_PTR)end - len);
+ curr->lpLocalName = end;
+ memcpy(end, buffer[i].lpLocalName, len);
+ left -= len;
+
+ len = WideCharToMultiByte(CP_ACP, 0, buffer[i].lpRemoteName, -1, NULL, 0, NULL, NULL);
+ len *= sizeof(WCHAR);
+ if (left < len)
+ {
+ ret = WN_MORE_DATA;
+ break;
+ }
+
+ end = (PVOID)((ULONG_PTR)end - len);
+ curr->lpRemoteName = end;
+ memcpy(end, buffer[i].lpRemoteName, len);
+ left -= len;
+
+ len = WideCharToMultiByte(CP_ACP, 0, buffer[i].lpProvider, -1, NULL, 0, NULL, NULL);
+ len *= sizeof(WCHAR);
+ if (left < len)
+ {
+ ret = WN_MORE_DATA;
+ break;
+ }
+
+ end = (PVOID)((ULONG_PTR)end - len);
+ curr->lpProvider = end;
+ memcpy(end, buffer[i].lpProvider, len);
+ left -= len;
+
+ ++curr;
+ }
+
+ count = *lpcCount - count;
+ size = left;
+ }
+
+ if (ret != WN_SUCCESS || count == 0)
+ {
+ break;
+ }
+ }
+ }
+
+ if (count == 0)
+ ret = WN_NO_MORE_ENTRIES;
+
+ *lpcCount = *lpcCount - count;
+ if (ret != WN_MORE_DATA && ret != WN_NO_MORE_ENTRIES)
+ ret = WN_SUCCESS;
+
+ HeapFree(GetProcessHeap(), 0, buffer);
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
+
/*********************************************************************
* WNetEnumResourceW [MPR.@]
*/
ret = _enumerateContextW(enumerator, lpcCount, lpBuffer,
lpBufferSize);
break;
+ case WNET_ENUMERATOR_TYPE_CONNECTED:
+ ret = _enumerateConnectedW(enumerator, lpcCount, lpBuffer,
+ lpBufferSize);
+ break;
default:
WARN("bogus enumerator type!\n");
ret = WN_NO_NETWORK;
*/
DWORD WINAPI WNetCloseEnum( HANDLE hEnum )
{
- DWORD ret;
+ DWORD ret, index;
+ PHANDLE handles;
TRACE( "(%p)\n", hEnum );
switch (enumerator->enumType)
{
+ case WNET_ENUMERATOR_TYPE_CONNECTED:
+ handles = enumerator->lpBuffer;
+ for (index = 0; index < providerTable->numProviders; index++)
+ {
+ if (providerTable->table[index].dwEnumScopes && handles[index] != 0)
+ providerTable->table[index].closeEnum(handles[index]);
+ }
+ HeapFree(GetProcessHeap(), 0, handles);
+ ret = WN_SUCCESS;
+ break;
case WNET_ENUMERATOR_TYPE_NULL:
ret = WN_SUCCESS;
break;
case WNET_ENUMERATOR_TYPE_GLOBAL:
- if (enumerator->lpNet)
- _freeEnumNetResource(enumerator->lpNet);
+ if (enumerator->lpBuffer)
+ _freeEnumNetResource(enumerator->lpBuffer);
if (enumerator->handle)
providerTable->table[enumerator->providerIndex].
closeEnum(enumerator->handle);
dwFlags, NULL, 0, NULL);
}
-/* Convert an ANSI string to wide */
-static LPWSTR strdupAtoW( LPCSTR str )
+struct use_connection_context
{
- LPWSTR ret;
- INT len;
+ 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*, WCHAR *);
+ void (*set_accessname)(struct use_connection_context*, WCHAR *);
+};
- 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 )
+static DWORD use_connection_pre_set_accessnameW(struct use_connection_context *ctxt, WCHAR *local_name)
{
- 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);
+ if (ctxt->accessname && ctxt->buffer_size && *ctxt->buffer_size)
+ {
+ DWORD len;
+
+ if (local_name)
+ len = strlenW(local_name);
+ 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;
}
-/*****************************************************************
- * 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)
+static void use_connection_set_accessnameW(struct use_connection_context *ctxt, WCHAR *local_name)
+{
+ WCHAR *accessname = ctxt->accessname;
+ if (local_name)
{
- convert_netresourcea_to_w(lpNetResource, &resourcesW);
- pRes = &resourcesW;
+ strcpyW(accessname, local_name);
+ if (ctxt->result)
+ *ctxt->result = CONNECT_LOCALDRIVE;
}
+ else
+ strcpyW(accessname, ctxt->resource->lpRemoteName);
+}
+
+static DWORD wnet_use_provider( struct use_connection_context *ctxt, NETRESOURCEW * netres, WNetProvider *provider, BOOLEAN redirect )
+{
+ DWORD caps, ret;
- passW = strdupAtoW(lpPassword);
- userIDW = strdupAtoW(lpUserID);
+ caps = provider->getCaps(WNNC_CONNECTION);
+ if (!(caps & (WNNC_CON_ADDCONNECTION | WNNC_CON_ADDCONNECTION3)))
+ return ERROR_BAD_PROVIDER;
- if (lpAccessName && lpBufferSize && *lpBufferSize)
+ ret = WN_ACCESS_DENIED;
+ do
{
- WCHAR probe;
+ if ((caps & WNNC_CON_ADDCONNECTION3) && provider->addConnection3)
+ ret = provider->addConnection3(ctxt->hwndOwner, netres, ctxt->password, ctxt->userid, ctxt->flags);
+ else if ((caps & WNNC_CON_ADDCONNECTION) && provider->addConnection)
+ ret = provider->addConnection(netres, ctxt->password, ctxt->userid);
- 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_ALREADY_CONNECTED && redirect)
+ netres->lpLocalName[0] -= 1;
+ } while (redirect && ret == WN_ALREADY_CONNECTED && netres->lpLocalName[0] >= 'C');
- if (ret == WN_MORE_DATA)
+ if (ret == WN_SUCCESS && ctxt->accessname)
+ ctxt->set_accessname(ctxt, netres->lpLocalName);
+
+ return ret;
+}
+
+static DWORD wnet_use_connection( struct use_connection_context *ctxt )
+{
+ WNetProvider *provider;
+ DWORD index, ret = WN_NO_NETWORK;
+ BOOL redirect = FALSE;
+ WCHAR letter[3] = {'Z', ':', 0};
+ NETRESOURCEW netres;
+
+ if (!providerTable || providerTable->numProviders == 0)
+ return WN_NO_NETWORK;
+
+ if (!ctxt->resource)
+ return ERROR_INVALID_PARAMETER;
+ netres = *ctxt->resource;
+
+ if (!netres.lpLocalName && (ctxt->flags & CONNECT_REDIRECT))
{
- ret = WNetUseConnectionW(hwndOwner, pRes, passW, userIDW, dwFlags,
- accessNameW, &bufferSize, lpResult);
- if (ret == WN_SUCCESS)
+ if (netres.dwType != RESOURCETYPE_DISK && netres.dwType != RESOURCETYPE_PRINT)
+ return ERROR_BAD_DEV_TYPE;
+
+ if (netres.dwType == RESOURCETYPE_PRINT)
{
- 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;
- }
- }
- }
+ FIXME("Local device selection is not implemented for printers.\n");
+ return WN_NO_NETWORK;
}
+
+ redirect = TRUE;
+ netres.lpLocalName = letter;
}
- if (lpNetResource)
+ if (ctxt->flags & CONNECT_INTERACTIVE)
+ return ERROR_BAD_NET_NAME;
+
+ if ((ret = ctxt->pre_set_accessname(ctxt, netres.lpLocalName)))
+ return ret;
+
+ if (netres.lpProvider)
{
- HeapFree(GetProcessHeap(), 0, resourcesW.lpLocalName);
- HeapFree(GetProcessHeap(), 0, resourcesW.lpRemoteName);
- HeapFree(GetProcessHeap(), 0, resourcesW.lpComment);
- HeapFree(GetProcessHeap(), 0, resourcesW.lpProvider);
+ index = _findProviderIndexW(netres.lpProvider);
+ if (index == BAD_PROVIDER_INDEX)
+ return ERROR_BAD_PROVIDER;
+
+ provider = &providerTable->table[index];
+ ret = wnet_use_provider(ctxt, &netres, provider, redirect);
+ }
+ else
+ {
+ for (index = 0; index < providerTable->numProviders; index++)
+ {
+ provider = &providerTable->table[index];
+ ret = wnet_use_provider(ctxt, &netres, provider, redirect);
+ if (ret == WN_SUCCESS || ret == WN_ALREADY_CONNECTED)
+ break;
+ }
}
- HeapFree(GetProcessHeap(), 0, passW);
- HeapFree(GetProcessHeap(), 0, userIDW);
- HeapFree(GetProcessHeap(), 0, accessNameW);
return ret;
}
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;
+ 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 );
- if (!providerTable || providerTable->numProviders == 0)
- return WN_NO_NETWORK;
+ 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;
- 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;
+ return wnet_use_connection(&ctxt);
+}
- if (accessname && buffer_size && *buffer_size)
+static DWORD use_connection_pre_set_accessnameA(struct use_connection_context *ctxt, WCHAR *local_name)
+{
+ if (ctxt->accessname && ctxt->buffer_size && *ctxt->buffer_size)
{
DWORD len;
- if (resource->lpLocalName)
- len = strlenW(resource->lpLocalName);
+ if (local_name)
+ len = WideCharToMultiByte(CP_ACP, 0, local_name, -1, NULL, 0, NULL, NULL) - 1;
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)
+static void use_connection_set_accessnameA(struct use_connection_context *ctxt, WCHAR *local_name)
+{
+ char *accessname = ctxt->accessname;
+ if (local_name)
{
- if (resource->lpLocalName)
- strcpyW(accessname, resource->lpLocalName);
- else
- strcpyW(accessname, resource->lpRemoteName);
+ WideCharToMultiByte(CP_ACP, 0, local_name, -1, accessname, *ctxt->buffer_size, NULL, NULL);
+ if (ctxt->result)
+ *ctxt->result = CONNECT_LOCALDRIVE;
}
+ 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;
}
*/
DWORD WINAPI WNetCancelConnectionA( LPCSTR lpName, BOOL fForce )
{
- FIXME( "(%s, %d), stub\n", debugstr_a(lpName), fForce );
-
- return WN_SUCCESS;
+ return WNetCancelConnection2A(lpName, 0, fForce);
}
/*********************************************************************
*/
DWORD WINAPI WNetCancelConnectionW( LPCWSTR lpName, BOOL fForce )
{
- FIXME( "(%s, %d), stub\n", debugstr_w(lpName), fForce );
-
- return WN_SUCCESS;
+ return WNetCancelConnection2W(lpName, 0, fForce);
}
/*********************************************************************
*/
DWORD WINAPI WNetCancelConnection2A( LPCSTR lpName, DWORD dwFlags, BOOL fForce )
{
- FIXME( "(%s, %08X, %d), stub\n", debugstr_a(lpName), dwFlags, fForce );
+ DWORD ret;
+ WCHAR * name = strdupAtoW(lpName);
+ if (!name)
+ return ERROR_NOT_CONNECTED;
- return WN_SUCCESS;
+ ret = WNetCancelConnection2W(name, dwFlags, fForce);
+ HeapFree(GetProcessHeap(), 0, name);
+
+ return ret;
}
/*********************************************************************
*/
DWORD WINAPI WNetCancelConnection2W( LPCWSTR lpName, DWORD dwFlags, BOOL fForce )
{
- FIXME( "(%s, %08X, %d), stub\n", debugstr_w(lpName), dwFlags, fForce );
+ DWORD ret = WN_NO_NETWORK;
+ DWORD index;
- return WN_SUCCESS;
+ if (providerTable != NULL)
+ {
+ for (index = 0; index < providerTable->numProviders; index++)
+ {
+ if(providerTable->table[index].getCaps(WNNC_CONNECTION) &
+ WNNC_CON_CANCELCONNECTION)
+ {
+ if (providerTable->table[index].cancelConnection)
+ ret = providerTable->table[index].cancelConnection((LPWSTR)lpName, fForce);
+ else
+ ret = WN_NO_NETWORK;
+ if (ret == WN_SUCCESS || ret == WN_OPEN_FILES)
+ break;
+ }
+ }
+ }
+ return ret;
}
/*****************************************************************
/* find the network connection for a given drive; helper for WNetGetConnection */
static DWORD get_drive_connection( WCHAR letter, LPWSTR remote, LPDWORD size )
{
+#ifndef __REACTOS__
char buffer[1024];
struct mountmgr_unix_drive *data = (struct mountmgr_unix_drive *)buffer;
HANDLE mgr;
}
CloseHandle( mgr );
return ret;
+#else
+ DWORD ret = WN_NO_NETWORK;
+ DWORD index;
+ WCHAR local[3] = {letter, ':', 0};
+
+ if (providerTable != NULL)
+ {
+ for (index = 0; index < providerTable->numProviders; index++)
+ {
+ if(providerTable->table[index].getCaps(WNNC_CONNECTION) &
+ WNNC_CON_GETCONNECTIONS)
+ {
+ if (providerTable->table[index].getConnection)
+ ret = providerTable->table[index].getConnection(
+ local, remote, size);
+ else
+ ret = WN_NO_NETWORK;
+ if (ret == WN_SUCCESS || ret == WN_MORE_DATA)
+ break;
+ }
+ }
+ }
+ if (ret)
+ SetLastError(ret);
+ return ret;
+#endif
}
/**************************************************************************
break;
}
case REMOTE_NAME_INFO_LEVEL:
- err = WN_NO_NETWORK;
+ err = WN_NOT_CONNECTED;
break;
default:
break;
}
case REMOTE_NAME_INFO_LEVEL:
- err = WN_NOT_CONNECTED;
+ err = WN_NO_NETWORK;
break;
default: