Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
6.6 KiB

  1. //#include <winnetwk.h>
  2. #include "stdafx.h"
  3. #include "crawler.h"
  4. #include "theapp.h"
  5. void CNetCrawler::_EnumNetResources(LPNETRESOURCE pnr)
  6. {
  7. HANDLE hEnum = NULL;
  8. INT cPrinters = 0;
  9. INT cShares = 0;
  10. DWORD dwScope = RESOURCE_GLOBALNET;
  11. // If no net resource structure passed then lets enumerate the workgroup
  12. NETRESOURCE nr = { 0 };
  13. if (!pnr)
  14. {
  15. pnr = &nr;
  16. dwScope = RESOURCE_CONTEXT;
  17. nr.dwType = RESOURCETYPE_ANY;
  18. nr.dwUsage = RESOURCEUSAGE_CONTAINER;
  19. }
  20. DWORD dwres = WNetOpenEnum(dwScope, RESOURCETYPE_ANY, 0, pnr, &hEnum);
  21. if (NO_ERROR == dwres)
  22. {
  23. // Avoid putting the buffer on the stack
  24. NETRESOURCE *pnrBuffer = (NETRESOURCE*)LocalAlloc(LPTR, CB_WNET_BUFFER);
  25. if (pnrBuffer)
  26. {
  27. // WNetEnumResource() needs us to continue the enumeration
  28. do
  29. {
  30. DWORD cbEnumBuffer= CB_WNET_BUFFER;
  31. DWORD dwCount = -1;
  32. // Enumerate the resources for this enum context and then lets
  33. // Determine the objects which we should see.
  34. dwres = WNetEnumResource(hEnum, &dwCount, pnrBuffer, &cbEnumBuffer);
  35. if (NO_ERROR == dwres || (dwres == ERROR_MORE_DATA))
  36. {
  37. DWORD index;
  38. for (index = 0 ; index != dwCount; index++)
  39. {
  40. LPNETRESOURCE pnr = &pnrBuffer[index];
  41. LPTSTR pszRemoteName = pnr->lpRemoteName;
  42. switch (pnr->dwDisplayType)
  43. {
  44. case RESOURCEDISPLAYTYPE_NETWORK:
  45. _EnumNetResources(pnr);
  46. break;
  47. case RESOURCEDISPLAYTYPE_DOMAIN:
  48. if (_cItems < _iMaxItems || -1 == _iMaxItems)
  49. {
  50. LPTSTR pszName = (LPTSTR) LocalAlloc(LPTR, (lstrlen(pnr->lpRemoteName)+1)*sizeof(WCHAR));
  51. if (pszName)
  52. {
  53. lstrcpy(pszName, pnr->lpRemoteName);
  54. _cItems++;
  55. if (-1 == DPA_AppendPtr(_hdpaWorkGroups, pszName))
  56. LocalFree(pszName);
  57. }
  58. }
  59. else
  60. {
  61. goto ENUMERATION_DONE;
  62. }
  63. break;
  64. // Add code here if we want to enumerate more network resources
  65. case RESOURCEDISPLAYTYPE_SERVER:
  66. case RESOURCEDISPLAYTYPE_SHARE:
  67. default:
  68. break;
  69. }
  70. }
  71. }
  72. } while ((NO_ERROR == dwres || dwres == ERROR_MORE_DATA) && (_cItems < _iMaxItems));
  73. ENUMERATION_DONE:
  74. LocalFree(pnrBuffer);
  75. }
  76. WNetCloseEnum(hEnum);
  77. }
  78. }
  79. DWORD WINAPI CNetCrawler::_EnumWorkGroups(LPVOID pv)
  80. {
  81. CNetCrawler * pNC = (CNetCrawler *) pv;
  82. INT nMachines = 10;
  83. NETRESOURCE nr = { 0 };
  84. nr.dwScope = RESOURCE_GLOBALNET;
  85. nr.dwType = RESOURCETYPE_ANY;
  86. nr.dwUsage = RESOURCEUSAGE_CONTAINER;
  87. pNC->_hdpaWorkGroups = DPA_Create(pNC->_iMaxItems);
  88. if (pNC->_hdpaWorkGroups)
  89. pNC->_EnumNetResources(&nr);
  90. pNC->_dwStatus = NC_FINISHED;
  91. pNC->Release();
  92. return 0;
  93. }
  94. CNetCrawler::~CNetCrawler(void)
  95. {
  96. ASSERT (!_cRef);
  97. if (_hdpaWorkGroups)
  98. {
  99. int n = DPA_GetPtrCount(_hdpaWorkGroups);
  100. LPTSTR pszName;
  101. for (int i = 0; i < n; i++)
  102. {
  103. pszName = (LPTSTR) DPA_GetPtr(_hdpaWorkGroups, i);
  104. if (pszName)
  105. {
  106. LocalFree(pszName);
  107. }
  108. }
  109. DPA_Destroy(_hdpaWorkGroups);
  110. }
  111. }
  112. void CNetCrawler::Init(DWORD dwFlags, int nItems)
  113. {
  114. DWORD idThread;
  115. HANDLE hThread;
  116. _iMaxItems = nItems;
  117. AddRef();
  118. if (dwFlags | NC_INIT_WORKGROUPS)
  119. hThread = CreateThread(NULL, 0, _EnumWorkGroups, (void *) this, 0, &idThread);
  120. if (hThread)
  121. {
  122. // Thread handle is no use, close it right a way
  123. _dwStatus = 0;
  124. CloseHandle(hThread);
  125. }
  126. else
  127. Release();
  128. }
  129. HRESULT CNetCrawler::GetWorkGroupName(LPTSTR pszWorkGroupName, int cb, BOOL fBlocking)
  130. {
  131. ASSERT(pszWorkGroupName);
  132. LPTSTR psz;
  133. BOOL hr = S_OK;
  134. TCHAR szMSHOME[MAX_COMPUTERNAME_LENGTH+1];
  135. TCHAR szWORKGROUP[MAX_COMPUTERNAME_LENGTH+1];
  136. LoadString(g_hinst, IDS_DEFAULT_WORKGROUP1, szMSHOME, _countof(szMSHOME));
  137. LoadString(g_hinst, IDS_DEFAULT_WORKGROUP2, szWORKGROUP, _countof(szWORKGROUP));
  138. if (fBlocking && _hdpaWorkGroups && !(_dwStatus & NC_FINISHED))
  139. {
  140. // Blocking call - wait for thread to finish
  141. while (!(_dwStatus & NC_FINISHED))
  142. {}
  143. }
  144. if (_hdpaWorkGroups && _dwStatus & NC_FINISHED)
  145. {
  146. int n = DPA_GetPtrCount(_hdpaWorkGroups);
  147. BOOL fHaveWorkgroup = FALSE;
  148. LPTSTR pszUserDefined = NULL;
  149. for (int i = 0; i < n; i++)
  150. {
  151. LPTSTR pszWG = (LPTSTR)DPA_GetPtr(_hdpaWorkGroups, i);
  152. if (0 == StrCmpI(pszWG, szWORKGROUP))
  153. {
  154. fHaveWorkgroup = TRUE;
  155. }
  156. else if (0 != StrCmpI(pszWG, szMSHOME))
  157. {
  158. if (!pszUserDefined)
  159. {
  160. pszUserDefined = pszWG;
  161. }
  162. else
  163. {
  164. // Choose the "lesser" of the two user defined workgroups
  165. if (StrCmpI(pszUserDefined, pszWG) > 0)
  166. {
  167. pszUserDefined = pszWG;
  168. }
  169. }
  170. }
  171. }
  172. if (pszUserDefined)
  173. {
  174. // We have a user-defined workgroup
  175. psz = pszUserDefined;
  176. }
  177. else if (fHaveWorkgroup)
  178. {
  179. // We have a "WORKGROUP" workgroup
  180. psz = szWORKGROUP;
  181. }
  182. else
  183. {
  184. // Use "MSHOME"
  185. psz = szMSHOME;
  186. }
  187. }
  188. // Enumeration not done, use the MSHOME with E_PENDING return
  189. else
  190. {
  191. hr = E_PENDING;
  192. psz = szMSHOME;
  193. }
  194. if (psz)
  195. lstrcpyn(pszWorkGroupName, psz, cb);
  196. return hr;
  197. }