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.

292 lines
7.7 KiB

  1. // InstalledSoftwareElement.cpp: implementation of the CInstalledSoftwareElement class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include <tchar.h>
  8. #include "InstalledSoftwareElement.h"
  9. #include "ExtendString.h"
  10. #include "ExtendQuery.h"
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CInstalledSoftwareElement::CInstalledSoftwareElement(CRequestObject *pObj, IWbemServices *pNamespace,
  15. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  16. {
  17. }
  18. CInstalledSoftwareElement::~CInstalledSoftwareElement()
  19. {
  20. }
  21. HRESULT CInstalledSoftwareElement::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  22. {
  23. HRESULT hr = WBEM_S_NO_ERROR;
  24. MSIHANDLE hView = NULL;
  25. MSIHANDLE hRecord = NULL;
  26. int i = -1;
  27. WCHAR wcBuf[BUFF_SIZE];
  28. WCHAR wcProductCode[39];
  29. WCHAR wcSoftware[BUFF_SIZE];
  30. WCHAR wcSysName[BUFF_SIZE];
  31. WCHAR wcComponentID[BUFF_SIZE];
  32. WCHAR wcElmName[BUFF_SIZE];
  33. #if !defined(_UNICODE)
  34. WCHAR wcTmp[BUFF_SIZE];
  35. #endif
  36. DWORD dwBufSize;
  37. bool bMatch = false;
  38. UINT uiStatus;
  39. CRequestObject *pSysRObj = NULL;
  40. CRequestObject *pElmRObj = NULL;
  41. bool bGotID = false;
  42. bool bGotName = false;
  43. bool bSysName = false;
  44. if(atAction != ACTIONTYPE_ENUM)
  45. {
  46. // we are doing GetObject so we need to be reinitialized
  47. hr = WBEM_E_NOT_FOUND;
  48. int j;
  49. //GetObject optimizations
  50. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  51. for(j = 0; j < m_pRequest->m_iPropCount; j++){
  52. if(_wcsicmp(m_pRequest->m_Property[j], L"System") == 0){
  53. pSysRObj = new CRequestObject();
  54. if(!pSysRObj) throw he;
  55. pSysRObj->Initialize(m_pNamespace);
  56. pSysRObj->ParsePath(m_pRequest->m_Value[j]);
  57. break;
  58. }
  59. }
  60. if(pSysRObj){
  61. for(j = 0; j < pSysRObj->m_iPropCount; j++){
  62. if(_wcsicmp(pSysRObj->m_Property[j], L"Name") == 0){
  63. //Get the product code we're looking for
  64. if ( ::SysStringLen ( pSysRObj->m_Value[j] ) < BUFF_SIZE )
  65. {
  66. wcscpy(wcSysName, pSysRObj->m_Value[j]);
  67. bSysName = true;
  68. break;
  69. }
  70. }
  71. }
  72. pSysRObj->Cleanup();
  73. delete pSysRObj;
  74. pSysRObj = NULL;
  75. }
  76. for(j = 0; j < m_pRequest->m_iPropCount; j++){
  77. if(_wcsicmp(m_pRequest->m_Property[j], L"Element") == 0){
  78. pElmRObj = new CRequestObject();
  79. if(!pElmRObj) throw he;
  80. pElmRObj->Initialize(m_pNamespace);
  81. pElmRObj->ParsePath(m_pRequest->m_Value[j]);
  82. break;
  83. }
  84. }
  85. if(pElmRObj){
  86. for(j = 0; j < pElmRObj->m_iPropCount; j++){
  87. if(_wcsicmp(pElmRObj->m_Property[j], L"SoftwareElementID") == 0){
  88. //Get the product code we're looking for
  89. if ( ::SysStringLen ( pElmRObj->m_Value[j] ) < BUFF_SIZE )
  90. {
  91. wcscpy(wcComponentID, pElmRObj->m_Value[j]);
  92. bGotID = true;
  93. }
  94. }
  95. if(_wcsicmp(pElmRObj->m_Property[j], L"Name") == 0){
  96. //Get the name we're looking for
  97. if ( ::SysStringLen ( pElmRObj->m_Value[j] ) < BUFF_SIZE )
  98. {
  99. wcscpy(wcElmName, pElmRObj->m_Value[j]);
  100. bGotName = true;
  101. }
  102. }
  103. }
  104. pElmRObj->Cleanup();
  105. delete pElmRObj;
  106. pElmRObj = NULL;
  107. }
  108. }
  109. //These will change from class to class
  110. bool bSoftware, bSystem;
  111. CStringExt wcComputer;
  112. Query wcQuery;
  113. wcQuery.Append ( 1, L"select distinct `Component` from Component" );
  114. //optimize for GetObject
  115. if ( bGotID || bGotName )
  116. {
  117. if ( bGotName )
  118. {
  119. wcQuery.Append ( 3, L" where `Component`=\'", wcElmName, L"\'" );
  120. }
  121. if ( bGotID )
  122. {
  123. if ( bGotName )
  124. {
  125. wcQuery.Append ( 3, L" or `ComponentId`=\'", wcComponentID, L"\'" );
  126. }
  127. else
  128. {
  129. wcQuery.Append ( 3, L" where `ComponentId`=\'", wcComponentID, L"\'" );
  130. }
  131. }
  132. }
  133. LPWSTR Buffer = NULL;
  134. LPWSTR dynBuffer = NULL;
  135. DWORD dwDynBuffer = 0L;
  136. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  137. {
  138. // safe operation:
  139. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  140. wcscpy(wcProductCode, m_pRequest->Package(i));
  141. //Open our database
  142. try
  143. {
  144. if ( GetView ( &hView, wcProductCode, wcQuery, L"Component", TRUE, FALSE ) )
  145. {
  146. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  147. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  148. CheckMSI(uiStatus);
  149. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  150. //----------------------------------------------------
  151. dwBufSize = BUFF_SIZE;
  152. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  153. dwBufSize = BUFF_SIZE;
  154. uiStatus = CreateSoftwareElementString ( msidata.GetDatabase(),
  155. Buffer,
  156. wcProductCode,
  157. wcSoftware,
  158. &dwBufSize
  159. );
  160. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  161. {
  162. dynBuffer [ 0 ] = 0;
  163. }
  164. if( uiStatus == ERROR_SUCCESS )
  165. {
  166. PutKeyProperty(m_pObj, pSoftware, wcSoftware, &bSoftware, m_pRequest);
  167. TCHAR cBuf[MAX_COMPUTERNAME_LENGTH + 1];
  168. dwBufSize = MAX_COMPUTERNAME_LENGTH+1;
  169. if(!GetComputerName(cBuf, &dwBufSize)) throw WBEM_E_FAILED;
  170. // safe operation
  171. wcComputer.Copy ( L"Win32_ComputerSystem.Name=\"" );
  172. #ifndef UNICODE
  173. WCHAR wcTmp[MAX_COMPUTERNAME_LENGTH + 1];
  174. mbstowcs(wcTmp, cBuf, MAX_COMPUTERNAME_LENGTH + 1);
  175. wcComputer.Append ( 2, wcTmp, L"\"" );
  176. #else UNICODE
  177. wcComputer.Append ( 2, cBuf, L"\"" );
  178. #endif UNICODE
  179. PutKeyProperty(m_pObj, pSystem, wcComputer, &bSystem, m_pRequest);
  180. if(bSoftware && bSystem) bMatch = true;
  181. if((atAction != ACTIONTYPE_GET) || bMatch){
  182. hr = pHandler->Indicate(1, &m_pObj);
  183. }
  184. }
  185. m_pObj->Release();
  186. m_pObj = NULL;
  187. g_fpMsiCloseHandle(hRecord);
  188. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  189. }
  190. }
  191. }
  192. catch(...)
  193. {
  194. if ( dynBuffer )
  195. {
  196. delete [] dynBuffer;
  197. dynBuffer = NULL;
  198. }
  199. g_fpMsiCloseHandle(hRecord);
  200. g_fpMsiViewClose(hView);
  201. g_fpMsiCloseHandle(hView);
  202. msidata.CloseDatabase ();
  203. if(m_pObj)
  204. {
  205. m_pObj->Release();
  206. m_pObj = NULL;
  207. }
  208. throw;
  209. }
  210. g_fpMsiCloseHandle(hRecord);
  211. g_fpMsiViewClose(hView);
  212. g_fpMsiCloseHandle(hView);
  213. msidata.CloseDatabase ();
  214. }
  215. if ( dynBuffer )
  216. {
  217. delete [] dynBuffer;
  218. dynBuffer = NULL;
  219. }
  220. return hr;
  221. }