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.

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