// ServicesDialog.cpp : implementation file // #include "stdafx.h" #include "systemstateinfo.h" #include "ServicesDialog.h" #include "OXIteratorService.h" #include "UTBStrOp.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define SERVICEREF_FLAG 0x22663344 ///////////////////////////////////////////////////////////////////////////// // CServicesDialog dialog CServicesDialog::CServicesDialog() : CPageDialog() { //{{AFX_DATA_INIT(CServicesDialog) m_nExpandLevel = 0; m_nExpandType = 1; //}}AFX_DATA_INIT BOOL bIsWindowsNT=FALSE; m_SysInfo.IsNT(&bIsWindowsNT); if(!bIsWindowsNT) AfxThrowNotSupportedException(); } void CServicesDialog::DoDataExchange(CDataExchange* pDX) { CPageDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CServicesDialog) DDX_Control(pDX, IDC_SPIN_EXPANDLEVEL, m_spinExpandLevel); DDX_Control(pDX, IDC_EDIT_EXPANDLEVEL, m_editExpandLevel); DDX_Control(pDX, IDC_TREE_SERVICES, m_tree); DDX_Text(pDX, IDC_EDIT_EXPANDLEVEL, m_nExpandLevel); DDX_Radio(pDX, IDC_RADIO_EXPANDLEVEL, m_nExpandType); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CServicesDialog, CPageDialog) //{{AFX_MSG_MAP(CServicesDialog) ON_BN_CLICKED(IDC_RADIO_EXPANDALL, OnRadioExpandall) ON_BN_CLICKED(IDC_RADIO_EXPANDLEVEL, OnRadioExpandlevel) ON_NOTIFY(NM_DBLCLK, IDC_TREE_SERVICES, OnDblclkTreeServices) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CServicesDialog message handlers void CServicesDialog::OnInitDialog() { CPageDialog::OnInitDialog(); // TODO: Add your specialized creation code here m_ilTree.Create(IDB_SERVICES_TREE_IMAGE,16,1,RGB(255,0,255)); m_tree.SetImageList(&m_ilTree,TVSIL_NORMAL); LV_COLUMN lvc={ sizeof(lvc) }; lvc.fmt=LVCFMT_LEFT; lvc.cx=237; lvc.pszText=_T("Item"); lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT; m_tree.SetColumn(0,&lvc); m_tree.InsertColumn(1,_T("Value"),LVCFMT_LEFT,200,1); // set COXTreeCtrl styles m_tree.ModifyExStyle(0,TVOXS_PICKANYWHERE|TVOXS_ROWSEL); m_tree.ModifyStyle(0,TVS_SHOWSELALWAYS|TVS_HASBUTTONS| TVS_HASLINES|TVS_LINESATROOT); // spin control m_spinExpandLevel.SetRange(0,3); m_spinExpandLevel.SetPos(0); // layout manager // m_LayoutManager.Attach(this); // tree control m_LayoutManager.TieChild(IDC_TREE_SERVICES,OX_LMS_ANY,OX_LMT_SAME); ////////////////// // radio buttons and expand level edit control m_LayoutManager.TieChild(IDC_RADIO_EXPANDALL, OX_LMS_LEFT|OX_LMS_BOTTOM,OX_LMT_SAME); m_LayoutManager.TieChild(IDC_RADIO_EXPANDLEVEL, OX_LMS_LEFT|OX_LMS_BOTTOM,OX_LMT_SAME); m_LayoutManager.TieChild(IDC_EDIT_EXPANDLEVEL,OX_LMS_LEFT, OX_LMT_OPPOSITE,IDC_RADIO_EXPANDLEVEL); m_LayoutManager.TieChild(IDC_EDIT_EXPANDLEVEL,OX_LMS_BOTTOM,OX_LMT_SAME); m_LayoutManager.TieChild(IDC_SPIN_EXPANDLEVEL,OX_LMS_LEFT, OX_LMT_OPPOSITE,IDC_EDIT_EXPANDLEVEL); m_LayoutManager.TieChild(IDC_SPIN_EXPANDLEVEL,OX_LMS_BOTTOM,OX_LMT_SAME); ////////////////// ////////////////////////////////////// PopulateTree(); ShowControls(); } void CServicesDialog::Refresh() { PopulateTree(); } void CServicesDialog::PopulateTree() { if(!UpdateData()) return; CWaitCursor waitCursor; m_tree.SetRedraw(FALSE); m_tree.DeleteAllItems(); COXTreeHeader* pHeader=(COXTreeHeader*)m_tree.GetDlgItem(0); ASSERT(pHeader); pHeader->SortColumn(-1,0); // create fonts to customize tree items appearance LOGFONT lf; CFont fontRoot; CFont fontSubRoot; CFont* pFontRoot=GetFont(); if(pFontRoot->GetLogFont(&lf)) { lf.lfHeight=-14; UTBStr::tcsncpy(lf.lfFaceName,LF_FACESIZE,_T("Arial"),LF_FACESIZE); fontRoot.CreateFontIndirect(&lf); lf.lfHeight=-12; lf.lfWeight=FW_BOLD; UTBStr::tcsncpy(lf.lfFaceName,LF_FACESIZE,_T("Times New Roman"),LF_FACESIZE); fontSubRoot.CreateFontIndirect(&lf); } pFontRoot=((HFONT)fontRoot!=NULL) ? &fontRoot : NULL; CFont* pFontSubRoot=((HFONT)fontSubRoot!=NULL) ? &fontSubRoot : NULL; HTREEITEM htiRoot=NULL; HTREEITEM htiSelectItem=NULL; COLORREF clrTopic=RGB(0,0,255); COXIteratorService iterServices; // iterate through all services // CStringArray arrAllServiceName; CStringArray arrServiceName; CStringArray arrDeviceName; VERIFY(iterServices.StartIteration()); iterServices.GetKeyNames(arrAllServiceName); int nIndex=0; for(nIndex=0; nIndex0) { htiRoot=InsertItem(_T("Services"),NULL,0,pFontRoot,clrTopic); htiSelectItem=htiRoot; } for(nIndex=0; nIndex0) { htiRoot=InsertItem(_T("Devices"),NULL,1,pFontRoot,clrTopic); if(htiSelectItem==NULL) htiSelectItem=htiRoot; } for(nIndex=0; nIndexItemHasChildren()) ExpandTree((nExpandLevel==-1 ? -1 : nExpandLevel-1),hti); hti=m_tree.GetNextItem(hti,TVGN_NEXT); } } HTREEITEM CServicesDialog::InsertItem(CString sItem, HTREEITEM htiParent/*=NULL*/, int nImage/*=-1*/, CFont* pFont/*=NULL*/, COLORREF clr/*=CLR_NONE*/) { HTREEITEM hti=m_tree.InsertItem(sItem,htiParent); ASSERT(hti!=NULL); // associate new font if(pFont!=NULL) VERIFY(m_tree.SetItemFont(hti,pFont)); // and new color if(clr!=CLR_NONE) VERIFY(m_tree.SetItemColor(hti,clr)); m_tree.SetItemImage(hti,nImage,nImage); return hti; } void CServicesDialog::InsertServiceInfo(CString sServiceKeyName, HTREEITEM htiRoot, CFont* pFont, BOOL bDevice) { CString sValue; DWORD dwValue; HTREEITEM htiSubRoot; HTREEITEM htiItem; // COLORREF clrTopic=RGB(0,0,255); COLORREF clrValue=RGB(0,128,0); COXService service(sServiceKeyName); SERVICE_STATUS ss; // Display name and status htiSubRoot=InsertItem(service.QueryDisplayName(),htiRoot,-1,pFont); service.QueryStatus(&ss,TRUE); switch(ss.dwCurrentState) { case SERVICE_STOPPED: sValue=_T("Stopped"); break; case SERVICE_START_PENDING: sValue=_T("Start pending"); break; case SERVICE_STOP_PENDING: sValue=_T("Stop pending"); break; case SERVICE_RUNNING: sValue=_T("Running"); break; case SERVICE_CONTINUE_PENDING: sValue=_T("Continue pending"); break; case SERVICE_PAUSE_PENDING: sValue=_T("Pause pending"); break; case SERVICE_PAUSED: sValue=_T("Paused"); break; default: if(ss.dwWin32ExitCode==NO_ERROR) sValue=_T("Status:"); else sValue=_T("Stopped"); } VERIFY(m_tree.SetSubItem(htiSubRoot,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); ///////////////////////////////////////////// // Binary Path Name CString sWindowsDirTag=_T("\\SystemRoot"); CString sWindowsDir; if(!m_SysInfo.GetWindowsDir(&sWindowsDir)) sWindowsDir.Empty(); sValue=service.QueryBinaryPathName(); if(sValue.IsEmpty()) sValue=_T(""); if(!sWindowsDir.IsEmpty() && sValue.Find(sWindowsDirTag)==0) sValue=sWindowsDir+sValue.Mid(sWindowsDirTag.GetLength()); htiItem=InsertItem(_T("Pathname"),htiSubRoot); VERIFY(m_tree.SetSubItem(htiItem,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); VERIFY(m_tree.SetItemDrawEllipsis(htiItem,DT_PATH_ELLIPSIS,1)); ///////////////////////////////////////////// // Service Type sValue.Empty(); htiItem=InsertItem(_T("Service Type"),htiSubRoot); if((ss.dwServiceType&SERVICE_WIN32_OWN_PROCESS)== SERVICE_WIN32_OWN_PROCESS) { ASSERT(!bDevice); sValue=_T("Runs in its own process"); } else if((ss.dwServiceType&SERVICE_WIN32_SHARE_PROCESS)== SERVICE_WIN32_SHARE_PROCESS) { ASSERT(!bDevice); sValue=_T("Shares a process with other processes"); } else if((ss.dwServiceType&SERVICE_KERNEL_DRIVER)== SERVICE_KERNEL_DRIVER) { ASSERT(bDevice); sValue=_T("Kernel device driver"); } else if((ss.dwServiceType&SERVICE_FILE_SYSTEM_DRIVER)== SERVICE_FILE_SYSTEM_DRIVER) { ASSERT(bDevice); sValue=_T("File system driver"); } if((ss.dwServiceType&SERVICE_INTERACTIVE_PROCESS)== SERVICE_INTERACTIVE_PROCESS) { ASSERT(!bDevice); ASSERT(!sValue.IsEmpty()); sValue=sValue+_T(" and can iteract with the desktop"); } VERIFY(m_tree.SetSubItem(htiItem,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); ///////////////////////////////////////////// // Start Type dwValue=service.QueryStartType(); htiItem=InsertItem(_T("Start Type"),htiSubRoot); switch(dwValue) { case SERVICE_BOOT_START: ASSERT(bDevice); sValue=_T("Boot"); break; case SERVICE_SYSTEM_START: ASSERT(bDevice); sValue=_T("System"); break; case SERVICE_AUTO_START: sValue=_T("Automatic"); break; case SERVICE_DEMAND_START: sValue=_T("Manual"); break; case SERVICE_DISABLED: sValue=_T("Disabled"); break; default: sValue=_T(""); } VERIFY(m_tree.SetSubItem(htiItem,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); ///////////////////////////////////////////// // Error Severity dwValue=service.QueryErrorControl(); htiItem=InsertItem(_T("Error Severity"),htiSubRoot); switch(dwValue) { case SERVICE_ERROR_IGNORE: sValue=_T("Ignore"); break; case SERVICE_ERROR_NORMAL: sValue=_T("Normal"); break; case SERVICE_ERROR_SEVERE: sValue=_T("Severe"); break; case SERVICE_ERROR_CRITICAL: sValue=_T("Critical"); break; default: sValue=_T(""); } VERIFY(m_tree.SetSubItem(htiItem,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); ///////////////////////////////////////////// // Load Order Group sValue=service.QueryLoadOrderGroup(); if(!sValue.IsEmpty()) { htiItem=InsertItem(_T("Group"),htiSubRoot); VERIFY(m_tree.SetSubItem(htiItem,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); } ///////////////////////////////////////////// // sValue=service.QueryStartName(); if(!bDevice) // Service Account Name { if(sValue.IsEmpty()) sValue=_T("LocalSystem"); htiItem=InsertItem(_T("Service Account Name"),htiSubRoot); VERIFY(m_tree.SetSubItem(htiItem,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); } else // Driver Object Name { if(!sValue.IsEmpty()) { htiItem=InsertItem(_T("Driver Object Name"),htiSubRoot); VERIFY(m_tree.SetSubItem(htiItem,1,OX_SUBITEM_TEXT|OX_SUBITEM_COLOR, sValue,0,NULL,clrValue)); } } ///////////////////////////////////////////// // Dependencies CString sDependencies=service.QueryDependencies(); if(!sDependencies.IsEmpty()) { htiItem=InsertItem(_T("Dependencies"),htiSubRoot,-1,pFont); int nPos; while((nPos=sDependencies.Find(_T("|")))!=-1) { ASSERT(nPos>1); CString sName=sDependencies.Left(nPos); if(sName.Left(1)==SC_GROUP_IDENTIFIER) sName=sName.Mid(1)+_T(" (Group)"); InsertItem(sName,htiItem); sDependencies=sDependencies.Mid(nPos+1); } if(sDependencies.Left(1)==SC_GROUP_IDENTIFIER) sDependencies=sDependencies.Mid(1)+_T(" (Group)"); InsertItem(sDependencies,htiItem); } ///////////////////////////////////////////// // Dependents COXIteratorService iterServices(service); if(iterServices.StartDependentIteration()) { CStringArray arrAllServiceName; iterServices.GetKeyNames(arrAllServiceName); HTREEITEM htiItem=NULL; if(arrAllServiceName.GetSize()>0) htiItem=InsertItem(_T("Dependents"),htiSubRoot,-1,pFont); for(int nIndex=0; nIndexEnableWindow((m_nExpandType==0)); pDlgItem=GetDlgItem(IDC_SPIN_EXPANDLEVEL); ASSERT(pDlgItem!=NULL); pDlgItem->EnableWindow((m_nExpandType==0)); } } void CServicesDialog::OnRadioExpandall() { // TODO: Add your control notification handler code here ShowControls(); } void CServicesDialog::OnRadioExpandlevel() { // TODO: Add your control notification handler code here ShowControls(); } void CServicesDialog::OnDblclkTreeServices(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here UNREFERENCED_PARAMETER(pNMHDR); CPoint point; if(::GetCursorPos(&point)) { m_tree.ScreenToClient(&point); UINT nFlags; int nItem=m_tree.HitTest(point,&nFlags); if(nItem!=-1) { HTREEITEM hti=m_tree.GetItemFromIndex(nItem); ASSERT(hti!=NULL); if(m_tree.GetItemIndent(hti)