Source code of Windows XP (NT5)
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.

377 lines
9.7 KiB

  1. //***************************************************************************
  2. //
  3. // VPPUT.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the PutInstance implementation
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <provcoll.h>
  15. #include <provtempl.h>
  16. #include <provmt.h>
  17. #include <typeinfo.h>
  18. #include <process.h>
  19. #include <objbase.h>
  20. #include <stdio.h>
  21. #include <wbemidl.h>
  22. #include <provcont.h>
  23. #include <provevt.h>
  24. #include <provthrd.h>
  25. #include <provlog.h>
  26. #include <cominit.h>
  27. #include <dsgetdc.h>
  28. #include <lmcons.h>
  29. #include <instpath.h>
  30. #include <genlex.h>
  31. #include <sql_1.h>
  32. #include <objpath.h>
  33. #include <vpdefs.h>
  34. #include <vpquals.h>
  35. #include <vpserv.h>
  36. #include <vptasks.h>
  37. extern BOOL CompareSimplePropertyValues(VARIANT* v1, VARIANT* v2, CIMTYPE ct);
  38. PutInstanceTaskObject::PutInstanceTaskObject (CViewProvServ *a_Provider , IWbemClassObject *a_Inst ,
  39. ULONG a_Flag , IWbemObjectSink *a_NotificationHandler,
  40. IWbemContext *pCtx)
  41. :WbemTaskObject (a_Provider, a_NotificationHandler, a_Flag, pCtx)
  42. {
  43. m_InstObject = a_Inst;
  44. if (m_InstObject != NULL)
  45. {
  46. m_InstObject->AddRef();
  47. if (WBEM_FLAG_CREATE_ONLY == (a_Flag & WBEM_FLAG_CREATE_ONLY))
  48. {
  49. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_PARAMETER );
  50. m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER );
  51. m_ErrorObject.SetMessage ( L"The provider does not support instance creation via PutInstanceAsync." );
  52. }
  53. }
  54. else
  55. {
  56. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_PARAMETER ) ;
  57. m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ;
  58. m_ErrorObject.SetMessage ( L"A non-null instance must be supplied as an argument" ) ;
  59. }
  60. }
  61. PutInstanceTaskObject::~PutInstanceTaskObject ()
  62. {
  63. BOOL t_Status = TRUE;
  64. IWbemClassObject *t_NotifyStatus = NULL ;
  65. if (WBEM_NO_ERROR != m_ErrorObject.GetWbemStatus ())
  66. {
  67. t_Status = GetExtendedNotifyStatusObject ( &t_NotifyStatus ) ;
  68. }
  69. if ( t_Status )
  70. {
  71. m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , t_NotifyStatus ) ;
  72. if (t_NotifyStatus)
  73. {
  74. t_NotifyStatus->Release () ;
  75. }
  76. }
  77. else
  78. {
  79. m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , NULL ) ;
  80. }
  81. if (m_InstObject != NULL)
  82. {
  83. m_InstObject->Release();
  84. }
  85. }
  86. BOOL PutInstanceTaskObject::PutInstance()
  87. {
  88. DebugOut4(
  89. CViewProvServ::sm_debugLog->WriteFileAndLine (
  90. _T(__FILE__),__LINE__,
  91. _T("PutInstanceTaskObject :: PutInstance\r\n)")
  92. ) ;
  93. )
  94. if (FAILED(m_ErrorObject.GetWbemStatus()))
  95. {
  96. return FALSE;
  97. }
  98. VARIANT v;
  99. VariantInit (&v);
  100. BOOL t_Status = SUCCEEDED(m_InstObject->Get(WBEM_PROPERTY_CLASS, 0, &v, NULL, NULL));
  101. if (( t_Status ) && (VT_BSTR == v.vt))
  102. {
  103. t_Status = SetClass(v.bstrVal) ;
  104. if (t_Status)
  105. {
  106. t_Status = ParseAndProcessClassQualifiers(m_ErrorObject);
  107. if (t_Status)
  108. {
  109. //only unions
  110. if (!m_bAssoc && !m_JoinOnArray.IsValid())
  111. {
  112. t_Status = PerformPut(m_ErrorObject);
  113. }
  114. else
  115. {
  116. m_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_SUPPORTED ) ;
  117. m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  118. m_ErrorObject.SetMessage ( L"Operation only supported for Union views" ) ;
  119. }
  120. }
  121. }
  122. else
  123. {
  124. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  125. m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  126. m_ErrorObject.SetMessage ( L"Class definition not found" ) ;
  127. DebugOut4(
  128. CViewProvServ::sm_debugLog->WriteFileAndLine (
  129. _T(__FILE__),__LINE__,
  130. _T("PutInstanceTaskObject :: PutInstance:Dynamic NT Eventlog Provider does not support WRITE for this class\r\n")
  131. ) ;
  132. )
  133. }
  134. }
  135. else
  136. {
  137. t_Status = FALSE ;
  138. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  139. m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_OBJECT ) ;
  140. m_ErrorObject.SetMessage ( L"Unable to obtain class name from object." ) ;
  141. DebugOut4(
  142. CViewProvServ::sm_debugLog->WriteFileAndLine (
  143. _T(__FILE__),__LINE__,
  144. _T("PutInstanceTaskObject :: PutInstance:Unable to obtain class name from object.\r\n")
  145. ) ;
  146. )
  147. }
  148. VariantClear(&v);
  149. DebugOut4(
  150. CViewProvServ::sm_debugLog->WriteFileAndLine (
  151. _T(__FILE__),__LINE__,
  152. _T("PutInstanceTaskObject :: PutInstance:returning %lx\r\n"),
  153. t_Status
  154. ) ;
  155. )
  156. return t_Status ;
  157. }
  158. BOOL PutInstanceTaskObject::PerformPut(WbemProvErrorObject &a_ErrorObject)
  159. {
  160. BOOL retVal = FALSE;
  161. VARIANT v;
  162. //Two step process, first get the instance being changed...
  163. if ( SUCCEEDED(m_InstObject->Get(WBEM_PROPERTY_RELPATH, 0, &v, NULL, NULL)) )
  164. {
  165. if (v.vt == VT_BSTR)
  166. {
  167. IWbemClassObject* pSrcInst;
  168. BSTR refStr = MapFromView(v.bstrVal, NULL, &pSrcInst, TRUE);
  169. if (refStr != NULL)
  170. {
  171. //Second step...
  172. //map any property changes to the new instance and call PutInstance
  173. VARIANT vCls;
  174. if ( SUCCEEDED(pSrcInst->Get(WBEM_PROPERTY_CLASS, 0, &vCls, NULL, NULL)) )
  175. {
  176. if (vCls.vt == VT_BSTR)
  177. {
  178. int index;
  179. if (m_ClassToIndexMap.Lookup(vCls.bstrVal, index))
  180. {
  181. POSITION propPos = m_PropertyMap.GetStartPosition();
  182. retVal = TRUE;
  183. while ((propPos != NULL) && retVal)
  184. {
  185. VARIANT vProp;
  186. CIMTYPE ct;
  187. CStringW propName;
  188. CPropertyQualifierItem* propProps;
  189. m_PropertyMap.GetNextAssoc(propPos, propName, propProps);
  190. if (!propProps->m_SrcPropertyNames[index].IsEmpty())
  191. {
  192. if ( SUCCEEDED(m_InstObject->Get(propName, 0, &vProp, &ct, NULL)) )
  193. {
  194. VARIANT vSProp;
  195. if ( SUCCEEDED (pSrcInst->Get(propProps->m_SrcPropertyNames[index], 0, &vSProp, &ct, NULL)) )
  196. {
  197. if (!CompareSimplePropertyValues(&vProp, &vSProp, ct))
  198. {
  199. if ( FAILED(pSrcInst->Put(propProps->m_SrcPropertyNames[index], 0, &vProp, ct)) )
  200. {
  201. retVal = FALSE;
  202. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  203. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  204. a_ErrorObject.SetMessage ( L"Failed to Put property in source instance" ) ;
  205. }
  206. }
  207. VariantClear(&vSProp);
  208. }
  209. else
  210. {
  211. retVal = FALSE;
  212. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  213. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  214. a_ErrorObject.SetMessage ( L"Failed to Get property from source instance" ) ;
  215. }
  216. VariantClear(&vProp);
  217. }
  218. else
  219. {
  220. retVal = FALSE;
  221. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  222. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  223. a_ErrorObject.SetMessage ( L"Failed to get property from view instance" ) ;
  224. }
  225. }
  226. }
  227. if (retVal)
  228. {
  229. //which namespace do we put into, try them all until we succeed
  230. CWbemServerWrap** pServs = m_NSpaceArray[index]->GetServerPtrs();
  231. HRESULT hr = WBEM_E_FAILED;
  232. for (UINT i = 0; i < m_NSpaceArray[index]->GetCount(); i++)
  233. {
  234. if (pServs[i] != NULL)
  235. {
  236. IWbemServices *ptmpServ = pServs[i]->GetServerOrProxy();
  237. if (ptmpServ)
  238. {
  239. hr = ptmpServ->PutInstance(pSrcInst, WBEM_FLAG_UPDATE_ONLY, m_Ctx, NULL);
  240. if ( FAILED(hr) && (HRESULT_FACILITY(hr) != FACILITY_ITF) && pServs[i]->IsRemote())
  241. {
  242. if ( SUCCEEDED(UpdateConnection(&(pServs[i]), &ptmpServ)) )
  243. {
  244. if (ptmpServ)
  245. {
  246. hr = ptmpServ->PutInstance(pSrcInst, WBEM_FLAG_UPDATE_ONLY, m_Ctx, NULL);
  247. }
  248. }
  249. }
  250. if (ptmpServ)
  251. {
  252. pServs[i]->ReturnServerOrProxy(ptmpServ);
  253. }
  254. if (SUCCEEDED (hr) )
  255. {
  256. break;
  257. }
  258. }
  259. }
  260. }
  261. if ( FAILED (hr) )
  262. {
  263. retVal = FALSE;
  264. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  265. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  266. #ifdef VP_SINGLE_NAMESPACE_TRIED
  267. wchar_t buff[100];
  268. wsprintf(buff, L"PutInstance on source object failed with code: %lx", hr);
  269. a_ErrorObject.SetMessage ( buff ) ;
  270. #else //VP_SINGLE_NAMESPACE_TRIED
  271. a_ErrorObject.SetMessage ( L"PutInstance on source object failed" ) ;
  272. #endif //VP_SINGLE_NAMESPACE_TRIED
  273. }
  274. }
  275. }
  276. else
  277. {
  278. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  279. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  280. a_ErrorObject.SetMessage ( L"Source instance class not found in source list" ) ;
  281. }
  282. }
  283. else
  284. {
  285. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  286. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  287. a_ErrorObject.SetMessage ( L"Source instance has non string __Class property" ) ;
  288. }
  289. VariantClear(&vCls);
  290. }
  291. else
  292. {
  293. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  294. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  295. a_ErrorObject.SetMessage ( L"Source instance has no __Class property" ) ;
  296. }
  297. pSrcInst->Release();
  298. SysFreeString(refStr);
  299. }
  300. else
  301. {
  302. a_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_FOUND ) ;
  303. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  304. a_ErrorObject.SetMessage ( L"Instance supplied could not be mapped to a single source instance" ) ;
  305. }
  306. }
  307. else
  308. {
  309. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  310. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ;
  311. a_ErrorObject.SetMessage ( L"Instance supplied has non string __RelPath property" ) ;
  312. }
  313. VariantClear(&v);
  314. }
  315. else
  316. {
  317. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ;
  318. a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ;
  319. a_ErrorObject.SetMessage ( L"Instance supplied has no __RelPath property" ) ;
  320. }
  321. return retVal;
  322. }