Ejemplo n.º 1
0
static VOID
XenVbd_StopRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend) {
  PXENVBD_FILTER_DATA xvfd = (PXENVBD_FILTER_DATA)xvdd->xvfd;
  NTSTATUS status;
  WDFREQUEST request;
  WDF_REQUEST_SEND_OPTIONS send_options;
  IO_STACK_LOCATION stack;
  SCSI_REQUEST_BLOCK srb;
  SRB_IO_CONTROL sic;

  FUNCTION_ENTER();
  
  /* send a 'stop' down if we are suspending */
  if (suspend) {
    status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, xvfd->wdf_target, &request);
    FUNCTION_MSG("WdfRequestCreate = %08x\n", status);

    RtlZeroMemory(&stack, sizeof(IO_STACK_LOCATION));
    stack.MajorFunction = IRP_MJ_SCSI;
    stack.MinorFunction = IRP_MN_SCSI_CLASS;
    stack.Parameters.Scsi.Srb = &srb;

    RtlZeroMemory(&srb, SCSI_REQUEST_BLOCK_SIZE);
    srb.SrbFlags = SRB_FLAGS_BYPASS_FROZEN_QUEUE | SRB_FLAGS_NO_QUEUE_FREEZE;
    srb.Length = SCSI_REQUEST_BLOCK_SIZE;
    srb.PathId = 0;
    srb.TargetId = 0;
    srb.Lun = 0;
    srb.OriginalRequest = WdfRequestWdmGetIrp(request);
    srb.Function = SRB_FUNCTION_IO_CONTROL;
    srb.DataBuffer = &sic;
    
    RtlZeroMemory(&sic, sizeof(SRB_IO_CONTROL));
    sic.HeaderLength = sizeof(SRB_IO_CONTROL);
    memcpy(sic.Signature, XENVBD_CONTROL_SIG, 8);
    sic.Timeout = 60;
    sic.ControlCode = XENVBD_CONTROL_STOP;
    
    WdfRequestWdmFormatUsingStackLocation(request, &stack);
    
    WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
    if (!WdfRequestSend(request, xvfd->wdf_target, &send_options)) {
      FUNCTION_MSG("Request was _NOT_ sent\n");
    }
    #if DBG
    status = WdfRequestGetStatus(request);
    FUNCTION_MSG("Request Status = %08x\n", status);
    FUNCTION_MSG("SRB Status = %08x\n", srb.SrbStatus);
    #endif

    WdfObjectDelete(request);
  }
  
  status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);

  FUNCTION_EXIT();
}
Ejemplo n.º 2
0
static VOID
XenVbd_SendEvent(WDFDEVICE device) {
  PXENVBD_FILTER_DATA xvfd = GetXvfd(device);
  NTSTATUS status;
  WDFREQUEST request;
  WDF_REQUEST_SEND_OPTIONS send_options;
  IO_STACK_LOCATION stack;
  PUCHAR buf;
  PSCSI_REQUEST_BLOCK srb;
  PSRB_IO_CONTROL sic;

  status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, xvfd->wdf_target, &request);
  if (status != STATUS_SUCCESS) {
    FUNCTION_MSG("WdfRequestCreate failed %08x\n", status);
    /* this is bad - event will be dropped */
    return;
  }

  buf = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL) + sizeof(LARGE_INTEGER), XENVBD_POOL_TAG);
  RtlZeroMemory(buf, sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL));
  srb = (PSCSI_REQUEST_BLOCK)(buf);
  sic = (PSRB_IO_CONTROL)(buf + sizeof(SCSI_REQUEST_BLOCK));
  
  srb->Length = sizeof(SCSI_REQUEST_BLOCK);
  srb->SrbFlags = SRB_FLAGS_BYPASS_FROZEN_QUEUE | SRB_FLAGS_NO_QUEUE_FREEZE;
  srb->PathId = 0;
  srb->TargetId = 0;
  srb->Lun = 0;
  srb->OriginalRequest = WdfRequestWdmGetIrp(request);
  srb->Function = SRB_FUNCTION_IO_CONTROL;
  srb->DataBuffer = sic;
  srb->DataTransferLength = sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL);
  srb->TimeOutValue = (ULONG)-1;
  
  sic->HeaderLength = sizeof(SRB_IO_CONTROL);
  memcpy(sic->Signature, XENVBD_CONTROL_SIG, 8);
  sic->Timeout = (ULONG)-1;
  sic->ControlCode = XENVBD_CONTROL_EVENT;
  
  KeQuerySystemTime((PLARGE_INTEGER)((PUCHAR)buf + sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL)));

  RtlZeroMemory(&stack, sizeof(IO_STACK_LOCATION));
  stack.MajorFunction = IRP_MJ_SCSI;
  stack.MinorFunction = IRP_MN_SCSI_CLASS;
  stack.Parameters.Scsi.Srb = srb;

  WdfRequestWdmFormatUsingStackLocation(request, &stack);
  WdfRequestSetCompletionRoutine(request, XenVbd_SendEventComplete, buf);
  
  WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, 0); //WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE);
  if (!WdfRequestSend(request, xvfd->wdf_target, &send_options)) {
    FUNCTION_MSG("Error sending request\n");
  }
}
Ejemplo n.º 3
0
NTSTATUS
BthEchoSharedDeviceContextHeaderInit(
    PBTHECHOSAMPLE_DEVICE_CONTEXT_HEADER Header,
    WDFDEVICE Device
)
/*++

Description:

    Initializes the common context header between server and client

Arguments:

    Header - Contex header
    Device - Framework device object

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status;
    WDF_OBJECT_ATTRIBUTES attributes;

    Header->Device = Device;

    Header->IoTarget = WdfDeviceGetIoTarget(Device);

    //
    // Initialize request object
    //

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = Device;

    status = WdfRequestCreate(
                 &attributes,
                 Header->IoTarget,
                 &Header->Request
             );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                    "Failed to pre-allocate request in device context, Status code %!STATUS!\n", status);

        goto exit;
    }

exit:
    return status;
}
Ejemplo n.º 4
0
NTSTATUS
CreateRequest(
	_In_ WDFDEVICE Device,
	_In_ WDFIOTARGET IoTarget,
	_Outptr_ WDFREQUEST * Request
	)
{
	NTSTATUS Status = STATUS_SUCCESS;
    WDF_OBJECT_ATTRIBUTES Attributes;

    WDF_OBJECT_ATTRIBUTES_INIT(&Attributes);
    Attributes.ParentObject = Device;

	Status = WdfRequestCreate(&Attributes, IoTarget, Request);
	if(!NT_SUCCESS(Status))
	{
		return Status;
	}

	return Status;
}
Ejemplo n.º 5
0
NTSTATUS
BthEchoCliRetrieveServerSdpRecord(
    __in PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx,
    __out PBTH_SDP_STREAM_RESPONSE * ServerSdpRecord    
    )
/*++

Description:

    Retrive server SDP record.
    We call this function on every file open to get the PSM

Arguments:

    DevCtx - Client context
    ServerSdpRecord - SDP record retrieved

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status, statusReuse, disconnectStatus;
    WDF_MEMORY_DESCRIPTOR inMemDesc;
    WDF_MEMORY_DESCRIPTOR outMemDesc;
    WDF_REQUEST_REUSE_PARAMS ReuseParams;    
    BTH_SDP_CONNECT connect = {0};
    BTH_SDP_DISCONNECT disconnect = {0};
    BTH_SDP_SERVICE_ATTRIBUTE_SEARCH_REQUEST requestSdp = {0};
    BTH_SDP_STREAM_RESPONSE responseSdp = {0};
    ULONG requestSize;
    PBTH_SDP_STREAM_RESPONSE serverSdpRecord = NULL;
    WDFREQUEST request;
    WDF_OBJECT_ATTRIBUTES attributes;
    

    PAGED_CODE();

    //
    // Allocate the request we will use for obtaining sdp record
    // NOTE that we do it for every file open, hence we
    //
    // can't use reserve request from the context
    //
    
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);

    status = WdfRequestCreate(
        &attributes,
        DevCtx->Header.IoTarget,
        &request
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "Failed to allocate request for retriving server sdp record, Status code %!STATUS!\n", status);

        goto exit;        
    }

    connect.bthAddress = DevCtx->ServerBthAddress;
    connect.requestTimeout = SDP_REQUEST_TO_DEFAULT;
    connect.fSdpConnect = 0;

    //
    // Connect to the SDP service.
    //

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &connect,
        sizeof(connect)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        &connect,
        sizeof(connect)
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_CONNECT,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "IOCTL_BTH_SDP_CONNECT failed, Status code %!STATUS!\n", status);

        goto exit1;
    }

    //
    // Obtain the required size of the SDP record
    //
    requestSdp.hConnection = connect.hConnection;
    requestSdp.uuids[0].u.uuid128 = BTHECHOSAMPLE_SVC_GUID;
    requestSdp.uuids[0].uuidType = SDP_ST_UUID128;
    requestSdp.range[0].minAttribute = 0;
    requestSdp.range[0].maxAttribute = 0xFFFF;

    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &requestSdp,
        sizeof(requestSdp)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        &responseSdp,
        sizeof(responseSdp)
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed while querying response size, "
            "status code %!STATUS!\n", status);

        goto exit2;
    }

    //
    // Allocate the required size for SDP record
    //

    status = RtlULongAdd(
        responseSdp.requiredSize, 
        sizeof(BTH_SDP_STREAM_RESPONSE), 
        &requestSize
        );

    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "SDP record size too large, status code %!STATUS!\n", status);

        goto exit2;
    }

    serverSdpRecord = ExAllocatePoolWithTag(NonPagedPool, requestSize, POOLTAG_BTHECHOSAMPLE);
    if (NULL == serverSdpRecord)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Allocating SDP record failed, returning status code %!STATUS!\n", status); 

        goto exit2;
    }

    //
    // Send request with required size
    //
    
    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &requestSdp,
        sizeof(requestSdp)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        serverSdpRecord,
        requestSize
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed, status code %!STATUS!\n", status);

        ExFreePoolWithTag(serverSdpRecord, POOLTAG_BTHECHOSAMPLE);
    }
    else
    {
        *ServerSdpRecord = serverSdpRecord;
    }
    
exit2:
    
    //
    // Disconnect from SDP service.
    //
    
    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    disconnect.hConnection = connect.hConnection;

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &disconnect,
        sizeof(disconnect)
        );
    
    disconnectStatus = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_DISCONNECT,
        &inMemDesc,
        NULL,   //outMemDesc
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    ASSERT(NT_SUCCESS(disconnectStatus)); //Disconnect should not fail

    if (!NT_SUCCESS(disconnectStatus))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "IOCTL_BTH_SDP_DISCONNECT failed, Status code %!STATUS!\n", status);
    }
    
exit1:    
    WdfObjectDelete(request);
exit:
    return status;
}
Ejemplo n.º 6
0
/* Source: WDK/src_5239/kmdf/1394/pnp.c, line 634. */
VOID
t1394_EvtDeviceSelfManagedIoCleanup(
/*     IN  WDFDEVICE Device */
    PDEVICE_EXTENSION   deviceExtension /* added for SLAyer */
    )
{
     PLIST_ENTRY         listEntry;

    //
    // Remove any isoch resource data
    //
    WHILE (TRUE) {

        WdfSpinLockAcquire(deviceExtension->IsochResourceSpinLock);

        if (!IsListEmpty(&deviceExtension->IsochResourceData)) {

            PISOCH_RESOURCE_DATA    IsochResourceData = NULL;

/* SLAyer: memory unsafety in original code. Reported as Windows 8 Bug #59410. Fixed by Patrick Maninger 9/Aug/2010.  */
	    listEntry = RemoveHeadList(&deviceExtension->CromData);

            IsochResourceData = CONTAINING_RECORD(listEntry,
						  ISOCH_RESOURCE_DATA,
						  IsochResourceList);

            WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock);

/*             TRACE(TL_TRACE, ("Surprise Removal: IsochResourceData = 0x%x\n", */
/*                              IsochResourceData)); */

            if (IsochResourceData) {

                PIRB          pIrb;
                WDFREQUEST    request;
	         NTSTATUS status;

/*                 TRACE(TL_TRACE, ("Surprise Removal: Freeing hResource = 0x%x\n", */
/*                                  IsochResourceData->hResource)); */

                status = WdfRequestCreate(
                    WDF_NO_OBJECT_ATTRIBUTES,
                    deviceExtension->StackIoTarget,
                    &request);

                if (!NT_SUCCESS(status)) {
/*                     TRACE(TL_ERROR, ("Failed to allocate request %x\n", status)); */
			free(IsochResourceData); /* SLAyer: added */
                }
                else {

                    pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_1394);

                    if (!pIrb) {

                        WdfObjectDelete(request);

/*                         TRACE(TL_ERROR, ("Failed to allocate pIrb!\n")); */
			free(IsochResourceData); /* SLAyer: added */
                    }
                    else {

                        RtlZeroMemory (pIrb, sizeof (IRB));
                        pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
                        pIrb->Flags = 0;
                        pIrb->u.IsochFreeResources.hResource = IsochResourceData->hResource;

                        status = t1394_SubmitIrpSynch(deviceExtension->StackIoTarget, request, pIrb);
			free(IsochResourceData); /* SLAyer: added */

                        if (!NT_SUCCESS(status)) {

/*                             TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", status)); */
                        }

                        ExFreePool(pIrb);
                        WdfObjectDelete(request);
                    }
                }
            }
        }
        else {


            WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock);
            break;
        }
    }

