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.

413 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. async.c
  5. Abstract:
  6. This is the main file for the AsyncMAC Driver for the Remote Access
  7. Service. This driver conforms to the NDIS 3.0 interface.
  8. This driver was adapted from the LANCE driver written by
  9. TonyE.
  10. NULL device driver code from DarrylH.
  11. The idea for handling loopback and sends simultaneously is largely
  12. adapted from the EtherLink II NDIS driver by Adam Barr.
  13. Author:
  14. Thomas J. Dimitri (TommyD) 08-May-1992
  15. Environment:
  16. Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
  17. Revision History:
  18. --*/
  19. #include "asyncall.h"
  20. // asyncmac.c will define the global parameters.
  21. #define GLOBALS
  22. #include "globals.h"
  23. NDIS_HANDLE NdisWrapperHandle;
  24. PDRIVER_OBJECT AsyncDriverObject;
  25. NDIS_HANDLE AsyncDeviceHandle;
  26. NPAGED_LOOKASIDE_LIST AsyncIoCtxList;
  27. NPAGED_LOOKASIDE_LIST AsyncInfoList;
  28. ULONG glConnectionCount = 0;
  29. VOID
  30. AsyncUnload(
  31. IN NDIS_HANDLE MacMacContext
  32. );
  33. NDIS_STATUS
  34. AsyncFillInGlobalData(
  35. IN PASYNC_ADAPTER Adapter,
  36. IN PNDIS_REQUEST NdisRequest);
  37. //
  38. // Define the local routines used by this driver module.
  39. //
  40. NTSTATUS
  41. AsyncIOCtlRequest(
  42. IN PIRP pIrp, // Pointer to I/O request packet
  43. IN PIO_STACK_LOCATION pIrpSp // Pointer to the IRP stack location
  44. );
  45. //
  46. // ZZZ Portable interface.
  47. //
  48. NTSTATUS
  49. DriverEntry(
  50. IN PDRIVER_OBJECT DriverObject,
  51. IN PUNICODE_STRING RegistryPath)
  52. /*++
  53. Routine Description:
  54. This is the primary initialization routine for the async driver.
  55. It is simply responsible for the intializing the wrapper and registering
  56. the MAC. It then calls a system and architecture specific routine that
  57. will initialize and register each adapter.
  58. Arguments:
  59. DriverObject - Pointer to driver object created by the system.
  60. Return Value:
  61. The status of the operation.
  62. --*/
  63. {
  64. NDIS_STATUS InitStatus;
  65. NDIS_MINIPORT_CHARACTERISTICS AsyncChar;
  66. //
  67. // Initialize some globals
  68. //
  69. ExInitializeNPagedLookasideList(&AsyncIoCtxList,
  70. NULL,
  71. NULL,
  72. 0,
  73. sizeof(ASYNC_IO_CTX),
  74. ASYNC_IOCTX_TAG,
  75. 0);
  76. ExInitializeNPagedLookasideList(&AsyncInfoList,
  77. NULL,
  78. NULL,
  79. 0,
  80. sizeof(ASYNC_INFO),
  81. ASYNC_INFO_TAG,
  82. 0);
  83. NdisAllocateSpinLock(&GlobalLock);
  84. AsyncDriverObject = DriverObject;
  85. //
  86. // Initialize the wrapper.
  87. //
  88. NdisMInitializeWrapper(&NdisWrapperHandle,
  89. DriverObject,
  90. RegistryPath,
  91. NULL);
  92. //
  93. // Initialize the MAC characteristics for the call to NdisRegisterMac.
  94. //
  95. NdisZeroMemory(&AsyncChar, sizeof(AsyncChar));
  96. AsyncChar.MajorNdisVersion = ASYNC_NDIS_MAJOR_VERSION;
  97. AsyncChar.MinorNdisVersion = ASYNC_NDIS_MINOR_VERSION;
  98. AsyncChar.Reserved = NDIS_USE_WAN_WRAPPER;
  99. //
  100. // We do not need the following handlers:
  101. // CheckForHang
  102. // DisableInterrupt
  103. // EnableInterrupt
  104. // HandleInterrupt
  105. // ISR
  106. // Send
  107. // TransferData
  108. //
  109. AsyncChar.HaltHandler = MpHalt;
  110. AsyncChar.InitializeHandler = MpInit;
  111. AsyncChar.QueryInformationHandler = MpQueryInfo;
  112. AsyncChar.ReconfigureHandler = MpReconfigure;
  113. AsyncChar.ResetHandler = MpReset;
  114. AsyncChar.WanSendHandler = MpSend;
  115. AsyncChar.SetInformationHandler = MpSetInfo;
  116. InitStatus =
  117. NdisMRegisterMiniport(NdisWrapperHandle,
  118. &AsyncChar,
  119. sizeof(AsyncChar));
  120. if ( InitStatus == NDIS_STATUS_SUCCESS ) {
  121. #if MY_DEVICE_OBJECT
  122. //
  123. // Initialize the driver object with this device driver's entry points.
  124. //
  125. NdisMjDeviceControl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
  126. NdisMjCreate = DriverObject->MajorFunction[IRP_MJ_CREATE];
  127. NdisMjCleanup = DriverObject->MajorFunction[IRP_MJ_CLEANUP];
  128. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AsyncDriverDispatch;
  129. DriverObject->MajorFunction[IRP_MJ_CREATE] = AsyncDriverCreate;
  130. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AsyncDriverCleanup;
  131. AsyncSetupExternalNaming(DriverObject);
  132. #endif
  133. NdisUnload = DriverObject->DriverUnload;
  134. DriverObject->DriverUnload = AsyncUnload;
  135. DbgTracef(0,("AsyncMAC succeeded to Register MAC\n"));
  136. return NDIS_STATUS_SUCCESS;
  137. }
  138. ExDeleteNPagedLookasideList(&AsyncIoCtxList);
  139. ExDeleteNPagedLookasideList(&AsyncInfoList);
  140. NdisTerminateWrapper(NdisWrapperHandle, DriverObject);
  141. return NDIS_STATUS_FAILURE;
  142. }
  143. NTSTATUS
  144. AsyncDriverCreate(
  145. IN PDEVICE_OBJECT pDeviceObject,
  146. IN PIRP pIrp
  147. )
  148. {
  149. //
  150. // Get current Irp stack location
  151. //
  152. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  153. #ifdef MY_DEVICE_OBJECT
  154. //
  155. // Make sure that this is for us
  156. //
  157. if (pDeviceObject != AsyncDeviceObject) {
  158. return(NdisMjCreate(pDeviceObject, pIrp));
  159. }
  160. #endif
  161. pIrp->IoStatus.Information = 0;
  162. pIrp->IoStatus.Status = STATUS_SUCCESS;
  163. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  164. return (STATUS_SUCCESS);
  165. }
  166. NTSTATUS
  167. AsyncDriverCleanup(
  168. IN PDEVICE_OBJECT pDeviceObject,
  169. IN PIRP pIrp
  170. )
  171. {
  172. //
  173. // Get current Irp stack location
  174. //
  175. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  176. #ifdef MY_DEVICE_OBJECT
  177. //
  178. // Make sure that this is for us
  179. //
  180. if (pDeviceObject != AsyncDeviceObject) {
  181. return(NdisMjCleanup(pDeviceObject, pIrp));
  182. }
  183. #endif
  184. pIrp->IoStatus.Information = 0;
  185. pIrp->IoStatus.Status = STATUS_SUCCESS;
  186. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  187. return (STATUS_SUCCESS);
  188. }
  189. NTSTATUS
  190. AsyncDriverDispatch(
  191. IN PDEVICE_OBJECT DeviceObject,
  192. IN PIRP Irp)
  193. /*++
  194. Routine Description:
  195. This routine is the main dispatch routine for the AsyncMac device
  196. driver. It accepts an I/O Request Packet, performs the request, and then
  197. returns with the appropriate status.
  198. Arguments:
  199. DeviceObject - Pointer to the device object for this driver.
  200. Irp - Pointer to the request packet representing the I/O request.
  201. Return Value:
  202. The function value is the status of the operation.
  203. --*/
  204. {
  205. NTSTATUS status;
  206. PIO_STACK_LOCATION irpSp;
  207. ULONG ulDeviceType;
  208. ULONG ulMethod;
  209. //
  210. // if this is win64 make sure the calling process is 64bit
  211. // since this interface is only used by rasman and rasman
  212. // will always be 64bit on 64bit systems we will not bother
  213. // with thunking. if the process is not a 64bit process get
  214. // out.
  215. #ifdef _WIN64
  216. if (IoIs32bitProcess(Irp)) {
  217. Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  218. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  219. return (STATUS_NOT_SUPPORTED);
  220. }
  221. #endif
  222. //
  223. // Get a pointer to the current stack location in the IRP. This is where
  224. // the function codes and parameters are stored.
  225. //
  226. irpSp = IoGetCurrentIrpStackLocation( Irp );
  227. ulDeviceType = (irpSp->Parameters.DeviceIoControl.IoControlCode >> 16) & 0x0000FFFF;
  228. ulMethod = irpSp->Parameters.DeviceIoControl.IoControlCode & 0x00000003;
  229. #ifdef MY_DEVICE_OBJECT
  230. //
  231. // Make sure that this is for us
  232. //
  233. if ((irpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL) ||
  234. (ulDeviceType != FILE_DEVICE_ASYMAC) ||
  235. (DeviceObject != AsyncDeviceObject)) {
  236. return(NdisMjDeviceControl(DeviceObject, Irp));
  237. }
  238. #else
  239. if ((irpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL) ||
  240. (ulDeviceType != FILE_DEVICE_NETWORK) ||
  241. (DeviceObject != AsyncDeviceObject) ||
  242. (ulMethod != METHOD_BUFFERED)) {
  243. Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  244. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  245. return (STATUS_NOT_SUPPORTED);
  246. }
  247. #endif
  248. status = AsyncIOCtlRequest(Irp, irpSp);
  249. switch (status) {
  250. case STATUS_SUCCESS:
  251. break;
  252. case STATUS_PENDING:
  253. return(status);
  254. case STATUS_INFO_LENGTH_MISMATCH:
  255. //
  256. // See if this was a request to get size needed for
  257. // ioctl.
  258. //
  259. if (irpSp->Parameters.DeviceIoControl.OutputBufferLength >=
  260. sizeof(ULONG)) {
  261. *(PULONG_PTR)Irp->AssociatedIrp.SystemBuffer =
  262. Irp->IoStatus.Information;
  263. Irp->IoStatus.Information = sizeof(ULONG);
  264. } else {
  265. Irp->IoStatus.Information = 0;
  266. }
  267. status = STATUS_SUCCESS;
  268. break;
  269. default:
  270. if (status < 0xC0000000) {
  271. status = STATUS_UNSUCCESSFUL;
  272. }
  273. Irp->IoStatus.Information = 0;
  274. break;
  275. }
  276. //
  277. // Copy the final status into the return status,
  278. // complete the request and get out of here.
  279. //
  280. Irp->IoStatus.Status = status;
  281. IoCompleteRequest( Irp, (UCHAR)0 );
  282. return (status);
  283. }
  284. VOID
  285. AsyncUnload(
  286. PDRIVER_OBJECT DriverObject
  287. )
  288. /*++
  289. Routine Description:
  290. AsyncUnload is called when the MAC is to unload itself.
  291. Arguments:
  292. MacMacContext - not used.
  293. Return Value:
  294. None.
  295. --*/
  296. {
  297. ExDeleteNPagedLookasideList(&AsyncIoCtxList);
  298. ExDeleteNPagedLookasideList(&AsyncInfoList);
  299. #ifdef MY_DEVICE_OBJECT
  300. AsyncCleanupExternalNaming();
  301. #endif
  302. (*NdisUnload)(DriverObject);
  303. }