Leaked source code of windows server 2003
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.

955 lines
23 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. main.c
  5. Abstract:
  6. This is the initialization file for the packet scheduler driver. This driver
  7. is used to provide Local Traffic Control
  8. Author:
  9. Charlie Wickham (charlwi)
  10. Rajesh Sundaram (rajeshsu) 01-Aug-1998.
  11. Environment:
  12. Kernel Mode
  13. Revision History:
  14. --*/
  15. #include "psched.h"
  16. #pragma hdrstop
  17. //
  18. // number of characters that are appended to the RegistryPath when constructing
  19. // the miniport device name
  20. //
  21. #define MPNAME_EXTENSION_SIZE ( 3 * sizeof(WCHAR))
  22. /* External */
  23. /* Static */
  24. /* Forward */
  25. NTSTATUS
  26. DriverEntry(
  27. IN PDRIVER_OBJECT DriverObject,
  28. IN PUNICODE_STRING RegistryPath
  29. );
  30. NDIS_STATUS
  31. InitializeNdisWrapper(
  32. IN PDRIVER_OBJECT DriverObject,
  33. IN PUNICODE_STRING RegistryPath
  34. );
  35. NDIS_STATUS
  36. DoMiniportInit(
  37. IN PDRIVER_OBJECT DriverObject,
  38. IN PUNICODE_STRING RegistryPath
  39. );
  40. NDIS_STATUS
  41. DoProtocolInit(IN PDRIVER_OBJECT DriverObject,
  42. IN PUNICODE_STRING RegistryPath);
  43. NTSTATUS
  44. RegisterWithGpc();
  45. NDIS_STATUS
  46. InitializeScheduler(VOID);
  47. VOID
  48. InitializationCleanup(ULONG ShutdownMask);
  49. VOID
  50. GetTimerInfo (OUT PULONG TimerResolution);
  51. VOID
  52. PSUnload(IN PDRIVER_OBJECT pDriverObject);
  53. /* End Forward */
  54. #pragma NDIS_INIT_FUNCTION(DriverEntry)
  55. #pragma NDIS_INIT_FUNCTION(InitializeNdisWrapper)
  56. #pragma NDIS_INIT_FUNCTION(DoProtocolInit)
  57. #pragma NDIS_INIT_FUNCTION(DoMiniportInit)
  58. NTSTATUS
  59. DriverEntry(
  60. IN PDRIVER_OBJECT DriverObject,
  61. IN PUNICODE_STRING RegistryPath
  62. )
  63. /*++
  64. Routine Description:
  65. This is the NT OS specific driver entry point. It kicks off initialization
  66. for the driver. Currently, it is not PnP aware. Return from this routine
  67. only after protocol registration, layered miniport registration, and both
  68. miniport and higher layer protocol initialization has been done.
  69. Arguments:
  70. DriverObject - NT OS specific Object
  71. RegistryPath - NT OS specific pointer to registry location for Psched
  72. Return Values:
  73. STATUS_SUCCESS
  74. STATUS_FAILURE
  75. --*/
  76. {
  77. NDIS_STATUS Status;
  78. NTSTATUS NtStatus;
  79. PVOID DumpData;
  80. #if DBG
  81. //
  82. // announce the version
  83. //
  84. PsDbgOut(DBG_INFO, DBG_INIT, (VersionHerald, VersionNumber, VersionTimestamp));
  85. #endif
  86. //
  87. // store a copy of our driver object. Used by NdisWriteEventLogEntry
  88. //
  89. PsDriverObject = DriverObject;
  90. //
  91. // Initialize the Driver refcount and DriverState
  92. //
  93. gDriverState = DriverStateLoaded;
  94. PS_INIT_SPIN_LOCK(&DriverUnloadLock);
  95. NdisInitializeEvent(&DriverUnloadEvent);
  96. NdisSetEvent(&DriverUnloadEvent);
  97. NdisInitializeEvent(&gZAWEvent);
  98. //
  99. // initialize global data and ndis request lookaside list
  100. //
  101. InitializeListHead(&PsComponentList);
  102. InitializeListHead(&AdapterList);
  103. PS_INIT_SPIN_LOCK(&AdapterListLock);
  104. InitializeListHead(&PsProfileList);
  105. // Initialize scheduling components
  106. InitializeTbConformer(&TbConformerInfo);
  107. InitializeDrrSequencer(&DrrSequencerInfo);
  108. InitializeSchedulerStub(&SchedulerStubInfo);
  109. //
  110. // Add these components to the component list
  111. //
  112. InsertHeadList(&PsComponentList, &TbConformerInfo.Links );
  113. InsertHeadList(&PsComponentList, &DrrSequencerInfo.Links );
  114. InsertHeadList(&PsComponentList, &SchedulerStubInfo.Links );
  115. PsProcs.DropPacket = DropPacket;
  116. PsProcs.NdisPipeHandle = GetNdisPipeHandle;
  117. PsProcs.GetTimerInfo = GetTimerInfo;
  118. //
  119. // init the LLists for NdisRequest, MCM_VC, AND CLIENT_VC structs
  120. // as these will be in high demand at times.
  121. //
  122. // Lookaside list depth is automatically managed by the executive.
  123. //
  124. NdisInitializeNPagedLookasideList(&NdisRequestLL,
  125. NULL,
  126. NULL,
  127. 0,
  128. sizeof(PS_NDIS_REQUEST),
  129. NdisRequestTag,
  130. (USHORT)0);
  131. NdisInitializeNPagedLookasideList(&GpcClientVcLL,
  132. NULL,
  133. NULL,
  134. 0,
  135. sizeof( GPC_CLIENT_VC ),
  136. GpcClientVcTag,
  137. (USHORT)0);
  138. //
  139. // get driver wide configuration data from the registry
  140. //
  141. Status = PsReadDriverRegistryDataInit();
  142. if(NT_SUCCESS(Status))
  143. {
  144. Status = PsReadDriverRegistryData();
  145. if(!NT_SUCCESS(Status))
  146. {
  147. PsDbgOut(DBG_FAILURE, DBG_INIT, ("DriverEntry: PsReadDriverRegistryData - Status: 0x%x\n",
  148. Status));
  149. goto DriverEntryError;
  150. }
  151. }
  152. else
  153. {
  154. PsDbgOut(DBG_FAILURE, DBG_INIT, ("DriverEntry: PsReadDriverRegistryDataInit - Status: 0x%x\n",
  155. Status));
  156. goto DriverEntryError;
  157. }
  158. //
  159. // Initialize space for WanLinks. Note that we don't need a lock to protect
  160. // this table - We recognize lineups only on the NDISWAN-IP binding, so we
  161. // can use the Adapter lock from the binding for synchronization.
  162. //
  163. PsAllocatePool(g_WanLinkTable,
  164. WAN_TABLE_INITIAL_SIZE * sizeof(ULONG_PTR),
  165. WanTableTag);
  166. if(!g_WanLinkTable)
  167. {
  168. PsDbgOut(DBG_CRITICAL_ERROR,
  169. DBG_INIT,
  170. ("[DriverEntry]: Cannot allocate memory for wanlinks \n"));
  171. NdisWriteEventLogEntry(PsDriverObject,
  172. EVENT_PS_NO_RESOURCES_FOR_INIT,
  173. 0,
  174. 0,
  175. NULL,
  176. 0,
  177. NULL);
  178. goto DriverEntryError;
  179. }
  180. g_WanTableSize = WAN_TABLE_INITIAL_SIZE;
  181. NdisZeroMemory(g_WanLinkTable, g_WanTableSize * sizeof(ULONG_PTR));
  182. //
  183. // The first entry is never used.
  184. //
  185. g_WanLinkTable[0] = (ULONG_PTR) -1;
  186. g_NextWanIndex = 1;
  187. //
  188. // Register with the Generic Packet Classifier
  189. //
  190. NtStatus = RegisterWithGpc();
  191. if(!NT_SUCCESS(NtStatus))
  192. {
  193. PsDbgOut(DBG_CRITICAL_ERROR,
  194. DBG_INIT,
  195. ("RegisterWithGpc Failed! Status: 0x%x\n", NtStatus));
  196. DumpData = &NtStatus;
  197. NdisWriteEventLogEntry(PsDriverObject,
  198. EVENT_PS_GPC_REGISTER_FAILED,
  199. 0,
  200. 0,
  201. NULL,
  202. sizeof(NTSTATUS),
  203. DumpData);
  204. goto DriverEntryError;
  205. }
  206. InitShutdownMask |= SHUTDOWN_DEREGISTER_GPC;
  207. //
  208. // initialize the wrapper with NDIS
  209. //
  210. Status = InitializeNdisWrapper( PsDriverObject, RegistryPath );
  211. if ( !NT_SUCCESS( Status )) {
  212. PsDbgOut(DBG_FAILURE, DBG_INIT,
  213. ("DriverEntry: InitializeNdisWrapper - Status: 0x%x\n", Status ));
  214. NdisWriteEventLogEntry(PsDriverObject,
  215. EVENT_PS_NO_RESOURCES_FOR_INIT,
  216. 0,
  217. 0,
  218. NULL,
  219. 0,
  220. NULL);
  221. goto DriverEntryError;
  222. }
  223. //
  224. // Initialize as a Miniport driver to the transports.
  225. //
  226. Status = DoMiniportInit(PsDriverObject, RegistryPath);
  227. if (!NT_SUCCESS(Status)){
  228. PsDbgOut(DBG_CRITICAL_ERROR,
  229. DBG_INIT | DBG_MINIPORT,
  230. ("DoMiniportInit Failed! Status: 0x%x\n", Status));
  231. DumpData = &Status;
  232. NdisWriteEventLogEntry(PsDriverObject,
  233. EVENT_PS_REGISTER_MINIPORT_FAILED,
  234. 0,
  235. 0,
  236. NULL,
  237. sizeof( Status ),
  238. DumpData);
  239. //
  240. // Terminate the wrapper
  241. //
  242. NdisTerminateWrapper(MpWrapperHandle, NULL);
  243. goto DriverEntryError;
  244. }
  245. InitShutdownMask |= SHUTDOWN_DEREGISTER_MINIPORT;
  246. //
  247. // do Protocol initialize first
  248. //
  249. Status = DoProtocolInit( PsDriverObject, RegistryPath );
  250. if (!NT_SUCCESS(Status)){
  251. PsDbgOut(DBG_CRITICAL_ERROR,
  252. DBG_INIT | DBG_PROTOCOL,
  253. ("DoProtocolInit Failed! Status: 0x%x\n", Status));
  254. DumpData = &Status;
  255. NdisWriteEventLogEntry(PsDriverObject,
  256. EVENT_PS_REGISTER_PROTOCOL_FAILED,
  257. 0,
  258. 0,
  259. NULL,
  260. sizeof( Status ),
  261. DumpData);
  262. goto DriverEntryError;
  263. }
  264. InitShutdownMask |= SHUTDOWN_DEREGISTER_PROTOCOL;
  265. NdisIMAssociateMiniport(LmDriverHandle, ClientProtocolHandle);
  266. return (STATUS_SUCCESS);
  267. //
  268. // An error occured so we need to cleanup things
  269. //
  270. DriverEntryError:
  271. InitializationCleanup(InitShutdownMask);
  272. NdisTerminateWrapper(MpWrapperHandle, NULL);
  273. return (STATUS_UNSUCCESSFUL);
  274. } // DriverEntry
  275. NDIS_STATUS
  276. InitializeNdisWrapper(
  277. IN PDRIVER_OBJECT DriverObject,
  278. IN PUNICODE_STRING RegistryPath
  279. )
  280. /*++
  281. Routine Description:
  282. Initialize the Ndis wrapper for both the miniport and protocol
  283. sections. Since the name in the registry path is the Protocol
  284. key (PSched), 'Mp' is appended onto the end to initialize
  285. the wrapper for the miniport side of the PS
  286. Arguments:
  287. DriverObject - pointer to NT driver object
  288. RegistryPath - pointer to path to driver params in registry
  289. Return Values:
  290. NDIS_STATUS_SUCCESS
  291. NDIS_STATUS_BAD_VERSION
  292. NDIS_STATUS_FAILURE
  293. --*/
  294. {
  295. NDIS_STATUS Status;
  296. USHORT MpDeviceNameLength;
  297. NDIS_PHYSICAL_ADDRESS HighAddress = NDIS_PHYSICAL_ADDRESS_CONST( -1, -1 );
  298. ULONG i;
  299. PWCHAR RegistryPathBuffer;
  300. //
  301. // NT needs the MP name to be different from the protocol name
  302. //
  303. MpDeviceNameLength = RegistryPath->Length + MPNAME_EXTENSION_SIZE;
  304. PsAllocatePool(RegistryPathBuffer,
  305. MpDeviceNameLength,
  306. PsMiscTag);
  307. if ( RegistryPathBuffer == NULL ) {
  308. PsDbgOut(DBG_CRITICAL_ERROR,
  309. DBG_INIT,
  310. ("Can't allocate buffer for MP Device Name\n" ));
  311. return NDIS_STATUS_RESOURCES;
  312. }
  313. //
  314. // max length includes a trailing null, while length is just the string
  315. //
  316. PsMpName.MaximumLength = MpDeviceNameLength;
  317. PsMpName.Length = PsMpName.MaximumLength - sizeof( WCHAR );
  318. PsMpName.Buffer = RegistryPathBuffer;
  319. NdisMoveMemory(PsMpName.Buffer,
  320. RegistryPath->Buffer,
  321. RegistryPath->Length );
  322. i = RegistryPath->Length / sizeof( WCHAR );
  323. RegistryPathBuffer[ i++ ] = L'M';
  324. RegistryPathBuffer[ i++ ] = L'P';
  325. RegistryPathBuffer[ i ] = L'\0';
  326. NdisMInitializeWrapper(&MpWrapperHandle,
  327. DriverObject,
  328. &PsMpName,
  329. NULL);
  330. return ((MpWrapperHandle) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_RESOURCES);
  331. } // InitializeNdisWrapper
  332. NDIS_STATUS
  333. DoMiniportInit(
  334. IN PDRIVER_OBJECT DriverObject,
  335. IN PUNICODE_STRING RegistryPath
  336. )
  337. /*++
  338. Routine Name:
  339. DoMiniportInit
  340. Routine Description:
  341. This routines registers Psched as a Miniport driver with the NDIS wrapper.
  342. Arguments:
  343. None
  344. Return Values:
  345. NDIS_STATUS_SUCCESS
  346. NDIS_STATUS_BAD_VERSION
  347. NDIS_STATUS_FAILURE
  348. --*/
  349. {
  350. NDIS_MINIPORT_CHARACTERISTICS MiniportChars;
  351. NDIS_STATUS Status;
  352. MiniportChars.MajorNdisVersion = 5;
  353. MiniportChars.MinorNdisVersion = 0;
  354. MiniportChars.Reserved = 0;
  355. MiniportChars.HaltHandler = MpHalt;
  356. MiniportChars.InitializeHandler = MpInitialize;
  357. MiniportChars.QueryInformationHandler = MpQueryInformation;
  358. MiniportChars.ResetHandler = NULL;
  359. MiniportChars.SetInformationHandler = MpSetInformation;
  360. MiniportChars.TransferDataHandler = MpTransferData;
  361. //
  362. // Unused handlers
  363. //
  364. MiniportChars.ReconfigureHandler = NULL;
  365. MiniportChars.DisableInterruptHandler = NULL;
  366. MiniportChars.EnableInterruptHandler = NULL;
  367. MiniportChars.HandleInterruptHandler = NULL;
  368. MiniportChars.ISRHandler = NULL;
  369. //
  370. // We will disable the check for hang timeout so we do not
  371. // need a check for hang handler!
  372. //
  373. MiniportChars.CheckForHangHandler = NULL;
  374. //
  375. // Ndis 4.0 handlers. No regular send routine since we have a
  376. // SendPackets handler.
  377. //
  378. MiniportChars.ReturnPacketHandler = MpReturnPacket;
  379. MiniportChars.SendPacketsHandler = NULL;
  380. MiniportChars.AllocateCompleteHandler = NULL;
  381. MiniportChars.SendHandler = MpSend;
  382. //
  383. // 4.1 handlers
  384. //
  385. MiniportChars.CoCreateVcHandler = NULL;
  386. MiniportChars.CoDeleteVcHandler = NULL;
  387. MiniportChars.CoActivateVcHandler = NULL;
  388. MiniportChars.CoDeactivateVcHandler = NULL;
  389. MiniportChars.CoSendPacketsHandler = NULL;
  390. MiniportChars.CoRequestHandler = NULL;
  391. Status = NdisIMRegisterLayeredMiniport(MpWrapperHandle,
  392. &MiniportChars,
  393. sizeof(MiniportChars),
  394. &LmDriverHandle);
  395. //
  396. // Hook the unload function
  397. //
  398. NdisMRegisterUnloadHandler(MpWrapperHandle, PSUnload);
  399. return (Status);
  400. } // DoMiniportInit
  401. NDIS_STATUS
  402. DoProtocolInit(
  403. IN PDRIVER_OBJECT DriverObject,
  404. IN PUNICODE_STRING RegistryPath
  405. )
  406. /*++
  407. Routine Name:
  408. DoProtocolInit
  409. Routine Description:
  410. This function registers the PS twice as a protocol - once for the protocol
  411. section of the LM and the other for the CM section.
  412. Arguments:
  413. RegistryPath - pointer to our key in the registry
  414. Return Values:
  415. NDIS_STATUS_BAD_CHARACTERISTICS
  416. NDIS_STATUS_BAD_VERSION
  417. NDIS_STATUS_RESOURCES
  418. NDIS_STATUS_SUCCESS
  419. --*/
  420. {
  421. NDIS_PROTOCOL_CHARACTERISTICS ProtocolChars;
  422. NDIS_STATUS Status;
  423. NDIS_STRING PsName = NDIS_STRING_CONST( "PSched" );
  424. //
  425. // register the client portion of the PS
  426. //
  427. NdisZeroMemory(&ProtocolChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  428. ProtocolChars.Name.Length = PsName.Length;
  429. ProtocolChars.Name.Buffer = (PVOID)PsName.Buffer;
  430. ProtocolChars.MajorNdisVersion = 5;
  431. ProtocolChars.MinorNdisVersion = 0;
  432. ProtocolChars.OpenAdapterCompleteHandler = ClLowerMpOpenAdapterComplete;
  433. ProtocolChars.CloseAdapterCompleteHandler = ClLowerMpCloseAdapterComplete;
  434. ProtocolChars.SendCompleteHandler = ClSendComplete;
  435. ProtocolChars.TransferDataCompleteHandler = ClTransferDataComplete;
  436. ProtocolChars.ResetCompleteHandler = ClResetComplete;
  437. ProtocolChars.RequestCompleteHandler = ClRequestComplete;
  438. ProtocolChars.ReceiveHandler = ClReceiveIndication;
  439. ProtocolChars.ReceiveCompleteHandler = ClReceiveComplete;
  440. ProtocolChars.StatusHandler = ClStatusIndication;
  441. ProtocolChars.StatusCompleteHandler = ClStatusIndicationComplete;
  442. ProtocolChars.ReceivePacketHandler = ClReceivePacket;
  443. ProtocolChars.BindAdapterHandler = ClBindToLowerMp;
  444. ProtocolChars.UnbindAdapterHandler = ClUnbindFromLowerMp;
  445. ProtocolChars.UnloadHandler = ClUnloadProtocol;
  446. ProtocolChars.CoSendCompleteHandler = ClCoSendComplete;
  447. ProtocolChars.CoStatusHandler = ClCoStatus;
  448. ProtocolChars.CoReceivePacketHandler = ClCoReceivePacket;
  449. ProtocolChars.CoAfRegisterNotifyHandler = ClCoAfRegisterNotifyHandler;
  450. ProtocolChars.PnPEventHandler = ClPnPEventHandler;
  451. NdisRegisterProtocol(&Status,
  452. &ClientProtocolHandle,
  453. &ProtocolChars,
  454. sizeof(NDIS_PROTOCOL_CHARACTERISTICS) + ProtocolChars.Name.Length);
  455. return Status;
  456. } // DoProtocolInit
  457. NTSTATUS
  458. RegisterWithGpc(
  459. )
  460. /*++
  461. Routine Name:
  462. RegisterWithGpc
  463. Routine Description:
  464. This function initializes the Gpc and gets its list of entry points.
  465. Next, it registers the PS as a client of the GPC and gets a GPC client
  466. handle. The PS must be a client of the GPC before it can classify packets.
  467. Arguments:
  468. GpcHandle - points to the location into which to write the handle which
  469. the GPC gives out to represent this client.
  470. Return Values:
  471. --*/
  472. {
  473. NTSTATUS Status;
  474. //
  475. // Function list for CF_INFO_QOS
  476. //
  477. GPC_CLIENT_FUNC_LIST GpcQosFuncList = {
  478. GpcMajorVersion,
  479. QosAddCfInfoComplete,
  480. QosAddCfInfoNotify,
  481. QosModifyCfInfoComplete,
  482. QosModifyCfInfoNotify,
  483. QosRemoveCfInfoComplete,
  484. QosRemoveCfInfoNotify,
  485. QosClGetCfInfoName
  486. };
  487. Status = GpcInitialize(&GpcEntries);
  488. if(!NT_SUCCESS(Status))
  489. {
  490. ASSERT(0);
  491. GpcEntries.Reserved = NULL;
  492. return Status;
  493. }
  494. PsAssert(GpcEntries.Reserved);
  495. PsAssert(GpcEntries.GpcRegisterClientHandler);
  496. //
  497. // Register for CF_INFO_QOS
  498. //
  499. Status = GpcEntries.GpcRegisterClientHandler(GPC_CF_QOS,
  500. GPC_FLAGS_FRAGMENT,
  501. 1,
  502. &GpcQosFuncList,
  503. (GPC_CLIENT_HANDLE)PS_QOS_CF,
  504. &GpcQosClientHandle);
  505. if (!NT_SUCCESS(Status))
  506. {
  507. ASSERT(0);
  508. GpcQosClientHandle = NULL;
  509. return Status;
  510. }
  511. return Status;
  512. }
  513. VOID
  514. InitializationCleanup(
  515. ULONG ShutdownMask
  516. )
  517. /*++
  518. Routine Description:
  519. This routine is responsible for cleaning up all allocated resources during
  520. initialization
  521. Arguments:
  522. ShutdownMask - A Mask that indicates the items that need to be cleaned up.
  523. Return Values:
  524. None
  525. --*/
  526. {
  527. NDIS_STATUS Status;
  528. PPSI_INFO PsComponent;
  529. PLIST_ENTRY NextProfile, NextComponent;
  530. PPS_PROFILE PsProfile;
  531. //
  532. // Deregister the protocol; we should have no references that would cause
  533. // this to pend
  534. //
  535. if(ShutdownMask & SHUTDOWN_DEREGISTER_MINIPORT){
  536. if(LmDriverHandle){
  537. NdisIMDeregisterLayeredMiniport(LmDriverHandle);
  538. }
  539. }
  540. if(ShutdownMask & SHUTDOWN_DEREGISTER_PROTOCOL){
  541. if(ClientProtocolHandle){
  542. NdisDeregisterProtocol(&Status, ClientProtocolHandle);
  543. if(Status != NDIS_STATUS_SUCCESS){
  544. PsDbgOut(DBG_CRITICAL_ERROR,
  545. DBG_INIT,
  546. ("[InitializationCleanup]: NdisDeregisterProtocol failed - Status 0x%x \n", Status));
  547. }
  548. }
  549. }
  550. //
  551. // Deregister with the GPC
  552. //
  553. if(ShutdownMask & SHUTDOWN_DEREGISTER_GPC){
  554. PsAssert(GpcEntries.GpcDeregisterClientHandler);
  555. Status = GpcEntries.GpcDeregisterClientHandler(GpcQosClientHandle);
  556. if(Status != GPC_STATUS_SUCCESS){
  557. PsDbgOut(DBG_CRITICAL_ERROR,
  558. DBG_INIT,
  559. ("[InitializationCleanup]: DeregisterGpc failed - Status %08X\n",
  560. Status));
  561. }
  562. }
  563. //
  564. // Call the DeInitializeGpc as well, otherwise, FileHandles will leak.
  565. //
  566. if (GpcEntries.Reserved) {
  567. GpcDeinitialize(&GpcEntries);
  568. }
  569. //
  570. // free the lookaside list resources
  571. //
  572. NdisDeleteNPagedLookasideList( &NdisRequestLL );
  573. NdisDeleteNPagedLookasideList( &GpcClientVcLL );
  574. //
  575. // Free up the components
  576. //
  577. NextComponent = PsComponentList.Flink;
  578. while ( NextComponent != &PsComponentList ) {
  579. PsComponent = CONTAINING_RECORD( NextComponent, PSI_INFO, Links );
  580. if(PsComponent->AddIn == TRUE) {
  581. if(PsComponent->ComponentName.Buffer) {
  582. PsFreePool(PsComponent->ComponentName.Buffer);
  583. }
  584. NextComponent = NextComponent->Flink;
  585. PsFreePool(PsComponent);
  586. }
  587. else {
  588. NextComponent = NextComponent->Flink;
  589. }
  590. }
  591. //
  592. // Free up the Profiles
  593. //
  594. NextProfile = PsProfileList.Flink;
  595. while( NextProfile != &PsProfileList) {
  596. PsProfile = CONTAINING_RECORD(NextProfile, PS_PROFILE, Links);
  597. if(PsProfile->ProfileName.Buffer) {
  598. PsFreePool(PsProfile->ProfileName.Buffer);
  599. }
  600. NextProfile = NextProfile->Flink;
  601. PsFreePool(PsProfile);
  602. }
  603. if(g_WanLinkTable)
  604. {
  605. PsFreePool(g_WanLinkTable);
  606. }
  607. if(PsMpName.Buffer)
  608. PsFreePool(PsMpName.Buffer);
  609. //
  610. // Free the locks
  611. //
  612. NdisFreeSpinLock(&AdapterListLock);
  613. NdisFreeSpinLock(&DriverUnloadLock);
  614. //
  615. // TIMESTMP CLEANUP
  616. // 1. Get rid of all the TS_ENTRYs. Release all the memory allocated for them.
  617. // 2. Delete the spin lock.
  618. //
  619. UnloadConformr();
  620. UnloadSequencer();
  621. UnloadPsStub();
  622. // Free the logging stuff //
  623. #if DBG
  624. SchedDeInitialize();
  625. #endif
  626. } // InitializationCleanup
  627. /*++
  628. Routine Description:
  629. This routine returns the timer resolution to the requesting scheduling component.
  630. Arguments:
  631. TimerResolution - Pointer to location in which to return timer resolution.
  632. Return Values:
  633. None
  634. --*/
  635. VOID
  636. GetTimerInfo (
  637. OUT PULONG TimerResolution
  638. )
  639. {
  640. // *TimerResolution = gTimerResolutionActualTime;
  641. *TimerResolution = 0;
  642. } // GetTimerInfo
  643. /*++
  644. Routine Description:
  645. This routine is the driver unload routine.
  646. Arguments:
  647. pDriverObject - The DriverObject that is being unloaded
  648. Return Values:
  649. None
  650. --*/
  651. VOID PSUnload(
  652. IN PDRIVER_OBJECT pDriverObject)
  653. {
  654. PADAPTER Adapter;
  655. PLIST_ENTRY NextAdapter;
  656. NDIS_STATUS Status;
  657. PsDbgOut(DBG_INFO,
  658. DBG_INIT,
  659. ("[PsUnload]: pDriverObject: %x\n", pDriverObject));
  660. PS_LOCK(&DriverUnloadLock);
  661. gDriverState = DriverStateUnloading;
  662. PS_UNLOCK(&DriverUnloadLock);
  663. //
  664. // We wait here till all binds are complete. All future binds are rejected
  665. //
  666. NdisWaitEvent(&DriverUnloadEvent, 0);
  667. //
  668. // we don't have to close opens from the unload handler. Our call
  669. // to NdisDeRegisterProtocol will not return until it issues unbinds
  670. //
  671. InitializationCleanup( 0xffffffff );
  672. PsDbgOut(DBG_INFO, DBG_INIT, (" Unloading psched....\n"));
  673. return;
  674. }
  675. /* end main.c */