Author: pschweitzer
Date: Tue Aug 2 10:04:19 2016
New Revision: 72087
URL:
http://svn.reactos.org/svn/reactos?rev=72087&view=rev
Log:
[MPR]
Implement connected resources enumeration
To be sent upstream.
Patch 6/6
CORE-11757
ROSAPPS-303
Modified:
trunk/reactos/dll/win32/mpr/wnet.c
Modified: trunk/reactos/dll/win32/mpr/wnet.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mpr/wnet.c?rev=7…
==============================================================================
--- trunk/reactos/dll/win32/mpr/wnet.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mpr/wnet.c [iso-8859-1] Tue Aug 2 10:04:19 2016
@@ -90,7 +90,7 @@
DWORD dwScope;
DWORD dwType;
DWORD dwUsage;
- LPNETRESOURCEW lpNet;
+ LPVOID lpBuffer;
} WNetEnumerator, *PWNetEnumerator;
#define BAD_PROVIDER_INDEX (DWORD)0xffffffff
@@ -416,7 +416,7 @@
ret->dwScope = dwScope;
ret->dwType = dwType;
ret->dwUsage = dwUsage;
- ret->lpNet = _copyNetResourceForEnumW(lpNet);
+ ret->lpBuffer = _copyNetResourceForEnumW(lpNet);
}
return ret;
}
@@ -456,6 +456,28 @@
ret->dwScope = dwScope;
ret->dwType = dwType;
ret->dwUsage = dwUsage;
+ }
+ 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;
}
@@ -821,8 +843,11 @@
ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
break;
case RESOURCE_REMEMBERED:
+ *lphEnum = _createNullEnumerator();
+ ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
+ break;
case RESOURCE_CONNECTED:
- *lphEnum = _createNullEnumerator();
+ *lphEnum = _createConnectedEnumerator(dwScope, dwType, dwUsage);
ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
break;
default:
@@ -1048,7 +1073,7 @@
{
ret = providerTable->table[enumerator->providerIndex].
openEnum(enumerator->dwScope, enumerator->dwType,
- enumerator->dwUsage, enumerator->lpNet,
+ enumerator->dwUsage, enumerator->lpBuffer,
&enumerator->handle);
if (ret == WN_SUCCESS)
{
@@ -1086,7 +1111,7 @@
switch (enumerator->dwScope)
{
case RESOURCE_GLOBALNET:
- if (enumerator->lpNet)
+ if (enumerator->lpBuffer)
ret = _enumerateGlobalPassthroughW(enumerator, lpcCount,
lpBuffer, lpBufferSize);
else
@@ -1203,6 +1228,143 @@
*lpBufferSize = bytesNeeded;
}
}
+ TRACE("Returning %d\n", ret);
+ 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;
}
@@ -1251,6 +1413,10 @@
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;
@@ -1267,7 +1433,8 @@
*/
DWORD WINAPI WNetCloseEnum( HANDLE hEnum )
{
- DWORD ret;
+ DWORD ret, index;
+ PHANDLE handles;
TRACE( "(%p)\n", hEnum );
@@ -1277,12 +1444,21 @@
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;
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);