📄 filter.cpp
字号:
)
* 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 + -