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.

811 lines
20 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: SPData.cpp
  6. * Content: Global variables for the DNSerial service provider in class
  7. * format.
  8. *
  9. *
  10. * History:
  11. * Date By Reason
  12. * ==== == ======
  13. * 03/15/99 jtk Dereived from Locals.cpp
  14. ***************************************************************************/
  15. #include "dnmdmi.h"
  16. //**********************************************************************
  17. // Constant definitions
  18. //**********************************************************************
  19. // default number of command descriptors to create
  20. #define DEFAULT_COMMAND_POOL_SIZE 20
  21. #define COMMAND_POOL_GROW_SIZE 5
  22. //**********************************************************************
  23. // Macro definitions
  24. //**********************************************************************
  25. //**********************************************************************
  26. // Structure definitions
  27. //**********************************************************************
  28. //**********************************************************************
  29. // Variable definitions
  30. //**********************************************************************
  31. //**********************************************************************
  32. // Function prototypes
  33. //**********************************************************************
  34. //**********************************************************************
  35. // Function definitions
  36. //**********************************************************************
  37. //**********************************************************************
  38. // ------------------------------
  39. // CModemSPData::CModemSPData - constructor
  40. //
  41. // Entry: Nothing
  42. //
  43. // Exit: Nothing
  44. // ------------------------------
  45. #undef DPF_MODNAME
  46. #define DPF_MODNAME "CModemSPData::CModemSPData"
  47. CModemSPData::CModemSPData():
  48. m_lRefCount( 0 ),
  49. m_lObjectRefCount( 0 ),
  50. m_hShutdownEvent( NULL ),
  51. m_SPType( TYPE_UNKNOWN ),
  52. m_State( SPSTATE_UNINITIALIZED ),
  53. m_pThreadPool( NULL ),
  54. m_fLockInitialized( FALSE ),
  55. m_fHandleTableInitialized( FALSE ),
  56. m_fDataPortDataLockInitialized( FALSE ),
  57. m_fInterfaceGlobalsInitialized( FALSE )
  58. {
  59. m_Sig[0] = 'S';
  60. m_Sig[1] = 'P';
  61. m_Sig[2] = 'D';
  62. m_Sig[3] = 'T';
  63. memset( &m_InitData, 0x00, sizeof( m_InitData ) );
  64. memset( &m_DataPortList, 0x00, sizeof( m_DataPortList ) );
  65. memset( &m_COMInterface, 0x00, sizeof( m_COMInterface ) );
  66. #ifndef DPNBUILD_LIBINTERFACE
  67. DNInterlockedIncrement( &g_lModemOutstandingInterfaceCount );
  68. #endif // ! DPNBUILD_LIBINTERFACE
  69. }
  70. //**********************************************************************
  71. //**********************************************************************
  72. // ------------------------------
  73. // CModemSPData::~CModemSPData - destructor
  74. //
  75. // Entry: Nothing
  76. //
  77. // Exit: Nothing
  78. // ------------------------------
  79. #undef DPF_MODNAME
  80. #define DPF_MODNAME "CModemSPData::~CModemSPData"
  81. CModemSPData::~CModemSPData()
  82. {
  83. UINT_PTR uIndex;
  84. DNASSERT( m_lRefCount == 0 );
  85. DNASSERT( m_lObjectRefCount == 0 );
  86. DNASSERT( m_hShutdownEvent == NULL );
  87. DNASSERT( m_SPType == TYPE_UNKNOWN );
  88. DNASSERT( m_State == SPSTATE_UNINITIALIZED );
  89. DNASSERT( m_pThreadPool == NULL );
  90. uIndex = LENGTHOF( m_DataPortList );
  91. while ( uIndex > 0 )
  92. {
  93. uIndex--;
  94. DNASSERT( m_DataPortList[ uIndex ] == NULL );
  95. }
  96. DNASSERT( m_fLockInitialized == FALSE );
  97. DNASSERT( m_fHandleTableInitialized == FALSE );
  98. DNASSERT( m_fDataPortDataLockInitialized == FALSE );
  99. DNASSERT( m_fInterfaceGlobalsInitialized == FALSE );
  100. #ifndef DPNBUILD_LIBINTERFACE
  101. DNInterlockedDecrement( &g_lModemOutstandingInterfaceCount );
  102. #endif // ! DPNBUILD_LIBINTERFACE
  103. }
  104. //**********************************************************************
  105. //**********************************************************************
  106. // ------------------------------
  107. // CModemSPData::Initialize - intialize
  108. //
  109. // Entry: Pointer to DirectNet
  110. //
  111. // Exit: Error code
  112. // ------------------------------
  113. #undef DPF_MODNAME
  114. #define DPF_MODNAME "CModemSPData::Initialize"
  115. HRESULT CModemSPData::Initialize( const SP_TYPE SPType,
  116. IDP8ServiceProviderVtbl *const pVtbl )
  117. {
  118. HRESULT hr;
  119. DNASSERT( pVtbl != NULL );
  120. //
  121. // initialize
  122. //
  123. hr = DPN_OK;
  124. DNASSERT( m_lRefCount == 1 );
  125. DNASSERT( m_lObjectRefCount == 0 );
  126. DNASSERT( GetType() == TYPE_UNKNOWN );
  127. DNASSERT( GetType() == TYPE_UNKNOWN );
  128. m_SPType = SPType;
  129. DNASSERT( m_COMInterface.m_pCOMVtbl == NULL );
  130. m_COMInterface.m_pCOMVtbl = pVtbl;
  131. DNASSERT( m_fLockInitialized == FALSE );
  132. DNASSERT( m_fDataPortDataLockInitialized == FALSE );
  133. DNASSERT( m_fInterfaceGlobalsInitialized == FALSE );
  134. //
  135. // attempt to initialize shutdown event
  136. //
  137. DNASSERT( m_hShutdownEvent == NULL );
  138. m_hShutdownEvent = DNCreateEvent( NULL, // pointer to security (none)
  139. TRUE, // manual reset
  140. TRUE, // start signalled (so close can be called without any endpoints being created)
  141. NULL // pointer to name (none)
  142. );
  143. if ( m_hShutdownEvent == NULL )
  144. {
  145. DWORD dwError;
  146. dwError = GetLastError();
  147. DPFX(DPFPREP, 0, "Failed to create event for shutting down spdata!" );
  148. DisplayErrorCode( 0, dwError );
  149. }
  150. //
  151. // initialize critical sections
  152. //
  153. if ( DNInitializeCriticalSection( &m_Lock ) == FALSE )
  154. {
  155. hr = DPNERR_OUTOFMEMORY;
  156. DPFX(DPFPREP, 0, "Failed to initialize SP lock!" );
  157. goto Failure;
  158. }
  159. DebugSetCriticalSectionRecursionCount( &m_Lock, 0 );
  160. DebugSetCriticalSectionGroup( &m_Lock, &g_blDPNModemCritSecsHeld ); // separate dpnmodem CSes from the rest of DPlay's CSes
  161. m_fLockInitialized = TRUE;
  162. hr = m_HandleTable.Initialize();
  163. if ( hr != DPN_OK )
  164. {
  165. DPFX(DPFPREP, 0, "Failed to initialize handle table!" );
  166. DisplayDNError( 0, hr );
  167. goto Failure;
  168. }
  169. m_fHandleTableInitialized = TRUE;
  170. if ( DNInitializeCriticalSection( &m_DataPortDataLock ) == FALSE )
  171. {
  172. hr = DPNERR_OUTOFMEMORY;
  173. DPFX(DPFPREP, 0, "Failed to initialize data port data lock!" );
  174. goto Failure;
  175. }
  176. DebugSetCriticalSectionRecursionCount( &m_DataPortDataLock, 0 );
  177. DebugSetCriticalSectionGroup( &m_DataPortDataLock, &g_blDPNModemCritSecsHeld ); // separate dpnmodem CSes from the rest of DPlay's CSes
  178. m_fDataPortDataLockInitialized = TRUE;
  179. //
  180. // get a thread pool
  181. //
  182. DNASSERT( m_pThreadPool == NULL );
  183. hr = InitializeInterfaceGlobals( this );
  184. if ( hr != DPN_OK )
  185. {
  186. DPFX(DPFPREP, 0, "Failed to create thread pool!" );
  187. DisplayDNError( 0, hr );
  188. goto Failure;
  189. }
  190. m_fInterfaceGlobalsInitialized = TRUE;
  191. Exit:
  192. if ( hr != DPN_OK )
  193. {
  194. DPFX(DPFPREP, 0, "Problem with CModemSPData::Initialize" );
  195. DisplayDNError( 0, hr );
  196. }
  197. return hr;
  198. Failure:
  199. Deinitialize();
  200. goto Exit;
  201. }
  202. //**********************************************************************
  203. //**********************************************************************
  204. // ------------------------------
  205. // CModemSPData::Shutdown - shut down this set of SP data
  206. //
  207. // Entry: Nothing
  208. //
  209. // Exit: Nothing
  210. // ------------------------------
  211. #undef DPF_MODNAME
  212. #define DPF_MODNAME "CModemSPData::Shutdown"
  213. void CModemSPData::Shutdown( void )
  214. {
  215. BOOL fLooping;
  216. //
  217. // Unbind this interface from the globals. This will cause a closure of all
  218. // of the I/O which will release endpoints, socket ports and then this data.
  219. //
  220. if ( m_fInterfaceGlobalsInitialized != FALSE )
  221. {
  222. DeinitializeInterfaceGlobals( this );
  223. DNASSERT( GetThreadPool() != NULL );
  224. m_fInterfaceGlobalsInitialized = FALSE;
  225. }
  226. SetState( SPSTATE_CLOSING );
  227. DNASSERT( m_hShutdownEvent != NULL );
  228. fLooping = TRUE;
  229. while ( fLooping != FALSE )
  230. {
  231. switch ( DNWaitForSingleObjectEx( m_hShutdownEvent, INFINITE, TRUE ) )
  232. {
  233. case WAIT_OBJECT_0:
  234. {
  235. fLooping = FALSE;
  236. break;
  237. }
  238. case WAIT_IO_COMPLETION:
  239. {
  240. break;
  241. }
  242. default:
  243. {
  244. DNASSERT( FALSE );
  245. break;
  246. }
  247. }
  248. }
  249. if ( DNCloseHandle( m_hShutdownEvent ) == FALSE )
  250. {
  251. DWORD dwError;
  252. dwError = GetLastError();
  253. DPFX(DPFPREP, 0, "Failed to close shutdown event!" );
  254. DisplayErrorCode( 0, dwError );
  255. }
  256. m_hShutdownEvent = NULL;
  257. if ( DP8SPCallbackInterface() != NULL)
  258. {
  259. IDP8SPCallback_Release( DP8SPCallbackInterface() );
  260. memset( &m_InitData, 0x00, sizeof( m_InitData ) );
  261. }
  262. }
  263. //**********************************************************************
  264. //**********************************************************************
  265. // ------------------------------
  266. // CModemSPData::Deinitialize - deinitialize
  267. //
  268. // Entry: Nothing
  269. //
  270. // Exit: Nothing
  271. // ------------------------------
  272. #undef DPF_MODNAME
  273. #define DPF_MODNAME "CModemSPData::Deinitialize"
  274. void CModemSPData::Deinitialize( void )
  275. {
  276. DPFX(DPFPREP, 9, "Entering CModemSPData::Deinitialize" );
  277. //
  278. // deinitialize interface globals
  279. //
  280. if ( m_fInterfaceGlobalsInitialized != FALSE )
  281. {
  282. DeinitializeInterfaceGlobals( this );
  283. DNASSERT( GetThreadPool() != NULL );
  284. m_fInterfaceGlobalsInitialized = FALSE;
  285. }
  286. if ( m_fDataPortDataLockInitialized != FALSE )
  287. {
  288. DNDeleteCriticalSection( &m_DataPortDataLock );
  289. m_fDataPortDataLockInitialized = FALSE;
  290. }
  291. if ( m_fHandleTableInitialized != FALSE )
  292. {
  293. m_HandleTable.Deinitialize();
  294. m_fHandleTableInitialized = FALSE;
  295. }
  296. if ( m_fLockInitialized != FALSE )
  297. {
  298. DNDeleteCriticalSection( &m_Lock );
  299. m_fLockInitialized = FALSE;
  300. }
  301. m_COMInterface.m_pCOMVtbl = NULL;
  302. SetState( SPSTATE_UNINITIALIZED );
  303. m_SPType = TYPE_UNKNOWN;
  304. if ( GetThreadPool() != NULL )
  305. {
  306. GetThreadPool()->DecRef();
  307. SetThreadPool( NULL );
  308. }
  309. if ( m_hShutdownEvent != NULL )
  310. {
  311. if ( DNCloseHandle( m_hShutdownEvent ) == FALSE )
  312. {
  313. DWORD dwError;
  314. dwError = GetLastError();
  315. DPFX(DPFPREP, 0, "Failed to close shutdown handle!" );
  316. DisplayErrorCode( 0, dwError );
  317. }
  318. m_hShutdownEvent = NULL;
  319. }
  320. }
  321. //**********************************************************************
  322. //**********************************************************************
  323. // ------------------------------
  324. // CModemSPData::SetCallbackData - set data for SP callbacks to application
  325. //
  326. // Entry: Pointer to initialization data
  327. //
  328. // Exit: Nothing
  329. // ------------------------------
  330. #undef DPF_MODNAME
  331. #define DPF_MODNAME "CModemSPData::SetCallbackData"
  332. void CModemSPData::SetCallbackData( const SPINITIALIZEDATA *const pInitData )
  333. {
  334. DNASSERT( pInitData != NULL );
  335. DNASSERT( pInitData->dwFlags == SP_SESSION_TYPE_PEER ||
  336. pInitData->dwFlags == SP_SESSION_TYPE_CLIENT ||
  337. pInitData->dwFlags == SP_SESSION_TYPE_SERVER ||
  338. pInitData->dwFlags == 0);
  339. m_InitData.dwFlags = pInitData->dwFlags;
  340. DNASSERT( pInitData->pIDP != NULL );
  341. m_InitData.pIDP = pInitData->pIDP;
  342. }
  343. //**********************************************************************
  344. //**********************************************************************
  345. // ------------------------------
  346. // CModemSPData::BindEndpoint - bind endpoint to a data port
  347. //
  348. // Entry: Pointer to endpoint
  349. // DeviceID
  350. // Device context
  351. //
  352. // Exit: Error code
  353. // ------------------------------
  354. #undef DPF_MODNAME
  355. #define DPF_MODNAME "CModemSPData::BindEndpoint"
  356. HRESULT CModemSPData::BindEndpoint( CModemEndpoint *const pEndpoint,
  357. const DWORD dwDeviceID,
  358. const void *const pDeviceContext )
  359. {
  360. HRESULT hr;
  361. CDataPort *pDataPort;
  362. BOOL fDataPortDataLocked;
  363. BOOL fDataPortCreated;
  364. BOOL fDataPortBoundToNetwork;
  365. DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p, %u, 0x%p)",
  366. this, pEndpoint, dwDeviceID, pDeviceContext);
  367. //
  368. // intialize
  369. //
  370. hr = DPN_OK;
  371. pDataPort = NULL;
  372. fDataPortDataLocked = FALSE;
  373. fDataPortCreated = FALSE;
  374. fDataPortBoundToNetwork = FALSE;
  375. LockDataPortData();
  376. fDataPortDataLocked = TRUE;
  377. if ( m_DataPortList[ dwDeviceID ] != NULL )
  378. {
  379. pDataPort = m_DataPortList[ dwDeviceID ];
  380. }
  381. else
  382. {
  383. DATA_PORT_POOL_CONTEXT DataPortPoolContext;
  384. memset( &DataPortPoolContext, 0x00, sizeof( DataPortPoolContext ) );
  385. DataPortPoolContext.pSPData = this;
  386. pDataPort = CreateDataPort( &DataPortPoolContext );
  387. if ( pDataPort == NULL )
  388. {
  389. hr = DPNERR_OUTOFMEMORY;
  390. DPFX(DPFPREP, 0, "Failed to create new data port!" );
  391. goto Failure;
  392. }
  393. fDataPortCreated = TRUE;
  394. hr = GetThreadPool()->CreateDataPortHandle( pDataPort );
  395. if ( hr != DPN_OK )
  396. {
  397. DPFX(DPFPREP, 0, "Failed to create handle for data port!" );
  398. DisplayDNError( 0, hr );
  399. goto Failure;
  400. }
  401. hr = pDataPort->BindToNetwork( dwDeviceID, pDeviceContext );
  402. if ( hr != DPN_OK )
  403. {
  404. DPFX(DPFPREP, 0, "Failed to bind data port to network!" );
  405. DisplayDNError( 0, hr );
  406. goto Failure;
  407. }
  408. fDataPortBoundToNetwork = TRUE;
  409. //
  410. // update the list, keep the reference added by 'CreateDataPort' as it
  411. // will be cleaned when the data port is removed from the active list.
  412. //
  413. m_DataPortList[ dwDeviceID ] = pDataPort;
  414. }
  415. DNASSERT( pDataPort != NULL );
  416. pDataPort->EndpointAddRef();
  417. hr = pDataPort->BindEndpoint( pEndpoint, pEndpoint->GetType() );
  418. if ( hr != DPN_OK )
  419. {
  420. pDataPort->EndpointDecRef();
  421. DPFX(DPFPREP, 0, "Failed to bind endpoint!" );
  422. DisplayDNError( 0, hr );
  423. goto Failure;
  424. }
  425. Exit:
  426. if ( fDataPortDataLocked != FALSE )
  427. {
  428. UnlockDataPortData();
  429. fDataPortDataLocked = FALSE;
  430. }
  431. DPFX(DPFPREP, 9, "(0x%p) Returning [0x%lx]", this, hr);
  432. return hr;
  433. Failure:
  434. if ( pDataPort != NULL )
  435. {
  436. if ( fDataPortBoundToNetwork != FALSE )
  437. {
  438. pDataPort->UnbindFromNetwork();
  439. fDataPortBoundToNetwork = FALSE;
  440. }
  441. if ( fDataPortCreated != FALSE )
  442. {
  443. if ( pDataPort->GetHandle() != 0 )
  444. {
  445. GetThreadPool()->CloseDataPortHandle( pDataPort );
  446. DNASSERT( pDataPort->GetHandle() == 0 );
  447. }
  448. pDataPort->DecRef();
  449. fDataPortCreated = FALSE;
  450. }
  451. pDataPort = NULL;
  452. }
  453. goto Exit;
  454. }
  455. //**********************************************************************
  456. //**********************************************************************
  457. // ------------------------------
  458. // CModemSPData::UnbindEndpoint - unbind an endpoint from a dataport
  459. //
  460. // Entry: Pointer to endpoint
  461. // Endpoint type
  462. //
  463. // Exit: Nothing
  464. // ------------------------------
  465. #undef DPF_MODNAME
  466. #define DPF_MODNAME "CModemSPData::UnbindEndpoint"
  467. void CModemSPData::UnbindEndpoint( CModemEndpoint *const pEndpoint, const ENDPOINT_TYPE EndpointType )
  468. {
  469. CDataPort *pDataPort;
  470. DWORD dwDeviceID;
  471. BOOL fCleanUpDataPort;
  472. DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p, %u)", this, pEndpoint, EndpointType);
  473. DNASSERT( pEndpoint != NULL );
  474. //
  475. // initialize
  476. //
  477. pDataPort = NULL;
  478. fCleanUpDataPort = FALSE;
  479. pDataPort = pEndpoint->GetDataPort();
  480. dwDeviceID = pDataPort->GetDeviceID();
  481. LockDataPortData();
  482. pDataPort->UnbindEndpoint( pEndpoint, EndpointType );
  483. if ( pDataPort->EndpointDecRef() == 0 )
  484. {
  485. DNASSERT( m_DataPortList[ dwDeviceID ] == pDataPort );
  486. m_DataPortList[ dwDeviceID ] = NULL;
  487. fCleanUpDataPort = TRUE;
  488. }
  489. UnlockDataPortData();
  490. if ( fCleanUpDataPort != FALSE )
  491. {
  492. pDataPort->DecRef();
  493. fCleanUpDataPort = FALSE;
  494. }
  495. DPFX(DPFPREP, 9, "(0x%p) Leave", this);
  496. }
  497. //**********************************************************************
  498. //**********************************************************************
  499. // ------------------------------
  500. // CModemSPData::GetNewEndpoint - get a new endpoint
  501. //
  502. // Entry: Nothing
  503. //
  504. // Exit: Pointer to new endpoint
  505. // NULL = out of memory
  506. // ------------------------------
  507. #undef DPF_MODNAME
  508. #define DPF_MODNAME "CModemSPData::GetNewEndpoint"
  509. CModemEndpoint *CModemSPData::GetNewEndpoint( void )
  510. {
  511. HRESULT hTempResult;
  512. CModemEndpoint *pEndpoint;
  513. DPNHANDLE hEndpoint;
  514. ENDPOINT_POOL_CONTEXT PoolContext;
  515. DPFX(DPFPREP, 9, "(0x%p) Enter", this);
  516. //
  517. // initialize
  518. //
  519. pEndpoint = NULL;
  520. hEndpoint = 0;
  521. memset( &PoolContext, 0x00, sizeof( PoolContext ) );
  522. PoolContext.pSPData = this;
  523. pEndpoint = CreateEndpoint( &PoolContext );
  524. if ( pEndpoint == NULL )
  525. {
  526. DPFX(DPFPREP, 0, "Failed to create endpoint!" );
  527. goto Failure;
  528. }
  529. hTempResult = m_HandleTable.Create( pEndpoint, &hEndpoint );
  530. if ( hTempResult != DPN_OK )
  531. {
  532. DNASSERT( hEndpoint == 0 );
  533. DPFX(DPFPREP, 0, "Failed to create endpoint handle!" );
  534. DisplayErrorCode( 0, hTempResult );
  535. goto Failure;
  536. }
  537. pEndpoint->SetHandle( hEndpoint );
  538. pEndpoint->AddCommandRef();
  539. pEndpoint->DecRef();
  540. Exit:
  541. DPFX(DPFPREP, 9, "(0x%p) Returning [0x%p]", this, pEndpoint);
  542. return pEndpoint;
  543. Failure:
  544. if ( hEndpoint != 0 )
  545. {
  546. m_HandleTable.Destroy( hEndpoint, NULL );
  547. hEndpoint = 0;
  548. }
  549. if ( pEndpoint != NULL )
  550. {
  551. pEndpoint->DecRef();
  552. pEndpoint = NULL;
  553. }
  554. goto Exit;
  555. }
  556. //**********************************************************************
  557. //**********************************************************************
  558. // ------------------------------
  559. // CModemSPData::EndpointFromHandle - get endpoint from handle
  560. //
  561. // Entry: Handle
  562. //
  563. // Exit: Pointer to endpoint
  564. // NULL = invalid handle
  565. // ------------------------------
  566. #undef DPF_MODNAME
  567. #define DPF_MODNAME "CModemSPData::EndpointFromHandle"
  568. CModemEndpoint *CModemSPData::EndpointFromHandle( const DPNHANDLE hEndpoint )
  569. {
  570. CModemEndpoint *pEndpoint;
  571. DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p)", this, hEndpoint);
  572. pEndpoint = NULL;
  573. m_HandleTable.Lock();
  574. if (SUCCEEDED(m_HandleTable.Find( hEndpoint, (PVOID*)&pEndpoint )))
  575. {
  576. pEndpoint->AddCommandRef();
  577. }
  578. m_HandleTable.Unlock();
  579. DPFX(DPFPREP, 9, "(0x%p) Returning [0x%p]", this, pEndpoint);
  580. return pEndpoint;
  581. }
  582. //**********************************************************************
  583. //**********************************************************************
  584. // ------------------------------
  585. // CModemSPData::CloseEndpointHandle - close endpoint handle
  586. //
  587. // Entry: Poiner to endpoint
  588. //
  589. // Exit: Nothing
  590. // ------------------------------
  591. #undef DPF_MODNAME
  592. #define DPF_MODNAME "CModemSPData::CloseEndpointHandle"
  593. void CModemSPData::CloseEndpointHandle( CModemEndpoint *const pEndpoint )
  594. {
  595. DPNHANDLE Handle;
  596. DNASSERT( pEndpoint != NULL );
  597. Handle = pEndpoint->GetHandle();
  598. DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p {handle = 0x%p})",
  599. this, pEndpoint, Handle);
  600. if (SUCCEEDED(m_HandleTable.Destroy( Handle, NULL )))
  601. {
  602. pEndpoint->DecCommandRef();
  603. }
  604. DPFX(DPFPREP, 9, "(0x%p) Leave", this);
  605. }
  606. //**********************************************************************
  607. //**********************************************************************
  608. // ------------------------------
  609. // CModemSPData::GetEndpointAndCloseHandle - get endpoint from handle and close the
  610. // handle
  611. //
  612. // Entry: Handle
  613. //
  614. // Exit: Pointer to endpoint (it needs a call to 'DecCommandRef' when done)
  615. // NULL = invalid handle
  616. // ------------------------------
  617. #undef DPF_MODNAME
  618. #define DPF_MODNAME "CModemSPData::GetEndpointAndCloseHandle"
  619. CModemEndpoint *CModemSPData::GetEndpointAndCloseHandle( const DPNHANDLE hEndpoint )
  620. {
  621. CModemEndpoint *pEndpoint;
  622. DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p)", this, hEndpoint);
  623. //
  624. // initialize
  625. //
  626. pEndpoint = NULL;
  627. if (SUCCEEDED( m_HandleTable.Destroy( hEndpoint, (PVOID*)&pEndpoint )))
  628. {
  629. pEndpoint->AddRef();
  630. }
  631. DPFX(DPFPREP, 9, "(0x%p) Returning [0x%p]", this, pEndpoint);
  632. return pEndpoint;
  633. }
  634. //**********************************************************************
  635. //**********************************************************************
  636. // ------------------------------
  637. // CModemSPData::DestroyThisObject - destroy this object
  638. //
  639. // Entry: Nothing
  640. //
  641. // Exit: Nothing
  642. // ------------------------------
  643. #undef DPF_MODNAME
  644. #define DPF_MODNAME "CModemSPData::DestroyThisObject"
  645. void CModemSPData::DestroyThisObject( void )
  646. {
  647. Deinitialize();
  648. delete this; // maybe a little too extreme......
  649. }
  650. //**********************************************************************