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.

1127 lines
29 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. nt.c
  5. Abstract:
  6. NT System entry points for ARP1394.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 11-05-98 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. // File-specific debugging defaults.
  15. //
  16. #define TM_CURRENT TM_NT
  17. // Global variables for this module.
  18. //
  19. ARP1394_GLOBALS ArpGlobals;
  20. // List of fixed resources used by ArpGlobals
  21. //
  22. enum
  23. {
  24. RTYPE_GLOBAL_BACKUP_TASKS,
  25. RTYPE_GLOBAL_DEVICE_OBJECT,
  26. RTYPE_GLOBAL_NDIS_BINDING,
  27. RTYPE_GLOBAL_ADAPTER_LIST,
  28. RTYPE_GLOBAL_IP_BINDING
  29. }; // ARP_GLOBAL_RESOURCES;
  30. //=========================================================================
  31. // L O C A L P R O T O T Y P E S
  32. //=========================================================================
  33. NTSTATUS
  34. DriverEntry(
  35. IN PDRIVER_OBJECT pDriverObject,
  36. IN PUNICODE_STRING pRegistryPath
  37. );
  38. VOID
  39. ArpUnload(
  40. IN PDRIVER_OBJECT pDriverObject
  41. );
  42. NTSTATUS
  43. ArpDispatch(
  44. IN PDEVICE_OBJECT pDeviceObject,
  45. IN PIRP pIrp
  46. );
  47. RM_STATUS
  48. arpResHandleGlobalDeviceObject(
  49. PRM_OBJECT_HEADER pObj,
  50. RM_RESOURCE_OPERATION Op,
  51. PVOID pvUserParams,
  52. PRM_STACK_RECORD psr
  53. );
  54. RM_STATUS
  55. arpResHandleGlobalNdisBinding(
  56. PRM_OBJECT_HEADER pObj,
  57. RM_RESOURCE_OPERATION Op,
  58. PVOID pvUserParams,
  59. PRM_STACK_RECORD psr
  60. );
  61. RM_STATUS
  62. arpResHandleGlobalIpBinding(
  63. PRM_OBJECT_HEADER pObj,
  64. RM_RESOURCE_OPERATION Op,
  65. PVOID pvUserParams,
  66. PRM_STACK_RECORD psr
  67. );
  68. RM_STATUS
  69. arpResHandleGlobalAdapterList(
  70. PRM_OBJECT_HEADER pObj,
  71. RM_RESOURCE_OPERATION Op,
  72. PVOID pvUserParams,
  73. PRM_STACK_RECORD psr
  74. );
  75. RM_STATUS
  76. arpResHandleGlobalBackupTasks(
  77. PRM_OBJECT_HEADER pObj,
  78. RM_RESOURCE_OPERATION Op,
  79. PVOID pvUserParams,
  80. PRM_STACK_RECORD psr
  81. );
  82. //
  83. // Identifies information pertaining to the use of the above resources.
  84. // Following table MUST be in strict increasing order of the RTYPE_GLOBAL
  85. // enum.
  86. //
  87. RM_RESOURCE_TABLE_ENTRY
  88. ArpGlobals_ResourceTable[] =
  89. {
  90. {RTYPE_GLOBAL_BACKUP_TASKS, arpResHandleGlobalBackupTasks},
  91. {RTYPE_GLOBAL_DEVICE_OBJECT, arpResHandleGlobalDeviceObject},
  92. {RTYPE_GLOBAL_NDIS_BINDING, arpResHandleGlobalNdisBinding},
  93. {RTYPE_GLOBAL_ADAPTER_LIST, arpResHandleGlobalAdapterList},
  94. {RTYPE_GLOBAL_IP_BINDING, arpResHandleGlobalIpBinding}
  95. };
  96. // Static informatiou about ArpGlobals.
  97. //
  98. RM_STATIC_OBJECT_INFO
  99. ArpGlobals_StaticInfo =
  100. {
  101. 0, // TypeUID
  102. 0, // TypeFlags
  103. "ArpGlobals", // TypeName
  104. 0, // Timeout
  105. NULL, // pfnCreate
  106. NULL, // pfnDelete
  107. NULL, // pfnVerifyLock
  108. sizeof(ArpGlobals_ResourceTable)/sizeof(ArpGlobals_ResourceTable[1]),
  109. ArpGlobals_ResourceTable
  110. };
  111. BOOLEAN
  112. arpAdapterCompareKey(
  113. PVOID pKey,
  114. PRM_HASH_LINK pItem
  115. )
  116. /*++
  117. Routine Description:
  118. Hash comparison function for ARP1394_ADAPTER.
  119. Arguments:
  120. pKey - Points to an NDIS_STRING containing an adapter name.
  121. pItem - Points to ARP1394_ADAPTER.Hdr.HashLink.
  122. Return Value:
  123. TRUE IFF the key (adapter name) exactly matches the key of the specified
  124. adapter object.
  125. --*/
  126. {
  127. ARP1394_ADAPTER *pA = CONTAINING_RECORD(pItem, ARP1394_ADAPTER, Hdr.HashLink);
  128. PNDIS_STRING pName = (PNDIS_STRING) pKey;
  129. //
  130. // TODO: maybe case-insensitive compare?
  131. //
  132. if ( (pA->bind.DeviceName.Length == pName->Length)
  133. && NdisEqualMemory(pA->bind.DeviceName.Buffer, pName->Buffer, pName->Length))
  134. {
  135. return TRUE;
  136. }
  137. else
  138. {
  139. return FALSE;
  140. }
  141. }
  142. ULONG
  143. arpAdapterHash(
  144. PVOID pKey
  145. )
  146. /*++
  147. Routine Description:
  148. Hash function responsible for returning a hash of pKey, which
  149. we expect to be a pointer to an NDIS_STRING.
  150. Return Value:
  151. ULONG-sized hash of the string.
  152. --*/
  153. {
  154. PNDIS_STRING pName = (PNDIS_STRING) pKey;
  155. WCHAR *pwch = pName->Buffer;
  156. WCHAR *pwchEnd = pName->Buffer + pName->Length/sizeof(*pwch);
  157. ULONG Hash = 0;
  158. for (;pwch < pwchEnd; pwch++)
  159. {
  160. Hash ^= (Hash<<1) ^ *pwch;
  161. }
  162. return Hash;
  163. }
  164. // arpAdapter_HashInfo contains information required maintain a hashtable
  165. // of ARP1394_ADAPTER objects.
  166. //
  167. RM_HASH_INFO
  168. arpAdapter_HashInfo =
  169. {
  170. NULL, // pfnTableAllocator
  171. NULL, // pfnTableDeallocator
  172. arpAdapterCompareKey, // fnCompare
  173. // Function to generate a ULONG-sized hash.
  174. //
  175. arpAdapterHash // pfnHash
  176. };
  177. // ArpGlobals_AdapterStaticInfo contains static information about
  178. // objects of type ARP1394_ADAPTER.
  179. //
  180. RM_STATIC_OBJECT_INFO
  181. ArpGlobals_AdapterStaticInfo =
  182. {
  183. 0, // TypeUID
  184. 0, // TypeFlags
  185. "Adapter", // TypeName
  186. 0, // Timeout
  187. arpAdapterCreate, // pfnCreate
  188. arpAdapterDelete, // pfnDelete
  189. NULL, // pfnVerifyLock
  190. 0, // Size of resource table
  191. NULL, // ResourceTable
  192. &arpAdapter_HashInfo
  193. };
  194. NTSTATUS
  195. DriverEntry(
  196. IN PDRIVER_OBJECT pDriverObject,
  197. IN PUNICODE_STRING pRegistryPath
  198. )
  199. /*++
  200. Routine Description:
  201. This is the "init" routine, called by the system when the ARP
  202. module is loaded. We initialize all our global objects, fill in our
  203. Dispatch and Unload routine addresses in the driver object, and create
  204. a device object for receiving I/O requests on (IOCTLs).
  205. Arguments:
  206. pDriverObject - Pointer to the driver object created by the system.
  207. pRegistryPath - Pointer to our global registry path. This is ignored.
  208. Return Value:
  209. NT Status code: STATUS_SUCCESS if successful, error code otherwise.
  210. --*/
  211. {
  212. NTSTATUS Status;
  213. BOOLEAN AllocatedGlobals = FALSE;
  214. ENTER("DriverEntry", 0xbfcb7eb1)
  215. RM_DECLARE_STACK_RECORD(sr)
  216. TIMESTAMPX("==>DriverEntry");
  217. do
  218. {
  219. // Must be done before any RM apis are used.
  220. //
  221. RmInitializeRm();
  222. RmInitializeLock(
  223. &ArpGlobals.Lock,
  224. LOCKLEVEL_GLOBAL
  225. );
  226. RmInitializeHeader(
  227. NULL, // pParentObject,
  228. &ArpGlobals.Hdr,
  229. ARP1394_GLOBALS_SIG,
  230. &ArpGlobals.Lock,
  231. &ArpGlobals_StaticInfo,
  232. NULL, // szDescription
  233. &sr
  234. );
  235. AllocatedGlobals = TRUE;
  236. //
  237. // Initialize the Driver Object.
  238. //
  239. {
  240. INT i;
  241. pDriverObject->DriverUnload = ArpUnload;
  242. pDriverObject->FastIoDispatch = NULL;
  243. for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
  244. {
  245. pDriverObject->MajorFunction[i] = ArpDispatch;
  246. }
  247. pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = ArpWmiDispatch;
  248. ArpGlobals.driver.pDriverObject = pDriverObject;
  249. }
  250. #if 0 // MILLEN
  251. TR_WARN((
  252. "&g_SkipAll =0x%p; &g_ulTracelevel=0x%p; &g_DiscardNonUnicastPackets=0x%p\n",
  253. &g_SkipAll,
  254. &g_ulTraceLevel,
  255. &g_DiscardNonUnicastPackets));
  256. #if DBG
  257. DbgBreakPoint();
  258. #endif // DBG
  259. #endif // 0
  260. Status = RmLoadGenericResource(
  261. &ArpGlobals.Hdr,
  262. RTYPE_GLOBAL_BACKUP_TASKS,
  263. &sr
  264. );
  265. if (FAIL(Status)) break;
  266. //
  267. // Create a device object for the driver.
  268. //
  269. Status = RmLoadGenericResource(
  270. &ArpGlobals.Hdr,
  271. RTYPE_GLOBAL_DEVICE_OBJECT,
  272. &sr
  273. );
  274. if (FAIL(Status)) break;
  275. //
  276. // Register ourselves with NDIS.
  277. //
  278. Status = RmLoadGenericResource(
  279. &ArpGlobals.Hdr,
  280. RTYPE_GLOBAL_NDIS_BINDING,
  281. &sr
  282. );
  283. if (FAIL(Status)) break;
  284. //
  285. // Create the Adapter List
  286. //
  287. Status = RmLoadGenericResource(
  288. &ArpGlobals.Hdr,
  289. RTYPE_GLOBAL_ADAPTER_LIST,
  290. &sr);
  291. if (FAIL(Status)) break;
  292. //
  293. // Register ourselves with IP.
  294. //
  295. Status = RmLoadGenericResource(
  296. &ArpGlobals.Hdr,
  297. RTYPE_GLOBAL_IP_BINDING,
  298. &sr
  299. );
  300. } while (FALSE);
  301. if (FAIL(Status))
  302. {
  303. if (AllocatedGlobals)
  304. {
  305. RmUnloadAllGenericResources(
  306. &ArpGlobals.Hdr,
  307. &sr
  308. );
  309. RmDeallocateObject(
  310. &ArpGlobals.Hdr,
  311. &sr
  312. );
  313. }
  314. // Must be done after any RM apis are used and async activity complete.
  315. //
  316. RmDeinitializeRm();
  317. }
  318. RM_ASSERT_CLEAR(&sr)
  319. EXIT()
  320. TIMESTAMP("<==DriverEntry");
  321. return Status;
  322. }
  323. VOID
  324. ArpUnload(
  325. IN PDRIVER_OBJECT pDriverObject
  326. )
  327. /*++
  328. Routine Description:
  329. This routine is called by the system prior to unloading us.
  330. Currently, we just undo everything we did in DriverEntry,
  331. that is, de-register ourselves as an NDIS protocol, and delete
  332. the device object we had created.
  333. Arguments:
  334. pDriverObject - Pointer to the driver object created by the system.
  335. Return Value:
  336. None
  337. --*/
  338. {
  339. ENTER("Unload", 0xc8482549)
  340. RM_DECLARE_STACK_RECORD(sr)
  341. TIMESTAMP("==>Unload");
  342. RmUnloadAllGenericResources(&ArpGlobals.Hdr, &sr);
  343. RmDeallocateObject(&ArpGlobals.Hdr, &sr);
  344. // Must be done after any RM apis are used and async activity complete.
  345. //
  346. RmDeinitializeRm();
  347. // TODO? Block(250);
  348. RM_ASSERT_CLEAR(&sr)
  349. EXIT()
  350. TIMESTAMP("<==Unload");
  351. return;
  352. }
  353. NTSTATUS
  354. ArpDispatch(
  355. IN PDEVICE_OBJECT pDeviceObject,
  356. IN PIRP pIrp
  357. )
  358. /*++
  359. Routine Description:
  360. This routine is called by the system when there is an IRP
  361. to be processed.
  362. Arguments:
  363. pDeviceObject - Pointer to device object we created for ourselves.
  364. pIrp - Pointer to IRP to be processed.
  365. Return Value:
  366. NT Status code.
  367. --*/
  368. {
  369. NTSTATUS NtStatus; // Return value
  370. PIO_STACK_LOCATION pIrpStack;
  371. PVOID pIoBuffer; // Values in/out
  372. ULONG InputBufferLength; // Length of input parameters
  373. ULONG OutputBufferLength; // Space for output values
  374. ENTER("Dispatch", 0x1dcf2679)
  375. //
  376. // Initialize
  377. //
  378. NtStatus = STATUS_SUCCESS;
  379. pIrp->IoStatus.Status = STATUS_SUCCESS;
  380. pIrp->IoStatus.Information = 0;
  381. //
  382. // Get all information in the IRP
  383. //
  384. pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
  385. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  386. InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
  387. OutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
  388. switch (pIrpStack->MajorFunction)
  389. {
  390. case IRP_MJ_CREATE:
  391. TR_INFO(("IRP_MJ_CREATE\n"));
  392. break;
  393. case IRP_MJ_CLOSE:
  394. TR_INFO(("IRP_MJ_CLOSE\n"));
  395. break;
  396. case IRP_MJ_CLEANUP:
  397. TR_INFO(("IRP_MJ_CLEANUP\n"));
  398. break;
  399. case IRP_MJ_DEVICE_CONTROL:
  400. TR_INFO(("IRP_MJ_DEVICE_CONTROL\n"));
  401. NtStatus = ArpHandleIoctlRequest(pIrp, pIrpStack);
  402. break;
  403. default:
  404. TR_WARN(("IRP: Unknown major function 0x%p\n",
  405. pIrpStack->MajorFunction));
  406. break;
  407. }
  408. if (NtStatus != STATUS_PENDING)
  409. {
  410. pIrp->IoStatus.Status = NtStatus;
  411. IoMarkIrpPending(pIrp);
  412. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  413. }
  414. EXIT()
  415. return STATUS_PENDING;
  416. }
  417. RM_STATUS
  418. arpResHandleGlobalDeviceObject(
  419. PRM_OBJECT_HEADER pObj,
  420. RM_RESOURCE_OPERATION Op,
  421. PVOID pvUserParams,
  422. PRM_STACK_RECORD pSR
  423. )
  424. /*++
  425. Routine Description:
  426. Responsible for loading and unloading of the RTYPE_GLOBAL_DEVICE_OBJECT resource.
  427. Arguments:
  428. pObj - Actually a pointer to an object of type ARP1394_GLOBALS.
  429. Op - Operation (load/unload)
  430. pvUserParams - (unused)
  431. Return Value:
  432. NDIS_STATUS_SUCCESS on success
  433. NDIS failure code otherwise.
  434. --*/
  435. {
  436. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  437. ARP1394_GLOBALS *pGlobals = CONTAINING_RECORD(pObj, ARP1394_GLOBALS, Hdr);
  438. BOOLEAN fCreatedSymbolicLink = FALSE;
  439. PDRIVER_OBJECT pDriverObject = (PDRIVER_OBJECT) pGlobals->driver.pDriverObject;
  440. UNICODE_STRING SymbolicName;
  441. ENTER("GlobalDeviceObject", 0x335f5f57)
  442. RtlInitUnicodeString(&SymbolicName, ARP1394_SYMBOLIC_NAME);
  443. if (Op == RM_RESOURCE_OP_LOAD)
  444. {
  445. TR_WARN(("LOADING"));
  446. do
  447. {
  448. PDEVICE_OBJECT pDeviceObject;
  449. UNICODE_STRING DeviceName;
  450. RtlInitUnicodeString(&DeviceName, ARP1394_DEVICE_NAME);
  451. pGlobals->driver.pDeviceObject = NULL;
  452. //
  453. // Create a device object for the ARP1394 module.
  454. //
  455. Status = IoCreateDevice(
  456. pDriverObject,
  457. 0,
  458. &DeviceName,
  459. FILE_DEVICE_NETWORK,
  460. FILE_DEVICE_SECURE_OPEN,
  461. FALSE,
  462. &pDeviceObject
  463. );
  464. if (FAIL(Status)) break;
  465. //
  466. // Retain the device object pointer -- we'll need this
  467. // if/when we are asked to unload ourselves.
  468. //
  469. pGlobals->driver.pDeviceObject = pDeviceObject;
  470. //
  471. // Set up a symbolic name for interaction with the user-mode
  472. // admin application.
  473. //
  474. {
  475. Status = IoCreateSymbolicLink(&SymbolicName, &DeviceName);
  476. if (FAIL(Status)) break;
  477. fCreatedSymbolicLink = TRUE;
  478. }
  479. //
  480. // Initialize the Device Object.
  481. //
  482. pDeviceObject->Flags |= DO_DIRECT_IO;
  483. } while (FALSE);
  484. }
  485. else if (Op == RM_RESOURCE_OP_UNLOAD)
  486. {
  487. TR_WARN(("UNLOADING"));
  488. //
  489. // Were unloading this "resource" -- we expect
  490. // that pGlobals->driver.pDeviceObject contains a valid
  491. // device object and that we have created a symbolic
  492. // link which we need to tear down.
  493. //
  494. ASSERTEX(pGlobals->driver.pDeviceObject != NULL, pGlobals);
  495. fCreatedSymbolicLink = TRUE;
  496. // Always return success on unload.
  497. //
  498. Status = NDIS_STATUS_SUCCESS;
  499. }
  500. else
  501. {
  502. // Unexpected op code.
  503. //
  504. ASSERTEX(FALSE, pObj);
  505. }
  506. //
  507. // Release all resources either on unload or on failed load.
  508. //
  509. if (Op == RM_RESOURCE_OP_UNLOAD || FAIL(Status))
  510. {
  511. // If we've created a symbolic link, delete it.
  512. if (fCreatedSymbolicLink)
  513. {
  514. IoDeleteSymbolicLink(&SymbolicName);
  515. }
  516. // If we've created a device object, free it.
  517. if (pGlobals->driver.pDeviceObject)
  518. {
  519. IoDeleteDevice(pGlobals->driver.pDeviceObject);
  520. pGlobals->driver.pDeviceObject = NULL;
  521. }
  522. }
  523. EXIT()
  524. return Status;
  525. }
  526. RM_STATUS
  527. arpResHandleGlobalNdisBinding(
  528. PRM_OBJECT_HEADER pObj,
  529. RM_RESOURCE_OPERATION Op,
  530. PVOID pvUserParams,
  531. PRM_STACK_RECORD pSR
  532. )
  533. /*++
  534. Routine Description:
  535. Responsible for loading and unloading of the RTYPE_GLOBAL_NDIS_BINDING resource.
  536. Arguments:
  537. pObj - Actually a pointer to an object of type ARP1394_GLOBALS.
  538. Op - Operation (load/unload)
  539. pvUserParams - (unused)
  540. Return Value:
  541. NDIS_STATUS_SUCCESS on success
  542. NDIS failure code otherwise.
  543. --*/
  544. {
  545. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  546. ARP1394_GLOBALS *pGlobals = CONTAINING_RECORD(
  547. pObj,
  548. ARP1394_GLOBALS,
  549. Hdr);
  550. PNDIS_PROTOCOL_CHARACTERISTICS pNdisPC = &(pGlobals->ndis.PC);
  551. PNDIS_CLIENT_CHARACTERISTICS pNdisCC = &(pGlobals->ndis.CC);
  552. ENTER("GlobalNdisBinding", 0x62b1181e)
  553. if (Op == RM_RESOURCE_OP_LOAD)
  554. {
  555. TR_WARN(("LOADING"));
  556. //
  557. // Fill in our Protocol and Client characteristics structures.
  558. //
  559. NdisZeroMemory(pNdisPC, sizeof(*pNdisPC));
  560. pNdisPC->MajorNdisVersion = ARP1394_NDIS_MAJOR_VERSION;
  561. pNdisPC->MinorNdisVersion = ARP1394_NDIS_MINOR_VERSION;
  562. pNdisPC->OpenAdapterCompleteHandler = ArpNdOpenAdapterComplete;
  563. pNdisPC->CloseAdapterCompleteHandler = ArpNdCloseAdapterComplete;
  564. pNdisPC->ResetCompleteHandler = ArpNdResetComplete;
  565. pNdisPC->RequestCompleteHandler = ArpNdRequestComplete;
  566. pNdisPC->StatusHandler = ArpNdStatus;
  567. pNdisPC->StatusCompleteHandler = ArpNdStatusComplete;
  568. pNdisPC->SendCompleteHandler = ArpNdSendComplete;
  569. #if ARP_ICS_HACK
  570. //
  571. // Add basic connectionless handlers.
  572. //
  573. // pNdisPC->SendCompleteHandler = ArpNdSendComplete;
  574. pNdisPC->ReceiveCompleteHandler = ArpNdReceiveComplete;
  575. pNdisPC->ReceiveHandler = ArpNdReceive;
  576. pNdisPC->ReceivePacketHandler = ArpNdReceivePacket;
  577. #endif // ARP_ICS_HACK
  578. NdisInitUnicodeString(
  579. &pNdisPC->Name,
  580. ARP1394_LL_NAME
  581. );
  582. //
  583. // Following protocol context handlers are unused and set to NULL.
  584. //
  585. // pNdisPC->TransferDataCompleteHandler
  586. // pNdisPC->ReceiveHandler
  587. // pNdisPC->ReceiveCompleteHandler
  588. // pNdisPC->ReceivePacketHandler
  589. //
  590. pNdisPC->ReceiveCompleteHandler = ArpNdReceiveComplete;
  591. pNdisPC->BindAdapterHandler = ArpNdBindAdapter;
  592. pNdisPC->UnbindAdapterHandler = ArpNdUnbindAdapter;
  593. pNdisPC->UnloadHandler = (UNLOAD_PROTOCOL_HANDLER)
  594. ArpNdUnloadProtocol;
  595. pNdisPC->PnPEventHandler = ArpNdPnPEvent;
  596. pNdisPC->CoSendCompleteHandler = ArpCoSendComplete;
  597. pNdisPC->CoStatusHandler = ArpCoStatus;
  598. pNdisPC->CoReceivePacketHandler = ArpCoReceivePacket;
  599. pNdisPC->CoAfRegisterNotifyHandler = ArpCoAfRegisterNotify;
  600. NdisZeroMemory(pNdisCC, sizeof(*pNdisCC));
  601. pNdisCC->MajorVersion = ARP1394_NDIS_MAJOR_VERSION;
  602. pNdisCC->MinorVersion = ARP1394_NDIS_MINOR_VERSION;
  603. pNdisCC->ClCreateVcHandler = ArpCoCreateVc;
  604. pNdisCC->ClDeleteVcHandler = ArpCoDeleteVc;
  605. pNdisCC->ClRequestHandler = ArpCoRequest;
  606. pNdisCC->ClRequestCompleteHandler = ArpCoRequestComplete;
  607. pNdisCC->ClOpenAfCompleteHandler = ArpCoOpenAfComplete;
  608. pNdisCC->ClCloseAfCompleteHandler = ArpCoCloseAfComplete;
  609. pNdisCC->ClMakeCallCompleteHandler = ArpCoMakeCallComplete;
  610. pNdisCC->ClModifyCallQoSCompleteHandler = ArpCoModifyQosComplete;
  611. pNdisCC->ClIncomingCloseCallHandler = ArpCoIncomingClose;
  612. pNdisCC->ClCallConnectedHandler = ArpCoCallConnected;
  613. pNdisCC->ClCloseCallCompleteHandler = ArpCoCloseCallComplete;
  614. //
  615. // Following client context handlers are unused and set to NULL.
  616. //
  617. // pNdisCC->ClRegisterSapCompleteHandler
  618. // pNdisCC->ClDeregisterSapCompleteHandler
  619. // pNdisCC->ClAddPartyCompleteHandler
  620. // pNdisCC->ClDropPartyCompleteHandler
  621. // pNdisCC->ClIncomingCallHandler
  622. // pNdisCC->ClIncomingCallQoSChangeHandler
  623. // pNdisCC->ClIncomingDropPartyHandler
  624. //
  625. //
  626. // Register ourselves as a protocol with NDIS.
  627. //
  628. NdisRegisterProtocol(
  629. &Status,
  630. &(pGlobals->ndis.ProtocolHandle),
  631. pNdisPC,
  632. sizeof(*pNdisPC)
  633. );
  634. if (FAIL(Status))
  635. {
  636. NdisZeroMemory(&(pGlobals->ndis), sizeof(pGlobals->ndis));
  637. }
  638. }
  639. else if (Op == RM_RESOURCE_OP_UNLOAD)
  640. {
  641. //
  642. // Were unloading this "resource", i.e., cleaning up and
  643. // unregistering with NDIS.
  644. //
  645. TR_WARN(("UNLOADING"));
  646. ASSERTEX(pGlobals->ndis.ProtocolHandle != NULL, pGlobals);
  647. // Unregister ourselves from ndis
  648. //
  649. NdisDeregisterProtocol(
  650. &Status,
  651. pGlobals->ndis.ProtocolHandle
  652. );
  653. NdisZeroMemory(&(pGlobals->ndis), sizeof(pGlobals->ndis));
  654. }
  655. else
  656. {
  657. // Unexpected op code.
  658. //
  659. ASSERT(FALSE);
  660. }
  661. EXIT()
  662. return Status;
  663. }
  664. RM_STATUS
  665. arpResHandleGlobalIpBinding(
  666. PRM_OBJECT_HEADER pObj,
  667. RM_RESOURCE_OPERATION Op,
  668. PVOID pvUserParams,
  669. PRM_STACK_RECORD pSR
  670. )
  671. /*++
  672. Routine Description:
  673. Responsible for loading and unloading of the RTYPE_GLOBAL_IP_BINDING resource.
  674. Arguments:
  675. pObj - Actually a pointer to an object of type ARP1394_GLOBALS.
  676. Op - Operation (load/unload)
  677. pvUserParams - (unused)
  678. Return Value:
  679. NDIS_STATUS_SUCCESS on success
  680. NDIS failure code otherwise.
  681. --*/
  682. {
  683. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  684. ARP1394_GLOBALS *pGlobals = CONTAINING_RECORD(
  685. pObj,
  686. ARP1394_GLOBALS,
  687. Hdr);
  688. ENTER("GlobalIpBinding", 0xf9d36d49)
  689. if (Op == RM_RESOURCE_OP_LOAD)
  690. {
  691. //
  692. // Register ourselves as an ARP Module with IP.
  693. //
  694. NDIS_STRING ArpName;
  695. IP_CHANGE_INDEX IpChangeIndex;
  696. IP_RESERVE_INDEX IpReserveIndex;
  697. IP_DERESERVE_INDEX IpDereserveIndex;
  698. TR_WARN(("LOADING"));
  699. NdisInitUnicodeString(&ArpName, ARP1394_UL_NAME);
  700. Status = IPRegisterARP(
  701. &ArpName,
  702. IP_ARP_BIND_VERSION,
  703. ArpNdBindAdapter,
  704. &(pGlobals->ip.pAddInterfaceRtn),
  705. &(pGlobals->ip.pDelInterfaceRtn),
  706. &(pGlobals->ip.pBindCompleteRtn),
  707. &(pGlobals->ip.pAddLinkRtn),
  708. &(pGlobals->ip.pDeleteLinkRtn),
  709. //
  710. // Following 3 are placeholders -- we don't use this information.
  711. // See 10/14/1998 entry in ipatmc\notes.txt
  712. //
  713. &IpChangeIndex,
  714. &IpReserveIndex,
  715. &IpDereserveIndex,
  716. &(pGlobals->ip.ARPRegisterHandle)
  717. );
  718. if (FAIL(Status))
  719. {
  720. TR_WARN(("IPRegisterARP FAILS. Status = 0x%p", Status));
  721. NdisZeroMemory(&(pGlobals->ip), sizeof(pGlobals->ip));
  722. }
  723. else
  724. {
  725. TR_WARN(("IPRegisterARP Succeeds"));
  726. }
  727. }
  728. else if (Op == RM_RESOURCE_OP_UNLOAD)
  729. {
  730. //
  731. // Were unloading this "resource", i.e., unregistering with IP.
  732. //
  733. TR_WARN(("UNLOADING"));
  734. ASSERTEX(pGlobals->ip.ARPRegisterHandle != NULL, pGlobals);
  735. //
  736. // Unload all adapters (and disallow new adapter from being added)
  737. // *before calling IPDerigesterARP.
  738. //
  739. RmUnloadAllObjectsInGroup(
  740. &pGlobals->adapters.Group,
  741. arpAllocateTask,
  742. arpTaskShutdownAdapter,
  743. NULL, // userParam
  744. NULL, // pTask
  745. 0, // uTaskPendCode
  746. pSR
  747. );
  748. Status = IPDeregisterARP(pGlobals->ip.ARPRegisterHandle);
  749. ASSERTEX(!FAIL(Status), pGlobals);
  750. NdisZeroMemory(&(pGlobals->ip), sizeof(pGlobals->ip));
  751. }
  752. else
  753. {
  754. // Unexpected op code.
  755. //
  756. ASSERT(FALSE);
  757. }
  758. EXIT()
  759. return Status;
  760. }
  761. RM_STATUS
  762. arpResHandleGlobalAdapterList(
  763. PRM_OBJECT_HEADER pObj,
  764. RM_RESOURCE_OPERATION Op,
  765. PVOID pvUserParams,
  766. PRM_STACK_RECORD pSR
  767. )
  768. /*++
  769. Routine Description:
  770. Responsible for loading and unloading of the RTYPE_GLOBAL_ADAPTER_LIST resource.
  771. Arguments:
  772. pObj - Actually a pointer to an object of type ARP1394_GLOBALS.
  773. Op - Operation (load/unload)
  774. pvUserParams - (unused)
  775. Return Value:
  776. NDIS_STATUS_SUCCESS on success
  777. NDIS failure code otherwise.
  778. --*/
  779. {
  780. ARP1394_GLOBALS *pGlobals = CONTAINING_RECORD(
  781. pObj,
  782. ARP1394_GLOBALS,
  783. Hdr);
  784. ENTER("GlobalAdapterList", 0xb407e79e)
  785. if (Op == RM_RESOURCE_OP_LOAD)
  786. {
  787. //
  788. // Allocate adapter list.
  789. //
  790. TR_WARN(("LOADING"));
  791. RmInitializeGroup(
  792. pObj, // pParentObject
  793. &ArpGlobals_AdapterStaticInfo, // pStaticInfo
  794. &(pGlobals->adapters.Group), // pGroup
  795. "Adapter group", // szDescription
  796. pSR // pStackRecord
  797. );
  798. }
  799. else if (Op == RM_RESOURCE_OP_UNLOAD)
  800. {
  801. //
  802. // We're unloading this "resource", i.e., unloading and deallocating the
  803. // global adapter list. We first unload and free all the adapters
  804. // in the list, and then free the list itself.
  805. //
  806. TR_WARN(("UNLOADING"));
  807. //
  808. // We expect there to be no adapter objects at this point.
  809. //
  810. ASSERT(pGlobals->adapters.Group.HashTable.NumItems == 0);
  811. if (0)
  812. {
  813. RmUnloadAllObjectsInGroup(
  814. &pGlobals->adapters.Group,
  815. arpAllocateTask,
  816. arpTaskShutdownAdapter,
  817. NULL, // userParam
  818. NULL, // pTask
  819. 0, // uTaskPendCode
  820. pSR
  821. );
  822. }
  823. RmDeinitializeGroup(&pGlobals->adapters.Group, pSR);
  824. NdisZeroMemory(&(pGlobals->adapters), sizeof(pGlobals->adapters));
  825. }
  826. else
  827. {
  828. // Unexpected op code.
  829. //
  830. ASSERT(FALSE);
  831. }
  832. EXIT()
  833. return NDIS_STATUS_SUCCESS;
  834. }
  835. RM_STATUS
  836. arpResHandleGlobalBackupTasks(
  837. PRM_OBJECT_HEADER pObj,
  838. RM_RESOURCE_OPERATION Op,
  839. PVOID pvUserParams,
  840. PRM_STACK_RECORD pSR
  841. )
  842. /*++
  843. Routine Description:
  844. Allocates 4 Tasks for each adapter to be used as a backup in case of a low mem
  845. condition.
  846. Arguments:
  847. pObj - Actually a pointer to an object of type ARP1394_GLOBALS.
  848. Op - Operation (load/unload)
  849. pvUserParams - (unused)
  850. Return Value:
  851. NDIS_STATUS_SUCCESS on success
  852. NDIS failure code otherwise.
  853. --*/
  854. {
  855. ARP1394_GLOBALS *pGlobals = CONTAINING_RECORD(
  856. pObj,
  857. ARP1394_GLOBALS,
  858. Hdr);
  859. ENTER("GlobalBackupTasks", 0xb64e5007)
  860. if (Op == RM_RESOURCE_OP_LOAD)
  861. {
  862. //
  863. // Allocate adapter list.
  864. //
  865. TR_WARN(("LOADING"));
  866. arpAllocateBackupTasks(pGlobals);
  867. }
  868. else if (Op == RM_RESOURCE_OP_UNLOAD)
  869. {
  870. //
  871. // We're unloading this "resource", i.e., unloading and deallocating the
  872. // global adapter list. We first unload and free all the adapters
  873. // in the list, and then free the list itself.
  874. //
  875. TR_WARN(("UNLOADING"));
  876. //
  877. // We expect there to be no adapter objects at this point.
  878. //
  879. arpFreeBackupTasks(pGlobals);
  880. }
  881. else
  882. {
  883. // Unexpected op code.
  884. //
  885. ASSERT(FALSE);
  886. }
  887. EXIT()
  888. return NDIS_STATUS_SUCCESS;
  889. }