Пример #1
0
 WDFINTERRUPT
 GetHandle(
     VOID
     )
 {
     return (WDFINTERRUPT) GetObjectHandle();
 }
Пример #2
0
BOOL CEngineEffect::Init(char* filename,CObjectBase* pObject)
{
	m_CurMotionNum = -1;
	m_bMotionPause = FALSE;
	m_pObject = pObject;

	DIRECTORYMGR->SetLoadMode(eLM_Effect);
	m_GXOHandle = GetObjectHandle(filename,MHEffectPROC,this,GXOBJECT_CREATE_TYPE_EFFECT);
	strcpy(m_ObjectName,filename);

	if(m_GXOHandle == NULL)
	{		
		char temp[256];
		sprintf(temp,"¿ÀºêÁ§Æ® »ý¼º ½ÇÆÐ : %s",filename);
		MessageBox(NULL,temp,NULL,NULL);
		DIRECTORYMGR->SetLoadMode(eLM_Root);
		return FALSE;		
	}
	
	//g_pExecutive->DisablePick(m_GXOHandle);
	//EnableShadow(FALSE);
	
	m_AniInfo = new ANIINFO[2];

	for(WORD n=0;n<2;++n)
	{
		m_AniInfo[n].EngineMotionIndex = n;
		m_AniInfo[n].StartFrame = 0;
		m_AniInfo[n].EndFrame = USHRT_MAX;
	}

	DIRECTORYMGR->SetLoadMode(eLM_Root);
	return TRUE;
}
 WDFCHILDLIST
 GetHandle(
     VOID
     )
 {
     return (WDFCHILDLIST) GetObjectHandle();
 }
Пример #4
0
 __forceinline
 WDFDMAENABLER
 GetHandle(
     VOID
     )
 {
     return (WDFDMAENABLER) GetObjectHandle();
 }
Пример #5
0
 FORCEINLINE
 WDFFILEOBJECT
 GetHandle(
     VOID
     )
 {
     return (WDFFILEOBJECT) GetObjectHandle();
 }
 FORCEINLINE
 WDFDRIVER
 GetHandle(
     VOID
     )
 {
     return (WDFDRIVER) GetObjectHandle();
 }
