📄 cxcopyprotectprop.cpp
字号:
/*+++ *******************************************************************\
*
* Copyright and Disclaimer:
*
* ---------------------------------------------------------------
* This software is provided "AS IS" without warranty of any kind,
* either expressed or implied, including but not limited to the
* implied warranties of noninfringement, merchantability and/or
* fitness for a particular purpose.
* ---------------------------------------------------------------
*
* Copyright (c) 2008 Conexant Systems, Inc.
* All rights reserved.
*
\******************************************************************* ---*/
#include "CxCopyProtectProp.h"
#include "IVideoDecoder.h"
#include "device.h"
#include "miscfuncs.h"
#include "debug.h"
CxCopyProtectProp::CxCopyProtectProp(
IVideoDecoder* p_decoder,
COPY_PROTECT_METHOD copy_protect_method
):
_p_decoder(p_decoder),
_scramble_thread_object(0),
_cp_count(0),
_method(copy_protect_method),
_video_muted(false)
{
KeInitializeEvent(
&_scramble_event_object,
SynchronizationEvent, // single wait satisfied resets it
FALSE // not signaled
);
}
CxCopyProtectProp::~CxCopyProtectProp()
{
}
VOID CxCopyProtectProp::videoMute()
{
if (_video_muted)
return;
_video_muted = true;
_p_decoder->videoMute();
}
VOID CxCopyProtectProp::videoUnmute()
{
if (!_video_muted)
return;
_video_muted = false;
_p_decoder->videoUnmute();
}
/////////////////////////////////////////////////////////////////////////////////////////
//CxFalconControlProp::static_getStatus
//
// Get copy protection status from the video decoder
//
NTSTATUS
CxCopyProtectProp::
static_getStatus(
PIRP p_irp,
PPROPERTY_DWORD p_request,
PDWORD p_data)
{
//DbgLogInfo((__FUNCTION__));
Device* p_device = getDevice(p_irp);
if(!p_device)
{
return STATUS_UNSUCCESSFUL;
}
if(!p_device->IsDevicePoweredUp() )
{
return STATUS_DEVICE_NOT_READY;
}
if(p_device->IsDeviceSurpriseRemoved() )
{
return STATUS_NO_SUCH_DEVICE;
}
IVideoDecoder* p_decoder = p_device->getVidDec();
*p_data = p_decoder->getCopyProtectStatus();
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Get copy Macrovision from the video decoder
//
NTSTATUS
CxCopyProtectProp::
static_getCopyMacrovision(
PIRP p_irp,
PPROPERTY_DWORD p_request,
PKS_COPY_MACROVISION p_copy_macrovision)
{
//DbgLogInfo((__FUNCTION__));
Device* p_device = getDevice(p_irp);
if(!p_device)
{
return STATUS_UNSUCCESSFUL;
}
if(!p_device->IsDevicePoweredUp() )
{
return STATUS_DEVICE_NOT_READY;
}
if(p_device->IsDeviceSurpriseRemoved() )
{
return STATUS_NO_SUCH_DEVICE;
}
IVideoDecoder* p_decoder = p_device->getVidDec();
p_copy_macrovision->MACROVISIONLevel = p_decoder->getCopyProtectStatus();
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID CxCopyProtectProp::checkCopyProtection()
{
DWORD cp_status = _p_decoder->getCopyProtectStatus();
switch(_method)
{
case CP_METHOD_BLACK:
cpBlack(cp_status);
break;
case CP_METHOD_FLASH:
cpFlash(cp_status);
break;
case CP_METHOD_NONE:
// should't actually get here;
break;
case CP_METHOD_USE_DEFAULT:
default:
cpDefault(cp_status);
}
}
VOID CxCopyProtectProp::cpBlack(DWORD cp_status)
{
if (cp_status)
{
videoMute();
}
else
{
videoUnmute();
}
}
VOID CxCopyProtectProp::cpFlash(DWORD cp_status)
{
if (cp_status)
{
// Throttle the flashing
if (_cp_count % 5)
{
videoMute();
}
else
{
videoUnmute();
}
_cp_count++;
}
else
{
videoUnmute();
}
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID CxCopyProtectProp::static_cpProc(CxCopyProtectProp* p_copy_protect_prop)
{
p_copy_protect_prop->cpProc();
}
VOID CxCopyProtectProp::cpProc()
{
while(true)
{
checkCopyProtection();
#define RELATIVE_WAIT(x) (-1*(x))
#define MICROSECONDS(x) ((x)*10L)
#define MILLISECONDS(x) ((x)*10000L)
#define SECONDS(x) ((x)*10000000L)
LARGE_INTEGER timeout;
timeout.QuadPart = RELATIVE_WAIT(SECONDS(1));
// Wait until our thread is signalled or time has expired (whichever is shorter)
NTSTATUS status = KeWaitForSingleObject(
&_scramble_event_object,
Executive,
KernelMode,
TRUE,
&timeout
);
if(STATUS_TIMEOUT != status) // status == STATUS_SUCCES when signalled
{
break;
}
}
videoUnmute();
//Set our thread object to NULL so that a new thread is started next time.
PsTerminateSystemThread(STATUS_SUCCESS);
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS CxCopyProtectProp::startCpThread()
{
if (_method == CP_METHOD_NONE)
{
return STATUS_SUCCESS;
}
if (_scramble_thread_object)
{
return STATUS_UNSUCCESSFUL;
}
HANDLE thread_handle;
NTSTATUS status = PsCreateSystemThread(
&thread_handle,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE) CxCopyProtectProp::static_cpProc, // Thread routine
this); // Context
if(!NT_SUCCESS(status))
return status;
return ObReferenceObjectByHandle(
thread_handle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&_scramble_thread_object,
NULL);
}
VOID CxCopyProtectProp::stopCpThread()
{
//Don't try to stop the thread if it isn't started.
if(!_scramble_thread_object)
{
return;
}
// signal the thread
LONG status = KeSetEvent(
&_scramble_event_object,
IO_NO_INCREMENT,
TRUE);
KeWaitForSingleObject(
_scramble_thread_object,
Executive,
KernelMode,
TRUE,
NULL);
_scramble_thread_object = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -