Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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