Implement the qc, qdescription and qfailure commands.

svn path=/trunk/; revision=71615
This commit is contained in:
Eric Kohl 2016-06-11 21:24:40 +00:00
parent 5b2c7d7e50
commit 8361105c91
7 changed files with 474 additions and 9 deletions

View file

@ -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

View 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;
}

View 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;
}

View 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;
}

View file

@ -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();

View file

@ -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_ */

View file

@ -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"));
}