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

📄 filter.cpp

📁 audio and video stream driver for windows. Tool: winddk
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            ) 
        *   ULONGLONG(LinesToCopy)
        ) 
    /   ULONGLONG(10000000)
    );
    for (Line = 0; (Line < LinesToCopy); Line++, Image += biWidthBytes) {
#if 1
        // Show some action on an otherwise static image
        // This will be a changing grayscale horizontal band
        // at the bottom of an RGB image and a changing color band at the 
        // top of a YUV image

        if (Line >= 3 && Line <= 6) {
            UINT j;
            for (j = 0; j < biWidthBytes; j++) {
                *(Image + j) = (UCHAR) m_FrameInfo.PictureNumber;
            }
            continue;
        }
#endif
        // Copy the synthesized line
        if (Line > cutoff) {
            RtlCopyMemory(
                    Image,
                    m_LineBuffer,
                    biWidthBytes );
        } else {
            RtlZeroMemory(
                    Image,
                    biWidthBytes );
        }
    }

    //
    // Report back the actual number of bytes copied to the destination buffer
    // (This can be smaller than the allocated buffer for compressed images)
    //

    return ByteCount;
}


void
CCapFilter::
CopyAudioData(
    OUT PVOID Data, 
    IN ULONG cBytes
    )

/*++

Routine Description:

    Copies cBytes worth of audio data from internal buffer 
    to memory pointed by Data.

Arguments:

    OUT PVOID Data - buffer where audio data should be copied

    IN ULONG cBytes - number of bytes to copy
    
Return Value:

--*/

{
    _DbgPrintF(DEBUGLVL_BLAB,("CopyAudioData"));
    
    ULONG cNextBytes;
    //
    // Copies from current offset in buffer to end. 
    // If this is not enough, restarts from begining.
    //
    do {
        cNextBytes = min(cBytes, m_ulAudioBufferSize - m_ulAudioBufferOffset);
        RtlCopyMemory(Data, &m_pAudioBuffer[m_ulAudioBufferOffset], cNextBytes);
        m_ulAudioBufferOffset = (m_ulAudioBufferOffset + cNextBytes) % m_ulAudioBufferSize;
        cBytes -= cNextBytes;
    
    } while (cBytes > 0 );
}


VOID 
CCapFilter::RegisterSample(
    IN SampleType Type, 
    IN LONGLONG TimeStamp,
    IN ULONGLONG Size
    )

/*++

Routine Description:

    Registers the output moment and size of a frame

Arguments:

    IN SampleType Type - frame type (audio or video)

    IN ULONGLONG TimeStamp - frame's timestamp
    
    IN ULONGLONG  Size - frame's size
    
Return Value:

--*/

{
    _DbgPrintF(DEBUGLVL_BLAB,("RegisterSample"));
    
    if (m_iSample < m_cSamples) {
        m_rgSamples[m_iSample].m_type = Type;
        m_rgSamples[m_iSample].m_ullSize = Size;
        m_rgSamples[m_iSample].m_llTimeStamp = TimeStamp;
    }
}


VOID 
CCapFilter::DumpSamples(
    )

/*++

Routine Description:

    Dump information about sent frames to debugger

Arguments:
    
Return Value:

--*/

{
    _DbgPrintF(DEBUGLVL_BLAB,("DumpSamples"));
    
    for (ULONG iSmp = 0; iSmp < m_iSample; iSmp++) {
        
        if ( m_rgSamples[iSmp].m_type == Audio ) {
            
            DbgPrint("ASmp[%lu] = %I64d, %I64u\n",
                     m_rgSamples[iSmp].m_llTimeStamp,
                     m_rgSamples[iSmp].m_ullSize);
        }
        else {
            
            DbgPrint("VSmp[%lu] = %I64d, %I64u\n",
                     m_rgSamples[iSmp].m_llTimeStamp,
                     m_rgSamples[iSmp].m_ullSize);
        }
    }

    m_iSample = 0;
}

#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA


NTSTATUS 
CCapFilter::
CopyFile(
    IN PWCHAR FileName
    )
