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

📄 dcampkt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:

    pDevExt->CurrentModeIndex = ModeIndex;
    DbgMsg2(("**IsochAlloc: hResource = %x\n", pDevExt->hResource));

    IoFreeIrp(Irp);     

    return STATUS_SUCCESS;



NoResource_abort:

    // Free bandwidth
    if(pDevExt->hBandwidth != NULL) {

        Irb->FunctionNumber = REQUEST_ISOCH_FREE_BANDWIDTH;
        Irb->Flags = 0;
        Irb->u.IsochFreeBandwidth.hBandwidth = pDevExt->hBandwidth;
        Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);
        pDevExt->hBandwidth = NULL;
        if(Status) {
            ERROR_LOG(("DCamAllocateIsochResource: Error %x while trying to free Isoch bandwidth\n", Status));
        }
    }

    // Free channel
    if (pDevExt->IsochChannel != ISOCH_ANY_CHANNEL) {

        Irb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL;
        Irb->Flags = 0;
        Irb->u.IsochFreeChannel.nChannel = pDevExt->IsochChannel;
        Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);
        pDevExt->IsochChannel = ISOCH_ANY_CHANNEL;  // Reset it.

        if(Status) {
            ERROR_LOG(("DCamAllocateIsochResource: Error %x while trying to free Isoch channel\n", Status));
        }
    }


    IoFreeIrp(Irp);
    return STATUS_INSUFFICIENT_RESOURCES;
    
}


NTSTATUS
DCamFreeIsochResource (
    PDCAM_EXTENSION pDevExt,
    PIRB Irb,
    BOOL bFreeResource
    )
/*++

Routine Description:

    Free resource allocated in DCamAllocateIsochResource().

Arguments:

    Srb - Pointer to Stream request block

Return Value:

    Nothing

--*/
{
    PIRP Irp;
    CCHAR StackSize;
    NTSTATUS Status = STATUS_SUCCESS;


    PAGED_CODE();

    DbgMsg2(("\'DCamFreeIsochResource: enter; DevExt=%x, Irb=%x\n", pDevExt, Irb));

    ASSERT(pDevExt);
    ASSERT(Irb);


    if(Irb == 0 ||
       pDevExt == 0) {
       DbgMsg2(("\'DCamFreeIsochResource: ABORTED!\n"));
       return STATUS_SUCCESS;
    }
    //
    // Get an Irp so we can send some free commands down
    //
    StackSize = pDevExt->BusDeviceObject->StackSize;
    Irp = IoAllocateIrp(StackSize, FALSE);

    if (!Irp) {   
        ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to allocate an Irp\n\n", Status));
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    //
    // 1. Free Resource
    //
    if (pDevExt->hResource && bFreeResource) {

        DbgMsg2(("\'DCamFreeIsochResource: Attempt to free ->hResource\n"));

        Irb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
        Irb->Flags = 0;
        Irb->u.IsochFreeResources.hResource = pDevExt->hResource;
        Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);

        pDevExt->hResource = NULL;
        if (Status) {

            ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to free Isoch resources\n\n", Status));
        }
    }

    //
    // 2. Free Channel
    //
    if (pDevExt->IsochChannel != ISOCH_ANY_CHANNEL) {

        DbgMsg2(("\'DCamFreeIsochResource: Attempt to free ->IsochChannel\n"));

        Irb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL;
        Irb->Flags = 0;
        Irb->u.IsochFreeChannel.nChannel = pDevExt->IsochChannel;
        Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);

        pDevExt->IsochChannel = ISOCH_ANY_CHANNEL;

        if(Status) {
            
            ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to free Isoch channel\n\n", Status));
        }
    }

    //
    // 3. Free Bandwidth
    //
    if (pDevExt->hBandwidth) {

        DbgMsg2(("\'DCamFreeIsochResource: Attempt to free ->hBandwidth\n"));

        Irb->FunctionNumber = REQUEST_ISOCH_FREE_BANDWIDTH;
        Irb->Flags = 0;
        Irb->u.IsochFreeBandwidth.hBandwidth = pDevExt->hBandwidth;
        Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);

        pDevExt->hBandwidth = NULL;

        if (Status) {

            ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to free Isoch bandwidth\n", Status));
        }
    }

    DbgMsg2(("\'DCamFreeIsochResource: hResource = %x\n", pDevExt->hResource));


    IoFreeIrp(Irp);

    return STATUS_SUCCESS;

}



