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.

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