/*     EXIT("t1394_PnpRemoveDevice", STATUS_SUCCESS); */

}
Ejemplo n.º 7
0
NTSTATUS
Toastmon_OpenDevice(
    WDFDEVICE Device,
    PUNICODE_STRING SymbolicLink,
    WDFIOTARGET *Target
    )
/*++

Routine Description:

    Open the I/O target and preallocate any resources required
    to communicate with the target device.

Arguments:

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS                    status = STATUS_SUCCESS;
    PTARGET_DEVICE_INFO         targetDeviceInfo = NULL;
    WDF_IO_TARGET_OPEN_PARAMS   openParams;
    WDFIOTARGET                 ioTarget;
    WDF_OBJECT_ATTRIBUTES       attributes;
    PDEVICE_EXTENSION           deviceExtension = GetDeviceExtension(Device);
    WDF_TIMER_CONFIG            wdfTimerConfig;
    

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, TARGET_DEVICE_INFO);

    status = WdfIoTargetCreate(deviceExtension->WdfDevice,
                            &attributes,
                            &ioTarget);
    if (!NT_SUCCESS(status)) {
        KdPrint(("WdfIoTargetCreate failed 0x%x\n", status));
        return status;
    }

    targetDeviceInfo = GetTargetDeviceInfo(ioTarget);
    targetDeviceInfo->DeviceExtension = deviceExtension;

    //
    // Warning: It's not recommended to open the targetdevice
    // from a pnp notification callback routine, because if
    // the target device initiates any kind of PnP action as
    // a result of this open, the PnP manager could deadlock.
    // You should queue a workitem to do that.
    // For example, SWENUM devices in conjunction with KS
    // initiate an enumeration of a device when you do the
    // open on the device interface.
    // We can open the target device here because we know the
    // toaster function driver doesn't trigger any pnp action.
    //

    WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
        &openParams,
        SymbolicLink,
        STANDARD_RIGHTS_ALL);

    openParams.ShareAccess = FILE_SHARE_WRITE | FILE_SHARE_READ;
    //
    // Framework provides default action for all of these if you don't register
    // these callbacks -it will close the handle to the target when the device is
    // being query-removed and reopen it if the query-remove fails.
    // In this sample, we use a periodic timers to post requests to the target.
    // So we need to register these callbacks so that we can start and stop
    // the timer when the state of the target device changes. Since we are
    // registering these callbacks, we are now responsbile for closing and
    // reopening the target.
    //
    openParams.EvtIoTargetQueryRemove = ToastMon_EvtIoTargetQueryRemove;
    openParams.EvtIoTargetRemoveCanceled = ToastMon_EvtIoTargetRemoveCanceled;
    openParams.EvtIoTargetRemoveComplete = ToastMon_EvtIoTargetRemoveComplete;


    status = WdfIoTargetOpen(ioTarget, &openParams);

    if (!NT_SUCCESS(status)) {
        KdPrint(("WdfIoTargetOpen failed with status 0x%x\n", status));
        WdfObjectDelete(ioTarget);
        return status;
    }
   
    KdPrint(("Target Device 0x%x, PDO 0x%x, Fileobject 0x%x, Filehandle 0x%x\n",
                        WdfIoTargetWdmGetTargetDeviceObject(ioTarget),
                        WdfIoTargetWdmGetTargetPhysicalDevice(ioTarget),
                        WdfIoTargetWdmGetTargetFileObject(ioTarget),
                        WdfIoTargetWdmGetTargetFileHandle(ioTarget)));

    //
    // Create two requests - one for read and one for write.
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = ioTarget;

    status = WdfRequestCreate(&attributes,
                              ioTarget,
                              &targetDeviceInfo->ReadRequest);

    if (!NT_SUCCESS(status)) {
        WdfObjectDelete(ioTarget);
        return status;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = ioTarget;

    status = WdfRequestCreate(&attributes,
                            ioTarget,
                            &targetDeviceInfo->WriteRequest);

    if (!NT_SUCCESS(status)) {
        WdfObjectDelete(ioTarget);
        return status;
    }

    //
    // Create a passive timer to post requests to the I/O target.
    //
    WDF_TIMER_CONFIG_INIT(&wdfTimerConfig,
                          Toastmon_EvtTimerPostRequests);
     
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, TIMER_CONTEXT);

    //
    // Make IoTarget as parent of the timer to prevent the ioTarget
    // from deleted until the dpc has runto completion.
    //
    attributes.ParentObject = ioTarget;

    //
    // By specifying WdfExecutionLevelPassive the framework will invoke
    // the timer callback Toastmon_EvtTimerPostRequests at PASSIVE_LEVEL.
    //
    attributes.ExecutionLevel = WdfExecutionLevelPassive;

    //
    // Setting the AutomaticSerialization to FALSE prevents
    // WdfTimerCreate to fail if the parent device object's 
    // execution level is set to WdfExecutionLevelPassive.
    //
    wdfTimerConfig.AutomaticSerialization = FALSE;
    
    status = WdfTimerCreate(&wdfTimerConfig,
                       &attributes,
                       &targetDeviceInfo->TimerForPostingRequests
                       );

    if(!NT_SUCCESS(status)) {
        KdPrint(("WdfTimerCreate failed 0x%x\n", status));
        WdfObjectDelete(ioTarget);
        return status;
    }

    GetTimerContext(targetDeviceInfo->TimerForPostingRequests)->IoTarget = ioTarget;

    //
    // Start the passive timer. The first timer will be queued after 1ms  interval and
    // after that it will be requeued in the timer callback function. 
    // The value of 1 ms (lowest timer resoltion allowed on NT) is chosen here so 
    // that timer would fire right away.
    //
    WdfTimerStart(targetDeviceInfo->TimerForPostingRequests,
                                        WDF_REL_TIMEOUT_IN_MS(1));

    *Target = ioTarget;

    return status;

}
NTSTATUS
kmdf1394_UpdateGenerationCount (
                                IN WDFDEVICE Device)
/*++

Routine Description:

    Routine to get and update generation count for the 1394 controller

Arguments:

    Device - WDF Device object

Return Value:

    NTSTATUS value
--*/
{
    PDEVICE_EXTENSION  deviceExtension = GetDeviceContext(Device);
    NTSTATUS    ntStatus = STATUS_SUCCESS;
    PIRB Irb = NULL;
    WDFREQUEST request = NULL;

    ENTER("kmdf1394_UpdateGenerationCountWorkItem");

    ntStatus = WdfRequestCreate ( 
                            WDF_NO_OBJECT_ATTRIBUTES,
                            deviceExtension->StackIoTarget,
                            &request);

    if (!NT_SUCCESS(ntStatus)) 
    {
        TRACE(TL_ERROR, ("Failed to allocate request!\n"));

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Irb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV);
    if (!Irb)
    {
        TRACE(TL_ERROR, ("Failed to allocate Irb!\n"));

        WdfObjectDelete (request);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory (Irb, sizeof (IRB));
    Irb->FunctionNumber = REQUEST_GET_GENERATION_COUNT;
    Irb->Flags = 0;

    ntStatus = kmdf1394_SubmitIrpSynch (deviceExtension->StackIoTarget, request, Irb);
    if (NT_SUCCESS(ntStatus))
    {
        TRACE(TL_TRACE, ("GenerationCount = 0x%x\n", deviceExtension->GenerationCount));
       
        //
        // Update our local copy of the GenerationCount
        //
        deviceExtension->GenerationCount = Irb->u.GetGenerationCount.GenerationCount;       
    }
    else
    {
        TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
    }

    WdfObjectDelete(request);
    ExFreePoolWithTag(Irb,POOLTAG_KMDF_VDEV);

    EXIT("kmdf1394_UpdateGenerationCountWorkItem", ntStatus);

    return ntStatus;
} // kmdf1394_UpdateGenerationCount 
Ejemplo n.º 9
0
VOID
kmdf1394_EvtDeviceSelfManagedIoCleanup (
                                        IN  WDFDEVICE Device)
/*++

Routine Description:

    EvtDeviceSelfManagedIoCleanup is called by the Framework when the device is
    being torn down, either in response to IRP_MN_REMOVE_DEVICE or
    IRP_MN_SURPRISE_REMOVE_DEVICE.  It will be called only once.  Its job is to
    stop all outstanding I/O in the driver that the Framework is not managing.

Arguments:

    Device - Handle to a framework device object.

Return Value:

    None

--*/
{
    PDEVICE_EXTENSION deviceExtension = NULL;
    PLIST_ENTRY listEntry = NULL;


    Enter();

    deviceExtension = GetDeviceContext(Device);

    DoTraceLevelMessage(TRACE_LEVEL_WARNING, 
                        TRACE_FLAG_PNP,
                        "Removing KMDF1394VDEV.SYS.\n");

    //
    // lets free up any crom data structs we've allocated...
    //
    WdfSpinLockAcquire (deviceExtension->CromSpinLock);

    while (!IsListEmpty (&deviceExtension->CromData))
    {
        PCROM_DATA      CromData;

        //
        // get struct off list
        //
        listEntry = RemoveHeadList (&deviceExtension->CromData);
        CromData = CONTAINING_RECORD (listEntry, CROM_DATA, CromList);

        //
        // need to free up everything associated with this allocate...
        //
        if (CromData)
        {
            if (CromData->Buffer)
            {
                ExFreePoolWithTag (CromData->Buffer, POOLTAG_KMDF_VDEV);
            }

            if (CromData->pMdl)
            {
                IoFreeMdl (CromData->pMdl);
            }
            //
            // we already checked CromData
            //
            ExFreePoolWithTag (CromData, POOLTAG_KMDF_VDEV);
        }
    }

    WdfSpinLockRelease (deviceExtension->CromSpinLock);

    //
    // lets free up any allocated addresses and deallocate all
    // memory associated with them...
    //
    WdfSpinLockAcquire (deviceExtension->AsyncSpinLock);

    while (!IsListEmpty (&deviceExtension->AsyncAddressData)) 
    {
        PASYNC_ADDRESS_DATA     AsyncAddressData;

        //
        // get struct off list
        //
        listEntry = RemoveHeadList (&deviceExtension->AsyncAddressData);

        AsyncAddressData = CONTAINING_RECORD (
            listEntry, 
            ASYNC_ADDRESS_DATA,
            AsyncAddressList);

        // 
        // need to free up everything associated with this allocate...
        //
        if (AsyncAddressData->pMdl)
        {
            IoFreeMdl (AsyncAddressData->pMdl);
        }

        if (AsyncAddressData->Buffer)
        {
            ExFreePoolWithTag(AsyncAddressData->Buffer, POOLTAG_KMDF_VDEV);
        }

        if (AsyncAddressData->AddressRange)
        {
            ExFreePoolWithTag(AsyncAddressData->AddressRange, POOLTAG_KMDF_VDEV);
        }

        ExFreePoolWithTag(AsyncAddressData, POOLTAG_KMDF_VDEV);
    }


    WdfSpinLockRelease(deviceExtension->AsyncSpinLock);

    //
    // TODO: Free up any attached isoch buffers when
    // we get the attach / detach code inserted again.
    //

    //
    // Remove any isoch resource data
    //
    WHILE (TRUE) 
    {
        WdfSpinLockAcquire(deviceExtension->IsochResourceSpinLock);

        if (!IsListEmpty(&deviceExtension->IsochResourceData)) 
        {
            PISOCH_RESOURCE_DATA    IsochResourceData = NULL;

            listEntry = RemoveHeadList(&deviceExtension->CromData);

            IsochResourceData = CONTAINING_RECORD (
                listEntry,
                ISOCH_RESOURCE_DATA,
                IsochResourceList);

            WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock);

            DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, 
                                TRACE_FLAG_PNP, 
                                "Surprise Removal: IsochResourceData = 0x%p\n",
                                IsochResourceData);

            if (IsochResourceData) 
            {
                PIRB pIrb;
                WDFREQUEST request;
                NTSTATUS ntStatus;

                DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, 
                                    TRACE_FLAG_PNP, 
                                    "Surprise Removal: Freeing hResource = 0x%p\n",
                                    IsochResourceData->hResource);

                ntStatus = WdfRequestCreate (
                    WDF_NO_OBJECT_ATTRIBUTES,
                    deviceExtension->StackIoTarget,
                    &request);
                if (!NT_SUCCESS (ntStatus)) 
                {
                    DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                                        TRACE_FLAG_PNP, 
                                        "Failed to allocate request %!STATUS!\n", 
                                        ntStatus);
                }
                else 
                {
                    pIrb = ExAllocatePoolWithTag(
                        NonPagedPool, 
                        sizeof(IRB), 
                        POOLTAG_KMDF_VDEV);
                    if (!pIrb) 
                    {
                        WdfObjectDelete(request);
                        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                                            TRACE_FLAG_PNP, 
                                            "Failed to allocate pIrb!\n");
                    }
                    else 
                    {
                        RtlZeroMemory (pIrb, sizeof (IRB));
                        pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
                        pIrb->Flags = 0;
                        pIrb->u.IsochFreeResources.hResource = \
                            IsochResourceData->hResource;

                        ntStatus = kmdf1394_SubmitIrpSynch (
                            deviceExtension->StackIoTarget, 
                            request, 
                            pIrb);
                        if (!NT_SUCCESS (ntStatus)) 
                        {
                            DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                                                TRACE_FLAG_PNP, 
                                                "SubmitIrpSync failed = %!STATUS!\n", 
                                                ntStatus);
                        }

                        ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV);
                        WdfObjectDelete (request);
                    } // else
                } // else
            } // if (IsochResourceData) 
        } //  if (!IsListEmpty(&deviceExtension->IsochResourceData)) 
        else 
        {
            WdfSpinLockRelease (deviceExtension->IsochResourceSpinLock);
            break;
        }
    }

    ExitS(STATUS_SUCCESS);
} // kmdf1394_EvtDeviceSelfManagedIoCleanup
Ejemplo n.º 10
0
NTSTATUS
BthEchoConnectionObjectInit(
    _In_ WDFOBJECT ConnectionObject,
    _In_ PBTHECHOSAMPLE_DEVICE_CONTEXT_HEADER DevCtxHdr
    )
