Скачать презентацию IFT-17584 Semaine 12 Programmation système Martin Dubois 2001 Скачать презентацию IFT-17584 Semaine 12 Programmation système Martin Dubois 2001

cebf952b097b1c5aa980b19fdc35e949.ppt

  • Количество слайдов: 55

IFT-17584 Semaine 12 Programmation système @Martin Dubois, 2001 578 IFT-17584 Semaine 12 Programmation système @Martin Dubois, 2001 578

Plan de la rencontre • Retour sur la semaine dernière • Pilote de périphérique Plan de la rencontre • Retour sur la semaine dernière • Pilote de périphérique Windows 2000 § § § Architecture WDM Les modes d’exécution La structure IRP La vie d’un IRP Les délais d’attentes @Martin Dubois, 2001 579

La semaine dernière • • • Gestion des interruptions Tasklets Situation de concurrences Verrou La semaine dernière • • • Gestion des interruptions Tasklets Situation de concurrences Verrou rotatif File d’attente de tâches @Martin Dubois, 2001 580

Modes d’exécutions PASSIVE_LEVEL • Possible d’accéder la mémoire utilisateur • Possible d’accéder de la Modes d’exécutions PASSIVE_LEVEL • Possible d’accéder la mémoire utilisateur • Possible d’accéder de la mémoire paginée • Possible de s’endormir DISPATCH_LEVEL • Impossible d’accéder la mémoire utilisateur • Impossible d’accéder de la mémoire paginée • Impossible de s’endormir • Toutes les interruptions sont activées DIRQ_LEVEL • Impossible d’accéder la mémoire utilisateur • Impossible d’accéder de la mémoire paginée • Impossible de s’endormir • Certaines interruptions sont désactivées @Martin Dubois, 2001 581

Architecture WDM = Windows Driver Model • • • Nouvelle architecture arrivée avec Windows Architecture WDM = Windows Driver Model • • • Nouvelle architecture arrivée avec Windows 2000 Aussi présente dans Windows 98 et Me Toujours vivante dans Windows XP C’est une architecture en couche Souvent un pilote de périphérique ne parle pas directement au matérielle mais il parle à un pilote de la couche inférieure • L’architecture est pensée pour le « Pn. P » et le « Power Management » @Martin Dubois, 2001 582

Types de driver WDM @Martin Dubois, 2001 583 Types de driver WDM @Martin Dubois, 2001 583

 « Bus Driver » • S’occupe de la gestion d’un « Bus » « Bus Driver » • S’occupe de la gestion d’un « Bus » d’interconnexion de périphériques • Responsabilités § Détection des nouveaux périphériques • Création des « Physical Device Object » § Attribution des ressources § Détection de la déconnexion d’un périphérique § Gestion de l’alimentation des périphériques § Contrôler l’accès au bus lui même § Fournir des moyens de communiquer avec les périphériques @Martin Dubois, 2001 584

 « Function Drivers » • C’est le type de pilote qui concerne le « Function Drivers » • C’est le type de pilote qui concerne le plus les développeurs de pilotes de périphériques • S’occupe des opérations sur le périphérique @Martin Dubois, 2001 585

 « Filter Driver » • Sert à filtrer les requêtes qui se rendent « Filter Driver » • Sert à filtrer les requêtes qui se rendent à un pilote de périphérique • Ce type de pilote à la possibilité de traiter chacune des requêtes adressées à un pilote avant de lui passer cette requête au pilote concerné • Ne s’occupe pas d’électronique • Ils ont de nombreuses utilités § § Logiciel antivirus Logiciel de chiffrement Firewall, VPN Logiciel de gestion de redondance @Martin Dubois, 2001 586

Classes de pilotes • Windows 2000 définit plusieurs classes de pilotes § § § Classes de pilotes • Windows 2000 définit plusieurs classes de pilotes § § § § § Battery Display Printer Modem Network device Smart card reader Storage Devices Streaming Devices … @Martin Dubois, 2001 587

Classes de pilotes • Pour ces classes de pilotes, le « Function Drivers » Classes de pilotes • Pour ces classes de pilotes, le « Function Drivers » est séparé en deux: un « Mini Port Driver » et un « Class Driver » • Le « Class Driver » est fournis par Microsoft. Il offre les fonctions générales utiles à la gestion des périphérique de ce type • Le développeur de logiciel s’occupe du « Mini Port Driver » . Celui-ci s’occupe de la partie du traitement qui dépend de l’électronique. @Martin Dubois, 2001 588

