CDXAReader.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "stdafx.h"
00023 #include <initguid.h>
00024 #include <uuids.h>
00025 #include "cdxareader.h"
00026 #include "..\..\..\..\include\matroska\matroska.h"
00027 #include "..\..\..\..\include\ogg\OggDS.h"
00028 #include "..\..\..\..\include\moreuuids.h"
00029 #include "..\..\..\DSUtil\DSUtil.h"
00030 
00032 
00033 static DWORD EDC_crctable[256] = 
00034 {
00035         0x00000000l, 0x90910101l, 0x91210201l, 0x01b00300l,
00036         0x92410401l, 0x02d00500l, 0x03600600l, 0x93f10701l,
00037         0x94810801l, 0x04100900l, 0x05a00a00l, 0x95310b01l,
00038         0x06c00c00l, 0x96510d01l, 0x97e10e01l, 0x07700f00l,
00039         0x99011001l, 0x09901100l, 0x08201200l, 0x98b11301l,
00040         0x0b401400l, 0x9bd11501l, 0x9a611601l, 0x0af01700l,
00041         0x0d801800l, 0x9d111901l, 0x9ca11a01l, 0x0c301b00l,
00042         0x9fc11c01l, 0x0f501d00l, 0x0ee01e00l, 0x9e711f01l,
00043         0x82012001l, 0x12902100l, 0x13202200l, 0x83b12301l,
00044         0x10402400l, 0x80d12501l, 0x81612601l, 0x11f02700l,
00045         0x16802800l, 0x86112901l, 0x87a12a01l, 0x17302b00l,
00046         0x84c12c01l, 0x14502d00l, 0x15e02e00l, 0x85712f01l,
00047         0x1b003000l, 0x8b913101l, 0x8a213201l, 0x1ab03300l,
00048         0x89413401l, 0x19d03500l, 0x18603600l, 0x88f13701l,
00049         0x8f813801l, 0x1f103900l, 0x1ea03a00l, 0x8e313b01l,
00050         0x1dc03c00l, 0x8d513d01l, 0x8ce13e01l, 0x1c703f00l,
00051         0xb4014001l, 0x24904100l, 0x25204200l, 0xb5b14301l,
00052         0x26404400l, 0xb6d14501l, 0xb7614601l, 0x27f04700l,
00053         0x20804800l, 0xb0114901l, 0xb1a14a01l, 0x21304b00l,
00054         0xb2c14c01l, 0x22504d00l, 0x23e04e00l, 0xb3714f01l,
00055         0x2d005000l, 0xbd915101l, 0xbc215201l, 0x2cb05300l,
00056         0xbf415401l, 0x2fd05500l, 0x2e605600l, 0xbef15701l,
00057         0xb9815801l, 0x29105900l, 0x28a05a00l, 0xb8315b01l,
00058         0x2bc05c00l, 0xbb515d01l, 0xbae15e01l, 0x2a705f00l,
00059         0x36006000l, 0xa6916101l, 0xa7216201l, 0x37b06300l,
00060         0xa4416401l, 0x34d06500l, 0x35606600l, 0xa5f16701l,
00061         0xa2816801l, 0x32106900l, 0x33a06a00l, 0xa3316b01l,
00062         0x30c06c00l, 0xa0516d01l, 0xa1e16e01l, 0x31706f00l,
00063         0xaf017001l, 0x3f907100l, 0x3e207200l, 0xaeb17301l,
00064         0x3d407400l, 0xadd17501l, 0xac617601l, 0x3cf07700l,
00065         0x3b807800l, 0xab117901l, 0xaaa17a01l, 0x3a307b00l,
00066         0xa9c17c01l, 0x39507d00l, 0x38e07e00l, 0xa8717f01l,
00067         0xd8018001l, 0x48908100l, 0x49208200l, 0xd9b18301l,
00068         0x4a408400l, 0xdad18501l, 0xdb618601l, 0x4bf08700l,
00069         0x4c808800l, 0xdc118901l, 0xdda18a01l, 0x4d308b00l,
00070         0xdec18c01l, 0x4e508d00l, 0x4fe08e00l, 0xdf718f01l,
00071         0x41009000l, 0xd1919101l, 0xd0219201l, 0x40b09300l,
00072         0xd3419401l, 0x43d09500l, 0x42609600l, 0xd2f19701l,
00073         0xd5819801l, 0x45109900l, 0x44a09a00l, 0xd4319b01l,
00074         0x47c09c00l, 0xd7519d01l, 0xd6e19e01l, 0x46709f00l,
00075         0x5a00a000l, 0xca91a101l, 0xcb21a201l, 0x5bb0a300l,
00076         0xc841a401l, 0x58d0a500l, 0x5960a600l, 0xc9f1a701l,
00077         0xce81a801l, 0x5e10a900l, 0x5fa0aa00l, 0xcf31ab01l,
00078         0x5cc0ac00l, 0xcc51ad01l, 0xcde1ae01l, 0x5d70af00l,
00079         0xc301b001l, 0x5390b100l, 0x5220b200l, 0xc2b1b301l,
00080         0x5140b400l, 0xc1d1b501l, 0xc061b601l, 0x50f0b700l,
00081         0x5780b800l, 0xc711b901l, 0xc6a1ba01l, 0x5630bb00l,
00082         0xc5c1bc01l, 0x5550bd00l, 0x54e0be00l, 0xc471bf01l,
00083         0x6c00c000l, 0xfc91c101l, 0xfd21c201l, 0x6db0c300l,
00084         0xfe41c401l, 0x6ed0c500l, 0x6f60c600l, 0xfff1c701l,
00085         0xf881c801l, 0x6810c900l, 0x69a0ca00l, 0xf931cb01l,
00086         0x6ac0cc00l, 0xfa51cd01l, 0xfbe1ce01l, 0x6b70cf00l,
00087         0xf501d001l, 0x6590d100l, 0x6420d200l, 0xf4b1d301l,
00088         0x6740d400l, 0xf7d1d501l, 0xf661d601l, 0x66f0d700l,
00089         0x6180d800l, 0xf111d901l, 0xf0a1da01l, 0x6030db00l,
00090         0xf3c1dc01l, 0x6350dd00l, 0x62e0de00l, 0xf271df01l,
00091         0xee01e001l, 0x7e90e100l, 0x7f20e200l, 0xefb1e301l,
00092         0x7c40e400l, 0xecd1e501l, 0xed61e601l, 0x7df0e700l,
00093         0x7a80e800l, 0xea11e901l, 0xeba1ea01l, 0x7b30eb00l,
00094         0xe8c1ec01l, 0x7850ed00l, 0x79e0ee00l, 0xe971ef01l,
00095         0x7700f000l, 0xe791f101l, 0xe621f201l, 0x76b0f300l,
00096         0xe541f401l, 0x75d0f500l, 0x7460f600l, 0xe4f1f701l,
00097         0xe381f801l, 0x7310f900l, 0x72a0fa00l, 0xe231fb01l,
00098         0x71c0fc00l, 0xe151fd01l, 0xe0e1fe01l, 0x7070ff00l
00099 };
00100 
00101 static DWORD build_edc(const void* in, unsigned from, unsigned upto)
00102 {
00103         const BYTE* p = (BYTE*)in + from;
00104         DWORD result = 0;
00105 
00106         for(; from < upto; from++)
00107                 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
00108         
00109         return result;
00110 }
00111 
00113 
00114 #ifdef REGISTER_FILTER
00115 
00116 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
00117 {
00118         {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL}
00119 };
00120 
00121 const AMOVIESETUP_PIN sudOpPin[] =
00122 {
00123         {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
00124 };
00125 
00126 const AMOVIESETUP_FILTER sudFilter[] =
00127 {
00128         {&__uuidof(CCDXAReader), L"CDXA Reader", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin}
00129 };
00130 
00131 CFactoryTemplate g_Templates[] =
00132 {
00133         {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CCDXAReader>, NULL, &sudFilter[0]}
00134 };
00135 
00136 int g_cTemplates = countof(g_Templates);
00137 
00138 STDAPI DllRegisterServer()
00139 {
00140         SetRegKeyValue(
00141                 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{D367878E-F3B8-4235-A968-F378EF1B9A44}"), 
00142                 _T("0"), _T("0,4,,52494646,8,4,,43445841")); // "RIFFxxxxCDXA"
00143 
00144         SetRegKeyValue(
00145                 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{D367878E-F3B8-4235-A968-F378EF1B9A44}"), 
00146                 _T("Source Filter"), _T("{D367878E-F3B8-4235-A968-F378EF1B9A44}"));
00147 
00148         return AMovieDllRegisterServer2(TRUE);
00149 }
00150 
00151 STDAPI DllUnregisterServer()
00152 {
00153         DeleteRegKey(_T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{D367878E-F3B8-4235-A968-F378EF1B9A44}"));
00154 
00155         return AMovieDllRegisterServer2(FALSE);
00156 }
00157 
00158 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00159 
00160 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00161 {
00162     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
00163 }
00164 
00165 #endif
00166 
00167 //
00168 // CCDXAReader
00169 //
00170 
00171 CCDXAReader::CCDXAReader(IUnknown* pUnk, HRESULT* phr)
00172         : CAsyncReader(NAME("CCDXAReader"), pUnk, &m_stream, phr, __uuidof(this))
00173 {
00174         if(phr) *phr = S_OK;
00175 }
00176 
00177 CCDXAReader::~CCDXAReader()
00178 {
00179 }
00180 
00181 STDMETHODIMP CCDXAReader::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00182 {
00183         return 
00184                 QI(IFileSourceFilter)
00185                 __super::NonDelegatingQueryInterface(riid, ppv);
00186 }
00187 
00188 STDMETHODIMP CCDXAReader::Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt) 
00189 {
00190         CMediaType mt;
00191         m_mt = mt;
00192 
00193         if(!m_stream.Load(pszFileName))
00194                 return E_FAIL;
00195 
00196         m_fn = pszFileName;
00197 
00198         mt.majortype = MEDIATYPE_Stream;
00199         mt.subtype = m_stream.m_subtype;
00200         m_mt = mt;
00201 
00202         return S_OK;
00203 }
00204 
00205 STDMETHODIMP CCDXAReader::GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt)
00206 {
00207         if(!ppszFileName) return E_POINTER;
00208         
00209         if(!(*ppszFileName = (LPOLESTR)CoTaskMemAlloc((m_fn.GetLength()+1)*sizeof(WCHAR))))
00210                 return E_OUTOFMEMORY;
00211 
00212         wcscpy(*ppszFileName, m_fn);
00213 
00214         return S_OK;
00215 }
00216 
00217 // CCDXAStream
00218 
00219 CCDXAStream::CCDXAStream()
00220 {
00221         m_subtype = MEDIASUBTYPE_NULL;
00222         
00223         m_hFile = INVALID_HANDLE_VALUE;
00224 
00225         m_llPosition = m_llLength = 0;
00226         m_nFirstSector = 0;
00227         m_nBufferedSector = -1;
00228 }
00229 
00230 CCDXAStream::~CCDXAStream()
00231 {
00232         if(m_hFile != INVALID_HANDLE_VALUE)
00233         {
00234                 CloseHandle(m_hFile);
00235                 m_hFile = INVALID_HANDLE_VALUE;
00236         }
00237 }
00238 
00239 bool CCDXAStream::Load(const WCHAR* fnw)
00240 {
00241         if(m_hFile != INVALID_HANDLE_VALUE)
00242         {
00243                 CloseHandle(m_hFile);
00244                 m_hFile = INVALID_HANDLE_VALUE;
00245         }
00246 
00247         m_hFile = CreateFile(CString(fnw), GENERIC_READ, FILE_SHARE_READ, NULL, 
00248                 OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, (HANDLE)NULL);
00249         if(m_hFile == INVALID_HANDLE_VALUE)
00250         {
00251                 return(false);
00252         }
00253 
00254         BYTE hdr[RIFFCDXA_HEADER_SIZE];
00255         DWORD NumberOfBytesRead;
00256         if(!ReadFile(m_hFile, (LPVOID)hdr, RIFFCDXA_HEADER_SIZE, &NumberOfBytesRead, NULL)
00257         || *((DWORD*)&hdr[0]) != 'FFIR' || *((DWORD*)&hdr[8]) != 'AXDC'
00258         || *((DWORD*)&hdr[4]) != (*((DWORD*)&hdr[0x28])+0x24))
00259         {
00260                 CloseHandle(m_hFile);
00261                 m_hFile = INVALID_HANDLE_VALUE;
00262                 return(false);
00263         }
00264 
00265         LARGE_INTEGER size = {0, 0};
00266         size.LowPart = (LONG)GetFileSize(m_hFile, (LPDWORD)&size.HighPart);
00267 
00268         m_llLength = int((size.QuadPart - RIFFCDXA_HEADER_SIZE) / RAW_SECTOR_SIZE) * RAW_DATA_SIZE;
00269 
00270         if(!LookForMediaSubType()) 
00271         {
00272                 m_llPosition = m_llLength = 0;
00273                 CloseHandle(m_hFile);
00274                 m_hFile = INVALID_HANDLE_VALUE;
00275                 return(false);
00276         }
00277 
00278         m_llPosition = 0;
00279 
00280         m_nBufferedSector = -1;
00281 
00282         return(true);
00283 }
00284 
00285 HRESULT CCDXAStream::SetPointer(LONGLONG llPos)
00286 {
00287         return (llPos >= 0 && llPos < m_llLength) ? m_llPosition = llPos, S_OK : S_FALSE;
00288 }
00289 
00290 HRESULT CCDXAStream::Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead)
00291 {
00292         CAutoLock lck(&m_csLock);
00293 
00294         PBYTE pbBufferOrg = pbBuffer;
00295         LONGLONG pos = m_llPosition;
00296 
00297         while(pos >= 0 && pos < m_llLength && dwBytesToRead > 0)
00298         {
00299                 UINT sector = m_nFirstSector + int(pos/RAW_DATA_SIZE);
00300                 __int64 offset = pos%RAW_DATA_SIZE;
00301 
00302                 if(m_nBufferedSector != sector)
00303                 {
00304                         LARGE_INTEGER FilePointer;
00305                         FilePointer.QuadPart = RIFFCDXA_HEADER_SIZE + sector*RAW_SECTOR_SIZE;
00306                         SetFilePointer(m_hFile, (LONG)FilePointer.LowPart, (PLONG)&FilePointer.HighPart, FILE_BEGIN);
00307 
00308                         memset(m_sector, 0, sizeof(m_sector));
00309 
00310                         DWORD NumberOfBytesRead = 0;
00311 
00312                         int nRetries = 3;
00313                         while(nRetries--)
00314                         {
00315                                 NumberOfBytesRead = 0;
00316                                 if(!ReadFile(m_hFile, m_sector, RAW_SECTOR_SIZE, &NumberOfBytesRead, NULL)
00317                                 || NumberOfBytesRead != RAW_SECTOR_SIZE) 
00318                                         break;
00319 
00320                                 if(*(DWORD*)&m_sector[RAW_SECTOR_SIZE-4] == 0) // no CRC? it happens...
00321                                         break;
00322 
00323                                 if(build_edc(m_sector, RAW_SYNC_SIZE + RAW_HEADER_SIZE, RAW_SECTOR_SIZE) == 0) 
00324                                         break;
00325 
00326                                 TRACE(_T("CCDXAStream: CRC error at sector %d (fp=0x%I64x, retriesleft=%d)\n"), sector, FilePointer.QuadPart, nRetries);
00327                         }
00328 
00329                         m_nBufferedSector = sector;
00330                 }
00331 
00332                 DWORD l = min(min(dwBytesToRead, RAW_DATA_SIZE - offset), m_llLength - pos);
00333                 memcpy(pbBuffer, &m_sector[RAW_SYNC_SIZE + RAW_HEADER_SIZE + RAW_SUBHEADER_SIZE + offset], l);
00334 
00335                 pbBuffer += l;
00336                 pos += l;
00337                 dwBytesToRead -= l;
00338         }
00339 
00340         if(pdwBytesRead) *pdwBytesRead = pbBuffer - pbBufferOrg;
00341         m_llPosition += pbBuffer - pbBufferOrg;
00342 
00343         if(dwBytesToRead != 0) return S_FALSE;
00344 
00345         return S_OK;
00346 }
00347 
00348 LONGLONG CCDXAStream::Size(LONGLONG* pSizeAvailable)
00349 {
00350         if(pSizeAvailable) *pSizeAvailable = m_llLength;
00351     return m_llLength;
00352 }
00353 
00354 DWORD CCDXAStream::Alignment()
00355 {
00356     return 1;
00357 }
00358 
00359 void CCDXAStream::Lock()
00360 {
00361     m_csLock.Lock();
00362 }
00363 
00364 void CCDXAStream::Unlock()
00365 {
00366     m_csLock.Unlock();
00367 }
00368 
00369 //
00370 
00371 bool CCDXAStream::LookForMediaSubType()
00372 {
00373         BYTE buff[RAW_DATA_SIZE];
00374 
00375         m_subtype = MEDIASUBTYPE_NULL;
00376 
00377         m_llPosition = 0;
00378 
00379         for(int iSectorsRead = 0;
00380                 Read(buff, RAW_DATA_SIZE, 1, NULL) == S_OK && iSectorsRead < 1000;
00381                 iSectorsRead++)
00382         {
00383                 if(*((DWORD*)&buff[0]) == 0xba010000) 
00384                 {
00385                         m_llPosition = 0;
00386                         m_llLength -= iSectorsRead*RAW_DATA_SIZE;
00387                         m_nFirstSector = iSectorsRead;
00388 
00389                         if((buff[4]&0xc4) == 0x44) m_subtype = MEDIASUBTYPE_MPEG2_PROGRAM;
00390                         else if((buff[4]&0xf1) == 0x21) m_subtype = MEDIASUBTYPE_MPEG1System;
00391 
00392                         return m_subtype != MEDIASUBTYPE_NULL;
00393                 }
00394                 else if(*((DWORD*)&buff[0]) == 'SggO') 
00395                 {
00396                         m_llPosition = 0;
00397                         m_llLength -= iSectorsRead*RAW_DATA_SIZE;
00398                         m_nFirstSector = iSectorsRead;
00399 
00400                         m_subtype = MEDIASUBTYPE_Ogg;
00401 
00402                         return(true);
00403                 }
00404                 else if(*((DWORD*)&buff[0]) == 0xA3DF451A) 
00405                 {
00406                         m_llPosition = 0;
00407                         m_llLength -= iSectorsRead*RAW_DATA_SIZE;
00408                         m_nFirstSector = iSectorsRead;
00409 
00410                         m_subtype = MEDIASUBTYPE_Matroska;
00411 
00412                         return(true);
00413                 }
00414                 else if(*((DWORD*)&buff[0]) == 'FMR.') 
00415                 {
00416                         m_llPosition = 0;
00417                         m_llLength -= iSectorsRead*RAW_DATA_SIZE;
00418                         m_nFirstSector = iSectorsRead;
00419 
00420                         m_subtype = MEDIASUBTYPE_RealMedia;
00421 
00422                         return(true);
00423                 }
00424                 else if(*((DWORD*)&buff[0]) == 'FFIR' && *((DWORD*)&buff[8]) == ' IVA')
00425                 {
00426                         m_llPosition = 0;
00427                         m_llLength = min(m_llLength, *((DWORD*)&buff[4])+8);
00428                         m_nFirstSector = iSectorsRead;
00429 
00430                         m_subtype = MEDIASUBTYPE_Avi;
00431                         
00432                         return(true);
00433                 }
00434                 else if(*((DWORD*)&buff[4]) == 'voom' || *((DWORD*)&buff[4]) == 'tadm'
00435                 || *((DWORD*)&buff[4]) == 'pytf' && *((DWORD*)&buff[8]) == 'mosi' && *((DWORD*)&buff[16]) == '14pm')
00436                 {
00437                         m_llPosition = 0;
00438                         m_llLength -= iSectorsRead*RAW_DATA_SIZE;
00439                         m_nFirstSector = iSectorsRead;
00440 
00441                         m_subtype = MEDIASUBTYPE_QTMovie;
00442                         
00443                         return(true);
00444                 }
00445         }
00446 
00447         m_llPosition = 0;
00448 
00449         CRegKey majorkey;
00450         CString majortype = _T("\\Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}");
00451         if(ERROR_SUCCESS == majorkey.Open(HKEY_CLASSES_ROOT, majortype, KEY_READ))
00452         {
00453                 TCHAR subtype[256+1];
00454                 DWORD len = 256;
00455                 for(int i = 0; ERROR_SUCCESS == majorkey.EnumKey(i, subtype, &len); i++, len = 256)
00456                 {
00457                         CRegKey subkey;
00458                         if(ERROR_SUCCESS != subkey.Open(HKEY_CLASSES_ROOT, majortype + _T("\\") + subtype, KEY_READ))
00459                                 continue;
00460 
00461                         for(int j = 0; true; j++)
00462                         {
00463                                 TCHAR number[10];
00464                                 _stprintf(number, _T("%d"), j);
00465 
00466                                 TCHAR pattern[256+1];
00467                                 ULONG len = 256;
00468                                 if(ERROR_SUCCESS != subkey.QueryStringValue(number, pattern, &len))
00469                                         break;
00470 
00471                                 CString p = pattern;
00472                                 p += ',';
00473 
00474                                 __int64 offset = 0;
00475                                 DWORD cb = 0;
00476                                 CByteArray mask, val;
00477 
00478                                 int nMatches = 0, nTries = 0;
00479 
00480                                 for(int k = 0, l; nTries >= 0 && (l = p.Find(',', k)) >= 0; k = l+1, nTries++)
00481                                 {
00482                                         CString s = p.Mid(k, l-k);
00483                                         TRACE(s + '\n');
00484 
00485                                         TCHAR* end = NULL;
00486 
00487                                         switch(nTries&3)
00488                                         {
00489                                                 case 0: offset = _tcstol(s, &end, 10); break;
00490                                                 case 1: cb = _tcstol(s, &end, 10); break;
00491                                                 case 2: StringToBin(s, mask); break;
00492                                                 case 3: StringToBin(s, val); break;
00493                                                 default: nTries = -1; break;
00494                                         }
00495 
00496                                         if(nTries >= 0 && (nTries&3) == 3)
00497                                         {
00498                                                 if(cb > 0 && val.GetSize() > 0 && cb == val.GetSize())
00499                                                 {
00500                                                         if(offset >= 0 && S_OK == SetPointer(offset)
00501                                                         || S_OK == SetPointer(m_llLength + offset))
00502                                                         {
00503                                                                 CAutoVectorPtr<BYTE> pData;
00504                                                                 if(pData.Allocate(cb))
00505                                                                 {
00506                                                                         DWORD BytesRead = 0;
00507                                                                         if(S_OK == Read(pData, cb, 1, &BytesRead) && cb == BytesRead)
00508                                                                         {
00509                                                                                 if(mask.GetSize() < cb)
00510                                                                                 {
00511                                                                                         int i = mask.GetSize();
00512                                                                                         mask.SetSize(cb);
00513                                                                                         for(; i < cb; i++) mask[i] = 0xff;
00514                                                                                 }
00515 
00516                                                                                 for(int i = 0; i < cb; i++)
00517                                                                                         pData[i] &= (BYTE)mask[i];
00518 
00519                                                                                 if(memcmp(pData, val.GetData(), cb) == 0)
00520                                                                                         nMatches++;
00521                                                                         }
00522                                                                 }
00523                                                         }
00524 
00525                                                         offset = 0; cb = 0;
00526                                                         mask.RemoveAll(); val.RemoveAll();
00527                                                 }
00528                                         }
00529                                 }
00530 
00531                                 if(nMatches > 0 && nMatches*4 == nTries)
00532                                 {
00533                                         m_subtype = GUIDFromCString(subtype);
00534                                         return S_OK;
00535                                 }
00536                         }
00537                 }
00538         }
00539 
00540         return(false);
00541 }

Generated on Tue Dec 13 14:47:23 2005 for guliverkli by  doxygen 1.4.5