2025-04-27 07:49:33 -04:00

348 lines
10 KiB
C++

inline HRESULT LastError()
{
return MAKE_HRESULT(SEVERITY_ERROR,
FACILITY_WIN32,
GetLastError());
}
class CTestFileRead
{
public:
CTestFileRead() {
m_hFile = INVALID_HANDLE_VALUE;
m_pHeader = NULL;
m_pszFile = NULL;
m_llOffset = 0;
}
~CTestFileRead() {
Close();
}
void Close()
{
if (m_hFile != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
delete [] (BYTE *)m_pHeader;
m_pHeader = NULL;
delete [] m_pszFile;
m_pszFile = NULL;
}
HRESULT Open(LPCTSTR lpszFile)
{
if (m_pszFile) {
Close();
}
m_pszFile = new TCHAR[lstrlen(lpszFile) + 1];
if (m_pszFile == NULL) {
//Error(ERROR_TYPE_TEST, E_OUTOFMEMORY, TEXT("Could not allocate file name string"));
return E_OUTOFMEMORY;
}
lstrcpy(m_pszFile, lpszFile);
m_hFile = CreateFile(lpszFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if (INVALID_HANDLE_VALUE == m_hFile) {
//TCHAR sz[1000];
//wsprintf(sz, TEXT("Error opening test data file for read %s"),
// lpszFile);
//Error(ERROR_TYPE_TEST, hr, sz);
return LastError();
}
// Check it's one of ours
DWORD dwReadSize = 0;
GUID guidFile;
ReadFile(m_hFile, &guidFile, sizeof(guidFile), &dwReadSize, NULL);
m_llOffset += dwReadSize;
if (dwReadSize != sizeof(guidFile) ||
guidFile != GUID_DMOFile) {
Close();
return E_INVALIDARG;
}
return S_OK;
}
HRESULT Next()
{
// Read the next chunk
DWORD dwRead;
DWORD dwLen;
if (!ReadFile(m_hFile, &dwLen, sizeof(dwLen), &dwRead, NULL)) {
// Error(ERROR_TYPE_TESTDATA, hr, TEXT("Problem reading test data file %s"), m_pszFile);
return LastError();
}
m_llOffset += dwRead;
// From ReadFile()'s documentation in MSDN "If the return value is nonzero and the
// number of bytes read is zero, the file pointer was beyond the current end of
// the file at the time of the read operation."
// Have we read all the data in the file?
if (0 == dwRead) {
return S_FALSE;
}
if (dwRead != sizeof(dwLen)) {
return E_FAIL;
}
if (dwLen < sizeof(CFileFormat::CHeader)) {
return E_FAIL;
}
delete [] (BYTE *)m_pHeader;
m_pHeader = (CFileFormat::CHeader *)new BYTE[dwLen];
m_pHeader->dwLength = dwLen;
// Now read for the length
if (!ReadFile(m_hFile, (PBYTE)m_pHeader + sizeof(DWORD),
dwLen - sizeof(DWORD), &dwRead, NULL)) {
//Error(ERROR_TYPE_TESTDATA, hr, TEXT("Problem reading test data file %s"), m_pszFile);
return LastError();
}
m_llOffset += dwRead;
if ((dwLen - sizeof(DWORD)) != dwRead) {
return E_FAIL;
}
// Now check out the chunks we know about
DWORD dwExpectedLen;
switch (m_pHeader->dwType) {
case CFileFormat::MediaType:
{
CFileFormat::CMediaType *pmt =
static_cast<CFileFormat::CMediaType *>(m_pHeader);
dwExpectedLen = sizeof(CFileFormat::CMediaType) + pmt->mt.cbFormat;
if (dwLen != dwExpectedLen) {
//Error(ERROR_TYPE_TEST_DATA, E_FAIL,
// TEXT("Invalid media type length - was %d, expected %d"),
// dwLen, dwExpectedLen);
return E_FAIL;
}
// Set pbFormat correct
pmt->mt.pbFormat = (BYTE *)(pmt+1);
// Make sure the pUnk is 0
pmt->mt.pUnk = NULL;
}
break;
case CFileFormat::Sample:
{
if (dwLen < sizeof(CFileFormat::CSample)) {
//Error(ERROR_TYPE_TEST_DATA, E_FAIL,
// TEXT("Invalid Sample length - was %d, expected >= %d"),
// dwLen, sizeof(CFileFormat::CSample));
return E_FAIL;
}
}
break;
default:
return E_UNEXPECTED;
}
return S_OK;
}
// Lots of helpers
DWORD Type()
{
if (NULL == m_pHeader) {
//Error(ERROR_TYPE_INTERNAL, E_FAIL,
// TEXT("Invalid call to CTestFile::Type"));
return 0;
}
return m_pHeader->dwType;
}
DWORD Stream()
{
if (NULL == m_pHeader) {
//Error(ERROR_TYPE_INTERNAL, E_FAIL,
// TEXT("Invalid call to CTestFile::Stream"));
return 0;
}
return m_pHeader->dwStreamId;
}
DMO_MEDIA_TYPE *MediaType()
{
if (NULL == m_pHeader || m_pHeader->dwType != CFileFormat::MediaType) {
//Error(ERROR_TYPE_INTERNAL, E_FAIL,
// TEXT("Invalid call to MediaType"));
return 0;
}
return &(static_cast<CFileFormat::CMediaType *>(m_pHeader))->mt;
}
CFileFormat::CSample *Sample()
{
if (NULL == m_pHeader || m_pHeader->dwType != CFileFormat::Sample) {
//Error(ERROR_TYPE_INTERNAL, E_FAIL,
// TEXT("Invalid call to Sample"));
return 0;
}
return (static_cast<CFileFormat::CSample *>(m_pHeader));
}
CFileFormat::CHeader *Header()
{
return m_pHeader;
}
LONGLONG Offset() const
{
return m_llOffset;
}
CFileFormat::CHeader *m_pHeader;
TCHAR *m_pszFile;
HANDLE m_hFile;
LONGLONG m_llOffset;
};
class CTestFileWrite
{
public:
CTestFileWrite() {
m_hFile = INVALID_HANDLE_VALUE;
m_pHeader = NULL;
m_pszFile = NULL;
}
~CTestFileWrite() {
Close();
}
void Close()
{
if (m_hFile != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
delete [] (BYTE *)m_pHeader;
m_pHeader = NULL;
delete [] m_pszFile;
m_pszFile = NULL;
}
HRESULT Open(LPCTSTR lpszFile)
{
m_pszFile = new TCHAR[lstrlen(lpszFile) + 1];
if (m_pszFile == NULL) {
//Error(ERROR_TYPE_TEST, E_OUTOFMEMORY, TEXT("Could not allocate file name string"));
return E_OUTOFMEMORY;
}
lstrcpy(m_pszFile, lpszFile);
m_hFile = CreateFile(lpszFile,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
0,
NULL);
if (INVALID_HANDLE_VALUE == m_hFile) {
//TCHAR sz[1000];
//wsprintf(sz, TEXT("Error opening test data file for write %s"),
// lpszFile);
//Error(ERROR_TYPE_TEST, sz, hr);
return LastError();
}
// Write our signature
DWORD dwWriteSize = 0;
if (!WriteFile(m_hFile, &GUID_DMOFile, sizeof(GUID_DMOFile), &dwWriteSize, NULL)) {
HRESULT hr = LastError();
Close();
return hr;
}
return S_OK;
}
HRESULT WriteMediaType(
DWORD dwStreamId,
const DMO_MEDIA_TYPE *pType
)
{
DWORD dwLength = sizeof(CFileFormat::CMediaType) +
pType->cbFormat;
CFileFormat::CMediaType* pFileType = (CFileFormat::CMediaType *) new BYTE[dwLength];
if( NULL == pFileType ) {
return E_OUTOFMEMORY;
}
ZeroMemory(pFileType, sizeof(CFileFormat::CMediaType));
pFileType->dwLength = dwLength;
pFileType->dwType = CFileFormat::MediaType;
pFileType->dwStreamId;
pFileType->mt = *pType;
CopyMemory(pFileType + 1, pType->pbFormat, pType->cbFormat);
DWORD dwBytesWritten;
if (!WriteFile(m_hFile,
pFileType,
dwLength,
&dwBytesWritten,
NULL)) {
//Error(ERROR_TYPE_TESTDATA, hr, TEXT("Problem writing test data file %s"), m_pszFile);
delete [] pFileType;
return LastError();
}
delete [] pFileType;
return S_OK;
}
HRESULT WriteSample(
DWORD dwStreamId,
const BYTE *pbData,
DWORD cbData,
DWORD dwFlags,
LONGLONG llStartTime,
LONGLONG llLength
)
{
DWORD dwLength = sizeof(CFileFormat::CSample) +
cbData;
CFileFormat::CSample* pFileSample = (CFileFormat::CSample *) new BYTE[dwLength];
if( NULL == pFileSample ) {
return E_OUTOFMEMORY;
}
ZeroMemory(pFileSample, sizeof(CFileFormat::CSample));
pFileSample->dwLength = dwLength;
pFileSample->dwType = CFileFormat::Sample;
pFileSample->dwStreamId;
pFileSample->dwFlags = dwFlags;
pFileSample->llStartTime = llStartTime;
pFileSample->llLength = llLength;
CopyMemory(pFileSample + 1, pbData, cbData);
DWORD dwBytesWritten;
if (!WriteFile(m_hFile,
pFileSample,
dwLength,
&dwBytesWritten,
NULL)) {
//Error(ERROR_TYPE_TESTDATA, hr, TEXT("Problem writing test data file %s"), m_pszFile);
delete [] pFileSample;
return LastError();
}
delete [] pFileSample;
return S_OK;
}
HANDLE m_hFile;
CFileFormat::CHeader *m_pHeader;
TCHAR *m_pszFile;
};