/*++

Description:

    This routine initializes connection object.
    It is invoked by BthEchoConnectionObjectCreate.

Arguments:

    ConnectionObject - Object to initialize
    DevCtxHdr - Device context header

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status;
    WDF_OBJECT_ATTRIBUTES attributes;
    PBTHECHO_CONNECTION connection = GetConnectionObjectContext(ConnectionObject);

    
    connection->DevCtxHdr = DevCtxHdr;

    connection->ConnectionState = ConnectionStateInitialized;

    //
    // Initialize spinlock
    //
    
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = ConnectionObject;

    status = WdfSpinLockCreate(
                               &attributes,
                               &connection->ConnectionLock
                               );
    if (!NT_SUCCESS(status))
    {
        goto exit;                
    }

    //
    // Create connect/disconnect request
    //
    
    status = WdfRequestCreate(
        &attributes,
        DevCtxHdr->IoTarget,
        &connection->ConnectDisconnectRequest
        );

    if (!NT_SUCCESS(status))
    {
        return status;
    }

    //
    // Initialize event
    //
    
    KeInitializeEvent(&connection->DisconnectEvent, NotificationEvent, TRUE);

    //
    // Initalize list entry
    //

    InitializeListHead(&connection->ConnectionListEntry);

    connection->ConnectionState = ConnectionStateInitialized;

exit:
    return status;
}
Ejemplo n.º 11
0
NTSTATUS
BthEchoRepeatReaderInitialize(
    _In_ PBTHECHO_CONNECTION Connection,
    _In_ PBTHECHO_REPEAT_READER RepeatReader,
    _In_ size_t BufferSize    
    )

/*++

Description:

    This routine initializes repeat reader.

Arguments:

    Connection - Connection with which this repeat reader is associated
    RepeatReader - Repeat reader
    BufferSize - Buffer size for read

Return Value:

    NTSTATUS Status code.

--*/

