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.

511 lines
16 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. /////////////////////////////////////////////////////////////////////////////
  3. //
  4. // CUserNode
  5. //
  6. /////////////////////////////////////////////////////////////////////////////
  7. /////////////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. // Access to Snapin
  10. #include "Pop3.h"
  11. #include "Pop3Snap.h"
  12. // Access to nodes we use
  13. #include "UserNode.h"
  14. #include "DomainNode.h"
  15. // Access to dialogs we use
  16. #include "DeleteMailDlg.h"
  17. static const GUID CUserNodeGUID_NODETYPE =
  18. { 0x794b0daf, 0xf2f1, 0x42dc, { 0x9f, 0x84, 0x41, 0xab, 0x1, 0xab, 0xa4, 0x8b } };
  19. const GUID* CUserNode::m_NODETYPE = &CUserNodeGUID_NODETYPE;
  20. const OLECHAR* CUserNode::m_SZNODETYPE = OLESTR("794B0DAF-F2F1-42dc-9F84-41AB01ABA48B");
  21. const OLECHAR* CUserNode::m_SZDISPLAY_NAME = OLESTR("");
  22. const CLSID* CUserNode::m_SNAPIN_CLASSID = &CLSID_POP3ServerSnap;
  23. CUserNode::CUserNode(IP3User* pUser, CDomainNode* pParent)
  24. {
  25. // Initialize our user
  26. m_spUser = pUser;
  27. m_pParent = pParent;
  28. // Get the Locked state for the icons below
  29. HRESULT hr = E_FAIL;
  30. BOOL bLocked = FALSE;
  31. if( m_spUser )
  32. {
  33. // Get our initial lock state for icon display
  34. m_spUser->get_Lock( &bLocked );
  35. // Get our name
  36. hr = m_spUser->get_Name( &m_bstrDisplayName );
  37. }
  38. if( FAILED(hr) )
  39. {
  40. m_bstrDisplayName = _T("");
  41. }
  42. // Initialize our column text
  43. m_bstrSize = _T("");
  44. m_bstrNumMessages = _T("");
  45. m_bstrState = _T("");
  46. // Initialize our Scope item even though we will never use it
  47. memset( &m_scopeDataItem, 0, sizeof(m_scopeDataItem) );
  48. m_scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  49. m_scopeDataItem.cChildren = 0;
  50. m_scopeDataItem.displayname = MMC_CALLBACK;
  51. m_scopeDataItem.nImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  52. m_scopeDataItem.nOpenImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  53. m_scopeDataItem.lParam = (LPARAM) this;
  54. // Initialize our result item, which is all we use
  55. memset( &m_resultDataItem, 0, sizeof(m_resultDataItem) );
  56. m_resultDataItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  57. m_resultDataItem.str = MMC_CALLBACK;
  58. m_resultDataItem.nImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  59. m_resultDataItem.lParam = (LPARAM) this;
  60. }
  61. HRESULT CUserNode::GetScopePaneInfo(SCOPEDATAITEM *pScopeDataItem)
  62. {
  63. if( !pScopeDataItem ) return E_INVALIDARG;
  64. if( !m_spUser ) return E_FAIL;
  65. BOOL bLocked = FALSE;
  66. m_spUser->get_Lock( &bLocked );
  67. if( pScopeDataItem->mask & SDI_STR )
  68. pScopeDataItem->displayname = m_bstrDisplayName;
  69. if( pScopeDataItem->mask & SDI_IMAGE )
  70. pScopeDataItem->nImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  71. if( pScopeDataItem->mask & SDI_OPENIMAGE )
  72. pScopeDataItem->nOpenImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  73. if( pScopeDataItem->mask & SDI_PARAM )
  74. pScopeDataItem->lParam = m_scopeDataItem.lParam;
  75. if( pScopeDataItem->mask & SDI_STATE )
  76. pScopeDataItem->nState = m_scopeDataItem.nState;
  77. if( pScopeDataItem->mask & SDI_CHILDREN )
  78. pScopeDataItem->cChildren = 0;
  79. return S_OK;
  80. }
  81. HRESULT CUserNode::GetResultPaneInfo(RESULTDATAITEM *pResultDataItem)
  82. {
  83. if( !pResultDataItem ) return E_INVALIDARG;
  84. if( !m_spUser ) return E_FAIL;
  85. BOOL bLocked = FALSE;
  86. m_spUser->get_Lock( &bLocked );
  87. if( pResultDataItem->bScopeItem )
  88. {
  89. if( pResultDataItem->mask & RDI_STR )
  90. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  91. if( pResultDataItem->mask & RDI_IMAGE )
  92. pResultDataItem->nImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  93. if( pResultDataItem->mask & RDI_PARAM )
  94. pResultDataItem->lParam = m_scopeDataItem.lParam;
  95. return S_OK;
  96. }
  97. if( pResultDataItem->mask & RDI_STR )
  98. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  99. if( pResultDataItem->mask & RDI_IMAGE )
  100. pResultDataItem->nImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  101. if( pResultDataItem->mask & RDI_PARAM )
  102. pResultDataItem->lParam = m_resultDataItem.lParam;
  103. if( pResultDataItem->mask & RDI_INDEX )
  104. pResultDataItem->nIndex = m_resultDataItem.nIndex;
  105. return S_OK;
  106. }
  107. LPOLESTR CUserNode::GetResultPaneColInfo(int nCol)
  108. {
  109. if( !m_spUser ) return L"";
  110. switch( nCol )
  111. {
  112. case 0: // Name
  113. {
  114. return m_bstrDisplayName;
  115. }
  116. case 1: // Size of Mailbox (KB)
  117. {
  118. // We want our result in Kilobytes
  119. long lFactor = 0;
  120. long lUsage = 0;
  121. HRESULT hr = m_spUser->get_MessageDiskUsage( &lFactor, &lUsage );
  122. if( FAILED(hr) )
  123. {
  124. lUsage = 0;
  125. }
  126. // Convert to KiloBytes
  127. __int64 i64Usage = lFactor * lUsage;
  128. i64Usage /= 1024;
  129. // 1K buffer: Not likely we'll exceed that many digits
  130. tstring strKiloByte = StrLoadString( IDS_KILOBYTE_EXTENSION );
  131. TCHAR szNum[1024] = {0};
  132. _sntprintf( szNum, 1023, strKiloByte.c_str(), i64Usage );
  133. // Store it in our own buffer
  134. m_bstrSize = szNum;
  135. return m_bstrSize;
  136. }
  137. case 2: // Message Count
  138. {
  139. long lCount = 0;
  140. HRESULT hr = m_spUser->get_MessageCount( &lCount );
  141. if( FAILED(hr) )
  142. {
  143. lCount = 0;
  144. }
  145. // 1K buffer: Not likely we'll exceed that many digits
  146. TCHAR szNum[1024];
  147. _sntprintf( szNum, 1023, _T("%d"), lCount );
  148. m_bstrNumMessages = szNum;
  149. return m_bstrNumMessages;
  150. }
  151. case 3: // State of Mailbox
  152. {
  153. BOOL bLocked = FALSE;
  154. m_spUser->get_Lock( &bLocked );
  155. tstring strTemp = StrLoadString( bLocked ? IDS_STATE_LOCKED : IDS_STATE_UNLOCKED );
  156. m_bstrState = strTemp.c_str();
  157. return m_bstrState;
  158. }
  159. default:
  160. {
  161. #if DBG
  162. return L"No Information";
  163. #else
  164. return L"";
  165. #endif
  166. }
  167. }
  168. }
  169. HRESULT CUserNode::Notify( MMC_NOTIFY_TYPE event,
  170. LPARAM arg,
  171. LPARAM param,
  172. IComponentData* pComponentData,
  173. IComponent* pComponent,
  174. DATA_OBJECT_TYPES type )
  175. {
  176. if( !m_pParent ) return E_FAIL;
  177. HRESULT hr = S_FALSE;
  178. _ASSERTE(pComponentData != NULL || pComponent != NULL);
  179. CComPtr<IConsole> spConsole;
  180. if( pComponentData )
  181. {
  182. spConsole = ((CPOP3ServerSnapData*)pComponentData)->m_spConsole;
  183. }
  184. else if( pComponent )
  185. {
  186. spConsole = ((CPOP3ServerSnapComponent*)pComponent)->m_spConsole;
  187. }
  188. if( !spConsole ) return E_INVALIDARG;
  189. switch( event )
  190. {
  191. case MMCN_SHOW:
  192. {
  193. hr = S_OK;
  194. break;
  195. }
  196. case MMCN_EXPAND:
  197. {
  198. hr = S_OK;
  199. break;
  200. }
  201. case MMCN_ADD_IMAGES:
  202. {
  203. IImageList* pImageList = (IImageList*) arg;
  204. if( !pImageList ) return E_INVALIDARG;
  205. hr = LoadImages(pImageList);
  206. break;
  207. }
  208. case MMCN_VIEW_CHANGE:
  209. case MMCN_REFRESH:
  210. {
  211. CComQIPtr<IResultData> spResultData = spConsole;
  212. if( !spResultData ) return E_NOINTERFACE;
  213. HRESULTITEM hrID;
  214. ZeroMemory( &hrID, sizeof(HRESULTITEM) );
  215. hr = spResultData->FindItemByLParam( (LPARAM)this, &hrID );
  216. if( SUCCEEDED(hr) )
  217. {
  218. hr = spResultData->UpdateItem( hrID );
  219. }
  220. // We also need to update the icon
  221. if( SUCCEEDED(hr) )
  222. {
  223. RESULTDATAITEM rdi;
  224. ZeroMemory( &rdi, sizeof(RESULTDATAITEM) );
  225. rdi.mask = RDI_IMAGE;
  226. rdi.itemID = hrID;
  227. GetResultPaneInfo( &rdi );
  228. hr = spResultData->SetItem( &rdi );
  229. }
  230. break;
  231. }
  232. case MMCN_DELETE:
  233. {
  234. hr = S_OK;
  235. // Pop-up our confirmation dialog
  236. // Ignoring return from GetAuth and defaulting to False
  237. BOOL bHash = FALSE;
  238. m_pParent->GetAuth( &bHash );
  239. CDeleteMailboxDlg dlg( bHash );
  240. if( dlg.DoModal() == IDYES )
  241. {
  242. // The parent needs to do the deletion
  243. hr = m_pParent->DeleteUser(this, dlg.m_bCreateUser);
  244. if( SUCCEEDED(hr) )
  245. {
  246. // Update our parent node
  247. CComPtr<IDataObject> spDataObject = NULL;
  248. hr = m_pParent->GetDataObject( &spDataObject, CCT_SCOPE );
  249. if( !spDataObject )
  250. {
  251. hr = E_NOINTERFACE;
  252. }
  253. else
  254. {
  255. hr = spConsole->UpdateAllViews( spDataObject, (LPARAM)this, (LONG_PTR)NAV_DELETE );
  256. }
  257. }
  258. if( SUCCEEDED(hr) )
  259. {
  260. delete this;
  261. }
  262. if( FAILED(hr) )
  263. {
  264. // Failed to Delete the User
  265. HWND hWnd = NULL;
  266. spConsole->GetMainWindow(&hWnd);
  267. tstring strMessage = StrLoadString(IDS_ERROR_DELETEUSER);
  268. tstring strTitle = StrLoadString(IDS_SNAPINNAME);
  269. DisplayError( hWnd, strMessage.c_str(), strTitle.c_str(), hr );
  270. }
  271. }
  272. break;
  273. }
  274. case MMCN_SELECT:
  275. {
  276. // if selecting node
  277. if( HIWORD(arg) )
  278. {
  279. hr = S_OK;
  280. // get the verb interface and enable rename
  281. CComPtr<IConsoleVerb> spConsVerb;
  282. if( spConsole->QueryConsoleVerb(&spConsVerb) == S_OK )
  283. {
  284. // Enable the Refresh Menu
  285. hr = spConsVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE);
  286. if( FAILED(hr) ) return hr;
  287. hr = spConsVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, FALSE);
  288. if( FAILED(hr) ) return hr;
  289. // Enable the Delete Menu
  290. hr = spConsVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, TRUE);
  291. if( FAILED(hr) ) return hr;
  292. hr = spConsVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, FALSE);
  293. if( FAILED(hr) ) return hr;
  294. }
  295. }
  296. break;
  297. }
  298. case MMCN_CONTEXTHELP:
  299. {
  300. hr = S_OK;
  301. TCHAR szWindowsDir[MAX_PATH+1] = {0};
  302. tstring strHelpFile = _T("");
  303. tstring strHelpFileName = StrLoadString(IDS_HELPFILE);
  304. tstring strHelpTopicName = StrLoadString(IDS_HELPTOPIC);
  305. if( strHelpFileName.empty() || strHelpTopicName.empty() )
  306. {
  307. return E_FAIL;
  308. }
  309. // Build path to %systemroot%\help
  310. UINT nSize = GetSystemWindowsDirectory( szWindowsDir, MAX_PATH );
  311. if( nSize == 0 || nSize > MAX_PATH )
  312. {
  313. return E_FAIL;
  314. }
  315. strHelpFile = szWindowsDir; // D:\windows
  316. strHelpFile += _T("\\Help\\"); // \help
  317. strHelpFile += strHelpFileName; // \filename.chm
  318. strHelpFile += _T("::/"); // ::/
  319. strHelpFile += strHelpTopicName; // index.htm
  320. // Show the Help topic
  321. CComQIPtr<IDisplayHelp> spHelp = spConsole;
  322. if( !spHelp ) return E_NOINTERFACE;
  323. hr = spHelp->ShowTopic( (LPTSTR)strHelpFile.c_str() );
  324. break;
  325. }
  326. }// switch
  327. return hr;
  328. }
  329. HRESULT CUserNode::AddMenuItems(LPCONTEXTMENUCALLBACK piCallback, long* pInsertionAllowed, DATA_OBJECT_TYPES type )
  330. {
  331. if( !piCallback || !pInsertionAllowed ) return E_INVALIDARG;
  332. if( !m_spUser || !m_pParent ) return E_FAIL;
  333. HRESULT hr = S_OK;
  334. tstring strMenu = _T("");
  335. tstring strDesc = _T("");
  336. // Insert Result specific items
  337. if( (type == CCT_RESULT) && (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) )
  338. {
  339. CComQIPtr<IContextMenuCallback2> spContext2 = piCallback;
  340. if( !spContext2 ) return E_NOINTERFACE;
  341. CONTEXTMENUITEM2 singleMenuItem;
  342. ZeroMemory(&singleMenuItem, sizeof(CONTEXTMENUITEM2));
  343. singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  344. singleMenuItem.fFlags = m_pParent->IsLocked() ? (MF_DISABLED | MF_GRAYED) : MF_ENABLED;
  345. singleMenuItem.fSpecialFlags = 0;
  346. // Query the state of this User to see which menu to load
  347. BOOL bLocked = FALSE;
  348. m_spUser->get_Lock( &bLocked );
  349. if( bLocked )
  350. {
  351. strMenu = StrLoadString(IDS_MENU_USER_UNLOCK);
  352. strDesc = StrLoadString(IDS_MENU_USER_UNLOCK_DESC);
  353. singleMenuItem.strName = (LPWSTR)strMenu.c_str();
  354. singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str();
  355. singleMenuItem.strLanguageIndependentName = L"USER_UNLOCK";
  356. singleMenuItem.lCommandID = IDM_USER_TOP_UNLOCK;
  357. }
  358. else
  359. {
  360. strMenu = StrLoadString(IDS_MENU_USER_LOCK);
  361. strDesc = StrLoadString(IDS_MENU_USER_LOCK_DESC);
  362. singleMenuItem.strName = (LPWSTR)strMenu.c_str();
  363. singleMenuItem.strStatusBarText = (LPWSTR)strDesc.c_str();
  364. singleMenuItem.strLanguageIndependentName = L"USER_LOCK";
  365. singleMenuItem.lCommandID = IDM_USER_TOP_LOCK;
  366. }
  367. if( !strMenu.empty() )
  368. {
  369. hr = spContext2->AddItem( &singleMenuItem );
  370. }
  371. else
  372. {
  373. hr = E_FAIL;
  374. }
  375. }
  376. return hr;
  377. }
  378. // Lock the User
  379. HRESULT CUserNode::OnUserLock( bool& bHandled, CSnapInObjectRootBase* pObj )
  380. {
  381. if( !pObj ) return E_INVALIDARG;
  382. if( !m_spUser ) return E_FAIL;
  383. bHandled = true;
  384. BOOL bLocked = FALSE;
  385. HRESULT hr = S_OK;
  386. // Get the current state
  387. hr = m_spUser->get_Lock( &bLocked );
  388. // Inverse the state
  389. bLocked = !bLocked;
  390. // Set the new state
  391. if( SUCCEEDED(hr) )
  392. {
  393. hr = m_spUser->put_Lock( bLocked );
  394. }
  395. // Update the icon
  396. if( SUCCEEDED(hr) )
  397. {
  398. // Set our icons here
  399. m_scopeDataItem.nImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  400. m_scopeDataItem.nOpenImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  401. m_resultDataItem.nImage = (bLocked ? USERNODE_LOCKED_ICON : USERNODE_ICON);
  402. CComPtr<IConsole> spConsole = NULL;
  403. hr = GetConsole( pObj, &spConsole );
  404. if( FAILED(hr) || !spConsole ) return E_NOINTERFACE;
  405. // Update our parent node
  406. CComPtr<IDataObject> spDataObject = NULL;
  407. hr = m_pParent->GetDataObject( &spDataObject, CCT_SCOPE );
  408. if( FAILED(hr) || !spDataObject ) return E_NOINTERFACE;
  409. spConsole->UpdateAllViews( spDataObject, (LPARAM)this, (LONG_PTR)NAV_REFRESHCHILD );
  410. }
  411. return S_OK;
  412. }