decssinputpin.cpp.svn-base
来自「ffshow源码」· SVN-BASE 代码 · 共 338 行
SVN-BASE
338 行
/* * Copyright (C) 2003-2004 Gabest * http://www.gabest.org * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * http://www.gnu.org/copyleft/gpl.html * */#include "stdafx.h"#include "DeCSSInputPin.h"#include "ffdshow_mediaguids.h"#include "CSSauth.h"#include "CSSscramble.h"//// CDeCSSInputPin//CDeCSSInputPin::CDeCSSInputPin(const char_t* pObjectName, CTransformFilter* pFilter, HRESULT* phr, const wchar_t *pName) : CTransformInputPin(pObjectName, pFilter, phr, pName){ m_varient = -1; memset(m_Challenge, 0, sizeof(m_Challenge)); memset(m_KeyCheck, 0, sizeof(m_KeyCheck)); memset(m_DiscKey, 0, sizeof(m_DiscKey)); memset(m_TitleKey, 0, sizeof(m_TitleKey));}STDMETHODIMP CDeCSSInputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv){ if (riid==IID_IKsPropertySet) return GetInterface<IKsPropertySet>(this,ppv); else return CTransformInputPin::NonDelegatingQueryInterface(riid, ppv);}// IMemInputPinSTDMETHODIMP CDeCSSInputPin::Receive(IMediaSample* pSample){ long len = pSample->GetActualDataLength(); BYTE* p = NULL; if(SUCCEEDED(pSample->GetPointer(&p)) && len > 0) { BYTE* base = p; if(m_mt.majortype == MEDIATYPE_DVD_ENCRYPTED_PACK && len == 2048 && (p[0x14]&0x30)) { CSSdescramble(p, m_TitleKey); p[0x14] &= ~0x30; if (comptrQ<IMediaSample2> pMS2=pSample) { AM_SAMPLE2_PROPERTIES props; memset(&props, 0, sizeof(props)); if(SUCCEEDED(pMS2->GetProperties(sizeof(props), (BYTE*)&props)) && (props.dwTypeSpecificFlags & AM_UseNewCSSKey)) { props.dwTypeSpecificFlags &= ~AM_UseNewCSSKey; pMS2->SetProperties(sizeof(props), (BYTE*)&props); } } } } HRESULT hr = Transform(pSample); return hr == S_OK ? CTransformInputPin::Receive(pSample) : hr == S_FALSE ? S_OK : hr;}void CDeCSSInputPin::StripPacket(BYTE*& p, long& len){ if(len > 0 && *(DWORD*)p == 0xba010000) // MEDIATYPE_*_PACK { len -= 14; p += 14; if(int stuffing = (p[-1]&7)) {len -= stuffing; p += stuffing;} } if(len > 0 && *(DWORD*)p == 0xbb010000) { len -= 4; p += 4; int hdrlen = ((p[0]<<8)|p[1]) + 2; len -= hdrlen; p += hdrlen; } if(len > 0 && ((*(DWORD*)p&0xf0ffffff) == 0xe0010000 || (*(DWORD*)p&0xe0ffffff) == 0xc0010000 || (*(DWORD*)p&0xbdffffff) == 0xbd010000)) // PES { bool ps1 = (*(DWORD*)p&0xbdffffff) == 0xbd010000; len -= 4; p += 4; int expected = ((p[0]<<8)|p[1]); len -= 2; p += 2; BYTE* p0 = p; for(int i = 0; i < 16 && *p == 0xff; i++, len--, p++); if((*p&0xc0) == 0x80) // mpeg2 { len -= 2; p += 2; len -= *p+1; p += *p+1; } else // mpeg1 { if((*p&0xc0) == 0x40) { len -= 2; p += 2; } if((*p&0x30) == 0x30 || (*p&0x30) == 0x20) { bool pts = !!(*p&0x20), dts = !!(*p&0x10); if(pts) len -= 5; p += 5; if(dts) {ASSERT((*p&0xf0) == 0x10); len -= 5; p += 5;} } else { len--; p++; } } if(ps1) { len--; p++; if(m_mt.subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO) {len -= 6; p += 6;} else if(m_mt.subtype == MEDIASUBTYPE_DOLBY_AC3 || m_mt.subtype == MEDIASUBTYPE_AC3_W || m_mt.subtype == MEDIASUBTYPE_DTS || m_mt.subtype == MEDIASUBTYPE_DTS) {len -= 3; p += 3;} } if(expected > 0) { expected -= int(p - p0); len = std::min((long)expected, len); } } if(len < 0) {ASSERT(0); len = 0;}}// IKsPropertySetSTDMETHODIMP CDeCSSInputPin::Set(REFGUID PropSet, ULONG Id, LPVOID pInstanceData, ULONG InstanceLength, LPVOID pPropertyData, ULONG DataLength){ if(PropSet != AM_KSPROPSETID_CopyProt) return E_NOTIMPL; switch(Id) { case AM_PROPERTY_COPY_MACROVISION: break; case AM_PROPERTY_DVDCOPY_CHLG_KEY: // 3. auth: receive drive nonce word, also store and encrypt the buskey made up of the two nonce words { AM_DVDCOPY_CHLGKEY* pChlgKey = (AM_DVDCOPY_CHLGKEY*)pPropertyData; for(int i = 0; i < 10; i++) m_Challenge[i] = pChlgKey->ChlgKey[9-i]; CSSkey2(m_varient, m_Challenge, &m_Key[5]); CSSbuskey(m_varient, m_Key, m_KeyCheck); } break; case AM_PROPERTY_DVDCOPY_DISC_KEY: // 5. receive the disckey { AM_DVDCOPY_DISCKEY* pDiscKey = (AM_DVDCOPY_DISCKEY*)pPropertyData; // pDiscKey->DiscKey holds the disckey encrypted with itself and the 408 disckeys encrypted with the playerkeys bool fSuccess = false; for(int j = 0; j < g_nPlayerKeys; j++) { for(int k = 1; k < 409; k++) { BYTE DiscKey[6]; int i; for(i = 0; i < 5; i++) DiscKey[i] = BYTE(pDiscKey->DiscKey[k*5+i] ^ m_KeyCheck[4-i]); DiscKey[5] = 0; CSSdisckey(DiscKey, g_PlayerKeys[j]); BYTE Hash[6]; for(i = 0; i < 5; i++) Hash[i] = BYTE(pDiscKey->DiscKey[i] ^ m_KeyCheck[4-i]); Hash[5] = 0; CSSdisckey(Hash, DiscKey); if(!memcmp(Hash, DiscKey, 6)) { memcpy(m_DiscKey, DiscKey, 6); j = g_nPlayerKeys; fSuccess = true; break; } } } if(!fSuccess) return E_FAIL; } break; case AM_PROPERTY_DVDCOPY_DVD_KEY1: // 2. auth: receive our drive-encrypted nonce word and decrypt it for verification { AM_DVDCOPY_BUSKEY* pKey1 = (AM_DVDCOPY_BUSKEY*)pPropertyData; int i; for(i = 0; i < 5; i++) m_Key[i] = pKey1->BusKey[4-i]; m_varient = -1; for(i = 31; i >= 0; i--) { CSSkey1(i, m_Challenge, m_KeyCheck); if(memcmp(m_KeyCheck, &m_Key[0], 5) == 0) m_varient = i; } } break; case AM_PROPERTY_DVDCOPY_REGION: break; case AM_PROPERTY_DVDCOPY_SET_COPY_STATE: break; case AM_PROPERTY_DVDCOPY_TITLE_KEY: // 6. receive the title key and decrypt it with the disc key { AM_DVDCOPY_TITLEKEY* pTitleKey = (AM_DVDCOPY_TITLEKEY*)pPropertyData; for(int i = 0; i < 5; i++) m_TitleKey[i] = BYTE(pTitleKey->TitleKey[i] ^ m_KeyCheck[4-i]); m_TitleKey[5] = 0; CSStitlekey(m_TitleKey, m_DiscKey); } break; default: return E_PROP_ID_UNSUPPORTED; } return S_OK;}STDMETHODIMP CDeCSSInputPin::Get(REFGUID PropSet, ULONG Id, LPVOID pInstanceData, ULONG InstanceLength, LPVOID pPropertyData, ULONG DataLength, ULONG* pBytesReturned){ if(PropSet != AM_KSPROPSETID_CopyProt) return E_NOTIMPL; switch(Id) { case AM_PROPERTY_DVDCOPY_CHLG_KEY: // 1. auth: send our nonce word { AM_DVDCOPY_CHLGKEY* pChlgKey = (AM_DVDCOPY_CHLGKEY*)pPropertyData; for(int i = 0; i < 10; i++) pChlgKey->ChlgKey[i] = BYTE(9 - (m_Challenge[i] = BYTE(i))); *pBytesReturned = sizeof(AM_DVDCOPY_CHLGKEY); } break; case AM_PROPERTY_DVDCOPY_DEC_KEY2: // 4. auth: send back the encrypted drive nonce word to finish the authentication { AM_DVDCOPY_BUSKEY* pKey2 = (AM_DVDCOPY_BUSKEY*)pPropertyData; for(int i = 0; i < 5; i++) pKey2->BusKey[4-i] = m_Key[5+i]; *pBytesReturned = sizeof(AM_DVDCOPY_BUSKEY); } break; case AM_PROPERTY_DVDCOPY_REGION: { DVD_REGION* pRegion = (DVD_REGION*)pPropertyData; pRegion->RegionData = 0; pRegion->SystemRegion = 0; *pBytesReturned = sizeof(DVD_REGION); } break; case AM_PROPERTY_DVDCOPY_SET_COPY_STATE: { AM_DVDCOPY_SET_COPY_STATE* pState = (AM_DVDCOPY_SET_COPY_STATE*)pPropertyData; pState->DVDCopyState = AM_DVDCOPYSTATE_AUTHENTICATION_REQUIRED; *pBytesReturned = sizeof(AM_DVDCOPY_SET_COPY_STATE); } break; default: return E_PROP_ID_UNSUPPORTED; } return S_OK;}STDMETHODIMP CDeCSSInputPin::QuerySupported(REFGUID PropSet, ULONG Id, ULONG* pTypeSupport){ if(PropSet != AM_KSPROPSETID_CopyProt) return E_NOTIMPL; switch(Id) { case AM_PROPERTY_COPY_MACROVISION: *pTypeSupport = KSPROPERTY_SUPPORT_SET; break; case AM_PROPERTY_DVDCOPY_CHLG_KEY: *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET; break; case AM_PROPERTY_DVDCOPY_DEC_KEY2: *pTypeSupport = KSPROPERTY_SUPPORT_GET; break; case AM_PROPERTY_DVDCOPY_DISC_KEY: *pTypeSupport = KSPROPERTY_SUPPORT_SET; break; case AM_PROPERTY_DVDCOPY_DVD_KEY1: *pTypeSupport = KSPROPERTY_SUPPORT_SET; break; case AM_PROPERTY_DVDCOPY_REGION: *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET; break; case AM_PROPERTY_DVDCOPY_SET_COPY_STATE: *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET; break; case AM_PROPERTY_DVDCOPY_TITLE_KEY: *pTypeSupport = KSPROPERTY_SUPPORT_SET; break; default: return E_PROP_ID_UNSUPPORTED; } return S_OK;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?