windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/wp/admex/excoper.cpp

545 lines
14 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1996 Microsoft Corporation
//
// Module Name:
// ExcOper.cpp
//
// Abstract:
// Implementation of exception classes.
//
// Author:
// David Potter (davidp) May 20, 1996
//
// Revision History:
//
// Notes:
// stdafx.h, TraceTag.h, and resource.h are all pulled from the project
// directory.
//
// stdafx.h must have an IDS typedef and disable some W4 warnings.
//
// TraceTag.h must define TraceError.
//
// resource.h must define IDS_UNKNOWN_ERROR, and the string must be
// defined something like "Error %d (0x%08.8x)." in the resource file.
//
/////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include "ExcOper.h"
#include "TraceTag.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CExceptionWithOper
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CExceptionWithOper, CException)
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExceptionWithOper::CExceptionWithOper
//
// Routine Description:
// Constructor.
//
// Arguments:
// idsOperation [IN] String ID for operation occurring during exception.
// pszOperArg1 [IN] 1st argument to operation string.
// pszOperArg2 [IN] 2nd argument to operation string.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CExceptionWithOper::CExceptionWithOper(
IN IDS idsOperation,
IN LPCTSTR pszOperArg1,
IN LPCTSTR pszOperArg2
)
{
SetOperation(idsOperation, pszOperArg1, pszOperArg2);
} //*** CExceptionWithOper::CExceptionWithOper()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExceptionWithOper::CExceptionWithOper
//
// Routine Description:
// Constructor.
//
// Arguments:
// idsOperation [IN] String ID for operation occurring during exception.
// pszOperArg1 [IN] 1st argument to operation string.
// pszOperArg2 [IN] 2nd argument to operation string.
// bAutoDelete [IN] Auto-delete the exception in Delete().
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CExceptionWithOper::CExceptionWithOper(
IN IDS idsOperation,
IN LPCTSTR pszOperArg1,
IN LPCTSTR pszOperArg2,
IN BOOL bAutoDelete
) : CException(bAutoDelete)
{
SetOperation(idsOperation, pszOperArg1, pszOperArg2);
} //*** CExceptionWithOper::CExceptionWithOper()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExceptionWithOper::~CExceptionWithOper
//
// Routine Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CExceptionWithOper::~CExceptionWithOper(void)
{
} //*** CExceptionWithOper::~CExceptionWithOper()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExceptionWithOper::GetErrorMessage
//
// Routine Description:
// Get the error message represented by the exception.
//
// Arguments:
// lpszError [OUT] String in which to return the error message.
// nMaxError [IN] Maximum length of the output string.
// pnHelpContext [OUT] Help context for the error message.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CExceptionWithOper::GetErrorMessage(
LPTSTR lpszError,
UINT nMaxError,
PUINT pnHelpContext
)
{
// Format the operation string.
FormatWithOperation(lpszError, nMaxError, NULL);
return TRUE;
} //*** CExceptionWithOper::GetErrorMessage()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExceptionWithOper::ReportError
//
// Routine Description:
// Report an error from the exception. Overriding to get a bigger
// error message buffer.
//
// Arguments:
// nType [IN] Type of message box.
// nError [IN] ID of a mesage to display if exception has no message.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
int CExceptionWithOper::ReportError(
UINT nType /* = MB_OK */,
UINT nError /* = 0 */
)
{
TCHAR szErrorMessage[EXCEPT_MAX_OPER_ARG_LENGTH * 3];
int nDisposition;
UINT nHelpContext;
if (GetErrorMessage(szErrorMessage, sizeof(szErrorMessage) / sizeof(TCHAR), &nHelpContext))
nDisposition = AfxMessageBox(szErrorMessage, nType, nHelpContext);
else
{
if (nError == 0)
nError = AFX_IDP_NO_ERROR_AVAILABLE;
nDisposition = AfxMessageBox(nError, nType, nHelpContext);
}
return nDisposition;
} //*** CExceptionWithOper::ReportError()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExceptionWithOper::SetOperation
//
// Routine Description:
// Constructor.
//
// Arguments:
// idsOperation [IN] String ID for operation occurring during exception.
// pszOperArg1 [IN] 1st argument to operation string.
// pszOperArg2 [IN] 2nd argument to operation string.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CExceptionWithOper::SetOperation(
IN IDS idsOperation,
IN LPCTSTR pszOperArg1,
IN LPCTSTR pszOperArg2
)
{
m_idsOperation = idsOperation;
if (pszOperArg1 == NULL)
m_szOperArg1[0] = _T('\0');
else
{
::_tcsncpy(m_szOperArg1, pszOperArg1, (sizeof(m_szOperArg1) / sizeof(TCHAR)) - 1);
m_szOperArg1[(sizeof(m_szOperArg1) / sizeof(TCHAR))- 1] = _T('\0');
} // else: first argument specified
if (pszOperArg2 == NULL)
m_szOperArg2[0] = _T('\0');
else
{
::_tcsncpy(m_szOperArg2, pszOperArg2, (sizeof(m_szOperArg2) / sizeof(TCHAR)) - 1);
m_szOperArg2[(sizeof(m_szOperArg2) / sizeof(TCHAR)) - 1] = _T('\0');
} // else: second argument specified
} //*** CExceptionWithOper::SetOperation()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExceptionWithOper::FormatWithOperation
//
// Routine Description:
// Get the error message represented by the exception.
//
// Arguments:
// lpszError [OUT] String in which to return the error message.
// nMaxError [IN] Maximum length of the output string.
// pszMsg [IN] Message to format with the operation string.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CExceptionWithOper::FormatWithOperation(
OUT LPTSTR lpszError,
IN UINT nMaxError,
IN LPCTSTR pszMsg
)
{
DWORD dwResult;
TCHAR szOperation[EXCEPT_MAX_OPER_ARG_LENGTH];
TCHAR szFmtOperation[EXCEPT_MAX_OPER_ARG_LENGTH * 3];
ASSERT(lpszError != NULL);
ASSERT(nMaxError > 0);
// Format the operation string.
if (m_idsOperation)
{
void * rgpvArgs[2] = { m_szOperArg1, m_szOperArg2 };
// Load the operation string.
dwResult = ::LoadString(AfxGetApp()->m_hInstance, m_idsOperation, szOperation, (sizeof(szOperation) / sizeof(TCHAR)));
ASSERT(dwResult != 0);
// Format the operation string.
::FormatMessage(
FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
szOperation,
0,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
szFmtOperation,
sizeof(szFmtOperation) / sizeof(TCHAR),
(va_list *) rgpvArgs
);
// ::_sntprintf(szFmtOperation, (sizeof(szFmtOperation) / sizeof(TCHAR)) - 1, szOperation, m_szOperArg1, m_szOperArg2);
szFmtOperation[(sizeof(szFmtOperation) / sizeof(TCHAR)) - 1] = _T('\0');
// Format the final error message.
if (pszMsg != NULL)
::_sntprintf(lpszError, nMaxError - 1, _T("%s\n\n%s"), szFmtOperation, pszMsg);
else
::_tcsncpy(lpszError, szFmtOperation, nMaxError - 1);
lpszError[nMaxError - 1] = _T('\0');
} // if: operation string specified
else
{
if (pszMsg != NULL)
{
::_tcsncpy(lpszError, pszMsg, nMaxError - 1);
lpszError[nMaxError - 1] = _T('\0');
} // if: additional message specified
else
lpszError[0] = _T('\0');
} // else: no operation string specified
} //*** CExceptionWithOper::FormatWithOperation()
//***************************************************************************
/////////////////////////////////////////////////////////////////////////////
// CException
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CNTException, CExceptionWithOper)
/////////////////////////////////////////////////////////////////////////////
//++
//
// CNTException::CNTException
//
// Routine Description:
// Constructor.
//
// Arguments:
// sc [IN] NT status code.
// idsOperation [IN] String ID for operation occurring during exception.
// pszOperArg1 [IN] 1st argument to operation string.
// pszOperArg2 [IN] 2nd argument to operation string.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CNTException::CNTException(
IN SC sc,
IN IDS idsOperation,
IN LPCTSTR pszOperArg1,
IN LPCTSTR pszOperArg2
) : CExceptionWithOper(idsOperation, pszOperArg1, pszOperArg2)
{
m_sc = sc;
} //*** CNTException::CNTException()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CNTException::CNTException
//
// Routine Description:
// Constructor.
//
// Arguments:
// sc [IN] NT status code.
// idsOperation [IN] String ID for operation occurring during exception.
// pszOperArg1 [IN] 1st argument to operation string.
// pszOperArg2 [IN] 2nd argument to operation string.
// bAutoDelete [IN] Auto-delete the exception in Delete().
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CNTException::CNTException(
IN SC sc,
IN IDS idsOperation,
IN LPCTSTR pszOperArg1,
IN LPCTSTR pszOperArg2,
IN BOOL bAutoDelete
) : CExceptionWithOper(idsOperation, pszOperArg1, pszOperArg2, bAutoDelete)
{
m_sc = sc;
} //*** CNTException::CNTException()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CNTException::~CNTException
//
// Routine Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CNTException::~CNTException(void)
{
} //*** CNTException::~CNTException()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CNTException::GetErrorMessage
//
// Routine Description:
// Get the error message represented by the exception.
//
// Arguments:
// lpszError [OUT] String in which to return the error message.
// nMaxError [IN] Maximum length of the output string.
// pnHelpContext [OUT] Help context for the error message.
//
// Return Value:
// TRUE Message available.
// FALSE No message available.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CNTException::GetErrorMessage(
LPTSTR lpszError,
UINT nMaxError,
PUINT pnHelpContext
)
{
DWORD dwResult;
TCHAR szNtMsg[128];
// Format the NT status code from the system.
dwResult = ::FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
m_sc,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
szNtMsg,
sizeof(szNtMsg) / sizeof(TCHAR),
0
);
if (dwResult == 0)
{
// Format the NT status code from NTDLL since this hasn't been
// integrated into the system yet.
dwResult = ::FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
::GetModuleHandle(_T("NTDLL.DLL")),
m_sc,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
szNtMsg,
sizeof(szNtMsg) / sizeof(TCHAR),
0
);
if (dwResult == 0)
{
TCHAR szErrorFmt[EXCEPT_MAX_OPER_ARG_LENGTH];
dwResult = ::LoadString(AfxGetApp()->m_hInstance, IDS_UNKNOWN_ERROR, szErrorFmt, (sizeof(szErrorFmt) / sizeof(TCHAR)));
ASSERT(dwResult != 0);
::_sntprintf(szNtMsg, sizeof(szNtMsg) / sizeof(TCHAR), szErrorFmt, m_sc, m_sc);
} // if: error formatting status code from NTDLL
} // if: error formatting status code from system
// Format the message with the operation string.
FormatWithOperation(lpszError, nMaxError, szNtMsg);
return TRUE;
} //*** CNTException::GetErrorMessage()
//***************************************************************************
/////////////////////////////////////////////////////////////////////////////
// Global Functions
/////////////////////////////////////////////////////////////////////////////
static CNTException gs_nte(ERROR_SUCCESS, NULL, NULL, NULL, FALSE);
static CExceptionWithOper gs_ewo(NULL, NULL, NULL, FALSE);
/////////////////////////////////////////////////////////////////////////////
//++
//
// ThrowStaticException
//
// Purpose:
// Throw the static NT Exception.
//
// Arguments:
// sc [IN] NT status code.
// idsOperation [IN] String ID for operation occurring during exception.
// pszOperArg1 [IN] 1st argument to operation string.
// pszOperArg2 [IN] 2nd argument to operation string.
//
// Returns:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void ThrowStaticException(
IN SC sc,
IN IDS idsOperation,
IN LPCTSTR pszOperArg1,
IN LPCTSTR pszOperArg2
)
{
gs_nte.SetOperation(sc, idsOperation, pszOperArg1, pszOperArg2);
TraceError(gs_nte);
throw &gs_nte;
} //*** ThrowStaticException()
/////////////////////////////////////////////////////////////////////////////
//++
//
// ThrowStaticException
//
// Purpose:
// Throw the static Cluster Administrator Exception.
//
// Arguments:
// idsOperation [IN] String ID for operation occurring during exception.
// pszOperArg1 [IN] 1st argument to operation string.
// pszOperArg2 [IN] 2nd argument to operation string.
//
// Returns:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void ThrowStaticException(
IN IDS idsOperation,
IN LPCTSTR pszOperArg1,
IN LPCTSTR pszOperArg2
)
{
gs_ewo.SetOperation(idsOperation, pszOperArg1, pszOperArg2);
TraceError(gs_ewo);
throw &gs_ewo;
} //*** ThrowStaticException()