{
    NTSTATUS status;
    WDF_OBJECT_ATTRIBUTES attributes;

    //
    // Create request object for pending read
    // Set connection object as the parent for the request
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = WdfObjectContextGetObject(Connection);

    status = WdfRequestCreate(
        &attributes,
        Connection->DevCtxHdr->IoTarget,
        &RepeatReader->RequestPendingRead
        );                    

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_CONT_READER, 
            "Creating request for pending read failed, "
            "Status code %!STATUS!\n",
            status
            );

        goto exit;
    }

    if (BufferSize <= 0)
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_CONT_READER,
            "BufferSize has an invalid value: %I64d\n",
            BufferSize
            );

        status = STATUS_INVALID_PARAMETER;

        goto exit;
    }

    //
    // Create memory object for the pending read
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = RepeatReader->RequestPendingRead;

    status = WdfMemoryCreate(
        &attributes,
        NonPagedPoolNx,
        POOLTAG_BTHECHOSAMPLE,
        BufferSize,
        &RepeatReader->MemoryPendingRead,
        NULL //buffer
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_CONT_READER, 
            "Creating memory for pending read failed, "
            "Status code %!STATUS!\n",
            status
            );

        goto exit;
    }

    //
    // Initialize Dpc that we will use for resubmitting pending read
    //
    KeInitializeDpc(
        &RepeatReader->ResubmitDpc, 
        BthEchoRepeatReaderResubmitReadDpc, 
        Connection->DevCtxHdr
        );

    //
    // Initialize event used to wait for stop.
    // This even is created as signalled. It gets cleared when
    // request is submitted.
    //
    KeInitializeEvent(&RepeatReader->StopEvent, NotificationEvent, TRUE);

    RepeatReader->Connection = Connection;
    
