⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcampkt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
    // buffers passed in using logical addressing.  We are not going to touch these 
    // buffer at all.
    //
    pSrb->StreamObject->Pio = FALSE;


    //
    // Set to last saved configuration
    //
    SetCurrentDevicePropertyValues(pDevExt, (PIRB) pSrb->SRBExtension);


    DbgMsg1((" #OPEN_STREAM#: %s DCam, Status %x, pDevExt %x, pStrmEx %x, IsochDescriptorList is at %x\n", 
              pDevExt->pchVendorName, pSrb->Status, pDevExt, pDevExt->pStrmEx, &pDevExt->IsochDescriptorList));

    ASSERT(pSrb->Status == STATUS_SUCCESS);

}




VOID
DCamCloseStream(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )
/*++

Routine Description:

    Called when an CloseStream Srb request is received.  We get this when calling user 
    application do a CloseHandle() on the pin connection handle.  This can happen after
    HwUninitialize().

Arguments:

    pSrb - Pointer to Stream request block

Return Value:

    Nothing

--*/
{
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX     pStrmEx;
    PIRB pIrb;

    PAGED_CODE();

    pSrb->Status = STATUS_SUCCESS;

    pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
    ASSERT(pDevExt);      
    if(!pDevExt) {
        StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
        return;
    }

    //
    // Wait until all pending work items are completed!
    //
    KeWaitForSingleObject( &pDevExt->PendingWorkItemEvent, Executive, KernelMode, FALSE, NULL );


    pStrmEx = (PSTREAMEX)pDevExt->pStrmEx;
    ASSERT(pStrmEx);
    if(!pStrmEx ) {
        StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
        return;    
    } 

    //
    // pDevExt->Irb might have been freed in HwUninitialize() 
    // due to Surprise removal; so we must use this:
    // 
    pIrb = (PIRB) pSrb->SRBExtension;


    //
    // If it is still in use (setting it to stop failed?),
    // we will diable ISO_ENABLE so other application can use it.
    //

    if(!pDevExt->bDevRemoved && 
       DCamDeviceInUse(pIrb, pDevExt)) {

        DbgMsg1(("DCamCloseStream: Is still in use! Disable it!\n"));
        // Disable EnableISO
        DCamIsoEnable(pIrb, pDevExt, FALSE);
    }


    //
    // Save current state and free resource alllocaed in OpenStream()
    //
    DCamSetPropertyValuesToRegistry(pDevExt);


    //
    // Free Isoch resource and master clock
    //

    DCamFreeIsochResource (pDevExt, pIrb, TRUE);
    if(pStrmEx->pVideoInfoHeader) {
        ExFreePool(pStrmEx->pVideoInfoHeader);
        pStrmEx->pVideoInfoHeader = NULL;
    }

    pStrmEx->hMasterClock = 0;
   

    //                                                 
    // If there are pening read, cancel them all.                                
    //
    if(pDevExt->PendingReadCount > 0) {

        if( InterlockedExchange( &pStrmEx->CancelToken, 1 ) == 0 ) {

            DCamCancelAllPackets(
                pDevExt,
                &pDevExt->PendingReadCount
                );
        }        
    }
    
    pDevExt->pStrmEx = 0;

    StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);

}




VOID
DCamTimeoutHandler(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )
/*++

Routine Description:

    This routine is called when a packet has been in the minidriver too long (Srb->TimeoutCounter == 0).
    We will cancel the SRB if we are in the RUN state; else set ->TimeoutCounter and return.
    We assume the cancel SRB is serialized and in the same order as it is read.  So this timeout is
    applying to the head of the queue.

Arguments:

    pSrb - Pointer to Stream request block that has timeout.

Return Value:

    Nothing

--*/

