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.

861 lines
26 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // MAINDLL.CPP
  6. //
  7. // rajesh 3/25/2000 Created.
  8. //
  9. // Contains the DLL entry points for the wmi2xml.dll
  10. // This DLL can be used as a COM DLL with 2 components that implement the
  11. // IWbemXMLConvertor and IXMLWbemConvertor interfaces, or it can be treated
  12. // as a non-COM DLL with the entry points WbemObjectToText() and TextToWbemObject()
  13. // The COM usage is done by the WMI Client API that uses XML. It uses the COM
  14. // components in this DLL to convert to/from XML and WMI.
  15. // The non-COM usage is by the WMI Core for purposed of implementation of th
  16. // IWbemObjectTextSrc interfaces. WMI Core uses the entry points WbemObjectToText
  17. // and TextToWbemObject to implement that interface when used with XML representations
  18. //
  19. //***************************************************************************
  20. #include "precomp.h"
  21. #include <olectl.h>
  22. #include <wbemidl.h>
  23. #include <wbemint.h>
  24. #include <genlex.h>
  25. #include <opathlex.h>
  26. #include <objpath.h>
  27. #include "classfac.h"
  28. #include "wmiconv.h"
  29. #include "maindll.h"
  30. // These the the CLSIDs of the 2 Components implemented in this DLL
  31. // {610037EC-CE06-11d3-93FC-00805F853771}
  32. DEFINE_GUID(CLSID_WbemXMLConvertor,
  33. 0x610037ec, 0xce06, 0x11d3, 0x93, 0xfc, 0x0, 0x80, 0x5f, 0x85, 0x37, 0x71);
  34. // {41388E26-F847-4a9d-96C0-9A847DBA4CFE}
  35. DEFINE_GUID(CLSID_XMLWbemConvertor,
  36. 0x41388e26, 0xf847, 0x4a9d, 0x96, 0xc0, 0x9a, 0x84, 0x7d, 0xba, 0x4c, 0xfe);
  37. // Count number of objects and number of locks.
  38. long g_cObj = 0 ;
  39. long g_cLock = 0 ;
  40. HMODULE ghModule = NULL;
  41. // An Object Factory used by TextToWbemObject
  42. _IWmiObjectFactory *g_pObjectFactory = NULL;
  43. // Some const BSTRs
  44. BSTR g_strName = NULL;
  45. BSTR g_strSuperClass = NULL;
  46. BSTR g_strType = NULL;
  47. BSTR g_strClassOrigin = NULL;
  48. BSTR g_strSize = NULL;
  49. BSTR g_strClassName = NULL;
  50. BSTR g_strValueType = NULL;
  51. BSTR g_strToSubClass = NULL;
  52. BSTR g_strToInstance = NULL;
  53. BSTR g_strAmended = NULL;
  54. BSTR g_strOverridable = NULL;
  55. BSTR g_strArraySize = NULL;
  56. BSTR g_strReferenceClass = NULL;
  57. // A critical section to create/delete globals
  58. CRITICAL_SECTION g_StaticsCreationDeletion;
  59. // A boolean that indicates whether globals have been initialized
  60. bool g_bGlobalsInitialized = false;
  61. // Control-specific registry strings
  62. LPCTSTR WMI_XML_DESCRIPTION = __TEXT("WMI TO XML Helper");
  63. LPCTSTR XML_WMI_DESCRIPTION = __TEXT("XML TO WMI Helper");
  64. // Standard registry key/value names
  65. LPCTSTR INPROC32_STR = __TEXT("InprocServer32");
  66. LPCTSTR INPROC_STR = __TEXT("InprocServer");
  67. LPCTSTR THREADING_MODEL_STR = __TEXT("ThreadingModel");
  68. LPCTSTR BOTH_STR = __TEXT("Both");
  69. LPCTSTR CLSID_STR = __TEXT("SOFTWARE\\CLASSES\\CLSID\\");
  70. LPCTSTR OBJECT_TXT_SRC_STR = __TEXT("SOFTWARE\\Microsoft\\WBEM\\TextSource");
  71. LPCTSTR XMLENCODER_STR = __TEXT("SOFTWARE\\Microsoft\\WBEM\\xml\\Encoders");
  72. LPCTSTR XMLDECODER_STR = __TEXT("SOFTWARE\\Microsoft\\WBEM\\xml\\Decoders");
  73. LPCTSTR VERSION_1 = __TEXT("1.0");
  74. LPCTSTR VERSION_2 = __TEXT("2.0");
  75. //***************************************************************************
  76. //
  77. // BOOL WINAPI DllMain
  78. //
  79. // DESCRIPTION:
  80. //
  81. // Entry point for DLL.
  82. //
  83. // PARAMETERS:
  84. //
  85. // hModule instance handle
  86. // ulReason why we are being called
  87. // pvReserved reserved
  88. //
  89. // RETURN VALUE:
  90. //
  91. // TRUE if OK.
  92. //
  93. //***************************************************************************
  94. BOOL WINAPI DllMain( HINSTANCE hModule,
  95. DWORD ulReason,
  96. LPVOID lpReserved
  97. )
  98. {
  99. switch (ulReason)
  100. {
  101. case DLL_PROCESS_DETACH:
  102. DeleteCriticalSection(&g_StaticsCreationDeletion);
  103. return TRUE;
  104. case DLL_PROCESS_ATTACH:
  105. InitializeCriticalSection(&g_StaticsCreationDeletion);
  106. ghModule = hModule;
  107. return TRUE;
  108. }
  109. return TRUE;
  110. }
  111. //***************************************************************************
  112. //
  113. // STDAPI DllGetClassObject
  114. //
  115. // DESCRIPTION:
  116. //
  117. // Called when Ole wants a class factory. Return one only if it is the sort
  118. // of class this DLL supports.
  119. //
  120. // PARAMETERS:
  121. //
  122. // rclsid CLSID of the object that is desired.
  123. // riid ID of the desired interface.
  124. // ppv Set to the class factory.
  125. //
  126. // RETURN VALUE:
  127. //
  128. // S_OK all is well
  129. // E_FAILED not something we support
  130. //
  131. //***************************************************************************
  132. STDAPI DllGetClassObject(
  133. IN REFCLSID rclsid,
  134. IN REFIID riid,
  135. OUT LPVOID *ppv
  136. )
  137. {
  138. HRESULT hr = E_FAIL;
  139. /*
  140. if (CLSID_WbemXMLConvertor == rclsid)
  141. {
  142. CWmiToXmlFactory *pObj = NULL;
  143. if (NULL == (pObj = new CWmiToXmlFactory()))
  144. return ResultFromScode(E_OUTOFMEMORY);
  145. hr=pObj->QueryInterface(riid, ppv);
  146. if ( FAILED ( hr ) )
  147. {
  148. delete pObj ;
  149. }
  150. }
  151. */
  152. /* Conversion to Text to Wbem Object has been cut from the WHistler Feature List and hence commented out
  153. else if (CLSID_XMLWbemConvertor == rclsid)
  154. {
  155. CXmlToWmiFactory *pObj = NULL;
  156. if (NULL == (pObj = new CXmlToWmiFactory()))
  157. return ResultFromScode(E_OUTOFMEMORY);
  158. hr=pObj->QueryInterface(riid, ppv);
  159. if ( FAILED ( hr ) )
  160. {
  161. delete pObj ;
  162. }
  163. }
  164. else
  165. return E_FAIL;
  166. */
  167. return hr ;
  168. }
  169. //***************************************************************************
  170. //
  171. // STDAPI DllCanUnloadNow
  172. //
  173. // DESCRIPTION:
  174. //
  175. // Answers if the DLL can be freed, that is, if there are no
  176. // references to anything this DLL provides.
  177. //
  178. // RETURN VALUE:
  179. //
  180. // S_OK if it is OK to unload
  181. // S_FALSE if still in use
  182. //
  183. //***************************************************************************
  184. STDAPI DllCanUnloadNow ()
  185. {
  186. //It is OK to unload if there are no objects or locks on the
  187. // class factory.
  188. if (0L==g_cObj && 0L==g_cLock)
  189. {
  190. ReleaseDLLResources();
  191. return S_OK;
  192. }
  193. return S_FALSE;
  194. }
  195. /***************************************************************************
  196. *
  197. * SetKeyAndValue
  198. *
  199. * Description: Helper function for DllRegisterServer that creates
  200. * a key, sets a value, and closes that key. If pszSubkey is NULL, then
  201. * the value is created for the pszKey key.
  202. *
  203. * Parameters:
  204. * pszKey LPTSTR to the name of the key
  205. * pszSubkey LPTSTR to the name of a subkey
  206. * pszValueName LPTSTR to the value name to use
  207. * pszValue LPTSTR to the value to store
  208. *
  209. * Return Value:
  210. * BOOL TRUE if successful, FALSE otherwise.
  211. ***************************************************************************/
  212. BOOL SetKeyAndValue(LPCTSTR pszKey, LPCTSTR pszSubkey, LPCTSTR pszValueName, LPCTSTR pszValue)
  213. {
  214. HKEY hKey;
  215. TCHAR szKey[256];
  216. _tcscpy(szKey, pszKey);
  217. // If a sub key is mentioned, use it.
  218. if (NULL != pszSubkey)
  219. {
  220. _tcscat(szKey, __TEXT("\\"));
  221. _tcscat(szKey, pszSubkey);
  222. }
  223. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  224. szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
  225. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  226. return FALSE;
  227. if (NULL != pszValue)
  228. {
  229. if (ERROR_SUCCESS != RegSetValueEx(hKey, pszValueName, 0, REG_SZ, (BYTE *)pszValue,
  230. (_tcslen(pszValue)+1)*sizeof(TCHAR)))
  231. {
  232. RegCloseKey(hKey);
  233. return FALSE;
  234. }
  235. }
  236. RegCloseKey(hKey);
  237. return TRUE;
  238. }
  239. /***************************************************************************
  240. *
  241. * DeleteKey
  242. *
  243. * Description: Helper function for DllUnRegisterServer that deletes the subkey
  244. * of a key.
  245. *
  246. * Parameters:
  247. * pszKey LPTSTR to the name of the key
  248. * pszSubkey LPTSTR ro the name of a subkey
  249. *
  250. * Return Value:
  251. * BOOL TRUE if successful, FALSE otherwise.
  252. ***************************************************************************/
  253. BOOL DeleteKey(LPCTSTR pszKey, LPCTSTR pszSubkey)
  254. {
  255. HKEY hKey;
  256. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  257. pszKey, 0, NULL, REG_OPTION_NON_VOLATILE,
  258. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  259. return FALSE;
  260. if(ERROR_SUCCESS != RegDeleteKey(hKey, pszSubkey))
  261. {
  262. RegCloseKey(hKey);
  263. return FALSE;
  264. }
  265. RegCloseKey(hKey);
  266. return TRUE;
  267. }
  268. /***************************************************************************
  269. *
  270. * DeleteValue
  271. *
  272. * Description: Helper function for DllUnRegisterServer that deletes a value
  273. * under a key.
  274. *
  275. * Parameters:
  276. * pszKey LPTSTR to the name of the key
  277. * pszValue LPTSTR to the name of a value under the key
  278. *
  279. * Return Value:
  280. * BOOL TRUE if successful, FALSE otherwise.
  281. ***************************************************************************/
  282. BOOL DeleteValue(LPCTSTR pszKey, LPCTSTR pszValue)
  283. {
  284. HKEY hKey;
  285. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  286. pszKey, 0, NULL, REG_OPTION_NON_VOLATILE,
  287. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  288. return FALSE;
  289. if(ERROR_SUCCESS != RegDeleteValue(hKey, pszValue))
  290. {
  291. RegCloseKey(hKey);
  292. return FALSE;
  293. }
  294. RegCloseKey(hKey);
  295. return TRUE;
  296. }
  297. //***************************************************************************
  298. //
  299. // DllRegisterServer
  300. //
  301. // Purpose: Called during setup or by regsvr32.
  302. //
  303. // Return: NOERROR if registration successful, error otherwise.
  304. //***************************************************************************
  305. STDAPI DllRegisterServer(void)
  306. {
  307. TCHAR szModule[512];
  308. DWORD dwLength = GetModuleFileName(ghModule, szModule, sizeof(szModule)/sizeof(TCHAR));
  309. if(dwLength < 512)
  310. {
  311. memset((szModule + dwLength),0,sizeof(TCHAR));
  312. }
  313. else
  314. {
  315. return SELFREG_E_CLASS;
  316. }
  317. TCHAR szWmiXmlClassID[128];
  318. TCHAR szWmiXmlCLSIDClassID[128];
  319. #ifdef UNICODE
  320. if(StringFromGUID2(CLSID_WbemXMLConvertor, szWmiXmlClassID, 128) == 0)
  321. return SELFREG_E_CLASS;
  322. #else
  323. WCHAR wszWmiXmlClassID[128];
  324. if(StringFromGUID2(CLSID_WbemXMLConvertor, wszWmiXmlClassID, 128) == 0)
  325. return SELFREG_E_CLASS;
  326. WideCharToMultiByte(CP_ACP, 0, wszWmiXmlClassID, -1, szWmiXmlCLSIDClassID, 128, NULL, NULL);
  327. #endif
  328. _tcscpy(szWmiXmlCLSIDClassID, CLSID_STR);
  329. _tcscat(szWmiXmlCLSIDClassID, szWmiXmlClassID);
  330. // Don't care about the return values. This is because
  331. // the registration of this COM component has been removed
  332. // This is added to remove registration from previous installations
  333. DeleteKey(szWmiXmlCLSIDClassID, INPROC32_STR);
  334. DeleteKey(CLSID_STR, szWmiXmlClassID);
  335. /* //
  336. // Create entries under CLSID for the Wmi to XML convertor
  337. //
  338. if (FALSE == SetKeyAndValue(szWmiXmlCLSIDClassID, NULL, NULL, WMI_XML_DESCRIPTION))
  339. return SELFREG_E_CLASS;
  340. if (FALSE == SetKeyAndValue(szWmiXmlCLSIDClassID, INPROC32_STR, NULL, szModule))
  341. return SELFREG_E_CLASS;
  342. if (FALSE == SetKeyAndValue(szWmiXmlCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, BOTH_STR))
  343. return SELFREG_E_CLASS;
  344. */
  345. TCHAR szXmlWmiClassID[128];
  346. TCHAR szXmlWmiCLSIDClassID[128];
  347. #ifdef UNICODE
  348. if(StringFromGUID2(CLSID_XMLWbemConvertor, szXmlWmiClassID, 128) == 0)
  349. return SELFREG_E_CLASS;
  350. #else
  351. WCHAR wszXmlWmiClassID[128];
  352. if(StringFromGUID2(CLSID_XMLWbemConvertor, wszXmlWmiClassID, 128) == 0)
  353. return SELFREG_E_CLASS;
  354. WideCharToMultiByte(CP_ACP, 0, wszXmlWmiClassID, -1, szXmlWmiCLSIDClassID, 128, NULL, NULL);
  355. #endif
  356. /* Conversion to Text to Wbem Object has been cut from the WHistler Feature List and hence commented out
  357. _tcscpy(szXmlWmiCLSIDClassID, CLSID_STR);
  358. _tcscat(szXmlWmiCLSIDClassID, szXmlWmiClassID);
  359. //
  360. // Create entries under CLSID for the XML to WMI convertor
  361. //
  362. if (FALSE == SetKeyAndValue(szXmlWmiCLSIDClassID, NULL, NULL, XML_WMI_DESCRIPTION))
  363. return SELFREG_E_CLASS;
  364. if (FALSE == SetKeyAndValue(szXmlWmiCLSIDClassID, INPROC32_STR, NULL, szModule))
  365. return SELFREG_E_CLASS;
  366. if (FALSE == SetKeyAndValue(szXmlWmiCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, BOTH_STR))
  367. return SELFREG_E_CLASS;
  368. */
  369. // Now create entries for the Core team's implementation of the IWbemObjectTxtSrc interface
  370. if (FALSE == SetKeyAndValue(OBJECT_TXT_SRC_STR,
  371. L"1", // WMI_OBJ_TEXT_CIM_DTD_2_0
  372. L"TextSourceDLL", szModule))
  373. return SELFREG_E_CLASS;
  374. if (FALSE == SetKeyAndValue(OBJECT_TXT_SRC_STR,
  375. L"2", // WMI_OBJ_TEXT_WMI_DTD_2_0, NULL
  376. L"TextSourceDLL", szModule))
  377. return SELFREG_E_CLASS;
  378. // We're done with the COM Entries. Now, we need to create our component specific entries.
  379. // Each WMI XML Encoder/Decoder is registered underneath the key HKLM/Software/Microsoft/WBEM/XML/Encoders
  380. // For each encoding (including these 2), we will have to create a value with the DTD version as name
  381. // and a value of the CLSID of the component. So, here we go
  382. // Remove the braces from the string representation first
  383. szWmiXmlClassID[wcslen(szWmiXmlClassID)-1] = NULL;
  384. if (FALSE == SetKeyAndValue(XMLENCODER_STR, NULL, VERSION_1, szWmiXmlClassID+1))
  385. return SELFREG_E_CLASS;
  386. if (FALSE == SetKeyAndValue(XMLENCODER_STR, NULL, VERSION_2, szWmiXmlClassID+1))
  387. return SELFREG_E_CLASS;
  388. if (FALSE == SetKeyAndValue(XMLDECODER_STR, NULL, VERSION_1, szXmlWmiClassID+1))
  389. return SELFREG_E_CLASS;
  390. if (FALSE == SetKeyAndValue(XMLDECODER_STR, NULL, VERSION_2, szXmlWmiClassID+1))
  391. return SELFREG_E_CLASS;
  392. return NOERROR;
  393. }
  394. //***************************************************************************
  395. //
  396. // DllUnregisterServer
  397. //
  398. // Purpose: Called when it is time to remove the registry entries.
  399. //
  400. // Return: NOERROR if registration successful, error otherwise.
  401. //***************************************************************************
  402. STDAPI DllUnregisterServer(void)
  403. {
  404. TCHAR szModule[512];
  405. DWORD dwLength = GetModuleFileName(ghModule,szModule, sizeof(szModule)/sizeof(TCHAR));
  406. if(dwLength < 512)
  407. {
  408. memset((szModule + dwLength),0,sizeof(TCHAR));
  409. }
  410. else
  411. {
  412. return SELFREG_E_CLASS;
  413. }
  414. TCHAR szWmiXmlClassID[128];
  415. TCHAR szWmiXmlCLSIDClassID[128];
  416. #ifdef UNICODE
  417. if(StringFromGUID2(CLSID_WbemXMLConvertor, szWmiXmlClassID, 128) == 0)
  418. return SELFREG_E_CLASS;
  419. #else
  420. WCHAR wszWmiXmlClassID[128];
  421. if(StringFromGUID2(CLSID_WbemXMLConvertor, wszWmiXmlClassID, 128) == 0)
  422. return SELFREG_E_CLASS;
  423. WideCharToMultiByte(CP_ACP, 0, wszWmiXmlClassID, -1, szWmiXmlClassID, 128, NULL, NULL);
  424. #endif
  425. _tcscpy(szWmiXmlCLSIDClassID, CLSID_STR);
  426. _tcscat(szWmiXmlCLSIDClassID, szWmiXmlClassID);
  427. //
  428. // Delete the keys for the WMI to XML COM obhect
  429. //
  430. // Don't care about the return values. This is because
  431. // the registration of this COM component has been removed
  432. // This is retained to remove any old installations of the DLL
  433. DeleteKey(szWmiXmlCLSIDClassID, INPROC32_STR);
  434. DeleteKey(CLSID_STR, szWmiXmlClassID);
  435. /* Conversion to Text to Wbem Object has been cut from the WHistler Feature List and hence commented out
  436. TCHAR szXmlWmiClassID[128];
  437. TCHAR szXmlWmiCLSIDClassID[128];
  438. #ifdef UNICODE
  439. if(StringFromGUID2(CLSID_XMLWbemConvertor, szXmlWmiClassID, 128) == 0)
  440. return SELFREG_E_CLASS;
  441. #else
  442. WCHAR wszXmlWmiClassID[128];
  443. if(StringFromGUID2(CLSID_XMLWbemConvertor, wszXmlWmiClassID, 128) == 0)
  444. return SELFREG_E_CLASS;
  445. WideCharToMultiByte(CP_ACP, 0, wszXmlWmiClassID, -1, szXmlWmiCLSIDClassID, 128, NULL, NULL);
  446. #endif
  447. _tcscpy(szXmlWmiCLSIDClassID, CLSID_STR);
  448. _tcscat(szXmlWmiCLSIDClassID, szXmlWmiClassID);
  449. //
  450. // Delete the keys for the XML to WMI COM obhect
  451. //
  452. if(FALSE == DeleteKey(szXmlWmiCLSIDClassID, INPROC32_STR))
  453. return SELFREG_E_CLASS;
  454. if(FALSE == DeleteKey(CLSID_STR, szXmlWmiClassID))
  455. return SELFREG_E_CLASS;
  456. */
  457. // Remove the entries for the Core team's implementation of the IWbemObjectTxtSrc interface
  458. if (FALSE == DeleteKey(OBJECT_TXT_SRC_STR, /*WMI_OBJ_TEXT_CIM_DTD_2_0, NULL*/ L"1"))
  459. return SELFREG_E_CLASS;
  460. if (FALSE == DeleteKey(OBJECT_TXT_SRC_STR, /*WMI_OBJ_TEXT_WMI_DTD_2_0, NULL*/ L"2"))
  461. return SELFREG_E_CLASS;
  462. // Delete the non-COM Registry stuff
  463. if(FALSE == DeleteValue(XMLENCODER_STR, VERSION_1))
  464. return SELFREG_E_CLASS;
  465. if(FALSE == DeleteValue(XMLENCODER_STR, VERSION_2))
  466. return SELFREG_E_CLASS;
  467. if(FALSE == DeleteValue(XMLDECODER_STR, VERSION_1))
  468. return SELFREG_E_CLASS;
  469. if(FALSE == DeleteValue(XMLDECODER_STR, VERSION_2))
  470. return SELFREG_E_CLASS;
  471. return NOERROR;
  472. }
  473. // This is called only if this DLL is treated as a NON COM DLL
  474. HRESULT AllocateDLLResources()
  475. {
  476. HRESULT hr = E_FAIL;
  477. EnterCriticalSection(&g_StaticsCreationDeletion);
  478. if(!g_bGlobalsInitialized)
  479. {
  480. g_bGlobalsInitialized = true;
  481. // Increment the object count since this is a COM DLL too.
  482. // Otherwise a COM Client in the process would call CoFreeUnusedLibraries and
  483. // this would result in unloading of the DLL while a C++ client is
  484. // holding on to a proc address obtained using Loadlibrary/GetProcAddress
  485. InterlockedIncrement(&g_cObj);
  486. // Create an object factory for use in TextToWbemObject
  487. if(SUCCEEDED(hr = CoCreateInstance(CLSID__WmiObjectFactory, NULL, CLSCTX_INPROC_SERVER,
  488. IID__IWmiObjectFactory, (LPVOID *)&g_pObjectFactory)))
  489. {
  490. if( (g_strName = SysAllocString(L"NAME")) &&
  491. (g_strSuperClass = SysAllocString(L"SUPERCLASS")) &&
  492. (g_strType = SysAllocString(L"TYPE")) &&
  493. (g_strClassOrigin = SysAllocString(L"CLASSORIGIN")) &&
  494. (g_strSize = SysAllocString(L"ARRAYSIZE")) &&
  495. (g_strClassName = SysAllocString(L"CLASSNAME")) &&
  496. (g_strValueType = SysAllocString(L"VALUETYPE")) &&
  497. (g_strToSubClass = SysAllocString(L"TOSUBCLASS")) &&
  498. (g_strToInstance = SysAllocString(L"TOINSTANCE")) &&
  499. (g_strAmended = SysAllocString(L"AMENDED")) &&
  500. (g_strOverridable = SysAllocString(L"OVERRIDABLE")) &&
  501. (g_strArraySize = SysAllocString(L"ARRAYSIZE")) &&
  502. (g_strReferenceClass = SysAllocString(L"REFERENCECLASS")) )
  503. {
  504. hr = S_OK;
  505. }
  506. else
  507. hr = E_OUTOFMEMORY;
  508. }
  509. // Release resources if things did not go well
  510. if(FAILED(hr))
  511. ReleaseDLLResources();
  512. }
  513. else
  514. hr = S_OK;
  515. LeaveCriticalSection(&g_StaticsCreationDeletion);
  516. return hr;
  517. }
  518. // This is called only if this DLL is treated as a NON COM DLL
  519. // It is the inverse operation of AllocateDLLResources()
  520. HRESULT ReleaseDLLResources()
  521. {
  522. EnterCriticalSection(&g_StaticsCreationDeletion);
  523. if(g_bGlobalsInitialized)
  524. {
  525. // Decrement the object count even though this isnt a COM call
  526. // The reason is described in the AllocateDLLResources() call
  527. InterlockedDecrement(&g_cObj);
  528. if(g_pObjectFactory)
  529. {
  530. g_pObjectFactory->Release();
  531. g_pObjectFactory = NULL;
  532. }
  533. SysFreeString(g_strName);
  534. g_strName = NULL;
  535. SysFreeString(g_strSuperClass);
  536. g_strSuperClass = NULL;
  537. SysFreeString(g_strType);
  538. g_strType = NULL;
  539. SysFreeString(g_strClassOrigin);
  540. g_strClassOrigin = NULL;
  541. SysFreeString(g_strSize);
  542. g_strSize = NULL;
  543. SysFreeString(g_strClassName);
  544. g_strClassName = NULL;
  545. SysFreeString(g_strValueType);
  546. g_strValueType = NULL;
  547. SysFreeString(g_strToSubClass);
  548. g_strToSubClass = NULL;
  549. SysFreeString(g_strToInstance);
  550. g_strToInstance = NULL;
  551. SysFreeString(g_strAmended);
  552. g_strAmended = NULL;
  553. SysFreeString(g_strOverridable);
  554. g_strOverridable = NULL;
  555. SysFreeString(g_strArraySize);
  556. g_strArraySize = NULL;
  557. SysFreeString(g_strReferenceClass);
  558. g_strReferenceClass = NULL;
  559. g_bGlobalsInitialized = false;
  560. }
  561. LeaveCriticalSection(&g_StaticsCreationDeletion);
  562. return S_OK;
  563. }
  564. //
  565. // Entry Points for WMI Core's implementation of IWbemObjectTextSrc
  566. //*****************************************************************
  567. HRESULT OpenWbemTextSource(long lFlags, ULONG uObjTextFormat)
  568. {
  569. return AllocateDLLResources();
  570. }
  571. HRESULT CloseWbemTextSource(long lFlags, ULONG uObjTextFormat)
  572. {
  573. return ReleaseDLLResources();
  574. }
  575. HRESULT WbemObjectToText(long lFlags, ULONG uObjTextFormat, void *pWbemContext, void *pWbemClassObject, BSTR *pstrText)
  576. {
  577. if(pWbemClassObject == NULL || pstrText == NULL)
  578. return WBEM_E_INVALID_PARAMETER;
  579. // Check to see if we support this encoding format
  580. if(uObjTextFormat != WMI_OBJ_TEXT_CIM_DTD_2_0 &&
  581. uObjTextFormat != WMI_OBJ_TEXT_WMI_DTD_2_0 )
  582. return WBEM_E_INVALID_PARAMETER;
  583. HRESULT hr = E_FAIL;
  584. // OpenTextSrc not called and so strings are not yet allocated and initialized
  585. if(!g_bGlobalsInitialized)
  586. {
  587. return WBEM_E_INVALID_OPERATION;
  588. }
  589. CWmiToXmlFactory oObjFactory;
  590. // Create an instance of the convertor
  591. IWbemXMLConvertor *pConvertor = NULL;
  592. if(SUCCEEDED(hr = oObjFactory.CreateInstance(NULL, IID_IWbemXMLConvertor, (LPVOID *)&pConvertor)))
  593. {
  594. // Create a stream
  595. IStream *pStream = NULL;
  596. if (SUCCEEDED(hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream)))
  597. {
  598. // See if we need to write a VALUE.NAMEDOBJECT, VALUE.OBJECTWITHLOCALPATH or VALUE.OBJECTWITHPATH
  599. // in the output. This is indicated by the "PathLevel" value in the IWbemContext object, if any
  600. int iValueTagToWrite = -1;
  601. if(pWbemContext)
  602. {
  603. VARIANT vPathLevel;
  604. VariantInit(&vPathLevel);
  605. if(SUCCEEDED(((IWbemContext *)pWbemContext)->GetValue(L"PathLevel", 0, &vPathLevel) ) && vPathLevel.vt != VT_NULL)
  606. {
  607. if(vPathLevel.lVal<0 || vPathLevel.lVal>3)
  608. hr = WBEM_E_INVALID_PARAMETER;
  609. iValueTagToWrite = vPathLevel.lVal;
  610. VariantClear(&vPathLevel);
  611. }
  612. }
  613. if(SUCCEEDED(hr))
  614. {
  615. switch(iValueTagToWrite)
  616. {
  617. case 1: pStream->Write ((void const *)L"<VALUE.NAMEDOBJECT>", wcslen (L"<VALUE.NAMEDOBJECT>") * sizeof (OLECHAR), NULL);break;
  618. case 2: pStream->Write ((void const *)L"<VALUE.OBJECTWITHLOCALPATH>", wcslen (L"<VALUE.OBJECTWITHLOCALPATH>") * sizeof (OLECHAR), NULL);break;
  619. case 3: pStream->Write ((void const *)L"<VALUE.OBJECTWITHPATH>", wcslen (L"<VALUE.OBJECTWITHPATH>") * sizeof (OLECHAR), NULL);break;
  620. }
  621. // Do the conversion
  622. if(SUCCEEDED(hr = pConvertor->MapObjectToXML((IWbemClassObject *)pWbemClassObject, NULL, 0,
  623. (IWbemContext *)pWbemContext, pStream, NULL)))
  624. {
  625. // Terminate with the correct tag
  626. switch(iValueTagToWrite)
  627. {
  628. case 1: pStream->Write ((void const *)L"</VALUE.NAMEDOBJECT>", wcslen (L"</VALUE.NAMEDOBJECT>") * sizeof (OLECHAR), NULL);break;
  629. case 2: pStream->Write ((void const *)L"</VALUE.OBJECTWITHLOCALPATH>", wcslen (L"</VALUE.OBJECTWITHLOCALPATH>") * sizeof (OLECHAR), NULL);break;
  630. case 3: pStream->Write ((void const *)L"</VALUE.OBJECTWITHPATH>", wcslen (L"</VALUE.OBJECTWITHPATH>") * sizeof (OLECHAR), NULL);break;
  631. }
  632. // Get the data from the stream
  633. LARGE_INTEGER offset;
  634. offset.LowPart = offset.HighPart = 0;
  635. if(SUCCEEDED(hr = pStream->Seek (offset, STREAM_SEEK_SET, NULL)))
  636. {
  637. STATSTG statstg;
  638. if (SUCCEEDED(hr = pStream->Stat(&statstg, STATFLAG_NONAME)))
  639. {
  640. ULONG cbSize = (statstg.cbSize).LowPart;
  641. WCHAR *pText = NULL;
  642. // Convert the data to a BSTR
  643. if(pText = new WCHAR [(cbSize/2)])
  644. {
  645. if (SUCCEEDED(hr = pStream->Read(pText, cbSize, NULL)))
  646. {
  647. *pstrText = NULL;
  648. if(*pstrText = SysAllocStringLen(pText, cbSize/2))
  649. {
  650. hr = S_OK;
  651. }
  652. else
  653. hr = E_OUTOFMEMORY;
  654. }
  655. delete [] pText;
  656. }
  657. }
  658. }
  659. }
  660. }
  661. pStream->Release();
  662. }
  663. pConvertor->Release();
  664. }
  665. return hr;
  666. }
  667. HRESULT TextToWbemObject(long lFlags, ULONG uObjTextFormat, void *pWbemContext, BSTR strText, void **ppWbemClassObject)
  668. {
  669. return WBEM_E_METHOD_NOT_IMPLEMENTED;
  670. /* Conversion to Text to Wbem Object has been cut from the WHistler Feature List and hence commented out
  671. if(ppWbemClassObject == NULL )
  672. return WBEM_E_INVALID_PARAMETER;
  673. // Check to see if we support this encoding format
  674. if(uObjTextFormat != WMI_OBJ_TEXT_CIM_DTD_2_0 &&
  675. uObjTextFormat != WMI_OBJ_TEXT_WMI_DTD_2_0 )
  676. return WBEM_E_INVALID_PARAMETER;
  677. // See if we should allow WMI extensions
  678. bool bAllowWMIExtensions = false;
  679. if(uObjTextFormat == WMI_OBJ_TEXT_WMI_DTD_2_0)
  680. bAllowWMIExtensions = true;
  681. HRESULT hr = E_FAIL;
  682. // Create an XML document for the body
  683. //==============================
  684. IXMLDOMDocument *pDocument = NULL;
  685. if(SUCCEEDED(hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
  686. IID_IXMLDOMDocument, (LPVOID *)&pDocument)))
  687. {
  688. VARIANT_BOOL bParse = VARIANT_FALSE;
  689. if(SUCCEEDED(hr = pDocument->loadXML(strText, &bParse)))
  690. {
  691. if(bParse == VARIANT_TRUE)
  692. {
  693. // Get the top level element
  694. IXMLDOMElement *pDocElement = NULL;
  695. if(SUCCEEDED(hr = pDocument->get_documentElement(&pDocElement)))
  696. {
  697. BSTR strDocName = NULL;
  698. if(SUCCEEDED(pDocElement->get_nodeName(&strDocName)))
  699. {
  700. if(_wcsicmp(strDocName, L"CLASS") == 0)
  701. hr = CXml2Wmi::MapClass(pDocElement, (IWbemClassObject **)ppWbemClassObject, NULL, NULL, false, bAllowWMIExtensions);
  702. else if(_wcsicmp(strDocName, L"INSTANCE") == 0)
  703. hr = CXml2Wmi::MapInstance(pDocElement, (IWbemClassObject **)ppWbemClassObject, NULL, NULL, bAllowWMIExtensions);
  704. else
  705. hr = WBEM_E_INVALID_SYNTAX;
  706. SysFreeString(strDocName);
  707. }
  708. else
  709. hr = WBEM_E_INVALID_SYNTAX;
  710. pDocElement->Release();
  711. }
  712. else
  713. hr = WBEM_E_FAILED;
  714. }
  715. else
  716. {
  717. // RAJESHR - This is debugging code to be removed
  718. IXMLDOMParseError *pError = NULL;
  719. if(SUCCEEDED(pDocument->get_parseError(&pError)))
  720. {
  721. LONG errorCode = 0;
  722. pError->get_errorCode(&errorCode);
  723. LONG line=0, linepos=0;
  724. BSTR reason=NULL, srcText = NULL;
  725. if(SUCCEEDED(pError->get_line(&line)) &&
  726. SUCCEEDED(pError->get_linepos(&linepos)) &&
  727. SUCCEEDED(pError->get_reason(&reason)) &&
  728. SUCCEEDED(pError->get_srcText(&srcText)))
  729. {
  730. }
  731. pError->Release();
  732. if(reason)
  733. SysFreeString(reason);
  734. if(srcText)
  735. SysFreeString(srcText);
  736. }
  737. hr = WBEM_E_INVALID_SYNTAX;
  738. }
  739. }
  740. else
  741. hr = WBEM_E_INVALID_SYNTAX;
  742. pDocument->Release();
  743. }
  744. return hr;
  745. */
  746. }