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.

301 lines
8.2 KiB

  1. // SoftwareElement.cpp: implementation of the CSoftwareElement class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "SoftwareElement.h"
  8. #include <CRegCls.h>
  9. #include <WBEMTime.h>
  10. #include "ExtendString.h"
  11. #include "ExtendQuery.h"
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CSoftwareElement::CSoftwareElement(CRequestObject *pObj, IWbemServices *pNamespace,
  16. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  17. {
  18. }
  19. CSoftwareElement::~CSoftwareElement()
  20. {
  21. }
  22. HRESULT CSoftwareElement::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  23. {
  24. HRESULT hr = WBEM_S_NO_ERROR;
  25. MSIHANDLE hView = NULL;
  26. MSIHANDLE hRecord = NULL;
  27. int i = -1;
  28. int iState;
  29. WCHAR wcBuf[BUFF_SIZE];
  30. WCHAR wcID[BUFF_SIZE];
  31. WCHAR wcName[BUFF_SIZE];
  32. WCHAR wcProductCode[39];
  33. DWORD dwBufSize;
  34. bool bMatch = false;
  35. UINT uiStatus;
  36. //These will change from class to class
  37. bool bName, bSEID, bSES, bTOS, bVersion;
  38. Query wcQuery;
  39. wcQuery.Append ( 1, L"select distinct `Component`, `ComponentId`, `Attributes` from Component" );
  40. INSTALLSTATE piInstalled;
  41. bool bGotID = false;
  42. //improve getobject performance by optimizing the query
  43. if(atAction != ACTIONTYPE_ENUM)
  44. {
  45. // we are doing GetObject so we need to be reinitialized
  46. hr = WBEM_E_NOT_FOUND;
  47. BSTR bstrCompare;
  48. int iPos = -1;
  49. bstrCompare = SysAllocString ( L"Name" );
  50. if ( bstrCompare )
  51. {
  52. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  53. {
  54. bGotID = true;
  55. wcQuery.Append ( 3, L" where `Component`=\'", m_pRequest->m_Value[iPos], L"\'" );
  56. }
  57. else
  58. {
  59. int iPos = -1;
  60. ::SysFreeString ( bstrCompare );
  61. bstrCompare = SysAllocString ( L"SoftwareElementID" );
  62. if ( bstrCompare )
  63. {
  64. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  65. {
  66. bGotID = true;
  67. wcQuery.Append ( 3, L" where `ComponentId`=\'", m_pRequest->m_Value[iPos], L"\'" );
  68. }
  69. SysFreeString ( bstrCompare );
  70. }
  71. else
  72. {
  73. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  74. }
  75. }
  76. }
  77. else
  78. {
  79. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  80. }
  81. }
  82. LPWSTR Buffer = NULL;
  83. LPWSTR dynBuffer = NULL;
  84. DWORD dwDynBuffer = 0L;
  85. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  86. {
  87. // safe operation:
  88. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  89. wcscpy(wcProductCode, m_pRequest->Package(i));
  90. //Open our database
  91. try
  92. {
  93. if(m_pRequest->m_dwCheckKeyPresentStatus != ERROR_SUCCESS)
  94. {
  95. m_pRequest->LoadHive();
  96. }
  97. if ( GetView ( &hView, wcProductCode, wcQuery, L"Component", FALSE, TRUE ) )
  98. {
  99. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  100. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED))
  101. {
  102. CheckMSI(uiStatus);
  103. if(FAILED(hr = SpawnAnInstance(&m_pObj)))
  104. {
  105. throw hr;
  106. }
  107. dwBufSize = BUFF_SIZE;
  108. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  109. PutKeyProperty(m_pObj, pName, Buffer, &bName, m_pRequest);
  110. PutProperty(m_pObj, pCaption, Buffer);
  111. PutProperty(m_pObj, pDescription, Buffer);
  112. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  113. {
  114. dynBuffer [ 0 ] = 0;
  115. }
  116. dwBufSize = BUFF_SIZE;
  117. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcBuf, &dwBufSize));
  118. wcscpy(wcName, wcBuf);
  119. //Check that this component exists on this system
  120. if(ValidateComponentID(wcBuf, wcProductCode))
  121. {
  122. wcscpy(wcID, wcBuf);
  123. PutKeyProperty(m_pObj, pSoftwareElementID, wcID, &bSEID, m_pRequest);
  124. PutProperty(m_pObj, pIdentificationCode, wcID);
  125. dwBufSize = BUFF_SIZE;
  126. wcscpy(wcBuf, L"");
  127. piInstalled = g_fpMsiGetComponentPathW(wcProductCode, wcID, wcBuf, &dwBufSize);
  128. PutProperty(m_pObj, pPath, wcBuf);
  129. SoftwareElementState(piInstalled, &iState);
  130. PutKeyProperty(m_pObj, pSoftwareElementState, iState, &bSES, m_pRequest);
  131. PutProperty(m_pObj, pInstallState, (int)piInstalled);
  132. PutKeyProperty(m_pObj, pTargetOperatingSystem, GetOS(), &bTOS, m_pRequest);
  133. dwBufSize = BUFF_SIZE;
  134. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"ProductVersion", wcBuf, &dwBufSize));
  135. PutKeyProperty(m_pObj, pVersion, wcBuf, &bVersion, m_pRequest);
  136. PutProperty(m_pObj, pAttributes, g_fpMsiRecordGetInteger(hRecord, 3));
  137. dwBufSize = BUFF_SIZE;
  138. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct(), L"Manufacturer", wcBuf, &dwBufSize));
  139. PutProperty(m_pObj, pManufacturer, wcBuf);
  140. dwBufSize = BUFF_SIZE;
  141. if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode,INSTALLPROPERTY_INSTALLDATE, wcBuf, &dwBufSize))
  142. {
  143. if ( ( lstrlenW ( wcBuf ) + lstrlenW ( L"000000.000000+000" ) + 1 ) < BUFF_SIZE )
  144. {
  145. lstrcatW ( wcBuf, L"000000.000000+000" );
  146. BSTR bstrWbemTime;
  147. if ( ( bstrWbemTime = ::SysAllocString ( wcBuf ) ) != NULL )
  148. {
  149. WBEMTime time ( bstrWbemTime );
  150. ::SysFreeString ( bstrWbemTime );
  151. if ( time.IsOk () )
  152. {
  153. bstrWbemTime= time.GetDMTF ( );
  154. try
  155. {
  156. PutProperty( m_pObj, pInstallDate, bstrWbemTime );
  157. }
  158. catch ( ... )
  159. {
  160. ::SysFreeString ( bstrWbemTime );
  161. throw;
  162. }
  163. ::SysFreeString ( bstrWbemTime );
  164. }
  165. else
  166. {
  167. hr = E_INVALIDARG;
  168. }
  169. }
  170. else
  171. {
  172. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  173. }
  174. }
  175. else
  176. {
  177. hr = E_FAIL;
  178. }
  179. }
  180. if(bName && bSEID && bSES && bTOS && bVersion)
  181. {
  182. bMatch = true;
  183. }
  184. if((atAction != ACTIONTYPE_GET) || bMatch)
  185. {
  186. hr = pHandler->Indicate(1, &m_pObj);
  187. }
  188. }
  189. m_pObj->Release();
  190. m_pObj = NULL;
  191. g_fpMsiCloseHandle(hRecord);
  192. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  193. }
  194. }
  195. }
  196. catch(...)
  197. {
  198. if ( dynBuffer )
  199. {
  200. delete [] dynBuffer;
  201. dynBuffer = NULL;
  202. }
  203. //remove the key if it wasn't there b4....
  204. if(m_pRequest->m_dwCheckKeyPresentStatus != ERROR_SUCCESS)
  205. {
  206. m_pRequest->UnloadHive();
  207. }
  208. g_fpMsiCloseHandle(hRecord);
  209. g_fpMsiViewClose(hView);
  210. g_fpMsiCloseHandle(hView);
  211. msidata.CloseProduct ();
  212. if(m_pObj)
  213. {
  214. m_pObj->Release();
  215. m_pObj = NULL;
  216. }
  217. throw;
  218. }
  219. //remove the key if it wasn't there b4....
  220. if(m_pRequest->m_dwCheckKeyPresentStatus != ERROR_SUCCESS)
  221. {
  222. m_pRequest->UnloadHive();
  223. }
  224. g_fpMsiCloseHandle(hRecord);
  225. g_fpMsiViewClose(hView);
  226. g_fpMsiCloseHandle(hView);
  227. msidata.CloseProduct ();
  228. }
  229. if ( dynBuffer )
  230. {
  231. delete [] dynBuffer;
  232. dynBuffer = NULL;
  233. }
  234. return hr;
  235. }