_Must_inspect_result_
NTSTATUS
FxIoTarget::InitModeSpecific(
    __in CfxDeviceBase* Device
    )
{
    NTSTATUS status;

    //
    // FxCREvent can fail in UMDF so it is initialized outside of constuctor 
    // for UMDF. It always succeeds for KMDF so it gets initialized in 
    // event's constructor.
    //
    
    status = m_SentIoEvent.Initialize(SynchronizationEvent, FALSE);
    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR,
                            TRACINGIOTARGET,
                            "Could not initialize m_SentIoEvent event for "
                            "WFIOTARGET %p, %!STATUS!", 
                            GetObjectHandle(), status);
        return status;
    }

    status = m_DisposeEventUm.Initialize();
    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR,
                            TRACINGIOTARGET,
                            "Could not initialize m_DisposeEventUm event for "
                            "WFIOTARGET %p, %!STATUS!", 
                            GetObjectHandle(), status);
        return status;
    }

    return STATUS_SUCCESS;
}
logical pc_ADK_Button :: SetupButton ( )
{
  PropertyHandle         *pbc   = GetParentProperty();
  char                   *names = NULL;
  logical                 term = NO;
  DBObjectHandle          dbo;
  names = strdup(GPH("sys_ident")->GetString());

  SetupFromParent();
  *GPH("auto_open") = YES;
  dbo = GetObjectHandle();
  PropertyHandle   buttons(dbo,"ADK_EventActionControl",PI_Read);  
  PropertyHandle   ph_default("_default");
  if ( buttons(*GPH("sys_ident")) || buttons.Get(ph_default) )
    GPH("button_control")->Add(buttons.ExtractKey());
  return(term);
}
logical pc_ADK_Field :: SetupColumn ( )
{
  PropertyHandle        *pfc = GetParentProperty();
  PropertyHandle        *my_class  = pfc->GPH("class");
  PropertyHandle        *member;
  logical                coll_opt;
  char                  *type;
  char                  *propnames = NULL;
  logical                term = NO;
BEGINSEQ
  if ( IsInitialized() )                             LEAVESEQ
  
  propnames = strdup(GPH("sys_ident")->GetString());
  if ( !my_class->Get(FIRST_INSTANCE) )              ERROR
    
  pc_ADK_Class   structure(*my_class);  
  if ( member = structure.GetMember(propnames) )
    coll_opt = pc0_SDB_Member(member).IsMultipleRef() ? YES : NO;
  else
  {
    pc_ADK_Class  all_class(GetObjectHandle(),PI_Read);  
    PropertyHandle phpropnames(propnames);
    if ( all_class.Get(phpropnames) )
    {
      type     = "DRT_Extent";
      coll_opt = YES;
    }
  }

  *GPH("auto_open") = YES;
  *GPH("size.oszwdth") = -1;
  *GPH("size.oszhgth") = 20;
  SetupDataSource(propnames,type,coll_opt);
  SetupTitle(propnames);

RECOVER
  term = YES;
ENDSEQ
  if ( propnames )
    free(propnames);
  return(term);
}
VOID
FxIoTargetRemote::ClearTargetPointers(
    VOID
    )
{
    DoTraceLevelMessage(
        GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGIOTARGET,
        "WDFIOTARGET %p cleared pointers %p state %!WDF_IO_TARGET_STATE!,"
        " open state %d, pdo %p, fileobj %p, handle %p",
        GetObjectHandle(), m_ClearedPointers, m_State, m_OpenState, m_TargetPdo,
        m_TargetFileObject, m_TargetHandle);

    //
    // Check to see if the caller who is changing state wants these pointer
    // values before they being cleared out.
    //
    if (m_ClearedPointers != NULL) {
        m_ClearedPointers->TargetPdo = m_TargetPdo;
        m_ClearedPointers->TargetFileObject = m_TargetFileObject;
        m_ClearedPointers->TargetHandle = m_TargetHandle;
        m_ClearedPointers = NULL;
    }

    //
    // m_TargetHandle is only an FxIoTargetRemote field, clear it now
    //
    m_TargetHandle = NULL;

    //
    // m_TargetPdo and m_TargetFileObject will be cleared in the following call.
    //
    // m_TargetNotifyHandle is not cleared in the following call and is left
    // valid because we want to receive the notification about query remove being
    // canceled or completing.  When we receive either of those notifications,
    // m_TargetNotifyHandle will be freed then.
    //
    __super::ClearTargetPointers();
}
logical pc_ADK_EventAction :: Setup ( )
{
  char                   *names = NULL;
  logical                 term = NO;
  names = strdup(GPH("sys_ident")->GetString());
  PropertyHandle *pphAllign = GPH("allign");
  pc_ADK_Allign(pphAllign).Setup(NO,NO);
  *GPH("auto_open") = YES;
  
  PropertyHandle   actions(GetObjectHandle(),"ADK_EventActionControl",PI_Read);  
  PropertyHandle ph_default("_default");
  if ( actions(*GPH("sys_ident")) || actions.Get(ph_default) )
    GPH("action_control")->Add(actions.ExtractKey());
  else
  {
    *GPH("default_action.action_type") = "ACT_Function";
    
    *names = toupper(*names);
    STRExchange(names,"_"," ",UNDEF);
    *GPH("text_definitions.title") = names;
    
  }
  return(term);
}
VOID
FxIoTargetRemote::Close(
    __in FxIoTargetRemoteCloseReason Reason
    )
{
    FxIoTargetClearedPointers pointers;
    MdTargetNotifyHandle pNotifyHandle;
    SINGLE_LIST_ENTRY sent;
    LIST_ENTRY pended;
    WDF_IO_TARGET_STATE removeState;
    KIRQL irql;
    BOOLEAN wait;
    PFX_DRIVER_GLOBALS pFxDriverGlobals;

    pFxDriverGlobals = GetDriverGlobals();
    DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
        "enter:  WDFIOTARGET %p, reason %d", GetObjectHandle(), Reason);

    RtlZeroMemory(&pointers, sizeof(pointers));
    pNotifyHandle = NULL;

    sent.Next = NULL;
    InitializeListHead(&pended);

    wait = FALSE;

    //
    // Pick a value that is not used anywhere in the function and make sure that 
    // we have changed it, before we go to the Remove state
    //
