Source code of Windows XP (NT5)
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.

339 lines
8.6 KiB

  1. /*
  2. IisRsta.cpp
  3. Implementation of WinMain for COM IIisServiceControl handler
  4. FILE HISTORY:
  5. Phillich 06-Oct-1998 Created
  6. */
  7. #include "stdafx.h"
  8. #include "resource.h"
  9. #include <initguid.h>
  10. #include "iisrsta.h"
  11. #include "dcomperm.h"
  12. //#include "..\interfac\iisrsta_i.c"
  13. #include "IisRestart.h"
  14. const DWORD dwTimeOut = 5000; // time for EXE to be idle before shutting down
  15. const DWORD dwPause = 1000; // time to wait for threads to finish up
  16. // Passed to CreateThread to monitor the shutdown event
  17. static DWORD WINAPI MonitorProc(void* pv)
  18. {
  19. CExeModule* p = (CExeModule*)pv;
  20. p->MonitorShutdown();
  21. return 0;
  22. }
  23. LONG CExeModule::Unlock()
  24. {
  25. LONG l = CComModule::Unlock();
  26. if (l == 0)
  27. {
  28. bActivity = true;
  29. SetEvent(hEventShutdown); // tell monitor that we transitioned to zero
  30. }
  31. return l;
  32. }
  33. //Monitors the shutdown event
  34. void CExeModule::MonitorShutdown()
  35. {
  36. while (1)
  37. {
  38. WaitForSingleObject(hEventShutdown, INFINITE);
  39. DWORD dwWait=0;
  40. do
  41. {
  42. bActivity = false;
  43. dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
  44. } while (dwWait == WAIT_OBJECT_0);
  45. // timed out
  46. if (!bActivity && m_nLockCnt == 0) // if no activity let's really bail
  47. {
  48. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  49. CoSuspendClassObjects();
  50. if (!bActivity && m_nLockCnt == 0)
  51. #endif
  52. break;
  53. }
  54. }
  55. CloseHandle(hEventShutdown);
  56. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  57. }
  58. bool CExeModule::StartMonitor()
  59. {
  60. hEventShutdown = CreateEvent(NULL, false, false, NULL);
  61. if (hEventShutdown == NULL)
  62. return false;
  63. DWORD dwThreadID;
  64. HANDLE h = CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
  65. return (h != NULL);
  66. }
  67. CExeModule _Module;
  68. BEGIN_OBJECT_MAP(ObjectMap)
  69. OBJECT_ENTRY(CLSID_IisServiceControl, CIisRestart)
  70. END_OBJECT_MAP()
  71. LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
  72. {
  73. while (p1 != NULL && *p1 != NULL)
  74. {
  75. LPCTSTR p = p2;
  76. while (p != NULL && *p != NULL)
  77. {
  78. if (*p1 == *p)
  79. return CharNext(p1);
  80. p = CharNext(p);
  81. }
  82. p1 = CharNext(p1);
  83. }
  84. return NULL;
  85. }
  86. /////////////////////////////////////////////////////////////////////////////
  87. //
  88. #if 0
  89. extern "C" int WINAPI wWinMain(HINSTANCE hInstance,
  90. HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  91. {
  92. lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  93. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  94. HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  95. #else
  96. HRESULT hRes = CoInitialize(NULL);
  97. #endif
  98. _ASSERTE(SUCCEEDED(hRes));
  99. _Module.Init(ObjectMap, hInstance/*, &LIBID_IISRSTALib*/);
  100. _Module.dwThreadID = GetCurrentThreadId();
  101. TCHAR szTokens[] = _T("-/");
  102. int nRet = 0;
  103. BOOL bRun = TRUE;
  104. LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
  105. while (lpszToken != NULL)
  106. {
  107. if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
  108. {
  109. _Module.UpdateRegistryFromResource(IDR_IISRESTART, FALSE);
  110. bRun = FALSE;
  111. break;
  112. }
  113. if (lstrcmpi(lpszToken, _T("RegServer"))==0)
  114. {
  115. _Module.UpdateRegistryFromResource(IDR_IISRESTART, TRUE);
  116. //
  117. // Assign ACL to CLSID ( a la dcomcnfg ) granting access only to admins, current user
  118. // and system
  119. //
  120. ChangeAppIDAccessACL( _T("{E8FB8615-588F-11D2-9D61-00C04F79C5FE}"),
  121. _T("administrators"),
  122. TRUE,
  123. TRUE );
  124. bRun = FALSE;
  125. break;
  126. }
  127. lpszToken = FindOneOf(lpszToken, szTokens);
  128. }
  129. if (bRun)
  130. {
  131. _Module.StartMonitor();
  132. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  133. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  134. REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
  135. _ASSERTE(SUCCEEDED(hRes));
  136. hRes = CoResumeClassObjects();
  137. #else
  138. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  139. REGCLS_MULTIPLEUSE);
  140. #endif
  141. _ASSERTE(SUCCEEDED(hRes));
  142. MSG msg;
  143. while (GetMessage(&msg, 0, 0, 0))
  144. DispatchMessage(&msg);
  145. _Module.RevokeClassObjects();
  146. Sleep(dwPause); //wait for any threads to finish
  147. }
  148. _Module.Term();
  149. CoUninitialize();
  150. return nRet;
  151. }
  152. #endif
  153. int _cdecl
  154. main(
  155. int argc,
  156. char **argv
  157. )
  158. {
  159. // FreeConsole();
  160. LPTSTR lpCmdLine = GetCommandLine(); // necessary for minimal CRT
  161. // HRESULT hRes = CoInitialize(NULL);
  162. // If you are running on NT 4.0 or higher you can use the following call
  163. // instead to make the EXE free threaded.
  164. // This means that calls come in on a random RPC thread
  165. HRESULT hRes;
  166. hRes = CoInitializeEx(NULL,COINIT_MULTITHREADED);
  167. if (FAILED(hRes)) {
  168. return 1;
  169. }
  170. hRes = CoInitializeSecurity(
  171. NULL,
  172. -1,
  173. NULL,
  174. NULL,
  175. RPC_C_AUTHN_LEVEL_CONNECT,
  176. RPC_C_IMP_LEVEL_DELEGATE,
  177. NULL,
  178. EOAC_STATIC_CLOAKING,
  179. NULL );
  180. if (FAILED(hRes)) {
  181. return 1;
  182. }
  183. _ASSERTE(SUCCEEDED(hRes));
  184. _Module.Init(ObjectMap,GetModuleHandle(NULL));
  185. _Module.dwThreadID = GetCurrentThreadId();
  186. TCHAR szTokens[] = _T("-/");
  187. int nRet = 0;
  188. BOOL bRun = TRUE;
  189. LPCTSTR lpszToken = FindOneOf(lpCmdLine,szTokens);
  190. while (lpszToken != NULL)
  191. {
  192. if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
  193. {
  194. //_Module.UpdateRegistryFromResource(IDR_Iisrsta, FALSE);
  195. //nRet = _Module.UnregisterServer(&LIBID_IISRSTALib/*TRUE*/);
  196. _Module.UpdateRegistryFromResource(IDR_IISRESTART, FALSE);
  197. bRun = FALSE;
  198. break;
  199. }
  200. if (lstrcmpi(lpszToken, _T("RegServer"))==0)
  201. {
  202. _Module.UpdateRegistryFromResource(IDR_IISRESTART, TRUE);
  203. //_Module.UpdateRegistryFromResource(IDR_Iisrsta, TRUE);
  204. //nRet = _Module.RegisterServer(TRUE);
  205. //
  206. // Assign access ACL to CLSID granting access only to admins, current user
  207. // and system
  208. //
  209. ChangeAppIDAccessACL( _T("{E8FB8615-588F-11D2-9D61-00C04F79C5FE}"),
  210. _T("administrators"),
  211. TRUE,
  212. TRUE );
  213. bRun = FALSE;
  214. break;
  215. }
  216. lpszToken = FindOneOf(lpszToken, szTokens);
  217. }
  218. if (bRun) {
  219. _Module.StartMonitor();
  220. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  221. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  222. REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
  223. _ASSERTE(SUCCEEDED(hRes));
  224. hRes = CoResumeClassObjects();
  225. #else
  226. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  227. REGCLS_MULTIPLEUSE);
  228. #endif
  229. _ASSERTE(SUCCEEDED(hRes));
  230. MSG msg;
  231. while (GetMessage(&msg, 0, 0, 0))
  232. {
  233. DispatchMessage(&msg);
  234. }
  235. _Module.RevokeClassObjects();
  236. Sleep(dwPause); //wait for any threads to finish
  237. }
  238. _Module.Term();
  239. CoUninitialize();
  240. return (nRet);
  241. }
  242. #if 0
  243. #define SPACECHAR _T(' ')
  244. #define DQUOTECHAR _T('\"')
  245. #ifdef _UNICODE
  246. //extern "C" void wWinMainCRTStartup()
  247. #else // _UNICODE
  248. //extern "C" void WinMainCRTStartup()
  249. #endif // _UNICODE
  250. extern "C" void mainCRTStartup(VOID)
  251. {
  252. LPTSTR lpszCommandLine = ::GetCommandLine();
  253. if(lpszCommandLine == NULL)
  254. ::ExitProcess((UINT)-1);
  255. // Skip past program name (first token in command line).
  256. // Check for and handle quoted program name.
  257. if(*lpszCommandLine == DQUOTECHAR)
  258. {
  259. // Scan, and skip over, subsequent characters until
  260. // another double-quote or a null is encountered.
  261. do
  262. {
  263. lpszCommandLine = ::CharNext(lpszCommandLine);
  264. }
  265. while((*lpszCommandLine != DQUOTECHAR) && (*lpszCommandLine != _T('\0')));
  266. // If we stopped on a double-quote (usual case), skip over it.
  267. if(*lpszCommandLine == DQUOTECHAR)
  268. lpszCommandLine = ::CharNext(lpszCommandLine);
  269. }
  270. else
  271. {
  272. while(*lpszCommandLine > SPACECHAR)
  273. lpszCommandLine = ::CharNext(lpszCommandLine);
  274. }
  275. // Skip past any white space preceeding the second token.
  276. while(*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
  277. lpszCommandLine = ::CharNext(lpszCommandLine);
  278. STARTUPINFO StartupInfo;
  279. StartupInfo.dwFlags = 0;
  280. ::GetStartupInfo(&StartupInfo);
  281. int nRet = _tWinMain(::GetModuleHandle(NULL), NULL, lpszCommandLine,
  282. (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ?
  283. StartupInfo.wShowWindow : SW_SHOWDEFAULT);
  284. ::ExitProcess((UINT)nRet);
  285. }
  286. #endif