Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1236 lines
30 KiB

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