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.

724 lines
19 KiB

  1. //
  2. // Microsoft Corporation 1998
  3. //
  4. // SNAPIN.CPP - CSnapin rountines
  5. //
  6. #include "main.h"
  7. #include <shlwapi.h>
  8. #define MAX_INI_SECTION_SIZE 10
  9. #define MAX_OPTION_SIZE 256
  10. #define RIGPSNAP_HELP_TOPIC L"RISconcepts.chm::/sag_RIS_CIW_Policy_and_ACLs.htm"
  11. unsigned int CSnapIn::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  12. TCHAR CSnapIn::m_szDefaultIcon[] = TEXT("mydocs.dll,0");
  13. struct {
  14. DWORD dwCtlIdAllow; // dialog control IDs
  15. DWORD dwCtlIdDontCare; // dialog control IDs
  16. DWORD dwCtlIdDeny; // dialog control IDs
  17. DWORD dwValId; // string resouce ID for the option's name
  18. } g_ChoiceOptions[] = {
  19. { IDC_R_AUTO_ALLOW, IDC_R_AUTO_DONTCARE, IDC_R_AUTO_DENY, IDS_AUTO },
  20. { IDC_R_CUST_ALLOW, IDC_R_CUST_DONTCARE, IDC_R_CUST_DENY, IDS_CUSTOM },
  21. { IDC_R_RESTART_ALLOW, IDC_R_RESTART_DONTCARE, IDC_R_RESTART_DENY, IDS_RESTART },
  22. { IDC_R_TOOLS_ALLOW, IDC_R_TOOLS_DONTCARE, IDC_R_TOOLS_DENY, IDS_TOOLS }
  23. };
  24. ///////////////////////////////////////////////////////////////////////////////
  25. //
  26. // CSnapIn object implementation
  27. //
  28. CSnapIn::CSnapIn(CComponentData *pComponent)
  29. {
  30. m_cRef = 1;
  31. InterlockedIncrement(&g_cRefThisDll);
  32. m_pcd = pComponent;
  33. m_pConsole = NULL;
  34. m_pResult = NULL;
  35. m_pHeader = NULL;
  36. m_pImageResult = NULL;
  37. m_pConsoleVerb = NULL;
  38. m_nColumnSize = 180;
  39. m_lViewMode = LVS_ICON;
  40. LoadString(g_hInstance, IDS_NAME, m_column1, sizeof(m_column1));
  41. }
  42. CSnapIn::~CSnapIn()
  43. {
  44. InterlockedDecrement(&g_cRefThisDll);
  45. }
  46. ///////////////////////////////////////////////////////////////////////////////
  47. //
  48. // CSnapIn object implementation (IUnknown)
  49. //
  50. HRESULT CSnapIn::QueryInterface (REFIID riid, void **ppv)
  51. {
  52. if (IsEqualIID(riid, IID_IComponent) || IsEqualIID(riid, IID_IUnknown))
  53. {
  54. *ppv = (LPCOMPONENT)this;
  55. m_cRef++;
  56. return S_OK;
  57. }
  58. else if (IsEqualIID(riid, IID_IExtendPropertySheet))
  59. {
  60. *ppv = (LPEXTENDPROPERTYSHEET)this;
  61. m_cRef++;
  62. return S_OK;
  63. }
  64. else
  65. {
  66. *ppv = NULL;
  67. return E_NOINTERFACE;
  68. }
  69. }
  70. ULONG CSnapIn::AddRef (void)
  71. {
  72. return ++m_cRef;
  73. }
  74. ULONG CSnapIn::Release (void)
  75. {
  76. if (--m_cRef == 0) {
  77. delete this;
  78. return 0;
  79. }
  80. return m_cRef;
  81. }
  82. ///////////////////////////////////////////////////////////////////////////////
  83. //
  84. // CSnapIn object implementation (IComponent)
  85. //
  86. STDMETHODIMP CSnapIn::Initialize(LPCONSOLE lpConsole)
  87. {
  88. HRESULT hr;
  89. // Save the IConsole pointer
  90. m_pConsole = lpConsole;
  91. m_pConsole->AddRef();
  92. hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
  93. reinterpret_cast<void**>(&m_pHeader));
  94. // Give the console the header control interface pointer
  95. if (SUCCEEDED(hr))
  96. m_pConsole->SetHeader(m_pHeader);
  97. m_pConsole->QueryInterface(IID_IResultData,
  98. reinterpret_cast<void**>(&m_pResult));
  99. hr = m_pConsole->QueryResultImageList(&m_pImageResult);
  100. hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
  101. return S_OK;
  102. }
  103. STDMETHODIMP CSnapIn::Destroy(MMC_COOKIE cookie)
  104. {
  105. if (m_pConsole != NULL)
  106. {
  107. m_pConsole->SetHeader(NULL);
  108. m_pConsole->Release();
  109. m_pConsole = NULL;
  110. }
  111. if (m_pHeader != NULL)
  112. {
  113. m_pHeader->Release();
  114. m_pHeader = NULL;
  115. }
  116. if (m_pResult != NULL)
  117. {
  118. m_pResult->Release();
  119. m_pResult = NULL;
  120. }
  121. if (m_pImageResult != NULL)
  122. {
  123. m_pImageResult->Release();
  124. m_pImageResult = NULL;
  125. }
  126. if (m_pConsoleVerb != NULL)
  127. {
  128. m_pConsoleVerb->Release();
  129. m_pConsoleVerb = NULL;
  130. }
  131. return S_OK;
  132. }
  133. STDMETHODIMP CSnapIn::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  134. {
  135. HRESULT hr = S_OK;
  136. switch(event)
  137. {
  138. case MMCN_CONTEXTHELP:
  139. {
  140. IDisplayHelp * phelp = NULL;
  141. hr = m_pConsole->QueryInterface( IID_IDisplayHelp,
  142. (void **)&phelp );
  143. if (SUCCEEDED( hr ))
  144. {
  145. phelp->ShowTopic ( RIGPSNAP_HELP_TOPIC );
  146. }
  147. if ( phelp != NULL )
  148. {
  149. phelp->Release();
  150. }
  151. }
  152. break;
  153. case MMCN_DBLCLICK:
  154. hr = S_FALSE;
  155. break;
  156. case MMCN_ADD_IMAGES:
  157. HBITMAP hbmp16x16;
  158. HBITMAP hbmp32x32;
  159. hbmp16x16 = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16));
  160. hbmp32x32 = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_32x32));
  161. if (hbmp16x16 && hbmp32x32) {
  162. // Set the images
  163. m_pImageResult->ImageListSetStrip(reinterpret_cast<PLONG_PTR>(hbmp16x16),
  164. reinterpret_cast<PLONG_PTR>(hbmp32x32),
  165. 0, RGB(255, 0, 255));
  166. }
  167. if (hbmp16x16) {
  168. DeleteObject(hbmp16x16);
  169. }
  170. if (hbmp32x32) {
  171. DeleteObject(hbmp32x32);
  172. }
  173. break;
  174. case MMCN_SHOW:
  175. if (arg == TRUE)
  176. {
  177. RESULTDATAITEM resultItem;
  178. LPGPTDATAOBJECT pGPTDataObject;
  179. MMC_COOKIE cookie;
  180. INT i;
  181. //
  182. // Get the cookie of the scope pane item
  183. //
  184. hr = lpDataObject->QueryInterface(IID_IGPTDataObject, (LPVOID *)&pGPTDataObject);
  185. if (FAILED(hr))
  186. return S_OK;
  187. hr = pGPTDataObject->GetCookie(&cookie);
  188. pGPTDataObject->Release(); // release initial ref
  189. if (FAILED(hr))
  190. return S_OK;
  191. //
  192. // Prepare the view
  193. //
  194. m_pHeader->InsertColumn(0, m_column1, LVCFMT_LEFT, m_nColumnSize);
  195. m_pResult->SetViewMode(m_lViewMode);
  196. //
  197. // Add result pane items for this node
  198. //
  199. for (i = 0; i < g_NameSpace[cookie].cResultItems; i++)
  200. {
  201. resultItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  202. resultItem.str = MMC_CALLBACK;
  203. resultItem.nImage = g_NameSpace[cookie].pResultItems[i].iImage;
  204. resultItem.lParam = (LPARAM) &g_NameSpace[cookie].pResultItems[i];
  205. m_pResult->InsertItem(&resultItem);
  206. }
  207. //m_pResult->Sort(0, 0, -1);
  208. }
  209. else
  210. {
  211. m_pHeader->GetColumnWidth(0, &m_nColumnSize);
  212. m_pResult->GetViewMode(&m_lViewMode);
  213. }
  214. break;
  215. case MMCN_SELECT:
  216. if (m_pConsoleVerb)
  217. {
  218. LPRESULTITEM pItem;
  219. LPGPTDATAOBJECT pGPTDataObject;
  220. DATA_OBJECT_TYPES type;
  221. MMC_COOKIE cookie;
  222. //
  223. // Set the default verb to open
  224. //
  225. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  226. //
  227. // See if this is one of our items.
  228. //
  229. hr = lpDataObject->QueryInterface(IID_IGPTDataObject, (LPVOID *)&pGPTDataObject);
  230. if (FAILED(hr))
  231. break;
  232. pGPTDataObject->GetType(&type);
  233. pGPTDataObject->GetCookie(&cookie);
  234. pGPTDataObject->Release();
  235. //
  236. // If this is a result pane item or the root of the namespace
  237. // nodes, enable the Properties menu item
  238. //
  239. if ((type == CCT_RESULT) || ((type == CCT_SCOPE) && (cookie == 0)))
  240. {
  241. m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
  242. //
  243. // If this is a result pane item, then change the default
  244. // verb to Properties.
  245. //
  246. if (type == CCT_RESULT)
  247. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  248. }
  249. }
  250. break;
  251. default:
  252. hr = E_UNEXPECTED;
  253. break;
  254. }
  255. return hr;
  256. }
  257. STDMETHODIMP CSnapIn::GetDisplayInfo(LPRESULTDATAITEM pResult)
  258. {
  259. if (pResult)
  260. {
  261. if (pResult->bScopeItem == TRUE)
  262. {
  263. if (pResult->mask & RDI_STR)
  264. {
  265. if (pResult->nCol == 0)
  266. pResult->str = g_NameSpace[pResult->lParam].szDisplayName;
  267. else
  268. pResult->str = L"";
  269. }
  270. if (pResult->mask & RDI_IMAGE)
  271. {
  272. pResult->nImage = 0;
  273. }
  274. }
  275. else
  276. {
  277. if (pResult->mask & RDI_STR)
  278. {
  279. if (pResult->nCol == 0)
  280. {
  281. LPRESULTITEM lpResultItem = (LPRESULTITEM)pResult->lParam;
  282. if (lpResultItem->szDisplayName[0] == TEXT('\0'))
  283. {
  284. LoadString (g_hInstance, lpResultItem->iStringID,
  285. lpResultItem->szDisplayName,
  286. MAX_DISPLAYNAME_SIZE);
  287. }
  288. pResult->str = lpResultItem->szDisplayName;
  289. }
  290. if (pResult->str == NULL)
  291. pResult->str = (LPOLESTR)L"";
  292. }
  293. }
  294. }
  295. return S_OK;
  296. }
  297. STDMETHODIMP CSnapIn::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT *ppDataObject)
  298. {
  299. return m_pcd->QueryDataObject(cookie, type, ppDataObject);
  300. }
  301. STDMETHODIMP CSnapIn::GetResultViewType(MMC_COOKIE cookie, LPOLESTR *ppViewType,
  302. LONG *pViewOptions)
  303. {
  304. return S_FALSE;
  305. }
  306. STDMETHODIMP CSnapIn::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  307. {
  308. HRESULT hr = S_FALSE;
  309. LPGPTDATAOBJECT pGPTDataObjectA, pGPTDataObjectB;
  310. MMC_COOKIE cookie1, cookie2;
  311. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  312. return E_POINTER;
  313. //
  314. // QI for the private GPTDataObject interface
  315. //
  316. if (FAILED(lpDataObjectA->QueryInterface(IID_IGPTDataObject,
  317. (LPVOID *)&pGPTDataObjectA)))
  318. {
  319. return S_FALSE;
  320. }
  321. if (FAILED(lpDataObjectB->QueryInterface(IID_IGPTDataObject,
  322. (LPVOID *)&pGPTDataObjectB)))
  323. {
  324. pGPTDataObjectA->Release();
  325. return S_FALSE;
  326. }
  327. pGPTDataObjectA->GetCookie(&cookie1);
  328. pGPTDataObjectB->GetCookie(&cookie2);
  329. if (cookie1 == cookie2)
  330. {
  331. hr = S_OK;
  332. }
  333. pGPTDataObjectA->Release();
  334. pGPTDataObjectB->Release();
  335. return hr;
  336. }
  337. ///////////////////////////////////////////////////////////////////////////////
  338. //
  339. // CComponentData object implementation (IExtendPropertySheet)
  340. //
  341. STDMETHODIMP CSnapIn::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  342. LONG_PTR handle, LPDATAOBJECT lpDataObject)
  343. {
  344. HRESULT hr;
  345. PROPSHEETPAGE psp;
  346. HPROPSHEETPAGE hPage[2];
  347. LPGPTDATAOBJECT pGPTDataObject;
  348. LPRESULTITEM pItem;
  349. MMC_COOKIE cookie;
  350. //
  351. // Make sure this is one of our objects
  352. //
  353. if (FAILED(lpDataObject->QueryInterface(IID_IGPTDataObject,
  354. (LPVOID *)&pGPTDataObject)))
  355. {
  356. return S_OK;
  357. }
  358. //
  359. // Get the cookie
  360. //
  361. pGPTDataObject->GetCookie(&cookie);
  362. pGPTDataObject->Release();
  363. pItem = (LPRESULTITEM)cookie;
  364. //
  365. // Initialize the common fields in the property sheet structure
  366. //
  367. psp.dwSize = sizeof(PROPSHEETPAGE);
  368. psp.dwFlags = 0;
  369. psp.hInstance = g_hInstance;
  370. psp.lParam = (LPARAM) this;
  371. //
  372. // Do the page specific stuff
  373. //
  374. switch (pItem->dwID)
  375. {
  376. case 2:
  377. psp.pszTemplate = MAKEINTRESOURCE(IDD_SCREEN);
  378. psp.pfnDlgProc = ChoiceDlgProc;
  379. hPage[0] = CreatePropertySheetPage(&psp);
  380. if (hPage[0])
  381. {
  382. hr = lpProvider->AddPage(hPage[0]);
  383. }
  384. else
  385. {
  386. DebugMsg((DM_WARNING, TEXT("CSnapIn::CreatePropertyPages: Failed to create property sheet page with %d."),
  387. GetLastError()));
  388. hr = E_FAIL;
  389. }
  390. break;
  391. }
  392. return (hr);
  393. }
  394. STDMETHODIMP CSnapIn::QueryPagesFor(LPDATAOBJECT lpDataObject)
  395. {
  396. LPGPTDATAOBJECT pGPTDataObject;
  397. DATA_OBJECT_TYPES type;
  398. if (SUCCEEDED(lpDataObject->QueryInterface(IID_IGPTDataObject,
  399. (LPVOID *)&pGPTDataObject)))
  400. {
  401. pGPTDataObject->GetType(&type);
  402. pGPTDataObject->Release();
  403. if (type == CCT_RESULT)
  404. return S_OK;
  405. }
  406. return S_FALSE;
  407. }
  408. ///////////////////////////////////////////////////////////////////////////////
  409. //
  410. // CSnapIn object implementation (Internal functions)
  411. //
  412. INT_PTR CALLBACK CSnapIn::ReadmeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  413. {
  414. return FALSE;
  415. }
  416. INT_PTR CALLBACK CSnapIn::_CreateDirectoryIfNeeded( LPOLESTR pszPath )
  417. {
  418. BOOL b = FALSE;
  419. LPOLESTR psz = &pszPath[ wcslen( pszPath ) ];
  420. DWORD dwErr;
  421. while ( psz = StrRChr( pszPath, psz, L'\\' ) )
  422. {
  423. WCHAR tmp = *psz; // save
  424. *psz = L'\0'; // terminate
  425. b = CreateDirectory( pszPath, NULL );
  426. *psz = tmp; // restore
  427. if (b)
  428. { // success in creating directory
  429. psz++;
  430. while ( psz = StrChr( psz, L'\\' ) )
  431. {
  432. WCHAR tmp = *psz; // save
  433. *psz = L'\0'; // terminate
  434. b = CreateDirectory( pszPath, NULL );
  435. *psz = tmp; // restore
  436. if ( !b )
  437. {
  438. dwErr = GetLastError();
  439. break;
  440. }
  441. psz++;
  442. }
  443. break;
  444. }
  445. // else failed... keep backing up
  446. dwErr = GetLastError();
  447. psz--;
  448. }
  449. return b;
  450. }
  451. INT_PTR CALLBACK CSnapIn::ChoiceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  452. {
  453. CSnapIn * pCS = (CSnapIn*) GetWindowLongPtr( hDlg, DWLP_USER );
  454. static BOOL bDirty;
  455. BOOL fReturn = FALSE;
  456. HRESULT hr;
  457. LPOLESTR pszPath = NULL;
  458. if ( message == WM_INITDIALOG )
  459. {
  460. bDirty = FALSE;
  461. pCS = (CSnapIn *) (((LPPROPSHEETPAGE)lParam)->lParam);
  462. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) pCS);
  463. if (!pCS)
  464. goto Cleanup;
  465. pszPath = SysAllocStringByteLen( NULL, MAX_PATH * sizeof(OLECHAR) );
  466. if (!pszPath)
  467. goto Cleanup;
  468. hr = pCS->m_pcd->m_pGPTInformation->GetFileSysPath( GPO_SECTION_USER, pszPath, MAX_PATH );
  469. if (SUCCEEDED(hr))
  470. {
  471. wcscat( pszPath, L"\\Microsoft\\RemoteInstall\\oscfilter.ini");
  472. for ( INT i = 0; i < ARRAYSIZE(g_ChoiceOptions); i++ )
  473. {
  474. WCHAR szValue[MAX_INI_SECTION_SIZE];
  475. LONG lValue = -1; // don't care
  476. DWORD dw;
  477. WCHAR szOption[ MAX_OPTION_SIZE ];
  478. dw = LoadString( g_hInstance, g_ChoiceOptions[i].dwValId, szOption, ARRAYSIZE( szOption ));
  479. dw = GetPrivateProfileString( L"Choice", szOption, L"", szValue, ARRAYSIZE( szValue ), pszPath );
  480. if ( dw != 0 )
  481. {
  482. lValue = wcstol( szValue, NULL, 10 );
  483. }
  484. switch (lValue)
  485. {
  486. case 0: // Deny
  487. Button_SetCheck( GetDlgItem( hDlg, g_ChoiceOptions[i].dwCtlIdDeny ), BST_CHECKED );
  488. break;
  489. case 1: // Allow
  490. Button_SetCheck( GetDlgItem( hDlg, g_ChoiceOptions[i].dwCtlIdAllow ), BST_CHECKED );
  491. break;
  492. default: // don't care / unknown value
  493. Button_SetCheck( GetDlgItem( hDlg, g_ChoiceOptions[i].dwCtlIdDontCare ), BST_CHECKED );
  494. break;
  495. }
  496. }
  497. }
  498. }
  499. if (!pCS)
  500. goto Cleanup;
  501. switch (message)
  502. {
  503. case WM_HELP:
  504. case WM_CONTEXTMENU:
  505. {
  506. MMCPropertyHelp( RIGPSNAP_HELP_TOPIC );
  507. }
  508. break;
  509. case WM_COMMAND:
  510. if ( ( LOWORD(wParam) >= IDC_FIRST_RADIO_BUTTON )
  511. && ( LOWORD(wParam) <= IDC_LAST_RADIO_BUTTON ) )
  512. {
  513. if ( !bDirty )
  514. {
  515. SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0);
  516. bDirty = TRUE;
  517. }
  518. }
  519. break;
  520. case WM_NOTIFY:
  521. switch (((NMHDR FAR*)lParam)->code)
  522. {
  523. case PSN_APPLY:
  524. {
  525. if (bDirty)
  526. {
  527. pszPath = SysAllocStringByteLen( NULL, MAX_PATH );
  528. if (!pszPath)
  529. goto Cleanup;
  530. hr = pCS->m_pcd->m_pGPTInformation->GetFileSysPath( GPO_SECTION_USER, pszPath, MAX_PATH );
  531. if (SUCCEEDED(hr))
  532. {
  533. wcscat( pszPath, L"\\Microsoft\\RemoteInstall\\oscfilter.ini");
  534. pCS->_CreateDirectoryIfNeeded( pszPath );
  535. for ( INT i = 0; i < ARRAYSIZE(g_ChoiceOptions); i++ )
  536. {
  537. DWORD dw;
  538. WCHAR szOption[ MAX_OPTION_SIZE ];
  539. dw = LoadString( g_hInstance, g_ChoiceOptions[i].dwValId, szOption, ARRAYSIZE( szOption ));
  540. if ( Button_GetCheck( GetDlgItem( hDlg, g_ChoiceOptions[i].dwCtlIdDeny ) ) == BST_CHECKED )
  541. {
  542. WritePrivateProfileString( L"Choice", szOption, L"0", pszPath );
  543. }
  544. if ( Button_GetCheck( GetDlgItem( hDlg, g_ChoiceOptions[i].dwCtlIdAllow ) ) == BST_CHECKED )
  545. {
  546. WritePrivateProfileString( L"Choice", szOption, L"1", pszPath );
  547. }
  548. if ( Button_GetCheck( GetDlgItem( hDlg, g_ChoiceOptions[i].dwCtlIdDontCare ) ) == BST_CHECKED )
  549. {
  550. WritePrivateProfileString( L"Choice", szOption, NULL, pszPath );
  551. }
  552. }
  553. // Notify the GPT manager that policy has changed
  554. pCS->m_pcd->m_pGPTInformation->PolicyChanged( FALSE, TRUE, (GUID *)&CLSID_RIClientExtension, (GUID *)&CLSID_GPTRemoteInstall );
  555. }
  556. }
  557. }
  558. // fall through...
  559. case PSN_RESET:
  560. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  561. bDirty = FALSE;
  562. fReturn = TRUE;
  563. break;
  564. }
  565. break;
  566. }
  567. Cleanup:
  568. if ( pszPath )
  569. SysFreeString( pszPath );
  570. return fReturn;
  571. }