exit:
    if (!NT_SUCCESS(status))
    {
        BthEchoRepeatReaderUninitialize(RepeatReader);
    }
    
    return status;
}
Ejemplo n.º 12
0
NTSTATUS
I2COpen(
    _In_ PDEVICE_CONTEXT DeviceContext
)
/*++

Routine Description:

    This routine opens a handle to the I2C controller.

Arguments:

    DeviceContext - a pointer to the device context

Return Value:

    NTSTATUS

--*/
{
    TRACE_FUNC_ENTRY(TRACE_I2C);

    PAGED_CODE();

    NTSTATUS status;
    WDF_IO_TARGET_OPEN_PARAMS openParams;
    WDF_OBJECT_ATTRIBUTES requestAttributes;
    WDF_OBJECT_ATTRIBUTES workitemAttributes;
    WDF_WORKITEM_CONFIG workitemConfig;

    // Create the device path using the connection ID.
    DECLARE_UNICODE_STRING_SIZE(DevicePath, RESOURCE_HUB_PATH_SIZE);

    RESOURCE_HUB_CREATE_PATH_FROM_ID(
        &DevicePath,
        DeviceContext->I2CConnectionId.LowPart,
        DeviceContext->I2CConnectionId.HighPart);

    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_I2C,
        "Opening handle to I2C target via %wZ", &DevicePath);

    status = WdfIoTargetCreate(DeviceContext->Device, WDF_NO_OBJECT_ATTRIBUTES, &DeviceContext->I2CIoTarget);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfIoTargetCreate failed - %!STATUS!", status);
        goto Exit;
    }

    // Open a handle to the I2C controller.
    WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
        &openParams,
        &DevicePath,
        (GENERIC_READ | GENERIC_WRITE));

    openParams.ShareAccess = 0;
    openParams.CreateDisposition = FILE_OPEN;
    openParams.FileAttributes = FILE_ATTRIBUTE_NORMAL;

    status = WdfIoTargetOpen(DeviceContext->I2CIoTarget, &openParams);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "Failed to open I2C I/O target - %!STATUS!", status);
        goto Exit;
    }

    // Create a WDFMEMORY object. Do call WdfMemoryAssignBuffer before use it,
    status = WdfMemoryCreatePreallocated(
        WDF_NO_OBJECT_ATTRIBUTES,
        static_cast<PVOID>(&status), // initial value does not matter
        sizeof(status),
        &DeviceContext->I2CMemory);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfMemoryCreatePreallocated failed with status %!STATUS!", status);
        goto Exit;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&requestAttributes);
    requestAttributes.ParentObject = DeviceContext->I2CIoTarget;

    for (ULONG i = 0; i < I2CRequestSourceMax; i++)
    {
        status = WdfRequestCreate(&requestAttributes, DeviceContext->I2CIoTarget, &DeviceContext->OutgoingRequests[i]);
        if (!NT_SUCCESS(status))
        {
            TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
                "WdfRequestCreate failed with status %!STATUS!", status);
            goto Exit;
        }
    }

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&workitemAttributes, WORKITEM_CONTEXT);
    workitemAttributes.ParentObject = DeviceContext->I2CIoTarget;

    WDF_WORKITEM_CONFIG_INIT(&workitemConfig, EvtWorkItemGetStatus);
    status = WdfWorkItemCreate(&workitemConfig, &workitemAttributes, &DeviceContext->I2CWorkItemGetStatus);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfWorkItemCreate failed with status %!STATUS!", status);
        goto Exit;
    }

    WDF_WORKITEM_CONFIG_INIT(&workitemConfig, EvtWorkItemGetControl);
    status = WdfWorkItemCreate(&workitemConfig, &workitemAttributes, &DeviceContext->I2CWorkItemGetControl);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_I2C,
            "WdfWorkItemCreate failed with status %!STATUS!", status);
        goto Exit;
    }

