📄 wnet.c
字号:
static PWNetEnumerator _createNullEnumerator(void)
{
PWNetEnumerator ret = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));
if (ret)
ret->enumType = WNET_ENUMERATOR_TYPE_NULL;
return ret;
}
static PWNetEnumerator _createGlobalEnumeratorW(DWORD dwScope, DWORD dwType,
DWORD dwUsage, LPNETRESOURCEW lpNet)
{
PWNetEnumerator ret = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));
if (ret)
{
ret->enumType = WNET_ENUMERATOR_TYPE_GLOBAL;
ret->dwScope = dwScope;
ret->dwType = dwType;
ret->dwUsage = dwUsage;
ret->lpNet = _copyNetResourceForEnumW(lpNet);
}
return ret;
}
static PWNetEnumerator _createProviderEnumerator(DWORD dwScope, DWORD dwType,
DWORD dwUsage, DWORD index, HANDLE handle)
{
PWNetEnumerator ret;
if (!providerTable || index >= providerTable->numProviders)
ret = NULL;
else
{
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));
if (ret)
{
ret->enumType = WNET_ENUMERATOR_TYPE_PROVIDER;
ret->providerIndex = index;
ret->dwScope = dwScope;
ret->dwType = dwType;
ret->dwUsage = dwUsage;
ret->handle = handle;
}
}
return ret;
}
static PWNetEnumerator _createContextEnumerator(DWORD dwScope, DWORD dwType,
DWORD dwUsage)
{
PWNetEnumerator ret = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));
if (ret)
{
ret->enumType = WNET_ENUMERATOR_TYPE_CONTEXT;
ret->dwScope = dwScope;
ret->dwType = dwType;
ret->dwUsage = dwUsage;
}
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.
* Returns WN_SUCCESS on success (all of lpNetArrayIn thunked), WN_MORE_DATA
* if not all members of the array could be thunked, and something else on
* failure.
*/
static DWORD _thunkNetResourceArrayWToA(const NETRESOURCEW *lpNetArrayIn,
const DWORD *lpcCount, LPVOID lpBuffer, const DWORD *lpBufferSize)
{
DWORD i, numToThunk, totalBytes, ret;
LPSTR strNext;
if (!lpNetArrayIn)
return WN_BAD_POINTER;
if (!lpcCount)
return WN_BAD_POINTER;
if (*lpcCount == -1)
return WN_BAD_VALUE;
if (!lpBuffer)
return WN_BAD_POINTER;
if (!lpBufferSize)
return WN_BAD_POINTER;
for (i = 0, numToThunk = 0, totalBytes = 0; i < *lpcCount; i++)
{
const NETRESOURCEW *lpNet = lpNetArrayIn + i;
totalBytes += sizeof(NETRESOURCEA);
if (lpNet->lpLocalName)
totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpLocalName,
-1, NULL, 0, NULL, NULL);
if (lpNet->lpRemoteName)
totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpRemoteName,
-1, NULL, 0, NULL, NULL);
if (lpNet->lpComment)
totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpComment,
-1, NULL, 0, NULL, NULL);
if (lpNet->lpProvider)
totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpProvider,
-1, NULL, 0, NULL, NULL);
if (totalBytes < *lpBufferSize)
numToThunk = i + 1;
}
strNext = (LPSTR)((LPBYTE)lpBuffer + numToThunk * sizeof(NETRESOURCEA));
for (i = 0; i < numToThunk; i++)
{
LPNETRESOURCEA lpNetOut = (LPNETRESOURCEA)lpBuffer + i;
const NETRESOURCEW *lpNetIn = lpNetArrayIn + i;
memcpy(lpNetOut, lpNetIn, sizeof(NETRESOURCEA));
/* lie about string lengths, we already verified how many
* we have space for above
*/
if (lpNetIn->lpLocalName)
{
lpNetOut->lpLocalName = strNext;
strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpLocalName, -1,
lpNetOut->lpLocalName, *lpBufferSize, NULL, NULL);
}
if (lpNetIn->lpRemoteName)
{
lpNetOut->lpRemoteName = strNext;
strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpRemoteName, -1,
lpNetOut->lpRemoteName, *lpBufferSize, NULL, NULL);
}
if (lpNetIn->lpComment)
{
lpNetOut->lpComment = strNext;
strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpComment, -1,
lpNetOut->lpComment, *lpBufferSize, NULL, NULL);
}
if (lpNetIn->lpProvider)
{
lpNetOut->lpProvider = strNext;
strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpProvider, -1,
lpNetOut->lpProvider, *lpBufferSize, NULL, NULL);
}
}
ret = numToThunk < *lpcCount ? WN_MORE_DATA : WN_SUCCESS;
TRACE("numToThunk is %d, *lpcCount is %d, returning %d\n", numToThunk,
*lpcCount, ret);
return ret;
}
/* Thunks the array of multibyte-string LPNETRESOURCEs lpNetArrayIn into buffer
* lpBuffer, with size *lpBufferSize. lpNetArrayIn contains *lpcCount entries
* to start. On return, *lpcCount reflects the number thunked into lpBuffer.
* Returns WN_SUCCESS on success (all of lpNetArrayIn thunked), WN_MORE_DATA
* if not all members of the array could be thunked, and something else on
* failure.
*/
static DWORD _thunkNetResourceArrayAToW(const NETRESOURCEA *lpNetArrayIn,
const DWORD *lpcCount, LPVOID lpBuffer, const DWORD *lpBufferSize)
{
DWORD i, numToThunk, totalBytes, ret;
LPWSTR strNext;
if (!lpNetArrayIn)
return WN_BAD_POINTER;
if (!lpcCount)
return WN_BAD_POINTER;
if (*lpcCount == -1)
return WN_BAD_VALUE;
if (!lpBuffer)
return WN_BAD_POINTER;
if (!lpBufferSize)
return WN_BAD_POINTER;
for (i = 0, numToThunk = 0, totalBytes = 0; i < *lpcCount; i++)
{
const NETRESOURCEA *lpNet = lpNetArrayIn + i;
totalBytes += sizeof(NETRESOURCEW);
if (lpNet->lpLocalName)
totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpLocalName,
-1, NULL, 0) * sizeof(WCHAR);
if (lpNet->lpRemoteName)
totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpRemoteName,
-1, NULL, 0) * sizeof(WCHAR);
if (lpNet->lpComment)
totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpComment,
-1, NULL, 0) * sizeof(WCHAR);
if (lpNet->lpProvider)
totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpProvider,
-1, NULL, 0) * sizeof(WCHAR);
if (totalBytes < *lpBufferSize)
numToThunk = i + 1;
}
strNext = (LPWSTR)((LPBYTE)lpBuffer + numToThunk * sizeof(NETRESOURCEW));
for (i = 0; i < numToThunk; i++)
{
LPNETRESOURCEW lpNetOut = (LPNETRESOURCEW)lpBuffer + i;
const NETRESOURCEA *lpNetIn = lpNetArrayIn + i;
memcpy(lpNetOut, lpNetIn, sizeof(NETRESOURCEW));
/* lie about string lengths, we already verified how many
* we have space for above
*/
if (lpNetIn->lpLocalName)
{
lpNetOut->lpLocalName = strNext;
strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpLocalName,
-1, lpNetOut->lpLocalName, *lpBufferSize);
}
if (lpNetIn->lpRemoteName)
{
lpNetOut->lpRemoteName = strNext;
strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpRemoteName,
-1, lpNetOut->lpRemoteName, *lpBufferSize);
}
if (lpNetIn->lpComment)
{
lpNetOut->lpComment = strNext;
strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpComment,
-1, lpNetOut->lpComment, *lpBufferSize);
}
if (lpNetIn->lpProvider)
{
lpNetOut->lpProvider = strNext;
strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpProvider,
-1, lpNetOut->lpProvider, *lpBufferSize);
}
}
ret = numToThunk < *lpcCount ? WN_MORE_DATA : WN_SUCCESS;
TRACE("numToThunk is %d, *lpcCount is %d, returning %d\n", numToThunk,
*lpcCount, ret);
return ret;
}
/*********************************************************************
* WNetOpenEnumA [MPR.@]
*
* See comments for WNetOpenEnumW.
*/
DWORD WINAPI WNetOpenEnumA( DWORD dwScope, DWORD dwType, DWORD dwUsage,
LPNETRESOURCEA lpNet, LPHANDLE lphEnum )
{
DWORD ret;
TRACE( "(%08X, %08X, %08X, %p, %p)\n",
dwScope, dwType, dwUsage, lpNet, lphEnum );
if (!lphEnum)
ret = WN_BAD_POINTER;
else if (!providerTable || providerTable->numProviders == 0)
ret = WN_NO_NETWORK;
else
{
if (lpNet)
{
LPNETRESOURCEW lpNetWide = NULL;
BYTE buf[1024];
DWORD size = sizeof(buf), count = 1;
BOOL allocated = FALSE;
ret = _thunkNetResourceArrayAToW(lpNet, &count, buf, &size);
if (ret == WN_MORE_DATA)
{
lpNetWide = HeapAlloc(GetProcessHeap(), 0,
size);
if (lpNetWide)
{
ret = _thunkNetResourceArrayAToW(lpNet, &count, lpNetWide,
&size);
allocated = TRUE;
}
else
ret = WN_OUT_OF_MEMORY;
}
else if (ret == WN_SUCCESS)
lpNetWide = (LPNETRESOURCEW)buf;
if (ret == WN_SUCCESS)
ret = WNetOpenEnumW(dwScope, dwType, dwUsage, lpNetWide,
lphEnum);
if (allocated)
HeapFree(GetProcessHeap(), 0, lpNetWide);
}
else
ret = WNetOpenEnumW(dwScope, dwType, dwUsage, NULL, lphEnum);
}
if (ret)
SetLastError(ret);
TRACE("Returning %d\n", ret);
return ret;
}
/*********************************************************************
* WNetOpenEnumW [MPR.@]
*
* Network enumeration has way too many parameters, so I'm not positive I got
* them right. What I've got so far:
*
* - If the scope is RESOURCE_GLOBALNET, and no LPNETRESOURCE is passed,
* all the network providers should be enumerated.
*
* - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and
* and neither the LPNETRESOURCE's lpRemoteName nor the LPNETRESOURCE's
* lpProvider is set, all the network providers should be enumerated.
* (This means the enumeration is a list of network providers, not that the
* enumeration is passed on to the providers.)
*
* - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and the
* resource matches the "Entire Network" resource (no remote name, no
* provider, comment is the "Entire Network" string), a RESOURCE_GLOBALNET
* enumeration is done on every network provider.
*
* - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and
* the LPNETRESOURCE's lpProvider is set, enumeration will be passed through
* only to the given network provider.
*
* - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and
* no lpProvider is set, enumeration will be tried on every network provider,
* in the order in which they're loaded.
*
* - The LPNETRESOURCE should be disregarded for scopes besides
* RESOURCE_GLOBALNET. MSDN states that lpNet must be NULL if dwScope is not
* RESOURCE_GLOBALNET, but Windows doesn't return an error if it isn't NULL.
*
* - If the scope is RESOURCE_CONTEXT, MS includes an "Entire Network" net
* resource in the enumerated list, as well as any machines in your
* workgroup. The machines in your workgroup come from doing a
* RESOURCE_CONTEXT enumeration of every Network Provider.
*/
DWORD WINAPI WNetOpenEnumW( DWORD dwScope, DWORD dwType, DWORD dwUsage,
LPNETRESOURCEW lpNet, LPHANDLE lphEnum )
{
DWORD ret;
TRACE( "(%08X, %08X, %08X, %p, %p)\n",
dwScope, dwType, dwUsage, lpNet, lphEnum );
if (!lphEnum)
ret = WN_BAD_POINTER;
else if (!providerTable || providerTable->numProviders == 0)
ret = WN_NO_NETWORK;
else
{
switch (dwScope)
{
case RESOURCE_GLOBALNET:
if (lpNet)
{
if (lpNet->lpProvider)
{
DWORD index = _findProviderIndexW(lpNet->lpProvider);
if (index != BAD_PROVIDER_INDEX)
{
if (providerTable->table[index].openEnum &&
providerTable->table[index].dwEnumScopes & dwScope)
{
HANDLE handle;
ret = providerTable->table[index].openEnum(
dwScope, dwType, dwUsage, lpNet, &handle);
if (ret == WN_SUCCESS)
{
*lphEnum =
(HANDLE)_createProviderEnumerator(
dwScope, dwType, dwUsage, index, handle);
ret = *lphEnum ? WN_SUCCESS :
WN_OUT_OF_MEMORY;
}
}
else
ret = WN_NOT_SUPPORTED;
}
else
ret = WN_BAD_PROVIDER;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -