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.

445 lines
10 KiB

  1. /*++
  2. Copyright (c) 1997 FORE Systems, Inc.
  3. Copyright (c) 1997 Microsoft Corporation
  4. Module Name:
  5. ntentry.c
  6. Abstract:
  7. NT entry points for ATMLANE driver.
  8. Author:
  9. Larry Cleeton, FORE Systems (v-lcleet@microsoft.com, lrc@fore.com)
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. //
  17. // Due to problems with including zwapi.h:
  18. //
  19. NTSYSAPI
  20. NTSTATUS
  21. NTAPI
  22. ZwLoadDriver(
  23. IN PUNICODE_STRING DriverServiceName
  24. );
  25. EXTERN
  26. NTSTATUS
  27. AtmLaneIoctlRequest(
  28. IN PIRP pIrp
  29. );
  30. NTSTATUS
  31. AtmLaneDeviceControl(
  32. IN PDEVICE_OBJECT DeviceObject,
  33. IN PIRP pIrp
  34. );
  35. VOID
  36. AtmLaneUnload(
  37. IN PDRIVER_OBJECT pDriverObject
  38. );
  39. NTSTATUS
  40. DriverEntry(
  41. IN PDRIVER_OBJECT pDriverObject,
  42. IN PUNICODE_STRING RegistryPath
  43. )
  44. /*++
  45. Routine Description:
  46. Entry point for the driver.
  47. Arguments:
  48. DriverObject - Pointer to the system allocated DRIVER_OBJECT.
  49. RegistryPath - Pointer to the UNICODE string defining the registry
  50. path for the driver's information.
  51. Return Value:
  52. Appropriate NDIS_STATUS value.
  53. --*/
  54. {
  55. NTSTATUS NtStatus = STATUS_SUCCESS;
  56. UNICODE_STRING DeviceName;
  57. UNICODE_STRING DeviceLinkUnicodeString;
  58. NDIS_STATUS NdisStatus;
  59. NDIS_HANDLE NdisWrapperHandle = NULL;
  60. NDIS_HANDLE MiniportDriverHandle;
  61. NDIS_HANDLE NdisProtocolHandle;
  62. NDIS50_PROTOCOL_CHARACTERISTICS AtmLaneProtChars;
  63. NDIS_MINIPORT_CHARACTERISTICS AtmLaneMiniChars;
  64. PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION];
  65. ULONG i;
  66. UNICODE_STRING AtmUniKeyName =
  67. NDIS_STRING_CONST("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Atmuni");
  68. #if DBG
  69. volatile ULONG DontRun = 0;
  70. #endif
  71. TRACEIN(DriverEntry);
  72. #if DBG
  73. DbgPrint("ATMLANE built %s %s\n", __DATE__, __TIME__);
  74. DbgPrint("ATMLANE: DbgVerbosity is at %p, currently set to %d\n",
  75. &DbgVerbosity, DbgVerbosity);
  76. if (DontRun > 0)
  77. {
  78. TRACEOUT(DriverEntry);
  79. return NDIS_STATUS_FAILURE;
  80. }
  81. #endif // DBG
  82. //
  83. // Initialize our globals.
  84. //
  85. AtmLaneInitGlobals();
  86. //
  87. // Save the pointer to the Driver Object
  88. //
  89. pAtmLaneGlobalInfo->pDriverObject = pDriverObject;
  90. do
  91. {
  92. //
  93. // Initialize the wrapper.
  94. //
  95. NdisInitializeWrapper(
  96. &NdisWrapperHandle,
  97. pDriverObject,
  98. RegistryPath,
  99. NULL);
  100. if (NULL == NdisWrapperHandle)
  101. {
  102. DBGP((0, "DriverEntry: NdisMInitializeWrapper failed!\n"));
  103. NdisStatus = NDIS_STATUS_FAILURE;
  104. break;
  105. }
  106. else
  107. {
  108. DBGP((3, "DriverEntry: NdisWrapperhandle %x\n", NdisWrapperHandle));
  109. //
  110. // Save the handle to the wrapper.
  111. //
  112. pAtmLaneGlobalInfo->NdisWrapperHandle = NdisWrapperHandle;
  113. }
  114. //
  115. // Attempt to load the standard UNI 3.1 Call Manager
  116. //
  117. NtStatus = ZwLoadDriver(&AtmUniKeyName);
  118. DBGP((1, "ATMLANE: attempt to load ATMUNI returned %x\n", NtStatus));
  119. //
  120. // We don't care whether we successfully loaded the call manager or not.
  121. //
  122. NtStatus = STATUS_SUCCESS;
  123. //
  124. // Initialize the miniport characteristics.
  125. //
  126. NdisZeroMemory(&AtmLaneMiniChars, sizeof(AtmLaneMiniChars));
  127. AtmLaneMiniChars.MajorNdisVersion = 4;
  128. AtmLaneMiniChars.MinorNdisVersion = 0;
  129. // CheckForHangHandler
  130. // DisableInterruptHandler
  131. // EnableInterruptHandler
  132. AtmLaneMiniChars.HaltHandler = AtmLaneMHalt;
  133. // HandleInterruptHandler
  134. AtmLaneMiniChars.InitializeHandler = AtmLaneMInitialize;
  135. // ISRHandler
  136. AtmLaneMiniChars.QueryInformationHandler = AtmLaneMQueryInformation;
  137. // ReconfigureHandler
  138. AtmLaneMiniChars.ResetHandler = AtmLaneMReset;
  139. // SendHandler
  140. AtmLaneMiniChars.SetInformationHandler = AtmLaneMSetInformation;
  141. // TransferDataHandler
  142. AtmLaneMiniChars.ReturnPacketHandler = AtmLaneMReturnPacket;
  143. AtmLaneMiniChars.SendPacketsHandler = AtmLaneMSendPackets;
  144. // AllocateCompleteHandler
  145. //
  146. // Register the Layered Miniport with NDIS.
  147. //
  148. NdisStatus = NdisIMRegisterLayeredMiniport(
  149. NdisWrapperHandle,
  150. &AtmLaneMiniChars,
  151. sizeof(AtmLaneMiniChars),
  152. &MiniportDriverHandle);
  153. if (NDIS_STATUS_SUCCESS == NdisStatus)
  154. {
  155. DBGP((3, "DriverEntry: NdisIMRegisterLayeredMiniport succeeded.\n"));
  156. //
  157. // Save the handle to the driver.
  158. //
  159. pAtmLaneGlobalInfo->MiniportDriverHandle = MiniportDriverHandle;
  160. }
  161. else
  162. {
  163. DBGP((0, "DriverEntry: NdisIMRegisterLayeredMiniport failed! Status: %x\n",
  164. NdisStatus));
  165. break;
  166. }
  167. //
  168. // Initialize the protocol characteristics.
  169. //
  170. NdisZeroMemory(&AtmLaneProtChars, sizeof(AtmLaneProtChars));
  171. AtmLaneProtChars.MajorNdisVersion = 5;
  172. AtmLaneProtChars.MinorNdisVersion = 0;
  173. AtmLaneProtChars.OpenAdapterCompleteHandler = AtmLaneOpenAdapterCompleteHandler;
  174. AtmLaneProtChars.CloseAdapterCompleteHandler = AtmLaneCloseAdapterCompleteHandler;
  175. AtmLaneProtChars.SendCompleteHandler = AtmLaneSendCompleteHandler;
  176. AtmLaneProtChars.TransferDataCompleteHandler = AtmLaneTransferDataCompleteHandler;
  177. AtmLaneProtChars.ResetCompleteHandler = AtmLaneResetCompleteHandler;
  178. AtmLaneProtChars.RequestCompleteHandler = AtmLaneRequestCompleteHandler;
  179. AtmLaneProtChars.ReceiveHandler = AtmLaneReceiveHandler;
  180. AtmLaneProtChars.ReceiveCompleteHandler = AtmLaneReceiveCompleteHandler;
  181. AtmLaneProtChars.StatusHandler = AtmLaneStatusHandler;
  182. AtmLaneProtChars.StatusCompleteHandler = AtmLaneStatusCompleteHandler;
  183. NdisInitUnicodeString(&AtmLaneProtChars.Name, ATMLANE_PROTOCOL_STRING);
  184. // ReceivePacketHandler;
  185. AtmLaneProtChars.BindAdapterHandler = AtmLaneBindAdapterHandler;
  186. AtmLaneProtChars.UnbindAdapterHandler = AtmLaneUnbindAdapterHandler;
  187. AtmLaneProtChars.PnPEventHandler = AtmLanePnPEventHandler;
  188. AtmLaneProtChars.UnloadHandler = AtmLaneUnloadProtocol;
  189. AtmLaneProtChars.CoSendCompleteHandler = AtmLaneCoSendCompleteHandler;
  190. AtmLaneProtChars.CoStatusHandler = AtmLaneCoStatusHandler;
  191. AtmLaneProtChars.CoReceivePacketHandler = AtmLaneCoReceivePacketHandler;
  192. AtmLaneProtChars.CoAfRegisterNotifyHandler = AtmLaneAfRegisterNotifyHandler;
  193. //
  194. // Register the Protocol with NDIS.
  195. //
  196. NdisRegisterProtocol(
  197. &NdisStatus,
  198. &NdisProtocolHandle,
  199. &AtmLaneProtChars,
  200. sizeof(AtmLaneProtChars));
  201. if (NDIS_STATUS_SUCCESS == NdisStatus)
  202. {
  203. DBGP((3, "DriverEntry: NdisProtocolhandle %x\n",
  204. NdisProtocolHandle));
  205. //
  206. // Save the NDIS Protocol handle.
  207. //
  208. pAtmLaneGlobalInfo->NdisProtocolHandle = NdisProtocolHandle;
  209. }
  210. else
  211. {
  212. DBGP((0, "DriverEntry: NdisRegisterProtocol failed! Status: %x\n",
  213. NdisStatus));
  214. break;
  215. }
  216. #ifndef LANE_WIN98
  217. //
  218. // Associate the miniport and protocol now
  219. //
  220. NdisIMAssociateMiniport(MiniportDriverHandle,
  221. NdisProtocolHandle);
  222. #endif // LANE_WIN98
  223. //
  224. // Register our protocol device name for special ioctls
  225. //
  226. for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
  227. {
  228. DispatchTable[i] = AtmLaneDeviceControl;
  229. }
  230. NdisInitUnicodeString(&DeviceName, ATMLANE_NTDEVICE_STRING);
  231. NdisInitUnicodeString(&DeviceLinkUnicodeString, ATMLANE_LINKNAME_STRING);
  232. NdisStatus = NdisMRegisterDevice(
  233. NdisWrapperHandle,
  234. &DeviceName,
  235. &DeviceLinkUnicodeString,
  236. &DispatchTable[0],
  237. &pAtmLaneGlobalInfo->pSpecialDeviceObject,
  238. &pAtmLaneGlobalInfo->SpecialNdisDeviceHandle
  239. );
  240. if (NDIS_STATUS_SUCCESS != NdisStatus)
  241. {
  242. DBGP((0, "DriverEntry: NdisMRegisterDevice failed! Status: %x\n",
  243. NdisStatus));
  244. break;
  245. }
  246. DBGP((3, "DriverEntry: NdisMRegisterDevice: pDevObj %x DevHandle %x\n",
  247. pAtmLaneGlobalInfo->pSpecialDeviceObject,
  248. pAtmLaneGlobalInfo->SpecialNdisDeviceHandle));
  249. NdisMRegisterUnloadHandler(NdisWrapperHandle,
  250. AtmLaneUnload);
  251. } while(FALSE);
  252. if (NDIS_STATUS_SUCCESS != NdisStatus)
  253. {
  254. //
  255. // Clean up.
  256. //
  257. if (NULL != NdisWrapperHandle)
  258. {
  259. NdisTerminateWrapper(
  260. NdisWrapperHandle,
  261. NULL);
  262. }
  263. }
  264. TRACEOUT(DriverEntry);
  265. return(NtStatus);
  266. }
  267. NTSTATUS
  268. AtmLaneDeviceControl(
  269. IN PDEVICE_OBJECT DeviceObject,
  270. IN PIRP pIrp
  271. )
  272. /*++
  273. Routine Description:
  274. This is the function that hooks NDIS's Device Control IRP
  275. handler to implement some protocol specific Ioctls.
  276. Arguments:
  277. DeviceObject - Pointer to device object for target device
  278. pIrp - Pointer to I/O request packet
  279. Return Value:
  280. NTSTATUS -- Indicates whether the request was successfully queued.
  281. --*/
  282. {
  283. PIO_STACK_LOCATION pIrpSp;
  284. NTSTATUS Status;
  285. TRACEIN(DeviceControl);
  286. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  287. DBGP((3, "DeviceControl %x %s\n", pIrpSp->MajorFunction,
  288. IrpToString(pIrpSp->MajorFunction)));
  289. //
  290. // We only hanle the IRP_MJ_DEVICE_CONTROL IRPs.
  291. //
  292. if (pIrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
  293. {
  294. DBGP((3, "DeviceControl: Handling request\n"));
  295. Status = AtmLaneIoctlRequest(pIrp);
  296. }
  297. else
  298. {
  299. switch (pIrpSp->MajorFunction)
  300. {
  301. case IRP_MJ_CREATE:
  302. case IRP_MJ_CLOSE:
  303. case IRP_MJ_CLEANUP:
  304. Status = STATUS_SUCCESS;
  305. break;
  306. case IRP_MJ_SHUTDOWN:
  307. Status = STATUS_NOT_IMPLEMENTED;
  308. break;
  309. default:
  310. DBGP((3, "DeviceControl: MajorFunction not supported\n"));
  311. Status = STATUS_NOT_SUPPORTED;
  312. }
  313. }
  314. ASSERT(STATUS_PENDING != Status);
  315. pIrp->IoStatus.Status = Status;
  316. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  317. TRACEOUT(DeviceControl);
  318. return Status;
  319. }
  320. VOID
  321. AtmLaneUnload(
  322. IN PDRIVER_OBJECT pDriverObject
  323. )
  324. /*++
  325. Routine Description:
  326. This routine is called by the system prior to unloading us.
  327. Currently, we just undo everything we did in DriverEntry,
  328. that is, de-register ourselves as an NDIS protocol, and delete
  329. the device object we had created.
  330. Arguments:
  331. pDriverObject - Pointer to the driver object created by the system.
  332. Return Value:
  333. None
  334. --*/
  335. {
  336. UNICODE_STRING DeviceLinkUnicodeString;
  337. NDIS_STATUS Status;
  338. TRACEIN(Unload);
  339. DBGP((0, "AtmLaneUnload\n"));
  340. // Shut down the protocol first. This is synchronous (i.e. blocks)
  341. AtmLaneUnloadProtocol();
  342. // Delete the symbolic link created for the admin util
  343. if (pAtmLaneGlobalInfo->SpecialNdisDeviceHandle)
  344. {
  345. DBGP((0, "Deregistering device handle %x from AtmLaneUnload\n",
  346. pAtmLaneGlobalInfo->SpecialNdisDeviceHandle));
  347. Status = NdisMDeregisterDevice(pAtmLaneGlobalInfo->SpecialNdisDeviceHandle);
  348. pAtmLaneGlobalInfo->SpecialNdisDeviceHandle = NULL;
  349. ASSERT(NDIS_STATUS_SUCCESS == Status);
  350. }
  351. TRACEOUT(Unload);
  352. return;
  353. }