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.

475 lines
14 KiB

  1. /*++
  2. Copyright (C) 1993-1999 Microsoft Corporation
  3. Module Name:
  4. IPropBag.cpp
  5. Abstract:
  6. Implementation of the private IPropertyBag interface used by
  7. the System Monitor control.
  8. --*/
  9. #include <assert.h>
  10. #include "polyline.h"
  11. #include "unkhlpr.h"
  12. #include "unihelpr.h"
  13. #include "utils.h"
  14. #include "strids.h"
  15. #include "globals.h"
  16. #include "smonmsg.h"
  17. #include "ipropbag.h"
  18. #define MAX_GUID_STRING_LENGTH 39
  19. /*
  20. * CImpIPropertyBag interface implementation
  21. */
  22. IMPLEMENT_CONTAINED_IUNKNOWN(CImpIPropertyBag)
  23. /*
  24. * CImpIPropertyBag::CImpIPropertyBag
  25. *
  26. * Purpose:
  27. * Constructor.
  28. *
  29. * Return Value:
  30. */
  31. CImpIPropertyBag::CImpIPropertyBag ( LPUNKNOWN pUnkOuter)
  32. : m_cRef ( 0 ),
  33. m_pUnkOuter ( pUnkOuter ),
  34. m_pszData ( NULL ),
  35. m_dwCurrentDataLength ( 0 ),
  36. m_plistData ( NULL )
  37. {
  38. return;
  39. }
  40. /*
  41. * CImpIPropertyBag::~CImpIPropertyBag
  42. *
  43. * Purpose:
  44. * Destructor.
  45. *
  46. * Return Value:
  47. */
  48. CImpIPropertyBag::~CImpIPropertyBag ( void )
  49. {
  50. if ( NULL != m_pszData ) {
  51. delete m_pszData;
  52. }
  53. while ( NULL != m_plistData ) {
  54. PPARAM_DATA pData = DataListRemoveHead();
  55. VariantClear ( &pData->vValue );
  56. delete pData;
  57. }
  58. return;
  59. }
  60. /*
  61. * CImpIPropertyBag::Read
  62. *
  63. * Purpose:
  64. *
  65. * This function is called to read a property from the property bag.
  66. *
  67. * Parameters:
  68. * pszPropName Pointer to name of property to be read
  69. * pVar Pointer to the VARIANT to receive the property value
  70. * pIErrorLog Pointer to the caller's error log
  71. */
  72. STDMETHODIMP
  73. CImpIPropertyBag::Read (
  74. LPCOLESTR pszPropName, //Pointer to the property to be read
  75. VARIANT* pVar, //Pointer to the VARIANT to receive the
  76. //property value
  77. IErrorLog* pIErrorLog ) //Pointer to the caller's error log // can be null
  78. {
  79. HRESULT hr = S_OK;
  80. PPARAM_DATA pData;
  81. if (NULL==pszPropName)
  82. return ResultFromScode(E_POINTER);
  83. if (NULL==pVar)
  84. return ResultFromScode(E_POINTER);
  85. // Currently don't handle error log.
  86. assert ( NULL == pIErrorLog );
  87. pIErrorLog; // Eliminate compiler warning.
  88. //Read the specified data into the passed variant.
  89. pData = FindProperty ( pszPropName );
  90. if ( NULL != pData ) {
  91. //VARTYPE vtTarget = vValue.vt;
  92. if( pVar->vt != VT_BSTR ){
  93. hr = VariantChangeTypeEx( pVar, &pData->vValue, LCID_SCRIPT, VARIANT_NOUSEROVERRIDE, pVar->vt );
  94. }else{
  95. hr = VariantChangeType ( pVar, &pData->vValue, NULL, pVar->vt );
  96. }
  97. } else {
  98. hr = E_INVALIDARG;
  99. }
  100. return hr;
  101. }
  102. /*
  103. * CImpIPropertyBag::Write
  104. *
  105. * Purpose:
  106. *
  107. * This function is called to write a property to the property bag.
  108. *
  109. * Parameters:
  110. * pszPropName Pointer to name of property to be written
  111. * pVar Pointer to the VARIANT containing the property value
  112. */
  113. STDMETHODIMP
  114. CImpIPropertyBag::Write (
  115. LPCOLESTR pszPropName, //Pointer to the property to be written
  116. VARIANT* pVar ) //Pointer to the VARIANT containing the
  117. //property value and type
  118. {
  119. HRESULT hr = S_OK;
  120. VARIANT vValueBstr;
  121. DWORD dwNameLength;
  122. DWORD dwDataLength;
  123. static DWORD dwDelimiterLength = 0;
  124. static DWORD dwParamNameLength = 0;
  125. static DWORD dwEolTagLength = 0;
  126. static DWORD dwValueTagLength = 0;
  127. static TCHAR szParamTag[128];
  128. static TCHAR szValueTag[128];
  129. static TCHAR szEolTag[128];
  130. HRESULT hrConvert;
  131. LPTSTR pszNextField = m_pszData;
  132. DWORD dwCurrentDataUsedLength;
  133. if (NULL==pszPropName)
  134. return ResultFromScode(E_POINTER);
  135. if (NULL==pVar)
  136. return ResultFromScode(E_POINTER);
  137. VariantInit ( &vValueBstr );
  138. if( pVar->vt != VT_BSTR ){
  139. hrConvert = VariantChangeTypeEx( &vValueBstr, pVar, LCID_SCRIPT, VARIANT_NOUSEROVERRIDE, VT_BSTR );
  140. }else{
  141. hrConvert = VariantChangeType ( &vValueBstr, pVar, NULL, VT_BSTR );
  142. }
  143. // All length values calculated number of TCHARs.
  144. if ( 0 == dwDelimiterLength ) {
  145. // Initialize static values
  146. if (LoadString(g_hInstance, IDS_HTML_PARAM_TAG, szParamTag, 128)) {
  147. if (LoadString(g_hInstance, IDS_HTML_VALUE_TAG, szValueTag, 128)) {
  148. if (LoadString(g_hInstance, IDS_HTML_VALUE_EOL_TAG, szEolTag, 128)) {
  149. dwParamNameLength = lstrlen (szParamTag);
  150. dwValueTagLength = lstrlen ( szValueTag );
  151. dwEolTagLength = lstrlen ( szEolTag );
  152. dwDelimiterLength = dwParamNameLength + dwValueTagLength + dwEolTagLength;
  153. } else {
  154. hr = E_OUTOFMEMORY;
  155. }
  156. } else {
  157. hr = E_OUTOFMEMORY;
  158. }
  159. } else {
  160. hr = E_OUTOFMEMORY;
  161. }
  162. }
  163. if ( SUCCEEDED ( hr ) ) {
  164. dwNameLength = lstrlen ( pszPropName );
  165. dwDataLength = lstrlen ( W2T ( vValueBstr.bstrVal ) );
  166. dwCurrentDataUsedLength = lstrlen ( m_pszData );
  167. // Add 1 to size calculation for NULL buffer terminator.
  168. if ( m_dwCurrentDataLength
  169. < dwCurrentDataUsedLength + dwNameLength + dwDataLength + dwDelimiterLength + 1 ) {
  170. LPTSTR pszNewBuffer;
  171. if ( 0 == m_dwCurrentDataLength ) {
  172. m_dwCurrentDataLength += eDefaultBufferLength;
  173. } else {
  174. m_dwCurrentDataLength *= 2;
  175. }
  176. pszNewBuffer = new TCHAR[m_dwCurrentDataLength];
  177. if ( NULL == pszNewBuffer )
  178. return E_OUTOFMEMORY;
  179. if ( NULL != m_pszData ) {
  180. memcpy ( pszNewBuffer, m_pszData, dwCurrentDataUsedLength * sizeof(TCHAR) );
  181. delete m_pszData;
  182. }
  183. m_pszData = pszNewBuffer;
  184. }
  185. // Build the new string and add it to the current data.
  186. pszNextField = m_pszData + dwCurrentDataUsedLength;
  187. memcpy ( pszNextField, szParamTag, dwParamNameLength * sizeof(TCHAR) );
  188. pszNextField += dwParamNameLength;
  189. memcpy ( pszNextField, pszPropName, dwNameLength * sizeof(TCHAR) );
  190. pszNextField += dwNameLength;
  191. memcpy ( pszNextField, szValueTag, dwValueTagLength * sizeof(TCHAR) );
  192. pszNextField += dwValueTagLength;
  193. memcpy ( pszNextField, W2T(vValueBstr.bstrVal), dwDataLength * sizeof(TCHAR) );
  194. pszNextField += dwDataLength;
  195. memcpy ( pszNextField, szEolTag, dwEolTagLength * sizeof(TCHAR) );
  196. pszNextField += dwEolTagLength;
  197. lstrcpy ( pszNextField, _T("") );
  198. }
  199. return hr;
  200. }
  201. /*
  202. * CImpIPropertyBag::GetData
  203. *
  204. * Purpose:
  205. * Return pointer to the data buffer.
  206. *
  207. * Return Value:
  208. * Pointer to the data buffer.
  209. */
  210. LPTSTR
  211. CImpIPropertyBag::GetData ( void )
  212. {
  213. return m_pszData;
  214. }
  215. /*
  216. * CImpIPropertyBag::LoadData
  217. *
  218. * Purpose:
  219. * Load data from the supplied buffer into internal data structures.
  220. *
  221. * Return Value:
  222. * Status.
  223. */
  224. HRESULT
  225. CImpIPropertyBag::LoadData ( LPTSTR pszData )
  226. {
  227. HRESULT hr = S_OK;
  228. LPWSTR pszDataAllocW = NULL;
  229. LPWSTR pszCurrentPos = NULL;
  230. LPWSTR pszParamTag;
  231. LPWSTR pszValueTag;
  232. LPWSTR pszEooTag;
  233. LPSTR pszGuidA = NULL;
  234. LPSTR pszCurrentPosA = NULL;
  235. LPSTR pszDataA = NULL;
  236. OLECHAR szGuidW[MAX_GUID_STRING_LENGTH];
  237. LPWSTR pszGuidW = NULL;
  238. INT iStatus;
  239. INT iBufLen;
  240. USES_CONVERSION;
  241. if ( NULL == pszData ) {
  242. assert ( FALSE );
  243. hr = E_POINTER;
  244. } else {
  245. assert ( sizeof(TCHAR) == sizeof(WCHAR) );
  246. pszParamTag = ResourceString ( IDS_HTML_PARAM_SEARCH_TAG );
  247. pszValueTag = ResourceString ( IDS_HTML_VALUE_SEARCH_TAG );
  248. pszEooTag = ResourceString ( IDS_HTML_OBJECT_FOOTER );
  249. if ( NULL == pszParamTag
  250. || NULL == pszValueTag
  251. || NULL == pszEooTag ) {
  252. hr = E_UNEXPECTED;
  253. } else {
  254. // Unicode search: Begin the search after the first instance
  255. // of the System Monitor class id.
  256. iStatus = StringFromGUID2(CLSID_SystemMonitor, szGuidW, sizeof(szGuidW)/sizeof(OLECHAR));
  257. if ( 0 < iStatus ) {
  258. pszGuidW = wcstok ( szGuidW, L"{} " );
  259. if ( NULL != pszGuidW ) {
  260. pszCurrentPos = wcsstr(pszData, pszGuidW );
  261. // Handle wide vs ansi.
  262. if ( NULL == pszCurrentPos ) {
  263. // Check for ANSI version:
  264. pszDataA = (CHAR*) pszData;
  265. pszGuidA = W2A( pszGuidW );
  266. if ( NULL != pszGuidA ) {
  267. pszCurrentPosA = strstr ( pszDataA, pszGuidA );
  268. if ( NULL != pszCurrentPosA ) {
  269. iBufLen = lstrlenA (pszDataA) + 1;
  270. pszDataAllocW = new WCHAR [iBufLen * sizeof(WCHAR)];
  271. if ( NULL != pszDataAllocW ) {
  272. _MbToWide ( pszDataAllocW, pszDataA, iBufLen );
  273. pszCurrentPos = wcsstr(pszDataAllocW, pszGuidW );
  274. } else {
  275. hr = E_OUTOFMEMORY;
  276. }
  277. }
  278. }
  279. }
  280. }
  281. } else {
  282. hr = E_UNEXPECTED;
  283. }
  284. }
  285. if ( NULL != pszCurrentPos ) {
  286. WCHAR szQuote[2];
  287. LPWSTR pszEoo;
  288. wcscpy ( szQuote, _T("\"") );
  289. // End of object is the first object footer tag after the first sysmon
  290. // class id found. If multiple objects in the data block, only parse the first sysmon.
  291. pszEoo = wcsstr(pszCurrentPos, pszEooTag );
  292. if ( NULL != pszEoo ) {
  293. // Find first parameter tag.
  294. pszCurrentPos = wcsstr(pszCurrentPos, pszParamTag );
  295. while ( NULL != pszCurrentPos && pszCurrentPos < pszEoo ) {
  296. LPWSTR pszNextPos;
  297. INT lStrLength;
  298. PPARAM_DATA pParamData;
  299. LPWSTR pszTemp;
  300. // Store parameter/property name.
  301. // Find one past first quote.
  302. pszCurrentPos = wcsstr(pszCurrentPos, szQuote ) + 1;
  303. // The param name is between first and second quote.
  304. pszNextPos = wcsstr(pszCurrentPos, szQuote );
  305. lStrLength = ( (INT)((UINT_PTR)pszNextPos - (UINT_PTR)pszCurrentPos) ) / sizeof ( WCHAR ) ;
  306. pParamData = new PARAM_DATA;
  307. if ( NULL != pParamData ) {
  308. pParamData->pNextParam = NULL;
  309. VariantInit ( &pParamData->vValue );
  310. pParamData->vValue.vt = VT_BSTR;
  311. } else {
  312. hr = E_OUTOFMEMORY;
  313. break;
  314. }
  315. wcsncpy ( pParamData->pszPropertyName, pszCurrentPos, lStrLength );
  316. pParamData->pszPropertyName[lStrLength] = TEXT ('\0');
  317. // Find value tag and store parameter/property value.
  318. // Find value tag and store parameter/property value.
  319. // Find value tag
  320. pszCurrentPos = wcsstr ( pszCurrentPos, pszValueTag );
  321. // Find one past first quote
  322. pszCurrentPos = wcsstr ( pszCurrentPos, szQuote ) + 1;
  323. // The value is between first and second quote.
  324. pszNextPos = wcsstr ( pszCurrentPos, szQuote );
  325. lStrLength = ( (INT)((UINT_PTR)pszNextPos - (UINT_PTR)pszCurrentPos) ) / sizeof ( WCHAR );
  326. pszTemp = new TCHAR[lStrLength+1];
  327. if (pszTemp != NULL) {
  328. wcsncpy ( pszTemp, pszCurrentPos, lStrLength );
  329. pszTemp[lStrLength] = TEXT('\0');
  330. pParamData->vValue.bstrVal =
  331. SysAllocString ( pszTemp );
  332. delete pszTemp;
  333. DataListAddHead ( pParamData );
  334. // Find next parameter/property tag.
  335. pszCurrentPos = wcsstr(pszCurrentPos, pszParamTag );
  336. } else {
  337. delete pParamData;
  338. hr = E_OUTOFMEMORY;
  339. break;
  340. }
  341. } // While parameter tags exist for a single object.
  342. } else {
  343. hr = SMON_STATUS_NO_SYSMON_OBJECT;
  344. }
  345. } else {
  346. hr = SMON_STATUS_NO_SYSMON_OBJECT;
  347. }
  348. }
  349. if ( NULL != pszDataAllocW ) {
  350. delete pszDataAllocW;
  351. }
  352. return hr;
  353. }
  354. void
  355. CImpIPropertyBag::DataListAddHead ( PPARAM_DATA pData )
  356. {
  357. pData->pNextParam = m_plistData;
  358. m_plistData = pData;
  359. return;
  360. }
  361. CImpIPropertyBag::PPARAM_DATA
  362. CImpIPropertyBag::DataListRemoveHead ( )
  363. {
  364. PPARAM_DATA pReturnData;
  365. pReturnData = m_plistData;
  366. if ( NULL != m_plistData )
  367. m_plistData = m_plistData->pNextParam;
  368. return pReturnData;
  369. }
  370. CImpIPropertyBag::PPARAM_DATA
  371. CImpIPropertyBag::FindProperty ( LPCTSTR pszPropName )
  372. {
  373. PPARAM_DATA pReturnData;
  374. pReturnData = m_plistData;
  375. while ( NULL != pReturnData ) {
  376. if ( 0 == lstrcmpi ( pszPropName, pReturnData->pszPropertyName ) )
  377. break;
  378. pReturnData = pReturnData->pNextParam;
  379. }
  380. return pReturnData;
  381. }