|
|
/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
ptutil.cpp
Abstract:
Implementation of Plug terminal registration classes. --*/
#include "stdafx.h"
#include "PTUtil.h"
#include "manager.h"
///////////////////////////////////////////
// CPTUtil implementation
//
HRESULT CPTUtil::RecursiveDeleteKey( IN HKEY hKey, IN BSTR bstrKeyChild ) { LOG((MSP_TRACE, "CPTUtil::RecursiveDeleteKey - enter"));
//
// Validates the arguments
//
if( NULL == hKey ) { LOG((MSP_TRACE, "CPTUtil::RecursiveDeleteKey exit -" "hKey was NULL")); return S_OK; }
if( IsBadStringPtr( bstrKeyChild, (UINT)-1)) { LOG((MSP_ERROR, "CPTUtil::RecursiveDeleteKey exit - " "bstrKeyChild invalid, returns E_INVALIDARG")); return E_INVALIDARG; }
//
// Open the child key
//
HKEY hKeyChild; LONG lResult = RegOpenKeyEx( hKey, bstrKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild);
if( ERROR_SUCCESS != lResult ) { LOG((MSP_ERROR, "CPTUtil::RecursiveDeleteKey exit - " "RegOpenKeyEx failed, returns E_UNEXPECTED")); return E_UNEXPECTED; }
//
// Enumerate the descendents
//
FILETIME time; TCHAR szBuffer[PTKEY_MAXSIZE]; DWORD dwSize = PTKEY_MAXSIZE;
while( RegEnumKeyEx( hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == ERROR_SUCCESS) { //
// Put the child name into a BSTR
//
BSTR bstrChild = SysAllocString(szBuffer); if( IsBadStringPtr( bstrChild, (UINT)(-1)) ) { RegCloseKey(hKeyChild);
LOG((MSP_ERROR, "CPTUtil::RecursiveDeleteKey exit - " "SysAllocString failed, return E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Delete the child
//
HRESULT hr; hr = RecursiveDeleteKey(hKeyChild, bstrChild);
//
// Clean-up bstrChild
//
SysFreeString(bstrChild);
if( FAILED(hr) ) { RegFlushKey(hKeyChild); RegCloseKey(hKeyChild);
LOG((MSP_ERROR, "CPTUtil::RecursiveDeleteKey exit - " "RecursiveDeleteKey failed, returns 0%08x", hr)); return hr; }
//
// Reset the buffer size
//
dwSize = PTKEY_MAXSIZE; }
//
// Close the child
//
RegFlushKey(hKeyChild); RegCloseKey(hKeyChild);
HRESULT hr; hr = RegDeleteKey( hKey, bstrKeyChild); RegFlushKey( hKey ); LOG((MSP_TRACE, "CPTUtil::RecursiveDeleteKey - exit 0x%08x", hr)); return hr; }
HRESULT CPTUtil::ListTerminalSuperclasses( OUT CLSID** ppSuperclasses, OUT DWORD* pdwCount ) { LOG((MSP_TRACE, "CPTUtil::ListTerminalSuperclasses - enter"));
//
// Validates argument
//
if( TM_IsBadWritePtr( ppSuperclasses, sizeof(CLSID*)) ) { LOG((MSP_ERROR, "CPTUtil::ListTerminalSuperclasses exit -" "pClasses invalid, returns E_POINTER")); return E_POINTER; }
if( TM_IsBadWritePtr( pdwCount, sizeof(DWORD)) ) { LOG((MSP_ERROR, "CPTUtil::ListTerminalSuperclasses exit -" "pClasses invalid, returns E_POINTER")); return E_POINTER; }
//
// Initialize the output arguments
//
*ppSuperclasses = NULL; *pdwCount = 0;
//
// Get the key path for terminal class
//
WCHAR szKey[ 256 ]; wsprintf( szKey, L"%s", PTKEY_TERMINALS ); LOG((MSP_TRACE, "CPTUtil::ListTerminalSuperclasses - " "TerminalsKey is %s", szKey));
//
// Open the terminal class key
//
HKEY hKey; LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
//
// Validates registry operation
//
if( ERROR_SUCCESS != lResult ) { LOG((MSP_ERROR, "CPTUtil::ListTerminalSuperclasses exit - " "RegOpenKeyEx failed, returns E_UNEXPECTED")); return E_UNEXPECTED; }
//
// Create the buffer for the CLSIDs
//
DWORD dwArraySize = 8; CLSID* pCLSIDs = new CLSID[ dwArraySize ]; if( pCLSIDs == NULL ) { // Clean-up hKey
RegCloseKey( hKey );
LOG((MSP_ERROR, "CPTUtil::ListTerminalSuperclasses exit - " "new operator failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Enumerate the descendents
//
HRESULT hr = S_OK; // The error code
FILETIME time; // We need this in RegEnumKeyEx
TCHAR szBuffer[PTKEY_MAXSIZE]; // Buffer
DWORD dwSize = PTKEY_MAXSIZE; // Buffer size
DWORD dwChildKey = 0; // Child key index from the registry
DWORD dwCLSIDIndex = 0; // CLSID index into the array
while( RegEnumKeyEx( hKey, dwChildKey, szBuffer, &dwSize, NULL, NULL, NULL, &time) == ERROR_SUCCESS) { LOG((MSP_TRACE, "CPTUtil::ListTerminalSuperclasses - " "we read the buffer: %s", szBuffer));
// Prepare for the next child key
dwChildKey++; dwSize = PTKEY_MAXSIZE;
// Try to get the CLSID from this key
CLSID clsid = CLSID_NULL; HRESULT hr = CLSIDFromString( szBuffer, &clsid); if( FAILED(hr) ) { // Go to the next child key
continue; }
// Have we enougth space for this element?
if( dwArraySize <= dwCLSIDIndex ) { LOG((MSP_TRACE, "CPTUtil::ListTerminalSuperclasses - " "we have to increase the buffer size"));
// We have to increase the space, double the size
dwArraySize *= 2;
CLSID* pNewCLSIDs = new CLSID[ dwArraySize ]; if( pNewCLSIDs == NULL ) { hr = E_OUTOFMEMORY; break; }
// Copies into the new buffer the old buffer
memcpy( pNewCLSIDs, pCLSIDs, sizeof(CLSID)*dwArraySize/2);
// Delete the old array
delete[] pCLSIDs;
// Set the new array to the old pointer
pCLSIDs = pNewCLSIDs; }
// We set the item into the CLSID array
pCLSIDs[ dwCLSIDIndex] = clsid; dwCLSIDIndex++;
}
//
// Clean-up hKey
//
RegCloseKey( hKey );
if( FAILED(hr) ) { // Clean-up
delete[] pCLSIDs;
LOG((MSP_ERROR, "CPTUtil::ListTerminalSuperclasses exit - " "failed, returns 0x%08x", hr)); return hr; }
//
// Set the returning values
//
*ppSuperclasses = pCLSIDs; *pdwCount = dwCLSIDIndex;
LOG((MSP_TRACE, "CPTUtil::ListTerminalSuperclasses - exit")); return S_OK; }
HRESULT CPTUtil::SearchForTerminal( IN IID iidTerminal, IN DWORD dwMediaType, IN TERMINAL_DIRECTION Direction, OUT CPTTerminal* pTerminal ) { LOG((MSP_TRACE, "CPTUtil::SearchForTerminal - enter"));
//
// Get the plug-in terminal superclasses
//
CLSID* pSuperclasses = NULL; DWORD dwSuperclasses = 0; HRESULT hr = E_FAIL;
hr = ListTerminalSuperclasses( &pSuperclasses, &dwSuperclasses );
if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTUtil::SearchForTerminal - exit " "ListTerminalSuperclasses failed, returns 0x%08x", hr)); return hr; }
//
// Enumerate the plug-in terminal superclasses
//
for( DWORD dwSuperclass = 0; dwSuperclass < dwSuperclasses; dwSuperclass++) {
//
// If we want a exact terminal (Exact) or just first matching
// terminal from this superclass
//
BOOL bPTExact = (pSuperclasses[dwSuperclass] != iidTerminal);
//
// Get the terminal
//
hr = FindTerminal( pSuperclasses[dwSuperclass], bPTExact ? iidTerminal : CLSID_NULL, dwMediaType, Direction, bPTExact, pTerminal);
if( FAILED(hr)) { if( !bPTExact) { //
// We had to find a terminal in this terminal class
// sorry!!!
break; } } else { //
// cool! we found it
//
break; } }
//
// Clean-up superclasses array, bstrTermialGUID
//
delete[] pSuperclasses;
//
// Return
//
LOG((MSP_TRACE, "CPTUtil::SearchForTerminal - exit 0x%08x", hr)); return hr; }
HRESULT CPTUtil::FindTerminal( IN CLSID clsidSuperclass, IN CLSID clsidTerminal, IN DWORD dwMediaType, IN TERMINAL_DIRECTION Direction, IN BOOL bExact, OUT CPTTerminal* pTerminal) { LOG((MSP_TRACE, "CPTUtil::FindTerminal - exit"));
//
// Terminal class object
//
CPTSuperclass Superclass; Superclass.m_clsidSuperclass = clsidSuperclass;
//
// The terminals array
//
CLSID* pTerminals = NULL; DWORD dwTerminals = 0; HRESULT hr = E_FAIL;
//
// Lists the terminals for a specific terminal class
//
hr = Superclass.ListTerminalClasses( dwMediaType, &pTerminals, &dwTerminals );
if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTUtil::FindTerminal - exit " "ListTerminalSuperclasses failed, returns 0x%08x", hr)); return hr; }
//
// Enumerate terminals
//
hr = E_FAIL;
for( DWORD dwTerminal = 0; dwTerminal < dwTerminals; dwTerminal++) {
//
// CPTTerminal object from registry
//
CPTTerminal Terminal; Terminal.m_clsidTerminalClass = pTerminals[dwTerminal]; hr = Terminal.Get( clsidSuperclass );
if( FAILED(hr) ) { continue; }
//
// try to log the name of the terminal that we are looking at
//
if (NULL != Terminal.m_bstrName) { //
// log the name
//
LOG((MSP_TRACE, "CPTUtil::FindTerminal - checking terminal %S", Terminal.m_bstrName)); } else {
//
// no name?? strange, but not much we can do...
//
LOG((MSP_TRACE, "CPTUtil::FindTerminal - terminal name is unavaliable")); }
//
// Is matching
//
if( (dwMediaType & Terminal.m_dwMediaTypes) == 0 ) { LOG((MSP_TRACE, "CPTUtil::FindTerminal - MediaType unmatched")); hr = E_FAIL; continue; }
//
// map TERMINAL_DIRECTION values to OR'able TMGR_DIRECTION values
//
DWORD dwRegistryDirection = 0;
if (Direction == TD_RENDER) { dwRegistryDirection = TMGR_TD_RENDER; } else if (Direction == TD_CAPTURE) {
dwRegistryDirection = TMGR_TD_CAPTURE; } else { //
// should not happen, really
//
LOG((MSP_ERROR, "CPTUtil::FindTerminal - bad direction value %lx", Direction));
hr = E_FAIL;
//
// this is strange, so debug to see how we got here
//
TM_ASSERT(FALSE);
break; }
//
// requested direction -- is it one of the directions supported by this terminal?
//
if ((dwRegistryDirection & Terminal.m_dwDirections) == 0) { LOG((MSP_TRACE, "CPTUtil::FindTerminal - Direction unmatched"));
hr = E_FAIL; continue; }
if( bExact ) { if( Terminal.m_clsidTerminalClass != clsidTerminal ) { LOG((MSP_TRACE, "CPTUtil::FindTerminal - PublicCLSID unmatched")); hr = E_FAIL; continue; } }
if( SUCCEEDED(hr) ) { LOG((MSP_TRACE, "CPTUtil::FindTerminal - find a matching")); *pTerminal = Terminal; break; } }
//
// Clean-up the safearray
//
delete[] pTerminals;
//
// Return
//
LOG((MSP_TRACE, "CPTUtil::FindTerminal - exit 0x%08x", hr)); return hr; }
HRESULT CPTUtil::ListTerminalClasses( IN DWORD dwMediaTypes, OUT CLSID** ppTerminalsClasses, OUT DWORD* pdwCount ) { LOG((MSP_TRACE, "CPTUtil::ListTerminalClasses - enter"));
//
// reset the output arguments
//
*ppTerminalsClasses = NULL; *pdwCount = 0;
//
// Get all terminal classes
//
HRESULT hr = E_FAIL; CLSID* pSuperclasses = NULL; DWORD dwSuperclasses = 0;
hr = ListTerminalSuperclasses( &pSuperclasses, &dwSuperclasses );
if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTUtil::ListTerminalClasses - exit " "ListTerminalSuperclasses failed, returns 0x%08x", hr)); return hr; }
DWORD dwArraySize = 8; CLSID* pTerminals = new CLSID[ dwArraySize]; DWORD dwIndex = 0;
if( pTerminals == NULL ) { // Cleanup
delete[] pSuperclasses;
LOG((MSP_ERROR, "CPTUtil::ListTerminalClasses - exit " "new operator failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Enumerate all superclasses
//
for( DWORD dwSuperclass = 0; dwSuperclass < dwSuperclasses; dwSuperclass++) { //
// List the terminals for this class
//
CPTSuperclass Superclass; Superclass.m_clsidSuperclass = pSuperclasses[dwSuperclass];
CLSID* pLocalTerminals = NULL; DWORD dwLocalTerminals = 0;
hr = Superclass.ListTerminalClasses( 0, &pLocalTerminals, &dwLocalTerminals );
if( FAILED(hr) ) { hr = S_OK;
LOG((MSP_TRACE, "CPTUtil::ListTerminalClasses - " "ListTerminalSuperclasses failed")); continue; }
//
// Increase the array room if it's necessary
//
if( dwArraySize <= dwIndex + dwLocalTerminals) { CLSID* pOldTerminals = pTerminals;
// Create the new buffer
dwArraySize *= 2; pTerminals = new CLSID[dwArraySize];
if( pTerminals == NULL ) { // Clean-up
delete[] pLocalTerminals;
//
// Recover the old list of terminals
//
pTerminals = pOldTerminals;
LOG((MSP_TRACE, "CPTUtil::ListTerminalClasses - " "new operator failed")); break; }
// Copies the old one into the new one
memcpy( pTerminals, pOldTerminals, sizeof(CLSID) * dwArraySize/2);
// Delete old terminals
delete[] pOldTerminals; }
//
// Add the terminals into terminals array
//
for( DWORD dwTerminal = 0; dwTerminal < dwLocalTerminals; dwTerminal++) { //
// MediaTypes is right?
//
CPTTerminal Terminal; Terminal.m_clsidTerminalClass = pLocalTerminals[dwTerminal]; hr = Terminal.Get( pSuperclasses[dwSuperclass] );
if( FAILED(hr) ) { hr = S_OK;
LOG((MSP_TRACE, "CPTUtil::ListTerminalClasses - " "GetTerminal failed")); continue; }
if( 0 == (dwMediaTypes & Terminal.m_dwMediaTypes) ) { LOG((MSP_TRACE, "CPTUtil::ListTerminalSuperclasses - " "wrong mediatype")); continue; }
//
// Add public clasid to the base safearray
//
pTerminals[dwIndex] = pLocalTerminals[dwTerminal]; dwIndex++;
}
// Clean-up
delete[] pLocalTerminals;
}
// Clean-up
delete[] pSuperclasses;
//
// Return values
//
if( SUCCEEDED(hr) ) { *ppTerminalsClasses = pTerminals; *pdwCount = dwIndex; }
LOG((MSP_TRACE, "CPTUtil::ListTerminalSuperclasses - exit 0x%08x", hr)); return hr; }
///////////////////////////////////////////
// CPTTerminal Implementation
//
// Constructor/destructor
CPTTerminal::CPTTerminal() { LOG((MSP_TRACE, "CPTTerminal::CPTTerminal - enter"));
m_bstrName = NULL; m_bstrCompany = NULL; m_bstrVersion = NULL;
m_clsidTerminalClass = CLSID_NULL; m_clsidCOM = CLSID_NULL;
//
// initialize with invalid direction and media type -- there is no other
// good default
//
m_dwDirections = 0; m_dwMediaTypes = 0;
LOG((MSP_TRACE, "CPTTerminal::CPTTerminal - exit")); }
CPTTerminal::~CPTTerminal() { LOG((MSP_TRACE, "CPTTerminal::~CPTTerminal - enter"));
if(m_bstrName) SysFreeString( m_bstrName );
if( m_bstrCompany) SysFreeString( m_bstrCompany );
if( m_bstrVersion) SysFreeString( m_bstrVersion );
LOG((MSP_TRACE, "CPTTerminal::~CPTTerminal - exit")); }
// CPTTerminal methods
HRESULT CPTTerminal::Add( IN CLSID clsidSuperclass ) { LOG((MSP_TRACE, "CPTTerminal::Add - enter"));
//
// we should have a valid media type
//
if ( !IsValidAggregatedMediaType(m_dwMediaTypes) ) { LOG((MSP_ERROR, "CPTTerminal::Add exit -" "media type is not valid %lx. return TAPI_E_INVALIDMEDIATYPE", m_dwMediaTypes));
return TAPI_E_INVALIDMEDIATYPE; }
//
// we should have a valid direction
//
if ( ( TMGR_TD_CAPTURE != m_dwDirections ) && ( TMGR_TD_RENDER != m_dwDirections ) && ( TMGR_TD_BOTH != m_dwDirections ) ) { LOG((MSP_ERROR, "CPTTerminal::Add exit - " "direction is not valid %lx. return TAPI_E_INVALIDDIRECTION", TAPI_E_INVALIDDIRECTION));
return TAPI_E_INVALIDDIRECTION; }
//
// We determine the terminal path into registry
//
LPOLESTR lpszSuperclass = NULL; LPOLESTR lpszTerminalClass = NULL; HRESULT hr = E_FAIL;
hr = StringFromCLSID( clsidSuperclass, &lpszSuperclass ); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTTerminal::Add exit -" "StringFromCLSID for Superclass failed, returns 0x%08x", hr)); return hr; }
hr = StringFromCLSID( m_clsidTerminalClass, &lpszTerminalClass ); if( FAILED(hr) ) { CoTaskMemFree( lpszSuperclass );
LOG((MSP_ERROR, "CPTTerminal::Add exit -" "StringFromCLSID for Superclass failed, returns 0x%08x", hr)); return hr; }
WCHAR szKey[PTKEY_MAXSIZE]; WCHAR szKeySuperclass[PTKEY_MAXSIZE]; wsprintf( szKey, TEXT("%s\\%s\\%s"), PTKEY_TERMINALS, lpszSuperclass, lpszTerminalClass );
wsprintf( szKeySuperclass, TEXT("%s\\%s"), PTKEY_TERMINALS, lpszSuperclass);
// Clean-up, we need later the TerminalClass
CoTaskMemFree( lpszSuperclass ); CoTaskMemFree( lpszTerminalClass );
//
// Try to see if the superclass key exist
//
HKEY hKeySuperclass = NULL; long lResult;
lResult = RegOpenKey( HKEY_LOCAL_MACHINE, szKeySuperclass, &hKeySuperclass);
if( ERROR_SUCCESS != lResult ) { // We don't have the superclass
LOG((MSP_ERROR, "CPTTerminal::Add exit -" "RegOpenKey for superclass failed, returns E_FAIL")); return E_FAIL; }
RegCloseKey( hKeySuperclass );
//
// Open or create key
//
HKEY hKey = NULL;
lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
//
// Validates registry operation
//
if( ERROR_SUCCESS != lResult ) { LOG((MSP_ERROR, "CPTTerminal::Add exit -" "RegCreateKeyEx failed, returns E_UNEXPECTED")); return E_UNEXPECTED; }
//
// Edit terminal name
//
if( !IsBadStringPtr(m_bstrName, (UINT)-1) ) { lResult = RegSetValueEx( hKey, PTKEY_NAME, 0, REG_SZ, (BYTE *)m_bstrName, (SysStringLen( m_bstrName) + 1) * sizeof(WCHAR) ); }
//
// Edit company name
//
if( !IsBadStringPtr(m_bstrCompany, (UINT)-1) ) { lResult = RegSetValueEx( hKey, PTKEY_COMPANY, 0, REG_SZ, (BYTE *)m_bstrCompany, (SysStringLen( m_bstrCompany) + 1) * sizeof(WCHAR) ); }
//
// Edit terminal version
//
if( !IsBadStringPtr(m_bstrVersion, (UINT)-1) ) { lResult = RegSetValueEx( hKey, PTKEY_VERSION, 0, REG_SZ, (BYTE *)m_bstrVersion, (SysStringLen( m_bstrVersion) + 1) * sizeof(WCHAR) ); }
//
// Edit terminal CLSID create
//
if( m_clsidCOM != CLSID_NULL ) { LPOLESTR lpszCOM = NULL; hr = StringFromCLSID( m_clsidCOM, &lpszCOM ); if( SUCCEEDED(hr) ) { lResult = RegSetValueEx( hKey, PTKEY_CLSIDCREATE, 0, REG_SZ, (BYTE *)lpszCOM, (wcslen( lpszCOM) + 1) * sizeof(WCHAR) );
// Clean-up
CoTaskMemFree( lpszCOM ); } }
//
// Edit terminal directions
//
lResult = RegSetValueEx( hKey, PTKEY_DIRECTIONS, 0, REG_DWORD, (BYTE *)&m_dwDirections, sizeof( m_dwDirections ) );
//
// Edit terminal mediatypes
//
lResult = RegSetValueEx( hKey, PTKEY_MEDIATYPES, 0, REG_DWORD, (BYTE *)&m_dwMediaTypes, sizeof( m_dwMediaTypes ) );
//
// Clean-up hKey
//
RegFlushKey( hKey ); RegCloseKey( hKey );
LOG((MSP_TRACE, "CPTTerminal::Add - exit")); return S_OK; }
HRESULT CPTTerminal::Delete( IN CLSID clsidSuperclass ) { LOG((MSP_TRACE, "CPTTerminal::Delete - enter"));
//
// We determine the terminal path into registry
//
LPOLESTR lpszSuperclass = NULL; LPOLESTR lpszTerminalClass = NULL; HRESULT hr = E_FAIL;
hr = StringFromCLSID( clsidSuperclass, &lpszSuperclass ); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTTerminal::Delete exit -" "StringFromCLSID for Superclass failed, returns 0x%08x", hr)); return hr; }
hr = StringFromCLSID( m_clsidTerminalClass, &lpszTerminalClass ); if( FAILED(hr) ) { CoTaskMemFree( lpszSuperclass );
LOG((MSP_ERROR, "CPTTerminal::Delete exit -" "StringFromCLSID for Superclass failed, returns 0x%08x", hr)); return hr; }
WCHAR szKey[PTKEY_MAXSIZE]; wsprintf( szKey, TEXT("%s\\%s\\%s"), PTKEY_TERMINALS, lpszSuperclass, lpszTerminalClass );
// Clean-up, we need later the TerminalClass
CoTaskMemFree( lpszSuperclass ); CoTaskMemFree( lpszTerminalClass );
//
// Remove key
//
hr = CPTUtil::RecursiveDeleteKey( HKEY_LOCAL_MACHINE, szKey );
//
// Return value
//
LOG((MSP_TRACE, "CPTTerminal::Delete - exit (0x%08x)", hr)); return hr; }
HRESULT CPTTerminal::Get( IN CLSID clsidSuperclass ) { LOG((MSP_TRACE, "CPTTerminal::Get - enter"));
//
// Reset members
//
if(m_bstrName) { SysFreeString( m_bstrName ); m_bstrName = NULL; }
if( m_bstrCompany) { SysFreeString( m_bstrCompany ); m_bstrCompany = NULL; }
if( m_bstrVersion) { SysFreeString( m_bstrVersion ); m_bstrVersion = NULL; }
m_clsidCOM = CLSID_NULL;
//
// initialize with invalid direction and media type
//
m_dwDirections = 0; m_dwMediaTypes = 0;
//
// We determine the terminal path into registry
//
LPOLESTR lpszSuperclass = NULL; LPOLESTR lpszTerminalClass = NULL; HRESULT hr = E_FAIL;
hr = StringFromCLSID( clsidSuperclass, &lpszSuperclass ); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTTerminal::Get exit -" "StringFromCLSID for Superclass failed, returns 0x%08x", hr)); return hr; }
hr = StringFromCLSID( m_clsidTerminalClass, &lpszTerminalClass ); if( FAILED(hr) ) { CoTaskMemFree( lpszSuperclass );
LOG((MSP_ERROR, "CPTTerminal::Get exit -" "StringFromCLSID for Superclass failed, returns 0x%08x", hr)); return hr; }
WCHAR szKey[PTKEY_MAXSIZE]; wsprintf( szKey, TEXT("%s\\%s\\%s"), PTKEY_TERMINALS, lpszSuperclass, lpszTerminalClass );
// Clean-up, we need later the TerminalClass
CoTaskMemFree( lpszSuperclass ); CoTaskMemFree( lpszTerminalClass );
//
// Open terminal key
//
HKEY hKey = NULL; LONG lResult;
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hKey);
//
// Validates registry operation
//
if( ERROR_SUCCESS != lResult ) { LOG((MSP_ERROR, "CPTTerminal::Get exit -" "RegOpenKeyEx failed, returns E_UNEXPECTED")); return E_UNEXPECTED; }
//
// Query for name
//
TCHAR szBuffer[PTKEY_MAXSIZE]; DWORD dwSize = PTKEY_MAXSIZE * sizeof( TCHAR ); DWORD dwType = REG_SZ;
lResult = RegQueryValueEx( hKey, PTKEY_NAME, 0, &dwType, (LPBYTE)szBuffer, &dwSize);
if( ERROR_SUCCESS == lResult ) { m_bstrName = SysAllocString( szBuffer ); }
//
// Query for company
//
dwSize = PTKEY_MAXSIZE * sizeof( TCHAR ); dwType = REG_SZ;
lResult = RegQueryValueEx( hKey, PTKEY_COMPANY, 0, &dwType, (LPBYTE)szBuffer, &dwSize);
if( ERROR_SUCCESS == lResult ) { m_bstrCompany = SysAllocString( szBuffer ); }
//
// Query for version
//
dwSize = PTKEY_MAXSIZE * sizeof( TCHAR ); dwType = REG_SZ;
lResult = RegQueryValueEx( hKey, PTKEY_VERSION, 0, &dwType, (LPBYTE)szBuffer, &dwSize);
if( ERROR_SUCCESS == lResult ) { m_bstrVersion = SysAllocString( szBuffer ); }
//
// Query for CLSID create
//
dwSize = PTKEY_MAXSIZE * sizeof( TCHAR ); dwType = REG_SZ;
lResult = RegQueryValueEx( hKey, PTKEY_CLSIDCREATE, 0, &dwType, (LPBYTE)szBuffer, &dwSize);
if( ERROR_SUCCESS == lResult ) { HRESULT hr = CLSIDFromString( szBuffer, &m_clsidCOM); if( FAILED(hr) ) { m_clsidCOM = CLSID_NULL; } }
//
// Query for directions
//
dwType = REG_DWORD; DWORD dwValue = 0; dwSize = sizeof( dwValue );
lResult = RegQueryValueEx( hKey, PTKEY_DIRECTIONS, 0, &dwType, (LPBYTE)&dwValue, &dwSize);
if( ERROR_SUCCESS == lResult ) { m_dwDirections = dwValue; }
//
// Query for media types
//
dwSize = sizeof( dwValue ); dwType = REG_DWORD; dwValue = 0;
lResult = RegQueryValueEx( hKey, PTKEY_MEDIATYPES, 0, &dwType, (LPBYTE)&dwValue, &dwSize);
if( ERROR_SUCCESS == lResult ) { m_dwMediaTypes = dwValue; }
//
// Clean-up hKey
//
RegCloseKey( hKey );
LOG((MSP_TRACE, "CPTTerminal::Get - exit")); return S_OK; }
///////////////////////////////////////////
// CPTSuperclass Implementation
//
// Constructor/Destructor
CPTSuperclass::CPTSuperclass() { LOG((MSP_TRACE, "CPTSuperclass::CPTSuperclass - enter"));
m_bstrName = NULL; m_clsidSuperclass = CLSID_NULL;
LOG((MSP_TRACE, "CPTSuperclass::CPTSuperclass - exit")); }
CPTSuperclass::~CPTSuperclass() { LOG((MSP_TRACE, "CPTSuperclass::~CPTSuperclass - enter"));
if(m_bstrName) SysFreeString( m_bstrName );
LOG((MSP_TRACE, "CPTSuperclass::~CPTSuperclass - exit")); }
// CPTSuperclass methods
HRESULT CPTSuperclass::Add() { LOG((MSP_TRACE, "CPTSuperclass::Add - enter"));
//
// Get the superclass CLSID as string
//
LPOLESTR lpszSuperclassCLSID = NULL; HRESULT hr = E_FAIL; hr = StringFromCLSID( m_clsidSuperclass, &lpszSuperclassCLSID); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTSuperclass::Add exit -" "StringFromCLSID failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Create key path for superclass
//
WCHAR szKey[PTKEY_MAXSIZE]; wsprintf( szKey, TEXT("%s\\%s"), PTKEY_TERMINALS, lpszSuperclassCLSID);
// Clean-up
CoTaskMemFree( lpszSuperclassCLSID );
//
// Open the registry key
//
HKEY hKey = NULL; long lResult;
lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
//
// Validates the registry operation
//
if( ERROR_SUCCESS != lResult ) { LOG((MSP_ERROR, "CPTSuperclass::Add exit -" "RegCreateKeyEx failed, returns E_UNEXPECTED")); return E_UNEXPECTED; }
//
// Edit the name of the terminal class
//
if( !IsBadStringPtr(m_bstrName, (UINT)-1) ) { lResult = RegSetValueEx( hKey, PTKEY_NAME, 0, REG_SZ, (BYTE *)m_bstrName, (SysStringLen( m_bstrName) + 1) * sizeof(WCHAR) ); }
//
// Clean-up hKey
//
RegFlushKey( hKey ); RegCloseKey( hKey );
LOG((MSP_TRACE, "CPTSuperclass::Add - exit")); return S_OK; }
HRESULT CPTSuperclass::Delete() { LOG((MSP_TRACE, "CPTSuperclass::Delete - enter"));
//
// Get the superclass CLSID as string
//
LPOLESTR lpszSuperclassCLSID = NULL; HRESULT hr = E_FAIL; hr = StringFromCLSID( m_clsidSuperclass, &lpszSuperclassCLSID); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTSuperclass::Delete exit -" "StringFromCLSID failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Create key path for superclass
//
WCHAR szKey[PTKEY_MAXSIZE]; wsprintf( szKey, TEXT("%s\\%s"), PTKEY_TERMINALS, lpszSuperclassCLSID);
// Clean-up
CoTaskMemFree( lpszSuperclassCLSID );
//
// Remove key
//
hr = CPTUtil::RecursiveDeleteKey( HKEY_LOCAL_MACHINE, szKey );
//
// Return value
//
LOG((MSP_TRACE, "CPTSuperclass::Delete - exit (0x%08x)", hr)); return hr; }
HRESULT CPTSuperclass::Get() { LOG((MSP_TRACE, "CPTSuperclass::Get - enter"));
//
// Get the superclass CLSID as string
//
LPOLESTR lpszSuperclassCLSID = NULL; HRESULT hr = E_FAIL; hr = StringFromCLSID( m_clsidSuperclass, &lpszSuperclassCLSID); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTSuperclass::Get exit -" "StringFromCLSID failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Create key path for superclass
//
WCHAR szKey[PTKEY_MAXSIZE]; wsprintf( szKey, TEXT("%s\\%s"), PTKEY_TERMINALS, lpszSuperclassCLSID);
// Clean-up
CoTaskMemFree( lpszSuperclassCLSID );
//
// Reset members
//
if(m_bstrName) { SysFreeString( m_bstrName ); m_bstrName = NULL; }
//
// Open terminal key
//
HKEY hKey = NULL; LONG lResult;
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hKey);
//
// Validates registry operation
//
if( ERROR_SUCCESS != lResult ) { LOG((MSP_ERROR, "CPTSuperclass::Get exit -" "RegOpenKeyEx failed, returns E_UNEXPECTED")); return E_UNEXPECTED; }
//
// Query for name
//
TCHAR szBuffer[PTKEY_MAXSIZE]; DWORD dwSize = PTKEY_MAXSIZE * sizeof( TCHAR ); DWORD dwType = REG_SZ;
lResult = RegQueryValueEx( hKey, PTKEY_NAME, 0, &dwType, (LPBYTE)szBuffer, &dwSize);
if( ERROR_SUCCESS == lResult ) { m_bstrName = SysAllocString( szBuffer ); } else { m_bstrName = SysAllocString(_T("")); }
//
// Clean-up hKey
//
RegCloseKey( hKey );
LOG((MSP_TRACE, "CPTSuperclass::Get - exit")); return S_OK; }
HRESULT CPTSuperclass::ListTerminalClasses( IN DWORD dwMediaTypes, OUT CLSID** ppTerminals, OUT DWORD* pdwCount ) { LOG((MSP_TRACE, "CPTSuperclass::ListTerminalSuperclasses - enter"));
//
// Validates argument
//
if( TM_IsBadWritePtr( ppTerminals, sizeof(CLSID*)) ) { LOG((MSP_ERROR, "CPTSuperclass::ListTerminalSuperclasses exit -" "pTerminals invalid, returns E_INVALIDARG")); return E_INVALIDARG; }
//
// Reset the output arguments
//
*ppTerminals = NULL; *pdwCount = 0;
//
// Get the superclass CLSID as string
//
LPOLESTR lpszSuperclassCLSID = NULL; HRESULT hr = E_FAIL; hr = StringFromCLSID( m_clsidSuperclass, &lpszSuperclassCLSID); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPTSuperclass::Get exit -" "StringFromCLSID failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Create key path for superclass
//
WCHAR szKey[PTKEY_MAXSIZE]; wsprintf( szKey, TEXT("%s\\%s"), PTKEY_TERMINALS, lpszSuperclassCLSID);
// Clean-up
CoTaskMemFree( lpszSuperclassCLSID );
//
// Open the terminal class key
//
HKEY hKey; LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
//
// Validates registry operation
//
if( ERROR_SUCCESS != lResult ) { LOG((MSP_ERROR, "CPTSuperclass::ListTerminalSuperclasses exit - " "RegOpenKeyEx failed, returns E_INVALIDARG")); return E_INVALIDARG; }
DWORD dwArraySize = 8; CLSID* pTerminals = new CLSID[dwArraySize];
if( pTerminals == NULL ) { // Clean-up hKey
RegCloseKey( hKey );
LOG((MSP_ERROR, "CPTSuperclass::ListTerminalSuperclasses exit - " "new operator failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
//
// Enumerate the descendents
//
FILETIME time; TCHAR szBuffer[PTKEY_MAXSIZE]; // Buffer
DWORD dwSize = PTKEY_MAXSIZE; // Buffer size
DWORD dwIndex = 0; // Index into array
DWORD dwChildIndex = 0; // Child index into registry
while( RegEnumKeyEx( hKey, dwChildIndex, szBuffer, &dwSize, NULL, NULL, NULL, &time) == ERROR_SUCCESS) { //
// Prepare for the nex child
//
dwChildIndex++; dwSize = PTKEY_MAXSIZE;
//
// I have to qury MediaType value for this entry
//
CPTTerminal Terminal; HRESULT hr = CLSIDFromString( szBuffer, &Terminal.m_clsidTerminalClass); if( FAILED(hr) ) { hr = S_OK;
continue; }
if( dwMediaTypes ) { HRESULT hr = E_FAIL; hr = Terminal.Get( m_clsidSuperclass ); if( FAILED(hr) ) { hr = S_OK;
continue; }
if( !(Terminal.m_dwMediaTypes & dwMediaTypes) ) { continue; } }
//
// Increase the array room if it's necessary
//
if( dwArraySize <= dwIndex) { // Old buffer
CLSID* pOldTerminals = pTerminals;
// New buffer
dwArraySize *= 2; pTerminals = new CLSID[dwArraySize]; if( pTerminals == NULL ) { delete[] pOldTerminals; LOG((MSP_ERROR, "CPTSuperclass::ListTerminalSuperclasses exit - " "new operator failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; }
// Copies the old buffer into the new one
memcpy( pTerminals, pOldTerminals, sizeof(CLSID)*dwArraySize/2);
// Delete the old buffer
delete[] pOldTerminals; }
//
// Add the terminal class
//
pTerminals[dwIndex] = Terminal.m_clsidTerminalClass; dwIndex++; }
//
// Clean-up hKey
//
RegCloseKey( hKey );
//
// Return values
//
if( SUCCEEDED(hr) ) { *ppTerminals = pTerminals; *pdwCount = dwIndex; }
LOG((MSP_TRACE, "CPTSuperclass::ListTerminalSuperclasses - exit Len=%ld, 0x%08x", dwIndex, hr)); return hr; }
// eof
|