Udostępnij przez


Zwalnianie zasobów przydzielonych przez sterownik

Specyfika sposobu, w jaki sterownik używa rejestru, konfiguruje obiekty systemowe i zasoby w jego rozszerzeniach urządzeń, rozszerzeniu kontrolera lub przydzielonej przez sterownik puli niestronicowanej różni się w zależności od sterownika do sterownika. Jednak każda procedura rozładunku musi etapowo zwalniać zasoby używane przez sterownik.

Każda procedura zwalniania sterownika musi upewnić się, że żadna inna procedura sterownika nie korzysta obecnie z określonego zasobu ani nie będzie go używać wkrótce, zanim ten zasób zostanie zwolniony.

Ogólnie rzecz biorąc, procedura zwalniania zwalnia wszystkie zasoby przydzielone przez sterownik w następujących etapach:

  1. Jeśli sterownik jeszcze tego nie zrobił, wyłącz przerwania na wszystkich urządzeniach fizycznych, jeśli to możliwe, a następnie wywołaj metodę IoDisconnectInterrupt natychmiast po wyłączeniu przerwań.

  2. Upewnij się, że żadna inna procedura sterownika nie może odwoływać się do zasobów, które mają być zwalniane przez procedurę zwalniania .

    Na przykład procedura zwalniania musi wywołać funkcję IoStopTimer, jeśli procedura IoTimer sterownika jest obecnie włączona dla określonego obiektu urządzenia. Musi zapewnić, że żaden wątek nie czeka na żaden z obiektów dyspozytora sterownika i że jego obiekty timera nie są kolejkowane do wywołań procedur CustomTimerDpc, zanim zwolni pamięć dla obiektów dyspozytora. Musi wywołać KeRemoveQueueDpc, jeśli ma procedurę CustomDpc, którą ISR mógł umieścić w kolejce, itd.

    Jeśli sterownik wywołał IoQueueWorkItem, musi upewnić się, że zadanie robocze zostało ukończone. IoQueueWorkItem pobiera odwołanie do skojarzonego obiektu urządzenia; nie można zwolnić sterownika, jeśli takie odwołania pozostaną.

    Jeśli sterownik wywołał PsCreateSystemThread, procedura Unload również musi spowodować uruchomienie wątku utworzonego przez sterownik, aby sam wątek mógł wywołać PsTerminateSystemThread przed zwolnieniem sterownika. Sterownik nie może zwolnić wątku systemowego utworzonego przez sterownik, wywołując element ZwClose z elementem ThreadHandle zwróconym przez polecenie PsCreateSystemThread.

  3. Zwolnij wszystkie zasoby specyficzne dla urządzenia, które zostały przydzielone przez sterownik. Może to obejmować wywołanie następujących procedur pomocy technicznej systemu:

  4. Zwolnij obiekty systemowe i zasoby, które procedura DriverEntry lub Reinitialize skonfigurowała w rozszerzeniu obiektów urządzenia lub w rozszerzeniu obiektu kontrolera (jeśli został utworzony). W szczególności sterownik musi wykonać następujące czynności przed podjęciem próby usunięcia obiektu urządzenia (IoDeleteDevice) lub obiektu kontrolera (IoDeleteController):

    • Wywołaj IoDisconnectInterrupt, aby zwolnić wskaźnik obiektu przerwania przechowywany w odpowiednim rozszerzeniu urządzenia lub kontrolera.
    • Wywołaj ObDereferenceObject ze wskaźnikiem do obiektu pliku sterownika na niższym poziomie, jeśli wywołał IoGetDeviceObjectPointer i przechował ten wskaźnik w rozszerzeniu urządzenia lub kontrolera.
    • Wywołaj metodę IoDetachDevice za pomocą wskaźnika do obiektu urządzenia niższego poziomu sterownika, jeśli wywołał IoAttachDevice lub IoAttachDeviceToDeviceStack i przechowywał ten wskaźnik w rozszerzeniu urządzenia lub kontrolera.
  5. Zwolnij zasoby sprzętowe, które rutyny DriverEntry lub Reinitialize zarezerwowały dla fizycznych urządzeń sterownika, jeśli istnieją, w rejestrze w drzewie \Registry\Machine\Hardware\ResourceMap.

  6. Usuń wszystkie nazwy jego urządzeń, które rutyny DriverEntry lub Reinitialize przechowywały w drzewie \Registry..\DeviceMap w rejestrze, jak również.

Po zwolnieniu zasobów urządzenia, systemu i sprzętowych, sterownik może usunąć obiekty urządzenia i kontrolera zgodnie z opisem w temacie Zwalnianie obiektów urządzeń i kontrolerów.