Reactos
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxObjectUm.cpp
8
9Abstract:
10
11 User mode implementations of FxObject APIs
12
13Author:
14
15
16Environment:
17
18 user mode only
19
20Revision History:
21
22--*/
23
24#include "fxobjectpch.hpp"
25
26extern "C" {
27
28#if defined(EVENT_TRACING)
29#include "FxObjectUm.tmh"
30#endif
31
32}
33
34extern "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)
45WDFAPI
46NTSTATUS
47WDFEXPORT(WdfFileObjectIncrementProcessKeepAliveCount)(
48 _In_
49 PWDF_DRIVER_GLOBALS DriverGlobals,
50 _In_
51 WDFFILEOBJECT FileObject
52 );
53
54_IRQL_requires_max_(PASSIVE_LEVEL)
55WDFAPI
56NTSTATUS
57WDFEXPORT(WdfFileObjectDecrementProcessKeepAliveCount)(
58 _In_
59 PWDF_DRIVER_GLOBALS DriverGlobals,
60 _In_
61 WDFFILEOBJECT FileObject
62 );
63
64}
65
66
67extern "C" {
68
69_Must_inspect_result_
70NTSTATUS
71FxObject::_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
81Routine 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
90Arguments:
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
100Returns:
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"