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.

296 lines
11 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMI OLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // The module contains the DLL Entry and Exit points, plus the OLE ClassFactory class for RootBinder object.
  7. //
  8. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. //#define DECLARE_GLOBALS
  10. //===============================================================================
  11. // Don't include everything from windows.h, but always bring in OLE 2 support
  12. //===============================================================================
  13. //#define WIN32_LEAN_AND_MEAN
  14. #define INC_OLE2
  15. //===============================================================================
  16. // Make sure constants get initialized
  17. //===============================================================================
  18. #define INITGUID
  19. #define DBINITCONSTANTS
  20. //===============================================================================
  21. // Basic Windows and OLE everything
  22. //===============================================================================
  23. #include <windows.h>
  24. //===============================================================================
  25. // OLE DB headers
  26. //===============================================================================
  27. #include "oledb.h"
  28. #include "oledberr.h"
  29. //===============================================================================
  30. // Data conversion library header
  31. //===============================================================================
  32. #include "msdadc.h"
  33. //===============================================================================
  34. // Guids for data conversion library
  35. //===============================================================================
  36. #include "msdaguid.h"
  37. //===============================================================================
  38. // GUIDs
  39. //===============================================================================
  40. #include "guids.h"
  41. //===============================================================================
  42. // Common project stuff
  43. //===============================================================================
  44. #include "headers.h"
  45. #include "binderclassfac.h"
  46. //===============================================================================
  47. // Globals
  48. //===============================================================================
  49. extern LONG g_cObj; // # of outstanding objects
  50. extern LONG g_cLock; // # of explicit locks set
  51. extern DWORD g_cAttachedProcesses; // # of attached processes
  52. extern DWORD g_dwPageSize; // System page size
  53. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  54. //
  55. // Destructor for this class
  56. //
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. CBinderClassFactory:: CBinderClassFactory( void )
  59. {
  60. m_cRef = 0;
  61. //================================================================
  62. // Decrement global object count
  63. //================================================================
  64. InterlockedIncrement(&g_cObj);
  65. }
  66. CBinderClassFactory:: ~CBinderClassFactory( void )
  67. {
  68. //================================================================
  69. // Decrement global object count
  70. //================================================================
  71. InterlockedDecrement(&g_cObj);
  72. }
  73. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. //
  75. // Returns a pointer to a specified interface. Callers use QueryInterface to determine which interfaces
  76. // the called object supports.
  77. //
  78. // HRESULT indicating the status of the method
  79. // S_OK Interface is supported and ppvObject is set.
  80. // E_NOINTERFACE Interface is not supported by the object
  81. // E_INVALIDARG One or more arguments are invalid.
  82. //
  83. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. STDMETHODIMP CBinderClassFactory::QueryInterface (
  85. REFIID riid, // IN Interface ID of the interface being queried for.
  86. LPVOID * ppvObj // OUT Pointer to interface that was instantiated
  87. )
  88. {
  89. HRESULT hr = S_OK;
  90. CSetStructuredExceptionHandler seh;
  91. TRY_BLOCK;
  92. //=================================================================
  93. // Check for valid ppvObj pointer
  94. //=================================================================
  95. if (!ppvObj){
  96. hr = E_INVALIDARG;
  97. LogMessage("QueryInterface: Invalid argument pointer");
  98. }
  99. else{
  100. //=================================================================
  101. // In case we fail, we need to zero output arguments
  102. //=================================================================
  103. *ppvObj = NULL;
  104. //=================================================================
  105. // Do we support this interface?
  106. //=================================================================
  107. if (riid == IID_IUnknown || riid == IID_IClassFactory)
  108. {
  109. *ppvObj = (LPVOID) this;
  110. }
  111. //=================================================================
  112. // If we're going to return an interface, AddRef it first
  113. //=================================================================
  114. if (*ppvObj){
  115. ((LPUNKNOWN) *ppvObj)->AddRef();
  116. }
  117. else{
  118. hr = E_NOINTERFACE;
  119. LogMessage("QueryInterface: No interface");
  120. }
  121. }
  122. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::QueryInterface for RootBinder");
  123. return hr;
  124. }
  125. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  126. //
  127. // Increments a persistence count for the object
  128. //
  129. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  130. STDMETHODIMP_( ULONG ) CBinderClassFactory::AddRef( void )
  131. {
  132. HRESULT hr = S_OK;
  133. CSetStructuredExceptionHandler seh;
  134. TRY_BLOCK;
  135. hr = InterlockedIncrement((long *)&m_cRef);
  136. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::AddRef for RootBinder");
  137. return hr;
  138. }
  139. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  140. //
  141. // Decrements a persistence count for the object and if persistence count is 0,the object destroys itself.
  142. //
  143. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  144. STDMETHODIMP_( ULONG ) CBinderClassFactory::Release( void )
  145. {
  146. HRESULT hr = S_OK;
  147. CSetStructuredExceptionHandler seh;
  148. TRY_BLOCK;
  149. if (!InterlockedDecrement((long *)&m_cRef)){
  150. delete this;
  151. }
  152. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::Release for RootBinder");
  153. return m_cRef;
  154. }
  155. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  156. //
  157. // Creates an uninitialized instance of an object class.Initialization is subsequently performed using
  158. // another interface-specific method
  159. //
  160. // HRESULT indicating the status of the method
  161. // S_OK Interface is supported and ppvObject is set.
  162. // E_NOINTERFACE Interface is not supported by the object
  163. // E_INVALIDARG One or more arguments are invalid.
  164. // E_OUTOFMEMORY Memory could not be allocated
  165. // OTHER Other HRESULTs returned by called functions
  166. //
  167. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  168. STDMETHODIMP CBinderClassFactory::CreateInstance (
  169. LPUNKNOWN pUnkOuter, // IN Points to the controlling IUnknown interface
  170. REFIID riid, // IN Interface ID of the interface being queried for.
  171. LPVOID * ppvObj // OUT Pointer to interface that was instantiated
  172. )
  173. {
  174. CBinder* pObj = NULL;
  175. HRESULT hr = S_OK;
  176. CSetStructuredExceptionHandler seh;
  177. TRY_BLOCK;
  178. //==============================================================
  179. // Check for valid ppvObj pointer
  180. //==============================================================
  181. if (ppvObj == NULL){
  182. LogMessage("CreateInstance: Invalid argument pointer");
  183. hr = ( E_INVALIDARG );
  184. }
  185. else
  186. {
  187. //==============================================================
  188. // In case we fail, we need to zero output arguments
  189. //==============================================================
  190. *ppvObj = NULL;
  191. //==============================================================
  192. // If we're given a controlling IUnknown, it must ask for
  193. // IUnknown. Otherwise, caller will end up getting a pointer to
  194. // their pUnkOuter instead of to the new object we create and
  195. // will have no way of getting back to this new object, so they
  196. // won't be able to free it. Bad!
  197. //==============================================================
  198. if (pUnkOuter && riid != IID_IUnknown){
  199. hr = DB_E_NOAGGREGATION;
  200. LogMessage("CreateInstance: No aggregation");
  201. }
  202. else{
  203. //==========================================================
  204. // Prepare for the possibility that there might be an error
  205. //==========================================================
  206. hr = E_OUTOFMEMORY;
  207. try
  208. {
  209. //==========================================================
  210. // Create a CBinder object
  211. //==========================================================
  212. pObj = new CBinder(pUnkOuter);
  213. }
  214. catch(...)
  215. {
  216. SAFE_DELETE_PTR(pObj);
  217. throw;
  218. }
  219. if (pObj != NULL ){
  220. //======================================================
  221. // Initialize it
  222. //======================================================
  223. if (SUCCEEDED(hr = pObj->InitBinder())){
  224. hr = pObj->QueryInterface( riid, ppvObj );
  225. }
  226. if (FAILED( hr )){
  227. LogMessage("CreateInstance: Out of memory");
  228. SAFE_DELETE_PTR( pObj );
  229. }
  230. }
  231. }
  232. }
  233. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::CreateInstance for RootBinder");
  234. return hr;
  235. }
  236. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  237. //
  238. // Controls whether an object application is kept in memory. Keeping the application alive in memory
  239. // allows instances of this class to be created more quickly.
  240. //
  241. // HRESULT indicating the status of the method
  242. // S_OK Interface is supported and ppvObject is set.
  243. //
  244. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  245. STDMETHODIMP CBinderClassFactory::LockServer ( BOOL fLock ) // IN TRUE or FALSE to lock or unlock
  246. {
  247. HRESULT hr = NOERROR;
  248. CSetStructuredExceptionHandler seh;
  249. TRY_BLOCK;
  250. if (fLock)
  251. {
  252. InterlockedIncrement( &g_cLock );
  253. }
  254. else
  255. {
  256. InterlockedDecrement( &g_cLock );
  257. }
  258. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::LockServer for RootBinder");
  259. return hr;
  260. }