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.

468 lines
15 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1998-2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: Endpoint.h
  6. * Content: DNSerial communications endpoint
  7. *
  8. *
  9. * History:
  10. * Date By Reason
  11. * ==== == ======
  12. * 01/20/99 jtk Created
  13. * 05/11/99 jtk Split out to make a base class
  14. ***************************************************************************/
  15. #ifndef __ENDPOINT_H__
  16. #define __ENDPOINT_H__
  17. //**********************************************************************
  18. // Constant definitions
  19. //**********************************************************************
  20. #define MAX_PHONE_NUMBER_SIZE 200
  21. //
  22. // enumeration of endpoint types
  23. //
  24. typedef enum _ENDPOINT_TYPE
  25. {
  26. ENDPOINT_TYPE_UNKNOWN = 0, // unknown endpoint type
  27. ENDPOINT_TYPE_LISTEN, // 'Listen' endpoint
  28. ENDPOINT_TYPE_CONNECT, // 'Conenct' endpoint
  29. ENDPOINT_TYPE_ENUM, // 'Enum' endpoint
  30. ENDPOINT_TYPE_CONNECT_ON_LISTEN // endpoint connected from a 'listen'
  31. } ENDPOINT_TYPE;
  32. //
  33. // enumeration of the states an endpoint can be in
  34. //
  35. typedef enum
  36. {
  37. ENDPOINT_STATE_UNINITIALIZED = 0, // uninitialized state
  38. ENDPOINT_STATE_ATTEMPTING_ENUM, // attempting to enum
  39. ENDPOINT_STATE_ENUM, // endpoint is supposed to enum connections
  40. ENDPOINT_STATE_ATTEMPTING_CONNECT, // attempting to connect
  41. ENDPOINT_STATE_CONNECT_CONNECTED, // endpoint is supposed to connect and is connected
  42. ENDPOINT_STATE_ATTEMPTING_LISTEN, // attempting to listen
  43. ENDPOINT_STATE_LISTENING, // endpoint is supposed to listen and is listening
  44. ENDPOINT_STATE_DISCONNECTING, // endpoint is disconnecting
  45. ENDPOINT_STATE_MAX
  46. } ENDPOINT_STATE;
  47. //**********************************************************************
  48. // Macro definitions
  49. //**********************************************************************
  50. //**********************************************************************
  51. // Structure definitions
  52. //**********************************************************************
  53. //
  54. // forward structure references
  55. //
  56. typedef struct _JOB_HEADER JOB_HEADER;
  57. typedef struct _THREAD_POOL_JOB THREAD_POOL_JOB;
  58. class CModemCommandData;
  59. class CDataPort;
  60. class CModemReadIOData;
  61. class CModemThreadPool;
  62. class CModemWriteIOData;
  63. //
  64. // structure used to get data from the endpoint port pool
  65. //
  66. typedef struct _ENDPOINT_POOL_CONTEXT
  67. {
  68. CModemSPData *pSPData;
  69. BOOL fModem;
  70. } ENDPOINT_POOL_CONTEXT;
  71. //
  72. // structure to bind extra information to an enum query to be used on enum reponse
  73. //
  74. typedef struct _ENDPOINT_ENUM_QUERY_CONTEXT
  75. {
  76. SPIE_QUERY EnumQueryData;
  77. HANDLE hEndpoint;
  78. UINT_PTR uEnumRTTIndex;
  79. } ENDPOINT_ENUM_QUERY_CONTEXT;
  80. //**********************************************************************
  81. // Variable definitions
  82. //**********************************************************************
  83. //**********************************************************************
  84. // Function prototypes
  85. //**********************************************************************
  86. //**********************************************************************
  87. // Class definition
  88. //**********************************************************************
  89. class CModemEndpoint
  90. {
  91. public:
  92. #undef DPF_MODNAME
  93. #define DPF_MODNAME "CModemEndpoint::Lock"
  94. void Lock( void )
  95. {
  96. DNASSERT( m_Flags.fInitialized != FALSE );
  97. DNEnterCriticalSection( &m_Lock );
  98. }
  99. #undef DPF_MODNAME
  100. #define DPF_MODNAME "CModemEndpoint::Unlock"
  101. void Unlock( void )
  102. {
  103. DNASSERT( m_Flags.fInitialized != FALSE );
  104. DNLeaveCriticalSection( &m_Lock );
  105. }
  106. void ReturnSelfToPool( void );
  107. #undef DPF_MODNAME
  108. #define DPF_MODNAME "CModemEndpoint::AddRef"
  109. void AddRef( void )
  110. {
  111. DNASSERT( m_iRefCount != 0 );
  112. DNInterlockedIncrement( &m_iRefCount );
  113. }
  114. #undef DPF_MODNAME
  115. #define DPF_MODNAME "CModemEndpoint::DecRef"
  116. void DecRef( void )
  117. {
  118. DNASSERT( m_iRefCount != 0 );
  119. if ( DNInterlockedDecrement( &m_iRefCount ) == 0 )
  120. {
  121. ReturnSelfToPool();
  122. }
  123. }
  124. void AddCommandRef( void )
  125. {
  126. DNInterlockedIncrement( &m_lCommandRefCount );
  127. AddRef();
  128. }
  129. void DecCommandRef( void )
  130. {
  131. if ( DNInterlockedDecrement( &m_lCommandRefCount ) == 0 )
  132. {
  133. CleanUpCommand();
  134. }
  135. DecRef();
  136. }
  137. DPNHANDLE GetHandle( void ) const { return m_Handle; }
  138. #undef DPF_MODNAME
  139. #define DPF_MODNAME "CModemEndpoint::SetHandle"
  140. void SetHandle( const DPNHANDLE Handle )
  141. {
  142. DNASSERT( ( m_Handle == 0 ) || ( Handle == 0 ) );
  143. m_Handle = Handle;
  144. }
  145. const CComPortData *ComPortData( void ) const { return &m_ComPortData; }
  146. const SP_BAUD_RATE GetBaudRate( void ) const { return m_ComPortData.GetBaudRate(); }
  147. HRESULT SetBaudRate( const SP_BAUD_RATE BaudRate ) { return m_ComPortData.SetBaudRate( BaudRate ); }
  148. const SP_STOP_BITS GetStopBits( void ) const { return m_ComPortData.GetStopBits(); }
  149. HRESULT SetStopBits( const SP_STOP_BITS StopBits ) { return m_ComPortData.SetStopBits( StopBits ); }
  150. const SP_PARITY_TYPE GetParity( void ) const { return m_ComPortData.GetParity(); }
  151. HRESULT SetParity( const SP_PARITY_TYPE Parity ) { return m_ComPortData.SetParity( Parity ); }
  152. const SP_FLOW_CONTROL GetFlowControl( void ) const { return m_ComPortData.GetFlowControl(); }
  153. HRESULT SetFlowControl( const SP_FLOW_CONTROL FlowControl ) { return m_ComPortData.SetFlowControl( FlowControl ); }
  154. const CComPortData *GetComPortData( void ) const { return &m_ComPortData; }
  155. const GUID *GetEncryptionGuid( void ) const
  156. {
  157. if (m_fModem)
  158. {
  159. return &g_ModemSPEncryptionGuid;
  160. }
  161. else
  162. {
  163. return &g_SerialSPEncryptionGuid;
  164. }
  165. }
  166. const TCHAR *GetPhoneNumber( void ) const { return m_PhoneNumber; }
  167. #undef DPF_MODNAME
  168. #define DPF_MODNAME "CModemEndpoint::SetPhoneNumber"
  169. HRESULT SetPhoneNumber( const TCHAR *const pPhoneNumber )
  170. {
  171. DNASSERT( pPhoneNumber != NULL );
  172. DNASSERT( lstrlen( pPhoneNumber ) < ( sizeof( m_PhoneNumber ) / sizeof( TCHAR ) ) );
  173. lstrcpyn( m_PhoneNumber, pPhoneNumber, MAX_PHONE_NUMBER_SIZE );
  174. return DPN_OK;
  175. }
  176. void *DeviceBindContext( void ) { return &m_dwDeviceID; }
  177. CDataPort *GetDataPort( void ) const { return m_pDataPort; }
  178. #undef DPF_MODNAME
  179. #define DPF_MODNAME "CModemEndpoint::SetDataPort"
  180. void SetDataPort( CDataPort *const pDataPort )
  181. {
  182. DNASSERT( ( m_pDataPort == NULL ) || ( pDataPort == NULL ) );
  183. m_pDataPort = pDataPort;
  184. }
  185. ENDPOINT_TYPE GetType( void ) const { return m_EndpointType; }
  186. void *GetUserEndpointContext( void ) const { return m_pUserEndpointContext; }
  187. #undef DPF_MODNAME
  188. #define DPF_MODNAME "CModemEndpoint::SetUserEndpointContext"
  189. void SetUserEndpointContext( void *const pContext )
  190. {
  191. DNASSERT( ( m_pUserEndpointContext == NULL ) || ( pContext == NULL ) );
  192. m_pUserEndpointContext = pContext;
  193. }
  194. ENDPOINT_STATE GetState( void ) const { return m_State; }
  195. void SetState( const ENDPOINT_STATE EndpointState );
  196. CModemSPData *GetSPData( void ) const { return m_pSPData; }
  197. CModemCommandData *GetCommandData( void ) const { return m_pCommandHandle; }
  198. DPNHANDLE GetDisconnectIndicationHandle( void ) const { return this->m_hDisconnectIndicationHandle; }
  199. void SetDisconnectIndicationHandle( const DPNHANDLE hDisconnectIndicationHandle )
  200. {
  201. DNASSERT( ( GetDisconnectIndicationHandle() == 0 ) ||
  202. ( hDisconnectIndicationHandle == 0 ) );
  203. m_hDisconnectIndicationHandle = hDisconnectIndicationHandle;
  204. }
  205. void CopyConnectData( const SPCONNECTDATA *const pConnectData );
  206. static void ConnectJobCallback( THREAD_POOL_JOB *const pJobHeader );
  207. static void CancelConnectJobCallback( THREAD_POOL_JOB *const pJobHeader );
  208. HRESULT CompleteConnect( void );
  209. void CopyListenData( const SPLISTENDATA *const pListenData );
  210. static void ListenJobCallback( THREAD_POOL_JOB *const pJobHeader );
  211. static void CancelListenJobCallback( THREAD_POOL_JOB *const pJobHeader );
  212. HRESULT CompleteListen( void );
  213. void CopyEnumQueryData( const SPENUMQUERYDATA *const pEnumQueryData );
  214. static void EnumQueryJobCallback( THREAD_POOL_JOB *const pJobHeader );
  215. static void CancelEnumQueryJobCallback( THREAD_POOL_JOB *const pJobHeader );
  216. HRESULT CompleteEnumQuery( void );
  217. void OutgoingConnectionEstablished( const HRESULT hCommandResult );
  218. HRESULT Open( IDirectPlay8Address *const pHostAddress,
  219. IDirectPlay8Address *const pAdapterAddress,
  220. const LINK_DIRECTION LinkDirection,
  221. const ENDPOINT_TYPE EndpointType );
  222. HRESULT OpenOnListen( const CModemEndpoint *const pEndpoint );
  223. void Close( const HRESULT hActiveCommandResult );
  224. DWORD GetLinkSpeed( void ) const;
  225. HRESULT Disconnect( const DPNHANDLE hOldEndpointHandle );
  226. void SignalDisconnect( const DPNHANDLE hOldEndpointHandle );
  227. //
  228. // send functions
  229. //
  230. #undef DPF_MODNAME
  231. #define DPF_MODNAME "CModemEndpoint::SendUserData"
  232. void SendUserData( CModemWriteIOData *const pWriteBuffer )
  233. {
  234. DNASSERT( pWriteBuffer != NULL );
  235. DNASSERT( m_pDataPort != NULL );
  236. m_pDataPort->SendUserData( pWriteBuffer );
  237. }
  238. #undef DPF_MODNAME
  239. #define DPF_MODNAME "CModemEndpoint::SendEnumResponseData"
  240. void SendEnumResponseData( CModemWriteIOData *const pWriteBuffer, const UINT_PTR uRTTIndex )
  241. {
  242. DNASSERT( pWriteBuffer != NULL );
  243. DNASSERT( m_pDataPort != NULL );
  244. m_pDataPort->SendEnumResponseData( pWriteBuffer, uRTTIndex );
  245. }
  246. void StopEnumCommand( const HRESULT hCommandResult );
  247. LINK_DIRECTION GetLinkDirection( void ) const;
  248. //
  249. // dialog settings
  250. //
  251. IDirectPlay8Address *GetRemoteHostDP8Address( void ) const;
  252. IDirectPlay8Address *GetLocalAdapterDP8Address( const ADDRESS_TYPE AddressType ) const;
  253. //
  254. // data processing functions
  255. //
  256. void ProcessEnumData( SPRECEIVEDBUFFER *const pReceivedBuffer, const UINT_PTR uRTTIndex );
  257. void ProcessEnumResponseData( SPRECEIVEDBUFFER *const pReceivedBuffer, const UINT_PTR uRTTIndex );
  258. void ProcessUserData( CModemReadIOData *const pReadData );
  259. void ProcessUserDataOnListen( CModemReadIOData *const pReadData );
  260. #ifndef DPNBUILD_NOSPUI
  261. //
  262. // UI functions
  263. //
  264. HRESULT ShowOutgoingSettingsDialog( CModemThreadPool *const pThreadPool );
  265. HRESULT ShowIncomingSettingsDialog( CModemThreadPool *const pThreadPool );
  266. void StopSettingsDialog( const HWND hDialog );
  267. void SettingsDialogComplete( const HRESULT hDialogReturnCode );
  268. HWND ActiveDialogHandle( void ) const { return m_hActiveDialogHandle; }
  269. #undef DPF_MODNAME
  270. #define DPF_MODNAME "CModemEndpoint::SetActiveDialogHandle"
  271. void SetActiveDialogHandle( const HWND hDialog )
  272. {
  273. DNASSERT( ( ActiveDialogHandle() == NULL ) || ( hDialog == NULL ) );
  274. m_hActiveDialogHandle = hDialog;
  275. }
  276. #endif // !DPNBUILD_NOSPUI
  277. //
  278. // port settings
  279. //
  280. DWORD GetDeviceID( void ) const
  281. {
  282. if (m_fModem)
  283. {
  284. return m_dwDeviceID;
  285. }
  286. else
  287. {
  288. return m_ComPortData.GetDeviceID();
  289. }
  290. }
  291. HRESULT SetDeviceID( const DWORD dwDeviceID )
  292. {
  293. if (m_fModem)
  294. {
  295. DNASSERT( ( m_dwDeviceID == INVALID_DEVICE_ID ) || ( dwDeviceID == INVALID_DEVICE_ID ) );
  296. m_dwDeviceID = dwDeviceID;
  297. return DPN_OK;
  298. }
  299. else
  300. {
  301. return m_ComPortData.SetDeviceID( dwDeviceID );
  302. }
  303. }
  304. //
  305. // pool functions
  306. //
  307. static BOOL PoolAllocFunction( void* pvItem, void* pvContext );
  308. static void PoolInitFunction( void* pvItem, void* pvContext );
  309. static void PoolReleaseFunction( void* pvItem );
  310. static void PoolDeallocFunction( void* pvItem );
  311. protected:
  312. BYTE m_Sig[4]; // debugging signature ('THPL')
  313. CModemSPData *m_pSPData; // pointer to SP data
  314. BOOL m_fModem;
  315. CComPortData m_ComPortData;
  316. DWORD m_dwDeviceID;
  317. TCHAR m_PhoneNumber[ MAX_PHONE_NUMBER_SIZE ];
  318. struct
  319. {
  320. BOOL fInitialized : 1;
  321. BOOL fConnectIndicated : 1;
  322. BOOL fCommandPending : 1;
  323. BOOL fListenStatusNeedsToBeIndicated : 1;
  324. } m_Flags;
  325. DWORD m_dwEnumSendIndex; // enum send index
  326. DWORD m_dwEnumSendTimes[ 4 ]; // enum send times
  327. union // Local copy of the pending command paramters.
  328. { // This data contains the pointers to the active
  329. SPCONNECTDATA ConnectData; // command, and the user context.
  330. SPLISTENDATA ListenData; //
  331. SPENUMQUERYDATA EnumQueryData; //
  332. } m_CurrentCommandParameters; //
  333. CModemCommandData *m_pCommandHandle; // pointer to active command (this is kept to
  334. // avoid a switch to go through the m_ActveCommandData
  335. // to find the command handle)
  336. HWND m_hActiveDialogHandle; // handle of active dialog
  337. #undef DPF_MODNAME
  338. #define DPF_MODNAME "CModemEndpoint::SetType"
  339. void SetType( const ENDPOINT_TYPE EndpointType )
  340. {
  341. DNASSERT( ( m_EndpointType == ENDPOINT_TYPE_UNKNOWN ) || ( EndpointType == ENDPOINT_TYPE_UNKNOWN ) );
  342. m_EndpointType = EndpointType;
  343. }
  344. CModemCommandData *CommandHandle( void ) const;
  345. #undef DPF_MODNAME
  346. #define DPF_MODNAME "CModemEndpoint::SetCommandHandle"
  347. void SetCommandHandle( CModemCommandData *const pCommandHandle )
  348. {
  349. DNASSERT( ( m_pCommandHandle == NULL ) || ( pCommandHandle == NULL ) );
  350. m_pCommandHandle = pCommandHandle;
  351. }
  352. HRESULT CommandResult( void ) const { return m_hPendingCommandResult; }
  353. void SetCommandResult( const HRESULT hCommandResult ) { m_hPendingCommandResult = hCommandResult; }
  354. void CompletePendingCommand( const HRESULT hResult );
  355. HRESULT PendingCommandResult( void ) const { return m_hPendingCommandResult; }
  356. static void EnumCompleteWrapper( const HRESULT hCompletionCode, void *const pContext );
  357. static void EnumTimerCallback( void *const pContext );
  358. void EnumComplete( const HRESULT hCompletionCode );
  359. HRESULT SignalConnect( SPIE_CONNECT *const pConnectData );
  360. const void *GetDeviceContext( void ) const;
  361. void CleanUpCommand( void );
  362. #ifndef DPNBUILD_ONLYONETHREAD
  363. DNCRITICAL_SECTION m_Lock; // critical section
  364. #endif // !DPNBUILD_ONLYONETHREAD
  365. DPNHANDLE m_Handle; // active handle for this endpoint
  366. volatile ENDPOINT_STATE m_State; // endpoint state
  367. volatile LONG m_lCommandRefCount; // Command ref count. When this
  368. // goes to zero, the endpoint unbinds
  369. // from the network
  370. volatile LONG m_iRefCount;
  371. ENDPOINT_TYPE m_EndpointType; // type of endpoint
  372. CDataPort *m_pDataPort; // pointer to associated data port
  373. HRESULT m_hPendingCommandResult; // command result returned when endpoint RefCount == 0
  374. DPNHANDLE m_hDisconnectIndicationHandle; // handle to be indicated with disconnect notification.
  375. void *m_pUserEndpointContext; // user context associated with this endpoint
  376. //
  377. // make copy constructor and assignment operator private and unimplemented
  378. // to prevent illegal copies from being made
  379. //
  380. CModemEndpoint( const CModemEndpoint & );
  381. CModemEndpoint& operator=( const CModemEndpoint & );
  382. };
  383. #undef DPF_MODNAME
  384. #endif // __ENDPOINT_H__