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.

972 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: sht.cxx
  7. //
  8. // Contents: Small Handle table implementation
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 2-03-97 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <lsapch.hxx>
  18. #include "sht.hxx"
  19. #if DBG
  20. #define DBG_SHT 1
  21. #else
  22. #define DBG_SHT 0
  23. #endif
  24. #define SHT_ACTION_ADDREF 0
  25. #define SHT_ACTION_DELREF 1
  26. #define SHT_ACTION_FORCEDEL 2
  27. #define SHT_ACTION_VALIDATE 3
  28. #define SHT_ACTION_ADDHANDLE 4
  29. #define SHT_ACTION_DELHANDLE 5
  30. #define SHT_ACTION_MASK 0x0000FFFF
  31. #define SHT_ACTION_LOCKED 0x00010000
  32. #define SHTP_HANDLE_CHECKED 0x20000000
  33. #define ShtLockTable( t ) \
  34. if ( (((PSMALL_HANDLE_TABLE) t)->Flags & SHT_NO_SERIALIZE ) == 0 ) \
  35. { \
  36. RtlEnterCriticalSection( &((PSMALL_HANDLE_TABLE)t)->Lock ); \
  37. }
  38. #define ShtUnlockTable( t ) \
  39. if ( (((PSMALL_HANDLE_TABLE) t)->Flags & SHT_NO_SERIALIZE ) == 0 ) \
  40. { \
  41. RtlLeaveCriticalSection( &((PSMALL_HANDLE_TABLE)t)->Lock ); \
  42. }
  43. HP_INITIALIZE_FN ShtInitialize ;
  44. HP_CREATE_FN ShtCreate ;
  45. HP_DELETE_FN ShtDelete ;
  46. HP_ADD_HANDLE_FN ShtAddHandle ;
  47. HP_DELETE_HANDLE_FN ShtDeleteHandle ;
  48. HP_VALIDATE_HANDLE_FN ShtValidateHandle ;
  49. HP_REF_HANDLE_FN ShtRefHandle ;
  50. HP_DEREF_HANDLE_KEY_FN ShtDerefHandleKey ;
  51. HP_GET_HANDLE_CONTEXT_FN ShtGetHandleContext ;
  52. HP_RELEASE_CONTEXT_FN ShtReleaseContext ;
  53. HANDLE_PACKAGE SmallHandlePackage = {
  54. sizeof( SMALL_HANDLE_TABLE),
  55. ShtInitialize,
  56. ShtCreate,
  57. ShtDelete,
  58. ShtAddHandle,
  59. ShtDeleteHandle,
  60. ShtValidateHandle,
  61. ShtRefHandle,
  62. ShtDerefHandleKey,
  63. ShtGetHandleContext,
  64. ShtReleaseContext
  65. };
  66. //+---------------------------------------------------------------------------
  67. //
  68. // Function: ShtInitialize
  69. //
  70. // Synopsis: Initialize the small handle table package
  71. //
  72. // Arguments: (none)
  73. //
  74. // History: 3-04-97 RichardW Created
  75. //
  76. // Notes:
  77. //
  78. //----------------------------------------------------------------------------
  79. BOOL
  80. ShtInitialize(
  81. VOID
  82. )
  83. {
  84. return TRUE ;
  85. }
  86. //+---------------------------------------------------------------------------
  87. //
  88. // Function: ShtCreate
  89. //
  90. // Synopsis: Create a small handle table
  91. //
  92. // Arguments: [Flags] -- Options
  93. // [HandleTable] -- Space to fill
  94. //
  95. // History: 3-04-97 RichardW Created
  96. //
  97. // Notes:
  98. //
  99. //----------------------------------------------------------------------------
  100. PVOID
  101. ShtCreate(
  102. IN ULONG Flags,
  103. IN PVOID HandleTable OPTIONAL,
  104. IN PHP_ENUM_CALLBACK_FN Callback OPTIONAL
  105. )
  106. {
  107. PSMALL_HANDLE_TABLE Table ;
  108. if ( HandleTable )
  109. {
  110. Table = (PSMALL_HANDLE_TABLE) HandleTable ;
  111. }
  112. else
  113. {
  114. Table = (PSMALL_HANDLE_TABLE) LsapAllocatePrivateHeap( sizeof( SMALL_HANDLE_TABLE ) );
  115. }
  116. if ( Table )
  117. {
  118. Table->Tag = SHT_TAG ;
  119. Table->Count = 0 ;
  120. Table->Flags = 0 ;
  121. InitializeListHead( &Table->List );
  122. //
  123. // Turn on general flags:
  124. //
  125. Table->Flags = (Flags & HANDLE_PACKAGE_GENERAL_FLAGS);
  126. if ( Flags & HANDLE_PACKAGE_NO_SERIALIZE )
  127. {
  128. Table->Flags |= SHT_NO_SERIALIZE ;
  129. }
  130. else
  131. {
  132. NTSTATUS Status = RtlInitializeCriticalSection( &Table->Lock );
  133. if (!NT_SUCCESS(Status))
  134. {
  135. if ( !HandleTable )
  136. {
  137. LsapFreePrivateHeap( Table );
  138. }
  139. Table = NULL ;
  140. }
  141. }
  142. if ( Table )
  143. {
  144. if ( Flags & HANDLE_PACKAGE_CALLBACK_ON_DELETE )
  145. {
  146. Table->DeleteCallback = Callback ;
  147. }
  148. if ( HandleTable )
  149. {
  150. Table->Flags |= SHT_NO_FREE ;
  151. }
  152. }
  153. }
  154. return Table ;
  155. }
  156. //+---------------------------------------------------------------------------
  157. //
  158. // Function: ShtDelete
  159. //
  160. // Synopsis: Deletes a handle table. Callback is called for every handle in
  161. // the table.
  162. //
  163. // Arguments: [HandleTable] --
  164. // [Callback] --
  165. //
  166. // History: 3-04-97 RichardW Created
  167. //
  168. // Notes:
  169. //
  170. //----------------------------------------------------------------------------
  171. BOOL
  172. ShtDelete(
  173. PVOID HandleTable,
  174. PHP_ENUM_CALLBACK_FN Callback
  175. )
  176. {
  177. PSMALL_HANDLE_TABLE Table ;
  178. PSEC_HANDLE_ENTRY Entry ;
  179. PLIST_ENTRY Scan ;
  180. ULONG RefCount ;
  181. Table = (PSMALL_HANDLE_TABLE) HandleTable ;
  182. ShtLockTable( Table );
  183. Table->Flags |= SHT_DELETE_PENDING ;
  184. while ( !IsListEmpty( &Table->List ) )
  185. {
  186. Scan = RemoveHeadList( &Table->List );
  187. Table->Count--;
  188. Entry = (PSEC_HANDLE_ENTRY) Scan ;
  189. Table->PendingHandle = Entry ;
  190. Entry->Flags |= SEC_HANDLE_FLAG_DELETE_PENDING ;
  191. RefCount = Entry->HandleCount ;
  192. Entry->HandleCount = 1;
  193. Entry->RefCount = 1 ;
  194. if ( ( Callback ) &&
  195. ( ( Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK ) == 0 ) )
  196. {
  197. Callback( &Entry->Handle, Entry->Context, RefCount );
  198. }
  199. LsapFreePrivateHeap( Entry );
  200. }
  201. DsysAssert( Table->Count == 0 );
  202. if ( ( Table->Flags & SHT_NO_SERIALIZE ) == 0 )
  203. {
  204. RtlDeleteCriticalSection( &Table->Lock );
  205. }
  206. if ( (Table->Flags & SHT_NO_FREE) == 0 )
  207. {
  208. LsapFreePrivateHeap( Table );
  209. }
  210. return TRUE ;
  211. }
  212. #if DBG_SHT
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Function: ShtpValidateList
  216. //
  217. // Synopsis: Debug only - validates a handle table
  218. //
  219. // Arguments: [Table] --
  220. //
  221. // History: 3-04-97 RichardW Created
  222. //
  223. // Notes:
  224. //
  225. //----------------------------------------------------------------------------
  226. VOID
  227. ShtpValidateList(
  228. PSMALL_HANDLE_TABLE Table,
  229. BOOL Locked
  230. )
  231. {
  232. PLIST_ENTRY List ;
  233. PSEC_HANDLE_ENTRY Entry ;
  234. PSEC_HANDLE_ENTRY Back ;
  235. ULONG Count ;
  236. if ( !Locked )
  237. {
  238. ShtLockTable( Table );
  239. }
  240. List = Table->List.Flink ;
  241. Count = 0 ;
  242. while ( List && (List != &Table->List) )
  243. {
  244. Entry = (PSEC_HANDLE_ENTRY) List ;
  245. if ( List->Blink != &Table->List )
  246. {
  247. Back = (PSEC_HANDLE_ENTRY) List->Blink ;
  248. DsysAssertMsg( Back->Handle.dwUpper <= Entry->Handle.dwUpper, "Handle Table Corrupt (1)" );
  249. }
  250. List = List->Flink ;
  251. Count++ ;
  252. }
  253. DsysAssertMsg( List, "Handle Table Corrupt (2)" );
  254. DsysAssertMsg( Count == Table->Count, "Handle Table Corrupt (3)" );
  255. if ( !Locked )
  256. {
  257. ShtUnlockTable( Table );
  258. }
  259. }
  260. #endif
  261. //+---------------------------------------------------------------------------
  262. //
  263. // Function: ShtpFindHandle
  264. //
  265. // Synopsis: General worker function for locating handles in the table
  266. //
  267. // Arguments: [Table] -- Table to search
  268. // [Handle] -- Handle to find
  269. // [Action] -- Action to take
  270. // [Removed] -- Flag if it was removed or just deref'd
  271. //
  272. // History: 3-04-97 RichardW Created
  273. //
  274. // Notes:
  275. //
  276. //----------------------------------------------------------------------------
  277. PSEC_HANDLE_ENTRY
  278. ShtpFindHandle(
  279. PSMALL_HANDLE_TABLE Table,
  280. PSecHandle Handle,
  281. ULONG Action,
  282. PBOOL Removed OPTIONAL
  283. )
  284. {
  285. PLIST_ENTRY Scan ;
  286. PSEC_HANDLE_ENTRY Entry ;
  287. BOOL Delete = FALSE ;
  288. Entry = NULL ;
  289. BOOL Locked ;
  290. BOOL Checked ;
  291. Locked = (Action & SHT_ACTION_LOCKED) == SHT_ACTION_LOCKED ;
  292. Checked = (Action & SHTP_HANDLE_CHECKED) == SHTP_HANDLE_CHECKED ;
  293. Action = Action & SHT_ACTION_MASK ;
  294. #if DBG_SHT
  295. ShtpValidateList( Table, Locked );
  296. #endif
  297. if ( !Locked )
  298. {
  299. ShtLockTable( Table );
  300. }
  301. if ( ( Table->Flags & SHT_DELETE_PENDING ) &&
  302. ( Table->PendingHandle ) )
  303. {
  304. if ( (Handle->dwUpper == Table->PendingHandle->Handle.dwUpper) &&
  305. (Handle->dwLower == Table->PendingHandle->Handle.dwLower) )
  306. {
  307. Entry = Table->PendingHandle ;
  308. DsysAssert( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING );
  309. goto FoundEntry ;
  310. }
  311. }
  312. Scan = Table->List.Flink ;
  313. while ( Scan != &Table->List )
  314. {
  315. Entry = (PSEC_HANDLE_ENTRY) Scan ;
  316. if ( Entry->Handle.dwUpper == Handle->dwUpper )
  317. {
  318. if ( Entry->Handle.dwLower == Handle->dwLower )
  319. {
  320. break;
  321. }
  322. }
  323. if ( Entry->Handle.dwUpper > Handle->dwUpper )
  324. {
  325. Entry = NULL ;
  326. break;
  327. }
  328. Scan = Entry->List.Flink ;
  329. Entry = NULL ;
  330. }
  331. if ( Entry &&
  332. ((Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING) != 0 ) )
  333. {
  334. DebugLog(( DEB_WARN, "Entry %p on list but marked delete pending\n", Entry ));
  335. Entry = NULL ;
  336. }
  337. if ( Entry &&
  338. ( Entry->HandleCount == 0 ) &&
  339. ( !Checked ) )
  340. {
  341. DebugLog(( DEB_TRACE_HANDLES, "Entry %p has handle count 0, no ref for %p:%p \n",
  342. Entry,
  343. Entry->Handle.dwUpper,
  344. Entry->Handle.dwLower ));
  345. Entry = NULL ;
  346. }
  347. FoundEntry :
  348. if ( Entry )
  349. {
  350. switch ( Action )
  351. {
  352. case SHT_ACTION_ADDHANDLE:
  353. Entry->HandleIssuedCount++;
  354. Entry->HandleCount++ ;
  355. //
  356. // Fall through to the ADDREF behavior:
  357. //
  358. case SHT_ACTION_ADDREF:
  359. Entry->RefCount++;
  360. break;
  361. case SHT_ACTION_DELHANDLE:
  362. if ( Entry->HandleCount )
  363. {
  364. Entry->HandleCount-- ;
  365. }
  366. else
  367. {
  368. break;
  369. }
  370. //
  371. // Fall through to the DELREF behavior
  372. //
  373. case SHT_ACTION_DELREF:
  374. case SHT_ACTION_FORCEDEL:
  375. Entry->RefCount -- ;
  376. DsysAssert( Entry->RefCount >= Entry->HandleCount );
  377. if ( ( Entry->RefCount == 0 ) ||
  378. ( Action == SHT_ACTION_FORCEDEL ) )
  379. {
  380. if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
  381. {
  382. RemoveEntryList( &Entry->List );
  383. Table->Count-- ;
  384. }
  385. Delete = TRUE ;
  386. }
  387. break;
  388. case SHT_ACTION_VALIDATE:
  389. default:
  390. break;
  391. }
  392. }
  393. if ( !Locked )
  394. {
  395. ShtUnlockTable( Table );
  396. }
  397. if ( Removed )
  398. {
  399. *Removed = Delete ;
  400. }
  401. #if DBG_SHT
  402. ShtpValidateList( Table, Locked );
  403. #endif
  404. return Entry ;
  405. }
  406. //+---------------------------------------------------------------------------
  407. //
  408. // Function: ShtpPopHandle
  409. //
  410. // Synopsis: Private function for the large package. Pops a handle out of
  411. // the table for redistribution.
  412. //
  413. // Arguments: [Table] --
  414. //
  415. // History: 3-04-97 RichardW Created
  416. //
  417. // Notes:
  418. //
  419. //----------------------------------------------------------------------------
  420. PSEC_HANDLE_ENTRY
  421. ShtpPopHandle(
  422. PSMALL_HANDLE_TABLE Table
  423. )
  424. {
  425. PLIST_ENTRY List ;
  426. ShtLockTable( Table );
  427. if ( !IsListEmpty( &Table->List ) )
  428. {
  429. List = RemoveHeadList( &Table->List );
  430. Table->Count-- ;
  431. }
  432. else
  433. {
  434. List = NULL ;
  435. }
  436. ShtUnlockTable( Table );
  437. #if DBG_SHT
  438. ShtpValidateList( Table, FALSE );
  439. #endif
  440. return ((PSEC_HANDLE_ENTRY) List );
  441. }
  442. //+---------------------------------------------------------------------------
  443. //
  444. // Function: ShtpInsertHandle
  445. //
  446. // Synopsis: Worker function for lht. Inserts an existing entry into a table
  447. //
  448. // Arguments: [Table] --
  449. // [Entry] --
  450. //
  451. // History: 3-04-97 RichardW Created
  452. //
  453. // Notes:
  454. //
  455. //----------------------------------------------------------------------------
  456. VOID
  457. ShtpInsertHandle(
  458. PSMALL_HANDLE_TABLE Table,
  459. PSEC_HANDLE_ENTRY Entry
  460. )
  461. {
  462. PLIST_ENTRY Scan ;
  463. PSEC_HANDLE_ENTRY Compare ;
  464. ShtLockTable( Table );
  465. Scan = Table->List.Flink ;
  466. while ( Scan != &Table->List )
  467. {
  468. Compare = (PSEC_HANDLE_ENTRY) Scan ;
  469. if ( Compare->Handle.dwUpper >= Entry->Handle.dwUpper )
  470. {
  471. break;
  472. }
  473. Scan = Compare->List.Flink ;
  474. Compare = NULL ;
  475. }
  476. InsertTailList( Scan, &Entry->List );
  477. Table->Count++;
  478. ShtUnlockTable( Table );
  479. #if DBG_SHT
  480. ShtpValidateList( Table, FALSE );
  481. #endif
  482. }
  483. //+---------------------------------------------------------------------------
  484. //
  485. // Function: ShtAddHandle
  486. //
  487. // Synopsis: Add a handle to the table.
  488. //
  489. // Arguments: [HandleTable] --
  490. // [Handle] --
  491. //
  492. // History: 3-04-97 RichardW Created
  493. //
  494. // Notes:
  495. //
  496. //----------------------------------------------------------------------------
  497. BOOL
  498. ShtAddHandle(
  499. PVOID HandleTable,
  500. PSecHandle Handle,
  501. PVOID Context,
  502. ULONG Flags
  503. )
  504. {
  505. PSMALL_HANDLE_TABLE Table ;
  506. PSEC_HANDLE_ENTRY Entry ;
  507. PSEC_HANDLE_ENTRY Compare ;
  508. PLIST_ENTRY Scan ;
  509. Table = (PSMALL_HANDLE_TABLE) HandleTable ;
  510. //
  511. // Need to make whole add operation atomic
  512. //
  513. ShtLockTable( Table );
  514. if ( ShtpFindHandle( Table,
  515. Handle,
  516. SHT_ACTION_ADDHANDLE | SHT_ACTION_LOCKED,
  517. NULL ) )
  518. {
  519. ShtUnlockTable( Table );
  520. if ( Table->Flags & HANDLE_PACKAGE_REQUIRE_UNIQUE )
  521. {
  522. return FALSE ;
  523. }
  524. return TRUE ;
  525. }
  526. Entry = (PSEC_HANDLE_ENTRY) LsapAllocatePrivateHeap(
  527. sizeof( SEC_HANDLE_ENTRY ) );
  528. if ( Entry )
  529. {
  530. Entry->RefCount = 1;
  531. Entry->HandleCount = 1;
  532. Entry->Handle = *Handle ;
  533. Entry->Context = Context ;
  534. Entry->HandleIssuedCount = 1;
  535. Scan = Table->List.Flink ;
  536. while ( Scan != &Table->List )
  537. {
  538. Compare = (PSEC_HANDLE_ENTRY) Scan ;
  539. if ( Compare->Handle.dwUpper >= Handle->dwUpper )
  540. {
  541. break;
  542. }
  543. Scan = Compare->List.Flink ;
  544. Compare = NULL ;
  545. }
  546. Entry->Flags = Flags ;
  547. InsertTailList( Scan, &Entry->List );
  548. Table->Count++;
  549. ShtUnlockTable( Table );
  550. #if DBG_SHT
  551. ShtpValidateList( Table, FALSE );
  552. #endif
  553. return TRUE ;
  554. }
  555. ShtUnlockTable( Table );
  556. return FALSE ;
  557. }
  558. //+---------------------------------------------------------------------------
  559. //
  560. // Function: ShtDeleteHandle
  561. //
  562. // Synopsis: Deletes a handle from the table
  563. //
  564. // Arguments: [HandleTable] --
  565. // [Handle] --
  566. // [Force] --
  567. //
  568. // History: 3-04-97 RichardW Created
  569. //
  570. // Notes:
  571. //
  572. //----------------------------------------------------------------------------
  573. BOOL
  574. ShtDeleteHandle(
  575. PVOID HandleTable,
  576. PSecHandle Handle,
  577. ULONG Options
  578. )
  579. {
  580. PSEC_HANDLE_ENTRY Entry ;
  581. BOOL Delete ;
  582. Entry = ShtpFindHandle( (PSMALL_HANDLE_TABLE) HandleTable,
  583. Handle,
  584. (Options & DELHANDLE_FORCE) ?
  585. SHT_ACTION_FORCEDEL : SHT_ACTION_DELHANDLE,
  586. &Delete );
  587. if ( Entry )
  588. {
  589. if ( Delete )
  590. {
  591. PSMALL_HANDLE_TABLE Table = (PSMALL_HANDLE_TABLE) HandleTable ;
  592. if ( ( Table->DeleteCallback ) &&
  593. ( ( Options & DELHANDLE_NO_CALLBACK ) == 0 ) &&
  594. ( ( Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK ) == 0 ) )
  595. {
  596. Table->DeleteCallback(
  597. &Entry->Handle,
  598. Entry->Context,
  599. Entry->HandleIssuedCount // Entry->RefCount
  600. );
  601. }
  602. if ( (Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING) == 0 )
  603. {
  604. LsapFreePrivateHeap( Entry );
  605. }
  606. }
  607. return TRUE ;
  608. }
  609. return FALSE ;
  610. }
  611. //+---------------------------------------------------------------------------
  612. //
  613. // Function: ShtValidateHandle
  614. //
  615. // Synopsis: Validates a handle is listed in the table.
  616. //
  617. // Arguments: [HandleTable] --
  618. // [Handle] --
  619. //
  620. // History: 3-04-97 RichardW Created
  621. //
  622. // Notes:
  623. //
  624. //----------------------------------------------------------------------------
  625. BOOL
  626. ShtValidateHandle(
  627. PVOID HandleTable,
  628. PSecHandle Handle,
  629. BOOL Deref
  630. )
  631. {
  632. PSEC_HANDLE_ENTRY Entry ;
  633. BOOL Delete = FALSE ;
  634. PSMALL_HANDLE_TABLE Table = (PSMALL_HANDLE_TABLE) HandleTable ;
  635. Entry = ShtpFindHandle( Table,
  636. Handle,
  637. (Deref ? SHT_ACTION_DELHANDLE : SHT_ACTION_VALIDATE),
  638. &Delete );
  639. if ( Entry )
  640. {
  641. if ( Delete )
  642. {
  643. if ( ( Table->DeleteCallback ) &&
  644. ( ( Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK ) == 0 ) )
  645. {
  646. Table->DeleteCallback(
  647. &Entry->Handle,
  648. Entry->Context,
  649. Entry->HandleIssuedCount // Entry->HandleCount
  650. );
  651. }
  652. if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
  653. {
  654. LsapFreePrivateHeap( Entry );
  655. }
  656. }
  657. return TRUE ;
  658. }
  659. else
  660. {
  661. return FALSE ;
  662. }
  663. }
  664. PVOID
  665. ShtRefHandle(
  666. PVOID HandleTable,
  667. PSecHandle Handle
  668. )
  669. {
  670. PSEC_HANDLE_ENTRY Entry ;
  671. Entry = ShtpFindHandle( (PSMALL_HANDLE_TABLE) HandleTable,
  672. Handle,
  673. SHT_ACTION_ADDREF,
  674. NULL );
  675. return Entry ;
  676. }
  677. VOID
  678. ShtDerefHandleKey(
  679. PVOID HandleTable,
  680. PVOID HandleKey
  681. )
  682. {
  683. PSMALL_HANDLE_TABLE Table = (PSMALL_HANDLE_TABLE) HandleTable ;
  684. PSEC_HANDLE_ENTRY Entry = (PSEC_HANDLE_ENTRY) HandleKey ;
  685. BOOL Delete = FALSE ;
  686. ShtLockTable( Table );
  687. Entry->RefCount -- ;
  688. DsysAssert( Entry->RefCount >= Entry->HandleCount );
  689. if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
  690. {
  691. if ( Entry->RefCount == 0 )
  692. {
  693. RemoveEntryList( &Entry->List );
  694. Delete = TRUE ;
  695. Table->Count-- ;
  696. }
  697. }
  698. ShtUnlockTable( Table );
  699. if ( Delete )
  700. {
  701. if ( ( Table->DeleteCallback ) &&
  702. ( ( Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK ) == 0 ) )
  703. {
  704. Table->DeleteCallback( &Entry->Handle, Entry->Context, Entry->HandleCount );
  705. }
  706. if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
  707. {
  708. LsapFreePrivateHeap( Entry );
  709. }
  710. }
  711. }
  712. //+---------------------------------------------------------------------------
  713. //
  714. // Function: ShtGetHandleContext
  715. //
  716. // Synopsis: Returns the context pointer associated with the handle
  717. //
  718. // Arguments: [HandleTable] --
  719. // [Handle] --
  720. //
  721. // History: 8-17-98 RichardW Created
  722. //
  723. // Notes: Adds a reference so it can't be deleted while in use.
  724. //
  725. //----------------------------------------------------------------------------
  726. PVOID
  727. ShtGetHandleContext(
  728. PVOID HandleTable,
  729. PSecHandle Handle
  730. )
  731. {
  732. PSEC_HANDLE_ENTRY Entry ;
  733. Entry = ShtpFindHandle( (PSMALL_HANDLE_TABLE) HandleTable,
  734. Handle,
  735. SHT_ACTION_ADDREF,
  736. NULL );
  737. if ( Entry )
  738. {
  739. return Entry->Context ;
  740. }
  741. return NULL ;
  742. }
  743. //+---------------------------------------------------------------------------
  744. //
  745. // Function: ShtReleaseContext
  746. //
  747. // Synopsis: Deref's a handle entry
  748. //
  749. // Arguments: [HandleTable] --
  750. // [Handle] --
  751. //
  752. // History: 8-17-98 RichardW Created
  753. //
  754. // Notes:
  755. //
  756. //----------------------------------------------------------------------------
  757. BOOL
  758. ShtReleaseContext(
  759. PVOID HandleTable,
  760. PSecHandle Handle
  761. )
  762. {
  763. PSEC_HANDLE_ENTRY Entry ;
  764. BOOL Delete ;
  765. Entry = ShtpFindHandle( (PSMALL_HANDLE_TABLE) HandleTable,
  766. Handle,
  767. SHT_ACTION_DELREF,
  768. &Delete );
  769. if ( Entry )
  770. {
  771. if ( Delete )
  772. {
  773. PSMALL_HANDLE_TABLE Table = (PSMALL_HANDLE_TABLE) HandleTable ;
  774. if ( ( Table->DeleteCallback ) &&
  775. ( ( Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK ) == 0 ) )
  776. {
  777. Table->DeleteCallback( &Entry->Handle, Entry->Context, Entry->RefCount );
  778. }
  779. if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
  780. {
  781. LsapFreePrivateHeap( Entry );
  782. }
  783. }
  784. return TRUE ;
  785. }
  786. return FALSE ;
  787. }