home *** CD-ROM | disk | FTP | other *** search
/ Softwarová Záchrana 3 / Softwarova-zachrana-3.bin / pserv.cpl / pserv-2.4.exe / source / cservice.cpp < prev    next >
C/C++ Source or Header  |  2005-01-05  |  30KB  |  909 lines

  1. #include "stdafx.h"
  2. #include "resource.h"
  3. #include "cservice.h"
  4. #include "WriteOptimizedFile.h"
  5. #include "2kwrapper.h"
  6. #include "cconfiguration.h"
  7. #include "MemoryBuffer.h"
  8. #include "stringresources.h"
  9.  
  10. CService::CService(CServiceList* owner)
  11.     :   m_pOwner( owner ),
  12.         m_hTempSCM( 0 ),
  13.         m_hTempService( 0 ),
  14.         m_dwChangeFlags( 0 ),
  15.         m_dwErrorControl( 0 ),
  16.         m_bRestartPending( FALSE ),
  17.         m_dwServiceType( (owner->m_dwEnumType == SERVICE_WIN32) ? SERVICE_WIN32_OWN_PROCESS : SERVICE_KERNEL_DRIVER ),
  18.         m_dwStartType( SERVICE_DEMAND_START )
  19. {
  20.     ZeroMemory( &m_ServiceStatus, sizeof(m_ServiceStatus) );
  21. }
  22.  
  23. COLORREF CService::GetTextColor()
  24. {
  25.     if(IsRunning())
  26.     {
  27.         return RGB(0, 0, 200);
  28.     }
  29.     else if(IsDisabled())
  30.     {
  31.         return RGB(128,128,128);
  32.     }
  33.     return RGB(0,0,0);
  34. }
  35.  
  36. CString CService::GetDisplayString(DWORD dwIndex)
  37. {
  38.     switch(dwIndex)
  39.     {
  40.     case 0: return m_strDisplayName;
  41.     case 1: return m_strServiceName;
  42.     case 2: return GetStatusAsString();
  43.     case 3: return GetStartAsString();
  44.     case 4: return GetTypeAsString();
  45.     case 5: return m_strBinaryPathName;
  46.     case 6: return GetPidAsString();
  47.     case 7: return m_strServiceStartName;
  48.     case 8: return m_strLoadOrderGroup;
  49.     case 9: return m_strDescription;
  50.     }
  51.     return CString();
  52. }
  53.  
  54. CString CService::GetInfoTip()
  55. {
  56.     return m_strDescription;
  57. }
  58.  
  59.  
  60. CService::~CService()
  61. {
  62.     FinishStateType();
  63. }
  64.  
  65. BOOL CService::RefreshServiceStatus()
  66. {
  67.     MemoryBuffer mb;
  68.     if( lpfnQueryServiceStatusEx )
  69.     {
  70.         LPSERVICE_STATUS_PROCESS ssp = mb.QueryServiceStatusEx(m_hTempService);
  71.         if( ssp )
  72.         {
  73.             m_ServiceStatus = *ssp;
  74.             return TRUE;
  75.         }
  76.         return FALSE;
  77.     }
  78.     return QueryServiceStatus( m_hTempService, (LPSERVICE_STATUS) &m_ServiceStatus );
  79. }
  80.  
  81. BOOL CService::ApplyChanges()
  82. {
  83.     // no changes -> success always
  84.     if(!m_dwChangeFlags )
  85.         return TRUE;
  86.  
  87.     BOOL bSuccess = FALSE;
  88.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT );
  89.     if( m_hTempSCM )
  90.     {
  91.         m_hTempService = OpenService(m_hTempSCM, m_strServiceName, SERVICE_CHANGE_CONFIG|SERVICE_QUERY_STATUS );
  92.         if( m_hTempService )
  93.         {
  94.             LPCTSTR lpszStartName = NULL, lpszStartPassword = NULL;
  95.             if( m_dwChangeFlags & CHANGED_LOGON_SYSTEM )
  96.             {
  97.                 lpszStartName = TEXT(".\\LOCALSYSTEM");
  98.                 lpszStartPassword = TEXT("");
  99.             }
  100.             else if( m_dwChangeFlags & CHANGED_LOGON_USER )
  101.             {
  102.                 lpszStartName = m_strServiceStartName;
  103.                 lpszStartPassword = m_strServiceStartPassword;
  104.             }
  105.  
  106.             bSuccess = ChangeServiceConfig( 
  107.                             m_hTempService, 
  108.                             (m_dwChangeFlags & CHANGED_ALLOW_UI) ? m_dwServiceType : SERVICE_NO_CHANGE,
  109.                             (m_dwChangeFlags & CHANGED_START_TYPE) ? m_dwStartType : SERVICE_NO_CHANGE,
  110.                             (m_dwChangeFlags & CHANGED_ERROR_CONTROL) ? m_dwErrorControl : SERVICE_NO_CHANGE,
  111.                             (m_dwChangeFlags & CHANGED_BINARYPATH) ? (LPCTSTR) m_strBinaryPathName : NULL,
  112.                             NULL,
  113.                             NULL, 
  114.                             NULL,
  115.                             lpszStartName,
  116.                             lpszStartPassword,
  117.                             (m_dwChangeFlags & CHANGED_DISPLAYNAME) ? (LPCTSTR) m_strDisplayName : NULL );
  118.             
  119.             if( bSuccess && (m_dwChangeFlags & CHANGED_DESCRIPTION) && (lpfnChangeServiceConfig2 != NULL))
  120.             {
  121.                 SERVICE_DESCRIPTION sd;
  122.                 sd.lpDescription = (LPTSTR) (LPCTSTR) m_strDescription;
  123.                 bSuccess = lpfnChangeServiceConfig2( m_hTempService, SERVICE_CONFIG_DESCRIPTION, &sd );
  124.             }
  125.  
  126.             DWORD dwLastError = GetLastError();
  127.             RefreshServiceStatus();
  128.             CloseServiceHandle( m_hTempService );
  129.             m_hTempService = 0;
  130.             SetLastError(dwLastError);
  131.         }
  132.         DWORD dwLastError = GetLastError();
  133.         CloseServiceHandle(m_hTempSCM);
  134.         m_hTempSCM = 0;
  135.         SetLastError(dwLastError);
  136.     }
  137.     return bSuccess;
  138. }
  139.  
  140. BOOL CService::Delete()
  141. {
  142.     BOOL bSuccess = FALSE;
  143.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, STANDARD_RIGHTS_REQUIRED );
  144.     if( m_hTempSCM )
  145.     {
  146.         m_hTempService = OpenService(m_hTempSCM, m_strServiceName, STANDARD_RIGHTS_REQUIRED  );
  147.         if( m_hTempService )
  148.         {
  149.             bSuccess = DeleteService(m_hTempService);
  150.             DWORD dwLastError = GetLastError();
  151.             CloseServiceHandle( m_hTempService );
  152.             m_hTempService = 0;
  153.             SetLastError(dwLastError);
  154.         }
  155.         DWORD dwLastError = GetLastError();
  156.         CloseServiceHandle(m_hTempSCM);
  157.         m_hTempSCM = 0;
  158.         SetLastError(dwLastError);
  159.     }
  160.     return bSuccess;
  161. }
  162.  
  163. BOOL CService::Install()
  164. {
  165.     BOOL bSuccess = FALSE;
  166.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE );
  167.     if( m_hTempSCM )
  168.     {
  169.         LPCTSTR lpszStartName = NULL, lpszStartPassword = NULL;
  170.         if( !IsEmptyString( m_strServiceStartName ) )
  171.         {
  172.             lpszStartName = m_strServiceStartName;
  173.             lpszStartPassword = m_strServiceStartPassword;
  174.         }
  175.  
  176.         m_hTempService = CreateService(m_hTempSCM,
  177.                                        m_strServiceName,
  178.                                        m_strDisplayName,
  179.                                        SERVICE_QUERY_CONFIG|SERVICE_QUERY_STATUS|SERVICE_CHANGE_CONFIG,
  180.                                        m_dwServiceType,
  181.                                        m_dwStartType,
  182.                                        m_dwErrorControl,
  183.                                        m_strBinaryPathName,
  184.                                        NULL,
  185.                                        NULL, 
  186.                                        NULL, 
  187.                                        lpszStartName,
  188.                                        lpszStartPassword );
  189.         if( m_hTempService )
  190.         {
  191.             bSuccess = TRUE;
  192.             if( !IsEmptyString(m_strDescription))
  193.             {
  194.                 SERVICE_DESCRIPTION sd;
  195.                 sd.lpDescription = (LPTSTR) (LPCTSTR) m_strDescription;
  196.                 bSuccess = lpfnChangeServiceConfig2( m_hTempService, SERVICE_CONFIG_DESCRIPTION, &sd );
  197.             }
  198.  
  199.             DWORD dwLastError = GetLastError();
  200.             RefreshServiceStatus();
  201.             CloseServiceHandle( m_hTempService );
  202.             m_hTempService = 0;
  203.             SetLastError(dwLastError);
  204.         }
  205.         DWORD dwLastError = GetLastError();
  206.         CloseServiceHandle(m_hTempSCM);
  207.         m_hTempSCM = 0;
  208.         SetLastError(dwLastError);
  209.     }
  210.     return bSuccess;
  211. }
  212.  
  213. BOOL CService::StartAtBoot()
  214. {
  215.     if( m_dwStartType != SERVICE_BOOT_START )
  216.     {
  217.         m_dwStartType = SERVICE_BOOT_START;
  218.         m_dwChangeFlags = CHANGED_START_TYPE;
  219.         return ApplyChanges();
  220.     }
  221.     return TRUE;
  222. }
  223.  
  224. BOOL CService::StartAtSystem()
  225. {
  226.     if( m_dwStartType != SERVICE_SYSTEM_START )
  227.     {
  228.         m_dwStartType = SERVICE_SYSTEM_START;
  229.         m_dwChangeFlags = CHANGED_START_TYPE;
  230.         return ApplyChanges();
  231.     }
  232.     return TRUE;
  233. }
  234.  
  235. BOOL CService::Enable()
  236. {
  237.     if( m_dwStartType != SERVICE_DEMAND_START )
  238.     {
  239.         m_dwStartType = SERVICE_DEMAND_START;
  240.         m_dwChangeFlags = CHANGED_START_TYPE;
  241.         return ApplyChanges();
  242.     }
  243.     return TRUE;
  244. }
  245.  
  246. BOOL CService::Disable()
  247. {
  248.     if( m_dwStartType != SERVICE_DISABLED )
  249.     {
  250.         m_dwStartType = SERVICE_DISABLED;
  251.         m_dwChangeFlags = CHANGED_START_TYPE;
  252.         return ApplyChanges();
  253.     }
  254.     return TRUE;
  255. }
  256.  
  257. BOOL CService::StartAutomatically()
  258. {
  259.     if( m_dwStartType != SERVICE_AUTO_START )
  260.     {
  261.         m_dwStartType = SERVICE_AUTO_START;
  262.         m_dwChangeFlags = CHANGED_START_TYPE;
  263.         return ApplyChanges();
  264.     }
  265.     return TRUE;
  266. }
  267.  
  268. SERVICE_STATE_TYPE CService::BeginStart(LPDWORD lpdwWaitHint)
  269. {
  270.     FinishStateType();
  271.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT );
  272.     if( m_hTempSCM )
  273.     {
  274.         m_hTempService = OpenService(m_hTempSCM, m_strServiceName, SERVICE_START|SERVICE_QUERY_STATUS );
  275.         if( m_hTempService )
  276.         {
  277.             if( StartService( m_hTempService, 0, NULL ) )
  278.             {
  279.                 if( RefreshServiceStatus() )
  280.                 {
  281.                     if( m_ServiceStatus.dwCurrentState == SERVICE_RUNNING )
  282.                     {
  283.                         return SERVICE_STATE_REACHED;
  284.                     }
  285.                     else if( m_ServiceStatus.dwCurrentState == SERVICE_START_PENDING )
  286.                     { 
  287.                         *lpdwWaitHint = m_ServiceStatus.dwWaitHint;
  288.                         return SERVICE_STATE_PENDING;
  289.                     }
  290.                 }
  291.             }
  292.         }
  293.     }
  294.     return SERVICE_STATE_FAILED;
  295.  
  296. SERVICE_STATE_TYPE CService::BeginStop(LPDWORD lpdwWaitHint)
  297. {
  298.     FinishStateType();
  299.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT );
  300.     if( m_hTempSCM )
  301.     {
  302.         m_hTempService = OpenService(m_hTempSCM, m_strServiceName, SERVICE_STOP|SERVICE_QUERY_STATUS );
  303.         if( m_hTempService )
  304.         {
  305.             if( ControlService( m_hTempService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &m_ServiceStatus) )
  306.             {
  307.                 if( m_ServiceStatus.dwCurrentState == SERVICE_STOPPED )
  308.                 {
  309.                     return SERVICE_STATE_REACHED;
  310.                 }
  311.                 else if( m_ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING )
  312.                 { 
  313.                     *lpdwWaitHint = m_ServiceStatus.dwWaitHint;
  314.                     return SERVICE_STATE_PENDING;
  315.                 }
  316.             }
  317.         }
  318.     }
  319.     return SERVICE_STATE_FAILED;
  320.  
  321. SERVICE_STATE_TYPE CService::BeginRestart(LPDWORD lpdwWaitHint)
  322. {
  323.     FinishStateType();
  324.     m_bRestartPending = TRUE;
  325.     m_bRestartHasBeenStopped = FALSE;
  326.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT );
  327.     if( m_hTempSCM )
  328.     {
  329.         m_hTempService = OpenService(m_hTempSCM, m_strServiceName, SERVICE_STOP|SERVICE_QUERY_STATUS );
  330.         if( m_hTempService )
  331.         {
  332.             if( ControlService( m_hTempService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &m_ServiceStatus) )
  333.             {
  334.                 if( m_ServiceStatus.dwCurrentState == SERVICE_STOPPED )
  335.                 {
  336.                     // ok, stopped, now restart
  337.                     m_bRestartHasBeenStopped = TRUE;
  338.                     return BeginStart(lpdwWaitHint);
  339.                 }
  340.                 else if( m_ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING )
  341.                 { 
  342.                     *lpdwWaitHint = m_ServiceStatus.dwWaitHint + (10 * 1000);
  343.                     return SERVICE_STATE_PENDING;
  344.                 }
  345.             }
  346.         }
  347.     }
  348.     return SERVICE_STATE_FAILED;
  349.  
  350. SERVICE_STATE_TYPE CService::BeginPause(LPDWORD lpdwWaitHint)
  351. {
  352.     FinishStateType();
  353.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT );
  354.     if( m_hTempSCM )
  355.     {
  356.         m_hTempService = OpenService(m_hTempSCM, m_strServiceName, SERVICE_PAUSE_CONTINUE|SERVICE_QUERY_STATUS );
  357.         if( m_hTempService )
  358.         {
  359.             if( ControlService( m_hTempService, SERVICE_CONTROL_PAUSE, (LPSERVICE_STATUS) &m_ServiceStatus) )
  360.             {
  361.                 if( m_ServiceStatus.dwCurrentState == SERVICE_PAUSED )
  362.                 {
  363.                     return SERVICE_STATE_REACHED;
  364.                 }
  365.                 else if( m_ServiceStatus.dwCurrentState == SERVICE_PAUSE_PENDING )
  366.                 { 
  367.                     *lpdwWaitHint = m_ServiceStatus.dwWaitHint;
  368.                     return SERVICE_STATE_PENDING;
  369.                 }
  370.             }
  371.         }
  372.     }
  373.     return SERVICE_STATE_FAILED;
  374.  
  375. SERVICE_STATE_TYPE CService::BeginContinue(LPDWORD lpdwWaitHint)
  376. {
  377.     FinishStateType();
  378.     m_hTempSCM = OpenSCManager( m_pOwner->m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT );
  379.     if( m_hTempSCM )
  380.     {
  381.         m_hTempService = OpenService(m_hTempSCM, m_strServiceName, SERVICE_PAUSE_CONTINUE|SERVICE_QUERY_STATUS );
  382.         if( m_hTempService )
  383.         {
  384.             if( ControlService( m_hTempService, SERVICE_CONTROL_CONTINUE, (LPSERVICE_STATUS) &m_ServiceStatus) )
  385.             {
  386.                 if( m_ServiceStatus.dwCurrentState == SERVICE_RUNNING )
  387.                 {
  388.                     return SERVICE_STATE_REACHED;
  389.                 }
  390.                 else if( m_ServiceStatus.dwCurrentState == SERVICE_CONTINUE_PENDING )
  391.                 { 
  392.                     *lpdwWaitHint = m_ServiceStatus.dwWaitHint;
  393.                     return SERVICE_STATE_PENDING;
  394.                 }
  395.             }
  396.         }
  397.     }
  398.     return SERVICE_STATE_FAILED;
  399.  
  400. SERVICE_STATE_TYPE CService::IsStarted()
  401. {
  402.     if( !m_hTempService || RefreshServiceStatus() )
  403.     {
  404.         if( m_ServiceStatus.dwCurrentState == SERVICE_RUNNING )
  405.         {
  406.             return SERVICE_STATE_REACHED;
  407.         }
  408.         else if( m_ServiceStatus.dwCurrentState == SERVICE_START_PENDING )
  409.         { 
  410.             return SERVICE_STATE_PENDING;
  411.         }
  412.     }
  413.     return SERVICE_STATE_FAILED;
  414. }
  415.  
  416. SERVICE_STATE_TYPE CService::IsRestarted()
  417. {
  418.     if( !m_hTempService || RefreshServiceStatus() )
  419.     {
  420.         if( m_ServiceStatus.dwCurrentState == SERVICE_RUNNING )
  421.         {
  422.             if( m_bRestartHasBeenStopped )
  423.             {
  424.                 return SERVICE_STATE_REACHED;
  425.             }
  426.             else
  427.             {
  428.                 // unable to restart, abort
  429.                 return SERVICE_STATE_FAILED;
  430.             }
  431.         }
  432.         else if( m_ServiceStatus.dwCurrentState == SERVICE_STOPPED )
  433.         {
  434.             if( m_bRestartHasBeenStopped )
  435.             {
  436.                 // unable to restart, abort
  437.                 return SERVICE_STATE_FAILED;
  438.             }
  439.             DWORD dwIgnoreMe;
  440.             SERVICE_STATE_TYPE result = BeginStart(&dwIgnoreMe);
  441.             if( result == SERVICE_STATE_PENDING )
  442.                 m_bRestartHasBeenStopped = TRUE;
  443.             return result;
  444.         }
  445.         else if( m_ServiceStatus.dwCurrentState == SERVICE_START_PENDING )
  446.         { 
  447.             return SERVICE_STATE_PENDING;
  448.         }
  449.         else if( m_ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING )
  450.         { 
  451.             return SERVICE_STATE_PENDING;
  452.         }
  453.     }
  454.     return SERVICE_STATE_FAILED;
  455. }
  456.  
  457. SERVICE_STATE_TYPE CService::IsStopped()
  458. {
  459.     if( !m_hTempService || RefreshServiceStatus() )
  460.     {
  461.         if( m_ServiceStatus.dwCurrentState == SERVICE_STOPPED )
  462.         {
  463.             return SERVICE_STATE_REACHED;
  464.         }
  465.         else if( m_ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING )
  466.         { 
  467.             return SERVICE_STATE_PENDING;
  468.         }
  469.     }
  470.     return SERVICE_STATE_FAILED;
  471. }
  472.  
  473. SERVICE_STATE_TYPE CService::IsContinued()
  474. {
  475.     if( !m_hTempService || RefreshServiceStatus() )
  476.     {
  477.         if( m_ServiceStatus.dwCurrentState == SERVICE_RUNNING )
  478.         {
  479.             return SERVICE_STATE_REACHED;
  480.         }
  481.         else if( m_ServiceStatus.dwCurrentState == SERVICE_CONTINUE_PENDING )
  482.         { 
  483.             return SERVICE_STATE_PENDING;
  484.         }
  485.     }
  486.     return SERVICE_STATE_FAILED;
  487. }
  488.  
  489.  
  490. SERVICE_STATE_TYPE CService::IsPaused()
  491. {
  492.     if( !m_hTempService || RefreshServiceStatus() )
  493.     {
  494.         if( m_ServiceStatus.dwCurrentState == SERVICE_PAUSED )
  495.         {
  496.             return SERVICE_STATE_REACHED;
  497.         }
  498.         else if( m_ServiceStatus.dwCurrentState == SERVICE_PAUSE_PENDING )
  499.         { 
  500.             return SERVICE_STATE_PENDING;
  501.         }
  502.     }
  503.     return SERVICE_STATE_FAILED;
  504. }
  505.  
  506. void CService::FinishStateType()
  507. {
  508.     if( m_hTempService )
  509.     {
  510.         CloseServiceHandle(m_hTempService);
  511.         m_hTempService = 0;
  512.     }
  513.     if( m_hTempSCM )
  514.     {
  515.         CloseServiceHandle(m_hTempSCM);
  516.         m_hTempSCM = 0;
  517.     }
  518.     m_bRestartPending = FALSE;
  519. }
  520.  
  521. CString CService::GetPidAsString()
  522. {
  523.     CString result( _T("") );
  524.     if( m_ServiceStatus.dwProcessId )
  525.         result.Format( _T("%d"), m_ServiceStatus.dwProcessId );
  526.     return result;
  527. }
  528.  
  529. CString CService::GetStatusAsString()
  530. {
  531.     switch(m_ServiceStatus.dwCurrentState)
  532.     {
  533.     case SERVICE_STOPPED:
  534.         return  strSERVICE_STATUS_STOPPED;
  535.     case SERVICE_START_PENDING:
  536.         return strSERVICE_STATUS_START_PENDING;
  537.     case SERVICE_STOP_PENDING:
  538.         return strSERVICE_STATUS_STOP_PENDING;
  539.     case SERVICE_RUNNING:
  540.         return strSERVICE_STATUS_RUNNING;
  541.     case SERVICE_CONTINUE_PENDING:
  542.         return strSERVICE_STATUS_CONTINUE_PENDING;
  543.     case SERVICE_PAUSE_PENDING:
  544.         return strSERVICE_STATUS_PAUSE_PENDING;
  545.     case SERVICE_PAUSED:
  546.         return strSERVICE_STATUS_PAUSED;
  547.     }
  548.     CString result;
  549.     result.Format(strSERVICE_STATUS_INVALID, m_ServiceStatus.dwCurrentState );
  550.     return result;
  551. }
  552.  
  553. CString CService::GetPrintStatusAsString()
  554. {
  555.     switch(m_ServiceStatus.dwCurrentState)
  556.     {
  557.     case SERVICE_STOPPED:
  558.         return _T("Stopped");
  559.     case SERVICE_START_PENDING:
  560.         return _T("Start pending");
  561.     case SERVICE_STOP_PENDING:
  562.         return _T("Stop pending");
  563.     case SERVICE_RUNNING:
  564.         return _T("Running");
  565.     case SERVICE_CONTINUE_PENDING:
  566.         return _T("Continue pending");
  567.     case SERVICE_PAUSE_PENDING:
  568.         return _T("Pause pending");
  569.     case SERVICE_PAUSED:
  570.         return _T("Paused");
  571.     }
  572.  
  573.     CString result;
  574.     result.Format(_T("<INVALID: 0x%08lx>"), m_ServiceStatus.dwCurrentState );
  575.     return result;
  576. }
  577.  
  578. CString CService::GetStartAsString()
  579. {
  580.     return GetStartAsString(m_dwStartType);
  581. }
  582.  
  583. CString CService::GetStartAsString(DWORD dwStartType)
  584. {
  585.     switch(dwStartType)
  586.     {
  587.     // WARNING: also used in PXmlReader.cpp !!!
  588.     case SERVICE_BOOT_START:
  589.         return _T("Boot");
  590.     case SERVICE_SYSTEM_START:    
  591.         return _T("System");
  592.     case SERVICE_AUTO_START:    
  593.         return _T("Automatic");
  594.     case SERVICE_DEMAND_START:    
  595.         return _T("Manual");
  596.     case SERVICE_DISABLED:        
  597.         return _T("Disabled");
  598.     }
  599.     CString result;
  600.     result.Format(_T("<INVALID: 0x%08lx>"), dwStartType );
  601.     return result;
  602. }
  603.  
  604. CString CService::GetTypeAsString()
  605. {
  606.     CString result;
  607.     if( m_dwServiceType & SERVICE_WIN32_OWN_PROCESS )        
  608.         result += _T("Process " );
  609.     if( m_dwServiceType & SERVICE_WIN32_SHARE_PROCESS )    
  610.         result += _T("Shared ");
  611.     if( m_dwServiceType & SERVICE_KERNEL_DRIVER )            
  612.         result += _T("Driver ");
  613.     if( m_dwServiceType & SERVICE_FILE_SYSTEM_DRIVER )    
  614.         result += _T("File System ");
  615.     if( m_dwServiceType & SERVICE_INTERACTIVE_PROCESS )    
  616.         result += _T("(Interactive) ");
  617.     return result;
  618. }
  619.  
  620. BOOL CService::CreateFrom(SC_HANDLE hSCM, LPENUM_SERVICE_STATUS_PROCESS lpStatus)
  621. {
  622.     m_strServiceName = lpStatus->lpServiceName;
  623.     m_strDisplayName = lpStatus->lpDisplayName;
  624.     m_ServiceStatus = lpStatus->ServiceStatusProcess;
  625.     m_strDescription = (LPCSTR) NULL;
  626.  
  627.     SC_HANDLE hService = OpenService(hSCM, m_strServiceName, SERVICE_QUERY_CONFIG );
  628.     if( hService )
  629.     {
  630.         MemoryBuffer mb;
  631.         LPQUERY_SERVICE_CONFIG pServiceConfig = mb.QueryServiceConfig(hService);
  632.         if( pServiceConfig )
  633.         {
  634.             m_strBinaryPathName = pServiceConfig->lpBinaryPathName;
  635.             m_dwErrorControl = pServiceConfig->dwErrorControl;
  636.             m_dwServiceType = pServiceConfig->dwServiceType;
  637.             m_dwStartType = pServiceConfig->dwStartType;
  638.             m_strServiceStartName = pServiceConfig->lpServiceStartName;
  639.             m_strLoadOrderGroup = pServiceConfig->lpLoadOrderGroup;
  640.             m_strDescription = mb.GetServiceDescription(hService);
  641.         }
  642.         CloseServiceHandle(hService);
  643.     }
  644.     return TRUE;
  645. }
  646.  
  647. void CServiceList::SetEnumType( DWORD dwEnumType )
  648. {
  649.     m_dwEnumType = dwEnumType;
  650.     RefreshTitleString();
  651. }
  652.  
  653. static GENERICCOMPAREFN SortMethods[10] = {
  654.     GENERICCOMPAREFN(&CServiceList::SortByDisplayName),
  655.     GENERICCOMPAREFN(&CServiceList::SortByServiceName),
  656.     GENERICCOMPAREFN(&CServiceList::SortByStatus),
  657.     GENERICCOMPAREFN(&CServiceList::SortByStart),
  658.     GENERICCOMPAREFN(&CServiceList::SortByType),
  659.     GENERICCOMPAREFN(&CServiceList::SortByBinaryPathName),
  660.     GENERICCOMPAREFN(&CServiceList::SortByPid),
  661.     GENERICCOMPAREFN(&CServiceList::SortByUser),
  662.     GENERICCOMPAREFN(&CServiceList::SortByLoadOrderGroup),
  663.     GENERICCOMPAREFN(&CServiceList::SortByDescription),
  664. };
  665.  
  666. CServiceList::CServiceList()
  667.     :   CListViewEntries( SortMethods, _T("Services") ),
  668.         m_dwEnumType( SERVICE_WIN32 )
  669. {
  670.     CreateColumns( _T("Service"), _T("Section"), _T("Status"), _T("Start"), _T("Type"), _T("Path"), _T("PID"), _T("User"), _T("Load Order Group"), _T("Description"), NULL );
  671.  
  672.     RefreshTitleString();
  673.  
  674.     // read in m_LoadOrderGroups
  675.     HKEY hKey;
  676.     LONG lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  677.                         _T("SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder"),
  678.                         0,
  679.                         _T(""),
  680.                         0,
  681.                         KEY_READ,
  682.                         NULL,
  683.                         &hKey,
  684.                         0 );
  685.     if( lResult == 0 )
  686.     {
  687.         DWORD dwType = 0, dwData = 0, dwData2;
  688.         RegQueryValueEx(hKey, _T("List"), 0, &dwType, NULL, &dwData ); 
  689.         if( dwData )
  690.         {
  691.             LPBYTE lpbData = new BYTE[dwData+1];
  692.             if( lpbData )
  693.             {
  694.                 dwData2 = dwData;
  695.                 if( RegQueryValueEx(hKey, _T("List"), 0, &dwType, lpbData, &dwData2 ) == 0 )
  696.                 {
  697.                     lpbData[dwData] = 0;
  698.                     ASSERT( dwType == REG_MULTI_SZ );
  699.  
  700.                     LPCTSTR p = (LPCTSTR) lpbData;
  701.                     while( *p )
  702.                     {
  703.                         m_LoadOrderGroups.Add( p );
  704.                         p += (lstrlen(p)+1)*sizeof(TCHAR);
  705.                     }
  706.  
  707.                 }
  708.                 delete lpbData;
  709.             }
  710.         }
  711.         RegCloseKey(hKey);
  712.     }
  713.  
  714. }
  715.  
  716. CServiceList::~CServiceList()
  717. {
  718. }
  719.  
  720. void CServiceList::ConnectTo( LPCTSTR lpszMachine )
  721. {
  722.     m_strServiceMachine = lpszMachine;
  723.     RefreshTitleString();
  724. }
  725.  
  726. void CServiceList::RefreshTitleString()
  727. {
  728.     LPCTSTR lpszTag = GetTagString();
  729.     LPCTSTR lpszMachine = m_strServiceMachine;
  730.     if( !lpszMachine || !*lpszMachine )
  731.     {
  732.         m_strTitle.Format( TEXT("pserv ") CURRENT_VERSION TEXT(": %s on local machine"), lpszTag );
  733.     }
  734.     else
  735.     {
  736.         m_strTitle.Format( TEXT("pserv ") CURRENT_VERSION TEXT(": %s on \\\\%s"), lpszTag, (LPCTSTR)m_strServiceMachine  );
  737.     }
  738. }
  739.  
  740.  
  741. int CServiceList::SortByDisplayName(const CService** ps1, const CService** ps2)
  742. {
  743.     return (*ps1)->m_strDisplayName.CompareNoCase((*ps2)->m_strDisplayName);
  744. }
  745.  
  746. int CServiceList::SortByServiceName(const CService** ps1, const CService** ps2)
  747. {
  748.     return (*ps1)->m_strServiceName.CompareNoCase((*ps2)->m_strServiceName);
  749. }
  750.  
  751. int CServiceList::SortByStatus(const CService** ps1, const CService** ps2)
  752. {
  753.     return LONG((*ps1)->m_ServiceStatus.dwCurrentState)-LONG((*ps2)->m_ServiceStatus.dwCurrentState);
  754. }
  755.  
  756. int CServiceList::SortByStart(const CService** ps1, const CService** ps2)
  757. {
  758.     return LONG((*ps1)->m_dwStartType)-LONG((*ps2)->m_dwStartType);
  759. }
  760.  
  761. int CServiceList::SortByType(const CService** ps1, const CService** ps2)
  762. {
  763.     return LONG((*ps1)->m_dwServiceType)-LONG((*ps2)->m_dwServiceType);
  764. }
  765.  
  766. int CServiceList::SortByBinaryPathName(const CService** ps1, const CService** ps2)
  767. {
  768.     return (*ps1)->m_strBinaryPathName.CompareNoCase((*ps2)->m_strBinaryPathName);
  769. }
  770.  
  771. int CServiceList::SortByUser(const CService** ps1, const CService** ps2)
  772. {
  773.     return (*ps1)->m_strServiceStartName.CompareNoCase((*ps2)->m_strServiceStartName);
  774. }
  775.  
  776. int CServiceList::SortByLoadOrderGroup(const CService** ps1, const CService** ps2)
  777. {
  778.     return (*ps1)->m_strLoadOrderGroup.CompareNoCase((*ps2)->m_strLoadOrderGroup);
  779. }
  780.  
  781. int CServiceList::SortByPid(const CService** ps1, const CService** ps2)
  782. {
  783.     return LONG((*ps1)->m_ServiceStatus.dwProcessId)-LONG((*ps2)->m_ServiceStatus.dwProcessId);
  784. }
  785.  
  786. int CServiceList::SortByDescription(const CService** ps1, const CService** ps2)
  787. {
  788.     return (*ps1)->m_strDescription.CompareNoCase((*ps2)->m_strDescription);
  789. }
  790.  
  791.  
  792. BOOL CServiceList::AddServiceFromStatus(SC_HANDLE hSCM, LPENUM_SERVICE_STATUS_PROCESS lpStatus)
  793. {
  794.     CService* instance = new CService(this);
  795.     if( instance != NULL )
  796.     {
  797.         if( instance->CreateFrom( hSCM, lpStatus ) )
  798.         {
  799.             m_Entries.Add(instance);
  800.             return TRUE;
  801.         }
  802.         else delete instance;
  803.     }
  804.     return FALSE;
  805. }
  806.  
  807. void CServiceList::ExportXmlToFile( CFile* pFile )
  808. {
  809.     LPCTSTR lpszTag = GetTagString();
  810.  
  811.     PrintToFile(pFile, _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"yes\"?>\r\n")
  812.               _T("<%s>\r\n"), lpszTag );
  813.  
  814.     for(int n = 0, nmax = m_Entries.GetSize(); n < nmax; n++ )
  815.     {
  816.         CService* p = (CService*)m_Entries.GetAt(n);
  817.         PrintToFile(pFile, _T("\t<service id=\"%s\">\r\n"), (LPCTSTR) XmlEscape(p->m_strServiceName) );
  818.         PrintToFile(pFile, _T("\t\t<name>%s</name>\r\n"),(LPCTSTR)  XmlEscape(p->m_strDisplayName) );
  819.         PrintToFile(pFile, _T("\t\t<status>%s</status>\r\n"), (LPCTSTR) p->GetStatusAsString() );
  820.         PrintToFile(pFile, _T("\t\t<start>%s</start>\r\n"), (LPCTSTR) p->GetStartAsString() );
  821.         PrintToFile(pFile, _T("\t\t<type>%s</type>\r\n"), (LPCTSTR) p->GetTypeAsString() );
  822.         PrintToFile(pFile, _T("\t\t<path>%s</path>\r\n"), (LPCTSTR) p->m_strBinaryPathName );
  823.         PrintToFile(pFile, _T("\t\t<pid>%s</pid>\r\n"), (LPCTSTR) p->GetPidAsString() );
  824.         PrintToFile(pFile, _T("\t\t<description>%s</description>\r\n"), (LPCTSTR) XmlEscape(p->m_strDescription) );
  825.         PrintToFile(pFile, _T("\t</service>\r\n") );
  826.     }
  827.  
  828.     PrintToFile(pFile, _T("</%s>"), lpszTag);
  829. }
  830.  
  831. BOOL CServiceList::Refresh()
  832. {
  833.     BOOL bSuccess = FALSE;
  834.     DeleteObjects( m_Entries );
  835.  
  836.     SC_HANDLE hSCM = OpenSCManager( m_strServiceMachine, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE ); 
  837.     if( hSCM )
  838.     {
  839.         DWORD dwBytesNeeded, dwServicesReturned, dwResumeHandle = 0;
  840.         if( lpfnEnumServicesStatusEx )
  841.         {
  842.             VERIFY( !lpfnEnumServicesStatusEx( hSCM, SC_ENUM_PROCESS_INFO, m_dwEnumType, SERVICE_STATE_ALL, 
  843.                 NULL, 0, &dwBytesNeeded, &dwServicesReturned, &dwResumeHandle, NULL ) );
  844.             
  845.             ASSERT( GetLastError() == ERROR_MORE_DATA );
  846.  
  847.             LPBYTE bBuffer = new BYTE[dwBytesNeeded];
  848.             if( bBuffer )
  849.             {
  850.                 if( lpfnEnumServicesStatusEx( hSCM, SC_ENUM_PROCESS_INFO, m_dwEnumType, SERVICE_STATE_ALL, 
  851.                     bBuffer, dwBytesNeeded, &dwBytesNeeded, &dwServicesReturned, &dwResumeHandle, NULL ) )
  852.                 {
  853.                     LPENUM_SERVICE_STATUS_PROCESS lpStatus = (LPENUM_SERVICE_STATUS_PROCESS)bBuffer;
  854.                     for( DWORD dwIndex = 0; dwIndex < dwServicesReturned; dwIndex++ )
  855.                     {
  856.                         bSuccess = AddServiceFromStatus( hSCM, &(lpStatus[dwIndex]));
  857.                     }
  858.                 }
  859.                 delete bBuffer;
  860.             }
  861.         }
  862.         else 
  863.         {
  864.             VERIFY( !EnumServicesStatus( hSCM, m_dwEnumType, SERVICE_STATE_ALL, 0, 0, &dwBytesNeeded, &dwServicesReturned, &dwResumeHandle ) );
  865.             ASSERT( GetLastError() == ERROR_MORE_DATA );
  866.  
  867.             LPBYTE bBuffer = new BYTE[dwBytesNeeded];
  868.             if( bBuffer )
  869.             {
  870.             
  871.                 if( EnumServicesStatus( hSCM, m_dwEnumType, SERVICE_STATE_ALL, (LPENUM_SERVICE_STATUS)bBuffer, dwBytesNeeded, &dwBytesNeeded, &dwServicesReturned, &dwResumeHandle ) )
  872.                 {
  873.                     LPENUM_SERVICE_STATUS lpStatus = (LPENUM_SERVICE_STATUS)bBuffer;
  874.                     for( DWORD dwIndex = 0; dwIndex < dwServicesReturned; dwIndex++ )
  875.                     {
  876.                         LPENUM_SERVICE_STATUS s = &(lpStatus[dwIndex]);
  877.                         ENUM_SERVICE_STATUS_PROCESS esp;
  878.                         CopyMemory( &esp, s, sizeof(ENUM_SERVICE_STATUS) );
  879.                         esp.ServiceStatusProcess.dwProcessId = 0;
  880.                         esp.ServiceStatusProcess.dwServiceFlags = 0;
  881.                         bSuccess = AddServiceFromStatus( hSCM, &esp);
  882.                     }
  883.                 }
  884.                 delete bBuffer;
  885.             }
  886.         }
  887.  
  888.         Sort();
  889.  
  890.         CloseServiceHandle(hSCM);
  891.     }
  892.     if( !bSuccess )
  893.         DisplayErrorMessage(_T("Unable to get initial list of %s"), GetTagString() );
  894.  
  895.     return bSuccess;
  896. }
  897.  
  898. UINT CServiceList::GetContextMenuID()
  899. {
  900.     return IDR_CONTEXTMENU;
  901. }
  902.  
  903.  
  904.