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.

371 lines
10 KiB

  1. /////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // events.cpp
  7. //
  8. // Abstract:
  9. // This module contains code which sets/clears the event handlers
  10. //
  11. //////////////////////////////////////////////////////////
  12. #include "sysvars.h"
  13. //////////////////////////////////////////////////////////////
  14. // private constants, types, and prototypes
  15. //////////////////////////////////////////////////////////////
  16. const PCHAR strFunc1 = "TSSetEventHandler";
  17. const PCHAR strFuncP1 = "TSSetEventComplete";
  18. //
  19. // information necessary to complete the command
  20. //
  21. struct EVENT_CONTEXT
  22. {
  23. PIRP pUpperIrp; // irp from dll to complete
  24. };
  25. typedef EVENT_CONTEXT *PEVENT_CONTEXT;
  26. //
  27. // completion function
  28. //
  29. TDI_STATUS
  30. TSSetEventComplete(
  31. PDEVICE_OBJECT DeviceObject,
  32. PIRP Irp,
  33. PVOID Context
  34. );
  35. //
  36. // dummy event handlers
  37. //
  38. TDI_STATUS
  39. TSErrorHandler(
  40. PVOID pvTdiEventContext,
  41. TDI_STATUS lStatus
  42. );
  43. TDI_STATUS
  44. TSSendPossibleHandler(
  45. PVOID pvTdiEventContext,
  46. PVOID pvConnectionContext,
  47. ULONG ulBytesAvailable
  48. );
  49. TDI_STATUS
  50. TSErrorExHandler(
  51. PVOID pvTdiEventContext,
  52. TDI_STATUS lStatus,
  53. PVOID pvBuffer
  54. );
  55. //////////////////////////////////////////////////////////////
  56. // public functions
  57. //////////////////////////////////////////////////////////////
  58. // -----------------------------------------------------------------
  59. //
  60. // Function: TSSetEventHandler
  61. //
  62. // Arguments: pAddressObject -- our address object structure
  63. // pSendBuffer -- arguments from user dll
  64. // pIrp -- completion information
  65. //
  66. // Returns: NTSTATUS (normally pending)
  67. //
  68. // Descript: This function enables or disables event handlers
  69. //
  70. // -------------------------------------------------------------------------------------------
  71. NTSTATUS
  72. TSSetEventHandler(PGENERIC_HEADER pGenericHeader,
  73. PSEND_BUFFER pSendBuffer,
  74. PIRP pUpperIrp)
  75. {
  76. ULONG ulEventId = pSendBuffer->COMMAND_ARGS.ulEventId;
  77. PADDRESS_OBJECT pAddressObject;
  78. if (pGenericHeader->ulSignature == ulEndpointObject)
  79. {
  80. PENDPOINT_OBJECT pEndpoint = (PENDPOINT_OBJECT)pGenericHeader;
  81. pAddressObject = pEndpoint->pAddressObject;
  82. }
  83. else
  84. {
  85. pAddressObject = (PADDRESS_OBJECT)pGenericHeader;
  86. }
  87. //
  88. // show debug, if it is turned on
  89. //
  90. if (ulDebugLevel & ulDebugShowCommand)
  91. {
  92. DebugPrint2("\nCommand = ulSETEVENTHANDLER\n"
  93. "AddressObject = %p\n"
  94. "EventId = 0x%08x\n",
  95. pAddressObject,
  96. ulEventId);
  97. }
  98. //
  99. // allocate all the necessary structures
  100. //
  101. PEVENT_CONTEXT pEventContext = NULL;
  102. //
  103. // first, our context
  104. //
  105. if ((TSAllocateMemory((PVOID *)&pEventContext,
  106. sizeof(EVENT_CONTEXT),
  107. strFunc1,
  108. "EventContext")) != STATUS_SUCCESS)
  109. {
  110. goto cleanup;
  111. }
  112. //
  113. // then the irp itself
  114. //
  115. PIRP pLowerIrp = TSAllocateIrp(pAddressObject->GenHead.pDeviceObject,
  116. NULL);
  117. if (pLowerIrp)
  118. {
  119. PVOID pvEventContext = pAddressObject;
  120. PVOID pvEventHandler = NULL;
  121. BOOLEAN fNeedIrpPool = FALSE;
  122. switch (ulEventId)
  123. {
  124. case TDI_EVENT_CONNECT:
  125. pvEventHandler = (PVOID)TSConnectHandler;
  126. fNeedIrpPool = TRUE;
  127. break;
  128. case TDI_EVENT_DISCONNECT:
  129. pvEventHandler = (PVOID)TSDisconnectHandler;
  130. fNeedIrpPool = TRUE;
  131. break;
  132. case TDI_EVENT_ERROR:
  133. pvEventHandler = (PVOID)TSErrorHandler;
  134. break;
  135. case TDI_EVENT_RECEIVE:
  136. fNeedIrpPool = TRUE;
  137. pvEventHandler = (PVOID)TSReceiveHandler;
  138. break;
  139. case TDI_EVENT_RECEIVE_DATAGRAM:
  140. fNeedIrpPool = TRUE;
  141. pvEventHandler = (PVOID)TSRcvDatagramHandler;
  142. break;
  143. case TDI_EVENT_RECEIVE_EXPEDITED:
  144. fNeedIrpPool = TRUE;
  145. pvEventHandler = (PVOID)TSRcvExpeditedHandler;
  146. break;
  147. case TDI_EVENT_SEND_POSSIBLE:
  148. pvEventHandler = (PVOID)TSSendPossibleHandler;
  149. break;
  150. case TDI_EVENT_CHAINED_RECEIVE:
  151. pvEventHandler = (PVOID)TSChainedReceiveHandler;
  152. break;
  153. case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM:
  154. pvEventHandler = (PVOID)TSChainedRcvDatagramHandler;
  155. break;
  156. case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED:
  157. pvEventHandler = (PVOID)TSChainedRcvExpeditedHandler;
  158. break;
  159. case TDI_EVENT_ERROR_EX:
  160. pvEventHandler = (PVOID)TSErrorExHandler;
  161. break;
  162. }
  163. //
  164. // if need to have irp pool for the handler, make sure that there
  165. // is one allocated..
  166. //
  167. if ((!pAddressObject->pIrpPool) && fNeedIrpPool)
  168. {
  169. pAddressObject->pIrpPool
  170. = TSAllocateIrpPool(pAddressObject->GenHead.pDeviceObject,
  171. ulIrpPoolSize);
  172. }
  173. //
  174. // if made it to here, everything is correctly allocated
  175. // set up irp and call the tdi provider
  176. //
  177. pEventContext->pUpperIrp = pUpperIrp;
  178. #pragma warning(disable: CONSTANT_CONDITIONAL)
  179. TdiBuildSetEventHandler(pLowerIrp,
  180. pAddressObject->GenHead.pDeviceObject,
  181. pAddressObject->GenHead.pFileObject,
  182. TSSetEventComplete,
  183. pEventContext,
  184. ulEventId,
  185. pvEventHandler,
  186. pvEventContext);
  187. #pragma warning(default: CONSTANT_CONDITIONAL)
  188. //
  189. // make the call to the tdi provider
  190. //
  191. pSendBuffer->pvLowerIrp = pLowerIrp; // so command can be cancelled
  192. NTSTATUS lStatus = IoCallDriver(pAddressObject->GenHead.pDeviceObject,
  193. pLowerIrp);
  194. if (((!NT_SUCCESS(lStatus)) && ulDebugLevel & ulDebugShowCommand))
  195. {
  196. DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n",
  197. strFunc1,
  198. lStatus);
  199. }
  200. return STATUS_PENDING;
  201. }
  202. //
  203. // get here if an allocation error occurred
  204. //
  205. cleanup:
  206. if (pEventContext)
  207. {
  208. TSFreeMemory(pEventContext);
  209. }
  210. return STATUS_INSUFFICIENT_RESOURCES;
  211. }
  212. /////////////////////////////////////////////////////////////
  213. // private functions
  214. /////////////////////////////////////////////////////////////
  215. // ---------------------------------------------------------
  216. //
  217. // Function: TSSetEventComplete
  218. //
  219. // Arguments: pDeviceObject -- device object that called tdiquery
  220. // pIrp -- IRP used in the call
  221. // pContext -- context used for the call
  222. //
  223. // Returns: status of operation (STATUS_MORE_PROCESSING_REQUIRED)
  224. //
  225. // Descript: Gets the result of the setevent, stuffs results into
  226. // receive buffer, completes the IRP from the dll, and
  227. // cleans up the Irp and associated data from the setevent
  228. //
  229. // ---------------------------------------------------------
  230. #pragma warning(disable: UNREFERENCED_PARAM)
  231. TDI_STATUS
  232. TSSetEventComplete(PDEVICE_OBJECT pDeviceObject,
  233. PIRP pLowerIrp,
  234. PVOID pvContext)
  235. {
  236. PEVENT_CONTEXT pEventContext = (PEVENT_CONTEXT)pvContext;
  237. NTSTATUS lStatus = pLowerIrp->IoStatus.Status;
  238. PRECEIVE_BUFFER pReceiveBuffer = TSGetReceiveBuffer(pEventContext->pUpperIrp);
  239. pReceiveBuffer->lStatus = lStatus;
  240. if (ulDebugLevel & ulDebugShowCommand)
  241. {
  242. if (NT_SUCCESS(lStatus))
  243. {
  244. if (pLowerIrp->IoStatus.Information)
  245. {
  246. DebugPrint2("%s: Information = 0x%08x\n",
  247. strFuncP1,
  248. pLowerIrp->IoStatus.Information);
  249. }
  250. }
  251. else
  252. {
  253. DebugPrint2("%s: Completed with status 0x%08x\n",
  254. strFuncP1,
  255. lStatus);
  256. }
  257. }
  258. TSCompleteIrp(pEventContext->pUpperIrp);
  259. //
  260. // now cleanup
  261. //
  262. TSFreeIrp(pLowerIrp, NULL);
  263. TSFreeMemory(pEventContext);
  264. return TDI_MORE_PROCESSING;
  265. }
  266. #pragma warning(default: UNREFERENCED_PARAM)
  267. /////////////////////////////////////////////
  268. // dummy event handlers
  269. /////////////////////////////////////////////
  270. #pragma warning(disable: UNREFERENCED_PARAM)
  271. TDI_STATUS
  272. TSErrorHandler(PVOID pvTdiEventContext,
  273. TDI_STATUS TdiStatus)
  274. {
  275. return TSErrorExHandler(pvTdiEventContext,
  276. TdiStatus,
  277. NULL);
  278. }
  279. TDI_STATUS
  280. TSSendPossibleHandler(PVOID pvTdiEventContext,
  281. PVOID pvConnectionContext,
  282. ULONG ulBytesAvailable)
  283. {
  284. DebugPrint3("TSSendPossibleHandler Called\n"
  285. "AddressObject = %p\n"
  286. "ConnectContext = %p\n"
  287. "BytesAvail = 0x%08x\n",
  288. pvTdiEventContext,
  289. pvConnectionContext,
  290. ulBytesAvailable);
  291. return TDI_SUCCESS;
  292. }
  293. TDI_STATUS
  294. TSErrorExHandler(PVOID pvTdiEventContext,
  295. TDI_STATUS TdiStatus,
  296. PVOID pvBuffer)
  297. {
  298. PADDRESS_OBJECT pAddressObject = (PADDRESS_OBJECT)pvTdiEventContext;
  299. if (ulDebugLevel & ulDebugShowCommand)
  300. {
  301. DebugPrint3("TSErrorExHandler Called\n"
  302. "AddressObject = %p\n"
  303. "Status = 0x%08x\n"
  304. "Buffer = %p\n",
  305. pvTdiEventContext,
  306. TdiStatus,
  307. pvBuffer);
  308. }
  309. return STATUS_SUCCESS;
  310. }
  311. #pragma warning(default: UNREFERENCED_PARAM)
  312. /////////////////////////////////////////////////////////////////////////////////
  313. // end of file events.cpp
  314. /////////////////////////////////////////////////////////////////////////////////