#pragma prefast(suppress: __WARNING_UNUSED_SCALAR_ASSIGNMENT, "PFD is warning that the following assignement is unused. Suppress it to prevent changing any logic.")
    removeState = WdfIoTargetStarted;

CheckState:
    Lock(&irql);

    //
    // If we are in the process of opening the target, wait for that to finish.
    //
    if (m_OpenState == FxIoTargetRemoteOpenStateOpening) {
        Unlock(irql);

        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
            "Closing WDFIOTARGET %p which is opening, waiting on event %p",
            GetObjectHandle(), m_OpenedEvent.GetEvent());

        m_OpenedEvent.EnterCRAndWaitAndLeave();

        //
        // Jump back to the top and recheck
        //
        goto CheckState;
    }

    if (Reason == FxIoTargetRemoteCloseReasonDelete) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
            "Closing WDFIOTARGET %p, reason:   delete", GetObjectHandle());

        removeState = WdfIoTargetDeleted;
    }
    else if (m_OpenState == FxIoTargetRemoteOpenStateOpen) {
        if (Reason == FxIoTargetRemoteCloseReasonQueryRemove) {
            DoTraceLevelMessage(
                pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
                "Closing WDFIOTARGET %p, reason:   query remove",
                GetObjectHandle());
            //
            // Not really being removed, but that is what the API name is...
            //
            removeState = WdfIoTargetClosedForQueryRemove;
        }
        else {
                       
            DoTraceLevelMessage(
                pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
                "Closing WDFIOTARGET %p, reason:   close", GetObjectHandle());
            
            if (pFxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,9)) {
                removeState = WdfIoTargetClosed;
            }
            else {
                removeState = WdfIoTargetClosedForQueryRemove;
            }            
        }
               
        //
        // Either way, we are no longer open for business
        //
        m_OpenState = FxIoTargetRemoteOpenStateClosed;
    }
    else {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
            "Closing WDFIOTARGET %p which is not open", GetObjectHandle());

        //
        // We are not opened, so treat this as a cleanup
        //
        removeState = WdfIoTargetClosed;
    }

    DoTraceLevelMessage(
        pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
        "WDFIOTARGET %p:  fileobj %p, devobj %p, handle %p, notify handle %I64d",
        GetObjectHandle(), m_TargetFileObject,
        m_TargetDevice, m_TargetHandle, (UINT64)m_TargetNotifyHandle);

    if (Reason != FxIoTargetRemoteCloseReasonQueryRemove) {
        //
        // If we are closing for a query remove, we want to keep the handle
        // around so that we can be notified of the final close or if the close
        // was canceled.
        //
        pNotifyHandle = m_TargetNotifyHandle;
        ResetTargetNotifyHandle();
    }

    ASSERT(removeState != WdfIoTargetStarted);
    m_ClearedPointers =  &pointers;
    GotoRemoveState(removeState, &pended, &sent, FALSE, &wait);

    Unlock(irql);

    UnregisterForPnpNotification(pNotifyHandle);

    //
    // Complete any requests we might have pulled off of our lists
    //
    CompletePendedRequestList(&pended);
    _CancelSentRequests(&sent);

    //
    // We were just removed, wait for any I/O to complete back if necessary.
    //
    if (wait) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
            "WDFIOTARGET %p, waiting for stop to complete", GetObjectHandle());

        WaitForSentIoToComplete();
    }

    switch (Reason) {
    case FxIoTargetRemoteCloseReasonQueryRemove:
        //
        // m_OpenParams is needed for reopen on canceled query remove
        //
        DO_NOTHING();
        break;

    case FxIoTargetRemoteCloseReasonDelete:
        m_OpenParams.Clear();
        break;

    default:
        //
        // If this object is not about to be deleted, we need to revert some
        // of the state that just changed.
        //
        m_SentIoEvent.Clear();
        break;
    }
    
    if (removeState == WdfIoTargetDeleted) {
       WaitForDisposeEvent();
    }

    //
    // Finally, close down our handle and pointers
    //
    if (pointers.TargetPdo != NULL) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGIOTARGET,
            "WDFIOTARGET %p derefing PDO %p on close",
            GetObjectHandle(), pointers.TargetPdo);

        Mx::MxDereferenceObject(pointers.TargetPdo);
    }

    if (pointers.TargetFileObject != NULL) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGIOTARGET,
            "WDFIOTARGET %p derefing FileObj %p on close",
            GetObjectHandle(), pointers.TargetFileObject);
        Mx::MxDereferenceObject(pointers.TargetFileObject);

