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.

1345 lines
30 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. HelpTab.h
  5. Abstract:
  6. Declaration __HelpEntry structure and CHelpSessionTable.
  7. Author:
  8. HueiWang 06/29/2000
  9. --*/
  10. #ifndef __CHELPSESSIONTABLE_H__
  11. #define __CHELPSESSIONTABLE_H__
  12. #include <stdio.h>
  13. #include <time.h>
  14. #define REGKEY_HELPSESSIONTABLE REG_CONTROL_HELPSESSIONENTRY
  15. #define REGKEY_HELPENTRYBACKUP _TEXT("Backup")
  16. #define REGVALUE_HELPSESSIONTABLE_DIRTY _TEXT("Dirty")
  17. #define REGVALUE_HELPSESSION_DIRTY REGVALUE_HELPSESSIONTABLE_DIRTY
  18. #define COLUMNNAME_SESSIONID _TEXT("SessionId")
  19. #define COLUMNNAME_SESSIONNAME _TEXT("SessionName")
  20. #define COLUMNNAME_SESSIONPWD _TEXT("SessionPwd")
  21. #define COLUMNNAME_SESSIONDESC _TEXT("SessionDesc")
  22. #define COLUMNNAME_SESSIONCREATEBLOB _TEXT("SessionCreateBlob")
  23. #define COLUMNNAME_ENABLESESSIONRESOLVER _TEXT("EnableResolver")
  24. #define COLUMNNAME_SESSIONRESOLVERBLOB _TEXT("Blob")
  25. #define COLUMNNAME_SESSIONUSERID _TEXT("UserSID")
  26. #define COLUMNNAME_CREATETIME _TEXT("CreationTime")
  27. #define COLUMNNAME_RDSSETTING _TEXT("RDS Setting")
  28. #define COLUMNNAME_KEYSTATUS _TEXT("Entry Status")
  29. #define COLUMNNAME_EXPIRATIONTIME _TEXT("ExpirationTime")
  30. #define COLUMNNAME_ICSPORT _TEXT("ICS Port")
  31. #define COLUMNNAME_IPADDRESS _TEXT("IP Address")
  32. #define ENTRY_VALID_PERIOD 30 // 30 days.
  33. #define REGVALUE_HELPSESSION_ENTRY_NORMAL 1
  34. #define REGVALUE_HELPSESSION_ENTRY_NEW 2
  35. #define REGVALUE_HELPSESSION_ENTRY_DIRTY 3
  36. #define REGVALUE_HELPSESSION_ENTRY_DELETED 4
  37. #define REGVALUE_HELPSESSION_ENTRY_DELETEONSTARTUP 5
  38. //
  39. // Default value
  40. static FILETIME defaultCreationTime = {0, 0};
  41. struct __HelpEntry;
  42. typedef __HelpEntry HELPENTRY;
  43. typedef __HelpEntry* PHELPENTRY;
  44. // similar to CComPtr
  45. template <class T>
  46. class BaseAccess : public T
  47. {
  48. };
  49. //
  50. // Template class for column value of registry DB,
  51. // All column type must be derived from this template.
  52. //
  53. template <class T>
  54. class HelpColumnValueBase {
  55. //friend bool __cdecl
  56. //operator==<>( const T& v1, const HelpColumnValueBase<T>& v2 );
  57. //friend bool __cdecl
  58. //operator==<>( const HelpColumnValueBase<T>& v2, const T& v1 );
  59. private:
  60. // copy of current value
  61. T m_Value;
  62. // Entry value has been modified and not yet
  63. // written to registry/
  64. BOOL m_bDirty;
  65. // Registry value name
  66. LPCTSTR m_pszColumnName;
  67. // default value
  68. T m_Default;
  69. // HKEY to registry
  70. HKEY m_hEntryKey;
  71. // Reference to critical section, note
  72. // we don't want to use one critical section for
  73. // a value to conserve resource
  74. CCriticalSection& m_Lock;
  75. // TRUE if registry value will be updated immediately
  76. // to reflect changes in m_Value
  77. BOOL m_ImmediateUpdate;
  78. //
  79. // Encrypt data
  80. //
  81. const BOOL m_bEncrypt;
  82. //
  83. // Default implementation of GetValue(),
  84. // GetValueSize(), GetValueType(), and
  85. // SetValue(). These routine is used when
  86. // writting to/reading from registry.
  87. //
  88. virtual const PBYTE
  89. GetValue()
  90. {
  91. return (PBYTE)&m_Value;
  92. }
  93. virtual DWORD
  94. GetValueSize()
  95. {
  96. return sizeof(m_Value);
  97. }
  98. virtual DWORD
  99. GetValueType()
  100. {
  101. return REG_BINARY;
  102. }
  103. virtual BOOL
  104. SetValue( PVOID pbData, DWORD cbData )
  105. {
  106. m_Value = *(T *)pbData;
  107. return TRUE;
  108. }
  109. public:
  110. //
  111. // TRUE if registry value is updated right away, FALSE
  112. // otherwise.
  113. BOOL
  114. IsImmediateUpdate()
  115. {
  116. return (NULL != m_hEntryKey && TRUE == m_ImmediateUpdate);
  117. }
  118. // similar to CComPtr
  119. BaseAccess<T>* operator->() const
  120. {
  121. return (BaseAccess<T>*)&m_Value;
  122. }
  123. HelpColumnValueBase(
  124. IN CCriticalSection& entryLock, // reference to critical section
  125. IN HKEY hEntryKey, // HKEY to registry, can be NULL
  126. IN LPCTSTR pszColumnName, // Name of registry value.
  127. IN T DefaultValue, // Default value if value not in registry
  128. IN BOOL bImmediateUpdate, // Update mode
  129. IN BOOL bEncrypt = FALSE
  130. ) :
  131. m_Lock(entryLock),
  132. m_hEntryKey(hEntryKey),
  133. m_bDirty(FALSE),
  134. m_pszColumnName(pszColumnName),
  135. m_Default(DefaultValue),
  136. m_Value(DefaultValue),
  137. m_ImmediateUpdate(bImmediateUpdate),
  138. m_bEncrypt(bEncrypt)
  139. {
  140. }
  141. //~HelpColumnValueBase()
  142. //{
  143. // m_Default.~T();
  144. //}
  145. HelpColumnValueBase&
  146. operator=(const T& newVal)
  147. {
  148. DWORD dwStatus;
  149. T orgValue;
  150. CCriticalSectionLocker l(m_Lock);
  151. m_bDirty = TRUE;
  152. orgValue = m_Value;
  153. m_Value = newVal;
  154. if( TRUE == IsImmediateUpdate() )
  155. {
  156. dwStatus = DBUpdateValue(NULL);
  157. MYASSERT(ERROR_SUCCESS == dwStatus);
  158. if( ERROR_SUCCESS != dwStatus )
  159. {
  160. // restore value
  161. m_Value = orgValue;
  162. }
  163. }
  164. return *this;
  165. }
  166. HelpColumnValueBase&
  167. operator=(const HelpColumnValueBase& newVal)
  168. {
  169. if( this != &newVal )
  170. {
  171. CCriticalSectionLocker l(m_Lock);
  172. m_Value = newVal.m_Value;
  173. }
  174. return *this;
  175. }
  176. bool
  177. operator==(const T& v) const
  178. {
  179. return v == m_Value;
  180. }
  181. operator T()
  182. {
  183. return m_Value;
  184. }
  185. // Load value from registry
  186. DWORD
  187. DBLoadValue(
  188. IN HKEY hKey
  189. );
  190. // update registry value
  191. DWORD
  192. DBUpdateValue(
  193. IN HKEY hKey
  194. );
  195. // delete registry value
  196. DWORD
  197. DBDeleteValue(
  198. IN HKEY hKey
  199. );
  200. // Change has been made but value has not
  201. // been written to registry
  202. BOOL
  203. IsDirty()
  204. {
  205. return m_bDirty;
  206. }
  207. // Set immediate update mode.
  208. void
  209. EnableImmediateUpdate(
  210. BOOL bImmediateUpdate
  211. )
  212. /*++
  213. --*/
  214. {
  215. m_ImmediateUpdate = bImmediateUpdate;
  216. }
  217. // Change registry location for the value.
  218. HKEY
  219. SetRegStoreHandle(
  220. IN HKEY hKey
  221. )
  222. /*++
  223. --*/
  224. {
  225. HKEY oldKey = m_hEntryKey;
  226. m_hEntryKey = hKey;
  227. return oldKey;
  228. }
  229. };
  230. //template <class T>
  231. //bool __cdecl operator==( const T& v1, const HelpColumnValueBase<T>& v2 )
  232. //{
  233. // return v1 == v2.m_Value;
  234. //}
  235. //template <class T>
  236. //bool __cdecl operator==( const HelpColumnValueBase<T>& v2, const T& v1 )
  237. //{
  238. // return v1 == v2.m_Value;
  239. //}
  240. template <class T>
  241. DWORD
  242. HelpColumnValueBase<T>::DBDeleteValue(
  243. IN HKEY hKey
  244. )
  245. /*++
  246. Routine Description:
  247. Delete registry value for the column.
  248. Parameter:
  249. hKey : Handle to HKEY where the value is stored, NULL will use default
  250. registry location passed in at object construction time or
  251. SetRegStoreHandle()
  252. Returns
  253. ERROR_SUCCESS or error code.
  254. --*/
  255. {
  256. DWORD dwStatus = ERROR_SUCCESS;
  257. if( NULL == hKey )
  258. {
  259. hKey = m_hEntryKey;
  260. }
  261. //
  262. // if no registry handle, no update is necessary,
  263. // assume it is a memory only value.
  264. //
  265. if( NULL != hKey )
  266. {
  267. CCriticalSectionLocker l( m_Lock );
  268. dwStatus = RegDeleteValue(
  269. hKey,
  270. m_pszColumnName
  271. );
  272. if( ERROR_SUCCESS == dwStatus )
  273. {
  274. m_bDirty = TRUE;
  275. }
  276. }
  277. return dwStatus;
  278. }
  279. template <class T>
  280. DWORD
  281. HelpColumnValueBase<T>::DBUpdateValue(
  282. IN HKEY hKey
  283. )
  284. /*++
  285. Routine Description:
  286. Update registry value.
  287. Parameters:
  288. hKey : Handle to registry key, NULL if use current location
  289. Returns:
  290. ERROR_SUCCESS or error code.
  291. --*/
  292. {
  293. DWORD dwStatus = ERROR_SUCCESS;
  294. if( NULL == hKey )
  295. {
  296. hKey = m_hEntryKey;
  297. }
  298. if( NULL != hKey )
  299. {
  300. // if value size is 0, no need to write anything to
  301. // registry, instead delete it to save some
  302. // space and let default value take care of reading.
  303. if( 0 == GetValueSize() )
  304. {
  305. dwStatus = RegDeleteValue(
  306. hKey,
  307. m_pszColumnName
  308. );
  309. if( ERROR_FILE_NOT_FOUND == dwStatus || ERROR_SUCCESS == dwStatus )
  310. {
  311. // no value in registry
  312. dwStatus = ERROR_SUCCESS;
  313. m_bDirty = FALSE;
  314. }
  315. }
  316. else
  317. {
  318. PBYTE pbData = NULL;
  319. DWORD cbData = 0;
  320. cbData = GetValueSize();
  321. if( m_bEncrypt )
  322. {
  323. pbData = (PBYTE)LocalAlloc( LPTR, cbData );
  324. if( NULL == pbData )
  325. {
  326. dwStatus = GetLastError();
  327. goto CLEANUPANDEXIT;
  328. }
  329. memcpy( pbData, GetValue(), cbData );
  330. dwStatus = TSHelpAssistantEncryptData(
  331. NULL,
  332. pbData,
  333. &cbData
  334. );
  335. }
  336. else
  337. {
  338. pbData = GetValue();
  339. }
  340. if( ERROR_SUCCESS == dwStatus )
  341. {
  342. dwStatus = RegSetValueEx(
  343. hKey,
  344. m_pszColumnName,
  345. NULL,
  346. GetValueType(),
  347. pbData,
  348. cbData
  349. );
  350. }
  351. if( m_bEncrypt && NULL != pbData )
  352. {
  353. LocalFree( pbData );
  354. }
  355. }
  356. if( ERROR_SUCCESS == dwStatus )
  357. {
  358. m_bDirty = FALSE;
  359. }
  360. }
  361. CLEANUPANDEXIT:
  362. return dwStatus;
  363. }
  364. template <class T>
  365. DWORD
  366. HelpColumnValueBase<T>::DBLoadValue(
  367. IN HKEY hKey
  368. )
  369. /*++
  370. Routine Description:
  371. Load value from registry.
  372. Parameters:
  373. hKey : Registry handle to read the value from, NULL if uses
  374. current location.
  375. Returns:
  376. ERROR_SUCCESS or error code.
  377. --*/
  378. {
  379. PBYTE pbData = NULL;
  380. DWORD cbData = 0;
  381. DWORD dwStatus = ERROR_SUCCESS;
  382. DWORD dwType;
  383. if( NULL == hKey )
  384. {
  385. hKey = m_hEntryKey;
  386. }
  387. if( NULL != hKey )
  388. {
  389. CCriticalSectionLocker l( m_Lock );
  390. dwStatus = RegQueryValueEx(
  391. hKey,
  392. m_pszColumnName,
  393. NULL,
  394. &dwType,
  395. NULL,
  396. &cbData
  397. );
  398. if( ERROR_SUCCESS == dwStatus )
  399. {
  400. if( dwType == GetValueType() )
  401. {
  402. // we only read registry value that has expected data
  403. // type
  404. pbData = (PBYTE) LocalAlloc( LPTR, cbData );
  405. if( NULL != pbData )
  406. {
  407. dwStatus = RegQueryValueEx(
  408. hKey,
  409. m_pszColumnName,
  410. NULL,
  411. &dwType,
  412. pbData,
  413. &cbData
  414. );
  415. if( ERROR_SUCCESS == dwStatus )
  416. {
  417. if( m_bEncrypt )
  418. {
  419. dwStatus = TSHelpAssistantDecryptData(
  420. NULL,
  421. pbData,
  422. &cbData
  423. );
  424. }
  425. if( ERROR_SUCCESS == dwStatus )
  426. {
  427. if( FALSE == SetValue(pbData, cbData) )
  428. {
  429. dwStatus = GetLastError();
  430. }
  431. }
  432. }
  433. }
  434. else
  435. {
  436. dwStatus = GetLastError();
  437. }
  438. }
  439. else
  440. {
  441. // bad data type, delete it and use default value
  442. (void)RegDeleteValue(
  443. hKey,
  444. m_pszColumnName
  445. );
  446. dwStatus = ERROR_FILE_NOT_FOUND;
  447. }
  448. }
  449. if( ERROR_FILE_NOT_FOUND == dwStatus )
  450. {
  451. // pick the default value if no value in registry
  452. m_Value = m_Default;
  453. dwStatus = ERROR_SUCCESS;
  454. }
  455. if( ERROR_SUCCESS == dwStatus )
  456. {
  457. m_bDirty = FALSE;
  458. }
  459. }
  460. if( NULL != pbData )
  461. {
  462. LocalFree(pbData);
  463. }
  464. return dwStatus;
  465. }
  466. //
  467. // GetValueType(), GetValueSize() for long registry value type.
  468. //
  469. inline DWORD
  470. HelpColumnValueBase<long>::GetValueType()
  471. {
  472. return REG_DWORD;
  473. }
  474. inline DWORD
  475. HelpColumnValueBase<long>::GetValueSize()
  476. {
  477. return sizeof(DWORD);
  478. }
  479. //
  480. // GetValueType(), GetValueSize() for REMOTE_DESKTOP_SHARING_CLASS
  481. // registry value type.
  482. //
  483. inline DWORD
  484. HelpColumnValueBase<REMOTE_DESKTOP_SHARING_CLASS>::GetValueType()
  485. {
  486. return REG_DWORD;
  487. }
  488. inline DWORD
  489. HelpColumnValueBase<REMOTE_DESKTOP_SHARING_CLASS>::GetValueSize()
  490. {
  491. return sizeof(DWORD);
  492. }
  493. //
  494. // GetValue(), GetValueType(), GetValueSize(), SetValue() implmentation
  495. // for CComBSTR
  496. //
  497. inline const PBYTE
  498. HelpColumnValueBase<CComBSTR>::GetValue()
  499. {
  500. return (PBYTE)(LPTSTR)m_Value;
  501. }
  502. inline DWORD
  503. HelpColumnValueBase<CComBSTR>::GetValueType()
  504. {
  505. return ( m_bEncrypt ) ? REG_BINARY : REG_SZ;
  506. }
  507. inline DWORD
  508. HelpColumnValueBase<CComBSTR>::GetValueSize()
  509. {
  510. DWORD dwValueSize;
  511. if( m_Value.Length() == 0 )
  512. {
  513. dwValueSize = 0;
  514. }
  515. else
  516. {
  517. dwValueSize = ( m_Value.Length() + 1 ) * sizeof(TCHAR);
  518. }
  519. return dwValueSize;
  520. }
  521. inline BOOL
  522. HelpColumnValueBase<CComBSTR>::SetValue( PVOID pbData, DWORD cbData )
  523. {
  524. m_Value = (LPTSTR)pbData;
  525. return TRUE;
  526. }
  527. typedef MAP< CComBSTR, PHELPENTRY > HelpEntryCache;
  528. typedef HRESULT (WINAPI* EnumHelpEntryCallback)(
  529. IN CComBSTR& bstrHelpId,
  530. IN HANDLE userData
  531. );
  532. //
  533. //
  534. // CHelpSessionTable class
  535. //
  536. class CHelpSessionTable {
  537. private:
  538. typedef struct __EnumHelpEntryParm {
  539. EnumHelpEntryCallback pCallback;
  540. CHelpSessionTable* pTable;
  541. HANDLE userData;
  542. } EnumHelpEntryParm, *PEnumHelpEntryParm;
  543. HKEY m_hHelpSessionTableKey;
  544. /*static*/ HelpEntryCache m_HelpEntryCache;
  545. DWORD m_NumHelp;
  546. CComBSTR m_bstrFileName;
  547. CCriticalSection m_TableLock;
  548. DWORD m_dwEntryValidPeriod;
  549. static HRESULT
  550. RestoreHelpSessionTable(
  551. HKEY hKey,
  552. LPTSTR pszKeyName,
  553. HANDLE userData
  554. );
  555. static HRESULT
  556. EnumOpenHelpEntry(
  557. HKEY hKey,
  558. LPTSTR pszKeyName,
  559. HANDLE userData
  560. );
  561. HRESULT
  562. RestoreHelpSessionEntry(
  563. HKEY hKey,
  564. LPTSTR pszKeyName
  565. );
  566. HRESULT
  567. LoadHelpEntry(
  568. HKEY hKey,
  569. LPTSTR pszKeyName,
  570. PHELPENTRY* pHelpEntry
  571. );
  572. public:
  573. void
  574. LockHelpTable()
  575. {
  576. m_TableLock.Lock();
  577. }
  578. void
  579. UnlockHelpTable()
  580. {
  581. m_TableLock.UnLock();
  582. }
  583. CHelpSessionTable();
  584. ~CHelpSessionTable();
  585. static HRESULT
  586. CreatePendingHelpTable();
  587. // open help session table
  588. HRESULT
  589. OpenSessionTable(
  590. IN LPCTSTR pszFileName
  591. );
  592. // close help session table
  593. HRESULT
  594. CloseSessionTable();
  595. // Delete help session table
  596. HRESULT
  597. DeleteSessionTable();
  598. // open a help session entry
  599. HRESULT
  600. OpenHelpEntry(
  601. IN const CComBSTR& bstrHelpSession,
  602. OUT PHELPENTRY* pHelpEntry
  603. );
  604. // create a help session entry
  605. HRESULT
  606. CreateInMemoryHelpEntry(
  607. IN const CComBSTR& bstrHelpSession,
  608. OUT PHELPENTRY* pHelpEntry
  609. );
  610. HRESULT
  611. MemEntryToStorageEntry(
  612. IN PHELPENTRY pHelpEntry
  613. );
  614. // delete a help session entry
  615. HRESULT
  616. DeleteHelpEntry(
  617. IN const CComBSTR& bstrHelpSession
  618. );
  619. // remove help entry from cache
  620. HRESULT
  621. ReleaseHelpEntry(
  622. IN CComBSTR& bstrHelpSession
  623. );
  624. HRESULT
  625. EnumHelpEntry(
  626. IN EnumHelpEntryCallback pFunc,
  627. IN HANDLE userData
  628. );
  629. DWORD
  630. NumEntries() { return m_NumHelp; }
  631. BOOL
  632. IsEntryExpired(
  633. PHELPENTRY pHelpEntry
  634. );
  635. };
  636. //
  637. // __HelpEntry structure contains a single help entry.
  638. //
  639. struct __HelpEntry {
  640. friend class CHelpSessionTable;
  641. private:
  642. CHelpSessionTable& m_pHelpSessionTable;
  643. CCriticalSection m_Lock;
  644. HKEY m_hEntryKey;
  645. LONG m_RefCount;
  646. //LONG m_Status;
  647. HRESULT
  648. BackupEntry();
  649. HRESULT
  650. RestoreEntryFromBackup();
  651. HRESULT
  652. DeleteEntryBackup();
  653. LONG
  654. AddRef()
  655. {
  656. DebugPrintf(
  657. _TEXT("HelpEntry %p AddRef %d\n"),
  658. this,
  659. m_RefCount
  660. );
  661. return InterlockedIncrement( &m_RefCount );
  662. }
  663. LONG
  664. Release()
  665. {
  666. DebugPrintf(
  667. _TEXT("HelpEntry %p Release %d\n"),
  668. this,
  669. m_RefCount
  670. );
  671. if( 0 >= InterlockedDecrement( &m_RefCount ) )
  672. {
  673. MYASSERT( 0 == m_RefCount );
  674. delete this;
  675. return 0;
  676. }
  677. return m_RefCount;
  678. }
  679. HRESULT
  680. UpdateEntryValues(
  681. HKEY hKey
  682. );
  683. HRESULT
  684. LoadEntryValues(
  685. HKEY hKey
  686. );
  687. void
  688. EnableImmediateUpdate(
  689. BOOL bImmediate
  690. )
  691. /*++
  692. --*/
  693. {
  694. m_EnableResolver.EnableImmediateUpdate( bImmediate );
  695. m_SessResolverBlob.EnableImmediateUpdate( bImmediate );
  696. m_UserSID.EnableImmediateUpdate( bImmediate );
  697. m_SessionRdsSetting.EnableImmediateUpdate( bImmediate );
  698. m_SessionId.EnableImmediateUpdate( bImmediate );
  699. m_CreationTime.EnableImmediateUpdate( bImmediate );
  700. m_ExpirationTime.EnableImmediateUpdate( bImmediate );
  701. m_ICSPort.EnableImmediateUpdate( bImmediate );
  702. m_IpAddress.EnableImmediateUpdate( bImmediate );
  703. m_SessionCreateBlob.EnableImmediateUpdate( bImmediate );
  704. }
  705. HKEY
  706. ConvertHelpEntry(
  707. HKEY hKey
  708. )
  709. /*++
  710. --*/
  711. {
  712. HKEY oldKey = m_hEntryKey;
  713. m_hEntryKey = hKey;
  714. m_EnableResolver.SetRegStoreHandle(m_hEntryKey);
  715. m_SessResolverBlob.SetRegStoreHandle(m_hEntryKey);
  716. m_UserSID.SetRegStoreHandle(m_hEntryKey);
  717. m_SessionRdsSetting.SetRegStoreHandle(m_hEntryKey);
  718. m_SessionId.SetRegStoreHandle(m_hEntryKey);
  719. m_CreationTime.SetRegStoreHandle(m_hEntryKey);
  720. m_ExpirationTime.SetRegStoreHandle(m_hEntryKey);
  721. m_ICSPort.SetRegStoreHandle(m_hEntryKey);
  722. m_IpAddress.SetRegStoreHandle(m_hEntryKey);
  723. m_SessionCreateBlob.SetRegStoreHandle(m_hEntryKey);
  724. return oldKey;
  725. }
  726. HRESULT
  727. DeleteEntry()
  728. /*++
  729. --*/
  730. {
  731. DWORD dwStatus;
  732. CCriticalSectionLocker l(m_Lock);
  733. m_EntryStatus = REGVALUE_HELPSESSION_ENTRY_DELETED;
  734. dwStatus = m_EntryStatus.DBUpdateValue(m_hEntryKey);
  735. if( NULL != m_hEntryKey )
  736. {
  737. RegCloseKey( m_hEntryKey );
  738. m_hEntryKey = NULL;
  739. }
  740. MYASSERT( ERROR_SUCCESS == dwStatus );
  741. return HRESULT_FROM_WIN32(dwStatus);
  742. }
  743. HelpColumnValueBase<long> m_EntryStatus;
  744. HelpColumnValueBase<FILETIME> m_CreationTime;
  745. DWORD
  746. GetRefCount()
  747. {
  748. return m_RefCount;
  749. }
  750. public:
  751. // Help Session ID
  752. HelpColumnValueBase<CComBSTR> m_SessionId;
  753. // Help Session create blob
  754. HelpColumnValueBase<CComBSTR> m_SessionCreateBlob;
  755. // Enable resolver callback
  756. HelpColumnValueBase<long> m_EnableResolver;
  757. // Blob to be passed to resolver
  758. HelpColumnValueBase<CComBSTR> m_SessResolverBlob;
  759. // SID of user that created this entry.
  760. HelpColumnValueBase<CComBSTR> m_UserSID;
  761. // Help session RDS setting.
  762. HelpColumnValueBase<REMOTE_DESKTOP_SHARING_CLASS> m_SessionRdsSetting;
  763. // Help Expiration date in absolute time
  764. HelpColumnValueBase<FILETIME> m_ExpirationTime;
  765. // ICS port
  766. HelpColumnValueBase<long> m_ICSPort;
  767. // IP Address when creating this ticket
  768. HelpColumnValueBase<CComBSTR> m_IpAddress;
  769. __HelpEntry(
  770. IN CHelpSessionTable& Table,
  771. IN HKEY hKey,
  772. IN DWORD dwDefaultExpirationTime = ENTRY_VALID_PERIOD,
  773. IN BOOL bImmediateUpdate = TRUE
  774. ) :
  775. m_pHelpSessionTable(Table),
  776. m_hEntryKey(hKey),
  777. m_EntryStatus(m_Lock, hKey, COLUMNNAME_KEYSTATUS, REGVALUE_HELPSESSION_ENTRY_NEW, bImmediateUpdate),
  778. m_CreationTime(m_Lock, hKey, COLUMNNAME_CREATETIME, defaultCreationTime, bImmediateUpdate),
  779. m_SessionId(m_Lock, hKey, COLUMNNAME_SESSIONID, CComBSTR(), bImmediateUpdate),
  780. m_SessionCreateBlob(m_Lock, hKey, COLUMNNAME_SESSIONCREATEBLOB, CComBSTR(), bImmediateUpdate),
  781. m_EnableResolver(m_Lock, hKey, COLUMNNAME_ENABLESESSIONRESOLVER, FALSE, bImmediateUpdate),
  782. m_SessResolverBlob(m_Lock, hKey, COLUMNNAME_SESSIONRESOLVERBLOB, CComBSTR(), bImmediateUpdate),
  783. m_UserSID(m_Lock, hKey, COLUMNNAME_SESSIONUSERID, CComBSTR(), bImmediateUpdate),
  784. m_SessionRdsSetting(m_Lock, hKey, COLUMNNAME_RDSSETTING, DESKTOPSHARING_DEFAULT, bImmediateUpdate),
  785. m_ExpirationTime(m_Lock, hKey, COLUMNNAME_EXPIRATIONTIME, defaultCreationTime, bImmediateUpdate),
  786. m_ICSPort(m_Lock, hKey, COLUMNNAME_ICSPORT, 0, bImmediateUpdate),
  787. m_IpAddress(m_Lock, hKey, COLUMNNAME_IPADDRESS, CComBSTR(), bImmediateUpdate),
  788. m_RefCount(1)
  789. {
  790. FILETIME ft;
  791. // Sets up entry creation time.
  792. GetSystemTimeAsFileTime( &ft );
  793. //
  794. // we are setting up default value for
  795. // ticket creation and expiration time, enabling it update
  796. // immediately will cause registry value to be overwritten.
  797. //
  798. m_CreationTime.EnableImmediateUpdate(FALSE);
  799. m_ExpirationTime.EnableImmediateUpdate(FALSE);
  800. m_CreationTime = ft;
  801. // sets up default expiration time.
  802. time_t curTime;
  803. time(&curTime);
  804. // 24 hour timeout period
  805. curTime += (dwDefaultExpirationTime * 60 * 60 * 24);
  806. UnixTimeToFileTime( curTime, &ft );
  807. m_ExpirationTime = ft;
  808. //
  809. // enabling update mode for ticket creation and
  810. // expiration time.
  811. //
  812. if( bImmediateUpdate )
  813. {
  814. // already setup the default, turn on the update mode,
  815. // note, turning on update mode does not cause value to
  816. // flush to registry.
  817. m_CreationTime.EnableImmediateUpdate(bImmediateUpdate);
  818. m_ExpirationTime.EnableImmediateUpdate(bImmediateUpdate);
  819. }
  820. }
  821. ~__HelpEntry()
  822. {
  823. //m_pHelpSessionTable.ReleaseHelpEntry( (CComBSTR)m_SessionId );
  824. if( NULL != m_hEntryKey )
  825. {
  826. RegCloseKey( m_hEntryKey );
  827. m_hEntryKey = NULL;
  828. }
  829. }
  830. __HelpEntry&
  831. operator=(const __HelpEntry& newVal)
  832. {
  833. if( this != &newVal )
  834. {
  835. m_SessionId = newVal.m_SessionId;
  836. m_EnableResolver = newVal.m_EnableResolver;
  837. m_SessResolverBlob = newVal.m_SessResolverBlob;
  838. m_UserSID = newVal.m_UserSID;
  839. m_CreationTime = newVal.m_CreationTime;
  840. m_SessionRdsSetting = newVal.m_SessionRdsSetting;
  841. m_ExpirationTime = newVal.m_ExpirationTime;
  842. m_ICSPort = newVal.m_ICSPort;
  843. m_IpAddress = newVal.m_IpAddress;
  844. m_SessionCreateBlob = newVal.m_SessionCreateBlob;
  845. }
  846. return *this;
  847. }
  848. HRESULT
  849. BeginUpdate()
  850. /*++
  851. Routine Description:
  852. Begin update save a copied of entries and disable immediate
  853. registry value update mode.
  854. Parameters:
  855. None.
  856. Returns:
  857. S_OK or error code.
  858. --*/
  859. {
  860. HRESULT hRes = S_OK;
  861. m_Lock.Lock();
  862. if( NULL != m_hEntryKey )
  863. {
  864. hRes = BackupEntry();
  865. if( FAILED(hRes) )
  866. {
  867. // unlock entry if can't save
  868. // a backup copy
  869. m_Lock.UnLock();
  870. }
  871. else
  872. {
  873. // ignore individual value update mode and
  874. // set to no immediate update
  875. EnableImmediateUpdate(FALSE);
  876. }
  877. }
  878. // note, we only commit changes to registry when caller
  879. // invoke CommitUpdate() so we don't need to mark entry
  880. // dirty in registry now.
  881. return hRes;
  882. }
  883. HRESULT
  884. CommitUpdate()
  885. /*++
  886. Routine Description:
  887. Commit all changes to registry.
  888. Parameters:
  889. None.
  890. Returns:
  891. S_OK or error code.
  892. --*/
  893. {
  894. HRESULT hRes = S_OK;
  895. if( NULL != m_hEntryKey )
  896. {
  897. hRes = UpdateEntryValues( m_hEntryKey );
  898. }
  899. // ignore individual value update mode and
  900. // set to immediate update
  901. EnableImmediateUpdate(TRUE);
  902. // let caller decide what to do when fail to update value.
  903. UnlockEntry();
  904. return hRes;
  905. }
  906. HRESULT
  907. AbortUpdate()
  908. /*++
  909. Routine Description:
  910. Abort changes to value and restore back to
  911. original value.
  912. Parameters:
  913. None.
  914. Returns:
  915. S_OK or error code.
  916. --*/
  917. {
  918. HRESULT hRes = HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
  919. if( NULL != m_hEntryKey )
  920. {
  921. hRes = RestoreEntryFromBackup();
  922. }
  923. EnableImmediateUpdate(TRUE);
  924. // let caller decide what to do when restore failed.
  925. UnlockEntry();
  926. return hRes;
  927. }
  928. HRESULT
  929. Close()
  930. /*++
  931. Routine Description:
  932. Close a help entry and remove from cache, entry is undefined
  933. after close.
  934. Parameters:
  935. None.
  936. Returns:
  937. S_OK or error code.
  938. --*/
  939. {
  940. HRESULT hRes;
  941. hRes = m_pHelpSessionTable.ReleaseHelpEntry( (CComBSTR)m_SessionId );
  942. if( FAILED(hRes) )
  943. {
  944. if( HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND) != hRes )
  945. {
  946. MYASSERT(FALSE);
  947. }
  948. Release();
  949. }
  950. // Always S_OK
  951. return S_OK;
  952. }
  953. HRESULT
  954. Delete()
  955. /*++
  956. Routine Description:
  957. Delete a help entry from table, entry is undefined after delete.
  958. Parameters:
  959. None.
  960. Returns:
  961. S_OK or error code.
  962. --*/
  963. {
  964. HRESULT hRes;
  965. // ignore error since restore will delete 'deleted' entry
  966. hRes = m_pHelpSessionTable.DeleteHelpEntry( (CComBSTR)m_SessionId );
  967. if( FAILED(hRes) )
  968. {
  969. //MYASSERT(FALSE);
  970. Release();
  971. }
  972. return hRes;
  973. }
  974. HRESULT
  975. Refresh()
  976. /*++
  977. Routine Description:
  978. Reload entry from registry.
  979. Parameters:
  980. None.
  981. Returns:
  982. S_OK or error code.
  983. --*/
  984. {
  985. HRESULT hRes;
  986. LockEntry();
  987. hRes = LoadEntryValues(m_hEntryKey);
  988. UnlockEntry();
  989. return hRes;
  990. }
  991. void
  992. LockEntry()
  993. /*++
  994. Routine Description:
  995. Lock entry for update.
  996. Parameters:
  997. None.
  998. Returns:
  999. None.
  1000. --*/
  1001. {
  1002. m_Lock.Lock();
  1003. }
  1004. void
  1005. UnlockEntry()
  1006. /*++
  1007. Routine Description:
  1008. Unlock entry.
  1009. Parameters:
  1010. None.
  1011. Returns:
  1012. None.
  1013. --*/
  1014. {
  1015. m_Lock.UnLock();
  1016. }
  1017. //
  1018. // Check if entry is locked for update
  1019. BOOL
  1020. IsUpdateInProgress();
  1021. //
  1022. // Get CRITICAL_SECTION used in current entry, this
  1023. // routine is used by help session object to save resource
  1024. CCriticalSection&
  1025. GetLock()
  1026. {
  1027. return m_Lock;
  1028. }
  1029. // TRUE if entry is memory only, FALSE if entry
  1030. // is backup to registry
  1031. BOOL
  1032. IsInMemoryHelpEntry()
  1033. {
  1034. return (NULL == m_hEntryKey);
  1035. }
  1036. BOOL
  1037. IsEntryExpired();
  1038. };
  1039. #endif