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.

299 lines
9.1 KiB

  1. // WriteRegistry.cpp: implementation of the CWriteRegistry class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "WriteRegistry.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CRegistryAction::CRegistryAction(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CRegistryAction::~CRegistryAction()
  18. {
  19. }
  20. HRESULT CRegistryAction::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 * 4];
  29. WCHAR wcProductCode[39];
  30. WCHAR wcID[39];
  31. DWORD dwBufSize;
  32. bool bMatch = false;
  33. UINT uiStatus;
  34. bool bGotID = false;
  35. WCHAR wcAction[BUFF_SIZE];
  36. WCHAR wcTestCode[39];
  37. //These will change from class to class
  38. bool bActionID;
  39. INSTALLSTATE piInstalled;
  40. int iState;
  41. SetSinglePropertyPath(L"ActionID");
  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"ActionID" );
  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], wcAction);
  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 `Registry`, `Component_`, `Root`, `Key`, `Name`, `Value` from Registry" );
  89. //optimize for GetObject
  90. if ( bGotID )
  91. {
  92. wcQuery.Append ( 3, L" where `Registry`=\'", wcAction, 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"Registry", 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 * 4;
  115. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  116. PutProperty(m_pObj, pRegistry, Buffer);
  117. PutProperty(m_pObj, pDescription, Buffer);
  118. PutProperty(m_pObj, pCaption, Buffer);
  119. PutKeyProperty ( m_pObj, pActionID, Buffer, &bActionID, m_pRequest, 1, wcProductCode );
  120. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  121. {
  122. dynBuffer [ 0 ] = 0;
  123. }
  124. //====================================================
  125. PutProperty(m_pObj, pRoot, g_fpMsiRecordGetInteger(hRecord, 3));
  126. dwBufSize = BUFF_SIZE * 4;
  127. PutPropertySpecial ( hRecord, 4, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pKey );
  128. dwBufSize = BUFF_SIZE * 4;
  129. PutPropertySpecial ( hRecord, 5, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pEntryName );
  130. dwBufSize = BUFF_SIZE * 4;
  131. PutPropertySpecial ( hRecord, 6, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pEntryValue );
  132. dwBufSize = BUFF_SIZE * 4;
  133. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  134. PutProperty(m_pObj, pName, Buffer);
  135. // make query on fly
  136. wcQuery1.Append ( 2, Buffer, L"\'" );
  137. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  138. {
  139. dynBuffer [ 0 ] = 0;
  140. }
  141. if(ERROR_SUCCESS == g_fpMsiDatabaseOpenViewW( msidata.GetDatabase (), wcQuery1, &hSEView ))
  142. {
  143. if(ERROR_SUCCESS == g_fpMsiViewExecute(hSEView, 0)){
  144. try{
  145. uiStatus = g_fpMsiViewFetch(hSEView, &hSERecord);
  146. dwBufSize = BUFF_SIZE * 4;
  147. GetBufferToPut ( hSERecord, 1, dwBufSize, wcID, dwDynBuffer, dynBuffer, Buffer );
  148. if ( ValidateComponentID ( Buffer, wcProductCode ) )
  149. {
  150. PutProperty(m_pObj, pSoftwareElementID, Buffer);
  151. dwBufSize = BUFF_SIZE * 4;
  152. wcBuf [ 0 ] = 0;
  153. piInstalled = g_fpMsiGetComponentPathW(wcProductCode, Buffer, wcBuf, &dwBufSize);
  154. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  155. {
  156. dynBuffer [ 0 ] = 0;
  157. }
  158. SoftwareElementState(piInstalled, &iState);
  159. PutProperty(m_pObj, pSoftwareElementState, iState);
  160. PutProperty(m_pObj, pTargetOperatingSystem, GetOS());
  161. dwBufSize = BUFF_SIZE * 4;
  162. CheckMSI(g_fpMsiGetProductPropertyW(msidata.GetProduct (), L"ProductVersion", wcBuf, &dwBufSize));
  163. PutProperty(m_pObj, pVersion, wcBuf);
  164. //----------------------------------------------------
  165. if(bActionID) bMatch = true;
  166. if((atAction != ACTIONTYPE_GET) || bMatch){
  167. hr = pHandler->Indicate(1, &m_pObj);
  168. }
  169. }
  170. else
  171. {
  172. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  173. {
  174. dynBuffer [ 0 ] = 0;
  175. }
  176. }
  177. }catch(...){
  178. g_fpMsiViewClose(hSEView);
  179. g_fpMsiCloseHandle(hSEView);
  180. g_fpMsiCloseHandle(hSERecord);
  181. throw;
  182. }
  183. g_fpMsiViewClose(hSEView);
  184. g_fpMsiCloseHandle(hSEView);
  185. g_fpMsiCloseHandle(hSERecord);
  186. }
  187. }
  188. m_pObj->Release();
  189. m_pObj = NULL;
  190. g_fpMsiCloseHandle(hRecord);
  191. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  192. }
  193. }
  194. }
  195. catch(...)
  196. {
  197. if ( dynBuffer )
  198. {
  199. delete [] dynBuffer;
  200. dynBuffer = NULL;
  201. }
  202. g_fpMsiCloseHandle(hRecord);
  203. g_fpMsiViewClose(hView);
  204. g_fpMsiCloseHandle(hView);
  205. msidata.CloseDatabase ();
  206. msidata.CloseProduct ();
  207. if(m_pObj)
  208. {
  209. m_pObj->Release();
  210. m_pObj = NULL;
  211. }
  212. throw;
  213. }
  214. g_fpMsiCloseHandle(hRecord);
  215. g_fpMsiViewClose(hView);
  216. g_fpMsiCloseHandle(hView);
  217. msidata.CloseDatabase ();
  218. msidata.CloseProduct ();
  219. }
  220. }
  221. if ( dynBuffer )
  222. {
  223. delete [] dynBuffer;
  224. dynBuffer = NULL;
  225. }
  226. return hr;
  227. }