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.

291 lines
8.5 KiB

  1. // FileSpecification.cpp: implementation of the CFileSpecification class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "FileSpecification.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CFileSpecification::CFileSpecification(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CFileSpecification::~CFileSpecification()
  18. {
  19. }
  20. HRESULT CFileSpecification::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. MSIHANDLE hView = NULL;
  24. MSIHANDLE hRecord = NULL;
  25. MSIHANDLE hSEView = NULL;
  26. MSIHANDLE hSERecord = NULL;
  27. int i = -1;
  28. WCHAR wcBuf[BUFF_SIZE];
  29. WCHAR wcProductCode[39];
  30. WCHAR wcID[39];
  31. DWORD dwBufSize;
  32. bool bMatch = false;
  33. UINT uiStatus;
  34. bool bGotID = false;
  35. WCHAR wcFile[BUFF_SIZE];
  36. WCHAR wcTestCode[39];
  37. //These will change from class to class
  38. bool bCheck;
  39. INSTALLSTATE piInstalled;
  40. int iState;
  41. SetSinglePropertyPath(L"CheckID");
  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"CheckID" );
  50. if ( bstrCompare )
  51. {
  52. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  53. {
  54. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) < BUFF_SIZE )
  55. {
  56. //Get the action we're looking for
  57. wcscpy(wcBuf, m_pRequest->m_Value[iPos]);
  58. // safe operation if wcslen ( wcBuf ) > 38
  59. if ( wcslen ( wcBuf ) > 38 )
  60. {
  61. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  62. }
  63. else
  64. {
  65. // we are not good to go, they have sent us longer string
  66. SysFreeString ( bstrCompare );
  67. throw hr;
  68. }
  69. // safe because lenght has been tested already in condition
  70. RemoveFinalGUID(m_pRequest->m_Value[iPos], wcFile);
  71. bGotID = true;
  72. }
  73. else
  74. {
  75. // we are not good to go, they have sent us longer string
  76. SysFreeString ( bstrCompare );
  77. throw hr;
  78. }
  79. }
  80. SysFreeString ( bstrCompare );
  81. }
  82. else
  83. {
  84. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  85. }
  86. }
  87. Query wcQuery;
  88. wcQuery.Append ( 1, L"select distinct `File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence` from File" );
  89. //optimize for GetObject
  90. if ( bGotID )
  91. {
  92. wcQuery.Append ( 3, L" where `File`=\'", wcFile, L"\'" );
  93. }
  94. QueryExt wcQuery1 ( L"select distinct `ComponentId` from Component where `Component`=\'" );
  95. LPWSTR Buffer = NULL;
  96. LPWSTR dynBuffer = NULL;
  97. DWORD dwDynBuffer = 0L;
  98. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  99. {
  100. // safe operation:
  101. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  102. wcscpy(wcProductCode, m_pRequest->Package(i));
  103. if((atAction == ACTIONTYPE_ENUM) || (bGotID && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  104. //Open our database
  105. try
  106. {
  107. if ( GetView ( &hView, wcProductCode, wcQuery, L"File", FALSE, FALSE ) )
  108. {
  109. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  110. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  111. CheckMSI(uiStatus);
  112. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  113. //----------------------------------------------------
  114. dwBufSize = BUFF_SIZE;
  115. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  116. PutKeyProperty ( m_pObj, pCheckID, Buffer, &bCheck, m_pRequest, 1, wcProductCode );
  117. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  118. {
  119. dynBuffer [ 0 ] = 0;
  120. }
  121. //====================================================
  122. dwBufSize = BUFF_SIZE;
  123. PutPropertySpecial ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, FALSE, 2, pCaption, pDescription );
  124. PutProperty(m_pObj, pFileSize, g_fpMsiRecordGetInteger(hRecord, 4));
  125. dwBufSize = BUFF_SIZE;
  126. PutPropertySpecial ( hRecord, 5, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pVersion );
  127. dwBufSize = BUFF_SIZE;
  128. PutPropertySpecial ( hRecord, 6, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pLanguage );
  129. PutProperty(m_pObj, pAttributes, g_fpMsiRecordGetInteger(hRecord, 7));
  130. PutProperty(m_pObj, pSequence, g_fpMsiRecordGetInteger(hRecord, 8));
  131. dwBufSize = BUFF_SIZE;
  132. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  133. PutProperty(m_pObj, pName, Buffer);
  134. // make query on fly
  135. wcQuery1.Append ( 2, Buffer, L"\'" );
  136. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  137. {
  138. dynBuffer [ 0 ] = 0;
  139. }
  140. if(ERROR_SUCCESS == g_fpMsiDatabaseOpenViewW( msidata.GetDatabase (), wcQuery1, &hSEView)){
  141. if(ERROR_SUCCESS == g_fpMsiViewExecute(hSEView, 0)){
  142. try{
  143. if ( ERROR_SUCCESS == g_fpMsiViewFetch(hSEView, &hSERecord)){
  144. dwBufSize = BUFF_SIZE;
  145. GetBufferToPut ( hSERecord, 1, dwBufSize, wcID, dwDynBuffer, dynBuffer, Buffer );
  146. if ( ValidateComponentID ( Buffer, wcProductCode ) )
  147. {
  148. PutProperty(m_pObj, pSoftwareElementID, Buffer);
  149. dwBufSize = BUFF_SIZE;
  150. wcscpy(wcBuf, L"");
  151. piInstalled = g_fpMsiGetComponentPathW(wcProductCode, Buffer, wcBuf, &dwBufSize);
  152. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  153. {
  154. dynBuffer [ 0 ] = 0;
  155. }
  156. SoftwareElementState(piInstalled, &iState);
  157. PutProperty(m_pObj, pSoftwareElementState, iState);
  158. PutProperty(m_pObj, pTargetOperatingSystem, GetOS());
  159. dwBufSize = BUFF_SIZE;
  160. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct (), L"ProductVersion", wcBuf,
  161. &dwBufSize));
  162. PutProperty(m_pObj, pVersion, wcBuf);
  163. //----------------------------------------------------
  164. if(bCheck) bMatch = true;
  165. if((atAction != ACTIONTYPE_GET) || bMatch){
  166. hr = pHandler->Indicate(1, &m_pObj);
  167. }
  168. }
  169. }
  170. }catch(...){
  171. g_fpMsiViewClose(hSEView);
  172. g_fpMsiCloseHandle(hSEView);
  173. g_fpMsiCloseHandle(hSERecord);
  174. throw;
  175. }
  176. g_fpMsiViewClose(hSEView);
  177. g_fpMsiCloseHandle(hSEView);
  178. g_fpMsiCloseHandle(hSERecord);
  179. }
  180. }
  181. m_pObj->Release();
  182. m_pObj = NULL;
  183. g_fpMsiCloseHandle(hRecord);
  184. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  185. }
  186. }
  187. }
  188. catch(...)
  189. {
  190. if ( dynBuffer )
  191. {
  192. delete [] dynBuffer;
  193. dynBuffer = NULL;
  194. }
  195. g_fpMsiCloseHandle(hRecord);
  196. g_fpMsiViewClose(hView);
  197. g_fpMsiCloseHandle(hView);
  198. msidata.CloseDatabase ();
  199. msidata.CloseProduct ();
  200. if(m_pObj)
  201. {
  202. m_pObj->Release();
  203. m_pObj = NULL;
  204. }
  205. throw;
  206. }
  207. g_fpMsiCloseHandle(hRecord);
  208. g_fpMsiViewClose(hView);
  209. g_fpMsiCloseHandle(hView);
  210. msidata.CloseDatabase ();
  211. msidata.CloseProduct ();
  212. }
  213. }
  214. if ( dynBuffer )
  215. {
  216. delete [] dynBuffer;
  217. dynBuffer = NULL;
  218. }
  219. return hr;
  220. }