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.

427 lines
12 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. // Copyright (c) 1996, 1997 Microsoft Corporation
  5. //
  6. //
  7. // Module Name:
  8. // test.c
  9. //
  10. // Abstract:
  11. //
  12. // This file is a test to find out if dual binding to NDIS and KS works
  13. //
  14. // Author:
  15. //
  16. // P Porzuczek
  17. //
  18. // Environment:
  19. //
  20. // Revision History:
  21. //
  22. //
  23. //////////////////////////////////////////////////////////////////////////////
  24. #ifndef DWORD
  25. #define DWORD ULONG
  26. #endif
  27. #include <forward.h>
  28. #include <wdm.h>
  29. #include <link.h>
  30. #include <ipsink.h>
  31. #include "device.h"
  32. #include "main.h"
  33. VOID
  34. vUnload(IN PDRIVER_OBJECT pDriverObject);
  35. //////////////////////////////////////////////////////////////////////////////
  36. //
  37. //
  38. NTSTATUS
  39. RegisterDevice(
  40. IN PVOID NdisWrapperHandle,
  41. IN UNICODE_STRING *DeviceName,
  42. IN UNICODE_STRING *SymbolicName,
  43. IN PDRIVER_DISPATCH MajorFunctions[],
  44. OUT PDEVICE_OBJECT *pDeviceObject,
  45. OUT PVOID *NdisDeviceHandle
  46. );
  47. //////////////////////////////////////////////////////////////////////////////
  48. NTSTATUS
  49. ntDispatchOpenClose(
  50. IN PDEVICE_OBJECT pDeviceObject,
  51. IN PIRP pIrp
  52. )
  53. //////////////////////////////////////////////////////////////////////////////
  54. {
  55. NTSTATUS status = STATUS_SUCCESS;
  56. PIO_STACK_LOCATION pIrpSp = NULL;
  57. //
  58. // Make sure status information is consistent every time.
  59. //
  60. IoMarkIrpPending (pIrp);
  61. pIrp->IoStatus.Status = STATUS_PENDING;
  62. pIrp->IoStatus.Information = 0;
  63. //
  64. // Get a pointer to the current stack location in the IRP. This is where
  65. // the function codes and parameters are stored.
  66. //
  67. pIrpSp = IoGetCurrentIrpStackLocation (pIrp);
  68. //
  69. // Case on the function that is being performed by the requestor. If the
  70. // operation is a valid one for this device, then make it look like it was
  71. // successfully completed, where possible.
  72. //
  73. switch (pIrpSp->MajorFunction)
  74. {
  75. //
  76. // The Create function opens a transport object (either address or
  77. // connection). Access checking is performed on the specified
  78. // address to ensure security of transport-layer addresses.
  79. //
  80. case IRP_MJ_CREATE:
  81. status = STATUS_SUCCESS;
  82. break;
  83. case IRP_MJ_CLEANUP:
  84. status = STATUS_SUCCESS;
  85. break;
  86. case IRP_MJ_CLOSE:
  87. status = STATUS_SUCCESS;
  88. break;
  89. default:
  90. status = STATUS_INVALID_DEVICE_REQUEST;
  91. }
  92. if (status != STATUS_PENDING)
  93. {
  94. pIrpSp->Control &= ~SL_PENDING_RETURNED;
  95. pIrp->IoStatus.Status = status;
  96. IoCompleteRequest (pIrp, IO_NETWORK_INCREMENT);
  97. }
  98. return status;
  99. }
  100. //////////////////////////////////////////////////////////////////////////////
  101. NTSTATUS
  102. ntDispatchInternal (
  103. IN PDEVICE_OBJECT pDeviceObject,
  104. IN PIRP pIrp
  105. )
  106. //////////////////////////////////////////////////////////////////////////////
  107. {
  108. NTSTATUS ntStatus = STATUS_SUCCESS;
  109. PIO_STACK_LOCATION pIrpSp = NULL;
  110. ULONG ulIoctl = 0L;
  111. ULONG ulInputLen = 0L;
  112. ULONG ulOutputLen = 0L;
  113. PVOID pvInputBuffer = NULL;
  114. PVOID pvOutputBuffer = NULL;
  115. PIPSINK_NDIS_COMMAND pCmd = NULL;
  116. //
  117. // Make sure status information is consistent every time.
  118. //
  119. IoMarkIrpPending (pIrp);
  120. pIrp->IoStatus.Status = STATUS_PENDING;
  121. pIrp->IoStatus.Information = 0;
  122. //
  123. // Get a pointer to the current stack location in the IRP. This is where
  124. // the function codes and parameters are stored.
  125. //
  126. pIrpSp = IoGetCurrentIrpStackLocation (pIrp);
  127. ulIoctl = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
  128. ulInputLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
  129. ulOutputLen = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  130. pvInputBuffer = pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
  131. //
  132. // Case on the function that is being performed by the requestor. If the
  133. // operation is a valid one for this device, then make it look like it was
  134. // successfully completed, where possible.
  135. //
  136. switch (pIrpSp->MajorFunction)
  137. {
  138. case IRP_MJ_CREATE:
  139. TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_CREATE\n"));
  140. TEST_DEBUG (TEST_DBG_TRACE, (" FileObject: %08X\n", pIrpSp->FileObject));
  141. ntStatus = STATUS_SUCCESS;
  142. break;
  143. case IRP_MJ_CLEANUP:
  144. TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_CLEANUP\n"));
  145. ntStatus = STATUS_SUCCESS;
  146. break;
  147. case IRP_MJ_CLOSE:
  148. TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_CLOSE\n"));
  149. ntStatus = STATUS_SUCCESS;
  150. break;
  151. case IRP_MJ_INTERNAL_DEVICE_CONTROL:
  152. TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_INTERNAL_DEVICE_CONTROL\n"));
  153. switch (pIrpSp->Parameters.DeviceIoControl.IoControlCode)
  154. {
  155. case IOCTL_GET_INTERFACE:
  156. TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal control code: IOCTL_GET_NDIS_INTERFACE\n"));
  157. pCmd = (PIPSINK_NDIS_COMMAND) pvInputBuffer;
  158. switch (pCmd->ulCommandID)
  159. {
  160. case CMD_QUERY_INTERFACE:
  161. TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal control code: QueryInterface Command\n"));
  162. //
  163. // Define paramters we're returning to the streaming component
  164. //
  165. pCmd->Parameter.Query.pNdisAdapter = (PVOID) global_pAdapter;
  166. //
  167. // Save a pointer to the Streaming components vtable
  168. //
  169. global_pAdapter->pFilter = (PIPSINK_FILTER) pCmd->Parameter.Query.pStreamAdapter;
  170. //
  171. // Increment the reference count for the filter
  172. //
  173. global_pAdapter->pFilter->lpVTable->AddRef (global_pAdapter->pFilter);
  174. ntStatus = STATUS_SUCCESS;
  175. break;
  176. default:
  177. ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  178. break;
  179. }
  180. break;
  181. default:
  182. ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  183. break;
  184. }
  185. break;
  186. default:
  187. ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  188. break;
  189. }
  190. //ret:
  191. if (ntStatus != STATUS_PENDING)
  192. {
  193. pIrpSp->Control &= ~SL_PENDING_RETURNED;
  194. pIrp->IoStatus.Status = ntStatus;
  195. IoCompleteRequest (pIrp, IO_NETWORK_INCREMENT);
  196. }
  197. return ntStatus;
  198. }
  199. //////////////////////////////////////////////////////////////////////////////
  200. NTSTATUS
  201. ntInitializeDeviceObject(
  202. IN PVOID nhWrapperHandle,
  203. IN PADAPTER pAdapter,
  204. OUT PDEVICE_OBJECT *pndisDriverObject,
  205. OUT PVOID *pndisDeviceHandle
  206. )
  207. //////////////////////////////////////////////////////////////////////////////
  208. {
  209. NTSTATUS status = 0l;
  210. PDEVICE_OBJECT pDeviceObject = NULL;
  211. PVOID ndisDeviceHandle = NULL;
  212. UNICODE_STRING DeviceName;
  213. UNICODE_STRING SymbolicName;
  214. PDRIVER_DISPATCH pDispatchTable[IRP_MJ_MAXIMUM_FUNCTION] = {NULL};
  215. //
  216. // Set the dispatch entries we are interested in.
  217. //
  218. pDispatchTable[IRP_MJ_CREATE] = ntDispatchOpenClose;
  219. pDispatchTable[IRP_MJ_CLOSE] = ntDispatchOpenClose;
  220. pDispatchTable[IRP_MJ_CLEANUP] = ntDispatchOpenClose;
  221. pDispatchTable[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ntDispatchInternal;
  222. //pDispatchTable[IRP_MJ_DEVICE_CONTROL] = NULL;
  223. //
  224. // Initialize the device, dosdevice and symbolic names.
  225. //
  226. RtlInitUnicodeString(&DeviceName, BDA_NDIS_MINIPORT);
  227. RtlInitUnicodeString(&SymbolicName, BDA_NDIS_SYMBOLIC_NAME);
  228. status = RegisterDevice (nhWrapperHandle,
  229. &DeviceName,
  230. &SymbolicName,
  231. pDispatchTable,
  232. &pDeviceObject,
  233. &ndisDeviceHandle);
  234. if (status == STATUS_SUCCESS)
  235. {
  236. *pndisDeviceHandle = ndisDeviceHandle;
  237. *pndisDriverObject = pDeviceObject;
  238. }
  239. return status;
  240. }
  241. #ifdef WIN9X
  242. //////////////////////////////////////////////////////////////////////////////
  243. NTSTATUS
  244. ntCreateDeviceContext(
  245. IN PDRIVER_OBJECT pDriverObject
  246. )
  247. //////////////////////////////////////////////////////////////////////////////
  248. {
  249. NTSTATUS ntStatus = STATUS_SUCCESS;
  250. PDEVICE_OBJECT pDeviceObject;
  251. UNICODE_STRING DeviceName;
  252. UNICODE_STRING dosdeviceName;
  253. UNICODE_STRING symbolicName;
  254. //
  255. // Create the device object for the sample transport, allowing
  256. // room at the end for the device name to be stored (for use
  257. // in logging errors).
  258. //
  259. RtlInitUnicodeString(&DeviceName, BDA_NDIS_MINIPORT);
  260. ntStatus = IoCreateDevice(
  261. pDriverObject,
  262. 0,
  263. &DeviceName,
  264. 0x00000022, // FILE_DEVICE_UNKNOWN
  265. 0,
  266. FALSE,
  267. &pDeviceObject);
  268. if (ntStatus != STATUS_SUCCESS)
  269. {
  270. goto ret;
  271. }
  272. //
  273. // Set device flag(s).
  274. //
  275. pDeviceObject->Flags |= DO_DIRECT_IO;
  276. //
  277. // Create Symbolic Link
  278. //
  279. RtlInitUnicodeString(&dosdeviceName, BDA_NDIS_MINIPORT);
  280. RtlInitUnicodeString(&symbolicName, BDA_NDIS_SYMBOLIC_NAME);
  281. ntStatus = IoCreateSymbolicLink(
  282. &symbolicName,
  283. &dosdeviceName );
  284. if (ntStatus != STATUS_SUCCESS)
  285. {
  286. ASSERT (FALSE);
  287. }
  288. pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  289. ret:
  290. return ntStatus;
  291. }
  292. //////////////////////////////////////////////////////////////////////////////
  293. NTSTATUS
  294. ntInitializeDriverObject(
  295. PDRIVER_OBJECT *ppDriverObject
  296. )
  297. //////////////////////////////////////////////////////////////////////////////
  298. {
  299. NTSTATUS ntStatus = 0l;
  300. UNICODE_STRING objectName;
  301. PDRIVER_OBJECT pDriverObject = *ppDriverObject;
  302. //
  303. // In case we did not create this driver object, set our global variable
  304. // equal to the one supplied.
  305. //
  306. pGlobalDriverObject = pDriverObject;
  307. *ppDriverObject = pDriverObject;
  308. //
  309. // Create a device object and symbolic name.
  310. //
  311. ntStatus = ntCreateDeviceContext(pDriverObject);
  312. if(ntStatus)
  313. {
  314. goto ret;
  315. }
  316. ret:
  317. return ntStatus;
  318. }
  319. //////////////////////////////////////////////////////////////////////////////
  320. VOID
  321. vSetDriverDispatchTable(
  322. PDRIVER_OBJECT pDriverObject
  323. )
  324. //////////////////////////////////////////////////////////////////////////////
  325. {
  326. //
  327. // Initialize the driver object with this driver's entry points.
  328. //
  329. pDriverObject->MajorFunction [IRP_MJ_CREATE] = ntDispatchOpenClose;
  330. pDriverObject->MajorFunction [IRP_MJ_CLOSE] = ntDispatchOpenClose;
  331. pDriverObject->MajorFunction [IRP_MJ_CLEANUP] = ntDispatchOpenClose;
  332. pDriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] = ntDispatchInternal;
  333. pDriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = NULL;
  334. pDriverObject->DriverUnload = vUnload;
  335. }
  336. #endif
  337.