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.

1201 lines
40 KiB

  1. #include "stdafx.h"
  2. #include "sceattch.h"
  3. #ifdef _DEBUG
  4. #define new DEBUG_NEW
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. // polstore is not threadsafe: we have multiple threads so we wrap critical sections around our calls to polstore
  9. CCriticalSection g_csPolStore;
  10. // Description:
  11. //
  12. // Safe version of strlen, that will not Access Violate if
  13. // passed a bad pointer or a non-null terminated string.
  14. // A non-null terminated string is detected by making
  15. // sure we do not read past the string into memory we do not own.
  16. //
  17. //
  18. // Arguments:
  19. //
  20. // pszStr - Input string.
  21. // pcchStrLen - pointer to variable in which to return string length.
  22. //
  23. // Return Value:
  24. // ERROR_INVALID_PARAMETER - if pszStr points to an invalid string.
  25. // ERROR_SUCCESS
  26. //
  27. DWORD
  28. WlsnpStringLenW(
  29. IN LPCWSTR pszStr,
  30. OUT size_t* pcchStrLen
  31. )
  32. {
  33. BOOL fBadStr = TRUE;
  34. DWORD dwError = ERROR_SUCCESS;
  35. size_t cchStrLen = 0;
  36. if (!pszStr) {
  37. dwError = ERROR_INVALID_PARAMETER;
  38. BAIL_ON_WIN32_ERROR(dwError);
  39. }
  40. __try {
  41. cchStrLen = wcslen(pszStr);
  42. } __except(EXCEPTION_EXECUTE_HANDLER) {
  43. dwError = ERROR_INVALID_PARAMETER;
  44. }
  45. BAIL_ON_WIN32_ERROR(dwError);
  46. *pcchStrLen = cchStrLen;
  47. return dwError;
  48. error:
  49. *pcchStrLen = 0;
  50. return dwError;
  51. }
  52. // Useful string safe function
  53. // Description:
  54. //
  55. // Safe string searching routine that will not Access Violate if
  56. // passed bad pointers or non-null terminated strings.
  57. // pszStartOfMatch is a pointer to the start of the first match
  58. // of the string to search for in the string to search.
  59. //
  60. //
  61. // Arguments:
  62. //
  63. // pszStrToSearch - Input string to search in.
  64. // pszStrToFind - Input string to search for.
  65. // bIsCaseSensitive - if true, perform case sensitive search
  66. // pszStartOfMatch - pointer to first occurrance of pszStrToFind
  67. // within pszStrToSearch
  68. //
  69. // Return Value:
  70. // ERROR_INVALID_PARAMETER - if either input string points to an invalid string.
  71. // ERROR_SUCCESS
  72. //
  73. DWORD
  74. WINAPI
  75. WlsnpStringFindW(
  76. IN LPCWSTR pszStrToSearch,
  77. IN LPCWSTR pszStrToFind,
  78. IN BOOL bIsCaseSensitive,
  79. OUT LPCWSTR* ppszStartOfMatch
  80. )
  81. {
  82. DWORD dwError = ERROR_SUCCESS;
  83. size_t uiSearchLen;
  84. size_t uiFindLen;
  85. size_t i;
  86. *ppszStartOfMatch = 0;
  87. WlsnpStringLenW(pszStrToSearch, &uiSearchLen);
  88. BAIL_ON_WIN32_ERROR(dwError);
  89. WlsnpStringLenW(pszStrToFind, &uiFindLen);
  90. BAIL_ON_WIN32_ERROR(dwError);
  91. i = 0;
  92. if (bIsCaseSensitive)
  93. {
  94. while ((*ppszStartOfMatch == 0) && ((uiSearchLen - i) >= uiFindLen))
  95. {
  96. if (wcsncmp(&pszStrToSearch[i], pszStrToFind, uiFindLen) == 0)
  97. {
  98. *ppszStartOfMatch = &pszStrToSearch[i];
  99. }
  100. ++i;
  101. }
  102. }
  103. else
  104. {
  105. while ((*ppszStartOfMatch == 0) && ((uiSearchLen - i) >= uiFindLen))
  106. {
  107. if (_wcsnicmp(&pszStrToSearch[i], pszStrToFind, uiFindLen) == 0)
  108. {
  109. *ppszStartOfMatch = &pszStrToSearch[i];
  110. }
  111. ++i;
  112. }
  113. }
  114. error:
  115. return dwError;
  116. }
  117. ///////////////////////////////////////////////////////////////////////////////
  118. // IComponentData implementation
  119. DEBUG_DECLARE_INSTANCE_COUNTER(CComponentDataImpl);
  120. CComponentDataImpl::CComponentDataImpl()
  121. {
  122. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  123. DEBUG_INCREMENT_INSTANCE_COUNTER(CComponentDataImpl);
  124. // Initialize members
  125. m_pConsoleNameSpace = NULL;
  126. m_pPrshtProvider = NULL;
  127. m_pConsole = NULL;
  128. m_pRootFolderScopeItem = NULL;
  129. m_bIsDirty = FALSE;
  130. m_enumLocation = LOCATION_LOCAL;
  131. m_bDontDisplayRootFolderProperties = FALSE;
  132. m_bStorageWarningIssued = FALSE;
  133. m_bLocationStorageWarningIssued = FALSE;
  134. m_bAttemptReconnect = TRUE;
  135. m_bNeedCleanUpWSA = FALSE;
  136. m_hPolicyStore = NULL;
  137. m_pScopeRootFolder = NULL;
  138. m_pGPEInformation = NULL;
  139. m_bRsop = FALSE;
  140. m_pRSOPInformation = NULL;
  141. #ifdef _DEBUG
  142. m_cDataObjects = 0;
  143. #endif
  144. // create our initial folder
  145. CComObject <CWirelessManagerFolder>::CreateInstance(&m_pScopeRootFolder);
  146. if (m_pScopeRootFolder == NULL)
  147. {
  148. // note: we are in a seriously bad state(!)
  149. // but this is ok, because we will now 'fail to initialize' and
  150. // mmc deals ok
  151. return;
  152. }
  153. // we are storing, and later using, m_pScopeRootFolder so AddRef it
  154. m_pScopeRootFolder->AddRef();
  155. m_pScopeRootFolder->SetDataObjectType( CCT_SCOPE );
  156. m_pScopeRootFolder->Initialize (this, NULL, FOLDER_IMAGE_IDX, OPEN_FOLDER_IMAGE_IDX, FALSE);
  157. m_pScopeRootFolder->GetScopeItem()->mask |= SDI_PARAM;
  158. m_pScopeRootFolder->GetScopeItem()->lParam = (LPARAM)m_pScopeRootFolder;
  159. #ifdef _DEBUG
  160. m_pScopeRootFolder->SetComponentData(this);
  161. #endif
  162. }
  163. CComponentDataImpl::~CComponentDataImpl()
  164. {
  165. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  166. DEBUG_DECREMENT_INSTANCE_COUNTER(CComponentDataImpl);
  167. // Some snap-in is hanging on to data objects.
  168. // If they access, it will crash!!!
  169. ASSERT(m_cDataObjects == 0);
  170. // release our interfaces
  171. SAFE_RELEASE(m_pScopeRootFolder); // triggers delete up sub folders
  172. SAFE_RELEASE(m_pConsoleNameSpace);
  173. SAFE_RELEASE(m_pConsole);
  174. SAFE_RELEASE(m_pPrshtProvider);
  175. SAFE_RELEASE(m_pGPEInformation);
  176. // cleanup winsock if we got it
  177. if (m_bNeedCleanUpWSA)
  178. WSACleanup();
  179. }
  180. STDMETHODIMP CComponentDataImpl::Initialize(LPUNKNOWN pUnknown)
  181. {
  182. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  183. HRESULT hr = E_UNEXPECTED;
  184. // TODO: clean this up and add error checking!
  185. ASSERT(pUnknown != NULL);
  186. // MMC should only call ::Initialize once!
  187. ASSERT(m_pConsoleNameSpace == NULL);
  188. pUnknown->QueryInterface(IID_IConsoleNameSpace, reinterpret_cast<void**>(&m_pConsoleNameSpace));
  189. pUnknown->QueryInterface(IID_IPropertySheetProvider, reinterpret_cast<void**>(&m_pPrshtProvider));
  190. // add the images for the scope tree
  191. CBitmap bmp16x16;
  192. LPIMAGELIST lpScopeImage;
  193. hr = pUnknown->QueryInterface(IID_IConsole, reinterpret_cast<void**>(&m_pConsole));
  194. ASSERT(hr == S_OK);
  195. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  196. ASSERT(hr == S_OK);
  197. // Load the bitmaps from the dll
  198. bmp16x16.LoadBitmap(IDB_16x16);
  199. // Set the images
  200. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp16x16)),
  201. reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp16x16)), 0, RGB(255, 0, 255));
  202. lpScopeImage->Release();
  203. // attempt to start winsock
  204. WORD wsaVersion = MAKEWORD(2,0);
  205. DWORD dwRet;
  206. dwRet = WSAStartup(wsaVersion, &wsaData);
  207. ASSERT (0 == dwRet);
  208. if (0 == dwRet)
  209. {
  210. // make sure we got a version we expected, but don't really
  211. // bother with any other failures as all this will effect is the
  212. // DNS lookup, which will just cram in a DNS name without looking
  213. // it up first... shrug.
  214. if ((LOBYTE(wsaData.wVersion) != LOBYTE(wsaVersion)) ||
  215. (HIBYTE(wsaData.wVersion) != HIBYTE(wsaVersion))) {
  216. WSACleanup();
  217. }
  218. else
  219. {
  220. m_bNeedCleanUpWSA = TRUE;
  221. }
  222. }
  223. return S_OK;
  224. }
  225. DWORD
  226. CComponentDataImpl::OpenPolicyStore(
  227. )
  228. {
  229. DWORD dwError = 0;
  230. HANDLE hPolicyStore = NULL;
  231. if (m_hPolicyStore)
  232. {
  233. WirelessClosePolicyStore(m_hPolicyStore);
  234. m_hPolicyStore = NULL;
  235. }
  236. DWORD dwProvider = WIRELESS_REGISTRY_PROVIDER;
  237. CString strLocationName;
  238. CString strDSGPOName;
  239. switch(EnumLocation())
  240. {
  241. case LOCATION_REMOTE:
  242. strLocationName = RemoteMachineName();
  243. break;
  244. case LOCATION_GLOBAL:
  245. strLocationName = RemoteMachineName();
  246. strDSGPOName = DomainGPOName();
  247. dwProvider = WIRELESS_DIRECTORY_PROVIDER;
  248. break;
  249. case LOCATION_WMI:
  250. strLocationName = RemoteMachineName(); //rsop namespace
  251. dwProvider = WIRELESS_WMI_PROVIDER;
  252. break;
  253. case LOCATION_LOCAL:
  254. default:
  255. break;
  256. }
  257. /*
  258. dwError = WirelessOpenPolicyStore(
  259. (LPWSTR) (LPCWSTR) strLocationName,
  260. dwProvider,
  261. NULL,
  262. &hPolicyStore
  263. );
  264. */
  265. dwError = WirelessGPOOpenPolicyStore(
  266. (LPWSTR) (LPCWSTR) strLocationName,
  267. dwProvider,
  268. (LPWSTR) (LPCWSTR) strDSGPOName,
  269. NULL,
  270. &hPolicyStore
  271. );
  272. if (dwError) {
  273. Destroy();
  274. return(dwError);
  275. }
  276. m_hPolicyStore = hPolicyStore;
  277. return dwError;
  278. }
  279. STDMETHODIMP CComponentDataImpl::CreateComponent(LPCOMPONENT* ppComponent)
  280. {
  281. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  282. ASSERT(ppComponent != NULL);
  283. CComObject<CComponentImpl>* pObject;
  284. CComObject<CComponentImpl>::CreateInstance(&pObject);
  285. ASSERT(pObject != NULL);
  286. // Store IComponentData
  287. pObject->SetIComponentData(this);
  288. return pObject->QueryInterface(IID_IComponent, reinterpret_cast<void**>(ppComponent));
  289. }
  290. STDMETHODIMP CComponentDataImpl::Notify(LPDATAOBJECT pDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  291. {
  292. OPT_TRACE( _T("CComponentDataImpl::Notify pDataObject-%p\n"), pDataObject );
  293. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  294. ASSERT(m_pConsoleNameSpace != NULL);
  295. HRESULT hr = S_FALSE;
  296. // Need pDataObject unless the event is one of these:
  297. // -MMCN_PROPERTY_CHANGE because this event is generated by a
  298. // MMCPropertyChangeNotify() which does not take pDataObject as an argument.
  299. //
  300. // -MMCN_COLUMN_CLICK because it is defined as having a NULL pDataObject.
  301. if (pDataObject == NULL && MMCN_PROPERTY_CHANGE != event && MMCN_COLUMN_CLICK != event)
  302. {
  303. TRACE(_T("CComponentDataImpl::Notify ERROR(?) called with pDataObject==NULL on event-%i\n"), event);
  304. // Is this an event for which there should be no IDataObj? If so, add it to
  305. // the if statement above.
  306. ASSERT( FALSE );
  307. return E_UNEXPECTED;
  308. }
  309. switch(event)
  310. {
  311. case MMCN_REMOVE_CHILDREN:
  312. {
  313. //
  314. // In RSoP, we may get called to refresh the scope pane when the query
  315. // is re-executed -- if this happens, current nodes will be removed and
  316. // we must reset all of our cached information. We reset the relevant
  317. // information below
  318. //
  319. if ( ((HSCOPEITEM)arg != NULL) && m_bRsop && (m_pRSOPInformation != NULL) )
  320. {
  321. m_pRSOPInformation->Release();
  322. m_pRSOPInformation = NULL;
  323. }
  324. break;
  325. }
  326. case MMCN_EXPANDSYNC:
  327. {
  328. //this event is not supported
  329. return S_FALSE;
  330. break;
  331. }
  332. case MMCN_EXPAND:
  333. {
  334. if (pDataObject)
  335. {
  336. // if we are an extension snap-in, IDataObject is from the parent snap-in and so it
  337. // won't know about the IID_IWirelessSnapInDataObject interface. Otherwise we created
  338. // the root now (IDataObject) so it does respond to the query, and we don't want
  339. // to do our extension snapin stuff
  340. CComQIPtr <IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
  341. if ( spData )
  342. {
  343. //should be internal format, as the external snapin does not know about our format
  344. return spData->Notify( event, arg, param, TRUE, m_pConsole, NULL );
  345. }
  346. else
  347. {
  348. //we may be in extension sanpin now
  349. UINT cfModeType = RegisterClipboardFormat(CCF_SCE_RSOP_UNKNOWN);
  350. STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
  351. FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  352. ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
  353. if (NULL == ObjMediumMode.hGlobal)
  354. {
  355. DWORD dwError = GetLastError();
  356. hr = HRESULT_FROM_WIN32(dwError);
  357. return hr;
  358. }
  359. hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
  360. LPUNKNOWN pUnkRSOP = *((LPUNKNOWN*) (ObjMediumMode.hGlobal));
  361. ASSERT (pUnkRSOP);
  362. if(pUnkRSOP) {
  363. if ( m_pRSOPInformation )
  364. {
  365. m_pRSOPInformation->Release();
  366. m_pRSOPInformation = NULL;
  367. }
  368. hr = pUnkRSOP->QueryInterface(IID_IRSOPInformation, (LPVOID *)&m_pRSOPInformation);
  369. pUnkRSOP->Release();
  370. }
  371. GlobalFree(ObjMediumMode.hGlobal);
  372. if(m_pRSOPInformation)
  373. {
  374. m_bRsop = TRUE;
  375. }
  376. if(m_pRSOPInformation)
  377. {
  378. ////RSOP case
  379. UINT cfModeType = RegisterClipboardFormat(CCF_SCE_MODE_TYPE);
  380. STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
  381. FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  382. ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
  383. if (NULL == ObjMediumMode.hGlobal)
  384. {
  385. DWORD dwError = GetLastError();
  386. m_pRSOPInformation->Release();
  387. m_pRSOPInformation = NULL;
  388. return HRESULT_FROM_WIN32(dwError);
  389. }
  390. DWORD dwSCEMode = SCE_MODE_UNKNOWN;
  391. hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
  392. dwSCEMode = *(DWORD*)(ObjMediumMode.hGlobal);
  393. GlobalFree(ObjMediumMode.hGlobal);
  394. //Bug296532, Wireless shouldn't show up as an extention unless we are in
  395. // the following SCE modes
  396. if (!
  397. (SCE_MODE_LOCAL_COMPUTER == dwSCEMode ||
  398. SCE_MODE_DOMAIN_COMPUTER == dwSCEMode ||
  399. SCE_MODE_OU_COMPUTER == dwSCEMode ||
  400. SCE_MODE_REMOTE_COMPUTER == dwSCEMode ||
  401. SCE_MODE_RSOP_COMPUTER == dwSCEMode)
  402. )
  403. {
  404. m_pRSOPInformation->Release();
  405. m_pRSOPInformation = NULL;
  406. hr = S_FALSE;
  407. return hr;
  408. }
  409. const int cchMaxLength = 512;
  410. WCHAR szNameSpace[cchMaxLength];
  411. if (m_pRSOPInformation->GetNamespace(GPO_SECTION_MACHINE, szNameSpace, cchMaxLength) == S_OK)
  412. {
  413. RemoteMachineName(szNameSpace);
  414. }
  415. else
  416. {
  417. RemoteMachineName (L"");
  418. }
  419. EnumLocation (LOCATION_WMI);
  420. m_pScopeRootFolder->SetExtScopeObject( m_pScopeRootFolder );
  421. } //if(m_pRSOPInformation)
  422. else
  423. {
  424. // The GPT knows where we are loaded from (DS, Local, Remote)
  425. // and will provide that information via its interface
  426. UINT cfModeType = RegisterClipboardFormat(CCF_SCE_GPT_UNKNOWN);
  427. STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
  428. FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  429. ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
  430. if (NULL == ObjMediumMode.hGlobal)
  431. {
  432. DWORD dwError = GetLastError();
  433. hr = HRESULT_FROM_WIN32(dwError);
  434. return hr;
  435. }
  436. hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
  437. // yes, CCF_SCE_GPT_UNKNOWN implies a GPT unknown, but what we actually
  438. // get is an unknown for a GPE!!
  439. LPUNKNOWN pUnkGPE = *((LPUNKNOWN*) (ObjMediumMode.hGlobal));
  440. ASSERT (pUnkGPE);
  441. // if we didn't get an IUNKNOWN something is serously wrong
  442. if (pUnkGPE == NULL)
  443. {
  444. GlobalFree(ObjMediumMode.hGlobal);
  445. hr = E_FAIL;
  446. return hr;
  447. }
  448. // need to look for the GPE interface
  449. if ( m_pGPEInformation )
  450. {
  451. m_pGPEInformation->Release();
  452. m_pGPEInformation = NULL;
  453. }
  454. hr = pUnkGPE->QueryInterface(cGPEguid, (void**) &m_pGPEInformation);
  455. // this is an alternative way of doing that QI if we wanted, I like the
  456. // more direct approach
  457. // CComQIPtr <IGPTInformation, &cGPTguid> spGPTInformation(pUnkGPT);
  458. // since calling GetDataHere is equivalent (so to speak) to a CreateInstance call
  459. // we need to release the IUnknown
  460. pUnkGPE->Release();
  461. GlobalFree(ObjMediumMode.hGlobal);
  462. // check to see if we got it
  463. if (m_pGPEInformation != NULL)
  464. {
  465. UINT cfModeType = RegisterClipboardFormat(CCF_SCE_MODE_TYPE);
  466. STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
  467. FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  468. ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
  469. if (NULL == ObjMediumMode.hGlobal)
  470. {
  471. DWORD dwError = GetLastError();
  472. return HRESULT_FROM_WIN32(dwError);
  473. }
  474. DWORD dwSCEMode = SCE_MODE_UNKNOWN;
  475. hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
  476. dwSCEMode = *(DWORD*)(ObjMediumMode.hGlobal);
  477. GlobalFree(ObjMediumMode.hGlobal);
  478. //Bug296532, Wireless shouldn't show up as an extention unless we are in
  479. // the following SCE modes
  480. if (!
  481. (SCE_MODE_LOCAL_COMPUTER == dwSCEMode ||
  482. SCE_MODE_DOMAIN_COMPUTER == dwSCEMode ||
  483. SCE_MODE_OU_COMPUTER == dwSCEMode ||
  484. SCE_MODE_REMOTE_COMPUTER == dwSCEMode ||
  485. SCE_MODE_RSOP_COMPUTER == dwSCEMode)
  486. )
  487. {
  488. m_pGPEInformation->Release();
  489. m_pGPEInformation = NULL;
  490. return S_FALSE;
  491. }
  492. CString strName;
  493. m_pGPEInformation->GetName (strName.GetBuffer(MAX_PATH), MAX_PATH);
  494. strName.ReleaseBuffer (-1);
  495. GROUP_POLICY_OBJECT_TYPE gpoType;
  496. m_pGPEInformation->GetType (&gpoType);
  497. switch (gpoType)
  498. {
  499. case GPOTypeLocal:
  500. {
  501. // redirect to local machine
  502. RemoteMachineName (L"");
  503. EnumLocation (LOCATION_LOCAL);
  504. hr = S_FALSE;
  505. return(hr);
  506. break;
  507. }
  508. case GPOTypeRemote:
  509. // redirect to the GetName machine
  510. RemoteMachineName (strName);
  511. EnumLocation (LOCATION_REMOTE);
  512. break;
  513. case GPOTypeDS:
  514. {
  515. hr = GetDomainDnsName(strName);
  516. if ( FAILED(hr) )
  517. return hr;
  518. RemoteMachineName (strName);
  519. hr = GetDomainGPOName(strName);
  520. if ( FAILED(hr) )
  521. return hr;
  522. DomainGPOName(strName);
  523. EnumLocation (LOCATION_GLOBAL);
  524. break;
  525. }
  526. }//switch (gpoType)
  527. // we save the m_pGPEInformation interface for later use instead of:
  528. // pGPEInformation->Release();
  529. }//if (m_pGPEInformation != NULL)
  530. // If we made it here we were loaded as an extension snap-in. Only do this once.
  531. m_pScopeRootFolder->SetExtScopeObject( m_pScopeRootFolder );
  532. } //else if(m_pRSOPInformation)
  533. }
  534. } //if (pDataObject)
  535. break;
  536. } //case MMCN_EXPAND
  537. default:
  538. break;
  539. }//switch
  540. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
  541. if (spData == NULL)
  542. {
  543. // Either we are loaded as an extension snapin (so it doesn't know about our
  544. // internal interface), or pDataObject is NULL. In either case, we can pass
  545. // the event on.
  546. LPUNKNOWN pUnkScope;
  547. if (NULL != m_pScopeRootFolder->GetExtScopeObject())
  548. {
  549. // We are loaded as an extension snapin, let the designated extension
  550. // scope object handle the event.
  551. pUnkScope = reinterpret_cast<LPUNKNOWN>(m_pScopeRootFolder->GetExtScopeObject());
  552. }
  553. else
  554. {
  555. // Let our static scope object handle the event.
  556. pUnkScope = reinterpret_cast<LPUNKNOWN>(m_pScopeRootFolder);
  557. }
  558. // Pass on event
  559. ASSERT( NULL != pUnkScope );
  560. if (NULL != pUnkScope)
  561. {
  562. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject>
  563. spExtData( pUnkScope );
  564. if (spExtData != NULL)
  565. {
  566. return spExtData->Notify( event, arg, param, TRUE, m_pConsole, NULL );
  567. }
  568. ASSERT( FALSE );
  569. }
  570. TRACE(_T("CComponentDataImpl::Notify - QI for IWirelessSnapInDataObject failed\n"));
  571. ASSERT( FALSE );
  572. hr = E_UNEXPECTED;
  573. }
  574. else
  575. {
  576. return spData->Notify( event, arg, param, TRUE, m_pConsole, NULL );
  577. }
  578. return hr;
  579. }
  580. HRESULT CComponentDataImpl::GetDomainGPOName(CString & strName)
  581. {
  582. WCHAR szADsPathName[MAX_PATH];
  583. HRESULT hr = S_OK;
  584. CString szName;
  585. CString szPrefixName;
  586. hr = m_pGPEInformation->GetDSPath(
  587. GPO_SECTION_MACHINE,
  588. szADsPathName,
  589. MAX_PATH
  590. );
  591. //Truncate the LDAP:// from the string
  592. szName = _wcsninc( szADsPathName, 7);
  593. //szPrefixName = L"CN=Windows,CN=Microsoft,";
  594. //strName = szPrefixName+szName;
  595. strName = szName;
  596. return hr;
  597. }
  598. HRESULT CComponentDataImpl::GetDomainDnsName(CString & strName)
  599. {
  600. WCHAR szADsPathName[MAX_PATH];
  601. WCHAR *szDnsName = NULL;
  602. LPCWSTR pszDirectoryName = NULL;
  603. ULONG ulSize = 0;
  604. HRESULT hr = S_OK;
  605. m_pGPEInformation->GetDSPath(
  606. GPO_SECTION_MACHINE,
  607. szADsPathName,
  608. MAX_PATH
  609. );
  610. WlsnpStringFindW(szADsPathName, L"dc=", false, &pszDirectoryName);
  611. TranslateName (
  612. pszDirectoryName , // object name
  613. NameFullyQualifiedDN, // name format
  614. NameCanonical, // new name format
  615. szDnsName, // name buffer
  616. &ulSize // buffer size
  617. );
  618. szDnsName = (WCHAR *) LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)* (ulSize+1));
  619. if ( szDnsName == NULL )
  620. {
  621. hr = E_OUTOFMEMORY;
  622. return hr;
  623. }
  624. if ( !TranslateName (
  625. pszDirectoryName , // object name
  626. NameFullyQualifiedDN, // name format
  627. NameCanonical, // new name format
  628. szDnsName, // name buffer
  629. &ulSize // buffer size
  630. ))
  631. {
  632. hr = HRESULT_FROM_WIN32(GetLastError());
  633. LocalFree( szDnsName );
  634. return hr;
  635. }
  636. if ( szDnsName[lstrlen(szDnsName) -1 ] == _T('/') )
  637. {
  638. szDnsName[lstrlen(szDnsName) -1 ] = _T('\0');
  639. }
  640. strName = szDnsName;
  641. LocalFree( szDnsName );
  642. return hr;
  643. }
  644. STDMETHODIMP CComponentDataImpl::Destroy()
  645. {
  646. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  647. // since they are shutting us down, we use our static node
  648. // Use our member data object to handle call.
  649. IUnknown* pUnk = (IUnknown*) NULL;
  650. HRESULT hr = GetStaticScopeObject()->QueryInterface(IID_IUnknown, (void**)&pUnk);
  651. ASSERT (hr == S_OK);
  652. if (NULL == pUnk)
  653. return E_UNEXPECTED;
  654. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
  655. if (spData == NULL)
  656. {
  657. TRACE(_T("CComponentDataImpl::GetDisplayInfo QI for IWirelessSnapInDataObject FAILED\n"));
  658. return E_UNEXPECTED;
  659. }
  660. spData->Destroy ();
  661. // Used our member data object to handle call, release it.
  662. pUnk->Release();
  663. return hr;
  664. }
  665. STDMETHODIMP CComponentDataImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  666. {
  667. OPT_TRACE( _T("CComponentDataImpl::QueryDataObject this-%p, cookie-%p\n"), this, cookie );
  668. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  669. // return failure since we weren't able to get up and running
  670. // causes mmc to report 'snapin failed to initialize'
  671. if (m_pScopeRootFolder == NULL)
  672. {
  673. return E_UNEXPECTED;
  674. }
  675. ASSERT( m_pScopeRootFolder->NodeName().GetLength() ); // we should know our own display name
  676. if (NULL == ppDataObject)
  677. {
  678. TRACE(_T("CComponentDataImpl::QueryDataObject - ERROR ppDataObject is NULL\n"));
  679. return E_UNEXPECTED;
  680. }
  681. *ppDataObject = NULL;
  682. #ifdef _DEBUG
  683. HRESULT hr;
  684. if (cookie == NULL)
  685. {
  686. hr = m_pScopeRootFolder->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
  687. OPT_TRACE(_T(" QI on m_pScopeRootFolder-%p -> pDataObj-%p\n"), m_pScopeRootFolder, *ppDataObject);
  688. ASSERT(hr == S_OK);
  689. ASSERT( NULL != *ppDataObject );
  690. return hr;
  691. }
  692. IUnknown* pUnk = (IUnknown*) cookie;
  693. hr = pUnk->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
  694. OPT_TRACE(_T(" QI on cookie-%p -> pDataObj-%p\n"), cookie, *ppDataObject);
  695. ASSERT(hr == S_OK);
  696. return hr;
  697. #else
  698. if (cookie == NULL)
  699. return m_pScopeRootFolder->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
  700. IUnknown* pUnk = (IUnknown*) cookie;
  701. return pUnk->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
  702. #endif
  703. }
  704. ///////////////////////////////////////////////////////////////////////////////
  705. //// IPersistStream interface members
  706. STDMETHODIMP CComponentDataImpl::GetClassID(CLSID *pClassID)
  707. {
  708. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  709. ASSERT (0);
  710. // TODO: CComponentDataImpl::GetClassID and CComponentImpl::GetClassID are identical (?)
  711. ASSERT(pClassID != NULL);
  712. // Copy the CLSID for this snapin
  713. *pClassID = CLSID_Snapin;
  714. return S_OK;
  715. }
  716. STDMETHODIMP CComponentDataImpl::IsDirty()
  717. {
  718. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  719. // return dirty state
  720. return InternalIsDirty() ? S_OK : S_FALSE;
  721. }
  722. STDMETHODIMP CComponentDataImpl::Load(IStream *pStm)
  723. {
  724. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  725. unsigned long read;
  726. // NOTE: it looks like there is a strange case were the MMC will
  727. // attempt to load the properties for the root node a second (or more)
  728. // time. To do so right click on an item in the results pane and then
  729. // double click on the empty space in the results pane
  730. m_bDontDisplayRootFolderProperties = TRUE;
  731. // read the location enum
  732. HRESULT hr = pStm->Read (&m_enumLocation, sizeof (enum STORAGE_LOCATION), &read);
  733. if ((hr != S_OK) || (read != sizeof (enum STORAGE_LOCATION)))
  734. {
  735. // for debug purposes, we should assert here
  736. ASSERT (0);
  737. // make sure we have a valid (even if incorrect) value
  738. m_enumLocation = LOCATION_LOCAL;
  739. // TODO: look into better return value(s)
  740. return E_UNEXPECTED;
  741. }
  742. // read the size of the location string
  743. unsigned int iStrLen;
  744. hr = pStm->Read (&iStrLen, sizeof (unsigned int), &read);
  745. if ((hr == S_OK) && (read == sizeof (unsigned int)))
  746. {
  747. // read the string itself
  748. LPCTSTR szStr = (LPCTSTR) malloc (iStrLen);
  749. hr = pStm->Read ((void*) szStr, iStrLen, &read);
  750. if ((hr == S_OK) && (read == iStrLen))
  751. {
  752. m_sRemoteMachineName = szStr;
  753. free ((void*)szStr);
  754. // we don't want to allow the location page to come up
  755. if (m_pScopeRootFolder)
  756. {
  757. m_pScopeRootFolder->LocationPageDisplayEnable(FALSE);
  758. }
  759. return S_OK;
  760. }
  761. // need to delete here as well
  762. free ((void*)szStr);
  763. }
  764. // we only get to here in an error situation
  765. ASSERT (0);
  766. // make sure we have a valid (even if incorrect) value
  767. m_enumLocation = LOCATION_GLOBAL;
  768. m_sRemoteMachineName = _T("");
  769. // TODO: look into better return value(s)
  770. return E_UNEXPECTED;
  771. }
  772. STDMETHODIMP CComponentDataImpl::Save(IStream *pStm, BOOL fClearDirty)
  773. {
  774. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  775. unsigned long written;
  776. // save the storage location
  777. HRESULT hr = pStm->Write(&m_enumLocation, sizeof (enum STORAGE_LOCATION), &written);
  778. if ((hr != S_OK) || (written != sizeof (enum STORAGE_LOCATION)))
  779. {
  780. ASSERT (0);
  781. // TODO: look into better return value(s)
  782. return E_UNEXPECTED;
  783. }
  784. // save the length of the location string
  785. unsigned int iStrLen = m_sRemoteMachineName.GetLength()*sizeof(wchar_t)+sizeof(wchar_t);
  786. hr = pStm->Write(&iStrLen, sizeof (unsigned int), &written);
  787. if ((hr != S_OK) || (written != sizeof (unsigned int)))
  788. {
  789. ASSERT (0);
  790. // TODO: look into better return value(s)
  791. return E_UNEXPECTED;
  792. }
  793. // save the location string itself
  794. hr = pStm->Write((LPCTSTR) m_sRemoteMachineName, iStrLen, &written);
  795. if ((hr != S_OK) || (written != iStrLen))
  796. {
  797. ASSERT (0);
  798. // TODO: look into better return value(s)
  799. return E_UNEXPECTED;
  800. }
  801. // if fClearDirty we clear it out
  802. if (fClearDirty == TRUE)
  803. {
  804. ClearDirty();
  805. }
  806. return S_OK;
  807. }
  808. STDMETHODIMP CComponentDataImpl::GetSizeMax(ULARGE_INTEGER *pcbSize)
  809. {
  810. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  811. // Set the size of the string to be saved
  812. ULISet32(*pcbSize, sizeof (enum STORAGE_LOCATION));
  813. return S_OK;
  814. }
  815. STDMETHODIMP CComponentDataImpl::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
  816. {
  817. if (pScopeDataItem == NULL)
  818. {
  819. TRACE(_T("CComponentDataImpl::GetDisplayInfo called with pScopeDataItem == NULL\n"));
  820. return E_UNEXPECTED;
  821. }
  822. IUnknown* pUnk = (IUnknown*) pScopeDataItem->lParam;
  823. if (pUnk == NULL)
  824. {
  825. // Use our member data object to handle call.
  826. HRESULT hr = GetStaticScopeObject()->QueryInterface(IID_IUnknown, (void**)&pUnk);
  827. ASSERT (hr == S_OK);
  828. if (NULL == pUnk)
  829. return E_UNEXPECTED;
  830. }
  831. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
  832. if (spData == NULL)
  833. {
  834. TRACE(_T("CComponentDataImpl::GetDisplayInfo QI for IWirelessSnapInDataObject FAILED\n"));
  835. return E_UNEXPECTED;
  836. }
  837. HRESULT hr = spData->GetScopeDisplayInfo( pScopeDataItem );
  838. if (NULL == pScopeDataItem->lParam)
  839. // Used our member data object to handle call, release it.
  840. pUnk->Release();
  841. return hr;
  842. }
  843. STDMETHODIMP CComponentDataImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  844. {
  845. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  846. ASSERT (0);
  847. return E_UNEXPECTED;
  848. // NOTE: to implement look to CComponentImpl::CompareObjects
  849. }
  850. /////////////////////////////////////////////////////////////////////////////
  851. // IExtendPropertySheet Implementation
  852. STDMETHODIMP CComponentDataImpl::QueryPagesFor(LPDATAOBJECT lpDataObject)
  853. {
  854. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  855. if (lpDataObject == NULL)
  856. {
  857. TRACE(_T("CComponentDataImpl::QueryPagesFor called with lpDataObject == NULL\n"));
  858. return E_UNEXPECTED;
  859. }
  860. CComQIPtr <IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
  861. if (spData == NULL)
  862. {
  863. TRACE(_T("CComponentDataImpl::QueryPagesFor - QI for IWirelessSnapInDataObject FAILED\n"));
  864. ASSERT( FALSE );
  865. return E_UNEXPECTED;
  866. }
  867. return spData->QueryPagesFor();
  868. }
  869. STDMETHODIMP CComponentDataImpl::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpDataObject)
  870. {
  871. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  872. if (lpDataObject == NULL)
  873. {
  874. TRACE(_T("CComponentDataImpl::CreatePropertyPages called with lpDataObject==NULL\n"));
  875. return E_UNEXPECTED;
  876. }
  877. CComQIPtr <IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
  878. if (spData == NULL)
  879. {
  880. TRACE(_T("CComponentDataImpl::CreatePropertyPages QI for IWirelessSnapInDataObject FAILED\n"));
  881. return E_UNEXPECTED;
  882. }
  883. return spData->CreatePropertyPages( lpProvider, handle );
  884. }
  885. #ifdef WIZ97WIZARDS
  886. STDMETHODIMP CComponentDataImpl::GetWatermarks (LPDATAOBJECT lpDataObject, HBITMAP* lphWatermark, HBITMAP* lphHeader, HPALETTE* lphPalette, BOOL* bStretch)
  887. {
  888. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  889. CBitmap* pbmpWatermark = new CBitmap;
  890. CBitmap* pbmpHeader = new CBitmap;
  891. if ((pbmpWatermark == NULL) || (pbmpHeader == NULL))
  892. return E_UNEXPECTED;
  893. // Load the bitmaps
  894. pbmpWatermark->LoadBitmap(IDB_WPOLICY);
  895. pbmpHeader->LoadBitmap(IDB_BPOLICY);
  896. *lphWatermark = static_cast<HBITMAP>(*pbmpWatermark);
  897. *lphHeader = static_cast<HBITMAP>(*pbmpHeader);
  898. *lphPalette = NULL;
  899. *bStretch = TRUE;
  900. return S_OK;
  901. }
  902. #endif
  903. STDMETHODIMP CComponentDataImpl::AddMenuItems(LPDATAOBJECT lpDataObject, LPCONTEXTMENUCALLBACK pContextMenuCallback, long *pInsertionAllowed)
  904. {
  905. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  906. if (lpDataObject == NULL)
  907. {
  908. TRACE(_T("CComponentDataImpl::AddMenuItems called with piDataObject==NULL\n"));
  909. return E_UNEXPECTED;
  910. }
  911. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
  912. if (spData == NULL)
  913. {
  914. TRACE(_T("CComponentDataImpl::AddMenuItems QI for IWirelessSnapInDataObject FAILED\n"));
  915. return E_UNEXPECTED;
  916. }
  917. return spData->AddMenuItems( pContextMenuCallback, pInsertionAllowed );
  918. }
  919. STDMETHODIMP CComponentDataImpl::Command(long nCommandID, LPDATAOBJECT lpDataObject)
  920. {
  921. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  922. ASSERT( NULL != m_pConsoleNameSpace );
  923. if (lpDataObject == NULL)
  924. {
  925. TRACE(_T("CComponentDataImpl::Command called with lpDataObject==NULL\n"));
  926. return E_UNEXPECTED;
  927. }
  928. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
  929. if (spData == NULL)
  930. {
  931. TRACE(_T("CComponentDataImpl::Command QI for IWirelessSnapInDataObject FAILED\n"));
  932. return E_UNEXPECTED;
  933. }
  934. return spData->Command( nCommandID, m_pConsoleNameSpace );
  935. }
  936. STDMETHODIMP CComponentDataImpl::GetHelpTopic (LPOLESTR* lpCompiledHelpFile)
  937. {
  938. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  939. if (lpCompiledHelpFile == NULL)
  940. return E_POINTER;
  941. // need to form a complete path to the .chm file
  942. CString s, s2;
  943. s.LoadString(IDS_HELPCONTENTSFILE);
  944. DWORD dw = ExpandEnvironmentStrings (s, s2.GetBuffer (512), 512);
  945. s2.ReleaseBuffer (-1);
  946. if ((dw == 0) || (dw > 512))
  947. {
  948. return E_UNEXPECTED;
  949. }
  950. *lpCompiledHelpFile = reinterpret_cast<LPOLESTR>
  951. (CoTaskMemAlloc((s2.GetLength() + 1)* sizeof(wchar_t)));
  952. if (*lpCompiledHelpFile == NULL)
  953. return E_OUTOFMEMORY;
  954. USES_CONVERSION;
  955. wcscpy(*lpCompiledHelpFile, T2OLE((LPTSTR)(LPCTSTR)s2));
  956. return S_OK;
  957. }
  958. void CComponentDataImpl::EnumLocation (enum STORAGE_LOCATION enumLocation)
  959. {
  960. SetDirty();
  961. m_enumLocation = enumLocation;
  962. // our enumlocation changed, so we should change the nodename of our
  963. // manager folder
  964. if (m_pScopeRootFolder)
  965. {
  966. m_pScopeRootFolder->SetNodeNameByLocation();
  967. }
  968. }
  969. ///////////////////////////////////////////////////////////////////////////////
  970. // class CComponentDataPrimaryImpl : IComponentData implementation
  971. CComponentDataPrimaryImpl::CComponentDataPrimaryImpl() : CComponentDataImpl()
  972. {
  973. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  974. ASSERT( NULL != GetStaticScopeObject() );
  975. // Store the coclass with the data object
  976. // GetStaticScopeObject()->INTERNALclsid( GetCoClassID() );
  977. GetStaticScopeObject()->clsid (GetCoClassID());
  978. }