/*==========================================================================; * * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. * * File: dxvt.cpp * Content: Full Duplex Test main program. * History: * Date By Reason * ============ * 08/19/99 pnewson created * 09/02/99 pnewson renamed to dxvt.cpp from fdtest.cpp * 11/01/99 rodtoll Bug #113726 - Voxware integration now uses COM * and this module uses LoadLibrary so we require * a CoInitialize() call. * 01/21/2000 pnewson Running this program with no command line options * now does nothing, since the cpanel is the correct * launch point now. * 03/03/2000 rodtoll Updated to handle alternative gamevoice build. * 04/19/2000 pnewson Error handling cleanup * removed obsolete retrocfg.h dependency * 06/28/2000 rodtoll Prefix Bug #38026 * 07/12/2000 rodtoll Bug #31468 - Add diagnostic spew to logfile to show what is failing the HW Wizard * 08/28/2000 masonb Voice Merge: Removed OSAL_* and dvosal.h, added STR_* and strutils.h * 04/02/2001 simonpow Bug #354859 Fixes for PREfast (BOOL casts on DVGUIDFromString calls) * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "dvoice.h" #include "creg.h" #include "osind.h" #include "priority.h" #include "fulldup.h" #include "fdtcfg.h" #include "dndbg.h" #include "dsound.h" #include "supervis.h" #include "guidutil.h" #include "strutils.h" #include "comutil.h" #include "diagnos.h" #include "..\..\bldcfg\dpvcfg.h" #undef DPF_SUBCOMP #define DPF_SUBCOMP DN_SUBCOMP_VOICE #define DPVOICE_REGISTRY_DUMPDIAGNOSTICS L"InitDiagnostics" struct DPVSETUP_PARAMETERS { BOOL fPriority; BOOL fFullDuplex; BOOL fTest; GUID guidRender; GUID guidCapture; }; #undef DPF_MODNAME #define DPF_MODNAME "ProcessCommandLine" BOOL ProcessCommandLine( TCHAR *pstrCommandLine, DPVSETUP_PARAMETERS* pParameters ) { TCHAR *pNextToken = NULL; WCHAR wszGuidString[GUID_STRING_LEN]; BOOL fRet; HRESULT hr=S_OK; DPF_ENTER(); ZeroMemory(pParameters, sizeof(DPVSETUP_PARAMETERS)); // default to the default voice devices pParameters->guidRender = DSDEVID_DefaultVoicePlayback; pParameters->guidCapture = DSDEVID_DefaultVoiceCapture; pNextToken = _tcstok(pstrCommandLine, _T(" ")); // skip dpvsetup portion of command-line. pNextToken = _tcstok( NULL, _T(" ") ); while( pNextToken != NULL ) { if( _tcsicmp(pNextToken, _T("/T")) == 0 || _tcsicmp(pNextToken, _T("/TEST")) == 0 || _tcsicmp(pNextToken, _T("-T")) == 0 || _tcsicmp(pNextToken, _T("-TEST")) == 0 || _tcsicmp(pNextToken, _T("TEST")) == 0) { pParameters->fTest = TRUE; } else if(_tcsicmp(pNextToken, _T("/F")) == 0 || _tcsicmp(pNextToken, _T("/FULLDUPLEX")) == 0 || _tcsicmp(pNextToken, _T("-F")) == 0 || _tcsicmp(pNextToken, _T("-FULLDUPLEX")) == 0 || _tcsicmp(pNextToken, _T("FULLDUPLEX")) == 0) { pParameters->fFullDuplex = TRUE; } else if(_tcsicmp(pNextToken, _T("/P")) == 0 || _tcsicmp(pNextToken, _T("/PRIORITY")) == 0 || _tcsicmp(pNextToken, _T("-P")) == 0 || _tcsicmp(pNextToken, _T("-PRIORITY")) == 0 || _tcsicmp(pNextToken, _T("PRIORITY")) == 0) { pParameters->fPriority = TRUE; } else if(_tcsicmp(pNextToken, _T("/R")) == 0 || _tcsicmp(pNextToken, _T("/RENDER")) == 0 || _tcsicmp(pNextToken, _T("-R")) == 0 || _tcsicmp(pNextToken, _T("-RENDER")) == 0) { // get the render device guid pNextToken = _tcstok( pstrCommandLine, _T(" ") ); if (pNextToken != NULL) { if (_tcslen(pstrCommandLine) != GUID_STRING_LEN - 1) { // command line guid string too long, error DPFX(DPFPREP, DVF_ERRORLEVEL, "guid on command line wrong size"); DPF_EXIT(); return FALSE; } else { #ifdef UNICODE wcscpy( wszGuidString, pNextToken ); #else if ( FAILED(STR_jkAnsiToWide(wszGuidString, pNextToken, GUID_STRING_LEN))) { DPFX(DPFPREP, DVF_ERRORLEVEL, "STR_jkAnsiToWide failed"); DPF_EXIT(); return FALSE; } #endif hr=DVGUIDFromString(wszGuidString, &pParameters->guidRender); if (FAILED(hr)) { DPFX(DPFPREP, DVF_ERRORLEVEL, "DVGUIDFromString failed"); DPF_EXIT(); return FALSE; } } } } else if( _tcsicmp(pNextToken, _T("/C")) == 0 || _tcsicmp(pNextToken, _T("/CAPTURE")) == 0 || _tcsicmp(pNextToken, _T("-C")) == 0 || _tcsicmp(pNextToken, _T("-CAPTURE")) == 0) { // get the render device guid pNextToken = _tcstok( pstrCommandLine, _T(" ") ); if (pNextToken != NULL) { if (_tcslen(pstrCommandLine) != GUID_STRING_LEN - 1) { // command line guid string too long, error DPFX(DPFPREP, DVF_ERRORLEVEL, "guid on command line wrong size"); DPF_EXIT(); return FALSE; } else { #ifdef UNICODE wcscpy( wszGuidString, pNextToken ); #else if ( FAILED(STR_jkAnsiToWide(wszGuidString, pNextToken, GUID_STRING_LEN))) { DPFX(DPFPREP, DVF_ERRORLEVEL, "STR_jkAnsiToWide failed"); DPF_EXIT(); return FALSE; } #endif hr=DVGUIDFromString(wszGuidString, &pParameters->guidCapture); if (FAILED(hr)) { DPFX(DPFPREP, DVF_ERRORLEVEL, "DVGUIDFromString failed"); DPF_EXIT(); return FALSE; } } } } else { DPF_EXIT(); return FALSE; } pNextToken = _tcstok( NULL, _T(" ") ); } // check to make sure only one of test, fullduplex, or priority was specified. int i = 0; if (pParameters->fTest) { ++i; } if (pParameters->fFullDuplex) { ++i; } if (pParameters->fPriority) { ++i; } if (i > 1) { DPF_EXIT(); return FALSE; } DPF_EXIT(); return TRUE; } #undef DPF_MODNAME #define DPF_MODNAME "GetDiagnosticsSetting" BOOL GetDiagnosticsSetting() { CRegistry cregSettings; BOOL fResult = FALSE; if( !cregSettings.Open( HKEY_CURRENT_USER, DPVOICE_REGISTRY_BASE, FALSE, TRUE ) ) { return FALSE; } cregSettings.ReadBOOL( DPVOICE_REGISTRY_DUMPDIAGNOSTICS, fResult ); return fResult; } #undef DPF_MODNAME #define DPF_MODNAME "WinMain" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, CHAR *szOriginalCmdLine, int iCmdShow) { HINSTANCE hResDLLInstance = NULL; HRESULT hr; DPVSETUP_PARAMETERS dpvsetupParam; BOOL fCoInitialized = FALSE; BOOL fDNOSInitialized = FALSE; BOOL fDiagnostics = FALSE; TCHAR *szCmdLine = GetCommandLine(); DPF_ENTER(); hr = COM_CoInitialize(NULL); if( FAILED( hr ) ) { MessageBox( NULL, _T("Error initializing COM"), _T("Error"), MB_OK|MB_ICONERROR); hr = DVERR_GENERIC; goto error_cleanup; } fCoInitialized = TRUE; if (!DNOSIndirectionInit()) { MessageBox( NULL, _T("Error initializing OS indirection layer"), _T("Error"), MB_OK|MB_ICONERROR); hr = DVERR_OUTOFMEMORY; goto error_cleanup; } fDNOSInitialized = TRUE; fDiagnostics = GetDiagnosticsSetting(); if (!ProcessCommandLine(szCmdLine, &dpvsetupParam)) { MessageBox(NULL, _T("Bad Command Line Parameters"), _T("Error"), MB_OK|MB_ICONERROR); hr = DVERR_INVALIDPARAM; goto error_cleanup; } hResDLLInstance = LoadLibraryA(gc_szResDLLName); if (hResDLLInstance == NULL) { MessageBox(NULL, _T("Unable to load resource DLL - exiting program"), _T("Error"), MB_OK|MB_ICONERROR); hr = DVERR_GENERIC; goto error_cleanup; } if (dpvsetupParam.fPriority) { // This process is the one that opens dsound in // priority mode and sets the primary buffer to various // formats. // use SEH to clean up any really nasty errors __try { Diagnostics_Begin( fDiagnostics, "dpv_pri.txt" ); hr = PriorityProcess(hResDLLInstance, hPrevInstance, szCmdLine, iCmdShow); Diagnostics_End(); } __except(1) { hr = DVERR_GENERIC; } if( FAILED( hr ) ) { goto error_cleanup; } } else if (dpvsetupParam.fFullDuplex) { // This process is the one that performs the full duplex // testing, in conjunction with the other process that // sets the primary buffer format. // use SEH to clean up any really nasty errors __try { Diagnostics_Begin( fDiagnostics, "dpv_fd.txt" ); hr = FullDuplexProcess(hResDLLInstance, hPrevInstance, szCmdLine, iCmdShow); Diagnostics_End(); } __except(1) { hr = DVERR_GENERIC; } if( FAILED( hr ) ) { goto error_cleanup; } } else if (dpvsetupParam.fTest) { Diagnostics_Begin( fDiagnostics, "dpv_sup.txt" ); // The user wants this program to run the whole test on the default // voice devices. hr = SupervisorCheckAudioSetup(&dpvsetupParam.guidRender, &dpvsetupParam.guidCapture, NULL, 0); Diagnostics_End(); if( FAILED( hr ) ) { goto error_cleanup; } } // With no command line parameters, this process does nothing. // You must know the secret handshake to get it to do something. // no error checking, since we're on our way out anyway FreeLibrary(hResDLLInstance); hResDLLInstance = NULL; DNOSIndirectionDeinit(); fDNOSInitialized = FALSE; COM_CoUninitialize(); fCoInitialized = FALSE; DPF_EXIT(); return DV_OK; error_cleanup: if (hResDLLInstance != NULL) { FreeLibrary(hResDLLInstance); hResDLLInstance = NULL; } if (fDNOSInitialized == TRUE) { DNOSIndirectionDeinit(); fDNOSInitialized = FALSE; } if (fCoInitialized == TRUE) { COM_CoUninitialize(); fCoInitialized = FALSE; } DPF_EXIT(); return hr; }