VOID 
InitializeStreamExtension(
    PDCAM_EXTENSION pDevExt,
    PHW_STREAM_OBJECT   pStreamObject,
    PSTREAMEX           pStrmEx
    )
{
    PAGED_CODE();

    pStrmEx->hMasterClock = 0;
    pStrmEx->FrameInfo.ExtendedHeaderSize = sizeof(KS_FRAME_INFO);
    pStrmEx->FrameInfo.PictureNumber = 0;
    pStrmEx->FrameInfo.DropCount     = 0;
    pStrmEx->FrameInfo.dwFrameFlags  = 0;     
    pStrmEx->FirstFrameTime    = 0;
    pStrmEx->pVideoInfoHeader  = 0;
    pStrmEx->KSState           = KSSTATE_STOP;
    pStrmEx->KSSavedState      = KSSTATE_STOP;
    pStrmEx->CancelToken       = 0;

    KeInitializeMutex( &pStrmEx->hMutex, 0);  // Level 0 and in Signal state

}

BOOL
DCamDeviceInUse(
    PIRB pIrb,
    PDCAM_EXTENSION pDevExt
)
/*++

Routine Description:

    See if this device is in used.  
    We check ISO_ENABLE since this is the only register
    in a 1394DCam that we can set/get and 99%+ of time
    this bit is set by its owner.

Arguments:

    pIrb - Pointer to IEEE 1394 Request Block definition (IRB)
    pDevExt - this device extension

Return Value:

    TRUE:  Iso_enable != 0
    FALSE: iso_enable == 0

--*/

{
    DCamRegArea RegArea;
    NTSTATUS status;
    LONG lRetries = MAX_READ_REG_RETRIES;


    // If a device is removed, it is not available.
    if(pDevExt->bDevRemoved)
        return TRUE;

    do {
        RegArea.AsULONG = 0;
        status = DCamReadRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, IsoEnable), &(RegArea.AsULONG));
#if DBG
        if(!NT_SUCCESS(status))
            ERROR_LOG(("**** DCamDeviceInUse: Status %x, ISO_ENABLE %x\n", status, RegArea.AsULONG));
#endif
    } while (--lRetries > 0 && !NT_SUCCESS(status));

    if(NT_SUCCESS(status)) 
        return ((RegArea.AsULONG & ISO_ENABLE_BIT) == ISO_ENABLE_BIT);

    // failed to query the device.
    return TRUE;  // Assume it is in use.
}


VOID
DCamOpenStream(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )

/*++

Routine Description:

    Called when an OpenStream Srb request is received

Arguments:

    pSrb - Pointer to Stream request block

Return Value:

    Nothing

--*/