Exemple de chaîne de pilotes @Martin Dubois, 2001 589 Exemple de chaîne de pilotes @Martin Dubois, 2001 589

Exemple de chaîne de pilotes @Martin Dubois, 2001 590 Exemple de chaîne de pilotes @Martin Dubois, 2001 590

Exemple de chaîne de pilotes • Un « Bus Driver » peut détecter un Exemple de chaîne de pilotes • Un « Bus Driver » peut détecter un périphérique qui est par la suite contrôler par un autre « Bus Driver » @Martin Dubois, 2001 591

Driver. Entry • Cette fonction doit spécifier l’adresse des fonctions servant de points d’entrées Driver. Entry • Cette fonction doit spécifier l’adresse des fonctions servant de points d’entrées du pilote de périphérique § Add. Device § Driver. Unload § Fonction de traitement des IRPs Voir Filter. c ligne 35 Le pilote utilisé comme exemple est tiré des exemples du DDK. C’est le code d’un pilote filtre. Les différences entre un pilote filtre et un autre pilote seront mentionnées tout au long de ce cours. J’utilise cet exemple car c’est de loin la plus simple que j’ai trouvé. @Martin Dubois, 2001 592

Le type NTSTATUS • C’est simplement un unsigned long • Plusieurs codes sont définis Le type NTSTATUS • C’est simplement un unsigned long • Plusieurs codes sont définis par Windows § § § STATUS_SUCCESS STATUS_TIMEOUT STATUS_PENDING STATUS_UNSUCCESSFUL STATUS_INVALID_PARAMETER … • Les développeurs peuvent en définir d’autres • La macro NT_SUCCESS permet de vérifier si un code représente la réussite de l’opération @Martin Dubois, 2001 593

 « Unload » • Ne peut pas échouer • Responsable de relâcher toutes « Unload » • Ne peut pas échouer • Responsable de relâcher toutes les ressources encore détenue par le pilote. Voir filter. c ligne 250 @Martin Dubois, 2001 594

 « Add. Device » • Responsabilités § Utiliser Io. Create. Device pour créer « Add. Device » • Responsabilités § Utiliser Io. Create. Device pour créer le « device object » § Utiliser Io. Register. Device. Interface pour rendre publique sont interface (Pas pour les filtres) § Conserver le pointeur vers le « Physical Device Object » § Participer à la gestion du « Power » § Utiliser Io. Attach. Device. To. Device. Stack pour ce connecter au « Physical Device Object » Voir filter. c ligne 83 @Martin Dubois, 2001 595

