Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

439 lines
16 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: addupgrd.cpp
  7. //
  8. // Contents: add upgrade dialog
  9. //
  10. // Classes: CAddUpgrade
  11. //
  12. // History: 03-14-1998 stevebl Commented
  13. //
  14. //---------------------------------------------------------------------------
  15. #include "precomp.hxx"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CAddUpgrade dialog
  23. CAddUpgrade::CAddUpgrade(CWnd* pParent /*=NULL*/)
  24. : CDialog(CAddUpgrade::IDD, pParent)
  25. {
  26. //{{AFX_DATA_INIT(CAddUpgrade)
  27. m_iUpgradeType = 1; // default to rip-and-replace
  28. m_iSource = 0; // default to current container
  29. m_szGPOName = L"";
  30. //}}AFX_DATA_INIT
  31. m_fPopulated = FALSE;
  32. }
  33. void CAddUpgrade::DoDataExchange(CDataExchange* pDX)
  34. {
  35. CDialog::DoDataExchange(pDX);
  36. //{{AFX_DATA_MAP(CAddUpgrade)
  37. DDX_Radio(pDX, IDC_RADIO4, m_iUpgradeType);
  38. DDX_Radio(pDX, IDC_RADIO1, m_iSource);
  39. DDX_Text(pDX, IDC_EDIT1, m_szGPOName);
  40. //}}AFX_DATA_MAP
  41. }
  42. BEGIN_MESSAGE_MAP(CAddUpgrade, CDialog)
  43. //{{AFX_MSG_MAP(CAddUpgrade)
  44. ON_BN_CLICKED(IDC_RADIO1, OnCurrentContainer)
  45. ON_BN_CLICKED(IDC_RADIO2, OnOtherContainer)
  46. ON_BN_CLICKED(IDC_RADIO10, OnAllContainers)
  47. ON_BN_CLICKED(IDC_BUTTON1, OnBrowse)
  48. ON_LBN_DBLCLK(IDC_LIST1, OnOK)
  49. ON_WM_CONTEXTMENU()
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CAddUpgrade message handlers
  54. BOOL CAddUpgrade::OnInitDialog()
  55. {
  56. // If m_fPopulated is FALSE then populate the map with all packages in
  57. // this GPO container _EXCEPT_ the current app.
  58. if (!m_fPopulated)
  59. {
  60. OnCurrentContainer();
  61. m_szGPO = m_pScope->m_szGPO;
  62. m_fPopulated = TRUE;
  63. }
  64. else
  65. {
  66. // This will be done in OnCurrentContainer if m_fPopulated is FALSE
  67. RefreshList();
  68. }
  69. CDialog::OnInitDialog();
  70. return TRUE; // return TRUE unless you set the focus to a control
  71. // EXCEPTION: OCX Property Pages should return FALSE
  72. }
  73. void CAddUpgrade::RefreshList()
  74. {
  75. // For every element in the map, if it isn't already in the upgrade
  76. // list then add it to the list.
  77. CListBox * pList = (CListBox *)GetDlgItem(IDC_LIST1);
  78. pList->ResetContent();
  79. BOOL fEnable = FALSE;
  80. // add all elements that aren't already in the upgrade list
  81. map<CString, CUpgradeData>::iterator i;
  82. for (i = m_NameIndex.begin(); i != m_NameIndex.end(); i++)
  83. {
  84. if (m_pUpgradeList->end() == m_pUpgradeList->find(GetUpgradeIndex(i->second.m_PackageGuid)))
  85. {
  86. fEnable = TRUE;
  87. pList->AddString(i->first);
  88. CDC * pDC = pList->GetDC();
  89. CSize size = pDC->GetTextExtent(i->first);
  90. pDC->LPtoDP(&size);
  91. pList->ReleaseDC(pDC);
  92. if (pList->GetHorizontalExtent() < size.cx)
  93. {
  94. pList->SetHorizontalExtent(size.cx);
  95. }
  96. }
  97. }
  98. GetDlgItem(IDOK)->EnableWindow(fEnable);
  99. if (NULL == GetFocus())
  100. {
  101. GetDlgItem(IDCANCEL)->SetFocus();
  102. }
  103. pList->SetCurSel(0);
  104. }
  105. void CAddUpgrade::OnOK()
  106. {
  107. CListBox * pList = (CListBox *)GetDlgItem(IDC_LIST1);
  108. int iSel = pList->GetCurSel();
  109. if (iSel != LB_ERR)
  110. {
  111. // only allow the dialog to close with IDOK if a selection has been made
  112. CDialog::OnOK();
  113. // Do this part later to make sure that all data members are
  114. // refreshed (this happens as part of the OnOk processing)
  115. pList->GetText(iSel, m_szPackageName);
  116. m_UpgradeData = m_NameIndex[m_szPackageName];
  117. m_UpgradeData.m_flags = (m_iUpgradeType == 1) ? UPGFLG_Uninstall : UPGFLG_NoUninstall;
  118. }
  119. }
  120. void CAddUpgrade::OnCurrentContainer()
  121. {
  122. // Populate the map with all packages in this GPO container _EXCEPT_ the
  123. // current app.
  124. CString szClassStore;
  125. HRESULT hr = m_pScope->GetClassStoreName(szClassStore, FALSE);
  126. ASSERT(hr == S_OK);
  127. m_NameIndex.erase(m_NameIndex.begin(), m_NameIndex.end());
  128. map <MMC_COOKIE, CAppData>::iterator i;
  129. for (i = m_pScope->m_AppData.begin(); i != m_pScope->m_AppData.end(); i ++)
  130. {
  131. CString szIndex = GetUpgradeIndex(i->second.m_pDetails->pInstallInfo->PackageGuid);
  132. if (0 != _wcsicmp(szIndex, m_szMyGuid))
  133. {
  134. // make sure we exclude legacy apps
  135. if (i->second.m_pDetails->pInstallInfo->PathType != SetupNamePath)
  136. {
  137. CUpgradeData data;
  138. memcpy(&data.m_PackageGuid, &i->second.m_pDetails->pInstallInfo->PackageGuid, sizeof(GUID));
  139. data.m_szClassStore = szClassStore;
  140. // Add this element to the list
  141. m_NameIndex[i->second.m_pDetails->pszPackageName] = data;
  142. }
  143. }
  144. }
  145. RefreshList();
  146. }
  147. void CAddUpgrade::OnOtherContainer()
  148. {
  149. // Populate the map with all packages in the other container.
  150. m_NameIndex.erase(m_NameIndex.begin(), m_NameIndex.end());
  151. WCHAR szBuffer[MAX_DS_PATH];
  152. LPGROUPPOLICYOBJECT pGPO = NULL;
  153. HRESULT hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL,
  154. CLSCTX_SERVER, IID_IGroupPolicyObject,
  155. (void **)&pGPO);
  156. if (SUCCEEDED(hr))
  157. {
  158. // open GPO object without opening registry data
  159. hr = pGPO->OpenDSGPO((LPOLESTR)((LPCOLESTR)m_szGPO), GPO_OPEN_READ_ONLY);
  160. if (SUCCEEDED(hr))
  161. {
  162. hr = pGPO->GetDSPath(m_pScope->m_fMachine ? GPO_SECTION_MACHINE : GPO_SECTION_USER, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
  163. if (SUCCEEDED(hr))
  164. {
  165. // OK, we should now have a DS path that we can use to locate
  166. // a class store.
  167. LPOLESTR szCSPath;
  168. hr = CsGetClassStorePath((LPOLESTR)((LPCOLESTR)szBuffer), &szCSPath);
  169. if (SUCCEEDED(hr))
  170. {
  171. // now we should have the DS path to the class store itself
  172. IClassAdmin * pIClassAdmin;
  173. hr = CsGetClassStore((LPOLESTR)((LPCOLESTR)szCSPath), (LPVOID*)&pIClassAdmin);
  174. if (SUCCEEDED(hr))
  175. {
  176. // and finally we should have a pointer to the IClassAdmin
  177. IEnumPackage * pIPE = NULL;
  178. hr = pIClassAdmin->EnumPackages(NULL,
  179. NULL,
  180. APPQUERY_ADMINISTRATIVE,
  181. NULL,
  182. NULL,
  183. &pIPE);
  184. if (SUCCEEDED(hr))
  185. {
  186. hr = pIPE->Reset();
  187. PACKAGEDISPINFO stPDI;
  188. ULONG nceltFetched;
  189. while (SUCCEEDED(hr))
  190. {
  191. hr = pIPE->Next(1, &stPDI, &nceltFetched);
  192. if (nceltFetched)
  193. {
  194. // make sure we exclude legacy apps
  195. // and deleted apps
  196. if (stPDI.PathType != SetupNamePath)
  197. {
  198. CString szIndex = GetUpgradeIndex(stPDI.PackageGuid);
  199. if (0 != _wcsicmp(szIndex, m_szMyGuid))
  200. {
  201. // Add this element to the list
  202. CString sz = stPDI.pszPackageName;
  203. if (0 != _wcsicmp(m_szGPO, m_pScope->m_szGPO))
  204. {
  205. // This isn't in the host GPO
  206. sz += L" (";
  207. sz += m_szGPOName;
  208. sz += L")";
  209. }
  210. CUpgradeData data;
  211. data.m_szClassStore = szCSPath;
  212. memcpy(&data.m_PackageGuid, &stPDI.PackageGuid, sizeof(GUID));
  213. m_NameIndex[sz] = data;
  214. }
  215. }
  216. }
  217. else
  218. {
  219. break;
  220. }
  221. OLESAFE_DELETE(stPDI.pszPackageName);
  222. OLESAFE_DELETE(stPDI.pszScriptPath);
  223. OLESAFE_DELETE(stPDI.pszPublisher);
  224. OLESAFE_DELETE(stPDI.pszUrl);
  225. UINT n = stPDI.cUpgrades;
  226. while (n--)
  227. {
  228. OLESAFE_DELETE(stPDI.prgUpgradeInfoList[n].szClassStore);
  229. }
  230. OLESAFE_DELETE(stPDI.prgUpgradeInfoList);
  231. }
  232. pIPE->Release();
  233. }
  234. pIClassAdmin->Release();
  235. }
  236. OLESAFE_DELETE(szCSPath);
  237. }
  238. }
  239. }
  240. pGPO->Release();
  241. }
  242. RefreshList();
  243. }
  244. void CAddUpgrade::OnAllContainers()
  245. {
  246. RefreshList();
  247. }
  248. //+--------------------------------------------------------------------------
  249. //
  250. // Function: GetDomainFromLDAPPath
  251. //
  252. // Synopsis: returns a freshly allocated string containing the LDAP path
  253. // to the domain name contained with an arbitrary LDAP path.
  254. //
  255. // Arguments: [szIn] - LDAP path to the initial object
  256. //
  257. // Returns: NULL - if no domain could be found or if OOM
  258. //
  259. // History: 5-06-1998 stevebl Created
  260. // 10-20-1998 stevebl modified to preserve server names
  261. //
  262. // Notes: This routine works by repeatedly removing leaf elements from
  263. // the LDAP path until an element with the "DC=" prefix is
  264. // found, indicating that a domain name has been located. If a
  265. // path is given that is not rooted in a domain (is that even
  266. // possible?) then NULL would be returned.
  267. //
  268. // The caller must free this path using the standard c++ delete
  269. // operation. (I/E this isn't an exportable function.)
  270. //
  271. // Stolen from GPEDIT\UTIL.CPP
  272. //
  273. //---------------------------------------------------------------------------
  274. LPOLESTR GetDomainFromLDAPPath(LPOLESTR szIn)
  275. {
  276. LPOLESTR sz = NULL;
  277. IADsPathname * pADsPathname = NULL;
  278. HRESULT hr = CoCreateInstance(CLSID_Pathname,
  279. NULL,
  280. CLSCTX_INPROC_SERVER,
  281. IID_IADsPathname,
  282. (LPVOID*)&pADsPathname);
  283. if (SUCCEEDED(hr))
  284. {
  285. BSTR bstrSzIn;
  286. bstrSzIn = SysAllocString(szIn);
  287. if (NULL == szIn || bstrSzIn != NULL)
  288. {
  289. hr = pADsPathname->Set(bstrSzIn, ADS_SETTYPE_FULL);
  290. SysFreeString(bstrSzIn);
  291. if (SUCCEEDED(hr))
  292. {
  293. BSTR bstr;
  294. BOOL fStop = FALSE;
  295. while (!fStop)
  296. {
  297. hr = pADsPathname->Retrieve(ADS_FORMAT_LEAF, &bstr);
  298. if (SUCCEEDED(hr))
  299. {
  300. // keep peeling them off until we find something
  301. // that is a domain name
  302. fStop = (0 == _wcsnicmp(L"DC=", bstr, 3));
  303. SysFreeString(bstr);
  304. }
  305. else
  306. {
  307. DebugMsg((DM_WARNING, TEXT("GetDomainFromLDAPPath: Failed to retrieve leaf with 0x%x."), hr));
  308. }
  309. if (!fStop)
  310. {
  311. hr = pADsPathname->RemoveLeafElement();
  312. if (FAILED(hr))
  313. {
  314. DebugMsg((DM_WARNING, TEXT("GetDomainFromLDAPPath: Failed to remove leaf with 0x%x."), hr));
  315. fStop = TRUE;
  316. }
  317. }
  318. }
  319. hr = pADsPathname->Retrieve(ADS_FORMAT_X500, &bstr);
  320. if (SUCCEEDED(hr))
  321. {
  322. ULONG ulNoChars = wcslen(bstr)+1;
  323. sz = new OLECHAR[ulNoChars];
  324. if (sz)
  325. {
  326. hr = StringCchCopy(sz, ulNoChars, bstr);
  327. ASSERT(SUCCEEDED(hr));
  328. }
  329. SysFreeString(bstr);
  330. }
  331. else
  332. {
  333. DebugMsg((DM_WARNING, TEXT("GetDomainFromLDAPPath: Failed to retrieve full path with 0x%x."), hr));
  334. }
  335. }
  336. else
  337. {
  338. DebugMsg((DM_WARNING, TEXT("GetDomainFromLDAPPath: Failed to set pathname with 0x%x."), hr));
  339. }
  340. pADsPathname->Release();
  341. }
  342. else
  343. {
  344. DebugMsg((DM_WARNING, TEXT("GetDomainFromLDAPPath: Failed to allocate memory")));
  345. }
  346. }
  347. else
  348. {
  349. DebugMsg((DM_WARNING, TEXT("GetDomainFromLDAPPath: Failed to CoCreateInstance for IID_IADsPathname with 0x%x."), hr));
  350. }
  351. return sz;
  352. }
  353. void CAddUpgrade::OnBrowse()
  354. {
  355. // Browse to the other container and then call OnOtherContainer.
  356. OLECHAR szPath[MAX_DS_PATH];
  357. OLECHAR szName[256];
  358. GPOBROWSEINFO stGBI;
  359. memset(&stGBI, 0, sizeof(GPOBROWSEINFO));
  360. stGBI.dwSize = sizeof(GPOBROWSEINFO);
  361. stGBI.dwFlags = GPO_BROWSE_NOCOMPUTERS | GPO_BROWSE_INITTOALL;
  362. stGBI.hwndOwner = m_hWnd;
  363. stGBI.lpInitialOU = GetDomainFromLDAPPath((LPWSTR)((LPCWSTR)m_szGPO));
  364. stGBI.lpDSPath = szPath;
  365. stGBI.dwDSPathSize = MAX_DS_PATH;
  366. stGBI.lpName = szName;
  367. stGBI.dwNameSize = 256;
  368. if (SUCCEEDED(BrowseForGPO(&stGBI)))
  369. {
  370. m_szGPO = szPath;
  371. m_szGPOName = szName;
  372. m_iSource = 1;
  373. UpdateData(FALSE);
  374. OnOtherContainer();
  375. }
  376. if (stGBI.lpInitialOU != NULL)
  377. {
  378. delete [] stGBI.lpInitialOU;
  379. }
  380. }
  381. LRESULT CAddUpgrade::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  382. {
  383. switch (message)
  384. {
  385. case WM_HELP:
  386. StandardHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, IDD);
  387. return 0;
  388. default:
  389. return CDialog::WindowProc(message, wParam, lParam);
  390. }
  391. }
  392. void CAddUpgrade::OnContextMenu(CWnd* pWnd, CPoint point)
  393. {
  394. StandardContextMenu(pWnd->m_hWnd, IDD_FIND_UPGRADE);
  395. }