隔离可分页代码

不能对使用旋转锁的例程进行分页。 但是,在某些情况下,可以在单独的例程中隔离需要旋转锁的操作,该例程不会包含在可分页节中。

例如,请考虑以下片段:

//  PAGED_CODE(); 
 
KeInitializeEvent( &event, NotificationEvent, FALSE ); 
irp = IoBuildDeviceIoControlRequest( IRP_MJ_DEVICE_CONTROL, 
                                     DeviceObject, 
                                     (PVOID) NULL, 
                                     0, 
                                     (PVOID) NULL, 
                                     0, 
                                     FALSE, 
                                     &event, 
                                     &ioStatus ); 
if (irp) { 
   irpSp = IoGetNextIrpStackLocation( irp ); 
   irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL; 
   irpSp->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM; 
   status = IoCallDriver( DeviceObject, irp ); 
   if (status == STATUS_PENDING) { 
   (VOID) KeWaitForSingleObject( &event, 
                                 Executive, 
                                 KernelMode, 
                                 FALSE, 
                                 (PLARGE_INTEGER) NULL ); 
   } 
} 

SPINLOCKUSE ! 
KeAcquireSpinLock( &IopDatabaseLock, &irql ); 
// Code inside spin lock ...

DeviceObject->ReferenceCount--; 
 
if (!DeviceObject->ReferenceCount && !DeviceObject->AttachedDevice) { 
   //Unload the driver
   .
   .
   . 
} else { 
   KeReleaseSpinLock( &IopDatabaseLock, irql ); 
} 

(将引用旋转锁的几行代码移动到单独的例程中,) 节省大约 160 个字节,就可以使上述例程变得可分页。

此外,请记住,如果驱动程序代码调用任何 KeXxx 支持例程(如 KeReleaseMutexKeReleaseSemaphore),其中 Wait 参数设置为 TRUE,则不得将其标记为可分页。 此类调用在 DISPATCH_LEVEL 返回 IRQL。