ucrtbase: Implement _register_onexit_function().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4551b72e75
commit
5f490de459
|
@ -60,7 +60,7 @@
|
||||||
@ stub _invalid_parameter_noinfo_noreturn
|
@ stub _invalid_parameter_noinfo_noreturn
|
||||||
@ stub _invoke_watson
|
@ stub _invoke_watson
|
||||||
@ stub _query_app_type
|
@ stub _query_app_type
|
||||||
@ stub _register_onexit_function
|
@ cdecl _register_onexit_function(ptr ptr) ucrtbase._register_onexit_function
|
||||||
@ stub _register_thread_local_exe_atexit_callback
|
@ stub _register_thread_local_exe_atexit_callback
|
||||||
@ cdecl _resetstkoflw() ucrtbase._resetstkoflw
|
@ cdecl _resetstkoflw() ucrtbase._resetstkoflw
|
||||||
@ cdecl -arch=i386,x86_64,arm _seh_filter_dll(long ptr) ucrtbase._seh_filter_dll
|
@ cdecl -arch=i386,x86_64,arm _seh_filter_dll(long ptr) ucrtbase._seh_filter_dll
|
||||||
|
|
|
@ -357,6 +357,48 @@ int CDECL MSVCRT__initialize_onexit_table(MSVCRT__onexit_table_t *table)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _register_onexit_function (UCRTBASE.@)
|
||||||
|
*/
|
||||||
|
int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT__onexit_t func)
|
||||||
|
{
|
||||||
|
TRACE("(%p %p)\n", table, func);
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!table->_first)
|
||||||
|
{
|
||||||
|
table->_first = MSVCRT_calloc(32, sizeof(void *));
|
||||||
|
if (!table->_first)
|
||||||
|
{
|
||||||
|
WARN("failed to allocate initial table.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
table->_last = table->_first;
|
||||||
|
table->_end = table->_first + 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grow if full */
|
||||||
|
if (table->_last == table->_end)
|
||||||
|
{
|
||||||
|
int len = table->_end - table->_first;
|
||||||
|
MSVCRT__onexit_t *tmp = MSVCRT_realloc(table->_first, 2 * len * sizeof(void *));
|
||||||
|
if (!tmp)
|
||||||
|
{
|
||||||
|
WARN("failed to grow table.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
table->_first = tmp;
|
||||||
|
table->_end = table->_first + 2 * len;
|
||||||
|
table->_last = table->_first + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
*table->_last = func;
|
||||||
|
table->_last++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _set_purecall_handler (MSVCR71.@)
|
* _set_purecall_handler (MSVCR71.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -36,6 +36,7 @@ typedef struct MSVCRT__onexit_table_t
|
||||||
} MSVCRT__onexit_table_t;
|
} MSVCRT__onexit_table_t;
|
||||||
|
|
||||||
static int (CDECL *p_initialize_onexit_table)(MSVCRT__onexit_table_t *table);
|
static int (CDECL *p_initialize_onexit_table)(MSVCRT__onexit_table_t *table);
|
||||||
|
static int (CDECL *p_register_onexit_function)(MSVCRT__onexit_table_t *table, MSVCRT__onexit_t func);
|
||||||
|
|
||||||
static void test__initialize_onexit_table(void)
|
static void test__initialize_onexit_table(void)
|
||||||
{
|
{
|
||||||
|
@ -97,11 +98,53 @@ static void test__initialize_onexit_table(void)
|
||||||
table._first, table._last, table._end);
|
table._first, table._last, table._end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CDECL onexit_func(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test__register_onexit_function(void)
|
||||||
|
{
|
||||||
|
MSVCRT__onexit_table_t table;
|
||||||
|
MSVCRT__onexit_t *f;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!p_register_onexit_function)
|
||||||
|
{
|
||||||
|
win_skip("_register_onexit_function() is not available.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&table, 0, sizeof(table));
|
||||||
|
ret = p_initialize_onexit_table(&table);
|
||||||
|
ok(ret == 0, "got %d\n", ret);
|
||||||
|
|
||||||
|
ret = p_register_onexit_function(NULL, NULL);
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
|
||||||
|
ret = p_register_onexit_function(NULL, onexit_func);
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
|
||||||
|
f = table._last;
|
||||||
|
ret = p_register_onexit_function(&table, NULL);
|
||||||
|
ok(ret == 0, "got %d\n", ret);
|
||||||
|
ok(f != table._last, "got %p, initial %p\n", table._last, f);
|
||||||
|
|
||||||
|
ret = p_register_onexit_function(&table, onexit_func);
|
||||||
|
ok(ret == 0, "got %d\n", ret);
|
||||||
|
|
||||||
|
f = table._last;
|
||||||
|
ret = p_register_onexit_function(&table, onexit_func);
|
||||||
|
ok(ret == 0, "got %d\n", ret);
|
||||||
|
ok(f != table._last, "got %p, initial %p\n", table._last, f);
|
||||||
|
}
|
||||||
|
|
||||||
static void init(void)
|
static void init(void)
|
||||||
{
|
{
|
||||||
HMODULE module = LoadLibraryA("ucrtbase.dll");
|
HMODULE module = LoadLibraryA("ucrtbase.dll");
|
||||||
|
|
||||||
p_initialize_onexit_table = (void*)GetProcAddress(module, "_initialize_onexit_table");
|
p_initialize_onexit_table = (void*)GetProcAddress(module, "_initialize_onexit_table");
|
||||||
|
p_register_onexit_function = (void*)GetProcAddress(module, "_register_onexit_function");
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(misc)
|
START_TEST(misc)
|
||||||
|
@ -109,4 +152,5 @@ START_TEST(misc)
|
||||||
init();
|
init();
|
||||||
|
|
||||||
test__initialize_onexit_table();
|
test__initialize_onexit_table();
|
||||||
|
test__register_onexit_function();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1861,7 +1861,7 @@
|
||||||
@ cdecl _read(long ptr long) MSVCRT__read
|
@ cdecl _read(long ptr long) MSVCRT__read
|
||||||
@ stub _realloc_base
|
@ stub _realloc_base
|
||||||
@ cdecl _recalloc(ptr long long)
|
@ cdecl _recalloc(ptr long long)
|
||||||
@ stub _register_onexit_function
|
@ cdecl _register_onexit_function(ptr ptr) MSVCRT__register_onexit_function
|
||||||
@ stub _register_thread_local_exe_atexit_callback
|
@ stub _register_thread_local_exe_atexit_callback
|
||||||
@ cdecl _resetstkoflw() MSVCRT__resetstkoflw
|
@ cdecl _resetstkoflw() MSVCRT__resetstkoflw
|
||||||
@ cdecl _rmdir(str) MSVCRT__rmdir
|
@ cdecl _rmdir(str) MSVCRT__rmdir
|
||||||
|
|
Loading…
Reference in New Issue