#if (FX_CORE_MODE == FX_CORE_USER_MODE)
        CloseWdfFileObject(pointers.TargetFileObject);
#endif
    }

#if (FX_CORE_MODE == FX_CORE_USER_MODE)
        UnbindHandle(&pointers);
#endif

    if (pointers.TargetHandle != NULL) {
        DoTraceLevelMessage(
            pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGIOTARGET,
            "WDFIOTARGET %p closing handle %p on close",
            GetObjectHandle(), pointers.TargetHandle);
        Mx::MxClose(pointers.TargetHandle);
    }
}
_Must_inspect_result_
NTSTATUS
FxIoTargetRemote::Open(
    __in PWDF_IO_TARGET_OPEN_PARAMS OpenParams
    )
{
    FxIoTargetRemoveOpenParams params, *pParams;
    UNICODE_STRING name;
    LIST_ENTRY pended;
    WDF_IO_TARGET_OPEN_TYPE type;
    NTSTATUS status;
    BOOLEAN close, reopen;
    PVOID pEa;
    ULONG eaLength;
    KIRQL irql;

    RtlZeroMemory(&name, sizeof(name));
    close = FALSE;
    reopen = OpenParams->Type == WdfIoTargetOpenReopen ? TRUE : FALSE;

    pEa = NULL;
    eaLength = 0;

    //
    // We only support reopening using stored settings when we open by name
    //
    if (reopen && m_OpenParams.OpenType != WdfIoTargetOpenByName) {
        status = STATUS_INVALID_DEVICE_REQUEST;
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
            "Reopen only supported if the open type is WdfIoTargetOpenByName WDFIOTARGET %p %!STATUS!",
            GetObjectHandle(), status);
        return status;
    }

    //
    // Must preallocate all settings now
    //
    if (reopen) {
        //
        // convert the type into the type used for the previous open
        //
        type = m_OpenParams.OpenType;
        pParams = &m_OpenParams;
    }
    else {
        type = OpenParams->Type;
        pParams = &params;

        if (OpenParams->Type == WdfIoTargetOpenByName) {

            status = FxDuplicateUnicodeString(GetDriverGlobals(),
                                              &OpenParams->TargetDeviceName,
                                              &name);
            if (!NT_SUCCESS(status)) {
                DoTraceLevelMessage(
                    GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                    "Could not allocate memory for target name for WDFIOTARGET %p",
                    GetObjectHandle());
                goto Done;
            }
            if (OpenParams->EaBuffer != NULL && OpenParams->EaBufferLength > 0) {

                pEa = FxPoolAllocate(GetDriverGlobals(),
                                     PagedPool,
                                     OpenParams->EaBufferLength);

                if (pEa == NULL) {
                    DoTraceLevelMessage(
                        GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                        "Could not allocate memory for target name "
                        "for WDFIOTARGET %p", GetObjectHandle());
                    status = STATUS_INSUFFICIENT_RESOURCES;
                    goto Done;
                }
                else {
                    eaLength = OpenParams->EaBufferLength;
                    RtlCopyMemory(pEa, OpenParams->EaBuffer, eaLength);
                }
            }
        }
    }

    Lock(&irql);

    if (m_State == WdfIoTargetDeleted) {
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
            "Opening WDFIOTARGET %p which is removed, state %d",
            GetObjectHandle(), m_State);
        status = STATUS_INVALID_DEVICE_STATE;
    }
    else if (m_OpenState != FxIoTargetRemoteOpenStateClosed) {
        //
        // We are either open or are opening
        //
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
            "Opening an already open WDFIOTARGET %p, open state %d",
            GetObjectHandle(), m_OpenState);
        status = STATUS_INVALID_DEVICE_STATE;
    }
    else {
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
            "Opening WDFIOTARGET %p", GetObjectHandle());

        //
        // Clear the event so that if something is waiting on the state
        // transition, they will block until we are done.
        //
        m_OpenedEvent.Clear();

        m_OpenState = FxIoTargetRemoteOpenStateOpening;
        status = STATUS_SUCCESS;
    }
    Unlock(irql);

    if (!NT_SUCCESS(status)) {
        goto Done;
    }

    ASSERT(m_TargetFileObject == NULL);
    ASSERT(m_TargetDevice == NULL);
    ASSERT(m_TargetPdo == NULL);
    ASSERT(m_TargetHandle == NULL);

    //
    // m_TargetNotifyHandle can be a valid value if the caller has previously
    // opened the target, received a query remove, then a cancel remove, and
    // is now reopening the target.
    //
    UnregisterForPnpNotification(m_TargetNotifyHandle);
    ResetTargetNotifyHandle();

    //
    // Only clear the open parameters if we are not attempting a reopen.
    //
    if (reopen == FALSE) {
        m_OpenParams.Clear();
    }

    switch (type) {
    case WdfIoTargetOpenUseExistingDevice:
        KMDF_ONLY_CODE_PATH_ASSERT();

        //
        // OpenParams must be non NULL b/c we can't reopen a target with a
        // previous device object.
        //
        ASSERT(OpenParams->Type == WdfIoTargetOpenUseExistingDevice);

        m_TargetDevice = (MdDeviceObject) OpenParams->TargetDeviceObject;
        m_TargetFileObject = (MdFileObject) OpenParams->TargetFileObject;
        m_TargetHandle = NULL;

        //
        // By taking a manual reference here, we simplify the code in
        // FxIoTargetRemote::Close where we can assume there is an outstanding
        // reference on the PFILE_OBJECT at all times as long as we have a non
        // NULL pointer.
        //
        if (m_TargetFileObject != NULL) {
            Mx::MxReferenceObject(m_TargetFileObject);
        }

        status = STATUS_SUCCESS;

        break;

    case WdfIoTargetOpenLocalTargetByFile:
        UMDF_ONLY_CODE_PATH_ASSERT();

        status = OpenLocalTargetByFile(OpenParams);
        break;

    case WdfIoTargetOpenByName:
        //
        // Only capture the open parameters if we are not reopening.
        //
        if (reopen == FALSE) {
            pParams->Set(OpenParams, &name, pEa, eaLength);
        }

        status = OpenTargetHandle(OpenParams, pParams);
        if (NT_SUCCESS(status)) {
            if (reopen == FALSE) {
                m_OpenParams.Set(OpenParams, &name, pEa, eaLength);

                //
                // Setting pEa to NULL stops it from being freed later.
                // Zeroing out name stops it from being freed later.
                //
                pEa = NULL;
                RtlZeroMemory(&name, sizeof(name));
            }
        }
        else {
            close = TRUE;
        }
        break;
    }

    InitializeListHead(&pended);

    //
    // Get Target file object for KMDF. Noop for UMDF.
    //
    if (NT_SUCCESS(status)) {
        status = GetTargetDeviceRelations(&close);
    }

    if (NT_SUCCESS(status) && CanRegisterForPnpNotification()) {
        if (reopen == FALSE) {
            //
            // Set the values before the register so that if a notification
            // comes in before the register returns, we have a function to call.
            //
            m_EvtQueryRemove.m_Method = OpenParams->EvtIoTargetQueryRemove;
            m_EvtRemoveCanceled.m_Method = OpenParams->EvtIoTargetRemoveCanceled;
            m_EvtRemoveComplete.m_Method = OpenParams->EvtIoTargetRemoveComplete;
        }

        status = RegisterForPnpNotification();

        //
        // Even if we can't register, we still are successful in opening
        // up the device and we will proceed from there.
        //
        if (!NT_SUCCESS(status)) {
            DoTraceLevelMessage(
                GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
                "WDFIOTARGET %p, could not register pnp notification, %!STATUS! not "
                "treated as an error", GetObjectHandle(), status);

            m_EvtQueryRemove.m_Method = NULL;
            m_EvtRemoveCanceled.m_Method = NULL;
            m_EvtRemoveComplete.m_Method = NULL;

            status = STATUS_SUCCESS;
        }
    }

    //
    // UMDF only. Bind handle to remote dispatcher. 
    //