Exit:
    TRACE_FUNC_EXIT(TRACE_I2C);
    return status;
}
Ejemplo n.º 13
0
NTSTATUS
kmdf1394_BusResetNotification (
                              IN WDFDEVICE Device,
                              IN WDFREQUEST Request,
                              IN ULONG fulFlags)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device);
    PIRB pIrb = NULL;
    WDFREQUEST newRequest = NULL;

    ENTER("kmdf1394_BusResetNotification");

    pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV);
    if (!pIrb) 
    {
        TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    if(!Request) 
    {
        ntStatus = WdfRequestCreate (
            WDF_NO_OBJECT_ATTRIBUTES,
            deviceExtension->StackIoTarget,
            &newRequest);

        if (!NT_SUCCESS (ntStatus)) 
        {
            TRACE(TL_ERROR, ("Failed to allocate request!\n"));

            ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV);
            return ntStatus;
        }

        Request = newRequest;
    }

    RtlZeroMemory (pIrb, sizeof (IRB));
    pIrb->FunctionNumber = REQUEST_BUS_RESET_NOTIFICATION;
    pIrb->Flags = 0;
    pIrb->u.BusResetNotification.fulFlags = fulFlags;
    pIrb->u.BusResetNotification.ResetRoutine = kmdf1394_BusResetRoutine;
    pIrb->u.BusResetNotification.ResetContext = Device;

    ntStatus = kmdf1394_SubmitIrpSynch(
        deviceExtension->StackIoTarget, 
        Request, 
        pIrb);
    if (!NT_SUCCESS(ntStatus))
    {
        TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
    }
    
    ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV);
    
    if (newRequest)
    {
        WdfObjectDelete (newRequest);
    }
   
    EXIT("kmdf1394_BusResetNotification", ntStatus);
    return ntStatus;
} // kmdf1394_BusResetNotification