mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
392 lines
8.5 KiB
392 lines
8.5 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Svcp.c
|
|
|
|
Abstract:
|
|
|
|
This module contains support for accessing the Service Controller.
|
|
|
|
Author:
|
|
|
|
Scott B. Suhy (ScottSu) 6/1/93
|
|
|
|
Environment:
|
|
|
|
User Mode
|
|
|
|
--*/
|
|
|
|
#include "svcp.h"
|
|
|
|
LPQUERY_SERVICE_CONFIG
|
|
ConstructSvcConfig(
|
|
IN HSVC hSvc,
|
|
IN LPENUM_SERVICE_STATUS Ess
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
ConstructSvcConfig constructs a QUERY_SERVICE_CONFIG structure based on the
|
|
supplied HSVC handle and ENUM_SERVICE_STATUS structure.
|
|
|
|
Arguments:
|
|
|
|
hSvc - Supplies an HSVC object which contains the
|
|
Service Controller Manager handle used to
|
|
open the service specified by the supplied
|
|
ENUM_SERVICE_STATUS structure.
|
|
Ess - Supplies a pointer to an ENUM_SERVICE_STATUS
|
|
structure which contains the name of the service
|
|
whose QUERY_SERVICE_CONFIG structure is being
|
|
constructed.
|
|
|
|
Return Value:
|
|
|
|
LPQUERY_SERVICE_CONFIG - Returns a pointer to a QUERY_SERVICE_CONFIG
|
|
structure for the supplied service, NULL if the
|
|
configuration information could not be queried.
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL Success;
|
|
SC_HANDLE Handle;
|
|
DWORD BytesNeeded;
|
|
LPQUERY_SERVICE_CONFIG SvcConfig;
|
|
|
|
//
|
|
// Validate the handle.
|
|
//
|
|
|
|
DbgPointerAssert( hSvc );
|
|
DbgAssert( CheckSignature( hSvc ));
|
|
if(( hSvc == NULL ) || ( ! CheckSignature( hSvc ))) {
|
|
return FALSE;
|
|
}
|
|
|
|
DbgPointerAssert( Ess );
|
|
|
|
//
|
|
// Open the supplied service with query configuration access.
|
|
//
|
|
|
|
Handle = OpenService(
|
|
hSvc->ScHandle,
|
|
Ess->lpServiceName,
|
|
SERVICE_QUERY_CONFIG
|
|
);
|
|
DbgHandleAssert( Handle );
|
|
if( Handle == NULL ) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Query the service controller for the number of bytes needed to retrieve
|
|
// the service's configuration information.
|
|
//
|
|
|
|
Success = QueryServiceConfig(
|
|
Handle,
|
|
NULL,
|
|
0,
|
|
&BytesNeeded
|
|
);
|
|
DbgAssert( Success == FALSE );
|
|
DbgAssert( GetLastError( ) == ERROR_INSUFFICIENT_BUFFER );
|
|
if( ( Success == TRUE )
|
|
|| ( GetLastError( ) != ERROR_INSUFFICIENT_BUFFER )) {
|
|
Success = CloseServiceHandle( Handle );
|
|
DbgAssert( Success );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate enough memory for the service's configuration information.
|
|
//
|
|
|
|
SvcConfig = AllocateMemory( QUERY_SERVICE_CONFIG, BytesNeeded );
|
|
DbgPointerAssert( SvcConfig );
|
|
if( SvcConfig == NULL ) {
|
|
Success = CloseServiceHandle( Handle );
|
|
DbgAssert( Success );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Query the service's configuration information.
|
|
//
|
|
|
|
Success = QueryServiceConfig(
|
|
Handle,
|
|
SvcConfig,
|
|
BytesNeeded,
|
|
&BytesNeeded
|
|
);
|
|
DbgAssert( Success );
|
|
if( Success == FALSE ) {
|
|
Success = CloseServiceHandle( Handle );
|
|
DbgAssert( Success );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Close the service controller's handle and return a pointer to the
|
|
// QUERY_SERVICE_CONFIG structure.
|
|
//
|
|
|
|
Success = CloseServiceHandle( Handle );
|
|
DbgAssert( Success );
|
|
|
|
return SvcConfig;
|
|
}
|
|
|
|
BOOL
|
|
CloseSvc(
|
|
IN HSVC hSvc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CloseSvc close an HSVC and release the resources associated with that
|
|
underlieing SVC object.
|
|
|
|
Arguments:
|
|
|
|
hSvc - Supplies a handle to the SVC object to be closed. The handle must
|
|
have been returned by previous call to OpenSvc.
|
|
|
|
Return Value:
|
|
|
|
BOOL - Returns TRUE if the resource associated with the supplied HSVC
|
|
are succesfully destroyed.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Validate the handle.
|
|
//
|
|
|
|
DbgPointerAssert( hSvc );
|
|
DbgAssert( CheckSignature( hSvc ));
|
|
if(( hSvc == NULL ) || ( ! CheckSignature( hSvc ))) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Note that return codes are not checked since Close Svc may be called with
|
|
// a partially construcred SVC by OpenSvc.
|
|
//
|
|
|
|
FreeMemory( hSvc->Ess );
|
|
CloseServiceHandle( hSvc->ScHandle );
|
|
FreeObject( hSvc );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
DestroySvcConfig(
|
|
IN LPQUERY_SERVICE_CONFIG SvcConfig
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
DestroySvcConfig releases all of the resources associated with the
|
|
supplied QUERY_SERVICE_CONFIG structure.
|
|
|
|
Arguments:
|
|
|
|
LPQUERY_SERVICE_CONFIG - Supplies a pointer to the structure to be freed.
|
|
|
|
Return Value:
|
|
|
|
BOOL - Returns TRUE if the QUERY_SERVICE_CONFIG was
|
|
succesfully freed.
|
|
|
|
--*/
|
|
|
|
{
|
|
return FreeMemory( SvcConfig );
|
|
}
|
|
|
|
HSVC
|
|
OpenSvc(
|
|
IN DWORD ServiceType
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
OpenSvc creates a SVC object for the supplied service type. The returned
|
|
SVC object can then be passed to QueryNextSvcEss to retreive the next
|
|
service's status.
|
|
|
|
|
|
Arguments:
|
|
|
|
ServiceType - Supplies the type of service that the SVC object should be
|
|
created for.
|
|
|
|
Return Value:
|
|
|
|
HSVC - Returns a a handle to a SVC object.
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL Success;
|
|
LPSVC Svc;
|
|
DWORD BytesNeeded;
|
|
DWORD ResumeHandle;
|
|
|
|
//
|
|
// Allocate space for the SVC object.
|
|
//
|
|
|
|
Svc = AllocateObject( SVC, 1 );
|
|
DbgPointerAssert( Svc );
|
|
if( Svc == NULL ) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Set the signature in case CloseSvc needs to be called due to an error.
|
|
//
|
|
|
|
SetSignature( Svc );
|
|
|
|
//
|
|
// Open the service controller with enumeration access.
|
|
//
|
|
|
|
Svc->ScHandle = OpenSCManager(
|
|
NULL,
|
|
NULL,
|
|
SC_MANAGER_ENUMERATE_SERVICE
|
|
);
|
|
DbgHandleAssert( Svc->ScHandle );
|
|
if( Svc->ScHandle == NULL ) {
|
|
CloseSvc( Svc );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Tell the sevice controller to start the enumeration at the beginning.
|
|
//
|
|
|
|
ResumeHandle = 0;
|
|
|
|
//
|
|
// Query the service controller for the number of bytes needed to retrieve
|
|
// the status of all service of the supplied type.
|
|
//
|
|
|
|
Success = EnumServicesStatus(
|
|
Svc->ScHandle,
|
|
ServiceType,
|
|
SERVICE_ACTIVE | SERVICE_INACTIVE,
|
|
NULL,
|
|
0,
|
|
&BytesNeeded,
|
|
&Svc->Count,
|
|
&ResumeHandle
|
|
);
|
|
DbgAssert( Success == FALSE );
|
|
DbgAssert( GetLastError( ) == ERROR_MORE_DATA );
|
|
if(( Success == TRUE ) || ( GetLastError( ) != ERROR_MORE_DATA )) {
|
|
CloseSvc( Svc );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate enough space for all of the service's status.
|
|
//
|
|
|
|
Svc->Ess = AllocateMemory( ENUM_SERVICE_STATUS, BytesNeeded );
|
|
DbgPointerAssert( Svc->Ess );
|
|
if( Svc->Ess == NULL ) {
|
|
CloseSvc( Svc );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Retrieve the status of all service of the supplie type.
|
|
//
|
|
|
|
Success = EnumServicesStatus(
|
|
Svc->ScHandle,
|
|
ServiceType,
|
|
SERVICE_ACTIVE | SERVICE_INACTIVE,
|
|
Svc->Ess,
|
|
BytesNeeded,
|
|
&BytesNeeded,
|
|
&Svc->Count,
|
|
&ResumeHandle
|
|
);
|
|
DbgAssert( Success );
|
|
if( Success == FALSE ) {
|
|
CloseSvc( Svc );
|
|
return NULL;
|
|
}
|
|
|
|
Svc->Current = 0;
|
|
|
|
return ( HSVC ) Svc;
|
|
}
|
|
|
|
LPENUM_SERVICE_STATUS
|
|
QueryNextSvcEss(
|
|
IN HSVC hSvc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
QueryNextSvcEss returns a pointer to the next ENUM_SERVICE_STATUS structure
|
|
if there are still more services to be enumerated.
|
|
|
|
Arguments:
|
|
|
|
hSvc - Supplies a handle to the SVC object that is being
|
|
enumerated.
|
|
|
|
Return Value:
|
|
|
|
LPENUM_SERVICE_STATUS - Returns a pointer to the ENUM_SERVICE_STATUS
|
|
structure for the next service in the enumeration.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Validate the handle.
|
|
//
|
|
|
|
DbgPointerAssert( hSvc );
|
|
DbgAssert( CheckSignature( hSvc ));
|
|
if(( hSvc == NULL ) || ( ! CheckSignature( hSvc ))) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// If there are still more services, return its status, otherwise
|
|
// retrun NULL.
|
|
//
|
|
|
|
return ( hSvc->Current < hSvc->Count )
|
|
? &( hSvc->Ess[ hSvc->Current++ ])
|
|
: NULL;
|
|
}
|