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.

4435 lines
138 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: browser.cpp
  7. //
  8. // Contents: implementation of the general GPO browser pane
  9. //
  10. // Classes: CBrowserPP
  11. //
  12. // Functions:
  13. //
  14. // History: 04-30-1998 stevebl Created
  15. //
  16. // Notes: This is the pane that behaves much like the standard file
  17. // open dialog. The class is used for all panes that have this
  18. // format since they share so much functionality. The
  19. // dwPageType parameter passed to CBrowserPP::Initialize is
  20. // used to distinguish between the different flavors.
  21. //
  22. //---------------------------------------------------------------------------
  23. #include "main.h"
  24. #include "browser.h"
  25. #include "commctrl.h"
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. //
  32. // Help ids
  33. //
  34. DWORD aBrowserDomainHelpIds[] =
  35. {
  36. IDC_COMBO1, IDH_BROWSER_LOOKIN,
  37. IDC_LIST1, IDH_BROWSER_DOMAINGPO,
  38. IDC_DESCRIPTION, IDH_NOCONTEXTHELP,
  39. 0, 0
  40. };
  41. DWORD aBrowserSiteHelpIds[] =
  42. {
  43. IDC_COMBO1, IDH_BROWSER_SITELIST,
  44. IDC_LIST1, IDH_BROWSER_GPOLIST,
  45. IDC_DESCRIPTION, IDH_NOCONTEXTHELP,
  46. 0, 0
  47. };
  48. DWORD aBrowserAllHelpIds[] =
  49. {
  50. IDC_COMBO1, IDH_BROWSER_DOMAINLIST,
  51. IDC_LIST1, IDH_BROWSER_FULLGPOLIST,
  52. IDC_DESCRIPTION, IDH_NOCONTEXTHELP,
  53. 0, 0
  54. };
  55. CBrowserPP::CBrowserPP()
  56. {
  57. m_ppActive = NULL;
  58. m_pGBI = NULL;
  59. m_pPrevSel = NULL;
  60. m_szServerName = NULL;
  61. m_szDomainName = NULL;
  62. }
  63. //+--------------------------------------------------------------------------
  64. //
  65. // Function: CopyAsFriendlyName
  66. //
  67. // Synopsis: Copies a LDAP path converting it to a friendly name by
  68. // removing the "LDAP://" and "XX=" and converting "," to "."
  69. // and removing a server name (if any)
  70. //
  71. // Arguments: [lpDest] - destination buffer
  72. // [lpSrc] - source buffer
  73. //
  74. // Returns: nothing
  75. //
  76. // History: 5-07-1998 stevebl Created
  77. //
  78. // Notes: The destination buffer should be as large as the source
  79. // buffer to ensure safe completion. lpDest and lpSrc may both
  80. // point to the same buffer.
  81. //
  82. // As an example, this routine would convert the following path:
  83. // LDAP://DC=abcd,DC=efg
  84. // into this:
  85. // abcd.efg
  86. //
  87. //---------------------------------------------------------------------------
  88. void CopyAsFriendlyName(WCHAR * lpDest, WCHAR * lpSrc)
  89. {
  90. LPOLESTR lpProvider = L"LDAP://";
  91. DWORD dwStrLen = wcslen(lpProvider);
  92. // lpStopChecking marks the last spot where we can safely
  93. // look ahead 2 spaces for an '=' character. Anything past
  94. // this and we are looking in memory we don't own.
  95. OLECHAR * lpStopChecking = (wcslen(lpSrc) - 2) + lpSrc;
  96. //
  97. // Skip the LDAP:// if found
  98. //
  99. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  100. lpProvider, dwStrLen, lpSrc, dwStrLen) == CSTR_EQUAL)
  101. {
  102. lpSrc += dwStrLen;
  103. }
  104. //
  105. // Remove server name (if any)
  106. //
  107. if (lpSrc < lpStopChecking)
  108. {
  109. if (*(lpSrc+2) != L'=')
  110. {
  111. // look for a '/' character marking the end of a server name
  112. while (*lpSrc)
  113. {
  114. if (*lpSrc == L'/')
  115. {
  116. lpSrc++;
  117. break;
  118. }
  119. lpSrc++;
  120. }
  121. }
  122. }
  123. //
  124. // Parse through the name replacing all the XX= with .
  125. //
  126. while (*lpSrc)
  127. {
  128. if (lpSrc < lpStopChecking)
  129. {
  130. if (*(lpSrc+2) == L'=')
  131. {
  132. lpSrc += 3;
  133. }
  134. }
  135. while (*lpSrc && (*lpSrc != L','))
  136. {
  137. // remove escape sequences
  138. if (*lpSrc == L'\\')
  139. {
  140. lpSrc++;
  141. // special cases
  142. // make sure that '\\x' becomes '\x'
  143. if (*lpSrc == L'\\')
  144. {
  145. *lpDest++ = *lpSrc++;
  146. }
  147. // make sure that '\0D' becomes '\r'
  148. else if (*lpSrc == L'0' && *(lpSrc+1) == L'D')
  149. {
  150. *lpDest++ = L'\r';
  151. lpSrc += 2;
  152. }
  153. // make sure that '\0A' becomes '\n'
  154. else if (*lpSrc == L'0' && *(lpSrc+1) == L'A')
  155. {
  156. *lpDest++ = L'\n';
  157. lpSrc += 2;
  158. }
  159. }
  160. else
  161. {
  162. *lpDest++ = *lpSrc++;
  163. }
  164. }
  165. if (*lpSrc == L',')
  166. {
  167. *lpDest++ = L'.';
  168. lpSrc++;
  169. }
  170. }
  171. *lpDest = L'\0';
  172. }
  173. //+--------------------------------------------------------------------------
  174. //
  175. // Member: CBrowserPP::Initialize
  176. //
  177. // Synopsis: Initializes the property page.
  178. //
  179. // Arguments: [dwPageType] - used to identify which page this is. (See
  180. // notes.)
  181. // [pGBI] - pointer to the browse info structure passed
  182. // by caller
  183. // [ppActive] - pointer to a common variable that remembers
  184. // which object was last given the focus.
  185. // Needed because only the page with the focus
  186. // is allowed to return data to the caller when
  187. // the property sheet is dismissed.
  188. //
  189. // Returns: Handle to the newly created property page.
  190. //
  191. // Modifies:
  192. //
  193. // Derivation:
  194. //
  195. // History: 04-30-1998 stevebl Created
  196. //
  197. // Notes: This class implements the following property pages:
  198. // PAGETYPE_DOMAINS - GPO's linked to domains
  199. // PAGETYPE_SITES - GPO's linked to sites
  200. // PAGETYPE_ALL - All GPO's in a selected
  201. //
  202. // PAGETYPE_COMPUTERS is implemented by CCompsPP since it
  203. // behaves so differently.
  204. //
  205. //---------------------------------------------------------------------------
  206. HPROPSHEETPAGE CBrowserPP::Initialize(DWORD dwPageType, LPGPOBROWSEINFO pGBI, void * * ppActive)
  207. {
  208. m_ppActive = ppActive;
  209. m_dwPageType = dwPageType;
  210. m_pGBI = pGBI;
  211. if (m_pGBI->lpInitialOU)
  212. {
  213. //
  214. // Get the server name
  215. //
  216. m_szServerName = ExtractServerName(m_pGBI->lpInitialOU);
  217. DebugMsg((DM_VERBOSE, TEXT("CBrowserPP::Initialize extracted server name: %s"), m_szServerName));
  218. //
  219. // Get the friendly domain name
  220. //
  221. LPOLESTR pszDomain = GetDomainFromLDAPPath(m_pGBI->lpInitialOU);
  222. //
  223. // Convert LDAP to dot (DN) style
  224. //
  225. if (pszDomain)
  226. {
  227. ConvertToDotStyle (pszDomain, &m_szDomainName);
  228. DebugMsg((DM_VERBOSE, TEXT("CBrowserPP::Initialize extracted domain name: %s"), m_szDomainName));
  229. delete [] pszDomain;
  230. }
  231. }
  232. DWORD dwTitle;
  233. switch (dwPageType)
  234. {
  235. case PAGETYPE_DOMAINS:
  236. dwTitle = IDS_DOMAINS;
  237. break;
  238. case PAGETYPE_SITES:
  239. dwTitle = IDS_SITES;
  240. break;
  241. case PAGETYPE_ALL:
  242. default:
  243. dwTitle = IDS_ALL;
  244. break;
  245. }
  246. LoadString(g_hInstance, dwTitle, m_szTitle, sizeof(m_szTitle) / sizeof(WCHAR));
  247. PROPSHEETPAGE psp;
  248. memset(&psp, 0, sizeof(psp));
  249. psp.dwSize = sizeof(psp);
  250. psp.dwFlags = PSP_USETITLE;
  251. psp.pszTitle = m_szTitle;
  252. psp.hInstance = g_hInstance;
  253. psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_GPOBROWSER);
  254. return CreatePropertySheetPage(&psp);
  255. }
  256. CBrowserPP::~CBrowserPP()
  257. {
  258. if (m_szServerName)
  259. {
  260. LocalFree(m_szServerName);
  261. }
  262. if (m_szDomainName)
  263. {
  264. LocalFree(m_szDomainName);
  265. }
  266. }
  267. /////////////////////////////////////////////////////////////////////////////
  268. // CBrowserPP message handlers
  269. INT CBrowserPP::AddElement(MYLISTEL * pel, INT index)
  270. {
  271. LV_ITEM item;
  272. memset(&item, 0, sizeof(item));
  273. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  274. if (-1 == index)
  275. {
  276. index = ListView_GetItemCount(m_hList);
  277. }
  278. item.iItem = index;
  279. item.pszText = pel->szName;
  280. if (pel->nType == ITEMTYPE_FOREST)
  281. {
  282. item.iImage = 10;
  283. }
  284. else if (pel->nType == ITEMTYPE_SITE)
  285. {
  286. item.iImage = 6;
  287. }
  288. else if (pel->nType == ITEMTYPE_DOMAIN)
  289. {
  290. item.iImage = 7;
  291. }
  292. else if (pel->nType == ITEMTYPE_OU)
  293. {
  294. item.iImage = 0;
  295. }
  296. else
  297. {
  298. if (pel->bDisabled)
  299. {
  300. item.iImage = 3;
  301. }
  302. else
  303. {
  304. item.iImage = 2;
  305. }
  306. }
  307. item.lParam = (LPARAM)pel;
  308. index = ListView_InsertItem(m_hList, &item);
  309. if (index != -1 && pel->nType == ITEMTYPE_GPO)
  310. {
  311. // check to see if we need to add the domain name
  312. LPOLESTR szObject = GetCurrentObject();
  313. LPOLESTR szDomain = GetDomainFromLDAPPath(pel->szData);
  314. if (szDomain && szObject)
  315. {
  316. // ignore potential differences in server name when we compare
  317. // the domain paths
  318. LPOLESTR szBuffer1 = NULL;
  319. LPOLESTR szBuffer2 = NULL;
  320. szBuffer1 = new OLECHAR[wcslen(szObject) + 1];
  321. szBuffer2 = new OLECHAR[wcslen(szDomain) + 1];
  322. if (NULL != szBuffer1 && NULL != szBuffer1)
  323. {
  324. CopyAsFriendlyName(szBuffer1, szObject);
  325. CopyAsFriendlyName(szBuffer2, szDomain);
  326. if (0 != wcscmp(szBuffer1, szBuffer2))
  327. {
  328. // Need to add the domain name since the domain is different
  329. // from the focus object.
  330. // Need to convert the domain to a friendly name.
  331. // Let's just do it in place so I don't have to allocate any
  332. // more memory. :)
  333. // We can get away with this because the string can only get smaller.
  334. CopyAsFriendlyName(szDomain, szDomain);
  335. memset(&item, 0, sizeof(item));
  336. item.mask = LVIF_TEXT;
  337. item.iItem = index;
  338. item.iSubItem = 1;
  339. item.pszText = szDomain;
  340. ListView_SetItem(m_hList, &item);
  341. }
  342. }
  343. if (szBuffer1)
  344. {
  345. delete [] szBuffer1;
  346. }
  347. if (szBuffer2)
  348. {
  349. delete [] szBuffer2;
  350. }
  351. }
  352. if (szDomain)
  353. delete [] szDomain;
  354. if (szObject)
  355. delete [] szObject;
  356. }
  357. return (index);
  358. }
  359. #include "ntdsapi.h"
  360. //+--------------------------------------------------------------------------
  361. //
  362. // Member: CBrowserPP::FillSitesList
  363. //
  364. // Synopsis: Fills the combobox with the trusted sites information.
  365. // The szData member of the combobox element structure is the
  366. // containing domain.
  367. //
  368. // Returns: TRUE - successful
  369. // FALSE - error
  370. //
  371. // History: 05-04-1998 stevebl created
  372. // 05-27-1999 stevebl now initializes to site in lpInitialOU
  373. //
  374. //---------------------------------------------------------------------------
  375. BOOL CBrowserPP::FillSitesList ()
  376. {
  377. HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  378. PDS_NAME_RESULTW pSites;
  379. int iInitialSite = 0;
  380. int iIndex = -1;
  381. HANDLE hDs;
  382. DWORD dw = DsBindW(NULL, NULL, &hDs);
  383. if (ERROR_SUCCESS == dw)
  384. {
  385. dw = DsListSitesW(hDs, &pSites);
  386. if (ERROR_SUCCESS == dw)
  387. {
  388. DWORD n = 0;
  389. for (n = 0; n < pSites->cItems; n++)
  390. {
  391. //
  392. // Add the site name (if it has a name)
  393. //
  394. if (pSites->rItems[n].pName)
  395. {
  396. LPTSTR lpFullPath, lpTempPath;
  397. LOOKDATA * pdata;
  398. pdata = new LOOKDATA;
  399. if (pdata)
  400. {
  401. HRESULT hr;
  402. ULONG ulNoChars;
  403. ulNoChars = wcslen(pSites->rItems[n].pName)+1;
  404. pdata->szName = new WCHAR[ulNoChars];
  405. if (pdata->szName)
  406. {
  407. hr = StringCchCopy(pdata->szName, ulNoChars, pSites->rItems[n].pName);
  408. ASSERT(SUCCEEDED(hr));
  409. }
  410. pdata->szData = NULL;
  411. ulNoChars = lstrlen(pSites->rItems[n].pName) + 10;
  412. lpTempPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  413. if (lpTempPath)
  414. {
  415. hr = StringCchCopy (lpTempPath, ulNoChars, TEXT("LDAP://"));
  416. ASSERT(SUCCEEDED(hr));
  417. hr = StringCchCat (lpTempPath, ulNoChars, pSites->rItems[n].pName);
  418. ASSERT(SUCCEEDED(hr));
  419. lpFullPath = GetFullPath (lpTempPath, m_hwndDlg);
  420. if (lpFullPath)
  421. {
  422. ulNoChars = wcslen(lpFullPath)+1;
  423. pdata->szData = new WCHAR[ulNoChars];
  424. if (pdata->szData)
  425. {
  426. hr = StringCchCopy(pdata->szData, ulNoChars, lpFullPath);
  427. ASSERT(SUCCEEDED(hr));
  428. }
  429. LocalFree (lpFullPath);
  430. }
  431. LocalFree (lpTempPath);
  432. }
  433. if (!pdata->szData)
  434. {
  435. if (pdata->szName)
  436. {
  437. delete [] pdata->szName;
  438. }
  439. delete pdata;
  440. continue;
  441. }
  442. // try and use a friendlier name for the site
  443. {
  444. IADs * pADs = NULL;
  445. // Get the friendly display name
  446. hr = OpenDSObject(pdata->szData, IID_IADs,
  447. (void **)&pADs);
  448. if (SUCCEEDED(hr))
  449. {
  450. VARIANT varName;
  451. BSTR bstrNameProp;
  452. VariantInit(&varName);
  453. bstrNameProp = SysAllocString(SITE_NAME_PROPERTY);
  454. if (bstrNameProp)
  455. {
  456. hr = pADs->Get(bstrNameProp, &varName);
  457. if (SUCCEEDED(hr))
  458. {
  459. ulNoChars = wcslen(varName.bstrVal) + 1;
  460. LPOLESTR sz = new OLECHAR[ulNoChars];
  461. if (sz)
  462. {
  463. hr = StringCchCopy(sz, ulNoChars, varName.bstrVal);
  464. ASSERT(SUCCEEDED(hr));
  465. if (pdata->szName)
  466. delete [] pdata->szName;
  467. pdata->szName = sz;
  468. }
  469. }
  470. SysFreeString(bstrNameProp);
  471. }
  472. VariantClear(&varName);
  473. pADs->Release();
  474. }
  475. }
  476. pdata->nIndent = 0;
  477. pdata->nType = ITEMTYPE_SITE;
  478. iIndex = (int)SendMessage(m_hCombo, CB_INSERTSTRING, (WPARAM) -1, (LPARAM) (LPCTSTR) pdata);
  479. if (CB_ERR == iIndex)
  480. {
  481. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddSitesList: Failed to alloc memory with %d"), GetLastError()));
  482. }
  483. if (NULL != pdata->szData && NULL != m_pGBI->lpInitialOU)
  484. {
  485. if (0 == wcscmp(pdata->szData, m_pGBI->lpInitialOU))
  486. {
  487. iInitialSite = iIndex;
  488. }
  489. }
  490. }
  491. }
  492. }
  493. DsFreeNameResultW(pSites);
  494. }
  495. DsUnBindW(&hDs);
  496. }
  497. else
  498. {
  499. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddSitesList: DsBindW failed with 0x%x"), dw));
  500. ReportError(m_hwndDlg, dw, IDS_DSBINDFAILED);
  501. }
  502. if (iIndex >= 0)
  503. {
  504. SendMessage (m_hCombo, CB_SETCURSEL, iInitialSite, 0);
  505. }
  506. SetCursor(hcur);
  507. return TRUE;
  508. }
  509. PDS_DOMAIN_TRUSTS Domains;
  510. int __cdecl CompareDomainInfo(const void * arg1, const void * arg2)
  511. {
  512. WCHAR * sz1, *sz2;
  513. sz1 = Domains[*(ULONG *)arg1].DnsDomainName;
  514. sz2 = Domains[*(ULONG *)arg2].DnsDomainName;
  515. if (!sz1)
  516. {
  517. sz1 = Domains[*(ULONG *)arg1].NetbiosDomainName;
  518. }
  519. if (!sz2)
  520. {
  521. sz2 = Domains[*(ULONG *)arg2].NetbiosDomainName;
  522. }
  523. return _wcsicmp(sz1,sz2);
  524. }
  525. typedef struct tag_WORKING_LIST_EL
  526. {
  527. ULONG index;
  528. struct tag_WORKING_LIST_EL * pNext;
  529. } WORKING_LIST_EL;
  530. //+--------------------------------------------------------------------------
  531. //
  532. // Function: BuildDomainList
  533. //
  534. // Synopsis: Builds a tree containing all domains that have a trust
  535. // relationship with the server.
  536. //
  537. // Siblings within the tree are alphabetized.
  538. //
  539. // Arguments: [szServerName] - (NULL for local)
  540. //
  541. // Returns: pointer to the root node of the tree (NULL on error)
  542. //
  543. // History: 10-16-1998 stevebl Created
  544. //
  545. // Notes: Tree nodes must be freed by the caller (using delete).
  546. //
  547. //---------------------------------------------------------------------------
  548. LOOKDATA * BuildDomainList(WCHAR * szServerName)
  549. {
  550. ULONG DomainCount;
  551. OLECHAR szBuffer[128];
  552. HRESULT hr;
  553. ULONG ulNoChars;
  554. #if FGPO_SUPPORT
  555. LOOKDATA * pDomainList = new LOOKDATA;
  556. if (!pDomainList)
  557. {
  558. // failed to even create the Forest node!
  559. return NULL;
  560. }
  561. pDomainList->szData = GetPathToForest(szServerName);
  562. if (!pDomainList->szData)
  563. {
  564. delete pDomainList;
  565. return NULL;
  566. }
  567. // load the name for the forest from resources
  568. if (0 == LoadStringW(g_hInstance, IDS_FOREST, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
  569. {
  570. // failed to get the resource name
  571. delete pDomainList;
  572. return NULL;
  573. }
  574. ulNoChars = lstrlen(szBuffer) + 1;
  575. pDomainList->szName = new OLECHAR [ulNoChars];
  576. if (NULL == pDomainList->szName)
  577. {
  578. // not enough memory to create name of the forest node
  579. delete pDomainList;
  580. return NULL;
  581. }
  582. hr = StringCchCopy(pDomainList->szName, ulNoChars, szBuffer);
  583. ASSERT(SUCCEEDED(hr));
  584. pDomainList->nIndent = 0;
  585. pDomainList->nType = ITEMTYPE_FOREST;
  586. pDomainList->pParent = NULL;
  587. pDomainList->pSibling = NULL;
  588. pDomainList->pChild = NULL;
  589. #else
  590. LOOKDATA * pDomainList = NULL;
  591. #endif
  592. long l = DsEnumerateDomainTrusts(szServerName,
  593. DS_DOMAIN_IN_FOREST | DS_DOMAIN_NATIVE_MODE |
  594. DS_DOMAIN_PRIMARY | DS_DOMAIN_TREE_ROOT,
  595. &Domains,
  596. &DomainCount);
  597. //
  598. // Some of the below code might be unnecessary since DsEnumerateTrusts will no
  599. // longer return domains from other forests. Shouldn't do any harm though..
  600. //
  601. if ((0 == l) && (DomainCount > 0))
  602. {
  603. // sort the list of domains alphabetically
  604. ULONG * rgSorted = new ULONG[DomainCount];
  605. if (rgSorted)
  606. {
  607. ULONG uCount = DomainCount;
  608. while (uCount--)
  609. {
  610. rgSorted[uCount] = uCount;
  611. }
  612. qsort(rgSorted, DomainCount, sizeof (ULONG), CompareDomainInfo);
  613. // Build a working list of the domains, sorted alphabetically in
  614. // INVERTED order.
  615. WORKING_LIST_EL * pWorkList = NULL;
  616. LOOKDATA ** rgDataMap = new LOOKDATA * [DomainCount];
  617. if (rgDataMap)
  618. {
  619. uCount = 0;
  620. while (uCount < DomainCount)
  621. {
  622. WORKING_LIST_EL * pNew = new WORKING_LIST_EL;
  623. if (pNew)
  624. {
  625. pNew->index = rgSorted[uCount];
  626. pNew->pNext = pWorkList;
  627. pWorkList = pNew;
  628. }
  629. rgDataMap[uCount] = NULL;
  630. uCount++;
  631. }
  632. // Build the ordered tree of domains by removing domains from the
  633. // working list and inserting them into the new tree until there are
  634. // none left in the working list.
  635. // NOTE - if this routine runs out of memory it will begin
  636. // to drop nodes rather than AV.
  637. WORKING_LIST_EL ** ppWorker;
  638. BOOL fContinue = TRUE;
  639. while (pWorkList && fContinue)
  640. {
  641. fContinue = FALSE;
  642. ppWorker = &pWorkList;
  643. while (*ppWorker)
  644. {
  645. if (NULL == Domains[(*ppWorker)->index].DnsDomainName)
  646. {
  647. //
  648. // For now, if it doesn't have a
  649. // DnsDomainName then we're going to
  650. // skip it.
  651. // Eventually we'll want to make sure it doesn't
  652. // have a DC by calling DsGetDcName with
  653. // DS_DIRECTORY_SERVICE_PREFERRED.
  654. // remove it from the worker list
  655. WORKING_LIST_EL * pNext = (*ppWorker)->pNext;
  656. delete *ppWorker;
  657. *ppWorker = pNext;
  658. }
  659. else
  660. {
  661. // Does this node have a parent?
  662. ULONG flags = Domains[(*ppWorker)->index].Flags;
  663. if ((0 != (flags & DS_DOMAIN_IN_FOREST)) && (0 == (flags & DS_DOMAIN_TREE_ROOT)))
  664. {
  665. // it has a parent has its parent been added?
  666. LOOKDATA * pParent = rgDataMap[Domains[(*ppWorker)->index].ParentIndex];
  667. if (pParent != NULL)
  668. {
  669. // its parent has been added
  670. // insert this one in its parent's child list
  671. LOOKDATA * pData = new LOOKDATA;
  672. if (pData)
  673. {
  674. WCHAR * szName = Domains[(*ppWorker)->index].DnsDomainName;
  675. if (!szName)
  676. {
  677. szName = Domains[(*ppWorker)->index].NetbiosDomainName;
  678. }
  679. ulNoChars = wcslen(szName) + 1;
  680. pData->szName = new WCHAR[ulNoChars];
  681. if (pData->szName)
  682. {
  683. int cch = 0;
  684. int count=0;
  685. // count the dots in szName;
  686. while (szName[count])
  687. {
  688. if (L'.' == szName[count])
  689. {
  690. cch++;
  691. }
  692. count++;
  693. }
  694. cch *= 3; // multiply the number of dots by 3;
  695. cch += 11; // add 10 + 1 (for the null)
  696. cch += count; // add the string size;
  697. pData->szData = new WCHAR[cch];
  698. if (pData->szData)
  699. {
  700. NameToPath(pData->szData, szName, cch);
  701. hr = StringCchCopy(pData->szName, ulNoChars, szName);
  702. ASSERT(SUCCEEDED(hr));
  703. pData->nIndent = pParent->nIndent+1;
  704. pData->nType = ITEMTYPE_DOMAIN;
  705. pData->pParent = pParent;
  706. pData->pSibling = pParent->pChild;
  707. pData->pChild = NULL;
  708. pParent->pChild = pData;
  709. rgDataMap[(*ppWorker)->index] = pData;
  710. // make sure we remember
  711. // that we added something
  712. // to the master list (helps
  713. // us avoid infinite loops
  714. // in case of an error)
  715. fContinue = TRUE;
  716. }
  717. else
  718. {
  719. delete [] pData->szName;
  720. delete pData;
  721. }
  722. }
  723. else
  724. {
  725. delete pData;
  726. }
  727. }
  728. // and remove it from the worker list
  729. WORKING_LIST_EL * pNext = (*ppWorker)->pNext;
  730. delete *ppWorker;
  731. *ppWorker = pNext;
  732. }
  733. else
  734. {
  735. // skip it for now
  736. ppWorker = &((*ppWorker)->pNext);
  737. }
  738. }
  739. else
  740. {
  741. // it doesn't have a parent add it just under the forest
  742. // level of the list
  743. LOOKDATA * pData = new LOOKDATA;
  744. if (pData)
  745. {
  746. WCHAR * szName = Domains[(*ppWorker)->index].DnsDomainName;
  747. if (!szName)
  748. {
  749. szName = Domains[(*ppWorker)->index].NetbiosDomainName;
  750. }
  751. ulNoChars = wcslen(szName) + 1;
  752. pData->szName = new WCHAR[ulNoChars];
  753. if (pData->szName)
  754. {
  755. int cch = 0;
  756. int count=0;
  757. // count the dots in szName;
  758. while (szName[count])
  759. {
  760. if (L'.' == szName[count])
  761. {
  762. cch++;
  763. }
  764. count++;
  765. }
  766. cch *= 3; // multiply the number of dots by 3;
  767. cch += 11; // add 10 + 1 for the null
  768. cch += count; // add the string size;
  769. pData->szData = new WCHAR[cch];
  770. if (pData->szData)
  771. {
  772. NameToPath(pData->szData, szName, cch);
  773. hr = StringCchCopy(pData->szName, ulNoChars, szName);
  774. ASSERT(SUCCEEDED(hr));
  775. #if FGPO_SUPPORT
  776. pData->nIndent = 1;
  777. pData->nType = ITEMTYPE_DOMAIN;
  778. pData->pParent = pDomainList;
  779. pData->pSibling = pDomainList->pChild;
  780. pData->pChild = NULL;
  781. pDomainList->pChild = pData;
  782. #else
  783. pData->nIndent = 0;
  784. pData->nType = ITEMTYPE_DOMAIN;
  785. pData->pParent = NULL;
  786. pData->pSibling = pDomainList;
  787. pData->pChild = NULL;
  788. pDomainList = pData;
  789. #endif
  790. rgDataMap[(*ppWorker)->index] = pData;
  791. // make sure we remember
  792. // that we added something
  793. // to the master list (helps
  794. // us avoid infinite loops
  795. // in case of an error)
  796. fContinue = TRUE;
  797. }
  798. else
  799. {
  800. delete [] pData->szName;
  801. delete pData;
  802. }
  803. }
  804. else
  805. {
  806. delete pData;
  807. }
  808. }
  809. // and remove it from the worker list
  810. WORKING_LIST_EL * pNext = (*ppWorker)->pNext;
  811. delete *ppWorker;
  812. *ppWorker = pNext;
  813. }
  814. }
  815. }
  816. }
  817. delete [] rgDataMap;
  818. }
  819. delete [] rgSorted;
  820. }
  821. NetApiBufferFree(Domains);
  822. }
  823. else
  824. {
  825. if (0 != l)
  826. {
  827. DebugMsg((DM_WARNING, TEXT("DsEnumerateDomainTrustsW failed with %u"), l));
  828. }
  829. }
  830. return pDomainList;
  831. }
  832. VOID FreeDomainInfo (LOOKDATA * pEntry)
  833. {
  834. if (!pEntry)
  835. {
  836. return;
  837. }
  838. if (pEntry->pChild)
  839. {
  840. FreeDomainInfo (pEntry->pChild);
  841. }
  842. if (pEntry->pSibling)
  843. {
  844. FreeDomainInfo (pEntry->pSibling);
  845. }
  846. delete [] pEntry->szName;
  847. delete pEntry;
  848. }
  849. //+--------------------------------------------------------------------------
  850. //
  851. // Member: CBrowserPP::FillDomainList
  852. //
  853. // Synopsis: Fills the combobox with the trusted domain information.
  854. // The szData member of the combobox element structure is the
  855. // LDAP domain name.
  856. //
  857. // Returns: TRUE - successful
  858. // FALSE - error
  859. //
  860. // History: 04-30-1998 stevebl Modified from original version
  861. // written by EricFlo
  862. // 10-20-1998 stevebl Heavily modified to support domains
  863. // "outside the forest" and to fix a
  864. // whole passle o' bugs.
  865. //
  866. // Note: This routine also sets the focus to the domain of the object
  867. // passed in via the lpInitialOU member of the GPOBROWSEINFO
  868. // structure.
  869. //
  870. //---------------------------------------------------------------------------
  871. BOOL CBrowserPP::FillDomainList ()
  872. {
  873. BOOL bResult = TRUE;
  874. HRESULT hr;
  875. DWORD dwIndex;
  876. BOOL fEnableBackbutton = FALSE;
  877. HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  878. WCHAR * szBuffer1 = NULL;
  879. if (m_pGBI->lpInitialOU)
  880. {
  881. if (IsForest(m_pGBI->lpInitialOU))
  882. {
  883. szBuffer1 = new TCHAR[128];
  884. LoadStringW(g_hInstance, IDS_FOREST, szBuffer1, 128);
  885. }
  886. else
  887. {
  888. WCHAR * sz = GetDomainFromLDAPPath(m_pGBI->lpInitialOU);
  889. if (sz)
  890. {
  891. szBuffer1 = new WCHAR[wcslen(sz) + 1];
  892. if (szBuffer1)
  893. {
  894. CopyAsFriendlyName(szBuffer1, sz);
  895. }
  896. delete [] sz;
  897. }
  898. }
  899. }
  900. LOOKDATA * pDomainList = BuildDomainList(m_szServerName);
  901. if (!pDomainList)
  902. {
  903. ReportError(m_hwndDlg, GetLastError(), IDS_DOMAINLIST);
  904. }
  905. // Walk the ordered tree of domains, inserting each one into the
  906. // dialog box
  907. DWORD dwInitialDomain = -1;
  908. // start at the head
  909. while (pDomainList)
  910. {
  911. WCHAR * szBuffer2 = NULL;
  912. // add this node
  913. dwIndex = (DWORD)SendMessage(m_hCombo, CB_INSERTSTRING, (WPARAM) -1, (LPARAM)(LPCTSTR) pDomainList);
  914. szBuffer2 = new WCHAR[wcslen(pDomainList->szData) + 1];
  915. if (szBuffer2)
  916. {
  917. CopyAsFriendlyName(szBuffer2, pDomainList->szData);
  918. }
  919. if (NULL != szBuffer1 && NULL !=szBuffer2 && 0 ==_wcsicmp(szBuffer1, szBuffer2))
  920. {
  921. // replace the domain path with the path provided by the caller
  922. // (because it contains the server)
  923. WCHAR * sz = GetDomainFromLDAPPath(m_pGBI->lpInitialOU);
  924. if (sz)
  925. {
  926. DebugMsg((DM_VERBOSE, TEXT("CBrowserPP::FillDomainList: Resetting domain path to user specified path: %s"), sz));
  927. delete [] pDomainList->szData;
  928. pDomainList->szData = sz;
  929. }
  930. dwInitialDomain = dwIndex;
  931. if (pDomainList->nIndent > 0)
  932. fEnableBackbutton = TRUE;
  933. }
  934. if (szBuffer2)
  935. {
  936. delete [] szBuffer2;
  937. }
  938. if (pDomainList->pChild)
  939. {
  940. // go to its child
  941. pDomainList = pDomainList->pChild;
  942. }
  943. else
  944. {
  945. if (pDomainList->pSibling)
  946. {
  947. // go to its sibling if there are no children
  948. pDomainList = pDomainList->pSibling;
  949. }
  950. else
  951. {
  952. // there are no children and no siblings
  953. // back up until we find a parent with a sibling
  954. // or there are no more parents (we're done)
  955. do
  956. {
  957. pDomainList = pDomainList->pParent;
  958. if (pDomainList)
  959. {
  960. if (pDomainList->pSibling)
  961. {
  962. pDomainList = pDomainList->pSibling;
  963. break;
  964. }
  965. }
  966. else
  967. {
  968. break;
  969. }
  970. } while (TRUE);
  971. }
  972. }
  973. }
  974. if (szBuffer1)
  975. {
  976. delete [] szBuffer1;
  977. }
  978. if (-1 == dwInitialDomain)
  979. {
  980. // didn't find the initial domain anywhere in that list
  981. // Set the first entry by default
  982. dwInitialDomain = 0;
  983. }
  984. SendMessage (m_hCombo, CB_SETCURSEL, dwInitialDomain, 0);
  985. SendMessage (m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_BACKBUTTON, (LPARAM) MAKELONG(fEnableBackbutton, 0));
  986. SetCursor(hcur);
  987. return bResult;
  988. }
  989. //+--------------------------------------------------------------------------
  990. //
  991. // Member: CBrowserPP::SetInitialOU
  992. //
  993. // Synopsis: Adds nodes to the combobox until the initial OU specified by
  994. // the caller via the lpInitalOU member of the GPOBROWSEINFO
  995. // structure is present and gives it the focus.
  996. //
  997. // Returns: TRUE - success
  998. //
  999. // History: 10-20-1998 stevebl Created
  1000. //
  1001. // Notes: This routine assumes that FillDomainList() was just called.
  1002. // It will not work properly otherwise.
  1003. //
  1004. //---------------------------------------------------------------------------
  1005. BOOL CBrowserPP::SetInitialOU()
  1006. {
  1007. if (!m_pGBI->lpInitialOU)
  1008. {
  1009. // nothing requested so nothing required
  1010. return TRUE;
  1011. }
  1012. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  1013. if (iIndex == CB_ERR)
  1014. {
  1015. DebugMsg((DM_WARNING, TEXT("CBrowserPP::SetInitialOU: No object selected.")));
  1016. return FALSE;
  1017. }
  1018. // get the current object to see what's selected
  1019. LOOKDATA * pdataSelected = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  1020. if (pdataSelected)
  1021. {
  1022. // is it the same as the requested object?
  1023. WCHAR * szSelected = NULL;
  1024. WCHAR * szRequested = NULL;
  1025. szSelected = new WCHAR[wcslen(pdataSelected->szData) + 1];
  1026. if (szSelected)
  1027. {
  1028. CopyAsFriendlyName(szSelected, pdataSelected->szData);
  1029. }
  1030. szRequested = new WCHAR[wcslen(m_pGBI->lpInitialOU + 1)];
  1031. if (NULL != szSelected && NULL != szRequested && 0 != wcscmp(szSelected, szRequested))
  1032. {
  1033. // it's not the same
  1034. // try and bind to the requested object
  1035. IADs * pADs = NULL;
  1036. HRESULT hr = OpenDSObject(m_pGBI->lpInitialOU,
  1037. IID_IADs, (void **)&pADs);
  1038. if (SUCCEEDED(hr))
  1039. {
  1040. // the requested object exists and we have access permission
  1041. // now make sure that it's a domain or OU
  1042. BOOL fDomainOrOU = FALSE;
  1043. VARIANT var;
  1044. VariantInit(&var);
  1045. BSTR bstrProperty = SysAllocString(L"objectClass");
  1046. if (bstrProperty)
  1047. {
  1048. hr = pADs->Get(bstrProperty, &var);
  1049. if (SUCCEEDED(hr))
  1050. {
  1051. int cElements = var.parray->rgsabound[0].cElements;
  1052. VARIANT * rgData = (VARIANT *)var.parray->pvData;
  1053. while (cElements--)
  1054. {
  1055. if (0 == _wcsicmp(L"domain", rgData[cElements].bstrVal))
  1056. {
  1057. fDomainOrOU = TRUE;
  1058. }
  1059. if (0 == _wcsicmp(L"organizationalUnit", rgData[cElements].bstrVal))
  1060. {
  1061. fDomainOrOU = TRUE;
  1062. }
  1063. }
  1064. }
  1065. SysFreeString(bstrProperty);
  1066. }
  1067. VariantClear(&var);
  1068. pADs->Release();
  1069. if (fDomainOrOU)
  1070. {
  1071. LOOKDATA * pLast = NULL;
  1072. LOOKDATA * pNew = NULL;
  1073. // build a list of nodes
  1074. // repeat removing leaf nodes until we're down to the domain
  1075. // (which will be the same as the selected object)
  1076. IADsPathname * pADsPathname = NULL;
  1077. BSTR bstr;
  1078. hr = CoCreateInstance(CLSID_Pathname,
  1079. NULL,
  1080. CLSCTX_INPROC_SERVER,
  1081. IID_IADsPathname,
  1082. (LPVOID*)&pADsPathname);
  1083. if (SUCCEEDED(hr))
  1084. {
  1085. BSTR bstrInitialOU = SysAllocString( m_pGBI->lpInitialOU );
  1086. if ( bstrInitialOU != NULL )
  1087. {
  1088. hr = pADsPathname->Set( bstrInitialOU, ADS_SETTYPE_FULL );
  1089. if (SUCCEEDED(hr))
  1090. {
  1091. while (TRUE)
  1092. {
  1093. // add this node to the list
  1094. hr = pADsPathname->Retrieve(ADS_FORMAT_X500, &bstr);
  1095. if (FAILED(hr))
  1096. {
  1097. break;
  1098. }
  1099. if (szRequested)
  1100. {
  1101. delete [] szRequested;
  1102. }
  1103. szRequested = new WCHAR[wcslen(bstr) + 1];
  1104. if (szRequested)
  1105. {
  1106. CopyAsFriendlyName(szRequested, bstr);
  1107. }
  1108. if (NULL != szRequested && 0 == wcscmp(szSelected, szRequested))
  1109. {
  1110. // we're back to the first node
  1111. SysFreeString(bstr);
  1112. break;
  1113. }
  1114. pNew = new LOOKDATA;
  1115. if (!pNew)
  1116. {
  1117. // ran out of memory
  1118. SysFreeString(bstr);
  1119. break;
  1120. }
  1121. ULONG ulNoCharsRequested = wcslen(szRequested) + 1;
  1122. pNew->szName = new WCHAR[ulNoCharsRequested];
  1123. if (!pNew->szName)
  1124. {
  1125. // ran out of memory
  1126. delete pNew;
  1127. SysFreeString(bstr);
  1128. break;
  1129. }
  1130. ULONG ulNoChars = wcslen(bstr) + 1;
  1131. pNew->szData = new WCHAR[ulNoChars];
  1132. if (!pNew->szData)
  1133. {
  1134. // ran out of memory
  1135. delete [] pNew->szName;
  1136. delete pNew;
  1137. SysFreeString(bstr);
  1138. break;
  1139. }
  1140. hr = StringCchCopy(pNew->szData, ulNoChars, bstr);
  1141. ASSERT(SUCCEEDED(hr));
  1142. hr = StringCchCopy(pNew->szName, ulNoCharsRequested, szRequested);
  1143. ASSERT(SUCCEEDED(hr));
  1144. SysFreeString(bstr);
  1145. pNew->nIndent = 0;
  1146. pNew->nType = ITEMTYPE_OU;
  1147. pNew->pParent = NULL;
  1148. pNew->pSibling = NULL;
  1149. pNew->pChild = pLast;
  1150. if (pLast)
  1151. {
  1152. pLast->pParent = pNew;
  1153. }
  1154. pLast = pNew;
  1155. // strip off a leaf node and go again
  1156. hr = pADsPathname->RemoveLeafElement();
  1157. if (FAILED(hr))
  1158. {
  1159. break;
  1160. }
  1161. }
  1162. }
  1163. SysFreeString( bstrInitialOU );
  1164. }
  1165. pADsPathname->Release();
  1166. }
  1167. // At this point I should have a list of LOOKDATA nodes
  1168. // (in pLast).
  1169. // The only things left to do are to link them into the
  1170. // tree, set their nIndent members, add them to the combo
  1171. // box and set the combo box's focus to the last one.
  1172. if (pLast)
  1173. {
  1174. // link in the list
  1175. pLast->pSibling = pdataSelected->pChild;
  1176. pLast->pParent = pdataSelected;
  1177. pLast->nIndent = pdataSelected->nIndent+1;
  1178. pdataSelected->pChild = pLast;
  1179. // now walk the tree, adding entries to the combo box
  1180. // and updating the nIndent members
  1181. while (pLast)
  1182. {
  1183. iIndex = (int)SendMessage(m_hCombo, CB_INSERTSTRING, iIndex+1, (LPARAM)(LPCTSTR) pLast);
  1184. if (pLast->pChild)
  1185. {
  1186. pLast->pChild->nIndent = pLast->nIndent+1;
  1187. }
  1188. pLast = pLast->pChild;
  1189. }
  1190. if (iIndex != CB_ERR)
  1191. {
  1192. SendMessage(m_hCombo, CB_SETCURSEL, iIndex, 0);
  1193. SendMessage(m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_BACKBUTTON, (LPARAM) MAKELONG(TRUE, 0));
  1194. }
  1195. }
  1196. }
  1197. }
  1198. }
  1199. if (szSelected)
  1200. {
  1201. delete [] szSelected;
  1202. }
  1203. if (szRequested)
  1204. {
  1205. delete [] szRequested;
  1206. }
  1207. }
  1208. return TRUE;
  1209. }
  1210. //+--------------------------------------------------------------------------
  1211. //
  1212. // Member: CBrowserPP::GetCurrentObject
  1213. //
  1214. // Synopsis: returns the LDAP path to the currently selected object
  1215. //
  1216. // Arguments: [] -
  1217. //
  1218. // Returns: NULL if no ojbect is selected else the LDAP path of the object
  1219. //
  1220. // Modifies:
  1221. //
  1222. // Derivation:
  1223. //
  1224. // History: 5-05-1998 stevebl Created
  1225. // 06-23-1999 stevebl Added logic to give DCs names
  1226. //
  1227. // Notes:
  1228. // Checks to see if a domain has a named server. If it doesn't
  1229. // then it calls GetDCName to get it one.
  1230. //
  1231. //---------------------------------------------------------------------------
  1232. LPOLESTR CBrowserPP::GetCurrentObject()
  1233. {
  1234. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  1235. if (iIndex == CB_ERR)
  1236. {
  1237. DebugMsg((DM_WARNING, TEXT("CBrowserPP::GetCurrentObject: No object selected.")));
  1238. return NULL;
  1239. }
  1240. LPOLESTR sz=NULL;
  1241. LOOKDATA * pdata = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  1242. if (pdata)
  1243. {
  1244. if (pdata->szData)
  1245. {
  1246. HRESULT hr;
  1247. ULONG ulNoChars;
  1248. if (ITEMTYPE_DOMAIN == pdata->nType)
  1249. {
  1250. // make sure that domains are resolved to a server
  1251. LPTSTR szServer = ExtractServerName(pdata->szData);
  1252. if (NULL == szServer)
  1253. {
  1254. LPWSTR szTemp = GetDCName(pdata->szName, NULL, NULL, TRUE, 0);
  1255. if (szTemp)
  1256. {
  1257. LPWSTR szFullPath = MakeFullPath(pdata->szData, szTemp);
  1258. if (szFullPath)
  1259. {
  1260. ulNoChars = wcslen(szFullPath)+1;
  1261. LPWSTR szTemp2 = new WCHAR[ulNoChars];
  1262. if (szTemp2)
  1263. {
  1264. hr = StringCchCopy (szTemp2, ulNoChars, szFullPath);
  1265. ASSERT(SUCCEEDED(hr));
  1266. delete [] pdata->szData;
  1267. pdata->szData = szTemp2;
  1268. }
  1269. LocalFree(szFullPath);
  1270. }
  1271. LocalFree(szTemp);
  1272. }
  1273. else
  1274. {
  1275. return NULL;
  1276. }
  1277. }
  1278. else
  1279. {
  1280. LocalFree(szServer);
  1281. }
  1282. }
  1283. ulNoChars = wcslen(pdata->szData) + 1;
  1284. sz = new OLECHAR[ulNoChars];
  1285. if (sz)
  1286. {
  1287. hr = StringCchCopy(sz, ulNoChars, pdata->szData);
  1288. ASSERT(SUCCEEDED(hr));
  1289. }
  1290. }
  1291. }
  1292. return sz;
  1293. }
  1294. //+--------------------------------------------------------------------------
  1295. //
  1296. // Member: CBrowserPP::IsCurrentObjectAForest
  1297. //
  1298. // Synopsis: tests to see if the currently selected object is a forest
  1299. //
  1300. // Arguments: [] -
  1301. //
  1302. // Returns: TRUE - if it is a forest
  1303. // FALSE - otherwise
  1304. //
  1305. // History: 03-31-2000 stevebl Created
  1306. //
  1307. //---------------------------------------------------------------------------
  1308. BOOL CBrowserPP::IsCurrentObjectAForest()
  1309. {
  1310. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  1311. if (iIndex == CB_ERR)
  1312. {
  1313. DebugMsg((DM_WARNING, TEXT("CBrowserPP::IsCurrentObjectAForest: No object selected.")));
  1314. return FALSE;
  1315. }
  1316. LOOKDATA * pdata = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  1317. return (ITEMTYPE_FOREST == pdata->nType);
  1318. }
  1319. //+--------------------------------------------------------------------------
  1320. //
  1321. // Member: CBrowserPP::GetCurrentDomain
  1322. //
  1323. // Synopsis: returns the domain of the currently selecte object (if the
  1324. // currently currently selected object is the domain then they
  1325. // are one and the same)
  1326. //
  1327. // Arguments: [] -
  1328. //
  1329. // Returns: NULL - if no object is selected else returns LDAP path of
  1330. // domain
  1331. //
  1332. // History: 05-04-1998 stevebl Created
  1333. // 06-23-1999 stevebl Added logic to give DCs names
  1334. //
  1335. // Notes: Checks to see if a domain has a named server. If it doesn't
  1336. // then it calls GetDCName to get it one.
  1337. //
  1338. //---------------------------------------------------------------------------
  1339. LPOLESTR CBrowserPP::GetCurrentDomain()
  1340. {
  1341. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  1342. if (iIndex == CB_ERR)
  1343. {
  1344. DebugMsg((DM_WARNING, TEXT("CBrowserPP::GetCurrentDomain: No object selected.")));
  1345. return NULL;
  1346. }
  1347. LOOKDATA * pdata = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  1348. switch (pdata->nType)
  1349. {
  1350. case ITEMTYPE_DOMAIN:
  1351. {
  1352. if (pdata->szData)
  1353. {
  1354. HRESULT hr;
  1355. ULONG ulNoChars;
  1356. // make sure the domain has a server
  1357. LPTSTR szServer = ExtractServerName(pdata->szData);
  1358. if (NULL == szServer)
  1359. {
  1360. LPWSTR szTemp = GetDCName(pdata->szName, NULL, NULL, TRUE, 0);
  1361. if (szTemp)
  1362. {
  1363. LPWSTR szFullPath = MakeFullPath(pdata->szData, szTemp);
  1364. if (szFullPath)
  1365. {
  1366. ulNoChars = wcslen(szFullPath)+1;
  1367. LPWSTR sz = new WCHAR[ulNoChars];
  1368. if (sz)
  1369. {
  1370. hr = StringCchCopy(sz, ulNoChars, szFullPath);
  1371. ASSERT(SUCCEEDED(hr));
  1372. delete [] pdata->szData;
  1373. pdata->szData = sz;
  1374. }
  1375. LocalFree(szFullPath);
  1376. }
  1377. LocalFree(szTemp);
  1378. }
  1379. else
  1380. {
  1381. return NULL;
  1382. }
  1383. }
  1384. else
  1385. {
  1386. LocalFree(szServer);
  1387. }
  1388. ulNoChars = wcslen(pdata->szData)+1;
  1389. LPOLESTR sz = new OLECHAR[ulNoChars];
  1390. if (sz)
  1391. {
  1392. hr = StringCchCopy(sz, ulNoChars, pdata->szData);
  1393. ASSERT(SUCCEEDED(hr));
  1394. }
  1395. return sz;
  1396. }
  1397. return NULL;
  1398. }
  1399. case ITEMTYPE_FOREST:
  1400. case ITEMTYPE_SITE:
  1401. case ITEMTYPE_OU:
  1402. {
  1403. return GetDomainFromLDAPPath(pdata->szData);
  1404. }
  1405. break;
  1406. default:
  1407. break;
  1408. }
  1409. return NULL;
  1410. }
  1411. BOOL CBrowserPP::AddGPOsLinkedToObject()
  1412. {
  1413. HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1414. LPOLESTR lpObject;
  1415. HRESULT hr;
  1416. IADs * pADs = NULL;
  1417. IADs * pADsGPO;
  1418. VARIANT var;
  1419. BSTR bstrProperty;
  1420. BOOL fResult = FALSE;
  1421. int index = ListView_GetItemCount(m_hList);
  1422. //
  1423. // Get the current object name
  1424. //
  1425. lpObject = GetCurrentObject();
  1426. if (NULL == lpObject)
  1427. {
  1428. return FALSE;
  1429. }
  1430. DebugMsg((DM_VERBOSE, TEXT("CBrowserPP::AddGPOsLinkedToObject: Reading gPLink property from %s"), lpObject));
  1431. hr = OpenDSObject(lpObject, IID_IADs, (void **)&pADs);
  1432. delete [] lpObject;
  1433. if (FAILED(hr))
  1434. {
  1435. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddGPOsLinkedToObject: OpenDSObject failed with 0x%x"), hr));
  1436. ReportError(m_hwndDlg, hr, IDS_FAILEDGPLINK);
  1437. goto Exit;
  1438. }
  1439. VariantInit(&var);
  1440. bstrProperty = SysAllocString(GPM_LINK_PROPERTY);
  1441. if (bstrProperty)
  1442. {
  1443. hr = pADs->Get(bstrProperty, &var);
  1444. if (SUCCEEDED(hr))
  1445. {
  1446. LPOLESTR szGPOList = var.bstrVal;
  1447. OLECHAR * pchTemp;
  1448. OLECHAR * pchGPO;
  1449. VARIANT varName;
  1450. BSTR bstrNameProp;
  1451. if (szGPOList)
  1452. {
  1453. OLECHAR * szGPO = new WCHAR[wcslen(szGPOList) + 1];
  1454. if (szGPO)
  1455. {
  1456. pchTemp = szGPOList;
  1457. while (TRUE)
  1458. {
  1459. // Look for the [
  1460. while (*pchTemp && (*pchTemp != L'['))
  1461. pchTemp++;
  1462. if (!(*pchTemp))
  1463. break;
  1464. pchTemp++;
  1465. // Copy the GPO name
  1466. pchGPO = szGPO;
  1467. while (*pchTemp && (*pchTemp != L';'))
  1468. *pchGPO++ = *pchTemp++;
  1469. *pchGPO = L'\0';
  1470. // Add the object to the list view
  1471. MYLISTEL * pel = new MYLISTEL;
  1472. if (pel)
  1473. {
  1474. pel->szData = NULL;
  1475. pel->bDisabled = FALSE;
  1476. LPTSTR szFullGPOPath = GetFullPath(szGPO, m_hwndDlg);
  1477. if (szFullGPOPath)
  1478. {
  1479. ULONG ulNoChars = wcslen(szFullGPOPath) + 1;
  1480. pel->szData = new WCHAR[ulNoChars];
  1481. if (pel->szData)
  1482. {
  1483. hr = StringCchCopy(pel->szData, ulNoChars, szFullGPOPath);
  1484. ASSERT(SUCCEEDED(hr));
  1485. }
  1486. else
  1487. {
  1488. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddGPOsLinkedToObject: Failed to allocate memory for new full gpo path")));
  1489. LocalFree(szFullGPOPath);
  1490. delete pel;
  1491. continue;
  1492. }
  1493. LocalFree(szFullGPOPath);
  1494. }
  1495. else
  1496. {
  1497. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddGPOsLinkedToObject: Failed to get full gpo path")));
  1498. delete pel;
  1499. continue;
  1500. }
  1501. VariantInit(&varName);
  1502. // get the friendly display name
  1503. hr = OpenDSObject(pel->szData, IID_IADs,
  1504. (void **)&pADsGPO);
  1505. if (hr == HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT))
  1506. {
  1507. delete pel;
  1508. continue;
  1509. }
  1510. if (SUCCEEDED(hr))
  1511. {
  1512. bstrNameProp = SysAllocString(GPO_NAME_PROPERTY);
  1513. if (bstrNameProp)
  1514. {
  1515. hr = pADsGPO->Get(bstrNameProp, &varName);
  1516. SysFreeString(bstrNameProp);
  1517. }
  1518. else
  1519. {
  1520. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  1521. }
  1522. pADsGPO->Release();
  1523. }
  1524. if (FAILED(hr))
  1525. {
  1526. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddGPOsLinkedToObject: Couldn't get display name for %s with 0x%x"), pel->szData, hr));
  1527. pel->szName = new WCHAR[200];
  1528. if (pel->szName)
  1529. {
  1530. LoadString(g_hInstance, IDS_GPM_NOGPONAME, pel->szName, 200);
  1531. }
  1532. pel->bDisabled = TRUE;
  1533. }
  1534. else
  1535. {
  1536. ULONG ulNoChars = wcslen(varName.bstrVal) + 1;
  1537. pel->szName = new WCHAR[ulNoChars];
  1538. if (pel->szName)
  1539. {
  1540. hr = StringCchCopy(pel->szName, ulNoChars, varName.bstrVal);
  1541. ASSERT(SUCCEEDED(hr));
  1542. }
  1543. }
  1544. VariantClear(&varName);
  1545. pel->nType = ITEMTYPE_GPO;
  1546. AddElement(pel, index);
  1547. }
  1548. }
  1549. delete [] szGPO;
  1550. }
  1551. }
  1552. }
  1553. SysFreeString(bstrProperty);
  1554. }
  1555. VariantClear(&var);
  1556. fResult = TRUE;
  1557. Exit:
  1558. if (pADs)
  1559. {
  1560. pADs->Release();
  1561. }
  1562. SetCursor(hcur);
  1563. return fResult;
  1564. }
  1565. //+--------------------------------------------------------------------------
  1566. //
  1567. // Member: CBrowserPP::AddGPOsForDomain
  1568. //
  1569. // Synopsis: Adds all the GPOs in the specified domain to the list view
  1570. // control. The szData member of the list element structure
  1571. // contains the LDAP path of the GPO.
  1572. //
  1573. // The domain is indicated by the currently selected combobox
  1574. // element.
  1575. //
  1576. // Returns: TRUE - successful
  1577. // FALSE - error
  1578. //
  1579. // History: 04-30-1998 stevebl Modified from original routine
  1580. // written by EricFlo.
  1581. //
  1582. //---------------------------------------------------------------------------
  1583. BOOL CBrowserPP::AddGPOsForDomain()
  1584. {
  1585. LPTSTR lpDomain;
  1586. LPTSTR lpGPO;
  1587. INT iIndex;
  1588. VARIANT var;
  1589. VARIANT varGPO;
  1590. ULONG ulResult;
  1591. HRESULT hr = E_FAIL;
  1592. IADsPathname * pADsPathname = NULL;
  1593. IADs * pADs = NULL;
  1594. IADsContainer * pADsContainer = NULL;
  1595. IDispatch * pDispatch = NULL;
  1596. IEnumVARIANT *pVar = NULL;
  1597. BSTR bstrContainer = NULL;
  1598. BSTR bstrCommonName = NULL;
  1599. BSTR bstrDisplayName = NULL;
  1600. BSTR bstrGPO = NULL;
  1601. TCHAR szDisplayName[512];
  1602. TCHAR szCommonName[50];
  1603. MYLISTEL * pel;
  1604. ULONG ulNoChars;
  1605. //
  1606. // Test to see if we're focused on a forest
  1607. //
  1608. BOOL fForest = IsCurrentObjectAForest();
  1609. //
  1610. // Get the current domain name
  1611. //
  1612. lpDomain = GetCurrentDomain();
  1613. if (!lpDomain)
  1614. {
  1615. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: NULL domain name.")));
  1616. return FALSE;
  1617. }
  1618. HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1619. //
  1620. // Create a pathname object we can work with
  1621. //
  1622. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  1623. IID_IADsPathname, (LPVOID*)&pADsPathname);
  1624. if (FAILED(hr))
  1625. {
  1626. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to create adspathname instance with 0x%x"), hr));
  1627. goto Exit;
  1628. }
  1629. //
  1630. // Add the domain name
  1631. //
  1632. BSTR bstrDomain = SysAllocString( lpDomain );
  1633. if ( bstrDomain == NULL )
  1634. {
  1635. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to allocate BSTR memory.")));
  1636. hr = E_OUTOFMEMORY;
  1637. goto Exit;
  1638. }
  1639. hr = pADsPathname->Set (bstrDomain, ADS_SETTYPE_FULL);
  1640. SysFreeString( bstrDomain );
  1641. if (FAILED(hr))
  1642. {
  1643. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to set pathname with 0x%x"), hr));
  1644. goto Exit;
  1645. }
  1646. BSTR bstrFolder = NULL;
  1647. if (fForest)
  1648. {
  1649. //
  1650. // Add the configuration folder to the path
  1651. //
  1652. bstrFolder = SysAllocString( TEXT("CN=Configuration") );
  1653. }
  1654. else
  1655. {
  1656. //
  1657. // Add the system folder to the path
  1658. //
  1659. bstrFolder = SysAllocString( TEXT("CN=System") );
  1660. }
  1661. if ( bstrFolder == NULL )
  1662. {
  1663. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to allocate BSTR memory.")));
  1664. hr = E_OUTOFMEMORY;
  1665. goto Exit;
  1666. }
  1667. hr = pADsPathname->AddLeafElement (bstrFolder);
  1668. SysFreeString( bstrFolder );
  1669. if (FAILED(hr))
  1670. {
  1671. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to add system folder with 0x%x"), hr));
  1672. goto Exit;
  1673. }
  1674. //
  1675. // Add the policies container to the path
  1676. //
  1677. BSTR bstrCNPolicies = SysAllocString( TEXT("CN=Policies") );
  1678. if ( bstrCNPolicies == NULL )
  1679. {
  1680. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to allocate BSTR memory.")));
  1681. hr = E_OUTOFMEMORY;
  1682. goto Exit;
  1683. }
  1684. hr = pADsPathname->AddLeafElement (bstrCNPolicies);
  1685. SysFreeString( bstrCNPolicies );
  1686. if (FAILED(hr))
  1687. {
  1688. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to add policies folder with 0x%x"), hr));
  1689. goto Exit;
  1690. }
  1691. //
  1692. // Retreive the container path - this is the path to the policies folder
  1693. //
  1694. hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrContainer);
  1695. if (FAILED(hr))
  1696. {
  1697. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to retreive container path with 0x%x"), hr));
  1698. goto Exit;
  1699. }
  1700. //
  1701. // Release the pathname object
  1702. //
  1703. pADsPathname->Release();
  1704. pADsPathname = NULL;
  1705. //
  1706. // Build an enumerator
  1707. //
  1708. hr = OpenDSObject(bstrContainer, IID_IADsContainer, (void **)&pADsContainer);
  1709. if (FAILED(hr))
  1710. {
  1711. if (hr != HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT))
  1712. {
  1713. DebugMsg((DM_VERBOSE, TEXT("AddGPOsForDomain: Failed to get gpo container interface with 0x%x for object %s"),
  1714. hr, bstrContainer));
  1715. ReportError(m_hwndDlg, hr, IDS_FAILEDGPLINK);
  1716. }
  1717. goto Exit;
  1718. }
  1719. hr = ADsBuildEnumerator (pADsContainer, &pVar);
  1720. if (FAILED(hr))
  1721. {
  1722. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to get enumerator with 0x%x"), hr));
  1723. goto Exit;
  1724. }
  1725. bstrCommonName = SysAllocString (L"cn");
  1726. if (!bstrCommonName)
  1727. {
  1728. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to allocate memory with %d"), GetLastError()));
  1729. goto Exit;
  1730. }
  1731. bstrDisplayName = SysAllocString (GPO_NAME_PROPERTY);
  1732. if (!bstrDisplayName)
  1733. {
  1734. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to allocate memory with %d"), GetLastError()));
  1735. goto Exit;
  1736. }
  1737. //
  1738. // Enumerate
  1739. //
  1740. while (TRUE)
  1741. {
  1742. BOOL fNeedDisplayName = FALSE;
  1743. VariantInit(&var);
  1744. hr = ADsEnumerateNext(pVar, 1, &var, &ulResult);
  1745. if (FAILED(hr))
  1746. {
  1747. DebugMsg((DM_VERBOSE, TEXT("AddGPOsForDomain: Failed to enumerator with 0x%x"), hr));
  1748. VariantClear (&var);
  1749. break;
  1750. }
  1751. if (S_FALSE == hr)
  1752. {
  1753. VariantClear (&var);
  1754. break;
  1755. }
  1756. //
  1757. // If var.vt isn't VT_DISPATCH, we're finished.
  1758. //
  1759. if (var.vt != VT_DISPATCH)
  1760. {
  1761. VariantClear (&var);
  1762. break;
  1763. }
  1764. //
  1765. // We found something, get the IDispatch interface
  1766. //
  1767. pDispatch = var.pdispVal;
  1768. if (!pDispatch)
  1769. {
  1770. DebugMsg((DM_VERBOSE, TEXT("AddGPOsForDomain: Failed to get IDispatch interface")));
  1771. goto LoopAgain;
  1772. }
  1773. //
  1774. // Now query for the IADs interface so we can get some
  1775. // properties from this GPO.
  1776. //
  1777. hr = pDispatch->QueryInterface(IID_IADs, (LPVOID *)&pADs);
  1778. if (FAILED(hr)) {
  1779. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: QI for IADs failed with 0x%x"), hr));
  1780. goto LoopAgain;
  1781. }
  1782. //
  1783. // Get the display name
  1784. //
  1785. VariantInit(&varGPO);
  1786. hr = pADs->Get(bstrDisplayName, &varGPO);
  1787. if (FAILED(hr))
  1788. {
  1789. DebugMsg((DM_VERBOSE, TEXT("AddGPOsForDomain: Failed to get display name with 0x%x"),hr));
  1790. fNeedDisplayName = TRUE;
  1791. }
  1792. else
  1793. {
  1794. wcsncpy (szDisplayName, varGPO.bstrVal, (sizeof(szDisplayName) / sizeof(szDisplayName[0])) - 1);
  1795. }
  1796. VariantClear (&varGPO);
  1797. //
  1798. // Get the common name
  1799. //
  1800. VariantInit(&varGPO);
  1801. hr = pADs->Get(bstrCommonName, &varGPO);
  1802. if (FAILED(hr))
  1803. {
  1804. DebugMsg((DM_VERBOSE, TEXT("AddGPOsForDomain: Failed to get common name with 0x%x"),hr));
  1805. VariantClear (&varGPO);
  1806. pADs->Release();
  1807. goto LoopAgain;
  1808. }
  1809. hr = StringCchCopy (szCommonName, ARRAYSIZE(szCommonName), TEXT("CN="));
  1810. if (SUCCEEDED(hr))
  1811. {
  1812. hr = StringCchCat (szCommonName, ARRAYSIZE(szCommonName), varGPO.bstrVal);
  1813. }
  1814. //
  1815. // Clean up
  1816. //
  1817. VariantClear (&varGPO);
  1818. pADs->Release();
  1819. if (FAILED(hr))
  1820. {
  1821. goto LoopAgain;
  1822. }
  1823. //
  1824. // Create a pathname object so we can tack the common name
  1825. // onto the end of the LDAP path
  1826. //
  1827. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  1828. IID_IADsPathname, (LPVOID*)&pADsPathname);
  1829. if (FAILED(hr))
  1830. {
  1831. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to create adspathname instance with 0x%x"), hr));
  1832. goto LoopAgain;
  1833. }
  1834. //
  1835. // Add the LDAP path
  1836. //
  1837. hr = pADsPathname->Set (bstrContainer, ADS_SETTYPE_FULL);
  1838. if (FAILED(hr))
  1839. {
  1840. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to set the ldap path with 0x%x"), hr));
  1841. goto LoopAgain;
  1842. }
  1843. //
  1844. // Add the GPO's common name
  1845. //
  1846. BSTR bstrTmpCommonName = SysAllocString( szCommonName );
  1847. if ( bstrTmpCommonName == NULL )
  1848. {
  1849. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to allocate BSTR memory.")));
  1850. hr = E_OUTOFMEMORY;
  1851. goto LoopAgain;
  1852. }
  1853. hr = pADsPathname->AddLeafElement (bstrTmpCommonName);
  1854. SysFreeString( bstrTmpCommonName );
  1855. if (FAILED(hr))
  1856. {
  1857. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to add the common name with 0x%x"), hr));
  1858. goto LoopAgain;
  1859. }
  1860. //
  1861. // Retreive the gpo path
  1862. //
  1863. hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrGPO);
  1864. if (FAILED(hr))
  1865. {
  1866. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to retreive gpo path with 0x%x"), hr));
  1867. goto LoopAgain;
  1868. }
  1869. //
  1870. // Make a copy of it
  1871. //
  1872. ulNoChars = wcslen(bstrGPO) + 1;
  1873. lpGPO = new WCHAR[ulNoChars];
  1874. if (!lpGPO)
  1875. {
  1876. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: Failed to alloc memory for gpo path with 0x%x"),
  1877. GetLastError()));
  1878. goto LoopAgain;
  1879. }
  1880. hr = StringCchCopy (lpGPO, ulNoChars, bstrGPO);
  1881. ASSERT(SUCCEEDED(hr));
  1882. pel = new MYLISTEL;
  1883. if (pel)
  1884. {
  1885. if (fNeedDisplayName)
  1886. {
  1887. pel->szName = new WCHAR[wcslen(lpGPO) + 1];
  1888. if (pel->szName)
  1889. {
  1890. CopyAsFriendlyName(pel->szName, lpGPO);
  1891. }
  1892. }
  1893. else
  1894. {
  1895. ulNoChars = wcslen(szDisplayName) + 1;
  1896. pel->szName = new WCHAR[ulNoChars];
  1897. if (pel->szName)
  1898. {
  1899. hr = StringCchCopy(pel->szName, ulNoChars, szDisplayName);
  1900. ASSERT(SUCCEEDED(hr));
  1901. }
  1902. }
  1903. pel->szData = lpGPO;
  1904. pel->nType = ITEMTYPE_GPO;
  1905. pel->bDisabled = FALSE;
  1906. AddElement(pel, -1);
  1907. }
  1908. LoopAgain:
  1909. if (pADsPathname)
  1910. {
  1911. pADsPathname->Release();
  1912. pADsPathname = NULL;
  1913. }
  1914. if (bstrGPO)
  1915. {
  1916. SysFreeString (bstrGPO);
  1917. bstrGPO = NULL;
  1918. }
  1919. VariantClear (&var);
  1920. }
  1921. SendMessage (m_hList, LB_SETCURSEL, 0, 0);
  1922. Exit:
  1923. if (pVar)
  1924. {
  1925. ADsFreeEnumerator (pVar);
  1926. }
  1927. if (pADsPathname)
  1928. {
  1929. pADsPathname->Release();
  1930. }
  1931. if (pADsContainer)
  1932. {
  1933. pADsContainer->Release();
  1934. }
  1935. if (bstrContainer)
  1936. {
  1937. SysFreeString (bstrContainer);
  1938. }
  1939. if (bstrCommonName)
  1940. {
  1941. SysFreeString (bstrCommonName);
  1942. }
  1943. if (bstrDisplayName)
  1944. {
  1945. SysFreeString (bstrDisplayName);
  1946. }
  1947. if (lpDomain)
  1948. {
  1949. delete [] lpDomain;
  1950. }
  1951. SetCursor(hcur);
  1952. return TRUE;
  1953. }
  1954. //+--------------------------------------------------------------------------
  1955. //
  1956. // Member: CBrowserPP::AddChildContainers
  1957. //
  1958. // Synopsis: Adds the child domains and OUs for the currently selected object
  1959. //
  1960. // History: 05-006-1998 stevebl Created
  1961. //
  1962. //---------------------------------------------------------------------------
  1963. BOOL CBrowserPP::AddChildContainers()
  1964. {
  1965. LPOLESTR szObject = NULL;
  1966. HRESULT hr;
  1967. ULONG ulNoChars;
  1968. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  1969. if (iIndex == CB_ERR)
  1970. {
  1971. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddChildContainers: No object selected.")));
  1972. return FALSE;
  1973. }
  1974. LOOKDATA * pdata = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  1975. if (pdata)
  1976. {
  1977. if (ITEMTYPE_DOMAIN == pdata->nType)
  1978. {
  1979. // make sure that domains are resolved to a server
  1980. LPTSTR szServer = ExtractServerName(pdata->szData);
  1981. if (NULL == szServer)
  1982. {
  1983. BOOL bDCFound = FALSE;
  1984. LPWSTR szTemp = GetDCName(pdata->szName, NULL, NULL, TRUE, 0);
  1985. if (szTemp)
  1986. {
  1987. LPWSTR szFullPath = MakeFullPath(pdata->szData, szTemp);
  1988. if (szFullPath)
  1989. {
  1990. ulNoChars = wcslen(szFullPath)+1;
  1991. LPWSTR sz = new WCHAR[ulNoChars];
  1992. if (sz)
  1993. {
  1994. hr = StringCchCopy(sz, ulNoChars, szFullPath);
  1995. ASSERT(SUCCEEDED(hr));
  1996. delete [] pdata->szData;
  1997. pdata->szData = sz;
  1998. bDCFound = TRUE;
  1999. }
  2000. LocalFree(szFullPath);
  2001. }
  2002. LocalFree(szTemp);
  2003. }
  2004. if (!bDCFound)
  2005. {
  2006. DebugMsg((DM_WARNING, TEXT("CBrowserPP::AddChildContainers: Failed to get a DC name for %s"),
  2007. pdata->szName));
  2008. return FALSE;
  2009. }
  2010. }
  2011. else
  2012. {
  2013. LocalFree(szServer);
  2014. }
  2015. }
  2016. LOOKDATA * pChild = pdata->pChild;
  2017. while (pChild)
  2018. {
  2019. // Add child domains this way since ADsEnumerateNext doesn't
  2020. // seem to be giving them to us.
  2021. if (ITEMTYPE_DOMAIN == pChild->nType)
  2022. {
  2023. // got something we can work with
  2024. MYLISTEL * pel = new MYLISTEL;
  2025. if (pel)
  2026. {
  2027. memset(pel, 0, sizeof(MYLISTEL));
  2028. ulNoChars = wcslen(pChild->szData) + 1;
  2029. pel->szData = new OLECHAR[ulNoChars];
  2030. if (pel->szData)
  2031. {
  2032. hr = StringCchCopy(pel->szData, ulNoChars, pChild->szData);
  2033. ASSERT(SUCCEEDED(hr));
  2034. }
  2035. ulNoChars = wcslen(pChild->szName) + 1;
  2036. pel->szName = new OLECHAR[ulNoChars];
  2037. if (pel->szName)
  2038. {
  2039. hr = StringCchCopy(pel->szName, ulNoChars, pChild->szName);
  2040. ASSERT(SUCCEEDED(hr));
  2041. }
  2042. pel->bDisabled = FALSE;
  2043. pel->nType = ITEMTYPE_DOMAIN;
  2044. INT index = -1;
  2045. AddElement(pel, -1);
  2046. }
  2047. pChild = pChild->pSibling;
  2048. }
  2049. }
  2050. szObject = pdata->szData;
  2051. m_pPrevSel = pdata;
  2052. } else {
  2053. m_pPrevSel = NULL;
  2054. }
  2055. if ( ! szObject )
  2056. {
  2057. return FALSE;
  2058. }
  2059. IADsContainer * pADsContainer;
  2060. hr = OpenDSObject(szObject, IID_IADsContainer, (void **)&pADsContainer);
  2061. if (SUCCEEDED(hr))
  2062. {
  2063. IEnumVARIANT *pVar;
  2064. hr = ADsBuildEnumerator(pADsContainer, &pVar);
  2065. if (SUCCEEDED(hr))
  2066. {
  2067. VARIANT var;
  2068. VariantInit(&var);
  2069. ULONG ulResult;
  2070. while (SUCCEEDED(ADsEnumerateNext(pVar, 1, &var, &ulResult)))
  2071. {
  2072. if (0 == ulResult)
  2073. {
  2074. break;
  2075. }
  2076. if (var.vt == VT_DISPATCH)
  2077. {
  2078. // query for the IADs interface so we can get its properties
  2079. IADs * pDSObject;
  2080. hr = var.pdispVal->QueryInterface(IID_IADs, (LPVOID *)&pDSObject);
  2081. if (SUCCEEDED(hr))
  2082. {
  2083. BSTR bstr;
  2084. DWORD dwType = -1;
  2085. hr = pDSObject->get_Class(&bstr);
  2086. if (SUCCEEDED(hr))
  2087. {
  2088. if (0 == wcscmp(bstr, CLASSNAME_OU))
  2089. {
  2090. dwType = ITEMTYPE_OU;
  2091. }
  2092. else if (0 == wcscmp(bstr, CLASSNAME_DOMAIN))
  2093. {
  2094. dwType = ITEMTYPE_DOMAIN;
  2095. }
  2096. SysFreeString(bstr);
  2097. }
  2098. if (ITEMTYPE_DOMAIN == dwType || ITEMTYPE_OU == dwType)
  2099. {
  2100. // got something we can work with
  2101. MYLISTEL * pel = new MYLISTEL;
  2102. if (pel)
  2103. {
  2104. memset(pel, 0, sizeof(MYLISTEL));
  2105. hr = pDSObject->get_ADsPath(&bstr);
  2106. if (SUCCEEDED(hr))
  2107. {
  2108. ulNoChars = wcslen(bstr) + 1;
  2109. pel->szData = new OLECHAR[ulNoChars];
  2110. if (pel->szData)
  2111. {
  2112. hr = StringCchCopy(pel->szData, ulNoChars, bstr);
  2113. ASSERT(SUCCEEDED(hr));
  2114. }
  2115. pel->szName = new OLECHAR[wcslen(bstr) + 1];
  2116. if (pel->szName)
  2117. {
  2118. // Need to convert to a friendly name.
  2119. CopyAsFriendlyName(pel->szName, bstr);
  2120. }
  2121. SysFreeString(bstr);
  2122. }
  2123. pel->nType = dwType;
  2124. INT index = -1;
  2125. AddElement(pel, -1);
  2126. }
  2127. }
  2128. pDSObject->Release();
  2129. }
  2130. }
  2131. VariantClear(&var);
  2132. }
  2133. ADsFreeEnumerator(pVar);
  2134. }
  2135. pADsContainer->Release();
  2136. }
  2137. return TRUE;
  2138. }
  2139. //+--------------------------------------------------------------------------
  2140. //
  2141. // Member: CBrowserPP::RefreshDomains
  2142. //
  2143. // Synopsis: refreshes the listview for the "domains" page
  2144. //
  2145. // History: 04-30-1998 stevebl Created
  2146. //
  2147. //---------------------------------------------------------------------------
  2148. void CBrowserPP::RefreshDomains()
  2149. {
  2150. LONG lStyle;
  2151. ListView_DeleteAllItems(m_hList);
  2152. lStyle = GetWindowLong (m_hList, GWL_STYLE);
  2153. lStyle &= ~LVS_SORTASCENDING;
  2154. SetWindowLong (m_hList, GWL_STYLE, lStyle);
  2155. if (AddChildContainers())
  2156. {
  2157. AddGPOsLinkedToObject();
  2158. EnableWindow (m_hList, TRUE);
  2159. if (!(m_pGBI->dwFlags & GPO_BROWSE_DISABLENEW)) {
  2160. SendMessage (m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_NEWFOLDER, (LPARAM) MAKELONG(1, 0));
  2161. }
  2162. }
  2163. else
  2164. {
  2165. EnableWindow (m_hList, FALSE);
  2166. SendMessage (m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_NEWFOLDER, (LPARAM) MAKELONG(0, 0));
  2167. }
  2168. }
  2169. //+--------------------------------------------------------------------------
  2170. //
  2171. // Member: CBrowserPP::RefreshSites
  2172. //
  2173. // Synopsis: refreshes the listview for the "sites" page
  2174. //
  2175. // History: 04-30-1998 stevebl Created
  2176. //
  2177. //---------------------------------------------------------------------------
  2178. void CBrowserPP::RefreshSites()
  2179. {
  2180. LONG lStyle;
  2181. ListView_DeleteAllItems(m_hList);
  2182. lStyle = GetWindowLong (m_hList, GWL_STYLE);
  2183. lStyle &= ~LVS_SORTASCENDING;
  2184. SetWindowLong (m_hList, GWL_STYLE, lStyle);
  2185. AddGPOsLinkedToObject();
  2186. }
  2187. //+--------------------------------------------------------------------------
  2188. //
  2189. // Member: CBrowserPP::RefreshAll
  2190. //
  2191. // Synopsis: refreshes the listview for the "all" page
  2192. //
  2193. // History: 04-30-1998 stevebl Created
  2194. //
  2195. //---------------------------------------------------------------------------
  2196. void CBrowserPP::RefreshAll()
  2197. {
  2198. LONG lStyle;
  2199. ListView_DeleteAllItems(m_hList);
  2200. lStyle = GetWindowLong (m_hList, GWL_STYLE);
  2201. lStyle |= LVS_SORTASCENDING;
  2202. SetWindowLong (m_hList, GWL_STYLE, lStyle);
  2203. if (AddGPOsForDomain())
  2204. {
  2205. EnableWindow (m_hList, TRUE);
  2206. SendMessage (m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_NEWFOLDER, (LPARAM) MAKELONG(1, 0));
  2207. }
  2208. else
  2209. {
  2210. EnableWindow (m_hList, FALSE);
  2211. SendMessage (m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_NEWFOLDER, (LPARAM) MAKELONG(0, 0));
  2212. }
  2213. }
  2214. void CBrowserPP::SetButtonState()
  2215. {
  2216. if (ListView_GetNextItem (m_hList, -1, LVNI_ALL | LVNI_SELECTED) != -1)
  2217. {
  2218. EnableWindow (GetDlgItem(GetParent(m_hwndDlg), IDOK), TRUE);
  2219. }
  2220. else
  2221. {
  2222. EnableWindow (GetDlgItem(GetParent(m_hwndDlg), IDOK), FALSE);
  2223. }
  2224. }
  2225. BOOL CBrowserPP::OnInitDialog()
  2226. {
  2227. DWORD dwDescription;
  2228. switch (m_dwPageType)
  2229. {
  2230. case PAGETYPE_DOMAINS:
  2231. dwDescription = IDS_DOMAINDESCRIPTION;
  2232. break;
  2233. case PAGETYPE_SITES:
  2234. dwDescription = IDS_SITEDESCRIPTION;
  2235. break;
  2236. case PAGETYPE_ALL:
  2237. default:
  2238. dwDescription = IDS_ALLDESCRIPTION;
  2239. break;
  2240. }
  2241. WCHAR szDescription[MAX_PATH]; // this is a resource - size doesn't need to be dynamic
  2242. LoadString(g_hInstance, dwDescription, szDescription, MAX_PATH);
  2243. SetDlgItemText(m_hwndDlg, IDC_DESCRIPTION, szDescription);
  2244. m_hList = GetDlgItem(m_hwndDlg, IDC_LIST1);
  2245. m_ilSmall = ImageList_LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16), SMALLICONSIZE, 0, RGB(255,0,255));
  2246. m_ilLarge = ImageList_LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_32x32), LARGEICONSIZE, 0, RGB(255, 0 ,255));
  2247. m_hCombo = GetDlgItem(m_hwndDlg, IDC_COMBO1);
  2248. RECT rect;
  2249. GetClientRect(m_hList, &rect);
  2250. WCHAR szText[32];
  2251. int dxScrollBar = GetSystemMetrics(SM_CXVSCROLL);
  2252. if (PAGETYPE_ALL == m_dwPageType)
  2253. {
  2254. LV_COLUMN lvcol;
  2255. memset(&lvcol, 0, sizeof(lvcol));
  2256. lvcol.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  2257. lvcol.fmt = LVCFMT_LEFT;
  2258. lvcol.cx = (rect.right - rect.left) - dxScrollBar;
  2259. LoadString(g_hInstance, IDS_NAMECOLUMN, szText, 32);
  2260. lvcol.pszText = szText;
  2261. ListView_InsertColumn(m_hList, 0, &lvcol);
  2262. }
  2263. else
  2264. {
  2265. LV_COLUMN lvcol;
  2266. memset(&lvcol, 0, sizeof(lvcol));
  2267. lvcol.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  2268. lvcol.fmt = LVCFMT_LEFT;
  2269. int cx = ((rect.right - rect.left) - dxScrollBar)*2/3;
  2270. lvcol.cx = cx;
  2271. LoadString(g_hInstance, IDS_NAMECOLUMN, szText, 32);
  2272. lvcol.pszText = szText;
  2273. ListView_InsertColumn(m_hList, 0, &lvcol);
  2274. memset(&lvcol, 0, sizeof(lvcol));
  2275. lvcol.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  2276. lvcol.fmt = LVCFMT_LEFT;
  2277. lvcol.cx = ((rect.right - rect.left) - dxScrollBar) - cx;
  2278. LoadString(g_hInstance, IDS_DOMAINCOLUMN, szText, 32);
  2279. lvcol.pszText = szText;
  2280. ListView_InsertColumn(m_hList, 1, &lvcol);
  2281. }
  2282. ListView_SetImageList(m_hList, m_ilSmall, LVSIL_SMALL);
  2283. ListView_SetImageList(m_hList, m_ilLarge, LVSIL_NORMAL);
  2284. SendMessage(m_hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_LABELTIP);
  2285. GetWindowRect(GetDlgItem(m_hwndDlg, IDC_STATIC1), &rect);
  2286. MapWindowPoints(NULL , m_hwndDlg, (LPPOINT) &rect , 2);
  2287. TBBUTTON rgButtons[3];
  2288. rgButtons[0].iBitmap = 0;
  2289. rgButtons[0].idCommand = ID_BACKBUTTON;
  2290. rgButtons[0].fsState = 0; // this button will be disabled by
  2291. // default and only enabled when there
  2292. // is something to back up to
  2293. //rgButtons[0].fsState = PAGETYPE_ALL == m_dwPageType ? 0 : TBSTATE_ENABLED;
  2294. rgButtons[0].fsStyle = TBSTYLE_BUTTON;
  2295. rgButtons[0].dwData = 0;
  2296. rgButtons[0].iString = 0;
  2297. rgButtons[1].iBitmap = 1;
  2298. rgButtons[1].idCommand = ID_NEWFOLDER;
  2299. rgButtons[1].fsStyle = TBSTYLE_BUTTON;
  2300. rgButtons[1].dwData = 0;
  2301. rgButtons[1].iString = 0;
  2302. if (PAGETYPE_ALL != m_dwPageType)
  2303. {
  2304. if (m_pGBI->dwFlags & GPO_BROWSE_DISABLENEW)
  2305. {
  2306. rgButtons[1].fsState = 0;
  2307. }
  2308. else
  2309. {
  2310. rgButtons[1].fsState = TBSTATE_ENABLED;
  2311. }
  2312. }
  2313. else
  2314. {
  2315. rgButtons[1].fsState =TBSTATE_ENABLED;
  2316. }
  2317. rgButtons[2].iBitmap = 2;
  2318. rgButtons[2].idCommand = ID_ROTATEVIEW;
  2319. rgButtons[2].fsState = TBSTATE_ENABLED ;
  2320. rgButtons[2].fsStyle = TBSTYLE_DROPDOWN;
  2321. rgButtons[2].dwData = 0;
  2322. rgButtons[2].iString = 0;
  2323. m_toolbar = CreateToolbarEx(m_hwndDlg,
  2324. WS_CHILD | WS_VISIBLE | CCS_NODIVIDER | CCS_NORESIZE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
  2325. IDR_TOOLBAR1,
  2326. 4,
  2327. g_hInstance,
  2328. IDR_TOOLBAR1,
  2329. rgButtons,
  2330. 3,
  2331. BUTTONSIZE,
  2332. BUTTONSIZE,
  2333. BUTTONSIZE,
  2334. BUTTONSIZE,
  2335. sizeof(TBBUTTON));
  2336. SendMessage(m_toolbar, TB_SETEXTENDEDSTYLE, TBSTYLE_EX_DRAWDDARROWS, TBSTYLE_EX_DRAWDDARROWS);
  2337. MoveWindow(m_toolbar, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, FALSE);
  2338. // Don't need to call Refresh in any of these because we're calling it in
  2339. // OnComboChange().
  2340. switch (m_dwPageType)
  2341. {
  2342. case PAGETYPE_DOMAINS:
  2343. FillDomainList();
  2344. SetInitialOU();
  2345. // RefreshDomains();
  2346. break;
  2347. case PAGETYPE_SITES:
  2348. SendMessage(m_hCombo, CB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  2349. FillSitesList();
  2350. // RefreshSites();
  2351. break;
  2352. default:
  2353. case PAGETYPE_ALL:
  2354. SendMessage(m_hCombo, CB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  2355. FillDomainList();
  2356. // RefreshAll();
  2357. break;
  2358. }
  2359. SetButtonState();
  2360. return TRUE; // return TRUE unless you set the focus to a control
  2361. // EXCEPTION: OCX Property Pages should return FALSE
  2362. }
  2363. BOOL CBrowserPP::DoBackButton()
  2364. {
  2365. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  2366. if (iIndex == CB_ERR)
  2367. {
  2368. DebugMsg((DM_WARNING, TEXT("CBrowserPP::DoBackButton: No object selected.")));
  2369. return FALSE;
  2370. }
  2371. LOOKDATA * pdata = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  2372. if (pdata)
  2373. {
  2374. if (pdata->pParent)
  2375. {
  2376. // if this item has a parent then select it
  2377. SendMessage(m_hCombo, CB_SELECTSTRING, (WPARAM)-1, (LPARAM) (LPCTSTR) pdata->pParent);
  2378. // force everything to refresh
  2379. OnComboChange();
  2380. }
  2381. }
  2382. return FALSE;
  2383. }
  2384. BOOL CBrowserPP::DeleteGPO()
  2385. {
  2386. BOOL fSucceeded = FALSE;
  2387. BOOL fRemoveListEntry = FALSE;
  2388. int index = ListView_GetNextItem(m_hList, -1, LVNI_SELECTED);
  2389. if (-1 == index)
  2390. {
  2391. return FALSE;
  2392. }
  2393. LVITEM item;
  2394. memset(&item, 0, sizeof(item));
  2395. item.mask = LVIF_PARAM;
  2396. item.iItem = index;
  2397. ListView_GetItem(m_hList, &item);
  2398. MYLISTEL * pel = (MYLISTEL *)item.lParam;
  2399. LPGROUPPOLICYOBJECT pGPO = NULL;
  2400. HRESULT hr;
  2401. WCHAR szBuffer[100];
  2402. WCHAR szConfirm[MAX_FRIENDLYNAME + 100];
  2403. WCHAR szTitle[100];
  2404. if (pel->nType != ITEMTYPE_GPO)
  2405. {
  2406. goto CleanUp;
  2407. }
  2408. LoadString(g_hInstance, IDS_CONFIRMTITLE, szTitle, 100);
  2409. LoadString(g_hInstance, IDS_DELETECONFIRM, szBuffer, 100);
  2410. (void) StringCchPrintf (szConfirm, ARRAYSIZE(szConfirm), szBuffer, pel->szName);
  2411. if (IDNO == MessageBox(m_hwndDlg, szConfirm, szTitle, MB_YESNO | MB_ICONEXCLAMATION))
  2412. {
  2413. goto CleanUp;
  2414. }
  2415. // If we're on any page other than the "All" page then we need to break
  2416. // the association before we can delete the object.
  2417. if (m_dwPageType != PAGETYPE_ALL)
  2418. {
  2419. // break the association
  2420. LPOLESTR szContainer = GetCurrentObject();
  2421. if (szContainer)
  2422. {
  2423. DeleteLink(pel->szData, szContainer);
  2424. delete [] szContainer;
  2425. }
  2426. }
  2427. hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL,
  2428. CLSCTX_SERVER, IID_IGroupPolicyObject,
  2429. (void **)&pGPO);
  2430. if (FAILED(hr))
  2431. {
  2432. DebugMsg((DM_WARNING, TEXT("CoCreateInstance failed with 0x%x\r\n"), hr));
  2433. goto Done;
  2434. }
  2435. // open GPO object without opening registry data
  2436. hr = pGPO->OpenDSGPO(pel->szData, 0);
  2437. if (FAILED(hr))
  2438. {
  2439. ReportError(m_hwndDlg, hr, IDS_FAILEDDS);
  2440. DebugMsg((DM_WARNING, TEXT("OpenDSGPO failed with 0x%x\r\n"), hr));
  2441. goto Done;
  2442. }
  2443. // delete it
  2444. hr = pGPO->Delete();
  2445. if (FAILED(hr))
  2446. {
  2447. ReportError(m_hwndDlg, hr, IDS_FAILEDDELETE);
  2448. DebugMsg((DM_WARNING, TEXT("Delete failed with 0x%x\r\n"), hr));
  2449. goto Done;
  2450. }
  2451. fRemoveListEntry = TRUE;
  2452. Done:
  2453. if (pGPO)
  2454. {
  2455. pGPO->Release();
  2456. }
  2457. // remove the list entry
  2458. if (fRemoveListEntry)
  2459. fSucceeded = ListView_DeleteItem(m_hList, index);
  2460. CleanUp:
  2461. return fSucceeded;
  2462. }
  2463. BOOL CBrowserPP::DoNewGPO()
  2464. {
  2465. BOOL fSucceeded = FALSE;
  2466. HRESULT hr;
  2467. LPGROUPPOLICYOBJECT pGPO = NULL;
  2468. BOOL fEdit = FALSE;
  2469. MYLISTEL * pel = NULL;
  2470. LPOLESTR szObject = GetCurrentObject();
  2471. LPOLESTR szDomain = GetCurrentDomain();
  2472. INT index = -1;
  2473. int cch = 0;
  2474. LPTSTR szFullPath = NULL;
  2475. LPTSTR szServerName = NULL;
  2476. DWORD dwOptions = 0;
  2477. if (NULL == szDomain)
  2478. {
  2479. goto Done;
  2480. }
  2481. if (NULL == szObject)
  2482. {
  2483. goto Done;
  2484. }
  2485. pel = new MYLISTEL;
  2486. if (NULL == pel)
  2487. {
  2488. DebugMsg((DM_WARNING, TEXT("CBrowserPP::DoNewGPO failed to allocate memory for GPO name")));
  2489. goto Done;
  2490. }
  2491. pel->bDisabled = FALSE;
  2492. pel->szData = NULL;
  2493. pel->szName = new OLECHAR[MAX_FRIENDLYNAME];
  2494. if (NULL == pel->szName)
  2495. {
  2496. DebugMsg((DM_WARNING, TEXT("CBrowserPP::DoNewGPO failed to allocate memory for GPO name")));
  2497. goto Done;
  2498. }
  2499. GetNewGPODisplayName (pel->szName, MAX_FRIENDLYNAME);
  2500. pel->nType = ITEMTYPE_GPO;
  2501. // Create a new GPO named "New Group Policy Object"
  2502. //
  2503. // Create a new GPO object to work with
  2504. //
  2505. hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL,
  2506. CLSCTX_SERVER, IID_IGroupPolicyObject,
  2507. (void**)&pGPO);
  2508. if (FAILED(hr))
  2509. {
  2510. DebugMsg((DM_WARNING, TEXT("CoCreateInstance failed with 0x%x\r\n"), hr));
  2511. goto Done;
  2512. }
  2513. //
  2514. // Open the requested object without mounting the registry
  2515. //
  2516. #if FGPO_SUPPORT
  2517. if (IsCurrentObjectAForest())
  2518. {
  2519. dwOptions = GPO_OPEN_FOREST;
  2520. }
  2521. #endif
  2522. hr = pGPO->New(szDomain, pel->szName, dwOptions);
  2523. if (FAILED(hr))
  2524. {
  2525. ReportError(m_hwndDlg, hr, IDS_FAILEDNEW);
  2526. DebugMsg((DM_WARNING, TEXT("Failed to create GPO object with 0x%x\r\n"), hr));
  2527. goto Done;
  2528. }
  2529. // continue to try to allocate memory until either a big enough buffer is
  2530. // created to load the GPO path or we run out of memory
  2531. pel->szData = NULL;
  2532. do
  2533. {
  2534. if (pel->szData)
  2535. {
  2536. delete [] pel->szData;
  2537. }
  2538. cch += MAX_PATH;
  2539. pel->szData = new OLECHAR[cch];
  2540. if (NULL == pel->szData)
  2541. {
  2542. }
  2543. hr = pGPO->GetPath(pel->szData, cch);
  2544. } while (hr == E_OUTOFMEMORY);
  2545. if (FAILED(hr))
  2546. {
  2547. DebugMsg((DM_WARNING, TEXT("Failed to get GPO object path with 0x%x\r\n"), hr));
  2548. goto Done;
  2549. }
  2550. szServerName = ExtractServerName(szDomain);
  2551. szFullPath = MakeFullPath(pel->szData, szServerName);
  2552. if (szFullPath)
  2553. {
  2554. ULONG ulNoChars = wcslen(szFullPath) + 1;
  2555. delete [] pel->szData;
  2556. pel->szData = new OLECHAR[ulNoChars];
  2557. if (NULL == pel->szData)
  2558. {
  2559. DebugMsg((DM_WARNING, TEXT("CBrowserPP::DoNewGPO failed to allocate memory for GPO path")));
  2560. goto Done;
  2561. }
  2562. hr = StringCchCopy(pel->szData, ulNoChars, szFullPath);
  2563. ASSERT(SUCCEEDED(hr));
  2564. }
  2565. if (m_dwPageType != PAGETYPE_ALL)
  2566. {
  2567. // If we're not on the "All" page then we need to create a link.
  2568. CreateLink(pel->szData, szObject);
  2569. }
  2570. // Add the entry to the list view
  2571. index = AddElement(pel, -1);
  2572. fSucceeded = index != -1;
  2573. // It's been added so now we need to make sure we don't delete it below
  2574. pel = NULL;
  2575. // Record that we got this far
  2576. fEdit = TRUE;
  2577. Done:
  2578. if (pel)
  2579. {
  2580. if (pel->szData)
  2581. {
  2582. delete [] pel->szData;
  2583. }
  2584. if (pel->szName)
  2585. {
  2586. delete [] pel->szName;
  2587. }
  2588. delete pel;
  2589. }
  2590. if (pGPO)
  2591. pGPO->Release();
  2592. if (fEdit)
  2593. {
  2594. // Now trigger an edit of the entry
  2595. SetFocus(m_hList);
  2596. ListView_EditLabel(m_hList, index);
  2597. }
  2598. if (szServerName)
  2599. LocalFree(szServerName);
  2600. if (szFullPath)
  2601. LocalFree(szFullPath);
  2602. if (szDomain)
  2603. delete [] szDomain;
  2604. if (szObject)
  2605. delete [] szObject;
  2606. return fSucceeded;
  2607. }
  2608. BOOL CBrowserPP::CreateLink(LPOLESTR szObject, LPOLESTR szContainer)
  2609. {
  2610. HRESULT hr = CreateGPOLink(szObject, szContainer, FALSE);
  2611. if (SUCCEEDED(hr))
  2612. {
  2613. return TRUE;
  2614. }
  2615. ReportError(m_hwndDlg, hr, IDS_FAILEDLINK);
  2616. return FALSE;
  2617. }
  2618. BOOL CBrowserPP::DeleteLink(LPOLESTR szObject, LPOLESTR szContainer)
  2619. {
  2620. HRESULT hr = DeleteGPOLink(szObject, szContainer);
  2621. if (SUCCEEDED(hr))
  2622. {
  2623. return TRUE;
  2624. }
  2625. ReportError(m_hwndDlg, hr, IDS_FAILEDUNLINK);
  2626. return FALSE;
  2627. }
  2628. BOOL CBrowserPP::DoRotateView()
  2629. {
  2630. DWORD dwStyle = GetWindowLong(m_hList, GWL_STYLE);
  2631. DWORD dw = dwStyle & LVS_TYPEMASK;
  2632. switch (dw)
  2633. {
  2634. case LVS_ICON:
  2635. dw = LVS_SMALLICON;
  2636. break;
  2637. case LVS_SMALLICON:
  2638. dw = LVS_LIST;
  2639. break;
  2640. case LVS_REPORT:
  2641. dw = LVS_ICON;
  2642. break;
  2643. case LVS_LIST:
  2644. default:
  2645. dw = LVS_REPORT;
  2646. break;
  2647. }
  2648. dwStyle -= dwStyle & LVS_TYPEMASK;
  2649. dwStyle += dw;
  2650. SetWindowLong(m_hList, GWL_STYLE, dwStyle);
  2651. return TRUE;
  2652. }
  2653. void CBrowserPP::OnDetails()
  2654. {
  2655. DWORD dwStyle = GetWindowLong(m_hList, GWL_STYLE);
  2656. dwStyle -= dwStyle & LVS_TYPEMASK;
  2657. SetWindowLong(m_hList, GWL_STYLE, dwStyle + LVS_REPORT);
  2658. }
  2659. void CBrowserPP::OnList()
  2660. {
  2661. DWORD dwStyle = GetWindowLong(m_hList, GWL_STYLE);
  2662. dwStyle -= dwStyle & LVS_TYPEMASK;
  2663. SetWindowLong(m_hList, GWL_STYLE, dwStyle + LVS_LIST);
  2664. }
  2665. void CBrowserPP::OnLargeicons()
  2666. {
  2667. DWORD dwStyle = GetWindowLong(m_hList, GWL_STYLE);
  2668. dwStyle -= dwStyle & LVS_TYPEMASK;
  2669. SetWindowLong(m_hList, GWL_STYLE, dwStyle + LVS_ICON);
  2670. }
  2671. void CBrowserPP::OnSmallicons()
  2672. {
  2673. DWORD dwStyle = GetWindowLong(m_hList, GWL_STYLE);
  2674. dwStyle -= dwStyle & LVS_TYPEMASK;
  2675. SetWindowLong(m_hList, GWL_STYLE, dwStyle + LVS_SMALLICON);
  2676. }
  2677. void CBrowserPP::OnContextMenu(LPARAM lParam)
  2678. {
  2679. int i = ListView_GetNextItem(m_hList, -1, LVNI_SELECTED);
  2680. RECT rc;
  2681. POINT pt;
  2682. pt.x = ((int)(short)LOWORD(lParam));
  2683. pt.y = ((int)(short)HIWORD(lParam));
  2684. GetWindowRect (GetDlgItem (m_hwndDlg, IDC_LIST1), &rc);
  2685. if (!PtInRect (&rc, pt))
  2686. {
  2687. if ((lParam == (LPARAM) -1) && (i >= 0))
  2688. {
  2689. rc.left = LVIR_SELECTBOUNDS;
  2690. SendMessage (m_hList, LVM_GETITEMRECT, i, (LPARAM) &rc);
  2691. pt.x = rc.left + 8;
  2692. pt.y = rc.top + ((rc.bottom - rc.top) / 2);
  2693. ClientToScreen (m_hList, &pt);
  2694. }
  2695. else
  2696. {
  2697. pt.x = rc.left + ((rc.right - rc.left) / 2);
  2698. pt.y = rc.top + ((rc.bottom - rc.top) / 2);
  2699. }
  2700. }
  2701. // get the popup menu
  2702. HMENU hPopup;
  2703. hPopup = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_LISTMENU));
  2704. HMENU hSubMenu = GetSubMenu(hPopup, 0);
  2705. if (i >= 0)
  2706. {
  2707. // item selected
  2708. // figure out what type it is
  2709. LVITEM item;
  2710. memset(&item, 0, sizeof(item));
  2711. item.mask = LVIF_PARAM;
  2712. item.iItem = i;
  2713. ListView_GetItem(m_hList, &item);
  2714. MYLISTEL * pel = (MYLISTEL *)item.lParam;
  2715. // get rid of the view menu and separator
  2716. RemoveMenu(hSubMenu, 0, MF_BYPOSITION);
  2717. RemoveMenu(hSubMenu, 0, MF_BYPOSITION);
  2718. // get rid of the arrange and line-up items
  2719. RemoveMenu(hSubMenu, 0, MF_BYPOSITION);
  2720. RemoveMenu(hSubMenu, 0, MF_BYPOSITION);
  2721. RemoveMenu(hSubMenu, 0, MF_BYPOSITION);
  2722. // get rid of the "new" menu item
  2723. RemoveMenu(hSubMenu, ID_NEW, MF_BYCOMMAND);
  2724. switch (pel->nType)
  2725. {
  2726. case ITEMTYPE_GPO:
  2727. if (pel->bDisabled)
  2728. {
  2729. // disable edit, rename, delete
  2730. EnableMenuItem(hSubMenu, ID_EDIT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2731. EnableMenuItem(hSubMenu, ID_RENAME, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2732. EnableMenuItem(hSubMenu, ID_DELETE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2733. }
  2734. break;
  2735. default:
  2736. case ITEMTYPE_FOREST:
  2737. case ITEMTYPE_SITE:
  2738. case ITEMTYPE_DOMAIN:
  2739. case ITEMTYPE_OU:
  2740. // remove the edit menu item and the separator
  2741. RemoveMenu(hSubMenu, ID_EDIT, MF_BYCOMMAND);
  2742. RemoveMenu(hSubMenu, 0, MF_BYPOSITION);
  2743. // disable rename, delete and properties
  2744. EnableMenuItem(hSubMenu, ID_RENAME, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2745. EnableMenuItem(hSubMenu, ID_DELETE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2746. EnableMenuItem(hSubMenu, ID_PROPERTIES, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2747. break;
  2748. }
  2749. }
  2750. else
  2751. {
  2752. // no item selected
  2753. // get rid of the edit menu item
  2754. RemoveMenu(hSubMenu, ID_EDIT, MF_BYCOMMAND);
  2755. // get rid of the delete and rename items
  2756. RemoveMenu(hSubMenu, ID_DELETE, MF_BYCOMMAND);
  2757. RemoveMenu(hSubMenu, ID_RENAME, MF_BYCOMMAND);
  2758. if (PAGETYPE_ALL != m_dwPageType)
  2759. {
  2760. if (m_pGBI->dwFlags & GPO_BROWSE_DISABLENEW)
  2761. {
  2762. // get rid of the "new" menu item
  2763. RemoveMenu(hSubMenu, ID_NEW, MF_BYCOMMAND);
  2764. RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
  2765. }
  2766. }
  2767. RemoveMenu(hSubMenu, (GetMenuItemCount(hSubMenu) - 1), MF_BYPOSITION);
  2768. RemoveMenu(hSubMenu, (GetMenuItemCount(hSubMenu) - 1), MF_BYPOSITION);
  2769. // set view radio button
  2770. UINT ui = ID_LIST;
  2771. DWORD dw = GetWindowLong(m_hList, GWL_STYLE) & LVS_TYPEMASK;
  2772. if (dw == LVS_ICON || dw == LVS_SMALLICON)
  2773. {
  2774. // Auto-Arrange means something in these views so we need to enable it
  2775. EnableMenuItem(hSubMenu, ID_ARRANGE_AUTO, MF_BYCOMMAND | MF_ENABLED);
  2776. // also need to make sure it's set correctly
  2777. if (LVS_AUTOARRANGE == (GetWindowLong(m_hList, GWL_STYLE) & LVS_AUTOARRANGE))
  2778. CheckMenuItem(hSubMenu, ID_ARRANGE_AUTO, MF_BYCOMMAND | MF_CHECKED);
  2779. }
  2780. switch (dw)
  2781. {
  2782. case LVS_ICON:
  2783. ui = ID_LARGEICONS;
  2784. break;
  2785. case LVS_SMALLICON:
  2786. ui = ID_SMALLICONS;
  2787. break;
  2788. case LVS_REPORT:
  2789. ui = ID_DETAILS;
  2790. break;
  2791. case LVS_LIST:
  2792. default:
  2793. ui = ID_LIST;
  2794. break;
  2795. }
  2796. CheckMenuRadioItem(hSubMenu, ui, ui, ui, MF_BYCOMMAND);
  2797. }
  2798. TrackPopupMenu(hSubMenu,
  2799. TPM_LEFTALIGN,
  2800. pt.x, pt.y,
  2801. 0,
  2802. m_hwndDlg,
  2803. NULL);
  2804. DestroyMenu(hPopup);
  2805. }
  2806. void CBrowserPP::OnArrangeAuto()
  2807. {
  2808. DWORD dwStyle = GetWindowLong(m_hList, GWL_STYLE);
  2809. if (LVS_AUTOARRANGE == (dwStyle & LVS_AUTOARRANGE))
  2810. SetWindowLong(m_hList, GWL_STYLE, dwStyle - LVS_AUTOARRANGE);
  2811. else
  2812. SetWindowLong(m_hList, GWL_STYLE, dwStyle + LVS_AUTOARRANGE);
  2813. }
  2814. int CALLBACK CompareName(LPARAM lParam1, LPARAM lParam2, LPARAM lParamsort)
  2815. {
  2816. MYLISTEL * pel1 = (MYLISTEL *)lParam1;
  2817. MYLISTEL * pel2 = (MYLISTEL *)lParam2;
  2818. return _wcsicmp(pel1->szName, pel2->szName);
  2819. }
  2820. int CALLBACK CompareType(LPARAM lParam1, LPARAM lParam2, LPARAM lParamsort)
  2821. {
  2822. MYLISTEL * pel1 = (MYLISTEL *)lParam1;
  2823. MYLISTEL * pel2 = (MYLISTEL *)lParam2;
  2824. return pel1->nType - pel2->nType;
  2825. }
  2826. void CBrowserPP::OnArrangeByname()
  2827. {
  2828. ListView_SortItems(m_hList, CompareName, 0);
  2829. }
  2830. void CBrowserPP::OnArrangeBytype()
  2831. {
  2832. ListView_SortItems(m_hList, CompareType, 0);
  2833. }
  2834. void CBrowserPP::OnDelete()
  2835. {
  2836. DeleteGPO();
  2837. }
  2838. void CBrowserPP::OnEdit()
  2839. {
  2840. INT i;
  2841. HRESULT hr;
  2842. LVITEM item;
  2843. MYLISTEL * pel;
  2844. LPTSTR lpDomainName;
  2845. LPOLESTR pszDomain;
  2846. i = ListView_GetNextItem(m_hList, -1, LVNI_SELECTED);
  2847. if (i >= 0)
  2848. {
  2849. memset(&item, 0, sizeof(item));
  2850. item.mask = LVIF_PARAM;
  2851. item.iItem = i;
  2852. ListView_GetItem(m_hList, &item);
  2853. pel = (MYLISTEL *)item.lParam;
  2854. if (pel->nType == ITEMTYPE_GPO)
  2855. {
  2856. //
  2857. // Get the friendly domain name
  2858. //
  2859. pszDomain = GetDomainFromLDAPPath(pel->szData);
  2860. if (!pszDomain)
  2861. {
  2862. DebugMsg((DM_WARNING, TEXT("CBrowserPP::OnEdit: Failed to get domain name")));
  2863. return;
  2864. }
  2865. //
  2866. // Convert LDAP to dot (DN) style
  2867. //
  2868. hr = ConvertToDotStyle (pszDomain, &lpDomainName);
  2869. delete [] pszDomain;
  2870. if (FAILED(hr))
  2871. {
  2872. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreatePropertyPages: Failed to convert domain name with 0x%x"), hr));
  2873. return;
  2874. }
  2875. //
  2876. // Check if the GPO is in the same domain as GPM is focused on
  2877. //
  2878. if (!lstrcmpi(lpDomainName, m_szDomainName))
  2879. {
  2880. SpawnGPE (pel->szData, GPHintUnknown, m_szServerName, m_hwndDlg);
  2881. }
  2882. else
  2883. {
  2884. SpawnGPE (pel->szData, GPHintUnknown, NULL, m_hwndDlg);
  2885. }
  2886. LocalFree (lpDomainName);
  2887. }
  2888. }
  2889. }
  2890. void CBrowserPP::OnNew()
  2891. {
  2892. DoNewGPO();
  2893. }
  2894. void CBrowserPP::OnProperties()
  2895. {
  2896. INT iIndex;
  2897. LVITEM item;
  2898. HRESULT hr;
  2899. LPGROUPPOLICYOBJECT pGPO;
  2900. HPROPSHEETPAGE *hPages;
  2901. UINT i, uPageCount;
  2902. PROPSHEETHEADER psh;
  2903. iIndex = ListView_GetNextItem(m_hList, -1, LVNI_ALL | LVNI_SELECTED);
  2904. if (iIndex >= 0)
  2905. {
  2906. memset(&item, 0, sizeof(item));
  2907. item.mask = LVIF_PARAM;
  2908. item.iItem = iIndex;
  2909. ListView_GetItem(m_hList, &item);
  2910. MYLISTEL * pel = (MYLISTEL *)item.lParam;
  2911. if (pel && pel->nType == ITEMTYPE_GPO)
  2912. {
  2913. hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL,
  2914. CLSCTX_SERVER, IID_IGroupPolicyObject,
  2915. (void**)&pGPO);
  2916. if (FAILED(hr))
  2917. {
  2918. DebugMsg((DM_WARNING, TEXT("CBrowserPP::OnProperties: CoCreateInstance failed with 0x%x\r\n"), hr));
  2919. return;
  2920. }
  2921. //
  2922. // Open the requested object without mounting the registry
  2923. //
  2924. hr = pGPO->OpenDSGPO(pel->szData, 0);
  2925. if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  2926. {
  2927. hr = pGPO->OpenDSGPO(pel->szData, GPO_OPEN_READ_ONLY);
  2928. }
  2929. if (FAILED(hr))
  2930. {
  2931. DebugMsg((DM_WARNING, TEXT("CBrowserPP::OnProperties: Failed to open GPO object with 0x%x\r\n"), hr));
  2932. ReportError(m_hwndDlg, hr, IDS_FAILEDDS);
  2933. return;
  2934. }
  2935. //
  2936. // Ask the GPO for the property sheet pages
  2937. //
  2938. hr = pGPO->GetPropertySheetPages (&hPages, &uPageCount);
  2939. if (FAILED(hr))
  2940. {
  2941. DebugMsg((DM_WARNING, TEXT("CBrowserPP::OnProperties: Failed to query property sheet pages with 0x%x."), hr));
  2942. pGPO->Release();
  2943. return;
  2944. }
  2945. //
  2946. // Display the property sheet
  2947. //
  2948. ZeroMemory (&psh, sizeof(psh));
  2949. psh.dwSize = sizeof(psh);
  2950. psh.dwFlags = PSH_PROPTITLE;
  2951. psh.hwndParent = m_hwndDlg;
  2952. psh.hInstance = g_hInstance;
  2953. psh.pszCaption = pel->szName;
  2954. psh.nPages = uPageCount;
  2955. psh.phpage = hPages;
  2956. PropertySheet (&psh);
  2957. LocalFree (hPages);
  2958. pGPO->Release();
  2959. }
  2960. }
  2961. }
  2962. void CBrowserPP::OnRefresh()
  2963. {
  2964. switch (m_dwPageType)
  2965. {
  2966. case PAGETYPE_DOMAINS:
  2967. RefreshDomains();
  2968. break;
  2969. case PAGETYPE_SITES:
  2970. RefreshSites();
  2971. break;
  2972. default:
  2973. case PAGETYPE_ALL:
  2974. RefreshAll();
  2975. break;
  2976. }
  2977. SetButtonState();
  2978. }
  2979. void CBrowserPP::OnRename()
  2980. {
  2981. //
  2982. // alow the rename only if it is possible to rename
  2983. //
  2984. int i = ListView_GetNextItem(m_hList, -1, LVNI_SELECTED);
  2985. if (i >= 0)
  2986. {
  2987. // item selected
  2988. // figure out what type it is
  2989. LVITEM item;
  2990. memset(&item, 0, sizeof(item));
  2991. item.mask = LVIF_PARAM;
  2992. item.iItem = i;
  2993. ListView_GetItem(m_hList, &item);
  2994. MYLISTEL * pel = (MYLISTEL *)item.lParam;
  2995. if ((pel) && (pel->nType == ITEMTYPE_GPO)
  2996. && (!(pel->bDisabled))) {
  2997. ListView_EditLabel(m_hList, ListView_GetNextItem(m_hList, -1, LVNI_SELECTED));
  2998. }
  2999. }
  3000. }
  3001. void CBrowserPP::OnTopLineupicons()
  3002. {
  3003. ListView_Arrange(m_hList, LVA_SNAPTOGRID);
  3004. }
  3005. void CBrowserPP::OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
  3006. {
  3007. LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
  3008. // Return FALSE to enable editing, TRUE to disable it
  3009. MYLISTEL * pel = (MYLISTEL *)pDispInfo->item.lParam;
  3010. *pResult = (pel->nType == ITEMTYPE_GPO) ? FALSE : TRUE;
  3011. }
  3012. void CBrowserPP::OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
  3013. {
  3014. *pResult = FALSE;
  3015. LPGROUPPOLICYOBJECT pGPO = NULL;
  3016. HRESULT hr;
  3017. LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
  3018. if (NULL == pDispInfo->item.pszText)
  3019. {
  3020. // user cancelled edit
  3021. return;
  3022. }
  3023. if (TEXT('\0') == (*pDispInfo->item.pszText))
  3024. {
  3025. // user entered an empty string
  3026. return;
  3027. }
  3028. MYLISTEL * pel = (MYLISTEL *)pDispInfo->item.lParam;
  3029. if (0 ==wcscmp(pDispInfo->item.pszText, pel->szName))
  3030. {
  3031. // user didn't change anything
  3032. return;
  3033. }
  3034. LPWSTR sz = new WCHAR[wcslen(pDispInfo->item.pszText)+1];
  3035. if (NULL == sz)
  3036. {
  3037. *pResult = FALSE;
  3038. goto Done;
  3039. return;
  3040. }
  3041. hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL,
  3042. CLSCTX_SERVER, IID_IGroupPolicyObject,
  3043. (void **)&pGPO);
  3044. if (FAILED(hr))
  3045. {
  3046. DebugMsg((DM_WARNING, TEXT("CoCreateInstance failed with 0x%x\r\n"), hr));
  3047. goto Done;
  3048. }
  3049. // open GPO object without opening registry data
  3050. hr = pGPO->OpenDSGPO(pel->szData, 0);
  3051. if (FAILED(hr))
  3052. {
  3053. ReportError(m_hwndDlg, hr, IDS_FAILEDDS);
  3054. DebugMsg((DM_WARNING, TEXT("OpenDSGPO failed with 0x%x\r\n"), hr));
  3055. goto Done;
  3056. }
  3057. // rename it
  3058. hr = pGPO->SetDisplayName(pDispInfo->item.pszText);
  3059. if (FAILED(hr))
  3060. {
  3061. ReportError(m_hwndDlg, hr, IDS_FAILEDSETNAME);
  3062. DebugMsg((DM_WARNING, TEXT("SetDisplayName failed with 0x%x\r\n"), hr));
  3063. goto Done;
  3064. }
  3065. // requery for the name
  3066. hr = pGPO->GetDisplayName(sz, (wcslen(pDispInfo->item.pszText)+1));
  3067. if (FAILED(hr))
  3068. {
  3069. ReportError(m_hwndDlg, hr, IDS_FAILEDSETNAME);
  3070. DebugMsg((DM_WARNING, TEXT("GetDisplayName failed with 0x%x\r\n"), hr));
  3071. goto Done;
  3072. }
  3073. delete [] pel->szName;
  3074. pel->szName = sz;
  3075. sz = NULL;
  3076. // return TRUE to accept the rename, FALSE to reject it
  3077. *pResult = TRUE;
  3078. PostMessage (m_hwndDlg, WM_REFRESHDISPLAY, (WPARAM) pDispInfo->item.iItem, 0);
  3079. Done:
  3080. if (sz)
  3081. {
  3082. delete [] sz;
  3083. }
  3084. if (pGPO)
  3085. {
  3086. pGPO->Release();
  3087. }
  3088. }
  3089. void CBrowserPP::OnBegindragList(NMHDR* pNMHDR, LRESULT* pResult)
  3090. {
  3091. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  3092. *pResult = 0;
  3093. }
  3094. void CBrowserPP::OnDeleteitemList(NMHDR* pNMHDR, LRESULT* pResult)
  3095. {
  3096. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  3097. MYLISTEL * pel = (MYLISTEL *)pNMListView->lParam;
  3098. if (pel)
  3099. {
  3100. if (pel->szName)
  3101. {
  3102. delete [] pel->szName;
  3103. }
  3104. if (pel->szData)
  3105. {
  3106. delete [] pel->szData;
  3107. }
  3108. delete pel;
  3109. }
  3110. *pResult = 0;
  3111. }
  3112. void CBrowserPP::OnDoubleclickList(NMHDR* pNMHDR, LRESULT* pResult)
  3113. {
  3114. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  3115. if (pNMListView->iItem >= 0)
  3116. {
  3117. // item selected
  3118. PropSheet_PressButton(GetParent(m_hwndDlg), PSBTN_OK);
  3119. }
  3120. *pResult = 0;
  3121. }
  3122. void CBrowserPP::OnColumnclickList(NMHDR* pNMHDR, LRESULT* pResult)
  3123. {
  3124. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  3125. switch (pNMListView->iSubItem)
  3126. {
  3127. case 0:
  3128. ListView_SortItems(m_hList, CompareName, 0);
  3129. break;
  3130. case 1:
  3131. default:
  3132. ListView_SortItems(m_hList, CompareType, 0);
  3133. break;
  3134. }
  3135. *pResult = 0;
  3136. }
  3137. void CBrowserPP::OnKeyDownList(NMHDR * pNMHDR, LRESULT * pResult)
  3138. {
  3139. LV_KEYDOWN * pnkd = (LV_KEYDOWN *)pNMHDR;
  3140. switch (pnkd->wVKey)
  3141. {
  3142. case VK_F5:
  3143. OnRefresh();
  3144. break;
  3145. case VK_F2:
  3146. OnRename();
  3147. break;
  3148. case VK_DELETE:
  3149. OnDelete();
  3150. break;
  3151. case VK_BACK:
  3152. DoBackButton();
  3153. break;
  3154. case VK_RETURN:
  3155. OnProperties();
  3156. break;
  3157. default:
  3158. break;
  3159. }
  3160. }
  3161. void CBrowserPP::OnItemChanged(NMHDR * pNMHDR, LRESULT * pResult)
  3162. {
  3163. SetButtonState();
  3164. }
  3165. void CBrowserPP::TrimComboBox()
  3166. {
  3167. LOOKDATA * pdataSelected = NULL;
  3168. int iCount;
  3169. // first check to see if something is selected
  3170. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  3171. if (iIndex != CB_ERR)
  3172. {
  3173. // something's selected, get a pointer to it's data
  3174. pdataSelected = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  3175. // check if the user selected the same thing again
  3176. if (m_pPrevSel && (m_pPrevSel == pdataSelected))
  3177. {
  3178. return;
  3179. }
  3180. // if it has a parent then enable the back button
  3181. SendMessage(m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_BACKBUTTON, (LPARAM)MAKELONG(NULL != pdataSelected->pParent, 0));
  3182. }
  3183. // If the child of the selected object is an OU then delete all of it's children
  3184. // otherwise delete ALL OUs from the list.
  3185. if (pdataSelected)
  3186. {
  3187. if (pdataSelected->pChild)
  3188. {
  3189. if (ITEMTYPE_OU == pdataSelected->pChild->nType)
  3190. {
  3191. // delete all of its children
  3192. goto DeleteChildren;
  3193. }
  3194. }
  3195. }
  3196. iCount = (int)SendMessage(m_hCombo, CB_GETCOUNT, 0, 0);
  3197. iIndex = 0;
  3198. while (iIndex < iCount)
  3199. {
  3200. // find the first entry that has an OU for a child.
  3201. pdataSelected = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  3202. if (pdataSelected)
  3203. {
  3204. if (pdataSelected->pChild)
  3205. {
  3206. if (ITEMTYPE_OU == pdataSelected->pChild->nType)
  3207. {
  3208. DeleteChildren:
  3209. LOOKDATA * pChild = pdataSelected->pChild;
  3210. pdataSelected->pChild = pChild->pSibling;
  3211. while (pChild)
  3212. {
  3213. iIndex = (int)SendMessage(m_hCombo, CB_FINDSTRING, iIndex, (LPARAM)(LPCTSTR*)pChild);
  3214. if (iIndex != CB_ERR)
  3215. {
  3216. pChild = pChild->pChild;
  3217. SendMessage(m_hCombo, CB_DELETESTRING, iIndex, 0);
  3218. }
  3219. else
  3220. {
  3221. pChild = NULL;
  3222. }
  3223. }
  3224. return;
  3225. }
  3226. }
  3227. }
  3228. iIndex++;
  3229. }
  3230. }
  3231. void CBrowserPP::OnComboChange()
  3232. {
  3233. switch (m_dwPageType)
  3234. {
  3235. case PAGETYPE_DOMAINS:
  3236. {
  3237. TrimComboBox();
  3238. }
  3239. // fall through to refresh the list view
  3240. case PAGETYPE_SITES:
  3241. case PAGETYPE_ALL:
  3242. default:
  3243. OnRefresh();
  3244. break;
  3245. }
  3246. }
  3247. BOOL CBrowserPP::OnSetActive()
  3248. {
  3249. *m_ppActive = this;
  3250. OnRefresh();
  3251. return TRUE;
  3252. }
  3253. BOOL CBrowserPP::OnApply()
  3254. {
  3255. if (*m_ppActive == (void *) this)
  3256. {
  3257. // perform the proper task on the selected item
  3258. int i = ListView_GetNextItem(m_hList, -1, LVNI_SELECTED);
  3259. if (i >= 0)
  3260. {
  3261. LVITEM item;
  3262. memset(&item, 0, sizeof(item));
  3263. item.mask = LVIF_PARAM;
  3264. item.iItem = i;
  3265. ListView_GetItem(m_hList, &item);
  3266. MYLISTEL * pel = (MYLISTEL *)item.lParam;
  3267. switch (pel->nType)
  3268. {
  3269. case ITEMTYPE_GPO:
  3270. m_pGBI->gpoType = GPOTypeDS;
  3271. wcsncpy(m_pGBI->lpDSPath, pel->szData, m_pGBI->dwDSPathSize);
  3272. if (m_pGBI->lpName)
  3273. {
  3274. wcsncpy(m_pGBI->lpName, pel->szName, m_pGBI->dwNameSize);
  3275. }
  3276. m_pGBI->gpoHint = GPHintUnknown;
  3277. break;
  3278. default:
  3279. case ITEMTYPE_FOREST:
  3280. case ITEMTYPE_SITE:
  3281. case ITEMTYPE_DOMAIN:
  3282. // change the focus
  3283. {
  3284. LOOKDATA * pdataSelected = NULL;
  3285. // first make sure something is selected
  3286. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  3287. if (iIndex != CB_ERR)
  3288. {
  3289. // something's selected, get a pointer to it's data
  3290. pdataSelected = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  3291. if (pdataSelected)
  3292. {
  3293. // Now walk its children until we find a match
  3294. pdataSelected = pdataSelected->pChild;
  3295. while (pdataSelected)
  3296. {
  3297. if (0 == wcscmp(pdataSelected->szData, pel->szData))
  3298. {
  3299. iIndex = (int)SendMessage(m_hCombo, CB_FINDSTRING, iIndex, (LPARAM) (LPCTSTR)pdataSelected);
  3300. if (iIndex != CB_ERR)
  3301. {
  3302. SendMessage(m_hCombo, CB_SETCURSEL, iIndex, 0);
  3303. // Enable the back-button
  3304. SendMessage(m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_BACKBUTTON, (LPARAM) MAKELONG(TRUE, 0));
  3305. }
  3306. break;
  3307. }
  3308. pdataSelected = pdataSelected->pSibling;
  3309. }
  3310. }
  3311. }
  3312. }
  3313. OnRefresh();
  3314. return FALSE; // don't allow propsheet to close
  3315. case ITEMTYPE_OU:
  3316. // Add the new object to combobox and change the focus.
  3317. {
  3318. LOOKDATA * pdataSelected = NULL;
  3319. // first make sure something is selected
  3320. int iIndex = (int)SendMessage (m_hCombo, CB_GETCURSEL, 0, 0);
  3321. if (iIndex != CB_ERR)
  3322. {
  3323. // something's selected, get a pointer to it's data
  3324. pdataSelected = (LOOKDATA *) SendMessage (m_hCombo, CB_GETITEMDATA, iIndex, 0);
  3325. if (pdataSelected)
  3326. {
  3327. LOOKDATA * pNew = new LOOKDATA;
  3328. if (pNew)
  3329. {
  3330. ULONG ulNoCharsName = wcslen(pel->szName)+1;
  3331. pNew->szName = new WCHAR[ulNoCharsName];
  3332. if (pNew->szName)
  3333. {
  3334. ULONG ulNoCharsData = wcslen(pel->szData)+1;
  3335. pNew->szData = new WCHAR[ulNoCharsData];
  3336. if (pNew->szData)
  3337. {
  3338. HRESULT hr;
  3339. hr = StringCchCopy(pNew->szName, ulNoCharsName, pel->szName);
  3340. ASSERT(SUCCEEDED(hr));
  3341. hr = StringCchCopy(pNew->szData, ulNoCharsData, pel->szData);
  3342. ASSERT(SUCCEEDED(hr));
  3343. pNew->nIndent = pdataSelected->nIndent + 1;
  3344. pNew->nType = ITEMTYPE_OU;
  3345. pNew->pParent = pdataSelected;
  3346. pNew->pSibling = pdataSelected->pChild;
  3347. pNew->pChild = NULL;
  3348. pdataSelected ->pChild = pNew;
  3349. SendMessage(m_hCombo, CB_INSERTSTRING, (WPARAM) iIndex + 1, (LPARAM) (LPCTSTR) pNew);
  3350. SendMessage(m_hCombo, CB_SETCURSEL, iIndex + 1, 0);
  3351. // Enable the back-button
  3352. SendMessage(m_toolbar, TB_ENABLEBUTTON, (WPARAM) ID_BACKBUTTON, (LPARAM) MAKELONG(TRUE, 0));
  3353. }
  3354. else
  3355. {
  3356. delete [] pNew->szName;
  3357. delete pNew;
  3358. }
  3359. }
  3360. else
  3361. {
  3362. delete pNew;
  3363. }
  3364. }
  3365. }
  3366. }
  3367. }
  3368. OnRefresh();
  3369. return FALSE; // don't allow propsheet to close
  3370. }
  3371. return TRUE;
  3372. }
  3373. else
  3374. return FALSE; // don't allow propsheet to close
  3375. }
  3376. return TRUE;
  3377. }
  3378. BOOL CBrowserPP::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3379. {
  3380. BOOL fReturn = FALSE;
  3381. m_hwndDlg = hwndDlg;
  3382. switch (uMsg)
  3383. {
  3384. case WM_INITDIALOG:
  3385. {
  3386. return OnInitDialog();
  3387. }
  3388. break;
  3389. case WM_NOTIFY:
  3390. {
  3391. LPNMHDR pnmh = (LPNMHDR) lParam;
  3392. LRESULT lResult = 0;
  3393. switch (pnmh->code)
  3394. {
  3395. case NM_KEYDOWN:
  3396. {
  3397. LPNMKEY pnkd = (LPNMKEY)pnmh;
  3398. if (VK_F5 == pnkd->nVKey)
  3399. {
  3400. OnRefresh();
  3401. }
  3402. }
  3403. break;
  3404. case PSN_SETACTIVE:
  3405. OnSetActive();
  3406. break;
  3407. case PSN_APPLY:
  3408. lResult = OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
  3409. fReturn = TRUE;
  3410. break;
  3411. case NM_DBLCLK:
  3412. if (IDC_LIST1 == wParam)
  3413. {
  3414. OnDoubleclickList(pnmh, &lResult);
  3415. fReturn = TRUE;
  3416. }
  3417. break;
  3418. case LVN_BEGINLABELEDIT:
  3419. OnBeginlabeleditList(pnmh, &lResult);
  3420. fReturn = TRUE;
  3421. break;
  3422. case LVN_ENDLABELEDIT:
  3423. OnEndlabeleditList(pnmh, &lResult);
  3424. fReturn = TRUE;
  3425. break;
  3426. case LVN_BEGINDRAG:
  3427. OnBegindragList(pnmh, &lResult);
  3428. fReturn = TRUE;
  3429. break;
  3430. case LVN_DELETEITEM:
  3431. OnDeleteitemList(pnmh, &lResult);
  3432. fReturn = TRUE;
  3433. break;
  3434. case LVN_COLUMNCLICK:
  3435. OnColumnclickList(pnmh, &lResult);
  3436. fReturn = TRUE;
  3437. break;
  3438. case LVN_KEYDOWN:
  3439. OnKeyDownList(pnmh, &lResult);
  3440. break;
  3441. case LVN_ITEMCHANGED:
  3442. OnItemChanged(pnmh, &lResult);
  3443. break;
  3444. case TBN_DROPDOWN:
  3445. {
  3446. RECT r;
  3447. SendMessage(m_toolbar, TB_GETRECT, ((TBNOTIFY *)lParam)->iItem, (LPARAM)&r);
  3448. MapWindowPoints(m_toolbar, NULL, (POINT *)&r, 2);
  3449. HMENU hPopup;
  3450. hPopup = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_LISTMENU));
  3451. if ( ! hPopup )
  3452. {
  3453. break;
  3454. }
  3455. UINT ui = ID_LIST;
  3456. DWORD dw = GetWindowLong(m_hList, GWL_STYLE) & LVS_TYPEMASK;
  3457. switch (dw)
  3458. {
  3459. case LVS_ICON:
  3460. ui = ID_LARGEICONS;
  3461. break;
  3462. case LVS_SMALLICON:
  3463. ui = ID_SMALLICONS;
  3464. break;
  3465. case LVS_REPORT:
  3466. ui = ID_DETAILS;
  3467. break;
  3468. case LVS_LIST:
  3469. default:
  3470. ui = ID_LIST;
  3471. break;
  3472. }
  3473. HMENU hSubMenu = GetSubMenu(GetSubMenu(hPopup, 0), 0);
  3474. CheckMenuRadioItem(hSubMenu, ui, ui, ui, MF_BYCOMMAND);
  3475. TrackPopupMenu(hSubMenu,
  3476. TPM_LEFTALIGN,
  3477. r.left, r.bottom,
  3478. 0,
  3479. m_hwndDlg,
  3480. &r);
  3481. fReturn = TRUE;
  3482. DestroyMenu(hPopup);
  3483. break;
  3484. }
  3485. break;
  3486. case TTN_GETDISPINFO:
  3487. {
  3488. LPNMTTDISPINFO pDI = (LPNMTTDISPINFO) lParam;
  3489. UINT id = 0;
  3490. if (pDI->hdr.idFrom == ID_BACKBUTTON)
  3491. id = IDS_TOOLTIP_BACK;
  3492. else if (pDI->hdr.idFrom == ID_NEWFOLDER)
  3493. id = IDS_TOOLTIP_NEW;
  3494. else if (pDI->hdr.idFrom == ID_ROTATEVIEW)
  3495. id = IDS_TOOLTIP_ROTATE;
  3496. if (id)
  3497. LoadString (g_hInstance, id, pDI->szText, 80);
  3498. else
  3499. pDI->szText[0] = TEXT('\0');
  3500. fReturn = TRUE;
  3501. }
  3502. break;
  3503. default:
  3504. break;
  3505. }
  3506. SetWindowLongPtr(m_hwndDlg, DWLP_MSGRESULT, lResult);
  3507. }
  3508. break;
  3509. case WM_COMMAND:
  3510. switch (LOWORD(wParam))
  3511. {
  3512. case IDC_COMBO1:
  3513. if (CBN_SELCHANGE == HIWORD(wParam))
  3514. {
  3515. OnComboChange();
  3516. }
  3517. break;
  3518. case ID_BACKBUTTON:
  3519. return DoBackButton();
  3520. case ID_NEWFOLDER:
  3521. return DoNewGPO();
  3522. case ID_ROTATEVIEW:
  3523. return DoRotateView();
  3524. case ID_DETAILS:
  3525. OnDetails();
  3526. fReturn = TRUE;
  3527. break;
  3528. case ID_LIST:
  3529. OnList();
  3530. fReturn = TRUE;
  3531. break;
  3532. case ID_LARGEICONS:
  3533. OnLargeicons();
  3534. fReturn = TRUE;
  3535. break;
  3536. case ID_SMALLICONS:
  3537. OnSmallicons();
  3538. fReturn = TRUE;
  3539. break;
  3540. case ID_ARRANGE_AUTO:
  3541. OnArrangeAuto();
  3542. fReturn = TRUE;
  3543. break;
  3544. case ID_ARRANGE_BYNAME:
  3545. OnArrangeByname();
  3546. fReturn = TRUE;
  3547. break;
  3548. case ID_ARRANGE_BYTYPE:
  3549. OnArrangeBytype();
  3550. fReturn = TRUE;
  3551. break;
  3552. case ID_DELETE:
  3553. OnDelete();
  3554. fReturn = TRUE;
  3555. break;
  3556. case ID_EDIT:
  3557. OnEdit();
  3558. fReturn = TRUE;
  3559. break;
  3560. case ID_NEW:
  3561. OnNew();
  3562. fReturn = TRUE;
  3563. break;
  3564. case ID_PROPERTIES:
  3565. OnProperties();
  3566. fReturn = TRUE;
  3567. break;
  3568. case ID_REFRESH:
  3569. OnRefresh();
  3570. fReturn = TRUE;
  3571. break;
  3572. case ID_RENAME:
  3573. OnRename();
  3574. fReturn = TRUE;
  3575. break;
  3576. case ID_TOP_LINEUPICONS:
  3577. OnTopLineupicons();
  3578. fReturn = TRUE;
  3579. break;
  3580. default:
  3581. break;
  3582. }
  3583. break;
  3584. case WM_CONTEXTMENU:
  3585. fReturn = TRUE;
  3586. if ((HWND)wParam != m_toolbar)
  3587. {
  3588. if (GetDlgItem(hwndDlg, IDC_LIST1) == (HWND)wParam)
  3589. {
  3590. OnContextMenu(lParam);
  3591. }
  3592. else
  3593. {
  3594. // right mouse click
  3595. switch (m_dwPageType)
  3596. {
  3597. case PAGETYPE_DOMAINS:
  3598. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  3599. (ULONG_PTR) (LPSTR) aBrowserDomainHelpIds);
  3600. break;
  3601. case PAGETYPE_SITES:
  3602. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  3603. (ULONG_PTR) (LPSTR) aBrowserSiteHelpIds);
  3604. break;
  3605. case PAGETYPE_ALL:
  3606. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  3607. (ULONG_PTR) (LPSTR) aBrowserAllHelpIds);
  3608. break;
  3609. }
  3610. }
  3611. }
  3612. break;
  3613. case WM_HELP:
  3614. // F1 help
  3615. if (((LPHELPINFO) lParam)->iCtrlId != IDR_TOOLBAR1)
  3616. {
  3617. switch (m_dwPageType)
  3618. {
  3619. case PAGETYPE_DOMAINS:
  3620. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  3621. (ULONG_PTR) (LPSTR) aBrowserDomainHelpIds);
  3622. break;
  3623. case PAGETYPE_SITES:
  3624. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  3625. (ULONG_PTR) (LPSTR) aBrowserSiteHelpIds);
  3626. break;
  3627. case PAGETYPE_ALL:
  3628. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  3629. (ULONG_PTR) (LPSTR) aBrowserAllHelpIds);
  3630. break;
  3631. }
  3632. }
  3633. fReturn = TRUE;
  3634. break;
  3635. case WM_DRAWITEM:
  3636. if (IDC_COMBO1 == wParam)
  3637. {
  3638. DrawItem((LPDRAWITEMSTRUCT)lParam);
  3639. fReturn = TRUE;
  3640. }
  3641. break;
  3642. case WM_MEASUREITEM:
  3643. if (IDC_COMBO1 == wParam)
  3644. {
  3645. MeasureItem((LPMEASUREITEMSTRUCT)lParam);
  3646. fReturn = TRUE;
  3647. }
  3648. break;
  3649. case WM_COMPAREITEM:
  3650. if (IDC_COMBO1 == wParam)
  3651. {
  3652. int iReturn = CompareItem((LPCOMPAREITEMSTRUCT)lParam);
  3653. SetWindowLongPtr(m_hwndDlg, DWLP_MSGRESULT, iReturn);
  3654. fReturn = TRUE;
  3655. }
  3656. break;
  3657. case WM_DELETEITEM:
  3658. if (IDC_COMBO1 == wParam)
  3659. {
  3660. DeleteItem((LPDELETEITEMSTRUCT)lParam);
  3661. fReturn = TRUE;
  3662. }
  3663. break;
  3664. case WM_REFRESHDISPLAY:
  3665. {
  3666. MYLISTEL * pel;
  3667. LVITEM item;
  3668. ZeroMemory (&item, sizeof(item));
  3669. item.mask = LVIF_PARAM;
  3670. item.iItem = (INT) wParam;
  3671. if (ListView_GetItem(m_hList, &item))
  3672. {
  3673. pel = (MYLISTEL *)item.lParam;
  3674. ListView_SetItemText(m_hList, (INT)wParam, 0, pel->szName);
  3675. }
  3676. }
  3677. break;
  3678. default:
  3679. break;
  3680. }
  3681. return fReturn;
  3682. }
  3683. void CBrowserPP::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  3684. {
  3685. // DRAWITEMSTRUCT:
  3686. // UINT CtlType // type of the control
  3687. // UINT CtlID; // ID of the control
  3688. // UINT itemID; // index of the item
  3689. // UINT itemAction;
  3690. // UINT itemState;
  3691. // HWND hwndItem;
  3692. // HDC hDC;
  3693. // RECT rcItem;
  3694. // DWORD itemData; // user-defined data
  3695. if (-1 != lpDrawItemStruct->itemID)
  3696. {
  3697. LOOKDATA * pdata = (LOOKDATA *)lpDrawItemStruct->itemData;
  3698. POINT pt;
  3699. INT iIndex;
  3700. if (pdata->nType == ITEMTYPE_FOREST)
  3701. {
  3702. iIndex = 10;
  3703. }
  3704. else if (pdata->nType == ITEMTYPE_SITE)
  3705. {
  3706. iIndex = 6;
  3707. }
  3708. else if (pdata->nType == ITEMTYPE_DOMAIN)
  3709. {
  3710. iIndex = 7;
  3711. }
  3712. else
  3713. {
  3714. iIndex = 0;
  3715. }
  3716. pt.x = lpDrawItemStruct->rcItem.left;
  3717. BOOL fSelected = ODS_SELECTED == (ODS_SELECTED & lpDrawItemStruct->itemState);
  3718. BOOL fComboBoxEdit = ODS_COMBOBOXEDIT != (ODS_COMBOBOXEDIT & lpDrawItemStruct->itemState);
  3719. if (fComboBoxEdit)
  3720. pt.x += (INDENT * pdata->nIndent);
  3721. pt.y = lpDrawItemStruct->rcItem.top;
  3722. ImageList_Draw(m_ilSmall, iIndex, lpDrawItemStruct->hDC, pt.x, pt.y, fSelected ? ILD_SELECTED : ILD_NORMAL);
  3723. SIZE size;
  3724. GetTextExtentPoint32(lpDrawItemStruct->hDC, pdata->szName, wcslen(pdata->szName), &size);
  3725. COLORREF crBk;
  3726. COLORREF crText;
  3727. if (fSelected)
  3728. {
  3729. crBk = GetBkColor(lpDrawItemStruct->hDC);
  3730. crText = GetTextColor(lpDrawItemStruct->hDC);
  3731. SetBkColor(lpDrawItemStruct->hDC, GetSysColor(COLOR_HIGHLIGHT));
  3732. SetTextColor(lpDrawItemStruct->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  3733. }
  3734. // NOTE, SMALLICONSIZE + 1 is used here to ensure it rounds UP
  3735. // instead of down when centering the text. (It looks better this
  3736. // way.)
  3737. // Adding 18 to the x coord spaces us past the icon.
  3738. ExtTextOut(lpDrawItemStruct->hDC, pt.x + (SMALLICONSIZE + 2), pt.y + (((SMALLICONSIZE + 1) - size.cy) / 2), ETO_CLIPPED, &lpDrawItemStruct->rcItem, pdata->szName, wcslen(pdata->szName), NULL);
  3739. if (fSelected)
  3740. {
  3741. SetBkColor(lpDrawItemStruct->hDC, crBk);
  3742. SetTextColor(lpDrawItemStruct->hDC, crText);
  3743. }
  3744. }
  3745. }
  3746. void CBrowserPP::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  3747. {
  3748. // MEASUREITEMSTRUCT:
  3749. // UINT CtlType // type of the control
  3750. // UINT CtlID; // ID of the control
  3751. // UINT itemID; // index of the item
  3752. // UINT itemWidth; // width of item in pixels
  3753. // UINT itemHeight; // height of item in pixels
  3754. // DWORD itemData; // user-defined data
  3755. lpMeasureItemStruct->itemHeight = SMALLICONSIZE;
  3756. }
  3757. int CBrowserPP::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
  3758. {
  3759. // COMPAREITEMSTRUCT:
  3760. // UINT CtlType // type of the control
  3761. // UINT CtlID; // ID of the control
  3762. // HWND hwndItem; // handle of the control
  3763. // UINT itemID; // index of the item
  3764. // DWORD itemData1; // user-defined data
  3765. // UINT itemID2; // index of the second item
  3766. // DWORD itemData2; // user-defined data
  3767. // I'm not doing any sorting.
  3768. return 0;
  3769. }
  3770. void CBrowserPP::DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct)
  3771. {
  3772. LOOKDATA * pdata = (LOOKDATA *)lpDeleteItemStruct->itemData;
  3773. if (NULL != pdata)
  3774. {
  3775. if (NULL != pdata->szName)
  3776. {
  3777. delete [] pdata->szName;
  3778. }
  3779. if (NULL != pdata->szData)
  3780. {
  3781. delete [] pdata->szData;
  3782. }
  3783. delete pdata;
  3784. }
  3785. }
  3786. LPTSTR CBrowserPP::GetFullPath (LPTSTR lpPath, HWND hParent)
  3787. {
  3788. LPTSTR lpFullPath = NULL, lpDomainName = NULL;
  3789. LPTSTR lpGPDCName;
  3790. LPOLESTR pszDomain;
  3791. HRESULT hr;
  3792. //
  3793. // Get the friendly domain name
  3794. //
  3795. pszDomain = GetDomainFromLDAPPath(lpPath);
  3796. if (!pszDomain)
  3797. {
  3798. DebugMsg((DM_WARNING, TEXT("CBrowserPP::GetFullPath: Failed to get domain name")));
  3799. return NULL;
  3800. }
  3801. //
  3802. // Convert LDAP to dot (DN) style
  3803. //
  3804. hr = ConvertToDotStyle (pszDomain, &lpDomainName);
  3805. delete [] pszDomain;
  3806. if (FAILED(hr))
  3807. {
  3808. DebugMsg((DM_WARNING, TEXT("CBrowserPP::GetFullPath: Failed to convert domain name with 0x%x"), hr));
  3809. return NULL;
  3810. }
  3811. if (!lstrcmpi(lpDomainName, m_szDomainName))
  3812. {
  3813. //
  3814. // Make the full path
  3815. //
  3816. lpFullPath = MakeFullPath (lpPath, m_szServerName);
  3817. if (!lpFullPath)
  3818. {
  3819. DebugMsg((DM_WARNING, TEXT("CBrowserPP::GetFullPath: Failed to build new DS object path")));
  3820. goto Exit;
  3821. }
  3822. }
  3823. else
  3824. {
  3825. //
  3826. // Get the GPO DC for this domain
  3827. //
  3828. lpGPDCName = GetDCName (lpDomainName, NULL, hParent, TRUE, 0);
  3829. if (!lpGPDCName)
  3830. {
  3831. DebugMsg((DM_WARNING, TEXT("CBrowserPP::GetFullPath: Failed to get DC name for %s"),
  3832. lpDomainName));
  3833. goto Exit;
  3834. }
  3835. //
  3836. // Make the full path
  3837. //
  3838. lpFullPath = MakeFullPath (lpPath, lpGPDCName);
  3839. LocalFree (lpGPDCName);
  3840. if (!lpFullPath)
  3841. {
  3842. DebugMsg((DM_WARNING, TEXT("CBrowserPP::GetFullPath: Failed to build new DS object path")));
  3843. goto Exit;
  3844. }
  3845. }
  3846. Exit:
  3847. if (lpDomainName)
  3848. {
  3849. LocalFree (lpDomainName);
  3850. }
  3851. return lpFullPath;
  3852. }