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