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.
500 lines
11 KiB
500 lines
11 KiB
;; Copyright Microsoft Corporation
|
|
;;
|
|
;; Module Name:
|
|
;;
|
|
;; winthrow.tpl
|
|
;;
|
|
;; Abstract:
|
|
;;
|
|
;; Author:
|
|
;;
|
|
;; July 2001 JayKrell
|
|
;;
|
|
;; Revision History:
|
|
;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
[Code]
|
|
TemplateName=winthrow_cpp
|
|
Begin=
|
|
@NoFormat(
|
|
|
|
//
|
|
// Microsoft Visual C++ 7.0 or higher required.
|
|
//
|
|
#if (defined(_MSC_VER) && _MSC_VER >= 1300 && defined(__cplusplus))
|
|
|
|
@If(@MicrosoftInternal)(
|
|
#include "winthrow_private.h"
|
|
)@Else(
|
|
#include "winthrow.h"
|
|
)
|
|
|
|
template <typename T>
|
|
bool
|
|
@PrivateNamespace_IsErrorAcceptable(
|
|
T Error,
|
|
SIZE_T NumberOfAcceptableErrors,
|
|
va_list VaListOfAcceptableErrors
|
|
)
|
|
{
|
|
while (NumberOfAcceptableErrors-- != 0)
|
|
{
|
|
const T AcceptableError = va_arg(VaListOfAcceptableErrors, DWORD);
|
|
if (Error == AcceptableError)
|
|
{
|
|
/* not consuming the whole va_list is not portable, but very common. */
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool
|
|
@PrivateNamespace_IsWin32ErrorAcceptable(
|
|
DWORD Win32Error,
|
|
SIZE_T NumberOfAcceptableErrors,
|
|
va_list VaListOfAcceptableErrors
|
|
)
|
|
{
|
|
return ::@PrivateNamespace_IsErrorAcceptable<DWORD>(Win32Error, NumberOfAcceptableErrors, VaListOfAcceptableErrors);
|
|
}
|
|
|
|
static bool
|
|
@PrivateNamespace_IsHResultAcceptable(
|
|
HRESULT HResult,
|
|
SIZE_T NumberOfAcceptableErrors,
|
|
va_list VaListOfAcceptableErrors
|
|
)
|
|
{
|
|
return ::@PrivateNamespace_IsErrorAcceptable<HRESULT>(HResult, NumberOfAcceptableErrors, VaListOfAcceptableErrors);
|
|
}
|
|
|
|
@If(@MicrosoftInternal)(
|
|
static bool
|
|
@PrivateNamespace_IsNtStatusAcceptable(
|
|
NTSTATUS NtStatus,
|
|
SIZE_T NumberOfAcceptableErrors,
|
|
va_list VaListOfAcceptableErrors
|
|
)
|
|
{
|
|
return ::@PrivateNamespace_IsErrorAcceptable<NTSTATUS>(NtStatus, NumberOfAcceptableErrors, VaListOfAcceptableErrors);
|
|
}
|
|
)
|
|
)
|
|
@Template(ImplementWinThrowIFunc)
|
|
@NL
|
|
@NL#endif // (defined(_MSC_VER) && _MSC_VER >= 1300 && defined(__cplusplus))
|
|
@NL
|
|
End=
|
|
|
|
[Code]
|
|
TemplateName=winthrow_h
|
|
Begin=
|
|
@NoFormat(
|
|
//
|
|
// Microsoft Visual C++ 7.0 or higher required.
|
|
//
|
|
#if (defined(_MSC_VER) && _MSC_VER >= 1300 && defined(__cplusplus))
|
|
|
|
#ifndef @HEADERjGUARD
|
|
#define @HEADERjGUARD
|
|
|
|
#pragma once
|
|
#include <stddef.h>
|
|
#include <stdarg.h>
|
|
@If(@MicrosoftInternal)(
|
|
#include "nt.h"
|
|
#include "ntrtl.h"
|
|
#include "nturtl.h"
|
|
)
|
|
#include "windows.h"
|
|
#include "ole2.h"
|
|
#include "commctrl.h"
|
|
#include "imagehlp.h"
|
|
#include "setupapi.h"
|
|
#include "wincrypt.h"
|
|
|
|
@If(@MicrosoftInternal)(
|
|
#if !defined(NT_INCLUDED)
|
|
typedef long NTSTATUS;
|
|
#endif
|
|
)
|
|
|
|
#if !defined(EXCEPTION_TYPE)
|
|
#define EXCEPTION_TYPE EXCEPTION_TYPE
|
|
|
|
class EXCEPTION_TYPE
|
|
{
|
|
typedef enum EType { etSuccess, etWin32Error, etHResult@If(@MicrosoftInternal)(, etNtStatus) } EType;
|
|
EType m_Type;
|
|
union
|
|
{
|
|
DWORD m_Win32Error;
|
|
HRESULT m_HResult;
|
|
@If(@MicrosoftInternal)(NTSTATUS m_NtStatus;)
|
|
};
|
|
|
|
//
|
|
// strawman, will be generated by genthunk
|
|
//
|
|
typedef enum ERichType { ertNone, ertCreateFile, ertReadFile } ERichType;
|
|
ERichType m_RichType;
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
WCHAR FileName[MAX_PATH];
|
|
} CreateFile;
|
|
struct
|
|
{
|
|
HANDLE Handle;
|
|
} ReadFile;
|
|
};
|
|
|
|
public:
|
|
EXCEPTION_TYPE() : m_Type(etSuccess), m_RichType(ertNone) { }
|
|
~EXCEPTION_TYPE() { }
|
|
|
|
DWORD GetWin32Error() const
|
|
{
|
|
//
|
|
// GetLastError sometimes returns HRESULTs, so we do too.
|
|
//
|
|
switch (m_Type)
|
|
{
|
|
case etSuccess:
|
|
return NO_ERROR;
|
|
case etWin32Error:
|
|
return m_Win32Error;
|
|
case etHResult:
|
|
if (HRESULT_FACILITY(m_HResult) == FACILITY_WIN32)
|
|
return HRESULT_CODE(m_HResult);
|
|
return m_HResult;
|
|
@If(@MicrosoftInternal)(
|
|
case etNtStatus:
|
|
return m_NtStatus;
|
|
)
|
|
}
|
|
}
|
|
|
|
DWORD GetHResult() const
|
|
{
|
|
switch (m_Type)
|
|
{
|
|
case etSuccess:
|
|
return NOERROR;
|
|
case etWin32Error:
|
|
return HRESULT_FROM_WIN32(m_Win32Error);
|
|
case etHResult:
|
|
return m_HResult;
|
|
@If(@MicrosoftInternal)(
|
|
case etNtStatus:
|
|
return HRESULT_FROM_NT(m_NtStatus);
|
|
)
|
|
}
|
|
}
|
|
|
|
@If(@MicrosoftInternal)(
|
|
NTSTATUS GetNtStatus() const
|
|
{
|
|
switch (m_Type)
|
|
{
|
|
case etSuccess:
|
|
return STATUS_SUCCESS;
|
|
case etWin32Error:
|
|
return HRESULT_FROM_WIN32(m_Win32Error);
|
|
case etHResult:
|
|
if (m_HResult & FACILITY_NT_BIT)
|
|
return (m_HResult & ~FACILITY_NT_BIT);
|
|
return m_HResult;
|
|
@If(@MicrosoftInternal)(
|
|
case etNtStatus:
|
|
return m_NtStatus;
|
|
)
|
|
}
|
|
})
|
|
|
|
//
|
|
// strawman, will be generated by genthunk
|
|
//
|
|
void InitCreateFileW(
|
|
IN DWORD Win32Error,
|
|
IN LPCWSTR lpFileName,
|
|
IN DWORD dwDesiredAccess,
|
|
IN DWORD dwShareMode,
|
|
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
IN DWORD dwCreationDisposition,
|
|
IN DWORD dwFlagsAndAttributes,
|
|
IN HANDLE hTemplateFile
|
|
)
|
|
{
|
|
this->InitWin32Error(Win32Error);
|
|
SIZE_T Length = ::lstrlenW(lpFileName);
|
|
if (Length >= MAX_PATH)
|
|
Length = MAX_PATH - 1;
|
|
CopyMemory(this->CreateFile.FileName, lpFileName, Length * sizeof(WCHAR));
|
|
this->CreateFile.FileName[Length] = 0;
|
|
this->m_RichType = ertCreateFile;
|
|
}
|
|
|
|
//
|
|
// strawman, will be generated by genthunk
|
|
//
|
|
void InitReadFile(
|
|
IN DWORD Win32Error,
|
|
IN HANDLE hFile,
|
|
OUT LPVOID lpBuffer,
|
|
IN DWORD nNumberOfBytesToRead,
|
|
OUT LPDWORD lpNumberOfBytesRead,
|
|
IN LPOVERLAPPED lpOverlapped
|
|
)
|
|
{
|
|
this->InitWin32Error(Win32Error);
|
|
this->ReadFile.Handle = hFile;
|
|
this->m_RichType = ertReadFile;
|
|
}
|
|
|
|
void InitWin32Error(DWORD Win32Error)
|
|
{
|
|
this->m_Type = etWin32Error;
|
|
this->m_Win32Error = Win32Error;
|
|
}
|
|
|
|
void InitHResult(HRESULT HResult)
|
|
{
|
|
this->m_Type = etHResult;
|
|
this->m_HResult = HResult;
|
|
}
|
|
|
|
@If(@MicrosoftInternal)(
|
|
void InitNtStatus(NTSTATUS NtStatus)
|
|
{
|
|
this->m_Type = etNtStatus;
|
|
this->m_NtStatus = NtStatus;
|
|
})
|
|
|
|
void Throw() const
|
|
{
|
|
throw *this;
|
|
}
|
|
};
|
|
#endif // EXCEPTION_TYPE
|
|
|
|
)
|
|
@Template(DeclareWinThrowIFunc)
|
|
|
|
@NL#endif // @HEADERjGUARD
|
|
@NL#endif // (defined(_MSC_VER) && _MSC_VER >= 1300 && defined(__cplusplus))
|
|
@NL
|
|
End=
|
|
|
|
[Macros]
|
|
TemplateName=ImplementWinThrowMacro
|
|
Begin=
|
|
@DeclareUnlessVa()@NL
|
|
@ImplementUnlessVa@NL@NL
|
|
@DeclareSameSignature()@NL
|
|
@ImplementSameSignature@NL@NL
|
|
@DeclareUnlessDots()@NL
|
|
@ImplementUnlessDots@NL@NL
|
|
End=
|
|
|
|
[IFunc]
|
|
TemplateName=ImplementWinThrowIFunc
|
|
Begin=
|
|
@If(@And(@Not(@DoesApiReturnVoid), @IsApiDeclared))(
|
|
@ImplementWinThrowMacro
|
|
)@Else(
|
|
/* @ApiName skipped */@NL@NL
|
|
)
|
|
End=
|
|
|
|
[Macros]
|
|
TemplateName=DeclareWinThrowMacro
|
|
Begin=
|
|
@DeclareUnlessVa(;)@NL@NL
|
|
@DeclareSameSignature(;)@NL@NL
|
|
@DeclareUnlessDots(;)@NL@NL
|
|
End=
|
|
|
|
[IFunc]
|
|
TemplateName=DeclareWinThrowIFunc
|
|
Begin=
|
|
@If(@And(@Not(@DoesApiReturnVoid), @IsApiDeclared))(
|
|
@DeclareWinThrowMacro
|
|
)@Else(
|
|
/* @ApiName skipped */@NL@NL
|
|
)
|
|
End=
|
|
|
|
[Macros]
|
|
TemplateName=ArgsOut
|
|
Begin=
|
|
@ArgList(@ArgName@ArgMore(,))
|
|
End=
|
|
|
|
TemplateName=ArgsOutNL
|
|
Begin=
|
|
@ArgList(@ArgName@ArgMore(,@NL))
|
|
End=
|
|
|
|
TemplateName=ArgsIn
|
|
Begin=
|
|
@ArgList(@ArgMod @ArgType @ArgName@ArgMore(,))
|
|
End=
|
|
|
|
TemplateName=ArgsInNL
|
|
Begin=
|
|
@ArgList(@ArgMod @ArgType @ArgName@ArgMore(,@NL))
|
|
End=
|
|
|
|
TemplateName=DeclareSameSignature
|
|
NumArgs=1
|
|
Begin=
|
|
@NewReturnTypeMacro @ApiFnMod @SameSignatureName(@Indent(@NL
|
|
@ArgsInNL))@MArg(1)
|
|
End=
|
|
|
|
[Macros]
|
|
TemplateName=ImplementSameSignature
|
|
Begin=
|
|
{@Indent(@NL
|
|
@DeclareLocalErrorOut
|
|
@IFNewReturnTypeNotVoidMacro(return) ::@UnlessVaName(@Indent(@NL@IfArgs(@ArgsOutNL,@NL)
|
|
@PassErrorOut
|
|
0,@NL
|
|
0));@NL
|
|
)}@NL
|
|
End=
|
|
|
|
TemplateName=DeclareUnlessVa
|
|
NumArgs=1
|
|
Begin=
|
|
@NewReturnTypeMacro @ApiFnMod @UnlessVaName(@Indent(@NL
|
|
@IfArgs(@ArgsInNL,@NL)
|
|
@DeclareErrorOut
|
|
SIZE_T NumberOfAcceptableErrors,@NL
|
|
va_list VaListOfAcceptableErrors))@MArg(1)
|
|
End=
|
|
|
|
TemplateName=ImplementUnlessVa
|
|
Begin=
|
|
{@Indent(@NL
|
|
@ClearErrorOut
|
|
@ApiFnRet const RetVal = ::@ApiName(@IfArgs(@NL@Indent(@ArgsOutNL)));@NL
|
|
@NL
|
|
if (@Failed)@NL
|
|
{@Indent(@NL
|
|
@SetErrorOut
|
|
if (!@IsErrorAcceptable)@NL
|
|
{@Indent(@NL
|
|
@ThrowError
|
|
)}@NL
|
|
)}@NL
|
|
@IFNewReturnTypeNotVoidMacro(return RetVal;@NL)
|
|
)}@NL
|
|
End=
|
|
|
|
TemplateName=DeclareUnlessDots
|
|
NumArgs=1
|
|
Begin=
|
|
@NewReturnTypeMacro __cdecl @UnlessDotsName(@Indent(@NL@IfArgs(@ArgsInNL,@NL)
|
|
@DeclareErrorOut
|
|
SIZE_T NumberOfAcceptableErrors,@NL
|
|
...))@MArg(1)
|
|
End=
|
|
|
|
[Macros]
|
|
TemplateName=ImplementUnlessDots
|
|
Begin=
|
|
{@Indent(@NL
|
|
va_list VaListOfAcceptableErrors;@NL
|
|
@NL
|
|
@ClearErrorOut
|
|
va_start(VaListOfAcceptableErrors, NumberOfAcceptableErrors);@NL
|
|
@NL
|
|
@IFNewReturnTypeNotVoidMacro(@ApiFnRet const RetVal =)::@UnlessVaName(@Indent(@NL@IfArgs(@ArgsOutNL,@NL)
|
|
@PassErrorOut
|
|
NumberOfAcceptableErrors,@NL
|
|
VaListOfAcceptableErrors));@NL
|
|
@NL
|
|
va_end(VaListOfAcceptableErrors);@NL
|
|
@NL
|
|
@IFNewReturnTypeNotVoidMacro(return RetVal;@NL)
|
|
)}@NL
|
|
End=
|
|
|
|
[Macros]
|
|
TemplateName=DeclareErrorOut
|
|
Begin=
|
|
@IfApiCode(DeclareErrorOut)@Else(@RetType(DeclareErrorOut))
|
|
End=
|
|
|
|
TemplateName=ClearErrorOut
|
|
Begin=
|
|
@IfApiCode(ClearErrorOut)@Else(@RetType(ClearErrorOut))
|
|
End=
|
|
|
|
TemplateName=ThrowError
|
|
Begin=
|
|
@IfApiCode(ThrowError)@Else(@RetType(ThrowError))
|
|
End=
|
|
|
|
TemplateName=IsErrorAcceptable
|
|
Begin=
|
|
@IfApiCode(IsErrorAcceptable)@Else(@RetType(IsErrorAcceptable))
|
|
End=
|
|
|
|
TemplateName=SetErrorOut
|
|
Begin=
|
|
@IfApiCode(SetErrorOut)@Else(@RetType(SetErrorOut))
|
|
End=
|
|
|
|
TemplateName=Failed
|
|
Begin=
|
|
@IfApiCode(Failed)@Else(@RetType(Failed))
|
|
End=
|
|
|
|
;;
|
|
;; This is a temporary for when SameSignature calls Unless(0);
|
|
;;
|
|
[Macros]
|
|
TemplateName=DeclareLocalErrorOut
|
|
Begin=
|
|
@IfApiCode(DeclareLocalErrorOut)@Else(@RetType(DeclareLocalErrorOut))
|
|
End=
|
|
|
|
[Macros]
|
|
TemplateName=PassErrorOut
|
|
Begin=
|
|
@IfApiCode(PassErrorOut)@Else(@RetType(PassErrorOut))
|
|
End=
|
|
|
|
;;
|
|
;; This code would change BOOL to void.
|
|
;;
|
|
;;TemplateName=NewReturnTypeMacro
|
|
;;Begin=
|
|
;;@IfRetType(BOOL,void)@Else(@ApiFnRet)
|
|
;;End=
|
|
;;
|
|
;;TemplateName=IFNewReturnTypeNotVoidMacro
|
|
;;NumArgs=1
|
|
;;Begin=
|
|
;;@IfRetType(BOOL,)@Else(@MArg(1))
|
|
;;End=
|
|
;;
|
|
;; This code just passed BOOL through unmodified.
|
|
;;
|
|
TemplateName=NewReturnTypeMacro
|
|
Begin=
|
|
@ApiFnRet
|
|
End=
|
|
|
|
TemplateName=IFNewReturnTypeNotVoidMacro
|
|
NumArgs=1
|
|
Begin=
|
|
@MArg(1)
|
|
End=
|