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

  1. // wuauserv.cpp
  2. #include <windows.h>
  3. #include <ausvc.h>
  4. #include <wusafefn.h>
  5. typedef HRESULT (WINAPI *AUSERVICEMAIN)(DWORD dwNumServicesArg,
  6. LPWSTR *lpServiceArgVectors,
  7. AUSERVICEHANDLER pfnServiceHandler,
  8. BOOL fJustSelfUpdated);
  9. AUSERVICEMAIN g_pfnServiceMain = NULL;
  10. AUSERVICEHANDLER g_pfnServiceHandler = NULL;
  11. AUGETENGSTATUS g_pfnGetEngineStatusInfo = NULL;
  12. AUREGSERVICEVER g_pfnRegisterServiceVersion = NULL;
  13. BOOL g_fCSInited = FALSE;
  14. CRITICAL_SECTION csWuaueng;
  15. BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
  16. DWORD dwReason,
  17. LPVOID lpReserved)
  18. {
  19. switch(dwReason)
  20. {
  21. case DLL_PROCESS_ATTACH:
  22. DisableThreadLibraryCalls(hinstDLL);
  23. g_fCSInited = SafeInitializeCriticalSection(&csWuaueng);
  24. break;
  25. case DLL_PROCESS_DETACH:
  26. if(g_fCSInited)
  27. {
  28. DeleteCriticalSection(&csWuaueng);
  29. }
  30. break;
  31. //case DLL_THREAD_ATTACH:
  32. //case DLL_THREAD_DETACH:
  33. }
  34. return TRUE;
  35. }
  36. DWORD WINAPI ServiceHandler(DWORD fdwControl, DWORD dwEventType, LPVOID pEventData, LPVOID lpContext)
  37. {
  38. DWORD dwRet = NOERROR;
  39. EnterCriticalSection(&csWuaueng);
  40. if ( NULL != g_pfnServiceHandler )
  41. {
  42. dwRet = g_pfnServiceHandler(fdwControl, dwEventType, pEventData, lpContext);
  43. }
  44. else
  45. {
  46. dwRet = ERROR_CALL_NOT_IMPLEMENTED;
  47. }
  48. LeaveCriticalSection(&csWuaueng);
  49. return dwRet;
  50. }
  51. void WINAPI ServiceMain(DWORD dwNumServicesArg, LPWSTR *lpServiceArgVectors)
  52. {
  53. HRESULT hr = S_OK;
  54. HMODULE hModule = NULL;
  55. AUENGINEINFO_VER_1 engineInfo;
  56. DWORD dwEngineVersion = 0;
  57. BOOL fCompatibleEngineVersion = FALSE;
  58. //If Initialization of the CS failed in DllMain, bail out
  59. if (!g_fCSInited)
  60. {
  61. return;
  62. }
  63. do
  64. {
  65. EnterCriticalSection(&csWuaueng);
  66. fCompatibleEngineVersion = FALSE;
  67. g_pfnServiceHandler = NULL;
  68. g_pfnGetEngineStatusInfo = NULL;
  69. g_pfnRegisterServiceVersion = NULL;
  70. // check if we need to release wuaueng.dll
  71. if ( (S_FALSE == hr) && !FreeLibrary(hModule) )
  72. {
  73. hr = E_FAIL;
  74. hModule = NULL;
  75. g_pfnServiceMain = NULL;
  76. g_pfnServiceHandler = NULL;
  77. }
  78. else
  79. {
  80. // if we can't load wuaueng.dll, we fail to start
  81. if ( (NULL == (hModule = LoadLibraryFromSystemDir(TEXT("wuaueng.dll")))) ||
  82. (NULL == (g_pfnServiceMain = (AUSERVICEMAIN)::GetProcAddress(hModule, "ServiceMain"))) ||
  83. (NULL == (g_pfnServiceHandler = (AUSERVICEHANDLER)::GetProcAddress(hModule, "ServiceHandler"))) )
  84. {
  85. hr = E_FAIL;
  86. g_pfnServiceMain = NULL;
  87. g_pfnServiceHandler = NULL;
  88. }
  89. else //wuaueng.dll successfully loaded, check to see if the engine supports following entry points
  90. {
  91. if ( (NULL != (g_pfnRegisterServiceVersion = (AUREGSERVICEVER)::GetProcAddress(hModule, "RegisterServiceVersion"))) &&
  92. (NULL != (g_pfnGetEngineStatusInfo = (AUGETENGSTATUS)::GetProcAddress(hModule, "GetEngineStatusInfo"))) )
  93. {
  94. fCompatibleEngineVersion = TRUE;
  95. }
  96. }
  97. }
  98. LeaveCriticalSection(&csWuaueng);
  99. if ( SUCCEEDED(hr) )
  100. {
  101. if (fCompatibleEngineVersion)
  102. {
  103. // Register service version with engine and check if engine supports the service version
  104. fCompatibleEngineVersion = g_pfnRegisterServiceVersion(AUSRV_VERSION, &dwEngineVersion);
  105. }
  106. hr = g_pfnServiceMain(dwNumServicesArg, lpServiceArgVectors, ServiceHandler,
  107. (S_FALSE == hr) ? TRUE: FALSE /* we just reloaded wuaueng.dll */);
  108. if(fCompatibleEngineVersion)
  109. {
  110. //The engine service main has exited, set the service status to SERVICE_STOP_PENDING
  111. fCompatibleEngineVersion = g_pfnGetEngineStatusInfo((void*)&engineInfo);
  112. }
  113. }
  114. } while ( S_FALSE == hr );
  115. EnterCriticalSection(&csWuaueng);
  116. if ( NULL != hModule )
  117. {
  118. FreeLibrary(hModule);
  119. }
  120. g_pfnServiceHandler = NULL;
  121. g_pfnGetEngineStatusInfo = NULL;
  122. g_pfnRegisterServiceVersion = NULL;
  123. g_pfnServiceMain = NULL;
  124. LeaveCriticalSection(&csWuaueng);
  125. if(fCompatibleEngineVersion)
  126. {
  127. //stop the service
  128. engineInfo.serviceStatus.dwCurrentState = SERVICE_STOPPED;
  129. SetServiceStatus(engineInfo.hServiceStatus, &engineInfo.serviceStatus);
  130. }
  131. return;
  132. }