1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxIoTargetRemote.cpp 8 9 Abstract: 10 11 Author: 12 13 Environment: 14 15 Both kernel and user mode 16 17 Revision History: 18 19 --*/ 20 21 #include "../fxtargetsshared.hpp" 22 23 extern "C" { 24 // #include "FxIoTargetRemote.tmh" 25 } 26 27 #include <initguid.h> 28 #include "wdmguid.h" 29 30 31 FxIoTargetRemote::FxIoTargetRemote( 32 __in PFX_DRIVER_GLOBALS FxDriverGlobals 33 ) : 34 FxIoTarget(FxDriverGlobals, sizeof(FxIoTargetRemote)), 35 m_EvtQueryRemove(FxDriverGlobals), 36 m_EvtRemoveCanceled(FxDriverGlobals), 37 m_EvtRemoveComplete(FxDriverGlobals) 38 { 39 40 // 41 // No automatic state changes based on the pnp state changes of our own 42 // device stack. The one exception is remove where we need to shut 43 // everything down. 44 // 45 m_InStack = FALSE; 46 47 m_ClearedPointers = NULL; 48 m_OpenState = FxIoTargetRemoteOpenStateClosed; 49 50 m_TargetHandle = NULL; 51 52 m_EvtQueryRemove.m_Method = NULL; 53 m_EvtRemoveCanceled.m_Method = NULL; 54 m_EvtRemoveComplete.m_Method = NULL; 55 56 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) 57 m_TargetNotifyHandle = NULL; 58 #elif (FX_CORE_MODE == FX_CORE_USER_MODE) 59 m_TargetNotifyHandle = WUDF_TARGET_CONTEXT_INVALID; 60 61 m_pIoDispatcher = NULL; 62 m_pRemoteDispatcher = NULL; 63 m_NotificationCallback = NULL; 64 #endif 65 } 66 67 FxIoTargetRemote::~FxIoTargetRemote() 68 { 69 } 70 71 _Must_inspect_result_ 72 NTSTATUS 73 FxIoTargetRemote::_Create( 74 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 75 __in PWDF_OBJECT_ATTRIBUTES Attributes, 76 __in CfxDeviceBase* Device, 77 __out FxIoTargetRemote** Target 78 ) 79 { 80 FxIoTargetRemote* pTarget; 81 FxObject* pParent; 82 WDFOBJECT hTarget; 83 NTSTATUS status; 84 85 *Target = NULL; 86 87 if (Attributes == NULL || Attributes->ParentObject == NULL) { 88 pParent = Device; 89 } 90 else { 91 CfxDeviceBase* pSearchDevice; 92 93 FxObjectHandleGetPtr(FxDriverGlobals, 94 Attributes->ParentObject, 95 FX_TYPE_OBJECT, 96 (PVOID*) &pParent); 97 98 pSearchDevice = FxDeviceBase::_SearchForDevice(pParent, NULL); 99 100 if (pSearchDevice == NULL) { 101 status = STATUS_INVALID_DEVICE_REQUEST; 102 103 DoTraceLevelMessage( 104 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 105 "Attributes->ParentObject 0x%p must have WDFDEVICE as an " 106 "eventual ancestor, %!STATUS!", 107 Attributes->ParentObject, status); 108 109 return status; 110 } 111 else if (pSearchDevice != Device) { 112 status = STATUS_INVALID_DEVICE_REQUEST; 113 114 DoTraceLevelMessage( 115 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 116 "Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but " 117 "not the same WDFDEVICE 0x%p passed to WdfIoTargetCreate, " 118 "%!STATUS!", 119 Attributes->ParentObject, pSearchDevice->GetHandle(), 120 Device->GetHandle(), status); 121 122 return status; 123 } 124 } 125 126 pTarget = new (FxDriverGlobals, Attributes) 127 FxIoTargetRemote(FxDriverGlobals); 128 129 if (pTarget == NULL) { 130 status = STATUS_INSUFFICIENT_RESOURCES; 131 DoTraceLevelMessage( 132 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 133 "Could not allocate memory for target, %!STATUS!", status); 134 return status; 135 } 136 137 // 138 // initialize the new target 139 // 140 status = pTarget->InitRemote(Device); 141 if (!NT_SUCCESS(status)) { 142 return status; 143 } 144 145 // 146 // Commit and apply the attributes 147 // 148 status = pTarget->Commit(Attributes, &hTarget, pParent); 149 150 if (NT_SUCCESS(status)) { 151 *Target = pTarget; 152 } 153 else { 154 // 155 // This will properly clean up the target's state and free it 156 // 157 DoTraceLevelMessage( 158 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 159 "Commit failed for target, %!STATUS!", status); 160 pTarget->DeleteFromFailedCreate(); 161 } 162 163 return status; 164 } 165 166 NTSTATUS 167 FxIoTargetRemote::InitRemote( 168 __in FxDeviceBase* Device 169 ) 170 { 171 NTSTATUS status; 172 173 // 174 // do the base class mode-specific initialization 175 // 176 status = FxIoTarget::InitModeSpecific(Device); // __super call 177 if (!NT_SUCCESS(status)) { 178 return status; 179 } 180 181 // 182 // Do mode-specific initilialization 183 // 184 status = InitRemoteModeSpecific(Device); 185 if (!NT_SUCCESS(status)) { 186 return status; 187 } 188 189 m_Driver = Device->GetDriver(); 190 191 SetDeviceBase(Device); 192 m_InStackDevice = Device->GetDeviceObject(); 193 194 (void) Device->AddIoTarget(this); 195 196 return STATUS_SUCCESS; 197 } 198 199 _Must_inspect_result_ 200 NTSTATUS 201 FxIoTargetRemote::Open( 202 __in PWDF_IO_TARGET_OPEN_PARAMS OpenParams 203 ) 204 { 205 FxIoTargetRemoveOpenParams params, *pParams; 206 UNICODE_STRING name; 207 LIST_ENTRY pended; 208 WDF_IO_TARGET_OPEN_TYPE type; 209 NTSTATUS status; 210 BOOLEAN close, reopen; 211 PVOID pEa; 212 ULONG eaLength; 213 KIRQL irql; 214 215 RtlZeroMemory(&name, sizeof(name)); 216 close = FALSE; 217 reopen = OpenParams->Type == WdfIoTargetOpenReopen ? TRUE : FALSE; 218 219 pEa = NULL; 220 eaLength = 0; 221 222 // 223 // We only support reopening using stored settings when we open by name 224 // 225 if (reopen && m_OpenParams.OpenType != WdfIoTargetOpenByName) { 226 status = STATUS_INVALID_DEVICE_REQUEST; 227 DoTraceLevelMessage( 228 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 229 "Reopen only supported if the open type is WdfIoTargetOpenByName WDFIOTARGET %p %!STATUS!", 230 GetObjectHandle(), status); 231 return status; 232 } 233 234 // 235 // Must preallocate all settings now 236 // 237 if (reopen) { 238 // 239 // convert the type into the type used for the previous open 240 // 241 type = m_OpenParams.OpenType; 242 pParams = &m_OpenParams; 243 } 244 else { 245 type = OpenParams->Type; 246 pParams = ¶ms; 247 248 if (OpenParams->Type == WdfIoTargetOpenByName) { 249 250 status = FxDuplicateUnicodeString(GetDriverGlobals(), 251 &OpenParams->TargetDeviceName, 252 &name); 253 if (!NT_SUCCESS(status)) { 254 DoTraceLevelMessage( 255 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 256 "Could not allocate memory for target name for WDFIOTARGET %p", 257 GetObjectHandle()); 258 goto Done; 259 } 260 if (OpenParams->EaBuffer != NULL && OpenParams->EaBufferLength > 0) { 261 262 pEa = FxPoolAllocate(GetDriverGlobals(), 263 PagedPool, 264 OpenParams->EaBufferLength); 265 266 if (pEa == NULL) { 267 DoTraceLevelMessage( 268 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 269 "Could not allocate memory for target name " 270 "for WDFIOTARGET %p", GetObjectHandle()); 271 status = STATUS_INSUFFICIENT_RESOURCES; 272 goto Done; 273 } 274 else { 275 eaLength = OpenParams->EaBufferLength; 276 RtlCopyMemory(pEa, OpenParams->EaBuffer, eaLength); 277 } 278 } 279 } 280 } 281 282 Lock(&irql); 283 284 if (m_State == WdfIoTargetDeleted) { 285 DoTraceLevelMessage( 286 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 287 "Opening WDFIOTARGET %p which is removed, state %d", 288 GetObjectHandle(), m_State); 289 status = STATUS_INVALID_DEVICE_STATE; 290 } 291 else if (m_OpenState != FxIoTargetRemoteOpenStateClosed) { 292 // 293 // We are either open or are opening 294 // 295 DoTraceLevelMessage( 296 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 297 "Opening an already open WDFIOTARGET %p, open state %d", 298 GetObjectHandle(), m_OpenState); 299 status = STATUS_INVALID_DEVICE_STATE; 300 } 301 else { 302 DoTraceLevelMessage( 303 GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 304 "Opening WDFIOTARGET %p", GetObjectHandle()); 305 306 // 307 // Clear the event so that if something is waiting on the state 308 // transition, they will block until we are done. 309 // 310 m_OpenedEvent.Clear(); 311 312 m_OpenState = FxIoTargetRemoteOpenStateOpening; 313 status = STATUS_SUCCESS; 314 } 315 Unlock(irql); 316 317 if (!NT_SUCCESS(status)) { 318 goto Done; 319 } 320 321 ASSERT(m_TargetFileObject == NULL); 322 ASSERT(m_TargetDevice == NULL); 323 ASSERT(m_TargetPdo == NULL); 324 ASSERT(m_TargetHandle == NULL); 325 326 // 327 // m_TargetNotifyHandle can be a valid value if the caller has previously 328 // opened the target, received a query remove, then a cancel remove, and 329 // is now reopening the target. 330 // 331 UnregisterForPnpNotification(m_TargetNotifyHandle); 332 ResetTargetNotifyHandle(); 333 334 // 335 // Only clear the open parameters if we are not attempting a reopen. 336 // 337 if (reopen == FALSE) { 338 m_OpenParams.Clear(); 339 } 340 341 switch (type) { 342 case WdfIoTargetOpenUseExistingDevice: 343 KMDF_ONLY_CODE_PATH_ASSERT(); 344 345 // 346 // OpenParams must be non NULL b/c we can't reopen a target with a 347 // previous device object. 348 // 349 ASSERT(OpenParams->Type == WdfIoTargetOpenUseExistingDevice); 350 351 m_TargetDevice = (MdDeviceObject) OpenParams->TargetDeviceObject; 352 m_TargetFileObject = (MdFileObject) OpenParams->TargetFileObject; 353 m_TargetHandle = NULL; 354 355 // 356 // By taking a manual reference here, we simplify the code in 357 // FxIoTargetRemote::Close where we can assume there is an outstanding 358 // reference on the PFILE_OBJECT at all times as long as we have a non 359 // NULL pointer. 360 // 361 if (m_TargetFileObject != NULL) { 362 Mx::MxReferenceObject(m_TargetFileObject); 363 } 364 365 status = STATUS_SUCCESS; 366 367 break; 368 369 case WdfIoTargetOpenLocalTargetByFile: 370 UMDF_ONLY_CODE_PATH_ASSERT(); 371 372 status = OpenLocalTargetByFile(OpenParams); 373 break; 374 375 case WdfIoTargetOpenByName: 376 // 377 // Only capture the open parameters if we are not reopening. 378 // 379 if (reopen == FALSE) { 380 pParams->Set(OpenParams, &name, pEa, eaLength); 381 } 382 383 status = OpenTargetHandle(OpenParams, pParams); 384 if (NT_SUCCESS(status)) { 385 if (reopen == FALSE) { 386 m_OpenParams.Set(OpenParams, &name, pEa, eaLength); 387 388 // 389 // Setting pEa to NULL stops it from being freed later. 390 // Zeroing out name stops it from being freed later. 391 // 392 pEa = NULL; 393 RtlZeroMemory(&name, sizeof(name)); 394 } 395 } 396 else { 397 close = TRUE; 398 } 399 break; 400 } 401 402 InitializeListHead(&pended); 403 404 // 405 // Get Target file object for KMDF. Noop for UMDF. 406 // 407 if (NT_SUCCESS(status)) { 408 status = GetTargetDeviceRelations(&close); 409 } 410 411 if (NT_SUCCESS(status) && CanRegisterForPnpNotification()) { 412 if (reopen == FALSE) { 413 // 414 // Set the values before the register so that if a notification 415 // comes in before the register returns, we have a function to call. 416 // 417 m_EvtQueryRemove.m_Method = OpenParams->EvtIoTargetQueryRemove; 418 m_EvtRemoveCanceled.m_Method = OpenParams->EvtIoTargetRemoveCanceled; 419 m_EvtRemoveComplete.m_Method = OpenParams->EvtIoTargetRemoveComplete; 420 } 421 422 status = RegisterForPnpNotification(); 423 424 // 425 // Even if we can't register, we still are successful in opening 426 // up the device and we will proceed from there. 427 // 428 if (!NT_SUCCESS(status)) { 429 DoTraceLevelMessage( 430 GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 431 "WDFIOTARGET %p, could not register pnp notification, %!STATUS! not " 432 "treated as an error", GetObjectHandle(), status); 433 434 m_EvtQueryRemove.m_Method = NULL; 435 m_EvtRemoveCanceled.m_Method = NULL; 436 m_EvtRemoveComplete.m_Method = NULL; 437 438 status = STATUS_SUCCESS; 439 } 440 } 441 442 // 443 // UMDF only. Bind handle to remote dispatcher. 444 // 445 #if (FX_CORE_MODE == FX_CORE_USER_MODE) 446 if (NT_SUCCESS(status) && type != WdfIoTargetOpenLocalTargetByFile) { 447 status = BindToHandle(); 448 if (!NT_SUCCESS(status)) { 449 close = TRUE; 450 } 451 } 452 #endif 453 454 Lock(&irql); 455 456 if (NT_SUCCESS(status)) { 457 458 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) 459 m_TargetStackSize = m_TargetDevice->StackSize; 460 m_TargetIoType = GetTargetIoType(); 461 #endif 462 463 m_OpenState = FxIoTargetRemoteOpenStateOpen; 464 465 // 466 // Set our state to started. This will also resend any pended requests 467 // due to a query remove. 468 // 469 status = GotoStartState(&pended, FALSE); 470 471 // 472 // We could not successfully start, close back down 473 // 474 if (!NT_SUCCESS(status)) { 475 DoTraceLevelMessage( 476 GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 477 "WDFIOTARGET %p could not transition to started state, %!STATUS!", 478 GetObjectHandle(), status); 479 480 close = TRUE; 481 } 482 } 483 else { 484 m_OpenState = FxIoTargetRemoteOpenStateClosed; 485 } 486 487 // 488 // No matter what, indicate to any waiters that our state change has 489 // completed. 490 // 491 m_OpenedEvent.Set(); 492 493 Unlock(irql); 494 495 Done: 496 // 497 // Resubmit any reads that were pended until now. 498 // 499 if (NT_SUCCESS(status)) { 500 SubmitPendedRequests(&pended); 501 } 502 else if (close) { 503 Close(FxIoTargetRemoteCloseReasonPlainClose); 504 } 505 506 if (name.Buffer != NULL) { 507 FxPoolFree(name.Buffer); 508 } 509 510 if (pEa != NULL) { 511 FxPoolFree(pEa); 512 } 513 514 return status; 515 } 516 517 518 VOID 519 FxIoTargetRemote::Close( 520 __in FxIoTargetRemoteCloseReason Reason 521 ) 522 { 523 FxIoTargetClearedPointers pointers; 524 MdTargetNotifyHandle pNotifyHandle; 525 SINGLE_LIST_ENTRY sent; 526 LIST_ENTRY pended; 527 WDF_IO_TARGET_STATE removeState; 528 KIRQL irql; 529 BOOLEAN wait; 530 PFX_DRIVER_GLOBALS pFxDriverGlobals; 531 532 pFxDriverGlobals = GetDriverGlobals(); 533 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 534 "enter: WDFIOTARGET %p, reason %d", GetObjectHandle(), Reason); 535 536 RtlZeroMemory(&pointers, sizeof(pointers)); 537 pNotifyHandle = NULL; 538 539 sent.Next = NULL; 540 InitializeListHead(&pended); 541 542 wait = FALSE; 543 544 // 545 // Pick a value that is not used anywhere in the function and make sure that 546 // we have changed it, before we go to the Remove state 547 // 548 #pragma prefast(suppress: __WARNING_UNUSED_SCALAR_ASSIGNMENT, "PFD is warning that the following assignement is unused. Suppress it to prevent changing any logic.") 549 removeState = WdfIoTargetStarted; 550 551 CheckState: 552 Lock(&irql); 553 554 // 555 // If we are in the process of opening the target, wait for that to finish. 556 // 557 if (m_OpenState == FxIoTargetRemoteOpenStateOpening) { 558 Unlock(irql); 559 560 DoTraceLevelMessage( 561 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 562 "Closing WDFIOTARGET %p which is opening, waiting on event %p", 563 GetObjectHandle(), m_OpenedEvent.GetEvent()); 564 565 m_OpenedEvent.EnterCRAndWaitAndLeave(); 566 567 // 568 // Jump back to the top and recheck 569 // 570 goto CheckState; 571 } 572 573 if (Reason == FxIoTargetRemoteCloseReasonDelete) { 574 DoTraceLevelMessage( 575 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 576 "Closing WDFIOTARGET %p, reason: delete", GetObjectHandle()); 577 578 removeState = WdfIoTargetDeleted; 579 } 580 else if (m_OpenState == FxIoTargetRemoteOpenStateOpen) { 581 if (Reason == FxIoTargetRemoteCloseReasonQueryRemove) { 582 DoTraceLevelMessage( 583 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 584 "Closing WDFIOTARGET %p, reason: query remove", 585 GetObjectHandle()); 586 // 587 // Not really being removed, but that is what the API name is... 588 // 589 removeState = WdfIoTargetClosedForQueryRemove; 590 } 591 else { 592 593 DoTraceLevelMessage( 594 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 595 "Closing WDFIOTARGET %p, reason: close", GetObjectHandle()); 596 597 if (pFxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,9)) { 598 removeState = WdfIoTargetClosed; 599 } 600 else { 601 removeState = WdfIoTargetClosedForQueryRemove; 602 } 603 } 604 605 // 606 // Either way, we are no longer open for business 607 // 608 m_OpenState = FxIoTargetRemoteOpenStateClosed; 609 } 610 else { 611 DoTraceLevelMessage( 612 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 613 "Closing WDFIOTARGET %p which is not open", GetObjectHandle()); 614 615 // 616 // We are not opened, so treat this as a cleanup 617 // 618 removeState = WdfIoTargetClosed; 619 } 620 621 DoTraceLevelMessage( 622 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 623 "WDFIOTARGET %p: fileobj %p, devobj %p, handle %p, notify handle %I64d", 624 GetObjectHandle(), m_TargetFileObject, 625 m_TargetDevice, m_TargetHandle, (UINT64)m_TargetNotifyHandle); 626 627 if (Reason != FxIoTargetRemoteCloseReasonQueryRemove) { 628 // 629 // If we are closing for a query remove, we want to keep the handle 630 // around so that we can be notified of the final close or if the close 631 // was canceled. 632 // 633 pNotifyHandle = m_TargetNotifyHandle; 634 ResetTargetNotifyHandle(); 635 } 636 637 ASSERT(removeState != WdfIoTargetStarted); 638 m_ClearedPointers = &pointers; 639 GotoRemoveState(removeState, &pended, &sent, FALSE, &wait); 640 641 Unlock(irql); 642 643 UnregisterForPnpNotification(pNotifyHandle); 644 645 // 646 // Complete any requests we might have pulled off of our lists 647 // 648 CompletePendedRequestList(&pended); 649 _CancelSentRequests(&sent); 650 651 // 652 // We were just removed, wait for any I/O to complete back if necessary. 653 // 654 if (wait) { 655 DoTraceLevelMessage( 656 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 657 "WDFIOTARGET %p, waiting for stop to complete", GetObjectHandle()); 658 659 WaitForSentIoToComplete(); 660 } 661 662 switch (Reason) { 663 case FxIoTargetRemoteCloseReasonQueryRemove: 664 // 665 // m_OpenParams is needed for reopen on canceled query remove 666 // 667 DO_NOTHING(); 668 break; 669 670 case FxIoTargetRemoteCloseReasonDelete: 671 m_OpenParams.Clear(); 672 break; 673 674 default: 675 // 676 // If this object is not about to be deleted, we need to revert some 677 // of the state that just changed. 678 // 679 m_SentIoEvent.Clear(); 680 break; 681 } 682 683 if (removeState == WdfIoTargetDeleted) { 684 WaitForDisposeEvent(); 685 } 686 687 // 688 // Finally, close down our handle and pointers 689 // 690 if (pointers.TargetPdo != NULL) { 691 DoTraceLevelMessage( 692 pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGIOTARGET, 693 "WDFIOTARGET %p derefing PDO %p on close", 694 GetObjectHandle(), pointers.TargetPdo); 695 696 Mx::MxDereferenceObject(pointers.TargetPdo); 697 } 698 699 if (pointers.TargetFileObject != NULL) { 700 DoTraceLevelMessage( 701 pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGIOTARGET, 702 "WDFIOTARGET %p derefing FileObj %p on close", 703 GetObjectHandle(), pointers.TargetFileObject); 704 Mx::MxDereferenceObject(pointers.TargetFileObject); 705 706 #if (FX_CORE_MODE == FX_CORE_USER_MODE) 707 CloseWdfFileObject(pointers.TargetFileObject); 708 #endif 709 } 710 711 #if (FX_CORE_MODE == FX_CORE_USER_MODE) 712 UnbindHandle(&pointers); 713 #endif 714 715 if (pointers.TargetHandle != NULL) { 716 DoTraceLevelMessage( 717 pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGIOTARGET, 718 "WDFIOTARGET %p closing handle %p on close", 719 GetObjectHandle(), pointers.TargetHandle); 720 Mx::MxClose(pointers.TargetHandle); 721 } 722 } 723 724 VOID 725 FxIoTargetRemote::ClearTargetPointers( 726 VOID 727 ) 728 { 729 DoTraceLevelMessage( 730 GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGIOTARGET, 731 "WDFIOTARGET %p cleared pointers %p state %!WDF_IO_TARGET_STATE!," 732 " open state %d, pdo %p, fileobj %p, handle %p", 733 GetObjectHandle(), m_ClearedPointers, m_State, m_OpenState, m_TargetPdo, 734 m_TargetFileObject, m_TargetHandle); 735 736 // 737 // Check to see if the caller who is changing state wants these pointer 738 // values before they being cleared out. 739 // 740 if (m_ClearedPointers != NULL) { 741 m_ClearedPointers->TargetPdo = m_TargetPdo; 742 m_ClearedPointers->TargetFileObject = m_TargetFileObject; 743 m_ClearedPointers->TargetHandle = m_TargetHandle; 744 m_ClearedPointers = NULL; 745 } 746 747 // 748 // m_TargetHandle is only an FxIoTargetRemote field, clear it now 749 // 750 m_TargetHandle = NULL; 751 752 // 753 // m_TargetPdo and m_TargetFileObject will be cleared in the following call. 754 // 755 // m_TargetNotifyHandle is not cleared in the following call and is left 756 // valid because we want to receive the notification about query remove being 757 // canceled or completing. When we receive either of those notifications, 758 // m_TargetNotifyHandle will be freed then. 759 // 760 FxIoTarget::ClearTargetPointers(); // __super call 761 } 762 763 VOID 764 FxIoTargetRemote::Remove( 765 VOID 766 ) 767 { 768 // 769 // Close is the same as remove in this object 770 // 771 Close(FxIoTargetRemoteCloseReasonDelete); 772 773 // 774 // Do mode-specific work 775 // 776 RemoveModeSpecific(); 777 778 return ; 779 } 780 781 VOID 782 FxIoTargetRemoveOpenParams::Clear( 783 VOID 784 ) 785 { 786 if (EaBuffer != NULL) { 787 FxPoolFree(EaBuffer); 788 } 789 790 if (TargetDeviceName.Buffer != NULL) { 791 FxPoolFree(TargetDeviceName.Buffer); 792 } 793 794 RtlZeroMemory(this, sizeof(FxIoTargetRemoveOpenParams)); 795 } 796 797 VOID 798 FxIoTargetRemoveOpenParams::Set( 799 __in PWDF_IO_TARGET_OPEN_PARAMS OpenParams, 800 __in PUNICODE_STRING Name, 801 __in PVOID Ea, 802 __in ULONG EaLength 803 ) 804 { 805 OpenType = WdfIoTargetOpenByName; 806 807 EaBuffer = Ea; 808 EaBufferLength = EaLength; 809 810 RtlCopyMemory(&TargetDeviceName, Name, sizeof(UNICODE_STRING)); 811 812 DesiredAccess = OpenParams->DesiredAccess; 813 FileAttributes = OpenParams->FileAttributes; 814 ShareAccess = OpenParams->ShareAccess; 815 CreateDisposition = OpenParams->CreateDisposition; 816 CreateOptions = OpenParams->CreateOptions; 817 818 if (OpenParams->AllocationSize != NULL) { 819 AllocationSize.QuadPart = *(OpenParams->AllocationSize); 820 AllocationSizePointer = &AllocationSize; 821 } 822 else { 823 AllocationSizePointer = NULL; 824 } 825 } 826