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.

218 lines
6.6 KiB

  1. /***************************************************************************\
  2. *
  3. * File: ComManager.cpp
  4. *
  5. * Description:
  6. * ComManager.cpp implements the process-wide COM manager used for all COM, OLE
  7. * and Automation operations.
  8. *
  9. *
  10. * History:
  11. * 1/18/2000: JStall: Created
  12. *
  13. * Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
  14. *
  15. \***************************************************************************/
  16. #include "stdafx.h"
  17. #include "Services.h"
  18. #include "ComManager.h"
  19. int ComManager::s_cRefs = 0;
  20. CritLock ComManager::s_lock;
  21. HINSTANCE ComManager::s_hDllCOM = NULL;
  22. CoInitializeExProc ComManager::s_pfnCoInit = NULL;
  23. CoUninitializeProc ComManager::s_pfnCoUninit = NULL;
  24. CoCreateInstanceProc ComManager::s_pfnCreate = NULL;
  25. OleInitializeProc ComManager::s_pfnOleInit = NULL;
  26. OleUninitializeProc ComManager::s_pfnOleUninit = NULL;
  27. RegisterDragDropProc ComManager::s_pfnRegisterDragDrop = NULL;
  28. RevokeDragDropProc ComManager::s_pfnRevokeDragDrop = NULL;
  29. ReleaseStgMediumProc ComManager::s_pfnReleaseStgMedium = NULL;
  30. HINSTANCE ComManager::s_hDllAuto = NULL;
  31. SysAllocStringProc ComManager::s_pfnAllocString = NULL;
  32. SysFreeStringProc ComManager::s_pfnFreeString = NULL;
  33. VariantInitProc ComManager::s_pfnVariantInit = NULL;
  34. VariantClearProc ComManager::s_pfnVariantClear = NULL;
  35. //------------------------------------------------------------------------------
  36. ComManager::ComManager()
  37. {
  38. m_fInitCOM = FALSE;
  39. m_fInitOLE = FALSE;
  40. s_lock.Enter();
  41. s_cRefs++;
  42. s_lock.Leave();
  43. }
  44. //------------------------------------------------------------------------------
  45. ComManager::~ComManager()
  46. {
  47. s_lock.Enter();
  48. if ((s_pfnOleUninit != NULL) && m_fInitOLE) {
  49. (s_pfnOleUninit)();
  50. }
  51. if ((s_pfnCoUninit != NULL) && m_fInitCOM) {
  52. (s_pfnCoUninit)();
  53. }
  54. AssertMsg(s_cRefs > 0, "Must have at least one outstanding reference");
  55. if (--s_cRefs == 0) {
  56. if (s_hDllAuto != NULL) {
  57. FreeLibrary(s_hDllAuto);
  58. s_hDllAuto = NULL;
  59. }
  60. if (s_hDllCOM != NULL) {
  61. FreeLibrary(s_hDllCOM);
  62. s_hDllCOM = NULL;
  63. }
  64. s_pfnCoInit = NULL;
  65. s_pfnCoUninit = NULL;
  66. s_pfnCreate = NULL;
  67. s_pfnOleInit = NULL;
  68. s_pfnOleUninit = NULL;
  69. s_pfnRegisterDragDrop = NULL;
  70. s_pfnRevokeDragDrop = NULL;
  71. s_pfnReleaseStgMedium = NULL;
  72. s_pfnAllocString = NULL;
  73. s_pfnFreeString = NULL;
  74. s_pfnVariantInit = NULL;
  75. s_pfnVariantClear = NULL;
  76. }
  77. s_lock.Leave();
  78. }
  79. //------------------------------------------------------------------------------
  80. BOOL
  81. ComManager::Init(UINT nMask)
  82. {
  83. BOOL fSuccess = TRUE;
  84. s_lock.Enter();
  85. if (TestFlag(nMask, sAuto)) {
  86. // OLE-Automation need COM.
  87. SetFlag(nMask, sCOM);
  88. }
  89. if (TestFlag(nMask, sCOM | sOLE)) {
  90. //
  91. // Load the DLL
  92. //
  93. if (s_hDllCOM == NULL) {
  94. s_hDllCOM = LoadLibrary(_T("ole32.dll"));
  95. if (s_hDllCOM == NULL) {
  96. fSuccess = FALSE;
  97. goto errorexit;
  98. }
  99. s_pfnCoInit = (CoInitializeExProc) GetProcAddress(s_hDllCOM, _T("CoInitializeEx"));
  100. s_pfnCoUninit = (CoUninitializeProc) GetProcAddress(s_hDllCOM, _T("CoUninitialize"));
  101. s_pfnCreate = (CoCreateInstanceProc)GetProcAddress(s_hDllCOM, _T("CoCreateInstance"));
  102. s_pfnOleInit = (OleInitializeProc) GetProcAddress(s_hDllCOM, _T("OleInitialize"));
  103. s_pfnOleUninit = (OleUninitializeProc) GetProcAddress(s_hDllCOM, _T("OleUninitialize"));
  104. s_pfnRegisterDragDrop = (RegisterDragDropProc) GetProcAddress(s_hDllCOM, _T("RegisterDragDrop"));
  105. s_pfnRevokeDragDrop = (RevokeDragDropProc) GetProcAddress(s_hDllCOM, _T("RevokeDragDrop"));
  106. s_pfnReleaseStgMedium = (ReleaseStgMediumProc) GetProcAddress(s_hDllCOM, _T("ReleaseStgMedium"));
  107. if ((s_pfnCoInit == NULL) || (s_pfnCoUninit == NULL) || (s_pfnCreate == NULL) ||
  108. (s_pfnOleInit == NULL) || (s_pfnOleUninit == NULL) ||
  109. (s_pfnRegisterDragDrop == NULL) || (s_pfnRevokeDragDrop == NULL) ||
  110. (s_pfnReleaseStgMedium == NULL)) {
  111. fSuccess = FALSE;
  112. goto errorexit;
  113. }
  114. }
  115. //
  116. // Start COM / OLE
  117. //
  118. if (TestFlag(nMask, sCOM) && (!m_fInitCOM)) {
  119. // UI threads can not be free-threaded, so use apartment.
  120. HRESULT hr = (s_pfnCoInit)(NULL, COINIT_APARTMENTTHREADED);
  121. if (FAILED(hr)) {
  122. fSuccess = FALSE;
  123. goto errorexit;
  124. }
  125. m_fInitCOM = TRUE;
  126. }
  127. if (TestFlag(nMask, sOLE) && (!m_fInitOLE)) {
  128. HRESULT hr = (s_pfnOleInit)(NULL);
  129. if (FAILED(hr)) {
  130. fSuccess = FALSE;
  131. goto errorexit;
  132. }
  133. m_fInitOLE = TRUE;
  134. }
  135. }
  136. if (TestFlag(nMask, sAuto) && (s_hDllAuto == NULL)) {
  137. s_hDllAuto = LoadLibrary(_T("oleaut32.dll"));
  138. if (s_hDllAuto == NULL) {
  139. fSuccess = FALSE;
  140. goto errorexit;
  141. }
  142. s_pfnAllocString = (SysAllocStringProc) GetProcAddress(s_hDllAuto, _T("SysAllocString"));
  143. s_pfnFreeString = (SysFreeStringProc) GetProcAddress(s_hDllAuto, _T("SysFreeString"));
  144. s_pfnVariantInit = (VariantInitProc) GetProcAddress(s_hDllAuto, _T("VariantInit"));
  145. s_pfnVariantClear = (VariantClearProc) GetProcAddress(s_hDllAuto, _T("VariantClear"));
  146. if ((s_pfnAllocString == NULL) || (s_pfnFreeString == NULL) ||
  147. (s_pfnVariantInit == NULL) || (s_pfnVariantClear == NULL)) {
  148. fSuccess = FALSE;
  149. goto errorexit;
  150. }
  151. }
  152. errorexit:
  153. s_lock.Leave();
  154. return fSuccess;
  155. }
  156. //------------------------------------------------------------------------------
  157. BOOL
  158. ComManager::IsInit(UINT nMask) const
  159. {
  160. if (TestFlag(nMask, sCOM) && (s_hDllCOM != NULL) && m_fInitCOM) {
  161. return TRUE;
  162. }
  163. if (TestFlag(nMask, sOLE) && (s_hDllCOM != NULL) && m_fInitOLE) {
  164. return TRUE;
  165. }
  166. if (TestFlag(nMask, sAuto) && (s_hDllAuto != NULL)) {
  167. return TRUE;
  168. }
  169. return FALSE;
  170. }