Leaked source code of windows server 2003
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.
 
 
 
 
 
 

272 lines
6.0 KiB

#include "stdinc.h"
#pragma hdrstop
#include <svcs.h>
#include "sxsserviceserver.h"
EXTERN_C RPC_IF_HANDLE SxsStoreManager_ServerIfHandle;
BOOL
CServiceStatus::Initialize(
PCWSTR pcwszServiceName,
LPHANDLER_FUNCTION pHandler,
DWORD dwServiceType,
DWORD dwControlsAccepted,
DWORD dwInitialState
)
{
NTSTATUS status = STATUS_SUCCESS;
BOOL fSuccess = FALSE;
//
// Double-initialization isn't a bad thing, but it's frowned on.
//
ASSERT(m_StatusHandle == NULL);
if (m_StatusHandle != NULL)
return TRUE;
InitializeCriticalSection(&m_CSection);
//
// Register this service as owning the service status
//
m_StatusHandle = RegisterServiceCtrlHandler(pcwszServiceName, pHandler);
if (m_StatusHandle == NULL) {
goto Failure;
}
//
// Set the initial state of the world
//
ZeroMemory(static_cast<SERVICE_STATUS*>(this), sizeof(SERVICE_STATUS));
this->dwServiceType = dwServiceType;
this->dwCurrentState = dwInitialState;
this->dwControlsAccepted = dwControlsAccepted;
if (!SetServiceStatus(m_StatusHandle, this)) {
goto Failure;
}
return TRUE;
Failure:
{
const DWORD dwLastError = ::GetLastError();
DeleteCriticalSection(&m_CSection);
m_StatusHandle = NULL;
SetLastError(dwLastError);
}
return FALSE;
}
BOOL
CServiceStatus::SetServiceState(
DWORD dwStatus,
DWORD dwCheckpoint
)
{
BOOL fSuccess = FALSE;
EnterCriticalSection(&m_CSection);
__try {
if (m_StatusHandle != NULL) {
this->dwCurrentState = dwStatus;
if (dwCheckpoint != 0xFFFFFFFF) {
this->dwCheckPoint = dwCheckpoint;
}
fSuccess = SetServiceStatus(m_StatusHandle, this);
}
}
__finally {
LeaveCriticalSection(&m_CSection);
}
return fSuccess;
}
//
// In-place construction
//
bool
CServiceStatus::Construct(
CServiceStatus *&pServiceStatusTarget
)
{
ASSERT(pServiceStatusTarget == NULL);
return (pServiceStatusTarget = new CServiceStatus) != NULL;
}
EXTERN_C HANDLE g_hFakeServiceControllerThread = INVALID_HANDLE_VALUE;
EXTERN_C DWORD g_dwFakeServiceControllerThreadId = 0;
EXTERN_C PSVCHOST_GLOBAL_DATA g_pGlobalServiceData = NULL;
BYTE g_rgbServiceStatusStorage[sizeof(CServiceStatus)];
EXTERN_C CServiceStatus *g_pServiceStatus = NULL;
//
// The service host will call this to send in API callbacks
//
VOID
SvchostPushServiceGlobals(
PSVCHOST_GLOBAL_DATA pGlobals
)
{
ASSERT(g_pGlobalServiceData == NULL);
g_pGlobalServiceData = pGlobals;
}
PVOID operator new(size_t cb, PVOID pv) {
return pv;
}
//
// Control handler for service notifications
//
VOID
ServiceHandler(
DWORD dwControlCode
)
{
return;
}
#define CHECKPOINT_ZERO (0)
#define CHECKPOINT_RPC_STARTED (1)
//
// Stop the service with an error code, ERROR_SUCCESS for a successful stoppage
//
VOID
ShutdownService(
DWORD dwLastError
)
{
return;
}
//
// Where the fun starts
//
VOID WINAPI
ServiceMain(
DWORD dwServiceArgs,
LPWSTR lpServiceArgList[]
)
{
NTSTATUS status = STATUS_SUCCESS;
//
// svchost must have given us some global data before we got to this point.
//
ASSERT(g_pGlobalServiceData != NULL);
ASSERT(g_pServiceStatus == NULL);
g_pServiceStatus = new (g_rgbServiceStatusStorage) CServiceStatus;
if (!g_pServiceStatus->Initialize(
SXS_STORE_SERVICE_NAME, ServiceHandler,
SERVICE_WIN32,
SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE,
SERVICE_START_PENDING))
{
DebugPrint(DBGPRINT_LVL_ERROR, "Can't start service status handler, error 0x%08lx\n", ::GetLastError());
}
//
// Go initialize RPC, and register our interface. If this fails, we shut down.
//
status = g_pGlobalServiceData->StartRpcServer(
SXS_STORE_SERVICE_NAME,
SxsStoreManager_ServerIfHandle);
if (!NT_SUCCESS(status)) {
ShutdownService(status);
return;
}
//
// Tell the world that we're off and running
//
g_pServiceStatus->SetServiceState(SERVICE_RUNNING);
return;
}
DWORD WINAPI FakeServiceController(PVOID pvCookie);
//
// This stub will start a dispatch thread, and then call into the
// service main function
//
BOOL
FakeRunningAsService()
{
//
// Create a thread running the service dispatch function, and then call
// the service main function to get things rolling
//
g_hFakeServiceControllerThread = CreateThread(
NULL,
0,
FakeServiceController,
0,
0,
&g_dwFakeServiceControllerThreadId);
if (g_hFakeServiceControllerThread == NULL) {
return FALSE;
}
ServiceMain(0, NULL);
return TRUE;
}
VOID __cdecl wmain(INT argc, WCHAR** argv)
{
SERVICE_TABLE_ENTRYW SxsGacServiceEntries[] = {
{ SXS_STORE_SERVICE_NAME, ServiceMain },
{ NULL, NULL }
};
BOOL RunningAsService = TRUE;
BOOL fSuccess = FALSE;
if (argc > 1 && (lstrcmpiW(argv[1], L"notservice") == 0)) {
RunningAsService = FALSE;
}
if (RunningAsService) {
fSuccess = StartServiceCtrlDispatcherW(SxsGacServiceEntries);
if (!fSuccess) {
const DWORD dwError = ::GetLastError();
DebugPrint(DBGPRINT_LVL_ERROR, "Failed starting service dispatch, error %ld\n", dwError);
}
}
else {
fSuccess = FakeRunningAsService();
if (!fSuccess) {
const DWORD dwError = ::GetLastError();
DebugPrint(DBGPRINT_LVL_ERROR, "Failed faking service startup, error %ld\n", dwError);
}
}
return;
}