{
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX pStrmEx;

    // Called from StreamClass at DisptchLevel


    //
    // We only expect stream SRB, but not device SRB.  
    //

    if ( (pSrb->Flags & SRB_HW_FLAGS_STREAM_REQUEST) != SRB_HW_FLAGS_STREAM_REQUEST) {
        ERROR_LOG(("DCamTimeoutHandler: Device SRB %x (cmd:%x) timed out!\n", pSrb, pSrb->Command));
        return;
    } 


    //
    // StreamSRB only valid if we have a stream extension
    //

    pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
    ASSERT(pDevExt);
    pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;

    if(!pStrmEx) {
        ERROR_LOG(("DCamTimeoutHandler: Stream SRB %x timeout with pDevExt %x, pStrmEx %x\n", pSrb, pDevExt, pStrmEx));
        ASSERT(pStrmEx);
        return;
    }
 
    //
    // Cancel IRP only if in RUN state, BUT...
    // Note: if we are TIMEOUT and in RUN state, something is terribley wrong.  
    //       but I guess that can happen when it is being suspended;
    //       so we will extend the time out for all states.
    //

    DbgMsg2(("\'DCamTimeoutHandler: pSrb %x, %s state, PendingReadCount %d.\n", 
        pSrb, 
        pStrmEx->KSState == KSSTATE_RUN   ? "RUN" : 
        pStrmEx->KSState == KSSTATE_PAUSE ? "PAUSE":
        pStrmEx->KSState == KSSTATE_STOP  ? "STOP": "Unknown",
        pDevExt->PendingReadCount));   

    // ASSERT(pStrmEx->KSState == KSSTATE_PAUSE);


    //
    // Reset Timeout counter, or we are going to get this call immediately.
    //

    pSrb->TimeoutCounter = pSrb->TimeoutOriginal;

}


NTSTATUS
DCamStartListenCR(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp,
    IN PDCAM_IO_CONTEXT pDCamIoContext    
    )

/*++

Routine Description:

    Returns more processing required so the IO Manager will leave us alone

Arguments:

    DriverObject - Pointer to driver object created by system.

    pIrp - Irp that just completed

    pDCamIoContext - Context 

Return Value:

    None.

--*/

{
    PDCAM_EXTENSION pDevExt;
    NTSTATUS Status;
    PIRB pIrb; 
    PIO_STACK_LOCATION NextIrpStack;

#ifdef WAIT_FOR_SLOW_DEVICE
    KeStallExecutionProcessor(5000);  // 5 msec
#endif

    DbgMsg2(("\'DCamStartListenCR: pIrp->IoStatus.Status=%x\n", pIrp->IoStatus.Status));

    if(STATUS_SUCCESS != pIrp->IoStatus.Status) {

        pDevExt = pDCamIoContext->pDevExt;
        pIrb = pDCamIoContext->pIrb;

        if(pDevExt->lRetries > 0) {

            pDevExt->lRetries--;
            DbgMsg1(("DCamStartListenCR: Try DCAM_RUNSTATE_SET_REQUEST_ISOCH_LISTEN again!\n"));
            
            pIrb->FunctionNumber = REQUEST_ISOCH_LISTEN;
            pIrb->Flags = 0;
            pIrb->u.IsochListen.hResource = pDevExt->hResource;
            pIrb->u.IsochListen.fulFlags = 0;

            NextIrpStack = IoGetNextIrpStackLocation(pIrp);
            NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
            NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
            NextIrpStack->Parameters.Others.Argument1 = pIrb;

            IoSetCompletionRoutine(
                pIrp,
                DCamStartListenCR,
                pDCamIoContext,
                TRUE,
                TRUE,
                TRUE
                );

            Status =
                IoCallDriver(
                    pDevExt->BusDeviceObject, 
                    pIrp);

            return STATUS_MORE_PROCESSING_REQUIRED;

        } else {
            ERROR_LOG(("Start Listening has failed Status=%x; try again in next read.\n", pIrp->IoStatus.Status)); 
            pDCamIoContext->pDevExt->bNeedToListen = TRUE;
        }
    }

    DCamFreeIrbIrpAndContext(pDCamIoContext, pDCamIoContext->pIrb, pIrp);

    // No StreamClassDeviceNotification() here since 
    // this is local initiated Irb (as part of AttachBufferCR().

    return STATUS_MORE_PROCESSING_REQUIRED;

}





