Macro MmLockPagableCodeSection (wdm.h)
La routine MmLockPagableCodeSection verrouille une section de code de pilote, contenant un ensemble de routines de pilotes marquées avec une directive de compilateur spéciale, dans l’espace système.
Syntaxe
void MmLockPagableCodeSection(
[in] Address
);
Paramètres
[in] Address
Spécifie une adresse symbolique. Cette adresse est généralement le nom d’une fonction de pilote dans une section de code de pilote marquée avec quelque chose comme #pragma alloc_text (PAGExxxx, driverfunction). Toutes les fonctions de la section PAGExxxx sont alors garanties d’être verrouillées lorsque cette fonction est retournée.
Valeur de retour
Aucun
Remarques
MmLockPagableCodeSection retourne une valeur opaque utilisée par le système d’exploitation pour identifier cette section du code du pilote. Cette valeur opaque peut être transmise par la suite à MmLockPagableSectionByHandle (si le pilote déverrouille, puis relocke ultérieurement la section) ou à MmUnlockPagableImageSection.
Les MmLockPagableCodeSection routine et MmUnlockPagableImageSection (la routine qui effectue l’action opposée) prennent en charge les pilotes qui peuvent effectuer les opérations suivantes :
Reportez le chargement d’un sous-ensemble de routines de pilotes dans la mémoire résidente jusqu’à ce que les demandes d’E/S entrantes pour les appareils du pilote rendent nécessaire pour ces routines de traiter les irPs.
Rendez le même sous-ensemble de routines de pilotes disponibles pour la pagination lorsqu’ils ont terminé le traitement des demandes d’E/S et qu’aucune demande supplémentaire pour les appareils du pilote n’est actuellement attendue.
mmLockPagableCodeSection, MmLockPagableSectionByHandle et MmUnlockPagableImageSection sont destinés à être utilisés par les pilotes de périphérique et intermédiaire qui ont les caractéristiques suivantes :
Le pilote a des chemins de code qui peuvent ne pas être nécessaires pendant l’exécution du système, mais, s’ils sont nécessaires, le code du pilote doit être résident, car il s’exécute dans un contexte de thread arbitraire ou à IRQL >= DISPATCH_LEVEL.
Le pilote peut déterminer exactement quand les routines paginables doivent être chargées et quand elles peuvent être paginées à nouveau.
Par exemple, le pilote de disque à tolérance de panne fourni par le système prend en charge la création de jeux de miroirs, de jeux de bandes et de jeux de volumes. Pourtant, une machine particulière ne peut être configurée qu’avec un ensemble miroir, uniquement avec un jeu de bandes, uniquement avec un jeu de volumes, ou avec n’importe quelle combinaison de ces trois options possibles. Dans ces circonstances, le pilote ftdisk système réduit la taille de son image chargée en marquant les routines qui prennent explicitement en charge les jeux de miroir, de bande et de volume comme appartenant aux sections de codes paginables. Lors de l’initialisation du pilote, les sections de codes paginables sont rendues résidentes uniquement si l’utilisateur a configuré les disques pour avoir des jeux de volumes, de bandes ou de miroirs. Si l’utilisateur repartit dynamiquement les disques, le pilote ftdisk verrouille toutes les sections de codes paginables supplémentaires nécessaires pour prendre en charge les jeux de volumes, de bandes ou de miroirs que l’utilisateur demande.
Comme d’autres exemples, les pilotes série et parallèles fournis par le système ont DispatchCreate et routines DispatchClose appelées lorsqu’un port particulier est ouvert pour les E/S exclusives et lorsque le handle d’un port ouvert est libéré, respectivement. Pourtant, les demandes d’E/S série et parallèle sont sporadiques, déterminées par les applications que l’utilisateur final exécute actuellement et quelles options d’application l’utilisateur final exerce actuellement. Dans ces circonstances, les pilotes série et parallèle système réduisent la taille de leurs images chargées en marquant de nombreuses routines comme appartenant à une section de code paginable que la routine DispatchCreate rend résident uniquement lorsque le premier port est ouvert pour les E/S.
Notez que chacun des pilotes système précédents répond aux deux critères pour avoir des sections paginables : le pilote a des chemins de code qui peuvent ne pas être nécessaires pendant l’exécution du système, et le pilote peut déterminer exactement quand sa section paginable doit être chargée et peut être paginée à nouveau.
Étant donné qu’il s’agit d’une opération coûteuse pour verrouiller une section, si un pilote verrouille une section de codes paginable à plusieurs endroits, utilisez MmLockPagableCodeSection pour la première requête. Effectuez les demandes de verrou suivantes en appelant MmLockPagableSectionByHandle en passant le handle retourné par MmLockPagableCodeSection. Le verrouillage par handle améliore considérablement les performances du pilote, car le gestionnaire de mémoire utilise la valeur de retour opaque pour localiser rapidement la section appropriée plutôt que de rechercher une liste de modules chargée. Une section verrouillée est déverrouillée en appelant MmUnlockPagableImageSection.
Chaque routine de pilote dans une section de codes paginable doit être marquée avec la directive du compilateur suivante :
#pragma alloc_text(PAGExxxx, DriverRoutine)
où xxxx est un identificateur unique de quatre caractères facultatif pour la section paginable de l’appelant et DriverRoutine est un point d’entrée à inclure dans la section de codes paginable. Le mot clé PAGE et le suffixe déterminé par le pilote, pouvant être jusqu’à quatre caractères, respectent la casse ; autrement dit, page doit être capitalisée.
Un seul appel à MmLockPagableCodeSection dans, par exemple, le DispatchCreate routine d’un pilote, provoque l’intégralité de la section, contenant chaque routine de pilote marquée avec le même PAGExxxx identificateur, à verrouiller dans l’espace système.
Certains types de routines de pilotes ne peuvent pas faire partie de la section paginable d’un pilote, y compris les éléments suivants :
Ne rendez jamais un ISR paginable. Il est possible qu’un pilote de périphérique reçoive une interruption impulsante même si son appareil n’est pas utilisé, en particulier si le vecteur d’interruption peut être partagé. En général, même si un pilote peut désactiver explicitement les interruptions sur son appareil, un ISR ne doit pas être rendu paginable.
Ne rendez jamais une routine DPC paginable si le pilote ne peut pas contrôler quand le DPC est mis en file d’attente, par exemple n’importe quelle DpcForIsr ou routine CustomDpc susceptible d’être mise en file d’attente à partir d’un ISR. En général, les routines de pilote qui s’exécutent à IRQL >= DISPATCH_LEVEL et qui peuvent être appelées dans un contexte de thread arbitraire ou en réponse à un événement externe aléatoire ne doivent pas être rendues paginables.
N’effectuez jamais le DispatchRead ou DispatchWrite routine paginable dans n’importe quel pilote qui peut faire partie du chemin d’E/S de pagination du système. Le pilote d’un disque qui peut contenir le fichier de page système doit avoir DispatchRead et routines DispatchWrite résidentes pendant l’exécution du système, comme doivent tous les pilotes superposés au-dessus d’un pilote de disque.
Notez que les routines d’une section paginable marquées avec la directive du compilateur #pragma alloc_text(PAGExxxx, ...) diffèrent des routines marquées avec la directive du compilateur #pragma alloc_text(INIT, ...). Les routines de la section INIT ne sont pas paginables et sont ignorées dès que le pilote revient de son DriverEntry ou de sa Réinitialiser routine, s’il en a un.
Le gestionnaire de mémoire gère un nombre de verrous interne sur la section paginable d’un pilote. Les appels à MmLockPagableCodeSection incrémentent ce nombre et la réciproque MmUnlockPagableImageSection décrémente le nombre. La section paginable d’un pilote n’est pas disponible pour être paginée, sauf si ce nombre est égal à zéro.
Pour plus d’informations sur la création de sections de codes paginables, consultez Rendre les pilotes paginables.
Exigences
Exigence | Valeur |
---|---|
plateforme cible | Bureau |
d’en-tête | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
bibliothèque | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <=APC_LEVEL |