[ATL][ATL_APITEST] Add test + implementation for CAtlFileMapping
authorMark Jansen <mark.jansen@reactos.org>
Fri, 5 Apr 2019 21:22:55 +0000 (23:22 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Thu, 18 Apr 2019 17:21:37 +0000 (19:21 +0200)
modules/rostests/apitests/atl/CAtlFileMapping.cpp [new file with mode: 0644]
modules/rostests/apitests/atl/CMakeLists.txt
modules/rostests/apitests/atl/devenv/ATLTest.sln
modules/rostests/apitests/atl/devenv/CAtlFile.vcxproj [new file with mode: 0644]
modules/rostests/apitests/atl/testlist.c
sdk/lib/atl/atlbase.h
sdk/lib/atl/atlcomcli.h
sdk/lib/atl/atldef.h [new file with mode: 0644]
sdk/lib/atl/atlexcept.h
sdk/lib/atl/atlfile.h [new file with mode: 0644]

diff --git a/modules/rostests/apitests/atl/CAtlFileMapping.cpp b/modules/rostests/apitests/atl/CAtlFileMapping.cpp
new file mode 100644 (file)
index 0000000..4999747
--- /dev/null
@@ -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
+}
index 3cbf35b..2497247 100644 (file)
@@ -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
index b36db07..0244f71 100644 (file)
@@ -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 (file)
index 0000000..e621459
--- /dev/null
@@ -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
index 232785a..0fa4608 100644 (file)
@@ -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 },
index 598abc3..abd0711 100644 (file)
 
 #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"
 
 #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
 {
index ad1582a..cba7810 100644 (file)
 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 (file)
index 0000000..4ab2fec
--- /dev/null
@@ -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
+
index 233dd09..a71b443 100644 (file)
@@ -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 (file)
index 0000000..cff0614
--- /dev/null
@@ -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());
+    }
+};
+
+
+}