2025-11-28 00:35:46 +09:00

430 lines
11 KiB
C++

/*--
Copyright (C) Microsoft Corporation, 2006
Main test routintes.
--*/
#include "stdafx.h"
#include "EraseTest.h"
#include "EraseEventTest.h"
VOID PrintHelp(WCHAR * selfName)
{
printf("Usage:\n"
"%S DriveLetter [-fullerase]\n"
"Example:\n"
"%S E: -fullerase\n",
selfName, selfName
);
return;
}
BOOLEAN
GetParameters(
IN DWORD Count,
IN WCHAR* Arguments[],
OUT IDiscRecorder2** Recorder,
OUT VARIANT_BOOL* FullErase
)
{
BOOLEAN validArgument = TRUE;
if ((Count < 1) || (Count > 2))
{
validArgument = FALSE;
}
if (validArgument && (Arguments[0][1] != ':'))
{
validArgument = FALSE;
}
if (validArgument && (Count == 2))
{
if ( _wcsnicmp(Arguments[1], (L"-fullerase"), strlen("-fullerase")) == 0 )
{
*FullErase = VARIANT_TRUE;
}
else
{
validArgument = FALSE;
}
}
//Try to retrieve the recorder.
if (validArgument)
{
HRESULT hr = S_OK;
IDiscMaster2* tmpDiscMaster = NULL;
IEnumVARIANT* tmpRecorderEnumerator = NULL;
IDiscRecorder2* tmpRecorder = NULL;
VARIANT tmpUniqueId;
BOOLEAN recorderFound = FALSE;
// create the disc master object
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_MsftDiscMaster2,
NULL,
CLSCTX_ALL,
IID_PPV_ARGS(&tmpDiscMaster)
);
if (FAILED(hr))
{
printf("Failed to Create DiscMaster. Error: 0x%X.\n", hr);
}
}
// get a new enumerator for the disc recorders
if (SUCCEEDED(hr))
{
hr = tmpDiscMaster->get__NewEnum(&tmpRecorderEnumerator);
if (FAILED(hr))
{
printf("Failed get__NewEnum. Error: 0x%X.\n", hr);
}
}
// Reset the enumerator to the beginning
if (SUCCEEDED(hr))
{
hr = tmpRecorderEnumerator->Reset();
if (FAILED(hr))
{
printf("Failed to reset enumerator. Error: 0x%X.\n", hr);
}
}
// request just that one recorder's BSTR
if (SUCCEEDED(hr))
{
while (SUCCEEDED(hr) && !recorderFound)
{
hr = tmpRecorderEnumerator->Next(1, &tmpUniqueId, NULL);
if (SUCCEEDED(hr))
{
// Create a new IDiscRecorder2
hr = CoCreateInstance(CLSID_MsftDiscRecorder2,
NULL,
CLSCTX_ALL,
IID_PPV_ARGS(&tmpRecorder)
);
if (FAILED(hr))
{
printf("Failed CoCreateInstance for DiscRecorder. Error: 0x%X.\n", hr);
}
// Initialize it with the provided BSTR
if (SUCCEEDED(hr))
{
hr = tmpRecorder->InitializeDiscRecorder(tmpUniqueId.bstrVal);
if (FAILED(hr))
{
printf("Failed to init disc recorder. Error: 0x%X.\n", hr);
}
}
//Check if it's the right recorder.
if (SUCCEEDED(hr))
{
SAFEARRAY * mountPoints = NULL;
hr = tmpRecorder->get_VolumePathNames(&mountPoints);
if (FAILED(hr))
{
printf("Unable to get mount points. Error: 0x%X.\n", hr);
}
else if (mountPoints->rgsabound[0].cElements == 0)
{
printf("\tMount Point: *** NO MOUNT POINTS FOR RECORDER ***\n");
}
else
{
VARIANT* tmp = (VARIANT*)(mountPoints->pvData);
for (ULONG i = 0; i < mountPoints->rgsabound[0].cElements; i++)
{
if ( _wcsnicmp(Arguments[0], tmp[i].bstrVal, 2) == 0 )
{
recorderFound = TRUE;
break;
}
}
}
SafeArrayDestroyDataAndNull(mountPoints);
}
}
}
}
// copy to caller or release recorder
if (SUCCEEDED(hr) && recorderFound)
{
*Recorder = tmpRecorder;
}
else
{
validArgument = FALSE;
ReleaseAndNull(tmpRecorder);
}
// all other cleanup
ReleaseAndNull(tmpDiscMaster);
}
return validArgument;
}
class CConsoleModule : public ::ATL::CAtlExeModuleT<CConsoleModule>
{
};
CConsoleModule _AtlModule;
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
IDiscRecorder2* recorder = NULL;
VARIANT_BOOL fullErase = VARIANT_FALSE;
if ( !GetParameters(argc-1, argv+1, &recorder, &fullErase) )
{
PrintHelp(argv[0]);
hr = E_INVALIDARG;
}
else
{
hr = TestErase(recorder, fullErase);
}
return hr;
}
////////////////////////////////////////////////////////////////////
DWORD GetSecondsElapsed(SYSTEMTIME* StartTime, SYSTEMTIME* EndTime)
{
FILETIME Start;
FILETIME End;
unsigned __int64 Start64 = 0;
unsigned __int64 End64 = 0;
unsigned __int64 Elapsed64 = 0;
//
//--- Convert System time
//
SystemTimeToFileTime(StartTime,&Start);
SystemTimeToFileTime(EndTime,&End);
//
//---- Convert start and end file
//---- time to 2 64 bit usigned integers
//
((LPDWORD)(&Start64))[1] = Start.dwHighDateTime;
((LPDWORD)(&Start64))[0] = Start.dwLowDateTime;
((LPDWORD)(&End64))[1] = End.dwHighDateTime;
((LPDWORD)(&End64))[0] = End.dwLowDateTime;
//
//--- Calc elapsed time
//
Elapsed64 = End64 - Start64;
//
//---- Get micro seconds elapsed
//
Elapsed64 /= 10;
//
//--- Get milly seconds elapsed
//
Elapsed64 /= 1000;
//
//--- Get Seconds elapsed
//
Elapsed64 /= 1000;
//
//--- Return the LowDateTime of seconds elapsed
//--- This will be good enough for ~136 years elapsed
//
return(((LPDWORD)(&Elapsed64))[0]);
}
#define SECONDS_IN_A_DAY ((DWORD)(SECONDS_IN_A_HOUR*24))
#define SECONDS_IN_A_HOUR ((DWORD)(SECONDS_IN_A_MINUTE*60))
#define SECONDS_IN_A_MINUTE ((DWORD)(60))
void CalcElapsedTime(SYSTEMTIME* StartTime, SYSTEMTIME* FinishTime, SYSTEMTIME* ElapsedTime)
{
DWORD SecondsElapsed = 0;
memset(ElapsedTime,0,sizeof(SYSTEMTIME));
SecondsElapsed = GetSecondsElapsed(StartTime, FinishTime);
if(SecondsElapsed >= SECONDS_IN_A_DAY)
{
ElapsedTime->wDay = (WORD) (SecondsElapsed / SECONDS_IN_A_DAY);
SecondsElapsed -= (ElapsedTime->wDay*SECONDS_IN_A_DAY);
}
if(SecondsElapsed >= SECONDS_IN_A_HOUR)
{
ElapsedTime->wHour = (WORD) (SecondsElapsed / SECONDS_IN_A_HOUR);
SecondsElapsed -= (ElapsedTime->wHour * SECONDS_IN_A_HOUR);
}
if(SecondsElapsed >= SECONDS_IN_A_MINUTE)
{
ElapsedTime->wMinute = (WORD) (SecondsElapsed / SECONDS_IN_A_MINUTE);
SecondsElapsed -= (ElapsedTime->wMinute * SECONDS_IN_A_MINUTE);
}
ElapsedTime->wSecond = (WORD) SecondsElapsed;
}
HRESULT TestErase(IDiscRecorder2* Recorder, VARIANT_BOOL FullErase)
{
HRESULT hr = S_OK;
IEraseSample* eraser = NULL;
IStream * dataStream = NULL;
ULONG sectorsInDataStream = 0;
BOOLEAN dualLayerDvdMedia = FALSE;
SYSTEMTIME startTime;
SYSTEMTIME endTime;
SYSTEMTIME elapsedTime;
::ATL::CComObject<CTestEraseEvent>* eventSink = NULL;
// create a EraseSample object
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(__uuidof(MsftEraseSample),
NULL,
CLSCTX_ALL,
IID_PPV_ARGS(&eraser)
);
if (FAILED(hr))
{
printf("CoCreateInstance of CLSID_MsftEraseSample failed. Error: 0x%X.\n", hr);
}
}
// Set the recorder as the recorder for erase object
if (SUCCEEDED(hr))
{
hr = eraser->put_Recorder(Recorder);
if (FAILED(hr))
{
printf("Failed put_Recorder(). Error: 0x%X.\n", hr);
}
}
// Set the app name for use with exclusive access
// THIS IS REQUIRED
if (SUCCEEDED(hr))
{
BSTR appName = ::SysAllocString(L"EraseTest");
hr = eraser->put_ClientName(appName);
if (FAILED(hr))
{
printf("FAILED to set client name for erase!. Error: 0x%X.\n", hr);
}
FreeSysStringAndNull(appName);
}
// get the current media in the recorder
if (SUCCEEDED(hr))
{
IMAPI_MEDIA_PHYSICAL_TYPE mediaType = IMAPI_MEDIA_TYPE_UNKNOWN;
hr = eraser->get_CurrentPhysicalMediaType(&mediaType);
if (FAILED(hr))
{
printf("FAILED to eraser->get_CurrentPhysicalMediaType. Error: 0x%X.\n", hr);
}
}
//// Set full erase flag
if (SUCCEEDED(hr))
{
hr = eraser->put_FullErase(FullErase);
if (FAILED(hr))
{
printf("Failed put_FullErase(). Error: 0x%X.\n", hr);
}
}
// release the recorder early...
ReleaseAndNull(Recorder);
// create event
if (SUCCEEDED(hr))
{
hr = ::ATL::CComObject<CTestEraseEvent>::CreateInstance(&eventSink);
if (FAILED(hr))
{
printf("Failed to create event sink. Error: 0x%X.\n", hr);
}
else
{
eventSink->AddRef();
}
}
// hookup events
if (SUCCEEDED(hr))
{
hr = eventSink->DispEventAdvise(eraser);
if (FAILED(hr))
{
printf("Failed to hookup event sink. Error: 0x%X.\n", hr);
}
}
// erase the disc
if (SUCCEEDED(hr))
{
GetSystemTime(&startTime);
hr = eraser->EraseMedia();
GetSystemTime(&endTime);
if (FAILED(hr))
{
printf("FAILED to erase!. Error: 0x%X.\n", hr);
}
else
{
printf("\n");
CalcElapsedTime(&startTime, &endTime, &elapsedTime);
printf(" - Time to erase: %02d:%02d:%02d\n", elapsedTime.wHour,
elapsedTime.wMinute,
elapsedTime.wSecond);
}
}
// unhook events
if (NULL != eventSink)
{
eventSink->DispEventUnadvise(eraser);
}
ReleaseAndNull(eventSink);
ReleaseAndNull(eraser);
if (SUCCEEDED(hr))
{
printf("EraseMedia succeeded.\n");
}
else
{
printf("EraseMedia FAILED. Error: 0x%X.\n", hr);
}
return hr;
}