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.

898 lines
29 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: regdlg.cpp
  7. //
  8. // Contents: implementation of CRegistryDialog
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "resource.h"
  14. #include "util.h"
  15. #include "servperm.h"
  16. #include "addobj.h"
  17. #include "RegDlg.h"
  18. #include <accctrl.h>
  19. #include <aclapi.h>
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. #define MAX_REGKEY 256
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CRegistryDialog dialog
  28. CRegistryDialog::CRegistryDialog()
  29. : CHelpDialog(a177HelpIDs, IDD, 0)
  30. {
  31. //{{AFX_DATA_INIT(CRegistryDialog)
  32. m_strReg = _T("");
  33. //}}AFX_DATA_INIT
  34. m_pConsole = NULL;
  35. m_pTemplate = NULL;
  36. m_dbHandle = NULL;
  37. m_cookie = 0;
  38. m_pIl = NULL;
  39. m_pDataObj = NULL;
  40. m_bNoUpdate = FALSE;
  41. }
  42. void CRegistryDialog::DoDataExchange(CDataExchange* pDX)
  43. {
  44. CDialog::DoDataExchange(pDX);
  45. //{{AFX_DATA_MAP(CRegistryDialog)
  46. DDX_Control(pDX, IDC_REGTREE, m_tcReg);
  47. DDX_Text(pDX, IDC_REGKEY, m_strReg);
  48. //}}AFX_DATA_MAP
  49. }
  50. /*-------------------------------------------------------------------------------------------
  51. Method: CreateKeyInfo
  52. Synopsis: Create a new TI_KEYINFO structure and optionaly set its members
  53. Arguments: [hKey] - Optional value to set the hKey member of TI_KEYINFO
  54. default is zero
  55. [Enum] - Optional value to set the Enum member of TI_KEYINFO
  56. default is zero
  57. Returns: a LPTI_KEYINFO pointer
  58. ---------------------------------------------------------------------------------------------*/
  59. LPTI_KEYINFO CRegistryDialog::CreateKeyInfo(HKEY hKey, bool Enum)
  60. {
  61. LPTI_KEYINFO pInfo = NULL;
  62. pInfo = new TI_KEYINFO;
  63. if(pInfo){
  64. pInfo->hKey = hKey;
  65. pInfo->Enum = Enum;
  66. }
  67. return pInfo;
  68. }
  69. /*-------------------------------------------------------------------------------------------
  70. Method: IsValidRegPath
  71. Synopsis: Returns true if strReg path. We can't assume that this
  72. HKEY exists in the current registry. We will only make
  73. sure that the root node exists and each string in
  74. between '\'s isn't blank.
  75. Arguments: [strReg] - A string represending a registry path
  76. subkeys are seperated by '\'s
  77. Returns: TRUE if strReg is a valid path.
  78. ---------------------------------------------------------------------------------------------*/
  79. BOOL CRegistryDialog::IsValidRegPath(LPCTSTR strReg)
  80. {
  81. ASSERT(this);
  82. ASSERT(m_tcReg);
  83. if(!strReg) return FALSE;
  84. int iStr = 0; // Current position in strReg
  85. CString strCheck; // String to check
  86. LPTI_KEYINFO pkInfo; // Tree item key info.
  87. //
  88. // Find which root node this registry value is in.
  89. //
  90. while(strReg[iStr] && strReg[iStr] != _T('\\')) iStr++;
  91. strCheck = strReg;
  92. strCheck = strCheck.Left(iStr);
  93. strCheck.MakeUpper();
  94. // Get the HKEY value from the tree ctrl
  95. HTREEITEM hTi = m_tcReg.GetRootItem();
  96. while(hTi){
  97. if(m_tcReg.GetItemText(hTi) == strCheck)
  98. break;
  99. hTi = m_tcReg.GetNextItem(hTi, TVGN_NEXT);
  100. }
  101. if(hTi == NULL) return FALSE;
  102. // Get TI_KEYINFO for this root node
  103. pkInfo = (LPTI_KEYINFO)m_tcReg.GetItemData(hTi);
  104. // This value should never be NULL.
  105. if(!pkInfo){
  106. TRACE(TEXT("Tree item TI_KEYINFO is NULL for root node '%s'"), (LPCTSTR)strCheck);
  107. return FALSE;
  108. }
  109. //
  110. // Check the rest of the string to make sure that string's
  111. // in between '\'s aren't blank
  112. //
  113. while(strReg[iStr]){
  114. // Check to make sure that the string item before
  115. // and after the '\' aren't spaces.
  116. if(strReg[iStr] == _T('\\')){
  117. if( strReg[iStr + 1] == _T(' ') ||
  118. strReg[iStr + 1] == _T('\t') ||
  119. //strReg[iStr + 1] == 0 ||
  120. iStr > 0 &&
  121. (
  122. strReg[iStr - 1] == _T(' ') ||
  123. strReg[iStr - 1] == _T('\t')
  124. )
  125. )
  126. return FALSE;
  127. }
  128. iStr++;
  129. }
  130. return TRUE;
  131. }
  132. /*-------------------------------------------------------------------------------------------
  133. Method: MakePathVisible
  134. Synopsis:
  135. Arguments: [strReg] - A string represending a registry path
  136. subkeys are seperated by '\'s
  137. Returns: TRUE if strReg is a valid path.
  138. ---------------------------------------------------------------------------------------------*/
  139. void CRegistryDialog::MakePathVisible(LPCTSTR strReg)
  140. {
  141. ASSERT(this);
  142. ASSERT(m_tcReg);
  143. if(!strReg) return;
  144. int iStr = 0; // Current position in strReg
  145. CString strCheck; // String to check
  146. LPTI_KEYINFO pkInfo; // Tree item key info.
  147. //
  148. // Find which root node this registry value is in.
  149. //
  150. while(strReg[iStr] && strReg[iStr] != _T('\\')) iStr++;
  151. strCheck = strReg;
  152. strCheck = strCheck.Left(iStr);
  153. strCheck.MakeUpper();
  154. // Get the HKEY value from the tree ctrl
  155. HTREEITEM hTi = m_tcReg.GetRootItem();
  156. while(hTi){
  157. if(m_tcReg.GetItemText(hTi) == strCheck)
  158. break;
  159. hTi = m_tcReg.GetNextItem(hTi, TVGN_NEXT);
  160. }
  161. if(hTi == NULL) return;
  162. // Get TI_KEYINFO for this root node
  163. pkInfo = (LPTI_KEYINFO)m_tcReg.GetItemData(hTi);
  164. // This value should never be NULL.
  165. if(!pkInfo){
  166. TRACE(TEXT("Tree item TI_KEYINFO is NULL for root node '%s'"), (LPCTSTR)strCheck);
  167. return;
  168. }
  169. //
  170. // Step through each sub item to see if it exists in the tree control
  171. //
  172. int iBegin = iStr + 1;
  173. int iNotFound = -1;
  174. while(strReg[iStr] && hTi){
  175. iStr++;
  176. if(strReg[iStr] == _T('\\') || strReg[iStr] == 0){
  177. CString strItem;
  178. //
  179. // Make sure we have tree items we can use.
  180. //
  181. EnumerateChildren(hTi);
  182. if(strReg[iStr] == 0 && strReg[iStr - 1] == _T('\\'))
  183. m_tcReg.Expand(hTi, TVE_EXPAND);
  184. //
  185. // Parse out the subkeys name.
  186. strCheck = strReg;
  187. strCheck = strCheck.Mid(iBegin, iStr - iBegin);
  188. strCheck.MakeUpper();
  189. iBegin = iStr + 1;
  190. //
  191. // Find child item with this name.
  192. //
  193. hTi = m_tcReg.GetNextItem(hTi, TVGN_CHILD);
  194. while(hTi){
  195. strItem = m_tcReg.GetItemText(hTi);
  196. strItem.MakeUpper();
  197. iNotFound = lstrcmpiW(strItem, strCheck);
  198. if(iNotFound >= 0)
  199. break;
  200. hTi = m_tcReg.GetNextItem(hTi, TVGN_NEXT);
  201. }
  202. if(strReg[iStr] != 0 && iNotFound != 0){
  203. hTi = NULL;
  204. break;
  205. }
  206. }
  207. }
  208. //
  209. // Select and ensure visibility if the path was found
  210. //
  211. if(hTi){
  212. if(strReg[iStr - 1] != _T('\\'))
  213. m_tcReg.Expand(hTi, TVE_COLLAPSE);
  214. if(!iNotFound){
  215. m_tcReg.SelectItem(hTi);
  216. }
  217. m_tcReg.EnsureVisible(hTi);
  218. }
  219. }
  220. /*-------------------------------------------------------------------------------------------
  221. Method: EnumerateChildren
  222. Synopsis: Enumerates a HKEY subkey and places them as children of 'hParent'
  223. Arguments: [hParent] - HTREEITEM to enumerate.
  224. Returns: void
  225. ---------------------------------------------------------------------------------------------*/
  226. void CRegistryDialog::EnumerateChildren(HTREEITEM hParent)
  227. {
  228. ASSERT(this);
  229. ASSERT(m_tcReg);
  230. //
  231. // We won't enumerate for the root.
  232. //
  233. if(!hParent || hParent == TVI_ROOT) return;
  234. LPTI_KEYINFO hkeyParent; // Used if the item being expanded has an invalid HKEY value
  235. LPTI_KEYINFO hkeyThis; // HKEY value of item expanding
  236. int n = 0; // Counter
  237. LPTSTR szName; // Used to acquire the name of a HKEY item
  238. DWORD cchName; // Buffer size of szName
  239. HTREEITEM hti;
  240. TV_INSERTSTRUCT tvii;
  241. TV_ITEM tviNew; // Expanding tree item
  242. TV_ITEM tvi; // Used to add children to the expanding HTREEITEM
  243. // pNMTreeView->itemNew is the TV_ITEM we're expanding.
  244. hkeyThis = (LPTI_KEYINFO)m_tcReg.GetItemData(hParent);
  245. // Exit if we have an invalid pointer.
  246. if(!hkeyThis) return;
  247. //
  248. // Allocate buffer for HKEY name
  249. //
  250. szName = new TCHAR [MAX_REGKEY]; //Raid #613152, yanggao
  251. if(!szName) return;
  252. cchName = MAX_REGKEY;
  253. //
  254. // Get item text
  255. //
  256. ZeroMemory(&tviNew,sizeof(tviNew));
  257. tviNew.hItem = hParent;
  258. tviNew.mask = TVIF_TEXT;
  259. tviNew.pszText = szName;
  260. tviNew.cchTextMax = cchName;
  261. m_tcReg.GetItem(&tviNew);
  262. //
  263. // Do we have an invalid HKEY value?
  264. //
  265. if (!hkeyThis->hKey) {
  266. // Get HKEY value of parent
  267. hti = m_tcReg.GetParentItem(hParent);
  268. ZeroMemory(&tvi,sizeof(tvi));
  269. tvi.hItem = hti;
  270. tvi.mask = TVIF_PARAM;
  271. m_tcReg.GetItem(&tvi);
  272. hkeyParent = (LPTI_KEYINFO)tvi.lParam;
  273. if(!hkeyParent){
  274. TRACE(TEXT("Parent of %s has an does not have a valid TI_KEYINFO struct"), (LPCTSTR)tviNew.pszText);
  275. delete [] szName;
  276. return;
  277. }
  278. //
  279. // If we can't open this key then set the parent item
  280. // to have no children.
  281. // This is not a safe usage. Change KEY_ALL_ACCESS. Raid #555894, yanggao.
  282. if (ERROR_SUCCESS != RegOpenKeyEx(hkeyParent->hKey,tviNew.pszText,0,KEY_READ,&(hkeyThis->hKey))) {
  283. tvi.mask = TVIF_CHILDREN;
  284. tvi.cChildren = 0;
  285. m_tcReg.SetItem(&tvi);
  286. delete [] szName;
  287. return;
  288. }
  289. //
  290. // Set the HKEY value for the item
  291. //
  292. tvi.hItem = hParent;
  293. tvi.lParam = (LPARAM) hkeyThis;
  294. m_tcReg.SetItem(&tvi);
  295. }
  296. //
  297. // Don't do anything if this item has already been enumerated or
  298. // does not have a valid TI_KEYINFO structure
  299. //
  300. if( !hkeyThis->Enum ){
  301. hkeyThis->Enum = true;
  302. DWORD cSubKeys; // Used when quering for number of children.
  303. HKEY hKey; // Used To querry sub keys.
  304. //
  305. // Prepare the TV_INSERTSTRUCT
  306. //
  307. ZeroMemory(&tvii, sizeof(TV_INSERTSTRUCT));
  308. tvii.hParent = hParent;
  309. tvii.hInsertAfter = TVI_LAST;
  310. tvii.item.mask = TVIF_CHILDREN | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  311. tvii.item.cChildren = 0;
  312. tvii.item.iImage = CONFIG_REG_IDX;
  313. tvii.item.iSelectedImage = CONFIG_REG_IDX;
  314. //
  315. // Add subkeys
  316. //
  317. while(ERROR_SUCCESS == RegEnumKeyEx(hkeyThis->hKey,n++, szName,&cchName,NULL,NULL,0,NULL)) {
  318. // Open the key so we can query it for the count of children
  319. // This is not a safe usage. Change KEY_ALL_ACCESS. Raid #555894, yanggao.
  320. if (ERROR_SUCCESS == RegOpenKeyEx(hkeyThis->hKey, szName, 0, KEY_READ, &(hKey))) {
  321. if(ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, 0, &cSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
  322. tvii.item.cChildren = cSubKeys;
  323. RegCloseKey(hKey);
  324. }
  325. else
  326. tvii.item.cChildren = 0;
  327. tvii.item.cchTextMax = cchName;
  328. tvii.item.pszText = szName;
  329. tvii.item.lParam = (LPARAM)CreateKeyInfo(0, false);
  330. m_tcReg.InsertItem(&tvii);
  331. cchName = MAX_REGKEY;
  332. }
  333. //
  334. // Sort children
  335. //
  336. m_tcReg.SortChildren(hParent);
  337. }
  338. delete [] szName;
  339. }
  340. /*-------------------------------------------------------------------------------------------
  341. Method: SetProfileInfo
  342. Synopsis: Sets either m_pTemplate;
  343. Arguments: [pspi] - the PEDITTEMPLATE to save the results in
  344. [ft] - Type of pointer 'pspi' is (unused)
  345. returns: void
  346. ---------------------------------------------------------------------------------------------*/
  347. void CRegistryDialog::SetProfileInfo(PEDITTEMPLATE pspi, FOLDER_TYPES ft)
  348. {
  349. m_pTemplate = (PEDITTEMPLATE)pspi;
  350. }
  351. /*-------------------------------------------------------------------------------------------
  352. Method: SetConsole
  353. Synopsis: Sets class variable 'm_pConsole'
  354. returns: void
  355. ---------------------------------------------------------------------------------------------*/
  356. void CRegistryDialog::SetConsole(LPCONSOLE pConsole)
  357. {
  358. m_pConsole = pConsole;
  359. }
  360. /*-------------------------------------------------------------------------------------------
  361. Method: SetComponentData
  362. Synopsis: Sets class varaible 'm_pComponentData'
  363. returns: void
  364. ---------------------------------------------------------------------------------------------*/
  365. void CRegistryDialog::SetComponentData(CComponentDataImpl *pComponentData)
  366. {
  367. m_pComponentData = pComponentData;
  368. }
  369. /*-------------------------------------------------------------------------------------------
  370. Method: SetCookie
  371. Synopsis: Sets class variable 'm_cookie'
  372. returns: void
  373. ---------------------------------------------------------------------------------------------*/
  374. void CRegistryDialog::SetCookie(MMC_COOKIE cookie)
  375. {
  376. m_cookie = cookie;
  377. }
  378. BEGIN_MESSAGE_MAP(CRegistryDialog, CHelpDialog)
  379. //{{AFX_MSG_MAP(CRegistryDialog)
  380. ON_NOTIFY(TVN_ITEMEXPANDING, IDC_REGTREE, OnItemexpandingRegtree)
  381. ON_NOTIFY(TVN_DELETEITEM, IDC_REGTREE, OnDeleteitemRegtree)
  382. ON_NOTIFY(TVN_SELCHANGED, IDC_REGTREE, OnSelchangedRegtree)
  383. ON_EN_CHANGE(IDC_REGKEY, OnChangeRegkey)
  384. ON_EN_SETFOCUS(IDC_REGKEY, OnSetFocus)
  385. //}}AFX_MSG_MAP
  386. END_MESSAGE_MAP()
  387. /////////////////////////////////////////////////////////////////////////////
  388. // CRegistryDialog message handlers
  389. /*-------------------------------------------------------------------------------------------
  390. Method: OnOK
  391. Synopsis: Message handler for the IDOK button,
  392. **BUG** Creating the new configuration item should happen outside of
  393. the dialog.
  394. Returns: void
  395. ---------------------------------------------------------------------------------------------*/
  396. void CRegistryDialog::OnOK()
  397. {
  398. UpdateData(TRUE);
  399. if (!m_strReg.IsEmpty()) {
  400. int nCont=0;
  401. CFolder *pFolder = (CFolder *)m_cookie;
  402. if ( m_cookie && AREA_REGISTRY_ANALYSIS == pFolder->GetType() ) {
  403. //
  404. // add a key to analysis area
  405. //
  406. if ( m_dbHandle ) {
  407. nCont = 1;
  408. }
  409. } else if ( m_pTemplate && m_pTemplate->pTemplate ) {
  410. nCont = 2;
  411. //
  412. // if no object is in the buffer, create it with count = 0
  413. // this buffer will be freed when the template is freed
  414. //
  415. if ( !m_pTemplate->pTemplate->pRegistryKeys.pAllNodes ) {
  416. PSCE_OBJECT_ARRAY pTemp = (PSCE_OBJECT_ARRAY)LocalAlloc(0, sizeof(SCE_OBJECT_ARRAY));
  417. if ( pTemp ) {
  418. pTemp->Count = 0;
  419. pTemp->pObjectArray = NULL;
  420. m_pTemplate->pTemplate->pRegistryKeys.pAllNodes = pTemp;
  421. } else
  422. nCont = 0;
  423. }
  424. else
  425. {
  426. //Raid #477628, yanggao
  427. //Make sure this key isn't already in the list:
  428. PSCE_OBJECT_ARRAY poa;
  429. unsigned int i;
  430. poa = m_pTemplate->pTemplate->pRegistryKeys.pAllNodes;
  431. for (i=0;i < poa->Count;i++)
  432. {
  433. if (lstrcmpi(poa->pObjectArray[i]->Name,m_strReg) == 0)
  434. {
  435. CDialog::OnOK();
  436. return;
  437. }
  438. }
  439. }
  440. }
  441. HRESULT hr=E_FAIL;
  442. if ( nCont ) {
  443. PSECURITY_DESCRIPTOR pSelSD=NULL;
  444. SECURITY_INFORMATION SelSeInfo = 0;
  445. BYTE ConfigStatus = 0;
  446. if (m_pComponentData) {
  447. if ( m_pComponentData->GetAddObjectSecurity(
  448. GetSafeHwnd(),
  449. m_strReg,
  450. TRUE,
  451. SE_REGISTRY_KEY,
  452. pSelSD,
  453. SelSeInfo,
  454. ConfigStatus
  455. ) == E_FAIL ) {
  456. return;
  457. }
  458. } else {
  459. return;
  460. }
  461. hr = S_OK;
  462. if ( pSelSD && SelSeInfo ) {
  463. if ( 1 == nCont ) {
  464. //
  465. // add to the engine directly
  466. //
  467. SCESTATUS sceStatus=SCESTATUS_SUCCESS;
  468. BYTE AnalStatus;
  469. //
  470. // start the transaction if it's not started
  471. //
  472. if ( m_pComponentData->EngineTransactionStarted() ) {
  473. sceStatus = SceUpdateObjectInfo(
  474. m_dbHandle,
  475. AREA_REGISTRY_SECURITY,
  476. (LPTSTR)(LPCTSTR)m_strReg,
  477. m_strReg.GetLength(), // number of characters
  478. ConfigStatus,
  479. TRUE,
  480. pSelSD,
  481. SelSeInfo,
  482. &AnalStatus
  483. );
  484. if ( SCESTATUS_SUCCESS == sceStatus ) {
  485. hr = m_pComponentData->UpdateScopeResultObject(m_pDataObj,
  486. m_cookie,
  487. AREA_REGISTRY_SECURITY);
  488. m_pTemplate->SetDirty(AREA_REGISTRY_SECURITY);
  489. }
  490. } else {
  491. //
  492. // can't start transaction
  493. //
  494. hr = E_FAIL;
  495. }
  496. } else {
  497. //
  498. // add to configuration template
  499. //
  500. PSCE_OBJECT_ARRAY poa;
  501. unsigned int i;
  502. poa = m_pTemplate->pTemplate->pRegistryKeys.pAllNodes;
  503. PSCE_OBJECT_SECURITY *pCopy;
  504. // For some reason the LocalReAlloc version of this keeps giving out of memory
  505. // errors, but allocing & copying everything works fine.
  506. pCopy = (PSCE_OBJECT_SECURITY *)LocalAlloc(LPTR,(poa->Count+1)*sizeof(PSCE_OBJECT_SECURITY));
  507. if (pCopy) {
  508. for (i=0; i<poa->Count; i++) {
  509. pCopy[i] = poa->pObjectArray[i];
  510. }
  511. pCopy[poa->Count] = (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR,sizeof(SCE_OBJECT_SECURITY));
  512. if ( pCopy[poa->Count] ) {
  513. pCopy[poa->Count]->Name = (PWSTR) LocalAlloc(LPTR,(m_strReg.GetLength()+1)*sizeof(TCHAR));
  514. if ( pCopy[poa->Count]->Name ) {
  515. //This may not be a safe usage. pCopy[poa->Count]->Name is PWSTR. Consider fix.
  516. lstrcpy(pCopy[poa->Count]->Name,m_strReg);
  517. pCopy[poa->Count]->pSecurityDescriptor = pSelSD;
  518. pCopy[poa->Count]->SeInfo = SelSeInfo;
  519. pCopy[poa->Count]->Status = ConfigStatus;
  520. pCopy[poa->Count]->IsContainer = TRUE;
  521. pSelSD = NULL;
  522. poa->Count++;
  523. if ( poa->pObjectArray ) {
  524. LocalFree(poa->pObjectArray);
  525. }
  526. poa->pObjectArray = pCopy;
  527. m_pTemplate->SetDirty(AREA_REGISTRY_SECURITY);
  528. ((CFolder *)m_cookie)->RemoveAllResultItems();
  529. m_pConsole->UpdateAllViews(NULL ,m_cookie, UAV_RESULTITEM_UPDATEALL);
  530. hr = S_OK;
  531. } else {
  532. LocalFree(pCopy[poa->Count]);
  533. LocalFree(pCopy);
  534. }
  535. } else
  536. LocalFree(pCopy);
  537. }
  538. }
  539. if ( pSelSD ) {
  540. LocalFree(pSelSD);
  541. }
  542. }
  543. }
  544. if ( FAILED(hr) ) {
  545. CString str;
  546. str.LoadString(IDS_CANT_ADD_KEY);
  547. AfxMessageBox(str);
  548. }
  549. }
  550. CDialog::OnOK();
  551. }
  552. /*-------------------------------------------------------------------------------------------
  553. Method: OnInitDialog
  554. Synopsis: Create root HKEY entries HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT,
  555. and HKEY_USERS in the tree control.
  556. Returns: return TRUE
  557. ---------------------------------------------------------------------------------------------*/
  558. BOOL CRegistryDialog::OnInitDialog()
  559. {
  560. CString strRegKeyName; // Used to load string resources
  561. // for name of the HTREEITEM
  562. HTREEITEM hti;
  563. TV_INSERTSTRUCT tvi;
  564. CDialog::OnInitDialog();
  565. //
  566. // Create image list for tree control
  567. //
  568. CThemeContextActivator activator; //Bug 424909, Yanggao, 6/29/2001
  569. m_pIl.Create(IDB_ICON16,16,1,RGB(255,0,255));
  570. m_tcReg.SetImageList (CImageList::FromHandle (m_pIl), TVSIL_NORMAL);
  571. //
  572. // Add Root HKEY items.
  573. //
  574. ZeroMemory(&tvi,sizeof(tvi));
  575. tvi.hParent = TVI_ROOT;
  576. tvi.hInsertAfter = TVI_LAST;
  577. tvi.item.mask = TVIF_CHILDREN | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  578. tvi.item.cChildren = 1; // Initial UI +
  579. tvi.item.iImage = CONFIG_REG_IDX;
  580. tvi.item.iSelectedImage = CONFIG_REG_IDX;
  581. // Insert HKEY_CLASSES_ROOT
  582. strRegKeyName.LoadString(IDS_HKCR);
  583. tvi.item.cchTextMax = strRegKeyName.GetLength()+1;
  584. tvi.item.pszText = strRegKeyName.LockBuffer();
  585. tvi.item.lParam = (LPARAM)CreateKeyInfo(HKEY_CLASSES_ROOT, false);
  586. hti = m_tcReg.InsertItem(&tvi);
  587. strRegKeyName.UnlockBuffer();
  588. // Insert HKEY_LOCAL_MACHINE
  589. strRegKeyName.LoadString(IDS_HKLM);
  590. tvi.item.cchTextMax = strRegKeyName.GetLength()+1;
  591. tvi.item.pszText = strRegKeyName.LockBuffer();
  592. tvi.item.lParam = (LPARAM)CreateKeyInfo(HKEY_LOCAL_MACHINE, false);
  593. hti = m_tcReg.InsertItem(&tvi);
  594. strRegKeyName.UnlockBuffer();
  595. // Insert HKEY_USERS
  596. strRegKeyName.LoadString(IDS_HKU);
  597. tvi.item.cchTextMax = strRegKeyName.GetLength()+1;
  598. tvi.item.pszText = strRegKeyName.LockBuffer();
  599. tvi.item.lParam = (LPARAM)CreateKeyInfo(HKEY_USERS, false);
  600. hti = m_tcReg.InsertItem(&tvi);
  601. strRegKeyName.UnlockBuffer();
  602. // Sort the tree control
  603. m_tcReg.SortChildren(NULL);
  604. return TRUE; // return TRUE unless you set the focus to a control
  605. // EXCEPTION: OCX Property Pages should return FALSE
  606. }
  607. /*-------------------------------------------------------------------------------------------
  608. Method: OnItemexpandingRegtree
  609. Synopsis: MFC OnNotify TVN_ITEMEXPANDING message handler. The lParam member of
  610. the HTREEITEM is a pointer to a TI_KEYINFO structure. When
  611. a tree item is expanded for the first time, we must enumerate all
  612. its children. The function will set the TI_KEYINFO.Enum = true after
  613. enumeration.
  614. returns: void
  615. ---------------------------------------------------------------------------------------------*/
  616. void CRegistryDialog::OnItemexpandingRegtree(NMHDR* pNMHDR, LRESULT* pResult)
  617. {
  618. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  619. *pResult = 0;
  620. EnumerateChildren(pNMTreeView->itemNew.hItem);
  621. }
  622. /*-------------------------------------------------------------------------------------------
  623. Method: OnDeleteitemRegtree
  624. Synopsis: MFC OnNotify TVN_DELETEITEM message handler. Delete the TI_KEYINFO
  625. structure associated with 'itemOld' and close
  626. the regestry key.
  627. returns: void
  628. ---------------------------------------------------------------------------------------------*/
  629. void CRegistryDialog::OnDeleteitemRegtree(NMHDR* pNMHDR, LRESULT* pResult)
  630. {
  631. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  632. LPTI_KEYINFO pInfo = (LPTI_KEYINFO)pNMTreeView->itemOld.lParam;
  633. if(pInfo){
  634. // Close registry key
  635. if(pInfo->hKey && (INT_PTR)(pInfo->hKey) != -1)
  636. RegCloseKey(pInfo->hKey);
  637. // delete the TI_KEYINFO
  638. delete pInfo;
  639. }
  640. *pResult = 0;
  641. }
  642. /*-------------------------------------------------------------------------------------------
  643. Method: ~CRegistryDialog
  644. Synopsis: Release memory used by this class
  645. returns: void
  646. ---------------------------------------------------------------------------------------------*/
  647. CRegistryDialog::~CRegistryDialog()
  648. {
  649. m_pIl.Destroy(); //Bug 424909, Yanggao, 6/29/2001
  650. }
  651. /*-------------------------------------------------------------------------------------------
  652. Method: OnSelchangedRegtree
  653. Synopsis: MFC OnNotify TVN_SELCHANGED message handler. Updates 'm_strReg' to
  654. the full path of the HKEY item
  655. returns: void
  656. ---------------------------------------------------------------------------------------------*/
  657. void CRegistryDialog::OnSelchangedRegtree(NMHDR* pNMHDR, LRESULT* pResult)
  658. {
  659. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  660. *pResult = 0;
  661. //
  662. // Sometime we don't want to be updated.
  663. //
  664. if(m_bNoUpdate) return;
  665. TV_ITEM tvi; // Used to get information about tree items
  666. CString strSel; // Used to build the path to the selected item
  667. LPTSTR szBuf; // Name of tree item
  668. DWORD cchBuf; // size of szBuf
  669. cchBuf = 500;
  670. szBuf = new TCHAR [ cchBuf ];
  671. if(!szBuf) return;
  672. // Get the selected items text
  673. tvi.hItem = pNMTreeView->itemNew.hItem;
  674. tvi.mask = TVIF_TEXT | TVIF_PARAM;
  675. tvi.pszText = szBuf;
  676. tvi.cchTextMax = cchBuf;
  677. if( tvi.hItem ) //Raid #473800, Yanggao
  678. {
  679. m_tcReg.GetItem(&tvi);
  680. strSel = tvi.pszText;
  681. // Retrieve text of all parent items.
  682. while(tvi.hItem = m_tcReg.GetParentItem(tvi.hItem)) {
  683. m_tcReg.GetItem(&tvi);
  684. strSel = L"\\" + strSel;
  685. strSel = tvi.pszText + strSel;
  686. }
  687. m_strReg = strSel;
  688. UpdateData(FALSE);
  689. // Enable the OK button
  690. if(GetDlgItem(IDOK)) GetDlgItem(IDOK)->EnableWindow(TRUE);
  691. }
  692. delete[] szBuf;
  693. }
  694. /*-------------------------------------------------------------------------------------------
  695. Method: OnChangeRegkey
  696. Synopsis: IDC_REGKEY edit control EN_CHANGE handler.
  697. returns: void
  698. ---------------------------------------------------------------------------------------------*/
  699. void CRegistryDialog::OnChangeRegkey()
  700. {
  701. UpdateData(TRUE);
  702. if(IsValidRegPath(m_strReg) && GetDlgItem(IDOK)) {
  703. GetDlgItem(IDOK)->EnableWindow(TRUE);
  704. m_bNoUpdate = TRUE;
  705. MakePathVisible(m_strReg);
  706. m_bNoUpdate = FALSE;
  707. }
  708. else {
  709. HTREEITEM hItem = m_tcReg.GetSelectedItem(); //Raid #473800, Yanggao
  710. if( hItem == NULL )
  711. {
  712. GetDlgItem(IDOK)->EnableWindow(FALSE);
  713. }
  714. }
  715. }
  716. void CRegistryDialog::OnSetFocus() //Raid #473800, Yanggao
  717. {
  718. HTREEITEM hItem = m_tcReg.GetSelectedItem();
  719. if( hItem != NULL )
  720. {
  721. m_tcReg.SelectItem(NULL);
  722. }
  723. }