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.

548 lines
15 KiB

  1. // LogUICtl.cpp : Implementation of the CLogUICtrl OLE control class.
  2. #include "stdafx.h"
  3. #include "cnfgprts.h"
  4. #include "LogUICtl.h"
  5. #include "LogUIPpg.h"
  6. #include <iiscnfg.h>
  7. #include "initguid.h"
  8. #include <inetcom.h>
  9. #include <logtype.h>
  10. #include <ilogobj.hxx>
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. IMPLEMENT_DYNCREATE(CLogUICtrl, COleControl)
  17. /////////////////////////////////////////////////////////////////////////////
  18. // Message map
  19. BEGIN_MESSAGE_MAP(CLogUICtrl, COleControl)
  20. //{{AFX_MSG_MAP(CLogUICtrl)
  21. //}}AFX_MSG_MAP
  22. ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
  23. ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
  24. END_MESSAGE_MAP()
  25. /////////////////////////////////////////////////////////////////////////////
  26. // Dispatch map
  27. BEGIN_DISPATCH_MAP(CLogUICtrl, COleControl)
  28. //{{AFX_DISPATCH_MAP(CLogUICtrl)
  29. DISP_FUNCTION(CLogUICtrl, "SetAdminTarget", SetAdminTarget, VT_EMPTY, VTS_BSTR VTS_BSTR)
  30. DISP_FUNCTION(CLogUICtrl, "ApplyLogSelection", ApplyLogSelection, VT_EMPTY, VTS_NONE)
  31. DISP_FUNCTION(CLogUICtrl, "SetComboBox", SetComboBox, VT_EMPTY, VTS_HANDLE)
  32. DISP_FUNCTION(CLogUICtrl, "Terminate", Terminate, VT_EMPTY, VTS_NONE)
  33. DISP_FUNCTION(CLogUICtrl, "SetUserData", SetUserData, VT_EMPTY, VTS_BSTR VTS_BSTR)
  34. DISP_STOCKFUNC_DOCLICK()
  35. DISP_STOCKPROP_CAPTION()
  36. DISP_STOCKPROP_FONT()
  37. DISP_STOCKPROP_ENABLED()
  38. DISP_STOCKPROP_BORDERSTYLE()
  39. //}}AFX_DISPATCH_MAP
  40. END_DISPATCH_MAP()
  41. /////////////////////////////////////////////////////////////////////////////
  42. // Event map
  43. BEGIN_EVENT_MAP(CLogUICtrl, COleControl)
  44. //{{AFX_EVENT_MAP(CLogUICtrl)
  45. EVENT_STOCK_CLICK()
  46. EVENT_STOCK_KEYUP()
  47. EVENT_STOCK_KEYDOWN()
  48. EVENT_STOCK_KEYPRESS()
  49. //}}AFX_EVENT_MAP
  50. END_EVENT_MAP()
  51. /////////////////////////////////////////////////////////////////////////////
  52. // Property pages
  53. BEGIN_PROPPAGEIDS(CLogUICtrl, 2)
  54. PROPPAGEID(CLogUIPropPage::guid)
  55. PROPPAGEID(CLSID_CFontPropPage)
  56. END_PROPPAGEIDS(CLogUICtrl)
  57. /////////////////////////////////////////////////////////////////////////////
  58. // Initialize class factory and guid
  59. IMPLEMENT_OLECREATE_EX(CLogUICtrl, "CNFGPRTS.LogUICtrl.1",
  60. 0xba634603, 0xb771, 0x11d0, 0x92, 0x96, 0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b)
  61. /////////////////////////////////////////////////////////////////////////////
  62. // Type library ID and version
  63. IMPLEMENT_OLETYPELIB(CLogUICtrl, _tlid, _wVerMajor, _wVerMinor)
  64. /////////////////////////////////////////////////////////////////////////////
  65. // Interface IDs
  66. const IID BASED_CODE IID_DLogUI =
  67. { 0xba634601, 0xb771, 0x11d0, { 0x92, 0x96, 0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b } };
  68. const IID BASED_CODE IID_DLogUIEvents =
  69. { 0xba634602, 0xb771, 0x11d0, { 0x92, 0x96, 0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b } };
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Control type information
  72. static const DWORD BASED_CODE _dwLogUIOleMisc =
  73. OLEMISC_ACTIVATEWHENVISIBLE |
  74. OLEMISC_SETCLIENTSITEFIRST |
  75. OLEMISC_INSIDEOUT |
  76. OLEMISC_CANTLINKINSIDE |
  77. OLEMISC_ACTSLIKEBUTTON |
  78. OLEMISC_RECOMPOSEONRESIZE;
  79. IMPLEMENT_OLECTLTYPE(CLogUICtrl, IDS_LOGUI, _dwLogUIOleMisc)
  80. /////////////////////////////////////////////////////////////////////////////
  81. // CLogUICtrl::CLogUICtrlFactory::UpdateRegistry -
  82. // Adds or removes system registry entries for CLogUICtrl
  83. BOOL CLogUICtrl::CLogUICtrlFactory::UpdateRegistry(BOOL bRegister)
  84. {
  85. // TODO: Verify that your control follows apartment-model threading rules.
  86. // Refer to MFC TechNote 64 for more information.
  87. // If your control does not conform to the apartment-model rules, then
  88. // you must modify the code below, changing the 6th parameter from
  89. // afxRegApartmentThreading to 0.
  90. if (bRegister)
  91. return AfxOleRegisterControlClass(
  92. AfxGetInstanceHandle(),
  93. m_clsid,
  94. m_lpszProgID,
  95. IDS_LOGUI,
  96. IDB_LOGUI,
  97. afxRegApartmentThreading,
  98. _dwLogUIOleMisc,
  99. _tlid,
  100. _wVerMajor,
  101. _wVerMinor);
  102. else
  103. return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  104. }
  105. /////////////////////////////////////////////////////////////////////////////
  106. // CLogUICtrl::CLogUICtrl - Constructor
  107. CLogUICtrl::CLogUICtrl():
  108. m_fUpdateFont( FALSE ),
  109. m_fComboInit( FALSE ),
  110. m_hAccel( NULL ),
  111. m_cAccel( 0 )
  112. {
  113. InitializeIIDs(&IID_DLogUI, &IID_DLogUIEvents);
  114. }
  115. /////////////////////////////////////////////////////////////////////////////
  116. // CLogUICtrl::~CLogUICtrl - Destructor
  117. CLogUICtrl::~CLogUICtrl()
  118. {
  119. if ( m_hAccel )
  120. DestroyAcceleratorTable( m_hAccel );
  121. m_hAccel = NULL;
  122. }
  123. /////////////////////////////////////////////////////////////////////////////
  124. // CLogUICtrl::OnDraw - Drawing function
  125. void CLogUICtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
  126. {
  127. DoSuperclassPaint(pdc, rcBounds);
  128. }
  129. /////////////////////////////////////////////////////////////////////////////
  130. // CLogUICtrl::DoPropExchange - Persistence support
  131. void CLogUICtrl::DoPropExchange(CPropExchange* pPX)
  132. {
  133. ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  134. COleControl::DoPropExchange(pPX);
  135. }
  136. /////////////////////////////////////////////////////////////////////////////
  137. // CLogUICtrl::OnResetState - Reset control to default state
  138. void CLogUICtrl::OnResetState()
  139. {
  140. COleControl::OnResetState(); // Resets defaults found in DoPropExchange
  141. }
  142. /////////////////////////////////////////////////////////////////////////////
  143. // CLogUICtrl::PreCreateWindow - Modify parameters for CreateWindowEx
  144. BOOL CLogUICtrl::PreCreateWindow(CREATESTRUCT& cs)
  145. {
  146. if ( cs.style & WS_CLIPSIBLINGS )
  147. cs.style ^= WS_CLIPSIBLINGS;
  148. cs.lpszClass = _T("BUTTON");
  149. return COleControl::PreCreateWindow(cs);
  150. }
  151. /////////////////////////////////////////////////////////////////////////////
  152. // CLogUICtrl::IsSubclassedControl - This is a subclassed control
  153. BOOL CLogUICtrl::IsSubclassedControl()
  154. {
  155. return TRUE;
  156. }
  157. /////////////////////////////////////////////////////////////////////////////
  158. // CLogUICtrl::OnOcmCommand - Handle command messages
  159. LRESULT CLogUICtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
  160. {
  161. #ifdef _WIN32
  162. WORD wNotifyCode = HIWORD(wParam);
  163. #else
  164. WORD wNotifyCode = HIWORD(lParam);
  165. #endif
  166. return 0;
  167. }
  168. /////////////////////////////////////////////////////////////////////////////
  169. // CLogUICtrl message handlers
  170. //---------------------------------------------------------------------------
  171. // OLE Interfaced Routine
  172. void CLogUICtrl::OnClick(USHORT iButton)
  173. {
  174. CWaitCursor wait;
  175. CString sz;
  176. sz.LoadString( IDS_LOG_ERR_TITLE );
  177. free((void*)AfxGetApp()->m_pszAppName);
  178. AfxGetApp()->m_pszAppName = _tcsdup(sz);
  179. if (GetSelectedStringIID(sz))
  180. {
  181. IID iid;
  182. HRESULT h = CLSIDFromString((LPTSTR)(LPCTSTR)sz, &iid);
  183. ActivateLogProperties(iid);
  184. }
  185. COleControl::OnClick(iButton);
  186. }
  187. void CLogUICtrl::OnFontChanged()
  188. {
  189. m_fUpdateFont = TRUE;
  190. COleControl::OnFontChanged();
  191. }
  192. void CLogUICtrl::SetAdminTarget(LPCTSTR szMachineName, LPCTSTR szMetaTarget)
  193. {
  194. m_szMachine = szMachineName;
  195. m_szMetaObject = szMetaTarget;
  196. }
  197. void CLogUICtrl::SetUserData(LPCTSTR szName, LPCTSTR szPassword)
  198. {
  199. m_szUserName = szName;
  200. m_szPassword = szPassword;
  201. }
  202. //---------------------------------------------------------------------------
  203. void CLogUICtrl::ActivateLogProperties(REFIID clsidUI)
  204. {
  205. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  206. IClassFactory * pcsfFactory = NULL;
  207. HRESULT hresError;
  208. ILogUIPlugin2 * pUI = NULL;
  209. hresError = CoGetClassObject(clsidUI, CLSCTX_INPROC, NULL, IID_IClassFactory, (void **)&pcsfFactory);
  210. if (SUCCEEDED(hresError))
  211. {
  212. hresError = pcsfFactory->CreateInstance(NULL, IID_LOGGINGUI2, (void **)&pUI);
  213. if (SUCCEEDED(hresError))
  214. {
  215. CString csTempPassword;
  216. m_szPassword.CopyTo(csTempPassword);
  217. pcsfFactory->Release();
  218. hresError = pUI->OnPropertiesEx(
  219. (LPTSTR)(LPCTSTR)m_szMachine,
  220. (LPTSTR)(LPCTSTR)m_szMetaObject,
  221. (LPTSTR)(LPCTSTR)m_szUserName,
  222. (LPTSTR)(LPCTSTR)csTempPassword);
  223. pUI->Release();
  224. }
  225. }
  226. }
  227. void CLogUICtrl::ApplyLogSelection()
  228. {
  229. CString szName;
  230. m_comboBox.GetWindowText( szName );
  231. // if nothing is selected, fail
  232. if (!szName.IsEmpty())
  233. {
  234. CString guid;
  235. CString csTempPassword;
  236. m_szPassword.CopyTo(csTempPassword);
  237. CComAuthInfo auth(m_szMachine, m_szUserName, csTempPassword);
  238. CMetaKey mk(&auth, NULL, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE);
  239. if (mk.Succeeded())
  240. {
  241. CMetabasePath path(TRUE, _T("logging"), szName);
  242. mk.QueryValue(MD_LOG_PLUGIN_MOD_ID, guid, NULL, path);
  243. }
  244. if (!guid.IsEmpty())
  245. {
  246. mk.SetValue(MD_LOG_PLUGIN_ORDER, guid, NULL, m_szMetaObject);
  247. }
  248. }
  249. }
  250. //---------------------------------------------------------------------------
  251. BOOL CLogUICtrl::GetSelectedStringIID( CString &szIID )
  252. {
  253. if (!m_fComboInit)
  254. return FALSE;
  255. BOOL bRes = FALSE;
  256. CString szName;
  257. m_comboBox.GetWindowText( szName );
  258. if (!szName.IsEmpty())
  259. {
  260. CString log_path = _T("/lm/logging"), guid;
  261. CString csTempPassword;
  262. m_szPassword.CopyTo(csTempPassword);
  263. CComAuthInfo auth(m_szMachine, m_szUserName, csTempPassword);
  264. CMetaKey mk(&auth, log_path, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE);
  265. if (mk.Succeeded())
  266. {
  267. mk.QueryValue(MD_LOG_PLUGIN_UI_ID, szIID, NULL, szName);
  268. bRes = mk.Succeeded();
  269. }
  270. }
  271. return bRes;
  272. }
  273. //---------------------------------------------------------------------------
  274. // OLE Interfaced Routine
  275. void CLogUICtrl::SetComboBox(HWND hComboBox)
  276. {
  277. CString szAvailableList;
  278. CString szCurrentModGuid;
  279. // in case there are any errors, prepare the error string
  280. // set the name of the application correctly
  281. szAvailableList.LoadString( IDS_LOG_ERR_TITLE );
  282. AfxGetApp()->m_pszAppName = _tcsdup(szAvailableList);
  283. szAvailableList.Empty();
  284. // attach the combo box
  285. m_comboBox.Attach(hComboBox);
  286. m_fComboInit = TRUE;
  287. CString csTempPassword;
  288. m_szPassword.CopyTo(csTempPassword);
  289. CComAuthInfo auth(m_szMachine, m_szUserName, csTempPassword);
  290. CMetaKey mk(&auth);
  291. if (mk.Succeeded())
  292. {
  293. if (FAILED(mk.QueryValue(MD_LOG_PLUGIN_ORDER, szCurrentModGuid, NULL, m_szMetaObject)))
  294. {
  295. AfxMessageBox( IDS_ERR_LOG_PLUGIN );
  296. return;
  297. }
  298. }
  299. CString info;
  300. CMetabasePath::GetServiceInfoPath(m_szMetaObject, info);
  301. if (FAILED(mk.QueryValue(MD_LOG_PLUGINS_AVAILABLE, szAvailableList, NULL, info)))
  302. {
  303. AfxMessageBox( IDS_ERR_LOG_PLUGIN );
  304. return;
  305. }
  306. CMetaEnumerator me(FALSE, &mk);
  307. CMetabasePath log_path(TRUE, _T("logging"));
  308. CString key, buf;
  309. BOOL fFoundCurrent = FALSE;
  310. while (SUCCEEDED(me.Next(key, log_path)))
  311. {
  312. int idx = 0;
  313. if ((idx = szAvailableList.Find(key)) >= 0)
  314. {
  315. // Log plugin name could include "Custom Logging". Check if this is part of string.
  316. // we should have comma before and after string
  317. BOOL bCommaAfter =
  318. szAvailableList.GetLength() == idx + key.GetLength()
  319. || szAvailableList.GetAt(idx + key.GetLength()) == _T(',');
  320. BOOL bCommaBefore = idx == 0 || szAvailableList.GetAt(idx - 1) == _T(',');
  321. if (!fFoundCurrent)
  322. {
  323. CMetabasePath current_path(FALSE, log_path, key);
  324. mk.QueryValue(MD_LOG_PLUGIN_MOD_ID, buf, NULL, current_path);
  325. fFoundCurrent = (buf == szCurrentModGuid);
  326. if (fFoundCurrent)
  327. {
  328. buf = key;
  329. }
  330. }
  331. if (bCommaBefore && bCommaAfter)
  332. {
  333. m_comboBox.AddString(key);
  334. }
  335. }
  336. }
  337. // select the current item in the combo box
  338. m_comboBox.SelectString(-1, buf);
  339. }
  340. //---------------------------------------------------------------------------
  341. // OLE Interfaced Routine
  342. void CLogUICtrl::Terminate()
  343. {
  344. if ( m_fComboInit )
  345. m_comboBox.Detach();
  346. m_fComboInit = FALSE;
  347. }
  348. //------------------------------------------------------------------------
  349. void CLogUICtrl::OnAmbientPropertyChange(DISPID dispid)
  350. {
  351. BOOL flag;
  352. UINT style;
  353. // do the right thing depending on the dispid
  354. switch ( dispid )
  355. {
  356. case DISPID_AMBIENT_DISPLAYASDEFAULT:
  357. if ( GetAmbientProperty( DISPID_AMBIENT_DISPLAYASDEFAULT, VT_BOOL, &flag ) )
  358. {
  359. style = GetWindowLong(
  360. GetSafeHwnd(), // handle of window
  361. GWL_STYLE // offset of value to retrieve
  362. );
  363. if ( flag )
  364. style |= BS_DEFPUSHBUTTON;
  365. else
  366. style ^= BS_DEFPUSHBUTTON;
  367. SetWindowLong(
  368. GetSafeHwnd(), // handle of window
  369. GWL_STYLE, // offset of value to retrieve
  370. style
  371. );
  372. Invalidate(TRUE);
  373. }
  374. break;
  375. };
  376. COleControl::OnAmbientPropertyChange(dispid);
  377. }
  378. //------------------------------------------------------------------------
  379. // an important method where we tell the container how to deal with us.
  380. // pControlInfo is passed in by the container, although we are responsible
  381. // for maintining the hAccel structure
  382. void CLogUICtrl::OnGetControlInfo(LPCONTROLINFO pControlInfo)
  383. {
  384. if ( !pControlInfo || pControlInfo->cb < sizeof(CONTROLINFO) )
  385. return;
  386. pControlInfo->hAccel = m_hAccel;
  387. pControlInfo->cAccel = m_cAccel;
  388. pControlInfo->dwFlags = CTRLINFO_EATS_RETURN;
  389. }
  390. //------------------------------------------------------------------------
  391. // the ole control container object specifically filters out the space
  392. // key so we do not get it as a OnMnemonic call. Thus we need to look
  393. // for it ourselves
  394. void CLogUICtrl::OnKeyUpEvent(USHORT nChar, USHORT nShiftState)
  395. {
  396. if ( nChar == _T(' ') )
  397. {
  398. OnClick((USHORT)GetDlgCtrlID());
  399. }
  400. COleControl::OnKeyUpEvent(nChar, nShiftState);
  401. }
  402. //------------------------------------------------------------------------
  403. void CLogUICtrl::OnMnemonic(LPMSG pMsg)
  404. {
  405. OnClick((USHORT)GetDlgCtrlID());
  406. COleControl::OnMnemonic(pMsg);
  407. }
  408. //------------------------------------------------------------------------
  409. void CLogUICtrl::OnTextChanged()
  410. {
  411. // get the new text
  412. CString sz = InternalGetText();
  413. // set the accelerator table
  414. SetAccelTable((LPCTSTR)sz);
  415. if ( SetAccelTable((LPCTSTR)sz) )
  416. // make sure the new accelerator table gets loaded
  417. ControlInfoChanged();
  418. // finish with the default handling.
  419. COleControl::OnTextChanged();
  420. }
  421. //------------------------------------------------------------------------
  422. BOOL CLogUICtrl::SetAccelTable( LPCTSTR pszCaption )
  423. {
  424. BOOL fAnswer = FALSE;
  425. ACCEL accel;
  426. int iAccel;
  427. // get the new text
  428. CString sz = pszCaption;
  429. sz.MakeLower();
  430. // if the handle has already been allocated, free it
  431. if ( m_hAccel )
  432. {
  433. DestroyAcceleratorTable( m_hAccel );
  434. m_hAccel = NULL;
  435. m_cAccel = 0;
  436. }
  437. // if there is a & character, then declare the accelerator
  438. iAccel = sz.Find(_T('&'));
  439. if ( iAccel >= 0 )
  440. {
  441. // fill in the accererator record
  442. accel.fVirt = FALT;
  443. accel.key = sz.GetAt(iAccel + 1);
  444. accel.cmd = (USHORT)GetDlgCtrlID();
  445. m_hAccel = CreateAcceleratorTable( &accel, 1 );
  446. if ( m_hAccel )
  447. m_cAccel = 1;
  448. fAnswer = TRUE;
  449. }
  450. // return the answer
  451. return fAnswer;
  452. }