You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
778 lines
18 KiB
778 lines
18 KiB
//
|
|
// Microsoft Windows Media Technologies
|
|
// Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
|
|
//
|
|
|
|
// MSHDSP.DLL is a sample WMDM Service Provider(SP) that enumerates fixed drives.
|
|
// This sample shows you how to implement an SP according to the WMDM documentation.
|
|
// This sample uses fixed drives on your PC to emulate portable media, and
|
|
// shows the relationship between different interfaces and objects. Each hard disk
|
|
// volume is enumerated as a device and directories and files are enumerated as
|
|
// Storage objects under respective devices. You can copy non-SDMI compliant content
|
|
// to any device that this SP enumerates. To copy an SDMI compliant content to a
|
|
// device, the device must be able to report a hardware embedded serial number.
|
|
// Hard disks do not have such serial numbers.
|
|
//
|
|
// To build this SP, you are recommended to use the MSHDSP.DSP file under Microsoft
|
|
// Visual C++ 6.0 and run REGSVR32.EXE to register the resulting MSHDSP.DLL. You can
|
|
// then build the sample application from the WMDMAPP directory to see how it gets
|
|
// loaded by the application. However, you need to obtain a certificate from
|
|
// Microsoft to actually run this SP. This certificate would be in the KEY.C file
|
|
// under the INCLUDE directory for one level up.
|
|
|
|
// MDSPDevice.cpp : Implementation of CMDSPDevice
|
|
|
|
#include "hdspPCH.h"
|
|
#include "mshdsp.h"
|
|
#include "wmsstd.h"
|
|
#define STRSAFE_NO_DEPRECATE
|
|
#include "strsafe.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMDSPDevice
|
|
HRESULT CMDSPDevice::InitGlobalDeviceInfo()
|
|
{
|
|
return SetGlobalDeviceStatus(m_wcsName, 0, FALSE);
|
|
}
|
|
|
|
CMDSPDevice::CMDSPDevice()
|
|
{
|
|
m_wcsName[0] = 0;
|
|
}
|
|
|
|
CMDSPDevice::~CMDSPDevice()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetName(LPWSTR pwszName, UINT nMaxChars)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(pwszName);
|
|
CPRg(nMaxChars>wcslen(m_wcsName));
|
|
|
|
if( m_wcsName[0] )
|
|
{
|
|
wcscpy(pwszName, m_wcsName);
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
}
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetName returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetManufacturer(LPWSTR pwszName, UINT nMaxChars)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(pwszName);
|
|
|
|
if(FAILED(UtilGetManufacturer(m_wcsName, &pwszName, nMaxChars)))
|
|
{
|
|
if (hr != STRSAFE_E_INSUFFICIENT_BUFFER)
|
|
{
|
|
hr = E_NOTIMPL;
|
|
}
|
|
}
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetManufacturer returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetVersion(DWORD * pdwVersion)
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetVersion returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetType(DWORD * pdwType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WMDMID snTmp;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(pdwType);
|
|
|
|
*pdwType = WMDM_DEVICE_TYPE_STORAGE | WMDM_DEVICE_TYPE_NONSDMI;
|
|
|
|
snTmp.cbSize = sizeof(WMDMID);
|
|
|
|
hr = UtilGetSerialNumber(m_wcsName, &snTmp, FALSE);
|
|
if( hr == S_OK )
|
|
{
|
|
*pdwType |= WMDM_DEVICE_TYPE_SDMI;
|
|
}
|
|
|
|
hr=S_OK;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetType returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetSerialNumber(
|
|
PWMDMID pSerialNumber,
|
|
BYTE abMac[WMDM_MAC_LENGTH])
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(pSerialNumber);
|
|
|
|
hr = UtilGetSerialNumber(m_wcsName, pSerialNumber, TRUE);
|
|
if( hr == HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) )
|
|
{
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
}
|
|
|
|
if( hr == S_OK )
|
|
{
|
|
// MAC the parameters
|
|
HMAC hMAC;
|
|
|
|
CORg(g_pAppSCServer->MACInit(&hMAC));
|
|
CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pSerialNumber), sizeof(WMDMID)));
|
|
CORg(g_pAppSCServer->MACFinal(hMAC, abMac));
|
|
}
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetSerialNumber returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetPowerSource(DWORD * pdwPowerSource, DWORD * pdwPercentRemaining)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(pdwPowerSource);
|
|
CARg(pdwPercentRemaining);
|
|
|
|
*pdwPowerSource = WMDM_POWER_CAP_EXTERNAL |
|
|
WMDM_POWER_IS_EXTERNAL |
|
|
WMDM_POWER_PERCENT_AVAILABLE;
|
|
*pdwPercentRemaining = 100;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetPowerSource returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetStatus(DWORD * pdwStatus)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(pdwStatus);
|
|
|
|
CHRg(GetGlobalDeviceStatus(m_wcsName, pdwStatus));
|
|
|
|
if( !( *pdwStatus & WMDM_STATUS_BUSY) )
|
|
{
|
|
*pdwStatus = WMDM_STATUS_READY;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetStatus returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetDeviceIcon(ULONG *hIcon)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CFRg(g_hinstance);
|
|
CARg(hIcon);
|
|
CWRg( (*hIcon)=HandleToULong(LoadIconA(g_hinstance, MAKEINTRESOURCEA(IDI_ICON_PM)) ));
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetDeviceIcon returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// Opaque Command to get extended certification information
|
|
//
|
|
// GUID = {C39BF696-B776-459c-A13A-4B7116AB9F09}
|
|
//
|
|
static const GUID guidCertInfoEx =
|
|
{ 0xc39bf696, 0xb776, 0x459c, { 0xa1, 0x3a, 0x4b, 0x71, 0x16, 0xab, 0x9f, 0x9 } };
|
|
|
|
typedef struct
|
|
{
|
|
HRESULT hr;
|
|
DWORD cbCert;
|
|
BYTE pbCert[1];
|
|
|
|
} CERTINFOEX;
|
|
|
|
static const BYTE bCertInfoEx_App[] =
|
|
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
|
|
|
|
static const BYTE bCertInfoEx_SP[] =
|
|
{ 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
|
|
0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
|
|
|
|
STDMETHODIMP CMDSPDevice::SendOpaqueCommand(OPAQUECOMMAND *pCommand)
|
|
{
|
|
HRESULT hr;
|
|
HMAC hMAC;
|
|
BYTE abMACVerify[WMDM_MAC_LENGTH];
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
// Compute and verify MAC
|
|
//
|
|
CORg( g_pAppSCServer->MACInit(&hMAC) );
|
|
CORg( g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(&(pCommand->guidCommand)), sizeof(GUID)) );
|
|
CORg( g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(&(pCommand->dwDataLen)), sizeof(pCommand->dwDataLen)) );
|
|
if( pCommand->pData )
|
|
{
|
|
CORg( g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pCommand->pData), pCommand->dwDataLen) );
|
|
}
|
|
CORg( g_pAppSCServer->MACFinal(hMAC, abMACVerify) );
|
|
|
|
if (memcmp(abMACVerify, pCommand->abMAC, WMDM_MAC_LENGTH) != 0)
|
|
{
|
|
CORg(WMDM_E_MAC_CHECK_FAILED);
|
|
}
|
|
|
|
// Take action based on the command GUID
|
|
//
|
|
if( memcmp(&(pCommand->guidCommand), &guidCertInfoEx, sizeof(GUID)) == 0 )
|
|
{
|
|
//
|
|
// Command to exchange extended authentication information
|
|
//
|
|
|
|
CERTINFOEX *pCertInfoEx;
|
|
|
|
DWORD cbData_App = sizeof( bCertInfoEx_App )/sizeof( BYTE );
|
|
DWORD cbData_SP = sizeof( bCertInfoEx_SP )/sizeof( BYTE );
|
|
DWORD cbData_Return = sizeof(CERTINFOEX) + cbData_SP;
|
|
|
|
// The caller must include their extended cert info
|
|
//
|
|
if( !pCommand->pData )
|
|
{
|
|
CORg( E_INVALIDARG );
|
|
}
|
|
|
|
// Map the data in the opaque command to a CERTINFOEX structure
|
|
//
|
|
pCertInfoEx = (CERTINFOEX *)pCommand->pData;
|
|
|
|
// In this simple extended authentication scheme, the caller must
|
|
// provide the exact cert info
|
|
//
|
|
if( (pCertInfoEx->cbCert != cbData_App) ||
|
|
(memcmp(pCertInfoEx->pbCert, bCertInfoEx_App, cbData_App) != 0) )
|
|
{
|
|
CORg( WMDM_E_NOTCERTIFIED );
|
|
}
|
|
|
|
// Free the caller data and allocate enough data for our return data
|
|
//
|
|
CoTaskMemFree( pCommand->pData );
|
|
|
|
CFRg( (pCommand->pData = (BYTE *)CoTaskMemAlloc(cbData_Return)) );
|
|
pCommand->dwDataLen = cbData_Return;
|
|
|
|
// Copy the extended cert info into return data structure
|
|
//
|
|
pCertInfoEx = (CERTINFOEX *)pCommand->pData;
|
|
|
|
pCertInfoEx->hr = S_OK;
|
|
pCertInfoEx->cbCert = cbData_SP;
|
|
memcpy( pCertInfoEx->pbCert, bCertInfoEx_SP, cbData_SP );
|
|
|
|
// Compute MAC on return data
|
|
//
|
|
CORg( g_pAppSCServer->MACInit( &hMAC ) );
|
|
CORg( g_pAppSCServer->MACUpdate( hMAC, (BYTE*)(&(pCommand->guidCommand)), sizeof(GUID) ) );
|
|
CORg( g_pAppSCServer->MACUpdate( hMAC, (BYTE*)(&(pCommand->dwDataLen)), sizeof(pCommand->dwDataLen) ) );
|
|
if( pCommand->pData )
|
|
{
|
|
CORg( g_pAppSCServer->MACUpdate( hMAC, (BYTE*)(pCommand->pData), pCommand->dwDataLen ) );
|
|
}
|
|
CORg( g_pAppSCServer->MACFinal( hMAC, pCommand->abMAC ) );
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
CORg(WMDM_E_NOTSUPPORTED);
|
|
}
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::SendOpaqueCommand returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// IMDSPDevice2
|
|
STDMETHODIMP CMDSPDevice::GetStorage( LPCWSTR pszStorageName, IMDSPStorage** ppStorage )
|
|
{
|
|
HRESULT hr;
|
|
HRESULT hrTemp;
|
|
WCHAR pwszFileName[MAX_PATH+1];
|
|
char pszTemp[MAX_PATH];
|
|
CComObject<CMDSPStorage> *pStg = NULL;
|
|
|
|
// Get name of new file
|
|
|
|
DWORD dwLen = wcslen(m_wcsName);
|
|
|
|
// We reserve one char for the \ that might be added below
|
|
if (dwLen >= ARRAYSIZE(pwszFileName)-1)
|
|
{
|
|
hr = STRSAFE_E_INSUFFICIENT_BUFFER; //defined in strsafe.h
|
|
goto Error;
|
|
}
|
|
|
|
wcscpy( pwszFileName, m_wcsName );
|
|
if( pwszFileName[dwLen-1] != '\\' )
|
|
wcscat( pwszFileName, L"\\" );
|
|
|
|
hrTemp = StringCchCatW( pwszFileName,
|
|
ARRAYSIZE(pwszFileName) - 1,
|
|
// - 1 ensures the result fits into a MAX_PATH buffer.
|
|
// This makes the wcscpy into pStg->m_wcsName (below) safe.
|
|
pszStorageName );
|
|
|
|
if (FAILED(hrTemp))
|
|
{
|
|
// The file does not exist
|
|
hr = E_FAIL; // @@@@ Something else? S_FALSE?
|
|
goto Error;
|
|
}
|
|
|
|
WideCharToMultiByte(CP_ACP, NULL, pwszFileName, -1, pszTemp, MAX_PATH, NULL, NULL);
|
|
if( GetFileAttributesA( pszTemp ) == -1 )
|
|
{
|
|
// The file does not exist
|
|
hr = S_FALSE;
|
|
goto Error;
|
|
}
|
|
|
|
// Create new storage object
|
|
hr = CComObject<CMDSPStorage>::CreateInstance(&pStg);
|
|
hr = pStg->QueryInterface( IID_IMDSPStorage, reinterpret_cast<void**>(ppStorage));
|
|
wcscpy(pStg->m_wcsName, pwszFileName);
|
|
|
|
Error:
|
|
if( hr != S_OK )
|
|
{
|
|
*ppStorage = NULL;
|
|
}
|
|
|
|
hrLogDWORD("IMDSPDevice::GetStorage returned 0x%08lx", hr, hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetFormatSupport2(
|
|
DWORD dwFlags,
|
|
_WAVEFORMATEX** ppAudioFormatEx,
|
|
UINT* pnAudioFormatCount,
|
|
_VIDEOINFOHEADER** ppVideoFormatEx,
|
|
UINT* pnVideoFormatCount,
|
|
WMFILECAPABILITIES** ppFileType,
|
|
UINT* pnFileTypeCount )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetSpecifyPropertyPages(
|
|
ISpecifyPropertyPages** ppSpecifyPropPages,
|
|
IUnknown*** pppUnknowns,
|
|
ULONG *pcUnks )
|
|
{
|
|
HRESULT hr;
|
|
IUnknown** ppUnknownArray = NULL;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(ppSpecifyPropPages);
|
|
CARg(pppUnknowns);
|
|
CARg(pcUnks);
|
|
|
|
// This object also supports the ISpecifyPropertyPages interface
|
|
CORg( QueryInterface( __uuidof(ISpecifyPropertyPages),
|
|
reinterpret_cast<void**>(ppSpecifyPropPages) ) );
|
|
|
|
// Return one IUnknown interface, property page will QI for IDevice
|
|
ppUnknownArray = (IUnknown**)CoTaskMemAlloc( sizeof(IUnknown*[1]) );
|
|
CORg( QueryInterface( __uuidof(IUnknown),
|
|
reinterpret_cast<void**>(&ppUnknownArray[0]) ) );
|
|
|
|
*pppUnknowns = ppUnknownArray;
|
|
*pcUnks = 1;
|
|
|
|
Error:
|
|
hrLogDWORD("IMDSPDevice::GetSpecifyPropertyPages returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetPnPName( LPWSTR pwszPnPName, UINT nMaxChars )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
// ISpecifyPropertyPages
|
|
STDMETHODIMP CMDSPDevice::GetPages(CAUUID *pPages)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if( pPages == NULL )
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
|
|
// Return the GUID for our property page
|
|
pPages->cElems = 1;
|
|
pPages->pElems = (GUID *)CoTaskMemAlloc( sizeof(GUID) * pPages->cElems );
|
|
if( pPages->pElems == NULL )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
memcpy( &pPages->pElems[0], &__uuidof(HDSPPropPage), sizeof(GUID) );
|
|
}
|
|
|
|
return( hr );
|
|
}
|
|
|
|
|
|
// IMDSPDeviceControl
|
|
STDMETHODIMP CMDSPDevice::GetDCStatus(/*[out]*/ DWORD *pdwStatus)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = GetStatus(pdwStatus);
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::GetDCStatus returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetCapabilities(/*[out]*/ DWORD *pdwCapabilitiesMask)
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
if( !pdwCapabilitiesMask )
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
*pdwCapabilitiesMask = WMDM_DEVICECAP_CANSTREAMPLAY;
|
|
|
|
hr = S_OK;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::GetCapabilities returned 0x%08lx", hr, hr);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::Play()
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::Play returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::Record(/*[in]*/ _WAVEFORMATEX *pFormat)
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::Record returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::Pause()
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::Pause returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::Resume()
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::Resume returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::Stop()
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::Stop returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::Seek(/*[in]*/ UINT fuMode, /*[in]*/ int nOffset)
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
hr = WMDM_E_NOTSUPPORTED;
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDeviceControl::Seek returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::GetFormatSupport(
|
|
_WAVEFORMATEX **pFormatEx,
|
|
UINT *pnFormatCount,
|
|
LPWSTR **pppwszMimeType,
|
|
UINT *pnMimeTypeCount)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(pFormatEx);
|
|
CARg(pppwszMimeType);
|
|
CARg(pnFormatCount);
|
|
CARg(pnMimeTypeCount);
|
|
|
|
*pnFormatCount = 1;
|
|
*pFormatEx = (_WAVEFORMATEX *)CoTaskMemAlloc(sizeof(_WAVEFORMATEX));
|
|
CPRg( *pFormatEx );
|
|
(*pFormatEx)->wFormatTag = WMDM_WAVE_FORMAT_ALL;
|
|
(*pFormatEx)->nChannels = 2;
|
|
(*pFormatEx)->cbSize = 0;
|
|
(*pFormatEx)->nSamplesPerSec = 0;
|
|
(*pFormatEx)->nAvgBytesPerSec = 0;
|
|
(*pFormatEx)->nBlockAlign = 0;
|
|
(*pFormatEx)->wBitsPerSample = 0;
|
|
|
|
*pnMimeTypeCount= 1;
|
|
*pppwszMimeType = (LPWSTR *)CoTaskMemAlloc(sizeof(LPWSTR)*1);
|
|
CPRg(*pppwszMimeType);
|
|
**pppwszMimeType = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR)*(wcslen(WCS_MIME_TYPE_ALL)+1));
|
|
CPRg(**pppwszMimeType);
|
|
wcscpy(**pppwszMimeType, WCS_MIME_TYPE_ALL);
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::GetFormatSupport returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMDSPDevice::EnumStorage(IMDSPEnumStorage** ppEnumStorage)
|
|
{
|
|
HRESULT hr;
|
|
|
|
CFRg(g_pAppSCServer);
|
|
if ( !(g_pAppSCServer->fIsAuthenticated()) )
|
|
{
|
|
CORg(WMDM_E_NOTCERTIFIED);
|
|
}
|
|
|
|
CARg(ppEnumStorage);
|
|
|
|
CComObject<CMDSPEnumStorage> *pEnumObj;
|
|
|
|
CORg(CComObject<CMDSPEnumStorage>::CreateInstance(&pEnumObj));
|
|
|
|
hr = pEnumObj->QueryInterface(
|
|
IID_IMDSPEnumStorage,
|
|
reinterpret_cast<void**>(ppEnumStorage)
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
delete pEnumObj;
|
|
}
|
|
else
|
|
{
|
|
// wcscpy(pEnumObj->m_wcsPath, m_wcsName);
|
|
hr = StringCbCopyW(pEnumObj->m_wcsPath,
|
|
ARRAYSIZE(pEnumObj->m_wcsPath),
|
|
m_wcsName);
|
|
if (FAILED(hr))
|
|
{
|
|
(*ppEnumStorage)->Release();
|
|
*ppEnumStorage = NULL;
|
|
goto Error;
|
|
}
|
|
}
|
|
|
|
Error:
|
|
|
|
hrLogDWORD("IMDSPDevice::EnumStorage returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|