windows-nt/Source/XPSP1/NT/shell/ext/hnw/wizard/crawler.cpp
2020-09-26 16:20:57 +08:00

248 lines
6.6 KiB
C++

//#include <winnetwk.h>
#include "stdafx.h"
#include "crawler.h"
#include "theapp.h"
void CNetCrawler::_EnumNetResources(LPNETRESOURCE pnr)
{
HANDLE hEnum = NULL;
INT cPrinters = 0;
INT cShares = 0;
DWORD dwScope = RESOURCE_GLOBALNET;
// If no net resource structure passed then lets enumerate the workgroup
NETRESOURCE nr = { 0 };
if (!pnr)
{
pnr = &nr;
dwScope = RESOURCE_CONTEXT;
nr.dwType = RESOURCETYPE_ANY;
nr.dwUsage = RESOURCEUSAGE_CONTAINER;
}
DWORD dwres = WNetOpenEnum(dwScope, RESOURCETYPE_ANY, 0, pnr, &hEnum);
if (NO_ERROR == dwres)
{
// Avoid putting the buffer on the stack
NETRESOURCE *pnrBuffer = (NETRESOURCE*)LocalAlloc(LPTR, CB_WNET_BUFFER);
if (pnrBuffer)
{
// WNetEnumResource() needs us to continue the enumeration
do
{
DWORD cbEnumBuffer= CB_WNET_BUFFER;
DWORD dwCount = -1;
// Enumerate the resources for this enum context and then lets
// Determine the objects which we should see.
dwres = WNetEnumResource(hEnum, &dwCount, pnrBuffer, &cbEnumBuffer);
if (NO_ERROR == dwres || (dwres == ERROR_MORE_DATA))
{
DWORD index;
for (index = 0 ; index != dwCount; index++)
{
LPNETRESOURCE pnr = &pnrBuffer[index];
LPTSTR pszRemoteName = pnr->lpRemoteName;
switch (pnr->dwDisplayType)
{
case RESOURCEDISPLAYTYPE_NETWORK:
_EnumNetResources(pnr);
break;
case RESOURCEDISPLAYTYPE_DOMAIN:
if (_cItems < _iMaxItems || -1 == _iMaxItems)
{
LPTSTR pszName = (LPTSTR) LocalAlloc(LPTR, (lstrlen(pnr->lpRemoteName)+1)*sizeof(WCHAR));
if (pszName)
{
lstrcpy(pszName, pnr->lpRemoteName);
_cItems++;
if (-1 == DPA_AppendPtr(_hdpaWorkGroups, pszName))
LocalFree(pszName);
}
}
else
{
goto ENUMERATION_DONE;
}
break;
// Add code here if we want to enumerate more network resources
case RESOURCEDISPLAYTYPE_SERVER:
case RESOURCEDISPLAYTYPE_SHARE:
default:
break;
}
}
}
} while ((NO_ERROR == dwres || dwres == ERROR_MORE_DATA) && (_cItems < _iMaxItems));
ENUMERATION_DONE:
LocalFree(pnrBuffer);
}
WNetCloseEnum(hEnum);
}
}
DWORD WINAPI CNetCrawler::_EnumWorkGroups(LPVOID pv)
{
CNetCrawler * pNC = (CNetCrawler *) pv;
INT nMachines = 10;
NETRESOURCE nr = { 0 };
nr.dwScope = RESOURCE_GLOBALNET;
nr.dwType = RESOURCETYPE_ANY;
nr.dwUsage = RESOURCEUSAGE_CONTAINER;
pNC->_hdpaWorkGroups = DPA_Create(pNC->_iMaxItems);
if (pNC->_hdpaWorkGroups)
pNC->_EnumNetResources(&nr);
pNC->_dwStatus = NC_FINISHED;
pNC->Release();
return 0;
}
CNetCrawler::~CNetCrawler(void)
{
ASSERT (!_cRef);
if (_hdpaWorkGroups)
{
int n = DPA_GetPtrCount(_hdpaWorkGroups);
LPTSTR pszName;
for (int i = 0; i < n; i++)
{
pszName = (LPTSTR) DPA_GetPtr(_hdpaWorkGroups, i);
if (pszName)
{
LocalFree(pszName);
}
}
DPA_Destroy(_hdpaWorkGroups);
}
}
void CNetCrawler::Init(DWORD dwFlags, int nItems)
{
DWORD idThread;
HANDLE hThread;
_iMaxItems = nItems;
AddRef();
if (dwFlags | NC_INIT_WORKGROUPS)
hThread = CreateThread(NULL, 0, _EnumWorkGroups, (void *) this, 0, &idThread);
if (hThread)
{
// Thread handle is no use, close it right a way
_dwStatus = 0;
CloseHandle(hThread);
}
else
Release();
}
HRESULT CNetCrawler::GetWorkGroupName(LPTSTR pszWorkGroupName, int cb, BOOL fBlocking)
{
ASSERT(pszWorkGroupName);
LPTSTR psz;
BOOL hr = S_OK;
TCHAR szMSHOME[MAX_COMPUTERNAME_LENGTH+1];
TCHAR szWORKGROUP[MAX_COMPUTERNAME_LENGTH+1];
LoadString(g_hinst, IDS_DEFAULT_WORKGROUP1, szMSHOME, _countof(szMSHOME));
LoadString(g_hinst, IDS_DEFAULT_WORKGROUP2, szWORKGROUP, _countof(szWORKGROUP));
if (fBlocking && _hdpaWorkGroups && !(_dwStatus & NC_FINISHED))
{
// Blocking call - wait for thread to finish
while (!(_dwStatus & NC_FINISHED))
{}
}
if (_hdpaWorkGroups && _dwStatus & NC_FINISHED)
{
int n = DPA_GetPtrCount(_hdpaWorkGroups);
BOOL fHaveWorkgroup = FALSE;
LPTSTR pszUserDefined = NULL;
for (int i = 0; i < n; i++)
{
LPTSTR pszWG = (LPTSTR)DPA_GetPtr(_hdpaWorkGroups, i);
if (0 == StrCmpI(pszWG, szWORKGROUP))
{
fHaveWorkgroup = TRUE;
}
else if (0 != StrCmpI(pszWG, szMSHOME))
{
if (!pszUserDefined)
{
pszUserDefined = pszWG;
}
else
{
// Choose the "lesser" of the two user defined workgroups
if (StrCmpI(pszUserDefined, pszWG) > 0)
{
pszUserDefined = pszWG;
}
}
}
}
if (pszUserDefined)
{
// We have a user-defined workgroup
psz = pszUserDefined;
}
else if (fHaveWorkgroup)
{
// We have a "WORKGROUP" workgroup
psz = szWORKGROUP;
}
else
{
// Use "MSHOME"
psz = szMSHOME;
}
}
// Enumeration not done, use the MSHOME with E_PENDING return
else
{
hr = E_PENDING;
psz = szMSHOME;
}
if (psz)
lstrcpyn(pszWorkGroupName, psz, cb);
return hr;
}