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.

1430 lines
36 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2003 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ResourceObject.cpp
  7. //
  8. // Description:
  9. // CResourceObject automation class implementation.
  10. //
  11. // Maintained By:
  12. // Ozan Ozhan (OzanO) 27-MAR-2002
  13. // Geoff Pease (GPease) 08-FEB-2000
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16. #include "Pch.h"
  17. #include "ResourceObject.h"
  18. DEFINE_THISCLASS( "CResourceObject" );
  19. #define STATIC_AUTOMATION_METHODS 5
  20. //////////////////////////////////////////////////////////////////////////////
  21. //
  22. // Constructor
  23. //
  24. //////////////////////////////////////////////////////////////////////////////
  25. CResourceObject::CResourceObject(
  26. RESOURCE_HANDLE hResourceIn,
  27. PLOG_EVENT_ROUTINE plerIn,
  28. HKEY hkeyIn,
  29. LPCWSTR pszNameIn
  30. ) :
  31. m_hResource( hResourceIn ),
  32. m_pler( plerIn ),
  33. m_hkey( hkeyIn ),
  34. m_pszName( pszNameIn )
  35. {
  36. TraceFunc( "" );
  37. Assert( m_cRef == 0 );
  38. AddRef();
  39. TraceFuncExit();
  40. } //*** CRsesourceObject::CResourceObject
  41. //////////////////////////////////////////////////////////////////////////////
  42. //
  43. // Destructor
  44. //
  45. //////////////////////////////////////////////////////////////////////////////
  46. CResourceObject::~CResourceObject( void )
  47. {
  48. TraceFunc( "" );
  49. // Don't free m_pszName.
  50. // Don't close m_hkey.
  51. TraceFuncExit();
  52. } //*** CResourceObject::~CResourceObject
  53. //****************************************************************************
  54. //
  55. // IUnknown
  56. //
  57. //****************************************************************************
  58. //////////////////////////////////////////////////////////////////////////////
  59. //
  60. // STDMETHODIMP
  61. // CScriptResource::[IUnknown] QueryInterface(
  62. // REFIID riid,
  63. // LPVOID * ppv
  64. // )
  65. //
  66. //////////////////////////////////////////////////////////////////////////////
  67. STDMETHODIMP
  68. CResourceObject::QueryInterface(
  69. REFIID riidIn
  70. , void ** ppvOut
  71. )
  72. {
  73. TraceQIFunc( riidIn, ppvOut );
  74. HRESULT hr = S_OK;
  75. *ppvOut = NULL;
  76. if ( riidIn == IID_IUnknown )
  77. {
  78. *ppvOut = TraceInterface( __THISCLASS__, IUnknown, (IDispatchEx*) this, 0 );
  79. hr = S_OK;
  80. }
  81. else if ( riidIn == IID_IDispatchEx )
  82. {
  83. *ppvOut = TraceInterface( __THISCLASS__, IDispatchEx, (IDispatchEx*) this, 0 );
  84. hr = S_OK;
  85. }
  86. else if ( riidIn == IID_IDispatch )
  87. {
  88. *ppvOut = TraceInterface( __THISCLASS__, IDispatch, (IDispatchEx*) this, 0 );
  89. hr = S_OK;
  90. }
  91. else
  92. {
  93. *ppvOut = NULL;
  94. hr = E_NOINTERFACE;
  95. }
  96. if ( SUCCEEDED( hr ) )
  97. {
  98. ((IUnknown *) *ppvOut)->AddRef();
  99. }
  100. QIRETURN( hr, riidIn );
  101. } //*** CResourceObject::QueryInterface
  102. //////////////////////////////////////////////////////////////////////////////
  103. //
  104. // STDMETHODIMP_( ULONG )
  105. // CScriptResource::[IUnknown] AddRef( void )
  106. //
  107. //////////////////////////////////////////////////////////////////////////////
  108. STDMETHODIMP_( ULONG )
  109. CResourceObject::AddRef( void )
  110. {
  111. TraceFunc( "[IUnknown]" );
  112. InterlockedIncrement( &m_cRef );
  113. CRETURN( m_cRef );
  114. } //*** CResourceObject::AddRef
  115. //////////////////////////////////////////////////////////////////////////////
  116. //
  117. // STDMETHODIMP_( ULONG )
  118. // CScriptResource::[IUnknown] Release( void )
  119. //
  120. //////////////////////////////////////////////////////////////////////////////
  121. STDMETHODIMP_( ULONG )
  122. CResourceObject::Release( void )
  123. {
  124. TraceFunc( "[IUnknown]" );
  125. LONG cRef;
  126. cRef = InterlockedDecrement( &m_cRef );
  127. if ( cRef == 0 )
  128. {
  129. TraceDo( delete this );
  130. }
  131. CRETURN( cRef );
  132. } //*** CResourceObject::Release
  133. //****************************************************************************
  134. //
  135. // IDispatch
  136. //
  137. //****************************************************************************
  138. //////////////////////////////////////////////////////////////////////////////
  139. //
  140. // STDMETHODIMP
  141. // CResourceObject::GetTypeInfoCount(
  142. // UINT * pctinfo // out
  143. // )
  144. //
  145. //////////////////////////////////////////////////////////////////////////////
  146. STDMETHODIMP
  147. CResourceObject::GetTypeInfoCount(
  148. UINT * pctinfo // out
  149. )
  150. {
  151. TraceFunc( "[IDispatch]" );
  152. HRESULT hr = E_NOTIMPL;
  153. if ( pctinfo == NULL )
  154. {
  155. hr = THR( E_POINTER );
  156. goto Cleanup;
  157. }
  158. *pctinfo = 0;
  159. Cleanup:
  160. HRETURN( hr );
  161. } //*** CResourceObject::GetTypeInfoCount
  162. //////////////////////////////////////////////////////////////////////////////
  163. //
  164. // STDMETHODIMP
  165. // CResourceObject::GetTypeInfo(
  166. // UINT iTInfo, // in
  167. // LCID lcid, // in
  168. // ITypeInfo * * ppTInfo // out
  169. // )
  170. //
  171. //////////////////////////////////////////////////////////////////////////////
  172. STDMETHODIMP
  173. CResourceObject::GetTypeInfo(
  174. UINT iTInfo // in
  175. , LCID lcid // in
  176. , ITypeInfo ** ppTInfo // out
  177. )
  178. {
  179. TraceFunc( "[IDispatch]" );
  180. HRESULT hr = E_NOTIMPL;
  181. if ( ppTInfo == NULL )
  182. {
  183. hr = THR( E_POINTER );
  184. goto Cleanup;
  185. }
  186. *ppTInfo = NULL;
  187. Cleanup:
  188. HRETURN( hr );
  189. } //*** CResourceObject::GetTypeInfo
  190. //////////////////////////////////////////////////////////////////////////////
  191. //
  192. // STDMETHODIMP
  193. // CResourceObject::GetIDsOfNames(
  194. // REFIID riid, // in
  195. // LPOLESTR * rgszNames, // in
  196. // UINT cNames, // in
  197. // LCID lcid, // in
  198. // DISPID * rgDispId // out
  199. // )
  200. //
  201. //////////////////////////////////////////////////////////////////////////////
  202. STDMETHODIMP
  203. CResourceObject::GetIDsOfNames(
  204. REFIID riid // in
  205. , LPOLESTR * rgszNames // in
  206. , UINT cNames // in
  207. , LCID lcid // in
  208. , DISPID * rgDispId // out
  209. )
  210. {
  211. TraceFunc( "[IDispatch]" );
  212. HRESULT hr = E_NOTIMPL;
  213. ZeroMemory( rgDispId, cNames * sizeof(DISPID) );
  214. HRETURN( hr );
  215. } //*** CResourceObject::GetIDsOfNames
  216. //////////////////////////////////////////////////////////////////////////////
  217. //
  218. // STDMETHODIMP
  219. // CResourceObject::Invoke(
  220. // DISPID dispIdMember, // in
  221. // REFIID riid, // in
  222. // LCID lcid, // in
  223. // WORD wFlags, // in
  224. // DISPPARAMS *pDispParams, // out in
  225. // VARIANT *pVarResult, // out
  226. // EXCEPINFO *pExcepInfo, // out
  227. // UINT *puArgErr // out
  228. // )
  229. //
  230. //////////////////////////////////////////////////////////////////////////////
  231. STDMETHODIMP
  232. CResourceObject::Invoke(
  233. DISPID dispIdMember // in
  234. , REFIID riid // in
  235. , LCID lcid // in
  236. , WORD wFlags // in
  237. , DISPPARAMS * pDispParams // out in
  238. , VARIANT * pVarResult // out
  239. , EXCEPINFO * pExcepInfo // out
  240. , UINT * puArgErr // out
  241. )
  242. {
  243. TraceFunc( "[IDispatch]" );
  244. HRESULT hr = E_NOTIMPL;
  245. HRETURN( hr );
  246. } //*** CResourceObject::Invoke
  247. //****************************************************************************
  248. //
  249. // IDispatchEx
  250. //
  251. //****************************************************************************
  252. //////////////////////////////////////////////////////////////////////////////
  253. //
  254. // STDMETHODIMP
  255. // CResourceObject::GetDispID(
  256. // BSTR bstrName, // in
  257. // DWORD grfdex, //in
  258. // DISPID *pid //out
  259. // )
  260. //
  261. //////////////////////////////////////////////////////////////////////////////
  262. STDMETHODIMP
  263. CResourceObject::GetDispID(
  264. BSTR bstrName // in
  265. , DWORD grfdex // in
  266. , DISPID * pid // out
  267. )
  268. {
  269. TraceFunc( "[IDispatchEx]" );
  270. HRESULT hr = S_OK;
  271. if ( ( pid == NULL ) || ( bstrName == NULL ) )
  272. {
  273. hr = THR( E_POINTER );
  274. goto Cleanup;
  275. }
  276. TraceMsg( mtfCALLS, "Looking for: %s\n", bstrName );
  277. if ( ClRtlStrICmp( bstrName, L"Name" ) == 0 )
  278. {
  279. *pid = 0;
  280. }
  281. else if ( ClRtlStrICmp( bstrName, L"LogInformation" ) == 0 )
  282. {
  283. *pid = 1;
  284. }
  285. else if ( ClRtlStrICmp( bstrName, L"AddProperty" ) == 0 )
  286. {
  287. *pid = 2;
  288. }
  289. else if ( ClRtlStrICmp( bstrName, L"RemoveProperty" ) == 0 )
  290. {
  291. *pid = 3;
  292. }
  293. else if ( ClRtlStrICmp( bstrName, L"PropertyExists" ) == 0 )
  294. {
  295. *pid = 4;
  296. }
  297. else
  298. {
  299. //
  300. // See if it is a private property.
  301. //
  302. DWORD dwIndex;
  303. DWORD scErr = ERROR_SUCCESS;
  304. hr = DISP_E_UNKNOWNNAME;
  305. //
  306. // Enum all the value under the \Cluster\Resources\{Resource}\Parameters.
  307. //
  308. for( dwIndex = 0; scErr == ERROR_SUCCESS; dwIndex ++ )
  309. {
  310. WCHAR szName[ 1024 ]; // randomly large
  311. DWORD cbName = sizeof(szName)/sizeof(szName[0]);
  312. scErr = ClusterRegEnumValue( m_hkey,
  313. dwIndex,
  314. szName,
  315. &cbName,
  316. NULL,
  317. NULL,
  318. NULL
  319. );
  320. if ( scErr == ERROR_NO_MORE_ITEMS )
  321. break; // done!
  322. if ( scErr != ERROR_SUCCESS )
  323. {
  324. hr = THR( HRESULT_FROM_WIN32( scErr ) );
  325. goto Error;
  326. }
  327. if ( ClRtlStrICmp( bstrName, szName ) == 0 )
  328. {
  329. //
  330. // Found a match.
  331. //
  332. *pid = STATIC_AUTOMATION_METHODS + dwIndex;
  333. hr = S_OK;
  334. break;
  335. }
  336. //
  337. // ...else keep going.
  338. //
  339. }
  340. }
  341. Cleanup:
  342. HRETURN( hr );
  343. Error:
  344. LogError( hr );
  345. goto Cleanup;
  346. } //*** CResourceObject::GetDiskID
  347. //////////////////////////////////////////////////////////////////////////////
  348. //
  349. // STDMETHODIMP
  350. // CResourceObject::InvokeEx(
  351. // DISPID idIn,
  352. // LCID lcidIn,
  353. // WORD wFlagsIn,
  354. // DISPPARAMS * pdpIn,
  355. // VARIANT * pvarResOut,
  356. // EXCEPINFO * peiOut,
  357. // IServiceProvider * pspCallerIn
  358. // )
  359. //
  360. //////////////////////////////////////////////////////////////////////////////
  361. STDMETHODIMP
  362. CResourceObject::InvokeEx(
  363. DISPID idIn
  364. , LCID lcidIn
  365. , WORD wFlagsIn
  366. , DISPPARAMS * pdpIn
  367. , VARIANT * pvarResOut
  368. , EXCEPINFO * peiOut
  369. , IServiceProvider * pspCallerIn
  370. )
  371. {
  372. TraceFunc2( "[IDispatchEx] idIn = %u, ..., wFlagsIn = 0x%08x, ...", idIn, wFlagsIn );
  373. HRESULT hr = DISP_E_MEMBERNOTFOUND;
  374. switch ( idIn )
  375. {
  376. case 0: // Name
  377. if ( wFlagsIn & DISPATCH_PROPERTYGET )
  378. {
  379. pvarResOut->vt = VT_BSTR;
  380. pvarResOut->bstrVal = SysAllocString( m_pszName );
  381. if ( pvarResOut->bstrVal == NULL )
  382. {
  383. hr = E_OUTOFMEMORY;
  384. }
  385. else
  386. {
  387. hr = S_OK;
  388. }
  389. }
  390. break;
  391. case 1: // LogInformation
  392. if ( wFlagsIn & DISPATCH_METHOD )
  393. {
  394. hr = THR( LogInformation( pdpIn->rgvarg->bstrVal ) );
  395. }
  396. break;
  397. case 2: // AddProperty
  398. if ( wFlagsIn & DISPATCH_METHOD )
  399. {
  400. hr = THR( AddPrivateProperty( pdpIn ) );
  401. }
  402. break;
  403. case 3: // RemoveProperty
  404. if ( wFlagsIn & DISPATCH_METHOD )
  405. {
  406. hr = THR( RemovePrivateProperty( pdpIn ) );
  407. }
  408. break;
  409. case 4: // PropertyExists
  410. if ( wFlagsIn & DISPATCH_METHOD )
  411. {
  412. pvarResOut->vt = VT_BOOL;
  413. hr = THR( PrivatePropertyExists( pdpIn ) );
  414. //
  415. // Property exists if hr is S_OK
  416. //
  417. if ( hr == S_OK )
  418. {
  419. pvarResOut->boolVal = VARIANT_TRUE;
  420. }
  421. else if ( hr == S_FALSE )
  422. {
  423. hr = S_OK; // Set hr to S_OK since there's no failure at all
  424. pvarResOut->boolVal = VARIANT_FALSE;
  425. }
  426. } // if: ( wFlagsIn & DISPATCH_METHOD )
  427. break;
  428. default:
  429. //
  430. // See if it is a private property.
  431. //
  432. if ( wFlagsIn & DISPATCH_PROPERTYGET )
  433. {
  434. hr = THR( ReadPrivateProperty( idIn - STATIC_AUTOMATION_METHODS, pvarResOut ) );
  435. }
  436. else if ( wFlagsIn & DISPATCH_PROPERTYPUT )
  437. {
  438. hr = THR( WritePrivateProperty( idIn - STATIC_AUTOMATION_METHODS, pdpIn ) );
  439. }
  440. break;
  441. } // switch: id
  442. HRETURN( hr );
  443. } //*** CResourceObject::InvokeEx
  444. //////////////////////////////////////////////////////////////////////////////
  445. //
  446. // STDMETHODIMP
  447. // CResourceObject::DeleteMemberByName(
  448. // BSTR bstr, // in
  449. // DWORD grfdex // in
  450. // )
  451. //
  452. //////////////////////////////////////////////////////////////////////////////
  453. STDMETHODIMP
  454. CResourceObject::DeleteMemberByName(
  455. BSTR bstr // in
  456. , DWORD grfdex // in
  457. )
  458. {
  459. TraceFunc( "[IDispatchEx]" );
  460. HRESULT hr = E_NOTIMPL;
  461. HRETURN( hr );
  462. } //*** CResourceObject::DeleteMemberByName
  463. //////////////////////////////////////////////////////////////////////////////
  464. //
  465. // STDMETHODIMP
  466. // CResourceObject::DeleteMemberByDispID(
  467. // DISPID id // in
  468. // )
  469. //
  470. //////////////////////////////////////////////////////////////////////////////
  471. STDMETHODIMP
  472. CResourceObject::DeleteMemberByDispID(
  473. DISPID id // in
  474. )
  475. {
  476. TraceFunc1( "[IDispatchEx] id = %u", id );
  477. HRESULT hr = E_NOTIMPL;
  478. HRETURN( hr );
  479. } //*** CResourceObject::DeleteMemberByDispID
  480. //////////////////////////////////////////////////////////////////////////////
  481. //
  482. // STDMETHODIMP
  483. // CResourceObject::GetMemberProperties(
  484. // DISPID id, // in
  485. // DWORD grfdexFetch, // in
  486. // DWORD * pgrfdex // out
  487. // )
  488. //
  489. //////////////////////////////////////////////////////////////////////////////
  490. STDMETHODIMP
  491. CResourceObject::GetMemberProperties(
  492. DISPID id // in
  493. , DWORD grfdexFetch // in
  494. , DWORD * pgrfdex // out
  495. )
  496. {
  497. TraceFunc2( "[IDispatchEx] id = %u, grfdexFetch = 0x%08x", id, grfdexFetch );
  498. HRESULT hr = E_NOTIMPL;
  499. HRETURN( hr );
  500. } //*** CResourceObject::GetMemberProperties
  501. //////////////////////////////////////////////////////////////////////////////
  502. //
  503. // STDMETHODIMP
  504. // CResourceObject::GetMemberName(
  505. // DISPID id, // in
  506. // BSTR * pbstrName // out
  507. // )
  508. //
  509. //////////////////////////////////////////////////////////////////////////////
  510. STDMETHODIMP
  511. CResourceObject::GetMemberName(
  512. DISPID id // in
  513. , BSTR * pbstrName // out
  514. )
  515. {
  516. TraceFunc1( "[IDispatchEx] id = %u, ...", id );
  517. HRESULT hr = E_NOTIMPL;
  518. HRETURN( hr );
  519. } //*** CResourceObject::GetMemberName
  520. //////////////////////////////////////////////////////////////////////////////
  521. //
  522. // STDMETHODIMP
  523. // CResourceObject::GetNextDispID(
  524. // DWORD grfdex, // in
  525. // DISPID id, // in
  526. // DISPID * pid // out
  527. // )
  528. //
  529. //////////////////////////////////////////////////////////////////////////////
  530. STDMETHODIMP
  531. CResourceObject::GetNextDispID(
  532. DWORD grfdex // in
  533. , DISPID id // in
  534. , DISPID * pid // out
  535. )
  536. {
  537. TraceFunc2( "[IDispatchEx] grfdex = 0x%08x, id = %u, ...", grfdex, id );
  538. HRESULT hr = E_NOTIMPL;
  539. HRETURN( hr );
  540. } //*** CResourceObject::GetNextDiskID
  541. //////////////////////////////////////////////////////////////////////////////
  542. //
  543. // STDMETHODIMP
  544. // CResourceObject::GetNameSpaceParent(
  545. // IUnknown * * ppunk // out
  546. // )
  547. //
  548. //////////////////////////////////////////////////////////////////////////////
  549. STDMETHODIMP
  550. CResourceObject::GetNameSpaceParent(
  551. IUnknown ** ppunk // out
  552. )
  553. {
  554. TraceFunc( "[IDispatchEx]" );
  555. HRESULT hr = E_NOTIMPL;
  556. if ( ppunk == NULL )
  557. {
  558. hr = THR( E_POINTER );
  559. goto Cleanup;
  560. }
  561. *ppunk = NULL;
  562. Cleanup:
  563. HRETURN( hr );
  564. } //*** CResourceObject::GetNameSpaceParent
  565. //****************************************************************************
  566. //
  567. // Private Methods
  568. //
  569. //****************************************************************************
  570. //////////////////////////////////////////////////////////////////////////////
  571. //
  572. // STDMETHODIMP
  573. // CResourceObject::LogError(
  574. // HRESULT hrIn
  575. // )
  576. //
  577. //////////////////////////////////////////////////////////////////////////////
  578. STDMETHODIMP
  579. CResourceObject::LogError(
  580. HRESULT hrIn
  581. )
  582. {
  583. TraceFunc1( "hrIn = 0x%08x", hrIn );
  584. HRESULT hr = S_OK;
  585. TraceMsg( mtfCALLS, "HRESULT: 0x%08x\n", hrIn );
  586. (ClusResLogEvent)( m_hResource, LOG_ERROR, L"HRESULT: 0x%1!08x!.\n", hrIn );
  587. HRETURN( hr );
  588. } //*** CResourceObject::LogError
  589. //////////////////////////////////////////////////////////////////////////////
  590. //
  591. // STDMETHODIMP
  592. // CResourceObject::ReadPrivateProperty(
  593. // DISPID idIn,
  594. // VARIANT * pvarResOut
  595. // )
  596. //
  597. //////////////////////////////////////////////////////////////////////////////
  598. STDMETHODIMP
  599. CResourceObject::ReadPrivateProperty(
  600. DISPID idIn
  601. , VARIANT * pvarResOut
  602. )
  603. {
  604. TraceFunc( "" );
  605. BSTR * pbstrList;
  606. BYTE rgbData[ 1024 ]; // randomly large
  607. WCHAR szName[ 1024 ]; // randomly large
  608. DWORD dwType;
  609. DWORD scErr;
  610. DWORD cbName = sizeof(szName)/sizeof(szName[0]);
  611. DWORD cbData = sizeof(rgbData);
  612. BOOL fFreepData = FALSE;
  613. LPBYTE pData = NULL;
  614. HRESULT hr = DISP_E_UNKNOWNNAME;
  615. //
  616. // We can jump to the exact entry because the script called
  617. // GetDispID() before calling this method.
  618. //
  619. for ( ;; )
  620. {
  621. scErr = ClusterRegEnumValue(
  622. m_hkey
  623. , idIn
  624. , szName
  625. , &cbName
  626. , &dwType
  627. , rgbData
  628. , &cbData
  629. );
  630. if ( scErr == ERROR_MORE_DATA )
  631. {
  632. //
  633. // Make some space if our stack buffer is too small.
  634. //
  635. pData = (LPBYTE) TraceAlloc( LMEM_FIXED, cbData );
  636. if ( pData == NULL )
  637. {
  638. hr = THR( E_OUTOFMEMORY );
  639. goto Cleanup;
  640. }
  641. fFreepData = TRUE;
  642. continue; // try again
  643. }
  644. if ( scErr == ERROR_NO_MORE_ITEMS )
  645. {
  646. goto Cleanup; // item must have dissappeared
  647. }
  648. if ( scErr != ERROR_SUCCESS )
  649. {
  650. hr = THR( HRESULT_FROM_WIN32( scErr ) );
  651. goto Error;
  652. }
  653. Assert( scErr == ERROR_SUCCESS );
  654. break; // exit loop
  655. } // for ever enumerating registry values
  656. //
  657. // It's a private property. Convert the data into the appropriate
  658. // VARIANT.
  659. //
  660. switch ( dwType )
  661. {
  662. case REG_DWORD:
  663. {
  664. DWORD * pdw = (DWORD *) rgbData;
  665. pvarResOut->vt = VT_I4;
  666. pvarResOut->intVal = *pdw;
  667. hr = S_OK;
  668. }
  669. break;
  670. case REG_EXPAND_SZ:
  671. {
  672. DWORD cbNeeded;
  673. WCHAR szExpandedString[ 2 * MAX_PATH ]; // randomly large
  674. DWORD cbSize = RTL_NUMBER_OF( szExpandedString );
  675. LPCWSTR pszData = (LPCWSTR) rgbData;
  676. cbNeeded = ExpandEnvironmentStringsW( pszData, szExpandedString, cbSize );
  677. if ( cbSize == 0 )
  678. {
  679. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  680. goto Cleanup;
  681. }
  682. if ( cbNeeded > cbSize )
  683. {
  684. hr = THR( E_OUTOFMEMORY );
  685. goto Cleanup;
  686. }
  687. pvarResOut->vt = VT_BSTR;
  688. pvarResOut->bstrVal = SysAllocString( szExpandedString );
  689. if ( pvarResOut->bstrVal == NULL )
  690. {
  691. hr = THR( E_OUTOFMEMORY );
  692. goto Cleanup;
  693. }
  694. hr = S_OK;
  695. }
  696. break;
  697. case REG_MULTI_SZ:
  698. {
  699. //
  700. // KB: gpease 08-FEB-2000
  701. // Currently VBScript doesn't support SAFEARRAYs. So someone
  702. // trying to access a multi-sz will get the following error:
  703. //
  704. // Error: 2148139466
  705. // Source: Microsoft VBScript runtime error
  706. // Description: Variable uses an Automation type not supported in VBScript
  707. //
  708. // The code is correct as far as I can tell, so I am just
  709. // going to leave it in (it doesn't AV or cause bad things
  710. // to happen).
  711. //
  712. LPWSTR psz;
  713. DWORD nCount;
  714. DWORD cbCount;
  715. DWORD cbBiggestOne;
  716. LPWSTR pszData = (LPWSTR) rgbData;
  717. SAFEARRAYBOUND rgsabound[ 1 ];
  718. //
  719. // Figure out how many item there are in the list.
  720. //
  721. cbBiggestOne = cbCount = nCount = 0;
  722. psz = pszData;
  723. while ( *psz != 0 )
  724. {
  725. psz++;
  726. cbCount ++;
  727. if ( *psz == 0 )
  728. {
  729. if ( cbCount > cbBiggestOne )
  730. {
  731. cbBiggestOne = cbCount;
  732. }
  733. cbCount = 0;
  734. nCount++;
  735. psz++;
  736. }
  737. }
  738. Assert( psz <= ( (LPWSTR) &rgbData[ cbData ] ) );
  739. //
  740. // Create a safe array to package the string into.
  741. //
  742. rgsabound[0].lLbound = 0;
  743. rgsabound[0].cElements = nCount;
  744. pvarResOut->vt = VT_SAFEARRAY;
  745. pvarResOut->parray = SafeArrayCreate( VT_BSTR, 1, rgsabound );
  746. if ( pvarResOut->parray == NULL )
  747. {
  748. hr = THR( E_OUTOFMEMORY );
  749. goto Cleanup;
  750. }
  751. //
  752. // Fix the memory location of the array so it can be accessed
  753. // thru an array pointer.
  754. //
  755. hr = THR( SafeArrayAccessData( pvarResOut->parray, (void**) &pbstrList ) );
  756. if ( FAILED( hr ) )
  757. {
  758. goto Error;
  759. }
  760. //
  761. // Convert the multi-string into BSTRs
  762. //
  763. psz = pszData;
  764. for( nCount = 0; *psz != 0 ; nCount ++ )
  765. {
  766. pbstrList[ nCount ] = SysAllocString( psz );
  767. if ( pbstrList[ nCount ] == NULL )
  768. {
  769. hr = THR( E_OUTOFMEMORY );
  770. goto Cleanup;
  771. }
  772. //
  773. // Skip the next entry.
  774. //
  775. while ( *psz != 0 )
  776. {
  777. psz++;
  778. }
  779. psz++;
  780. }
  781. Assert( psz <= ( (LPWSTR) &rgbData[ cbData ] ) );
  782. //
  783. // Release the array.
  784. //
  785. hr = THR( SafeArrayUnaccessData( pvarResOut->parray ) );
  786. if ( FAILED( hr ) )
  787. {
  788. goto Error;
  789. }
  790. hr = S_OK;
  791. }
  792. break;
  793. case REG_SZ:
  794. {
  795. LPCWSTR pszData = (LPCWSTR) rgbData;
  796. pvarResOut->bstrVal = SysAllocString( pszData );
  797. if ( pvarResOut->bstrVal == NULL )
  798. {
  799. hr = THR( E_OUTOFMEMORY );
  800. goto Cleanup;
  801. }
  802. pvarResOut->vt = VT_BSTR;
  803. hr = S_OK;
  804. }
  805. break;
  806. case REG_BINARY:
  807. default:
  808. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATATYPE );
  809. goto Error;
  810. } // switch: dwType
  811. Cleanup:
  812. if ( fFreepData && ( pData != NULL ) )
  813. {
  814. TraceFree( pData );
  815. }
  816. //
  817. // Make sure this has been wiped if there is a problem.
  818. //
  819. if ( FAILED( hr ) )
  820. {
  821. VariantClear( pvarResOut );
  822. }
  823. HRETURN( hr );
  824. Error:
  825. LogError( hr );
  826. goto Cleanup;
  827. } //*** CResourceObject::ReadPrivateProperty
  828. //////////////////////////////////////////////////////////////////////////////
  829. //
  830. // STDMETHODIMP
  831. // CResourceObject::WritePrivateProperty(
  832. // DISPID idIn,
  833. // DISPPARAMS * pdpIn
  834. // )
  835. //
  836. //////////////////////////////////////////////////////////////////////////////
  837. STDMETHODIMP
  838. CResourceObject::WritePrivateProperty(
  839. DISPID idIn
  840. , DISPPARAMS * pdpIn
  841. )
  842. {
  843. TraceFunc( "" );
  844. DWORD dwType;
  845. DWORD scErr;
  846. DWORD cbData;
  847. UINT uiArg;
  848. WCHAR szName [ 1024 ]; // randomly large
  849. DWORD cbName = sizeof(szName)/sizeof(szName[0]);
  850. HRESULT hr = DISP_E_UNKNOWNNAME;
  851. //
  852. // Do some parameter validation.
  853. //
  854. if ( ( pdpIn->cArgs != 1 ) || ( pdpIn->cNamedArgs > 1 ) )
  855. {
  856. hr = THR( DISP_E_BADPARAMCOUNT );
  857. goto Error;
  858. }
  859. //
  860. // We can jump to the exact entry because the script called
  861. // GetDispID() before calling this method. Here we are only
  862. // going to validate that the value exists and what type
  863. // the value is.
  864. //
  865. scErr = ClusterRegEnumValue( m_hkey,
  866. idIn,
  867. szName,
  868. &cbName,
  869. &dwType,
  870. NULL,
  871. NULL
  872. );
  873. if ( scErr == ERROR_NO_MORE_ITEMS )
  874. {
  875. goto Cleanup; // item must have dissappeared
  876. }
  877. if ( scErr != ERROR_SUCCESS )
  878. {
  879. hr = HRESULT_FROM_WIN32( TW32( scErr ) );
  880. goto Error;
  881. }
  882. //
  883. // It's a private property. Convert the script data into the
  884. // appropriate VARIANT and then write it into the hive.
  885. //
  886. switch ( dwType )
  887. {
  888. case REG_DWORD:
  889. {
  890. VARIANT var;
  891. VariantInit( &var );
  892. hr = THR( DispGetParam( pdpIn, (UINT) DISPID_PROPERTYPUT, VT_I4, &var, &uiArg ) );
  893. if ( FAILED( hr ) )
  894. {
  895. goto Error;
  896. }
  897. cbData = sizeof( var.intVal );
  898. scErr = TW32( ClusterRegSetValue( m_hkey, szName, dwType, (LPBYTE) &var.intVal, cbData ) );
  899. if ( scErr != ERROR_SUCCESS )
  900. {
  901. hr = HRESULT_FROM_WIN32( scErr );
  902. goto Error;
  903. }
  904. VariantClear( &var );
  905. hr = S_OK;
  906. }
  907. break;
  908. case REG_EXPAND_SZ:
  909. case REG_SZ:
  910. {
  911. VARIANT var;
  912. VariantInit( &var );
  913. hr = THR( DispGetParam( pdpIn, (UINT) DISPID_PROPERTYPUT, VT_BSTR, &var, &uiArg ) );
  914. if ( FAILED( hr ) )
  915. {
  916. goto Error;
  917. }
  918. cbData = sizeof(WCHAR) * ( SysStringLen( var.bstrVal ) + 1 );
  919. scErr = TW32( ClusterRegSetValue( m_hkey, szName, dwType, (LPBYTE) var.bstrVal, cbData ) );
  920. if ( scErr != ERROR_SUCCESS )
  921. {
  922. hr = HRESULT_FROM_WIN32( scErr );
  923. goto Error;
  924. }
  925. VariantClear( &var );
  926. hr = S_OK;
  927. }
  928. break;
  929. case REG_MULTI_SZ:
  930. case REG_BINARY:
  931. //
  932. // Can't handle these since VBScript can't generate them.
  933. //
  934. default:
  935. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATATYPE );
  936. goto Error;
  937. } // switch: dwType
  938. Cleanup:
  939. HRETURN( hr );
  940. Error:
  941. LogError( hr );
  942. goto Cleanup;
  943. } //*** CResourceObject::WritePrivateProperty
  944. //////////////////////////////////////////////////////////////////////////////
  945. //
  946. // STDMETHODIMP
  947. // CResourceObject::RemovePrivateProperty(
  948. // DISPPARAMS * pdpIn
  949. // )
  950. //
  951. //////////////////////////////////////////////////////////////////////////////
  952. STDMETHODIMP
  953. CResourceObject::RemovePrivateProperty(
  954. DISPPARAMS * pdpIn
  955. )
  956. {
  957. TraceFunc( "" );
  958. HRESULT hr;
  959. DWORD scErr;
  960. UINT uiArg;
  961. VARIANT var;
  962. VariantInit( &var );
  963. //
  964. // Do some parameter validation.
  965. //
  966. if ( pdpIn->cArgs != 1 || pdpIn->cNamedArgs > 1 )
  967. {
  968. hr = THR( DISP_E_BADPARAMCOUNT );
  969. goto Error;
  970. }
  971. //
  972. // Retrieve the name of the property to remove.
  973. //
  974. hr = THR( DispGetParam( pdpIn, 0, VT_BSTR, &var, &uiArg ) );
  975. if ( FAILED( hr ) )
  976. {
  977. goto Error;
  978. }
  979. //
  980. // Delete the value from the hive.
  981. //
  982. scErr = TW32( ClusterRegDeleteValue( m_hkey, var.bstrVal ) );
  983. if ( scErr == ERROR_FILE_NOT_FOUND )
  984. {
  985. hr = THR( DISP_E_UNKNOWNNAME );
  986. goto Error;
  987. }
  988. else if ( scErr != ERROR_SUCCESS )
  989. {
  990. hr = HRESULT_FROM_WIN32( scErr );
  991. goto Error;
  992. }
  993. hr = S_OK;
  994. Cleanup:
  995. VariantClear( &var );
  996. HRETURN( hr );
  997. Error:
  998. LogError( hr );
  999. goto Cleanup;
  1000. } //*** CResourceObject::RemovePrivateProperty
  1001. //////////////////////////////////////////////////////////////////////////////
  1002. //
  1003. // STDMETHODIMP
  1004. // CResourceObject::AddPrivateProperty(
  1005. // DISPPARAMS * pdpIn
  1006. // )
  1007. //
  1008. //////////////////////////////////////////////////////////////////////////////
  1009. STDMETHODIMP
  1010. CResourceObject::AddPrivateProperty(
  1011. DISPPARAMS * pdpIn
  1012. )
  1013. {
  1014. TraceFunc( "" );
  1015. DWORD dwType;
  1016. DWORD scErr;
  1017. DWORD cbData;
  1018. UINT uiArg;
  1019. LPBYTE pData;
  1020. VARIANT varProperty;
  1021. VARIANT varValue;
  1022. HRESULT hr;
  1023. WCHAR szNULL [] = L"";
  1024. VariantInit( &varProperty );
  1025. VariantInit( &varValue );
  1026. //
  1027. // Do some parameter validation.
  1028. //
  1029. if ( ( pdpIn->cArgs == 0 )
  1030. || ( pdpIn->cArgs > 2 )
  1031. || ( pdpIn->cNamedArgs > 2 )
  1032. )
  1033. {
  1034. hr = THR( DISP_E_BADPARAMCOUNT );
  1035. goto Error;
  1036. }
  1037. //
  1038. // Retrieve the name of the property.
  1039. //
  1040. hr = THR( DispGetParam( pdpIn, 0, VT_BSTR, &varProperty, &uiArg ) );
  1041. if ( FAILED( hr ) )
  1042. {
  1043. goto Error;
  1044. }
  1045. //
  1046. // If there are 2 args, the second one indicates the default value.
  1047. //
  1048. if ( pdpIn->cArgs == 2 )
  1049. {
  1050. //
  1051. // DISPPARAMS are parsed in reverse order so "1" is actually the name
  1052. // and "0" is the default value.
  1053. //
  1054. switch ( pdpIn->rgvarg[0].vt )
  1055. {
  1056. case VT_I4:
  1057. case VT_I2:
  1058. case VT_BOOL:
  1059. case VT_UI1:
  1060. case VT_UI2:
  1061. case VT_UI4:
  1062. case VT_INT:
  1063. case VT_UINT:
  1064. hr = THR( DispGetParam( pdpIn, 1, VT_I4, &varValue, &uiArg ) );
  1065. if ( FAILED( hr ) )
  1066. goto Error;
  1067. dwType = REG_DWORD;
  1068. pData = (LPBYTE) &varValue.intVal;
  1069. cbData = sizeof(DWORD);
  1070. break;
  1071. case VT_BSTR:
  1072. hr = THR( DispGetParam( pdpIn, 1, VT_BSTR, &varValue, &uiArg ) );
  1073. if ( FAILED( hr ) )
  1074. goto Error;
  1075. dwType = REG_SZ;
  1076. pData = (LPBYTE) varValue.bstrVal;
  1077. cbData = sizeof(WCHAR) * ( SysStringLen( varValue.bstrVal ) + 1 );
  1078. break;
  1079. default:
  1080. hr = THR( E_INVALIDARG );
  1081. goto Error;
  1082. } // switch: variant type
  1083. } // if: 2 args specified
  1084. else
  1085. {
  1086. //
  1087. // Provide a default of a NULL string.
  1088. //
  1089. dwType = REG_SZ;
  1090. pData = (LPBYTE) &szNULL[0];
  1091. cbData = sizeof(szNULL);
  1092. } // else: 2 args not specified
  1093. //
  1094. // Create the value in the hive.
  1095. //
  1096. scErr = TW32( ClusterRegSetValue( m_hkey, varProperty.bstrVal, dwType, pData, cbData ) );
  1097. if ( scErr != ERROR_SUCCESS )
  1098. {
  1099. hr = HRESULT_FROM_WIN32( scErr );
  1100. goto Error;
  1101. }
  1102. hr = S_OK;
  1103. Cleanup:
  1104. VariantClear( &varProperty );
  1105. VariantClear( &varValue );
  1106. HRETURN( hr );
  1107. Error:
  1108. LogError( hr );
  1109. goto Cleanup;
  1110. }//*** CResourceObject::AddPrivateProperty
  1111. //////////////////////////////////////////////////////////////////////////////
  1112. //
  1113. // STDMETHODIMP
  1114. // CResourceObject::PrivatePropertyExists(
  1115. // DISPID idIn,
  1116. // DISPPARAMS * pdpIn
  1117. // )
  1118. //
  1119. // Return Value:
  1120. // S_OK - If the property exists
  1121. // S_FALSE - If the property does not exist
  1122. // Other - On failure
  1123. //
  1124. //////////////////////////////////////////////////////////////////////////////
  1125. STDMETHODIMP
  1126. CResourceObject::PrivatePropertyExists(
  1127. DISPPARAMS * pdpIn
  1128. )
  1129. {
  1130. TraceFunc( "" );
  1131. DWORD scErr;
  1132. DWORD cbData;
  1133. UINT uiArg;
  1134. VARIANT varProperty;
  1135. HRESULT hr = S_OK;
  1136. VariantInit( &varProperty );
  1137. //
  1138. // Do some parameter validation.
  1139. //
  1140. if ( ( pdpIn->cArgs != 1 ) || ( pdpIn->cNamedArgs > 1 ) )
  1141. {
  1142. hr = THR( DISP_E_BADPARAMCOUNT );
  1143. LogError( hr );
  1144. goto Cleanup;
  1145. }
  1146. //
  1147. // Retrieve the name of the property.
  1148. //
  1149. hr = THR( DispGetParam( pdpIn, 0, VT_BSTR, &varProperty, &uiArg ) );
  1150. if ( FAILED( hr ) )
  1151. {
  1152. LogError( hr );
  1153. goto Cleanup;
  1154. }
  1155. //
  1156. // Query the cluster hive for this property.
  1157. //
  1158. scErr = ClusterRegQueryValue(
  1159. m_hkey
  1160. , varProperty.bstrVal
  1161. , NULL
  1162. , NULL
  1163. , &cbData
  1164. );
  1165. if ( scErr == ERROR_FILE_NOT_FOUND )
  1166. {
  1167. hr = S_FALSE;
  1168. goto Cleanup; // Property is not in the cluster hive.
  1169. }
  1170. if ( scErr != ERROR_SUCCESS )
  1171. {
  1172. hr = HRESULT_FROM_WIN32( TW32( scErr ) );
  1173. LogError( hr );
  1174. goto Cleanup;
  1175. }
  1176. Cleanup:
  1177. VariantClear( &varProperty );
  1178. HRETURN( hr );
  1179. } //*** CResourceObject::PrivatePropertyExists
  1180. //////////////////////////////////////////////////////////////////////
  1181. //
  1182. // STDMETHODIMP
  1183. // CResourceObject::LogInformation(
  1184. // BSTR bstrString
  1185. // )
  1186. //
  1187. //////////////////////////////////////////////////////////////////////
  1188. STDMETHODIMP
  1189. CResourceObject::LogInformation(
  1190. BSTR bstrString
  1191. )
  1192. {
  1193. TraceFunc1( "%ws", bstrString );
  1194. TraceMsg( mtfCALLS, "LOG_INFORMATION: %s\n", bstrString );
  1195. m_pler( m_hResource, LOG_INFORMATION, L"%1\n", bstrString );
  1196. HRETURN( S_OK );
  1197. } //*** CResourceObject::LogInformation