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.

280 lines
8.3 KiB

  1. #include "StdAfx.h"
  2. #include "WNetUtil.h"
  3. #ifdef _DEBUG
  4. #define new DEBUG_NEW
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. #define VALD_NETDOMAIN_ENUM 1000666 // bad pointer validation signature
  9. #define DOM_BUFFER_SIZE (32768) // buffer size held allocated by class
  10. class TNetDomainEnum
  11. {
  12. public:
  13. TNetDomainEnum();
  14. ~TNetDomainEnum();
  15. DWORD GetMsNetProvider( NETRESOURCE * resourceInfo, DWORD infoSize );
  16. WCHAR * GetNext();
  17. DWORD GetLastRc() const { return rc; };
  18. BOOL IsValid() const { return vald == VALD_NETDOMAIN_ENUM; };
  19. private:
  20. DWORD vald;
  21. HANDLE hEnum;
  22. NETRESOURCE * resourceBuffer;
  23. DWORD rc,
  24. totEntries,
  25. nextEntry,
  26. buffSize;
  27. };
  28. //-----------------------------------------------------------------------------
  29. // TNetDomainEnum::TNetDomainEnum
  30. //-----------------------------------------------------------------------------
  31. TNetDomainEnum::TNetDomainEnum()
  32. {
  33. //--------------------------
  34. // Initialize Class Members
  35. //--------------------------
  36. vald = VALD_NETDOMAIN_ENUM;
  37. hEnum = INVALID_HANDLE_VALUE;
  38. // init currEntry > totEntries to force first-time read
  39. totEntries = 0;
  40. nextEntry = 1;
  41. resourceBuffer = (NETRESOURCE *)new char[DOM_BUFFER_SIZE];
  42. if ( !resourceBuffer )
  43. {
  44. rc = 1;
  45. }
  46. else
  47. {
  48. //-----------------------------------
  49. // Determine Network Provider to Use
  50. //-----------------------------------
  51. char buffer[16384];
  52. NETRESOURCE * info = (NETRESOURCE *)buffer;
  53. rc = GetMsNetProvider( info, sizeof(buffer));
  54. if ( ! rc )
  55. {
  56. rc = WNetOpenEnum( RESOURCE_GLOBALNET,
  57. RESOURCETYPE_ANY,
  58. RESOURCEUSAGE_CONTAINER,
  59. info,
  60. &hEnum );
  61. delete [] info->lpProvider;
  62. }
  63. if ( rc )
  64. {
  65. if ( resourceBuffer )
  66. {
  67. delete resourceBuffer;
  68. resourceBuffer = NULL;
  69. }
  70. }
  71. }
  72. }
  73. //-----------------------------------------------------------------------------
  74. // TNetDomainEnum::~TNetDomainEnum
  75. //-----------------------------------------------------------------------------
  76. TNetDomainEnum::~TNetDomainEnum()
  77. {
  78. if ( hEnum != INVALID_HANDLE_VALUE )
  79. {
  80. WNetCloseEnum( hEnum );
  81. hEnum = INVALID_HANDLE_VALUE;
  82. }
  83. vald = 0;
  84. if ( resourceBuffer )
  85. {
  86. delete resourceBuffer;
  87. }
  88. }
  89. //-----------------------------------------------------------------------------
  90. // GetMsNetProvider - Retrieves network resource information for the 'Microsoft
  91. // Windows Network' provider.
  92. //
  93. // Input: A pointer to a NETRESOURCE structure that we will fill if we find a
  94. // resource meeting our needs.
  95. //
  96. // Output: 0 of we found a provider. resourceInfo populated in this case
  97. // non-zero if no provider. resourceInfo contents undefined
  98. //-----------------------------------------------------------------------------
  99. DWORD TNetDomainEnum::GetMsNetProvider( NETRESOURCE * resourceInfo, DWORD infoSize )
  100. {
  101. _TCHAR szProvider[_MAX_PATH];
  102. DWORD cchProvider = sizeof(szProvider) / sizeof(szProvider[0]);
  103. DWORD dwError = WNetGetProviderName(WNNC_NET_LANMAN, szProvider, &cchProvider);
  104. if (dwError == NO_ERROR)
  105. {
  106. memset(resourceInfo, 0, infoSize);
  107. resourceInfo->dwScope = RESOURCE_GLOBALNET;
  108. resourceInfo->dwType = RESOURCETYPE_ANY;
  109. resourceInfo->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
  110. resourceInfo->dwUsage = RESOURCEUSAGE_CONTAINER;
  111. resourceInfo->lpProvider = new _TCHAR[_tcslen(szProvider) + 1];
  112. if (resourceInfo->lpProvider)
  113. {
  114. _tcscpy(resourceInfo->lpProvider, szProvider);
  115. rc = NO_ERROR;
  116. }
  117. else
  118. {
  119. rc = ERROR_OUTOFMEMORY;
  120. }
  121. }
  122. else
  123. {
  124. rc = dwError;
  125. }
  126. return rc;
  127. }
  128. //-----------------------------------------------------------------------------
  129. // TNetDomainEnum::GetNext()
  130. //-----------------------------------------------------------------------------
  131. WCHAR *
  132. TNetDomainEnum::GetNext()
  133. {
  134. rc = (DWORD)-1; // init rc to internal error before reset
  135. if ( hEnum == INVALID_HANDLE_VALUE )
  136. return NULL;
  137. if ( !resourceBuffer )
  138. return NULL;
  139. if ( nextEntry >= totEntries )
  140. {
  141. buffSize = DOM_BUFFER_SIZE;
  142. totEntries = (DWORD)-1;
  143. rc = WNetEnumResource(
  144. hEnum,
  145. &totEntries,
  146. (void *)resourceBuffer,
  147. &buffSize );
  148. if ( rc == 0 )
  149. nextEntry = 0;
  150. else
  151. {
  152. totEntries = 0;
  153. return NULL;
  154. }
  155. }
  156. else
  157. rc = 0;
  158. return resourceBuffer[nextEntry++].lpRemoteName;
  159. }
  160. //#pragma page()
  161. /*============================================================================*\
  162. Windows Network Domain Enumeration APIs. These are a shell around the
  163. TNetDomainEnum class member function. The handle used is nothing more
  164. than the "this" pointer to the instantiated object.
  165. \*============================================================================*/
  166. //-----------------------------------------------------------------------------
  167. // EaWNetDomainEnumOpen
  168. //
  169. // Creates the enumeration object and gives the caller the handle
  170. //-----------------------------------------------------------------------------
  171. DWORD _stdcall // ret-0 or error code
  172. EaWNetDomainEnumOpen(
  173. void ** handle // out-opaque handle addr to enum
  174. )
  175. {
  176. TNetDomainEnum * domainEnum = new TNetDomainEnum();
  177. *handle = (PVOID)domainEnum;
  178. if ( ! domainEnum )
  179. return (DWORD)-1; // internal error
  180. return domainEnum->GetLastRc();
  181. }
  182. //-----------------------------------------------------------------------------
  183. // EaWNetDomainEnumNext
  184. //
  185. // Sets the domain string buffer to the next domain name in the enumeration
  186. //-----------------------------------------------------------------------------
  187. DWORD _stdcall // ret-0 or error code
  188. EaWNetDomainEnumNext(
  189. void * handle ,// i/o-opaque handle to enumeration
  190. EaWNetDomainInfo * domain // out-domain information structure
  191. )
  192. {
  193. TNetDomainEnum * domainEnum = (TNetDomainEnum *)handle;
  194. WCHAR * str;
  195. if ( !domainEnum || !domainEnum->IsValid() )
  196. return ERROR_INVALID_PARAMETER; // caller's error - invalid handle
  197. str = domainEnum->GetNext();
  198. if ( !str )
  199. {
  200. domain->name[0] = _T('\0');
  201. }
  202. else
  203. {
  204. wcsncpy(domain->name, str, EA_MAX_DOMAIN_NAME_SIZE);
  205. domain->name[EA_MAX_DOMAIN_NAME_SIZE - 1] = _T('\0');
  206. }
  207. return domainEnum->GetLastRc();
  208. }
  209. //-----------------------------------------------------------------------------
  210. // EaWNetDomainEnumFirst
  211. //
  212. // Sets the domain string buffer to the first domain name in the enumeration
  213. //-----------------------------------------------------------------------------
  214. DWORD _stdcall // ret-0 or error code
  215. EaWNetDomainEnumFirst(
  216. void * handle ,// i/o-opaque handle to enumeration
  217. EaWNetDomainInfo * domain // out-domain information structure
  218. )
  219. {
  220. // We're cheating here by making the first/next the same. We probably want to
  221. // change this eventually to make "first" really properly reset the enum to the
  222. // start
  223. return EaWNetDomainEnumNext(handle, domain);
  224. }
  225. //-----------------------------------------------------------------------------
  226. // EaWNetDomainEnumClose
  227. //
  228. // Closes and destroys the enumeration handle and the objects it contains
  229. //-----------------------------------------------------------------------------
  230. DWORD _stdcall // ret-0 or error code
  231. EaWNetDomainEnumClose(
  232. void * handle // i/o-opaque handle addr to enum
  233. )
  234. {
  235. TNetDomainEnum * domainEnum = (TNetDomainEnum *)handle;
  236. if ( !domainEnum || !domainEnum->IsValid() )
  237. return ERROR_INVALID_PARAMETER; // caller's error - invalid handle
  238. delete domainEnum;
  239. return 0;
  240. }