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.

2711 lines
68 KiB

  1. // RequestObject.cpp: implementation of the CRequestObject class.
  2. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. //////////////////////////////////////////////////////////////////////
  5. #include "precomp.h"
  6. #include "requestobject.h"
  7. #include <stdio.h>
  8. #include <CRegCls.h>
  9. #include <wininet.h>
  10. //Classes
  11. #include "ApplicationService.h"
  12. #include "Binary.h"
  13. #include "BindImage.h"
  14. #include "ClassInfoAction.h"
  15. #include "CommandLineAccess.h"
  16. #include "Condition.h"
  17. #include "CreateFolder.h"
  18. #include "DirectorySpecification.h"
  19. #include "DuplicateFile.h"
  20. #include "Environment.h"
  21. #include "ExtensionInfoAction.h"
  22. #include "FileSpecification.h"
  23. #include "FontInfoAction.h"
  24. #include "IniFile.h"
  25. #include "LaunchCondition.h"
  26. #include "MIMEInfoAction.h"
  27. #include "MoveFile.h"
  28. #include "ODBCAttribute.h"
  29. #include "ODBCDataSource.h"
  30. #include "ODBCDriver.h"
  31. #include "ODBCSourceAttribute.h"
  32. #include "ODBCTranslator.h"
  33. #include "Patch.h"
  34. #include "PatchPackAge.h"
  35. #include "ProgIDSpecification.h"
  36. #include "Product.h"
  37. #include "Property.h"
  38. #include "PublishComponent.h"
  39. #include "RemoveFile.h"
  40. #include "RemoveIniValue.h"
  41. #include "ReserveCost.h"
  42. #include "SelfRegModule.h"
  43. #include "ServiceControl.h"
  44. #include "ServiceSpecification.h"
  45. #include "ShortcutAction.h"
  46. #include "SoftwareElement.h"
  47. #include "SoftwareElementCondition.h"
  48. #include "SoftwareFeature.h"
  49. #include "TypeLibraryAction.h"
  50. //#include "Upgrade.h"
  51. #include "WriteRegistry.h"
  52. //Associations
  53. #include "ActionCheck.h"
  54. #include "ApplicationCommandLine.h"
  55. #include "CheckCheck.h"
  56. #include "InstalledSoftwareElement.h"
  57. #include "ODBCDataSourceAttribute.h"
  58. #include "ODBCDriverAttribute.h"
  59. #include "ODBCDriverSoftwareElement.h"
  60. #include "PatchFile.h"
  61. #include "ProductResource1.h"
  62. #include "ProductEnvironment.h"
  63. #include "ProductSoftwareFeatures.h"
  64. #include "ServiceSpecificationService.h"
  65. #include "ShortcutSAP.h"
  66. #include "SoftwareElementAction.h"
  67. #include "SoftwareElementCheck.h"
  68. #include "SoftwareElementServiceControl.h"
  69. #include "SoftwareFeatureAction.h"
  70. #include "SoftwareFeatureCondition.h"
  71. #include "SoftwareFeatureParent.h"
  72. #include "SoftwareFeatureSoftwareElements.h"
  73. CRITICAL_SECTION CRequestObject::m_cs;
  74. CHeap_Exception CRequestObject::m_he(CHeap_Exception::E_ALLOCATION_ERROR);
  75. //////////////////////////////////////////////////////////////////////
  76. // event handler for methods
  77. //////////////////////////////////////////////////////////////////////
  78. int WINAPI MyEventHandler ( LPVOID pvContext, UINT iMessageType, LPCWSTR szMessage )
  79. {
  80. // request object
  81. CRequestObject* pObj = NULL;
  82. pObj = reinterpret_cast < CRequestObject* > ( pvContext );
  83. BSTR bstrMsg = NULL;
  84. try
  85. {
  86. if ( pObj && pObj->m_iThreadID != THREAD_NO_PROGRESS )
  87. {
  88. ProListNode *pNode = NULL;
  89. if ( ( pNode = pObj->GetNode ( pObj->m_iThreadID ) ) != NULL )
  90. {
  91. if ( pNode->pSink != NULL)
  92. {
  93. //Get the values we need from the MessageType
  94. UINT uiMsg = iMessageType & 0x0F000000L;
  95. if(szMessage)
  96. {
  97. bstrMsg = SysAllocString(szMessage);
  98. }
  99. else
  100. {
  101. bstrMsg = SysAllocString(L"");
  102. }
  103. HRESULT hr = WBEM_S_NO_ERROR;
  104. HRESULT hrProgress = WBEM_STATUS_PROGRESS;
  105. bool bSuccess = true;
  106. switch(uiMsg)
  107. {
  108. case INSTALLMESSAGE_FATALEXIT:
  109. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  110. break;
  111. case INSTALLMESSAGE_ERROR:
  112. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  113. break;
  114. case INSTALLMESSAGE_WARNING:
  115. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  116. break;
  117. case INSTALLMESSAGE_USER:
  118. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  119. break;
  120. case INSTALLMESSAGE_INFO:
  121. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  122. break;
  123. case INSTALLMESSAGE_FILESINUSE:
  124. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  125. break;
  126. case INSTALLMESSAGE_RESOLVESOURCE:
  127. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  128. break;
  129. case INSTALLMESSAGE_OUTOFDISKSPACE:
  130. if(!pObj->CreateProgress(NULL, &hr, pObj->m_iThreadID)) bSuccess = false;
  131. break;
  132. case INSTALLMESSAGE_ACTIONSTART:
  133. if(!pObj->ActionStartProgress(&hr, pObj->m_iThreadID)) bSuccess = false;
  134. break;
  135. case INSTALLMESSAGE_ACTIONDATA:
  136. if(!pObj->ActionDataProgress(&hr, pObj->m_iThreadID)) bSuccess = false;
  137. break;
  138. case INSTALLMESSAGE_PROGRESS:
  139. ProgressStruct ps;
  140. if(pObj->ParseProgress(bstrMsg, &ps))
  141. {
  142. if(!pObj->CreateProgress(&ps, &hr, pObj->m_iThreadID)) bSuccess = false;
  143. }
  144. break;
  145. case INSTALLMESSAGE_INITIALIZE:
  146. break;
  147. case INSTALLMESSAGE_TERMINATE:
  148. break;
  149. default:
  150. bSuccess = false;
  151. break;
  152. }
  153. //Send the message
  154. if(bSuccess)
  155. {
  156. pNode->pSink->SetStatus(hrProgress, hr, bstrMsg, NULL);
  157. }
  158. }
  159. }
  160. }
  161. }
  162. catch(...)
  163. {
  164. }
  165. if ( bstrMsg )
  166. {
  167. ::SysFreeString(bstrMsg);
  168. }
  169. return 0;
  170. }
  171. //////////////////////////////////////////////////////////////////////
  172. // Construction/Destruction
  173. //////////////////////////////////////////////////////////////////////
  174. CRequestObject::CRequestObject()
  175. {
  176. m_cRef = 0;
  177. m_bstrPath = NULL;
  178. m_bstrClass = NULL;
  179. m_pPackageHead = NULL;
  180. m_hKey = NULL;
  181. }
  182. CRequestObject::~CRequestObject()
  183. {
  184. }
  185. //***************************************************************************
  186. //
  187. // CRequestObject::QueryInterface
  188. // CRequestObject::AddRef
  189. // CRequestObject::Release
  190. //
  191. // Purpose: IUnknown members for CRequestObject object.
  192. //***************************************************************************
  193. /*
  194. STDMETHODIMP CRequestObject::QueryInterface(REFIID riid, PPVOID ppv)
  195. {
  196. *ppv = NULL;
  197. if(riid == IID_IMsiMethodStatusSink)
  198. *ppv = (IMsiMethodStatusSink *)this;
  199. if(riid == IID_IUnknown)
  200. *ppv = (IMsiMethodStatusSink *)this;
  201. if(NULL != *ppv){
  202. AddRef();
  203. return NOERROR;
  204. }else return E_NOINTERFACE;
  205. }
  206. STDMETHODIMP_(ULONG) CRequestObject::AddRef(void)
  207. {
  208. InterlockedIncrement((long *)&m_cRef);
  209. return m_cRef;
  210. }
  211. STDMETHODIMP_(ULONG) CRequestObject::Release(void)
  212. {
  213. ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
  214. // if(0L == nNewCount) delete this;
  215. return nNewCount;
  216. }
  217. */
  218. void CRequestObject::Initialize(IWbemServices *pNamespace)
  219. {
  220. m_pNamespace = pNamespace;
  221. m_pHandler = NULL;
  222. m_bstrClass = NULL;
  223. m_bstrPath = NULL;
  224. m_iPropCount = m_iValCount = 0;
  225. m_iThreadID = THREAD_NO_PROGRESS;
  226. m_pHead = NULL;
  227. m_dwCheckKeyPresentStatus = ERROR_SUCCESS;
  228. for(int i = 0; i < MSI_KEY_LIST_SIZE; i++) m_Property[i] = m_Value[i] = NULL;
  229. HANDLE hTokenImpersonationHandle;
  230. DWORD dwStatus;
  231. if(OpenThreadToken(GetCurrentThread(), (TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY),
  232. TRUE ,& hTokenImpersonationHandle)){
  233. dwStatus = GetAccount(hTokenImpersonationHandle, m_wcDomain, m_wcUser );
  234. if(dwStatus == 0)
  235. {
  236. if ( wcslen ( m_wcDomain ) + wcslen ( m_wcUser ) + 1 + 1 < BUFF_SIZE )
  237. {
  238. wcscpy(m_wcAccount, m_wcDomain);
  239. wcscat(m_wcAccount, L"\\");
  240. wcscat(m_wcAccount, m_wcUser);
  241. WCHAR wcSID[BUFF_SIZE];
  242. if((dwStatus = GetSid(hTokenImpersonationHandle, wcSID)) == S_OK ){
  243. CRegistry *pReg = new CRegistry();
  244. if(!pReg) throw m_he;
  245. //check if SID already present under HKEY_USER ...
  246. m_dwCheckKeyPresentStatus = pReg->Open(HKEY_USERS, wcSID, KEY_READ) ;
  247. if(m_dwCheckKeyPresentStatus == ERROR_NOT_ENOUGH_MEMORY)
  248. throw m_he;
  249. pReg->Close();
  250. delete pReg;
  251. }
  252. }
  253. }
  254. CloseHandle(hTokenImpersonationHandle);
  255. }
  256. }
  257. void CRequestObject::FinalRelease()
  258. {
  259. }
  260. HRESULT CRequestObject::CreateObject(BSTR bstrPath, IWbemObjectSink *pHandler, IWbemContext *pCtx)
  261. {
  262. HRESULT hr = WBEM_S_NO_ERROR;
  263. CGenericClass *pClass = NULL;
  264. m_bstrPath = SysAllocString(bstrPath);
  265. if(!m_bstrPath)
  266. throw m_he;
  267. if(ParsePath(bstrPath)){
  268. try{
  269. //create the appropriate class
  270. if(SUCCEEDED(hr = CreateClass(&pClass, pCtx))){
  271. if(!pClass)
  272. throw m_he;
  273. //get the requested object
  274. hr = pClass->CreateObject(pHandler, ACTIONTYPE_GET);
  275. }
  276. }catch(...){
  277. if(pClass){
  278. pClass->CleanUp();
  279. delete pClass;
  280. }
  281. throw;
  282. }
  283. if(pClass){
  284. pClass->CleanUp();
  285. delete pClass;
  286. }
  287. }else hr = WBEM_E_FAILED;
  288. return hr;
  289. }
  290. HRESULT CRequestObject::CreateClass(CGenericClass **pClass, IWbemContext *pCtx)
  291. {
  292. HRESULT hr = WBEM_S_NO_ERROR;
  293. //Create the appropriate class
  294. /////////////
  295. // Classes //
  296. /////////////
  297. if(0 == _wcsicmp(m_bstrClass, L"WIN32_APPLICATIONSERVICE")){
  298. *pClass = new CApplicationService(this, m_pNamespace, pCtx);
  299. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_BINARY")){
  300. *pClass = new CBinary(this, m_pNamespace, pCtx);
  301. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_BINDIMAGEACTION")){
  302. *pClass = new CBindImage(this, m_pNamespace, pCtx);
  303. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_CLASSINFOACTION")){
  304. *pClass = new CClassInfoAction(this, m_pNamespace, pCtx);
  305. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_COMMANDLINEACCESS")){
  306. *pClass = new CCommandLineAccess(this, m_pNamespace, pCtx);
  307. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_CONDITION")){
  308. *pClass = new CCondition(this, m_pNamespace, pCtx);
  309. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_CREATEFOLDERACTION")){
  310. *pClass = new CCreateFolder(this, m_pNamespace, pCtx);
  311. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_DIRECTORYSPECIFICATION")){
  312. *pClass = new CDirectorySpecification(this, m_pNamespace, pCtx);
  313. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_DUPLICATEFILEACTION")){
  314. *pClass = new CDuplicateFile(this, m_pNamespace, pCtx);
  315. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ENVIRONMENTSPECIFICATION")){
  316. *pClass = new CEnvironment(this, m_pNamespace, pCtx);
  317. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_EXTENSIONINFOACTION")){
  318. *pClass = new CExtensionInfoAction(this, m_pNamespace, pCtx);
  319. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_FILESPECIFICATION")){
  320. *pClass = new CFileSpecification(this, m_pNamespace, pCtx);
  321. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_FONTINFOACTION")){
  322. *pClass = new CFontInfoAction(this, m_pNamespace, pCtx);
  323. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_INIFILESPECIFICATION")){
  324. *pClass = new CIniFile(this, m_pNamespace, pCtx);
  325. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_LAUNCHCONDITION")){
  326. *pClass = new CLaunchCondition(this, m_pNamespace, pCtx);
  327. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_MIMEINFOACTION")){
  328. *pClass = new CMIMEInfoAction(this, m_pNamespace, pCtx);
  329. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_MOVEFILEACTION")){
  330. *pClass = new CMoveFile(this, m_pNamespace, pCtx);
  331. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCATTRIBUTE")){
  332. *pClass = new CODBCAttribute(this, m_pNamespace, pCtx);
  333. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCDATASOURCESPECIFICATION")){
  334. *pClass = new CODBCDataSource(this, m_pNamespace, pCtx);
  335. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCDRIVERSPECIFICATION")){
  336. *pClass = new CODBCDriver(this, m_pNamespace, pCtx);
  337. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCSOURCEATTRIBUTE")){
  338. *pClass = new CODBCSourceAttribute(this, m_pNamespace, pCtx);
  339. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCTRANSLATORSPECIFICATION")){
  340. *pClass = new CODBCTranslator(this, m_pNamespace, pCtx);
  341. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PATCH")){
  342. *pClass = new CPatch(this, m_pNamespace, pCtx);
  343. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PATCHPACKAGE")){
  344. *pClass = new CPatchPackAge(this, m_pNamespace, pCtx);
  345. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PROGIDSPECIFICATION")){
  346. *pClass = new CProgIDSpecification(this, m_pNamespace, pCtx);
  347. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PRODUCT")){
  348. *pClass = new CProduct(this, m_pNamespace, pCtx);
  349. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PROPERTY")){
  350. *pClass = new CProperty(this, m_pNamespace, pCtx);
  351. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PUBLISHCOMPONENTACTION")){
  352. *pClass = new CPublishComponent(this, m_pNamespace, pCtx);
  353. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_REMOVEFILEACTION")){
  354. *pClass = new CRemoveFile(this, m_pNamespace, pCtx);
  355. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_REMOVEINIACTION")){
  356. *pClass = new CRemoveIniValue(this, m_pNamespace, pCtx);
  357. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_RESERVECOST")){
  358. *pClass = new CReserveCost(this, m_pNamespace, pCtx);
  359. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SELFREGMODULEACTION")){
  360. *pClass = new CSelfRegModule(this, m_pNamespace, pCtx);
  361. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SERVICECONTROL")){
  362. *pClass = new CServiceControl(this, m_pNamespace, pCtx);
  363. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SERVICESPECIFICATION")){
  364. *pClass = new CServiceSpecification(this, m_pNamespace, pCtx);
  365. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SHORTCUTACTION")){
  366. *pClass = new CShortcutAction(this, m_pNamespace, pCtx);
  367. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREELEMENT")){
  368. *pClass = new CSoftwareElement(this, m_pNamespace, pCtx);
  369. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREELEMENTCONDITION")){
  370. *pClass = new CSoftwareElementCondition(this, m_pNamespace, pCtx);
  371. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREFEATURE")){
  372. *pClass = new CSoftwareFeature(this, m_pNamespace, pCtx);
  373. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_TYPELIBRARYACTION")){
  374. *pClass = new CTypeLibraryAction(this, m_pNamespace, pCtx);
  375. // }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_UPGRADE")){
  376. // *pClass = new CUpgrade(this, m_pNamespace, pCtx);
  377. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_REGISTRYACTION")){
  378. *pClass = new CRegistryAction(this, m_pNamespace, pCtx);
  379. //////////////////
  380. // Associations //
  381. //////////////////
  382. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ACTIONCHECK")){
  383. *pClass = new CActionCheck(this, m_pNamespace, pCtx);
  384. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_APPLICATIONCOMMANDLINE")){
  385. *pClass = new CApplicationCommandLine(this, m_pNamespace, pCtx);
  386. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_CHECKCHECK")){
  387. *pClass = new CCheckCheck(this, m_pNamespace, pCtx);
  388. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_INSTALLEDSOFTWAREELEMENT")){
  389. *pClass = new CInstalledSoftwareElement(this, m_pNamespace, pCtx);
  390. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCDATASOURCEATTRIBUTE")){
  391. *pClass = new CODBCDataSourceAttribute(this, m_pNamespace, pCtx);
  392. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCDRIVERATTRIBUTE")){
  393. *pClass = new CODBCDriverAttribute(this, m_pNamespace, pCtx);
  394. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_ODBCDRIVERSOFTWAREELEMENT")){
  395. *pClass = new CODBCDriverSoftwareElement(this, m_pNamespace, pCtx);
  396. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PATCHFILE")){
  397. *pClass = new CPatchFile(this, m_pNamespace, pCtx);
  398. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PRODUCTCHECK")){
  399. *pClass = new CProductEnvironment(this, m_pNamespace, pCtx);
  400. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PRODUCTRESOURCE")){
  401. *pClass = new CProductResource(this, m_pNamespace, pCtx);
  402. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_PRODUCTSOFTWAREFEATURES")){
  403. *pClass = new CProductSoftwareFeatures(this, m_pNamespace, pCtx);
  404. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SERVICESPECIFICATIONSERVICE")){
  405. *pClass = new CServiceSpecificationService(this, m_pNamespace, pCtx);
  406. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SHORTCUTSAP")){
  407. *pClass = new CShortcutSAP(this, m_pNamespace, pCtx);
  408. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREELEMENTACTION")){
  409. *pClass = new CSoftwareElementAction(this, m_pNamespace, pCtx);
  410. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREELEMENTCHECK")){
  411. *pClass = new CSoftwareElementCheck(this, m_pNamespace, pCtx);
  412. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREELEMENTRESOURCE")){
  413. *pClass = new CSoftwareElementServiceControl(this, m_pNamespace, pCtx);
  414. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREFEATUREACTION")){
  415. *pClass = new CSoftwareFeatureAction(this, m_pNamespace, pCtx);
  416. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREFEATURECHECK")){
  417. *pClass = new CSoftwareFeatureCondition(this, m_pNamespace, pCtx);
  418. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREFEATUREPARENT")){
  419. *pClass = new CSoftwareFeatureParent(this, m_pNamespace, pCtx);
  420. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREFEATURESOFTWAREELEMENTS")){
  421. *pClass = new CSoftwareFeatureSofwareElements(this, m_pNamespace, pCtx);
  422. }else return WBEM_E_NOT_FOUND;
  423. if(!(*pClass)) throw m_he;
  424. return hr;
  425. };
  426. HRESULT CRequestObject::CreateObjectEnum(BSTR bstrPath, IWbemObjectSink *pHandler, IWbemContext *pCtx)
  427. {
  428. HRESULT hr = WBEM_S_NO_ERROR;
  429. CGenericClass *pClass = NULL;
  430. m_bstrPath = SysAllocString(bstrPath);
  431. if(!m_bstrPath) throw m_he;
  432. if(ParsePath(bstrPath)){
  433. try{
  434. //Create the appropriate class
  435. if(SUCCEEDED(hr = CreateClass(&pClass, pCtx))){
  436. if(!pClass) throw m_he;
  437. //Enumerate the objects
  438. hr = pClass->CreateObject(pHandler, ACTIONTYPE_ENUM);
  439. }
  440. }catch(...){
  441. if(pClass){
  442. pClass->CleanUp();
  443. delete pClass;
  444. }
  445. throw;
  446. }
  447. if(pClass){
  448. pClass->CleanUp();
  449. delete pClass;
  450. }
  451. }else hr = WBEM_E_FAILED;
  452. return hr;
  453. }
  454. HRESULT CRequestObject::PutObject(IWbemClassObject *pInst, IWbemObjectSink *pHandler, IWbemContext *pCtx)
  455. {
  456. return WBEM_E_NOT_SUPPORTED;
  457. }
  458. HRESULT CRequestObject::ExecMethod(BSTR bstrPath, BSTR bstrMethod, IWbemClassObject *pInParams,
  459. IWbemObjectSink *pHandler, IWbemContext *pCtx)
  460. {
  461. HRESULT hr = WBEM_S_NO_ERROR;
  462. // WCHAR wcTmp[BUFF_SIZE];
  463. m_bstrPath = SysAllocString(bstrPath);
  464. if(!m_bstrPath) throw m_he;
  465. //Initialize Eventing system
  466. if(!InitializeProgress(pHandler)) return WBEM_E_FAILED;
  467. if(ParsePath(bstrPath)){
  468. if(0 == _wcsicmp(m_bstrClass, L"WIN32_PRODUCT")){
  469. CProduct *pClass = new CProduct(this, m_pNamespace, pCtx);
  470. if(!pClass) throw m_he;
  471. //Static Methods
  472. if(0 == _wcsicmp(bstrMethod, L"ADMIN"))
  473. if(!IsInstance()){
  474. try{
  475. if ( pInParams )
  476. {
  477. hr = pClass->Admin(this, pInParams, pHandler, pCtx);
  478. }
  479. else
  480. {
  481. hr = WBEM_E_INVALID_PARAMETER;
  482. }
  483. }catch(...){
  484. pClass->CleanUp();
  485. delete pClass;
  486. throw;
  487. }
  488. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  489. else if(0 == _wcsicmp(bstrMethod, L"ADVERTISE"))
  490. if(!IsInstance()){
  491. try{
  492. if ( pInParams )
  493. {
  494. hr = pClass->Advertise(this, pInParams, pHandler, pCtx);
  495. }
  496. else
  497. {
  498. hr = WBEM_E_INVALID_PARAMETER;
  499. }
  500. }catch(...){
  501. pClass->CleanUp();
  502. delete pClass;
  503. throw;
  504. }
  505. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  506. else if(0 == _wcsicmp(bstrMethod, L"INSTALL"))
  507. if(!IsInstance()){
  508. try{
  509. if ( pInParams )
  510. {
  511. hr = pClass->Install(this, pInParams, pHandler, pCtx);
  512. }
  513. else
  514. {
  515. hr = WBEM_E_INVALID_PARAMETER;
  516. }
  517. }catch(...){
  518. pClass->CleanUp();
  519. delete pClass;
  520. throw;
  521. }
  522. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  523. //Non-Static Methods
  524. else if(0 == _wcsicmp(bstrMethod, L"CONFIGURE"))
  525. if(IsInstance()){
  526. try{
  527. if ( pInParams )
  528. {
  529. hr = pClass->Configure(this, pInParams, pHandler, pCtx);
  530. }
  531. else
  532. {
  533. hr = WBEM_E_INVALID_PARAMETER;
  534. }
  535. }catch(...){
  536. pClass->CleanUp();
  537. delete pClass;
  538. throw;
  539. }
  540. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  541. else if(0 == _wcsicmp(bstrMethod, L"REINSTALL"))
  542. if(IsInstance()){
  543. try{
  544. if ( pInParams )
  545. {
  546. hr = pClass->Reinstall(this, pInParams, pHandler, pCtx);
  547. }
  548. else
  549. {
  550. hr = WBEM_E_INVALID_PARAMETER;
  551. }
  552. }catch(...){
  553. pClass->CleanUp();
  554. delete pClass;
  555. throw;
  556. }
  557. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  558. else if(0 == _wcsicmp(bstrMethod, L"UNINSTALL"))
  559. if(IsInstance()){
  560. try{
  561. // doesn't matter as we do not expect pInParams
  562. hr = pClass->Uninstall(this, pInParams, pHandler, pCtx);
  563. }catch(...){
  564. pClass->CleanUp();
  565. delete pClass;
  566. throw;
  567. }
  568. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  569. else if(0 == _wcsicmp(bstrMethod, L"UPGRADE"))
  570. if(IsInstance()){
  571. try{
  572. if ( pInParams )
  573. {
  574. hr = pClass->Upgrade(this, pInParams, pHandler, pCtx);
  575. }
  576. else
  577. {
  578. hr = WBEM_E_INVALID_PARAMETER;
  579. }
  580. }catch(...){
  581. pClass->CleanUp();
  582. delete pClass;
  583. throw;
  584. }
  585. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  586. else hr = WBEM_E_NOT_SUPPORTED;
  587. pClass->CleanUp();
  588. delete pClass;
  589. }else if(0 == _wcsicmp(m_bstrClass, L"WIN32_SOFTWAREFEATURE")){
  590. CSoftwareFeature *pClass = new CSoftwareFeature(this, m_pNamespace, pCtx);
  591. if(!pClass) throw m_he;
  592. if(0 == _wcsicmp(bstrMethod, L"CONFIGURE"))
  593. if(IsInstance()){
  594. try{
  595. if ( pInParams )
  596. {
  597. hr = pClass->Configure(this, pInParams, pHandler, pCtx);
  598. }
  599. else
  600. {
  601. hr = WBEM_E_INVALID_PARAMETER;
  602. }
  603. }catch(...){
  604. pClass->CleanUp();
  605. delete pClass;
  606. throw;
  607. }
  608. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  609. else if(0 == _wcsicmp(bstrMethod, L"REINSTALL"))
  610. if(IsInstance()){
  611. try{
  612. if ( pInParams )
  613. {
  614. hr = pClass->Reinstall(this, pInParams, pHandler, pCtx);
  615. }
  616. else
  617. {
  618. hr = WBEM_E_INVALID_PARAMETER;
  619. }
  620. }catch(...){
  621. pClass->CleanUp();
  622. delete pClass;
  623. throw;
  624. }
  625. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  626. else hr = WBEM_E_NOT_SUPPORTED;
  627. pClass->CleanUp();
  628. delete pClass;
  629. }else hr = WBEM_E_NOT_SUPPORTED;
  630. }else
  631. return WBEM_E_FAILED;
  632. return hr;
  633. }
  634. HRESULT CRequestObject::DeleteObject(BSTR bstrPath, IWbemObjectSink *pHandler, IWbemContext *pCtx)
  635. {
  636. HRESULT hr = WBEM_S_NO_ERROR;
  637. // WCHAR wcTmp[BUFF_SIZE];
  638. m_bstrPath = SysAllocString(bstrPath);
  639. if(!m_bstrPath) throw m_he;
  640. //Initialize Eventing system
  641. if(!InitializeProgress(pHandler)) return WBEM_E_FAILED;
  642. if(ParsePath(bstrPath)){
  643. if(0 == _wcsicmp(m_bstrClass, L"WIN32_PRODUCT")){
  644. CProduct *pClass = new CProduct(this, m_pNamespace, pCtx);
  645. if(!pClass) throw m_he;
  646. if(IsInstance()){
  647. try{
  648. hr = pClass->Uninstall(this, NULL, pHandler, pCtx);
  649. }catch(...){
  650. pClass->CleanUp();
  651. delete pClass;
  652. throw;
  653. }
  654. }else hr = WBEM_E_INVALID_METHOD_PARAMETERS;
  655. pClass->CleanUp();
  656. delete pClass;
  657. }else hr = WBEM_E_NOT_SUPPORTED;
  658. }else hr = WBEM_E_FAILED;
  659. return hr;
  660. }
  661. #ifdef _EXEC_QUERY_SUPPORT
  662. HRESULT CRequestObject::ExecQuery(BSTR bstrQuery, IWbemObjectSink *pHandler, IWbemContext *pCtx)
  663. {
  664. HRESULT hr = WBEM_S_NO_ERROR;
  665. CGenericClass *pClass = NULL;
  666. if(ParseQuery(bstrQuery)){
  667. try{
  668. //Create the appropriate class
  669. if(SUCCEEDED(hr = CreateClass(&pClass, pCtx))){
  670. if(!pClass) throw m_he;
  671. //Enumerate the objects
  672. hr = pClass->CreateObject(pHandler, ACTIONTYPE_QUERY);
  673. }
  674. }catch(...){
  675. if(pClass){
  676. pClass->CleanUp();
  677. delete pClass;
  678. }
  679. throw;
  680. }
  681. if(pClass){
  682. pClass->CleanUp();
  683. delete pClass;
  684. }
  685. }else
  686. hr = WBEM_E_PROVIDER_NOT_CAPABLE;
  687. return hr;
  688. }
  689. bool CRequestObject::ParseQuery(BSTR bstrQuery)
  690. {
  691. LPWSTR wcTest = NULL;
  692. try
  693. {
  694. if ( ( wcTest = new WCHAR [ ::SysStringLen ( bstrQuery ) + 1 ] ) != NULL )
  695. {
  696. wcscpy ( wcTest, bstrQuery );
  697. }
  698. else
  699. {
  700. throw m_he;
  701. }
  702. }
  703. catch ( ... )
  704. {
  705. if ( wcTest )
  706. {
  707. delete [] wcTest;
  708. wcTest = NULL;
  709. }
  710. throw;
  711. }
  712. WCHAR *pwcTest = wcTest;
  713. WCHAR wcProp[BUFF_SIZE];
  714. WCHAR wcClass[BUFF_SIZE];
  715. WCHAR wcTmp[BUFF_SIZE];
  716. bool bResult = false;
  717. if ( ExpectedToken ( &pwcTest, L"SELECT" ) )
  718. {
  719. //Get the requested property list
  720. GetNextToken(&pwcTest, wcProp);
  721. if(*wcProp != L'*'){
  722. while(ExpectedToken(&pwcTest, L",")){
  723. //not doing anything here yet
  724. GetNextToken(&pwcTest, wcProp);
  725. }
  726. }
  727. if ( ExpectedToken ( &pwcTest, L"FROM" ) )
  728. {
  729. //Get the class name
  730. if ( GetNextToken ( &pwcTest, wcClass ) != NULL )
  731. {
  732. m_bstrClass = SysAllocString(wcClass);
  733. if ( !EOL ( &pwcTest ) )
  734. {
  735. if ( ExpectedToken ( &pwcTest, L"WHERE" ) )
  736. {
  737. m_iPropCount = -1;
  738. int iParens = 0;
  739. bool bContinue = true;
  740. //Get the "where" clause
  741. while ( bContinue && !EOL ( &pwcTest ) )
  742. {
  743. GetNextToken(&pwcTest, wcTmp);
  744. if(_wcsicmp(wcTmp, L"(") == 0){
  745. iParens++;
  746. }else if(_wcsicmp(wcTmp, L")") == 0){
  747. iParens--;
  748. }else if(!((_wcsicmp(wcTmp, L"or") == 0) || (_wcsicmp(wcTmp, L"and") == 0))){
  749. //if we have "or" or "and" skip over it... (treat all as or)
  750. if( m_iPropCount >= MSI_KEY_LIST_SIZE) {
  751. throw m_he;
  752. }
  753. m_Property[++m_iPropCount] = SysAllocString(wcTmp);
  754. //Syntax checking
  755. if ( ExpectedToken ( &pwcTest, L"=" ) )
  756. {
  757. if(wcscmp(GetNextToken(&pwcTest, wcTmp), L"\"") == 0){
  758. if( m_iPropCount >= MSI_KEY_LIST_SIZE) {
  759. throw m_he;
  760. }
  761. //Deal with quoted strings
  762. m_Value[m_iPropCount] = SysAllocString(GetStringValue(&pwcTest, wcTmp));
  763. if ( !ExpectedToken ( &pwcTest, L"\"" ) )
  764. {
  765. bContinue = false;
  766. bResult = false;
  767. }
  768. }else{
  769. if( m_iPropCount >= MSI_KEY_LIST_SIZE) {
  770. throw m_he;
  771. }
  772. m_Value[m_iPropCount] = SysAllocString(wcTmp);
  773. }
  774. m_iValCount++;
  775. }
  776. else
  777. {
  778. bContinue = false;
  779. bResult = false;
  780. }
  781. }
  782. }
  783. m_iPropCount++;
  784. if(iParens == 0)
  785. {
  786. bResult = true;
  787. }
  788. }
  789. }
  790. else
  791. {
  792. bResult = true;
  793. }
  794. }
  795. }
  796. }
  797. if ( wcTest )
  798. {
  799. delete [] wcTest;
  800. wcTest = NULL;
  801. }
  802. return bResult;
  803. }
  804. WCHAR * CRequestObject::GetStringValue(WCHAR **pwcString, WCHAR wcToken[])
  805. {
  806. //eat white space
  807. while(**pwcString == L' '){ (*pwcString)++; }
  808. wcscpy(wcToken, *pwcString);
  809. WCHAR *pwcStart = wcToken;
  810. WCHAR *pwcToken = wcToken;
  811. WCHAR *pwcPrev;
  812. //deal with eol
  813. if(*pwcToken == NULL) return NULL;
  814. //deal with strings
  815. while((*pwcToken != NULL) && ((*pwcToken != L'\"') || (*pwcPrev == L'\\'))){
  816. if((*pwcToken == L'\"') && (*pwcPrev == L'\\')){
  817. WCHAR *pwcTmp = pwcPrev;
  818. while(*pwcPrev){
  819. *pwcPrev = *pwcToken;
  820. pwcPrev = (pwcToken++);
  821. }
  822. pwcToken = pwcTmp;
  823. }
  824. pwcPrev = (pwcToken++);
  825. (*pwcString)++;
  826. }
  827. *pwcToken = NULL;
  828. return pwcStart;
  829. }
  830. bool CRequestObject::ExpectedToken(WCHAR **pwcString, WCHAR *pwcExpected)
  831. {
  832. WCHAR wcTmp[BUFF_SIZE];
  833. GetNextToken(pwcString, wcTmp);
  834. if(_wcsicmp(wcTmp, pwcExpected) == 0) return true;
  835. else return false;
  836. }
  837. WCHAR * CRequestObject::GetNextProperty(WCHAR **pwcString, WCHAR wcProp[])
  838. {
  839. //eat white space
  840. while(**pwcString == L' '){ (*pwcString)++; }
  841. wcscpy(wcProp, *pwcString);
  842. WCHAR *pwcStart = wcProp;
  843. WCHAR *pwcToken = wcProp;
  844. //deal with strings
  845. while(*pwcToken != L'='){
  846. pwcToken++;
  847. (*pwcString)++;
  848. }
  849. *pwcToken = NULL;
  850. return pwcStart;
  851. }
  852. WCHAR * CRequestObject::GetNextValue(WCHAR **pwcString, WCHAR wcVal[])
  853. {
  854. wcscpy(wcVal, *pwcString);
  855. WCHAR *pwcStart = wcVal;
  856. WCHAR *pwcToken = wcVal;
  857. WCHAR *pwcPrev;
  858. //deal with strings
  859. while((*pwcToken != L' ') || ((*pwcToken != L'\"') || (*pwcPrev == L'\\'))){
  860. pwcPrev = (pwcToken++);
  861. (*pwcString)++;
  862. }
  863. *pwcToken = NULL;
  864. return pwcStart;
  865. }
  866. bool CRequestObject::EOL(WCHAR **pwcString)
  867. {
  868. while(**pwcString == L' ') (*pwcString)++;
  869. if(wcscmp(*pwcString, L"") == 0) return true;
  870. else return false;
  871. }
  872. WCHAR * CRequestObject::GetNextToken(WCHAR **pwcString, WCHAR wcToken[])
  873. {
  874. //eat white space
  875. while(**pwcString == L' '){ (*pwcString)++; }
  876. wcscpy(wcToken, *pwcString);
  877. WCHAR *pwcStart = wcToken;
  878. WCHAR *pwcToken = wcToken;
  879. WCHAR *pwcPrev;
  880. //deal with special chars
  881. if((*pwcToken == L'(') || (*pwcToken == L')') || (*pwcToken == L',') || (*pwcToken == L'=') || (*pwcToken == L'"')){
  882. *(++pwcToken) = NULL;
  883. (*pwcString)++;
  884. return pwcStart;
  885. }
  886. //deal with eol
  887. if(*pwcToken == NULL) return NULL;
  888. //deal with strings
  889. while((*pwcToken != NULL) && (*pwcToken != L' ') && (*pwcToken != L',') &&
  890. (*pwcToken != L'=') && ((*pwcToken != L'\"') || (*pwcPrev == L'\\'))){
  891. pwcPrev = (pwcToken++);
  892. (*pwcString)++;
  893. }
  894. *pwcToken = NULL;
  895. return pwcStart;
  896. }
  897. #endif //_EXEC_QUERY_SUPPORT
  898. bool CRequestObject::ParsePath(BSTR bstrPath)
  899. {
  900. if(wcslen(bstrPath) < 1) return false;
  901. LPWSTR wcTest = NULL;
  902. try
  903. {
  904. if ( ( wcTest = new WCHAR [ ::SysStringLen ( bstrPath ) + 1 ] ) != NULL )
  905. {
  906. wcscpy ( wcTest, bstrPath );
  907. }
  908. else
  909. {
  910. throw m_he;
  911. }
  912. }
  913. catch ( ... )
  914. {
  915. if ( wcTest )
  916. {
  917. delete [] wcTest;
  918. wcTest = NULL;
  919. }
  920. throw;
  921. }
  922. WCHAR *pwcTest = NULL;
  923. WCHAR *pwcClassStart = wcTest;
  924. WCHAR *pwcNamespace = NULL;
  925. WCHAR *pwcStart = NULL;
  926. WCHAR *pwcStrip = NULL;
  927. WCHAR wcPrevious = NULL;
  928. int iNumQuotes = 0;
  929. bool bClass = false;
  930. bool bDoubles = false;
  931. try
  932. {
  933. //Main Parsing Loop
  934. for(pwcTest = wcTest; *pwcTest; pwcTest++){
  935. if((*pwcTest == L'\\') && !bClass){
  936. for(pwcNamespace = pwcTest; *pwcNamespace != L':'; pwcNamespace++){}
  937. pwcClassStart = pwcNamespace + 1;
  938. pwcTest = pwcNamespace;
  939. }else if(*pwcTest == L'.'){
  940. if(iNumQuotes == 0){
  941. // issolate the class name.
  942. *pwcTest = NULL;
  943. if(m_bstrClass){
  944. SysFreeString(m_bstrClass);
  945. m_bstrClass = NULL;
  946. }
  947. m_bstrClass = SysAllocString(pwcClassStart);
  948. if(!m_bstrClass) throw m_he;
  949. bClass = true;
  950. pwcStart = (pwcTest + 1);
  951. }
  952. }else if(*pwcTest == L'='){
  953. if(iNumQuotes == 0){
  954. if(!bClass){
  955. // issolate the class name.
  956. *pwcTest = NULL;
  957. if(m_bstrClass){
  958. SysFreeString(m_bstrClass);
  959. m_bstrClass = NULL;
  960. }
  961. m_bstrClass = SysAllocString(pwcClassStart);
  962. if(!m_bstrClass) throw m_he;
  963. bClass = true;
  964. pwcStart = (pwcTest + 1);
  965. }else{
  966. // issolate the property name.
  967. *pwcTest = NULL;
  968. if(pwcStart != NULL){
  969. if( m_iPropCount >= MSI_KEY_LIST_SIZE) {
  970. throw m_he;
  971. }
  972. m_Property[m_iPropCount] = SysAllocString(pwcStart);
  973. if(!m_Property[m_iPropCount++]) throw m_he;
  974. pwcStart = (pwcTest + 1);
  975. }else pwcStart = (pwcTest + 1);
  976. }
  977. }
  978. }else if(*pwcTest == L','){
  979. if(iNumQuotes != 1){
  980. // issolate the property value.
  981. *pwcTest = NULL;
  982. if(pwcStart != NULL){
  983. if( m_iValCount >= MSI_KEY_LIST_SIZE) {
  984. throw m_he;
  985. }
  986. m_Value[m_iValCount] = SysAllocString(pwcStart);
  987. if(!m_Value[m_iValCount++]) throw m_he;
  988. pwcStart = (pwcTest + 1);
  989. }else return false;
  990. }
  991. }else if(*pwcTest == L'\"'){
  992. if(wcPrevious != L'\\'){
  993. // deal with quotes in path.
  994. iNumQuotes++;
  995. if(iNumQuotes == 1) pwcStart = (pwcTest + 1);
  996. else if(iNumQuotes == 2){
  997. *pwcTest = NULL;
  998. iNumQuotes = 0;
  999. }
  1000. }else if(iNumQuotes == 1){
  1001. //deal with embedded quotes
  1002. for(pwcStrip = (--pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1003. *pwcStrip = NULL;
  1004. }
  1005. }else if((*pwcTest == L'\\') && (wcPrevious == L'\\') && bClass && !bDoubles){
  1006. for(pwcStrip = (--pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1007. *pwcStrip = NULL;
  1008. }
  1009. #ifdef _STRIP_ESCAPED_CHARS
  1010. else if(*pwcTest == L'%'){
  1011. //deal with escaped URL characters
  1012. if(*(pwcTest + 1) == L'0'){
  1013. if(*(pwcTest + 2) == L'7'){
  1014. //bell
  1015. *pwcTest = L'\\';
  1016. *(++pwcTest) = L'a';
  1017. for(pwcStrip = (++pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1018. *pwcStrip = NULL;
  1019. }else if(*(pwcTest + 2) == L'8'){
  1020. //backspace
  1021. *pwcTest = L'\\';
  1022. *(++pwcTest) = L'b';
  1023. for(pwcStrip = (++pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1024. *pwcStrip = NULL;
  1025. }else if(*(pwcTest + 2) == L'9'){
  1026. //horizontal tab
  1027. *pwcTest = L'\\';
  1028. *(++pwcTest) = L't';
  1029. for(pwcStrip = (++pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1030. *pwcStrip = NULL;
  1031. }else if((*(pwcTest + 2) == L'A') || (*(pwcTest + 2) == L'a')){
  1032. //newline
  1033. *pwcTest = L'\\';
  1034. *(++pwcTest) = L'n';
  1035. for(pwcStrip = (++pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1036. *pwcStrip = NULL;
  1037. }else if((*(pwcTest + 2) == L'B') || (*(pwcTest + 2) == L'b')){
  1038. //vertical tab
  1039. *pwcTest = L'\\';
  1040. *(++pwcTest) = L'v';
  1041. for(pwcStrip = (++pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1042. *pwcStrip = NULL;
  1043. }else if((*(pwcTest + 2) == L'C') || (*(pwcTest + 2) == L'c')){
  1044. //formfeed
  1045. *pwcTest = L'\\';
  1046. *(++pwcTest) = L'f';
  1047. for(pwcStrip = (++pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1048. *pwcStrip = NULL;
  1049. }else if((*(pwcTest + 2) == L'D') || (*(pwcTest + 2) == L'd')){
  1050. //carriage return
  1051. *pwcTest = L'\\';
  1052. *(++pwcTest) = L'r';
  1053. for(pwcStrip = (++pwcTest); *pwcStrip; pwcStrip++) *pwcStrip = *(pwcStrip + 1);
  1054. *pwcStrip = NULL;
  1055. }else return false;
  1056. }else if(*(pwcTest + 1) == L'1'){
  1057. return false;
  1058. }else if(*(pwcTest + 1) == L'2'){
  1059. if(*(pwcTest + 2) == L'0'){
  1060. //space
  1061. *pwcTest++ = L' ';
  1062. for(int ip = 0; ip < 2; ip++)
  1063. for(pwcStrip = (pwcTest); *pwcStrip; pwcStrip++)
  1064. *pwcStrip = *(pwcStrip + 1);
  1065. *pwcStrip = NULL;
  1066. }else return false;
  1067. }
  1068. }
  1069. #endif //_STRIP_ESCAPED_CHARS
  1070. if((wcPrevious == *pwcTest) && !bDoubles) bDoubles = true;
  1071. else bDoubles = false;
  1072. wcPrevious = *pwcTest;
  1073. }
  1074. // if we still have values to add, do so now
  1075. if(pwcStart != NULL){
  1076. if( m_iValCount >= MSI_KEY_LIST_SIZE) {
  1077. throw m_he;
  1078. }
  1079. m_Value[m_iValCount] = SysAllocString(pwcStart);
  1080. if(!m_Value[m_iValCount++]) throw m_he;
  1081. }else if((m_iPropCount < 1) && (m_iValCount < 1)){
  1082. if(m_bstrClass){
  1083. SysFreeString(m_bstrClass);
  1084. m_bstrClass = NULL;
  1085. }
  1086. m_bstrClass = SysAllocString(pwcClassStart);
  1087. if(!m_bstrClass) throw m_he;
  1088. }
  1089. if(iNumQuotes != 0) return false;
  1090. if(m_iValCount != m_iPropCount){
  1091. if(m_iValCount > m_iPropCount){ if(m_iValCount != 1) return false; }
  1092. else return false;
  1093. }
  1094. }
  1095. catch ( ... )
  1096. {
  1097. if ( wcTest )
  1098. {
  1099. delete [] wcTest;
  1100. wcTest = NULL;
  1101. }
  1102. throw;
  1103. }
  1104. if ( wcTest )
  1105. {
  1106. delete [] wcTest;
  1107. wcTest = NULL;
  1108. }
  1109. if(!m_bstrClass) return false;
  1110. return true;
  1111. }
  1112. HRESULT CRequestObject::InitializeList(bool bGetList)
  1113. {
  1114. int i = 0;
  1115. WCHAR wcGUIDBuf[39];
  1116. UINT uiStatus;
  1117. bool bHaveItems = false;
  1118. PackageListNode *pLast = NULL;
  1119. try
  1120. {
  1121. if(bGetList)
  1122. {
  1123. m_pPackageHead = new PackageListNode();
  1124. if(!m_pPackageHead) throw m_he;
  1125. PackageListNode *pPos = m_pPackageHead;
  1126. try
  1127. {
  1128. if(m_dwCheckKeyPresentStatus != ERROR_SUCCESS)
  1129. {
  1130. LoadHive();
  1131. }
  1132. while((uiStatus = g_fpMsiEnumProductsW(i++, wcGUIDBuf)) != ERROR_NO_MORE_ITEMS)
  1133. {
  1134. if(uiStatus != S_OK)
  1135. {
  1136. throw ConvertError(uiStatus);
  1137. }
  1138. bHaveItems = true;
  1139. // ok ( products return string representation of GUID )
  1140. wcscpy(pPos->wcCode, wcGUIDBuf);
  1141. pLast = pPos;
  1142. pPos = pPos->pNext = new PackageListNode();
  1143. if(!pPos)
  1144. {
  1145. throw m_he;
  1146. }
  1147. }
  1148. }
  1149. catch(...)
  1150. {
  1151. //remove the key if it wasn't there b4....
  1152. if(m_dwCheckKeyPresentStatus != ERROR_SUCCESS)
  1153. {
  1154. UnloadHive();
  1155. }
  1156. if ( pPos != m_pPackageHead )
  1157. {
  1158. delete pPos;
  1159. pPos = NULL;
  1160. }
  1161. throw;
  1162. }
  1163. //remove the key if it wasn't there b4....
  1164. if(m_dwCheckKeyPresentStatus != ERROR_SUCCESS)
  1165. {
  1166. UnloadHive();
  1167. }
  1168. delete pPos;
  1169. pPos = NULL;
  1170. if( !bHaveItems )
  1171. {
  1172. m_pPackageHead = NULL;
  1173. return WBEM_S_NO_MORE_DATA;
  1174. }
  1175. else
  1176. {
  1177. if(pLast)
  1178. {
  1179. pLast->pNext = NULL;
  1180. }
  1181. else
  1182. {
  1183. return WBEM_E_FAILED;
  1184. }
  1185. }
  1186. }
  1187. else
  1188. {
  1189. m_pPackageHead = NULL;
  1190. }
  1191. }
  1192. catch(HRESULT e_hr)
  1193. {
  1194. if(pLast)
  1195. {
  1196. pLast->pNext = NULL;
  1197. }
  1198. return e_hr;
  1199. }
  1200. catch(...)
  1201. {
  1202. if(pLast)
  1203. {
  1204. pLast->pNext = NULL;
  1205. }
  1206. throw;
  1207. }
  1208. return WBEM_S_NO_ERROR;
  1209. }
  1210. bool CRequestObject::DestroyList()
  1211. {
  1212. PackageListNode *pPos = m_pPackageHead;
  1213. PackageListNode *pLast;
  1214. while(pPos){
  1215. pLast = pPos;
  1216. pPos = pPos->pNext;
  1217. delete pLast;
  1218. }
  1219. m_pPackageHead = NULL;
  1220. return true;
  1221. }
  1222. WCHAR * CRequestObject::Package(int iPos)
  1223. {
  1224. PackageListNode *pPos = m_pPackageHead;
  1225. while(iPos-- > 0){
  1226. if(!pPos) return NULL;
  1227. pPos = pPos->pNext;
  1228. }
  1229. if(!pPos) return NULL;
  1230. else return pPos->wcCode;
  1231. }
  1232. bool CRequestObject::Cleanup()
  1233. {
  1234. //Let's destroy our list and clear up some space
  1235. if(m_bstrClass != NULL) SysFreeString(m_bstrClass);
  1236. if(m_bstrPath != NULL) SysFreeString(m_bstrPath);
  1237. for(int i = 0; i < MSI_KEY_LIST_SIZE; i++){
  1238. if(m_Property[i] != NULL) SysFreeString(m_Property[i]);
  1239. if(m_Value[i] != NULL) SysFreeString(m_Value[i]);
  1240. }
  1241. DestroyList();
  1242. if(m_iThreadID != THREAD_NO_PROGRESS){
  1243. ProListNode * pNode = RemoveNode(m_iThreadID);
  1244. delete pNode;
  1245. }
  1246. return true;
  1247. }
  1248. bool CRequestObject::IsInstance()
  1249. {
  1250. if((m_iPropCount > 0) || (m_iValCount > 0)) return true;
  1251. return false;
  1252. }
  1253. ProListNode * CRequestObject::InitializeProgress(IWbemObjectSink *pHandler)
  1254. {
  1255. try
  1256. {
  1257. if(!m_pHead)
  1258. {
  1259. m_pHead = new ProListNode();
  1260. if(!m_pHead) throw m_he;
  1261. m_pHead->pNext = NULL;
  1262. m_pHead->pSink = NULL;
  1263. m_pHead->iThread = 0;
  1264. m_pHead->wTotal = m_pHead->wComplete = 0;
  1265. m_pHead->lTotal = m_pHead->lComplete = m_pHead->lActionData = 0;
  1266. }
  1267. }
  1268. catch(...)
  1269. {
  1270. if ( m_pHead )
  1271. {
  1272. delete m_pHead;
  1273. m_pHead = NULL;
  1274. }
  1275. throw;
  1276. }
  1277. ProListNode *pNode = new ProListNode;
  1278. if(!pNode) throw m_he;
  1279. pNode->pNext = NULL;
  1280. pNode->wTotal = pNode->wComplete = 0;
  1281. pNode->lTotal = pNode->lComplete = pNode->lActionData = 0;
  1282. pNode->pSink = pHandler;
  1283. try
  1284. {
  1285. m_iThreadID = InsertNode(pNode);
  1286. }
  1287. catch(...)
  1288. {
  1289. throw;
  1290. }
  1291. if(m_iThreadID == THREAD_NO_PROGRESS)
  1292. {
  1293. delete pNode;
  1294. pNode = NULL;
  1295. }
  1296. return pNode;
  1297. }
  1298. bool CRequestObject::ParseProgress(WCHAR *wcMessage, ProgressStruct *ps)
  1299. {
  1300. WCHAR *wcp = wcMessage;
  1301. WCHAR *wcpStart = wcMessage;
  1302. WCHAR *wcpVal;
  1303. while(*wcp){
  1304. if(*wcp == L':'){
  1305. *wcp++ = NULL;
  1306. wcpVal = wcp;
  1307. while(*wcp == ' ') wcp++;
  1308. while(*wcp && (*wcp != ' ')) wcp++;
  1309. *wcp = NULL;
  1310. switch(_wtoi(wcpStart)){
  1311. case 1:
  1312. ps->field1 = _wtoi(wcpVal);
  1313. break;
  1314. case 2:
  1315. ps->field2 = _wtoi(wcpVal);
  1316. break;
  1317. case 3:
  1318. ps->field3 = _wtoi(wcpVal);
  1319. break;
  1320. case 4:
  1321. ps->field4 = _wtoi(wcpVal);
  1322. break;
  1323. default:
  1324. return false;
  1325. }
  1326. wcpStart = (wcp + 1);
  1327. }
  1328. wcp++;
  1329. }
  1330. return true;
  1331. }
  1332. bool CRequestObject::ActionDataProgress(HRESULT *hr, int iThread)
  1333. {
  1334. ProListNode *pNode = GetNode(iThread);
  1335. if ( pNode )
  1336. {
  1337. //add the actiondata increment
  1338. if((pNode->lTotal != 0) && (pNode->lActionData != 0)){
  1339. pNode->lComplete += pNode->lActionData;
  1340. pNode->wComplete = (WORD)((10000 * pNode->lComplete) / pNode->lTotal);
  1341. }
  1342. *hr = (pNode->wTotal << 16) + pNode->wComplete;
  1343. return true;
  1344. }
  1345. else
  1346. {
  1347. *hr = WBEM_E_UNEXPECTED;
  1348. return false;
  1349. }
  1350. }
  1351. bool CRequestObject::ActionStartProgress(HRESULT *hr, int iThread)
  1352. {
  1353. ProListNode *pNode = GetNode(iThread);
  1354. if ( pNode )
  1355. {
  1356. //reset the actiondata increment
  1357. pNode->lActionData = 0;
  1358. *hr = (pNode->wTotal << 16) + pNode->wComplete;
  1359. return true;
  1360. }
  1361. else
  1362. {
  1363. *hr = WBEM_E_UNEXPECTED;
  1364. return false;
  1365. }
  1366. }
  1367. bool CRequestObject::CreateProgress(ProgressStruct *ps, HRESULT *hr, int iThread)
  1368. {
  1369. bool bResult = true;
  1370. ProListNode *pNode = GetNode(iThread);
  1371. //parse the progress information we get from MSI
  1372. if(ps){
  1373. switch(ps->field1){
  1374. //1:0 2:x 3:x 4:x
  1375. case 0:
  1376. if ( pNode )
  1377. {
  1378. pNode->wTotal = 10000;
  1379. pNode->lTotal = ps->field2;
  1380. pNode->wComplete = 0;
  1381. pNode->lComplete = 0;
  1382. }
  1383. break;
  1384. //1:1 2:x 3:x 4:x
  1385. case 1:
  1386. //1:1 2:x 3:1 4:x
  1387. if(ps->field3 == 1)
  1388. {
  1389. if ( pNode )
  1390. {
  1391. pNode->lActionData = ps->field2;
  1392. }
  1393. }
  1394. break;
  1395. //1:2 2:x 3:x 4:x
  1396. case 2:
  1397. if ( pNode )
  1398. {
  1399. pNode->lComplete += ps->field2;
  1400. if(pNode->lTotal != 0)
  1401. {
  1402. pNode->wComplete = (WORD)((10000 * pNode->lComplete)/pNode->lTotal);
  1403. }
  1404. }
  1405. break;
  1406. //1:3 2:x 3:x 4:x
  1407. case 3:
  1408. if ( pNode )
  1409. {
  1410. pNode->lTotal += ps->field2;
  1411. if(pNode->lTotal != 0)
  1412. {
  1413. pNode->wComplete = (WORD)((10000 * pNode->lComplete)/pNode->lTotal);
  1414. }
  1415. }
  1416. break;
  1417. default:
  1418. bResult = false;
  1419. break;
  1420. }
  1421. }
  1422. if ( pNode )
  1423. {
  1424. *hr = (pNode->wTotal << 16) + pNode->wComplete;
  1425. }
  1426. else
  1427. {
  1428. *hr = WBEM_E_UNEXPECTED;
  1429. bResult = false;
  1430. }
  1431. return bResult;
  1432. }
  1433. ProListNode * CRequestObject::GetNode(int iThread)
  1434. {
  1435. //initial sanity code
  1436. if(!m_pHead) return NULL;
  1437. ProListNode *ptr = m_pHead;
  1438. while( ptr && (ptr->pNext) && (ptr->iThread < iThread) )
  1439. {
  1440. ptr = ptr->pNext;
  1441. }
  1442. if( ptr && ptr->iThread == iThread )
  1443. {
  1444. return ptr;
  1445. }
  1446. else
  1447. {
  1448. return NULL;
  1449. }
  1450. }
  1451. // Note - does not delete, simply removes from list
  1452. ProListNode * CRequestObject::RemoveNode(int iThread)
  1453. {
  1454. ProListNode *ptr = m_pHead;
  1455. if ( ptr != NULL )
  1456. {
  1457. while((ptr->pNext) && (ptr->pNext->iThread < iThread)) {ptr = ptr->pNext;}
  1458. if(ptr->pNext){
  1459. if(ptr->pNext->iThread == iThread){
  1460. ProListNode *pTmp = ptr->pNext;
  1461. ptr->pNext = ptr->pNext->pNext;
  1462. return pTmp;
  1463. }else return NULL;
  1464. }else return NULL;
  1465. }
  1466. return NULL;
  1467. }
  1468. int CRequestObject::InsertNode(ProListNode *pNode)
  1469. {
  1470. int iID = 0;
  1471. ProListNode *ptr = m_pHead;
  1472. while(ptr->pNext){
  1473. if(ptr->iThread > iID){
  1474. pNode->iThread = iID;
  1475. //If it's already here, fail
  1476. if((ptr->pNext) && (ptr->pNext->iThread == pNode->iThread)) return THREAD_NO_PROGRESS;
  1477. pNode->pNext = ptr->pNext;
  1478. ptr->pNext = pNode;
  1479. return iID;
  1480. }
  1481. iID++;
  1482. }
  1483. pNode->iThread = ++iID;
  1484. //If it's already here, fail
  1485. if((ptr->pNext) && (ptr->pNext->iThread == pNode->iThread)) return THREAD_NO_PROGRESS;
  1486. pNode->pNext = ptr->pNext;
  1487. ptr->pNext = pNode;
  1488. return iID;
  1489. }
  1490. DWORD CRequestObject::GetAccount(HANDLE TokenHandle, WCHAR *wcDomain, WCHAR *wcUser)
  1491. {
  1492. DWORD dwStatus = S_OK;
  1493. TOKEN_USER *tTokenUser = NULL;
  1494. DWORD dwReturnLength = 0;
  1495. TOKEN_INFORMATION_CLASS tTokenInformationClass = TokenUser;
  1496. if(!GetTokenInformation(TokenHandle, tTokenInformationClass, NULL, 0, &dwReturnLength) &&
  1497. GetLastError () == ERROR_INSUFFICIENT_BUFFER){
  1498. tTokenUser = (TOKEN_USER*) new UCHAR[dwReturnLength];
  1499. if(tTokenUser){
  1500. try{
  1501. if(GetTokenInformation(TokenHandle, tTokenInformationClass,
  1502. (void *)tTokenUser, dwReturnLength, &dwReturnLength)){
  1503. DWORD dwUserSize = BUFF_SIZE;
  1504. DWORD dwDomainSize = BUFF_SIZE;
  1505. SID_NAME_USE Use;
  1506. if(!LookupAccountSidW(NULL, tTokenUser->User.Sid, wcUser, &dwUserSize,
  1507. wcDomain, &dwDomainSize, &Use)){
  1508. dwStatus = GetLastError();
  1509. }
  1510. }else dwStatus = GetLastError();
  1511. }catch(...){
  1512. delete [] (UCHAR *)tTokenUser;
  1513. throw;
  1514. }
  1515. delete [] (UCHAR *)tTokenUser;
  1516. }else{
  1517. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1518. }
  1519. }else dwStatus = GetLastError();
  1520. return dwStatus ;
  1521. }
  1522. DWORD CRequestObject::GetSid(HANDLE TokenHandle, WCHAR *wcSID, DWORD dwSID)
  1523. {
  1524. DWORD dwStatus = S_OK ;
  1525. TOKEN_USER *tTokenUser = NULL ;
  1526. DWORD dwReturnLength = 0 ;
  1527. TOKEN_INFORMATION_CLASS tTokenInformationClass = TokenUser ;
  1528. if(!GetTokenInformation(TokenHandle, tTokenInformationClass, NULL, 0, &dwReturnLength) &&
  1529. GetLastError() == ERROR_INSUFFICIENT_BUFFER){
  1530. tTokenUser = (TOKEN_USER *) new UCHAR[dwReturnLength] ;
  1531. if(tTokenUser){
  1532. try{
  1533. if(GetTokenInformation(TokenHandle, tTokenInformationClass, (void *)tTokenUser,
  1534. dwReturnLength, &dwReturnLength)){
  1535. // Initialize m_strSid - human readable form of our SID
  1536. SID_IDENTIFIER_AUTHORITY *psia = ::GetSidIdentifierAuthority(tTokenUser->User.Sid);
  1537. // We assume that only last byte is used (authorities between 0 and 15).
  1538. // Correct this if needed.
  1539. // ASSERT(psia->Value[0] == psia->Value[1] == psia->Value[2] == psia->Value[3]
  1540. // == psia->Value[4] == 0);
  1541. DWORD dwTopAuthority = psia->Value[5];
  1542. LPWSTR bstrtTempSid = NULL;
  1543. try
  1544. {
  1545. if ( ( bstrtTempSid = new WCHAR [ BUFF_SIZE ] ) == NULL )
  1546. {
  1547. throw m_he;
  1548. }
  1549. }
  1550. catch ( ... )
  1551. {
  1552. if ( bstrtTempSid )
  1553. {
  1554. delete [] bstrtTempSid;
  1555. bstrtTempSid = NULL;
  1556. }
  1557. throw;
  1558. }
  1559. wcscpy(bstrtTempSid, L"S-1-");
  1560. WCHAR wstrAuth[32] = { L'\0' };
  1561. _itow(dwTopAuthority, wstrAuth, 10);
  1562. wcscat(bstrtTempSid, wstrAuth);
  1563. int iSubAuthorityCount = *(GetSidSubAuthorityCount(tTokenUser->User.Sid));
  1564. DWORD dwTempSidCur = BUFF_SIZE;
  1565. DWORD dwTempSid = 0L;
  1566. dwTempSid = wcslen ( bstrtTempSid );
  1567. for(int i = 0; i < iSubAuthorityCount; i++){
  1568. DWORD dwSubAuthority = *(GetSidSubAuthority( tTokenUser->User.Sid, i ));
  1569. wstrAuth[ 0 ] = L'\0';
  1570. _itow(dwSubAuthority, wstrAuth,10);
  1571. DWORD dwAuth = 0L;
  1572. dwAuth = wcslen ( wstrAuth );
  1573. if ( dwTempSid + dwAuth + 1 + 1 < dwTempSidCur )
  1574. {
  1575. wcscat(bstrtTempSid, L"-");
  1576. wcscat(bstrtTempSid, wstrAuth);
  1577. dwTempSid = dwTempSid + dwAuth + 1;
  1578. }
  1579. else
  1580. {
  1581. LPWSTR wsz = NULL;
  1582. try
  1583. {
  1584. if ( ( wsz = new WCHAR [ ( dwTempSid + dwAuth + 1 ) * 2 + 1 ] ) != NULL )
  1585. {
  1586. wcscpy ( wsz, bstrtTempSid );
  1587. wcscat ( wsz, L"-" );
  1588. wcscat ( wsz, wstrAuth );
  1589. dwTempSid = wcslen ( wsz );
  1590. dwTempSidCur = dwTempSid * 2;
  1591. }
  1592. else
  1593. {
  1594. throw m_he;
  1595. }
  1596. if ( bstrtTempSid )
  1597. {
  1598. delete [] bstrtTempSid;
  1599. bstrtTempSid = NULL;
  1600. }
  1601. bstrtTempSid = wsz;
  1602. }
  1603. catch ( ... )
  1604. {
  1605. if ( wsz )
  1606. {
  1607. delete [] wsz;
  1608. wsz = NULL;
  1609. }
  1610. if ( bstrtTempSid )
  1611. {
  1612. delete [] bstrtTempSid;
  1613. bstrtTempSid = NULL;
  1614. }
  1615. throw;
  1616. }
  1617. }
  1618. }
  1619. if ( wcslen ( bstrtTempSid ) + 1 < dwSID )
  1620. {
  1621. wcscpy(wcSID, bstrtTempSid);
  1622. }
  1623. else
  1624. {
  1625. dwStatus = ERROR_OUTOFMEMORY;
  1626. }
  1627. if ( bstrtTempSid )
  1628. {
  1629. delete [] bstrtTempSid;
  1630. bstrtTempSid = NULL;
  1631. }
  1632. }else dwStatus = GetLastError();
  1633. }catch(...){
  1634. delete [] (UCHAR *)tTokenUser;
  1635. throw ;
  1636. }
  1637. delete [] (UCHAR *)tTokenUser;
  1638. }else throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  1639. }else dwStatus = GetLastError();
  1640. return dwStatus ;
  1641. }
  1642. DWORD CRequestObject::LoadHive(/*LPWSTR pszUserName, LPWSTR pszKeyName*/)
  1643. {
  1644. DWORD i, dwSIDSize, dwDomainNameSize, dwSubAuthorities ;
  1645. char SIDBuffer [ _MAX_PATH ];
  1646. WCHAR szDomainName[_MAX_PATH], szSID[_MAX_PATH], szTemp[_MAX_PATH];
  1647. SID *pSID = (SID *) SIDBuffer ;
  1648. PSID_IDENTIFIER_AUTHORITY pSIA ;
  1649. SID_NAME_USE AccountType ;
  1650. CRegistry Reg;
  1651. DWORD dwRetCode = ERROR_INVALID_PARAMETER;
  1652. // Set the necessary privs
  1653. //========================
  1654. if ( ( dwRetCode = AcquirePrivilege() ) == ERROR_SUCCESS )
  1655. {
  1656. // Look up the user's account info
  1657. //================================
  1658. dwSIDSize = _MAX_PATH * sizeof ( char ) ;
  1659. dwDomainNameSize = _MAX_PATH;
  1660. BOOL bLookup = FALSE;
  1661. bLookup = LookupAccountNameW ( NULL,
  1662. m_wcAccount,
  1663. pSID,
  1664. &dwSIDSize,
  1665. szDomainName,
  1666. &dwDomainNameSize,
  1667. &AccountType
  1668. );
  1669. if(bLookup)
  1670. {
  1671. // Translate the SID into text (a la PSS article Q131320)
  1672. //=======================================================
  1673. pSIA = GetSidIdentifierAuthority(pSID) ;
  1674. dwSubAuthorities = *GetSidSubAuthorityCount(pSID) ;
  1675. dwSIDSize = swprintf(szSID, _T("S-%lu-"), (DWORD) SID_REVISION) ;
  1676. if((pSIA->Value[0] != 0) || (pSIA->Value[1] != 0)){
  1677. dwSIDSize += swprintf(szSID + wcslen(szSID), L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
  1678. (USHORT) pSIA->Value[0],
  1679. (USHORT) pSIA->Value[1],
  1680. (USHORT) pSIA->Value[2],
  1681. (USHORT) pSIA->Value[3],
  1682. (USHORT) pSIA->Value[4],
  1683. (USHORT) pSIA->Value[5]) ;
  1684. }else{
  1685. dwSIDSize += swprintf(szSID + wcslen(szSID), L"%lu",
  1686. (ULONG)(pSIA->Value[5] ) +
  1687. (ULONG)(pSIA->Value[4] << 8) +
  1688. (ULONG)(pSIA->Value[3] << 16) +
  1689. (ULONG)(pSIA->Value[2] << 24));
  1690. }
  1691. for(i = 0 ; i < dwSubAuthorities && dwRetCode == ERROR_SUCCESS; i++)
  1692. {
  1693. if ( dwSIDSize > _MAX_PATH * sizeof ( char ) )
  1694. {
  1695. dwRetCode = ERROR_INSUFFICIENT_BUFFER;
  1696. }
  1697. else
  1698. {
  1699. try
  1700. {
  1701. dwSIDSize += swprintf(szSID + dwSIDSize, L"-%lu", *GetSidSubAuthority(pSID, i)) ;
  1702. }
  1703. catch ( ... )
  1704. {
  1705. dwRetCode = ERROR_INVALID_PARAMETER;
  1706. }
  1707. }
  1708. }
  1709. if ( dwRetCode == ERROR_SUCCESS )
  1710. {
  1711. // See if the key already exists
  1712. //==============================
  1713. dwRetCode = Reg.Open(HKEY_USERS, szSID, KEY_READ) ;
  1714. // We need to keep a handle open. See m_hKey below, so we'll let the destructor close this.
  1715. // Reg.vClose();
  1716. if(dwRetCode != ERROR_SUCCESS)
  1717. {
  1718. // Try to locate user's registry hive
  1719. //===================================
  1720. swprintf(szTemp, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%s", szSID) ;
  1721. dwRetCode = Reg.Open(HKEY_LOCAL_MACHINE, szTemp, KEY_READ);
  1722. if(dwRetCode == ERROR_SUCCESS)
  1723. {
  1724. CHString chsTemp;
  1725. dwRetCode = Reg.GetCurrentKeyValue ( L"ProfileImagePath", chsTemp );
  1726. Reg.Close();
  1727. if(dwRetCode == ERROR_SUCCESS)
  1728. {
  1729. // NT 4 doesn't include the file name in the registry
  1730. //===================================================
  1731. if(!IsLessThan4())
  1732. {
  1733. chsTemp += L"\\NTUSER.DAT";
  1734. }
  1735. ExpandEnvironmentStrings ( (LPCTSTR) chsTemp, szTemp, _MAX_PATH ) ;
  1736. // Try it three times, another process may have the file open
  1737. bool bTryTryAgain = false;
  1738. int nTries = 0;
  1739. do{
  1740. // need to serialize access, using "write" because RegLoadKey wants exclusive access
  1741. // even though it is a read operation
  1742. try
  1743. {
  1744. EnterCriticalSection(&m_cs);
  1745. }
  1746. catch ( ... )
  1747. {
  1748. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1749. }
  1750. try
  1751. {
  1752. dwRetCode = (DWORD) RegLoadKey(HKEY_USERS, szSID, szTemp) ;
  1753. }
  1754. catch(...)
  1755. {
  1756. SafeLeaveCriticalSection(&m_cs);
  1757. throw;
  1758. }
  1759. SafeLeaveCriticalSection(&m_cs);
  1760. if((dwRetCode == ERROR_SHARING_VIOLATION) && (++nTries < 11))
  1761. {
  1762. Sleep(20 * nTries);
  1763. bTryTryAgain = true;
  1764. }
  1765. else
  1766. {
  1767. bTryTryAgain = false;
  1768. }
  1769. }while (bTryTryAgain);
  1770. }
  1771. }
  1772. }
  1773. }
  1774. if(dwRetCode == ERROR_SUCCESS)
  1775. {
  1776. DWORD dwLen = 0L;
  1777. dwLen = wcslen ( szSID );
  1778. if ( dwLen < 1024 )
  1779. {
  1780. wcscpy(m_wcKeyName, szSID) ;
  1781. WCHAR wcKey[BUFF_SIZE];
  1782. if ( dwLen + wcslen(L"\\Software") < BUFF_SIZE )
  1783. {
  1784. wcscpy(wcKey, szSID);
  1785. wcscat(wcKey, L"\\Software");
  1786. LONG lRetVal = 0L;
  1787. lRetVal = RegOpenKeyExW(HKEY_USERS, wcKey, 0, KEY_QUERY_VALUE, &m_hKey);
  1788. if ( lRetVal != ERROR_SUCCESS )
  1789. {
  1790. dwRetCode = lRetVal;
  1791. }
  1792. }
  1793. else
  1794. {
  1795. dwRetCode = ERROR_OUTOFMEMORY ;
  1796. }
  1797. }
  1798. else
  1799. {
  1800. dwRetCode = ERROR_OUTOFMEMORY ;
  1801. }
  1802. }
  1803. }
  1804. else
  1805. {
  1806. dwRetCode = ERROR_BAD_USERNAME ;
  1807. }
  1808. // Restore original privilege level
  1809. //=================================
  1810. RestorePrivilege() ;
  1811. }
  1812. return dwRetCode ;
  1813. }
  1814. DWORD CRequestObject::UnloadHive(/*LPCWSTR pszKeyName*/)
  1815. {
  1816. DWORD dwRetCode = ( DWORD ) E_FAIL;
  1817. if(m_hKey != NULL){
  1818. RegCloseKey(m_hKey);
  1819. m_hKey = NULL;
  1820. }
  1821. if ( ( dwRetCode = AcquirePrivilege() ) == ERROR_SUCCESS )
  1822. {
  1823. try
  1824. {
  1825. EnterCriticalSection(&m_cs);
  1826. }
  1827. catch ( ... )
  1828. {
  1829. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1830. }
  1831. try
  1832. {
  1833. dwRetCode = RegUnLoadKey(HKEY_USERS, m_wcKeyName);
  1834. }
  1835. catch(...)
  1836. {
  1837. SafeLeaveCriticalSection(&m_cs);
  1838. throw;
  1839. }
  1840. SafeLeaveCriticalSection(&m_cs);
  1841. RestorePrivilege() ;
  1842. }
  1843. DWORD dwRetCodeHelp = ERROR_SUCCESS;
  1844. if ( FAILED ( dwRetCodeHelp = ( DWORD ) CoImpersonateClient() ) && SUCCEEDED ( dwRetCode ) )
  1845. {
  1846. // return failure in the case ofimpersonation failed
  1847. dwRetCode = dwRetCodeHelp;
  1848. }
  1849. return dwRetCode ;
  1850. }
  1851. DWORD CRequestObject::AcquirePrivilege()
  1852. {
  1853. BOOL bRetCode = FALSE;
  1854. HANDLE hToken = INVALID_HANDLE_VALUE ;
  1855. TOKEN_PRIVILEGES TPriv ;
  1856. LUID LUID ;
  1857. // Validate the platform
  1858. //======================
  1859. // Try getting the thread token. If it fails the first time it's
  1860. // because we're a system thread and we don't yet have a thread
  1861. // token, so just impersonate self and try again.
  1862. if (OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
  1863. TOKEN_QUERY, FALSE, &hToken))
  1864. {
  1865. try{
  1866. GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &m_dwSize);
  1867. if (m_dwSize > 0){
  1868. // This is cleaned in the destructor, so no try/catch required
  1869. m_pOriginalPriv = (TOKEN_PRIVILEGES*) new BYTE[m_dwSize];
  1870. if (m_pOriginalPriv == NULL){
  1871. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1872. }
  1873. }
  1874. if(m_pOriginalPriv && GetTokenInformation(hToken, TokenPrivileges, m_pOriginalPriv, m_dwSize, &m_dwSize)){
  1875. bRetCode = LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &LUID);
  1876. if(bRetCode){
  1877. TPriv.PrivilegeCount = 1 ;
  1878. TPriv.Privileges[0].Luid = LUID ;
  1879. TPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1880. bRetCode = AdjustTokenPrivileges(hToken, FALSE, &TPriv,
  1881. sizeof(TOKEN_PRIVILEGES), NULL, NULL);
  1882. }
  1883. bRetCode = LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &LUID);
  1884. if(bRetCode){
  1885. TPriv.PrivilegeCount = 1 ;
  1886. TPriv.Privileges[0].Luid = LUID ;
  1887. TPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1888. bRetCode = AdjustTokenPrivileges(hToken, FALSE, &TPriv,
  1889. sizeof(TOKEN_PRIVILEGES), NULL, NULL) ;
  1890. }
  1891. }
  1892. }catch(...){
  1893. CloseHandle(hToken);
  1894. throw ;
  1895. }
  1896. CloseHandle(hToken);
  1897. }
  1898. if(!bRetCode){
  1899. return GetLastError();
  1900. }
  1901. return ERROR_SUCCESS ;
  1902. }
  1903. void CRequestObject::RestorePrivilege()
  1904. {
  1905. if (m_pOriginalPriv != NULL){
  1906. HANDLE hToken;
  1907. try{
  1908. if(OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  1909. TRUE, &hToken)){
  1910. AdjustTokenPrivileges(hToken, FALSE, m_pOriginalPriv, m_dwSize, NULL, NULL);
  1911. CloseHandle(hToken) ;
  1912. }
  1913. }catch(...){
  1914. delete m_pOriginalPriv;
  1915. m_pOriginalPriv = NULL;
  1916. m_dwSize = 0;
  1917. throw;
  1918. }
  1919. delete m_pOriginalPriv;
  1920. m_pOriginalPriv = NULL;
  1921. m_dwSize = 0;
  1922. }
  1923. }
  1924. //Properties
  1925. /////////////////////
  1926. const char * pAccesses = "Accesses";
  1927. const char * pAction = "Action";
  1928. const char * pActionID = "ActionID";
  1929. const char * pAntecedent = "Antecedent";
  1930. const char * pAppData = "AppData";
  1931. const char * pAppID = "AppID";
  1932. const char * pArgument = "Argument";
  1933. const char * pArguments = "Arguments";
  1934. const char * pAttribute = "Attribute";
  1935. const char * pAttributes = "Attributes";
  1936. const char * pCaption = "Caption";
  1937. const char * pCabinet = "Cabinet";
  1938. const char * pCheck = "Check";
  1939. const char * pCheckID = "CheckID";
  1940. const char * pCLSID = "CLSID";
  1941. const char * pCommand = "Command";
  1942. const char * pCommandLine = "CommandLine";
  1943. const char * pComponent = "Component";
  1944. const char * pComponentID = "ComponentID";
  1945. const char * pCondition = "Condition";
  1946. const char * pContext = "Context";
  1947. const char * pContentType = "ContentType";
  1948. const char * pCost = "Cost";
  1949. const char * pCreationClassName = "CreationClassName";
  1950. const char * pDataSource = "DataSource";
  1951. const char * pDefaultDir = "DefaultDir";
  1952. const char * pDefInprocHandler = "DefInprocHandler";
  1953. const char * pDependencies = "Dependencies";
  1954. const char * pDependent = "Dependent";
  1955. const char * pDescription = "Description";
  1956. const char * pDestination = "Destination";
  1957. const char * pDestFolder = "DestFolder";
  1958. const char * pDestName = "DestName";
  1959. const char * pDirectory = "Directory";
  1960. const char * pDirectoryName = "DirectoryName";
  1961. const char * pDirectoryPath = "DirectoryPath";
  1962. const char * pDirProperty = "DirProperty";
  1963. const char * pDiskID = "DiskID";
  1964. const char * pDiskPrompt = "DiskPrompt";
  1965. const char * pDisplay = "Display";
  1966. const char * pDisplayName = "DisplayName";
  1967. const char * pDomain = "Domain";
  1968. const char * pDriver = "Driver";
  1969. const char * pDriverDescription = "DriverDescription";
  1970. const char * pElement = "Element";
  1971. const char * pEntryName = "EntryName";
  1972. const char * pEntryValue = "EntryValue";
  1973. const char * pEnvironment = "Environment";
  1974. const char * pError = "Error";
  1975. const char * pErrorControl = "ErrorControl";
  1976. const char * pEvent = "Event";
  1977. const char * pExpression = "Expression";
  1978. const char * pExpressionType = "ExpressionType";
  1979. const char * pExtension = "Extension";
  1980. const char * pFeature = "Feature";
  1981. const char * pFeatures = "Features";
  1982. const char * pField = "Field";
  1983. const char * pFile = "File";
  1984. const char * pFileKey = "FileKey";
  1985. const char * pFileName = "FileName";
  1986. const char * pFileSize = "FileSize";
  1987. const char * pFileTypeMask = "FileTypeMask";
  1988. const char * pFontTitle = "FontTitle";
  1989. const char * pGroupComponent = "GroupComponent";
  1990. const char * pHotKey = "HotKey";
  1991. const char * pID = "ID";
  1992. const char * pIdentificationCode = "IdentificationCode";
  1993. const char * pIdentifyingNumber = "IdentifyingNumber";
  1994. const char * pIniFile = "IniFile";
  1995. const char * pInsertable = "Insertable";
  1996. const char * pInstallDate = "InstallDate";
  1997. const char * pInstallDate2 = "InstallDate2";
  1998. const char * pInstallLocation = "InstallLocation";
  1999. const char * pInstallMode = "InstallMode";
  2000. const char * pInstallState = "InstallState";
  2001. const char * pKey = "Key";
  2002. const char * pLanguage = "Language";
  2003. const char * pLastSequence = "LastSequence";
  2004. const char * pLastUse = "LastUse";
  2005. const char * pLevel = "Level";
  2006. const char * pLibID = "LibID";
  2007. const char * pLoadOrderGroup = "LoadOrderGroup";
  2008. const char * pLocation = "Location";
  2009. const char * pManufacturer = "Manufacturer";
  2010. const char * pMaxDate = "MaxDate";
  2011. const char * pMaxSize = "MaxSize";
  2012. const char * pMaxVersion = "MaxVersion";
  2013. const char * pMessage = "Message";
  2014. const char * pMIME = "MIME";
  2015. const char * pMinDate = "MinDate";
  2016. const char * pMinSize = "MinSize";
  2017. const char * pMinVersion = "MinVersion";
  2018. const char * pName = "Name";
  2019. const char * pNext = "Next";
  2020. const char * pOperator = "Operator";
  2021. const char * pOptions = "Options";
  2022. const char * pPackageCache = "PackageCache";
  2023. const char * pParent = "Parent";
  2024. const char * pPartComponent = "PartComponent";
  2025. const char * pPassword = "Password";
  2026. const char * pPatch = "Patch";
  2027. const char * pPatchID = "PatchID";
  2028. const char * pPatchSize = "PatchSize";
  2029. const char * pPath = "Path";
  2030. const char * pPermission = "Permission";
  2031. const char * pPrior = "Prior";
  2032. const char * pProduct = "Product";
  2033. const char * pProductCode = "ProductCode";
  2034. const char * pProductName = "ProductName";
  2035. const char * pProductVersion = "ProductVersion";
  2036. const char * pProgID = "ProgID";
  2037. const char * pProperty = "Property";
  2038. const char * pQual = "Qual";
  2039. const char * pRegistration = "Registration";
  2040. const char * pRegistry = "Registry";
  2041. const char * pRemoteName = "RemoteName";
  2042. const char * pReserveKey = "ReserveKey";
  2043. const char * pReserveLocal = "ReserveLocal";
  2044. const char * pReserveSource = "ReserveSource";
  2045. const char * pResource = "Resource";
  2046. const char * pRoot = "Root";
  2047. const char * pSection = "Section";
  2048. const char * pSequence = "Sequence";
  2049. const char * pServiceType = "ServiceType";
  2050. const char * pSetting = "Setting";
  2051. const char * pSetupFile = "SetupFile";
  2052. const char * pShellNew = "ShellNew";
  2053. const char * pShellNewValue = "ShellNewValue";
  2054. const char * pSignature = "Signature";
  2055. const char * pShortcut = "Shortcut";
  2056. const char * pShowCmd = "ShowCmd";
  2057. const char * pSoftware = "Software";
  2058. const char * pSoftwareElementID = "SoftwareElementID";
  2059. const char * pSoftwareElementState = "SoftwareElementState";
  2060. const char * pSource = "Source";
  2061. const char * pSourceFolder = "SourceFolder";
  2062. const char * pSourceName = "SourceName";
  2063. const char * pStartMode = "StartMode";
  2064. const char * pStartName = "StartName";
  2065. const char * pStartType = "StartType";
  2066. const char * pStatus = "Status";
  2067. const char * pSystem = "System";
  2068. const char * pSystemCreationClassName = "SystemCreationClassName";
  2069. const char * pSystemName = "SystemName";
  2070. const char * pTable = "Table";
  2071. const char * pTarget = "Target";
  2072. const char * pTargetOperatingSystem = "TargetOperatingSystem";
  2073. const char * pTranslator = "Translator";
  2074. const char * pType = "Type";
  2075. const char * pUpgradeCode = "UpgradeCode";
  2076. const char * pUser = "User";
  2077. const char * pValue = "Value";
  2078. const char * pVendor = "Vendor";
  2079. const char * pVerb = "Verb";
  2080. const char * pVersion = "Version";
  2081. const char * pVolumeLabel = "VolumeLabel";
  2082. const char * pWait = "Wait";
  2083. const char * pWkDir = "WkDir";