/*
** AdapterCompareGUIDsAndFormatSize()
**
**   Checks for a match on the three GUIDs and FormatSize
**
** Arguments:
**
**         IN DataRange1
**         IN DataRange2
**
** Returns:
** 
**   TRUE if all elements match
**   FALSE if any are different
**
** Side Effects:  none
*/

BOOL 
AdapterCompareGUIDsAndFormatSize(
    IN PKSDATARANGE DataRange1,
    IN PKSDATARANGE DataRange2)
{
    PAGED_CODE();

    return (
        IsEqualGUID (
            &DataRange1->MajorFormat, 
            &DataRange2->MajorFormat) &&
        IsEqualGUID (
            &DataRange1->SubFormat, 
            &DataRange2->SubFormat) &&
        IsEqualGUID (
            &DataRange1->Specifier, 
            &DataRange2->Specifier) &&
        (DataRange1->FormatSize == DataRange2->FormatSize));
}

/*
** AdapterVerifyFormat()
**
**   Checks the validity of a format request by walking through the
**       array of supported PKSDATARANGEs for a given stream.
**
** Arguments:
**
**   pKSDataFormatVideoToVerify - pointer of a KS_DATAFORMAT_VIDEOINFOHEADER structure.
**   StreamNumber - index of the stream being queried / opened.
**
** Returns:
** 
**   TRUE if the format is supported
**   FALSE if the format cannot be suppored
**
** Side Effects:  none
*/

BOOL 
AdapterVerifyFormat(
    ULONG VideoModesSupported,
    PKSDATAFORMAT  *pDCamStrmModesSupported,
    PKS_DATAFORMAT_VIDEOINFOHEADER pDataFormatVideoToVerify, 
    int StreamNumber)
{
    PKS_VIDEOINFOHEADER         pVideoInfoHdrToVerify = &pDataFormatVideoToVerify->VideoInfoHeader;
    PKSDATAFORMAT               *paDataFormatsVideoAvail;  // an array of PKSDATAFORMAT (not PKS_DATARANGE_VIDEO !!)
    PKS_DATARANGE_VIDEO         pDataRangeVideo;
    KS_VIDEO_STREAM_CONFIG_CAPS *pConfigCaps; 
    PKS_BITMAPINFOHEADER        pbmiHeader, 
                                pbmiHeaderToVerify;
    int                         j;

    PAGED_CODE();
    
    //
    // Make sure the stream index is valid
    // We only has one capure pin/stream (index 0).
    //
    if (StreamNumber >= 1) {
        return FALSE;
    }

    //
    // Get the pointer to the array of available formats
    //
    paDataFormatsVideoAvail = &pDCamStrmModesSupported[0]; // &pDevExt->DCamStrmModes[0];


    //
    // Walk the array, searching for a match
    //
    for (j = 0; j < (LONG) VideoModesSupported; j++, paDataFormatsVideoAvail++) {

        pDataRangeVideo = (PKS_DATARANGE_VIDEO) *paDataFormatsVideoAvail;
        
        //
        // Check for matching size, Major Type, Sub Type, and Specifier
        //

        //
        // Check for matching size, Major Type, Sub Type, and Specifier
        //

        if (!IsEqualGUID (&pDataRangeVideo->DataRange.MajorFormat, 
            &pDataFormatVideoToVerify->DataFormat.MajorFormat)) {
               DbgMsg2(("\'%d) AdapterVerifyFormat: MajorFormat mismatch!\n", j));
               continue;
        }

        if (!IsEqualGUID (&pDataRangeVideo->DataRange.SubFormat, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -