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.
 
 
 
 
 
 

161 lines
4.5 KiB

// wuauserv.cpp
#include <windows.h>
#include <ausvc.h>
#include <wusafefn.h>
typedef HRESULT (WINAPI *AUSERVICEMAIN)(DWORD dwNumServicesArg,
LPWSTR *lpServiceArgVectors,
AUSERVICEHANDLER pfnServiceHandler,
BOOL fJustSelfUpdated);
AUSERVICEMAIN g_pfnServiceMain = NULL;
AUSERVICEHANDLER g_pfnServiceHandler = NULL;
AUGETENGSTATUS g_pfnGetEngineStatusInfo = NULL;
AUREGSERVICEVER g_pfnRegisterServiceVersion = NULL;
BOOL g_fCSInited = FALSE;
CRITICAL_SECTION csWuaueng;
BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
DWORD dwReason,
LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
g_fCSInited = SafeInitializeCriticalSection(&csWuaueng);
break;
case DLL_PROCESS_DETACH:
if(g_fCSInited)
{
DeleteCriticalSection(&csWuaueng);
}
break;
//case DLL_THREAD_ATTACH:
//case DLL_THREAD_DETACH:
}
return TRUE;
}
DWORD WINAPI ServiceHandler(DWORD fdwControl, DWORD dwEventType, LPVOID pEventData, LPVOID lpContext)
{
DWORD dwRet = NOERROR;
EnterCriticalSection(&csWuaueng);
if ( NULL != g_pfnServiceHandler )
{
dwRet = g_pfnServiceHandler(fdwControl, dwEventType, pEventData, lpContext);
}
else
{
dwRet = ERROR_CALL_NOT_IMPLEMENTED;
}
LeaveCriticalSection(&csWuaueng);
return dwRet;
}
void WINAPI ServiceMain(DWORD dwNumServicesArg, LPWSTR *lpServiceArgVectors)
{
HRESULT hr = S_OK;
HMODULE hModule = NULL;
AUENGINEINFO_VER_1 engineInfo;
DWORD dwEngineVersion = 0;
BOOL fCompatibleEngineVersion = FALSE;
//If Initialization of the CS failed in DllMain, bail out
if (!g_fCSInited)
{
return;
}
do
{
EnterCriticalSection(&csWuaueng);
fCompatibleEngineVersion = FALSE;
g_pfnServiceHandler = NULL;
g_pfnGetEngineStatusInfo = NULL;
g_pfnRegisterServiceVersion = NULL;
// check if we need to release wuaueng.dll
if ( (S_FALSE == hr) && !FreeLibrary(hModule) )
{
hr = E_FAIL;
hModule = NULL;
g_pfnServiceMain = NULL;
g_pfnServiceHandler = NULL;
}
else
{
// if we can't load wuaueng.dll, we fail to start
if ( (NULL == (hModule = LoadLibraryFromSystemDir(TEXT("wuaueng.dll")))) ||
(NULL == (g_pfnServiceMain = (AUSERVICEMAIN)::GetProcAddress(hModule, "ServiceMain"))) ||
(NULL == (g_pfnServiceHandler = (AUSERVICEHANDLER)::GetProcAddress(hModule, "ServiceHandler"))) )
{
hr = E_FAIL;
g_pfnServiceMain = NULL;
g_pfnServiceHandler = NULL;
}
else //wuaueng.dll successfully loaded, check to see if the engine supports following entry points
{
if ( (NULL != (g_pfnRegisterServiceVersion = (AUREGSERVICEVER)::GetProcAddress(hModule, "RegisterServiceVersion"))) &&
(NULL != (g_pfnGetEngineStatusInfo = (AUGETENGSTATUS)::GetProcAddress(hModule, "GetEngineStatusInfo"))) )
{
fCompatibleEngineVersion = TRUE;
}
}
}
LeaveCriticalSection(&csWuaueng);
if ( SUCCEEDED(hr) )
{
if (fCompatibleEngineVersion)
{
// Register service version with engine and check if engine supports the service version
fCompatibleEngineVersion = g_pfnRegisterServiceVersion(AUSRV_VERSION, &dwEngineVersion);
}
hr = g_pfnServiceMain(dwNumServicesArg, lpServiceArgVectors, ServiceHandler,
(S_FALSE == hr) ? TRUE: FALSE /* we just reloaded wuaueng.dll */);
if(fCompatibleEngineVersion)
{
//The engine service main has exited, set the service status to SERVICE_STOP_PENDING
fCompatibleEngineVersion = g_pfnGetEngineStatusInfo((void*)&engineInfo);
}
}
} while ( S_FALSE == hr );
EnterCriticalSection(&csWuaueng);
if ( NULL != hModule )
{
FreeLibrary(hModule);
}
g_pfnServiceHandler = NULL;
g_pfnGetEngineStatusInfo = NULL;
g_pfnRegisterServiceVersion = NULL;
g_pfnServiceMain = NULL;
LeaveCriticalSection(&csWuaueng);
if(fCompatibleEngineVersion)
{
//stop the service
engineInfo.serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(engineInfo.hServiceStatus, &engineInfo.serviceStatus);
}
return;
}