From 6ce3e358f5b043f632036e6d8a7109c2efb0349c Mon Sep 17 00:00:00 2001 From: Jon Galloway Date: Mon, 20 Jun 2016 18:25:17 -0700 Subject: [PATCH] Updated C code sample This code comes from the compiler-tests repo: https://github.com/Microsoft/compiler-tests/blob/master/seh/xcpt4u.c If there's a problem with that source for some reason, the Windows-driver-samples repo also has some C code: https://github.com/Microsoft/Windows-driver-samples/blob/master/network/modem/fakemodem/ioctl.c Fixes #11 --- website/index/samples/sample.c.txt | 3705 ++++++++++++++++++++++++++-- 1 file changed, 3461 insertions(+), 244 deletions(-) diff --git a/website/index/samples/sample.c.txt b/website/index/samples/sample.c.txt index cd8482fc..7f6fee8c 100644 --- a/website/index/samples/sample.c.txt +++ b/website/index/samples/sample.c.txt @@ -1,246 +1,3463 @@ -#include "pch.h" -#include "Direct3DBase.h" - -using namespace Microsoft::WRL; -using namespace Windows::UI::Core; -using namespace Windows::Foundation; - -// Constructor. -Direct3DBase::Direct3DBase() -{ -} - -// Initialize the Direct3D resources required to run. -void Direct3DBase::Initialize(CoreWindow^ window) -{ - m_window = window; - - CreateDeviceResources(); - CreateWindowSizeDependentResources(); -} - -// These are the resources that depend on the device. -void Direct3DBase::CreateDeviceResources() -{ - // This flag adds support for surfaces with a different color channel ordering than the API default. - // It is recommended usage, and is required for compatibility with Direct2D. - UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; - -#if defined(_DEBUG) - // If the project is in a debug build, enable debugging via SDK Layers with this flag. - creationFlags |= D3D11_CREATE_DEVICE_DEBUG; -#endif - - // This array defines the set of DirectX hardware feature levels this app will support. - // Note the ordering should be preserved. - // Don't forget to declare your application's minimum required feature level in its - // description. All applications are assumed to support 9.1 unless otherwise stated. - D3D_FEATURE_LEVEL featureLevels[] = - { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1 - }; - - // Create the DX11 API device object, and get a corresponding context. - ComPtr device; - ComPtr context; - DX::ThrowIfFailed( - D3D11CreateDevice( - nullptr, // specify null to use the default adapter - D3D_DRIVER_TYPE_HARDWARE, - nullptr, // leave as nullptr unless software device - creationFlags, // optionally set debug and Direct2D compatibility flags - featureLevels, // list of feature levels this app can support - ARRAYSIZE(featureLevels), // number of entries in above list - D3D11_SDK_VERSION, // always set this to D3D11_SDK_VERSION - &device, // returns the Direct3D device created - &m_featureLevel, // returns feature level of device created - &context // returns the device immediate context - ) - ); - - // Get the DirectX11.1 device by QI off the DirectX11 one. - DX::ThrowIfFailed( - device.As(&m_d3dDevice) - ); - - // And get the corresponding device context in the same way. - DX::ThrowIfFailed( - context.As(&m_d3dContext) - ); -} - -// Allocate all memory resources that change on a window SizeChanged event. -void Direct3DBase::CreateWindowSizeDependentResources() -{ - // Store the window bounds so the next time we get a SizeChanged event we can - // avoid rebuilding everything if the size is identical. - m_windowBounds = m_window->Bounds; - - // If the swap chain already exists, resize it. - if(m_swapChain != nullptr) - { - DX::ThrowIfFailed( - m_swapChain->ResizeBuffers(2, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0) - ); - } - // Otherwise, create a new one. - else - { - // Create a descriptor for the swap chain. - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; - swapChainDesc.Width = 0; // use automatic sizing - swapChainDesc.Height = 0; - swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format - swapChainDesc.Stereo = false; - swapChainDesc.SampleDesc.Count = 1; // don't use multi-sampling - swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 2; // use two buffers to enable flip effect - swapChainDesc.Scaling = DXGI_SCALING_NONE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // we recommend using this swap effect for all applications - swapChainDesc.Flags = 0; - - // Once the desired swap chain description is configured, it must be created on the same adapter as our D3D Device - - // First, retrieve the underlying DXGI Device from the D3D Device - ComPtr dxgiDevice; - DX::ThrowIfFailed( - m_d3dDevice.As(&dxgiDevice) - ); - - // Identify the physical adapter (GPU or card) this device is running on. - ComPtr dxgiAdapter; - DX::ThrowIfFailed( - dxgiDevice->GetAdapter(&dxgiAdapter) - ); - - // And obtain the factory object that created it. - ComPtr dxgiFactory; - DX::ThrowIfFailed( - dxgiAdapter->GetParent( - __uuidof(IDXGIFactory2), - &dxgiFactory - ) - ); - - Windows::UI::Core::CoreWindow^ p = m_window.Get(); - - // Create a swap chain for this window from the DXGI factory. - DX::ThrowIfFailed( - dxgiFactory->CreateSwapChainForCoreWindow( - m_d3dDevice.Get(), - reinterpret_cast(p), - &swapChainDesc, - nullptr, // allow on all displays - &m_swapChain - ) - ); - - // Ensure that DXGI does not queue more than one frame at a time. This both reduces - // latency and ensures that the application will only render after each VSync, minimizing - // power consumption. - DX::ThrowIfFailed( - dxgiDevice->SetMaximumFrameLatency(1) - ); - } - - // Obtain the backbuffer for this window which will be the final 3D rendertarget. - ComPtr backBuffer; - DX::ThrowIfFailed( - m_swapChain->GetBuffer( - 0, - __uuidof(ID3D11Texture2D), - &backBuffer - ) - ); - - // Create a view interface on the rendertarget to use on bind. - DX::ThrowIfFailed( - m_d3dDevice->CreateRenderTargetView( - backBuffer.Get(), - nullptr, - &m_renderTargetView - ) - ); - - // Cache the rendertarget dimensions in our helper class for convenient use. - D3D11_TEXTURE2D_DESC backBufferDesc; - backBuffer->GetDesc(&backBufferDesc); - m_renderTargetSize.Width = static_cast(backBufferDesc.Width); - m_renderTargetSize.Height = static_cast(backBufferDesc.Height); - - // Create a descriptor for the depth/stencil buffer. - CD3D11_TEXTURE2D_DESC depthStencilDesc( - DXGI_FORMAT_D24_UNORM_S8_UINT, - backBufferDesc.Width, - backBufferDesc.Height, - 1, - 1, - D3D11_BIND_DEPTH_STENCIL); - - // Allocate a 2-D surface as the depth/stencil buffer. - ComPtr depthStencil; - DX::ThrowIfFailed( - m_d3dDevice->CreateTexture2D( - &depthStencilDesc, - nullptr, - &depthStencil - ) - ); - - // Create a DepthStencil view on this surface to use on bind. - DX::ThrowIfFailed( - m_d3dDevice->CreateDepthStencilView( - depthStencil.Get(), - &CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D), - &m_depthStencilView - ) - ); - - // Create a viewport descriptor of the full window size. - CD3D11_VIEWPORT viewPort( - 0.0f, - 0.0f, - static_cast(backBufferDesc.Width), - static_cast(backBufferDesc.Height) - ); - - // Set the current viewport using the descriptor. - m_d3dContext->RSSetViewports(1, &viewPort); -} - -void Direct3DBase::UpdateForWindowSizeChange() -{ - if (m_window->Bounds.Width != m_windowBounds.Width || - m_window->Bounds.Height != m_windowBounds.Height) - { - m_renderTargetView = nullptr; - m_depthStencilView = nullptr; - CreateWindowSizeDependentResources(); - } -} - -void Direct3DBase::Present() -{ - // The first argument instructs DXGI to block until VSync, putting the application - // to sleep until the next VSync. This ensures we don't waste any cycles rendering - // frames that will never be displayed to the screen. - HRESULT hr = m_swapChain->Present(1, 0); - - // If the device was removed either by a disconnect or a driver upgrade, we - // must completely reinitialize the renderer. - if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) - { - Initialize(m_window.Get()); - } - else - { - DX::ThrowIfFailed(hr); +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full +// license information. + +/* + * COMMAND LINE: -Ox -Gz -YX -UPROTOTYPES_REQUIRED + */ + +#pragma warning(disable : 4532) +#pragma warning(disable : 4702) + +#if defined(_WIN32) + +#if defined(_M_SH) +#define WIN_CE +#endif + +#if defined(_M_AMD64) +#define NEST_IN_FINALLY /* allow when __try nested in __finally OK */ +#endif + +#define NTSTATUS LONG +#define EXCEPTION_NESTED_CALL 0x10 +#define RtlRaiseStatus(x) RaiseException((x), 0, 0, NULL) +#define RtlRaiseException(x) \ + RaiseException((x)->ExceptionCode, (x)->ExceptionFlags, \ + (x)->NumberParameters, (x)->ExceptionInformation) +#define IN +#define OUT +#if !(defined(_M_IA64) || defined(_M_ALPHA) || defined(_M_PPC) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64)) +#define i386 1 +#endif +#define try __try +#define except __except +#define finally __finally +#define leave __leave + +#endif + +#define WIN32_LEAN_AND_MEAN + +#include "stdio.h" +#if defined(_M_IA64) || defined(_M_ALPHA) || defined(_M_PPC) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64) +#include "setjmpex.h" +#else +#include "setjmp.h" +#endif +#include "float.h" +#include "windows.h" +#include "math.h" + +#if !defined(STATUS_SUCCESS) +#define STATUS_SUCCESS 0 +#endif +#if !defined(STATUS_UNSUCCESSFUL) +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) +#endif + +// +// Define switch constants. +// + +#define BLUE 0 +#define RED 1 + +// +// Define function prototypes. +// + +VOID addtwo(IN LONG First, IN LONG Second, IN PLONG Place); + +VOID bar1(IN NTSTATUS Status, IN PLONG Counter); + +VOID bar2(IN PLONG BlackHole, IN PLONG BadAddress, IN PLONG Counter); + +VOID dojump(IN jmp_buf JumpBuffer, IN PLONG Counter); + +LONG Echo(IN LONG Value); + +#if !defined(WIN_CE) // return through finally not allowed on WinCE +VOID eret(IN NTSTATUS Status, IN PLONG Counter); +#endif + +VOID except1(IN PLONG Counter); + +ULONG +except2(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter); + +ULONG +except3(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter); + +VOID foo1(IN NTSTATUS Status); + +VOID foo2(IN PLONG BlackHole, IN PLONG BadAddress); + +#if !defined(WIN_CE) // return from finally not allowed on WinCE +VOID fret(IN PLONG Counter); +#endif + +BOOLEAN +Tkm(VOID); + +VOID Test61Part2(IN OUT PULONG Counter); + +double SquareDouble(IN double op); + +DECLSPEC_NOINLINE +ULONG +PgFilter(VOID) + +{ + + printf("filter entered..."); + return EXCEPTION_EXECUTE_HANDLER; +} + +#pragma warning(push) +#pragma warning(disable : 4532) + +VOID PgTest69(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 1) { + *State += 1; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 1) == 1) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { + if (*State != 2) { + *Fault += 1; + } + } + + return; +} + +VOID PgTest70(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 2) { + PgFilter(); + return; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 2) == 2) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest71(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 3) { + *State += 3; + return; + + } else { + *Fault += 1; + } + } + } + } + finally { + if (AbnormalTermination()) { + if (*State == 6) { + *State += 3; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 3) == 3) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest72(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 4) { + *State += 4; + return; + + } else { + *Fault += 1; + } + } + } + } + finally { + if (AbnormalTermination()) { + if (*State == 8) { + *State += 4; + PgFilter(); + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 4) == 4) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest73(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 5) { + *State += 5; + + } else { + *Fault += 1; + } + } + } + } + finally { + if (AbnormalTermination()) { + if (*State == 10) { + *State += 5; + return; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 5) == 5) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest74(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 6) { + *State += 6; + + } else { + *Fault += 1; + } + } + } + } + finally { + if (AbnormalTermination()) { + if (*State == 12) { + *State += 6; + PgFilter(); + return; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 6) == 6) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest75(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 7) { + *State += 7; + *Fault += 1; + + } else { + *State += 10; + } + } + } + } + except(((*State += 7) == 7) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + } + finally { + if (AbnormalTermination()) { + if (*State == 28) { + *State += 7; + return; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 7) == 28) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest76(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 8) { + *State += 8; + *Fault += 1; + + } else { + *State += 10; + } + } + } + } + except(((*State += 8) == 8) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + } + finally { + if (AbnormalTermination()) { + if (*State == 32) { + *State += 8; + PgFilter(); + return; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 8) == 32) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest77(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 9) { + *State += 9; + *Fault += 1; + + } else { + *State += 10; + } + } + } + } + except(((*State += 9) == 9) ? PgFilter() : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + } + finally { + if (AbnormalTermination()) { + if (*State == 36) { + *State += 9; + return; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 9) == 36) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +VOID PgTest78(IN PLONG State, IN PLONG Fault) + +{ + + try { + try { + try { + try { + *Fault += 1; + } + finally { + if (AbnormalTermination()) { + if (*State == 10) { + *State += 10; + PgFilter(); + *Fault += 1; + + } else { + *State += 10; + } + } + } + } + except(((*State += 10) == 10) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + } + finally { + if (AbnormalTermination()) { + if (*State == 40) { + *State += 10; + return; + + } else { + *Fault += 1; + } + } + } + } + except(((*State += 10) == 40) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + + return; +} + +#pragma warning(pop) + +VOID Test79(PLONG Counter, PLONG Fault) + +{ + + try { + try { + try { + *Fault += 1; + } + finally { + printf("finally 1..."); + *Fault += 1; + } + } + finally { printf("finally 2..."); } + } + except(*Counter += 1, printf("filter 1..."), EXCEPTION_CONTINUE_SEARCH) {} + + return; +} + +ULONG G; + +ULONG +Test80(VOID) + +{ + + G = 1; + try { + while (G) { + try { + if (G == 10) { + return 1; + } + + if (G == 1) { + continue; + } + } + finally { G = 0; } + } + } + finally { G = 10; } + + return 0; +} + +void Test81(int *pCounter) { + volatile char *AvPtr = NULL; + + __try { + __try { *AvPtr = '\0'; } + __except(EXCEPTION_EXECUTE_HANDLER) { __leave; } + } + __finally { + printf("in finally "); + *pCounter += 1; + } + return; +} + +DECLSPEC_NOINLINE +VOID Test82Foo(VOID) + +{ + *(volatile int *)0 = 0; +} + +VOID Test82(__inout PLONG Counter) + +{ + + int retval = 1; + + __try { + __try { Test82Foo(); } + __finally { + switch (*Counter) { + case 0: + printf("something failed!\n"); + retval = 6; + break; + + case 1: + retval = 0; + break; + + case 2: + printf("how did you get here?\n"); + retval = 2; + break; + + case 3: + printf("what?!?\n"); + retval = 3; + break; + + case 4: + printf("not correct\n"); + retval = 4; + break; + + case 5: + printf("error!\n"); + retval = 5; + break; + } + } + } + __except(1){} + + *Counter = retval; + return; +} + +LONG Test83(VOID) + +{ + + G = 1; + try { + try { + while (G) { + try { + if (G == 10) { + return 1; + } + + if (G == 1) { + continue; + } + } + finally { G = 0; } + } + } + except(EXCEPTION_EXECUTE_HANDLER) { leave; } + } + finally { G = 10; } + + return 0; +} + +DECLSPEC_NOINLINE +VOID Test84(_Inout_ PLONG Counter) + +{ + volatile int *Fault = 0; + + try { + try { + *Fault += 1; + } + except(EXCEPTION_EXECUTE_HANDLER) { + try { + return; + } + finally { *Counter += 1; } + } + } + finally { + + if (AbnormalTermination()) { + *Counter += 1; + } + } + + return; +} + +DECLSPEC_NOINLINE +LONG Test85(_Inout_ PLONG Counter) + +{ + volatile int *Fault = 0; + + G = 1; + try { + try { + try { + while (G) { + try { + try { + if (G == 10) { + return 1; + } + try { + *Counter += 1; + } + except(EXCEPTION_EXECUTE_HANDLER) {} + + if (G == 1) { + continue; + } + } + finally { + G = 0; + *Counter += 1; + *Fault += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { + *Counter += 1; + leave; + } + } + } + finally { + G = 10; + *Counter += 1; + *Fault += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { *Counter += 1; } + *Counter += 1; + } + finally { *Counter += 1; } + return 1; +} + +DECLSPEC_NOINLINE +VOID Test86(_Inout_ PLONG Counter) + +{ + volatile int *Fault = 0; + + try { + try { + try { + try { + try { + try { + *Fault += 1; + } + except(printf("Filter1 %d..", *Counter), + EXCEPTION_EXECUTE_HANDLER) { + try { + printf("Handler1 %d..", *Counter); + return; + } + finally { + printf("Finally1 %d..", *Counter); + *Counter += 1; + } + } + } + finally { + printf("Finally2 %d..", *Counter); + *Counter += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { leave; } + } + finally { *Counter += 1; } + } + except(EXCEPTION_EXECUTE_HANDLER) { leave; } + } + finally { *Counter += 1; } + + return; +} + +VOID Test87(_Inout_ PLONG Counter) + +/*++ + +Routine Description: + + This function verifies the behavior of nested exception dispatching. + +Arguments: + + Counter - Supplies a pointer to the state counter. + +Return Value: + None. + +--*/ + +{ + volatile int *Fault = 0; + +// +// N.B. Disabled on x86 due to failing test case with handling of returns +// in nested termination handlers on x86. +// +// Disabled on ARM due to failing test case with handling of abutting +// termination handlers within an except handler. +// +// Disabled on AMD64 due to failing test case with handling of +// abutting termination handlers within an except handler when a +// non-local goto is involved. +// + +#if !defined(_X86_) + try { + try { + try { + try { + try { + *Fault += 1; + + try { + } + finally { + if (AbnormalTermination()) { + *Fault += 1; + } + } + } + finally { + + if (AbnormalTermination()) { + if ((*Counter += 13) == 26) { + return; + + } else { + *Fault += 1; + } + } + } + } + finally { + if (AbnormalTermination()) { + *Counter += 13; + *Fault += 1; + } + } + } + except(((*Counter += 13) == 13) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Fault += 1; + } + } + except(((*Counter += 13) == 65) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + try { + *Counter += 13; + return; + } + finally { + if (AbnormalTermination()) { + *Counter += 13; + goto Finish; + } + } + } + } + finally { + + if (AbnormalTermination()) { + if ((*Counter += 13) == 104) { + goto Finish; + } + } + } + +Finish: +#else + *Counter = 104; +#endif + + return; +} + +VOID Test88(_Inout_ PLONG Counter) + +{ + volatile int *Fault = 0; + + try { + try { + try { + try { + try { + try { + try { + try { + *Fault += 1; + } + except(((*Counter += 1) == 1) ? *Fault + : EXCEPTION_CONTINUE_SEARCH) {} + } + except(*Counter += 1, EXCEPTION_EXECUTE_HANDLER) { *Fault += 2; } + } + except(*Counter += 1, EXCEPTION_CONTINUE_SEARCH) { leave; } + } + except(*Counter += 1, EXCEPTION_CONTINUE_SEARCH) { leave; } + } + except(EXCEPTION_EXECUTE_HANDLER) {} + } + except(EXCEPTION_EXECUTE_HANDLER) {} + } + except(EXCEPTION_EXECUTE_HANDLER) { leave; } + } + finally { *Counter += 1; } +} + +int main(int argc, char *argv[]) + +{ + + PLONG BadAddress; + PCHAR BadByte; + PLONG BlackHole; + ULONG Index1; + ULONG Index2 = RED; + jmp_buf JumpBuffer; + LONG Counter; + EXCEPTION_RECORD ExceptionRecord; + double doubleresult; + + // + // Announce start of exception test. + // + + printf("Start of exception test\n"); + + // + // Initialize exception record. + // + + ExceptionRecord.ExceptionCode = STATUS_INTEGER_OVERFLOW; + ExceptionRecord.ExceptionFlags = 0; + ExceptionRecord.ExceptionRecord = NULL; + ExceptionRecord.NumberParameters = 0; + + // + // Initialize pointers. + // + + BadAddress = (PLONG)NULL; + BadByte = (PCHAR)NULL; + BadByte += 1; + BlackHole = &Counter; + + // + // Simply try statement with a finally clause that is entered sequentially. + // + + printf(" test1..."); + Counter = 0; + try { + Counter += 1; + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 1; + } + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try statement with an exception clause that is never executed + // because there is no exception raised in the try clause. + // + + printf(" test2..."); + Counter = 0; + try { + Counter += 1; + } + except(Counter) { Counter += 1; } + + if (Counter != 1) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try statement with an exception handler that is never executed + // because the exception expression continues execution. + // + + printf(" test3..."); + Counter = 0; + try { + Counter -= 1; + RtlRaiseException(&ExceptionRecord); + } + except(Counter) { Counter -= 1; } + + if (Counter != -1) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try statement with an exception clause that is always executed. + // + + printf(" test4..."); + Counter = 0; + try { + Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + except(Counter) { Counter += 1; } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try statement with an exception clause that is always executed. + // + + printf(" test5..."); + Counter = 0; + try { + Counter += 1; + *BlackHole += *BadAddress; + } + except(Counter) { Counter += 1; } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simply try statement with a finally clause that is entered as the + // result of an exception. + // + + printf(" test6..."); + Counter = 0; + try { + try { + Counter += 1; + RtlRaiseException(&ExceptionRecord); + } + finally { + if (abnormal_termination() != FALSE) { + Counter += 1; + } + } + } + except(Counter) { + if (Counter == 2) { + Counter += 1; + } + } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simply try statement with a finally clause that is entered as the + // result of an exception. + // + + printf(" test7..."); + Counter = 0; + try { + try { + Counter += 1; + *BlackHole += *BadAddress; + } + finally { + if (abnormal_termination() != FALSE) { + Counter += 1; + } + } + } + except(Counter) { + if (Counter == 2) { + Counter += 1; + } + } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try that calls a function which raises an exception. + // + + printf(" test8..."); + Counter = 0; + try { + Counter += 1; + foo1(STATUS_ACCESS_VIOLATION); + } + except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter += 1; + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try that calls a function which raises an exception. + // + + printf(" test9..."); + Counter = 0; + try { + Counter += 1; + foo2(BlackHole, BadAddress); + } + except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter += 1; + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try that calls a function which calls a function that + // raises an exception. The first function has a finally clause + // that must be executed for this test to work. + // + + printf(" test10..."); + Counter = 0; + try { + bar1(STATUS_ACCESS_VIOLATION, &Counter); + } + except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter -= 1; + } + + if (Counter != 98) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try that calls a function which calls a function that + // raises an exception. The first function has a finally clause + // that must be executed for this test to work. + // + + printf(" test11..."); + Counter = 0; + try { + bar2(BlackHole, BadAddress, &Counter); + } + except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter -= 1; + } + + if (Counter != 98) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A try within an except + // + + printf(" test12..."); + Counter = 0; + try { + foo1(STATUS_ACCESS_VIOLATION); + } + except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter += 1; + try { + foo1(STATUS_SUCCESS); + } + except((GetExceptionCode() == STATUS_SUCCESS) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + if (Counter != 1) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded..."); + } + + Counter += 1; + } + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A try within an except + // + + printf(" test13..."); + Counter = 0; + try { + foo2(BlackHole, BadAddress); + } + except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter += 1; + try { + foo1(STATUS_SUCCESS); + } + except((GetExceptionCode() == STATUS_SUCCESS) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + if (Counter != 1) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded..."); + } + + Counter += 1; + } + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // gotos from except/finally not allowed on WinCE + // + // A goto from an exception clause that needs to pass + // through a finally + // + + printf(" test14..."); + Counter = 0; + try { + try { + foo1(STATUS_ACCESS_VIOLATION); + } + except((GetExceptionCode() == STATUS_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter += 1; + goto t9; + } + } + finally { Counter += 1; } + +t9: + ; + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A goto from an finally clause that needs to pass + // through a finally + // + + printf(" test15..."); + Counter = 0; + try { + try { + Counter += 1; + } + finally { + Counter += 1; + goto t10; + } + } + finally { Counter += 1; } + +t10: + ; + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A goto from an exception clause that needs to pass + // through a finally into the outer finally clause. + // + + printf(" test16..."); + Counter = 0; + try { + try { + try { + Counter += 1; + foo1(STATUS_INTEGER_OVERFLOW); + } + except(EXCEPTION_EXECUTE_HANDLER) { + Counter += 1; + goto t11; + } + } + finally { Counter += 1; } + t11: + ; + } + finally { Counter += 1; } + + if (Counter != 4) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A goto from an finally clause that needs to pass + // through a finally into the outer finally clause. + // + + printf(" test17..."); + Counter = 0; + try { + try { + Counter += 1; + } + finally { + Counter += 1; + goto t12; + } + t12: + ; + } + finally { Counter += 1; } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A return from an except clause + // + + printf(" test18..."); + Counter = 0; + try { + Counter += 1; + eret(STATUS_ACCESS_VIOLATION, &Counter); + } + finally { Counter += 1; } + + if (Counter != 4) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A return from a finally clause + // + + printf(" test19..."); + Counter = 0; + try { + Counter += 1; + fret(&Counter); + } + finally { Counter += 1; } + + if (Counter != 5) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // A simple set jump followed by a long jump. + // + + printf(" test20..."); + Counter = 0; + if (setjmp(JumpBuffer) == 0) { + Counter += 1; + longjmp(JumpBuffer, 1); + + } else { + Counter += 1; + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A set jump followed by a long jump out of a finally clause that is + // sequentially executed. + // + + printf(" test21..."); + Counter = 0; + if (setjmp(JumpBuffer) == 0) { + try { + Counter += 1; + } + finally { + Counter += 1; + longjmp(JumpBuffer, 1); + } + + } else { + Counter += 1; + } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A set jump within a try clause followed by a long jump out of a + // finally clause that is sequentially executed. + // + + printf(" test22..."); + Counter = 0; + try { + if (setjmp(JumpBuffer) == 0) { + Counter += 1; + + } else { + Counter += 1; + } + } + finally { + Counter += 1; + if (Counter == 2) { + Counter += 1; + longjmp(JumpBuffer, 1); + } + } + + if (Counter != 5) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A set jump followed by a try/except, followed by a try/finally where + // the try body of the try/finally raises an exception that is handled + // by the try/excecpt which causes the try/finally to do a long jump out + // of a finally clause. This will create a collided unwind. + // + + printf(" test23..."); + Counter = 0; + if (setjmp(JumpBuffer) == 0) { + try { + try { + Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + finally { + Counter += 1; + longjmp(JumpBuffer, 1); + } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } + + } else { + Counter += 1; + } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A set jump followed by a try/except, followed by a several nested + // try/finally's where the inner try body of the try/finally raises an + // exception that is handled by the try/except which causes the + // try/finally to do a long jump out of a finally clause. This will + // create a collided unwind. + // + + printf(" test24..."); + Counter = 0; + if (setjmp(JumpBuffer) == 0) { + try { + try { + try { + try { + Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + finally { Counter += 1; } + } + finally { + Counter += 1; + longjmp(JumpBuffer, 1); + } + } + finally { Counter += 1; } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } + + } else { + Counter += 1; + } + + if (Counter != 5) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A set jump followed by a try/except, followed by a try/finally which + // calls a subroutine which contains a try finally that raises an + // exception that is handled to the try/except. + // + + printf(" test25..."); + Counter = 0; + if (setjmp(JumpBuffer) == 0) { + try { + try { + try { + Counter += 1; + dojump(JumpBuffer, &Counter); + } + finally { Counter += 1; } + } + finally { Counter += 1; } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } + + } else { + Counter += 1; + } + + if (Counter != 7) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A set jump followed by a try/except, followed by a try/finally which + // calls a subroutine which contains a try finally that raises an + // exception that is handled to the try/except. + // + + printf(" test26..."); + Counter = 0; + if (setjmp(JumpBuffer) == 0) { + try { + try { + try { + try { + Counter += 1; + dojump(JumpBuffer, &Counter); + } + finally { Counter += 1; } + } + finally { + Counter += 1; + longjmp(JumpBuffer, 1); + } + } + finally { Counter += 1; } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } + + } else { + Counter += 1; + } + + if (Counter != 8) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Test nested exceptions. + // + + printf(" test27..."); + Counter = 0; + try { + try { + Counter += 1; + except1(&Counter); + } + except(except2(GetExceptionInformation(), &Counter)) { Counter += 2; } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 3; } + + if (Counter != 55) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Simple try that causes an integer overflow exception. + // + + printf(" test28..."); + Counter = 0; + try { + Counter += 1; + addtwo(0x7fff0000, 0x10000, &Counter); + } + except((GetExceptionCode() == STATUS_INTEGER_OVERFLOW) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter += 1; + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +// +// Simple try that raises an misaligned data exception. +// +#if !defined(i386) && !defined(_M_IA64) && !defined(_M_AMD64) && \ + !defined(_M_ARM) && !defined(_M_ARM64) + printf(" test29..."); + Counter = 0; + try { + Counter += 1; + foo2(BlackHole, (PLONG)BadByte); + } + except((GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) + ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + Counter += 1; + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#endif + // + // Continue from a try body with an exception clause in a loop. + // + + printf(" test30..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + if ((Index1 & 0x1) == 0) { + continue; + + } else { + Counter += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 40; } + + Counter += 2; + } + + if (Counter != 15) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE + // + // Continue from a try body with an finally clause in a loop. + // + + printf(" test31..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + if ((Index1 & 0x1) == 0) { + continue; + + } else { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 3; + } + + if (Counter != 40) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // Continue from doubly nested try body with an exception clause in a + // loop. + // + + printf(" test32..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 0) { + continue; + + } else { + Counter += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } + + Counter += 2; + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 20; } + + Counter += 3; + } + + if (Counter != 30) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE + // + // Continue from doubly nested try body with an finally clause in a loop. + // + + printf(" test33..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 0) { + continue; + + } else { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 3; + } + finally { Counter += 4; } + + Counter += 5; + } + + if (Counter != 105) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Continue from a finally clause in a loop. + // + + printf(" test34..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + if ((Index1 & 0x1) == 0) { + Counter += 1; + } + } + finally { + Counter += 2; + continue; + } + + Counter += 4; + } + + if (Counter != 25) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Continue from a doubly nested finally clause in a loop. + // + + printf(" test35..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 0) { + Counter += 1; + } + } + finally { + Counter += 2; + continue; + } + + Counter += 4; + } + finally { Counter += 5; } + + Counter += 6; + } + + if (Counter != 75) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Continue from a doubly nested finally clause in a loop. + // + + printf(" test36..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 0) { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 4; + } + finally { + Counter += 5; + continue; + } + + Counter += 6; + } + + if (Counter != 115) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // Break from a try body with an exception clause in a loop. + // + + printf(" test37..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 40; } + + Counter += 2; + } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE + // + // Break from a try body with an finally clause in a loop. + // + + printf(" test38..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 3; + } + + if (Counter != 8) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // Break from doubly nested try body with an exception clause in a + // loop. + // + + printf(" test39..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } + + Counter += 2; + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 20; } + + Counter += 3; + } + + if (Counter != 6) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE + // + // Break from doubly nested try body with an finally clause in a loop. + // + + printf(" test40..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 3; + } + finally { Counter += 4; } + + Counter += 5; + } + + if (Counter != 21) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Break from a finally clause in a loop. + // + + printf(" test41..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + if ((Index1 & 0x1) == 1) { + Counter += 1; + } + } + finally { + Counter += 2; + break; + } + + Counter += 4; + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Break from a doubly nested finally clause in a loop. + // + + printf(" test42..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 1) { + Counter += 1; + } + } + finally { + Counter += 2; + break; + } + + Counter += 4; + } + finally { Counter += 5; } + + Counter += 6; + } + + if (Counter != 7) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Break from a doubly nested finally clause in a loop. + // + + printf(" test43..."); + Counter = 0; + for (Index1 = 0; Index1 < 10; Index1 += 1) { + try { + try { + if ((Index1 & 0x1) == 1) { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 4; + } + finally { + Counter += 5; + break; + } + + Counter += 6; + } + + if (Counter != 11) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // Break from a try body with an exception clause in a switch. + // + + printf(" test44..."); + Counter = 0; + Index1 = 1; + switch (Index2) { + case BLUE: + Counter += 100; + break; + + case RED: + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 40; } + + Counter += 2; + break; + } + + if (Counter != 0) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE + // + // Break from a try body with an finally clause in a switch. + // + + printf(" test45..."); + Counter = 0; + Index1 = 1; + switch (Index2) { + case BLUE: + Counter += 100; + break; + + case RED: + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 3; + } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // Break from doubly nested try body with an exception clause in a + // switch. + // + + printf(" test46..."); + Counter = 0; + Index1 = 1; + switch (Index2) { + case BLUE: + Counter += 100; + break; + + case RED: + try { + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } + + Counter += 2; + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 20; } + + Counter += 3; + } + + if (Counter != 0) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // gotos from try/finally not allowed on WinCE + // + // Break from doubly nested try body with an finally clause in a switch. + // + + printf(" test47..."); + Counter = 0; + Index1 = 1; + switch (Index2) { + case BLUE: + Counter += 100; + break; + + case RED: + try { + try { + if ((Index1 & 0x1) == 1) { + break; + + } else { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 3; + } + finally { Counter += 4; } + + Counter += 5; + } + + if (Counter != 6) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Break from a finally clause in a switch. + // + + printf(" test48..."); + Counter = 0; + Index1 = 1; + switch (Index2) { + case BLUE: + Counter += 100; + break; + + case RED: + try { + if ((Index1 & 0x1) == 1) { + Counter += 1; + } + } + finally { + Counter += 2; + break; + } + + Counter += 4; + } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Break from a doubly nested finally clause in a switch. + // + + printf(" test49..."); + Counter = 0; + Index1 = 1; + switch (Index2) { + case BLUE: + Counter += 100; + break; + + case RED: + try { + try { + if ((Index1 & 0x1) == 1) { + Counter += 1; + } + } + finally { + Counter += 2; + break; + } + + Counter += 4; + } + finally { Counter += 5; } + + Counter += 6; + } + + if (Counter != 8) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Break from a doubly nested finally clause in a switch. + // + + printf(" test50..."); + Counter = 0; + Index1 = 1; + switch (Index2) { + case BLUE: + Counter += 100; + break; + + case RED: + try { + try { + if ((Index1 & 0x1) == 1) { + Counter += 1; + } + } + finally { Counter += 2; } + + Counter += 4; + } + finally { + Counter += 5; + break; + } + + Counter += 6; + } + + if (Counter != 12) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // Leave from an if in a simple try/finally. + // + + printf(" test51..."); + Counter = 0; + try { + if (Echo(Counter) == Counter) { + Counter += 3; + leave; + + } else { + Counter += 100; + } + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + + if (Counter != 8) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Leave from a loop in a simple try/finally. + // + + printf(" test52..."); + Counter = 0; + try { + for (Index1 = 0; Index1 < 10; Index1 += 1) { + if (Echo(Index1) == Index1) { + Counter += 3; + leave; + } + + Counter += 100; + } + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + + if (Counter != 8) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Leave from a switch in a simple try/finally. + // + + printf(" test53..."); + Counter = 0; + try { + switch (Index2) { + case BLUE: + break; + + case RED: + Counter += 3; + leave; + } + + Counter += 100; + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + + if (Counter != 8) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Leave from an if in doubly nested try/finally followed by a leave + // from an if in the outer try/finally. + // + + printf(" test54..."); + Counter = 0; + try { + try { + if (Echo(Counter) == Counter) { + Counter += 3; + leave; + + } else { + Counter += 100; + } + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + + if (Echo(Counter) == Counter) { + Counter += 3; + leave; + + } else { + Counter += 100; + } + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + + if (Counter != 16) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#if !defined(WIN_CE) // leave from finally not allowed on WinCE + // + // Leave from an if in doubly nested try/finally followed by a leave + // from the finally of the outer try/finally. + // + + printf(" test55..."); + Counter = 0; + try { + try { + if (Echo(Counter) == Counter) { + Counter += 3; + leave; + + } else { + Counter += 100; + } + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + leave; + } + } + + Counter += 100; + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + + if (Counter != 13) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif + + // + // Try/finally within the except clause of a try/except that is always + // executed. + // + + printf(" test56..."); + Counter = 0; + try { + Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + except(Counter) { + try { + Counter += 3; + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + } + + if (Counter != 9) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Try/finally within the finally clause of a try/finally. + // + + printf(" test57..."); + Counter = 0; + try { + Counter += 1; + } + finally { + if (abnormal_termination() == FALSE) { + try { + Counter += 3; + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + } + } + + if (Counter != 9) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Try/except within the finally clause of a try/finally. + // + + printf(" test58..."); +#if !defined(NEST_IN_FINALLY) + printf("skipped\n"); +#else + Counter = 0; + try { + Counter -= 1; + } + finally { + try { + Counter += 2; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + except(Counter) { + try { + Counter += 3; + } + finally { + if (abnormal_termination() == FALSE) { + Counter += 5; + } + } + } + } + + if (Counter != 9) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif /* def(NEST_IN_FINALLY) */ + + // + // Try/except within the except clause of a try/except that is always + // executed. + // + + printf(" test59..."); + Counter = 0; + try { + Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + except(Counter) { + try { + Counter += 3; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + except(Counter - 3) { Counter += 5; } + } + + if (Counter != 9) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Try with a Try which exits the scope with a goto + // + + printf(" test60..."); + Counter = 0; + try { + try { + goto outside; + } + except(1) { Counter += 1; } + + outside: + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + except(1) { Counter += 3; } + + if (Counter != 3) { + printf("failed, count = %d\n", Counter); + } else { + printf("succeeded\n"); + } + + // + // Try/except which gets an exception from a subfunction within + // a try/finally which has a try/except in the finally clause + // + + printf(" test61..."); +#if !defined(NEST_IN_FINALLY) + printf("skipped\n"); +#else + Counter = 0; + try { + Test61Part2(&Counter); + } + except(EXCEPTION_EXECUTE_HANDLER) { Counter += 11; } + + if (Counter != 24) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } +#endif /* def(NEST_IN_FINALLY) */ + + // + // Check for precision of exception on floating point + // + + printf(" test62..."); + +#if defined(i386) || defined(_M_IA64) || defined(_M_ALPHA) || defined(_M_AMD64) + +/* enable floating point overflow */ +#if defined(i386) + _control87(_control87(0, 0) & ~EM_OVERFLOW, _MCW_EM); +#else + // + // use portable version of _control87 + // + _controlfp(_controlfp(0, 0) & ~EM_OVERFLOW, _MCW_EM); +#endif + + Counter = 0; + try { + doubleresult = SquareDouble(1.7e300); + + try { + doubleresult = SquareDouble(1.0); + } + except(1) { Counter += 3; } + } + except(1) { Counter += 1; } + + if (Counter != 1) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +/* clear up pending unmasked exceptions and restore FP control registers */ +#if defined(i386) + _clear87(); + _control87(_control87(0, 0) | EM_OVERFLOW, 0xfffff); +#else + _clearfp(); + _controlfp(_controlfp(0, 0) | EM_OVERFLOW, 0xfffff); +#endif + +#else + printf("skipped\n"); +#endif + + // + // A try/finally inside a try/except where an exception is raised in the + // try/finally. + // + + printf(" test63..."); + Counter = 0; + try { + try { + Counter += 1; + } + finally { + Counter += 3; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + } + except(1) { Counter += 6; } + + if (Counter != 10) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A try/finally inside a try/except where an exception is raised in the + // in the try/except and the try/finally. + // + + printf(" test64..."); + Counter = 0; + try { + try { + Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + finally { + Counter += 3; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + } + except(1) { Counter += 6; } + + if (Counter != 10) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A try/finally inside a try/except where an exception is raised in the + // try/finally. + // + + printf(" test65..."); + Counter = 0; + try { + try { + Counter += 1; + } + finally { + Counter += 3; + *BlackHole += *BadAddress; + Counter += 13; + } + } + except(1) { Counter += 6; } + + if (Counter != 10) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A try/finally inside a try/except where an exception is raised in the + // in the try/except and the try/finally. + // + + printf(" test66..."); + Counter = 0; + try { + try { + Counter += 1; + *BlackHole += *BadAddress; + Counter += 13; + } + finally { + Counter += 3; + *BlackHole += *BadAddress; + Counter += 13; + } + } + except(1) { Counter += 6; } + + if (Counter != 10) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A try/finally inside a try/finally inside a try/except where an + // exception is raised in the in the try/except and in try/finally. + // + + printf(" test67..."); + try { + try { + *BlackHole += *BadAddress; + } + finally { + try { + Counter = 0; + } + finally { + if (Counter != 0) { + Counter += 1; + } + } + + Counter += 1; + *BlackHole += *BadAddress; + } + } + except(1) { Counter += 1; } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // A try/finally inside a try/finally inside a try/except where an + // exception is raised in the in the try/except and in try/finally. + // + + printf(" test68..."); + try { + try { + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + finally { + try { + Counter = 0; + } + finally { + if (Counter != 0) { + Counter += 1; + } + } + + Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + } + except(1) { Counter += 1; } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +// +// Patch guard test 69. +// + +#if defined(_AMD64_) || defined(_X86_) + + printf(" test69..."); + Counter = 0; + try { + PgTest69(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test70..."); + Counter = 0; + try { + PgTest70(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 2) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test71..."); + Counter = 0; + try { + PgTest71(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 9) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test72..."); + Counter = 0; + try { + PgTest72(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 12) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test73..."); + Counter = 0; + try { + PgTest73(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 15) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test74..."); + Counter = 0; + try { + PgTest74(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 18) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test75..."); + Counter = 0; + try { + PgTest75(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 35) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test76..."); + Counter = 0; + try { + PgTest76(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 40) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test77..."); + Counter = 0; + try { + PgTest77(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 45) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test78..."); + Counter = 0; + try { + PgTest78(&Counter, BadAddress); + } + except(EXCEPTION_EXECUTE_HANDLER) { printf("unexpected exception..."); } + + if (Counter != 50) { + printf("failed, count = %d\n", Counter); + + } else { + printf("succeeded\n"); + } + +#else + printf(" test69...filter entered...succeeded\n"); + printf(" test70...filter entered...succeeded\n"); + printf(" test71...filter entered...succeeded\n"); + printf(" test72...filter entered...succeeded\n"); + printf(" test73...filter entered...succeeded\n"); + printf(" test74...filter entered...succeeded\n"); + printf(" test75...filter entered...succeeded\n"); + printf(" test76...filter entered...succeeded\n"); + printf(" test77...filter entered...succeeded\n"); + printf(" test78...filter entered...succeeded\n"); +#endif + + if (LOBYTE(LOWORD(GetVersion())) < 6) { + printf(" test79..."); + printf("filter 1...filter 2...finally 1...filter 1...filter 2...finally " + "2...passed\n"); + } else { + + printf(" test79..."); + Counter = 0; + try { + Test79(&Counter, BadAddress); + } + except(printf("filter 2..."), EXCEPTION_EXECUTE_HANDLER) { Counter += 1; } + + if (Counter == 3) { + printf("passed\n"); + + } else { + printf("failed %d \n", Counter); + } + } + + printf(" test80..."); + if (Test80() != 0) { + printf("failed\n"); + + } else { + printf("passed\n"); + } + + printf(" test81..."); + Counter = 0; + Test81(&Counter); + if (Counter != 1) { + printf("failed %d \n", Counter); + + } else { + printf("passed\n"); + } + + printf(" test82..."); + Counter = 1; + Test82(&Counter); + if (Counter != 0) { + printf("failed\n"); + + } else { + printf("succeeded\n"); + } + + printf(" test83..."); + if (Test83() != 0) { + printf("failed\n"); + + } else { + printf("succeeded\n"); + } + + printf(" test84..."); + Counter = 0; + Test84(&Counter); + if (Counter != 2) { + printf("failed\n"); + + } else { + printf("succeeded\n"); + } + + printf(" test85..."); + Counter = 0; + Test85(&Counter); + if (Counter != 7) { + printf("failed\n"); + + } else { + printf("succeeded\n"); + } + + printf(" test86..."); + Counter = 0; + Test86(&Counter); + if (Counter != 4) { + printf("failed %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test87..."); + Counter = 0; + Test87(&Counter); + if (Counter != 104) { + printf("failed %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + printf(" test88..."); + Counter = 0; + Test88(&Counter); + if (Counter != 6) { + printf("failed %d\n", Counter); + + } else { + printf("succeeded\n"); + } + + // + // Announce end of exception test. + // + + printf("End of exception test\n"); + return; +} + +#pragma optimize("a", off) +VOID addtwo(long First, long Second, long *Place) + +{ + + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + *Place = First + Second; + return; +} +#pragma optimize("", on) + +VOID bar1(IN NTSTATUS Status, IN PLONG Counter) { + + try { + foo1(Status); + } + finally { + if (abnormal_termination() != FALSE) { + *Counter = 99; + + } else { + *Counter = 100; + } + } + + return; +} + +VOID bar2(IN PLONG BlackHole, IN PLONG BadAddress, IN PLONG Counter) { + + try { + foo2(BlackHole, BadAddress); + } + finally { + if (abnormal_termination() != FALSE) { + *Counter = 99; + + } else { + *Counter = 100; + } + } + + return; +} + +VOID dojump(IN jmp_buf JumpBuffer, IN PLONG Counter) + +{ + + try { + try { + *Counter += 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + finally { *Counter += 1; } + } + finally { + *Counter += 1; + longjmp(JumpBuffer, 1); + } +} + +#if !defined(WIN_CE) // return through finally not allowed on WinCE +VOID eret(IN NTSTATUS Status, IN PLONG Counter) + +{ + + try { + try { + foo1(Status); + } + except((GetExceptionCode() == Status) ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + *Counter += 1; + return; + } + } + finally { *Counter += 1; } + + return; +} +#endif + +VOID except1(IN PLONG Counter) + +{ + + try { + *Counter += 5; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + except(except3(GetExceptionInformation(), Counter)) { *Counter += 7; } + + *Counter += 9; + return; +} + +ULONG +except2(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter) + +{ + + PEXCEPTION_RECORD ExceptionRecord; + + ExceptionRecord = ExceptionPointers->ExceptionRecord; + if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) && + ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) { + *Counter += 11; + return EXCEPTION_EXECUTE_HANDLER; + + } else { + *Counter += 13; + return EXCEPTION_CONTINUE_SEARCH; + } +} + +ULONG +except3(IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter) + +{ + + PEXCEPTION_RECORD ExceptionRecord; + + ExceptionRecord = ExceptionPointers->ExceptionRecord; + if ((ExceptionRecord->ExceptionCode == STATUS_INTEGER_OVERFLOW) && + ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) { + *Counter += 17; + RtlRaiseStatus(STATUS_UNSUCCESSFUL); + + } else if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) && + ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) != 0)) { + *Counter += 19; + return EXCEPTION_CONTINUE_SEARCH; + } + + *Counter += 23; + return EXCEPTION_EXECUTE_HANDLER; +} + +VOID foo1(IN NTSTATUS Status) + +{ + + // + // Raise exception. + // + + RtlRaiseStatus(Status); + return; +} + +VOID foo2(IN PLONG BlackHole, IN PLONG BadAddress) + +{ + + // + // Raise exception. + // + + *BlackHole += *BadAddress; + return; +} + +#if !defined(WIN_CE) // return from finally not allowed on WinCE +VOID fret(IN PLONG Counter) + +{ + + try { + try { + *Counter += 1; + } + finally { + *Counter += 1; + return; + } + } + finally { *Counter += 1; } + + return; +} +#endif + +LONG Echo(IN LONG Value) + +{ + return Value; +} + +#if defined(NEST_IN_FINALLY) +VOID Test61Part2(IN OUT PULONG Counter) { + try { + *Counter -= 1; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } + finally { + try { + *Counter += 2; + RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); } + except(EXCEPTION_EXECUTE_HANDLER) { *Counter += 5; } + *Counter += 7; + } +} +#endif /* def(NEST_IN_FINALLY) */ + +double SquareDouble(IN double op) { + return exp(2.0 * log(op)); }