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.

999 lines
24 KiB

  1. #include "headers.hxx"
  2. #pragma hdrstop
  3. #include "resource.h"
  4. #include "nr.hxx"
  5. /////////////////////////////////////////////////////////////////////////////
  6. // Exported from t.cxx
  7. //
  8. VOID
  9. PlaceIt(
  10. HWND hwnd
  11. );
  12. /////////////////////////////////////////////////////////////////////////////
  13. TCHAR g_szRoot[] = TEXT("Entire Network");
  14. /////////////////////////////////////////////////////////////////////////////
  15. //
  16. // Timing stuff (stolen from the shell)
  17. //
  18. #if 1
  19. __inline DWORD clockrate() {LARGE_INTEGER li; QueryPerformanceFrequency(&li); return li.LowPart;}
  20. __inline DWORD clock() {LARGE_INTEGER li; QueryPerformanceCounter(&li); return li.LowPart;}
  21. #else
  22. __inline DWORD clockrate() {return 1000;}
  23. __inline DWORD clock() {return GetTickCount();}
  24. #endif
  25. #define TIMEVAR(t) DWORD t ## T; DWORD t ## N
  26. #define TIMEIN(t) t ## T = 0, t ## N = 0
  27. #define TIMESTART(t) t ## T -= clock(), t ## N ++
  28. #define TIMESTOP(t) t ## T += clock()
  29. #define TIMEFMT(t) ((DWORD)(t) / clockrate()), (((DWORD)((t) * 1000) / clockrate()) % 1000)
  30. #define TIMEOUT(t) if (t ## N) { \
  31. TCHAR szBuf[1000]; \
  32. wsprintf(szBuf, TEXT(#t) TEXT(": %ld calls, time: %ld, total: %ld.%03ld sec, average: %ld.%03ld sec/call\n"), t ## N, t ## T, TIMEFMT(t ## T), TIMEFMT( t ## T / t ## N )); \
  33. OutputDebugString(szBuf); \
  34. }
  35. //
  36. // Globals
  37. //
  38. HIMAGELIST g_himl;
  39. #define DEFAULT_BUFFER_SIZE 50000
  40. LPBYTE g_pBuffer = NULL;
  41. DWORD g_dwBufferSize = 0;
  42. BOOL g_bUseWNetFormatNetworkName = FALSE;
  43. DWORD g_dwScope = 0;
  44. DWORD g_dwType = 0;
  45. DWORD g_dwUsage = 0;
  46. DWORD CALLBACK
  47. EnumThreadProc(
  48. LPVOID lpThreadParameter
  49. );
  50. INT_PTR CALLBACK
  51. DlgProcStart(
  52. IN HWND hwnd,
  53. IN UINT uMsg,
  54. IN WPARAM wParam,
  55. IN LPARAM lParam
  56. );
  57. INT_PTR CALLBACK
  58. DlgProcMain(
  59. IN HWND hwnd,
  60. IN UINT uMsg,
  61. IN WPARAM wParam,
  62. IN LPARAM lParam
  63. );
  64. BOOL
  65. OnInitDialog(
  66. IN HWND hwnd,
  67. IN LPNETRESOURCE pRootNR
  68. );
  69. BOOL
  70. OnTreeNotify(
  71. IN HWND hwnd,
  72. IN LPNM_TREEVIEW ptvn
  73. );
  74. BOOL
  75. OnExpand(
  76. IN HWND hwnd,
  77. IN LPNM_TREEVIEW ptvn
  78. );
  79. BOOL
  80. OnGetDispInfo(
  81. IN HWND hwnd,
  82. IN LPNM_TREEVIEW ptvn
  83. );
  84. VOID
  85. InsertChildren(
  86. IN HWND hwnd,
  87. IN HTREEITEM hParent,
  88. IN CNetResource* pnrParent,
  89. IN HANDLE hEnum
  90. );
  91. VOID
  92. InsertItem(
  93. IN HWND hwnd,
  94. IN HTREEITEM hParent,
  95. IN CNetResource* pnrParent,
  96. IN LPNETRESOURCE pnr
  97. );
  98. VOID
  99. GetItemText(
  100. IN LPNETRESOURCE pnr,
  101. OUT LPTSTR pszBuf // assume it's big enough
  102. );
  103. VOID
  104. ErrorPopup(
  105. IN HWND hwnd,
  106. IN DWORD dwErr
  107. );
  108. /////////////////////////////////////////////////////////////////////////////
  109. //
  110. // For image list
  111. //
  112. //
  113. // NOTE: the I_* indices defined in global.hxx MUST MATCH THIS ARRAY!
  114. //
  115. WORD s_IconArray[] =
  116. {
  117. IDI_GENERIC,
  118. IDI_DOMAIN,
  119. IDI_SERVER,
  120. IDI_SHARE,
  121. IDI_FILE,
  122. IDI_GROUP,
  123. IDI_NETWORK,
  124. IDI_ROOT,
  125. IDI_SHAREADMIN,
  126. IDI_DIRECTORY,
  127. IDI_TREE
  128. };
  129. int g_IconIndex[ARRAYLEN(s_IconArray)];
  130. /////////////////////////////////////////////////////////////////////////////
  131. ULONG
  132. DoEnumeration(
  133. IN HWND hwnd
  134. )
  135. {
  136. DWORD idThread;
  137. HANDLE hThread = CreateThread(NULL, 0, EnumThreadProc, (LPVOID)NULL, 0, &idThread);
  138. if (hThread)
  139. {
  140. CloseHandle(hThread);
  141. }
  142. else
  143. {
  144. MessageBox(hwnd, TEXT("Couldn't create enumeration thread"), TEXT("Error!"), MB_OK);
  145. }
  146. return 0;
  147. }
  148. DWORD CALLBACK
  149. EnumThreadProc(
  150. LPVOID lpThreadParameter
  151. )
  152. {
  153. InitCommonControls();
  154. //
  155. // Create the image list
  156. //
  157. int cxIcon = GetSystemMetrics(SM_CXSMICON);
  158. int cyIcon = GetSystemMetrics(SM_CYSMICON);
  159. g_himl = ImageList_Create(cxIcon, cyIcon, ILC_MASK, ARRAYLEN(g_IconIndex), 0);
  160. if (NULL == g_himl)
  161. {
  162. return (ULONG)-1;
  163. }
  164. for (UINT i=0; i < ARRAYLEN(g_IconIndex); i++)
  165. {
  166. HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(s_IconArray[i]));
  167. if (NULL == hIcon)
  168. {
  169. continue;
  170. }
  171. g_IconIndex[i] = ImageList_AddIcon(g_himl, hIcon);
  172. if (-1 == g_IconIndex[i])
  173. {
  174. // failed!
  175. }
  176. DestroyIcon(hIcon);
  177. }
  178. // Now see what the user wants to do
  179. DWORD finalret = 0;
  180. INT_PTR ret;
  181. ret = DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_START), NULL, DlgProcStart);
  182. if (-1 == ret)
  183. {
  184. ErrorPopup(NULL, GetLastError());
  185. finalret = 1;
  186. }
  187. else if (!ret)
  188. {
  189. // user cancelled
  190. finalret = 1;
  191. }
  192. //
  193. // Release image list
  194. //
  195. if (NULL != g_himl)
  196. {
  197. ImageList_Destroy(g_himl);
  198. }
  199. return finalret;
  200. }
  201. /////////////////////////////////////////////////////////////////////////////
  202. class CWaitCursor
  203. {
  204. public:
  205. CWaitCursor(UINT idResCursor = 0);
  206. ~CWaitCursor();
  207. private:
  208. HCURSOR _hcurWait;
  209. HCURSOR _hcurOld;
  210. };
  211. //----------------------------------------------------------------------------
  212. CWaitCursor::CWaitCursor(UINT idResCursor)
  213. {
  214. _hcurWait = _hcurOld = NULL;
  215. if (0 != idResCursor)
  216. {
  217. _hcurWait = LoadCursor(g_hInstance, MAKEINTRESOURCE(idResCursor));
  218. _hcurOld = SetCursor(_hcurWait);
  219. }
  220. else
  221. {
  222. _hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  223. }
  224. }
  225. CWaitCursor::~CWaitCursor()
  226. {
  227. ::SetCursor( _hcurOld );
  228. if (_hcurWait)
  229. {
  230. ::DestroyCursor( _hcurWait );
  231. }
  232. }
  233. /////////////////////////////////////////////////////////////////////////////
  234. INT_PTR CALLBACK
  235. DlgProcStart(
  236. IN HWND hwnd,
  237. IN UINT uMsg,
  238. IN WPARAM wParam,
  239. IN LPARAM lParam
  240. )
  241. {
  242. switch (uMsg)
  243. {
  244. case WM_INITDIALOG:
  245. {
  246. PlaceIt(hwnd);
  247. // Set default to be enumeration from the root of the network
  248. SetDlgItemInt(hwnd, IDC_BUFFER_SIZE, DEFAULT_BUFFER_SIZE, FALSE);
  249. SetDlgItemText(hwnd, IDC_REMOTE_TEXT, TEXT(""));
  250. EnableWindow(GetDlgItem(hwnd, IDC_REMOTE_TEXT), FALSE);
  251. CheckDlgButton(hwnd, IDC_REMOTE_TEXT, 0);
  252. SetDlgItemText(hwnd, IDC_PROVIDER_TEXT, TEXT(""));
  253. EnableWindow(GetDlgItem(hwnd, IDC_PROVIDER_TEXT), FALSE);
  254. CheckDlgButton(hwnd, IDC_PROVIDER_TEXT, 0);
  255. CheckRadioButton(hwnd, IDC_RESOURCE_CONNECTED, IDC_RESOURCE_SHAREABLE, IDC_RESOURCE_GLOBALNET);
  256. CheckRadioButton(hwnd, IDC_DISK, IDC_RESERVED, IDC_ANY);
  257. CheckDlgButton(hwnd, IDC_RESOURCEUSAGE_CONNECTABLE, 1);
  258. CheckDlgButton(hwnd, IDC_RESOURCEUSAGE_CONTAINER, 1);
  259. return 1; // didn't call SetFocus
  260. }
  261. case WM_COMMAND:
  262. {
  263. switch (LOWORD(wParam))
  264. {
  265. case IDOK:
  266. {
  267. NETRESOURCE nr = {0};
  268. LPNETRESOURCE pnr = &nr;
  269. DWORD dwScope = 0;
  270. if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCE_CONNECTED))
  271. {
  272. dwScope = RESOURCE_CONNECTED;
  273. }
  274. else if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCE_GLOBALNET))
  275. {
  276. dwScope = RESOURCE_GLOBALNET;
  277. }
  278. else if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCE_REMEMBERED))
  279. {
  280. dwScope = RESOURCE_REMEMBERED;
  281. }
  282. else if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCE_RECENT))
  283. {
  284. dwScope = RESOURCE_RECENT;
  285. }
  286. else if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCE_CONTEXT))
  287. {
  288. dwScope = RESOURCE_CONTEXT;
  289. }
  290. else if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCE_SHAREABLE))
  291. {
  292. dwScope = RESOURCE_SHAREABLE;
  293. }
  294. else
  295. {
  296. // internal error
  297. }
  298. DWORD dwType = 0;
  299. if (1 == IsDlgButtonChecked(hwnd, IDC_DISK))
  300. {
  301. dwType = RESOURCETYPE_DISK;
  302. }
  303. else if (1 == IsDlgButtonChecked(hwnd, IDC_PRINTER))
  304. {
  305. dwType = RESOURCETYPE_PRINT;
  306. }
  307. else if (1 == IsDlgButtonChecked(hwnd, IDC_ANY))
  308. {
  309. dwType = RESOURCETYPE_ANY;
  310. }
  311. else if (1 == IsDlgButtonChecked(hwnd, IDC_RESERVED))
  312. {
  313. dwType = RESOURCETYPE_RESERVED;
  314. }
  315. else
  316. {
  317. // internal error
  318. }
  319. DWORD dwUsage = 0;
  320. if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCEUSAGE_CONNECTABLE))
  321. {
  322. dwUsage |= RESOURCEUSAGE_CONNECTABLE;
  323. }
  324. if (1 == IsDlgButtonChecked(hwnd, IDC_RESOURCEUSAGE_CONTAINER))
  325. {
  326. dwUsage |= RESOURCEUSAGE_CONTAINER;
  327. }
  328. TCHAR szRemoteName[200];
  329. LPTSTR pszRemoteName = NULL;
  330. if (1 == IsDlgButtonChecked(hwnd, IDC_REMOTE))
  331. {
  332. GetDlgItemText(hwnd, IDC_REMOTE_TEXT, szRemoteName, ARRAYLEN(szRemoteName));
  333. pszRemoteName = szRemoteName;
  334. }
  335. TCHAR szProviderName[200];
  336. LPTSTR pszProviderName = NULL;
  337. if (1 == IsDlgButtonChecked(hwnd, IDC_PROVIDER))
  338. {
  339. GetDlgItemText(hwnd, IDC_PROVIDER_TEXT, szProviderName, ARRAYLEN(szProviderName));
  340. pszProviderName = szProviderName;
  341. }
  342. pnr->dwScope = 0;
  343. pnr->dwType = 0;
  344. pnr->dwDisplayType = 0;
  345. pnr->dwUsage = 0;
  346. pnr->lpLocalName = NULL;
  347. pnr->lpRemoteName = NewDup(pszRemoteName);
  348. pnr->lpComment = NULL;
  349. pnr->lpProvider = NewDup(pszProviderName);
  350. BOOL bTranslated;
  351. UINT uiSize = GetDlgItemInt(hwnd, IDC_BUFFER_SIZE, &bTranslated, FALSE);
  352. if (bTranslated)
  353. {
  354. g_dwBufferSize = (DWORD)uiSize;
  355. }
  356. else
  357. {
  358. g_dwBufferSize = DEFAULT_BUFFER_SIZE;
  359. }
  360. g_pBuffer = (LPBYTE)LocalAlloc(LMEM_FIXED, g_dwBufferSize);
  361. if (NULL == g_pBuffer)
  362. {
  363. MessageBox(hwnd, TEXT("Error allocating buffer"), TEXT("Error"), MB_OK);
  364. EndDialog(hwnd, FALSE); // pretend we cancelled
  365. }
  366. else
  367. {
  368. g_bUseWNetFormatNetworkName = FALSE;
  369. if (1 == IsDlgButtonChecked(hwnd, IDC_USE_WNETFORMATNETWORKNAME))
  370. {
  371. g_bUseWNetFormatNetworkName = TRUE;
  372. }
  373. g_dwScope = dwScope;
  374. g_dwType = dwType;
  375. g_dwUsage = dwUsage;
  376. if ((NULL == nr.lpRemoteName) && (NULL == nr.lpProvider))
  377. {
  378. pnr = NULL; // root
  379. }
  380. INT_PTR ret = DialogBoxParam(g_hInstance,
  381. MAKEINTRESOURCE(IDD_MAIN),
  382. hwnd,
  383. DlgProcMain,
  384. (LPARAM) pnr);
  385. if (-1 == ret)
  386. {
  387. ErrorPopup(NULL, GetLastError());
  388. EndDialog(hwnd, FALSE); // pretend we cancelled
  389. }
  390. LocalFree(g_pBuffer);
  391. g_pBuffer = NULL;
  392. }
  393. return TRUE;
  394. }
  395. case IDCANCEL:
  396. EndDialog(hwnd, FALSE);
  397. return TRUE;
  398. case IDC_REMOTE:
  399. EnableWindow(GetDlgItem(hwnd, IDC_REMOTE_TEXT),
  400. (1 == IsDlgButtonChecked(hwnd, IDC_REMOTE)));
  401. return TRUE;
  402. case IDC_PROVIDER:
  403. EnableWindow(GetDlgItem(hwnd, IDC_PROVIDER_TEXT),
  404. (1 == IsDlgButtonChecked(hwnd, IDC_PROVIDER)));
  405. return TRUE;
  406. } // end switch (LOWORD(wParam))
  407. return FALSE;
  408. }
  409. default:
  410. return FALSE; // didn't process
  411. }
  412. }
  413. INT_PTR CALLBACK
  414. DlgProcMain(
  415. IN HWND hwnd,
  416. IN UINT uMsg,
  417. IN WPARAM wParam,
  418. IN LPARAM lParam
  419. )
  420. {
  421. switch (uMsg)
  422. {
  423. case WM_INITDIALOG:
  424. return OnInitDialog(hwnd, (LPNETRESOURCE)lParam);
  425. case WM_COMMAND:
  426. switch (LOWORD(wParam))
  427. {
  428. case IDOK:
  429. EndDialog(hwnd, 0);
  430. break;
  431. }
  432. return 0;
  433. case WM_NOTIFY:
  434. return OnTreeNotify(hwnd, (LPNM_TREEVIEW)lParam);
  435. default:
  436. return 0; // didn't process
  437. }
  438. }
  439. BOOL
  440. OnInitDialog(
  441. IN HWND hwnd,
  442. IN LPNETRESOURCE pRootNR
  443. )
  444. {
  445. PlaceIt(hwnd);
  446. // Set the image list
  447. HIMAGELIST himl = TreeView_SetImageList(GetDlgItem(hwnd, IDC_TREE), g_himl, TVSIL_NORMAL);
  448. // fill top-level enumeration
  449. TCHAR szBuf[500]; // for the item name
  450. szBuf[0] = TEXT('\0');
  451. GetItemText(pRootNR, szBuf);
  452. CNetResource* pnr = new CNetResource(pRootNR);
  453. // appAssert(pnr->GetNetResource()->dwDisplayType >= 0
  454. // && pnr->GetNetResource()->dwDisplayType < ARRAYLEN(g_IconIndex));
  455. int iImage = g_IconIndex[RESOURCEDISPLAYTYPE_ROOT];
  456. TV_ITEM tvi;
  457. tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  458. tvi.hItem = NULL;
  459. tvi.state = 0;
  460. tvi.stateMask = 0;
  461. tvi.pszText = szBuf;
  462. tvi.cchTextMax = 0; // not used
  463. tvi.iImage = iImage;
  464. tvi.iSelectedImage = iImage;
  465. tvi.cChildren = 1; // anything >0
  466. tvi.lParam = (LPARAM)pnr;
  467. TV_INSERTSTRUCT tvis;
  468. tvis.hParent = TVI_ROOT;
  469. tvis.item = tvi;
  470. tvis.hInsertAfter = TVI_FIRST;
  471. HTREEITEM hret = TreeView_InsertItem(GetDlgItem(hwnd, IDC_TREE), &tvis);
  472. return 1;
  473. }
  474. BOOL
  475. OnTreeNotify(
  476. IN HWND hwnd,
  477. IN LPNM_TREEVIEW ptvn
  478. )
  479. {
  480. switch (ptvn->hdr.code)
  481. {
  482. case TVN_ITEMEXPANDING:
  483. return OnExpand(hwnd, ptvn);
  484. case TVN_GETDISPINFO:
  485. return OnGetDispInfo(hwnd, ptvn);
  486. case TVN_SETDISPINFO:
  487. return 0;
  488. case TVN_DELETEITEM:
  489. {
  490. CNetResource* pnr = (CNetResource*)ptvn->itemOld.lParam;
  491. delete pnr;
  492. return 1;
  493. }
  494. default:
  495. return 0;
  496. }
  497. }
  498. BOOL
  499. OnExpand(
  500. IN HWND hwnd,
  501. IN LPNM_TREEVIEW ptvn
  502. )
  503. {
  504. HWND hwndTree = GetDlgItem(hwnd, IDC_TREE);
  505. BOOL b;
  506. CWaitCursor wait;
  507. if (ptvn->action == TVE_COLLAPSE)
  508. {
  509. // delete all children of ptvn->itemNew.hItem
  510. HTREEITEM hChild;
  511. for (;;) // forever
  512. {
  513. hChild = TreeView_GetChild(hwndTree, ptvn->itemNew.hItem);
  514. if (NULL == hChild)
  515. {
  516. break;
  517. }
  518. TreeView_DeleteItem(hwndTree, hChild);
  519. }
  520. }
  521. else if (ptvn->action == TVE_EXPAND)
  522. {
  523. // enumerate and add children
  524. HTREEITEM hParent = ptvn->itemNew.hItem;
  525. TV_ITEM tvi;
  526. tvi.hItem = hParent;
  527. tvi.mask = TVIF_PARAM;
  528. b = TreeView_GetItem(hwndTree, &tvi);
  529. CNetResource* pnrParent = (CNetResource*)tvi.lParam;
  530. LPNETRESOURCE pnr = pnrParent->GetNetResource();
  531. HANDLE hEnum;
  532. TIMEVAR(WNetOpenEnum);
  533. TIMEIN(WNetOpenEnum);
  534. TIMESTART(WNetOpenEnum);
  535. DWORD dwErr = WNetOpenEnum(
  536. g_dwScope,
  537. g_dwType,
  538. g_dwUsage,
  539. (g_dwScope == RESOURCE_GLOBALNET || g_dwScope == RESOURCE_SHAREABLE)
  540. ? pnr : NULL,
  541. &hEnum);
  542. TIMESTOP(WNetOpenEnum);
  543. TIMEOUT(WNetOpenEnum);
  544. if (NO_ERROR == dwErr)
  545. {
  546. InsertChildren(hwnd, hParent, pnrParent, hEnum);
  547. dwErr = WNetCloseEnum(hEnum);
  548. if (NO_ERROR != dwErr)
  549. {
  550. ErrorPopup(hwnd, dwErr);
  551. }
  552. }
  553. else
  554. {
  555. ErrorPopup(hwnd, dwErr);
  556. }
  557. }
  558. else
  559. {
  560. // nothing interesting
  561. }
  562. return 0;
  563. }
  564. BOOL
  565. OnGetDispInfo(
  566. IN HWND hwnd,
  567. IN LPNM_TREEVIEW ptvn
  568. )
  569. {
  570. // 1. delete all children
  571. // 2. enumerate and add children
  572. HWND hwndTree = GetDlgItem(hwnd, IDC_TREE);
  573. TV_DISPINFO* ptvdi = (TV_DISPINFO*)ptvn;
  574. if (!(TVIF_CHILDREN & ptvdi->item.mask))
  575. {
  576. // not asking for children, so go away
  577. }
  578. return 1;
  579. }
  580. TIMEVAR(WNetFormatNetworkName);
  581. VOID
  582. InsertChildren(
  583. IN HWND hwnd,
  584. IN HTREEITEM hParent,
  585. IN CNetResource* pnrParent,
  586. IN HANDLE hEnum
  587. )
  588. {
  589. DWORD cEntries = 0xffffffff; // as many as possible
  590. DWORD cNewItems = 0;
  591. NETRESOURCE* pnr;
  592. DWORD cbBuffer = g_dwBufferSize;
  593. DWORD dwErr;
  594. TIMEVAR(WNetEnumResource);
  595. TIMEVAR(InsertItems);
  596. TIMEVAR(SortItems);
  597. TIMEIN(WNetEnumResource);
  598. TIMEIN(InsertItems);
  599. TIMEIN(WNetFormatNetworkName);
  600. TIMEIN(SortItems);
  601. do
  602. {
  603. TIMESTART(WNetEnumResource);
  604. dwErr = WNetEnumResource(hEnum, &cEntries, g_pBuffer, &cbBuffer);
  605. TIMESTOP(WNetEnumResource);
  606. if (NO_ERROR == dwErr)
  607. {
  608. /////////////////
  609. TCHAR sz[300];
  610. wsprintf(sz, TEXT("Got %d entries. Total new: %d\n"), cEntries, cNewItems);
  611. OutputDebugString(sz);
  612. /////////////////
  613. TIMEVAR(InsertOnce);
  614. TIMEIN(InsertOnce);
  615. pnr = (NETRESOURCE*)g_pBuffer;
  616. cNewItems += cEntries;
  617. TIMESTART(InsertItems);
  618. TIMESTART(InsertOnce);
  619. for (DWORD i=0; i<cEntries; i++)
  620. {
  621. InsertItem(hwnd, hParent, pnrParent, &pnr[i]);
  622. }
  623. TIMESTOP(InsertOnce);
  624. TIMESTOP(InsertItems);
  625. TIMEOUT(InsertOnce);
  626. }
  627. else if (ERROR_NO_MORE_ITEMS != dwErr)
  628. {
  629. ErrorPopup(hwnd, GetLastError());
  630. }
  631. } while (dwErr == NO_ERROR);
  632. TIMESTART(SortItems);
  633. TreeView_SortChildren(GetDlgItem(hwnd, IDC_TREE), hParent, 0);
  634. TIMESTOP(SortItems);
  635. TIMEOUT(WNetEnumResource);
  636. TIMEOUT(InsertItems);
  637. TIMEOUT(WNetFormatNetworkName);
  638. TIMEOUT(SortItems);
  639. if (0 == cNewItems)
  640. {
  641. MessageBox(hwnd, TEXT("No items were found"), TEXT("Error"), MB_OK);
  642. }
  643. }
  644. VOID
  645. InsertItem(
  646. IN HWND hwnd,
  647. IN HTREEITEM hParent,
  648. IN CNetResource* pnrParent,
  649. IN LPNETRESOURCE pnr
  650. )
  651. {
  652. TCHAR szBuf[500]; // for the item name
  653. szBuf[0] = TEXT('\0');
  654. if (g_bUseWNetFormatNetworkName)
  655. {
  656. TIMESTART(WNetFormatNetworkName);
  657. DWORD dwLen = ARRAYLEN(szBuf);
  658. DWORD dwErr = WN_SUCCESS;
  659. if (NULL == pnr->lpProvider || NULL == pnr->lpRemoteName)
  660. {
  661. if (pnr->dwDisplayType == RESOURCEDISPLAYTYPE_ROOT)
  662. {
  663. _tcscpy(szBuf, g_szRoot);
  664. }
  665. else
  666. {
  667. dwErr = WN_NET_ERROR;
  668. }
  669. }
  670. else
  671. {
  672. dwErr = WNetFormatNetworkName(
  673. pnr->lpProvider,
  674. pnr->lpRemoteName,
  675. szBuf,
  676. &dwLen,
  677. WNFMT_ABBREVIATED | WNFMT_INENUM,
  678. 1000); // random large #
  679. }
  680. TIMESTOP(WNetFormatNetworkName);
  681. if (NO_ERROR != dwErr)
  682. {
  683. ErrorPopup(hwnd, GetLastError());
  684. return;
  685. }
  686. }
  687. else
  688. {
  689. GetItemText(pnr, szBuf);
  690. }
  691. CNetResource* pnrChild = new CNetResource(pnr);
  692. // appAssert(pnrChild->GetNetResource()->dwDisplayType >= 0
  693. // && pnrChild->GetNetResource()->dwDisplayType < ARRAYLEN(g_IconIndex));
  694. int iImage = g_IconIndex[pnrChild->GetNetResource()->dwDisplayType];
  695. TV_ITEM tvi;
  696. tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  697. tvi.hItem = NULL;
  698. tvi.state = 0;
  699. tvi.stateMask = 0;
  700. tvi.pszText = szBuf;
  701. tvi.cchTextMax = 0; // not used
  702. tvi.iImage = iImage;
  703. tvi.iSelectedImage = iImage;
  704. tvi.cChildren = (pnr->dwUsage & RESOURCEUSAGE_CONTAINER) ? 1 : 0;
  705. tvi.lParam = (LPARAM)pnrChild;
  706. TV_INSERTSTRUCT tvis;
  707. tvis.hParent = hParent;
  708. tvis.item = tvi;
  709. tvis.hInsertAfter = TVI_LAST;
  710. // tvis.hInsertAfter = TVI_FIRST;
  711. // tvis.hInsertAfter = TVI_SORT;
  712. HTREEITEM hret = TreeView_InsertItem(GetDlgItem(hwnd, IDC_TREE), &tvis);
  713. if (NULL == hret)
  714. {
  715. TCHAR szMess[1000];
  716. wsprintf(szMess, TEXT("Couldn't insert item %s"), szBuf);
  717. MessageBox(hwnd, szMess, TEXT("Error"), MB_OK);
  718. }
  719. }
  720. VOID
  721. GetItemText(
  722. IN LPNETRESOURCE pnr,
  723. OUT LPTSTR pszBuf // assume it's big enough
  724. )
  725. {
  726. LPTSTR pszT = NULL;
  727. TCHAR szTmp[500];
  728. *pszBuf = TEXT('\0');
  729. if (NULL == pnr)
  730. {
  731. _tcscat(pszBuf, g_szRoot);
  732. return;
  733. }
  734. if (pnr->lpRemoteName == NULL)
  735. {
  736. _stprintf(szTmp, TEXT("Null remote"));
  737. _tcscat(pszBuf, szTmp);
  738. }
  739. else if ( (pnr->lpRemoteName != NULL)
  740. && (*pnr->lpRemoteName != TEXT('\0'))
  741. )
  742. {
  743. _stprintf(szTmp, TEXT("%s"), pnr->lpRemoteName);
  744. _tcscat(pszBuf, szTmp);
  745. }
  746. if ( (pnr->lpLocalName != NULL)
  747. && (*pnr->lpLocalName != TEXT('\0'))
  748. )
  749. {
  750. _stprintf(szTmp, TEXT(" {%s}"), pnr->lpLocalName);
  751. _tcscat(pszBuf, szTmp);
  752. }
  753. if ( (pnr->lpComment != NULL)
  754. && (*pnr->lpComment != TEXT('\0'))
  755. )
  756. {
  757. _stprintf(szTmp, TEXT(" [%s]"), pnr->lpComment);
  758. _tcscat(pszBuf, szTmp);
  759. }
  760. if ( (pnr->lpProvider != NULL)
  761. && (*pnr->lpProvider != TEXT('\0'))
  762. )
  763. {
  764. _stprintf(szTmp, TEXT(" <%s>"), pnr->lpProvider);
  765. _tcscat(pszBuf, szTmp);
  766. }
  767. if (pnr->dwUsage & RESOURCEUSAGE_CONNECTABLE)
  768. {
  769. _tcscat(pszBuf, TEXT(" [connectable]"));
  770. }
  771. if (pnr->dwUsage & RESOURCEUSAGE_CONTAINER)
  772. {
  773. _tcscat(pszBuf, TEXT(" [container]"));
  774. }
  775. switch (pnr->dwDisplayType)
  776. {
  777. case RESOURCEDISPLAYTYPE_GENERIC: pszT = TEXT(" {generic}"); break;
  778. case RESOURCEDISPLAYTYPE_DOMAIN: pszT = TEXT(" {domain}"); break;
  779. case RESOURCEDISPLAYTYPE_SERVER: pszT = TEXT(" {server}"); break;
  780. case RESOURCEDISPLAYTYPE_SHARE: pszT = TEXT(" {share}"); break;
  781. case RESOURCEDISPLAYTYPE_FILE: pszT = TEXT(" {file}"); break;
  782. case RESOURCEDISPLAYTYPE_GROUP: pszT = TEXT(" {group}"); break;
  783. case RESOURCEDISPLAYTYPE_NETWORK: pszT = TEXT(" {network}"); break;
  784. case RESOURCEDISPLAYTYPE_ROOT: pszT = TEXT(" {root}"); break;
  785. case RESOURCEDISPLAYTYPE_SHAREADMIN: pszT = TEXT(" {shareadmin}"); break;
  786. case RESOURCEDISPLAYTYPE_DIRECTORY: pszT = TEXT(" {directory}"); break;
  787. case RESOURCEDISPLAYTYPE_TREE: pszT = TEXT(" {tree}"); break;
  788. default: pszT = TEXT(" {unknown}"); break;
  789. }
  790. _tcscat(pszBuf, pszT);
  791. }
  792. VOID
  793. ErrorPopup(
  794. IN HWND hwnd,
  795. IN DWORD dwErr
  796. )
  797. {
  798. TCHAR sz[500];
  799. if (dwErr == WN_EXTENDED_ERROR)
  800. {
  801. DWORD npErr;
  802. TCHAR szNpErr[500];
  803. TCHAR szNpName[500];
  804. DWORD dw = WNetGetLastError(&npErr, szNpErr, ARRAYLEN(szNpErr), szNpName, ARRAYLEN(szNpName));
  805. if (dw == WN_SUCCESS)
  806. {
  807. wsprintf(sz,
  808. TEXT("WN_EXTENDED_ERROR: %d, %s (%s)"),
  809. npErr,
  810. szNpErr,
  811. szNpName);
  812. }
  813. else
  814. {
  815. wsprintf(sz,
  816. TEXT("WN_EXTENDED_ERROR: WNetGetLastError error %d"),
  817. dw);
  818. }
  819. MessageBox(hwnd, sz, TEXT("Error"), MB_OK);
  820. }
  821. else
  822. {
  823. wsprintf(sz, TEXT("%d (0x%08lx) "), dwErr, dwErr);
  824. TCHAR szBuffer[MAX_PATH];
  825. DWORD dwBufferSize = ARRAYLEN(szBuffer);
  826. DWORD dwReturn = FormatMessage(
  827. FORMAT_MESSAGE_FROM_SYSTEM,
  828. NULL,
  829. dwErr,
  830. LANG_SYSTEM_DEFAULT,
  831. szBuffer,
  832. dwBufferSize,
  833. NULL);
  834. if (0 == dwReturn)
  835. {
  836. // couldn't find message
  837. _tcscat(sz, TEXT("unknown error"));
  838. }
  839. else
  840. {
  841. _tcscat(sz, szBuffer);
  842. }
  843. MessageBox(hwnd, sz, TEXT("Error"), MB_OK);
  844. }
  845. }