{

    PIRB Irb;
    ULONG nSize;
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX pStrmEx;
    PKS_DATAFORMAT_VIDEOINFOHEADER  pKSDataFormat = 
                (PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
    PKS_VIDEOINFOHEADER     pVideoInfoHdrRequested = 
                &pKSDataFormat->VideoInfoHeader;


    PAGED_CODE();

    Irb = (PIRB) pSrb->SRBExtension;
    pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
    pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;

    DbgMsg2(("\'DCamOpenStream: >>> !!! pDevEx %x; pStrmEx %x !!!\n", pDevExt, pStrmEx));


    //
    // Cache the stream extension.
    //

    pDevExt->pStrmEx = pStrmEx; 


    //
    // default to success
    //

    pSrb->Status = STATUS_SUCCESS;

    //
    // determine which stream number is being opened.  This number indicates
    // the offset into the array of streaminfo structures that was filled out
    // in the AdapterStreamInfo call.
    //
    // So:
    //   0 - Video data from camera
    //

    switch (pSrb->StreamObject->StreamNumber) {

    case 0:

         //
         // Make sure that this device is not in used 
         //
         if(DCamDeviceInUse(Irb, pDevExt)) {
             ERROR_LOG(("Device is in used! Open Stream fail!!\n"));
             pDevExt->pStrmEx = NULL; 
             pSrb->Status = STATUS_UNSUCCESSFUL;
             return;
         }


         //
         // Figure out what format they're trying to open first
         //

         if (!AdapterVerifyFormat (pDevExt->ModeSupported, pDevExt->DCamStrmModes, pKSDataFormat, pSrb->StreamObject->StreamNumber)) {
             pDevExt->pStrmEx = NULL; 
             ERROR_LOG(("DCamOpenStream: AdapterVerifyFormat failed.\n"));
             pSrb->Status = STATUS_INVALID_PARAMETER;
             return;
         }

         InitializeStreamExtension(pDevExt, pSrb->StreamObject, pStrmEx);

         // It should already been freed by DCamCloseStream()
         ASSERT(pStrmEx->pVideoInfoHeader == NULL);
         ASSERT(pVideoInfoHdrRequested != (PKS_VIDEOINFOHEADER) 0);

         // 
         // use our safe version of KS_SIZE_VIDEOHEADER
         //
         if (!NT_SUCCESS(RTL_SAFE_KS_SIZE_VIDEOHEADER(pVideoInfoHdrRequested, &nSize))) {

             pSrb->Status = STATUS_INTEGER_OVERFLOW;
             return;
         }

         pStrmEx->pVideoInfoHeader = ExAllocatePoolWithTag(NonPagedPool, nSize, 'macd');
         if (pStrmEx->pVideoInfoHeader == NULL) {

             ERROR_LOG(("DCamOpenStream: ExAllocatePool (->pVideoInfoHeader) failed!\n"));
             ASSERT(pStrmEx->pVideoInfoHeader != NULL);

             pDevExt->pStrmEx = NULL;

             pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
             return;
         }

         // Copy the VIDEOINFOHEADER requested to our storage
         RtlCopyMemory(
                    pStrmEx->pVideoInfoHeader,
                    pVideoInfoHdrRequested,
                    nSize);

         DbgMsg3(("\'DCamOpenStream: Copied biSizeImage=%d Duration=%ld (100ns)\n", 
                    pStrmEx->pVideoInfoHeader->bmiHeader.biSizeImage, (DWORD) pStrmEx->pVideoInfoHeader->AvgTimePerFrame));

         // Allocate ISOCH resource
         pSrb->Status = DCamAllocateIsochResource(pDevExt, pSrb->SRBExtension, TRUE);               
         
         if (pSrb->Status) {

             ERROR_LOG(("DCamOpenStream: !!!! Allocate ISOCH resource failed.  CanNOT STREAM!!!!!\n"));
             
             ExFreePool(pStrmEx->pVideoInfoHeader);
             pStrmEx->pVideoInfoHeader = NULL;             
             pDevExt->pStrmEx = NULL;
             pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;             
             return;
         } 

         pSrb->StreamObject->ReceiveDataPacket    = (PVOID) DCamReceiveDataPacket;
         pSrb->StreamObject->ReceiveControlPacket = (PVOID) DCamReceiveCtrlPacket;

         // If bus reset failed and user close the stream and reopen the stream successfully,
         // This must be reset !!
         if(pDevExt->bDevRemoved || pDevExt->bStopIsochCallback) {
            DbgMsg1(("Stream Open successful, reset bDevRemoved and bStopCallback!!\n"));
            pDevExt->bStopIsochCallback = FALSE;
            pDevExt->bDevRemoved = FALSE;
         }

         //
         // initialize the stream extension data handling information
         //

         break;

    default:
         ERROR_LOG(("DCamOpenStream: Hit a non-support pSrb->StreamObject->StreamNumber (%d).\n", pSrb->StreamObject->StreamNumber));
         ASSERT(FALSE);
         pDevExt->pStrmEx = NULL; 
         pSrb->Status = STATUS_INVALID_PARAMETER;
         return;
    }


    pSrb->StreamObject->HwClockObject.ClockSupportFlags = 0;

    // We don't use DMA.
    pSrb->StreamObject->Dma = FALSE;
    pSrb->StreamObject->StreamHeaderMediaSpecific = sizeof(KS_FRAME_INFO);

    //
    // The PIO flag must be set when the mini driver will be accessing the data

⌨️ 快捷键说明

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