From e56d3d3e0790c6f22c99b7ed9d5a2a050153606c Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 17 May 2024 23:03:19 +0900 Subject: [PATCH] filesrc: Don't abort on _get_osfhandle() _get_osfhandle() expects valid fd and CRT will abort program if given paramerter is invalid. The fd can be invalidated in various way, file was deleted by other process after we open a file. To avoid it, our own exception handler must be installed so that _get_osfhandle() can return INVALID_HANDLE_VALUE if fd is invalid. Part-of: --- subprojects/gstreamer/meson.build | 6 ++++ .../gstreamer/plugins/elements/gstfilesrc.c | 36 +++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/subprojects/gstreamer/meson.build b/subprojects/gstreamer/meson.build index dda46eb051..9753377485 100644 --- a/subprojects/gstreamer/meson.build +++ b/subprojects/gstreamer/meson.build @@ -277,6 +277,12 @@ foreach f : check_functions endif endforeach +if host_system == 'windows' + if cc.has_function('_set_thread_local_invalid_parameter_handler', prefix : '#include ') + cdata.set('HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER', 1) + endif +endif + if cc.has_function('localtime_r', prefix : '#include') cdata.set('HAVE_LOCALTIME_R', 1) # Needed by libcheck diff --git a/subprojects/gstreamer/plugins/elements/gstfilesrc.c b/subprojects/gstreamer/plugins/elements/gstfilesrc.c index 5dfe014169..01d2ff6946 100644 --- a/subprojects/gstreamer/plugins/elements/gstfilesrc.c +++ b/subprojects/gstreamer/plugins/elements/gstfilesrc.c @@ -57,6 +57,9 @@ /* Prevent stat.h from defining the stat* functions as * _stat*, since we're explicitly overriding that */ #undef _INC_STAT_INL +#ifdef HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER +#include +#endif #endif #include @@ -403,6 +406,35 @@ gst_file_src_is_seekable (GstBaseSrc * basesrc) return src->seekable; } +#ifdef G_OS_WIN32 +#ifdef HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER +static void __cdecl +gst_file_src_win32_iph (wchar_t const *exp, wchar_t const *func, + wchar_t const *file, unsigned int line, uintptr_t reserved) +{ + /* Do nothing */ +} + +static HANDLE +gst_file_src_win32_get_osfhandle (int fd) +{ + HANDLE handle; + _invalid_parameter_handler old_iph = + _set_thread_local_invalid_parameter_handler (gst_file_src_win32_iph); + handle = (HANDLE) _get_osfhandle (fd); + _set_thread_local_invalid_parameter_handler (old_iph); + + return handle; +} +#else /* HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER */ +static HANDLE +gst_file_src_win32_get_osfhandle (int fd) +{ + return (HANDLE) _get_osfhandle (fd); +} +#endif /* HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER */ +#endif /* G_OS_WIN32 */ + static gboolean gst_file_src_get_size (GstBaseSrc * basesrc, guint64 * size) { @@ -417,7 +449,7 @@ gst_file_src_get_size (GstBaseSrc * basesrc, guint64 * size) } #ifdef G_OS_WIN32 { - HANDLE h = (HANDLE) _get_osfhandle (src->fd); + HANDLE h = gst_file_src_win32_get_osfhandle (src->fd); LARGE_INTEGER file_size; if (h == INVALID_HANDLE_VALUE) @@ -472,7 +504,7 @@ gst_file_src_start (GstBaseSrc * basesrc) #ifdef G_OS_WIN32 { - HANDLE h = (HANDLE) _get_osfhandle (src->fd); + HANDLE h = gst_file_src_win32_get_osfhandle (src->fd); FILE_STANDARD_INFO file_info; if (h == INVALID_HANDLE_VALUE)