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.

428 lines
15 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.
  7. //
  8. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. //===============================================================================
  10. // Don't include everything from windows.h, but always bring in OLE 2 support
  11. //===============================================================================
  12. //#define WIN32_LEAN_AND_MEAN
  13. #define INC_OLE2
  14. //===============================================================================
  15. // Basic Windows and OLE everything
  16. //===============================================================================
  17. #include <windows.h>
  18. //===============================================================================
  19. // OLE DB headers
  20. //===============================================================================
  21. #include "oledb.h"
  22. #include "oledberr.h"
  23. //===============================================================================
  24. // Data conversion library header
  25. //===============================================================================
  26. #include "msdadc.h"
  27. //===============================================================================
  28. // Guids for data conversion library
  29. //===============================================================================
  30. #include "msdaguid.h"
  31. //===============================================================================
  32. // GUIDs
  33. //===============================================================================
  34. #include "guids.h"
  35. #include <cguid.h>
  36. //===============================================================================
  37. // Common project stuff
  38. //===============================================================================
  39. #include "headers.h"
  40. #include "classfac.h"
  41. #include "binderclassfac.h"
  42. #include "binder.h"
  43. #include "schema.h"
  44. #include "enumerat.h"
  45. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  46. //
  47. // Constructor for this class
  48. //
  49. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  50. CClassFactory::CClassFactory( void )
  51. {
  52. m_cRef = 0;
  53. //================================================================
  54. // Increment global object count
  55. //================================================================
  56. InterlockedIncrement(&g_cObj);
  57. }
  58. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. //
  60. // Destructor for this class
  61. //
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. CClassFactory:: ~CClassFactory( void )
  64. {
  65. //================================================================
  66. // Decrement global object count
  67. //================================================================
  68. InterlockedDecrement(&g_cObj);
  69. }
  70. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. //
  72. // Returns a pointer to a specified interface. Callers use QueryInterface to determine which interfaces
  73. // the called object supports.
  74. //
  75. // HRESULT indicating the status of the method
  76. // S_OK Interface is supported and ppvObject is set.
  77. // E_NOINTERFACE Interface is not supported by the object
  78. // E_INVALIDARG One or more arguments are invalid.
  79. //
  80. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. STDMETHODIMP CClassFactory::QueryInterface ( REFIID riid, // IN Interface ID of the interface being queried for.
  82. LPVOID * ppvObj // OUT Pointer to interface that was instantiated
  83. )
  84. {
  85. HRESULT hr = S_OK;
  86. CSetStructuredExceptionHandler seh;
  87. TRY_BLOCK;
  88. //=================================================================
  89. // Check for valid ppvObj pointer
  90. //=================================================================
  91. if (!ppvObj){
  92. hr = E_INVALIDARG;
  93. LogMessage("QueryInterface: Invalid argument pointer");
  94. }
  95. else{
  96. //=================================================================
  97. // In case we fail, we need to zero output arguments
  98. //=================================================================
  99. *ppvObj = NULL;
  100. //=================================================================
  101. // Do we support this interface?
  102. //=================================================================
  103. if (riid == IID_IUnknown || riid == IID_IClassFactory)
  104. {
  105. *ppvObj = (LPVOID) this;
  106. }
  107. //=================================================================
  108. // If we're going to return an interface, AddRef it first
  109. //=================================================================
  110. if (*ppvObj){
  111. ((LPUNKNOWN) *ppvObj)->AddRef();
  112. }
  113. else{
  114. hr = E_NOINTERFACE;
  115. LogMessage("QueryInterface: No interface");
  116. }
  117. }
  118. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::QueryInterface");
  119. return hr;
  120. }
  121. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  122. //
  123. // Increments a persistence count for the object
  124. //
  125. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  126. STDMETHODIMP_( ULONG ) CClassFactory::AddRef( void )
  127. {
  128. HRESULT hr = S_OK;
  129. CSetStructuredExceptionHandler seh;
  130. TRY_BLOCK;
  131. hr = InterlockedIncrement((long*)&m_cRef);
  132. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::AddRef");
  133. return hr;
  134. }
  135. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  136. //
  137. // Decrements a persistence count for the object and if persistence count is 0,the object destroys itself.
  138. //
  139. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  140. STDMETHODIMP_( ULONG ) CClassFactory::Release( void )
  141. {
  142. HRESULT hr = S_OK;
  143. CSetStructuredExceptionHandler seh;
  144. TRY_BLOCK;
  145. if (!InterlockedDecrement((long*)&m_cRef)){
  146. delete this;
  147. return 0;
  148. }
  149. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::Release");
  150. return m_cRef;
  151. }
  152. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  153. //
  154. // Controls whether an object application is kept in memory. Keeping the application alive in memory
  155. // allows instances of this class to be created more quickly.
  156. //
  157. // HRESULT indicating the status of the method
  158. // S_OK Interface is supported and ppvObject is set.
  159. //
  160. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  161. STDMETHODIMP CClassFactory::LockServer ( BOOL fLock ) // IN TRUE or FALSE to lock or unlock
  162. {
  163. HRESULT hr = S_OK;
  164. CSetStructuredExceptionHandler seh;
  165. TRY_BLOCK;
  166. if (fLock)
  167. {
  168. InterlockedIncrement( &g_cLock );
  169. }
  170. else
  171. {
  172. InterlockedDecrement( &g_cLock );
  173. }
  174. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::LockServer");
  175. return hr;
  176. }
  177. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  178. //
  179. // CDataSourceClassFactory
  180. //
  181. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  182. STDMETHODIMP CDataSourceClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj )
  183. {
  184. PCDATASOURCE pObj = NULL;
  185. HRESULT hr = S_OK;
  186. CSetStructuredExceptionHandler seh;
  187. TRY_BLOCK;
  188. //==============================================================
  189. // Check for valid ppvObj pointer
  190. //==============================================================
  191. if (ppvObj == NULL){
  192. LogMessage("CreateInstance: Invalid argument pointer");
  193. hr = ( E_INVALIDARG );
  194. }
  195. else
  196. {
  197. //==============================================================
  198. // In case we fail, we need to zero output arguments
  199. //==============================================================
  200. *ppvObj = NULL;
  201. //==============================================================
  202. // If we're given a controlling IUnknown, it must ask for
  203. // IUnknown. Otherwise, caller will end up getting a pointer to
  204. // their pUnkOuter instead of to the new object we create and
  205. // will have no way of getting back to this new object, so they
  206. // won't be able to free it. Bad!
  207. //==============================================================
  208. if (pUnkOuter && riid != IID_IUnknown){
  209. hr = DB_E_NOAGGREGATION;
  210. LogMessage("CreateInstance: No aggregation");
  211. }
  212. else{
  213. //==========================================================
  214. // Prepare for the possibility that there might be an error
  215. //==========================================================
  216. hr = E_OUTOFMEMORY;
  217. try
  218. {
  219. pObj = new CDataSource( pUnkOuter );
  220. }
  221. catch(...)
  222. {
  223. SAFE_DELETE_PTR(pObj);
  224. throw;
  225. }
  226. //==========================================================
  227. // Create a CDataSource object
  228. //==========================================================
  229. if ((pObj != NULL)){
  230. //======================================================
  231. // Initialize it
  232. //======================================================
  233. if (SUCCEEDED(hr = pObj->FInit())){
  234. hr = pObj->QueryInterface( riid, ppvObj );
  235. }
  236. if (FAILED( hr )){
  237. LogMessage("CreateInstance: Out of memory");
  238. SAFE_DELETE_PTR( pObj );
  239. }
  240. }
  241. }
  242. }
  243. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::CreateInstance for Datasource");
  244. return hr;
  245. }
  246. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  247. //
  248. // CEnumeratorClassFactory
  249. //
  250. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  251. STDMETHODIMP CEnumeratorClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj )
  252. {
  253. CEnumeratorNameSpace* pObj = NULL;
  254. HRESULT hr = S_OK;
  255. CSetStructuredExceptionHandler seh;
  256. TRY_BLOCK;
  257. //==============================================================
  258. // Check for valid ppvObj pointer
  259. //==============================================================
  260. if (ppvObj == NULL){
  261. LogMessage("CreateInstance: Invalid argument pointer");
  262. hr = E_INVALIDARG;
  263. }
  264. else
  265. {
  266. //==============================================================
  267. // In case we fail, we need to zero output arguments
  268. //==============================================================
  269. *ppvObj = NULL;
  270. //==============================================================
  271. // If we're given a controlling IUnknown, it must ask for
  272. // IUnknown. Otherwise, caller will end up getting a pointer to
  273. // their pUnkOuter instead of to the new object we create and
  274. // will have no way of getting back to this new object, so they
  275. // won't be able to free it. Bad!
  276. //==============================================================
  277. if (pUnkOuter && riid != IID_IUnknown){
  278. hr = DB_E_NOAGGREGATION;
  279. LogMessage("CreateInstance: No aggregation");
  280. }
  281. else{
  282. //==========================================================
  283. // Prepare for the possibility that there might be an error
  284. //==========================================================
  285. hr = E_OUTOFMEMORY;
  286. try
  287. {
  288. //==========================================================
  289. // Create a CBinder object
  290. //==========================================================
  291. pObj = new CEnumeratorNameSpace(pUnkOuter);
  292. }
  293. catch(...)
  294. {
  295. SAFE_DELETE_PTR(pObj);
  296. throw;
  297. }
  298. if (pObj != NULL ){
  299. //======================================================
  300. // Initialize it
  301. //======================================================
  302. hr = pObj->Initialize();
  303. if( S_OK == hr ){
  304. hr = pObj->QueryInterface( riid, ppvObj );
  305. }
  306. if (FAILED( hr )){
  307. LogMessage("CreateInstance: Out of memory");
  308. SAFE_DELETE_PTR( pObj );
  309. }
  310. }
  311. }
  312. }
  313. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::CreateInstance for Enumerator");
  314. return hr;
  315. }
  316. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  317. //
  318. // Creates an uninitialized instance of an object class.
  319. //
  320. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  321. STDMETHODIMP CErrorLookupClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, //IN Points to the controlling IUnknown interface
  322. REFIID riid, //IN Interface ID of the interface being queried for.
  323. LPVOID * ppvObj ) //OUT Pointer to interface that was instantiated
  324. {
  325. PCERRORLOOKUP pObj = NULL;
  326. HRESULT hr;
  327. CSetStructuredExceptionHandler seh;
  328. TRY_BLOCK;
  329. //============================================================================
  330. // Check for valid ppvObj pointer
  331. //============================================================================
  332. if (ppvObj == NULL){
  333. ERRORTRACE((THISPROVIDER,"CErrorLookupClassFactory::CreateInstance invalid argument "));
  334. hr = E_INVALIDARG;
  335. }
  336. else
  337. {
  338. //============================================================================
  339. // In case we fail, we need to zero output arguments
  340. //============================================================================
  341. *ppvObj = NULL;
  342. //============================================================================
  343. // If we're given a controlling IUnknown, it must ask for IUnknown.
  344. // Otherwise, the caller will end up getting a pointer to their pUnkOuter
  345. // instead of to the new object we create and will have no way of getting
  346. // back to this new object, so they won't be able to free it. Bad!
  347. //============================================================================
  348. if( pUnkOuter && riid != IID_IUnknown ){
  349. ERRORTRACE((THISPROVIDER,"CErrorLookupClassFactory::CreateInstance no aggregation "));
  350. hr = CLASS_E_NOAGGREGATION;
  351. }
  352. else
  353. {
  354. hr = E_OUTOFMEMORY;
  355. try
  356. {
  357. //============================================================================
  358. // Create a CErrorLookup object
  359. //============================================================================
  360. pObj = new CErrorLookup(pUnkOuter);
  361. }
  362. catch(...)
  363. {
  364. SAFE_DELETE_PTR(pObj);
  365. throw;
  366. }
  367. if( pObj != NULL)
  368. {
  369. hr = pObj->QueryInterface(riid, ppvObj);
  370. if( FAILED(hr) ){
  371. delete pObj;
  372. ERRORTRACE((THISPROVIDER,"ClassFactory::CreateInstance failed in call to CError::QueryInterface."));
  373. }
  374. }
  375. }
  376. }
  377. CATCH_BLOCK_HRESULT(hr,L"IClassFactory::CreateInstance for ErrorLookup");
  378. return hr;
  379. }