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.

671 lines
13 KiB

  1. //--------------------------------------------------------//
  2. // //
  3. // //
  4. // ZwLoadDriver is locally declared because if I try //
  5. // and include ZwApi.h there are conflicts with //
  6. // structures defined in wdm.h //
  7. // //
  8. // //
  9. //--------------------------------------------------------//
  10. #include "precomp.h"
  11. NDIS_STRING ArpName = NDIS_STRING_CONST("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\ARP1394");
  12. //----------------------------------------------------------//
  13. // Local Prototypes //
  14. //----------------------------------------------------------//
  15. NTSYSAPI
  16. NTSTATUS
  17. NTAPI
  18. ZwLoadDriver(
  19. IN PUNICODE_STRING DriverServiceName
  20. );
  21. NTSYSAPI
  22. NTSTATUS
  23. NTAPI
  24. ZwUnloadDriver(
  25. IN PUNICODE_STRING DriverServiceName
  26. );
  27. VOID
  28. nicEthStartArpWorkItem (
  29. PNDIS_WORK_ITEM pWorkItem,
  30. IN PVOID Context
  31. );
  32. NTSYSAPI
  33. NTSTATUS
  34. NTAPI
  35. ZwDeviceIoControlFile(
  36. IN HANDLE FileHandle,
  37. IN HANDLE Event OPTIONAL,
  38. IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
  39. IN PVOID ApcContext OPTIONAL,
  40. OUT PIO_STATUS_BLOCK IoStatusBlock,
  41. IN ULONG IoControlCode,
  42. IN PVOID InputBuffer OPTIONAL,
  43. IN ULONG InputBufferLength,
  44. OUT PVOID OutputBuffer OPTIONAL,
  45. IN ULONG OutputBufferLength
  46. );
  47. VOID
  48. nicSetupIoctlToLoadArp (
  49. IN PADAPTERCB pAdapter,
  50. IN PARP_INFO pArpInfo
  51. );
  52. VOID
  53. nicSetupAndSendIoctlToArp (
  54. IN PADAPTERCB pAdapter,
  55. IN PARP_INFO pArpInfo
  56. );
  57. //----------------------------------------------------------//
  58. // Functions //
  59. //----------------------------------------------------------//
  60. VOID
  61. nicSendIoctlToArp(
  62. PARP1394_IOCTL_COMMAND pCmd
  63. )
  64. /*++
  65. Routine Description:
  66. Send the start Ioctl to the ARp module
  67. Arguments:
  68. Return Value:
  69. --*/
  70. {
  71. BOOLEAN fRet = FALSE;
  72. PUCHAR pc;
  73. HANDLE DeviceHandle;
  74. ULONG BytesReturned;
  75. OBJECT_ATTRIBUTES Atts;
  76. NDIS_STRING strArp1394 = NDIS_STRING_CONST ("\\Device\\Arp1394");
  77. HANDLE Handle;
  78. NTSTATUS status = STATUS_UNSUCCESSFUL;
  79. IO_STATUS_BLOCK ioStatusBlock;
  80. do
  81. {
  82. InitializeObjectAttributes(&Atts,
  83. &strArp1394,
  84. OBJ_CASE_INSENSITIVE,
  85. NULL,
  86. NULL);
  87. status = ZwCreateFile(&Handle,
  88. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  89. &Atts,
  90. &ioStatusBlock,
  91. NULL,
  92. FILE_ATTRIBUTE_NORMAL,
  93. FILE_SHARE_READ | FILE_SHARE_WRITE,
  94. FILE_OPEN_IF,
  95. 0,
  96. NULL,
  97. 0);
  98. if (!NT_SUCCESS(status))
  99. {
  100. Handle = NULL;
  101. break;
  102. }
  103. //
  104. // Submit the request to the forwarder
  105. //
  106. status = ZwDeviceIoControlFile(
  107. Handle,
  108. NULL,
  109. NULL,
  110. NULL,
  111. &ioStatusBlock,
  112. ARP_IOCTL_CLIENT_OPERATION,
  113. pCmd,
  114. sizeof(*pCmd),
  115. pCmd,
  116. sizeof(*pCmd));
  117. //
  118. // Close the device.
  119. //
  120. ZwClose(Handle);
  121. if (!NT_SUCCESS(status))
  122. {
  123. ASSERT (status == STATUS_SUCCESS);
  124. break;
  125. }
  126. } while (FALSE);
  127. }
  128. VOID
  129. nicLoadArpDriver ()
  130. /*++
  131. Routine Description:
  132. Load the arp module
  133. Arguments:
  134. Return Value:
  135. --*/
  136. {
  137. ZwLoadDriver(&ArpName);
  138. TRACE (TL_T, TM_Mp,("Loaded the Arp Module %p\n", &ArpName));
  139. }
  140. VOID
  141. nicGetAdapterName (
  142. IN PADAPTERCB pAdapter,
  143. IN WCHAR* pAdapterName,
  144. IN ULONG BufferSize,
  145. IN PULONG pSizeReturned
  146. )
  147. /*++
  148. Routine Description:
  149. Get the Adapter Name From NDIS
  150. Arguments:
  151. Return Value:
  152. --*/
  153. {
  154. //
  155. // The BufferSize always has to be greater than SizeReturned
  156. //
  157. NdisMoveMemory (pAdapterName,
  158. &pAdapter->AdapterName[0],
  159. pAdapter->AdapterNameSize * sizeof (WCHAR));
  160. if (pSizeReturned != NULL)
  161. {
  162. *pSizeReturned = pAdapter->AdapterNameSize ;
  163. }
  164. }
  165. VOID
  166. nicSetupIoctlToArp (
  167. IN PADAPTERCB pAdapter,
  168. IN PARP_INFO pArpInfo
  169. )
  170. /*++
  171. Routine Description:
  172. Sets up the Ioctl to be sent to the Arp module
  173. Arguments:
  174. Return Value:
  175. --*/
  176. {
  177. PARP1394_IOCTL_ETHERNET_NOTIFICATION pEthCmd = &pAdapter->ArpIoctl.EthernetNotification;
  178. ADAPTER_ACQUIRE_LOCK(pAdapter);
  179. if (BindArp == pArpInfo->Action || LoadArp == pArpInfo->Action)
  180. {
  181. // BRIDGE START
  182. pEthCmd->Hdr.Op = ARP1394_IOCTL_OP_ETHERNET_START_EMULATION;
  183. pAdapter->fIsArpStarted = TRUE;
  184. ADAPTER_SET_FLAG(pAdapter,fADAPTER_BridgeMode);
  185. }
  186. if (UnloadArp == pArpInfo->Action || UnloadArpNoRequest== pArpInfo->Action)
  187. {
  188. // BRIDGE STOP
  189. pEthCmd->Hdr.Op = ARP1394_IOCTL_OP_ETHERNET_STOP_EMULATION;
  190. pAdapter->fIsArpStarted = FALSE;
  191. ADAPTER_CLEAR_FLAG(pAdapter,fADAPTER_BridgeMode);
  192. }
  193. ADAPTER_RELEASE_LOCK(pAdapter);
  194. }
  195. VOID
  196. nicSetupAndSendIoctlToArp (
  197. IN PADAPTERCB pAdapter,
  198. PARP_INFO pArpInfo )
  199. /*++
  200. Routine Description:
  201. Sets up an Ioctl and Sends it to the Arp module
  202. Arguments:
  203. Return Value:
  204. --*/
  205. {
  206. nicSetupIoctlToArp (pAdapter, pArpInfo);
  207. nicSendIoctlToArp(&pAdapter->ArpIoctl);
  208. }
  209. VOID
  210. nicSendNotificationToArp(
  211. IN PADAPTERCB pAdapter,
  212. IN PARP_INFO pArpInfo
  213. )
  214. /*++
  215. Routine Description:
  216. Send the notification to the arp module
  217. Arguments:
  218. Return Value:
  219. --*/
  220. {
  221. PNDIS_REQUEST pRequest = NULL;
  222. ULONG Start = FALSE;
  223. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  224. ARP1394_IOCTL_COMMAND ArpIoctl;
  225. //
  226. // Extract our variables from the workitem
  227. //
  228. TRACE (TL_T, TM_Mp, ("==>nicEthStartArpWorkItem Start %x", Start ));
  229. do
  230. {
  231. //
  232. // First complete the request, so that protocols can start sending new
  233. // requests . Notes 11/30/00
  234. //
  235. if (pArpInfo->Action == LoadArp || pArpInfo->Action == UnloadArp)
  236. {
  237. //
  238. // in either of these cases, it is a request that has initiated the action.
  239. //
  240. //
  241. if (pRequest == NULL)
  242. {
  243. //
  244. // This came in through our CL SetInformation Handler
  245. //
  246. NdisMSetInformationComplete (pAdapter->MiniportAdapterHandle, NdisStatus );
  247. }
  248. else
  249. {
  250. NdisMCoRequestComplete ( NdisStatus ,
  251. pAdapter->MiniportAdapterHandle,
  252. pRequest);
  253. }
  254. }
  255. //
  256. // "arp13 -bstart adapter"
  257. // If we are asked to Load Arp, we verify that the arp hasn't
  258. // already been started
  259. //
  260. if (pArpInfo->Action == LoadArp && pAdapter->fIsArpStarted == FALSE)// we are turning ON
  261. {
  262. //
  263. // Load the driver
  264. //
  265. nicLoadArpDriver ();
  266. //
  267. // Send it an IOCTL to open the nic1394 adapter
  268. //
  269. }
  270. if (pArpInfo->Action == BindArp && pAdapter->fIsArpStarted == FALSE)
  271. {
  272. //
  273. // if the arp module has not been started and we are asking to bind,
  274. // then it means that an unload was ahead of us in the queue and
  275. // unbound nic1394 from arp1394. This thread can exit.
  276. //
  277. break;
  278. }
  279. //
  280. // Send the Ioctl to the Arp module
  281. //
  282. nicSetupAndSendIoctlToArp (pAdapter, pArpInfo);
  283. } while (FALSE);
  284. //
  285. // end of function
  286. //
  287. FREE_NONPAGED (pArpInfo);
  288. TRACE (TL_T, TM_Mp, ("<==nicEthStartArpWorkItem fLoadArp %x", pArpInfo->Action));
  289. return;
  290. }
  291. VOID
  292. nicProcessNotificationForArp(
  293. IN PNDIS_WORK_ITEM pWorkItem,
  294. IN PVOID Context
  295. )
  296. /*++
  297. Routine Description:
  298. This function extracts the notification from the workitem and
  299. sends the Load/Unload/ BInd notfication to ARp 1394
  300. Arguments:
  301. Return Value:
  302. --*/
  303. {
  304. PADAPTERCB pAdapter = (PADAPTERCB) Context;
  305. ADAPTER_ACQUIRE_LOCK (pAdapter);
  306. //
  307. // Empty the Queue indicating as many packets as possible
  308. //
  309. while (IsListEmpty(&pAdapter->LoadArp.Queue)==FALSE)
  310. {
  311. PARP_INFO pArpInfo;
  312. PLIST_ENTRY pLink;
  313. NDIS_STATUS NdisStatus;
  314. pAdapter->LoadArp.PktsInQueue--;
  315. pLink = RemoveHeadList(&pAdapter->LoadArp.Queue);
  316. ADAPTER_RELEASE_LOCK (pAdapter);
  317. //
  318. // Extract the send context
  319. //
  320. if (pLink != NULL)
  321. {
  322. pArpInfo = CONTAINING_RECORD(
  323. pLink,
  324. ARP_INFO,
  325. Link);
  326. nicSendNotificationToArp(pAdapter, pArpInfo);
  327. }
  328. ADAPTER_ACQUIRE_LOCK (pAdapter);
  329. }
  330. //
  331. // clear the flag
  332. //
  333. ASSERT (pAdapter->LoadArp.PktsInQueue==0);
  334. ASSERT (IsListEmpty(&pAdapter->LoadArp.Queue));
  335. pAdapter->LoadArp.bTimerAlreadySet = FALSE;
  336. ADAPTER_RELEASE_LOCK (pAdapter);
  337. NdisInterlockedDecrement (&pAdapter->OutstandingWorkItems);
  338. }
  339. VOID
  340. nicInitializeLoadArpStruct(
  341. PADAPTERCB pAdapter
  342. )
  343. /*++
  344. Routine Description:
  345. This function initializes the LoadArp struct in _ADAPTERCB
  346. Arguments:
  347. Return Value:
  348. --*/
  349. {
  350. if (pAdapter->LoadArp.bInitialized == FALSE)
  351. {
  352. PARP1394_IOCTL_ETHERNET_NOTIFICATION pEthCmd = &pAdapter->ArpIoctl.EthernetNotification;
  353. ULONG Size;
  354. NdisZeroMemory (&pAdapter->LoadArp, sizeof(pAdapter->LoadArp));
  355. InitializeListHead(&pAdapter->LoadArp.Queue);
  356. pAdapter->LoadArp.bInitialized = TRUE;
  357. NdisInitializeWorkItem (&pAdapter->LoadArp.WorkItem,
  358. nicProcessNotificationForArp,
  359. pAdapter);
  360. nicGetAdapterName (pAdapter,
  361. pEthCmd->AdapterName,
  362. sizeof(pEthCmd->AdapterName)-sizeof(WCHAR),
  363. &Size );
  364. pEthCmd->AdapterName[Size/2]=0;
  365. pEthCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  366. }
  367. }
  368. NDIS_STATUS
  369. nicQueueRequestToArp(
  370. PADAPTERCB pAdapter,
  371. ARP_ACTION Action,
  372. PNDIS_REQUEST pRequest
  373. )
  374. /*++
  375. Routine Description:
  376. This function inserts a request to load/unload or bind the Arp module
  377. If there is no timer servicing the queue
  378. then it queues a timer to dequeue the packet in Global Event's context
  379. Arguments:
  380. Self explanatory
  381. Return Value:
  382. Success - if inserted into the the queue
  383. --*/
  384. {
  385. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  386. BOOLEAN fSetWorkItem = FALSE;
  387. PARP_INFO pArpInfo;
  388. do
  389. {
  390. pArpInfo = ALLOC_NONPAGED(sizeof (ARP_INFO), MTAG_DEFAULT);
  391. if (pArpInfo == NULL)
  392. {
  393. break;
  394. }
  395. ADAPTER_ACQUIRE_LOCK (pAdapter);
  396. //
  397. // Find out if this thread needs to fire the timer
  398. //
  399. pArpInfo->Action = Action;
  400. pArpInfo->pRequest = pRequest;
  401. if (pAdapter->LoadArp.bTimerAlreadySet == FALSE)
  402. {
  403. fSetWorkItem = TRUE;
  404. pAdapter->LoadArp.bTimerAlreadySet = TRUE;
  405. }
  406. InsertTailList(
  407. &pAdapter->LoadArp.Queue,
  408. &pArpInfo->Link
  409. );
  410. pAdapter->LoadArp.PktsInQueue++;
  411. ADAPTER_RELEASE_LOCK (pAdapter);
  412. //
  413. // Now queue the timer
  414. //
  415. if (fSetWorkItem== TRUE)
  416. {
  417. PNDIS_WORK_ITEM pWorkItem;
  418. //
  419. // Initialize the timer
  420. //
  421. pWorkItem = &pAdapter->LoadArp.WorkItem;
  422. TRACE( TL_V, TM_Recv, ( " Set Timer "));
  423. NdisInterlockedIncrement(&pAdapter->OutstandingWorkItems);
  424. NdisScheduleWorkItem (pWorkItem);
  425. }
  426. Status = NDIS_STATUS_SUCCESS;
  427. } while (FALSE);
  428. ASSERT (Status == NDIS_STATUS_SUCCESS);
  429. return Status;
  430. }