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.

260 lines
6.9 KiB

  1. /////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // tdiquery
  7. //
  8. // Abstract:
  9. // This module contains code which deals with tdi queries
  10. //
  11. //////////////////////////////////////////////////////////
  12. #include "sysvars.h"
  13. //////////////////////////////////////////////////////////////
  14. // private constants, types, and prototypes
  15. //////////////////////////////////////////////////////////////
  16. const PCHAR strFunc1 = "TSQueryInfo";
  17. const PCHAR strFuncP1 = "TSQueryComplete";
  18. //
  19. // completion context
  20. //
  21. struct QUERY_CONTEXT
  22. {
  23. PIRP pUpperIrp; // irp from dll to complete
  24. PMDL pLowerMdl; // mdl from lower irp
  25. PUCHAR pucLowerBuffer; // data buffer from lower irp
  26. };
  27. typedef QUERY_CONTEXT *PQUERY_CONTEXT;
  28. //
  29. // completion function
  30. //
  31. TDI_STATUS
  32. TSQueryComplete(
  33. PDEVICE_OBJECT DeviceObject,
  34. PIRP Irp,
  35. PVOID Context
  36. );
  37. //////////////////////////////////////////////////////////////
  38. // public functions
  39. //////////////////////////////////////////////////////////////
  40. // -----------------------------------------------------------------
  41. //
  42. // Function: TSQueryInfo
  43. //
  44. // Arguments: pGenericHeader -- handle of appropriate type
  45. // pSendBuffer -- arguments from user dll
  46. // pIrp -- completion information
  47. //
  48. // Returns: NTSTATUS (normally pending)
  49. //
  50. // Descript: This function queries the appropriate object for some information
  51. //
  52. // ----------------------------------------------------------------------------
  53. NTSTATUS
  54. TSQueryInfo(PGENERIC_HEADER pGenericHeader,
  55. PSEND_BUFFER pSendBuffer,
  56. PIRP pUpperIrp)
  57. {
  58. ULONG ulQueryId = pSendBuffer->COMMAND_ARGS.ulQueryId;
  59. //
  60. // show debug, if it is turned on
  61. //
  62. if (ulDebugLevel & ulDebugShowCommand)
  63. {
  64. DebugPrint2("\nCommand = ulQUERYINFO\n"
  65. "FileObject = %p\n"
  66. "QueryId = 0x%08x\n",
  67. pGenericHeader,
  68. ulQueryId);
  69. }
  70. //
  71. // allocate all the necessary structures
  72. //
  73. PQUERY_CONTEXT pQueryContext = NULL;
  74. PUCHAR pucBuffer = NULL;
  75. PMDL pQueryMdl = NULL;
  76. // first, our context
  77. //
  78. if ((TSAllocateMemory((PVOID *)&pQueryContext,
  79. sizeof(QUERY_CONTEXT),
  80. strFunc1,
  81. "QueryContext")) != STATUS_SUCCESS)
  82. {
  83. goto cleanup;
  84. }
  85. //
  86. // next the data buffer (for the mdl)
  87. //
  88. if ((TSAllocateMemory((PVOID *)&pucBuffer,
  89. ulMAX_BUFFER_LENGTH,
  90. strFunc1,
  91. "pucBuffer")) != STATUS_SUCCESS)
  92. {
  93. goto cleanup;
  94. }
  95. //
  96. // then the actual mdl
  97. //
  98. pQueryMdl = TSAllocateBuffer(pucBuffer,
  99. ulMAX_BUFFER_LENGTH);
  100. if (pQueryMdl)
  101. {
  102. pQueryContext->pUpperIrp = pUpperIrp;
  103. pQueryContext->pLowerMdl = pQueryMdl;
  104. pQueryContext->pucLowerBuffer = pucBuffer;
  105. //
  106. // finally, the irp itself
  107. //
  108. PIRP pLowerIrp = TSAllocateIrp(pGenericHeader->pDeviceObject,
  109. NULL);
  110. if (pLowerIrp)
  111. {
  112. //
  113. // if made it to here, everything is correctly allocated
  114. // set up irp and call the tdi provider
  115. //
  116. #pragma warning(disable: CONSTANT_CONDITIONAL)
  117. TdiBuildQueryInformation(pLowerIrp,
  118. pGenericHeader->pDeviceObject,
  119. pGenericHeader->pFileObject,
  120. TSQueryComplete,
  121. pQueryContext,
  122. ulQueryId,
  123. pQueryMdl);
  124. #pragma warning(default: CONSTANT_CONDITIONAL)
  125. //
  126. // make the call to the tdi provider
  127. //
  128. pSendBuffer->pvLowerIrp = pLowerIrp; // so command can be cancelled
  129. NTSTATUS lStatus = IoCallDriver(pGenericHeader->pDeviceObject,
  130. pLowerIrp);
  131. if ((!NT_SUCCESS(lStatus)) && (ulDebugLevel & ulDebugShowCommand))
  132. {
  133. DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n",
  134. strFunc1,
  135. lStatus);
  136. }
  137. return STATUS_PENDING;
  138. }
  139. }
  140. //
  141. // get to here if there was an error
  142. //
  143. cleanup:
  144. if (pQueryContext)
  145. {
  146. TSFreeMemory(pQueryContext);
  147. }
  148. if (pucBuffer)
  149. {
  150. TSFreeMemory(pucBuffer);
  151. }
  152. if (pQueryMdl)
  153. {
  154. TSFreeBuffer(pQueryMdl);
  155. }
  156. return STATUS_INSUFFICIENT_RESOURCES;
  157. }
  158. /////////////////////////////////////////////////////////////
  159. // private functions
  160. /////////////////////////////////////////////////////////////
  161. // ---------------------------------------------------------
  162. //
  163. // Function: TSQueryComplete
  164. //
  165. // Arguments: pDeviceObject -- device object that called tdiquery
  166. // pIrp -- IRP used in the call
  167. // pContext -- context used for the call
  168. //
  169. // Returns: status of operation (STATUS_MORE_PROCESSING_REQUIRED)
  170. //
  171. // Descript: Gets the result of the query, stuffs results into
  172. // receive buffer, completes the IRP from the dll, and
  173. // cleans up the Irp and associated data from the query
  174. //
  175. // ---------------------------------------------------------
  176. #pragma warning(disable: UNREFERENCED_PARAM)
  177. TDI_STATUS
  178. TSQueryComplete(PDEVICE_OBJECT pDeviceObject,
  179. PIRP pLowerIrp,
  180. PVOID pvContext)
  181. {
  182. PQUERY_CONTEXT pQueryContext = (PQUERY_CONTEXT)pvContext;
  183. NTSTATUS lStatus = pLowerIrp->IoStatus.Status;
  184. ULONG_PTR ulCopyLength = pLowerIrp->IoStatus.Information;
  185. PRECEIVE_BUFFER pReceiveBuffer = TSGetReceiveBuffer(pQueryContext->pUpperIrp);
  186. pReceiveBuffer->lStatus = lStatus;
  187. if (NT_SUCCESS(lStatus))
  188. {
  189. pReceiveBuffer->RESULTS.QueryRet.ulBufferLength = (ULONG)ulCopyLength;
  190. if (ulCopyLength)
  191. {
  192. RtlCopyMemory(pReceiveBuffer->RESULTS.QueryRet.pucDataBuffer,
  193. pQueryContext->pucLowerBuffer,
  194. ulCopyLength);
  195. }
  196. }
  197. else if (ulDebugLevel & ulDebugShowCommand)
  198. {
  199. DebugPrint2("%s: Completed with status 0x%08x\n",
  200. strFuncP1,
  201. lStatus);
  202. }
  203. TSCompleteIrp(pQueryContext->pUpperIrp);
  204. //
  205. // now cleanup
  206. //
  207. TSFreeBuffer(pQueryContext->pLowerMdl);
  208. TSFreeMemory(pQueryContext->pucLowerBuffer);
  209. TSFreeMemory(pQueryContext);
  210. TSFreeIrp(pLowerIrp, NULL);
  211. return TDI_MORE_PROCESSING;
  212. }
  213. #pragma warning(default: UNREFERENCED_PARAM)
  214. ///////////////////////////////////////////////////////////////////////////////
  215. // end of file tdiquery.cpp
  216. ///////////////////////////////////////////////////////////////////////////////