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.
310 lines
7.0 KiB
310 lines
7.0 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name :
|
|
customerror.cxx
|
|
|
|
Abstract:
|
|
Custom Error goo
|
|
|
|
Author:
|
|
Bilal Alam (balam) 10-Mar-2000
|
|
|
|
Environment:
|
|
Win32 - User Mode
|
|
|
|
Project:
|
|
ULW3.DLL
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
HRESULT
|
|
CUSTOM_ERROR_TABLE::FindCustomError(
|
|
USHORT StatusCode,
|
|
USHORT SubError,
|
|
BOOL * pfIsFile,
|
|
STRU * pstrError
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find the applicable custom error entry for a given status/subcode
|
|
|
|
Arguments:
|
|
|
|
StatusCode - Status code
|
|
SubError - sub error
|
|
pfIsFile - Set to TRUE if this is a file error
|
|
pstrError - Error path (URL or file)
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
LIST_ENTRY * pListEntry;
|
|
CUSTOM_ERROR_ENTRY * pCustomEntry = NULL;
|
|
BOOL fFound = FALSE;
|
|
HRESULT hr = NO_ERROR;
|
|
|
|
if ( pfIsFile == NULL ||
|
|
pstrError == NULL )
|
|
{
|
|
DBG_ASSERT( FALSE );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
for ( pListEntry = _ErrorListHead.Flink;
|
|
pListEntry != &_ErrorListHead;
|
|
pListEntry = pListEntry->Flink )
|
|
{
|
|
pCustomEntry = CONTAINING_RECORD( pListEntry,
|
|
CUSTOM_ERROR_ENTRY,
|
|
_listEntry );
|
|
DBG_ASSERT( pCustomEntry != NULL );
|
|
|
|
if ( pCustomEntry->_StatusCode == StatusCode )
|
|
{
|
|
if ( pCustomEntry->_SubError == SubError ||
|
|
pCustomEntry->_SubError == SUBERROR_WILDCARD )
|
|
{
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( fFound )
|
|
{
|
|
hr = pstrError->Copy( pCustomEntry->_strError );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
*pfIsFile = pCustomEntry->_fIsFile;
|
|
return NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
CUSTOM_ERROR_TABLE::BuildTable(
|
|
WCHAR * pszErrorList
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build custom error table from metabase
|
|
|
|
Arguments:
|
|
|
|
pszErrorList - Magic error MULTISZ
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
WCHAR * pszType;
|
|
WCHAR * pszSubError;
|
|
WCHAR * pszPath;
|
|
WCHAR * pszNewPath;
|
|
WCHAR cTemp;
|
|
USHORT StatusCode;
|
|
USHORT SubError;
|
|
BOOL fIsFile;
|
|
CUSTOM_ERROR_ENTRY* pNewEntry;
|
|
DWORD dwPathLength;
|
|
HRESULT hr = NO_ERROR;
|
|
|
|
for (;;)
|
|
{
|
|
//
|
|
// Get the status code
|
|
//
|
|
|
|
StatusCode = (USHORT) _wtoi( pszErrorList );
|
|
if ( StatusCode < 300 )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
goto Finished;
|
|
}
|
|
|
|
//
|
|
// Now convert the second parameter (the suberror) to a number.
|
|
//
|
|
|
|
pszSubError = wcschr( pszErrorList, L',' );
|
|
if ( pszSubError == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
goto Finished;
|
|
}
|
|
pszSubError++;
|
|
|
|
while ( SAFEIsSpace( *pszSubError ) )
|
|
{
|
|
pszSubError++;
|
|
}
|
|
|
|
//
|
|
// Either we have a specific sub error or a wildcard (any suberror)
|
|
//
|
|
|
|
if ( *pszSubError == L'*' )
|
|
{
|
|
SubError = SUBERROR_WILDCARD;
|
|
}
|
|
else
|
|
{
|
|
if ( !iswdigit( *pszSubError ) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
goto Finished;
|
|
}
|
|
|
|
SubError = (USHORT) _wtoi( pszSubError );
|
|
}
|
|
|
|
//
|
|
// Now find the comma that seperates the number and the type.
|
|
//
|
|
|
|
pszType = wcschr( pszSubError, L',' );
|
|
if ( pszType == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
goto Finished;
|
|
}
|
|
pszType++;
|
|
|
|
while ( SAFEIsSpace( *pszType ) )
|
|
{
|
|
pszType++;
|
|
}
|
|
|
|
// We found the end of ws. If this isn't an alphabetic character, it's
|
|
// an error. If it is, find the end of the alpha. chars.
|
|
|
|
if ( !iswalpha( *pszType ) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
goto Finished;
|
|
}
|
|
pszPath = pszType;
|
|
|
|
while ( iswalpha( *pszPath ) )
|
|
{
|
|
pszPath++;
|
|
}
|
|
|
|
cTemp = *pszPath;
|
|
*pszPath = L'\0';
|
|
|
|
//
|
|
// What type of custom error is this?
|
|
//
|
|
|
|
if ( !_wcsicmp( pszType, L"FILE" ) )
|
|
{
|
|
fIsFile = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (!_wcsicmp( pszType, L"URL" ) )
|
|
{
|
|
fIsFile = FALSE;
|
|
}
|
|
else
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
}
|
|
}
|
|
*pszPath = cTemp;
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Finished;
|
|
}
|
|
|
|
//
|
|
// Now find the comma that seperates the type from the URL/path.
|
|
//
|
|
|
|
pszPath = wcschr( pszPath, L',' );
|
|
if ( pszPath == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
goto Finished;
|
|
}
|
|
pszPath++;
|
|
|
|
while ( SAFEIsSpace( *pszPath ) )
|
|
{
|
|
pszPath++;
|
|
}
|
|
|
|
if ( *pszPath == '\0' )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
goto Finished;
|
|
}
|
|
|
|
dwPathLength = wcslen( pszPath ) + 1;
|
|
|
|
//
|
|
// OK. Now we can allocate a table entry
|
|
//
|
|
|
|
pNewEntry = new CUSTOM_ERROR_ENTRY;
|
|
if ( pNewEntry == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
|
goto Finished;
|
|
}
|
|
|
|
pNewEntry->_StatusCode = StatusCode;
|
|
pNewEntry->_SubError = SubError;
|
|
pNewEntry->_fIsFile = fIsFile;
|
|
|
|
hr = pNewEntry->_strError.Copy( pszPath );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
delete pNewEntry;
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Give more specific errors higher priority in lookup
|
|
//
|
|
|
|
if ( SubError == SUBERROR_WILDCARD )
|
|
{
|
|
InsertTailList( &_ErrorListHead, &pNewEntry->_listEntry );
|
|
}
|
|
else
|
|
{
|
|
InsertHeadList( &_ErrorListHead, &pNewEntry->_listEntry );
|
|
}
|
|
|
|
pszErrorList = pszPath + dwPathLength;
|
|
|
|
if ( *pszErrorList == L'\0' )
|
|
{
|
|
hr = NO_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
Finished:
|
|
return hr;
|
|
}
|