466 lines
12 KiB
C++
466 lines
12 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
winssnap.cpp
|
|
WINS snapin entry points/registration functions
|
|
|
|
Note: Proxy/Stub Information
|
|
To build a separate proxy/stub DLL,
|
|
run nmake -f Snapinps.mak in the project directory.
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "initguid.h"
|
|
#include "winscomp.h"
|
|
#include "winssnap.h"
|
|
#include "ncglobal.h" // network console global defines
|
|
#include "cmptrmgr.h" // computer management snapin node types
|
|
#include "locale.h" // for setlocale
|
|
|
|
#include <lmerr.h> // for NERR stuff
|
|
|
|
#ifdef _DEBUG
|
|
void DbgVerifyInstanceCounts();
|
|
#define DEBUG_VERIFY_INSTANCE_COUNTS DbgVerifyInstanceCounts()
|
|
#else
|
|
#define DEBUG_VERIFY_INSTANCE_COUNTS
|
|
#endif
|
|
|
|
CComModule _Module;
|
|
|
|
BEGIN_OBJECT_MAP(ObjectMap)
|
|
OBJECT_ENTRY(CLSID_WinsSnapin, CWinsComponentDataPrimary)
|
|
OBJECT_ENTRY(CLSID_WinsSnapinExtension, CWinsComponentDataExtension)
|
|
OBJECT_ENTRY(CLSID_WinsSnapinAbout, CWinsAbout)
|
|
END_OBJECT_MAP()
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
CWinsSnapinApp theApp;
|
|
|
|
BOOL CWinsSnapinApp::InitInstance()
|
|
{
|
|
_Module.Init(ObjectMap, m_hInstance);
|
|
|
|
SHFusionInitializeFromModuleID (m_hInstance, 2);
|
|
|
|
//
|
|
// Initialize the CWndIpAddress control window class IPADDRESS
|
|
//
|
|
CWndIpAddress::CreateWindowClass( m_hInstance ) ;
|
|
|
|
// set the default locale to the system locale
|
|
setlocale(LC_ALL, "");
|
|
|
|
//
|
|
// Initialize use of the WinSock routines
|
|
//
|
|
WSADATA wsaData ;
|
|
|
|
if ( ::WSAStartup( MAKEWORD( 1, 1 ), & wsaData ) != 0 )
|
|
{
|
|
m_bWinsockInited = TRUE;
|
|
Trace0("InitInstance: Winsock initialized!\n");
|
|
}
|
|
else
|
|
{
|
|
m_bWinsockInited = FALSE;
|
|
}
|
|
|
|
::IPAddrInit(m_hInstance);
|
|
|
|
return CWinApp::InitInstance();
|
|
}
|
|
|
|
int CWinsSnapinApp::ExitInstance()
|
|
{
|
|
SHFusionUninitialize();
|
|
|
|
_Module.Term();
|
|
|
|
DEBUG_VERIFY_INSTANCE_COUNTS;
|
|
|
|
//
|
|
// Terminate use of the WinSock routines.
|
|
//
|
|
if ( m_bWinsockInited )
|
|
{
|
|
WSACleanup() ;
|
|
}
|
|
|
|
return CWinApp::ExitInstance();
|
|
}
|
|
|
|
/***
|
|
*
|
|
* CWinsadmnApp::GetSystemMessage
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Given a message ID, determine where the message resides,
|
|
* and load it into the buffer.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* UINT nId Message ID number
|
|
* char * chBuffer Character buffer to load into.
|
|
* int cbBuffSize Size of buffer in characters
|
|
*
|
|
* Returns:
|
|
*
|
|
* API error return code, or ERROR_SUCCESS
|
|
*
|
|
*/
|
|
DWORD
|
|
CWinsSnapinApp::GetSystemMessage(
|
|
UINT nId,
|
|
TCHAR * chBuffer,
|
|
int cbBuffSize
|
|
)
|
|
{
|
|
TCHAR * pszText = NULL ;
|
|
HINSTANCE hdll = NULL ;
|
|
|
|
DWORD flags = FORMAT_MESSAGE_IGNORE_INSERTS
|
|
| FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
|
|
|
//
|
|
// Interpret the error. Need to special case
|
|
// the lmerr & ntstatus ranges.
|
|
//
|
|
if( nId >= NERR_BASE && nId <= MAX_NERR )
|
|
{
|
|
hdll = ::LoadLibrary( _T("netmsg.dll") );
|
|
}
|
|
else if( nId >= 0x40000000L )
|
|
{
|
|
hdll = ::LoadLibrary( _T("ntdll.dll") );
|
|
}
|
|
|
|
if( hdll == NULL )
|
|
{
|
|
flags |= FORMAT_MESSAGE_FROM_SYSTEM;
|
|
}
|
|
else
|
|
{
|
|
flags |= FORMAT_MESSAGE_FROM_HMODULE;
|
|
}
|
|
|
|
DWORD dwResult = ::FormatMessage( flags,
|
|
(LPVOID) hdll,
|
|
nId,
|
|
0,
|
|
chBuffer,
|
|
cbBuffSize,
|
|
NULL );
|
|
|
|
if( hdll != NULL )
|
|
{
|
|
LONG err = ::GetLastError();
|
|
::FreeLibrary( hdll );
|
|
if ( dwResult == 0 )
|
|
{
|
|
::SetLastError( err );
|
|
}
|
|
}
|
|
|
|
return dwResult ? ERROR_SUCCESS : ::GetLastError();
|
|
}
|
|
|
|
/***
|
|
*
|
|
* CWinsadmnApp::MessageBox
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Replacement for AfxMessageBox(). This function will call up the
|
|
* appropriate message from wherever before displaying it
|
|
*
|
|
* Arguments:
|
|
*
|
|
* UINT nIdPrompt Message ID
|
|
* UINT nType AfxMessageBox type (YESNO, OKCANCEL, etc)
|
|
* UINT nHelpContext Help context ID for AfxMessageBox();
|
|
*
|
|
* Notes:
|
|
*
|
|
* If an error occurs, a standard message (hard-coded in english) will
|
|
* be shown that gives the error number.
|
|
*
|
|
*/
|
|
int
|
|
CWinsSnapinApp::MessageBox (
|
|
UINT nIdPrompt,
|
|
UINT nType,
|
|
UINT nHelpContext
|
|
)
|
|
{
|
|
CThemeContextActivator themeActivator;
|
|
//
|
|
// Substitute a friendly message for "RPC server not
|
|
// available" and "No more endpoints available from
|
|
// the endpoint mapper".
|
|
//
|
|
if (nIdPrompt == EPT_S_NOT_REGISTERED ||
|
|
nIdPrompt == RPC_S_SERVER_UNAVAILABLE)
|
|
{
|
|
nIdPrompt = IDS_ERR_WINS_DOWN;
|
|
}
|
|
|
|
//
|
|
// If it's our error, the text is in our resource segment.
|
|
// Otherwise, use FormatMessage() and the appropriate DLL>
|
|
//
|
|
if ((nIdPrompt >= IDS_ERR_INVALID_IP) && (nIdPrompt <= IDS_MSG_LAST))
|
|
{
|
|
return ::AfxMessageBox(nIdPrompt, nType, nHelpContext);
|
|
}
|
|
|
|
TCHAR szMesg [1024] ;
|
|
int nResult;
|
|
|
|
if ((nResult = GetSystemMessage(nIdPrompt, szMesg, sizeof(szMesg)/sizeof(TCHAR)))
|
|
== ERROR_SUCCESS)
|
|
{
|
|
return ::AfxMessageBox(szMesg, nType, nHelpContext);
|
|
}
|
|
|
|
Trace1("Message number %d not found", nIdPrompt);
|
|
ASSERT(0 && "Error Message ID not handled");
|
|
|
|
//
|
|
// Do something for the retail version
|
|
//
|
|
::wsprintf ( szMesg, _T("Error: %lu"), nIdPrompt);
|
|
::AfxMessageBox(szMesg, nType, nHelpContext);
|
|
|
|
return nResult;
|
|
}
|
|
|
|
int
|
|
CWinsSnapinApp::MessageBox (
|
|
LPCTSTR pPrefixText,
|
|
UINT nIdPrompt,
|
|
UINT nType,
|
|
UINT nHelpContext
|
|
)
|
|
{
|
|
CThemeContextActivator themeActivator;
|
|
|
|
CString strText = pPrefixText;
|
|
CString strAppend;
|
|
|
|
//
|
|
// Substitute a friendly message for "RPC server not
|
|
// available" and "No more endpoints available from
|
|
// the endpoint mapper".
|
|
//
|
|
if (nIdPrompt == EPT_S_NOT_REGISTERED ||
|
|
nIdPrompt == RPC_S_SERVER_UNAVAILABLE)
|
|
{
|
|
nIdPrompt = IDS_ERR_WINS_DOWN;
|
|
}
|
|
|
|
//
|
|
// If it's our error, the text is in our resource segment.
|
|
// Otherwise, use FormatMessage() and the appropriate DLL>
|
|
//
|
|
if ((nIdPrompt >= IDS_ERR_BASE) && (nIdPrompt <= IDS_MSG_LAST))
|
|
{
|
|
strAppend.LoadString(nIdPrompt);
|
|
strText += strAppend;
|
|
|
|
return ::AfxMessageBox(strText, nType, nHelpContext);
|
|
}
|
|
|
|
TCHAR szMesg [1024] ;
|
|
int nResult;
|
|
|
|
if ((nResult = GetSystemMessage(nIdPrompt, szMesg, sizeof(szMesg)/sizeof(TCHAR)))
|
|
== ERROR_SUCCESS)
|
|
{
|
|
strText += szMesg;
|
|
return ::AfxMessageBox(strText, nType, nHelpContext);
|
|
}
|
|
|
|
Trace1("Message number %d not found", nIdPrompt);
|
|
ASSERT(0 && "Error Message ID not handled");
|
|
|
|
//
|
|
// Do something for the retail version
|
|
//
|
|
::wsprintf ( szMesg, _T("Error: %lu"), nIdPrompt);
|
|
strText += szMesg;
|
|
::AfxMessageBox(strText, nType, nHelpContext);
|
|
|
|
return nResult;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Used to determine whether the DLL can be unloaded by OLE
|
|
|
|
STDAPI DllCanUnloadNow(void)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
return (AfxDllCanUnloadNow()==S_OK && _Module.GetLockCount()==0) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Returns a class factory to create an object of the requested type
|
|
|
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
|
{
|
|
return _Module.GetClassObject(rclsid, riid, ppv);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DllRegisterServer - Adds entries to the system registry
|
|
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
//
|
|
// registers object, typelib and all interfaces in typelib
|
|
//
|
|
HRESULT hr = _Module.RegisterServer(/* bRegTypeLib */ FALSE);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
CString strDesc, strExtDesc, strRootDesc, strVersion;
|
|
|
|
strDesc.LoadString(IDS_SNAPIN_DESC);
|
|
strExtDesc.LoadString(IDS_SNAPIN_EXTENSION_DESC);
|
|
strRootDesc.LoadString(IDS_ROOT_DESC);
|
|
strVersion.LoadString(IDS_ABOUT_VERSION);
|
|
|
|
//
|
|
// register the snapin into the console snapin list
|
|
//
|
|
hr = RegisterSnapinGUID(&CLSID_WinsSnapin,
|
|
&GUID_WinsRootNodeType,
|
|
&CLSID_WinsSnapinAbout,
|
|
strDesc,
|
|
strVersion,
|
|
TRUE);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = RegisterSnapinGUID(&CLSID_WinsSnapinExtension,
|
|
NULL,
|
|
&CLSID_WinsSnapinAbout,
|
|
strExtDesc,
|
|
strVersion,
|
|
FALSE);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
//
|
|
// register the snapin nodes into the console node list
|
|
//
|
|
hr = RegisterNodeTypeGUID(&CLSID_WinsSnapin,
|
|
&GUID_WinsRootNodeType,
|
|
strRootDesc);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
#ifdef __NETWORK_CONSOLE__
|
|
|
|
hr = RegisterAsRequiredExtensionGUID(&GUID_NetConsRootNodeType,
|
|
&CLSID_WinsSnapinExtension,
|
|
strExtDesc,
|
|
EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
|
|
&CLSID_WinsSnapinExtension); // the value doesn't matter,
|
|
// just needs to be non-null
|
|
ASSERT(SUCCEEDED(hr));
|
|
#endif
|
|
|
|
hr = RegisterAsRequiredExtensionGUID(&NODETYPE_COMPUTERMANAGEMENT_SERVERAPPS,
|
|
&CLSID_WinsSnapinExtension,
|
|
strExtDesc,
|
|
EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
|
|
&NODETYPE_COMPUTERMANAGEMENT_SERVERAPPS); // NULL : not dynamic
|
|
ASSERT(SUCCEEDED(hr));
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DllUnregisterServer - Removes entries from the system registry
|
|
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
HRESULT hr = _Module.UnregisterServer();
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
// un register the snapin
|
|
//
|
|
hr = UnregisterSnapinGUID(&CLSID_WinsSnapin);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = UnregisterSnapinGUID(&CLSID_WinsSnapinExtension);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
// unregister the snapin nodes
|
|
//
|
|
hr = UnregisterNodeTypeGUID(&GUID_WinsRootNodeType);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
#ifdef __NETWORK_CONSOLE__
|
|
|
|
hr = UnregisterAsRequiredExtensionGUID(&GUID_NetConsRootNodeType,
|
|
&CLSID_WinsSnapinExtension,
|
|
EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
|
|
&CLSID_WinsSnapinExtension);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
#endif
|
|
// computer management snapin extension
|
|
hr = UnregisterAsRequiredExtensionGUID(&NODETYPE_COMPUTERMANAGEMENT_SERVERAPPS,
|
|
&CLSID_WinsSnapinExtension,
|
|
EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
|
|
&CLSID_WinsSnapinExtension);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
return hr;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void DbgVerifyInstanceCounts()
|
|
{
|
|
DEBUG_VERIFY_INSTANCE_COUNT(CHandler);
|
|
DEBUG_VERIFY_INSTANCE_COUNT(CMTHandler);
|
|
}
|
|
|
|
|
|
|
|
#endif // _DEBUG
|
|
|