Io. Register. Device. Interface NTSTATUS Io. Register. Device. Interface( PDEVICE_OBJECT a. PDO, const GUID Io. Register. Device. Interface NTSTATUS Io. Register. Device. Interface( PDEVICE_OBJECT a. PDO, const GUID *a. Interface. Class. Guid, PUNICODE_STRING a. Ref. String, PUNICODE_STRING a. Symbolic. Link. Name ); @Martin Dubois, 2001 596

 « Device Object » • Un pilote doit créer un « Device Object « Device Object » • Un pilote doit créer un « Device Object » pour chacun des périphériques qu’il contrôle • Dans le cas d’un « Bus Driver » , cet objet sera nommé un « Physical Device Object » • Dans le cas d’un « Function Driver » , il est nommé « Function Device Object » • Il y a aussi les « Filter Device Object » • Le système associe à un « device object » : § Une queue de requêtes § Un « Device Extension » @Martin Dubois, 2001 597

Qu’est-ce qu’un PDO ? PDO = « Physical Device Object » • C’est avant Qu’est-ce qu’un PDO ? PDO = « Physical Device Object » • C’est avant tout un « Device Object » • Il est créé par un « Bus Driver » • Il définit comment parler avec le périphérique détecté par le « Bus Driver » Par exemple, Le PDO associé à une carte PCI § § Adresse des ports et de la mémoire Interruption à utiliser Fonction pour éteindre ou allumer la carte … @Martin Dubois, 2001 598

Les fonctions majeurs • Obligatoires § IRP_MJ_PNP • IRP_MN_START_DEVICE • IRP_MN_STOP_DEVICE • … § Les fonctions majeurs • Obligatoires § IRP_MJ_PNP • IRP_MN_START_DEVICE • IRP_MN_STOP_DEVICE • … § IRP_MJ_POWER § IRP_MJ_CREATE § IRP_MJ_CLEANUP § IRP_MJ_CLOSE § IRP_MJ_READ § IRP_MJ_WRITE § IRP_MJ_DEVICE_CONTROL § IRP_MJ_INTERNAL_DEVICE_CONTROL § IRP_MJ_SYSTEM_CONTROL Liens avec Linux ? @Martin Dubois, 2001 599

Les fonctions majeurs • Optionnelles § § IRP_MJ_QUERY_INFORMATION IRP_MJ_SET_INFORMATION IRP_MJ_FLUSH_BUFFERS IRP_MJ_SHUTDOWN Liens avec Linux Les fonctions majeurs • Optionnelles § § IRP_MJ_QUERY_INFORMATION IRP_MJ_SET_INFORMATION IRP_MJ_FLUSH_BUFFERS IRP_MJ_SHUTDOWN Liens avec Linux ? @Martin Dubois, 2001 600

Les « dispatcher » • Ce sont les fonctions appelées lorsque qu’un pilote doit Les « dispatcher » • Ce sont les fonctions appelées lorsque qu’un pilote doit traiter une requête • L’exemple fournis nous montre l’interface du « dispatcher » et comment cette fonction fait pour retrouver les informations nécessaires • Malheureusement, c’est ici que l’utilité de l’exemple prend fin. Comme, c’est un filtre très simple, il exécute la même tâche pour toutes les requêtes qu’il reçoit, soit la passer au pilote sous lui. Voir filter. c ligne 278 @Martin Dubois, 2001 601

IRP • C’est la structure que reçoit un pilote pour décrire une requête @Martin IRP • C’est la structure que reçoit un pilote pour décrire une requête @Martin Dubois, 2001 602

IRP Typedef struct _IRP { … PMDL Mdl. Address; … union { … PVOID IRP Typedef struct _IRP { … PMDL Mdl. Address; … union { … PVOID System. Buffer; } Assoicated. Irp; … IO_STATUS_BLOCK Io. Status; BOOLEAN Pending. Returned; … BOOLEAN Cancel; KIRQL Cancel. Irql; PDRIVER_CANCEL Cancel. Routine; PVOID User. Buffer @Martin Dubois, 2001 603

Les raisons du « stack » • Dans cette architecture en couche, il arrive Les raisons du « stack » • Dans cette architecture en couche, il arrive souvent qu’un pilote, pour traiter une requête, doit passer la requête à un pilote situé sous lui • Pour éviter d’avoir à créer une nouvelle structure de requête à chaque passage, la même structure comporte plusieurs emplacements de paramètres qui sont utilisés à cette fin • L’entête du IRP contient un index de l’espace courante @Martin Dubois, 2001 604

Les paramètres des requête typedef struct _IO_STACK_LOCATION { UCHAR Major. Function UCHAR Minor. Function Les paramètres des requête typedef struct _IO_STACK_LOCATION { UCHAR Major. Function UCHAR Minor. Function UCHAR Flags UCHAR Control union { @Martin Dubois, 2001 605

IRP_MJ_READ struct { ULONG Length; ULONG POINTER_ALIGNEMENT Key; LARGE_INTEGER Byte. Offset } Read; • IRP_MJ_READ struct { ULONG Length; ULONG POINTER_ALIGNEMENT Key; LARGE_INTEGER Byte. Offset } Read; • C’est la même structure pour IRP_MJ_WRITE • Et les données ! Je fais quoi avec ? @Martin Dubois, 2001 606

Que faire avec les données ? • Mode « Buffered » § IRP->Associated. Irp. Que faire avec les données ? • Mode « Buffered » § IRP->Associated. Irp. System. Buffer est alors l’adresse du tampon qui sera recopié automatiquement dans l’espace utilisateur par Windows § Simple mais implique une copie de donnée inutile • Mode « Direct » § IRP->Mdl. Address donne l’adresse d’une structure qui décrit chacune des pages du tampon utilisateur • Lors de la création du « device object » le drapeau DO_BUFFERED_IO ou DO_DIRECT_IO doit être utilisé pour spécifier le mode à utiliser Voir filter. c ligne 171 @Martin Dubois, 2001 607

Le mode « Direct » Que faire avec un MDL (Memory Descriptor List) ? Le mode « Direct » Que faire avec un MDL (Memory Descriptor List) ? • Si vous voulez écrire (ou lire) dans ce tampon § vous devez le rendre accessible dans l’espace d’adressage du noyau § Mm. Get. System. Address. For. Mdl. Safe permet cela • Si votre périphérique écrit directement dans la mémoire (DMA) § Il est inutile d’effectuer la modification des tables de mémoire virtuelle du noyau § Il existe des fonctions qui permettent de connaître l’adresse physique de chacune des pages § Windows s’assure que le tampon est en mémoire centrale et qu’il ne peut pas la quitter durant le traitement. @Martin Dubois, 2001 608

IRP_MJ_DEVICE_CONTROL Struct { ULONG Output. Buffer. Length ULONG POINTER_ALIGNEMENT Input. Buffer. Length ULONG POINTER_ALIGNEMENT IRP_MJ_DEVICE_CONTROL Struct { ULONG Output. Buffer. Length ULONG POINTER_ALIGNEMENT Input. Buffer. Length ULONG POINTER_ALIGNEMENT Io. Control. Code PVOID Type 2 Input. Buffer; } Device. Io. Control; • Pour les données, il est possible d’utiliser le mode « Buffered » , le mode « Direct » et le mode « Neither » • Dans ce troisième mode, l’adresse du tampon utilisateur est directement passé dans IRP->Parameters. Device. Io. Control. Type 3 Input. Buffer Dans ce cas, une valeur remplace souvent le pointeur. @Martin Dubois, 2001 609

IRP_MJ_PNP Une petite note spéciale pour la mineur IRP_MN_START_DEVICE Dans ce cas, les paramètres IRP_MJ_PNP Une petite note spéciale pour la mineur IRP_MN_START_DEVICE Dans ce cas, les paramètres décrivent les ressources requises par le périphérique (ports d’E/S, mémoire d’E/S, interruption) Voir TP 3 Device. cpp ligne 303 @Martin Dubois, 2001 610

La vie d’un IRP @Martin Dubois, 2001 611 La vie d’un IRP @Martin Dubois, 2001 611

Étape 1 – Le « dispatcher » • Ses responsabilités § Valider les arguments Étape 1 – Le « dispatcher » • Ses responsabilités § Valider les arguments de la requête § Si possible, compléter le traitement § Sinon, placer la requête dans la queue • Cette partie s’exécute à PASSIVE_LEVEL • L’exécution du « dispatcher » peut être interrompu par une ISR ou par un DPC ou même par une autre tâche de plus haute priorité • Il est permis de « toucher » à l’électronique mais les dangers d’interruption poussent souvent les développeurs à attendre à la prochaine étapes Voir TP 3 Device. cpp ligne 634 @Martin Dubois, 2001 612

Étape 2 – L’exécution sérialisé • Si le dispatcher a placé la requête dans Étape 2 – L’exécution sérialisé • Si le dispatcher a placé la requête dans la queue, la fonction Start. IO traitera la requête quand son tour viendra. • Start. IO s’exécute au DISPACH_LEVEL • Une ISR peut interrompre cette fonction • Sur un ordinateur multiprocesseur, un autre DPC pourrait aussi s’exécuter sur le second processeur mais il est certain que ce ne serait pas cette même fonction Start. IO • Une autre requête en attente dans la même queue ne sera pas traitée avant que le pilote en donne explicitement la permission Voir TP 3 Device. cpp ligne 1002 @Martin Dubois, 2001 613

Étape 2 – L’exécution sérialisé • Habituellement Start. IO est un gros switch qui Étape 2 – L’exécution sérialisé • Habituellement Start. IO est un gros switch qui redirige la requête selon son numéro • C’est à ce moment que le vrai travail commence • Il est possible que le traitement se termine ici même • Il est aussi possible que le pilote soit obligé d’attendre un certain temps ou d’attendre un interruption • Dans tout les cas, cette fonction doit retourner dans un temps raisonnable Voir TP 3 Device. cpp ligne 594 @Martin Dubois, 2001 614

Étape 3 – La ISR • Il est possible que l’interruption ne soit pas Étape 3 – La ISR • Il est possible que l’interruption ne soit pas pour nous • Il est possible que nous devions attendre un autre interruption avant de continuer le traitement de la requête à un autre niveau • Il est possible que nous désirions continuer le traitement au DISPATCH_LEVEL • Nous ne pouvons pas compléter une requête à partir de cette routine Voir TP 3 Device. cpp ligne 1109 @Martin Dubois, 2001 615

Étape 3 – La ISR • Sur un ordinateur multiprocesseur, Il est possible que Étape 3 – La ISR • Sur un ordinateur multiprocesseur, Il est possible que le DPC commence sont exécution immédiatement, avant même le retour de la ISR @Martin Dubois, 2001 616

Étape 4 – Le « DPC for interrupt » • Il est possible que Étape 4 – Le « DPC for interrupt » • Il est possible que la requête termine ici • Il est possible que d’autres traitements soient nécessaire ou que d’autres interruptions doivent être attendus. Voir TP 3 Device. cpp ligne 1074 @Martin Dubois, 2001 617

Utilisation d’un DPC • Étape 1 – Définition de la fonctions void Function( PKDPC Utilisation d’un DPC • Étape 1 – Définition de la fonctions void Function( PKDPC PVOID a. DPC, a. Context, a. Arg 1, a. Arg 2 ) { … } @Martin Dubois, 2001 618

Utilisation d’un DPC • Étape 2 – L’initialisation void Ke. Initialize. Dpc( @Martin Dubois, Utilisation d’un DPC • Étape 2 – L’initialisation void Ke. Initialize. Dpc( @Martin Dubois, 2001 PKDPC a. DPC, PKDEFERRED_ROUTINE a. Function, PVOID a. Context ); 619

Utilisation d’un DPC • Étape 3 – Le déclenchement BOOLEAN Ke. Insert. Queue. Dpc( Utilisation d’un DPC • Étape 3 – Le déclenchement BOOLEAN Ke. Insert. Queue. Dpc( PKDPC a. DPC, PVOID a. Arg 1, PVOID a. Arg 2 ); • Si le DPC n’est pas déjà dans la queue, il y est ajouté et la fonction retourne TRUE • La fonction Ke. Remove. Queue. Dpc sert à retirer un DPC de la queue. Il faut cependant faire attention car il est peut-être trop tard • Il n’existe malheureusement pas de moyen de « désactiver » temporairement un DPC @Martin Dubois, 2001 620

Utilisation d’un DPC Le système alloue une structure KDPC pour chacun des « device Utilisation d’un DPC Le système alloue une structure KDPC pour chacun des « device object » VOID Io. Initialize. Dpc. Request( PDEVICE_OBJECT a. Device. Object, PIO_DPC_ROUTINE a. Function ); VOID Io. Request. Dpc( PDEVICE_OBJECT a. Device. Object, PIRP a. IRP, PVOID a. Context ); VOID Fonction( @Martin Dubois, 2001 PKDPC a. DPC, PDEVICE_OBJECT a. Device. Object, PIRP a. IRP, PVOID a. Context ); 621

Les « Timers » La manière la plus simple d’utiliser les « Timers » Les « Timers » La manière la plus simple d’utiliser les « Timers » de windows et de définir une fonction à exécuter lors de l’expiration du délai. • Cette fonction prend la forme d’un DPC • La résolution des « Timers » windows et d’environs 10 ms • Avant d’utiliser un « Timer » il faut l’initialiser à l’aide de la fonction suivante void Ke. Initialize. Timer( PKTIMER a. Timer ); @Martin Dubois, 2001 622

Les « Timers » BOOLEAN Ke. Set. Timer( PKTIMER a. Timer, LARGE_INTEGER a. Due. Les « Timers » BOOLEAN Ke. Set. Timer( PKTIMER a. Timer, LARGE_INTEGER a. Due. Time, PKDPC a. DPC ); • a. Due. Time § exprimé en nombre de 100 ns § Une valeur négative est utilisée pour un temps relatif à maintenant § Une valeur positive est par rapport au premier janvier 1970 • a. DPC § doit être initialisé @Martin Dubois, 2001 623

Les « Timers » Il est possible de canceller l’expiration d’un « Timer » Les « Timers » Il est possible de canceller l’expiration d’un « Timer » BOOLEAN Ke. Cancel. Timer( PKTIMER a. Timer ); • Encore une fois, il est important d’effectuer cet opération avec de grandes précautions. § Le DPC associé est peut-être en cours sur le second processeur § Il est aussi possible que le « Timer » soit expiré mais que l’appel de la fonction attend sont tour dans la file d’attente des DPC § Dans les deux cas, ce sont des « BUG » vraiment méchant ! @Martin Dubois, 2001 624

Comment faire attendre une tâche NTSTATUS Ke. Delay. Excution. Thread( KPROCESSOR_MODE a. Wait. Mode, Comment faire attendre une tâche NTSTATUS Ke. Delay. Excution. Thread( KPROCESSOR_MODE a. Wait. Mode, BOOLEAN a. Alertable, PLARGE_INTEGER a. Interval ); • a. Wait. Mode § User. Mode § Kernel. Mode • a. Interval § Voir la manière d’indiquer le temps pour les « Timers » • La résolution est d’environs 10 ms @Martin Dubois, 2001 625

Et pour les délais plus court ? VOID Ke. Stall. Excution. Processor( ULONG a. Et pour les délais plus court ? VOID Ke. Stall. Excution. Processor( ULONG a. Micro. Seconds ); • C’est une attente active • La résolution est de 1 us • Microsoft recommande fortement de ne pas utiliser cette fonction pour des attentes de plus de 50 us @Martin Dubois, 2001 626

Gestion de la mémoire Sous Windows un bloc de mémoire peut être • • Gestion de la mémoire Sous Windows un bloc de mémoire peut être • • • Continu ou non continu Paginé ou non paginé Caché ou non caché Aligné ou non aligné Critique ou non critique @Martin Dubois, 2001 627

Allocation de mémoire PVOID Ex. Allocate. Pool( POOL_TYPE a. Pool. Type, SIZE_T a. Number. Allocation de mémoire PVOID Ex. Allocate. Pool( POOL_TYPE a. Pool. Type, SIZE_T a. Number. Of. Bytes ); void Ex. Free. Pool( PVOID a. P ); Difficile de faire plus simple Attendez de voir la liste des types de « pool » ! @Martin Dubois, 2001 628

Les types de « pool » • Paged. Pool. Cache. Aligned § Pour usage Les types de « pool » • Paged. Pool. Cache. Aligned § Pour usage interne seulement • Non. Paged. Pool. Must. Succeed § Pour usage interne seulement § Seulement durant le démarrage • Non. Paged. Pool. Cache. Aligned § Pour usage interne seulement • Non. Paged. Pool. Cache. Aligned. Must. S § Pour usage interne seulement § Seulement durant le démarrage @Martin Dubois, 2001 629

Mémoire physique continue PVOID Mm. Allocate. Continuous. Memory( ULONG a. Number. Of. Bytes, PHYSICAL_ADDRESS Mémoire physique continue PVOID Mm. Allocate. Continuous. Memory( ULONG a. Number. Of. Bytes, PHYSICAL_ADDRESS a. Highest. Acceptable. Address ); void Mm. Free. Continuous. Memory( PVOID a. Base. Address ); • Fonctionne par page entière @Martin Dubois, 2001 630

Et pour les autres cas PVOID Mm. Allocate. Continuous. Memory. Specify. Cache( SIZE_T a. Et pour les autres cas PVOID Mm. Allocate. Continuous. Memory. Specify. Cache( SIZE_T a. Number. Of. Bytes, PHYSICAL_ADDRESS a. Lowest. Acceptable. Address, PHYSICAL_ADDRESS a. Higest. Acceptable. Address, PHYSICAL_ADDRESS a. Boundary. Address. Multiple, MEMORY_CACHING_TYPE a. Cache. Type ); VOID Mm. Free. Continuous. Memory. Specify. Cache( PVOID a. Base. Address, SIZE_T a. Number. Of. Bytes, MEMORY_CACHING_TYPE a. Cache. Type ); • a. Cache. Type : Mm. Non. Cached, Mm. Cached ou Mm. Write. Combined @Martin Dubois, 2001 631

 « Lookaside List » void Ex. Initialize. Paged. Lookasize. List( PPAGED_LOOKASIDE_LIST a. Lookaside, « Lookaside List » void Ex. Initialize. Paged. Lookasize. List( PPAGED_LOOKASIDE_LIST a. Lookaside, PALLOCATE_FUNCTION a. Allocate, PFREE_FUNCTION a. Free, ULONG a. Flags, SIZE_T a. Size, ULONG a. Tag, USHORT a. Depth ); PVOID Ex. Allocate. From. Paged. Lookaside. List( PPAGED_LOOKASIZE_LIST a. Lookaside ); void Ex. Free. To. Paged. Lookaside. List( PPAGE_LOOKASIDE_LIST a. Lookaside, PVOID a. Entry ); Il existe aussi la version NPaged @Martin Dubois, 2001 632