https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9853cc4d7e04617960d57…
commit 9853cc4d7e04617960d57ea184ded34b162ab9d8
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Fri Apr 5 23:22:55 2019 +0200
Commit: Mark Jansen <mark.jansen(a)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(a)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(a)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(a)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());
+ }
+};
+
+
+}