#if (FX_CORE_MODE == FX_CORE_USER_MODE)
    if (NT_SUCCESS(status) && type != WdfIoTargetOpenLocalTargetByFile) {
        status = BindToHandle();
        if (!NT_SUCCESS(status)) {
            close = TRUE;
        }
    }
#endif

    Lock(&irql);

    if (NT_SUCCESS(status)) {
        
#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
        m_TargetStackSize = m_TargetDevice->StackSize;
        m_TargetIoType = GetTargetIoType();
#endif

        m_OpenState = FxIoTargetRemoteOpenStateOpen;

        //
        // Set our state to started.  This will also resend any pended requests
        // due to a query remove.
        //
        status = GotoStartState(&pended, FALSE);

        //
        // We could not successfully start, close back down
        //
        if (!NT_SUCCESS(status)) {
            DoTraceLevelMessage(
                GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
                "WDFIOTARGET %p could not transition to started state, %!STATUS!",
                GetObjectHandle(), status);

            close = TRUE;
        }
    }
    else {
        m_OpenState = FxIoTargetRemoteOpenStateClosed;
    }

    //
    // No matter what, indicate to any waiters that our state change has
    // completed.
    //
    m_OpenedEvent.Set();

    Unlock(irql);

Done:
    //
    // Resubmit any reads that were pended until now.
    //
    if (NT_SUCCESS(status)) {
        SubmitPendedRequests(&pended);
    }
    else if (close) {
        Close(FxIoTargetRemoteCloseReasonPlainClose);
    }

    if (name.Buffer != NULL) {
        FxPoolFree(name.Buffer);
    }

    if (pEa != NULL) {
        FxPoolFree(pEa);
    }

    return status;
}
Пример #14
0
logical pc_ADK_Field :: SetupField ( )
{
  PropertyHandle        *pfc = GetParentProperty();
  PropertyHandle        *my_class  = pfc->GPH("class");
  PropertyHandle        *member;
  PropertyHandle        *fc;
  logical                vgrow = YES;
  logical                hgrow = YES;
  logical                coll_opt;
  char                  *ref_type;  
  char                  *propnames = NULL;
  char                   strnames[ID_SIZE+1];
  logical                term = NO;
BEGINSEQ
  if ( IsInitialized() )                             LEAVESEQ
    
  propnames = strdup(GPH("sys_ident")->GetString());
    
  SetupFromParent();
  
  if ( !my_class->Get(FIRST_INSTANCE) )              ERROR
    
  pc_ADK_Class   new_class(GetObjectHandle(),PI_Update);  
  PropertyHandle extent(GetObjectHandle(),"SDB_Extend",PI_Read);  
  PropertyHandle phpropnames(propnames);
  pc_ADK_Class    structure(*my_class);  
  if ( member = structure.GetMember(propnames) )
  {
    if ( !(fc = new_class.ProvideDefaultControl(member,hgrow,vgrow)) ||
         !fc->Exist()  )                             ERROR
    coll_opt = pc0_SDB_Member(member).IsMultipleRef() ? YES : NO;
    ref_type = "DRT_PropertyPath";
    strcpy(strnames,member->GetString("ddetype"));
  }
  else if ( extent.Get(phpropnames) )
  {
    if ( !(fc = new_class.ProvideDefaultControl(&extent,hgrow,vgrow)) ||
         !fc->Exist()  )                             ERROR
    coll_opt = YES;
    ref_type = "DRT_Extent";
    strcpy(strnames,extent.GetString("ddetype"));
  }
  else                                               ERROR
    
  if ( !hgrow )
    *GPH("allign.hori_sizing") = "SIZE_Fixed";
  if ( !vgrow )
    *GPH("allign.vert_sizing") = "SIZE_Fixed";
  
  *GPH("auto_open") = YES;
  SetupDataSource(propnames,ref_type,coll_opt);
  SetupFromFieldControl(fc);
  SetupTitle(propnames);

  GPH("class")->Add(new_class.ExtractKey());        CTXCERR
  GPH("field_control")->Add(fc->ExtractKey());      CTXCERR


RECOVER
  term = YES;
ENDSEQ
  if ( propnames )
    free(propnames);
  return(term);
}
VOID
FxIoTargetSelf::Send(
    _In_ MdIrp Irp
    )
