https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9853cc4d7e04617960d57e...
commit 9853cc4d7e04617960d57ea184ded34b162ab9d8 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Fri Apr 5 23:22:55 2019 +0200 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Thu Apr 18 19:21:37 2019 +0200
[ATL][ATL_APITEST] Add test + implementation for CAtlFileMapping --- modules/rostests/apitests/atl/CAtlFileMapping.cpp | 254 +++++++++++++++++++ modules/rostests/apitests/atl/CMakeLists.txt | 1 + modules/rostests/apitests/atl/devenv/ATLTest.sln | 10 + .../rostests/apitests/atl/devenv/CAtlFile.vcxproj | 168 ++++++++++++ modules/rostests/apitests/atl/testlist.c | 2 + sdk/lib/atl/atlbase.h | 15 +- sdk/lib/atl/atlcomcli.h | 6 + sdk/lib/atl/atldef.h | 59 +++++ sdk/lib/atl/atlexcept.h | 7 +- sdk/lib/atl/atlfile.h | 281 +++++++++++++++++++++ 10 files changed, 789 insertions(+), 14 deletions(-)
diff --git a/modules/rostests/apitests/atl/CAtlFileMapping.cpp b/modules/rostests/apitests/atl/CAtlFileMapping.cpp new file mode 100644 index 0000000000..49997474c1 --- /dev/null +++ b/modules/rostests/apitests/atl/CAtlFileMapping.cpp @@ -0,0 +1,254 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Test for CAtlFileMapping + * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org) + */ + +#include <atlfile.h> + +#ifdef __REACTOS__ + #include <apitest.h> +#else + #include <stdlib.h> + #include <stdio.h> + #include <stdarg.h> + #include <windows.h> + int g_tests_executed = 0; + int g_tests_failed = 0; + int g_tests_skipped = 0; + const char *g_file = NULL; + int g_line = 0; + void set_location(const char *file, int line) + { + g_file = file; + g_line = line; + } + void ok_func(int value, const char *fmt, ...) + { + va_list va; + va_start(va, fmt); + if (!value) + { + printf("%s (%d): ", g_file, g_line); + vprintf(fmt, va); + g_tests_failed++; + } + g_tests_executed++; + va_end(va); + } + void skip_func(const char *fmt, ...) + { + va_list va; + va_start(va, fmt); + printf("%s (%d): test skipped: ", g_file, g_line); + vprintf(fmt, va); + g_tests_skipped++; + va_end(va); + } + #undef ok + #define ok(value, ...) do { \ + set_location(__FILE__, __LINE__); \ + ok_func(value, __VA_ARGS__); \ + } while (0) + #define ok_(x1,x2) set_location(x1,x2); ok_func + #define skip(...) do { \ + set_location(__FILE__, __LINE__); \ + skip_func(__VA_ARGS__); \ + } while (0) + #define START_TEST(x) int main() + char *wine_dbgstr_w(const wchar_t *wstr) + { + static char buf[512]; + WideCharToMultiByte(CP_ACP, 0, wstr, -1, buf, _countof(buf), NULL, NULL); + return buf; + } +#endif + +struct TestData +{ + int data[4]; +}; + + +static void test_SharedMem() +{ + CAtlFileMapping<TestData> test1, test2; + CAtlFileMappingBase test3; + BOOL bAlreadyExisted; + HRESULT hr; + + ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData()); + ok(test3.GetData() == NULL, "Expected NULL, got %p\n", test3.GetData()); + ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle()); + ok(test3.GetHandle() == NULL, "Expected NULL, got %p\n", test3.GetHandle()); + ok(test1.GetMappingSize() == 0, "Expected 0, got %lu\n", test1.GetMappingSize()); + ok(test3.GetMappingSize() == 0, "Expected 0, got %lu\n", test3.GetMappingSize()); + + test1 = test1; + //test1 = test2; // Asserts on orig.m_pData != NULL, same with CopyFrom + //test1 = test3; // does not compile + hr = test1.Unmap(); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + + // Asserts on name == NULL + hr = test1.OpenMapping(_T("TEST_MAPPING"), 123, 0, FILE_MAP_ALL_ACCESS); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%lx\n", hr); + ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData()); + ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle()); + ok(test1.GetMappingSize() == 123, "Expected 123, got %lu\n", test1.GetMappingSize()); + + hr = test1.Unmap(); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData()); + ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle()); + ok(test1.GetMappingSize() == 123, "Expected 123, got %lu\n", test1.GetMappingSize()); + + bAlreadyExisted = 123; + hr = test1.MapSharedMem(sizeof(TestData), _T("TEST_MAPPING"), &bAlreadyExisted, (LPSECURITY_ATTRIBUTES)0, PAGE_READWRITE, FILE_MAP_ALL_ACCESS); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData()); + ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle()); + ok(test1.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test1.GetMappingSize()); + ok(bAlreadyExisted == FALSE, "Expected FALSE, got %u\n", bAlreadyExisted); + + if (test1.GetData()) + { + memset(test1.GetData(), 0x35, sizeof(TestData)); + } + + hr = test2.CopyFrom(test1); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test2.GetData() != NULL, "Expected ptr, got %p\n", test2.GetData()); + ok(test2.GetHandle() != NULL, "Expected handle, got %p\n", test2.GetHandle()); + ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize()); + + // test1 is not closed: + ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData()); + ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle()); + ok(test1.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test1.GetMappingSize()); + + // test2 does not equal test1 + ok(test1.GetData() != test2.GetData(), "Expected different ptrs\n"); + ok(test1.GetHandle() != test2.GetHandle(), "Expected different handles\n"); + + TestData* t1 = test1; + TestData* t2 = test2; + if (t1 && t2) + { + ok(t1->data[0] == 0x35353535, "Expected 0x35353535, got 0x%x\n", t1->data[0]); + ok(t2->data[0] == 0x35353535, "Expected 0x35353535, got 0x%x\n", t2->data[0]); + + t1->data[0] = 0xbeefbeef; + ok(t1->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t1->data[0]); + ok(t2->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t2->data[0]); + } + + hr = test3.OpenMapping(_T("TEST_MAPPING"), sizeof(TestData), offsetof(TestData, data[1])); + ok(hr == HRESULT_FROM_WIN32(ERROR_MAPPED_ALIGNMENT), "Expected HRESULT_FROM_WIN32(ERROR_MAPPED_ALIGNMENT), got 0x%lx\n", hr); + ok(test3.GetData() == NULL, "Expected NULL, got %p\n", test3.GetData()); + ok(test3.GetHandle() == NULL, "Expected NULL, got %p\n", test3.GetHandle()); + ok(test3.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test3.GetMappingSize()); + + hr = test2.Unmap(); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test2.GetData() == NULL, "Expected NULL, got %p\n", test2.GetData()); + ok(test2.GetHandle() == NULL, "Expected NULL, got %p\n", test2.GetHandle()); + ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize()); + + bAlreadyExisted = 123; + // Wrong access flag + hr = test2.MapSharedMem(sizeof(TestData), _T("TEST_MAPPING"), &bAlreadyExisted, (LPSECURITY_ATTRIBUTES)0, PAGE_EXECUTE_READ, FILE_MAP_ALL_ACCESS); + ok(hr == E_ACCESSDENIED, "Expected E_ACCESSDENIED, got 0x%lx\n", hr); + ok(test2.GetData() == NULL, "Expected NULL, got %p\n", test2.GetData()); + ok(test2.GetHandle() == NULL, "Expected NULL, got %p\n", test2.GetHandle()); + ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize()); + ok(bAlreadyExisted == TRUE, "Expected TRUE, got %u\n", bAlreadyExisted); + + bAlreadyExisted = 123; + hr = test2.MapSharedMem(sizeof(TestData), _T("TEST_MAPPING"), &bAlreadyExisted, (LPSECURITY_ATTRIBUTES)0, PAGE_READWRITE, FILE_MAP_ALL_ACCESS); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test2.GetData() != NULL, "Expected ptr, got %p\n", test2.GetData()); + ok(test2.GetHandle() != NULL, "Expected handle, got %p\n", test2.GetHandle()); + ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize()); + ok(bAlreadyExisted == TRUE, "Expected TRUE, got %u\n", bAlreadyExisted); + + // test2 does not equal test1 + ok(test1.GetData() != test2.GetData(), "Expected different ptrs\n"); + ok(test1.GetHandle() != test2.GetHandle(), "Expected different handles\n"); + + t2 = test2; + if (t1 && t2) + { + ok(t1->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t1->data[0]); + ok(t2->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t2->data[0]); + + t1->data[0] = 0xdeaddead; + ok(t1->data[0] == (int)0xdeaddead, "Expected 0xdeaddead, got 0x%x\n", t1->data[0]); + ok(t2->data[0] == (int)0xdeaddead, "Expected 0xdeaddead, got 0x%x\n", t2->data[0]); + } +} + +static void test_FileMapping() +{ + WCHAR Buf[MAX_PATH] = {0}; + ULARGE_INTEGER FileSize; + + GetModuleFileNameW(NULL, Buf, _countof(Buf)); + + CAtlFileMapping<IMAGE_DOS_HEADER> test1, test2; + HRESULT hr; + + { + CHandle hFile(CreateFileW(Buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)); + ok(hFile != INVALID_HANDLE_VALUE, "Could not open %S, aborting test\n", Buf); + if (hFile == INVALID_HANDLE_VALUE) + return; + + FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart); + + hr = test1.MapFile(hFile, 0, 0, PAGE_READONLY, FILE_MAP_READ); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData()); + ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle()); + ok(test1.GetMappingSize() == FileSize.LowPart, "Expected %lu, got %lu\n", FileSize.LowPart, test1.GetMappingSize()); + + hr = test2.MapFile(hFile, 0, 0x10000, PAGE_READONLY, FILE_MAP_READ); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test2.GetData() != NULL, "Expected ptr, got %p\n", test2.GetData()); + ok(test2.GetHandle() != NULL, "Expected handle, got %p\n", test2.GetHandle()); + // Offset is subtracted + ok(test2.GetMappingSize() == FileSize.LowPart - 0x10000, "Expected %lu, got %lu\n", FileSize.LowPart-0x10000, test2.GetMappingSize()); + + hr = test1.Unmap(); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData()); + ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle()); + ok(test1.GetMappingSize() == FileSize.LowPart, "Expected %lu, got %lu\n", FileSize.LowPart, test1.GetMappingSize()); + + hr = test1.MapFile(hFile, 0x1000); + ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr); + ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData()); + ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle()); + ok(test1.GetMappingSize() == 0x1000, "Expected 0x1000, got %lu\n", test1.GetMappingSize()); + } + + // We can still access it after the file is closed + PIMAGE_DOS_HEADER dos = test1; + if (dos) + { + ok(dos->e_magic == IMAGE_DOS_SIGNATURE, "Expected IMAGE_DOS_SIGNATURE, got 0x%x\n", dos->e_magic); + } +} + + +START_TEST(CAtlFileMapping) +{ + test_SharedMem(); + test_FileMapping(); + +#ifndef __REACTOS__ + printf("CAtlFile: %i tests executed (0 marked as todo, %i failures), %i skipped.\n", g_tests_executed, g_tests_failed, g_tests_skipped); + return g_tests_failed; +#endif +} diff --git a/modules/rostests/apitests/atl/CMakeLists.txt b/modules/rostests/apitests/atl/CMakeLists.txt index 3cbf35bc09..249724746c 100644 --- a/modules/rostests/apitests/atl/CMakeLists.txt +++ b/modules/rostests/apitests/atl/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl)
list(APPEND SOURCE atltypes.cpp + CAtlFileMapping.cpp CComBSTR.cpp CComHeapPtr.cpp CComObject.cpp diff --git a/modules/rostests/apitests/atl/devenv/ATLTest.sln b/modules/rostests/apitests/atl/devenv/ATLTest.sln index b36db07333..0244f71980 100644 --- a/modules/rostests/apitests/atl/devenv/ATLTest.sln +++ b/modules/rostests/apitests/atl/devenv/ATLTest.sln @@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CComObject", "CComObject.vc EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CComQIPtr", "CComQIPtr.vcxproj", "{907AEF87-D169-4A2F-A9E3-FF3DD1D59E65}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CAtlFileMapping", "CAtlFile.vcxproj", "{3AE82A8E-D43D-41F6-8093-9C687283FAB6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -71,6 +73,14 @@ Global {907AEF87-D169-4A2F-A9E3-FF3DD1D59E65}.Release|x64.Build.0 = Release|x64 {907AEF87-D169-4A2F-A9E3-FF3DD1D59E65}.Release|x86.ActiveCfg = Release|Win32 {907AEF87-D169-4A2F-A9E3-FF3DD1D59E65}.Release|x86.Build.0 = Release|Win32 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Debug|x64.ActiveCfg = Debug|x64 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Debug|x64.Build.0 = Debug|x64 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Debug|x86.ActiveCfg = Debug|Win32 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Debug|x86.Build.0 = Debug|Win32 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Release|x64.ActiveCfg = Release|x64 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Release|x64.Build.0 = Release|x64 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Release|x86.ActiveCfg = Release|Win32 + {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/modules/rostests/apitests/atl/devenv/CAtlFile.vcxproj b/modules/rostests/apitests/atl/devenv/CAtlFile.vcxproj new file mode 100644 index 0000000000..e6214597f6 --- /dev/null +++ b/modules/rostests/apitests/atl/devenv/CAtlFile.vcxproj @@ -0,0 +1,168 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\CAtlFileMapping.cpp" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3AE82A8E-D43D-41F6-8093-9C687283FAB6}</ProjectGuid> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> + <Keyword>AtlProj</Keyword> + <ProjectName>CAtlFileMapping</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/modules/rostests/apitests/atl/testlist.c b/modules/rostests/apitests/atl/testlist.c index 232785a4b8..0fa460898a 100644 --- a/modules/rostests/apitests/atl/testlist.c +++ b/modules/rostests/apitests/atl/testlist.c @@ -2,6 +2,7 @@ #include <apitest.h>
extern void func_atltypes(void); +extern void func_CAtlFileMapping(void); extern void func_CComBSTR(void); extern void func_CComHeapPtr(void); extern void func_CComObject(void); @@ -16,6 +17,7 @@ extern void func_CString(void); const struct test winetest_testlist[] = { { "atltypes", func_atltypes }, + { "CAtlFileMapping", func_CAtlFileMapping }, { "CComBSTR", func_CComBSTR }, { "CComHeapPtr", func_CComHeapPtr }, { "CComObject", func_CComObject }, diff --git a/sdk/lib/atl/atlbase.h b/sdk/lib/atl/atlbase.h index 598abc3f3d..abd0711503 100644 --- a/sdk/lib/atl/atlbase.h +++ b/sdk/lib/atl/atlbase.h @@ -20,10 +20,12 @@
#pragma once
+#include "atldef.h" #include "atlcore.h" #include "statreg.h" #include "atlcomcli.h" #include "atlalloc.h" +#include "atlexcept.h" #include "comcat.h" #include "tchar.h"
@@ -32,18 +34,6 @@ #pragma warning(disable:4355) #endif
-#ifndef _ATL_PACKING -#define _ATL_PACKING 8 -#endif - -#ifndef _ATL_FREE_THREADED -#ifndef _ATL_APARTMENT_THREADED -#ifndef _ATL_SINGLE_THREADED -#define _ATL_FREE_THREADED -#endif -#endif -#endif - #ifndef ATLTRY #define ATLTRY(x) x; #endif @@ -58,7 +48,6 @@ #define ATL_DEPRECATED __declspec(deprecated) #endif
-#define offsetofclass(base, derived) (reinterpret_cast<DWORD_PTR>(static_cast<base *>(reinterpret_cast<derived *>(_ATL_PACKING))) - _ATL_PACKING)
namespace ATL { diff --git a/sdk/lib/atl/atlcomcli.h b/sdk/lib/atl/atlcomcli.h index ad1582a6ca..cba78101d2 100644 --- a/sdk/lib/atl/atlcomcli.h +++ b/sdk/lib/atl/atlcomcli.h @@ -53,6 +53,12 @@ namespace ATL {
+inline HRESULT AtlHresultFromLastError() throw() +{ + DWORD dwError = ::GetLastError(); + return HRESULT_FROM_WIN32(dwError); +} +
template<class T> class CComPtr diff --git a/sdk/lib/atl/atldef.h b/sdk/lib/atl/atldef.h new file mode 100644 index 0000000000..4ab2fec45d --- /dev/null +++ b/sdk/lib/atl/atldef.h @@ -0,0 +1,59 @@ +/* +* PROJECT: ReactOS ATL +* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) +* PURPOSE: ATL Base definitions +* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org) +*/ + +#pragma once + + +#define _ATL_PACKING 8 + + +#ifndef AtlThrow +#ifndef _ATL_CUSTOM_THROW +#define AtlThrow(x) ATL::AtlThrowImp(x) +#endif +#endif + + +#ifndef ATLASSERT +#define ATLASSERT(expr) _ASSERTE(expr) +#endif + + +// ATLASSUME, ATLENSURE, ATLVERIFY, ... + + + + + +#ifdef _ATL_DISABLE_NO_VTABLE +#define ATL_NO_VTABLE +#else +#define ATL_NO_VTABLE __declspec(novtable) +#endif + +#ifndef ATL_DEPRECATED +#define ATL_DEPRECATED __declspec(deprecated) +#endif + +// ATL_NOTHROW, ATL_FORCEINLINE, ATL_NOINLINE + +// _ATL, ATL_VER, ATL_FILENAME_VER, ATL_FILENAME_VERNUM, ... + + + +#define offsetofclass(base, derived) (reinterpret_cast<DWORD_PTR>(static_cast<base *>(reinterpret_cast<derived *>(_ATL_PACKING))) - _ATL_PACKING) + + + +#ifndef _ATL_FREE_THREADED +#ifndef _ATL_APARTMENT_THREADED +#ifndef _ATL_SINGLE_THREADED +#define _ATL_FREE_THREADED +#endif +#endif +#endif + diff --git a/sdk/lib/atl/atlexcept.h b/sdk/lib/atl/atlexcept.h index 233dd09559..a71b4430d0 100644 --- a/sdk/lib/atl/atlexcept.h +++ b/sdk/lib/atl/atlexcept.h @@ -9,6 +9,9 @@ #endif #endif
+namespace ATL +{ +
//FIXME: Enable when RaiseException is marked as NORETURN //DECLSPEC_NORETURN @@ -37,9 +40,11 @@ inline void AtlThrowImp(HRESULT hr) }
- #ifndef AtlThrow #define AtlThrow(x) AtlThrowImp(x) #endif
+ +}; // namespace ATL + #endif diff --git a/sdk/lib/atl/atlfile.h b/sdk/lib/atl/atlfile.h new file mode 100644 index 0000000000..cff0614d1c --- /dev/null +++ b/sdk/lib/atl/atlfile.h @@ -0,0 +1,281 @@ +/* +* PROJECT: ReactOS ATL +* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) +* PURPOSE: ATL File implementation +* COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org) +*/ + +#pragma once + +#include <atlbase.h> + +namespace ATL +{ + +//class CAtlFile: TODO +// public CHandle +//{ +//}; + + +//class CAtlTemporaryFile TODO +//{ +//}; + + + +class CAtlFileMappingBase +{ +private: + void* m_pData; + SIZE_T m_nMappingSize; + HANDLE m_hMapping; + ULARGE_INTEGER m_nOffset; + DWORD m_dwViewDesiredAccess; + +public: + CAtlFileMappingBase() throw() + :m_pData(NULL) + ,m_nMappingSize(0) + ,m_hMapping(NULL) + ,m_dwViewDesiredAccess(0) + { + m_nOffset.QuadPart = 0; + } + + ~CAtlFileMappingBase() throw() + { + Unmap(); + } + + CAtlFileMappingBase(CAtlFileMappingBase& orig) + { + HRESULT hr; + + m_pData = NULL; + m_nMappingSize = 0; + m_hMapping = NULL; + m_dwViewDesiredAccess = 0; + m_nOffset.QuadPart = 0; + + hr = CopyFrom(orig); + if (FAILED(hr)) + AtlThrow(hr); + } + + CAtlFileMappingBase& operator=(CAtlFileMappingBase& orig) + { + HRESULT hr; + + hr = CopyFrom(orig); + if (FAILED(hr)) + AtlThrow(hr); + + return *this; + } + + HRESULT CopyFrom(CAtlFileMappingBase& orig) throw() + { + HRESULT hr = S_OK; + + if (&orig == this) + return S_OK; + + ATLASSERT(m_pData == NULL); + ATLASSERT(m_hMapping == NULL); + ATLASSERT(orig.m_pData != NULL); + + m_nMappingSize = orig.m_nMappingSize; + m_nOffset.QuadPart = orig.m_nOffset.QuadPart; + m_dwViewDesiredAccess = orig.m_dwViewDesiredAccess; + + if (::DuplicateHandle(GetCurrentProcess(), orig.m_hMapping, GetCurrentProcess(), &m_hMapping, NULL, TRUE, DUPLICATE_SAME_ACCESS)) + { + m_pData = ::MapViewOfFile(m_hMapping, m_dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize); + if (!m_pData) + { + hr = AtlHresultFromLastError(); + ::CloseHandle(m_hMapping); + m_hMapping = NULL; + } + } + else + { + hr = AtlHresultFromLastError(); + } + + return hr; + } + + HRESULT MapFile( + HANDLE hFile, + SIZE_T nMappingSize = 0, + ULONGLONG nOffset = 0, + DWORD dwMappingProtection = PAGE_READONLY, + DWORD dwViewDesiredAccess = FILE_MAP_READ) throw() + { + HRESULT hr = S_OK; + ULARGE_INTEGER FileSize; + + ATLASSERT(hFile != INVALID_HANDLE_VALUE); + ATLASSERT(m_pData == NULL); + ATLASSERT(m_hMapping == NULL); + + FileSize.LowPart = ::GetFileSize(hFile, &FileSize.HighPart); + FileSize.QuadPart = nMappingSize > FileSize.QuadPart ? nMappingSize : FileSize.QuadPart; + + m_hMapping = ::CreateFileMapping(hFile, NULL, dwMappingProtection, FileSize.HighPart, FileSize.LowPart, 0); + if (m_hMapping) + { + m_nMappingSize = nMappingSize == 0 ? (SIZE_T)(FileSize.QuadPart - nOffset) : nMappingSize; + m_nOffset.QuadPart = nOffset; + m_dwViewDesiredAccess = dwViewDesiredAccess; + + m_pData = ::MapViewOfFile(m_hMapping, m_dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize); + if (!m_pData) + { + hr = AtlHresultFromLastError(); + ::CloseHandle(m_hMapping); + m_hMapping = NULL; + } + } + else + { + hr = AtlHresultFromLastError(); + } + + return hr; + } + + HRESULT MapSharedMem( + SIZE_T nMappingSize, + LPCTSTR szName, + BOOL* pbAlreadyExisted = NULL, + LPSECURITY_ATTRIBUTES lpsa = NULL, + DWORD dwMappingProtection = PAGE_READWRITE, + DWORD dwViewDesiredAccess = FILE_MAP_ALL_ACCESS) throw() + { + HRESULT hr = S_OK; + ULARGE_INTEGER Size; + + ATLASSERT(nMappingSize > 0); + ATLASSERT(szName != NULL); + ATLASSERT(m_pData == NULL); + ATLASSERT(m_hMapping == NULL); + + m_nMappingSize = nMappingSize; + m_dwViewDesiredAccess = dwViewDesiredAccess; + m_nOffset.QuadPart = 0; + Size.QuadPart = nMappingSize; + + m_hMapping = ::CreateFileMapping(NULL, lpsa, dwMappingProtection, Size.HighPart, Size.LowPart, szName); + if (m_hMapping != NULL) + { + if (pbAlreadyExisted) + *pbAlreadyExisted = GetLastError() == ERROR_ALREADY_EXISTS; + + m_pData = ::MapViewOfFile(m_hMapping, dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize); + if (!m_pData) + { + hr = AtlHresultFromLastError(); + ::CloseHandle(m_hMapping); + m_hMapping = NULL; + } + } + else + { + hr = AtlHresultFromLastError(); + } + + return hr; + } + + HRESULT OpenMapping( + LPCTSTR szName, + SIZE_T nMappingSize, + ULONGLONG nOffset = 0, + DWORD dwViewDesiredAccess = FILE_MAP_ALL_ACCESS) throw() + { + HRESULT hr = S_OK; + + ATLASSERT(szName != NULL); + ATLASSERT(m_pData == NULL); + ATLASSERT(m_hMapping == NULL); + + m_nMappingSize = nMappingSize; + m_dwViewDesiredAccess = dwViewDesiredAccess; + m_nOffset.QuadPart = nOffset; + + m_hMapping = ::OpenFileMapping(m_dwViewDesiredAccess, FALSE, szName); + if (m_hMapping) + { + m_pData = ::MapViewOfFile(m_hMapping, dwViewDesiredAccess, m_nOffset.HighPart, m_nOffset.LowPart, m_nMappingSize); + if (!m_pData) + { + hr = AtlHresultFromLastError(); + ::CloseHandle(m_hMapping); + m_hMapping = NULL; + } + } + else + { + hr = AtlHresultFromLastError(); + } + + return hr; + } + + HRESULT Unmap() throw() + { + HRESULT hr = S_OK; + + if (m_pData) + { + if (!::UnmapViewOfFile(m_pData)) + hr = AtlHresultFromLastError(); + + m_pData = NULL; + } + if (m_hMapping) + { + // If we already had an error, do not overwrite it + if (!::CloseHandle(m_hMapping) && SUCCEEDED(hr)) + hr = AtlHresultFromLastError(); + + m_hMapping = NULL; + } + + return hr; + } + + void* GetData() const throw() + { + return m_pData; + } + + HANDLE GetHandle() throw () + { + return m_hMapping; + } + + SIZE_T GetMappingSize() throw() + { + return m_nMappingSize; + } + +}; + + +template <typename T = char> +class CAtlFileMapping: + public CAtlFileMappingBase +{ +public: + operator T*() const throw() + { + return reinterpret_cast<T*>(GetData()); + } +}; + + +}