1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxObjectUm.cpp
8 
9 Abstract:
10 
11     User mode implementations of FxObject APIs
12 
13 Author:
14 
15 
16 Environment:
17 
18     user mode only
19 
20 Revision History:
21 
22 --*/
23 
24 #include "fxobjectpch.hpp"
25 
26 extern "C" {
27 
28 #if defined(EVENT_TRACING)
29 #include "FxObjectUm.tmh"
30 #endif
31 
32 }
33 
34 extern "C" {
35 
36 #define INITGUID
37 #include <guiddef.h>
38 
39 #include <WdfFileObject_private.h>
40 
41 //
42 // Function declarations for the WdfObjectQuery DDIs
43 //
44 _IRQL_requires_max_(PASSIVE_LEVEL)
45 WDFAPI
46 NTSTATUS
47 WDFEXPORT(WdfFileObjectIncrementProcessKeepAliveCount)(
48     _In_
49     PWDF_DRIVER_GLOBALS DriverGlobals,
50     _In_
51     WDFFILEOBJECT FileObject
52     );
53 
54 _IRQL_requires_max_(PASSIVE_LEVEL)
55 WDFAPI
56 NTSTATUS
57 WDFEXPORT(WdfFileObjectDecrementProcessKeepAliveCount)(
58     _In_
59     PWDF_DRIVER_GLOBALS DriverGlobals,
60     _In_
61     WDFFILEOBJECT FileObject
62     );
63 
64 }
65 
66 
67 extern "C" {
68 
69 _Must_inspect_result_
70 NTSTATUS
71 FxObject::_ObjectQuery(
72     _In_    FxObject* Object,
73     _In_    CONST GUID* Guid,
74     _In_    ULONG QueryBufferLength,
75     _Out_writes_bytes_(QueryBufferLength)
76             PVOID QueryBuffer
77     )
78 
79 /*++
80 
81 Routine Description:
82 
83     Query the object handle for specific information
84 
85     This allows dynamic extensions to DDI's.
86 
87     Currently, it is used to allow test hooks for verification
88     which are not available in a production release.
89 
90 Arguments:
91 
92     Object - Object to query
93 
94     Guid - GUID to represent the information/DDI to query for
95 
96     QueryBufferLength - Length of QueryBuffer to return data in
97 
98     QueryBuffer - Pointer to QueryBuffer
99 
100 Returns:
101 
102     NTSTATUS
103 
104 --*/
105 
106 {
107     PFX_DRIVER_GLOBALS pFxDriverGlobals = Object->GetDriverGlobals();
108 
109     //
110     // Design Note: This interface does not look strongly typed
111     // but it is. The GUID defines a specific strongly typed
112     // contract for QueryBuffer and QueryBufferLength.
113     //
114 
115 #if DBG
116 
117     //
118     // These operations are only available on checked builds for deep unit
119     // testing, code coverage analysis, and model verification.
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133     //
134 
135     // Add code based on the GUID
136 
137     // IsEqualGUID(guid1, guid2), DEFINE_GUID, INITGUID, inc\wnet\guiddef.h
138 #endif
139 
140     if (IsEqualGUID(*Guid, GUID_WDFP_FILEOBJECT_INTERFACE)) {
141 
142         //
143         // Check the query buffer size before performing the cast
144         //
145         const ULONG RequiredBufferLength = sizeof(WDFP_FILEOBJECT_INTERFACE);
146 
147         if (QueryBufferLength < RequiredBufferLength) {
148             DoTraceLevelMessage(
149                 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
150                 "Insufficient query buffer size for file object query "
151                 "Required size %d, %!STATUS!",
152                 RequiredBufferLength,
153                 STATUS_BUFFER_TOO_SMALL);
154             FxVerifierDbgBreakPoint(pFxDriverGlobals);
155             return STATUS_BUFFER_TOO_SMALL;
156         }
157 
158         if (nullptr == QueryBuffer) {
159             DoTraceLevelMessage(
160                 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
161                 "NULL query buffer for file object query, %!STATUS!",
162                 STATUS_BUFFER_TOO_SMALL);
163             FxVerifierDbgBreakPoint(pFxDriverGlobals);
164             return STATUS_INVALID_PARAMETER;
165         }
166 
167         PWDFP_FILEOBJECT_INTERFACE FileObjectInterface =
168             reinterpret_cast<PWDFP_FILEOBJECT_INTERFACE>(QueryBuffer);
169 
170         //
171         // Check the struct version (require an exact match for a private DDI)
172         //
173         if (FileObjectInterface->Size != RequiredBufferLength) {
174             DoTraceLevelMessage(
175                 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
176                 "Wrong struct version provided for file object query, "
177                 "%!STATUS!",
178                 STATUS_INVALID_PARAMETER);
179             FxVerifierDbgBreakPoint(pFxDriverGlobals);
180             return STATUS_INVALID_PARAMETER;
181         }
182 
183         FileObjectInterface->WdfpFileObjectIncrementProcessKeepAliveCount =
184             WDFEXPORT(WdfFileObjectIncrementProcessKeepAliveCount);
185         FileObjectInterface->WdfpFileObjectDecrementProcessKeepAliveCount =
186             WDFEXPORT(WdfFileObjectDecrementProcessKeepAliveCount);
187 
188         return STATUS_SUCCESS;
189     }
190 
191     return STATUS_NOT_FOUND;
192 }
193 
194 } // extern "C"
195