/*++    
Routine Description:
    send an MdIrp to the Self IO Target.

Arguments:

    MdIrp for IRP_MJ_READ, IRP_MJ_WRITE, or IRP_MJ_DEVICE_CONTROL

Returns:

    VOID
 
Implementation Note: 

    Function body inspired by WdfDeviceWdmDispatchIrpToIoQueue API.
 
--*/
{
    FxIrp irp(Irp);
    FxIoQueue* queue;
    NTSTATUS status;
    UCHAR majorFunction;
    FxIoInCallerContext* ioInCallerCtx;

#if (FX_CORE_MODE == FX_CORE_USER_MODE)

    //
    // Prepare the request to forward to the inteternal target. 
    //
    (static_cast<IWudfIoIrp2*>(Irp))->PrepareToForwardToSelf();

#else
    //
    // Set Next Stack Location
    //
    irp.SetNextIrpStackLocation();
    
    //
    // Set Device Object.
    //
    irp.SetCurrentDeviceObject(m_Device->GetDeviceObject());
#endif

    majorFunction = irp.GetMajorFunction();

    //
    // Retrieve Queue
    //
    queue = GetDispatchQueue(majorFunction);

    if (queue == NULL) {
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
            "Send WDFIOTARGET %p, No Dispatch Queue Found for Major Function %d",
            GetObjectHandle(), majorFunction);
        status = STATUS_INVALID_DEVICE_STATE;
        goto Fail;
    }
  
    //
    // Only read/writes/ctrls/internal_ctrls IRPs are allowed to be sent to 
    // Self IO Target
    //
    if (m_Device->GetDispatchPackage(majorFunction) != m_Device->m_PkgIo) {
        status = STATUS_INVALID_PARAMETER;
        DoTraceLevelMessage(
                GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                "Only Read/Write/Control/Internal-Control IRPs can be "
                "forwarded to Self IO Target 0x%p, %!IRPMJ!, "
                "IRP_MN %x, Device 0x%p, %!STATUS!",
                 GetHandle(), majorFunction, irp.GetMinorFunction(), 
                 m_Device->GetObjectHandle(), status);
        FxVerifierDbgBreakPoint(GetDriverGlobals());
        goto Fail;
    }

    //
    // Retrieve the InContextCallback function
    //
    ioInCallerCtx = m_Device->m_PkgIo->GetIoInCallerContextCallback(
                                            queue->GetCxDeviceInfo());

    //
    // DispatchStep2 will convert the IRP into a WDFREQUEST, queue it and if 
    // possible dispatch the request to the driver.
    // If a failure occurs, DispatchStep2 completes teh Irp 
    //
    (VOID) m_Device->m_PkgIo->DispatchStep2(Irp, ioInCallerCtx, queue);    
    return;

Fail:

    irp.SetStatus(status);
    irp.SetInformation(0);
    irp.CompleteRequest(IO_NO_INCREMENT);

    return;
}