學編程的人不能不看的好文章
http://blog.csdn.net/dljhf/archive/2005/06/28/406271.aspx看完只是覺得, 小子你還太嫩了. 看來是沒學過演算法吧, 連基本的演算法都不知道就開始寫程式, 難怪被定的滿頭包.
而且第一題是很基本的歸納法啊, 高中就學過了, 題目沒看仔細就開始作答了, 難怪不會上. 如果每個大陸人都是這樣, 那我應該還有幾年的飯可以吃.....
PIRP IoBuildDeviceIoControlRequest ( INULONG IoControlCode, INPDEVICE_OBJECT DeviceObject, INPVOID InputBuffer OPTIONAL, INULONG InputBufferLength, OUTPVOID OutputBuffer OPTIONAL, INULONG OutputBufferLength, INBOOLEAN InternalDeviceIoControl, INPKEVENT Event, OUTPIO_STATUS_BLOCK IoStatusBlock );
VOID UsbBuildInterruptOrBulkTransferRequest ( IN OUTPURB Urb, INUSHORT Length, INUSBD_PIPE_HANDLE PipeHandle, INPVOID TransferBuffer OPTIONAL, INPMDL TransferBufferMDL OPTIONAL, INULONG TransferBufferLength, INULONG TransferFlags, INPURB Link );
PIO_STACK_LOCATION nextStack =IoGetNextIrpStackLocation (irp); nextStack->Parameters.Others.Argument1 = pUrb;
PIRP IoAllocateIrp ( INCCHAR StackSize, INBOOLEAN ChargeQuota );
PIO_STACK_LOCATION nextStack =IoGetNextIrpStackLocation (irp); nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; // Internal Device Control for USB nextStack->Parameters.Others.Argument1 = pUrb; // for USB nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; // for USB submition
VOID IoSetCompletionRoutine ( INPIRP Irp, INPIO_COMPLETION_ROUTINE CompletionRoutine, INPVOID Context, INBOOLEAN InvokeOnSuccess, INBOOLEAN InvokeOnError, INBOOLEAN InvokeOnCancel );
NTSTATUS IoCompletion ( INPDEVICE_OBJECT DeviceObject, INPIRP Irp, INPVOID Context );
NTSTATUS IoCallDriver ( INPDEVICE_OBJECT DeviceObject, IN OUTPIRP Irp );
NTSTATUS KeWaitForSingleObject ( INPVOID Object, INKWAIT_REASON WaitReason, INKPROCESSOR_MODE WaitMode, INBOOLEAN Alertable, INPLARGE_INTEGER Timeout OPTIONAL );
BOOLEAN IoCancelIrp (INPIRP Irp);
VOID IoFreeIrp (INPIRP Irp);
#define IoGetCurrentIrpStackLocation( Irp ) { (Irp)->Tail.Overlay.CurrentStackLocation; }
#define IoGetNextIrpStackLocation( Irp ) { (Irp)->Tail.Overlay.CurrentStackLocation - 1 ) }
#define IoSetNextIrpStackLocation( Irp ) { (Irp)->CurrentLocation--; (Irp)->Tail.Overlay.CurrentStackLocation--; }
NTSTATUS IoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp) { IoSetNextIrpStackLocation(Irp); PIO_STACK_LOCATION stack = IoGetCurrentStackLocation(Irp); stack->DeviceObject = DeviceObject; ULONG fcn = stack->MajorFunction; PDRIVER_OBJECT driver = DeviceObject->DriverObject; return (*driver->MajorFunction[func])(DeviceObject, Irp); }
#define IoCopyCurrentIrpStackLocationToNext( Irp ) { PIO_STACK_LOCATION __irpSp; PIO_STACK_LOCATION __nextIrpSp; __irpSp = IoGetCurrentIrpStackLocation( (Irp) ); __nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); RtlCopyMemory( __nextIrpSp, __irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); __nextIrpSp->Control = 0; }
#define IoSkipCurrentIrpStackLocation( Irp ) { (Irp)->CurrentLocation++; (Irp)->Tail.Overlay.CurrentStackLocation++; }
typedef struct _IRP { CSHORT Type; USHORT Size; // Define the common fields used to control the IRP. // Define a pointer to the Memory Descriptor List (MDL) for this I/O // request. This field is only used if the I/O is "direct I/O". PMDL MdlAddress; // Flags word - used to remember various flags. ULONG Flags; // The following union is used for one of three purposes: // 1. This IRP is an associated IRP. The field is a pointer to a master IRP. // // 2. This is the master IRP. The field is the count of the number of // IRPs which must complete (associated IRPs) before the master can // complete. // // 3. This operation is being buffered and the field is the address of // the system space buffer. union { struct _IRP *MasterIrp; __volatile LONG IrpCount; PVOID SystemBuffer; } AssociatedIrp; // Thread list entry - allows queueing the IRP to the thread pending I/O // request packet list. LIST_ENTRY ThreadListEntry; // I/O status - final status of operation. IO_STATUS_BLOCK IoStatus; // Requestor mode - mode of the original requestor of this operation. KPROCESSOR_MODE RequestorMode; // Pending returned - TRUE if pending was initially returned as the // status for this packet. BOOLEAN PendingReturned; // Stack state information. CHAR StackCount; CHAR CurrentLocation; // Cancel - packet has been canceled. BOOLEAN Cancel; // Cancel Irql - Irql at which the cancel spinlock was acquired. KIRQL CancelIrql; // ApcEnvironment - Used to save the APC environment at the time that the // packet was initialized. CCHAR ApcEnvironment; // Allocation control flags. UCHAR AllocationFlags; // User parameters. PIO_STATUS_BLOCK UserIosb; PKEVENT UserEvent; union { struct { union { PIO_APC_ROUTINE UserApcRoutine; PVOID IssuingProcess; }; PVOID UserApcContext; } AsynchronousParameters; LARGE_INTEGER AllocationSize; } Overlay; // CancelRoutine - Used to contain the address of a cancel routine supplied // by a device driver when the IRP is in a cancelable state. __volatile PDRIVER_CANCEL CancelRoutine; // Note that the UserBuffer parameter is outside of the stack so that I/O // completion can copy data back into the user's address space without // having to know exactly which service was being invoked. The length // of the copy is stored in the second half of the I/O status block. If // the UserBuffer field is NULL, then no copy is performed. PVOID UserBuffer; // Kernel structures // // The following section contains kernel structures which the IRP needs // in order to place various work information in kernel controller system // queues. Because the size and alignment cannot be controlled, they are // placed here at the end so they just hang off and do not affect the // alignment of other fields in the IRP. union { struct { union { // DeviceQueueEntry - The device queue entry field is used to // queue the IRP to the device driver device queue. KDEVICE_QUEUE_ENTRY DeviceQueueEntry; struct { // The following are available to the driver to use in // whatever manner is desired, while the driver owns the // packet. PVOID DriverContext[4]; } ; } ; // Thread - pointer to caller's Thread Control Block. PETHREAD Thread; // Auxiliary buffer - pointer to any auxiliary buffer that is // required to pass information to a driver that is not contained // in a normal buffer. PCHAR AuxiliaryBuffer; // The following unnamed structure must be exactly identical // to the unnamed structure used in the minipacket header used // for completion queue entries. struct { // List entry - used to queue the packet to completion queue, among others. LIST_ENTRY ListEntry; union { // Current stack location - contains a pointer to the current // IO_STACK_LOCATION structure in the IRP stack. This field // should never be directly accessed by drivers. They should // use the standard functions. struct _IO_STACK_LOCATION *CurrentStackLocation; // Minipacket type. ULONG PacketType; }; }; // Original file object - pointer to the original file object // that was used to open the file. This field is owned by the // I/O system and should not be used by any other drivers. PFILE_OBJECT OriginalFileObject; } Overlay; // APC - This APC control block is used for the special kernel APC as // well as for the caller's APC, if one was specified in the original // argument list. If so, then the APC is reused for the normal APC for // whatever mode the caller was in and the "special" routine that is // invoked before the APC gets control simply deallocates the IRP. KAPC Apc; // CompletionKey - This is the key that is used to distinguish // individual I/O operations initiated on a single file handle. PVOID CompletionKey; } Tail; } IRP, *PIRP;
typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; }; // A common use of the Information field is to hold the total number of bytes transferred // by an operation such as IRP_MJ_READ that transfers data. ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _IO_STACK_LOCATION { UCHAR MajorFunction; UCHAR MinorFunction; UCHAR Flags; UCHAR Control; // The following user parameters are based on the service that is being // invoked. Drivers and file systems can determine which set to use based // on the above major and minor function codes. union { // System service parameters for: NtCreateFile struct { PIO_SECURITY_CONTEXT SecurityContext; ULONG Options; USHORT FileAttributes; USHORT ShareAccess; ULONG EaLength; } Create; // System service parameters for: NtReadFile struct { ULONG Length; ULONG Key; LARGE_INTEGER ByteOffset; } Read; // System service parameters for: NtWriteFile struct { ULONG Length; ULONG Key; LARGE_INTEGER ByteOffset; } Write; // System service parameters for: NtQueryDirectoryFile struct { ULONG Length; PUNICODE_STRING FileName; FILE_INFORMATION_CLASS FileInformationClass; ULONG FileIndex; } QueryDirectory; // System service parameters for: NtNotifyChangeDirectoryFile struct { ULONG Length; ULONG CompletionFilter; } NotifyDirectory; // System service parameters for: NtQueryInformationFile struct { ULONG Length; FILE_INFORMATION_CLASS FileInformationClass; } QueryFile; // System service parameters for: NtSetInformationFile struct { ULONG Length; FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; PFILE_OBJECT FileObject; union { struct { BOOLEAN ReplaceIfExists; BOOLEAN AdvanceOnly; }; ULONG ClusterCount; HANDLE DeleteHandle; }; } SetFile; // System service parameters for: NtQueryEaFile struct { ULONG Length; PVOID EaList; ULONG EaListLength; ULONG EaIndex; } QueryEa; // System service parameters for: NtSetEaFile struct { ULONG Length; } SetEa; // System service parameters for: NtQueryVolumeInformationFile struct { ULONG Length; FS_INFORMATION_CLASS FsInformationClass; } QueryVolume; // System service parameters for: NtSetVolumeInformationFile struct { ULONG Length; FS_INFORMATION_CLASS FsInformationClass; } SetVolume; // System service parameters for: NtFsControlFile // // Note that the user's output buffer is stored in the UserBuffer field // and the user's input buffer is stored in the SystemBuffer field. struct { ULONG OutputBufferLength; ULONG InputBufferLength; ULONG FsControlCode; PVOID Type3InputBuffer; } FileSystemControl; // System service parameters for: NtLockFile/NtUnlockFile struct { PLARGE_INTEGER Length; ULONG POINTER_ALIGNMENT Key; LARGE_INTEGER ByteOffset; } LockControl; // System service parameters for: NtFlushBuffersFile // // No extra user-supplied parameters. // System service parameters for: NtCancelIoFile // No extra user-supplied parameters. // System service parameters for: NtDeviceIoControlFile // Note that the user's output buffer is stored in the UserBuffer field // and the user's input buffer is stored in the SystemBuffer field. struct { ULONG OutputBufferLength; ULONG InputBufferLength; ULONG IoControlCode; PVOID Type3InputBuffer; } DeviceIoControl; // System service parameters for: NtQuerySecurityObject struct { SECURITY_INFORMATION SecurityInformation; ULONG Length; } QuerySecurity; // System service parameters for: NtSetSecurityObject struct { SECURITY_INFORMATION SecurityInformation; PSECURITY_DESCRIPTOR SecurityDescriptor; } SetSecurity; // Non-system service parameters. // // Parameters for MountVolume struct { PVPB Vpb; PDEVICE_OBJECT DeviceObject; } MountVolume; // Parameters for VerifyVolume struct { PVPB Vpb; PDEVICE_OBJECT DeviceObject; } VerifyVolume; // Parameters for Scsi with internal device contorl. struct { struct _SCSI_REQUEST_BLOCK *Srb; } Scsi; // System service parameters for: NtQueryQuotaInformationFile struct { ULONG Length; PSID StartSid; PFILE_GET_QUOTA_INFORMATION SidList; ULONG SidListLength; } QueryQuota; // System service parameters for: NtSetQuotaInformationFile struct { ULONG Length; } SetQuota; // Parameters for IRP_MN_QUERY_DEVICE_RELATIONS struct { DEVICE_RELATION_TYPE Type; } QueryDeviceRelations; // Parameters for IRP_MN_QUERY_INTERFACE struct { CONST GUID *InterfaceType; USHORT Size; USHORT Version; PINTERFACE Interface; PVOID InterfaceSpecificData; } QueryInterface; // Parameters for IRP_MN_QUERY_CAPABILITIES struct { PDEVICE_CAPABILITIES Capabilities; } DeviceCapabilities; // Parameters for IRP_MN_FILTER_RESOURCE_REQUIREMENTS struct { PIO_RESOURCE_REQUIREMENTS_LIST IoResourceRequirementList; } FilterResourceRequirements; // Parameters for IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG struct { ULONG WhichSpace; PVOID Buffer; ULONG Offset; ULONG Length; } ReadWriteConfig; // Parameters for IRP_MN_SET_LOCK struct { BOOLEAN Lock; } SetLock; // Parameters for IRP_MN_QUERY_ID struct { BUS_QUERY_ID_TYPE IdType; } QueryId; // Parameters for IRP_MN_QUERY_DEVICE_TEXT struct { DEVICE_TEXT_TYPE DeviceTextType; LCID LocaleId; } QueryDeviceText; // Parameters for IRP_MN_DEVICE_USAGE_NOTIFICATION struct { BOOLEAN InPath; BOOLEAN Reserved[3]; DEVICE_USAGE_NOTIFICATION_TYPE Type; } UsageNotification; // Parameters for IRP_MN_WAIT_WAKE struct { SYSTEM_POWER_STATE PowerState; } WaitWake; // Parameter for IRP_MN_POWER_SEQUENCE struct { PPOWER_SEQUENCE PowerSequence; } PowerSequence; // Parameters for IRP_MN_SET_POWER and IRP_MN_QUERY_POWER struct { union { ULONG SystemContext; SYSTEM_POWER_STATE_CONTEXT SystemPowerStateContext; }; POWER_STATE_TYPE Type; POWER_STATE State; POWER_ACTION ShutdownType; } Power; struct { ULONG SystemContext; POWER_STATE_TYPE Type; POWER_STATE State; POWER_ACTION ShutdownType; } Power; // Parameters for StartDevice struct { PCM_RESOURCE_LIST AllocatedResources; PCM_RESOURCE_LIST AllocatedResourcesTranslated; } StartDevice; // Parameters for Cleanup // // No extra parameters supplied // WMI Irps struct { ULONG_PTR ProviderId; PVOID DataPath; ULONG BufferSize; PVOID Buffer; } WMI; // Others - driver-specific struct { PVOID Argument1; PVOID Argument2; PVOID Argument3; PVOID Argument4; } Others; } Parameters; // Save a pointer to this device driver's device object for this request // so it can be passed to the completion routine if needed. // IoCallDriver() fills this field. PDEVICE_OBJECT DeviceObject; // The following location contains a pointer to the file object for this // request. PFILE_OBJECT FileObject; // The following routine is invoked depending on the flags in the above flags field. // Use IoSetCompletionRoutine() to set this field. PIO_COMPLETION_ROUTINE CompletionRoutine; // The following is used to store the address of the context parameter // that should be passed to the CompletionRoutine. // Use IoSetCompletionRoutine() to set this field. PVOID Context; } IO_STACK_LOCATION, *PIO_STACK_LOCATION;
#define IRP_MJ_CREATE 0x00#define IRP_MJ_CREATE_NAMED_PIPE 0x01#define IRP_MJ_CLOSE 0x02#define IRP_MJ_READ 0x03#define IRP_MJ_WRITE 0x04#define IRP_MJ_QUERY_INFORMATION 0x05#define IRP_MJ_SET_INFORMATION 0x06#define IRP_MJ_QUERY_EA 0x07#define IRP_MJ_SET_EA 0x08#define IRP_MJ_FLUSH_BUFFERS 0x09#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b#define IRP_MJ_DIRECTORY_CONTROL 0x0c#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d#define IRP_MJ_DEVICE_CONTROL 0x0e#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f#define IRP_MJ_SHUTDOWN 0x10#define IRP_MJ_LOCK_CONTROL 0x11#define IRP_MJ_CLEANUP 0x12#define IRP_MJ_CREATE_MAILSLOT 0x13#define IRP_MJ_QUERY_SECURITY 0x14#define IRP_MJ_SET_SECURITY 0x15#define IRP_MJ_POWER 0x16#define IRP_MJ_SYSTEM_CONTROL 0x17#define IRP_MJ_DEVICE_CHANGE 0x18#define IRP_MJ_QUERY_QUOTA 0x19#define IRP_MJ_SET_QUOTA 0x1a#define IRP_MJ_PNP 0x1b#define IRP_MJ_PNP_POWER IRP_MJ_PNP// Obsolete.... #define IRP_MJ_MAXIMUM_FUNCTION 0x1b
typedef NTSTATUS (*PDRIVER_DISPATCH) ( INstruct _DEVICE_OBJECT *DeviceObject, INstruct _IRP *Irp );
typedef struct _DEVICE_OBJECT { CSHORT Type; USHORT Size; LONG ReferenceCount; struct _DRIVER_OBJECT *DriverObject; struct _DEVICE_OBJECT *NextDevice; struct _DEVICE_OBJECT *AttachedDevice; struct _IRP *CurrentIrp; PIO_TIMER Timer; ULONG Flags; ULONG Characteristics; __volatile PVPB Vpb; PVOID DeviceExtension; DEVICE_TYPE DeviceType; CCHAR StackSize; union { LIST_ENTRY ListEntry; WAIT_CONTEXT_BLOCK Wcb; } Queue; ULONG AlignmentRequirement; KDEVICE_QUEUE DeviceQueue; KDPC Dpc; ULONG ActiveThreadCount; PSECURITY_DESCRIPTOR SecurityDescriptor; KEVENT DeviceLock; USHORT SectorSize; USHORT Spare1; struct _DEVOBJ_EXTENSION *DeviceObjectExtension; PVOID Reserved; } DEVICE_OBJECT;
typedef struct _DRIVER_OBJECT { CSHORT Type; CSHORT Size; // The following links all of the devices created by a single driver together on a list, and the Flags word provides an extensible flag // location for driver objects. PDEVICE_OBJECT DeviceObject; ULONG Flags; // The following section describes where the driver is loaded. The count // field is used to count the number of times the driver has had its // registered reinitialization routine invoked. PVOID DriverStart; ULONG DriverSize; PVOID DriverSection; PDRIVER_EXTENSION DriverExtension; // The driver name field is used by the error log thread // determine the name of the driver that an I/O request is/was bound. UNICODE_STRING DriverName; // The following section is for registry support. Thise is a pointer // to the path to the hardware information in the registry PUNICODE_STRING HardwareDatabase; // The following section contains the optional pointer to an array of // alternate entry points to a driver for "fast I/O" support. Fast I/O // is performed by invokzing the driver routine directly with separate // parameters, rather than using the standard IRP call mechanism. Note // that these functions may only be used for synchronous I/O, and when // the file is cached. PFAST_IO_DISPATCH FastIoDispatch; // The following section describes the entry points to this particular // driver. Note that the major function dispatch table must be the last // field in the object so that it remains extensible. PDRIVER_INITIALIZE DriverInit; PDRIVER_STARTIO DriverStartIo; PDRIVER_UNLOAD DriverUnload; PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; } DRIVER_OBJECT;
typedef struct _DRIVER_EXTENSION { // Back pointer to Driver Object struct _DRIVER_OBJECT *DriverObject; // The AddDevice entry point is called by the Plug & Play manager // to inform the driver when a new device instance arrives that this // driver must control. PDRIVER_ADD_DEVICE AddDevice; // The count field is used to count the number of times the driver has // had its registered reinitialization routine invoked. ULONG Count; // The service name field is used by the pnp manager to determine // where the driver related info is stored in the registry. UNICODE_STRING ServiceKeyName; // Note: any new shared fields get added here. } DRIVER_EXTENSION, *PDRIVER_EXTENSION;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
NTSTATUS IoCreateDevice( IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName OPTIONAL, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject );
typedef struct _MDL {struct _MDL *Next;CSHORT Size;CSHORT MdlFlags;struct _EPROCESS *Process;PVOID MappedSystemVa;PVOID StartVa;ULONG ByteCount;ULONG ByteOffset; }MDL , *PMDL ;
PVOID buf = NULL;PMDL mdl = NULL;NDIS_STATUS ndis_status; ndis_status =NdisAllocateMemoryWithTag (&buf, 1000, 0x1111L); if (ndis_status != NDIS_STATUS_SUCCESS){DbgPrint ("NetVMini : Can not allocate test Memory for MDL.\n"); } else { mdl =IoAllocateMdl (buf, 1000, FALSE, FALSE, NULL); if (mdl != NULL) { MmBuildMdlForNonPagedPool(mdl);DbgPrint ("buf = 0x%p\n", buf);DbgPrint ("MDL.Size = 0x%X\n", mdl->Size);DbgPrint ("MDL.MdlFlags = 0x%X\n", mdl->MdlFlags);DbgPrint ("MDL.MappedSystemVa = 0x%p\n", mdl->MappedSystemVa);DbgPrint ("MDL.StartVa = 0x%p\n", mdl->StartVa);DbgPrint ("MDL.ByteCount = 0x%X\n", mdl->ByteCount);DbgPrint ("MDL.ByteOffset = 0x%X\n", mdl->ByteOffset);IoFreeMdl (mdl); mdl = NULL; }NdisFreeMemory (buf, 1000, 0); }
00000008 0.00103058 buf = 0x85322008 00000009 0.00104175 MDL.Size = 0x20 00000010 0.00104985 MDL.MdlFlags = 0xC 00000011 0.00106243 MDL.MappedSystemVa = 0x85322008 00000012 0.00107919 MDL.StartVa = 0x85322000 00000013 0.00109120 MDL.ByteCount = 0x3E8 00000014 0.00110321 MDL.ByteOffset = 0x8
PMDL IoAllocateMdl ( INPVOID VirtualAddress, INULONG Length, INBOOLEAN SecondaryBuffer, INBOOLEAN ChargeQuota, IN OUTPIRP Irp OPTIONAL );
VOID MmBuildMdlForNonPagedPool ( IN OUTPMDL MemoryDescriptorList );
VOIDIoBuildPartialMdl ( IN PMDL SourceMdl, IN OUT PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length );
VOIDIoFreeMdl ( IN PMDL Mdl );
ULONGMmGetMdlByteCount (IN PMDL Mdl){ return Mdl->ByteCount; }
ULONGMmGetMdlByteOffset (IN PMDL Mdl) { return Mdl->ByteOffset; }
PVOIDMmGetMdlVirtualAddress (IN PMDL Mdl) { return ((PVOID) ((PCHAR) ((Mdl)->StartVa) + (Mdl)->ByteOffset)); }
PVOIDMmGetSystemAddressForMdlSafe (IN PMDL Mdl, IN MM_PAGE_PRIORITY Priority) { if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL)) { return Mdl->MappedSystemVa; } else { return MmMapLockedPagesSpecifyCache(Mdl, KernelMode, MmCached, NULL, FALSE, Priority); } }
VOIDMmInitializeMdl (IN PMDL MemoryDescriptorList, IN PVOID BaseVa, IN SIZE_T Length){ MemoryDescriptorList->Next = (PMDL) NULL; MemoryDescriptorList->Size = (CSHORT)(sizeof(MDL) + sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES((BaseVa), (Length)))); MemoryDescriptorList->MdlFlags = 0; MemoryDescriptorList->StartVa = (PVOID) PAGE_ALIGN((BaseVa)); MemoryDescriptorList->ByteOffset = BYTE_OFFSET((BaseVa)); MemoryDescriptorList->ByteCount = (ULONG)(Length); }
VOIDMmPrepareMdlForReuse (IN PMDL MDL) { if ((MDL->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED) != 0) { MmUnmapLockedPages( MDL->MappedSystemVa, MDL ); } }
VOIDMmProbeAndLockPages ( IN OUT PMDL MemoryDescriptorList, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation );
ULONGMmSizeOfMdl ( IN PVOID Base, IN SIZE_T Length );
VOIDMmUnmapLockedPages ( IN PVOID BaseAddress, IN PMDL MemoryDescriptorList );