mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 17:01:28 +00:00
- Use a more generic print service
- don't assign a service name at the start as it causes problems when query(ex) doesn't supply one. - Simplify the service starting code. - Add missing options to the print type - rewrite the querying functionality to be cleaner, and use existing code. - remove the braces I left, used for collapsing dbg info svn path=/trunk/; revision=23868
This commit is contained in:
parent
9e843c89fc
commit
61059050bb
|
@ -21,7 +21,6 @@ Control(DWORD Control,
|
|||
DWORD dwDesiredAccess = 0;
|
||||
|
||||
#ifdef SCDBG
|
||||
{
|
||||
LPCTSTR *TmpArgs = Args;
|
||||
INT TmpCnt = ArgCount;
|
||||
_tprintf(_T("service to control - %s\n"), ServiceName);
|
||||
|
@ -34,7 +33,6 @@ Control(DWORD Control,
|
|||
TmpCnt--;
|
||||
}
|
||||
_tprintf(_T("\n"));
|
||||
}
|
||||
#endif /* SCDBG */
|
||||
|
||||
switch (Control)
|
||||
|
@ -75,8 +73,16 @@ Control(DWORD Control,
|
|||
Control,
|
||||
&Status))
|
||||
{
|
||||
SERVICE_STATUS_PROCESS StatusEx;
|
||||
|
||||
/* FIXME: lazy hack ;) */
|
||||
CopyMemory(&StatusEx, &Status, sizeof(Status));
|
||||
StatusEx.dwProcessId = 0;
|
||||
StatusEx.dwServiceFlags = 0;
|
||||
|
||||
PrintService(ServiceName,
|
||||
&Status);
|
||||
&StatusEx,
|
||||
FALSE);
|
||||
|
||||
CloseServiceHandle(hSc);
|
||||
CloseServiceHandle(hSCManager);
|
||||
|
|
|
@ -29,7 +29,6 @@ BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs)
|
|||
lpBinaryPathName = *ServiceArgs;
|
||||
|
||||
#ifdef SCDBG
|
||||
{
|
||||
_tprintf(_T("service name - %s\n"), ServiceName);
|
||||
_tprintf(_T("display name - %s\n"), ServiceName);
|
||||
_tprintf(_T("service type - %lu\n"), dwServiceType);
|
||||
|
@ -41,7 +40,6 @@ BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs)
|
|||
_tprintf(_T("dependincies - %s\n"), lpDependencies);
|
||||
_tprintf(_T("account start name - %s\n"), lpServiceStartName);
|
||||
_tprintf(_T("account password - %s\n"), lpPassword);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ServiceName)
|
||||
|
|
|
@ -15,9 +15,7 @@ BOOL Delete(LPCTSTR ServiceName)
|
|||
SC_HANDLE hSc = NULL;
|
||||
|
||||
#ifdef SCDBG
|
||||
{
|
||||
_tprintf(_T("service to delete - %s\n\n"), ServiceName);
|
||||
}
|
||||
#endif
|
||||
|
||||
hSCManager = OpenSCManager(NULL,
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Services
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/system/sc/print.c
|
||||
* PURPOSE: print service info
|
||||
* COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
|
||||
|
||||
VOID
|
||||
PrintServiceEx(LPCTSTR lpServiceName,
|
||||
LPSERVICE_STATUS_PROCESS pStatusEx)
|
||||
{
|
||||
SERVICE_STATUS Status;
|
||||
|
||||
/*FIXME: quick hack, assign values 1 by 1 */
|
||||
CopyMemory(&Status, pStatusEx, sizeof(SERVICE_STATUS));
|
||||
|
||||
PrintService(lpServiceName,
|
||||
&Status);
|
||||
|
||||
_tprintf(_T("\tPID : %lu\n"),
|
||||
pStatusEx->dwProcessId);
|
||||
_tprintf(_T("\tFLAGS : %lu\n"),
|
||||
pStatusEx->dwServiceFlags);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
PrintService(LPCTSTR lpServiceName,
|
||||
LPSERVICE_STATUS pStatus)
|
||||
LPSERVICE_STATUS_PROCESS pStatus,
|
||||
BOOL bExtended)
|
||||
{
|
||||
_tprintf(_T("SERVICE_NAME: %s\n"), lpServiceName);
|
||||
|
||||
|
@ -30,10 +21,30 @@ PrintService(LPCTSTR lpServiceName,
|
|||
(unsigned int)pStatus->dwServiceType);
|
||||
switch (pStatus->dwServiceType)
|
||||
{
|
||||
case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
|
||||
case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
|
||||
case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
|
||||
case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
|
||||
case SERVICE_KERNEL_DRIVER:
|
||||
_tprintf(_T("KERNEL_DRIVER\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_FILE_SYSTEM_DRIVER:
|
||||
_tprintf(_T("FILE_SYSTEM_DRIVER\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_WIN32_OWN_PROCESS:
|
||||
_tprintf(_T("WIN32_OWN_PROCESS\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_WIN32_SHARE_PROCESS:
|
||||
_tprintf(_T("WIN32_SHARE_PROCESS\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_WIN32_OWN_PROCESS + SERVICE_INTERACTIVE_PROCESS:
|
||||
_tprintf(_T("WIN32_OWN_PROCESS (interactive)\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_WIN32_SHARE_PROCESS + SERVICE_INTERACTIVE_PROCESS:
|
||||
_tprintf(_T("WIN32_SHARE_PROCESS (interactive)\n"));
|
||||
break;
|
||||
|
||||
default : _tprintf(_T("\n")); break;
|
||||
}
|
||||
|
||||
|
@ -65,7 +76,7 @@ PrintService(LPCTSTR lpServiceName,
|
|||
_tprintf(_T("NOT_PAUSABLE,"));
|
||||
|
||||
if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN)
|
||||
_tprintf(_T("???"));
|
||||
_tprintf(_T("ACCEPTS_SHUTDOWN"));
|
||||
else
|
||||
_tprintf(_T("IGNORES_SHUTDOWN"));
|
||||
|
||||
|
@ -81,4 +92,14 @@ PrintService(LPCTSTR lpServiceName,
|
|||
(unsigned int)pStatus->dwCheckPoint);
|
||||
_tprintf(_T("\tWAIT_HINT : 0x%x\n"),
|
||||
(unsigned int)pStatus->dwWaitHint);
|
||||
|
||||
if (bExtended)
|
||||
{
|
||||
_tprintf(_T("\tPID : %lu\n"),
|
||||
pStatus->dwProcessId);
|
||||
_tprintf(_T("\tFLAGS : %lu\n"),
|
||||
pStatus->dwServiceFlags);
|
||||
}
|
||||
|
||||
_tprintf(_T("\n"));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS SC utility
|
||||
* FILE: subsys/system/sc/query.c
|
||||
* PURPOSE: control ReactOS services
|
||||
* PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
|
||||
* REVISIONS:
|
||||
* Ged Murphy 20/10/05 Created
|
||||
* PROJECT: ReactOS Services
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/system/sc/query.c
|
||||
* PURPOSE: queries service info
|
||||
* COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
|
||||
*
|
||||
*/
|
||||
/*
|
||||
|
@ -16,82 +14,20 @@
|
|||
|
||||
#include "sc.h"
|
||||
|
||||
/* local function decs */
|
||||
VOID PrintService2(BOOL bExtended);
|
||||
BOOL EnumServices(DWORD ServiceType, DWORD ServiceState);
|
||||
BOOL QueryService(LPCTSTR ServiceName, BOOL bExtended);
|
||||
|
||||
/* global variables */
|
||||
static ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL;
|
||||
DWORD NumServices = 0;
|
||||
LPTSTR QueryOpts[] = {
|
||||
_T("type="),
|
||||
_T("state="),
|
||||
_T("bufsize="),
|
||||
_T("ri="),
|
||||
_T("group="),
|
||||
};
|
||||
|
||||
|
||||
BOOL
|
||||
Query(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, BOOL bExtended)
|
||||
{
|
||||
if (! ServiceName) /* display all running services and drivers */
|
||||
{
|
||||
/* get default values */
|
||||
EnumServices(SERVICE_WIN32, SERVICE_ACTIVE);
|
||||
|
||||
/* print default values */
|
||||
PrintService2(bExtended);
|
||||
}
|
||||
else if (_tcsicmp(ServiceName, _T("type=")) == 0)
|
||||
{
|
||||
LPCTSTR Type = *ServiceArgs;
|
||||
|
||||
if (_tcsicmp(Type, _T("driver")) == 0)
|
||||
EnumServices(SERVICE_DRIVER, SERVICE_ACTIVE);
|
||||
else if (_tcsicmp(Type, _T("service")) == 0)
|
||||
EnumServices(SERVICE_WIN32, SERVICE_ACTIVE);
|
||||
else if (_tcsicmp(Type, _T("all")) == 0)
|
||||
EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_ACTIVE);
|
||||
else
|
||||
{
|
||||
_tprintf(_T("\nERROR following \"type=\"!\n"));
|
||||
_tprintf(_T("Must be \"driver\" or \"service\" or \"all\"\n"));
|
||||
}
|
||||
|
||||
PrintService2(bExtended);
|
||||
}
|
||||
else if(_tcsicmp(ServiceName, _T("state=")) == 0)
|
||||
{
|
||||
LPCTSTR State = *ServiceArgs;
|
||||
|
||||
if (_tcsicmp(State, _T("inactive")) == 0)
|
||||
EnumServices(SERVICE_WIN32, SERVICE_INACTIVE);
|
||||
else if (_tcsicmp(State, _T("all")) == 0)
|
||||
EnumServices(SERVICE_WIN32, SERVICE_STATE_ALL);
|
||||
else
|
||||
{
|
||||
_tprintf(_T("\nERROR following \"state=\"!\n"));
|
||||
_tprintf(_T("Must be \"active\" or \"inactive\" or \"all\"\n"));
|
||||
}
|
||||
|
||||
PrintService2(bExtended);
|
||||
}
|
||||
/*
|
||||
else if(_tcsicmp(ServiceName, _T("bufsize=")))
|
||||
|
||||
else if(_tcsicmp(ServiceName, _T("ri=")))
|
||||
|
||||
else if(_tcsicmp(ServiceName, _T("group=")))
|
||||
*/
|
||||
else /* print only the service requested */
|
||||
{
|
||||
QueryService(ServiceName, bExtended);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
QueryService(LPCTSTR ServiceName, BOOL bExtended)
|
||||
LPSERVICE_STATUS_PROCESS
|
||||
QueryService(LPCTSTR ServiceName)
|
||||
{
|
||||
SC_HANDLE hSCManager;
|
||||
SERVICE_STATUS_PROCESS *pServiceInfo = NULL;
|
||||
LPSERVICE_STATUS_PROCESS pServiceInfo = NULL;
|
||||
SC_HANDLE hSc;
|
||||
DWORD BufSiz = 0;
|
||||
DWORD BytesNeeded = 0;
|
||||
|
@ -103,120 +39,59 @@ QueryService(LPCTSTR ServiceName, BOOL bExtended)
|
|||
if (hSCManager == NULL)
|
||||
{
|
||||
ReportLastError();
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hSc = OpenService(hSCManager, ServiceName, SERVICE_QUERY_STATUS);
|
||||
|
||||
hSc = OpenService(hSCManager,
|
||||
ServiceName,
|
||||
SERVICE_QUERY_STATUS);
|
||||
if (hSc == NULL)
|
||||
{
|
||||
_tprintf(_T("QueryService: openService failed\n"));
|
||||
ReportLastError();
|
||||
return FALSE;
|
||||
}
|
||||
goto fail;
|
||||
|
||||
Ret = QueryServiceStatusEx(hSc,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
NULL,
|
||||
BufSiz,
|
||||
&BytesNeeded);
|
||||
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
NULL,
|
||||
BufSiz,
|
||||
&BytesNeeded);
|
||||
if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
|
||||
{
|
||||
_tprintf(_T("QueryService: First call to QueryServiceStatusEx failed : "));
|
||||
ReportLastError();
|
||||
return FALSE;
|
||||
}
|
||||
else /* Call function again if required size was returned */
|
||||
{
|
||||
/* reserve memory for service info array */
|
||||
pServiceInfo = (SERVICE_STATUS_PROCESS *)
|
||||
HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
|
||||
if (pServiceInfo == NULL)
|
||||
{
|
||||
_tprintf(_T("QueryService: Failed to allocate memory : "));
|
||||
ReportLastError();
|
||||
return FALSE;
|
||||
}
|
||||
goto fail;
|
||||
|
||||
/* fill array with service info */
|
||||
if (! QueryServiceStatusEx(hSc,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)pServiceInfo,
|
||||
BytesNeeded,
|
||||
&BytesNeeded))
|
||||
{
|
||||
_tprintf(_T("QueryService: Second call to QueryServiceStatusEx failed : "));
|
||||
ReportLastError();
|
||||
HeapFree(GetProcessHeap(), 0, pServiceInfo);
|
||||
return FALSE;
|
||||
}
|
||||
pServiceInfo = (LPSERVICE_STATUS_PROCESS)HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
BytesNeeded);
|
||||
if (pServiceInfo == NULL)
|
||||
goto fail;
|
||||
|
||||
if (!QueryServiceStatusEx(hSc,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)pServiceInfo,
|
||||
BytesNeeded,
|
||||
&BytesNeeded))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return pServiceInfo;
|
||||
|
||||
_tprintf(_T("SERVICE_NAME: %s\n"), ServiceName);
|
||||
|
||||
_tprintf(_T("\tTYPE : %x "),
|
||||
(unsigned int)pServiceInfo->dwServiceType);
|
||||
switch (pServiceInfo->dwServiceType)
|
||||
{
|
||||
case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
|
||||
case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
|
||||
case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
|
||||
case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
|
||||
default : _tprintf(_T("\n")); break;
|
||||
}
|
||||
|
||||
_tprintf(_T("\tSTATE : %x "),
|
||||
(unsigned int)pServiceInfo->dwCurrentState);
|
||||
|
||||
switch (pServiceInfo->dwCurrentState)
|
||||
{
|
||||
case 1 : _tprintf(_T("STOPPED\n")); break;
|
||||
case 2 : _tprintf(_T("START_PENDING\n")); break;
|
||||
case 3 : _tprintf(_T("STOP_PENDING\n")); break;
|
||||
case 4 : _tprintf(_T("RUNNING\n")); break;
|
||||
case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;
|
||||
case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;
|
||||
case 7 : _tprintf(_T("PAUSED\n")); break;
|
||||
default : _tprintf(_T("\n")); break;
|
||||
}
|
||||
|
||||
// _tprintf(_T("\n\taccepted : 0x%x\n\n"),
|
||||
// pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted);
|
||||
// (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)
|
||||
|
||||
_tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"),
|
||||
(unsigned int)pServiceInfo->dwWin32ExitCode,
|
||||
(unsigned int)pServiceInfo->dwWin32ExitCode);
|
||||
_tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"),
|
||||
(unsigned int)pServiceInfo->dwServiceSpecificExitCode,
|
||||
(unsigned int)pServiceInfo->dwServiceSpecificExitCode);
|
||||
_tprintf(_T("\tCHECKPOINT : 0x%x\n"),
|
||||
(unsigned int)pServiceInfo->dwCheckPoint);
|
||||
_tprintf(_T("\tWAIT_HINT : 0x%x\n"),
|
||||
(unsigned int)pServiceInfo->dwWaitHint);
|
||||
if (bExtended)
|
||||
{
|
||||
_tprintf(_T("\tPID : %lu\n"),
|
||||
pServiceInfo->dwProcessId);
|
||||
_tprintf(_T("\tFLAGS : %lu\n"),
|
||||
pServiceInfo->dwServiceFlags);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pServiceInfo);
|
||||
|
||||
return TRUE;
|
||||
fail:
|
||||
ReportLastError();
|
||||
if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo);
|
||||
if (hSc) CloseServiceHandle(hSc);
|
||||
if (hSCManager) CloseServiceHandle(hSCManager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
EnumServices(DWORD ServiceType, DWORD ServiceState)
|
||||
static BOOL
|
||||
EnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus,
|
||||
DWORD ServiceType,
|
||||
DWORD ServiceState)
|
||||
{
|
||||
SC_HANDLE hSCManager;
|
||||
DWORD BufSize = 0;
|
||||
DWORD BytesNeeded = 0;
|
||||
DWORD ResumeHandle = 0;
|
||||
DWORD NumServices = 0;
|
||||
DWORD Ret;
|
||||
|
||||
hSCManager = OpenSCManager(NULL,
|
||||
|
@ -228,120 +103,146 @@ EnumServices(DWORD ServiceType, DWORD ServiceState)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* determine required buffer size */
|
||||
Ret = EnumServicesStatusEx(hSCManager,
|
||||
SC_ENUM_PROCESS_INFO,
|
||||
ServiceType,
|
||||
ServiceState,
|
||||
(LPBYTE)pServiceStatus,
|
||||
BufSize,
|
||||
&BytesNeeded,
|
||||
&NumServices,
|
||||
&ResumeHandle,
|
||||
0);
|
||||
SC_ENUM_PROCESS_INFO,
|
||||
ServiceType,
|
||||
ServiceState,
|
||||
(LPBYTE)*pServiceStatus,
|
||||
BufSize,
|
||||
&BytesNeeded,
|
||||
&NumServices,
|
||||
&ResumeHandle,
|
||||
0);
|
||||
|
||||
if ((Ret != 0) && (GetLastError() != ERROR_MORE_DATA))
|
||||
if ((Ret == 0) && (GetLastError() == ERROR_MORE_DATA))
|
||||
{
|
||||
_tprintf(_T("EnumServices: First call to EnumServicesStatusEx failed : "));
|
||||
ReportLastError();
|
||||
*pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *)
|
||||
HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
BytesNeeded);
|
||||
if (*pServiceStatus != NULL)
|
||||
{
|
||||
if (EnumServicesStatusEx(hSCManager,
|
||||
SC_ENUM_PROCESS_INFO,
|
||||
ServiceType,
|
||||
ServiceState,
|
||||
(LPBYTE)*pServiceStatus,
|
||||
BytesNeeded,
|
||||
&BytesNeeded,
|
||||
&NumServices,
|
||||
&ResumeHandle,
|
||||
0))
|
||||
{
|
||||
return NumServices;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReportLastError();
|
||||
if (pServiceStatus)
|
||||
HeapFree(GetProcessHeap(), 0, *pServiceStatus);
|
||||
|
||||
return NumServices;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
Query(LPCTSTR *ServiceArgs,
|
||||
DWORD ArgCount,
|
||||
BOOL bExtended)
|
||||
{
|
||||
LPENUM_SERVICE_STATUS_PROCESS pServiceStatus = NULL;
|
||||
DWORD NumServices = 0;
|
||||
//DWORD ServiceType;
|
||||
//DWORD ServiceState;
|
||||
BOOL bServiceName = TRUE;
|
||||
DWORD OptSize, i;
|
||||
|
||||
LPCTSTR *TmpArgs;
|
||||
INT TmpCnt;
|
||||
|
||||
#ifdef SCDBG
|
||||
TmpArgs = ServiceArgs;
|
||||
TmpCnt = ArgCount;
|
||||
_tprintf(_T("Arguments:\n"));
|
||||
while (TmpCnt)
|
||||
{
|
||||
_tprintf(_T(" %s\n"), *TmpArgs);
|
||||
TmpArgs++;
|
||||
TmpCnt--;
|
||||
}
|
||||
_tprintf(_T("\n"));
|
||||
#endif /* SCDBG */
|
||||
|
||||
/* display all running services and drivers */
|
||||
if (ArgCount == 0)
|
||||
{
|
||||
NumServices = EnumServices(&pServiceStatus,
|
||||
SERVICE_WIN32,
|
||||
SERVICE_ACTIVE);
|
||||
|
||||
if (NumServices != 0)
|
||||
{
|
||||
for (i=0; i < NumServices; i++)
|
||||
{
|
||||
PrintService(pServiceStatus[i].lpServiceName,
|
||||
&pServiceStatus[i].ServiceStatusProcess,
|
||||
bExtended);
|
||||
}
|
||||
|
||||
_tprintf(_T("number : %lu\n"), NumServices);
|
||||
|
||||
if (pServiceStatus)
|
||||
HeapFree(GetProcessHeap(), 0, pServiceStatus);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else /* Call function again if required size was returned */
|
||||
{
|
||||
/* reserve memory for service info array */
|
||||
pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *)
|
||||
HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
|
||||
if (pServiceStatus == NULL)
|
||||
{
|
||||
_tprintf(_T("EnumServices: Failed to allocate memory : "));
|
||||
ReportLastError();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* fill array with service info */
|
||||
if (! EnumServicesStatusEx(hSCManager,
|
||||
SC_ENUM_PROCESS_INFO,
|
||||
ServiceType,
|
||||
ServiceState,
|
||||
(LPBYTE)pServiceStatus,
|
||||
BytesNeeded,
|
||||
&BytesNeeded,
|
||||
&NumServices,
|
||||
&ResumeHandle,
|
||||
0))
|
||||
TmpArgs = ServiceArgs;
|
||||
TmpCnt = ArgCount;
|
||||
OptSize = sizeof(QueryOpts) / sizeof(QueryOpts[0]);
|
||||
while (TmpCnt--)
|
||||
{
|
||||
for (i=0; i < OptSize; i++)
|
||||
{
|
||||
_tprintf(_T("EnumServices: Second call to EnumServicesStatusEx failed : "));
|
||||
ReportLastError();
|
||||
HeapFree(GetProcessHeap(), 0, pServiceStatus);
|
||||
return FALSE;
|
||||
if (!lstrcmpi(*TmpArgs, QueryOpts[i]))
|
||||
{
|
||||
bServiceName = FALSE;
|
||||
}
|
||||
}
|
||||
*TmpArgs++;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: parse options */
|
||||
|
||||
|
||||
/* print only the service requested */
|
||||
if (bServiceName)
|
||||
{
|
||||
LPSERVICE_STATUS_PROCESS pStatus;
|
||||
LPCTSTR ServiceName = *ServiceArgs;
|
||||
|
||||
pStatus = QueryService(ServiceName);
|
||||
if (bExtended)
|
||||
{
|
||||
PrintService(ServiceName,
|
||||
pStatus,
|
||||
TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintService(ServiceName,
|
||||
pStatus,
|
||||
FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (pServiceStatus)
|
||||
HeapFree(GetProcessHeap(), 0, pServiceStatus);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
PrintService2(BOOL bExtended)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for (i=0; i < NumServices; i++)
|
||||
{
|
||||
|
||||
_tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus[i].lpServiceName);
|
||||
_tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus[i].lpDisplayName);
|
||||
|
||||
_tprintf(_T("\tTYPE : %x "),
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwServiceType);
|
||||
switch (pServiceStatus[i].ServiceStatusProcess.dwServiceType)
|
||||
{
|
||||
case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
|
||||
case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
|
||||
case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
|
||||
case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
|
||||
default : _tprintf(_T("\n")); break;
|
||||
}
|
||||
|
||||
_tprintf(_T("\tSTATE : %x "),
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwCurrentState);
|
||||
|
||||
switch (pServiceStatus[i].ServiceStatusProcess.dwCurrentState)
|
||||
{
|
||||
case 1 : _tprintf(_T("STOPPED\n")); break;
|
||||
case 2 : _tprintf(_T("START_PENDING\n")); break;
|
||||
case 3 : _tprintf(_T("STOP_PENDING\n")); break;
|
||||
case 4 : _tprintf(_T("RUNNING\n")); break;
|
||||
case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;
|
||||
case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;
|
||||
case 7 : _tprintf(_T("PAUSED\n")); break;
|
||||
default : _tprintf(_T("\n")); break;
|
||||
}
|
||||
|
||||
// _tprintf(_T("\n\taccepted : 0x%x\n\n"),
|
||||
// pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted);
|
||||
// (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)
|
||||
|
||||
_tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"),
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwWin32ExitCode,
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwWin32ExitCode);
|
||||
_tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"),
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwServiceSpecificExitCode,
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwServiceSpecificExitCode);
|
||||
_tprintf(_T("\tCHECKPOINT : 0x%x\n"),
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwCheckPoint);
|
||||
_tprintf(_T("\tWAIT_HINT : 0x%x\n"),
|
||||
(unsigned int)pServiceStatus[i].ServiceStatusProcess.dwWaitHint);
|
||||
if (bExtended)
|
||||
{
|
||||
_tprintf(_T("\tPID : %lu\n"),
|
||||
pServiceStatus[i].ServiceStatusProcess.dwProcessId);
|
||||
_tprintf(_T("\tFLAGS : %lu\n"),
|
||||
pServiceStatus[i].ServiceStatusProcess.dwServiceFlags);
|
||||
}
|
||||
|
||||
_tprintf(_T("\n"));
|
||||
}
|
||||
|
||||
_tprintf(_T("number : %lu\n"), NumServices);
|
||||
}
|
||||
|
|
|
@ -42,10 +42,11 @@ ReportLastError(VOID)
|
|||
static INT
|
||||
ScControl(LPCTSTR Server, // remote machine name
|
||||
LPCTSTR Command, // sc command
|
||||
LPCTSTR ServiceName, // name of service
|
||||
LPCTSTR *ServiceArgs, // any options
|
||||
DWORD ArgCount) // argument counter
|
||||
{
|
||||
LPCTSTR ServiceName = NULL;
|
||||
|
||||
if (Server)
|
||||
{
|
||||
_tprintf(_T("Remote service control is not yet implemented\n"));
|
||||
|
@ -54,18 +55,21 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
|
||||
if (!lstrcmpi(Command, _T("query")))
|
||||
{
|
||||
Query(ServiceName,
|
||||
ServiceArgs,
|
||||
Query(ServiceArgs,
|
||||
ArgCount,
|
||||
FALSE);
|
||||
}
|
||||
else if (!lstrcmpi(Command, _T("queryex")))
|
||||
{
|
||||
Query(ServiceName,
|
||||
ServiceArgs,
|
||||
Query(ServiceArgs,
|
||||
ArgCount,
|
||||
TRUE);
|
||||
}
|
||||
else if (!lstrcmpi(Command, _T("start")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (ServiceName)
|
||||
{
|
||||
Start(ServiceName,
|
||||
|
@ -77,6 +81,9 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
else if (!lstrcmpi(Command, _T("pause")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (ServiceName)
|
||||
{
|
||||
Control(SERVICE_CONTROL_PAUSE,
|
||||
|
@ -89,6 +96,9 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
else if (!lstrcmpi(Command, _T("interrogate")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (ServiceName)
|
||||
{
|
||||
Control(SERVICE_CONTROL_INTERROGATE,
|
||||
|
@ -101,6 +111,9 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
else if (!lstrcmpi(Command, _T("stop")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (ServiceName)
|
||||
{
|
||||
Control(SERVICE_CONTROL_STOP,
|
||||
|
@ -113,6 +126,9 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
else if (!lstrcmpi(Command, _T("continue")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (ServiceName)
|
||||
{
|
||||
Control(SERVICE_CONTROL_CONTINUE,
|
||||
|
@ -125,6 +141,9 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
else if (!lstrcmpi(Command, _T("delete")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (ServiceName)
|
||||
Delete(ServiceName);
|
||||
else
|
||||
|
@ -132,6 +151,9 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
}
|
||||
else if (!lstrcmpi(Command, _T("create")))
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
if (*ServiceArgs)
|
||||
Create(ServiceName,
|
||||
ServiceArgs);
|
||||
|
@ -142,6 +164,9 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
{
|
||||
INT CtlValue;
|
||||
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
CtlValue = _ttoi(ServiceArgs[0]);
|
||||
ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
@ -170,9 +195,9 @@ static
|
|||
|
||||
int _tmain(int argc, LPCTSTR argv[])
|
||||
{
|
||||
LPCTSTR Server = NULL; // remote machine
|
||||
LPCTSTR Command = NULL; // sc command
|
||||
LPCTSTR ServiceName = NULL; // name of service
|
||||
LPCTSTR Server = NULL; // remote machine
|
||||
LPCTSTR Command = NULL; // sc command
|
||||
LPCTSTR *Args = NULL; // Any remaining args
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
|
@ -192,25 +217,23 @@ int _tmain(int argc, LPCTSTR argv[])
|
|||
Server = argv[1];
|
||||
Command = argv[2];
|
||||
if (argc > 3)
|
||||
ServiceName = argv[3];
|
||||
Args = &argv[3];
|
||||
|
||||
return ScControl(Server,
|
||||
Command,
|
||||
ServiceName,
|
||||
&argv[4],
|
||||
argc-4);
|
||||
Args,
|
||||
argc-3);
|
||||
}
|
||||
else
|
||||
{
|
||||
Command = argv[1];
|
||||
if (argc > 2)
|
||||
ServiceName = argv[2];
|
||||
Args = &argv[2];
|
||||
|
||||
return ScControl(Server,
|
||||
Command,
|
||||
ServiceName,
|
||||
&argv[3],
|
||||
argc-3);
|
||||
Args,
|
||||
argc-2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
//#define SCDBG
|
||||
|
||||
VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS pStatus);
|
||||
VOID PrintServiceEx(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus);
|
||||
#define SCDBG
|
||||
|
||||
/* control functions */
|
||||
BOOL Query(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, BOOL bExtended);
|
||||
BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount);
|
||||
BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs);
|
||||
BOOL Delete(LPCTSTR ServiceName);
|
||||
BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args, INT ArgCount);
|
||||
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended);
|
||||
|
||||
LPSERVICE_STATUS_PROCESS QueryService(LPCTSTR ServiceName);
|
||||
|
||||
/* print and error functions */
|
||||
VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended);
|
||||
VOID ReportLastError(VOID);
|
||||
|
||||
/* usage functions */
|
||||
|
|
|
@ -11,15 +11,11 @@
|
|||
|
||||
BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount)
|
||||
{
|
||||
SC_HANDLE hSCManager = NULL;
|
||||
SC_HANDLE hSc = NULL;
|
||||
SC_HANDLE hSCManager;
|
||||
SC_HANDLE hSc;
|
||||
LPSERVICE_STATUS_PROCESS pServiceInfo = NULL;
|
||||
DWORD BufSiz = 0;
|
||||
DWORD BytesNeeded = 0;
|
||||
DWORD Ret;
|
||||
|
||||
#ifdef SCDBG
|
||||
{
|
||||
LPCTSTR *TmpArgs = ServiceArgs;
|
||||
INT TmpCnt = ArgCount;
|
||||
_tprintf(_T("service to control - %s\n"), ServiceName);
|
||||
|
@ -31,24 +27,23 @@ BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount)
|
|||
TmpCnt--;
|
||||
}
|
||||
_tprintf(_T("\n"));
|
||||
}
|
||||
#endif /* SCDBG */
|
||||
|
||||
hSCManager = OpenSCManager(NULL,
|
||||
NULL,
|
||||
SC_MANAGER_CONNECT);
|
||||
if (hSCManager == NULL)
|
||||
goto fail;
|
||||
{
|
||||
ReportLastError();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hSc = OpenService(hSCManager,
|
||||
ServiceName,
|
||||
SERVICE_START | SERVICE_QUERY_STATUS);
|
||||
|
||||
if (hSc == NULL)
|
||||
{
|
||||
_tprintf(_T("openService failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (! StartService(hSc,
|
||||
ArgCount,
|
||||
|
@ -58,33 +53,14 @@ BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
Ret = QueryServiceStatusEx(hSc,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
NULL,
|
||||
BufSiz,
|
||||
&BytesNeeded);
|
||||
if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) //FIXME: check this
|
||||
goto fail;
|
||||
|
||||
|
||||
pServiceInfo = (LPSERVICE_STATUS_PROCESS)HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
BytesNeeded);
|
||||
if (pServiceInfo == NULL)
|
||||
goto fail;
|
||||
|
||||
if (!QueryServiceStatusEx(hSc,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)pServiceInfo,
|
||||
BytesNeeded,
|
||||
&BytesNeeded))
|
||||
pServiceInfo = QueryService(ServiceName);
|
||||
if (pServiceInfo != NULL)
|
||||
{
|
||||
goto fail;
|
||||
PrintService(ServiceName,
|
||||
pServiceInfo,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
PrintServiceEx(ServiceName,
|
||||
pServiceInfo);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pServiceInfo);
|
||||
CloseServiceHandle(hSc);
|
||||
CloseServiceHandle(hSCManager);
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS SC utility
|
||||
* FILE: subsys/system/sc/usage.c
|
||||
* PURPOSE: control ReactOS services
|
||||
* PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
|
||||
* REVISIONS:
|
||||
* Ged Murphy 20/10/05 Created
|
||||
* PROJECT: ReactOS Services
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/system/sc/usage.c
|
||||
* PURPOSE: display usage info
|
||||
* COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
|
||||
*
|
||||
*/
|
||||
#include "sc.h"
|
||||
|
@ -26,7 +24,7 @@ VOID MainUsage(VOID)
|
|||
_T("\t query : Queries the status for a service, or\n")
|
||||
_T("\t enumerates the status for types of services.\n")
|
||||
_T("\t queryex : Queries the extended status for a service, or\n")
|
||||
// _T("\t enumerates the status for types of services.\n"
|
||||
_T("\t enumerates the status for types of services.\n")
|
||||
_T("\t start : Starts a service.\n")
|
||||
_T("\t pause : Sends a PAUSE control request to a service.\n")
|
||||
_T("\t interrogate : Sends a INTERROGATE control request to a service.\n")
|
||||
|
@ -63,7 +61,7 @@ VOID MainUsage(VOID)
|
|||
_T(" for that service is returned. Further options do not apply in\n")
|
||||
_T(" this case. If the query command is followed by nothing or one of\n")
|
||||
_T(" the options listed below, the services are enumerated.\n")
|
||||
_T(" type= Type of services to enumerate (driver, service, all)\n")
|
||||
_T(" type= Type of services to enumerate (driver, service, interact, all)\n")
|
||||
_T(" (default = service)\n")
|
||||
_T(" state= State of services to enumerate (inactive, all)\n")
|
||||
_T(" (default = active)\n")
|
||||
|
@ -85,8 +83,8 @@ VOID MainUsage(VOID)
|
|||
// _T("sc query bufsize= 50 - Enumerates with a 50 byte buffer.\n")
|
||||
// _T("sc query ri= 14 - Enumerates with resume index = 14\n")
|
||||
// _T("sc queryex group= "" - Enumerates active services not in a group\n")
|
||||
_T("sc query type= service type= interact - Enumerates all interactive services\n"));
|
||||
// _T("sc query type= driver group= NDIS - Enumerates all NDIS drivers\n"));
|
||||
_T("sc query type= service type= interact - Enumerates all interactive services\n")
|
||||
_T("sc query type= driver group= NDIS - Enumerates all NDIS drivers\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue