windows-nt/Source/XPSP1/NT/multimedia/directx/dxdiag/testmus.cpp
2020-09-26 16:20:57 +08:00

362 lines
12 KiB
C++

/****************************************************************************
*
* File: testmus.cpp
* Project: DxDiag (DirectX Diagnostic Tool)
* Author: Mike Anderson (manders@microsoft.com)
* Purpose: Test DMusic functionality on this machine
*
* (C) Copyright 1998 Microsoft Corp. All rights reserved.
*
****************************************************************************/
#include <Windows.h>
#include <multimon.h>
#include <dmusicc.h>
#include <dmusici.h>
#include "reginfo.h"
#include "sysinfo.h"
#include "dispinfo.h"
#include "musinfo.h"
#include "testmus.h"
#include "resource.h"
#ifndef ReleasePpo
#define ReleasePpo(ppo) \
if (*(ppo) != NULL) \
{ \
(*(ppo))->Release(); \
*(ppo) = NULL; \
} \
else (VOID)0
#endif
enum TESTID
{
TESTID_COINITIALIZE = 1,
TESTID_CREATEDMLOADER,
TESTID_CREATEDMPERF,
TESTID_INITPERF,
TESTID_CREATEPORT,
TESTID_ACTIVATEPORT,
TESTID_SETAUTODOWNLOAD,
TESTID_ADDPORT,
TESTID_ASSIGNPCHANNELBLOCK,
TESTID_SPEWRESOURCETOFILE,
TESTID_SETSEARCHDIRECTORY,
TESTID_LOADERGETOBJECT,
TESTID_PLAYSEGMENT,
};
BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish = FALSE); // from main.cpp (yuck)
static HRESULT SpewResourceToFile(TCHAR* pszResType, LONG idRes, TCHAR* pszFileName);
static HRESULT LoadSegment( BOOL fUseCWD );
static VOID DeleteTempFile(TCHAR* pszFileName);
/****************************************************************************
*
* TestMusic
*
****************************************************************************/
VOID TestMusic(HWND hwndMain, MusicInfo* pMusicInfo)
{
HRESULT hr;
MusicPort* pMusicPort = NULL;
IDirectMusicLoader* pLoader = NULL;
IDirectMusicPerformance* pPerformance = NULL;
IDirectMusic* pdm = NULL;
IDirectMusicPort* pPort = NULL;
IDirectMusicSegment* pSegment = NULL;
BOOL bComInitialized = FALSE;
TCHAR szFmt[300];
TCHAR sz[300];
TCHAR szTitle[100];
if (pMusicInfo == NULL)
return;
// Determine pMusicPort of port to test:
for (pMusicPort = pMusicInfo->m_pMusicPortFirst; pMusicPort != NULL; pMusicPort = pMusicPort->m_pMusicPortNext)
{
if (pMusicPort->m_guid == pMusicInfo->m_guidMusicPortTest)
break;
}
if (pMusicPort == NULL)
return;
LoadString(NULL, IDS_APPFULLNAME, szTitle, 100);
LoadString(NULL, IDS_STARTDMUSICTEST, szFmt, 300);
wsprintf(sz, szFmt, pMusicPort->m_szDescription);
if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO))
return;
// Remove info from any previous test:
ZeroMemory(&pMusicInfo->m_testResult, sizeof(TestResult));
pMusicInfo->m_testResult.m_bStarted = TRUE;
// Initialize COM
if (FAILED(hr = CoInitialize(NULL)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_COINITIALIZE;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
bComInitialized = TRUE;
// Create performance object
if (FAILED(hr = CoCreateInstance(CLSID_DirectMusicPerformance, NULL,
CLSCTX_INPROC, IID_IDirectMusicPerformance, (VOID**)&pPerformance)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEDMPERF;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Initialize the performance -- also creates DirectMusic object
if (FAILED(hr = pPerformance->Init(&pdm, NULL, hwndMain)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_INITPERF;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Create a port using the user-specified GUID
DMUS_PORTPARAMS portParams;
ZeroMemory(&portParams, sizeof(portParams));
portParams.dwSize = sizeof(portParams);
portParams.dwValidParams = DMUS_PORTPARAMS_EFFECTS | DMUS_PORTPARAMS_CHANNELGROUPS |
DMUS_PORTPARAMS_AUDIOCHANNELS;
portParams.dwEffectFlags = DMUS_EFFECT_REVERB;
portParams.dwChannelGroups = pMusicPort->m_dwMaxChannelGroups;
portParams.dwAudioChannels = pMusicPort->m_dwMaxAudioChannels;
if (FAILED(hr = pdm->CreatePort(pMusicPort->m_guid, &portParams, &pPort, NULL)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEPORT;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Activate the port
if (FAILED(hr = pPort->Activate(TRUE)))
{
// Bug 21677: catch case where user has no sound card
if (hr == DSERR_NODRIVER && !pMusicPort->m_bExternal)
{
LoadString(NULL, IDS_NOSOUNDDRIVER, sz, 300);
MessageBox(hwndMain, sz, szTitle, MB_OK);
}
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ACTIVATEPORT;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Set autodownloading to be on
BOOL fAutoDownload;
fAutoDownload = TRUE;
if (FAILED(hr = pPerformance->SetGlobalParam(GUID_PerfAutoDownload,
&fAutoDownload, sizeof(BOOL))))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SETAUTODOWNLOAD;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Add the port to the performance
if (FAILED(hr = pPerformance->AddPort(pPort)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ADDPORT;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
if (FAILED(hr = pPerformance->AssignPChannelBlock(0, pPort, 1)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ASSIGNPCHANNELBLOCK;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
if (FAILED(hr = SpewResourceToFile(TEXT("SGMT"), IDR_TSTSGMT, TEXT("Edge.sgt"))))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SPEWRESOURCETOFILE;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
if (FAILED(hr = SpewResourceToFile(TEXT("STYL"), IDR_TSTSTYL, TEXT("Edge.sty"))))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SPEWRESOURCETOFILE;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Create loader object
if (FAILED(hr = CoCreateInstance(CLSID_DirectMusicLoader, NULL,
CLSCTX_INPROC, IID_IDirectMusicLoader, (VOID**)&pLoader)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEDMLOADER;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Set search path to temp dir to find segment and style:
WCHAR wszDir[MAX_PATH];
TCHAR szTempPath[MAX_PATH];
GetTempPath(MAX_PATH, szTempPath);
szTempPath[lstrlen(szTempPath) - 1] = '\0';
#ifdef UNICODE
lstrcpy(wszDir, szTempPath);
#else
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTempPath, -1, wszDir, MAX_PATH);
#endif
if (FAILED(hr = pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wszDir, FALSE)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SETSEARCHDIRECTORY;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Load the segment
// now load the segment file.
// sections load as type Segment, as do MIDI files, for example.
DMUS_OBJECTDESC objDesc; // Object descriptor for pLoader->GetObject()
objDesc.guidClass = CLSID_DirectMusicSegment;
objDesc.dwSize = sizeof(DMUS_OBJECTDESC);
wcscpy(objDesc.wszFileName, L"edge.sgt");
objDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;
if (FAILED(hr = pLoader->GetObject(&objDesc, IID_IDirectMusicSegment, (VOID**)&pSegment)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_LOADERGETOBJECT;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
// Play the segment and wait. The DMUS_SEGF_BEAT indicates to play on the
// next beat if there is a segment currently playing. The first 0 indicates
// to play (on the next beat from) now.
// The final NULL means do not return an IDirectMusicSegmentState* in
// the last parameter.
if (FAILED(hr = pPerformance->PlaySegment(pSegment, DMUS_SEGF_BEAT, 0, NULL)))
{
pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_PLAYSEGMENT;
pMusicInfo->m_testResult.m_hr = hr;
goto LEnd;
}
if (pMusicPort->m_bExternal)
LoadString(NULL, IDS_EXTERNALMUSICPLAYING, sz, 300);
else
LoadString(NULL, IDS_MUSICPLAYING, sz, 300);
MessageBox(hwndMain, sz, szTitle, MB_OK);
pPerformance->Stop(pSegment, NULL, 0, 0);
LEnd:
DeleteTempFile(TEXT("Edge.sgt"));
DeleteTempFile(TEXT("Edge.sty"));
ReleasePpo(&pdm);
ReleasePpo(&pPort);
if (pPerformance != NULL)
pPerformance->CloseDown();
ReleasePpo(&pPerformance);
ReleasePpo(&pLoader);
if (bComInitialized)
{
// Release COM
CoUninitialize();
}
if (pMusicInfo->m_testResult.m_iStepThatFailed == 0)
{
LoadString(NULL, IDS_TESTSSUCCESSFUL, sz, 300);
lstrcpy(pMusicInfo->m_testResult.m_szDescription, sz);
LoadString(NULL, IDS_TESTSSUCCESSFUL_ENGLISH, sz, 300);
lstrcpy(pMusicInfo->m_testResult.m_szDescriptionEnglish, sz);
}
else
{
TCHAR szDesc[200];
TCHAR szError[200];
if (0 == LoadString(NULL, IDS_FIRSTDMUSICTESTERROR +
pMusicInfo->m_testResult.m_iStepThatFailed - 1, szDesc, 200))
{
LoadString(NULL, IDS_UNKNOWNERROR, sz, 300);
lstrcpy(szDesc, sz);
}
LoadString(NULL, IDS_FAILUREFMT, sz, 300);
BTranslateError(pMusicInfo->m_testResult.m_hr, szError);
wsprintf(pMusicInfo->m_testResult.m_szDescription, sz,
pMusicInfo->m_testResult.m_iStepThatFailed,
szDesc, pMusicInfo->m_testResult.m_hr, szError);
// Nonlocalized version:
if (0 == LoadString(NULL, IDS_FIRSTDMUSICTESTERROR_ENGLISH +
pMusicInfo->m_testResult.m_iStepThatFailed - 1, szDesc, 200))
{
LoadString(NULL, IDS_UNKNOWNERROR_ENGLISH, sz, 300);
lstrcpy(szDesc, sz);
}
LoadString(NULL, IDS_FAILUREFMT_ENGLISH, sz, 300);
BTranslateError(pMusicInfo->m_testResult.m_hr, szError, TRUE);
wsprintf(pMusicInfo->m_testResult.m_szDescriptionEnglish, sz,
pMusicInfo->m_testResult.m_iStepThatFailed,
szDesc, pMusicInfo->m_testResult.m_hr, szError);
}
}
/****************************************************************************
*
* SpewResourceToFile
*
****************************************************************************/
HRESULT SpewResourceToFile(TCHAR* pszResType, LONG idRes, TCHAR* pszFileName)
{
TCHAR szTempPath[MAX_PATH];
HRSRC hResInfo = NULL;
HGLOBAL hResData = NULL;
BYTE* pbData = NULL;
HANDLE hfile;
DWORD numBytes;
DWORD numBytesWritten;
GetTempPath(MAX_PATH, szTempPath);
lstrcat(szTempPath, pszFileName);
if (NULL == (hResInfo = FindResource(NULL, MAKEINTRESOURCE(idRes), pszResType)))
return E_FAIL;
numBytes = SizeofResource(NULL, hResInfo);
if (NULL == (hResData = LoadResource(NULL, hResInfo)))
return E_FAIL;
if (NULL == (pbData = (BYTE*)LockResource(hResData)))
return E_FAIL;
hfile = CreateFile(szTempPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY, NULL);
if (hfile == INVALID_HANDLE_VALUE)
return E_FAIL;
WriteFile(hfile, pbData, numBytes, &numBytesWritten, NULL);
CloseHandle(hfile);
return S_OK;
}
/****************************************************************************
*
* DeleteTempFile
*
****************************************************************************/
VOID DeleteTempFile(TCHAR* pszFileName)
{
TCHAR szTempPath[MAX_PATH];
GetTempPath(MAX_PATH, szTempPath);
lstrcat(szTempPath, pszFileName);
DeleteFile(szTempPath);
}