Leaked source code of windows server 2003
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.

2194 lines
64 KiB

  1. //
  2. // browsesrv.cpp: browse for servers list box
  3. //
  4. // This file is built for both UNICODE and ANSI
  5. // and is shared between the mstsc replacement (clshell) and
  6. // the mmc client
  7. //
  8. #include "stdafx.h"
  9. #include "browsesrv.h"
  10. //#include "atlconv.h"
  11. #include "winsock.h"
  12. #include "wuiids.h"
  13. CBrowseServersCtl::CBrowseServersCtl(HINSTANCE hResInstance) : _hInst(hResInstance)
  14. {
  15. bIsWin95 = FALSE;
  16. hLibrary = NULL;
  17. #ifndef OS_WINCE
  18. lpfnNetServerEnum = NULL;
  19. lpfnNetApiBufferFree = NULL;
  20. lpfnNetServerEnum2 = NULL;
  21. lpfnNetWkStaGetInfo = NULL;
  22. lpfnNetWkStaGetInfo_NT = NULL;
  23. lpfnDsGetDcName = NULL;
  24. lpfnNetEnumerateTrustedDomains = NULL;
  25. #else
  26. lpfnWNetOpenEnum = NULL;
  27. lpfnWNetEnumResource = NULL;
  28. lpfnWNetCloseEnum = NULL;
  29. #endif
  30. _fbrowseDNSDomain = FALSE;
  31. _hEvent = NULL;
  32. _hwndDialog = NULL;
  33. _refCount = 0;
  34. _nServerImage=0;
  35. _nDomainImage=0;
  36. _nDomainSelectedImage=0;
  37. _hPrev = (HTREEITEM) TVI_FIRST;
  38. _hPrevRootItem = NULL;
  39. _hPrevLev2Item = NULL;
  40. }
  41. CBrowseServersCtl::~CBrowseServersCtl()
  42. {
  43. // ASSERT(0 == _refCount);
  44. #ifdef OS_WINCE
  45. if (hLibrary)
  46. FreeLibrary(hLibrary);
  47. #endif
  48. }
  49. //
  50. // Ref count mechanism is used to control lifetime because up to two threads
  51. // use this class and have different lifetimes..
  52. //
  53. DCINT CBrowseServersCtl::AddRef()
  54. {
  55. #ifdef OS_WIN32
  56. return InterlockedIncrement( ( LPLONG )&_refCount );
  57. #else
  58. return InterlockedIncrement( ++_refCount );
  59. #endif
  60. }
  61. DCINT CBrowseServersCtl::Release()
  62. {
  63. #ifdef OS_WIN32
  64. if( InterlockedDecrement( ( LPLONG )&_refCount ) == 0 )
  65. #else
  66. if(0 == --_refCount)
  67. #endif
  68. {
  69. delete this;
  70. return 0;
  71. }
  72. return _refCount;
  73. }
  74. //
  75. // Initialize the image lists
  76. //
  77. #define NUM_IMGLIST_ICONS 2
  78. BOOL CBrowseServersCtl::Init(HWND hwndDlg)
  79. {
  80. HIMAGELIST himl; // handle to image list
  81. HICON hIcon; // handle to icon
  82. HWND hwndTV = NULL;
  83. UINT uFlags = TRUE;
  84. int cxSmIcon;
  85. int cySmIcon;
  86. cxSmIcon = GetSystemMetrics(SM_CXSMICON);
  87. cySmIcon = GetSystemMetrics(SM_CYSMICON);
  88. hwndTV = GetDlgItem( hwndDlg, UI_IDC_SERVERS_TREE);
  89. if(!hwndTV)
  90. {
  91. return FALSE;
  92. }
  93. // Create the image list.
  94. if ((himl = ImageList_Create(cxSmIcon, cySmIcon,
  95. TRUE, NUM_IMGLIST_ICONS, 1)) == NULL)
  96. {
  97. return FALSE;
  98. }
  99. // Add icons for the tree (computer, domain)
  100. hIcon = (HICON)LoadImage(_hInst, MAKEINTRESOURCE(UI_IDI_SERVER), IMAGE_ICON,
  101. cxSmIcon, cySmIcon, LR_DEFAULTCOLOR);
  102. if (hIcon)
  103. {
  104. _nServerImage = ImageList_AddIcon(himl, hIcon);
  105. DestroyIcon(hIcon);
  106. }
  107. hIcon = (HICON)LoadImage(_hInst, MAKEINTRESOURCE(UI_IDI_DOMAIN), IMAGE_ICON,
  108. cxSmIcon, cySmIcon, LR_DEFAULTCOLOR);
  109. if (hIcon)
  110. {
  111. _nDomainImage = ImageList_AddIcon(himl, hIcon);
  112. DestroyIcon(hIcon);
  113. }
  114. // Fail if not all of the images were added.
  115. if (ImageList_GetImageCount(himl) < NUM_IMGLIST_ICONS)
  116. return FALSE;
  117. // Associate the image list with the tree view control.
  118. TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
  119. return TRUE;
  120. }
  121. //
  122. // Cleanup any image lists that need to be freed
  123. //
  124. BOOL CBrowseServersCtl::Cleanup()
  125. {
  126. return TRUE;
  127. }
  128. #ifdef OS_WIN32
  129. /****************************************************************************/
  130. /* Name: PopulateListBox */
  131. /* */
  132. /* Purpose: Fills in the owner-draw list box with the Hydra servers */
  133. /* */
  134. /* Returns: pointer to a domain list box item array. */
  135. /* */
  136. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  137. /****************************************************************************/
  138. ServerListItem*
  139. CBrowseServersCtl::PopulateListBox(
  140. HWND hwndDlg,
  141. DCUINT *pDomainCount
  142. )
  143. {
  144. //
  145. // check to see we are running on win9x and call out appropriate worker
  146. // routine.
  147. //
  148. #ifndef OS_WINCE
  149. if( bIsWin95 == TRUE ) {
  150. return( PopulateListBox95(hwndDlg, pDomainCount) );
  151. }
  152. #endif
  153. return( PopulateListBoxNT(hwndDlg, pDomainCount) );
  154. }
  155. #ifndef OS_WINCE
  156. /****************************************************************************/
  157. /* Name: PopulateListBox95 */
  158. /* */
  159. /* Purpose: Fills in the owner-draw list box with the Hydra servers */
  160. /* */
  161. /* Returns: pointer to a domain list box item array. */
  162. /* */
  163. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  164. /****************************************************************************/
  165. ServerListItem*
  166. CBrowseServersCtl::PopulateListBox95(
  167. HWND hwndDlg,
  168. DCUINT *pDomainCount
  169. )
  170. {
  171. DWORD dwError;
  172. ServerListItem *plbi = NULL;
  173. ServerListItem *plbiAllotted = NULL;
  174. ServerListItem *plbiReturned = NULL;
  175. DWORD dwIndex = 0;
  176. struct wksta_info_10 *pwki10 = NULL;
  177. unsigned short cb;
  178. DWORD dwDomains;
  179. int nCount;
  180. HWND hTree = NULL;
  181. hTree = GetDlgItem( hwndDlg, UI_IDC_SERVERS_TREE );
  182. //
  183. // set return parameters to zero first.
  184. //
  185. *pDomainCount = 0;
  186. //
  187. // check to see the load library was done before calling this
  188. // routine, if not, simply return.
  189. //
  190. if( lpfnNetWkStaGetInfo == NULL ) {
  191. dwError = ERROR_INVALID_DATA;
  192. goto Cleanup;
  193. }
  194. if( hwndDlg == NULL ) {
  195. dwError = ERROR_INVALID_HANDLE;
  196. goto Cleanup;
  197. }
  198. //
  199. // get work group domain.
  200. //
  201. dwError = (*lpfnNetWkStaGetInfo)(NULL, 10, NULL, 0, &cb);
  202. if( dwError != NERR_BufTooSmall ) {
  203. goto Cleanup;
  204. }
  205. //
  206. // allocated required buffer size.
  207. //
  208. pwki10 = (struct wksta_info_10 *)LocalAlloc(LMEM_FIXED, cb);
  209. if( pwki10 == NULL ){
  210. dwError = ERROR_OUTOFMEMORY;
  211. goto Cleanup;
  212. }
  213. //
  214. // query again.
  215. //
  216. dwError = (*lpfnNetWkStaGetInfo)(NULL, 10, (char *)pwki10, cb, &cb);
  217. if( dwError != ERROR_SUCCESS ) {
  218. goto Cleanup;
  219. }
  220. //
  221. // check to see we are browsing a dns domain also, if so, allocated 2 list
  222. // entries.
  223. //
  224. dwDomains = _fbrowseDNSDomain ? 2 : 1;
  225. plbiAllotted = plbi =
  226. (ServerListItem*)LocalAlloc( LMEM_FIXED, sizeof(ServerListItem) * dwDomains );
  227. if( plbiAllotted == NULL ) {
  228. dwError = ERROR_OUTOFMEMORY;
  229. goto Cleanup;
  230. }
  231. //
  232. // display and expand DNS domain if we need to.
  233. //
  234. if( _fbrowseDNSDomain ) {
  235. _tcscpy( plbi->ContainerName, (LPTSTR)_browseDNSDomainName );
  236. plbi->Comment[0] = _T('\0');
  237. plbi->bContainsServers = TRUE;
  238. plbi->bServersExpandedOnce = FALSE;
  239. plbi->bDNSDomain = TRUE;
  240. plbi->nServerCount = 0;
  241. plbi->ServerItems = NULL;
  242. AddItemToTree( hTree, plbi->ContainerName, NULL,
  243. plbi, SRV_TREE_DOMAINLEVEL);
  244. //
  245. // Expand DNS Domain
  246. //
  247. ExpandDomain(hwndDlg, plbi->ContainerName, plbi, &dwIndex);
  248. //
  249. // move to the next list box entry.
  250. //
  251. plbi++;
  252. }
  253. //
  254. // fill up the work group domain now.
  255. //
  256. #ifdef UNICODE
  257. //
  258. // convert to UNICODE.
  259. //
  260. nCount =
  261. MultiByteToWideChar(
  262. CP_ACP,
  263. MB_COMPOSITE,
  264. (LPSTR)pwki10->wki10_langroup,
  265. -1,
  266. plbi->ContainerName,
  267. sizeof(plbi->ContainerName)/sizeof(WCHAR));
  268. if( nCount == 0 )
  269. {
  270. dwError = GetLastError();
  271. goto Cleanup;
  272. }
  273. #else
  274. _tcscpy( plbi->ContainerName, pwki10->wki10_langroup );
  275. #endif
  276. plbi->Comment[0] = _T('\0');
  277. plbi->bContainsServers = TRUE;
  278. plbi->bServersExpandedOnce = FALSE;
  279. plbi->bDNSDomain = FALSE;
  280. plbi->nServerCount = 0;
  281. plbi->ServerItems = NULL;
  282. AddItemToTree( hTree, plbi->ContainerName, NULL,
  283. plbi, SRV_TREE_DOMAINLEVEL);
  284. //
  285. // Expand the present Domain
  286. //
  287. ExpandDomain(hwndDlg, NULL, plbi, &dwIndex);
  288. //
  289. // we successfully populated the domain list,
  290. // set return parameters.
  291. //
  292. plbiReturned = plbiAllotted;
  293. *pDomainCount = dwDomains;
  294. plbiAllotted = NULL;
  295. dwError = ERROR_SUCCESS;
  296. Cleanup:
  297. if( plbiAllotted != NULL ) {
  298. LocalFree(plbiAllotted);
  299. }
  300. if( pwki10 != NULL ) {
  301. LocalFree(pwki10);
  302. }
  303. SetLastError( dwError );
  304. return plbiReturned;
  305. }
  306. #endif
  307. /****************************************************************************/
  308. /* Name: PopulateListBoxNT */
  309. /* */
  310. /* Purpose: Fills in the owner-draw list box with the Hydra servers */
  311. /* */
  312. /* Returns: pointer to a domain list box item array. */
  313. /* */
  314. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  315. /****************************************************************************/
  316. ServerListItem*
  317. CBrowseServersCtl::PopulateListBoxNT(
  318. HWND hwndDlg,
  319. DCUINT *pdwDomainCount
  320. )
  321. {
  322. DWORD dwError;
  323. PDCTCHAR pchTrustedDomains = NULL;
  324. PDCTCHAR pchTDomain;
  325. DCUINT dwDomainCount = 0;
  326. ServerListItem *plbiAllotted = NULL;
  327. ServerListItem *plbiReturned = NULL;
  328. ServerListItem *plbi;
  329. HWND hTree = NULL;
  330. DWORD dwDlgIndex=0;
  331. DWORD i;
  332. hTree = GetDlgItem( hwndDlg, UI_IDC_SERVERS_TREE );
  333. //
  334. // set the return parameter to zero first.
  335. //
  336. *pdwDomainCount = 0;
  337. if( hwndDlg == NULL ) {
  338. dwError = ERROR_INVALID_HANDLE;
  339. goto Cleanup;
  340. }
  341. //
  342. // enumurate trusted domain names.
  343. //
  344. pchTrustedDomains = UIGetTrustedDomains();
  345. if( pchTrustedDomains == NULL ) {
  346. dwError = ERROR_CANT_ACCESS_DOMAIN_INFO;
  347. goto Cleanup;
  348. }
  349. //
  350. // count number of domains.
  351. //
  352. pchTDomain = pchTrustedDomains;
  353. while( *pchTDomain != _T('\0') ) {
  354. dwDomainCount++;
  355. pchTDomain += (_tcslen(pchTDomain) + 1);
  356. }
  357. //
  358. // check to see we need to browse the DNS domain.
  359. //
  360. if( _fbrowseDNSDomain ) {
  361. dwDomainCount++;
  362. }
  363. //
  364. // allocate the memory for the ServerListItem (based on the no. of domains)
  365. //
  366. plbiAllotted = (ServerListItem *)
  367. LocalAlloc( LMEM_FIXED, (sizeof(ServerListItem) * dwDomainCount) );
  368. if ( plbiAllotted == NULL ) {
  369. dwError = ERROR_NOT_ENOUGH_MEMORY;
  370. goto Cleanup;
  371. }
  372. //
  373. // set scan variables.
  374. //
  375. plbi = plbiAllotted;
  376. pchTDomain = pchTrustedDomains;
  377. //
  378. // display and expand DNS domain if we need to.
  379. //
  380. if( _fbrowseDNSDomain ) {
  381. _tcscpy(plbi->ContainerName, (LPTSTR)_browseDNSDomainName );
  382. plbi->Comment[0] = _T('\0');
  383. plbi->bContainsServers = TRUE;
  384. plbi->bServersExpandedOnce = FALSE;
  385. plbi->bDNSDomain = TRUE;
  386. plbi->nServerCount = 0;
  387. plbi->ServerItems = NULL;
  388. plbi->hTreeParentItem = NULL;
  389. plbi->hTreeItem = AddItemToTree( hTree, plbi->ContainerName,
  390. NULL, plbi, SRV_TREE_DOMAINLEVEL);
  391. //
  392. // expand the primary domain
  393. //
  394. ExpandDomain(hwndDlg, plbi->ContainerName, plbi, &dwDlgIndex);
  395. //
  396. // move to next list entry.
  397. //
  398. plbi++;
  399. }
  400. //
  401. // first entry in the domain list is the primary domain,
  402. // display it and expand it by default.
  403. //
  404. _tcscpy(plbi->ContainerName, pchTDomain);
  405. plbi->Comment[0] = _T('\0');
  406. plbi->bContainsServers = TRUE;
  407. plbi->bServersExpandedOnce = FALSE;
  408. plbi->bDNSDomain = FALSE;
  409. plbi->nServerCount = 0;
  410. plbi->ServerItems = NULL;
  411. plbi->hTreeParentItem = NULL;
  412. plbi->hTreeItem = AddItemToTree( hTree, pchTDomain, NULL, plbi,
  413. SRV_TREE_DOMAINLEVEL);
  414. //
  415. // expand the primary domain
  416. //
  417. if(ExpandDomain(hwndDlg, NULL, plbi, &dwDlgIndex))
  418. {
  419. if(plbi->hTreeItem)
  420. {
  421. //Expand default domain
  422. TreeView_Expand( hTree, plbi->hTreeItem, TVE_EXPAND);
  423. }
  424. }
  425. //
  426. // display other domains, don't expand them.
  427. //
  428. for((i = (_fbrowseDNSDomain == TRUE) ? 2 : 1); i < dwDomainCount; i++) {
  429. //
  430. // move to the next entry in the domain list.
  431. //
  432. plbi++;
  433. pchTDomain += (_tcslen(pchTDomain) + 1);
  434. _tcscpy(plbi->ContainerName, pchTDomain);
  435. plbi->Comment[0] = _T('\0');
  436. plbi->bContainsServers = TRUE;
  437. plbi->bServersExpandedOnce = FALSE;
  438. plbi->bDNSDomain = FALSE;
  439. plbi->nServerCount = 0;
  440. plbi->ServerItems = NULL;
  441. plbi->hTreeParentItem = NULL;
  442. plbi->hTreeItem = AddItemToTree( hTree, pchTDomain, NULL, plbi,
  443. SRV_TREE_DOMAINLEVEL);
  444. }
  445. //
  446. // we successfully populated the domain list,
  447. // set return parameters.
  448. //
  449. *pdwDomainCount = dwDomainCount;
  450. plbiReturned = plbiAllotted;
  451. plbiAllotted = NULL;
  452. dwError = ERROR_SUCCESS;
  453. Cleanup:
  454. if( pchTrustedDomains != NULL ) {
  455. LocalFree( pchTrustedDomains );
  456. }
  457. if( plbiAllotted != NULL ) {
  458. LocalFree( plbiAllotted );
  459. }
  460. SetLastError( dwError );
  461. return( plbiReturned );
  462. }
  463. #endif //OS_WIN32
  464. #ifdef OS_WIN32
  465. /****************************************************************************/
  466. /* Name: LoadLibraries */
  467. /* */
  468. /* Purpose: Load the appropriate libraries for win95 and winnt. */
  469. /* */
  470. /* Returns: None */
  471. /* */
  472. /* Params: None */
  473. /****************************************************************************/
  474. void CBrowseServersCtl::LoadLibraries(void)
  475. {
  476. #ifndef OS_WINCE
  477. OSVERSIONINFOA osVersionInfo;
  478. osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  479. //A version to avoid wrapping
  480. if(GetVersionExA(&osVersionInfo) == TRUE)
  481. {
  482. if(VER_PLATFORM_WIN32_WINDOWS == osVersionInfo.dwPlatformId )
  483. {
  484. bIsWin95 = TRUE;
  485. if(!hLibrary)
  486. {
  487. hLibrary = LoadLibrary(__T("msnet32.dll"));
  488. }
  489. if(NULL == hLibrary)
  490. return ;
  491. lpfnNetServerEnum2 = (LPFNNETSERVERENUM2)GetProcAddress((HMODULE)hLibrary,
  492. (LPCSTR)0x0029);
  493. lpfnNetWkStaGetInfo = (LPFNNETWKSTAGETINFO)GetProcAddress((HMODULE)hLibrary,
  494. (LPCSTR)0x0039);
  495. }
  496. else if(VER_PLATFORM_WIN32_NT == osVersionInfo.dwPlatformId )
  497. {
  498. if(!hLibrary)
  499. {
  500. hLibrary = LoadLibrary(__T("NetApi32.dll"));
  501. }
  502. if(NULL == hLibrary)
  503. return;
  504. lpfnNetServerEnum = (LPFNNETSERVERENUM)
  505. GetProcAddress((HMODULE)hLibrary,
  506. "NetServerEnum");
  507. lpfnNetApiBufferFree = (LPFNNETAPIBUFFERFREE)
  508. GetProcAddress((HMODULE)hLibrary,
  509. "NetApiBufferFree");
  510. lpfnNetWkStaGetInfo_NT = (LPFNNETWKSTAGETINFO_NT)GetProcAddress(
  511. (HMODULE)hLibrary,
  512. "NetWkstaGetInfo");
  513. lpfnNetEnumerateTrustedDomains = (LPFNNETENUMERATETRUSTEDDOMAINS)
  514. GetProcAddress((HMODULE)hLibrary,
  515. "NetEnumerateTrustedDomains");
  516. #ifdef UNICODE
  517. lpfnDsGetDcName = (LPFNDSGETDCNAME)
  518. GetProcAddress((HMODULE)hLibrary,
  519. "DsGetDcNameW");
  520. #else // UNICODE
  521. lpfnDsGetDcName = (LPFNDSGETDCNAME)
  522. GetProcAddress((HMODULE)hLibrary,
  523. "DsGetDcNameA");
  524. #endif // UNICODE
  525. }
  526. }
  527. return;
  528. #else
  529. hLibrary = LoadLibrary(L"coredll.dll");
  530. lpfnWNetOpenEnum = (LPFNWNETOPENENUM )
  531. GetProcAddress((HMODULE)hLibrary,
  532. L"WNetOpenEnumW");
  533. lpfnWNetEnumResource = (LPFNWNETENUMRESOURCE )
  534. GetProcAddress((HMODULE)hLibrary,
  535. L"WNetEnumResourceW");
  536. lpfnWNetCloseEnum = (LPFNWNETCLOSEENUM )
  537. GetProcAddress((HMODULE)hLibrary,
  538. L"WNetCloseEnum");
  539. #endif
  540. }
  541. #endif //OS_WIN32
  542. /****************************************************************************/
  543. /* Name: ExpandDomain */
  544. /* */
  545. /* Purpose: Enumerates the Hydra Servers in a Domain/workgroup, adds */
  546. /* them to the linked-list and as items in the list box. */
  547. /* */
  548. /* Returns: */
  549. /* */
  550. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  551. /****************************************************************************/
  552. int CBrowseServersCtl::ExpandDomain(HWND hwndDlg, TCHAR *pDomainName,
  553. ServerListItem *plbi, DWORD *pdwIndex)
  554. {
  555. //
  556. // check to see we are expanding a DNS domain.
  557. //
  558. if( plbi->bDNSDomain ) {
  559. return( UIExpandDNSDomain( hwndDlg, pDomainName, plbi, pdwIndex ) );
  560. }
  561. //
  562. // check to we are running on Win9x machine.
  563. //
  564. #ifndef OS_WINCE
  565. if( bIsWin95 == TRUE) {
  566. return( ExpandDomain95(hwndDlg, pDomainName, plbi, pdwIndex) );
  567. }
  568. else {
  569. return( ExpandDomainNT(hwndDlg, pDomainName, plbi, pdwIndex) );
  570. }
  571. #else
  572. return ExpandDomainCE(hwndDlg, pDomainName, plbi, pdwIndex);
  573. #endif
  574. }//ExpandDomain
  575. /****************************************************************************/
  576. /* Name: ExpandDomain95 */
  577. /* */
  578. /* Purpose: Enumerates the Hydra Servers in a Domain/workgroup, adds */
  579. /* them to the linked-list and as items in the list box. */
  580. /* */
  581. /* Returns: */
  582. /* */
  583. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  584. /****************************************************************************/
  585. #ifdef OS_WIN32
  586. #ifndef OS_WINCE
  587. int CBrowseServersCtl::ExpandDomain95(HWND hwndDlg, TCHAR *pDomainName,
  588. ServerListItem *plbi, DWORD *pdwIndex)
  589. {
  590. UNREFERENCED_PARAMETER(pDomainName);
  591. DWORD dwIndex = *pdwIndex;
  592. unsigned short AvailCount = 0, TotalEntries = 0;
  593. ServerListItem *plbistore = NULL, *pItemsStore = NULL;
  594. DCUINT index = 0, cb = 0;
  595. struct server_info_1 *pInfo1 = NULL;
  596. int err = 0;
  597. int nCount = 0;
  598. HWND hTree = NULL;
  599. if(NULL == lpfnNetServerEnum2)
  600. return 0;
  601. SetCursor(LoadCursor(NULL, IDC_WAIT));
  602. if(!plbi->ServerItems)
  603. {
  604. // Determine how much information is available
  605. err = (*lpfnNetServerEnum2)(NULL, 1, NULL, 0, &AvailCount,
  606. &TotalEntries, HYDRA_SERVER_LANMAN_BITS, NULL);
  607. if(err != ERROR_MORE_DATA)
  608. return 0;
  609. // Allocate memory to receive the information
  610. // Give a little extra, since sometimes one is missed
  611. cb = (TotalEntries + 1) * sizeof(struct server_info_1);
  612. pInfo1 = (struct server_info_1 *)LocalAlloc(0, cb);
  613. if ( pInfo1 == NULL )
  614. {
  615. goto done1;
  616. }
  617. memset(pInfo1,0,cb);
  618. //
  619. // lpfnNetServerEnum2 is going to take a long time,
  620. // Retrieve the information
  621. err = (*lpfnNetServerEnum2)(
  622. NULL,
  623. 1,
  624. (char far *)pInfo1,
  625. (unsigned short)cb,
  626. &AvailCount,
  627. &TotalEntries,
  628. HYDRA_SERVER_LANMAN_BITS,
  629. NULL);
  630. // Due to the dynamic nature of the network, we may get
  631. // ERROR_MORE_DATA, but that means we got the bulk of the
  632. // correct values, and we should display them
  633. if ((err != NERR_Success) && (err != ERROR_MORE_DATA))
  634. goto done1;
  635. //Allocate memory.
  636. cb = sizeof(ServerListItem)*AvailCount;
  637. plbi->ServerItems = (ServerListItem *)LocalAlloc(0, (sizeof(ServerListItem)*AvailCount));
  638. if ( plbi->ServerItems == NULL )
  639. {
  640. goto done1;
  641. }
  642. memset(plbi->ServerItems,0,sizeof(ServerListItem)*AvailCount);
  643. pItemsStore = plbi->ServerItems;
  644. if(IsBadWritePtr((LPVOID)plbi->ServerItems,sizeof(ServerListItem)*AvailCount))
  645. goto done1;
  646. // Traverse list, copy servers to plbi.
  647. for( index = 0; index < AvailCount; index++ )
  648. {
  649. if( ((pInfo1[index].sv1_version_major & MAJOR_VERSION_MASK) >=
  650. 4) && (pInfo1[index].sv1_version_minor >= 0) )
  651. {
  652. #ifdef UNICODE
  653. nCount =
  654. MultiByteToWideChar(
  655. CP_ACP,
  656. MB_COMPOSITE,
  657. (LPSTR)pInfo1[index].sv1_name,
  658. -1,
  659. pItemsStore->ContainerName,
  660. sizeof(pItemsStore->ContainerName)/sizeof(WCHAR));
  661. if( nCount == 0 )
  662. {
  663. return 0;
  664. }
  665. #else
  666. _tcscpy(pItemsStore->ContainerName, pInfo1[index].sv1_name);
  667. #endif
  668. if(pInfo1[index].sv1_comment != NULL)
  669. {
  670. #ifdef UNICODE
  671. nCount =
  672. MultiByteToWideChar(
  673. CP_ACP,
  674. MB_COMPOSITE,
  675. (LPSTR)pInfo1[index].sv1_comment,
  676. -1,
  677. pItemsStore->Comment,
  678. sizeof(pItemsStore->Comment)/sizeof(WCHAR));
  679. if( nCount == 0 )
  680. {
  681. return 0;
  682. }
  683. #else
  684. _tcscpy(pItemsStore->Comment, pInfo1[index].sv1_comment);
  685. #endif
  686. }
  687. pItemsStore->bContainsServers = FALSE;
  688. pItemsStore++;
  689. plbi->nServerCount++;
  690. }
  691. }
  692. done1:
  693. if ( AvailCount && pInfo1 )
  694. {
  695. LocalFree( pInfo1 );
  696. }
  697. if(!plbi->ServerItems)
  698. {
  699. return 0;
  700. }
  701. }
  702. else
  703. AvailCount = (unsigned short)plbi->nServerCount;
  704. // Traverse the plbi>ServerItems and add the servers to the List-box:
  705. pItemsStore = plbi->ServerItems;
  706. hTree = GetDlgItem( hwndDlg, UI_IDC_SERVERS_TREE );
  707. HTREEITEM hTreeParentNode = plbi->hTreeItem;
  708. for (index = 0; index < plbi->nServerCount; ++index)
  709. {
  710. if(hwndDlg)
  711. {
  712. if (DC_TSTRCMP(pItemsStore->ContainerName, _T("")))
  713. {
  714. pItemsStore->hTreeParentItem = hTreeParentNode;
  715. pItemsStore->hTreeItem =
  716. AddItemToTree(hTree, pItemsStore->ContainerName,
  717. hTreeParentNode,
  718. pItemsStore, SRV_TREE_SERVERLEVEL);
  719. }
  720. }
  721. pItemsStore++;
  722. }
  723. plbi->bServersExpandedOnce = TRUE;
  724. *pdwIndex = dwIndex;
  725. if(hwndDlg)
  726. {
  727. InvalidateRect(hwndDlg, NULL, TRUE);
  728. }
  729. SetCursor(LoadCursor(NULL, IDC_ARROW));
  730. return AvailCount;
  731. }/* ExpandDomain95 */
  732. /****************************************************************************/
  733. /* Name: ExpandDomainNT */
  734. /* */
  735. /* Purpose: Enumerates the Hydra Servers in a Domain/workgroup, adds */
  736. /* them to the linked-list and as items in the list box. */
  737. /* */
  738. /* Returns: */
  739. /* */
  740. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  741. /****************************************************************************/
  742. int CBrowseServersCtl::ExpandDomainNT(HWND hwndDlg, TCHAR *pDomainName,
  743. ServerListItem *plbi, DWORD *pdwIndex)
  744. {
  745. DWORD dwIndex = *pdwIndex, AvailCount = 0, TotalEntries = 0;
  746. SERVER_INFO_101 *pInfo = NULL;
  747. DCUINT index = 0;
  748. ServerListItem *plbistore = NULL, *pItemsStore = NULL;
  749. WCHAR pDomain[BROWSE_MAX_ADDRESS_LENGTH];
  750. int nCount = 0;
  751. HWND hTree = NULL;
  752. if(NULL == lpfnNetServerEnum)
  753. return 0;
  754. if(NULL == lpfnNetApiBufferFree)
  755. return 0;
  756. SetCursor(LoadCursor(NULL, IDC_WAIT));
  757. if(plbi->ServerItems)
  758. {
  759. AvailCount = plbi->nServerCount;
  760. }
  761. else
  762. {
  763. //
  764. //enumerate the servers in the primary domain if not already present
  765. //
  766. if(pDomainName)
  767. {
  768. #ifndef UNICODE
  769. nCount = MultiByteToWideChar(CP_ACP,
  770. MB_COMPOSITE,
  771. pDomainName,
  772. lstrlen(pDomainName) * sizeof(TCHAR),
  773. (LPWSTR)pDomain,
  774. sizeof(pDomain) / sizeof(TCHAR));
  775. if(nCount)
  776. {
  777. pDomain[nCount] = 0;
  778. }
  779. else
  780. {
  781. AvailCount = 0;
  782. goto done;
  783. }
  784. #else
  785. _tcsncpy( pDomain, (LPTSTR)pDomainName,
  786. sizeof(pDomain)/sizeof(TCHAR) - 1);
  787. pDomain[sizeof(pDomain)/sizeof(TCHAR) - 1] = 0;
  788. #endif
  789. }
  790. //
  791. // lpfnNetServerEnum is going to take a long time,
  792. //
  793. if ((*lpfnNetServerEnum)(NULL,
  794. 101,
  795. (LPBYTE *)&pInfo,
  796. (DWORD) -1,
  797. &AvailCount,
  798. &TotalEntries,
  799. HYDRA_SERVER_LANMAN_BITS,
  800. pDomainName ?
  801. (LPTSTR)pDomain :
  802. NULL,
  803. NULL ) || !AvailCount )
  804. {
  805. AvailCount = 0;
  806. goto done;
  807. }
  808. //Allocate memory.
  809. if ( (plbi->ServerItems = (ServerListItem *)LocalAlloc(0,
  810. (sizeof(ServerListItem)*AvailCount))) == NULL )
  811. {
  812. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  813. goto done;
  814. }
  815. memset(plbi->ServerItems,0,sizeof(ServerListItem)*AvailCount);
  816. pItemsStore = plbi->ServerItems;
  817. // Traverse list, copy servers to plbi.
  818. for( index = 0; index < AvailCount; index++ )
  819. {
  820. if( ((pInfo[index].sv101_version_major & MAJOR_VERSION_MASK) >=
  821. 4) )
  822. {
  823. #ifdef UNICODE
  824. lstrcpy(pItemsStore->ContainerName, pInfo[index].sv101_name);
  825. lstrcpy(pItemsStore->Comment, pInfo[index].sv101_comment);
  826. #else
  827. WideCharToMultiByte(CP_ACP,
  828. WC_COMPOSITECHECK|WC_SEPCHARS,
  829. (LPCWSTR)pInfo[index].sv101_name,
  830. wcslen((const wchar_t *)pInfo[index].sv101_name),
  831. pItemsStore->ContainerName,
  832. sizeof(pItemsStore->ContainerName),
  833. NULL,
  834. NULL);
  835. WideCharToMultiByte(CP_ACP,
  836. WC_COMPOSITECHECK|WC_SEPCHARS,
  837. (LPCWSTR)pInfo[index].sv101_comment,
  838. wcslen((const wchar_t *)pInfo[index].sv101_comment),
  839. pItemsStore->Comment,
  840. sizeof(pItemsStore->Comment),
  841. NULL,
  842. NULL);
  843. #endif
  844. pItemsStore->bContainsServers = FALSE;
  845. pItemsStore++;
  846. plbi->nServerCount ++;
  847. }
  848. }
  849. done:
  850. if ( AvailCount && pInfo )
  851. {
  852. (*lpfnNetApiBufferFree)( pInfo );
  853. }
  854. }
  855. // Traverse the plbi>ServerItems and add the servers to the List-box:
  856. pItemsStore = plbi->ServerItems;
  857. hTree = GetDlgItem( hwndDlg, UI_IDC_SERVERS_TREE );
  858. HTREEITEM hTreeParentNode = plbi->hTreeItem;
  859. for (index = 0; index < plbi->nServerCount;++index)
  860. {
  861. if(hwndDlg)
  862. {
  863. if (DC_TSTRCMP(pItemsStore->ContainerName, _T("")))
  864. {
  865. pItemsStore->hTreeParentItem = hTreeParentNode;
  866. pItemsStore->hTreeItem =
  867. AddItemToTree(hTree, pItemsStore->ContainerName,
  868. hTreeParentNode,
  869. pItemsStore, SRV_TREE_SERVERLEVEL);
  870. }
  871. }
  872. plbi->bServersExpandedOnce = TRUE;
  873. pItemsStore++;
  874. }
  875. *pdwIndex = dwIndex;
  876. SetCursor(LoadCursor(NULL, IDC_ARROW));
  877. return AvailCount;
  878. } /* ExpandDomainNT */
  879. #else
  880. /****************************************************************************/
  881. /* Name: ExpandDomainCE */
  882. /* */
  883. /* Purpose: Enumerates the Hydra Servers in a Domain/workgroup, adds */
  884. /* them to the linked-list and as items in the list box. */
  885. /* */
  886. /* Returns: */
  887. /* */
  888. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  889. /****************************************************************************/
  890. int CBrowseServersCtl::ExpandDomainCE(HWND hwndDlg, TCHAR *pDomainName,
  891. ServerListItem *plbi, DWORD *pdwIndex)
  892. {
  893. DWORD AvailCount = 0;
  894. NETRESOURCE *pNetRsrc = NULL;
  895. HWND hTree = NULL;
  896. DWORD dwInitBufSize = 16*1024;
  897. if((NULL == lpfnWNetOpenEnum) || (NULL == lpfnWNetCloseEnum) || (NULL == lpfnWNetEnumResource))
  898. return 0;
  899. SetCursor(LoadCursor(NULL, IDC_WAIT));
  900. if(plbi->ServerItems)
  901. {
  902. AvailCount = plbi->nServerCount;
  903. }
  904. else
  905. {
  906. NETRESOURCE netrsrc;
  907. HANDLE hEnum = NULL;
  908. DWORD dwRet = NO_ERROR;
  909. netrsrc.dwScope = RESOURCE_GLOBALNET;
  910. netrsrc.dwType = RESOURCETYPE_ANY;
  911. netrsrc.dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
  912. netrsrc.dwUsage = RESOURCEUSAGE_CONTAINER;
  913. netrsrc.lpLocalName = NULL;
  914. netrsrc.lpRemoteName = pDomainName;
  915. netrsrc.lpComment = NULL;
  916. netrsrc.lpProvider = NULL;
  917. hTree = GetDlgItem( hwndDlg, UI_IDC_SERVERS_TREE );
  918. dwRet = lpfnWNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_RESERVED, HYDRA_SERVER_LANMAN_BITS, &netrsrc, &hEnum);
  919. if ((dwRet != NO_ERROR) || (hEnum == NULL))
  920. return 0;
  921. AvailCount = 0;
  922. pNetRsrc = (NETRESOURCE *)LocalAlloc(0, dwInitBufSize);
  923. if (!pNetRsrc)
  924. goto done;
  925. while(dwRet == NO_ERROR)
  926. {
  927. DWORD dwCount, dwTempSize;
  928. dwCount = 0xffffffff;
  929. dwTempSize = dwInitBufSize;
  930. dwRet = lpfnWNetEnumResource(hEnum, &dwCount, pNetRsrc, &dwTempSize);
  931. if (dwRet == NO_ERROR)
  932. {
  933. AvailCount += dwCount;
  934. for (DWORD i=0; i<dwCount; i++)
  935. {
  936. AddItemToTree(hTree, pNetRsrc[i].lpRemoteName,
  937. plbi->hTreeItem,
  938. NULL, SRV_TREE_SERVERLEVEL);
  939. }
  940. }
  941. }
  942. lpfnWNetCloseEnum(hEnum);
  943. hEnum = NULL;
  944. done:
  945. if (pNetRsrc)
  946. LocalFree(pNetRsrc);
  947. lpfnWNetCloseEnum(hEnum);
  948. }
  949. SetCursor(LoadCursor(NULL, IDC_ARROW));
  950. return AvailCount;
  951. } /* ExpandDomainCE */
  952. #endif
  953. #endif //OS_WIN32
  954. /****************************************************************************/
  955. /* Name: UIGetTrustedDomains */
  956. /* */
  957. /* Purpose: Queries teh registry for a list of the Trusted Domains */
  958. /* */
  959. /* Returns: */
  960. /* */
  961. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  962. /****************************************************************************/
  963. #ifdef OS_WIN32
  964. #ifndef OS_WINCE
  965. PDCTCHAR CBrowseServersCtl::UIGetTrustedDomains()
  966. {
  967. HKEY hKey = NULL;
  968. DWORD size = 0 , size1 = 0;
  969. PDCTCHAR pTrustedDomains = NULL;
  970. PDCTCHAR pPutHere = NULL;
  971. PDCTCHAR szPrimaryDomain = NULL;
  972. PDCTCHAR szWkstaDomainName = NULL;
  973. PDCTCHAR pDomain = NULL;
  974. BOOL bGetTrustedDomains = FALSE;
  975. OSVERSIONINFOA OsVer;
  976. memset(&OsVer, 0x0, sizeof(OSVERSIONINFOA));
  977. OsVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  978. GetVersionExA(&OsVer);
  979. if(OsVer.dwMajorVersion <= 4)
  980. {
  981. // Get the current domain information from the winlogon settings.
  982. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, DOMAIN_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  983. {
  984. DWORD dwResult = 0;
  985. dwResult = RegQueryValueEx(hKey, PRIMARY_VAL, NULL, NULL, NULL, &size);
  986. if (dwResult == ERROR_SUCCESS && size > 0)
  987. {
  988. szPrimaryDomain = (PDCTCHAR)LocalAlloc(LPTR, (size + 1)*sizeof(TCHAR));
  989. if (szPrimaryDomain == NULL)
  990. {
  991. goto Cleanup;
  992. }
  993. if ((RegQueryValueEx(
  994. hKey,
  995. PRIMARY_VAL,
  996. NULL, NULL,
  997. (LPBYTE)szPrimaryDomain,
  998. &size
  999. ) == ERROR_SUCCESS) &&
  1000. szPrimaryDomain[0])
  1001. {
  1002. pDomain = szPrimaryDomain;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. else
  1008. {
  1009. if(NULL == lpfnDsGetDcName)
  1010. return 0;
  1011. DOMAIN_CONTROLLER_INFO *pDCI = NULL;
  1012. // this section gets the current domain the app is running on
  1013. if((*lpfnDsGetDcName)(NULL, NULL, NULL,
  1014. NULL, DS_RETURN_FLAT_NAME,
  1015. &pDCI ) == NO_ERROR)
  1016. {
  1017. pDomain = pDCI->DomainName;
  1018. }
  1019. }
  1020. // Get the domain/work group information from NetWkStaGetInfo
  1021. if (lpfnNetWkStaGetInfo_NT)
  1022. {
  1023. LPBYTE buffer = NULL;
  1024. if ((*lpfnNetWkStaGetInfo_NT)(NULL, 100, &buffer) == NERR_Success && buffer)
  1025. {
  1026. LPWSTR langroup = ((WKSTA_INFO_100 *)buffer)->wki100_langroup;
  1027. DWORD langroupLen = (langroup) ? wcslen(langroup) : 0;
  1028. if (langroupLen)
  1029. {
  1030. szWkstaDomainName = (PDCTCHAR)LocalAlloc(LPTR, (langroupLen + 1)*sizeof(TCHAR));
  1031. if (szWkstaDomainName == NULL)
  1032. {
  1033. goto Cleanup;
  1034. }
  1035. #ifdef UNICODE
  1036. _tcscpy(szWkstaDomainName,langroup);
  1037. pDomain = szWkstaDomainName;
  1038. #else
  1039. // convert the unicode string to ansi
  1040. if (WideCharToMultiByte(CP_ACP,
  1041. 0,
  1042. langroup,
  1043. -1,
  1044. szWkstaDomainName,
  1045. (langroupLen + 1) * sizeof(TCHAR),
  1046. NULL,
  1047. NULL))
  1048. {
  1049. pDomain = szWkstaDomainName;
  1050. }
  1051. #endif
  1052. }
  1053. if (lpfnNetApiBufferFree)
  1054. {
  1055. (*lpfnNetApiBufferFree)(buffer);
  1056. }
  1057. }
  1058. }
  1059. //
  1060. // We should get the list of trusted domains only when the machine belongs to a domain, not a workgroup
  1061. // We determine that the machine belongs to a domain if the winlogon cached information, and the langroup from
  1062. // NetWkstaGetInfo match.
  1063. //
  1064. if (szPrimaryDomain &&
  1065. szPrimaryDomain[0] &&
  1066. szWkstaDomainName &&
  1067. _tcscmp(szPrimaryDomain, szWkstaDomainName) == 0)
  1068. {
  1069. bGetTrustedDomains = TRUE;
  1070. }
  1071. size = (pDomain) ? _tcslen(pDomain) : 0;
  1072. if(size > 0)
  1073. {
  1074. if (bGetTrustedDomains && hKey != NULL && (OsVer.dwMajorVersion < 4))
  1075. {
  1076. if(ERROR_SUCCESS == RegQueryValueEx(hKey, CACHE_VAL_NT351,
  1077. NULL, NULL,
  1078. NULL, &size1))
  1079. {
  1080. pTrustedDomains = (PDCTCHAR)LocalAlloc(LPTR, (size + size1 + 2) * sizeof(TCHAR));
  1081. if(NULL == pTrustedDomains)
  1082. goto Cleanup;
  1083. _tcscpy(pTrustedDomains, pDomain);
  1084. pPutHere = pTrustedDomains;
  1085. pPutHere += (_tcslen(pTrustedDomains) + 1);
  1086. *pPutHere = _T('\0');
  1087. }
  1088. else
  1089. {
  1090. goto Cleanup;
  1091. }
  1092. }
  1093. else if (bGetTrustedDomains && hKey != NULL && (4 == OsVer.dwMajorVersion) )
  1094. {
  1095. if(ERROR_SUCCESS == RegQueryValueEx(hKey, CACHE_VAL,
  1096. NULL, NULL,
  1097. NULL, &size1))
  1098. {
  1099. pTrustedDomains = (PDCTCHAR)LocalAlloc(LPTR, (size + size1 + 2) * sizeof(TCHAR));
  1100. if(NULL == pTrustedDomains)
  1101. goto Cleanup;
  1102. _tcscpy(pTrustedDomains, pDomain);
  1103. pPutHere = pTrustedDomains;
  1104. pPutHere += (_tcslen(pTrustedDomains) + 1);
  1105. *pPutHere = _T('\0');
  1106. RegQueryValueEx(hKey, CACHE_VAL, NULL, NULL, (LPBYTE)pPutHere, &size1);
  1107. }
  1108. }
  1109. else if (5 <= OsVer.dwMajorVersion)
  1110. {
  1111. LPWSTR szDomainNames = NULL;
  1112. if(NULL == lpfnNetEnumerateTrustedDomains)
  1113. goto Cleanup;
  1114. size1 = 0;
  1115. DWORD dwCount;
  1116. LPWSTR szWideBuf = NULL;
  1117. if( (*lpfnNetEnumerateTrustedDomains)(NULL,
  1118. &szDomainNames ) == ERROR_SUCCESS )
  1119. {
  1120. szWideBuf = szDomainNames;
  1121. while(*szWideBuf && (*szWideBuf+1))
  1122. {
  1123. size1 += wcslen(szWideBuf) + 1;
  1124. szWideBuf += wcslen(szWideBuf) + 1;
  1125. }
  1126. szWideBuf = szDomainNames;
  1127. }
  1128. pTrustedDomains = (PDCTCHAR)LocalAlloc(LPTR, (size + size1 + 2) * sizeof(TCHAR));
  1129. if(NULL == pTrustedDomains)
  1130. goto Cleanup;
  1131. _tcscpy(pTrustedDomains, pDomain);
  1132. pPutHere = pTrustedDomains + _tcslen(pTrustedDomains) + 1;
  1133. *pPutHere = _T('\0');
  1134. if(size1)
  1135. {
  1136. //
  1137. // CONVERT unicode domain name to ansi.
  1138. //
  1139. while(*szWideBuf && (*szWideBuf+1))
  1140. {
  1141. #ifndef UNICODE
  1142. WideCharToMultiByte(CP_ACP, 0, szWideBuf, -1,
  1143. pPutHere, wcslen(szWideBuf) * sizeof(TCHAR), NULL, NULL );
  1144. #else // UNICODE
  1145. lstrcpy(pPutHere, szWideBuf);
  1146. #endif //UNICODE
  1147. pPutHere += _tcslen(pPutHere);
  1148. *pPutHere++ = 0;
  1149. szWideBuf += wcslen(szWideBuf) + 1;
  1150. }
  1151. if(NULL == lpfnNetApiBufferFree)
  1152. return 0;
  1153. (*lpfnNetApiBufferFree)( szDomainNames );
  1154. }
  1155. }
  1156. }
  1157. Cleanup:
  1158. if (hKey)
  1159. {
  1160. RegCloseKey(hKey);
  1161. }
  1162. if (szPrimaryDomain)
  1163. {
  1164. LocalFree(szPrimaryDomain);
  1165. }
  1166. if (szWkstaDomainName)
  1167. {
  1168. LocalFree(szWkstaDomainName);
  1169. }
  1170. return pTrustedDomains;
  1171. }
  1172. #else
  1173. PDCTCHAR CBrowseServersCtl::UIGetTrustedDomains()
  1174. {
  1175. HKEY hKey = NULL;
  1176. DWORD size = 0;
  1177. PDCTCHAR szPrimaryDomain = NULL;
  1178. PDCTCHAR pTrustedDomains = NULL;
  1179. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, DOMAIN_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  1180. {
  1181. DWORD dwResult = 0;
  1182. dwResult = RegQueryValueEx(hKey, PRIMARY_VAL, NULL, NULL, NULL, &size);
  1183. if (dwResult == ERROR_SUCCESS && size > 0)
  1184. {
  1185. szPrimaryDomain = (PDCTCHAR)LocalAlloc(LPTR, (size + 1)*sizeof(TCHAR));
  1186. if (szPrimaryDomain == NULL)
  1187. {
  1188. RegCloseKey(hKey);
  1189. return NULL;
  1190. }
  1191. if ((RegQueryValueEx(
  1192. hKey,
  1193. PRIMARY_VAL,
  1194. NULL, NULL,
  1195. (LPBYTE)szPrimaryDomain,
  1196. &size
  1197. ) == ERROR_SUCCESS) &&
  1198. szPrimaryDomain[0])
  1199. {
  1200. pTrustedDomains = szPrimaryDomain;
  1201. }
  1202. else
  1203. {
  1204. LocalFree(szPrimaryDomain);
  1205. }
  1206. }
  1207. }
  1208. return pTrustedDomains;
  1209. }
  1210. #endif
  1211. #endif //OS_WIN32
  1212. /* UIGetTrustedDomains */
  1213. /****************************************************************************/
  1214. /* Name: UIExpandDNSDomain */
  1215. /* */
  1216. /* Purpose: Enumerates the Hydra Servers in a DNS Domain, adds */
  1217. /* them to the linked-list and as items in the list box. */
  1218. /* */
  1219. /* Returns: numbers of server expanded */
  1220. /* */
  1221. /* Params: HWND hwndDlg Handle to the dialogwindow containing the list-box */
  1222. /****************************************************************************/
  1223. int
  1224. CBrowseServersCtl::UIExpandDNSDomain(
  1225. HWND hwndDlg,
  1226. TCHAR *pDomainName,
  1227. ServerListItem *plbi,
  1228. DWORD *pdwIndex
  1229. )
  1230. {
  1231. DWORD dwError;
  1232. LPHOSTENT lpHostEnt;
  1233. LPHOSTENT lpRevHostEnt;
  1234. DWORD dwIPEntries;
  1235. LPSTR FAR *lplpIPEntry;
  1236. DWORD FAR *lpIPAddrsAlloted = NULL;
  1237. DWORD FAR *lpIPAddrs;
  1238. ServerListItem *lpServerListItem = NULL;
  1239. ServerListItem *lpLBItem;
  1240. DWORD i;
  1241. DWORD dwEntriesDisplayed = 0;
  1242. HWND hTree = NULL;
  1243. HTREEITEM hTreeParentNode = NULL;
  1244. //
  1245. // set cursor to wait cursor while we do this.
  1246. //
  1247. SetCursor(LoadCursor(NULL, IDC_WAIT));
  1248. //
  1249. // check to see the specified list box entry is server entry.
  1250. //
  1251. // TRC_ASSERT((plbi->bContainsServers == TRUE),
  1252. // (TB,"Not a server entry"));
  1253. if( plbi->bContainsServers == FALSE ) {
  1254. dwError = ERROR_INVALID_DATA;
  1255. goto Cleanup;
  1256. }
  1257. if( hwndDlg == NULL ) {
  1258. dwError = ERROR_INVALID_DATA;
  1259. goto Cleanup;
  1260. }
  1261. //
  1262. // resolve the DNS domain name if it is not done before.
  1263. //
  1264. if( plbi->ServerItems == NULL ) {
  1265. #ifdef UNICODE
  1266. WCHAR achDomainName[BROWSE_MAX_ADDRESS_LENGTH];
  1267. DWORD dwCount;
  1268. //
  1269. // CONVERT unicode domain name to ansi.
  1270. //
  1271. dwCount =
  1272. WideCharToMultiByte(
  1273. CP_ACP,
  1274. WC_COMPOSITECHECK | WC_SEPCHARS,
  1275. pDomainName,
  1276. -1,
  1277. (LPSTR)achDomainName,
  1278. sizeof(achDomainName),
  1279. NULL,
  1280. NULL);
  1281. if( dwCount == 0 ) {
  1282. dwError = GetLastError();
  1283. goto Cleanup;
  1284. }
  1285. achDomainName[dwCount/sizeof(TCHAR)]= '\0';
  1286. lpHostEnt = gethostbyname( (LPSTR)achDomainName );
  1287. #else // UNICODE
  1288. //
  1289. // resolve the domain name to ip address list.
  1290. //
  1291. lpHostEnt = gethostbyname( pDomainName );
  1292. #endif // UNICODE
  1293. if( lpHostEnt == NULL ) {
  1294. dwError = GetLastError();
  1295. goto Cleanup;
  1296. }
  1297. //
  1298. // we handle only IP address type.
  1299. //
  1300. /*
  1301. TRC_ASSERT((lpHostEnt->h_addrtype == PF_INET),
  1302. (TB,"Invalid address type"));
  1303. TRC_ASSERT((lpHostEnt->h_length == 4),
  1304. (TB,"Invalid address length"));
  1305. */
  1306. if( (lpHostEnt->h_addrtype != PF_INET) ||
  1307. (lpHostEnt->h_length != 4) ) {
  1308. dwError = ERROR_INVALID_DATA;
  1309. goto Cleanup;
  1310. }
  1311. dwIPEntries = 0;
  1312. lplpIPEntry = lpHostEnt->h_addr_list;
  1313. while( *lplpIPEntry != NULL ) {
  1314. dwIPEntries++;
  1315. lplpIPEntry++;
  1316. }
  1317. //
  1318. // allocate memory for the ip address list and
  1319. // save for further use in this routine (only).
  1320. //
  1321. // Note: lpHostEnt points to a thread storeage
  1322. // which is reused by gethostbyname() and
  1323. // gethostbyaddr() calls with in the same
  1324. // thread, since we need to call gethostbyaddr()
  1325. // we better save the address list.
  1326. //
  1327. lpIPAddrsAlloted =
  1328. lpIPAddrs = (DWORD FAR *)
  1329. LocalAlloc( LMEM_FIXED, sizeof(DWORD) * dwIPEntries );
  1330. if( lpIPAddrs == NULL ) {
  1331. dwError = ERROR_OUTOFMEMORY;
  1332. goto Cleanup;
  1333. }
  1334. lplpIPEntry = lpHostEnt->h_addr_list;
  1335. while( *lplpIPEntry != NULL ) {
  1336. *lpIPAddrs = *(DWORD *)(*lplpIPEntry);
  1337. lpIPAddrs++;
  1338. lplpIPEntry++;
  1339. }
  1340. //
  1341. // allocate memory for domain ServerListItem array.
  1342. //
  1343. lpLBItem =
  1344. lpServerListItem = (ServerListItem *)
  1345. LocalAlloc( LMEM_FIXED, dwIPEntries * sizeof(ServerListItem) );
  1346. if( lpServerListItem == NULL ) {
  1347. dwError = ERROR_OUTOFMEMORY;
  1348. goto Cleanup;
  1349. }
  1350. //
  1351. // reverse resolve each ip address and get the name.
  1352. //
  1353. lpIPAddrs = lpIPAddrsAlloted;
  1354. for( i = 0; i < dwIPEntries; i++ ) {
  1355. CHAR achContainerName[BROWSE_MAX_ADDRESS_LENGTH];
  1356. int nCount;
  1357. BOOL bIPAddressString = FALSE;
  1358. lpRevHostEnt =
  1359. gethostbyaddr(
  1360. (LPSTR)lpIPAddrs,
  1361. sizeof(*lpIPAddrs),
  1362. PF_INET );
  1363. //
  1364. // if we can not reverse resolve the address or
  1365. // if the host name is too long, or
  1366. // display the ipaddress.
  1367. //
  1368. if( (lpRevHostEnt == NULL) ||
  1369. ((strlen(lpRevHostEnt->h_name) + 1) >
  1370. (BROWSE_MAX_ADDRESS_LENGTH/sizeof(TCHAR)) ) ) {
  1371. bIPAddressString = TRUE;
  1372. }
  1373. else {
  1374. LPSTR lpszDomainName;
  1375. #ifdef UNICODE
  1376. lpszDomainName = (LPSTR)achDomainName;
  1377. #else // UNICODE
  1378. lpszDomainName = pDomainName;
  1379. #endif // UNICODE
  1380. //
  1381. // the resolved name is same of the orginal name,
  1382. // display the ipaddress.
  1383. //
  1384. //
  1385. // compare the entire name first.
  1386. //
  1387. if( _stricmp(
  1388. lpRevHostEnt->h_name,
  1389. lpszDomainName ) != 0 ) {
  1390. LPSTR lpszDotPostion1;
  1391. LPSTR lpszDotPostion2;
  1392. DWORD dwCmpLen = 0;
  1393. //
  1394. // compare the only the first part of the name.
  1395. //
  1396. lpszDotPostion1 = strchr( lpRevHostEnt->h_name, '.');
  1397. lpszDotPostion2 = strchr( lpszDomainName, '.');
  1398. if( (lpszDotPostion1 == NULL) &&
  1399. (lpszDotPostion2 != NULL) ) {
  1400. dwCmpLen = (DWORD)(lpszDotPostion2 - lpszDomainName);
  1401. }
  1402. else if( (lpszDotPostion1 != NULL) &&
  1403. (lpszDotPostion2 == NULL) ) {
  1404. dwCmpLen = (DWORD)(lpszDotPostion1 -
  1405. lpRevHostEnt->h_name);
  1406. }
  1407. if( dwCmpLen != 0 ) {
  1408. if( _strnicmp(
  1409. lpRevHostEnt->h_name,
  1410. lpszDomainName,
  1411. (size_t)dwCmpLen ) == 0 ) {
  1412. bIPAddressString = TRUE;
  1413. }
  1414. }
  1415. }
  1416. else {
  1417. bIPAddressString = TRUE;
  1418. }
  1419. }
  1420. if( bIPAddressString ) {
  1421. strcpy(
  1422. (LPSTR)achContainerName,
  1423. inet_ntoa( *(struct in_addr *)lpIPAddrs ));
  1424. }
  1425. else {
  1426. strcpy( (LPSTR)achContainerName, lpRevHostEnt->h_name);
  1427. }
  1428. #ifdef UNICODE
  1429. //
  1430. // convert to UNICODE.
  1431. //
  1432. nCount =
  1433. MultiByteToWideChar(
  1434. CP_ACP,
  1435. MB_COMPOSITE,
  1436. (LPSTR)achContainerName,
  1437. -1,
  1438. lpLBItem->ContainerName,
  1439. sizeof(lpLBItem->ContainerName)/sizeof(WCHAR));
  1440. if( nCount == 0 ) {
  1441. dwError = GetLastError();
  1442. goto Cleanup;
  1443. }
  1444. //
  1445. // terminate converted string.
  1446. //
  1447. lpLBItem->ContainerName[nCount] = _T('\0');
  1448. #else // UNICODE
  1449. strcpy( lpLBItem->ContainerName, (LPSTR)achContainerName );
  1450. #endif // UNICODE
  1451. lpLBItem->Comment[0] = _T('\0');
  1452. lpLBItem->bContainsServers = FALSE;;
  1453. lpLBItem->bServersExpandedOnce = FALSE;
  1454. lpLBItem->bDNSDomain = FALSE;
  1455. lpLBItem->nServerCount = 0;
  1456. lpLBItem->ServerItems = NULL;
  1457. //
  1458. // move to next entry.
  1459. //
  1460. lpLBItem++;
  1461. lpIPAddrs++;
  1462. }
  1463. //
  1464. // Hook the allotted ServerListItem to the server
  1465. // structure, it will be used in future.
  1466. //
  1467. plbi->ServerItems = lpServerListItem;
  1468. plbi->nServerCount = dwIPEntries;
  1469. //
  1470. // set lpServerListItem to NULL, so that
  1471. // it will not get freed.
  1472. //
  1473. lpServerListItem = NULL;
  1474. }
  1475. //
  1476. // When we are here ..
  1477. //
  1478. // plbi->ServerItems points to the servers ServerListItem array
  1479. // and plbi->nServerCount has the count.
  1480. //
  1481. //
  1482. // display entires.
  1483. //
  1484. lpLBItem = plbi->ServerItems;
  1485. hTree = GetDlgItem( hwndDlg, UI_IDC_SERVERS_TREE );
  1486. hTreeParentNode = plbi->hTreeItem;
  1487. for( i = 0; i < plbi->nServerCount; i++ ) {
  1488. lpLBItem->hTreeParentItem = hTreeParentNode;
  1489. lpLBItem->hTreeItem =
  1490. AddItemToTree(hTree, lpLBItem->ContainerName,
  1491. hTreeParentNode,
  1492. lpLBItem, SRV_TREE_SERVERLEVEL);
  1493. lpLBItem++;
  1494. }
  1495. //
  1496. // Refresh the dialog box.
  1497. //
  1498. InvalidateRect(hwndDlg, NULL, TRUE);
  1499. plbi->bServersExpandedOnce = TRUE;
  1500. dwEntriesDisplayed = plbi->nServerCount;
  1501. //
  1502. // We are done.
  1503. //
  1504. dwError = ERROR_SUCCESS;
  1505. Cleanup:
  1506. if( lpIPAddrsAlloted != NULL ) {
  1507. LocalFree( lpIPAddrsAlloted );
  1508. }
  1509. if( lpServerListItem != NULL ) {
  1510. LocalFree( lpServerListItem );
  1511. }
  1512. if( dwError != ERROR_SUCCESS ) {
  1513. //TRC_NRM((TB, "UIExpandDNSDomain failed, %ld", dwError));
  1514. }
  1515. SetLastError( dwError );
  1516. SetCursor(LoadCursor(NULL, IDC_ARROW));
  1517. return( dwEntriesDisplayed );
  1518. }
  1519. #ifdef OS_WIN32
  1520. DWORD WINAPI CBrowseServersCtl::UIStaticPopListBoxThread(LPVOID lpvThreadParm)
  1521. {
  1522. DWORD dwRetVal=0;
  1523. //TRC_ASSERT(lpvThreadParm, (TB, "Thread param is NULL (instance pointer should be set)\n"));
  1524. if(lpvThreadParm)
  1525. {
  1526. CBrowseServersCtl* pBrowseSrv = (CBrowseServersCtl*)lpvThreadParm;
  1527. dwRetVal = pBrowseSrv->UIPopListBoxThread(NULL);
  1528. }
  1529. return dwRetVal;
  1530. }
  1531. /****************************************************************************/
  1532. /* Name: UIPopListBoxThread */
  1533. /* */
  1534. /* Purpose: Thread function to populate the list box. */
  1535. /* */
  1536. /* Returns: Success/Failure of the function */
  1537. /* */
  1538. /* Params: */
  1539. /* */
  1540. /****************************************************************************/
  1541. DWORD WINAPI CBrowseServersCtl::UIPopListBoxThread(LPVOID lpvThreadParm)
  1542. {
  1543. DWORD dwResult = 0;
  1544. ServerListItem *pBrowsePlbi = NULL, *ptempList = NULL;
  1545. DCUINT browseCount = 0;
  1546. DC_IGNORE_PARAMETER(lpvThreadParm);
  1547. // TRC_ASSERT( _hwndDialog, (TB, "_hwndDialog is not set\n"));
  1548. PostMessage(_hwndDialog, UI_LB_POPULATE_START, 0, 0);
  1549. LoadLibraries();
  1550. pBrowsePlbi = PopulateListBox( _hwndDialog, &browseCount);
  1551. //message is posted to the main thread to notify that the listbox has been populated
  1552. PostMessage(_hwndDialog, UI_LB_POPULATE_END, 0, 0);
  1553. //wait for the event to be signalled when the "connect server" dialog box is destroyed
  1554. if(_hEvent)
  1555. {
  1556. DWORD dwRetVal;
  1557. dwRetVal = WaitForSingleObject(_hEvent, INFINITE);
  1558. if(WAIT_FAILED == dwRetVal)
  1559. {
  1560. /// TRC_ASSERT(WAIT_FAILED != dwRetVal, (TB, "Wait failed\n"));
  1561. }
  1562. if(!CloseHandle(_hEvent))
  1563. {
  1564. DWORD dwLastErr = GetLastError();
  1565. // TRC_ABORT((TB, "Close handle failed: GetLastError=%d\n",dwLastErr));
  1566. }
  1567. }
  1568. ptempList = pBrowsePlbi;
  1569. //free the ServerListItems and memory to linked-list
  1570. if(pBrowsePlbi)
  1571. {
  1572. while(browseCount)
  1573. {
  1574. if(ptempList->ServerItems)
  1575. {
  1576. LocalFree((HANDLE)ptempList->ServerItems);
  1577. }
  1578. ptempList++;
  1579. browseCount --;
  1580. }
  1581. LocalFree((HLOCAL)pBrowsePlbi);
  1582. }
  1583. //decrement ref count for this object held by this thread
  1584. Release();
  1585. return (dwResult);
  1586. } /*UIPopListBoxThread*/
  1587. #endif /* OS_WIN32 */
  1588. HTREEITEM CBrowseServersCtl::AddItemToTree( HWND hwndTV, LPTSTR lpszItem,
  1589. HTREEITEM hParent,
  1590. ServerListItem* pItem,
  1591. int nLevel)
  1592. {
  1593. TVITEM tvi;
  1594. TVINSERTSTRUCT tvins;
  1595. #ifndef OS_WINCE
  1596. HTREEITEM hti;
  1597. #endif
  1598. tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE |TVIF_SELECTEDIMAGE;
  1599. if(nLevel == SRV_TREE_DOMAINLEVEL)
  1600. {
  1601. //
  1602. // Assume all domains have child servers
  1603. // they won't actually be enumerated until
  1604. // the user tries to expand the nodes
  1605. //
  1606. tvi.mask |= TVIF_CHILDREN;
  1607. tvi.cChildren = 1; //min number of children, will be updated
  1608. tvi.iImage = _nDomainImage;
  1609. tvi.iSelectedImage = _nDomainImage;
  1610. }
  1611. else
  1612. {
  1613. tvi.iImage = _nServerImage;
  1614. tvi.iSelectedImage = _nServerImage;
  1615. }
  1616. // Set the text of the item.
  1617. tvi.pszText = lpszItem;
  1618. tvi.cchTextMax = lstrlen(lpszItem);
  1619. // Save the ServerListItem info in the user defined area
  1620. // data area.
  1621. tvi.lParam = (LPARAM) pItem;
  1622. tvins.item = tvi;
  1623. tvins.hInsertAfter = _hPrev;
  1624. // Set the parent item based on the specified level.
  1625. tvins.hParent = hParent;
  1626. // Add the item to the tree view control.
  1627. _hPrev = (HTREEITEM) SendMessage(hwndTV, TVM_INSERTITEM, 0,
  1628. (LPARAM) (LPTVINSERTSTRUCT) &tvins);
  1629. // Save the handle to the item.
  1630. if (nLevel == SRV_TREE_DOMAINLEVEL)
  1631. _hPrevRootItem = _hPrev;
  1632. else if (nLevel == SRV_TREE_SERVERLEVEL)
  1633. _hPrevLev2Item = _hPrev;
  1634. return _hPrev;
  1635. }
  1636. //
  1637. //Handle TVN_ITEMEXPANDING
  1638. //
  1639. // On first expansion of a domain node, enumerate
  1640. // all the servers in that node and add them to the
  1641. // tree. Subsequent expands/collapses will just be handled
  1642. // by the tree.
  1643. //
  1644. // Return TRUE to allow expansion
  1645. // false otherwise
  1646. //
  1647. BOOL CBrowseServersCtl::OnItemExpanding(HWND hwndDlg, LPNMTREEVIEW nmTv)
  1648. {
  1649. ServerListItem* pSrvItem = NULL;
  1650. if(nmTv &&
  1651. (TVE_EXPAND == nmTv->action) &&
  1652. (nmTv->itemNew.mask & TVIF_PARAM))
  1653. {
  1654. //
  1655. // Expanding, need to build the list
  1656. // of servers for this domain
  1657. //
  1658. pSrvItem = (ServerListItem*)nmTv->itemNew.lParam;
  1659. if(pSrvItem)
  1660. {
  1661. //
  1662. // Only expanddomain if we've never expanded this node
  1663. // before
  1664. //
  1665. if(!pSrvItem->bServersExpandedOnce)
  1666. {
  1667. //Attempt to expand the domain
  1668. DWORD cItems = 0;
  1669. if(ExpandDomain( hwndDlg, pSrvItem->ContainerName,
  1670. pSrvItem, (DWORD*)&cItems))
  1671. {
  1672. return TRUE;
  1673. }
  1674. else
  1675. {
  1676. //
  1677. // Pop a message explaining that
  1678. // there are no TS's in this domain
  1679. //
  1680. UINT intRC;
  1681. TCHAR noTerminalServer[MAX_PATH];
  1682. intRC = LoadString(_hInst,
  1683. UI_IDS_NO_TERMINAL_SERVER,
  1684. noTerminalServer,
  1685. MAX_PATH);
  1686. if(intRC)
  1687. {
  1688. TCHAR title[MAX_PATH];
  1689. intRC = LoadString(_hInst,
  1690. UI_IDS_APP_NAME,
  1691. title,
  1692. MAX_PATH);
  1693. if(intRC)
  1694. {
  1695. DCTCHAR szBuffer[MAX_PATH +
  1696. BROWSE_MAX_ADDRESS_LENGTH];
  1697. _stprintf(szBuffer, noTerminalServer,
  1698. pSrvItem->ContainerName);
  1699. MessageBox( hwndDlg, szBuffer, title,
  1700. MB_OK | MB_ICONINFORMATION);
  1701. }
  1702. }
  1703. return FALSE;
  1704. }
  1705. }
  1706. else
  1707. {
  1708. //Already expanded so everythign is cached
  1709. //and ready to go, allow expansion
  1710. return TRUE;
  1711. }
  1712. }
  1713. else
  1714. {
  1715. return FALSE;
  1716. }
  1717. }
  1718. else
  1719. {
  1720. //Allow everythign else to expand
  1721. return TRUE;
  1722. }
  1723. }
  1724. BOOL CBrowseServersCtl::OnNotify( HWND hwndDlg, WPARAM wParam, LPARAM lParam)
  1725. {
  1726. LPNMHDR pnmh = (LPNMHDR) lParam;
  1727. if(pnmh)
  1728. {
  1729. switch( pnmh->code)
  1730. {
  1731. case TVN_ITEMEXPANDING:
  1732. {
  1733. return OnItemExpanding(
  1734. hwndDlg, (LPNMTREEVIEW) lParam);
  1735. }
  1736. break;
  1737. }
  1738. }
  1739. return TRUE;
  1740. }
  1741. #ifndef OS_WINCE
  1742. //
  1743. // Returns currently selected server
  1744. // or false if current selection is not a server but a domain
  1745. //
  1746. BOOL CBrowseServersCtl::GetServer(LPTSTR szServer, int cchLen)
  1747. {
  1748. HTREEITEM hti;
  1749. HWND hTree;
  1750. if(!_hwndDialog)
  1751. {
  1752. return FALSE;
  1753. }
  1754. hTree = GetDlgItem( _hwndDialog, UI_IDC_SERVERS_TREE );
  1755. hti = TreeView_GetSelection( hTree );
  1756. if( hti )
  1757. {
  1758. TVITEM item;
  1759. item.hItem = hti;
  1760. item.mask = TVIF_PARAM;
  1761. if(TreeView_GetItem( hTree, &item))
  1762. {
  1763. ServerListItem* ps = (ServerListItem*)item.lParam;
  1764. if(ps && !ps->bContainsServers)
  1765. {
  1766. _tcsncpy( szServer, ps->ContainerName, cchLen);
  1767. return TRUE;
  1768. }
  1769. }
  1770. }
  1771. return FALSE;
  1772. }
  1773. #else
  1774. BOOL CBrowseServersCtl::GetServer(LPTSTR szServer, int cchLen)
  1775. {
  1776. HTREEITEM hti;
  1777. HWND hTree;
  1778. if(!_hwndDialog)
  1779. {
  1780. return FALSE;
  1781. }
  1782. hTree = GetDlgItem( _hwndDialog, UI_IDC_SERVERS_TREE );
  1783. hti = TreeView_GetSelection( hTree );
  1784. if( hti )
  1785. {
  1786. TVITEM item;
  1787. item.hItem = hti;
  1788. item.mask = TVIF_TEXT | TVIF_PARAM;;
  1789. item.pszText = szServer;
  1790. item.cchTextMax = cchLen;
  1791. if(TreeView_GetItem( hTree, &item))
  1792. {
  1793. _tcsncpy( szServer, item.pszText, item.cchTextMax);
  1794. return TRUE;
  1795. }
  1796. }
  1797. return FALSE;
  1798. }
  1799. #endif