;; 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 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(Win32Error, NumberOfAcceptableErrors, VaListOfAcceptableErrors); } static bool @PrivateNamespace_IsHResultAcceptable( HRESULT HResult, SIZE_T NumberOfAcceptableErrors, va_list VaListOfAcceptableErrors ) { return ::@PrivateNamespace_IsErrorAcceptable(HResult, NumberOfAcceptableErrors, VaListOfAcceptableErrors); } @If(@MicrosoftInternal)( static bool @PrivateNamespace_IsNtStatusAcceptable( NTSTATUS NtStatus, SIZE_T NumberOfAcceptableErrors, va_list VaListOfAcceptableErrors ) { return ::@PrivateNamespace_IsErrorAcceptable(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 #include @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=