mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[SC]
Implement the qc, qdescription and qfailure commands. svn path=/trunk/; revision=71615
This commit is contained in:
parent
5b2c7d7e50
commit
8361105c91
7 changed files with 474 additions and 9 deletions
|
@ -6,6 +6,9 @@ list(APPEND SOURCE
|
|||
create.c
|
||||
delete.c
|
||||
print.c
|
||||
qc.c
|
||||
qdescription.c
|
||||
qfailure.c
|
||||
query.c
|
||||
sc.c
|
||||
sdset.c
|
||||
|
|
190
reactos/base/applications/sc/qc.c
Normal file
190
reactos/base/applications/sc/qc.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Services
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/applications/sc/qc.c
|
||||
* PURPOSE: Show the service configuration
|
||||
* COPYRIGHT: Copyright 2016 Eric Kohl
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
|
||||
BOOL QueryConfig(LPCTSTR ServiceName)
|
||||
{
|
||||
SC_HANDLE hManager = NULL;
|
||||
SC_HANDLE hService = NULL;
|
||||
BOOL bResult = TRUE;
|
||||
DWORD cbBytesNeeded = 0;
|
||||
LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
|
||||
LPWSTR lpPtr;
|
||||
INT nLen, i;
|
||||
|
||||
#ifdef SCDBG
|
||||
_tprintf(_T("service to show configuration - %s\n\n"), ServiceName);
|
||||
#endif
|
||||
|
||||
hManager = OpenSCManager(NULL,
|
||||
NULL,
|
||||
SC_MANAGER_CONNECT);
|
||||
if (hManager == NULL)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hService = OpenService(hManager, ServiceName, SERVICE_QUERY_CONFIG);
|
||||
if (hService == NULL)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!QueryServiceConfig(hService,
|
||||
NULL,
|
||||
0,
|
||||
&cbBytesNeeded))
|
||||
{
|
||||
if (cbBytesNeeded == 0)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
pServiceConfig = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded);
|
||||
if (pServiceConfig == NULL)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!QueryServiceConfig(hService,
|
||||
pServiceConfig,
|
||||
cbBytesNeeded,
|
||||
&cbBytesNeeded))
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
_tprintf(_T("SERVICE_NAME: %s\n"), ServiceName);
|
||||
_tprintf(_T(" TYPE : %-3lx "), pServiceConfig->dwServiceType);
|
||||
switch (pServiceConfig->dwServiceType)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
_tprintf(_T(" START_TYPE : %-3lx "), pServiceConfig->dwStartType);
|
||||
switch (pServiceConfig->dwStartType)
|
||||
{
|
||||
case SERVICE_BOOT_START:
|
||||
_tprintf(_T("BOOT_START\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_SYSTEM_START:
|
||||
_tprintf(_T("SYSTEM_START\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_AUTO_START:
|
||||
_tprintf(_T("AUTO_START\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_DEMAND_START:
|
||||
_tprintf(_T("DEMAND_START\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_DISABLED:
|
||||
_tprintf(_T("DISABLED\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
_tprintf(_T("\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
_tprintf(_T(" ERROR_CONTROL : %-3lx "), pServiceConfig->dwErrorControl);
|
||||
switch (pServiceConfig->dwErrorControl)
|
||||
{
|
||||
case SERVICE_ERROR_IGNORE:
|
||||
_tprintf(_T("IGNORE\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_ERROR_NORMAL:
|
||||
_tprintf(_T("NORMAL\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_ERROR_SEVERE:
|
||||
_tprintf(_T("SEVERE\n"));
|
||||
break;
|
||||
|
||||
case SERVICE_ERROR_CRITICAL:
|
||||
_tprintf(_T("CRITICAL\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
_tprintf(_T("\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
_tprintf(_T(" BINARY_PATH_NAME : %s\n"), pServiceConfig->lpBinaryPathName);
|
||||
_tprintf(_T(" LOAD_ORDER_GROUP : %s\n"), pServiceConfig->lpLoadOrderGroup);
|
||||
_tprintf(_T(" TAG : %lu\n"), pServiceConfig->dwTagId);
|
||||
_tprintf(_T(" DISPLAY_NAME : %s\n"), pServiceConfig->lpDisplayName);
|
||||
_tprintf(_T(" DEPENDENCIES : "));
|
||||
lpPtr = pServiceConfig->lpDependencies;
|
||||
i = 0;
|
||||
while (*lpPtr != _T('\0'))
|
||||
{
|
||||
nLen = _tcslen(lpPtr);
|
||||
if (i != 0)
|
||||
_tprintf(_T("\n : "));
|
||||
_tprintf(_T("%s"), lpPtr);
|
||||
lpPtr = lpPtr + nLen + 1;
|
||||
i++;
|
||||
}
|
||||
_tprintf(_T("\n"));
|
||||
|
||||
_tprintf(_T(" SERVICE_START_NAME : %s\n"), pServiceConfig->lpServiceStartName);
|
||||
|
||||
done:
|
||||
if (bResult == FALSE)
|
||||
ReportLastError();
|
||||
|
||||
if (pServiceConfig != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, pServiceConfig);
|
||||
|
||||
if (hService)
|
||||
CloseServiceHandle(hService);
|
||||
|
||||
if (hManager)
|
||||
CloseServiceHandle(hManager);
|
||||
|
||||
return bResult;
|
||||
}
|
88
reactos/base/applications/sc/qdescription.c
Normal file
88
reactos/base/applications/sc/qdescription.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Services
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/applications/sc/qdescription.c
|
||||
* PURPOSE: Show the service description
|
||||
* COPYRIGHT: Copyright 2016 Eric Kohl
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
|
||||
BOOL QueryDescription(LPCTSTR ServiceName)
|
||||
{
|
||||
SC_HANDLE hManager = NULL;
|
||||
SC_HANDLE hService = NULL;
|
||||
BOOL bResult = TRUE;
|
||||
DWORD cbBytesNeeded = 0;
|
||||
LPSERVICE_DESCRIPTION pServiceDescription = NULL;
|
||||
|
||||
#ifdef SCDBG
|
||||
_tprintf(_T("service to show description - %s\n\n"), ServiceName);
|
||||
#endif
|
||||
|
||||
hManager = OpenSCManager(NULL,
|
||||
NULL,
|
||||
SC_MANAGER_CONNECT);
|
||||
if (hManager == NULL)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hService = OpenService(hManager, ServiceName, SERVICE_QUERY_CONFIG);
|
||||
if (hService == NULL)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!QueryServiceConfig2(hService,
|
||||
SERVICE_CONFIG_DESCRIPTION,
|
||||
NULL,
|
||||
0,
|
||||
&cbBytesNeeded))
|
||||
{
|
||||
if (cbBytesNeeded == 0)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
pServiceDescription = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded);
|
||||
if (pServiceDescription == NULL)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!QueryServiceConfig2(hService,
|
||||
SERVICE_CONFIG_DESCRIPTION,
|
||||
(LPBYTE)pServiceDescription,
|
||||
cbBytesNeeded,
|
||||
&cbBytesNeeded))
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
_tprintf(_T("SERVICE_NAME: %s\n"), ServiceName);
|
||||
_tprintf(_T(" DESCRIPTION : %s\n"), pServiceDescription->lpDescription);
|
||||
|
||||
done:
|
||||
if (bResult == FALSE)
|
||||
ReportLastError();
|
||||
|
||||
if (pServiceDescription != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, pServiceDescription);
|
||||
|
||||
if (hService)
|
||||
CloseServiceHandle(hService);
|
||||
|
||||
if (hManager)
|
||||
CloseServiceHandle(hManager);
|
||||
|
||||
return bResult;
|
||||
}
|
118
reactos/base/applications/sc/qfailure.c
Normal file
118
reactos/base/applications/sc/qfailure.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Services
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/applications/sc/qfailure.c
|
||||
* PURPOSE: Show the service failure action
|
||||
* COPYRIGHT: Copyright 2016 Eric Kohl
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
|
||||
BOOL QueryFailure(LPCTSTR ServiceName)
|
||||
{
|
||||
SC_HANDLE hManager = NULL;
|
||||
SC_HANDLE hService = NULL;
|
||||
BOOL bResult = TRUE;
|
||||
DWORD cbBytesNeeded = 0;
|
||||
LPSERVICE_FAILURE_ACTIONS pServiceFailure = NULL;
|
||||
INT i;
|
||||
|
||||
#ifdef SCDBG
|
||||
_tprintf(_T("service to show failure action - %s\n\n"), ServiceName);
|
||||
#endif
|
||||
|
||||
hManager = OpenSCManager(NULL,
|
||||
NULL,
|
||||
SC_MANAGER_CONNECT);
|
||||
if (hManager == NULL)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hService = OpenService(hManager, ServiceName, SERVICE_QUERY_CONFIG);
|
||||
if (hService == NULL)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!QueryServiceConfig2(hService,
|
||||
SERVICE_CONFIG_FAILURE_ACTIONS,
|
||||
NULL,
|
||||
0,
|
||||
&cbBytesNeeded))
|
||||
{
|
||||
if (cbBytesNeeded == 0)
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
pServiceFailure = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded);
|
||||
if (pServiceFailure == NULL)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!QueryServiceConfig2(hService,
|
||||
SERVICE_CONFIG_FAILURE_ACTIONS,
|
||||
(LPBYTE)pServiceFailure,
|
||||
cbBytesNeeded,
|
||||
&cbBytesNeeded))
|
||||
{
|
||||
bResult = FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
_tprintf(_T("SERVICE_NAME: %s\n"), ServiceName);
|
||||
_tprintf(_T(" RESET_PERIOD : %lu seconds\n"), pServiceFailure->dwResetPeriod);
|
||||
_tprintf(_T(" REBOOT_MESSAGE : %s\n"), (pServiceFailure->lpRebootMsg) ? pServiceFailure->lpRebootMsg : _T(""));
|
||||
_tprintf(_T(" COMMAND_LINE : %s\n"), (pServiceFailure->lpCommand) ? pServiceFailure->lpCommand : _T(""));
|
||||
_tprintf(_T(" FAILURE_ACTIONS : "));
|
||||
for (i = 0; i < pServiceFailure->cActions; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
_tprintf(_T(" "));
|
||||
switch (pServiceFailure->lpsaActions[i].Type)
|
||||
{
|
||||
case SC_ACTION_NONE:
|
||||
continue;
|
||||
|
||||
case SC_ACTION_RESTART:
|
||||
_tprintf(_T("RESTART -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay);
|
||||
break;
|
||||
|
||||
case SC_ACTION_REBOOT:
|
||||
_tprintf(_T("REBOOT -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay);
|
||||
break;
|
||||
|
||||
case SC_ACTION_RUN_COMMAND:
|
||||
_tprintf(_T("RUN_COMMAND -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay);
|
||||
break;
|
||||
|
||||
default:
|
||||
_tprintf(_T("\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (bResult == FALSE)
|
||||
ReportLastError();
|
||||
|
||||
if (pServiceFailure != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, pServiceFailure);
|
||||
|
||||
if (hService)
|
||||
CloseServiceHandle(hService);
|
||||
|
||||
if (hManager)
|
||||
CloseServiceHandle(hManager);
|
||||
|
||||
return bResult;
|
||||
}
|
|
@ -208,6 +208,42 @@ ScControl(LPCTSTR Server, // remote machine name
|
|||
else
|
||||
SdSetUsage();
|
||||
}
|
||||
else if (!lstrcmpi(Command, _T("qc")))
|
||||
{
|
||||
if (ArgCount > 0)
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
QueryConfig(ServiceName);
|
||||
}
|
||||
else
|
||||
QueryConfigUsage();
|
||||
}
|
||||
else if (!lstrcmpi(Command, _T("qdescription")))
|
||||
{
|
||||
if (ArgCount > 0)
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
QueryDescription(ServiceName);
|
||||
}
|
||||
else
|
||||
QueryDescriptionUsage();
|
||||
}
|
||||
else if (!lstrcmpi(Command, _T("qfailure")))
|
||||
{
|
||||
if (ArgCount > 0)
|
||||
{
|
||||
ServiceName = *ServiceArgs++;
|
||||
ArgCount--;
|
||||
|
||||
QueryFailure(ServiceName);
|
||||
}
|
||||
else
|
||||
QueryFailureUsage();
|
||||
}
|
||||
else
|
||||
{
|
||||
MainUsage();
|
||||
|
|
|
@ -21,6 +21,9 @@ BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended);
|
|||
LPSERVICE_STATUS_PROCESS QueryService(LPCTSTR ServiceName);
|
||||
BOOL SdShow(LPCTSTR ServiceName);
|
||||
BOOL SdSet(LPCTSTR ServiceName, LPCTSTR SecurityDescriptor);
|
||||
BOOL QueryConfig(LPCTSTR ServiceName);
|
||||
BOOL QueryDescription(LPCTSTR ServiceName);
|
||||
BOOL QueryFailure(LPCTSTR ServiceName);
|
||||
|
||||
/* print and error functions */
|
||||
VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended);
|
||||
|
@ -40,5 +43,8 @@ VOID CreateUsage(VOID);
|
|||
VOID ControlUsage(VOID);
|
||||
VOID SdShowUsage(VOID);
|
||||
VOID SdSetUsage(VOID);
|
||||
VOID QueryConfigUsage(VOID);
|
||||
VOID QueryDescriptionUsage(VOID);
|
||||
VOID QueryFailureUsage(VOID);
|
||||
|
||||
#endif /* _SC_PCH_ */
|
||||
|
|
|
@ -36,9 +36,9 @@ VOID MainUsage(VOID)
|
|||
// "\t config : Changes the configuration of a service (persistant).\n"
|
||||
// "\t description : Changes the description of a service.\n"
|
||||
// "\t failure : Changes the actions taken by a service upon failure.\n"
|
||||
// "\t qc : Queries the configuration information for a service.\n"
|
||||
// "\t qdescription : Queries the description for a service.\n"
|
||||
// "\t qfailure : Queries the actions taken by a service upon failure.\n"
|
||||
_T("\t qc : Queries the configuration information for a service.\n")
|
||||
_T("\t qdescription : Queries the description for a service.\n")
|
||||
_T("\t qfailure : Queries the actions taken by a service upon failure.\n")
|
||||
_T("\t delete : Deletes a service (from the registry).\n")
|
||||
_T("\t create : Creates a service. (adds it to the registry).\n")
|
||||
_T("\t control : Sends a control to a service.\n")
|
||||
|
@ -194,15 +194,39 @@ VOID ControlUsage(VOID)
|
|||
VOID SdShowUsage(VOID)
|
||||
{
|
||||
_tprintf(_T("DESCRIPTION:\n")
|
||||
_T(" Displays a service's security descriptor in SDDL format.\n")
|
||||
_T("USAGE:\n")
|
||||
_T(" sc <server> sdshow <service name>\n"));
|
||||
_T(" Displays a service's security descriptor in SDDL format.\n")
|
||||
_T("USAGE:\n")
|
||||
_T(" sc <server> sdshow <service name>\n"));
|
||||
}
|
||||
|
||||
VOID SdSetUsage(VOID)
|
||||
{
|
||||
_tprintf(_T("DESCRIPTION:\n")
|
||||
_T(" Sets a service's security descriptor.\n")
|
||||
_T("USAGE:\n")
|
||||
_T(" sc <server> sdset <service name> <SD in SDDL format>\n"));
|
||||
_T(" Sets a service's security descriptor.\n")
|
||||
_T("USAGE:\n")
|
||||
_T(" sc <server> sdset <service name> <SD in SDDL format>\n"));
|
||||
}
|
||||
|
||||
VOID QueryConfigUsage(VOID)
|
||||
{
|
||||
_tprintf(_T("DESCRIPTION:\n")
|
||||
_T(" Queries the configuration information for a service.\n")
|
||||
_T("USAGE:\n")
|
||||
_T(" sc <server> qc [service name] <bufferSize>\n"));
|
||||
}
|
||||
|
||||
VOID QueryDescriptionUsage(VOID)
|
||||
{
|
||||
_tprintf(_T("DESCRIPTION:\n")
|
||||
_T(" Retrieves the description string of a service.\n")
|
||||
_T("USAGE:\n")
|
||||
_T(" sc <server> qdescription [service name] <bufferSize>\n"));
|
||||
}
|
||||
|
||||
VOID QueryFailureUsage(VOID)
|
||||
{
|
||||
_tprintf(_T("DESCRIPTION:\n")
|
||||
_T(" Retrieves the actions performed on service failure.\n")
|
||||
_T("USAGE:\n")
|
||||
_T(" sc <server> qfailure [service name] <bufferSize>\n"));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue