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.

163 lines
4.4 KiB

  1. // SAFInciTrac.cpp : Implementation of DLL Exports.
  2. // Note: Proxy/Stub Information
  3. // To build a separate proxy/stub DLL,
  4. // run nmake -f SAFInciTracps.mk in the project directory.
  5. #include "stdafx.h"
  6. #include "resource.h"
  7. #include <initguid.h>
  8. #include "obj\i386\SAFInciTrac.h"
  9. #include "obj\SAFInciTrac_i.c"
  10. #include "SAFChannelNotifyIncident.h"
  11. const DWORD dwTimeOut = 5000; // time for EXE to be idle before shutting down
  12. const DWORD dwPause = 1000; // time to wait for threads to finish up
  13. // Passed to CreateThread to monitor the shutdown event
  14. static DWORD WINAPI MonitorProc(void* pv)
  15. {
  16. CExeModule* p = (CExeModule*)pv;
  17. p->MonitorShutdown();
  18. return 0;
  19. }
  20. LONG CExeModule::Unlock()
  21. {
  22. LONG l = CComModule::Unlock();
  23. if (l == 0)
  24. {
  25. bActivity = true;
  26. SetEvent(hEventShutdown); // tell monitor that we transitioned to zero
  27. }
  28. return l;
  29. }
  30. //Monitors the shutdown event
  31. void CExeModule::MonitorShutdown()
  32. {
  33. while (1)
  34. {
  35. WaitForSingleObject(hEventShutdown, INFINITE);
  36. DWORD dwWait=0;
  37. do
  38. {
  39. bActivity = false;
  40. dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
  41. } while (dwWait == WAIT_OBJECT_0);
  42. // timed out
  43. if (!bActivity && m_nLockCnt == 0 && CSAFChannelNotifyIncident::m_nRefCount == 0) // if no activity let's really bail
  44. {
  45. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  46. CoSuspendClassObjects();
  47. if (!bActivity && m_nLockCnt == 0)
  48. #endif
  49. break;
  50. }
  51. }
  52. CloseHandle(hEventShutdown);
  53. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  54. }
  55. bool CExeModule::StartMonitor()
  56. {
  57. hEventShutdown = CreateEvent(NULL, false, false, NULL);
  58. if (hEventShutdown == NULL)
  59. return false;
  60. DWORD dwThreadID;
  61. HANDLE h = CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
  62. return (h != NULL);
  63. }
  64. CExeModule _Module;
  65. BEGIN_OBJECT_MAP(ObjectMap)
  66. OBJECT_ENTRY(CLSID_SAFChannelNotifyIncident, CSAFChannelNotifyIncident)
  67. END_OBJECT_MAP()
  68. LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
  69. {
  70. while (p1 != NULL && *p1 != NULL)
  71. {
  72. LPCTSTR p = p2;
  73. while (p != NULL && *p != NULL)
  74. {
  75. if (*p1 == *p)
  76. return CharNext(p1);
  77. p = CharNext(p);
  78. }
  79. p1 = CharNext(p1);
  80. }
  81. return NULL;
  82. }
  83. /////////////////////////////////////////////////////////////////////////////
  84. //
  85. extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
  86. HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  87. {
  88. lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  89. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  90. HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  91. #else
  92. HRESULT hRes = CoInitialize(NULL);
  93. #endif
  94. _ASSERTE(SUCCEEDED(hRes));
  95. _Module.Init(ObjectMap, hInstance, &LIBID_SAFINCITRACLib);
  96. _Module.dwThreadID = GetCurrentThreadId();
  97. TCHAR szTokens[] = _T("-/");
  98. int nRet = 0;
  99. BOOL bRun = TRUE;
  100. LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
  101. while (lpszToken != NULL)
  102. {
  103. if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
  104. {
  105. _Module.UpdateRegistryFromResource(IDR_SAFCHANNELNOTIFYINCIDENT, FALSE);
  106. nRet = _Module.UnregisterServer(TRUE);
  107. bRun = FALSE;
  108. break;
  109. }
  110. if (lstrcmpi(lpszToken, _T("RegServer"))==0)
  111. {
  112. _Module.UpdateRegistryFromResource(IDR_SAFCHANNELNOTIFYINCIDENT, TRUE);
  113. nRet = _Module.RegisterServer(TRUE);
  114. bRun = FALSE;
  115. break;
  116. }
  117. lpszToken = FindOneOf(lpszToken, szTokens);
  118. }
  119. if (bRun)
  120. {
  121. _Module.StartMonitor();
  122. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  123. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  124. REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
  125. _ASSERTE(SUCCEEDED(hRes));
  126. hRes = CoResumeClassObjects();
  127. #else
  128. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
  129. REGCLS_MULTIPLEUSE);
  130. #endif
  131. _ASSERTE(SUCCEEDED(hRes));
  132. MSG msg;
  133. while (GetMessage(&msg, 0, 0, 0))
  134. DispatchMessage(&msg);
  135. _Module.RevokeClassObjects();
  136. CSAFInciTrayIcon::RemoveTrayIcon();
  137. Sleep(dwPause); //wait for any threads to finish
  138. }
  139. _Module.Term();
  140. CoUninitialize();
  141. return nRet;
  142. }