1 /*++
2 
3   Copyright (c) Microsoft Corporation
4 
5   Module Name:
6 
7   FxRequestBufferKm.hpp
8 
9   Abstract:
10 
11   This module implements km specific functions for FxRequestBuffer.
12 
13   Author:
14 
15 
16 
17   Environment:
18 
19   Kernel mode only
20 
21   Revision History:
22 
23   --*/
24 
25 #ifndef _FXREQUESTBUFFERKM_HPP_
26 #define _FXREQUESTBUFFERKM_HPP_
27 
28 __inline
29 VOID
30 FxRequestBuffer::SetMdl(
31     __in PMDL Mdl,
32     __in ULONG Length
33     )
34 {
35     DataType = FxRequestBufferMdl;
36     u.Mdl.Mdl = Mdl;
37     u.Mdl.Length = Length;
38 }
39 
40 FORCEINLINE
41 NTSTATUS
42 FxRequestBuffer::GetOrAllocateMdlWorker(
43     __in PFX_DRIVER_GLOBALS FxDriverGlobals,
44     __deref_out PMDL*       Mdl,
45     __in BOOLEAN *          ReuseMdl,
46     __in LONG               Length,
47     __in PVOID              Buffer,
48     __inout size_t*         SizeOfMdl,
49     __in BOOLEAN            UnlockWhenFreed,
50     __deref_out_opt PMDL*   MdlToFree
51         )
52 {
53     size_t sizeofCurrentMdl;
54     sizeofCurrentMdl = MmSizeOfMdl(Buffer, Length);
55 
56     //
57     // Caller of this function (GetOrAllocateMdl) verifies that pages
58     // are already unlocked. Asserting here, in case we start using this
59     // function elsewhere.
60     //
61     // This is why we don't unlock pages either in reuse or non-reuse case.
62     //
63     ASSERT(UnlockWhenFreed == FALSE);
64      UNREFERENCED_PARAMETER(UnlockWhenFreed); //for fre build
65 
66     //
67     // If ReuseMdl is TRUE then the Mdl to be reused is passed in.
68     //
69     if (*ReuseMdl && sizeofCurrentMdl <= *SizeOfMdl) {
70         MmPrepareMdlForReuse(*MdlToFree);
71         *Mdl = *MdlToFree;
72     }
73     else {
74         *ReuseMdl = FALSE;
75 
76         //
77         // Since *Mdl may have the original IRP Mdl
78         // free *MdlToFree and not *Mdl
79         //
80         if (*MdlToFree != NULL) {
81             FxMdlFree(FxDriverGlobals, *MdlToFree);
82             *MdlToFree = NULL;
83              if (SizeOfMdl != NULL) {
84                 *SizeOfMdl = 0;
85             }
86         }
87 
88         *Mdl = FxMdlAllocate(FxDriverGlobals,
89                              NULL, // owning FxObject
90                              Buffer,
91                              Length,
92                              FALSE,
93                              FALSE);
94 
95         if (*Mdl == NULL) {
96 
97             ASSERT(SizeOfMdl ? (*SizeOfMdl == 0) : TRUE);
98 
99             return STATUS_INSUFFICIENT_RESOURCES;
100         }
101 
102         if (SizeOfMdl != NULL) {
103             *SizeOfMdl  = sizeofCurrentMdl;
104         }
105     }
106 
107     return STATUS_SUCCESS;
108 }
109 
110 
111 #endif // _FXREQUESTBUFFERKM_HPP_
112