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.
 
 
 
 
 
 

477 lines
11 KiB

#include <objbase.h>
#include <olectl.h>
#include <initguid.h>
#include "guids.h"
#include "basesnap.h"
#include "comp.h"
#include "compdata.h"
#include "about.h"
#include "uddi.h"
#include <assert.h>
LONG UnRegisterServer( const CLSID& clsid );
//
// Globals Variables
//
HINSTANCE g_hinst;
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD fdwReason, void* lpvReserved )
{
if( DLL_PROCESS_ATTACH == fdwReason )
{
g_hinst = hinst;
}
return TRUE;
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj)
{
if( ( rclsid != CLSID_CUDDIServices ) && ( rclsid != CLSID_CSnapinAbout ) )
return CLASS_E_CLASSNOTAVAILABLE;
if( !ppvObj )
return E_FAIL;
*ppvObj = NULL;
//
// We can only hand out IUnknown and IClassFactory pointers. Fail
// if they ask for anything else.
//
if( !IsEqualIID(riid, IID_IUnknown) && !IsEqualIID( riid, IID_IClassFactory ) )
return E_NOINTERFACE;
CClassFactory *pFactory = NULL;
//
// make the factory passing in the creation function for the type of object they want
//
if( CLSID_CUDDIServices == rclsid )
pFactory = new CClassFactory( CClassFactory::COMPONENT );
else if( CLSID_CSnapinAbout == rclsid )
pFactory = new CClassFactory( CClassFactory::ABOUT );
if( NULL == pFactory )
return E_OUTOFMEMORY;
HRESULT hr = pFactory->QueryInterface( riid, ppvObj );
return hr;
}
STDAPI DllCanUnloadNow(void)
{
if( ( 0 == g_uObjects ) && ( 0 == g_uSrvLock ) )
return S_OK;
else
return S_FALSE;
}
CClassFactory::CClassFactory(FACTORY_TYPE factoryType)
: m_cref(0)
, m_factoryType(factoryType)
{
OBJECT_CREATED
}
CClassFactory::~CClassFactory()
{
OBJECT_DESTROYED
}
STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID *ppv)
{
if( !ppv )
return E_FAIL;
*ppv = NULL;
if( IsEqualIID( riid, IID_IUnknown ) )
*ppv = static_cast<IClassFactory *>(this);
else
if( IsEqualIID(riid, IID_IClassFactory ) )
*ppv = static_cast<IClassFactory *>(this);
if( *ppv )
{
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CClassFactory::AddRef()
{
return InterlockedIncrement( (LONG*)&m_cref );
}
STDMETHODIMP_(ULONG) CClassFactory::Release()
{
if( 0 == InterlockedDecrement( (LONG *)&m_cref ) )
{
delete this;
return 0;
}
return m_cref;
}
STDMETHODIMP CClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj )
{
HRESULT hr;
void* pObj;
if( !ppvObj )
return E_FAIL;
*ppvObj = NULL;
//
// Our object does does not support aggregation, so we need to
// fail if they ask us to do aggregation.
//
if( pUnkOuter )
return CLASS_E_NOAGGREGATION;
if( COMPONENT == m_factoryType )
{
pObj = new CComponentData();
}
else
{
pObj = new CSnapinAbout();
}
if( !pObj )
return E_OUTOFMEMORY;
//
// QueryInterface will do the AddRef() for us, so we do not
// do it in this function
//
hr = ( (LPUNKNOWN) pObj )->QueryInterface( riid, ppvObj );
if( FAILED(hr) )
delete pObj;
return hr;
}
STDMETHODIMP CClassFactory::LockServer( BOOL fLock )
{
if( fLock )
InterlockedIncrement( (LONG *) &g_uSrvLock );
else
InterlockedDecrement( (LONG *) &g_uSrvLock);
return S_OK;
}
//
// Register the component in the registry.
//
HRESULT RegisterServer( HMODULE hModule, // DLL module handle
const CLSID& clsid, // Class ID
const _TCHAR* szFriendlyName ) // IDs
{
LPOLESTR wszCLSID = NULL;
try
{
//
// Get server location.
//
_TCHAR szModule[ MAX_PATH + 1];
DWORD dwResult =
::GetModuleFileName( hModule,
szModule,
sizeof(szModule)/sizeof(_TCHAR) );
szModule[ MAX_PATH ] = NULL;
assert( 0 != dwResult );
//
// Get CLSID
//
HRESULT hr = StringFromCLSID( clsid, &wszCLSID );
if( FAILED(hr) || ( NULL == wszCLSID ) )
{
return hr;
}
//
// Build the key CLSID\\{...}
//
tstring strKey( _T("CLSID\\") );
strKey += wszCLSID;
CUDDIRegistryKey::Create( HKEY_CLASSES_ROOT, strKey );
CUDDIRegistryKey key( HKEY_CLASSES_ROOT, strKey );
key.SetValue( _T(""), szFriendlyName );
key.Close();
strKey += _T( "\\InprocServer32" );
CUDDIRegistryKey::Create( HKEY_CLASSES_ROOT, strKey );
CUDDIRegistryKey keyInprocServer32( HKEY_CLASSES_ROOT, strKey );
keyInprocServer32.SetValue( _T(""), szModule );
keyInprocServer32.SetValue( _T("ThreadingModel"), _T("Apartment") );
keyInprocServer32.Close();
//
// Free memory.
//
CoTaskMemFree( wszCLSID );
return S_OK;
}
catch( ... )
{
CoTaskMemFree( wszCLSID );
return E_OUTOFMEMORY;
}
}
//////////////////////////////////////////////////////////
//
// Exported functions
//
//
// Server registration
//
STDAPI DllRegisterServer()
{
try
{
HRESULT hr = S_OK;
_TCHAR szName[ 256 ];
_TCHAR szSnapInName[ 256 ];
_TCHAR szAboutName[ 256 ];
_TCHAR szProvider[ 256 ];
//
// TODO: Fix the version thing here
//
//_TCHAR szVersion[ 100 ];
LoadString( g_hinst, IDS_UDDIMMC_NAME, szName, ARRAYLEN( szName ) );
LoadString( g_hinst, IDS_UDDIMMC_SNAPINNAME, szSnapInName, ARRAYLEN( szSnapInName ) );
LoadString( g_hinst, IDS_UDDIMMC_ABOUTNAME, szAboutName, ARRAYLEN( szAboutName ) );
LoadString( g_hinst, IDS_UDDIMMC_PROVIDER, szProvider, ARRAYLEN( szProvider ) );
//
// TODO: Fix the version thing here
//
//LoadString( g_hinst, IDS_UDDIMMC_VERSION, szVersion, ARRAYLEN( szVersion ) );
//
// Register our Components
//
hr = RegisterServer( g_hinst, CLSID_CUDDIServices, szName );
if( FAILED(hr) )
return hr;
hr = RegisterServer( g_hinst, CLSID_CSnapinAbout, szAboutName );
if( FAILED(hr) )
return hr;
//
// Create the primary snapin nodes
//
LPOLESTR wszCLSID = NULL;
hr = StringFromCLSID( CLSID_CUDDIServices, &wszCLSID );
if( FAILED(hr) )
{
return hr;
}
LPOLESTR wszCLSIDAbout = NULL;
hr = StringFromCLSID( CLSID_CSnapinAbout, &wszCLSIDAbout );
if( FAILED(hr) )
{
CoTaskMemFree( wszCLSID );
return hr;
}
TCHAR szPath[ MAX_PATH + 1 ];
GetModuleFileName( g_hinst, szPath, MAX_PATH );
tstring strNameStringIndirect( _T("@") );
strNameStringIndirect += szPath;
strNameStringIndirect += _T(",-");
_TCHAR szNameResourceIndex[ 10 ];
strNameStringIndirect += _itot( IDS_UDDIMMC_NAME, szNameResourceIndex, 10 );
tstring strMMCKey( g_szMMCBasePath );
strMMCKey += _T("\\SnapIns\\");
strMMCKey += wszCLSID;
CUDDIRegistryKey::Create( HKEY_LOCAL_MACHINE, strMMCKey );
CUDDIRegistryKey keyMMC( strMMCKey );
keyMMC.SetValue( _T("About"), wszCLSIDAbout );
keyMMC.SetValue( _T("NameString"), szName );
keyMMC.SetValue( _T("NameStringIndirect"), strNameStringIndirect.c_str() );
keyMMC.SetValue( _T("Provider"), szProvider );
//
// TODO: Fix the version thing here
//
keyMMC.SetValue( _T("Version" ), _T("1.0") );
keyMMC.Close();
tstring strStandAlone( strMMCKey );
strStandAlone += _T("\\StandAlone");
CUDDIRegistryKey::Create( HKEY_LOCAL_MACHINE, strStandAlone );
tstring strNodeTypes( strMMCKey );
strNodeTypes += _T("\\NodeTypes");
CUDDIRegistryKey::Create( HKEY_LOCAL_MACHINE, strNodeTypes );
//
// No NodeTypes to register
// We do not allow extensions of our nodes
//
//
// Register as a dynamic extension to computer management
//
tstring strExtKey( g_szMMCBasePath );
strExtKey += _T("\\NodeTypes\\");
strExtKey += g_szServerAppsGuid;
strExtKey += _T("\\Dynamic Extensions");
CUDDIRegistryKey dynamicExtensions( strExtKey );
dynamicExtensions.SetValue( wszCLSID, szSnapInName );
dynamicExtensions.Close();
//
// Register as a namespace extension to computer management
//
tstring strNameSpaceExtensionKey( g_szMMCBasePath );
strNameSpaceExtensionKey += _T("\\NodeTypes\\");
strNameSpaceExtensionKey += g_szServerAppsGuid;
strNameSpaceExtensionKey += _T("\\Extensions\\NameSpace");
CUDDIRegistryKey hkeyNameSpace( strNameSpaceExtensionKey );
hkeyNameSpace.SetValue( wszCLSID, szSnapInName );
hkeyNameSpace.Close();
CoTaskMemFree( wszCLSID );
CoTaskMemFree( wszCLSIDAbout );
return hr;
}
catch( ... )
{
return E_FAIL;
}
}
STDAPI DllUnregisterServer()
{
LPOLESTR wszCLSID = NULL;
try
{
HRESULT hr = S_OK;
UnRegisterServer( CLSID_CUDDIServices );
if( FAILED(hr) )
return hr;
UnRegisterServer( CLSID_CSnapinAbout );
if( FAILED(hr) )
return hr;
//
// Remove \\SnapIns\\ entry
//
hr = StringFromCLSID( CLSID_CUDDIServices, &wszCLSID );
if( FAILED( hr) || ( NULL == wszCLSID ) )
{
return hr;
}
tstring strMMCKey( g_szMMCBasePath );
strMMCKey += _T("\\SnapIns\\");
strMMCKey += wszCLSID;
CUDDIRegistryKey::DeleteKey( HKEY_LOCAL_MACHINE, strMMCKey );
//
// Remove \\Dynamic Extensions key
//
tstring strExtKey( g_szMMCBasePath );
strExtKey += _T("\\NodeTypes\\");
strExtKey += g_szServerAppsGuid;
strExtKey += _T("\\Dynamic Extensions");
CUDDIRegistryKey dynamicExtensions( strExtKey );
dynamicExtensions.DeleteValue( wszCLSID );
dynamicExtensions.Close();
//
// Delete \\NodeTypes\\...\\Extensions\\Namespace Value
//
tstring strNameSpaceExtensionKey( g_szMMCBasePath );
strNameSpaceExtensionKey += _T("\\NodeTypes\\");
strNameSpaceExtensionKey += g_szServerAppsGuid;
strNameSpaceExtensionKey += _T("\\Extensions\\NameSpace");
CUDDIRegistryKey hkeyNameSpace( strNameSpaceExtensionKey );
hkeyNameSpace.DeleteValue( wszCLSID );
hkeyNameSpace.Close();
CoTaskMemFree( wszCLSID );
return S_OK;
}
catch(...)
{
CoTaskMemFree( wszCLSID );
return E_FAIL;
}
}
//
// Remove the component from the registry.
//
LONG UnRegisterServer( const CLSID& clsid )
{
LPOLESTR wszCLSID = NULL;
try
{
//
// Get CLSID
//
HRESULT hr = StringFromCLSID( clsid, &wszCLSID );
if( FAILED(hr) || ( NULL == wszCLSID ) )
{
return hr;
}
//
// Build the key CLSID\\{...}
//
wstring wstrKey( L"CLSID\\" );
wstrKey += wszCLSID;
//
// Delete the CLSID Key - CLSID\{...}
//
CUDDIRegistryKey::DeleteKey( HKEY_CLASSES_ROOT, wstrKey );
}
catch( ... )
{
//
// Free memory.
//
CoTaskMemFree( wszCLSID );
return E_OUTOFMEMORY;
}
//
// Free memory.
//
CoTaskMemFree( wszCLSID );
return S_OK ;
}