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.

978 lines
28 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2003 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // GenScript.cpp
  7. //
  8. // Description:
  9. // DLL services/entry points for the generic script resource.
  10. //
  11. // Maintained By:
  12. // Ozan Ozhan (OzanO) 04-APR-2002
  13. // Geoff Pease (GPease) 08-FEB-2000
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16. #include "Pch.h"
  17. #include "ActiveScriptSite.h"
  18. #include "ScriptResource.h"
  19. #include "SpinLock.h"
  20. //
  21. // Debugging Module Name
  22. //
  23. DEFINE_MODULE("SCRIPTRES")
  24. //
  25. // DLL Globals
  26. //
  27. HINSTANCE g_hInstance = NULL;
  28. LONG g_cObjects = 0;
  29. LONG g_cLock = 0;
  30. WCHAR g_szDllFilename[ MAX_PATH ] = { 0 };
  31. #if defined(DEBUG)
  32. LPVOID g_GlobalMemoryList = NULL; // Global memory tracking list
  33. #endif
  34. PSET_RESOURCE_STATUS_ROUTINE g_prsrCallback = NULL;
  35. extern "C"
  36. {
  37. extern CLRES_FUNCTION_TABLE GenScriptFunctionTable;
  38. //
  39. // GenScript resource read-write private properties
  40. //
  41. RESUTIL_PROPERTY_ITEM
  42. GenScriptResourcePrivateProperties[] = {
  43. { CLUSREG_NAME_GENSCRIPT_SCRIPT_FILEPATH, NULL, CLUSPROP_FORMAT_SZ, 0, 0, 0, RESUTIL_PROPITEM_REQUIRED, FIELD_OFFSET( GENSCRIPT_PROPS, pszScriptFilePath ) },
  44. { 0 }
  45. };
  46. DWORD
  47. ScriptValidateResourcePrivateProperties(
  48. CScriptResource * pres
  49. , PVOID pvBufferIn
  50. , DWORD dwBufferInSizeIn
  51. , PGENSCRIPT_PROPS pPropsCurrent
  52. , PGENSCRIPT_PROPS pPropsNew
  53. );
  54. //****************************************************************************
  55. //
  56. // DLL Entry Points
  57. //
  58. //****************************************************************************
  59. //////////////////////////////////////////////////////////////////////////////
  60. //
  61. // BOOL
  62. // WINAPI
  63. // GenScriptDllEntryPoint(
  64. // HANDLE hInstIn,
  65. // ULONG ulReasonIn,
  66. // LPVOID lpReservedIn
  67. // )
  68. //
  69. // Description:
  70. // Dll entry point.
  71. //
  72. // Arguments:
  73. // hInstIn - DLL instance handle.
  74. // ulReasonIn - DLL reason code for entrance.
  75. // lpReservedIn - Not used.
  76. //
  77. //////////////////////////////////////////////////////////////////////////////
  78. BOOL
  79. WINAPI
  80. GenScriptDllEntryPoint(
  81. HINSTANCE hInstIn,
  82. ULONG ulReasonIn,
  83. LPVOID // lpReservedIn
  84. )
  85. {
  86. //
  87. // KB: THREAD_OPTIMIZATIONS gpease 19-OCT-1999
  88. //
  89. // By defining this you can prevent the linker
  90. // from calling your DllEntry for every new thread.
  91. // This makes creating new threads significantly
  92. // faster if every DLL in a process does it.
  93. // Unfortunately, not all DLLs do this.
  94. //
  95. // In CHKed/DEBUG, we keep this on for memory
  96. // tracking.
  97. //
  98. #if ! defined( DEBUG )
  99. #define THREAD_OPTIMIZATIONS
  100. #endif // DEBUG
  101. switch( ulReasonIn )
  102. {
  103. //////////////////////////////////////////////////////////////////////
  104. // DLL_PROCESS_ATTACH
  105. //////////////////////////////////////////////////////////////////////
  106. case DLL_PROCESS_ATTACH:
  107. {
  108. #if defined( DEBUG_SW_TRACING_ENABLED )
  109. TraceInitializeProcess( g_rgTraceControlGuidList, ARRAYSIZE( g_rgTraceControlGuidList ), TRUE );
  110. #else // ! DEBUG_SW_TRACING_ENABLED
  111. TraceInitializeProcess( TRUE );
  112. #endif // DEBUG_SW_TRACING_ENABLED
  113. TraceFunc( "" );
  114. TraceMessage( TEXT(__FILE__),
  115. __LINE__,
  116. __MODULE__,
  117. mtfDLL,
  118. TEXT("DLL: DLL_PROCESS_ATTACH - ThreadID = %#x"),
  119. GetCurrentThreadId()
  120. );
  121. g_hInstance = hInstIn;
  122. #if defined( ENTRY_PREFIX )
  123. hProxyDll = g_hInstance;
  124. #endif // ENTRY_PREFIX
  125. GetModuleFileNameW( g_hInstance, g_szDllFilename, ARRAYSIZE( g_szDllFilename ) );
  126. //
  127. // Create a global memory list so that memory allocated by one
  128. // thread and handed to another can be tracked without causing
  129. // unnecessary trace messages.
  130. //
  131. TraceCreateMemoryList( g_GlobalMemoryList );
  132. #if defined( THREAD_OPTIMIZATIONS )
  133. {
  134. //
  135. // Disable thread library calls so that we don't get called
  136. // on thread attach and detach.
  137. //
  138. BOOL fResult = DisableThreadLibraryCalls( g_hInstance );
  139. if ( ! fResult )
  140. {
  141. TW32MSG( GetLastError(), "DisableThreadLibraryCalls()" );
  142. }
  143. }
  144. #endif // THREAD_OPTIMIZATIONS
  145. #if defined( USE_FUSION )
  146. //
  147. // Initialize Fusion.
  148. //
  149. // The value of IDR_MANIFEST in the call to
  150. // SHFusionInitializeFromModuleID() must match the value specified in the
  151. // sources file for SXS_MANIFEST_RESOURCE_ID.
  152. //
  153. BOOL fResult = SHFusionInitializeFromModuleID( hInstIn, IDR_MANIFEST );
  154. if ( ! fResult )
  155. {
  156. TW32MSG( GetLastError(), "SHFusionInitializeFromModuleID()" );
  157. }
  158. #endif // USE_FUSION
  159. #if defined( DO_MODULE_INIT )
  160. THR( HrLocalProcessInit() );
  161. #endif
  162. //
  163. // This is necessary here because TraceFunc() defines a variable
  164. // on the stack which isn't available outside the scope of this
  165. // block.
  166. // This function doesn't do anything but clean up after
  167. // TraceFunc().
  168. //
  169. FRETURN( TRUE );
  170. break;
  171. } // case: DLL_PROCESS_ATTACH
  172. //////////////////////////////////////////////////////////////////////
  173. // DLL_PROCESS_DETACH
  174. //////////////////////////////////////////////////////////////////////
  175. case DLL_PROCESS_DETACH:
  176. {
  177. TraceFunc( "" );
  178. TraceMessage( TEXT(__FILE__),
  179. __LINE__,
  180. __MODULE__,
  181. mtfDLL,
  182. TEXT("DLL: DLL_PROCESS_DETACH - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
  183. GetCurrentThreadId(),
  184. g_cLock,
  185. g_cObjects
  186. );
  187. #if defined( DO_MODULE_UNINIT )
  188. THR( HrLocalProcessUninit() );
  189. #endif
  190. //
  191. // Cleanup the global memory list used to track memory allocated
  192. // in one thread and then handed to another.
  193. //
  194. TraceTerminateMemoryList( g_GlobalMemoryList );
  195. //
  196. // This is necessary here because TraceFunc() defines a variable
  197. // on the stack which isn't available outside the scope of this
  198. // block.
  199. // This function doesn't do anything but clean up after
  200. // TraceFunc().
  201. //
  202. FRETURN( TRUE );
  203. #if defined( DEBUG_SW_TRACING_ENABLED )
  204. TraceTerminateProcess( g_rgTraceControlGuidList, ARRAYSIZE( g_rgTraceControlGuidList )
  205. );
  206. #else // ! DEBUG_SW_TRACING_ENABLED
  207. TraceTerminateProcess();
  208. #endif // DEBUG_SW_TRACING_ENABLED
  209. #if defined( USE_FUSION )
  210. SHFusionUninitialize();
  211. #endif // USE_FUSION
  212. break;
  213. } // case: DLL_PROCESS_DETACH
  214. #if ! defined( THREAD_OPTIMIZATIONS )
  215. //////////////////////////////////////////////////////////////////////
  216. // DLL_THREAD_ATTACH
  217. //////////////////////////////////////////////////////////////////////
  218. case DLL_THREAD_ATTACH:
  219. {
  220. TraceInitializeThread( NULL );
  221. TraceMessage( TEXT(__FILE__),
  222. __LINE__,
  223. __MODULE__,
  224. mtfDLL,
  225. TEXT("Thread %#x has started."),
  226. GetCurrentThreadId()
  227. );
  228. TraceFunc( "" );
  229. TraceMessage( TEXT(__FILE__),
  230. __LINE__,
  231. __MODULE__,
  232. mtfDLL,
  233. TEXT("DLL: DLL_THREAD_ATTACH - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
  234. GetCurrentThreadId(),
  235. g_cLock,
  236. g_cObjects
  237. );
  238. //
  239. // This is necessary here because TraceFunc() defines a variable
  240. // on the stack which isn't available outside the scope of this
  241. // block.
  242. // This function doesn't do anything but clean up after
  243. // TraceFunc().
  244. //
  245. FRETURN( TRUE );
  246. break;
  247. } // case: DLL_THREAD_ATTACH
  248. //////////////////////////////////////////////////////////////////////
  249. // DLL_THREAD_DETACH
  250. //////////////////////////////////////////////////////////////////////
  251. case DLL_THREAD_DETACH:
  252. {
  253. TraceFunc( "" );
  254. TraceMessage( TEXT(__FILE__),
  255. __LINE__,
  256. __MODULE__,
  257. mtfDLL,
  258. TEXT("DLL: DLL_THREAD_DETACH - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
  259. GetCurrentThreadId(),
  260. g_cLock,
  261. g_cObjects
  262. );
  263. //
  264. // This is necessary here because TraceFunc() defines a variable
  265. // on the stack which isn't available outside the scope of this
  266. // block.
  267. // This function doesn't do anything but clean up after
  268. // TraceFunc().
  269. //
  270. FRETURN( TRUE );
  271. TraceThreadRundown();
  272. break;
  273. } // case: DLL_THREAD_DETACH
  274. #endif // ! THREAD_OPTIMIZATIONS
  275. default:
  276. {
  277. TraceFunc( "" );
  278. TraceMessage( TEXT(__FILE__),
  279. __LINE__,
  280. __MODULE__,
  281. mtfDLL,
  282. TEXT("DLL: UNKNOWN ENTRANCE REASON - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
  283. GetCurrentThreadId(),
  284. g_cLock,
  285. g_cObjects
  286. );
  287. #if defined( THREAD_OPTIMIZATIONS )
  288. Assert( ( ulReasonIn != DLL_THREAD_ATTACH )
  289. && ( ulReasonIn != DLL_THREAD_DETACH ) );
  290. #endif // THREAD_OPTIMIZATIONS
  291. //
  292. // This is necessary here because TraceFunc defines a variable
  293. // on the stack which isn't available outside the scope of this
  294. // block.
  295. // This function doesn't do anything but clean up after TraceFunc.
  296. //
  297. FRETURN( TRUE );
  298. break;
  299. } // default case
  300. } // switch on reason code
  301. return TRUE;
  302. } //*** GenScriptDllEntryPoint()
  303. //****************************************************************************
  304. //
  305. // Cluster Resource Entry Points
  306. //
  307. //****************************************************************************
  308. //////////////////////////////////////////////////////////////////////////////
  309. //
  310. // void
  311. // WINAPI
  312. // ScriptResClose(
  313. // RESID residIn
  314. // )
  315. //
  316. //////////////////////////////////////////////////////////////////////////////
  317. void
  318. WINAPI
  319. ScriptResClose(
  320. RESID residIn
  321. )
  322. {
  323. TraceFunc1( "ScriptResClose( residIn = 0x%08x )\n", residIn );
  324. HRESULT hr;
  325. CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
  326. if ( pres == NULL )
  327. {
  328. goto Cleanup;
  329. }
  330. hr = THR( pres->Close( ) );
  331. hr = STATUS_TO_RETURN( hr );
  332. //
  333. // Matching Release() for object creation in ScriptResOpen( ).
  334. //
  335. pres->Release( );
  336. Cleanup:
  337. TraceFuncExit( );
  338. } //*** ScriptResClose( )
  339. //////////////////////////////////////////////////////////////////////////////
  340. //
  341. // RESID
  342. // WINAPI
  343. // ScriptResOpen(
  344. // LPCWSTR pszNameIn,
  345. // HKEY hkeyIn,
  346. // RESOURCE_HANDLE hResourceIn
  347. // )
  348. //
  349. //////////////////////////////////////////////////////////////////////////////
  350. RESID
  351. WINAPI
  352. ScriptResOpen(
  353. LPCWSTR pszNameIn,
  354. HKEY hkeyIn,
  355. RESOURCE_HANDLE hResourceIn
  356. )
  357. {
  358. TraceFunc1( "ScriptResOpen( pszNameIn = '%s', hkeyIn, hResourceIn )\n", pszNameIn );
  359. HRESULT hr;
  360. CScriptResource * pres;
  361. pres = CScriptResource_CreateInstance( pszNameIn, hkeyIn, hResourceIn );
  362. if ( pres == NULL )
  363. {
  364. hr = TW32( ERROR_OUTOFMEMORY );
  365. goto Cleanup;
  366. }
  367. hr = THR( pres->Open( ) );
  368. hr = STATUS_TO_RETURN( hr );
  369. Cleanup:
  370. //
  371. // KB: Don't pres->Release( ) as we are handing it out as out RESID.
  372. //
  373. RETURN( pres );
  374. } //*** ScriptResOpen( )
  375. //////////////////////////////////////////////////////////////////////////////
  376. //
  377. // DWORD
  378. // WINAPI
  379. // ScriptResOnline(
  380. // RESID residIn,
  381. // PHANDLE hEventInout
  382. // )
  383. //
  384. //////////////////////////////////////////////////////////////////////////////
  385. DWORD
  386. WINAPI
  387. ScriptResOnline(
  388. RESID residIn,
  389. PHANDLE hEventInout
  390. )
  391. {
  392. TraceFunc2( "ScriptResOnline( residIn = 0x%08x, hEventInout = 0x%08x )\n",
  393. residIn, hEventInout );
  394. HRESULT hr;
  395. CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
  396. if ( pres == NULL )
  397. {
  398. hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
  399. goto Cleanup;
  400. }
  401. hr = THR( pres->Online( ) );
  402. hr = STATUS_TO_RETURN( hr );
  403. Cleanup:
  404. RETURN( hr );
  405. } //*** ScriptResOnline( )
  406. //////////////////////////////////////////////////////////////////////////////
  407. //
  408. // DWORD
  409. // WINAPI
  410. // ScriptResOffline(
  411. // RESID residIn
  412. // )
  413. //
  414. //////////////////////////////////////////////////////////////////////////////
  415. DWORD
  416. WINAPI
  417. ScriptResOffline(
  418. RESID residIn
  419. )
  420. {
  421. TraceFunc1( "ScriptResOffline( residIn = 0x%08x )\n", residIn );
  422. HRESULT hr;
  423. CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
  424. if ( pres == NULL )
  425. {
  426. hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
  427. goto Cleanup;
  428. }
  429. hr = THR( pres->Offline( ) );
  430. hr = STATUS_TO_RETURN( hr );
  431. Cleanup:
  432. RETURN( hr );
  433. } //*** ScriptResOffline( )
  434. //////////////////////////////////////////////////////////////////////////////
  435. //
  436. // void
  437. // WINAPI
  438. // ScriptResTerminate(
  439. // RESID residIn
  440. // )
  441. //
  442. //////////////////////////////////////////////////////////////////////////////
  443. void
  444. WINAPI
  445. ScriptResTerminate(
  446. RESID residIn
  447. )
  448. {
  449. TraceFunc1( "ScriptResTerminate( residIn = 0x%08x )\n", residIn );
  450. CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
  451. if ( pres == NULL )
  452. {
  453. THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
  454. goto Cleanup;
  455. }
  456. THR( pres->Terminate( ) );
  457. Cleanup:
  458. TraceFuncExit( );
  459. } // ScriptResTerminate( )
  460. //////////////////////////////////////////////////////////////////////////////
  461. //
  462. // BOOL
  463. // WINAPI
  464. // ScriptResLooksAlive(
  465. // RESID residIn
  466. // )
  467. //
  468. //////////////////////////////////////////////////////////////////////////////
  469. BOOL
  470. WINAPI
  471. ScriptResLooksAlive(
  472. RESID residIn
  473. )
  474. {
  475. TraceFunc1( "ScriptResLooksAlive( residIn = 0x%08x )\n", residIn );
  476. HRESULT hr;
  477. BOOL fLooksAlive = FALSE;
  478. CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
  479. if ( pres == NULL )
  480. {
  481. hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
  482. goto Cleanup;
  483. }
  484. hr = STHR( pres->LooksAlive( ) );
  485. if ( hr == S_OK )
  486. {
  487. fLooksAlive = TRUE;
  488. } // if: S_OK
  489. hr = STATUS_TO_RETURN( hr );
  490. Cleanup:
  491. RETURN( fLooksAlive );
  492. } //*** ScriptResLooksAlive( )
  493. //////////////////////////////////////////////////////////////////////////////
  494. //
  495. // BOOL
  496. // WINAPI
  497. // ScriptResIsAlive(
  498. // RESID residIn
  499. // )
  500. //
  501. //////////////////////////////////////////////////////////////////////////////
  502. BOOL
  503. WINAPI
  504. ScriptResIsAlive(
  505. RESID residIn
  506. )
  507. {
  508. TraceFunc1( "ScriptResIsAlive( residIn = 0x%08x )\n", residIn );
  509. HRESULT hr;
  510. BOOL fIsAlive = FALSE;
  511. CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
  512. if ( pres == NULL )
  513. {
  514. hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
  515. goto Cleanup;
  516. }
  517. hr = STHR( pres->IsAlive( ) );
  518. if ( hr == S_OK )
  519. {
  520. fIsAlive = TRUE;
  521. } // if: S_OK
  522. hr = STATUS_TO_RETURN( hr );
  523. Cleanup:
  524. RETURN( fIsAlive );
  525. } //*** ScriptResIsAlive( )
  526. //////////////////////////////////////////////////////////////////////////////
  527. //
  528. // DWORD
  529. // ScriptResResourceControl(
  530. // RESID residIn,
  531. // DWORD dwControlCodeIn,
  532. // PVOID pvBufferIn,
  533. // DWORD dwBufferInSizeIn,
  534. // PVOID pvBufferOut,
  535. // DWORD dwBufferOutSizeIn,
  536. // LPDWORD pdwBytesReturnedOut
  537. // )
  538. //
  539. //////////////////////////////////////////////////////////////////////////////
  540. DWORD
  541. ScriptResResourceControl(
  542. RESID residIn,
  543. DWORD dwControlCodeIn,
  544. PVOID pvBufferIn,
  545. DWORD dwBufferInSizeIn,
  546. PVOID pvBufferOut,
  547. DWORD dwBufferOutSizeIn,
  548. LPDWORD pdwBytesReturnedOut
  549. )
  550. {
  551. TraceFunc( "ScriptResResourceControl( ... )\n " );
  552. DWORD scErr = ERROR_SUCCESS;
  553. DWORD dwBytesRequired = 0;
  554. DWORD dwPendingTimeout = 0;
  555. GENSCRIPT_PROPS propsNew;
  556. GENSCRIPT_PROPS propsCurrent;
  557. *pdwBytesReturnedOut = 0;
  558. CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
  559. if ( pres == NULL )
  560. {
  561. scErr = (DWORD) THR( E_INVALIDARG );
  562. goto Cleanup;
  563. }
  564. switch ( dwControlCodeIn )
  565. {
  566. case CLUSCTL_RESOURCE_UNKNOWN:
  567. break;
  568. case CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTY_FMTS:
  569. scErr = TW32( ResUtilGetPropertyFormats(
  570. GenScriptResourcePrivateProperties
  571. , pvBufferOut
  572. , dwBufferOutSizeIn
  573. , pdwBytesReturnedOut
  574. , &dwBytesRequired
  575. ) );
  576. if ( scErr == ERROR_MORE_DATA )
  577. {
  578. *pdwBytesReturnedOut = dwBytesRequired;
  579. }
  580. break;
  581. case CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES:
  582. scErr = TW32( ResUtilGetAllProperties(
  583. pres->GetRegistryParametersKey()
  584. , GenScriptResourcePrivateProperties
  585. , pvBufferOut
  586. , dwBufferOutSizeIn
  587. , pdwBytesReturnedOut
  588. , &dwBytesRequired
  589. ) );
  590. if ( scErr == ERROR_MORE_DATA )
  591. {
  592. *pdwBytesReturnedOut = dwBytesRequired;
  593. }
  594. break;
  595. case CLUSCTL_RESOURCE_VALIDATE_PRIVATE_PROPERTIES:
  596. scErr= TW32( ScriptValidateResourcePrivateProperties(
  597. pres
  598. , pvBufferIn
  599. , dwBufferInSizeIn
  600. , &propsCurrent
  601. , &propsNew
  602. ) );
  603. break;
  604. case CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES:
  605. scErr= TW32( ScriptValidateResourcePrivateProperties(
  606. pres
  607. , pvBufferIn
  608. , dwBufferInSizeIn
  609. , &propsCurrent
  610. , &propsNew
  611. ) );
  612. if ( scErr != ERROR_SUCCESS )
  613. {
  614. goto Cleanup;
  615. }
  616. scErr = pres->SetPrivateProperties( &propsNew );
  617. break;
  618. case CLUSCTL_RESOURCE_SET_COMMON_PROPERTIES:
  619. //
  620. // Find the resource pending timeout in the property list.
  621. //
  622. scErr = ResUtilFindDwordProperty(
  623. pvBufferIn
  624. , dwBufferInSizeIn
  625. , CLUSREG_NAME_RES_PENDING_TIMEOUT
  626. , &dwPendingTimeout
  627. );
  628. if ( scErr == ERROR_SUCCESS )
  629. {
  630. //
  631. // Pending timeout period was changed.
  632. //
  633. pres->SetResourcePendingTimeoutChanged( TRUE );
  634. }
  635. scErr = ERROR_INVALID_FUNCTION;
  636. break;
  637. default:
  638. scErr = ERROR_INVALID_FUNCTION;
  639. break;
  640. } // switch: on control code
  641. Cleanup:
  642. RETURN( scErr );
  643. } //*** ScriptResResourceControl
  644. //////////////////////////////////////////////////////////////////////////////
  645. //
  646. // DWORD
  647. // ScriptResTypeControl(
  648. // LPCWSTR ResourceTypeName,
  649. // DWORD dwControlCodeIn,
  650. // PVOID pvBufferIn,
  651. // DWORD dwBufferInSizeIn,
  652. // PVOID pvBufferOut,
  653. // DWORD dwBufferOutSizeIn,
  654. // LPDWORD pdwBytesReturnedOut
  655. // )
  656. //
  657. //////////////////////////////////////////////////////////////////////////////
  658. DWORD
  659. ScriptResTypeControl(
  660. LPCWSTR ResourceTypeName,
  661. DWORD dwControlCodeIn,
  662. PVOID pvBufferIn,
  663. DWORD dwBufferInSizeIn,
  664. PVOID pvBufferOut,
  665. DWORD dwBufferOutSizeIn,
  666. LPDWORD pdwBytesReturnedOut
  667. )
  668. {
  669. TraceFunc( "ScriptResTypeControl( ... )\n " );
  670. DWORD dwErr = ERROR_SUCCESS;
  671. DWORD dwBytesRequired;
  672. *pdwBytesReturnedOut = 0;
  673. switch ( dwControlCodeIn )
  674. {
  675. case CLUSCTL_RESOURCE_TYPE_UNKNOWN:
  676. break;
  677. case CLUSCTL_RESOURCE_TYPE_GET_PRIVATE_RESOURCE_PROPERTY_FMTS:
  678. dwErr = ResUtilGetPropertyFormats( GenScriptResourcePrivateProperties,
  679. pvBufferOut,
  680. dwBufferOutSizeIn,
  681. pdwBytesReturnedOut,
  682. &dwBytesRequired );
  683. if ( dwErr == ERROR_MORE_DATA ) {
  684. *pdwBytesReturnedOut = dwBytesRequired;
  685. }
  686. break;
  687. default:
  688. dwErr = ERROR_INVALID_FUNCTION;
  689. break;
  690. }
  691. RETURN( dwErr );
  692. } //*** ScriptResTypeControl( )
  693. //////////////////////////////////////////////////////////////////////////////
  694. //
  695. // DWORD
  696. // ScriptValidateResourcePrivateProperties(
  697. // CScriptResource * pres
  698. // , PVOID pvBufferIn
  699. // , DWORD dwBufferInSizeIn
  700. // , PGENSCRIPT_PROPS pPropsCurrent
  701. // , PGENSCRIPT_PROPS pPropsNew
  702. // )
  703. //
  704. //////////////////////////////////////////////////////////////////////////////
  705. DWORD
  706. ScriptValidateResourcePrivateProperties(
  707. CScriptResource * pres
  708. , PVOID pvBufferIn
  709. , DWORD dwBufferInSizeIn
  710. , PGENSCRIPT_PROPS pPropsCurrent
  711. , PGENSCRIPT_PROPS pPropsNew
  712. )
  713. {
  714. DWORD scErr = ERROR_SUCCESS;
  715. HANDLE hFile = INVALID_HANDLE_VALUE;
  716. LPWSTR pszNameOfPropInError;
  717. LPWSTR pszFilePath = NULL;
  718. //
  719. // Check if there is input data.
  720. //
  721. if ( ( pvBufferIn == NULL ) || ( dwBufferInSizeIn < sizeof( DWORD ) ) )
  722. {
  723. scErr = ERROR_INVALID_DATA;
  724. goto Cleanup;
  725. } // if: no input buffer or input buffer not big enough to contain property list
  726. //
  727. // Retrieve the current set of private properties from the
  728. // cluster database.
  729. //
  730. ZeroMemory( pPropsCurrent, sizeof( *pPropsCurrent ) );
  731. scErr = TW32( ResUtilGetPropertiesToParameterBlock(
  732. pres->GetRegistryParametersKey()
  733. , GenScriptResourcePrivateProperties
  734. , reinterpret_cast< LPBYTE >( pPropsCurrent )
  735. , FALSE // CheckForRequiredProperties
  736. , &pszNameOfPropInError
  737. ) );
  738. if ( scErr != ERROR_SUCCESS )
  739. {
  740. (ClusResLogEvent)(
  741. pres->GetResourceHandle()
  742. , LOG_ERROR
  743. , L"ValidatePrivateProperties: Unable to read the '%1!ws!' property. Error: %2!u! (%2!#08x!).\n"
  744. , (pszNameOfPropInError == NULL ? L"" : pszNameOfPropInError)
  745. , scErr
  746. );
  747. goto Cleanup;
  748. } // if: error getting properties
  749. ZeroMemory( pPropsNew, sizeof( *pPropsNew ) );
  750. scErr = TW32( ResUtilDupParameterBlock(
  751. reinterpret_cast< LPBYTE >( pPropsNew )
  752. , reinterpret_cast< LPBYTE >( pPropsCurrent )
  753. , GenScriptResourcePrivateProperties
  754. ) );
  755. if ( scErr != ERROR_SUCCESS )
  756. {
  757. goto Cleanup;
  758. } // if: error duplicating the parameter block
  759. //
  760. // Parse and validate the properties.
  761. //
  762. scErr = TW32( ResUtilVerifyPropertyTable(
  763. GenScriptResourcePrivateProperties
  764. , NULL
  765. , TRUE // AllowUnknownProperties
  766. , pvBufferIn
  767. , dwBufferInSizeIn
  768. , reinterpret_cast< LPBYTE >( pPropsNew )
  769. ) );
  770. if ( scErr != ERROR_SUCCESS )
  771. {
  772. goto Cleanup;
  773. } // if: error parsing the property table.
  774. //
  775. // If the new script file path is NULL: i.e. the case where /usedefault
  776. // switch is used to set ScriptFilePath property using cluster.exe.
  777. // Or if an empty string specified for the ScriptFilePath property.
  778. //
  779. if ( ( pPropsNew->pszScriptFilePath == NULL ) || ( *pPropsNew->pszScriptFilePath == L'\0' ) )
  780. {
  781. scErr = TW32( ERROR_INVALID_PARAMETER );
  782. goto Cleanup;
  783. } // if: the new ScriptFilePath is NULL, or it is an empty string.
  784. //
  785. // Expand the new script file path.
  786. //
  787. pszFilePath = ClRtlExpandEnvironmentStrings( pPropsNew->pszScriptFilePath );
  788. if ( pszFilePath == NULL )
  789. {
  790. scErr = TW32( ERROR_OUTOFMEMORY );
  791. goto Cleanup;
  792. } // if: ( pszFilePath == NULL )
  793. //
  794. // Open the script file.
  795. //
  796. hFile = CreateFile(
  797. pszFilePath
  798. , GENERIC_READ
  799. , FILE_SHARE_READ
  800. , NULL
  801. , OPEN_EXISTING
  802. , 0
  803. , NULL
  804. );
  805. if ( hFile == INVALID_HANDLE_VALUE )
  806. {
  807. scErr = TW32( GetLastError() );
  808. (ClusResLogEvent)(
  809. pres->GetResourceHandle()
  810. , LOG_ERROR
  811. , L"Error opening script '%1!ws!'. SCODE: 0x%2!08x!\n"
  812. , pPropsNew->pszScriptFilePath
  813. , scErr
  814. );
  815. goto Cleanup;
  816. } // if: failed to open
  817. Cleanup:
  818. LocalFree( pszFilePath );
  819. if ( hFile != INVALID_HANDLE_VALUE )
  820. {
  821. CloseHandle( hFile );
  822. } // if: hFile
  823. return scErr;
  824. } //*** ScriptValidateResourcePrivateProperties
  825. //***********************************************************
  826. //
  827. // Define Function Table
  828. //
  829. //***********************************************************
  830. CLRES_V1_FUNCTION_TABLE( GenScriptFunctionTable, // Name
  831. CLRES_VERSION_V1_00, // Version
  832. ScriptRes, // Prefix
  833. NULL, // Arbitrate
  834. NULL, // Release
  835. ScriptResResourceControl, // ResControl
  836. ScriptResTypeControl // ResTypeControl
  837. );
  838. } // extern "C"