示例#1
0
文件: mdlsup.c 项目: RPG-7/reactos
/*
 * @implemented
 */
PMDL
NTAPI
MmCreateMdl(IN PMDL Mdl,
            IN PVOID Base,
            IN SIZE_T Length)
{
    SIZE_T Size;

    //
    // Check if we don't have an MDL built
    //
    if (!Mdl)
    {
        //
        // Calculate the size we'll need  and allocate the MDL
        //
        Size = MmSizeOfMdl(Base, Length);
        Mdl = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL);
        if (!Mdl) return NULL;
    }

    //
    // Initialize it
    //
    MmInitializeMdl(Mdl, Base, Length);
    return Mdl;
}
FORCEINLINE
NTSTATUS
FxRequestBuffer::GetOrAllocateMdlWorker(
    __in PFX_DRIVER_GLOBALS FxDriverGlobals,
    __deref_out PMDL*       Mdl,
    __in BOOLEAN *          ReuseMdl,
    __in LONG               Length,
    __in PVOID              Buffer,
    __inout size_t*         SizeOfMdl,
    __in BOOLEAN            UnlockWhenFreed,
    __deref_out_opt PMDL*   MdlToFree
        )
{
    size_t sizeofCurrentMdl;
    sizeofCurrentMdl = MmSizeOfMdl(Buffer, Length);
    
    //
    // Caller of this function (GetOrAllocateMdl) verifies that pages
    // are already unlocked. Asserting here, in case we start using this
    // function elsewhere.
    //
    // This is why we don't unlock pages either in reuse or non-reuse case.
    //
    ASSERT(UnlockWhenFreed == FALSE);
     UNREFERENCED_PARAMETER(UnlockWhenFreed); //for fre build

    //
    // If ReuseMdl is TRUE then the Mdl to be reused is passed in.
    //            
    if (*ReuseMdl && sizeofCurrentMdl <= *SizeOfMdl) {
        MmPrepareMdlForReuse(*MdlToFree);
        *Mdl = *MdlToFree;
    }
    else {
        *ReuseMdl = FALSE;

        //
        // Since *Mdl may have the original IRP Mdl 
        // free *MdlToFree and not *Mdl
        //
        if (*MdlToFree != NULL) {                
            FxMdlFree(FxDriverGlobals, *MdlToFree);  
            *MdlToFree = NULL;
             if (SizeOfMdl != NULL) {
                *SizeOfMdl = 0;
            }
        }

        *Mdl = FxMdlAllocate(FxDriverGlobals,
                             NULL, // owning FxObject
                             Buffer,
                             Length,
                             FALSE,
                             FALSE);

        if (*Mdl == NULL) {

            ASSERT(SizeOfMdl ? (*SizeOfMdl == 0) : TRUE);
                
            return STATUS_INSUFFICIENT_RESOURCES;
        }
        
        if (SizeOfMdl != NULL) {
            *SizeOfMdl  = sizeofCurrentMdl;
        }
    }
        
    return STATUS_SUCCESS;
}