1 /*++
2 
3 Copyright (c) Microsoft Corporation.  All rights reserved.
4 
5 Module Name:
6 
7     FxIoTargetRemote.hpp
8 
9 Abstract:
10 
11     Derivation of FxIoTarget specializing in targets remote to this device
12     stack.
13 
14 Author:
15 
16 
17 
18 Environment:
19 
20     Both kernel and user mode
21 
22 Revision History:
23 
24 --*/
25 
26 #ifndef _FXIOTARGETREMOTE_H_
27 #define _FXIOTARGETREMOTE_H_
28 
29 enum FxIoTargetRemoteCloseReason {
30     FxIoTargetRemoteCloseReasonQueryRemove = 1,
31     FxIoTargetRemoteCloseReasonPlainClose,
32     FxIoTargetRemoteCloseReasonDelete
33 };
34 
35 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
36 typedef PVOID               MdTargetNotifyHandle;
37 #else
38 typedef WUDF_TARGET_CONTEXT MdTargetNotifyHandle;
39 #endif
40 
41 class FxIoTargetRemoteNotificationCallback;
42 
43 struct FxIoTargetQueryRemove : public FxCallback {
44 
FxIoTargetQueryRemoveFxIoTargetQueryRemove45     FxIoTargetQueryRemove(
46         __in PFX_DRIVER_GLOBALS FxDriverGlobals
47         ) :
48         FxCallback(FxDriverGlobals),
49         m_Method(NULL)
50     {
51     }
52 
53     _Must_inspect_result_
54     NTSTATUS
InvokeFxIoTargetQueryRemove55     Invoke(
56         __in WDFIOTARGET IoTarget
57         )
58     {
59         NTSTATUS status;
60 
61         CallbackStart();
62         status = m_Method(IoTarget);
63         CallbackEnd();
64 
65         return status;
66     }
67 
68     PFN_WDF_IO_TARGET_QUERY_REMOVE  m_Method;
69 };
70 
71 struct FxIoTargetRemoveCanceled : public FxCallback {
72 
FxIoTargetRemoveCanceledFxIoTargetRemoveCanceled73     FxIoTargetRemoveCanceled(
74         __in PFX_DRIVER_GLOBALS FxDriverGlobals
75         ) :
76         FxCallback(FxDriverGlobals),
77         m_Method(NULL)
78     {
79     }
80 
81     VOID
InvokeFxIoTargetRemoveCanceled82     Invoke(
83         __in WDFIOTARGET Target
84         )
85     {
86         CallbackStart();
87         m_Method(Target);
88         CallbackEnd();
89     }
90 
91     PFN_WDF_IO_TARGET_REMOVE_CANCELED  m_Method;
92 };
93 
94 struct FxIoTargetRemoveComplete : public FxCallback {
95 
FxIoTargetRemoveCompleteFxIoTargetRemoveComplete96     FxIoTargetRemoveComplete(
97         __in PFX_DRIVER_GLOBALS FxDriverGlobals
98         ) :
99         FxCallback(FxDriverGlobals),
100         m_Method(NULL)
101     {
102     }
103 
104     VOID
InvokeFxIoTargetRemoveComplete105     Invoke(
106         __in WDFIOTARGET Target
107         )
108     {
109         CallbackStart();
110         m_Method(Target);
111         CallbackEnd();
112     }
113 
114     PFN_WDF_IO_TARGET_REMOVE_COMPLETE m_Method;
115 };
116 
117 enum FxIoTargetRemoteOpenState {
118     FxIoTargetRemoteOpenStateClosed = 1,
119     FxIoTargetRemoteOpenStateOpening,
120     FxIoTargetRemoteOpenStateOpen,
121 };
122 
123 struct FxIoTargetRemoveOpenParams {
124 
FxIoTargetRemoveOpenParamsFxIoTargetRemoveOpenParams125     FxIoTargetRemoveOpenParams()
126     {
127         RtlZeroMemory(this, sizeof(FxIoTargetRemoveOpenParams));
128     }
129 
130     VOID
131     Set(
132         __in PWDF_IO_TARGET_OPEN_PARAMS OpenParams,
133         __in PUNICODE_STRING Name,
134         __in PVOID Ea,
135         __in ULONG EaLength
136         );
137 
138     VOID
139     Clear(
140         VOID
141         );
142 
143     UNICODE_STRING TargetDeviceName;
144 
145     WDF_IO_TARGET_OPEN_TYPE OpenType;
146 
147     ACCESS_MASK DesiredAccess;
148 
149     ULONG ShareAccess;
150 
151     ULONG FileAttributes;
152 
153     ULONG CreateDisposition;
154 
155     ULONG CreateOptions;
156 
157     __field_bcount(EaBufferLength) PVOID EaBuffer;
158 
159     ULONG EaBufferLength;
160 
161     LARGE_INTEGER AllocationSize;
162 
163     PLARGE_INTEGER AllocationSizePointer;
164 
165 };
166 
167 struct FxIoTargetClearedPointers {
168     MdDeviceObject TargetPdo;
169     MdFileObject TargetFileObject;
170     HANDLE TargetHandle;
171 };
172 
173 class FxIoTargetRemote : public FxIoTarget {
174 
175 public:
176 
177     static
178     _Must_inspect_result_
179     NTSTATUS
180     _Create(
181         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
182         __in PWDF_OBJECT_ATTRIBUTES Attributes,
183         __in FxDeviceBase* Device,
184         __out FxIoTargetRemote** Target
185         );
186 
187     ~FxIoTargetRemote();
188 
189     NTSTATUS
190     InitRemote(
191         __in FxDeviceBase* Device
192         );
193 
194     NTSTATUS
195     InitRemoteModeSpecific(
196         __in FxDeviceBase* Device
197         );
198 
199     _Must_inspect_result_
200     NTSTATUS
201     Open(
202         __in PWDF_IO_TARGET_OPEN_PARAMS OpenParams
203         );
204 
205     VOID
206     Close(
207         __in FxIoTargetRemoteCloseReason Reason
208         );
209 
210     NTSTATUS
211     GetTargetDeviceRelations(
212         _Out_ BOOLEAN* Close
213         );
214 
215     BOOLEAN
CanRegisterForPnpNotification(VOID)216     CanRegisterForPnpNotification(
217         VOID
218         )
219     {
220         BOOLEAN canRegister = FALSE;
221 
222 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
223         if (m_TargetFileObject != NULL) {
224             canRegister = TRUE;
225         }
226 #else // FX_CORE_USER_MODE
227         if (m_TargetHandle != NULL) {
228             canRegister = TRUE;
229         }
230 #endif
231         return canRegister;
232     }
233 
234     VOID
ResetTargetNotifyHandle(VOID)235     ResetTargetNotifyHandle(
236         VOID
237         )
238     {
239 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
240     m_TargetNotifyHandle = NULL;
241 #else // FX_CORE_USER_MODE
242     m_TargetNotifyHandle = WUDF_TARGET_CONTEXT_INVALID;
243 #endif
244     }
245 
246     NTSTATUS
247     OpenTargetHandle(
248         _In_ PWDF_IO_TARGET_OPEN_PARAMS OpenParams,
249         _Inout_ FxIoTargetRemoveOpenParams* pParams
250         );
251 
252     VOID
253     CloseTargetHandle(
254         VOID
255         );
256 
257     HANDLE
258     GetTargetHandle(
259         VOID
260         );
261 
262     NTSTATUS
263     RegisterForPnpNotification(
264         VOID
265         );
266 
267     VOID
268     UnregisterForPnpNotification(
269         _In_ MdTargetNotifyHandle Handle
270         );
271 
272     __inline
273     WDFIOTARGET
GetHandle(VOID)274     GetHandle(
275         VOID
276         )
277     {
278         return (WDFIOTARGET) GetObjectHandle();
279     }
280 
281     virtual
282     VOID
283     Remove(
284         VOID
285         );
286 
287     VOID
288     RemoveModeSpecific(
289         VOID
290         );
291 
292 protected:
293     FxIoTargetRemote(
294         __in PFX_DRIVER_GLOBALS FxDriverGlobals
295         );
296 
297     virtual
298     VOID
299     ClearTargetPointers(
300         VOID
301         );
302 
303     _Must_inspect_result_
304     NTSTATUS
QueryInterface(__in FxQueryInterfaceParams * Params)305     QueryInterface(
306         __in FxQueryInterfaceParams* Params
307         )
308     {
309         if (Params->Type == FX_TYPE_IO_TARGET_REMOTE) {
310             *Params->Object = (FxIoTargetRemote*) this;
311             return STATUS_SUCCESS;
312         }
313         else {
314             return FxIoTarget::QueryInterface(Params); // __super call
315         }
316     }
317 
318     _Must_inspect_result_
319     NTSTATUS
320     OpenLocalTargetByFile(
321         _In_ PWDF_IO_TARGET_OPEN_PARAMS OpenParams
322         );
323 
324 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
325     static
326     DRIVER_NOTIFICATION_CALLBACK_ROUTINE
327     _PlugPlayNotification;
328 
329 #else // FX_CORE_USER_MODE
330     //
331     // I/O dispatcher to be used for IRPs forwarded to this remote target. It is
332     // created when the CWdfRemoteTarget is created. The win32 handle is
333     // associated with it via a call to m_pRemoteDispatcher->BindToHandle()
334     // right after we call CreateFile(...). We must call
335     // m_pRemoteDispatcher->CloseHandle() to close the handle.
336     //
337     // Because of the plug-in pattern of the IoDispatcher, we need two
338     // interface pointers (one to the outer object, and one to the plug-in.
339     //
340     IWudfIoDispatcher     * m_pIoDispatcher;
341     IWudfRemoteDispatcher * m_pRemoteDispatcher;
342 
343     //
344     // Implements host's callback interface for pnp notification
345     //
346     FxIoTargetRemoteNotificationCallback* m_NotificationCallback;
347 
348     VOID
Forward(_In_ MdIrp Irp)349     Forward(
350         _In_ MdIrp Irp
351         )
352     {
353         if (m_OpenParams.OpenType == WdfIoTargetOpenLocalTargetByFile) {
354             //
355             // Ignore the return value because once we have sent the request, we
356             // want all processing to be done in the completion routine.
357             //
358             (void) Irp->Forward();
359         }
360         else {
361             IWudfIoIrp* pSubmitIrp = FxIrp(Irp).GetIoIrp();
362 
363             //
364             // Move the stack location to the next location
365             //
366             pSubmitIrp->SetNextIrpStackLocation();
367 
368             //
369             // Route it using Remote dispatcher
370             //
371             m_pIoDispatcher->Dispatch(pSubmitIrp, NULL);
372         }
373     }
374 
375 private:
376 
377     NTSTATUS
378     BindToHandle(
379         VOID
380         );
381 
382     VOID
383     UnbindHandle(
384         _In_ FxIoTargetClearedPointers* TargetPointers
385         );
386 
387     NTSTATUS
388     CreateWdfFileObject(
389         _In_opt_ PUNICODE_STRING  FileName,
390         _Out_ MdFileObject* FileObject
391         );
392 
393     VOID
394     CloseWdfFileObject(
395         _In_ MdFileObject FileObject
396         );
397 
398 #endif // FX_CORE_USER-MODE)
399 
400 public:
401     //
402     // File handle for m_TargetHandle
403     //
404     HANDLE m_TargetHandle;
405 
406     //
407     // Notification handle returned by IoRegisterPlugPlayNotification for KMDF,
408     // or host's notification registartion interface for UMDf. Note that host
409     // uses the term RegistrationId for the same (with WUDF_CONTEXT_TYPE which
410     // is UINT64).
411     //
412     MdTargetNotifyHandle m_TargetNotifyHandle;
413 
414     //
415     // Driver writer callbacks to indicate state changes
416     //
417     FxIoTargetQueryRemove m_EvtQueryRemove;
418     FxIoTargetRemoveCanceled m_EvtRemoveCanceled;
419     FxIoTargetRemoveComplete m_EvtRemoveComplete;
420 
421     FxCREvent m_OpenedEvent;
422 
423     FxIoTargetClearedPointers* m_ClearedPointers;
424 
425     //
426     // Value from FxIoTargetRemoteOpenState
427     //
428     UCHAR m_OpenState;
429 
430 protected:
431     FxIoTargetRemoveOpenParams m_OpenParams;
432 };
433 
434 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
435 #include "fxiotargetremotekm.hpp"
436 #else
437 #include "fxiotargetremoteum.hpp"
438 #endif
439 
440 #endif // _FXIOTARGETREMOTE_H_
441