30 static void DisplayBITMAPINFO(
const BITMAPINFOHEADER* pbmi);
31 static void DisplayRECT(LPCTSTR szLabel,
const RECT& rc);
44 const LPCTSTR pKeyNames[] = {
57 const TCHAR CAutoTrace::_szEntering[] = TEXT(
"->: %s");
58 const TCHAR CAutoTrace::_szLeaving[] = TEXT(
"<-: %s");
60 const INT iMAXLEVELS =
NUMELMS(pKeyNames);
64 DWORD m_Levels[iMAXLEVELS];
65 CRITICAL_SECTION m_CSDebug;
68 DWORD m_dwObjectCount;
71 DWORD dwWaitTimeout = INFINITE;
73 bool g_fUseKASSERT =
false;
74 bool g_fDbgInDllEntryPoint =
false;
75 bool g_fAutoRefreshLevels =
false;
77 LPCTSTR pBaseKey = TEXT(
"SOFTWARE\\Microsoft\\DirectShow\\Debug");
78 LPCTSTR pGlobalKey = TEXT(
"GLOBAL");
79 static CHAR *pUnknownName =
"UNKNOWN";
81 LPCTSTR TimeoutName = TEXT(
"TIMEOUT");
88 InitializeCriticalSection(&m_CSDebug);
93 if (GetProfileInt(m_ModuleName, TEXT(
"BreakOnLoad"), 0))
95 DbgInitModuleSettings(
false);
96 DbgInitGlobalSettings(
true);
97 dwTimeOffset = timeGetTime();
113 DeleteCriticalSection(&m_CSDebug);
121 void WINAPI DbgInitKeyLevels(HKEY hKey,
bool fTakeMax)
130 for (lKeyPos = 0;lKeyPos < iMAXLEVELS;lKeyPos++) {
132 dwKeySize =
sizeof(DWORD);
133 lReturn = RegQueryValueEx(
138 (LPBYTE) &dwKeyValue,
145 if (lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD) {
148 lReturn = RegSetValueEx(
156 if (lReturn != ERROR_SUCCESS) {
157 DbgLog((
LOG_ERROR,1,TEXT(
"Could not create subkey %s"),pKeyNames[lKeyPos]));
163 m_Levels[lKeyPos] = max(dwKeyValue,m_Levels[lKeyPos]);
168 m_Levels[lKeyPos] = dwKeyValue;
174 dwKeySize =
sizeof(DWORD);
175 lReturn = RegQueryValueEx(
180 (LPBYTE) &dwWaitTimeout,
187 if (lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD) {
189 dwWaitTimeout = INFINITE;
190 lReturn = RegSetValueEx(
195 (PBYTE) &dwWaitTimeout,
198 if (lReturn != ERROR_SUCCESS) {
199 DbgLog((
LOG_ERROR,1,TEXT(
"Could not create subkey %s"),pKeyNames[lKeyPos]));
200 dwWaitTimeout = INFINITE;
208 UINT cb = lstrlen(psz);
212 WideCharToMultiByte(CP_ACP, 0, psz, -1, szDest,
NUMELMS(szDest), 0, 0);
213 WriteFile (m_hOutput, szDest, cb, &dw,
NULL);
215 WriteFile (m_hOutput, psz, cb, &dw,
NULL);
218 OutputDebugString (psz);
225 HRESULT DbgUniqueProcessName(LPCTSTR inName, LPTSTR outName)
228 const TCHAR *pIn = inName;
232 while (*pIn && (pIn - inName) <
MAX_PATH)
234 if ( TEXT(
'.') == *pIn )
235 dotPos = (int)(pIn-inName);
242 DWORD dwProcessId = GetCurrentProcessId();
247 hr = StringCchPrintf(outName,
MAX_PATH, TEXT(
"%s_%d"), inName, dwProcessId);
251 TCHAR pathAndBasename[
MAX_PATH] = {0};
254 hr = StringCchCopyN(pathAndBasename,
MAX_PATH, inName, (
size_t)dotPos);
258 hr = StringCchPrintf(outName,
MAX_PATH, TEXT(
"%s_%d%s"), pathAndBasename, dwProcessId, inName + dotPos);
268 void WINAPI DbgInitLogTo (
275 static const TCHAR cszKey[] = TEXT(
"LogToFile");
278 lReturn = RegQueryValueEx(
288 if (lReturn != ERROR_SUCCESS || dwKeyType != REG_SZ)
290 dwKeySize =
sizeof(TCHAR);
291 lReturn = RegSetValueEx(
308 if (!lstrcmpi(szFile, TEXT(
"Console"))) {
309 m_hOutput = GetStdHandle (STD_OUTPUT_HANDLE);
312 m_hOutput = GetStdHandle (STD_OUTPUT_HANDLE);
314 SetConsoleTitle (TEXT(
"ActiveX Debug Output"));
315 }
else if (szFile[0] &&
316 lstrcmpi(szFile, TEXT(
"Debug")) &&
317 lstrcmpi(szFile, TEXT(
"Debugger")) &&
318 lstrcmpi(szFile, TEXT(
"Deb")))
320 m_hOutput = CreateFile(szFile, GENERIC_WRITE,
323 FILE_ATTRIBUTE_NORMAL,
327 GetLastError() == ERROR_SHARING_VIOLATION)
330 if (SUCCEEDED(DbgUniqueProcessName(szFile, uniqueName)))
332 m_hOutput = CreateFile(uniqueName, GENERIC_WRITE,
335 FILE_ATTRIBUTE_NORMAL,
342 static const TCHAR cszBar[] = TEXT(
"\r\n\r\n=====DbgInitialize()=====\r\n\r\n");
343 SetFilePointer (m_hOutput, 0,
NULL, FILE_END);
357 void WINAPI DbgInitGlobalSettings(
bool fTakeMax)
364 (
void)StringCchPrintf(szInfo,
NUMELMS(szInfo),TEXT(
"%s\\%s"),pBaseKey,pGlobalKey);
367 lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
372 GENERIC_READ | GENERIC_WRITE,
377 if (lReturn != ERROR_SUCCESS) {
378 lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
387 if (lReturn != ERROR_SUCCESS) {
393 DbgInitKeyLevels(hGlobalKey, fTakeMax);
394 RegCloseKey(hGlobalKey);
404 void WINAPI DbgInitModuleSettings(
bool fTakeMax)
411 (
void)StringCchPrintf(szInfo,
NUMELMS(szInfo),TEXT(
"%s\\%s"),pBaseKey,m_ModuleName);
414 lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
419 GENERIC_READ | GENERIC_WRITE,
424 if (lReturn != ERROR_SUCCESS) {
425 lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
434 if (lReturn != ERROR_SUCCESS) {
440 DbgInitLogTo(hModuleKey);
441 DbgInitKeyLevels(hModuleKey, fTakeMax);
442 RegCloseKey(hModuleKey);
448 void WINAPI DbgInitModuleName()
453 GetModuleFileName(m_hInst,FullName,
iDEBUGINFO);
454 pName = _tcsrchr(FullName,
'\\');
476 DWORD WINAPI MsgBoxThread(
477 __inout LPVOID lpParameter
480 MsgBoxMsg *pmsg = (MsgBoxMsg *)lpParameter;
481 pmsg->iResult = MessageBox(
490 INT MessageBoxOtherThread(
496 if(g_fDbgInDllEntryPoint)
506 MsgBoxMsg msg = {hwnd, szTitle, szMessage, dwFlags, 0};
508 HANDLE hThread = CreateThread(
517 WaitForSingleObject(hThread, INFINITE);
518 CloseHandle(hThread);
529 void WINAPI DbgAssert(LPCTSTR pCondition,LPCTSTR pFileName,INT iLine)
533 DbgKernelAssert(pCondition, pFileName, iLine);
540 (
void)StringCchPrintf(szInfo,
NUMELMS(szInfo),TEXT(
"%s \nAt line %d of %s\nContinue? (Cancel to debug)"),
541 pCondition, iLine, pFileName);
543 INT MsgId = MessageBoxOtherThread(
NULL,szInfo,TEXT(
"ASSERT Failed"),
552 FatalAppExit(FALSE, TEXT(
"Application terminated"));
568 void WINAPI DbgBreakPoint(LPCTSTR pCondition,LPCTSTR pFileName,INT iLine)
572 DbgKernelAssert(pCondition, pFileName, iLine);
578 (
void)StringCchPrintf(szInfo,
NUMELMS(szInfo),TEXT(
"%s \nAt line %d of %s\nContinue? (Cancel to debug)"),
579 pCondition, iLine, pFileName);
581 INT MsgId = MessageBoxOtherThread(
NULL,szInfo,TEXT(
"Hard coded break point"),
590 FatalAppExit(FALSE, TEXT(
"Application terminated"));
604 void WINAPI DbgBreakPoint(LPCTSTR pFileName,INT iLine,__format_string LPCTSTR szFormatString,...)
611 const DWORD MAX_BREAK_POINT_MESSAGE_SIZE = 2000;
613 TCHAR szBreakPointMessage[MAX_BREAK_POINT_MESSAGE_SIZE];
616 va_start( va, szFormatString );
618 HRESULT
hr = StringCchVPrintf( szBreakPointMessage,
NUMELMS(szBreakPointMessage), szFormatString, va );
623 DbgBreak(
"ERROR in DbgBreakPoint(). The variable length debug message could not be displayed because StringCchVPrintf() failed." );
627 ::DbgBreakPoint( szBreakPointMessage, pFileName, iLine );
646 if(g_fAutoRefreshLevels)
650 static DWORD g_dwLastRefresh = 0;
651 DWORD dwTime = timeGetTime();
652 if(dwTime - g_dwLastRefresh > 1000) {
653 g_dwLastRefresh = dwTime;
658 DbgInitModuleSettings(
false);
666 if ((Type & ((1<<iMAXLEVELS)-1))) {
672 for (LONG lKeyPos = 0;lKeyPos < iMAXLEVELS;lKeyPos++) {
691 for (LONG lKeyPos = 0;lKeyPos < iMAXLEVELS;lKeyPos++) {
703 g_fAutoRefreshLevels = fAuto;
711 void WINAPI DbgLogInfo(DWORD Type,DWORD Level,__format_string LPCSTR pFormat,...)
716 if (bAccept == FALSE) {
725 va_start(va, pFormat);
728 TEXT(
"%s(tid %x) %8d : "),
730 GetCurrentThreadId(), timeGetTime() - dwTimeOffset);
733 WideCharToMultiByte(CP_ACP, 0, szInfo, -1, szInfoA,
NUMELMS(szInfoA), 0, 0);
735 (
void)StringCchVPrintfA(szInfoA + lstrlenA(szInfoA),
NUMELMS(szInfoA) - lstrlenA(szInfoA), pFormat, va);
736 (
void)StringCchCatA(szInfoA,
NUMELMS(szInfoA),
"\r\n");
738 WCHAR wszOutString[2000];
739 MultiByteToWideChar(CP_ACP, 0, szInfoA, -1, wszOutString,
NUMELMS(wszOutString));
745 void WINAPI DbgAssert(LPCSTR pCondition,LPCSTR pFileName,INT iLine)
749 DbgKernelAssert(pCondition, pFileName, iLine);
756 (
void)StringCchPrintf(szInfo,
NUMELMS(szInfo), TEXT(
"%hs \nAt line %d of %hs\nContinue? (Cancel to debug)"),
757 pCondition, iLine, pFileName);
759 INT MsgId = MessageBoxOtherThread(
NULL,szInfo,TEXT(
"ASSERT Failed"),
768 FatalAppExit(FALSE, TEXT(
"Application terminated"));
784 void WINAPI DbgBreakPoint(LPCSTR pCondition,LPCSTR pFileName,INT iLine)
788 DbgKernelAssert(pCondition, pFileName, iLine);
794 (
void)StringCchPrintf(szInfo,
NUMELMS(szInfo),TEXT(
"%hs \nAt line %d of %hs\nContinue? (Cancel to debug)"),
795 pCondition, iLine, pFileName);
797 INT MsgId = MessageBoxOtherThread(
NULL,szInfo,TEXT(
"Hard coded break point"),
806 FatalAppExit(FALSE, TEXT(
"Application terminated"));
820 void WINAPI DbgKernelAssert(LPCSTR pCondition,LPCSTR pFileName,INT iLine)
822 DbgLog((
LOG_ERROR,0,TEXT(
"Assertion FAILED (%hs) at line %d in file %hs"),
823 pCondition, iLine, pFileName));
838 void WINAPI DbgLogInfo(DWORD Type,DWORD Level,LPCTSTR pFormat,...)
844 if (bAccept == FALSE) {
853 va_start(va, pFormat);
856 TEXT(
"%s(tid %x) %8d : "),
858 GetCurrentThreadId(), timeGetTime() - dwTimeOffset);
860 (
void)StringCchVPrintf(szInfo + lstrlen(szInfo),
NUMELMS(szInfo) - lstrlen(szInfo), pFormat, va);
861 (
void)StringCchCat(szInfo,
NUMELMS(szInfo), TEXT(
"\r\n"));
872 void WINAPI DbgKernelAssert(LPCTSTR pCondition,LPCTSTR pFileName,INT iLine)
874 DbgLog((
LOG_ERROR,0,TEXT(
"Assertion FAILED (%s) at line %d in file %s"),
875 pCondition, iLine, pFileName));
888 LPCWSTR wszObjectName)
892 ASSERT(!!szObjectName ^ !!wszObjectName);
900 if (pObject ==
NULL) {
908 if (m_bInit == FALSE) {
913 EnterCriticalSection(&m_CSDebug);
916 if (!szObjectName && !wszObjectName) {
917 szObjectName = pUnknownName;
935 pObject->
m_dwCookie, wszObjectName, m_dwObjectCount));
938 pObject->
m_dwCookie, szObjectName, m_dwObjectCount));
941 LeaveCriticalSection(&m_CSDebug);
954 EnterCriticalSection(&m_CSDebug);
969 if (pObject ==
NULL) {
970 DbgBreak(
"Apparently destroying a bogus object");
971 LeaveCriticalSection(&m_CSDebug);
977 if (pPrevious ==
NULL) {
996 LeaveCriticalSection(&m_CSDebug);
1009 EnterCriticalSection(&m_CSDebug);
1028 (
void)StringCchPrintf(szInfo,
NUMELMS(szInfo),TEXT(
"Total object count %5d"),m_dwObjectCount);
1031 LeaveCriticalSection(&m_CSDebug);
1039 dwWaitResult = WaitForSingleObject(h, dwWaitTimeout);
1040 ASSERT(dwWaitResult == WAIT_OBJECT_0);
1041 }
while (dwWaitResult == WAIT_TIMEOUT);
1042 return dwWaitResult;
1045 __in_ecount(nCount) CONST
HANDLE *lpHandles,
1050 dwWaitResult = WaitForMultipleObjects(nCount,
1054 ASSERT((DWORD)(dwWaitResult - WAIT_OBJECT_0) < MAXIMUM_WAIT_OBJECTS);
1055 }
while (dwWaitResult == WAIT_TIMEOUT);
1056 return dwWaitResult;
1061 dwWaitTimeout = dwTimeout;
1070 GUID_STRING_ENTRY g_GuidNames[] = {
1071 #define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
1072 { #name, { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } },
1076 CGuidNameList GuidNames;
1077 int g_cGuidNames =
sizeof(g_GuidNames) /
sizeof(g_GuidNames[0]);
1079 char *CGuidNameList::operator [] (
const GUID &guid)
1081 for (
int i = 0; i < g_cGuidNames; i++) {
1082 if (g_GuidNames[i].guid == guid) {
1083 return g_GuidNames[i].szName;
1086 if (guid == GUID_NULL) {
1093 return "Unknown GUID Name";
1117 digit = li.LowPart % 10;
1119 temp[--pos] = (TCHAR) digit+L
'0';
1120 }
while (li.QuadPart);
1136 (
void)StringFromGUID2(clsid, wszTemp,
NUMELMS(wszTemp));
1150 llDiv = (LONGLONG)24 * 3600 * 10000000;
1151 if (llTime >= llDiv) {
1153 llTime = llTime % llDiv;
1155 llDiv = (LONGLONG)3600 * 10000000;
1156 if (llTime >= llDiv) {
1158 llTime = llTime % llDiv;
1160 llDiv = (LONGLONG)60 * 10000000;
1161 if (llTime >= llDiv) {
1163 llTime = llTime % llDiv;
1166 (LONG)llTime / 10000000,
1167 (LONG)((llTime % 10000000) / 10000));
1170 #endif // __STREAMS__
1177 TCHAR str[MAX_PIN_NAME];
1181 pPin->QueryPinInfo(&pi);
1182 pi.pFilter->GetClassID(&clsid);
1185 WideCharToMultiByte(GetACP(), 0, pi.achName, lstrlenW(pi.achName) + 1,
1188 (
void)StringCchCopy(str,
NUMELMS(str), pi.achName);
1191 (
void)StringCchCopy(str,
NUMELMS(str), TEXT(
"NULL IPin"));
1194 m_pString = (PTCHAR)
new TCHAR[lstrlen(str)+64];
1199 (
void)StringCchPrintf(
m_pString, lstrlen(str) + 64, TEXT(
"%hs(%s)"), GuidNames[clsid], str);
1206 HRESULT
hr = pUnk->QueryInterface(IID_IBaseFilter, (
void **)&pf);
1210 hr = pf->QueryFilterInfo(&fi);
1215 size_t len = lstrlenW(fi.achName) + 1;
1234 hr = pUnk->QueryInterface(IID_IPin, (
void **)&pp);
1268 void WINAPI
DisplayType(LPCTSTR label,
const AM_MEDIA_TYPE *pmtIn)
1275 GuidNames[pmtIn->majortype],
1276 GuidNames[pmtIn->subtype]));
1281 if (pmtIn->bTemporalCompression) {
1287 if (pmtIn->bFixedSizeSamples) {
1293 if (pmtIn->formattype == FORMAT_VideoInfo) {
1295 VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *)pmtIn->pbFormat;
1297 DisplayRECT(TEXT(
"Source rectangle"),pVideoInfo->rcSource);
1298 DisplayRECT(TEXT(
"Target rectangle"),pVideoInfo->rcTarget);
1299 DisplayBITMAPINFO(HEADER(pmtIn->pbFormat));
1301 }
if (pmtIn->formattype == FORMAT_VideoInfo2) {
1303 VIDEOINFOHEADER2 *pVideoInfo2 = (VIDEOINFOHEADER2 *)pmtIn->pbFormat;
1305 DisplayRECT(TEXT(
"Source rectangle"),pVideoInfo2->rcSource);
1306 DisplayRECT(TEXT(
"Target rectangle"),pVideoInfo2->rcTarget);
1308 pVideoInfo2->dwPictAspectRatioX,
1309 pVideoInfo2->dwPictAspectRatioY));
1310 DisplayBITMAPINFO(&pVideoInfo2->bmiHeader);
1312 }
else if (pmtIn->majortype == MEDIATYPE_Audio) {
1314 GuidNames[pmtIn->formattype]));
1316 GuidNames[pmtIn->subtype]));
1318 if ((pmtIn->subtype != MEDIASUBTYPE_MPEG1Packet)
1319 && (pmtIn->cbFormat >=
sizeof(PCMWAVEFORMAT)))
1323 WAVEFORMATEX *pwfx = (WAVEFORMATEX *) pmtIn->pbFormat;
1326 DbgLog((
LOG_TRACE,2,TEXT(
"nSamplesPerSec %lu"), pwfx->nSamplesPerSec));
1327 DbgLog((
LOG_TRACE,2,TEXT(
"nAvgBytesPerSec %lu"), pwfx->nAvgBytesPerSec));
1329 DbgLog((
LOG_TRACE,2,TEXT(
"wBitsPerSample %u"), pwfx->wBitsPerSample));
1333 if (pmtIn->cbFormat >=
sizeof(WAVEFORMATEX)) {
1341 GuidNames[pmtIn->formattype]));
1346 void DisplayBITMAPINFO(
const BITMAPINFOHEADER* pbmi)
1348 DbgLog((
LOG_TRACE,5,TEXT(
"Size of BITMAPINFO structure %d"),pbmi->biSize));
1349 if (pbmi->biCompression < 256) {
1351 pbmi->biWidth, pbmi->biHeight,
1352 pbmi->biBitCount, pbmi->biCompression));
1355 pbmi->biWidth, pbmi->biHeight,
1356 pbmi->biBitCount, &pbmi->biCompression));
1361 DbgLog((
LOG_TRACE,5,TEXT(
"X Pels per metre %d"),pbmi->biXPelsPerMeter));
1362 DbgLog((
LOG_TRACE,5,TEXT(
"Y Pels per metre %d"),pbmi->biYPelsPerMeter));
1367 void DisplayRECT(LPCTSTR szLabel,
const RECT& rc)
1378 void WINAPI
DumpGraph(IFilterGraph *pGraph, DWORD dwLevel)
1385 IEnumFilters *pFilters;
1389 if (FAILED(pGraph->EnumFilters(&pFilters))) {
1393 IBaseFilter *pFilter;
1395 while (pFilters->Next(1, &pFilter, &
n) == S_OK) {
1398 if (FAILED(pFilter->QueryFilterInfo(&info))) {
1399 DbgLog((
LOG_TRACE,dwLevel,TEXT(
" Filter [%p] -- failed QueryFilterInfo"), pFilter));
1405 DbgLog((
LOG_TRACE,dwLevel,TEXT(
" Filter [%p] '%ls'"), pFilter, info.achName));
1409 if (FAILED(pFilter->EnumPins(&pins))) {
1414 while (pins->Next(1, &pPin, &
n) == S_OK) {
1417 if (FAILED(pPin->QueryPinInfo(&pinInfo))) {
1418 DbgLog((
LOG_TRACE,dwLevel,TEXT(
" Pin [%x] -- failed QueryPinInfo"), pPin));
1422 IPin *pPinConnected =
NULL;
1424 HRESULT
hr = pPin->ConnectedTo(&pPinConnected);
1426 if (pPinConnected) {
1428 TEXT(
" Connected to pin [%p]"),
1429 pPin, pinInfo.achName,
1430 pinInfo.dir == PINDIR_INPUT ? TEXT(
"In") : TEXT(
"Out"),
1433 pPinConnected->Release();
1437 if (pinInfo.dir == PINDIR_OUTPUT) {
1440 hr = pPin->ConnectionMediaType(&mt);
1442 if (SUCCEEDED(
hr)) {
1450 TEXT(
" Pin [%x] '%ls' [%sput]"),
1451 pPin, pinInfo.achName,
1452 pinInfo.dir == PINDIR_INPUT ? TEXT(
"In") : TEXT(
"Out")));
1469 pFilters->Release();