/*++

Routine Description:
    Copies the content of a file to an internal buffer

Arguments:
    IN PWCHAR FileName -
        Name of the file to be copied

Return:
    Status of copy operation.

--*/
{
    _DbgPrintF(DEBUGLVL_BLAB,("CopyFile"));
    
    NTSTATUS status;
    IO_STATUS_BLOCK ioStatusBlock;
    UNICODE_STRING fileNameString;
    OBJECT_ATTRIBUTES objectAttributes;
    ACCESS_MASK desiredHandleAccess;
    ACCESS_MASK desiredObjectAccess;
    ULONG ulShareAccess;
    ULONG ulDisposition;
    FILE_STANDARD_INFORMATION StandardInformation;
    HANDLE hFile = NULL;
    FILE_OBJECT *pFileObject = NULL;

    //
    // Attempt to open the file based on the access rights of the caller.
    // Note that the SYNCHRONIZE flag must be set on the Create even
    // though this is contained in the translated GENERIC_READ attributes.
    // This is because the bit is tested before the Generic attributes
    // are translated. This filter only does synchronous I/O on stream
    // Read requests.
    //

    RtlInitUnicodeString(&fileNameString, FileName);

    InitializeObjectAttributes(
        &objectAttributes,
        &fileNameString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    //
    // Set the access desired based on the type of filter which was
    // actually created.
    //

    desiredHandleAccess = GENERIC_READ | SYNCHRONIZE;
    desiredObjectAccess = FILE_READ_DATA;
    ulShareAccess = FILE_SHARE_READ;
    ulDisposition = FILE_OPEN;
    
    status = IoCreateFile(&hFile,
                          desiredHandleAccess,
                          &objectAttributes,
                          &ioStatusBlock,
                          NULL,
                          0,
                          ulShareAccess,
                          ulDisposition,
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_FORCE_ACCESS_CHECK | IO_NO_PARAMETER_CHECKING);
    
    if ( !NT_SUCCESS(status) ) {
        _DbgPrintF(DEBUGLVL_BLAB, ("Failed to open file, error 0x%lx", status));
        goto error;
    }
    
    status = ObReferenceObjectByHandle(hFile,
                                       desiredObjectAccess,
                                       *IoFileObjectType,
                                       ExGetPreviousMode(),
                                       reinterpret_cast<void **>(&pFileObject),
                                       NULL);
    if ( !NT_SUCCESS(status) ) {
        goto error;
    }
    

    if (m_pAudioBuffer != NULL) {
        
        ExFreePool(m_pAudioBuffer);
        m_pAudioBuffer = NULL;
    }
    m_ulAudioBufferOffset = 0;
    m_ulAudioBufferSize = 0;

    //
    // retrieve file's size
    //
    status = KsQueryInformationFile(pFileObject,
                                    &StandardInformation,
                                    sizeof(StandardInformation),
                                    FileStandardInformation);
    if ( !NT_SUCCESS(status) || StandardInformation.EndOfFile.QuadPart > MAXLONG ) {
        goto error;
    }
    else {
        m_ulAudioBufferSize = (LONG)(StandardInformation.EndOfFile.QuadPart);
        _DbgPrintF(DEBUGLVL_TERSE, ("File size is %lu", 
                                    m_ulAudioBufferSize));
    }

    //
    // allocate a buffer to hold file's content
    //
    m_pAudioBuffer = (BYTE*)ExAllocatePoolWithTag(NonPagedPool,
                                                  m_ulAudioBufferSize,
                                                  'dfZB');
    if ( m_pAudioBuffer == NULL ) {
        _DbgPrintF(DEBUGLVL_TERSE, ("Failed to allocate file data buffer"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto error;
    }

    //
    // read file's content to buffer
    //
    status = KsReadFile(pFileObject,
                        NULL,
                        NULL,
                        &ioStatusBlock,
                        m_pAudioBuffer,
                        m_ulAudioBufferSize,
                        0,
                        KernelMode);
    
error:
    if ( !NT_SUCCESS(status) && m_pAudioBuffer != NULL ) {
        ExFreePool(m_pAudioBuffer);
        m_pAudioBuffer = NULL;
    }

    if ( pFileObject != NULL ) {
        ObDereferenceObject(pFileObject);
    }

    if ( hFile != NULL ) {
        ZwClose(hFile);
    }

    return status;
}


NTSTATUS
CCapFilter::
FilterCreate(
    IN OUT PKSFILTER Filter,
    IN PIRP Irp
    )
/*++

Routine Description:
    Handle specific processing on filter create

Arguments:
    IN OUT PKSFILTER Filter -
        Filter instance data
        
    IN PIRP Irp - 
        Create request

Return:
    STATUS_SUCCESS if creation was handled successfully
    an error code otherwise

--*/
{
    _DbgPrintF(DEBUGLVL_BLAB,("FilterCreate"));

    PAGED_CODE();

    ASSERT(Filter);
    ASSERT(Irp);
    
    NTSTATUS status = STATUS_SUCCESS;
    CCapFilter *filter;

    do { //just to have something to break from
        
        //
        // alocate and initialize filter instance
        //
        filter = new(NonPagedPool,'pChS') CCapFilter;
        if ( filter == NULL ) {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        filter->m_pKsFilter = Filter;
        Filter->Context = PVOID(filter);
        filter->m_pFilterObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;

        //
        // copy audio data
        //
        // uncomment when audio is required.
        //
        //status = filter->CopyFile(L"\\DosDevices\\C:\\avssamp.dat");
        //if ( ! NT_SUCCESS(status) ) {
        //	DbgPrint( "avssamp: Must have file c:\\avssamp.dat\n" );
        //    break;
        //}

        //
        // allocate n array for debug timestamps
        //
        filter->m_rgTimestamps = 
            reinterpret_cast<TS_SIGN *>(
                ExAllocatePoolWithTag(NonPagedPool, 
                                      sizeof(TS_SIGN)*MAX_TIMESTAMPS,
                                      'stCK'));
        if ( filter->m_rgTimestamps == NULL ) {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }

    } while ( FALSE );

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


NTSTATUS
CCapFilter::
FilterClose(
    IN OUT PKSFILTER Filter,
    IN PIRP Irp
    )
/*++

Routine Description:
    Handle specific processing on filter close

Arguments:
    IN OUT PKSFILTER Filter -
        Filter instance data
        
    IN PIRP Irp - 
        Create request

Return:
    STATUS_SUCCESS

--*/
{

⌨️ 快捷键说明

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