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.

873 lines
24 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // File: order.cpp
  4. //
  5. // Synopsis: code for Advanced Options->Provider Order
  6. //
  7. // History: 1-Dec-97 SumitC Created
  8. //
  9. // Copyright 1985-1997 Microsoft Corporation, All Rights Reserved
  10. //
  11. //--------------------------------------------------------------------
  12. #include "pch.h"
  13. #pragma hdrstop
  14. #include "achelp.h"
  15. #include "acsheet.h"
  16. #include "order.h"
  17. #include "ncui.h"
  18. #include "ncreg.h"
  19. #include "ncsetup.h"
  20. #include "winspool.h"
  21. extern const WCHAR c_szNetCfgHelpFile[];
  22. const int c_nMaxProviderTitle = 128;
  23. const WCHAR c_chComma = WCHAR(',');
  24. const WCHAR c_szNetwkProviderKey[] = L"System\\CurrentControlSet\\Control\\NetworkProvider\\Order";
  25. const WCHAR c_szNetwkProviderValue[] = L"ProviderOrder";
  26. const WCHAR c_szNetwkService0[] = L"System\\CurrentControlSet\\Services\\%s\\NetworkProvider";
  27. const WCHAR c_szNetwkDisplayName[] = L"Name";
  28. const WCHAR c_szNetwkClass[] = L"Class";
  29. const WCHAR c_szPrintProviderKey[] = L"System\\CurrentControlSet\\Control\\Print\\Providers";
  30. const WCHAR c_szPrintProviderValue[] = L"Order";
  31. const WCHAR c_szPrintService0[] = L"System\\CurrentControlSet\\Control\\Print\\Providers\\%s";
  32. const WCHAR c_szPrintDisplayName[] = L"DisplayName";
  33. const WCHAR c_szNetwkGetFailed[] = L"failed to get network providers";
  34. const WCHAR c_szPrintGetFailed[] = L"failed to get print providers";
  35. const DWORD g_aHelpIDs_IDD_ADVCFG_Provider[]=
  36. {
  37. IDC_TREEVIEW,IDH_TREEVIEW,
  38. IDC_MOVEUP,IDH_MOVEUP,
  39. IDC_MOVEDOWN,IDH_MOVEDOWN,
  40. 0,0
  41. };
  42. CProviderOrderDlg::CProviderOrderDlg()
  43. {
  44. m_hcurAfter = m_hcurNoDrop = NULL;
  45. m_hiconUpArrow = m_hiconDownArrow = NULL;
  46. }
  47. CProviderOrderDlg::~CProviderOrderDlg()
  48. {
  49. DeleteColString(&m_lstrNetwork);
  50. DeleteColString(&m_lstrNetworkDisp);
  51. DeleteColString(&m_lstrPrint);
  52. DeleteColString(&m_lstrPrintDisp);
  53. if (m_hiconUpArrow)
  54. {
  55. DeleteObject(m_hiconUpArrow);
  56. }
  57. if (m_hiconDownArrow)
  58. {
  59. DeleteObject(m_hiconDownArrow);
  60. }
  61. }
  62. LRESULT
  63. CProviderOrderDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  64. {
  65. HWND hwndTV;
  66. HTREEITEM htiRoot;
  67. HRESULT hr;
  68. PCWSTR pszNetwork, pszPrint;
  69. HIMAGELIST hil = NULL;
  70. INT iNetClient, iPrinter;
  71. // CascadeDialogToWindow(hwndDlg, porder->GetParent(), FALSE);
  72. // setup drag and drop cursors
  73. m_hcurAfter = LoadCursor(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDCUR_AFTER));
  74. m_hcurNoDrop = LoadCursor(NULL, IDC_NO);
  75. m_hiconUpArrow = (HICON)LoadImage(_Module.GetResourceInstance(),
  76. MAKEINTRESOURCE(IDI_UP_ARROW),
  77. IMAGE_ICON, 16, 16, 0);
  78. m_hiconDownArrow = (HICON)LoadImage(_Module.GetResourceInstance(),
  79. MAKEINTRESOURCE(IDI_DOWN_ARROW),
  80. IMAGE_ICON, 16, 16, 0);
  81. m_htiNetwork = NULL;
  82. m_htiPrint = NULL;
  83. m_fNoNetworkProv = m_fNoPrintProv = FALSE;
  84. pszNetwork = SzLoadIds(IDS_NCPA_NETWORK);
  85. pszPrint = SzLoadIds(IDS_NCPA_PRINT);
  86. //$ REVIEW (sumitc, 11-dec-97): why exactly do we have this separator line? (NT4 has it too)
  87. // Changes the style of the static control so it displays
  88. HWND hLine = GetDlgItem(IDC_STATIC_LINE);
  89. ::SetWindowLong(hLine, GWL_EXSTYLE, WS_EX_STATICEDGE | ::GetWindowLong(hLine, GWL_EXSTYLE));
  90. ::SetWindowPos(hLine, 0, 0,0,0,0, SWP_FRAMECHANGED|SWP_NOMOVE|
  91. SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
  92. // treeview stuff
  93. hwndTV = GetDlgItem(IDC_TREEVIEW);
  94. // prepare treeview
  95. {
  96. // use system imagelist functions
  97. SP_CLASSIMAGELIST_DATA cild;
  98. hr = HrSetupDiGetClassImageList(&cild);
  99. hil = ImageList_Duplicate(cild.ImageList);
  100. //$ REVIEW (sumitc, 11-dec-97) note down these indices and hardcode them?
  101. hr = ::HrSetupDiGetClassImageIndex(
  102. &cild,
  103. const_cast<LPGUID>(&GUID_DEVCLASS_NETCLIENT),
  104. &iNetClient);
  105. hr = ::HrSetupDiGetClassImageIndex(
  106. &cild,
  107. const_cast<LPGUID>(&GUID_DEVCLASS_PRINTER),
  108. &iPrinter);
  109. hr = HrSetupDiDestroyClassImageList(&cild);
  110. }
  111. TreeView_SetImageList(hwndTV, hil, TVSIL_NORMAL);
  112. // fill treeview
  113. //
  114. // Network Providers
  115. hr = ReadNetworkProviders(m_lstrNetwork, m_lstrNetworkDisp);
  116. #if DBG
  117. DumpItemList(m_lstrNetworkDisp, "Network Provider Order");
  118. #endif
  119. if (hr == S_OK)
  120. {
  121. htiRoot = AppendItem(hwndTV, (HTREEITEM)NULL, pszNetwork, NULL, iNetClient);
  122. AppendItemList(hwndTV, htiRoot, m_lstrNetworkDisp, m_lstrNetwork, iNetClient);
  123. TreeView_Expand(hwndTV, htiRoot, TVE_EXPAND);
  124. m_htiNetwork = htiRoot;
  125. }
  126. else
  127. {
  128. AppendItem(hwndTV, NULL, c_szNetwkGetFailed, NULL, iNetClient);
  129. m_fNoNetworkProv = TRUE;
  130. }
  131. // Print Providers
  132. hr = ReadPrintProviders(m_lstrPrint, m_lstrPrintDisp);
  133. #if DBG
  134. DumpItemList(m_lstrPrintDisp, "Print Provider Order");
  135. #endif
  136. if (hr == S_OK)
  137. {
  138. htiRoot = AppendItem(hwndTV, (HTREEITEM)NULL, pszPrint, NULL, iPrinter);
  139. AppendItemList(hwndTV, htiRoot, m_lstrPrintDisp, m_lstrPrint, iPrinter);
  140. TreeView_Expand(hwndTV, htiRoot, TVE_EXPAND);
  141. m_htiPrint = htiRoot;
  142. }
  143. else
  144. {
  145. AppendItem(hwndTV, NULL, c_szPrintGetFailed, NULL, iPrinter);
  146. m_fNoPrintProv = TRUE;
  147. }
  148. SendDlgItemMessage(IDC_MOVEUP, BM_SETIMAGE, IMAGE_ICON,
  149. reinterpret_cast<LPARAM>(m_hiconUpArrow));
  150. SendDlgItemMessage(IDC_MOVEDOWN, BM_SETIMAGE, IMAGE_ICON,
  151. reinterpret_cast<LPARAM>(m_hiconDownArrow));
  152. UpdateUpDownButtons(hwndTV);
  153. return TRUE;
  154. }
  155. //+---------------------------------------------------------------------------
  156. //
  157. // Method: CProviderOrderDlg::OnContextMenu
  158. //
  159. // Desc: Bring up context-sensitive help
  160. //
  161. // Args: Standard command parameters
  162. //
  163. // Return: LRESULT
  164. //
  165. LRESULT
  166. CProviderOrderDlg::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
  167. {
  168. ::WinHelp(m_hWnd,
  169. c_szNetCfgHelpFile,
  170. HELP_CONTEXTMENU,
  171. reinterpret_cast<ULONG_PTR>(g_aHelpIDs_IDD_ADVCFG_Provider));
  172. return 0;
  173. }
  174. //+---------------------------------------------------------------------------
  175. //
  176. // Method: CProviderOrderDlg::OnHelp
  177. //
  178. // Desc: Bring up context-sensitive help when dragging ? icon over a control
  179. //
  180. // Args: Standard command parameters
  181. //
  182. // Return: LRESULT
  183. //
  184. //
  185. LRESULT
  186. CProviderOrderDlg::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
  187. {
  188. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  189. Assert(lphi);
  190. if ((g_aHelpIDs_IDD_ADVCFG_Provider != NULL) && (HELPINFO_WINDOW == lphi->iContextType))
  191. {
  192. ::WinHelp(static_cast<HWND>(lphi->hItemHandle),
  193. c_szNetCfgHelpFile,
  194. HELP_WM_HELP,
  195. (ULONG_PTR)g_aHelpIDs_IDD_ADVCFG_Provider);
  196. }
  197. return 0;
  198. }
  199. //+--------------------------------------------------------------------------
  200. //
  201. // Method: CProviderOrderDlg::OnOk
  202. //
  203. // Desc: if we found network or print providers, write out the new values
  204. //
  205. // Args: [usual dialog stuff]
  206. //
  207. // Return: LRESULT
  208. //
  209. // Notes:
  210. //
  211. // History: 1-Dec-97 SumitC Created
  212. //
  213. //---------------------------------------------------------------------------
  214. LRESULT
  215. CProviderOrderDlg::OnOk(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  216. {
  217. HRESULT hr;
  218. HWND hwndTV;
  219. CWaitCursor wc;
  220. hwndTV = GetDlgItem(IDC_TREEVIEW);
  221. hr = m_fNoNetworkProv ? S_OK : WriteProviders(hwndTV, FALSE);
  222. if (hr == S_OK)
  223. {
  224. hr = m_fNoPrintProv ? S_OK : WriteProviders(hwndTV, TRUE);
  225. if (FAILED(hr))
  226. {
  227. NcMsgBox(_Module.GetResourceInstance(), m_hWnd,
  228. IDS_ADVANCEDLG_WRITE_PROVIDERS_CAPTION,
  229. IDS_ADVANCEDLG_WRITE_PRINT_PROVIDERS_ERROR,
  230. MB_OK | MB_ICONEXCLAMATION);
  231. }
  232. }
  233. else
  234. {
  235. NcMsgBox(_Module.GetResourceInstance(), m_hWnd,
  236. IDS_ADVANCEDLG_WRITE_PROVIDERS_CAPTION,
  237. IDS_ADVANCEDLG_WRITE_NET_PROVIDERS_ERROR,
  238. MB_OK | MB_ICONEXCLAMATION);
  239. }
  240. TraceError("CProviderOrderDlg::OnOk", hr);
  241. return LresFromHr(hr);
  242. }
  243. LRESULT
  244. CProviderOrderDlg::OnMoveUp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  245. {
  246. MoveItem(TRUE);
  247. return 0;
  248. }
  249. LRESULT
  250. CProviderOrderDlg::OnMoveDown(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  251. {
  252. MoveItem(FALSE);
  253. return 0;
  254. }
  255. LRESULT
  256. CProviderOrderDlg::OnTreeItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  257. {
  258. LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)pnmh;
  259. HWND hwndTV = GetDlgItem(IDC_TREEVIEW);
  260. if (pnmtv && pnmtv->itemOld.hItem)
  261. UpdateUpDownButtons(hwndTV);
  262. return 0;
  263. }
  264. //+--------------------------------------------------------------------------
  265. //
  266. // Utility member functions
  267. //
  268. //---------------------------------------------------------------------------
  269. //+--------------------------------------------------------------------------
  270. //
  271. // Method: CProviderOrderDlg::MoveItem
  272. //
  273. // Desc: does the list mangling required in order to move an item
  274. //
  275. // Args: [fMoveUp] -- true -> move up, false -> move down
  276. //
  277. // Return: HRESULT
  278. //
  279. // Notes:
  280. //
  281. // History: 1-Dec-97 SumitC Created
  282. //
  283. //---------------------------------------------------------------------------
  284. HRESULT
  285. CProviderOrderDlg::MoveItem(bool fMoveUp)
  286. {
  287. HWND hwndTV = GetDlgItem(IDC_TREEVIEW);
  288. HTREEITEM htiSel = TreeView_GetSelection(hwndTV);
  289. HTREEITEM htiOther;
  290. HTREEITEM flag;
  291. WCHAR achText[c_nMaxProviderTitle+1];
  292. TV_ITEM tvi;
  293. TV_INSERTSTRUCT tvii;
  294. // find tree element, find which element (iElement)
  295. tvi.hItem = htiSel;
  296. tvi.mask = TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_TEXT;
  297. tvi.pszText = achText;
  298. tvi.cchTextMax = c_nMaxProviderTitle;
  299. TreeView_GetItem(hwndTV, &tvi);
  300. // find the item to insert the item after
  301. if (fMoveUp)
  302. {
  303. htiOther = TreeView_GetPrevSibling(hwndTV, htiSel);
  304. if (NULL != htiOther)
  305. {
  306. htiOther = TreeView_GetPrevSibling(hwndTV, htiOther);
  307. }
  308. flag = TVI_FIRST;
  309. }
  310. else
  311. {
  312. htiOther = TreeView_GetNextSibling(hwndTV, htiSel);
  313. flag = TVI_LAST;
  314. }
  315. // insert into new location
  316. if (NULL == htiOther)
  317. {
  318. tvii.hInsertAfter = flag;
  319. }
  320. else
  321. {
  322. tvii.hInsertAfter = htiOther;
  323. }
  324. tvii.hParent = TreeView_GetParent(hwndTV, htiSel);
  325. tvii.item = tvi;
  326. htiOther = TreeView_InsertItem(hwndTV, &tvii);
  327. // remove from old location
  328. TreeView_DeleteItem(hwndTV, htiSel);
  329. // set selection focus to new location
  330. TreeView_SelectItem(hwndTV, htiOther);
  331. return S_OK;
  332. }
  333. //+--------------------------------------------------------------------------
  334. //
  335. // Method: CProviderOrderDlg::UpdateUpDownButtons
  336. //
  337. // Desc: enables/disables the up and down arrows as appropriate
  338. //
  339. // Args: [hwndTV] -- handle to the treeview root
  340. //
  341. // Return: HRESULT
  342. //
  343. // Notes:
  344. //
  345. // History: 1-Dec-97 SumitC Created
  346. //
  347. //---------------------------------------------------------------------------
  348. HRESULT
  349. CProviderOrderDlg::UpdateUpDownButtons(HWND hwndTV)
  350. {
  351. HTREEITEM htiSel;
  352. bool fEnableUp, fEnableDown;
  353. HWND hwndUp = GetDlgItem(IDC_MOVEUP);
  354. HWND hwndDn = GetDlgItem(IDC_MOVEDOWN);
  355. HWND hwndFocus = GetFocus();
  356. HWND hwndNewFocus = hwndTV;
  357. UINT nIdNewDef = 0;
  358. // Initialize to disabled
  359. fEnableUp = fEnableDown = FALSE;
  360. if (htiSel = TreeView_GetSelection(hwndTV))
  361. {
  362. // if this item has no children it can be moved.
  363. //
  364. if (TreeView_GetChild(hwndTV, htiSel) == NULL)
  365. {
  366. if (TreeView_GetPrevSibling(hwndTV, htiSel) != NULL)
  367. {
  368. // Enable Move Up button
  369. fEnableUp = TRUE;
  370. }
  371. if (TreeView_GetNextSibling(hwndTV, htiSel) != NULL)
  372. {
  373. // Enable Move Down button
  374. fEnableDown = TRUE;
  375. }
  376. }
  377. }
  378. if ((hwndFocus == hwndUp) && (FALSE == fEnableUp))
  379. {
  380. if (fEnableDown)
  381. {
  382. hwndNewFocus = hwndDn;
  383. nIdNewDef = IDC_MOVEDOWN;
  384. }
  385. SetDefaultButton(m_hWnd, nIdNewDef);
  386. ::SetFocus(hwndNewFocus);
  387. }
  388. else if ((hwndFocus == hwndDn) && (FALSE == fEnableDown))
  389. {
  390. if (fEnableUp)
  391. {
  392. hwndNewFocus = hwndUp;
  393. nIdNewDef = IDC_MOVEUP;
  394. }
  395. SetDefaultButton(m_hWnd, nIdNewDef);
  396. ::SetFocus(hwndNewFocus);
  397. }
  398. else
  399. {
  400. // Neither Up or Down is button with focus, remove any default button
  401. //
  402. SetDefaultButton(m_hWnd, 0);
  403. }
  404. ::EnableWindow(hwndUp, fEnableUp);
  405. ::EnableWindow(hwndDn, fEnableDown);
  406. return S_OK;
  407. }
  408. //+--------------------------------------------------------------------------
  409. //
  410. // Method: CProviderOrderDlg::WriteProviders
  411. //
  412. // Desc: writes out, to the registry, the providers for network/print,
  413. //
  414. // Args: [hwndTV] -- handle to treeview
  415. // [fPrint] -- true -> print, false -> network
  416. //
  417. // Return: HRESULT
  418. //
  419. // Notes:
  420. //
  421. // History: 1-Dec-97 SumitC Created
  422. //
  423. //---------------------------------------------------------------------------
  424. HRESULT
  425. CProviderOrderDlg::WriteProviders(HWND hwndTV, bool fPrint)
  426. {
  427. HRESULT hr = S_OK;
  428. ListStrings lstrNewOrder;
  429. HTREEITEM htvi;
  430. TV_ITEM tvi;
  431. WCHAR achBuf[c_nMaxProviderTitle+1];
  432. HKEY hkey = NULL;
  433. tvi.mask = TVIF_TEXT;
  434. tvi.pszText = achBuf;
  435. tvi.cchTextMax = c_nMaxProviderTitle;
  436. // retrieve items in order
  437. ListStrings * plstrProvider = fPrint ? &m_lstrPrint : &m_lstrNetwork;
  438. #if DBG
  439. DumpItemList(*plstrProvider, "WriteProviders list (just before clearing)");
  440. #endif
  441. plstrProvider->clear();
  442. // we clear out the provider list, but NOTE! we don't delete the tstrings,
  443. // since they're still being referenced by the lParams of the treeview items.
  444. // the following block of code gets them back into (a new) m_lstrX.
  445. htvi = TreeView_GetChild(hwndTV, fPrint ? m_htiPrint : m_htiNetwork);
  446. while (NULL != htvi)
  447. {
  448. tvi.hItem = htvi;
  449. TreeView_GetItem(hwndTV, &tvi);
  450. TraceTag(ttidAdvCfg, "recovered item: %S and %S", tvi.pszText, ((tstring *)(tvi.lParam))->c_str());
  451. plstrProvider->push_back((tstring *)(tvi.lParam));
  452. htvi = TreeView_GetNextSibling(hwndTV, htvi);
  453. }
  454. if (fPrint)
  455. {
  456. #if DBG
  457. DumpItemList(m_lstrPrint, "PrintProviders");
  458. #endif
  459. PROVIDOR_INFO_2 p2info;
  460. ColStringToMultiSz(m_lstrPrint, &p2info.pOrder);
  461. if (!AddPrintProvidor(NULL, 2, reinterpret_cast<LPBYTE>(&p2info)))
  462. {
  463. hr = HrFromLastWin32Error();
  464. }
  465. delete [] p2info.pOrder;
  466. }
  467. else
  468. {
  469. hr = ::HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szNetwkProviderKey, KEY_WRITE, &hkey);
  470. if (hr == S_OK)
  471. {
  472. tstring str;
  473. ::ConvertColStringToString(m_lstrNetwork, c_chComma, str);
  474. #if DBG
  475. TraceTag(ttidAdvCfg, "net providers = %S", str.c_str());
  476. #endif
  477. hr = ::HrRegSetSz(hkey, c_szNetwkProviderValue, str.c_str());
  478. }
  479. }
  480. RegSafeCloseKey(hkey);
  481. return hr;
  482. }
  483. //+--------------------------------------------------------------------------
  484. //
  485. // Utility functions (non-member)
  486. //
  487. //---------------------------------------------------------------------------
  488. //+-------------------------------------------------------------------------
  489. //
  490. // Func: AppendItem
  491. //
  492. // Desc: adds one item into a treeview control
  493. //
  494. // Args:
  495. //
  496. // Return:
  497. //
  498. // Notes:
  499. //
  500. // History: 1-Dec-97 SumitC Created
  501. //
  502. //--------------------------------------------------------------------------
  503. HTREEITEM
  504. AppendItem(HWND hwndTV, HTREEITEM htiRoot, PCWSTR pszText, void * lParam, INT iImage)
  505. {
  506. TV_INSERTSTRUCT tvis;
  507. tvis.hParent = htiRoot;
  508. tvis.hInsertAfter = TVI_LAST;
  509. tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  510. tvis.item.pszText = (PWSTR) pszText;
  511. tvis.item.iImage = iImage;
  512. tvis.item.iSelectedImage = iImage;
  513. tvis.item.lParam = (LPARAM) lParam;
  514. TraceTag(ttidAdvCfg, "append item: item = %S, data = %S", pszText, lParam ? ((tstring *)(lParam))->c_str() : L"null");
  515. return( TreeView_InsertItem( hwndTV, &tvis ) );
  516. }
  517. //+--------------------------------------------------------------------------
  518. //
  519. // Func: AppendItemList
  520. //
  521. // Desc: adds a list of providers as subitems to a given tree node.
  522. //
  523. // Args:
  524. //
  525. // Return: (void)
  526. //
  527. // Notes:
  528. //
  529. // History: 1-Dec-97 SumitC Created
  530. //
  531. //---------------------------------------------------------------------------
  532. void
  533. AppendItemList(HWND hwndTV, HTREEITEM htiRoot, ListStrings lstr, ListStrings lstr2, INT iImage)
  534. {
  535. ListIter iter;
  536. ListIter iter2;
  537. AssertSz(lstr.size() == lstr2.size(), "data corruption - these lists should the same size");
  538. for (iter = lstr.begin(), iter2 = lstr2.begin();
  539. iter != lstr.end();
  540. iter++, iter2++)
  541. {
  542. AppendItem(hwndTV, (HTREEITEM)htiRoot, (*iter)->c_str(), (void *)(*iter2), iImage);
  543. }
  544. }
  545. //+--------------------------------------------------------------------------
  546. //
  547. // Meth: ReadNetworkProviders
  548. //
  549. // Desc: fills up lstr with network provider names, and lstrDisp with the
  550. // corresponding 'friendly' names.
  551. //
  552. // Args: [lstr] -- string list for providers (short names)
  553. // [lstrDisp] -- string list for provider display-names (friendly names)
  554. //
  555. // Return: HRESULT
  556. //
  557. // Notes: m_lstrNetwork and m_lstrNetworkDisp must be empty on entry.
  558. //
  559. // History: 1-Dec-97 SumitC Created
  560. //
  561. //---------------------------------------------------------------------------
  562. HRESULT
  563. ReadNetworkProviders(ListStrings& lstr, ListStrings& lstrDisp)
  564. {
  565. HKEY hkey;
  566. HRESULT hr;
  567. ListIter iter;
  568. AssertSz(lstr.empty(), "incorrect call order (this should be empty)");
  569. WCHAR szBuf[c_nMaxProviderTitle + 1];
  570. DWORD cBuf = sizeof(szBuf);
  571. hr = ::HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szNetwkProviderKey, KEY_READ, &hkey);
  572. if (hr == S_OK)
  573. {
  574. hr = ::HrRegQuerySzBuffer(hkey, c_szNetwkProviderValue, szBuf, &cBuf);
  575. if (hr == S_OK)
  576. {
  577. ConvertStringToColString(szBuf, c_chComma, lstr);
  578. }
  579. RegSafeCloseKey(hkey);
  580. }
  581. if (hr)
  582. goto Error;
  583. AssertSz(lstrDisp.empty(), "incorrect call order (this should be empty)");
  584. for (iter = lstr.begin(); iter != lstr.end(); iter++)
  585. {
  586. WCHAR szBuf[c_nMaxProviderTitle + sizeof(c_szNetwkService0)];
  587. tstring str;
  588. HKEY hkeyProv;
  589. wsprintfW(szBuf, c_szNetwkService0, (*iter)->c_str());
  590. hr = ::HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuf, KEY_READ, &hkeyProv);
  591. if (hr == S_OK)
  592. {
  593. #if 0
  594. DWORD dwClass = 0;
  595. // now get displayname and class
  596. hr = ::HrRegQueryDword(hkeyProv, c_szNetwkClass, &dwClass);
  597. if (dwClass & WN_NETWORK_CLASS)
  598. {
  599. #endif
  600. hr = ::HrRegQueryString(hkeyProv, c_szNetwkDisplayName, &str);
  601. if (hr == S_OK)
  602. {
  603. lstrDisp.push_back(new tstring(str));
  604. }
  605. else
  606. {
  607. TraceTag(ttidAdvCfg, "failed to get DisplayName for network provider %S", (*iter)->c_str());
  608. }
  609. #if 0
  610. }
  611. else
  612. {
  613. hr = S_OK;
  614. // actually, if we start taking the netclass into account we'll
  615. // have to delete the corresponding item (*iter) from m_lstrNetwork,
  616. // otherwise the two lists will be out of sync.
  617. }
  618. #endif
  619. RegSafeCloseKey(hkeyProv);
  620. }
  621. else
  622. {
  623. TraceTag(ttidAdvCfg, "a member of the networkprovider string is missing NetworkProvider key under Services!");
  624. }
  625. }
  626. AssertSz(lstr.size() == lstrDisp.size(), "lists must be the same size");
  627. Error:
  628. return hr;
  629. }
  630. //+--------------------------------------------------------------------------
  631. //
  632. // Method: ReadPrintProviders
  633. //
  634. // Desc: fills up lstr with print provider names, and lstrDisp with the
  635. // corresponding 'friendly' names.
  636. //
  637. // Args: [lstr] -- string list for providers (short names)
  638. // [lstrDisp] -- string list for provider display-names (friendly names)
  639. //
  640. // Return: HRESULT
  641. //
  642. // Notes: m_lstrPrint and m_lstrPrintDisp must be empty on entry.
  643. //
  644. // History: 1-Dec-97 SumitC Created
  645. //
  646. //---------------------------------------------------------------------------
  647. HRESULT
  648. ReadPrintProviders(ListStrings& lstr, ListStrings& lstrDisp)
  649. {
  650. HKEY hkey;
  651. HRESULT hr;
  652. ListIter iter;
  653. AssertSz(lstr.empty(), "incorrect call order (this should be empty)");
  654. hr = ::HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szPrintProviderKey, KEY_READ, &hkey);
  655. if (hr == S_OK)
  656. {
  657. hr = ::HrRegQueryColString(hkey, c_szPrintProviderValue, &lstr);
  658. RegSafeCloseKey(hkey);
  659. }
  660. AssertSz(lstrDisp.empty(), "incorrect call order (this should be empty)");
  661. for (iter = lstr.begin(); iter != lstr.end(); iter++)
  662. {
  663. WCHAR szBuf[c_nMaxProviderTitle + sizeof(c_szPrintService0)];
  664. tstring str;
  665. HKEY hkeyProv;
  666. wsprintfW(szBuf, c_szPrintService0, (*iter)->c_str());
  667. hr = ::HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuf, KEY_READ, &hkeyProv);
  668. if (hr == S_OK)
  669. {
  670. hr = ::HrRegQueryString(hkeyProv, c_szPrintDisplayName, &str);
  671. if (hr == S_OK)
  672. {
  673. lstrDisp.push_back(new tstring(str));
  674. }
  675. else
  676. {
  677. TraceTag(ttidAdvCfg, "failed to get DisplayName for printer %S", (*iter)->c_str());
  678. }
  679. RegSafeCloseKey(hkeyProv);
  680. }
  681. else
  682. {
  683. TraceTag(ttidAdvCfg, "a member of the print/providers/order string doesn't have key under control/print/providers!");
  684. }
  685. }
  686. AssertSz(lstr.size() == lstrDisp.size(), "lists must be the same size");
  687. return hr;
  688. }
  689. bool
  690. AreThereMultipleProviders(void)
  691. {
  692. HRESULT hr;
  693. ListStrings lstrN, lstrND, lstrP, lstrPD; // netwk, netwk display, etc..
  694. bool fRetval = FALSE;
  695. hr = ReadNetworkProviders(lstrN, lstrND);
  696. if (hr == S_OK)
  697. {
  698. hr = ReadPrintProviders(lstrP, lstrPD);
  699. if (hr == S_OK)
  700. {
  701. fRetval = ((lstrN.size() > 1) || (lstrP.size() > 1));
  702. }
  703. }
  704. DeleteColString(&lstrN);
  705. DeleteColString(&lstrND);
  706. DeleteColString(&lstrP);
  707. DeleteColString(&lstrPD);
  708. return fRetval;
  709. }
  710. #if DBG
  711. //+--------------------------------------------------------------------------
  712. //
  713. // Funct: DumpItemList
  714. //
  715. // Desc: debug utility function to dump out the given list
  716. //
  717. // Args:
  718. //
  719. // Return: (void)
  720. //
  721. // Notes:
  722. //
  723. // History: 1-Dec-97 SumitC Created
  724. //
  725. //---------------------------------------------------------------------------
  726. static void
  727. DumpItemList(ListStrings& lstr, PSTR szInfoAboutList = NULL)
  728. {
  729. ListIter iter;
  730. if (szInfoAboutList)
  731. {
  732. TraceTag(ttidAdvCfg, "Dumping contents of: %s", szInfoAboutList);
  733. }
  734. for (iter = lstr.begin(); iter != lstr.end(); ++iter)
  735. {
  736. PWSTR psz = (PWSTR)((*iter)->c_str());
  737. TraceTag(ttidAdvCfg, "%S", psz);
  738. }
  739. TraceTag(ttidAdvCfg, "... end list");
  740. }
  741. #endif