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.

271 lines
6.8 KiB

  1. // Property.cpp: implementation of the CProperty class.
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "Property.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CProperty::CProperty(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CProperty::~CProperty()
  18. {
  19. }
  20. HRESULT CProperty::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. MSIHANDLE hView = NULL, hRecord = NULL;
  24. int i = -1;
  25. WCHAR wcBuf[BUFF_SIZE];
  26. WCHAR wcProductCode[39];
  27. DWORD dwBufSize;
  28. bool bMatch = false;
  29. UINT uiStatus;
  30. bool bGotID = false;
  31. WCHAR wcTestCode[39];
  32. bool bGotName = false;
  33. WCHAR wcName[BUFF_SIZE];
  34. //These will change from class to class
  35. bool bProperty, bProduct;
  36. //improve getobject performance by optimizing the query
  37. if(atAction != ACTIONTYPE_ENUM)
  38. {
  39. // we are doing GetObject so we need to be reinitialized
  40. hr = WBEM_E_NOT_FOUND;
  41. BSTR bstrCompare;
  42. int iPos = -1;
  43. bstrCompare = SysAllocString ( L"ProductCode" );
  44. if ( bstrCompare )
  45. {
  46. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  47. {
  48. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) == 38 )
  49. {
  50. //Get the product code we're looking for
  51. wcscpy(wcTestCode, m_pRequest->m_Value[iPos]);
  52. bGotID = true;
  53. }
  54. else
  55. {
  56. // we are not good to go, they have sent us longer string
  57. SysFreeString ( bstrCompare );
  58. throw hr;
  59. }
  60. }
  61. SysFreeString ( bstrCompare );
  62. }
  63. else
  64. {
  65. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  66. }
  67. iPos = -1;
  68. bstrCompare = SysAllocString ( L"Property" );
  69. if ( bstrCompare )
  70. {
  71. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  72. {
  73. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) < BUFF_SIZE )
  74. {
  75. //Get the name we're looking for
  76. wcscpy(wcName, m_pRequest->m_Value[iPos]);
  77. bGotName = true;
  78. }
  79. else
  80. {
  81. // we are not good to go, they have sent us longer string
  82. SysFreeString ( bstrCompare );
  83. throw hr;
  84. }
  85. }
  86. SysFreeString ( bstrCompare );
  87. }
  88. else
  89. {
  90. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  91. }
  92. }
  93. Query wcQuery;
  94. wcQuery.Append ( 1, L"select distinct `Property`, `Value` from Property" );
  95. //optimize for GetObject
  96. if ( bGotName )
  97. {
  98. wcQuery.Append ( 3, L" where `Property`=\'", wcName, L"\'" );
  99. }
  100. LPWSTR Buffer = NULL;
  101. LPWSTR dynBuffer = NULL;
  102. DWORD dwDynBuffer = 0L;
  103. while(!bMatch && (m_pRequest->Package(++i)) && (hr != WBEM_E_CALL_CANCELLED))
  104. {
  105. // safe operation:
  106. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  107. wcscpy(wcProductCode, m_pRequest->Package(i));
  108. if((atAction == ACTIONTYPE_ENUM) || (bGotID && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  109. //Open our database
  110. try
  111. {
  112. if ( GetView ( &hView, wcProductCode, wcQuery, L"Property", TRUE, FALSE ) )
  113. {
  114. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  115. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  116. CheckMSI(uiStatus);
  117. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  118. //----------------------------------------------------
  119. dwBufSize = BUFF_SIZE;
  120. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  121. PutKeyProperty(m_pObj, pProperty, Buffer, &bProperty, m_pRequest);
  122. PutProperty(m_pObj, pCaption, Buffer);
  123. PutProperty(m_pObj, pDescription, Buffer);
  124. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  125. {
  126. dynBuffer [ 0 ] = 0;
  127. }
  128. PutKeyProperty(m_pObj, pProductCode, wcProductCode, &bProduct, m_pRequest);
  129. //====================================================
  130. dwBufSize = BUFF_SIZE;
  131. uiStatus = g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize);
  132. //check if we overflowed the buffer.. if so try to compensate
  133. if ( uiStatus == ERROR_MORE_DATA)
  134. {
  135. LPWSTR wcBigBuf = NULL;
  136. try
  137. {
  138. if ( ( wcBigBuf = new WCHAR [ ++dwBufSize ] ) != NULL )
  139. {
  140. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBigBuf, &dwBufSize));
  141. PutProperty(m_pObj, pValue, wcBigBuf);
  142. }
  143. else
  144. {
  145. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  146. }
  147. }
  148. catch ( ... )
  149. {
  150. if ( wcBigBuf )
  151. {
  152. delete [] wcBigBuf;
  153. wcBigBuf = NULL;
  154. }
  155. throw;
  156. }
  157. if ( wcBigBuf )
  158. {
  159. delete [] wcBigBuf;
  160. wcBigBuf = NULL;
  161. }
  162. }else{
  163. CheckMSI(uiStatus);
  164. PutProperty(m_pObj, pValue, wcBuf);
  165. }
  166. //----------------------------------------------------
  167. if(bProperty && bProduct) bMatch = true;
  168. if((atAction != ACTIONTYPE_GET) || bMatch){
  169. hr = pHandler->Indicate(1, &m_pObj);
  170. }
  171. m_pObj->Release();
  172. m_pObj = NULL;
  173. g_fpMsiCloseHandle(hRecord);
  174. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  175. }
  176. }
  177. }
  178. catch(...)
  179. {
  180. if ( dynBuffer )
  181. {
  182. delete [] dynBuffer;
  183. dynBuffer = NULL;
  184. }
  185. if (hRecord)
  186. g_fpMsiCloseHandle(hRecord);
  187. if (hView)
  188. {
  189. g_fpMsiViewClose(hView);
  190. g_fpMsiCloseHandle(hView);
  191. }
  192. msidata.CloseDatabase ();
  193. if(m_pObj)
  194. {
  195. m_pObj->Release();
  196. m_pObj = NULL;
  197. }
  198. throw;
  199. }
  200. if (hRecord)
  201. g_fpMsiCloseHandle(hRecord);
  202. if (hView)
  203. {
  204. g_fpMsiViewClose(hView);
  205. g_fpMsiCloseHandle(hView);
  206. }
  207. msidata.CloseDatabase ();
  208. }
  209. }
  210. if ( dynBuffer )
  211. {
  212. delete [] dynBuffer;
  213. dynBuffer = NULL;
  214. }
  215. return hr;
  216. }