00001
00002
00003
00004
00005
00006 #define WINVER 0x400
00007 #define _WIN32_IE 0x501
00008 #define _WIN32_WINNT 0x400
00009
00010 #include "fsDShowFilterDetector.h"
00011 #include "../system.h"
00012 #include <stdio.h>
00013
00014 fsDShowFilterDetector::fsDShowFilterDetector()
00015 {
00016 ZeroMemory(&m_mt, sizeof (m_mt));
00017 m_mt.lSampleSize = 1;
00018 m_mt.bFixedSizeSamples = TRUE;
00019 m_mt.majortype = MEDIATYPE_Stream;
00020 m_uFileOkLen = 0;
00021 }
00022
00023 fsDShowFilterDetector::~fsDShowFilterDetector()
00024 {
00025
00026 }
00027
00028 const AM_MEDIA_TYPE* fsDShowFilterDetector::DetectMediaType(HANDLE hFile, UINT64 uFileOkLen)
00029 {
00030 HKEY key;
00031 if (ERROR_SUCCESS != RegOpenKey (HKEY_CLASSES_ROOT,
00032 "Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}", &key))
00033 return NULL;
00034
00035 m_uFileOkLen = uFileOkLen;
00036 if (m_uFileOkLen == _UI64_MAX)
00037 {
00038 DWORD dw1, dw2;
00039 dw1 = GetFileSize (hFile, &dw2);
00040 m_uFileOkLen = UINT64 (dw1) | UINT64 (dw2) << 32;
00041 }
00042
00043 const AM_MEDIA_TYPE* mt = DetectMediaType (hFile, key);
00044
00045 RegCloseKey (key);
00046
00047 return mt;
00048 }
00049
00050 const AM_MEDIA_TYPE* fsDShowFilterDetector::Get_MediaType()
00051 {
00052 return &m_mt;
00053 }
00054
00055 const AM_MEDIA_TYPE* fsDShowFilterDetector::DetectMediaType(HANDLE hFile, HKEY hkFilters)
00056 {
00057 DWORD dwRes = ERROR_SUCCESS;
00058 char szKey [1000];
00059
00060 for (DWORD i = 0; dwRes == ERROR_SUCCESS; i++)
00061 {
00062 dwRes = RegEnumKey (hkFilters, i, szKey, sizeof (szKey));
00063
00064
00065 if (szKey [strlen (szKey)-1] != '}')
00066 strcat (szKey, "}");
00067
00068 if (dwRes == ERROR_SUCCESS)
00069 {
00070 HKEY hKey;
00071 if (ERROR_SUCCESS != RegOpenKey (hkFilters, szKey, &hKey))
00072 continue;
00073
00074 if (IsFilterMeets (hFile, hKey))
00075 {
00076 RegCloseKey (hKey);
00077 break;
00078 }
00079
00080 RegCloseKey (hKey);
00081 }
00082 }
00083
00084 if (dwRes != ERROR_SUCCESS)
00085 return NULL;
00086
00087 GUID guid;
00088 wchar_t szFilterGUID [1000];
00089 ZeroMemory (szFilterGUID, sizeof (szFilterGUID));
00090 MultiByteToWideChar (CP_ACP, 0, szKey, -1, szFilterGUID, 1000);
00091 if (FAILED (CLSIDFromString (szFilterGUID, &guid)))
00092 return NULL;
00093
00094 m_mt.subtype = guid;
00095
00096 return &m_mt;
00097 }
00098
00099 BOOL fsDShowFilterDetector::IsFilterMeets(HANDLE hFile, HKEY hkFilter)
00100 {
00101 DWORD dwRes = ERROR_SUCCESS;
00102 for (DWORD i = 0; dwRes == ERROR_SUCCESS; i++)
00103 {
00104 char szValue [1000], szData [1000];
00105 DWORD dwValLen = sizeof (szValue),
00106 dwDataLen = sizeof (szData);
00107 DWORD dwType;
00108
00109 dwRes = RegEnumValue (hkFilter, i, szValue, &dwValLen, NULL,
00110 &dwType, (LPBYTE)szData, &dwDataLen);
00111
00112 if (dwRes == ERROR_SUCCESS && dwType == REG_SZ)
00113 {
00114 if (stricmp (szValue, "Source Filter") == 0)
00115 continue;
00116
00117 if (IsFilterMeets (hFile, szData))
00118 return TRUE;
00119 }
00120 }
00121
00122 return FALSE;
00123 }
00124
00125 BOOL fsDShowFilterDetector::IsFilterMeets(HANDLE hFile, LPCSTR pszCheckBytes)
00126 {
00127 while (*pszCheckBytes)
00128 {
00129 char szOffset [100], szCb [100], szMask [10000], szVal [10000];
00130 int pos = 0;
00131
00132
00133 while (*pszCheckBytes && *pszCheckBytes == ' ')
00134 pszCheckBytes++;
00135
00136
00137 while (*pszCheckBytes && *pszCheckBytes != ',')
00138 szOffset [pos++] = *pszCheckBytes++;
00139 szOffset [pos] = 0;
00140 pos = 0;
00141 if (*pszCheckBytes) pszCheckBytes++;
00142 while (*pszCheckBytes && *pszCheckBytes == ' ')
00143 pszCheckBytes++;
00144
00145
00146 while (*pszCheckBytes && *pszCheckBytes != ',')
00147 szCb [pos++] = *pszCheckBytes++;
00148 szCb [pos] = 0;
00149 pos = 0;
00150 if (*pszCheckBytes) pszCheckBytes++;
00151 while (*pszCheckBytes && *pszCheckBytes == ' ')
00152 pszCheckBytes++;
00153
00154
00155 while (*pszCheckBytes && *pszCheckBytes != ',')
00156 szMask [pos++] = *pszCheckBytes++;
00157 szMask [pos] = 0;
00158 pos = 0;
00159 if (*pszCheckBytes) pszCheckBytes++;
00160 while (*pszCheckBytes && *pszCheckBytes == ' ')
00161 pszCheckBytes++;
00162
00163
00164 while (*pszCheckBytes && *pszCheckBytes != ',')
00165 szVal [pos++] = *pszCheckBytes++;
00166 szVal [pos] = 0;
00167 pos = 0;
00168 if (*pszCheckBytes) pszCheckBytes++;
00169 while (*pszCheckBytes && *pszCheckBytes == ' ')
00170 pszCheckBytes++;
00171
00172 if (*szOffset == 0 || *szCb == 0 || *szVal == 0)
00173 return FALSE;
00174
00175 if (*szMask == 0)
00176 {
00177 for (UINT i = 0; i < strlen (szVal); i++)
00178 szMask [i] = 'F';
00179 szMask [i] = 0;
00180 }
00181
00182 if (FALSE == IsFilterMeets (hFile, szOffset, szCb, szMask, szVal))
00183 return FALSE;
00184 }
00185
00186 return TRUE;
00187 }
00188
00189 BOOL fsDShowFilterDetector::IsFilterMeets(HANDLE hFile, LPCSTR pszOffset, LPCSTR pszCb, LPCSTR pszMask, LPCSTR pszVal)
00190 {
00191 INT64 offset = _atoi64 (pszOffset);
00192 int cb = atoi (pszCb);
00193 DWORD dw;
00194
00195 if (offset < 0)
00196 {
00197 DWORD dw1, dw2;
00198 dw1 = GetFileSize (hFile, &dw2);
00199 INT64 iSize = UINT64 (dw1) | UINT64 (dw2) << 32;
00200 offset += iSize;
00201 }
00202
00203 if (UINT64 (offset + cb) > m_uFileOkLen)
00204 return FALSE;
00205
00206 fsSetFilePointer (hFile, offset, FILE_BEGIN);
00207
00208 LPBYTE buf = new BYTE [cb];
00209
00210 if (FALSE == ReadFile (hFile, buf, cb, &dw, NULL))
00211 return FALSE;
00212
00213 for (int i = 0; i < cb; i++)
00214 {
00215 char szHexMaskByte [3];
00216 szHexMaskByte [0] = pszMask [i*2];
00217 szHexMaskByte [1] = pszMask [i*2+1];
00218 szHexMaskByte [2] = 0;
00219
00220 char szHexValByte [3];
00221 szHexValByte [0] = pszVal [i*2];
00222 szHexValByte [1] = pszVal [i*2+1];
00223 szHexValByte [2] = 0;
00224
00225 int x;
00226
00227 sscanf (szHexMaskByte, "%x", &x);
00228 BYTE bMask = (BYTE) x;
00229
00230 sscanf (szHexValByte, "%x", &x);
00231 BYTE bVal = (BYTE) x;
00232
00233 if ((buf [i] & bMask) != bVal)
00234 return FALSE;
00235 }
00236
00237 return TRUE;
00238 }