From de4b1acdef4928c8b5415313ee2925503e761056 Mon Sep 17 00:00:00 2001 From: Dean M Greer <38226388+Gcenx@users.noreply.github.com> Date: Tue, 14 Jan 2025 10:55:23 -0500 Subject: [PATCH] game-porting-toolkit: Add patch fixing Steam --- devel/game-porting-toolkit/Portfile | 7 +- .../files/1007-steam.diff | 1627 +++++++++++++++++ 2 files changed, 1631 insertions(+), 3 deletions(-) create mode 100644 devel/game-porting-toolkit/files/1007-steam.diff diff --git a/devel/game-porting-toolkit/Portfile b/devel/game-porting-toolkit/Portfile index bbc98b99404c7..4430dd042c9c6 100644 --- a/devel/game-porting-toolkit/Portfile +++ b/devel/game-porting-toolkit/Portfile @@ -7,8 +7,8 @@ name game-porting-toolkit set my_name wine version 1.1 set my_name wine -revision 0 -platforms {darwin >= 23} +revision 1 +platforms {darwin any >= 23} license LGPL-2.1+ categories devel @@ -65,7 +65,8 @@ patchfiles-append \ 1003-default-win10-19043.diff \ 1004-mscoree-update-wine-mono-to-7.4.1.diff \ 1005-ntdll-d3dmetal-env.diff \ - 1006-build_fixes.diff + 1006-build_fixes.diff \ + 1007-steam.diff post-patch { reinplace -q "s|;(cw)||g" ${worksrcpath}/loader/wine.inf.in diff --git a/devel/game-porting-toolkit/files/1007-steam.diff b/devel/game-porting-toolkit/files/1007-steam.diff new file mode 100644 index 0000000000000..0fac6cc678a83 --- /dev/null +++ b/devel/game-porting-toolkit/files/1007-steam.diff @@ -0,0 +1,1627 @@ +diff --git a/configure b/configure +index 475f1229ffa..abc3f23b986 100755 +--- a/configure ++++ b/configure +@@ -965,6 +965,7 @@ enable_avicap32 + enable_avifil32 + enable_avrt + enable_bcrypt ++enable_bcryptprimitives + enable_bluetoothapis + enable_browseui + enable_bthprops_cpl +@@ -1218,6 +1219,7 @@ enable_msimtf + enable_msisip + enable_msisys_ocx + enable_msls31 ++enable_msmpeg2vdec + enable_msnet32 + enable_mspatcha + enable_msports +@@ -21837,6 +21839,7 @@ wine_fn_config_makefile dlls/avifile.dll16 enable_win16 + wine_fn_config_makefile dlls/avrt enable_avrt + wine_fn_config_makefile dlls/bcrypt enable_bcrypt + wine_fn_config_makefile dlls/bcrypt/tests enable_tests ++wine_fn_config_makefile dlls/bcryptprimitives enable_bcryptprimitives + wine_fn_config_makefile dlls/bluetoothapis enable_bluetoothapis + wine_fn_config_makefile dlls/browseui enable_browseui + wine_fn_config_makefile dlls/browseui/tests enable_tests +@@ -22225,6 +22228,7 @@ wine_fn_config_makefile dlls/msimtf enable_msimtf + wine_fn_config_makefile dlls/msisip enable_msisip + wine_fn_config_makefile dlls/msisys.ocx enable_msisys_ocx + wine_fn_config_makefile dlls/msls31 enable_msls31 ++wine_fn_config_makefile dlls/msmpeg2vdec enable_msmpeg2vdec + wine_fn_config_makefile dlls/msnet32 enable_msnet32 + wine_fn_config_makefile dlls/mspatcha enable_mspatcha + wine_fn_config_makefile dlls/mspatcha/tests enable_tests +diff --git a/configure.ac b/configure.ac +index c576648576b..4ff64396658 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2455,6 +2455,7 @@ WINE_CONFIG_MAKEFILE(dlls/avifile.dll16,enable_win16) + WINE_CONFIG_MAKEFILE(dlls/avrt) + WINE_CONFIG_MAKEFILE(dlls/bcrypt) + WINE_CONFIG_MAKEFILE(dlls/bcrypt/tests) ++WINE_CONFIG_MAKEFILE(dlls/bcryptprimitives) + WINE_CONFIG_MAKEFILE(dlls/bluetoothapis) + WINE_CONFIG_MAKEFILE(dlls/browseui) + WINE_CONFIG_MAKEFILE(dlls/browseui/tests) +@@ -2843,6 +2844,7 @@ WINE_CONFIG_MAKEFILE(dlls/msimtf) + WINE_CONFIG_MAKEFILE(dlls/msisip) + WINE_CONFIG_MAKEFILE(dlls/msisys.ocx) + WINE_CONFIG_MAKEFILE(dlls/msls31) ++WINE_CONFIG_MAKEFILE(dlls/msmpeg2vdec) + WINE_CONFIG_MAKEFILE(dlls/msnet32) + WINE_CONFIG_MAKEFILE(dlls/mspatcha) + WINE_CONFIG_MAKEFILE(dlls/mspatcha/tests) +diff --git a/dlls/bcryptprimitives/Makefile.in b/dlls/bcryptprimitives/Makefile.in +new file mode 100644 +index 00000000000..537383ba530 +--- /dev/null ++++ b/dlls/bcryptprimitives/Makefile.in +@@ -0,0 +1,5 @@ ++MODULE = bcryptprimitives.dll ++IMPORTS = advapi32 ++ ++C_SRCS = \ ++ main.c +diff --git a/dlls/bcryptprimitives/bcryptprimitives.spec b/dlls/bcryptprimitives/bcryptprimitives.spec +new file mode 100644 +index 00000000000..928cb06afcd +--- /dev/null ++++ b/dlls/bcryptprimitives/bcryptprimitives.spec +@@ -0,0 +1 @@ ++@ stdcall ProcessPrng(ptr long) +diff --git a/dlls/bcryptprimitives/main.c b/dlls/bcryptprimitives/main.c +new file mode 100644 +index 00000000000..6562d672389 +--- /dev/null ++++ b/dlls/bcryptprimitives/main.c +@@ -0,0 +1,27 @@ ++/* ++ * Copyright 2023 Christopher S. Denton ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include ++#include "windef.h" ++#include "winbase.h" ++#include "ntsecapi.h" ++ ++BOOL WINAPI ProcessPrng(BYTE *data, SIZE_T size) ++{ ++ return RtlGenRandom(data, size); ++} +diff --git a/dlls/dwmapi/Makefile.in b/dlls/dwmapi/Makefile.in +index e63dbc2ea00..37411a57608 100644 +--- a/dlls/dwmapi/Makefile.in ++++ b/dlls/dwmapi/Makefile.in +@@ -1,4 +1,5 @@ + MODULE = dwmapi.dll ++IMPORTS = user32 + IMPORTLIB = dwmapi + + EXTRADLLFLAGS = -Wb,--prefer-native +diff --git a/dlls/dwmapi/dwmapi_main.c b/dlls/dwmapi/dwmapi_main.c +index cec20220ec2..aff7afe48b2 100644 +--- a/dlls/dwmapi/dwmapi_main.c ++++ b/dlls/dwmapi/dwmapi_main.c +@@ -197,9 +197,46 @@ BOOL WINAPI DwmDefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, + */ + HRESULT WINAPI DwmGetWindowAttribute(HWND hwnd, DWORD attribute, PVOID pv_attribute, DWORD size) + { +- FIXME("(%p %ld %p %ld) stub\n", hwnd, attribute, pv_attribute, size); +- +- return E_NOTIMPL; ++ BOOL enabled = FALSE; ++ HRESULT hr; ++ ++ TRACE("(%p %ld %p %ld)\n", hwnd, attribute, pv_attribute, size); ++ ++ if (DwmIsCompositionEnabled(&enabled) == S_OK && !enabled) ++ return E_HANDLE; ++ if (!IsWindow(hwnd)) ++ return E_HANDLE; ++ ++ switch (attribute) { ++ case DWMWA_EXTENDED_FRAME_BOUNDS: ++ { ++ RECT *rect = (RECT *)pv_attribute; ++ DPI_AWARENESS_CONTEXT context; ++ ++ if (!rect) ++ return E_INVALIDARG; ++ if (size < sizeof(*rect)) ++ return E_NOT_SUFFICIENT_BUFFER; ++ if (GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD) ++ return E_HANDLE; ++ ++ /* DWM frame bounds are always in physical coords */ ++ context = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); ++ if (GetWindowRect(hwnd, rect)) ++ hr = S_OK; ++ else ++ hr = HRESULT_FROM_WIN32(GetLastError()); ++ ++ SetThreadDpiAwarenessContext(context); ++ break; ++ } ++ default: ++ FIXME("attribute %ld not implemented.\n", attribute); ++ hr = E_NOTIMPL; ++ break; ++ } ++ ++ return hr; + } + + /********************************************************************** +@@ -212,16 +249,50 @@ HRESULT WINAPI DwmRegisterThumbnail(HWND dest, HWND src, PHTHUMBNAIL thumbnail_i + return E_NOTIMPL; + } + ++static int get_display_frequency(void) ++{ ++ DEVMODEA mode; ++ ++ memset(&mode, 0, sizeof(mode)); ++ mode.dmSize = sizeof(mode); ++ if (EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &mode)) ++ return mode.dmDisplayFrequency; ++ else ++ { ++ WARN("Failed to query display frequency, returning a fallback value.\n"); ++ return 60; ++ } ++} ++ + /********************************************************************** + * DwmGetCompositionTimingInfo (DWMAPI.@) + */ + HRESULT WINAPI DwmGetCompositionTimingInfo(HWND hwnd, DWM_TIMING_INFO *info) + { +- static int i; ++ LARGE_INTEGER performance_frequency; ++ static int i, display_frequency; ++ ++ if (!info) ++ return E_INVALIDARG; ++ ++ if (info->cbSize != sizeof(DWM_TIMING_INFO)) ++ return MILERR_MISMATCHED_SIZE; + + if(!i++) FIXME("(%p %p)\n", hwnd, info); + +- return E_NOTIMPL; ++ memset(info, 0, info->cbSize); ++ info->cbSize = sizeof(DWM_TIMING_INFO); ++ ++ display_frequency = get_display_frequency(); ++ info->rateRefresh.uiNumerator = display_frequency; ++ info->rateRefresh.uiDenominator = 1; ++ info->rateCompose.uiNumerator = display_frequency; ++ info->rateCompose.uiDenominator = 1; ++ ++ QueryPerformanceFrequency(&performance_frequency); ++ info->qpcRefreshPeriod = performance_frequency.QuadPart / display_frequency; ++ ++ return S_OK; + } + + /********************************************************************** +diff --git a/dlls/dwmapi/tests/Makefile.in b/dlls/dwmapi/tests/Makefile.in +index 6c6130401d6..e819e3ca09a 100644 +--- a/dlls/dwmapi/tests/Makefile.in ++++ b/dlls/dwmapi/tests/Makefile.in +@@ -1,5 +1,5 @@ + TESTDLL = dwmapi.dll +-IMPORTS = dwmapi ++IMPORTS = dwmapi user32 + + C_SRCS = \ + dwmapi.c +diff --git a/dlls/dwmapi/tests/dwmapi.c b/dlls/dwmapi/tests/dwmapi.c +index 7cb9eb424f1..a89a1fd705b 100644 +--- a/dlls/dwmapi/tests/dwmapi.c ++++ b/dlls/dwmapi/tests/dwmapi.c +@@ -33,7 +33,116 @@ static void test_DwmIsCompositionEnabled(void) + ok(enabled == TRUE || enabled == FALSE, "Got unexpected %#x.\n", enabled); + } + ++static void test_DwmGetCompositionTimingInfo(void) ++{ ++ LARGE_INTEGER performance_frequency; ++ int result, display_frequency; ++ DWM_TIMING_INFO timing_info; ++ QPC_TIME refresh_period; ++ DEVMODEA mode; ++ BOOL enabled; ++ HRESULT hr; ++ ++ enabled = FALSE; ++ hr = DwmIsCompositionEnabled(&enabled); ++ ok(hr == S_OK, "Got hr %#lx.\n", hr); ++ ++ if (!enabled) ++ { ++ skip("DWM is disabled.\n"); ++ return; ++ } ++ ++ hr = DwmGetCompositionTimingInfo(NULL, NULL); ++ ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); ++ ++ memset(&timing_info, 0, sizeof(timing_info)); ++ hr = DwmGetCompositionTimingInfo(NULL, &timing_info); ++ ok(hr == MILERR_MISMATCHED_SIZE, "Got hr %#lx.\n", hr); ++ ++ memset(&mode, 0, sizeof(mode)); ++ mode.dmSize = sizeof(mode); ++ result = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &mode); ++ ok(!!result, "Failed to get display mode %#lx.\n", GetLastError()); ++ display_frequency = mode.dmDisplayFrequency; ++ ok(!!QueryPerformanceFrequency(&performance_frequency), "Failed to get performance counter frequency.\n"); ++ refresh_period = performance_frequency.QuadPart / display_frequency; ++ ++ timing_info.cbSize = sizeof(timing_info); ++ hr = DwmGetCompositionTimingInfo(NULL, &timing_info); ++ ok(hr == S_OK, "Got hr %#lx.\n", hr); ++ ok(timing_info.cbSize == sizeof(timing_info), "Got wrong struct size %d.\n", timing_info.cbSize); ++ ok(timing_info.rateRefresh.uiDenominator == 1 && timing_info.rateRefresh.uiNumerator == display_frequency, ++ "Got wrong monitor refresh rate %d/%d.\n", timing_info.rateRefresh.uiDenominator, ++ timing_info.rateRefresh.uiNumerator); ++ ok(timing_info.rateCompose.uiDenominator == 1 && timing_info.rateCompose.uiNumerator == display_frequency, ++ "Got wrong composition rate %d/%d.\n", timing_info.rateCompose.uiDenominator, ++ timing_info.rateCompose.uiNumerator); ++ ok(timing_info.qpcRefreshPeriod == refresh_period ++ || broken(timing_info.qpcRefreshPeriod == display_frequency), /* win10 v1507 */ ++ "Got wrong monitor refresh period %s.\n", wine_dbgstr_longlong(timing_info.qpcRefreshPeriod)); ++} ++ ++static void test_DWMWA_EXTENDED_FRAME_BOUNDS(void) ++{ ++ DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); ++ DPI_AWARENESS_CONTEXT old_context = NULL; ++ BOOL enabled; ++ HRESULT hr; ++ RECT rect, window_rect, intersection; ++ HWND hwnd, child; ++ ++ pSetThreadDpiAwarenessContext = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), ++ "SetThreadDpiAwarenessContext"); ++ if (pSetThreadDpiAwarenessContext) ++ old_context = pSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); ++ ++ hwnd = CreateWindowW(L"static", L"static", WS_OVERLAPPEDWINDOW | WS_POPUP | WS_VISIBLE, 10, 10, 200, 200, NULL, NULL, NULL, NULL); ++ child = CreateWindowW(L"edit", L"edit", WS_CHILD | WS_VISIBLE, 0, 0, 50, 50, hwnd, NULL, NULL, NULL); ++ ++ DwmIsCompositionEnabled(&enabled); ++ hr = DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(rect)); ++ if (!enabled) { ++ ok(hr == E_HANDLE, "Got hr %#lx.\n", hr); ++ skip("DWM is disabled.\n"); ++ goto cleanup; ++ } ++ ++ hr = DwmGetWindowAttribute(NULL, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(rect)); ++ ok(hr == E_HANDLE, "Got hr %#lx.\n", hr); ++ hr = DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &enabled, sizeof(enabled)); ++ ok(hr == E_NOT_SUFFICIENT_BUFFER, "Got hr %#lx.\n", hr); ++ hr = DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, NULL, 0); ++ ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); ++ hr = DwmGetWindowAttribute(child, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(rect)); ++ ok(hr == E_HANDLE, "Got hr %#lx.\n", hr); ++ hr = DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(rect)); ++ ok(hr == S_OK, "Got hr %#lx.\n", hr); ++ ++ /* Window rectangle covers extended frame */ ++ GetWindowRect(hwnd, &window_rect); ++ IntersectRect(&intersection, &window_rect, &rect); ++ ok(EqualRect(&intersection, &rect), "Got wrong frame %s, window %s.\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&window_rect)); ++ ++ /* Extended frame bounds aren't adjusted for DPI */ ++ if (pSetThreadDpiAwarenessContext) { ++ RECT unaware_rect; ++ pSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE); ++ hr = DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &unaware_rect, sizeof(unaware_rect)); ++ ok(hr == S_OK, "Got hr %#lx.\n", hr); ++ ok(EqualRect(&rect, &unaware_rect), "Expected %s, got %s.\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&unaware_rect)); ++ } ++ ++cleanup: ++ if (pSetThreadDpiAwarenessContext) ++ pSetThreadDpiAwarenessContext(old_context); ++ DestroyWindow(child); ++ DestroyWindow(hwnd); ++} ++ + START_TEST(dwmapi) + { + test_DwmIsCompositionEnabled(); ++ test_DwmGetCompositionTimingInfo(); ++ test_DWMWA_EXTENDED_FRAME_BOUNDS(); + } +diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec +index 341eadef19f..c25a22a0cfe 100644 +--- a/dlls/kernel32/kernel32.spec ++++ b/dlls/kernel32/kernel32.spec +@@ -694,6 +694,7 @@ + @ stdcall -import GetFinalPathNameByHandleW(long ptr long long) + @ stdcall GetFirmwareEnvironmentVariableA(str str ptr long) + @ stdcall GetFirmwareEnvironmentVariableW(wstr wstr ptr long) ++@ stdcall GetFirmwareType(ptr) + @ stdcall -import GetFullPathNameA(str long ptr ptr) + # @ stub GetFullPathNameTransactedA + # @ stub GetFullPathNameTransactedW +@@ -1448,6 +1449,7 @@ + @ stdcall SetProcessAffinityMask(long long) + @ stdcall -import SetProcessAffinityUpdateMode(long long) + @ stdcall SetProcessDEPPolicy(long) ++@ stdcall -import SetProcessInformation(long long ptr long) + @ stdcall -import SetProcessMitigationPolicy(long ptr long) + @ stdcall -import SetProcessPreferredUILanguages(long ptr ptr) + @ stdcall -import SetProcessPriorityBoost(long long) +diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c +index 4630043645c..e9e18925911 100644 +--- a/dlls/kernel32/process.c ++++ b/dlls/kernel32/process.c +@@ -740,6 +740,18 @@ BOOL WINAPI SetFirmwareEnvironmentVariableW(const WCHAR *name, const WCHAR *guid + return FALSE; + } + ++/*********************************************************************** ++ * GetFirmwareType (KERNEL32.@) ++ */ ++BOOL WINAPI GetFirmwareType(FIRMWARE_TYPE *type) ++{ ++ if (!type) ++ return FALSE; ++ ++ *type = FirmwareTypeUnknown; ++ return TRUE; ++} ++ + /********************************************************************** + * GetNumaNodeProcessorMask (KERNEL32.@) + */ +diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c +index c1312bd8916..560759aacda 100644 +--- a/dlls/kernel32/tests/process.c ++++ b/dlls/kernel32/tests/process.c +@@ -3727,7 +3727,7 @@ static void test_process_info(HANDLE hproc) + 0 /* FIXME: sizeof(?) ProcessTlsInformation */, + sizeof(ULONG) /* ProcessCookie */, + sizeof(SECTION_IMAGE_INFORMATION) /* ProcessImageInformation */, +- 0 /* FIXME: sizeof(PROCESS_CYCLE_TIME_INFORMATION) ProcessCycleTime */, ++ sizeof(PROCESS_CYCLE_TIME_INFORMATION) /* ProcessCycleTime */, + sizeof(ULONG) /* ProcessPagePriority */, + 40 /* ProcessInstrumentationCallback */, + 0 /* FIXME: sizeof(PROCESS_STACK_ALLOCATION_INFORMATION) ProcessThreadStackAllocation */, +@@ -3797,6 +3797,7 @@ static void test_process_info(HANDLE hproc) + case ProcessHandleCount: + case ProcessImageFileName: + case ProcessImageInformation: ++ case ProcessCycleTime: + case ProcessPagePriority: + case ProcessImageFileNameWin32: + ok(status == STATUS_SUCCESS, "for info %lu expected STATUS_SUCCESS, got %08lx (ret_len %lu)\n", i, status, ret_len); +diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c +index 365194b9065..eef8dc86fdf 100644 +--- a/dlls/kernel32/tests/virtual.c ++++ b/dlls/kernel32/tests/virtual.c +@@ -50,7 +50,6 @@ static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID); + static BOOL (WINAPI *pGetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL); + static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); + static NTSTATUS (WINAPI *pNtProtectVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG *); +-static PVOID (WINAPI *pVirtualAllocFromApp)(PVOID, SIZE_T, DWORD, DWORD); + + /* ############################### */ + +@@ -444,39 +443,6 @@ static void test_VirtualAlloc(void) + ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n"); + } + +-static void test_VirtualAllocFromApp(void) +-{ +- void *p; +- BOOL ret; +- if (!pVirtualAllocFromApp) +- { +- win_skip("VirtualAllocFromApp is not available.\n"); +- return; +- } +- +- p = GetProcAddress(hkernel32, "VirtualAllocFromApp"); +- ok(!p, "Found VirtualAllocFromApp in kernel32.dll.\n"); +- +- SetLastError(0xdeadbeef); +- p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_READWRITE); +- ok(p && GetLastError() == 0xdeadbeef, "Got unexpected mem %p, GetLastError() %lu.\n", p, GetLastError()); +- ret = VirtualFree(p, 0, MEM_RELEASE); +- ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError()); +- +- SetLastError(0xdeadbeef); +- p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE); +- ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", +- p, GetLastError()); +- SetLastError(0xdeadbeef); +- p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE_READ); +- ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", +- p, GetLastError()); +- SetLastError(0xdeadbeef); +- p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE_READWRITE); +- ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", +- p, GetLastError()); +-} +- + static void test_MapViewOfFile(void) + { + static const char testfile[] = "testfile.xxx"; +@@ -4294,7 +4260,6 @@ START_TEST(virtual) + pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlAddVectoredExceptionHandler" ); + pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlRemoveVectoredExceptionHandler" ); + pNtProtectVirtualMemory = (void *)GetProcAddress( hntdll, "NtProtectVirtualMemory" ); +- pVirtualAllocFromApp = (void *)GetProcAddress( hkernelbase, "VirtualAllocFromApp" ); + + GetSystemInfo(&si); + trace("system page size %#lx\n", si.dwPageSize); +@@ -4309,7 +4274,6 @@ START_TEST(virtual) + test_VirtualProtect(); + test_VirtualAllocEx(); + test_VirtualAlloc(); +- test_VirtualAllocFromApp(); + test_MapViewOfFile(); + test_NtAreMappedFilesTheSame(); + test_CreateFileMapping(); +diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec +index ae6bc842f7b..110c318c672 100644 +--- a/dlls/kernelbase/kernelbase.spec ++++ b/dlls/kernelbase/kernelbase.spec +@@ -981,6 +981,7 @@ + # @ stub MapPredefinedHandleInternal + @ stdcall MapUserPhysicalPages(ptr long ptr) + @ stdcall MapViewOfFile(long long long long long) ++@ stdcall MapViewOfFile3(long long ptr int64 long long long ptr long) + @ stdcall MapViewOfFileEx(long long long long long ptr) + @ stdcall MapViewOfFileExNuma(long long long long long ptr long) + # @ stub MapViewOfFileFromApp +@@ -1491,7 +1492,7 @@ + @ stdcall SetProcessAffinityUpdateMode(long long) + # @ stub SetProcessDefaultCpuSets + @ stdcall SetProcessGroupAffinity(long ptr ptr) +-# @ stub SetProcessInformation ++@ stdcall SetProcessInformation(long long ptr long) + @ stdcall SetProcessMitigationPolicy(long ptr long) + @ stdcall SetProcessPreferredUILanguages(long ptr ptr) + @ stdcall SetProcessPriorityBoost(long long) +diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c +index 83a40a7cd5a..7d54e48eb44 100644 +--- a/dlls/kernelbase/memory.c ++++ b/dlls/kernelbase/memory.c +@@ -247,6 +247,24 @@ LPVOID WINAPI DECLSPEC_HOTPATCH MapViewOfFileEx( HANDLE handle, DWORD access, DW + return addr; + } + ++/*********************************************************************** ++ * MapViewOfFile3 (kernelbase.@) ++ */ ++LPVOID WINAPI DECLSPEC_HOTPATCH MapViewOfFile3( HANDLE handle, HANDLE process, PVOID baseaddr, ULONG64 offset, ++ SIZE_T size, ULONG alloc_type, ULONG protection, MEM_EXTENDED_PARAMETER *params, ULONG params_count ) ++{ ++ LARGE_INTEGER off; ++ void *addr; ++ ++ addr = baseaddr; ++ off.QuadPart = offset; ++ if (!set_ntstatus( NtMapViewOfSectionEx( handle, process, &addr, &off, &size, alloc_type, protection, ++ params, params_count ))) ++ { ++ return NULL; ++ } ++ return addr; ++} + + /*********************************************************************** + * ReadProcessMemory (kernelbase.@) +diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c +index aebc647b175..c99762dc278 100644 +--- a/dlls/kernelbase/process.c ++++ b/dlls/kernelbase/process.c +@@ -861,6 +861,26 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW( const WCHAR *app_name, WCHAR *cmd_ + } + + ++/********************************************************************** ++ * SetProcessInformation (kernelbase.@) ++ */ ++BOOL WINAPI SetProcessInformation( HANDLE process, PROCESS_INFORMATION_CLASS info_class, void *info, DWORD size ) ++{ ++ switch (info_class) ++ { ++ case ProcessMemoryPriority: ++ return set_ntstatus( NtSetInformationProcess( process, ProcessPagePriority, info, size )); ++ case ProcessPowerThrottling: ++ return set_ntstatus( NtSetInformationProcess( process, ProcessPowerThrottlingState, info, size )); ++ case ProcessLeapSecondInfo: ++ return set_ntstatus( NtSetInformationProcess( process, ProcessLeapSecondInformation, info, size )); ++ default: ++ FIXME("Unrecognized information class %d.\n", info_class); ++ return FALSE; ++ } ++} ++ ++ + /********************************************************************* + * DuplicateHandle (kernelbase.@) + */ +@@ -1248,10 +1268,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH ProcessIdToSessionId( DWORD pid, DWORD *id ) + */ + BOOL WINAPI DECLSPEC_HOTPATCH QueryProcessCycleTime( HANDLE process, ULONG64 *cycle ) + { +- static int once; +- if (!once++) FIXME( "(%p,%p): stub!\n", process, cycle ); +- SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); +- return FALSE; ++ PROCESS_CYCLE_TIME_INFORMATION time; ++ ++ if (!set_ntstatus( NtQueryInformationProcess( process, ProcessCycleTime, &time, sizeof(time), NULL ) )) ++ return FALSE; ++ ++ *cycle = time.AccumulatedCycles; ++ return TRUE; + } + + +@@ -1867,85 +1890,60 @@ BOOL WINAPI DECLSPEC_HOTPATCH InitializeProcThreadAttributeList( struct _PROC_TH + } + + +-/*********************************************************************** +- * UpdateProcThreadAttribute (kernelbase.@) +- */ +-BOOL WINAPI DECLSPEC_HOTPATCH UpdateProcThreadAttribute( struct _PROC_THREAD_ATTRIBUTE_LIST *list, +- DWORD flags, DWORD_PTR attr, void *value, +- SIZE_T size, void *prev_ret, SIZE_T *size_ret ) ++static inline DWORD validate_proc_thread_attribute( DWORD_PTR attr, SIZE_T size ) + { +- DWORD mask; +- struct proc_thread_attr *entry; +- +- TRACE( "(%p %lx %08Ix %p %Id %p %p)\n", list, flags, attr, value, size, prev_ret, size_ret ); +- +- if (list->count >= list->size) +- { +- SetLastError( ERROR_GEN_FAILURE ); +- return FALSE; +- } +- + switch (attr) + { + case PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: +- if (size != sizeof(HANDLE)) +- { +- SetLastError( ERROR_BAD_LENGTH ); +- return FALSE; +- } ++ if (size != sizeof(HANDLE)) return ERROR_BAD_LENGTH; + break; +- + case PROC_THREAD_ATTRIBUTE_HANDLE_LIST: +- if ((size / sizeof(HANDLE)) * sizeof(HANDLE) != size) +- { +- SetLastError( ERROR_BAD_LENGTH ); +- return FALSE; +- } ++ if ((size / sizeof(HANDLE)) * sizeof(HANDLE) != size) return ERROR_BAD_LENGTH; + break; +- + case PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR: +- if (size != sizeof(PROCESSOR_NUMBER)) +- { +- SetLastError( ERROR_BAD_LENGTH ); +- return FALSE; +- } ++ if (size != sizeof(PROCESSOR_NUMBER)) return ERROR_BAD_LENGTH; + break; +- + case PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY: +- if (size != sizeof(DWORD) && size != sizeof(DWORD64)) +- { +- SetLastError( ERROR_BAD_LENGTH ); +- return FALSE; +- } ++ if (size != sizeof(DWORD) && size != sizeof(DWORD64)) return ERROR_BAD_LENGTH; + break; +- + case PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY: + if (size != sizeof(DWORD) && size != sizeof(DWORD64) && size != sizeof(DWORD64) * 2) +- { +- SetLastError( ERROR_BAD_LENGTH ); +- return FALSE; +- } ++ return ERROR_BAD_LENGTH; + break; +- + case PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE: +- if (size != sizeof(HPCON)) +- { +- SetLastError( ERROR_BAD_LENGTH ); +- return FALSE; +- } ++ if (size != sizeof(HPCON)) return ERROR_BAD_LENGTH; + break; +- + case PROC_THREAD_ATTRIBUTE_JOB_LIST: +- if ((size / sizeof(HANDLE)) * sizeof(HANDLE) != size) +- { +- SetLastError( ERROR_BAD_LENGTH ); +- return FALSE; +- } ++ if ((size / sizeof(HANDLE)) * sizeof(HANDLE) != size) return ERROR_BAD_LENGTH; + break; +- + default: +- SetLastError( ERROR_NOT_SUPPORTED ); + FIXME( "Unhandled attribute %Iu\n", attr & PROC_THREAD_ATTRIBUTE_NUMBER ); ++ return ERROR_NOT_SUPPORTED; ++ } ++ return 0; ++} ++ ++ ++/*********************************************************************** ++ * UpdateProcThreadAttribute (kernelbase.@) ++ */ ++BOOL WINAPI DECLSPEC_HOTPATCH UpdateProcThreadAttribute( struct _PROC_THREAD_ATTRIBUTE_LIST *list, ++ DWORD flags, DWORD_PTR attr, void *value, ++ SIZE_T size, void *prev_ret, SIZE_T *size_ret ) ++{ ++ DWORD mask, err; ++ struct proc_thread_attr *entry; ++ ++ TRACE( "(%p %lx %08Ix %p %Id %p %p)\n", list, flags, attr, value, size, prev_ret, size_ret ); ++ ++ if (list->count >= list->size) ++ { ++ SetLastError( ERROR_GEN_FAILURE ); ++ return FALSE; ++ } ++ if ((err = validate_proc_thread_attribute( attr, size ))) ++ { ++ SetLastError( err ); + return FALSE; + } + +diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c +index d119dca650d..a8862a07e30 100644 +--- a/dlls/kernelbase/tests/process.c ++++ b/dlls/kernelbase/tests/process.c +@@ -31,6 +31,10 @@ + #include "wine/test.h" + + static BOOL (WINAPI *pCompareObjectHandles)(HANDLE, HANDLE); ++static LPVOID (WINAPI *pMapViewOfFile3)(HANDLE, HANDLE, PVOID, ULONG64 offset, SIZE_T size, ++ ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG); ++static LPVOID (WINAPI *pVirtualAlloc2)(HANDLE, void *, SIZE_T, DWORD, DWORD, MEM_EXTENDED_PARAMETER *, ULONG); ++static PVOID (WINAPI *pVirtualAllocFromApp)(PVOID, SIZE_T, DWORD, DWORD); + + static void test_CompareObjectHandles(void) + { +@@ -89,16 +93,236 @@ static void test_CompareObjectHandles(void) + CloseHandle( h1 ); + } + +-START_TEST(process) ++static void test_MapViewOfFile3(void) ++{ ++ static const char testfile[] = "testfile.xxx"; ++ HANDLE file, mapping; ++ void *ptr; ++ BOOL ret; ++ ++ if (!pMapViewOfFile3) ++ { ++ win_skip("MapViewOfFile3() is not supported.\n"); ++ return; ++ } ++ ++ SetLastError(0xdeadbeef); ++ file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); ++ ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() ); ++ SetFilePointer( file, 12288, NULL, FILE_BEGIN ); ++ SetEndOfFile( file ); ++ ++ SetLastError(0xdeadbeef); ++ mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL ); ++ ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() ); ++ ++ SetLastError(0xdeadbeef); ++ ptr = pMapViewOfFile3( mapping, GetCurrentProcess(), NULL, 0, 4096, 0, PAGE_READONLY, NULL, 0); ++ ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() ); ++ UnmapViewOfFile( ptr ); ++ ++ CloseHandle( mapping ); ++ CloseHandle( file ); ++ ret = DeleteFileA( testfile ); ++ ok(ret, "Failed to delete a test file.\n"); ++} ++ ++#define check_region_size(p, s) check_region_size_(p, s, __LINE__) ++static void check_region_size_(void *p, SIZE_T s, unsigned int line) ++{ ++ MEMORY_BASIC_INFORMATION info; ++ SIZE_T ret; ++ ++ memset(&info, 0, sizeof(info)); ++ ret = VirtualQuery(p, &info, sizeof(info)); ++ ok_(__FILE__,line)(ret == sizeof(info), "Unexpected return value.\n"); ++ ok_(__FILE__,line)(info.RegionSize == s, "Unexpected size %Iu, expected %Iu.\n", info.RegionSize, s); ++} ++ ++static void test_VirtualAlloc2(void) ++{ ++ void *placeholder1, *placeholder2, *view1, *view2, *addr; ++ MEMORY_BASIC_INFORMATION info; ++ char *p, *p1, *p2; ++ HANDLE section; ++ SIZE_T size; ++ BOOL ret; ++ ++ if (!pVirtualAlloc2) ++ { ++ win_skip("VirtualAlloc2() is not supported.\n"); ++ return; ++ } ++ ++ size = 0x80000; ++ addr = pVirtualAlloc2(NULL, NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE, NULL, 0); ++ todo_wine ++ ok(!!addr, "Failed to allocate, error %lu.\n", GetLastError()); ++ ret = VirtualFree(addr, 0, MEM_RELEASE); ++ todo_wine ++ ok(ret, "Unexpected return value %d, error %lu.\n", ret, GetLastError()); ++ ++ /* Placeholder splitting functionality */ ++ placeholder1 = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); ++ todo_wine ++ ok(!!placeholder1, "Failed to create a placeholder range.\n"); ++ if (!placeholder1) return; ++ ++ memset(&info, 0, sizeof(info)); ++ VirtualQuery(placeholder1, &info, sizeof(info)); ++ ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect); ++ ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State); ++ ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type); ++ ok(info.RegionSize == 2 * size, "Unexpected size.\n"); ++ ++ ret = VirtualFree(placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); ++ ok(ret, "Failed to split placeholder.\n"); ++ ++ memset(&info, 0, sizeof(info)); ++ VirtualQuery(placeholder1, &info, sizeof(info)); ++ ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect); ++ ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State); ++ ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type); ++ ok(info.RegionSize == size, "Unexpected size.\n"); ++ ++ placeholder2 = (void *)((BYTE *)placeholder1 + size); ++ memset(&info, 0, sizeof(info)); ++ VirtualQuery(placeholder2, &info, sizeof(info)); ++ ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect); ++ ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State); ++ ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type); ++ ok(info.RegionSize == size, "Unexpected size.\n"); ++ ++ section = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, NULL); ++ ok(!!section, "Failed to create a section.\n"); ++ ++ view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); ++ ok(!!view1, "Failed to map a section.\n"); ++ ++ view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); ++ ok(!!view2, "Failed to map a section.\n"); ++ ++ CloseHandle(section); ++ UnmapViewOfFile(view1); ++ UnmapViewOfFile(view2); ++ ++ VirtualFree(placeholder1, 0, MEM_RELEASE); ++ VirtualFree(placeholder2, 0, MEM_RELEASE); ++ ++ /* Split in three regions. */ ++ p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); ++ ok(!!p, "Failed to create a placeholder range.\n"); ++ ++ p1 = p + size / 2; ++ p2 = p1 + size / 4; ++ ret = VirtualFree(p1, size / 4, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); ++ ok(ret, "Failed to split a placeholder.\n"); ++ check_region_size(p, size / 2); ++ check_region_size(p1, size / 4); ++ check_region_size(p2, 2 * size - size / 2 - size / 4); ++ ret = VirtualFree(p, 0, MEM_RELEASE); ++ ok(ret, "Failed to release a region.\n"); ++ ret = VirtualFree(p1, 0, MEM_RELEASE); ++ ok(ret, "Failed to release a region.\n"); ++ ret = VirtualFree(p2, 0, MEM_RELEASE); ++ ok(ret, "Failed to release a region.\n"); ++ ++ /* Split in two regions, specifying lower part. */ ++ p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); ++ ok(!!p, "Failed to create a placeholder range.\n"); ++ ++ p1 = p; ++ p2 = p + size / 2; ++ ret = VirtualFree(p1, size / 2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); ++ ok(ret, "Failed to split a placeholder.\n"); ++ check_region_size(p1, size / 2); ++ check_region_size(p2, 2 * size - size / 2); ++ ret = VirtualFree(p1, 0, MEM_RELEASE); ++ ok(ret, "Failed to release a region.\n"); ++ ret = VirtualFree(p2, 0, MEM_RELEASE); ++ ok(ret, "Failed to release a region.\n"); ++ ++ /* Split in two regions, specifying second half. */ ++ p = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); ++ ok(!!p, "Failed to create a placeholder range.\n"); ++ ++ p1 = p; ++ p2 = p + size; ++ ret = VirtualFree(p2, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); ++ ok(ret, "Failed to split a placeholder.\n"); ++ check_region_size(p1, size); ++ check_region_size(p2, size); ++ ret = VirtualFree(p1, 0, MEM_RELEASE); ++ ok(ret, "Failed to release a region.\n"); ++ ret = VirtualFree(p2, 0, MEM_RELEASE); ++ ok(ret, "Failed to release a region.\n"); ++} ++ ++static void test_VirtualAllocFromApp(void) + { +- HMODULE hmod; ++ BOOL ret; ++ void *p; ++ ++ if (!pVirtualAllocFromApp) ++ { ++ win_skip("VirtualAllocFromApp is not available.\n"); ++ return; ++ } + +- hmod = GetModuleHandleA("kernel32.dll"); +- pCompareObjectHandles = (void *)GetProcAddress(hmod, "CompareObjectHandles"); +- ok(!pCompareObjectHandles, "expected CompareObjectHandles only in kernelbase.dll\n"); ++ SetLastError(0xdeadbeef); ++ p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_READWRITE); ++ ok(p && GetLastError() == 0xdeadbeef, "Got unexpected mem %p, GetLastError() %lu.\n", p, GetLastError()); ++ ret = VirtualFree(p, 0, MEM_RELEASE); ++ ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError()); + +- hmod = GetModuleHandleA("kernelbase.dll"); +- pCompareObjectHandles = (void *)GetProcAddress(hmod, "CompareObjectHandles"); ++ SetLastError(0xdeadbeef); ++ p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE); ++ ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", ++ p, GetLastError()); ++ SetLastError(0xdeadbeef); ++ p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE_READ); ++ ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", ++ p, GetLastError()); ++ SetLastError(0xdeadbeef); ++ p = pVirtualAllocFromApp(NULL, 0x1000, MEM_RESERVE, PAGE_EXECUTE_READWRITE); ++ ok(!p && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected mem %p, GetLastError() %lu.\n", ++ p, GetLastError()); ++} ++ ++static void test_QueryProcessCycleTime(void) ++{ ++ ULONG64 cycles1, cycles2; ++ BOOL ret; ++ ++ ret = QueryProcessCycleTime( GetCurrentProcess(), &cycles1 ); ++ ok( ret, "QueryProcessCycleTime failed, error %lu.\n", GetLastError() ); ++ ++ ret = QueryProcessCycleTime( GetCurrentProcess(), &cycles2 ); ++ ok( ret, "QueryProcessCycleTime failed, error %lu.\n", GetLastError() ); ++ ++ todo_wine ++ ok( cycles2 > cycles1, "CPU cycles used by process should be increasing.\n" ); ++} ++ ++static void init_funcs(void) ++{ ++ HMODULE hmod = GetModuleHandleA("kernelbase.dll"); ++ ++#define X(f) { p##f = (void*)GetProcAddress(hmod, #f); } ++ X(CompareObjectHandles); ++ X(MapViewOfFile3); ++ X(VirtualAlloc2); ++ X(VirtualAllocFromApp); ++#undef X ++} ++ ++START_TEST(process) ++{ ++ init_funcs(); + + test_CompareObjectHandles(); ++ test_MapViewOfFile3(); ++ test_VirtualAlloc2(); ++ test_VirtualAllocFromApp(); ++ test_QueryProcessCycleTime(); + } +diff --git a/dlls/msmpeg2vdec/Makefile.in b/dlls/msmpeg2vdec/Makefile.in +new file mode 100644 +index 00000000000..609c6a34f9a +--- /dev/null ++++ b/dlls/msmpeg2vdec/Makefile.in +@@ -0,0 +1,4 @@ ++MODULE = msmpeg2vdec.dll ++ ++C_SRCS = \ ++ main.c +diff --git a/dlls/msmpeg2vdec/main.c b/dlls/msmpeg2vdec/main.c +new file mode 100644 +index 00000000000..0ff52f5d1cb +--- /dev/null ++++ b/dlls/msmpeg2vdec/main.c +@@ -0,0 +1,27 @@ ++/* ++ * Copyright (C) 2023 Mohamad Al-Jaf ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(msmpeg2vdec); ++ ++HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) ++{ ++ FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out ); ++ return CLASS_E_CLASSNOTAVAILABLE; ++} +diff --git a/dlls/msmpeg2vdec/msmpeg2vdec.spec b/dlls/msmpeg2vdec/msmpeg2vdec.spec +new file mode 100644 +index 00000000000..b81b77ce108 +--- /dev/null ++++ b/dlls/msmpeg2vdec/msmpeg2vdec.spec +@@ -0,0 +1,8 @@ ++@ stub GetH264DecoderFunctionTable ++@ stub ?GetSurface@CVIDEOfilter@@QEAAJHPEAEJ@Z ++@ stub ?GetSurfaceSize@CVIDEOfilter@@QEAAJHPEAJ@Z ++@ stub ?LoadSurface@CVIDEOfilter@@QEAAJHPEAEK@Z ++@ stdcall -private DllCanUnloadNow() ++@ stdcall -private DllGetClassObject(ptr ptr ptr) ++@ stdcall -private DllRegisterServer() ++@ stdcall -private DllUnregisterServer() +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 492b5f42646..c654526916a 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -253,6 +253,7 @@ + # @ stub NtMapUserPhysicalPages + # @ stub NtMapUserPhysicalPagesScatter + @ stdcall -syscall NtMapViewOfSection(long long ptr long long ptr ptr long long long) ++@ stdcall -syscall NtMapViewOfSectionEx(long long ptr ptr ptr long long ptr long) + # @ stub NtModifyBootEntry + @ stdcall -syscall NtNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) + @ stdcall -syscall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long) +@@ -1279,6 +1280,7 @@ + # @ stub ZwMapUserPhysicalPages + # @ stub ZwMapUserPhysicalPagesScatter + @ stdcall -private -syscall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) NtMapViewOfSection ++@ stdcall -private -syscall ZwMapViewOfSectionEx(long long ptr ptr ptr long long ptr long) NtMapViewOfSectionEx + # @ stub ZwModifyBootEntry + @ stdcall -private -syscall ZwNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) NtNotifyChangeDirectoryFile + @ stdcall -private -syscall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) NtNotifyChangeKey +diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c +index 30a97ba9d94..aeef2ed8fb9 100644 +--- a/dlls/ntdll/tests/virtual.c ++++ b/dlls/ntdll/tests/virtual.c +@@ -39,6 +39,9 @@ static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char*); + static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); + static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG, + MEM_EXTENDED_PARAMETER *, ULONG); ++static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE, HANDLE, PVOID *, const LARGE_INTEGER *, SIZE_T *, ++ ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG); ++ + static const BOOL is_win64 = sizeof(void*) != sizeof(int); + static BOOL is_wow64; + +@@ -908,6 +911,150 @@ static void test_NtMapViewOfSection(void) + CloseHandle(process); + } + ++static void test_NtMapViewOfSectionEx(void) ++{ ++ static const char testfile[] = "testfile.xxx"; ++ static const char data[] = "test data for NtMapViewOfSectionEx"; ++ char buffer[sizeof(data)]; ++ HANDLE file, mapping, process; ++ DWORD status, written; ++ SIZE_T size, result; ++ LARGE_INTEGER offset; ++ void *ptr, *ptr2; ++ BOOL ret; ++ ++ if (!pNtMapViewOfSectionEx) ++ { ++ win_skip("NtMapViewOfSectionEx() is not supported.\n"); ++ return; ++ } ++ ++ if (!pIsWow64Process || !pIsWow64Process(NtCurrentProcess(), &is_wow64)) is_wow64 = FALSE; ++ ++ file = CreateFileA(testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); ++ ok(file != INVALID_HANDLE_VALUE, "Failed to create test file\n"); ++ WriteFile(file, data, sizeof(data), &written, NULL); ++ SetFilePointer(file, 4096, NULL, FILE_BEGIN); ++ SetEndOfFile(file); ++ ++ /* read/write mapping */ ++ ++ mapping = CreateFileMappingA(file, NULL, PAGE_READWRITE, 0, 4096, NULL); ++ ok(mapping != 0, "CreateFileMapping failed\n"); ++ ++ process = create_target_process("sleep"); ++ ok(process != NULL, "Can't start process\n"); ++ ++ ptr = NULL; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr, &offset, &size, 0, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status); ++ ok(!((ULONG_PTR)ptr & 0xffff), "returned memory %p is not aligned to 64k\n", ptr); ++ ++ ret = ReadProcessMemory(process, ptr, buffer, sizeof(buffer), &result); ++ ok(ret, "ReadProcessMemory failed\n"); ++ ok(result == sizeof(buffer), "ReadProcessMemory didn't read all data (%Ix)\n", result); ++ ok(!memcmp(buffer, data, sizeof(buffer)), "Wrong data read\n"); ++ ++ /* mapping at the same page conflicts */ ++ ptr2 = ptr; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx\n", status); ++ ++ /* offset has to be aligned */ ++ ptr2 = ptr; ++ size = 0; ++ offset.QuadPart = 1; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_MAPPED_ALIGNMENT, "Unexpected status %08lx\n", status); ++ ++ /* ptr has to be aligned */ ++ ptr2 = (char *)ptr + 42; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_MAPPED_ALIGNMENT, "Unexpected status %08lx\n", status); ++ ++ /* still not 64k aligned */ ++ ptr2 = (char *)ptr + 0x1000; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, 0, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_MAPPED_ALIGNMENT, "Unexpected status %08lx\n", status); ++ ++ if (!is_win64 && !is_wow64) ++ { ++ /* new memory region conflicts with previous mapping */ ++ ptr2 = ptr; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx\n", status); ++ ++ ptr2 = (char *)ptr + 42; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_CONFLICTING_ADDRESSES, "Unexpected status %08lx\n", status); ++ ++ /* in contrary to regular NtMapViewOfSection, only 4kb align is enforced */ ++ ptr2 = (char *)ptr + 0x1000; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status); ++ ok((char *)ptr2 == (char *)ptr + 0x1000, ++ "expected address %p, got %p\n", (char *)ptr + 0x1000, ptr2); ++ status = NtUnmapViewOfSection(process, ptr2); ++ ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status); ++ ++ /* the address is rounded down if not on a page boundary */ ++ ptr2 = (char *)ptr + 0x1001; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status); ++ ok((char *)ptr2 == (char *)ptr + 0x1000, ++ "expected address %p, got %p\n", (char *)ptr + 0x1000, ptr2); ++ status = NtUnmapViewOfSection(process, ptr2); ++ ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status); ++ ++ ptr2 = (char *)ptr + 0x2000; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0); ++ ok(status == STATUS_SUCCESS, "Unexpected status %08lx\n", status); ++ ok((char *)ptr2 == (char *)ptr + 0x2000, ++ "expected address %p, got %p\n", (char *)ptr + 0x2000, ptr2); ++ status = NtUnmapViewOfSection(process, ptr2); ++ ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status); ++ } ++ else ++ { ++ ptr2 = (char *)ptr + 0x1000; ++ size = 0; ++ offset.QuadPart = 0; ++ status = pNtMapViewOfSectionEx(mapping, process, &ptr2, &offset, &size, AT_ROUND_TO_PAGE, PAGE_READWRITE, NULL, 0); ++ todo_wine ++ ok(status == STATUS_INVALID_PARAMETER_9 || status == STATUS_INVALID_PARAMETER, ++ "NtMapViewOfSection returned %08lx\n", status); ++ } ++ ++ status = NtUnmapViewOfSection(process, ptr); ++ ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection returned %08lx\n", status); ++ ++ NtClose(mapping); ++ ++ CloseHandle(file); ++ DeleteFileA(testfile); ++ ++ TerminateProcess(process, 0); ++ CloseHandle(process); ++} ++ + #define SUPPORTED_XSTATE_FEATURES ((1 << XSTATE_LEGACY_FLOATING_POINT) | (1 << XSTATE_LEGACY_SSE) | (1 << XSTATE_AVX)) + + static void test_user_shared_data(void) +@@ -1160,6 +1307,7 @@ START_TEST(virtual) + pRtlFindExportedRoutineByName = (void *)GetProcAddress(mod, "RtlFindExportedRoutineByName"); + pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures"); + pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx"); ++ pNtMapViewOfSectionEx = (void *)GetProcAddress(mod, "NtMapViewOfSectionEx"); + + NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL); + trace("system page size %#lx\n", sbi.PageSize); +@@ -1169,6 +1317,7 @@ START_TEST(virtual) + test_NtAllocateVirtualMemory(); + test_RtlCreateUserStack(); + test_NtMapViewOfSection(); ++ test_NtMapViewOfSectionEx(); + test_user_shared_data(); + test_syscalls(); + } +diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c +index 8e54c994277..782aa5ff148 100644 +--- a/dlls/ntdll/unix/loader.c ++++ b/dlls/ntdll/unix/loader.c +@@ -213,6 +213,7 @@ static void * const syscalls[] = + NtLockVirtualMemory, + NtMakeTemporaryObject, + NtMapViewOfSection, ++ NtMapViewOfSectionEx, + NtNotifyChangeDirectoryFile, + NtNotifyChangeKey, + NtNotifyChangeMultipleKeys, +diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c +index ebb87194ce5..20a8eac13cf 100644 +--- a/dlls/ntdll/unix/process.c ++++ b/dlls/ntdll/unix/process.c +@@ -1901,7 +1901,24 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class + } + else ret = STATUS_INFO_LENGTH_MISMATCH; + break; ++ case ProcessCycleTime: ++ len = sizeof(PROCESS_CYCLE_TIME_INFORMATION); ++ if (size == len) ++ { ++ if (!info) ret = STATUS_ACCESS_VIOLATION; ++ else ++ { ++ PROCESS_CYCLE_TIME_INFORMATION cycles; + ++ FIXME( "ProcessCycleTime (%p,%p,0x%08x,%p) stub\n", handle, info, (int)size, ret_len ); ++ cycles.AccumulatedCycles = 0; ++ cycles.CurrentCycleCount = 0; ++ ++ memcpy(info, &cycles, sizeof(PROCESS_CYCLE_TIME_INFORMATION)); ++ } ++ } ++ else ret = STATUS_INFO_LENGTH_MISMATCH; ++ break; + default: + FIXME("(%p,info_class=%d,%p,0x%08x,%p) Unknown information class\n", + handle, class, info, size, ret_len ); +diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c +index 8ead2cc99d7..77b9b8c31c0 100644 +--- a/dlls/ntdll/unix/virtual.c ++++ b/dlls/ntdll/unix/virtual.c +@@ -4653,6 +4653,18 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p + offset_ptr, size_ptr, alloc_type, protect ); + } + ++/*********************************************************************** ++ * NtMapViewOfSectionEx (NTDLL.@) ++ * ZwMapViewOfSectionEx (NTDLL.@) ++ */ ++NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr_ptr, const LARGE_INTEGER *offset_ptr, ++ SIZE_T *size_ptr, ULONG alloc_type, ULONG protect, MEM_EXTENDED_PARAMETER *params, ULONG params_count ) ++{ ++ if (params) ++ FIXME("Ignoring extended parameters.\n"); ++ ++ return NtMapViewOfSection( handle, process, addr_ptr, 0, 0, offset_ptr, size_ptr, ViewShare, alloc_type, protect ); ++} + + /*********************************************************************** + * NtUnmapViewOfSection (NTDLL.@) +diff --git a/dlls/userenv/userenv.spec b/dlls/userenv/userenv.spec +index 4d8bc4ec407..6395bba1949 100644 +--- a/dlls/userenv/userenv.spec ++++ b/dlls/userenv/userenv.spec +@@ -1,5 +1,6 @@ + 138 stdcall @(long str str str str long str long long str str long) USERENV_138 + ++@ stdcall CreateAppContainerProfile(wstr wstr wstr ptr long ptr) + @ stdcall CreateEnvironmentBlock(ptr ptr long) + @ stdcall DestroyEnvironmentBlock(ptr) + @ stdcall EnterCriticalPolicySection(long) +diff --git a/dlls/userenv/userenv_main.c b/dlls/userenv/userenv_main.c +index 2b5171254dc..6a09286638b 100644 +--- a/dlls/userenv/userenv_main.c ++++ b/dlls/userenv/userenv_main.c +@@ -688,3 +688,13 @@ BOOL WINAPI USERENV_138( int csidl, LPCSTR lnk_dir, LPCSTR lnk_filename, + + return FALSE; + } ++ ++HRESULT WINAPI CreateAppContainerProfile(PCWSTR container_name, PCWSTR display_name, PCWSTR description, ++ SID_AND_ATTRIBUTES *capabilities, DWORD capability_count, ++ SID **container_sid) ++{ ++ FIXME("(%s, %s, %s, %p, %ld, %p): stub\n", debugstr_w(container_name), debugstr_w(display_name), ++ debugstr_w(description), capabilities, capability_count, container_sid); ++ ++ return E_NOTIMPL; ++} +diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c +index e8bae92853c..6221072ed37 100644 +--- a/dlls/wow64/process.c ++++ b/dlls/wow64/process.c +@@ -794,6 +794,7 @@ NTSTATUS WINAPI wow64_NtQueryInformationProcess( UINT *args ) + case ProcessDebugFlags: /* ULONG */ + case ProcessExecuteFlags: /* ULONG */ + case ProcessCookie: /* ULONG */ ++ case ProcessCycleTime: /* PROCESS_CYCLE_TIME_INFORMATION */ + /* FIXME: check buffer alignment */ + return NtQueryInformationProcess( handle, class, ptr, len, retlen ); + +@@ -1120,6 +1121,9 @@ NTSTATUS WINAPI wow64_NtSetInformationProcess( UINT *args ) + case ProcessDefaultHardErrorMode: /* ULONG */ + case ProcessPriorityClass: /* PROCESS_PRIORITY_CLASS */ + case ProcessExecuteFlags: /* ULONG */ ++ case ProcessPagePriority: /* MEMORY_PRIORITY_INFORMATION */ ++ case ProcessPowerThrottlingState: /* PROCESS_POWER_THROTTLING_STATE */ ++ case ProcessLeapSecondInformation: /* PROCESS_LEAP_SECOND_INFO */ + return NtSetInformationProcess( handle, class, ptr, len ); + + case ProcessAffinityMask: /* ULONG_PTR */ +diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h +index a354c069c46..67443bc9b48 100644 +--- a/dlls/wow64/syscall.h ++++ b/dlls/wow64/syscall.h +@@ -108,6 +108,7 @@ + SYSCALL_ENTRY( NtLockVirtualMemory ) \ + SYSCALL_ENTRY( NtMakeTemporaryObject ) \ + SYSCALL_ENTRY( NtMapViewOfSection ) \ ++ SYSCALL_ENTRY( NtMapViewOfSectionEx ) \ + SYSCALL_ENTRY( NtNotifyChangeDirectoryFile ) \ + SYSCALL_ENTRY( NtNotifyChangeKey ) \ + SYSCALL_ENTRY( NtNotifyChangeMultipleKeys ) \ +diff --git a/dlls/wow64/virtual.c b/dlls/wow64/virtual.c +index 6298bd71615..33ac9285dce 100644 +--- a/dlls/wow64/virtual.c ++++ b/dlls/wow64/virtual.c +@@ -297,6 +297,40 @@ NTSTATUS WINAPI wow64_NtMapViewOfSection( UINT *args ) + return status; + } + ++/********************************************************************** ++ * wow64_NtMapViewOfSectionEx ++ */ ++NTSTATUS WINAPI wow64_NtMapViewOfSectionEx( UINT *args ) ++{ ++ HANDLE handle = get_handle( &args ); ++ HANDLE process = get_handle( &args ); ++ ULONG *addr32 = get_ptr( &args ); ++ const LARGE_INTEGER *offset = get_ptr( &args ); ++ ULONG *size32 = get_ptr( &args ); ++ ULONG alloc = get_ulong( &args ); ++ ULONG protect = get_ulong( &args ); ++ MEM_EXTENDED_PARAMETER *params = get_ptr( &args ); ++ ULONG params_count = get_ulong( &args ); ++ ++ void *addr; ++ SIZE_T size; ++ NTSTATUS status; ++ ++ status = NtMapViewOfSectionEx( handle, process, addr_32to64( &addr, addr32 ), offset, size_32to64( &size, size32 ), alloc, ++ protect, params, params_count ); ++ if (NT_SUCCESS(status)) ++ { ++ SECTION_IMAGE_INFORMATION info; ++ ++ if (!NtQuerySection( handle, SectionImageInformation, &info, sizeof(info), NULL )) ++ { ++ if (info.Machine == current_machine) init_image_mapping( addr ); ++ } ++ put_addr( addr32, addr ); ++ put_size( size32, size ); ++ } ++ return status; ++} + + /********************************************************************** + * wow64_NtProtectVirtualMemory +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index 212c4caf20d..8189b9b5db8 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1929,7 +1929,7 @@ NTSTATUS WINAPI ZwSetEvent(HANDLE,PULONG); + NTSTATUS WINAPI ZwSetInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS); + NTSTATUS WINAPI ZwSetInformationKey(HANDLE,const int,PVOID,ULONG); + NTSTATUS WINAPI ZwSetInformationObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG); +-NTSTATUS WINAPI ZwSetInformationProcess(HANDLE,PROCESS_INFORMATION_CLASS,PVOID,ULONG); ++NTSTATUS WINAPI ZwSetInformationProcess(HANDLE,PROCESSINFOCLASS,PVOID,ULONG); + NTSTATUS WINAPI ZwSetInformationThread(HANDLE,THREADINFOCLASS,LPCVOID,ULONG); + NTSTATUS WINAPI ZwSetIoCompletion(HANDLE,ULONG,ULONG,NTSTATUS,ULONG); + NTSTATUS WINAPI ZwSetLdtEntries(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG); +diff --git a/include/winbase.h b/include/winbase.h +index 55a5c59c364..a5d489169ed 100644 +--- a/include/winbase.h ++++ b/include/winbase.h +@@ -1763,6 +1763,21 @@ typedef struct _WIN32_FIND_STREAM_DATA { + WCHAR cStreamName[MAX_PATH + 36]; + } WIN32_FIND_STREAM_DATA,*PWIN32_FIND_STREAM_DATA; + ++typedef enum _PROCESS_INFORMATION_CLASS ++{ ++ ProcessMemoryPriority, ++ ProcessMemoryExhaustionInfo, ++ ProcessAppMemoryInfo, ++ ProcessInPrivateInfo, ++ ProcessPowerThrottling, ++ ProcessReservedValue1, ++ ProcessTelemetryCoverageInfo, ++ ProcessProtectionLevelInfo, ++ ProcessLeapSecondInfo, ++ ProcessMachineTypeInfo, ++ ProcessInformationClassMax ++} PROCESS_INFORMATION_CLASS; ++ + WINBASEAPI BOOL WINAPI ActivateActCtx(HANDLE,ULONG_PTR *); + WINADVAPI BOOL WINAPI AddAccessAllowedAce(PACL,DWORD,DWORD,PSID); + WINADVAPI BOOL WINAPI AddAccessAllowedAceEx(PACL,DWORD,DWORD,DWORD,PSID); +@@ -2176,6 +2191,7 @@ WINBASEAPI DWORD WINAPI GetFileSize(HANDLE,LPDWORD); + WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE,PLARGE_INTEGER); + WINBASEAPI BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME); + WINBASEAPI DWORD WINAPI GetFileType(HANDLE); ++WINBASEAPI BOOL WINAPI GetFirmwareType(PFIRMWARE_TYPE); + #define GetFreeSpace(w) (__MSABI_LONG(0x100000)) + WINBASEAPI DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*); + WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR,DWORD,LPWSTR,LPWSTR*); +@@ -2487,6 +2503,7 @@ WINADVAPI BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_ + WINADVAPI VOID WINAPI MapGenericMask(PDWORD,PGENERIC_MAPPING); + WINBASEAPI BOOL WINAPI MapUserPhysicalPages(PVOID,ULONG_PTR,PULONG_PTR); + WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,SIZE_T); ++WINBASEAPI LPVOID WINAPI MapViewOfFile3(HANDLE,HANDLE,PVOID,ULONG64,SIZE_T,ULONG,ULONG,MEM_EXTENDED_PARAMETER*,ULONG); + WINBASEAPI LPVOID WINAPI MapViewOfFileEx(HANDLE,DWORD,DWORD,DWORD,SIZE_T,LPVOID); + WINBASEAPI BOOL WINAPI MoveFileA(LPCSTR,LPCSTR); + WINBASEAPI BOOL WINAPI MoveFileW(LPCWSTR,LPCWSTR); +@@ -2575,6 +2592,7 @@ WINBASEAPI BOOL WINAPI QueryInformationJobObject(HANDLE,JOBOBJECTINFOCLAS + WINBASEAPI BOOL WINAPI QueryMemoryResourceNotification(HANDLE,PBOOL); + WINBASEAPI BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER*); + WINBASEAPI BOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER*); ++WINBASEAPI BOOL WINAPI QueryProcessCycleTime(HANDLE,PULONG64); + WINBASEAPI BOOL WINAPI QueryThreadCycleTime(HANDLE,PULONG64); + WINBASEAPI BOOL WINAPI QueryUmsThreadInformation(PUMS_CONTEXT,UMS_THREAD_INFO_CLASS,PVOID,ULONG,PULONG); + WINBASEAPI DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,ULONG_PTR); +@@ -2675,6 +2693,7 @@ WINBASEAPI BOOL WINAPI SetPriorityClass(HANDLE,DWORD); + WINADVAPI BOOL WINAPI SetPrivateObjectSecurity(SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR*,PGENERIC_MAPPING,HANDLE); + WINADVAPI BOOL WINAPI SetPrivateObjectSecurityEx(SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR*,ULONG,PGENERIC_MAPPING,HANDLE); + WINBASEAPI BOOL WINAPI SetProcessAffinityMask(HANDLE,DWORD_PTR); ++WINBASEAPI BOOL WINAPI SetProcessInformation(HANDLE,PROCESS_INFORMATION_CLASS,LPVOID,DWORD); + WINBASEAPI BOOL WINAPI SetProcessPriorityBoost(HANDLE,BOOL); + WINBASEAPI BOOL WINAPI SetProcessShutdownParameters(DWORD,DWORD); + WINBASEAPI BOOL WINAPI SetProcessWorkingSetSize(HANDLE,SIZE_T,SIZE_T); +diff --git a/include/winerror.h b/include/winerror.h +index 1dc810ffb26..6f9b12eddb4 100644 +--- a/include/winerror.h ++++ b/include/winerror.h +@@ -3886,6 +3886,47 @@ static inline HRESULT HRESULT_FROM_WIN32(unsigned int x) + #define WINCODEC_ERR_WIN32ERROR _HRESULT_TYPEDEF_(0x88982f94) + #define WINCODEC_ERR_INVALIDPROGRESSIVELEVEL _HRESULT_TYPEDEF_(0x88982f95) + ++#define MILERR_OBJECTBUSY _HRESULT_TYPEDEF_(0x88980001) ++#define MILERR_INSUFFICIENTBUFFER _HRESULT_TYPEDEF_(0x88980002) ++#define MILERR_WIN32ERROR _HRESULT_TYPEDEF_(0x88980003) ++#define MILERR_SCANNER_FAILED _HRESULT_TYPEDEF_(0x88980004) ++#define MILERR_SCREENACCESSDENIED _HRESULT_TYPEDEF_(0x88980005) ++#define MILERR_DISPLAYSTATEINVALID _HRESULT_TYPEDEF_(0x88980006) ++#define MILERR_NONINVERTIBLEMATRIX _HRESULT_TYPEDEF_(0x88980007) ++#define MILERR_ZEROVECTOR _HRESULT_TYPEDEF_(0x88980008) ++#define MILERR_TERMINATED _HRESULT_TYPEDEF_(0x88980009) ++#define MILERR_BADNUMBER _HRESULT_TYPEDEF_(0x8898000a) ++#define MILERR_INTERNALERROR _HRESULT_TYPEDEF_(0x88980080) ++#define MILERR_DISPLAYFORMATNOTSUPPORTED _HRESULT_TYPEDEF_(0x88980084) ++#define MILERR_INVALIDCALL _HRESULT_TYPEDEF_(0x88980085) ++#define MILERR_ALREADYLOCKED _HRESULT_TYPEDEF_(0x88980086) ++#define MILERR_NOTLOCKED _HRESULT_TYPEDEF_(0x88980087) ++#define MILERR_DEVICECANNOTRENDERTEXT _HRESULT_TYPEDEF_(0x88980088) ++#define MILERR_GLYPHBITMAPMISSED _HRESULT_TYPEDEF_(0x88980089) ++#define MILERR_MALFORMEDGLYPHCACHE _HRESULT_TYPEDEF_(0x8898008a) ++#define MILERR_GENERIC_IGNORE _HRESULT_TYPEDEF_(0x8898008b) ++#define MILERR_MALFORMED_GUIDELINE_DATA _HRESULT_TYPEDEF_(0x8898008c) ++#define MILERR_NO_HARDWARE_DEVICE _HRESULT_TYPEDEF_(0x8898008d) ++#define MILERR_NEED_RECREATE_AND_PRESENT _HRESULT_TYPEDEF_(0x8898008e) ++#define MILERR_ALREADY_INITIALIZED _HRESULT_TYPEDEF_(0x8898008f) ++#define MILERR_MISMATCHED_SIZE _HRESULT_TYPEDEF_(0x88980090) ++#define MILERR_NO_REDIRECTION_SURFACE_AVAILABLE _HRESULT_TYPEDEF_(0x88980091) ++#define MILERR_REMOTING_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x88980092) ++#define MILERR_QUEUED_PRESENT_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x88980093) ++#define MILERR_NOT_QUEUING_PRESENTS _HRESULT_TYPEDEF_(0x88980094) ++#define MILERR_NO_REDIRECTION_SURFACE_RETRY_LATER _HRESULT_TYPEDEF_(0x88980095) ++#define MILERR_TOOMANYSHADERELEMNTS _HRESULT_TYPEDEF_(0x88980096) ++#define MILERR_MROW_READLOCK_FAILED _HRESULT_TYPEDEF_(0x88980097) ++#define MILERR_MROW_UPDATE_FAILED _HRESULT_TYPEDEF_(0x88980098) ++#define MILERR_SHADER_COMPILE_FAILED _HRESULT_TYPEDEF_(0x88980099) ++#define MILERR_MAX_TEXTURE_SIZE_EXCEEDED _HRESULT_TYPEDEF_(0x8898009a) ++#define MILERR_QPC_TIME_WENT_BACKWARD _HRESULT_TYPEDEF_(0x8898009b) ++#define MILERR_DXGI_ENUMERATION_OUT_OF_SYNC _HRESULT_TYPEDEF_(0x8898009d) ++#define MILERR_ADAPTER_NOT_FOUND _HRESULT_TYPEDEF_(0x8898009e) ++#define MILERR_COLORSPACE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8898009f) ++#define MILERR_PREFILTER_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x889800a0) ++#define MILERR_DISPLAYID_ACCESS_DENIED _HRESULT_TYPEDEF_(0x889800a1) ++ + #define DWRITE_E_FILEFORMAT _HRESULT_TYPEDEF_(0x88985000) + #define DWRITE_E_UNEXPECTED _HRESULT_TYPEDEF_(0x88985001) + #define DWRITE_E_NOFONT _HRESULT_TYPEDEF_(0x88985002) +diff --git a/include/winnt.h b/include/winnt.h +index 781f430d91a..016d1ada164 100644 +--- a/include/winnt.h ++++ b/include/winnt.h +@@ -796,18 +796,25 @@ typedef struct _WIN32_MEMORY_RANGE_ENTRY + #define PAGE_NOCACHE 0x200 + #define PAGE_WRITECOMBINE 0x400 + +-#define MEM_COMMIT 0x00001000 +-#define MEM_RESERVE 0x00002000 +-#define MEM_DECOMMIT 0x00004000 +-#define MEM_RELEASE 0x00008000 ++#define MEM_COMMIT 0x00001000 ++#define MEM_RESERVE 0x00002000 ++#define MEM_REPLACE_PLACEHOLDER 0x00004000 ++#define MEM_RESERVE_PLACEHOLDER 0x00040000 ++#define MEM_RESET 0x00080000 ++#define MEM_TOP_DOWN 0x00100000 ++#define MEM_PHYSICAL 0x00400000 ++#define MEM_RESET_UNDO 0x10000000 ++#define MEM_LARGE_PAGES 0x20000000 ++ ++#define MEM_COALESCE_PLACEHOLDERS 0x00000001 ++#define MEM_PRESERVE_PLACEHOLDER 0x00000002 ++#define MEM_DECOMMIT 0x00004000 ++#define MEM_RELEASE 0x00008000 ++ + #define MEM_FREE 0x00010000 + #define MEM_PRIVATE 0x00020000 + #define MEM_MAPPED 0x00040000 +-#define MEM_RESET 0x00080000 +-#define MEM_TOP_DOWN 0x00100000 + #define MEM_WRITE_WATCH 0x00200000 +-#define MEM_PHYSICAL 0x00400000 +-#define MEM_LARGE_PAGES 0x20000000 + #define MEM_4MB_PAGES 0x80000000 + + #define SEC_FILE 0x00800000 +@@ -6265,6 +6272,13 @@ typedef enum _PROCESS_MITIGATION_POLICY + MaxProcessMitigationPolicy + } PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY; + ++typedef enum _FIRMWARE_TYPE ++{ ++ FirmwareTypeUnknown, ++ FirmwareTypeBios, ++ FirmwareTypeUefi, ++ FirmwareTypeMax ++} FIRMWARE_TYPE, *PFIRMWARE_TYPE; + + /* Intrinsic functions */ + +diff --git a/include/winternl.h b/include/winternl.h +index 8b0a4839b81..e4e3ddc24b6 100644 +--- a/include/winternl.h ++++ b/include/winternl.h +@@ -1568,11 +1568,21 @@ typedef enum _PROCESSINFOCLASS { + ProcessThreadStackAllocation = 41, + ProcessWorkingSetWatchEx = 42, + ProcessImageFileNameWin32 = 43, ++ ProcessImageFileMapping = 44, ++ ProcessAffinityUpdateMode = 45, ++ ProcessMemoryAllocationMode = 46, ++ ProcessGroupInformation = 47, ++ ProcessTokenVirtualizationEnabled = 48, ++ ProcessConsoleHostProcess = 49, ++ ProcessWindowInformation = 50, ++ ProcessHandleInformation = 51, ++ ProcessPowerThrottlingState = 77, ++ ProcessLeapSecondInformation = 97, + MaxProcessInfoClass, + #ifdef __WINESRC__ + ProcessWineMakeProcessSystem = 1000, + #endif +-} PROCESSINFOCLASS, PROCESS_INFORMATION_CLASS; ++} PROCESSINFOCLASS; + + #define MEM_EXECUTE_OPTION_DISABLE 0x01 + #define MEM_EXECUTE_OPTION_ENABLE 0x02 +@@ -2222,6 +2232,11 @@ typedef struct _PROCESS_PRIORITY_CLASS { + UCHAR PriorityClass; + } PROCESS_PRIORITY_CLASS, *PPROCESS_PRIORITY_CLASS; + ++typedef struct _PROCESS_CYCLE_TIME_INFORMATION { ++ ULONGLONG AccumulatedCycles; ++ ULONGLONG CurrentCycleCount; ++} PROCESS_CYCLE_TIME_INFORMATION, *PPROCESS_CYCLE_TIME_INFORMATION; ++ + typedef struct _PROCESS_STACK_ALLOCATION_INFORMATION + { + SIZE_T ReserveSize; +@@ -4009,6 +4024,7 @@ NTSYSAPI NTSTATUS WINAPI NtLockFile(HANDLE,HANDLE,PIO_APC_ROUTINE,void*,PIO_STA + NTSYSAPI NTSTATUS WINAPI NtLockVirtualMemory(HANDLE,PVOID*,SIZE_T*,ULONG); + NTSYSAPI NTSTATUS WINAPI NtMakeTemporaryObject(HANDLE); + NTSYSAPI NTSTATUS WINAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG_PTR,SIZE_T,const LARGE_INTEGER*,SIZE_T*,SECTION_INHERIT,ULONG,ULONG); ++NTSYSAPI NTSTATUS WINAPI NtMapViewOfSectionEx(HANDLE,HANDLE,PVOID*,const LARGE_INTEGER*,SIZE_T*,ULONG,ULONG,MEM_EXTENDED_PARAMETER*,ULONG); + NTSYSAPI NTSTATUS WINAPI NtNotifyChangeDirectoryFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,ULONG,BOOLEAN); + NTSYSAPI NTSTATUS WINAPI NtNotifyChangeKey(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN); + NTSYSAPI NTSTATUS WINAPI NtNotifyChangeMultipleKeys(HANDLE,ULONG,OBJECT_ATTRIBUTES*,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN); +@@ -4124,7 +4140,7 @@ NTSYSAPI NTSTATUS WINAPI NtSetInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULO + NTSYSAPI NTSTATUS WINAPI NtSetInformationJobObject(HANDLE,JOBOBJECTINFOCLASS,PVOID,ULONG); + NTSYSAPI NTSTATUS WINAPI NtSetInformationKey(HANDLE,const int,PVOID,ULONG); + NTSYSAPI NTSTATUS WINAPI NtSetInformationObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG); +-NTSYSAPI NTSTATUS WINAPI NtSetInformationProcess(HANDLE,PROCESS_INFORMATION_CLASS,PVOID,ULONG); ++NTSYSAPI NTSTATUS WINAPI NtSetInformationProcess(HANDLE,PROCESSINFOCLASS,PVOID,ULONG); + NTSYSAPI NTSTATUS WINAPI NtSetInformationThread(HANDLE,THREADINFOCLASS,LPCVOID,ULONG); + NTSYSAPI NTSTATUS WINAPI NtSetInformationToken(HANDLE,TOKEN_INFORMATION_CLASS,PVOID,ULONG); + NTSYSAPI NTSTATUS WINAPI NtSetIntervalProfile(ULONG,KPROFILE_SOURCE);