mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-11-28 04:49:54 +01:00
Add OS profile sources for Windows
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,7 +9,6 @@ tags
|
||||
*.pc
|
||||
.*.swp
|
||||
.sw?
|
||||
*.rc
|
||||
*.gcno
|
||||
*.gcda
|
||||
*.gcov
|
||||
|
||||
1
build-aux/meson.build
Normal file
1
build-aux/meson.build
Normal file
@@ -0,0 +1 @@
|
||||
subdir('win32')
|
||||
162
build-aux/win32/app.c
Normal file
162
build-aux/win32/app.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright © 2025 Luca Bacci
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Luca Bacci <luca.bacci@outlook.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <vcruntime.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
set_process_wide_settings (void)
|
||||
{
|
||||
#if defined (_M_IX86) || defined (__i386__)
|
||||
/* https://learn.microsoft.com/en-us/archive/blogs/michael_howard/faq-about-heapsetinformation-in-windows-vista-and-heap-based-buffer-overruns */
|
||||
/* https://web.archive.org/web/20080825034220/https://blogs.msdn.com/sdl/archive/2008/06/06/corrupted-heap-termination-redux.aspx */
|
||||
HeapSetInformation (NULL, HeapEnableTerminationOnCorruption, NULL, 0);
|
||||
|
||||
/* https://learn.microsoft.com/en-us/archive/blogs/michael_howard/new-nx-apis-added-to-windows-vista-sp1-windows-xp-sp3-and-windows-server-2008 */
|
||||
SetProcessDEPPolicy (PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION);
|
||||
#endif
|
||||
|
||||
SetErrorMode (GetErrorMode () | SEM_FAILCRITICALERRORS);
|
||||
}
|
||||
|
||||
static void
|
||||
set_crt_non_interactive (void)
|
||||
{
|
||||
/* The Debug CRT may show UI dialogs even in console applications.
|
||||
* Direct to stderr instead.
|
||||
*/
|
||||
_CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
_CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
|
||||
|
||||
_CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR);
|
||||
_CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
|
||||
|
||||
_CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR);
|
||||
_CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||
}
|
||||
|
||||
static void
|
||||
set_stderr_unbuffered_mode (void)
|
||||
{
|
||||
/* MSVCRT.DLL can open stderr in full-buffering mode. That depends on
|
||||
* the type of output device; for example, it's fully buffered for
|
||||
* named pipes but not for console devices.
|
||||
*
|
||||
* Having a fully buffered stderr is not a good default since we can
|
||||
* loose important messages before a crash. Moreover, POSIX forbids
|
||||
* full buffering on stderr. So here we set stderr to unbuffered mode.
|
||||
*
|
||||
* Note: line buffering mode would be good enough, but the Windows C
|
||||
* RunTime library implements it the same as full buffering:
|
||||
*
|
||||
* "for some systems, _IOLBF provides line buffering. However, for
|
||||
* Win32, the behavior is the same as _IOFBF: Full Buffering"
|
||||
*
|
||||
* https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setvbuf#remarks
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* - https://sourceforge.net/p/mingw/mailman/message/27121137/
|
||||
*/
|
||||
#if !defined (_UCRT)
|
||||
int ret = setvbuf (stderr, NULL, _IONBF, 0);
|
||||
assert (ret == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
early_flush_exit_handler (void)
|
||||
{
|
||||
/* There are two ways to flush open streams: calling fflush with NULL
|
||||
* argument and calling _flushall. The former flushes output streams
|
||||
* only, the latter flushes both input and output streams.
|
||||
* We should not do anything with input streams here since flushing
|
||||
* means * discarding * data.
|
||||
*/
|
||||
fflush (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
register_early_flush_at_exit (void)
|
||||
{
|
||||
/* Implement the two-phase flushing at process exit.
|
||||
*
|
||||
* The C RunTime library flushes open streams within its DllMain handler.
|
||||
* This goes against the rules for DllMain, as each stream is protected
|
||||
* by a lock and locks must not be acquired in DllMain.
|
||||
*
|
||||
* So we flush from app code using an atexit handler. The handler runs when
|
||||
* the application is in a fully working state and thus is completely safe.
|
||||
*
|
||||
* This ensures that all important data is flushed. Anything that is written
|
||||
* after exit will be flushed lately by the C RunTime library (and therefore
|
||||
* may be skipped).
|
||||
*
|
||||
* See comments in "%ProgramFiles(x86)%\Windows Kits\10\Source\<version>\
|
||||
* \ucrt\stdio\fflush.cpp" for more informations.
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* - https://devblogs.microsoft.com/oldnewthing/20070503-00/?p=27003
|
||||
* - https://devblogs.microsoft.com/oldnewthing/20100122-00/?p=15193
|
||||
* - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
|
||||
*/
|
||||
int ret = atexit (early_flush_exit_handler);
|
||||
assert (ret == 0);
|
||||
}
|
||||
|
||||
/* Boilerplate for CRT constructor */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static void startup (void);
|
||||
|
||||
__pragma (section (".CRT$XCT", long, read))
|
||||
|
||||
__declspec (allocate (".CRT$XCT"))
|
||||
const void (*ptr_startup) (void) = startup;
|
||||
|
||||
#ifdef _M_IX86
|
||||
__pragma (comment (linker, "/INCLUDE:" "_ptr_startup"))
|
||||
#else
|
||||
__pragma (comment (linker, "/INCLUDE:" "ptr_startup"))
|
||||
#endif
|
||||
#else
|
||||
static void __attribute__((constructor)) startup (void);
|
||||
#endif
|
||||
|
||||
static void
|
||||
startup (void)
|
||||
{
|
||||
set_crt_non_interactive ();
|
||||
set_process_wide_settings ();
|
||||
set_stderr_unbuffered_mode ();
|
||||
register_early_flush_at_exit ();
|
||||
}
|
||||
40
build-aux/win32/app.manifest.xml
Normal file
40
build-aux/win32/app.manifest.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly manifestVersion="1.0"
|
||||
xmlns="urn:schemas-microsoft-com:asm.v1"
|
||||
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">
|
||||
<activeCodePage>UTF-8</activeCodePage>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 10 and Windows 11 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<!--
|
||||
UAC settings:
|
||||
- app should run at same integrity level as calling process
|
||||
- app does not need to manipulate windows belonging to
|
||||
higher-integrity-level processes
|
||||
-->
|
||||
<requestedExecutionLevel
|
||||
level="asInvoker"
|
||||
uiAccess="false"
|
||||
/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
||||
6
build-aux/win32/app.rc
Normal file
6
build-aux/win32/app.rc
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma code_page(65001)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest.xml"
|
||||
14
build-aux/win32/meson.build
Normal file
14
build-aux/win32/meson.build
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
if host_system == 'windows'
|
||||
static_lib = static_library('os-profile-app-static-lib',
|
||||
sources: ['app.c'],
|
||||
include_directories: [configinc])
|
||||
|
||||
resources = windows.compile_resources('app.rc',
|
||||
depend_files: ['app.manifest.xml'])
|
||||
|
||||
app_profile_dep = declare_dependency(link_whole: [static_lib],
|
||||
sources: [resources])
|
||||
else
|
||||
app_profile_dep = declare_dependency()
|
||||
endif
|
||||
Reference in New Issue
Block a user