Leaked source code of windows server 2003
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.
 
 
 
 
 
 

859 lines
18 KiB

// Device.cpp : Implementation of CDevice
#include "stdafx.h"
#include "mswmdm.h"
#include "Device.h"
#include "Storage.h"
#include "WMDMStorageEnum.h"
#include "loghelp.h"
#include "scserver.h"
#include "scclient.h"
#include "spinfo.h"
#define DISABLE_DRM_LOG
#include <drmerr.h>
/////////////////////////////////////////////////////////////////////////////
// CWMDMDevice
extern CSecureChannelServer *g_pAppSCServer;
extern CSPInfo **g_pSPs;
CWMDMDevice::CWMDMDevice()
: m_pDevice(NULL)
{
GlobalAddRef();
}
CWMDMDevice::~CWMDMDevice()
{
if (m_pDevice)
m_pDevice->Release();
GlobalRelease();
}
//IWMDMDevice Methods
HRESULT CWMDMDevice::GetName(LPWSTR pwszName,
UINT nMaxChars)
{
HRESULT hr;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetName(pwszName, nMaxChars) );
Error:
hrLogDWORD("IWMDMDevice::GetName returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetManufacturer(LPWSTR pwszName,
UINT nMaxChars)
{
HRESULT hr;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetManufacturer(pwszName, nMaxChars) );
Error:
hrLogDWORD("IWMDMDevice::GetManufacturer returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetVersion(DWORD *pdwVersion)
{
HRESULT hr;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetVersion(pdwVersion) );
Error:
hrLogDWORD("IWMDMDevice::GetVersion returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetType(DWORD *pdwType)
{
HRESULT hr;
CARg (pdwType);
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetType(pdwType) );
#if 0
//////////////////////////////////////////
//RC1 Hack for non-reentrant devices
//////////////////////////////////////////
WCHAR wszManufacturer[MAX_PATH];
CORg(m_pDevice->GetManufacturer (wszManufacturer, MAX_PATH));
if (wcsstr(_wcsupr(wszManufacturer), L"S3/DIAMOND MULTIMEDIA"))
{
*pdwType |= WMDM_DEVICE_TYPE_NONREENTRANT | WMDM_DEVICE_TYPE_FILELISTRESYNC;
}
#endif
//////////////////////////////////////////
Error:
hrLogDWORD("IWMDMDevice::GetType returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetSerialNumber(PWMDMID pSerialNumber, BYTE abMac[WMDM_MAC_LENGTH])
{
HRESULT hr;
HMAC hMAC;
CSecureChannelClient *pSCClient;
BYTE abTempMAC[WMDM_MAC_LENGTH];
BYTE abMACVerify[WMDM_MAC_LENGTH];
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
g_pSPs[m_wSPIndex]->GetSCClient(&pSCClient);
if (!pSCClient)
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetSerialNumber(pSerialNumber, abTempMAC) );
// Verify the MAC from SP
CORg( pSCClient->MACInit(&hMAC) );
CORg( pSCClient->MACUpdate(hMAC, (BYTE*)(pSerialNumber), sizeof(WMDMID)) );
CORg( pSCClient->MACFinal(hMAC, abMACVerify) );
if (memcmp(abMACVerify, abTempMAC, WMDM_MAC_LENGTH) != 0)
{
CORg( WMDM_E_MAC_CHECK_FAILED );
}
// Compute the MAC to send back to the application
CORg( g_pAppSCServer->MACInit(&hMAC) );
CORg( g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pSerialNumber), sizeof(WMDMID)) );
CORg( g_pAppSCServer->MACFinal(hMAC, abMac) );
Error:
hrLogDWORD("IWMDMDevice::GetSerialNumber returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetPowerSource(DWORD *pdwPowerSource,
DWORD *pdwPercentRemaining)
{
HRESULT hr;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetPowerSource(pdwPowerSource, pdwPercentRemaining) );
Error:
hrLogDWORD("IWMDMDevice::GetPowerSource returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetStatus(DWORD *pdwStatus)
{
HRESULT hr;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetStatus(pdwStatus) );
Error:
hrLogDWORD("IWMDMDevice::GetStatus returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::EnumStorage(IWMDMEnumStorage **ppEnumStorage)
{
HRESULT hr;
CComObject<CWMDMStorageEnum> *pEnumObj = NULL;
IMDSPEnumStorage *pEnumStg = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CARg( ppEnumStorage );
CORg( m_pDevice->EnumStorage(&pEnumStg) );
CORg( CComObject<CWMDMStorageEnum>::CreateInstance(&pEnumObj) );
CORg( pEnumObj->QueryInterface(IID_IWMDMEnumStorage, reinterpret_cast<void**>(ppEnumStorage)) );
if (FAILED(hr))
{
delete pEnumObj;
pEnumObj = NULL;
goto Error;
}
pEnumObj->SetContainedPointer(pEnumStg, m_wSPIndex);
Error:
if(pEnumStg)
pEnumStg->Release();
hrLogDWORD("IWMDMDevice::EnumStorage returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetFormatSupport(_WAVEFORMATEX **ppFormatEx,
UINT *pnFormatCount,
LPWSTR **pppwszMimeType,
UINT *pnMimeTypeCount)
{
HRESULT hr;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetFormatSupport(ppFormatEx, pnFormatCount, pppwszMimeType, pnMimeTypeCount) );
Error:
hrLogDWORD("IWMDMDevice::GetFormatSupport returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetDeviceIcon(ULONG *hIcon)
{
HRESULT hr;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->GetDeviceIcon(hIcon) );
Error:
hrLogDWORD("IWMDMDevice::GetDeviceIcon returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::SendOpaqueCommand(OPAQUECOMMAND *pCommand)
{
HRESULT hr;
HMAC hMAC;
CSecureChannelClient *pSCClient;
BYTE abMACVerify[WMDM_MAC_LENGTH];
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
if( (pCommand == NULL) ||
((pCommand->pData == NULL) && (pCommand->dwDataLen > 0)) )
{
CORg( E_INVALIDARG );
}
// Verify the MAC from APP
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 );
}
g_pSPs[m_wSPIndex]->GetSCClient(&pSCClient);
if (!pSCClient)
{
CORg( E_FAIL );
}
// Compute the MAC to send back to the SP
CORg( pSCClient->MACInit(&hMAC) );
CORg( pSCClient->MACUpdate(hMAC, (BYTE*)(&(pCommand->guidCommand)), sizeof(GUID)) );
CORg( pSCClient->MACUpdate(hMAC, (BYTE*)(&(pCommand->dwDataLen)), sizeof(pCommand->dwDataLen)) );
if (pCommand->pData)
{
CORg( pSCClient->MACUpdate(hMAC, (BYTE*)(pCommand->pData), pCommand->dwDataLen) );
}
CORg( pSCClient->MACFinal(hMAC, pCommand->abMAC) );
// Pass the call down to the SP
CORg( m_pDevice->SendOpaqueCommand(pCommand) );
// Verify the MAC from SP
CORg( pSCClient->MACInit(&hMAC) );
CORg( pSCClient->MACUpdate(hMAC, (BYTE*)(&(pCommand->guidCommand)), sizeof(GUID)) );
CORg( pSCClient->MACUpdate(hMAC, (BYTE*)(&(pCommand->dwDataLen)), sizeof(pCommand->dwDataLen)) );
if (pCommand->pData)
{
CORg( pSCClient->MACUpdate(hMAC, (BYTE*)(pCommand->pData), pCommand->dwDataLen) );
}
CORg( pSCClient->MACFinal(hMAC, abMACVerify) );
if (memcmp(abMACVerify, pCommand->abMAC, WMDM_MAC_LENGTH) != 0)
{
CORg( WMDM_E_MAC_CHECK_FAILED );
}
// Compute the MAC to send back to the application
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) );
Error:
hrLogDWORD("IWMDMDevice::SendOpaqueCommand returned 0x%08lx", hr, hr);
return hr;
}
// IWMDMDevice2
HRESULT CWMDMDevice::GetStorage( LPCWSTR pszStorageName, IWMDMStorage** ppStorage )
{
HRESULT hr;
IMDSPDevice2* pDev2 = NULL;
IMDSPStorage* pMDSPStorageFound = NULL;
IMDSPStorage* pMDSubStorage = NULL;
CComObject<CWMDMStorage>* pStgObj = NULL;
CARg( ppStorage );
CARg( pszStorageName );
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
// Get the Storage pointer from the SP (as a IMDSPStorage)
hr = m_pDevice->QueryInterface(IID_IMDSPDevice2, reinterpret_cast<void**>(&pDev2));
if( SUCCEEDED(hr) )
{
hr = pDev2->GetStorage( pszStorageName, &pMDSPStorageFound );
}
// This functionalty is not implemented by the SP. Find the storage by enumerating all storages
if( hr == E_NOTIMPL || hr == E_NOINTERFACE )
{
IMDSPEnumStorage *pEnum = NULL;
WCHAR pswzMDSubStorageName[MAX_PATH];
ULONG ulFetched;
CORg(m_pDevice->EnumStorage(&pEnum));
while( S_OK == pEnum->Next(1, &pMDSubStorage, &ulFetched) )
{
hr = pMDSubStorage->GetName( pswzMDSubStorageName, MAX_PATH );
if( SUCCEEDED(hr) && ( _wcsicmp( pswzMDSubStorageName, pszStorageName ) == 0 ) )
{
// We have found the storage we are looking for.
pMDSPStorageFound = pMDSubStorage;
break;
}
pMDSubStorage->Release();
}
pEnum->Release();
}
// Create a IWMDMStorage object and connect it to the the storage from the SP
if( pMDSPStorageFound != NULL )
{
CORg( CComObject<CWMDMStorage>::CreateInstance(&pStgObj) );
CORg( pStgObj->QueryInterface(IID_IWMDMStorage, reinterpret_cast<void**>(ppStorage)) );
pStgObj->SetContainedPointer(pMDSPStorageFound, m_wSPIndex);
}
// Did not find a matching storage
else if( SUCCEEDED(hr) )
{
hr = S_FALSE;
}
Error:
if( pDev2 )
pDev2->Release();
if( hr != S_OK )
{
ppStorage = NULL;
delete pStgObj;
}
hrLogDWORD("IWMDMDevice2::GetStorage returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetFormatSupport2(
DWORD dwFlags,
_WAVEFORMATEX **ppAudioFormatEx,
UINT *pnAudioFormatCount,
_VIDEOINFOHEADER **ppVideoFormatEx,
UINT *pnVideoFormatCount,
WMFILECAPABILITIES **ppFileType,
UINT *pnFileTypeCount)
{
HRESULT hr = S_OK;
IMDSPDevice2* pDev2 = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDevice2, reinterpret_cast<void**>(&pDev2)) );
CORg( pDev2->GetFormatSupport2( dwFlags,
ppAudioFormatEx,
pnAudioFormatCount,
ppVideoFormatEx,
pnVideoFormatCount,
ppFileType,
pnFileTypeCount) );
Error:
if( pDev2 )
pDev2->Release();
hrLogDWORD("IWMDMDevice2::GetFormatSupport2 returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetSpecifyPropertyPages(
ISpecifyPropertyPages** ppSpecifyPropPages,
IUnknown*** pppUnknowns,
ULONG* pcUnks )
{
HRESULT hr = S_OK;
IMDSPDevice2* pDev2 = NULL;
CARg( ppSpecifyPropPages );
CARg( pppUnknowns );
CARg( pcUnks );
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDevice2, reinterpret_cast<void**>(&pDev2)) );
CORg( pDev2->GetSpecifyPropertyPages( ppSpecifyPropPages, pppUnknowns, pcUnks ) );
Error:
if( pDev2 )
pDev2->Release();
hrLogDWORD("IWMDMDevice2::GetSpecifyPropertyPages returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::GetPnPName( LPWSTR pwszPnPName, UINT nMaxChars )
{
HRESULT hr = S_OK;
IMDSPDevice2* pDev2 = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDevice2, reinterpret_cast<void**>(&pDev2)) );
CORg( pDev2->GetPnPName( pwszPnPName, nMaxChars ) );
Error:
if( pDev2 )
{
pDev2->Release();
}
hrLogDWORD("IWMDMDevice2::GetPnPName returned 0x%08lx", hr, hr);
return hr;
}
// IWMDMDeviceControl
HRESULT CWMDMDevice::GetCapabilities(DWORD *pdwCapabilitiesMask)
{
HRESULT hr;
IMDSPDeviceControl *pDevCtrl = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
if (!pdwCapabilitiesMask)
{
CORg( E_INVALIDARG );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDeviceControl, reinterpret_cast<void**>(&pDevCtrl)) );
CORg( pDevCtrl->GetCapabilities(pdwCapabilitiesMask) );
Error:
if (pDevCtrl)
pDevCtrl->Release();
hrLogDWORD("IWMDMDeviceControl::GetCapabilities returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::Play()
{
HRESULT hr;
IMDSPDeviceControl *pDevCtrl = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDeviceControl, reinterpret_cast<void**>(&pDevCtrl)) );
CORg( pDevCtrl->Play() );
Error:
if (pDevCtrl)
pDevCtrl->Release();
hrLogDWORD("IWMDMDeviceControl::Play returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::Record(_WAVEFORMATEX *pFormat)
{
HRESULT hr;
IMDSPDeviceControl *pDevCtrl = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
if (!pFormat)
{
CORg( E_INVALIDARG );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDeviceControl, reinterpret_cast<void**>(&pDevCtrl)) );
CORg( pDevCtrl->Record(pFormat) );
Error:
if (pDevCtrl)
pDevCtrl->Release();
hrLogDWORD("IWMDMDeviceControl::Record returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::Pause()
{
HRESULT hr;
IMDSPDeviceControl *pDevCtrl = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDeviceControl, reinterpret_cast<void**>(&pDevCtrl)) );
CORg( pDevCtrl->Pause() );
Error:
if (pDevCtrl)
pDevCtrl->Release();
hrLogDWORD("IWMDMDeviceControl::Pause returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::Resume()
{
HRESULT hr;
IMDSPDeviceControl *pDevCtrl = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDeviceControl, reinterpret_cast<void**>(&pDevCtrl)) );
CORg( pDevCtrl->Resume() );
Error:
if (pDevCtrl)
pDevCtrl->Release();
hrLogDWORD("IWMDMDeviceControl::Resume returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::Stop()
{
HRESULT hr;
IMDSPDeviceControl *pDevCtrl = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDeviceControl, reinterpret_cast<void**>(&pDevCtrl)) );
CORg( pDevCtrl->Stop() );
Error:
if (pDevCtrl)
pDevCtrl->Release();
hrLogDWORD("IWMDMDeviceControl::Stop returned 0x%08lx", hr, hr);
return hr;
}
HRESULT CWMDMDevice::Seek(UINT fuMode, int nOffset)
{
HRESULT hr;
IMDSPDeviceControl *pDevCtrl = NULL;
if (g_pAppSCServer)
{
if(!g_pAppSCServer->fIsAuthenticated())
{
CORg( WMDM_E_NOTCERTIFIED );
}
}
else
{
CORg( E_FAIL );
}
CORg( m_pDevice->QueryInterface(IID_IMDSPDeviceControl, reinterpret_cast<void**>(&pDevCtrl)) );
CORg( pDevCtrl->Seek(fuMode, nOffset) );
Error:
if (pDevCtrl)
pDevCtrl->Release();
hrLogDWORD("IWMDMDeviceControl::Seek returned 0x%08lx", hr, hr);
return hr;
}
void CWMDMDevice::SetContainedPointer(IMDSPDevice *pDevice, WORD wSPIndex)
{
m_pDevice = pDevice;
m_pDevice->AddRef();
m_wSPIndex = wSPIndex;
return;
}