mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 08:27:18 +00:00
ntdll/tests: Add test for Win10 OutputDebugStringW evolution.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
parent
b9db434034
commit
b7004335c5
|
@ -76,6 +76,7 @@ static BOOL (WINAPI *pInitializeContext2)(void *buffer, DWORD context_flags
|
|||
static void * (WINAPI *pLocateXStateFeature)(CONTEXT *context, DWORD feature_id, DWORD *length);
|
||||
static BOOL (WINAPI *pSetXStateFeaturesMask)(CONTEXT *context, DWORD64 feature_mask);
|
||||
static BOOL (WINAPI *pGetXStateFeaturesMask)(CONTEXT *context, DWORD64 *feature_mask);
|
||||
static BOOL (WINAPI *pWaitForDebugEventEx)(DEBUG_EVENT *, DWORD);
|
||||
|
||||
#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64
|
||||
|
||||
|
@ -8564,25 +8565,43 @@ static void test_debug_service(DWORD numexc)
|
|||
}
|
||||
#endif /* defined(__i386__) || defined(__x86_64__) */
|
||||
|
||||
static DWORD outputdebugstring_exceptions;
|
||||
static DWORD outputdebugstring_exceptions_ansi;
|
||||
static DWORD outputdebugstring_exceptions_unicode;
|
||||
|
||||
static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
PEXCEPTION_RECORD rec = ExceptionInfo->ExceptionRecord;
|
||||
trace("vect. handler %08lx addr:%p\n", rec->ExceptionCode, rec->ExceptionAddress);
|
||||
|
||||
ok(rec->ExceptionCode == DBG_PRINTEXCEPTION_C, "ExceptionCode is %08lx instead of %08lx\n",
|
||||
rec->ExceptionCode, DBG_PRINTEXCEPTION_C);
|
||||
ok(rec->NumberParameters == 2, "ExceptionParameters is %ld instead of 2\n", rec->NumberParameters);
|
||||
ok(rec->ExceptionInformation[0] == 12, "ExceptionInformation[0] = %ld instead of 12\n", (DWORD)rec->ExceptionInformation[0]);
|
||||
ok(!strcmp((char *)rec->ExceptionInformation[1], "Hello World"),
|
||||
"ExceptionInformation[1] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[1]);
|
||||
switch (rec->ExceptionCode)
|
||||
{
|
||||
case DBG_PRINTEXCEPTION_C:
|
||||
ok(rec->NumberParameters == 2, "ExceptionParameters is %ld instead of 2\n", rec->NumberParameters);
|
||||
ok(rec->ExceptionInformation[0] == 12, "ExceptionInformation[0] = %ld instead of 12\n", (DWORD)rec->ExceptionInformation[0]);
|
||||
ok(!strcmp((char *)rec->ExceptionInformation[1], "Hello World"),
|
||||
"ExceptionInformation[1] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[1]);
|
||||
outputdebugstring_exceptions_ansi++;
|
||||
break;
|
||||
case DBG_PRINTEXCEPTION_WIDE_C:
|
||||
ok(outputdebugstring_exceptions_ansi == 0, "Unicode exception should come first\n");
|
||||
ok(rec->NumberParameters == 4, "ExceptionParameters is %ld instead of 4\n", rec->NumberParameters);
|
||||
ok(rec->ExceptionInformation[0] == 12, "ExceptionInformation[0] = %ld instead of 12\n", (DWORD)rec->ExceptionInformation[0]);
|
||||
ok(!wcscmp((WCHAR *)rec->ExceptionInformation[1], L"Hello World"),
|
||||
"ExceptionInformation[1] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[1]);
|
||||
ok(rec->ExceptionInformation[2] == 12, "ExceptionInformation[2] = %ld instead of 12\n", (DWORD)rec->ExceptionInformation[2]);
|
||||
ok(!strcmp((char *)rec->ExceptionInformation[3], "Hello World"),
|
||||
"ExceptionInformation[3] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[3]);
|
||||
outputdebugstring_exceptions_unicode++;
|
||||
break;
|
||||
default:
|
||||
ok(0, "ExceptionCode is %08lx unexpected\n", rec->ExceptionCode);
|
||||
break;
|
||||
}
|
||||
|
||||
outputdebugstring_exceptions++;
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
static void test_outputdebugstring(DWORD numexc, BOOL todo)
|
||||
static void test_outputdebugstring(BOOL unicode, DWORD numexc_ansi, BOOL todo_ansi, DWORD numexc_unicode)
|
||||
{
|
||||
PVOID vectored_handler;
|
||||
|
||||
|
@ -8595,12 +8614,111 @@ static void test_outputdebugstring(DWORD numexc, BOOL todo)
|
|||
vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &outputdebugstring_vectored_handler);
|
||||
ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
|
||||
|
||||
outputdebugstring_exceptions = 0;
|
||||
OutputDebugStringA("Hello World");
|
||||
outputdebugstring_exceptions_ansi = outputdebugstring_exceptions_unicode = 0;
|
||||
|
||||
todo_wine_if(todo)
|
||||
ok(outputdebugstring_exceptions == numexc, "OutputDebugStringA generated %ld exceptions, expected %ld\n",
|
||||
outputdebugstring_exceptions, numexc);
|
||||
if (unicode)
|
||||
OutputDebugStringW(L"Hello World");
|
||||
else
|
||||
OutputDebugStringA("Hello World");
|
||||
|
||||
todo_wine_if(todo_ansi)
|
||||
ok(outputdebugstring_exceptions_ansi == numexc_ansi,
|
||||
"OutputDebugString%c generated %ld ansi exceptions, expected %ld\n",
|
||||
unicode ? 'W' : 'A', outputdebugstring_exceptions_ansi, numexc_ansi);
|
||||
todo_wine_if(unicode)
|
||||
ok(outputdebugstring_exceptions_unicode == numexc_unicode,
|
||||
"OutputDebugString%c generated %lu unicode exceptions, expected %ld\n",
|
||||
unicode ? 'W' : 'A', outputdebugstring_exceptions_unicode, numexc_unicode);
|
||||
|
||||
pRtlRemoveVectoredExceptionHandler(vectored_handler);
|
||||
}
|
||||
|
||||
static DWORD outputdebugstring_exceptions_newmodel_order;
|
||||
static DWORD outputdebugstring_newmodel_return;
|
||||
|
||||
static LONG CALLBACK outputdebugstring_new_model_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
PEXCEPTION_RECORD rec = ExceptionInfo->ExceptionRecord;
|
||||
trace("vect. handler %08lx addr:%p\n", rec->ExceptionCode, rec->ExceptionAddress);
|
||||
|
||||
switch (rec->ExceptionCode)
|
||||
{
|
||||
case DBG_PRINTEXCEPTION_C:
|
||||
ok(rec->NumberParameters == 2, "ExceptionParameters is %ld instead of 2\n", rec->NumberParameters);
|
||||
ok(rec->ExceptionInformation[0] == 12, "ExceptionInformation[0] = %ld instead of 12\n", (DWORD)rec->ExceptionInformation[0]);
|
||||
ok(!strcmp((char *)rec->ExceptionInformation[1], "Hello World"),
|
||||
"ExceptionInformation[1] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[1]);
|
||||
outputdebugstring_exceptions_newmodel_order =
|
||||
(outputdebugstring_exceptions_newmodel_order << 8) | 'A';
|
||||
break;
|
||||
case DBG_PRINTEXCEPTION_WIDE_C:
|
||||
ok(rec->NumberParameters == 4, "ExceptionParameters is %ld instead of 4\n", rec->NumberParameters);
|
||||
ok(rec->ExceptionInformation[0] == 12, "ExceptionInformation[0] = %ld instead of 12\n", (DWORD)rec->ExceptionInformation[0]);
|
||||
ok(!wcscmp((WCHAR *)rec->ExceptionInformation[1], L"Hello World"),
|
||||
"ExceptionInformation[1] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[1]);
|
||||
ok(rec->ExceptionInformation[2] == 12, "ExceptionInformation[2] = %ld instead of 12\n", (DWORD)rec->ExceptionInformation[2]);
|
||||
ok(!strcmp((char *)rec->ExceptionInformation[3], "Hello World"),
|
||||
"ExceptionInformation[3] = '%s' instead of 'Hello World'\n", (char *)rec->ExceptionInformation[3]);
|
||||
outputdebugstring_exceptions_newmodel_order =
|
||||
(outputdebugstring_exceptions_newmodel_order << 8) | 'W';
|
||||
break;
|
||||
default:
|
||||
ok(0, "ExceptionCode is %08lx unexpected\n", rec->ExceptionCode);
|
||||
break;
|
||||
}
|
||||
|
||||
return outputdebugstring_newmodel_return;
|
||||
}
|
||||
|
||||
static void test_outputdebugstring_newmodel(void)
|
||||
{
|
||||
PVOID vectored_handler;
|
||||
struct
|
||||
{
|
||||
/* input */
|
||||
BOOL unicode;
|
||||
DWORD ret_code;
|
||||
/* expected output */
|
||||
DWORD exceptions_order;
|
||||
}
|
||||
tests[] =
|
||||
{
|
||||
{FALSE, EXCEPTION_CONTINUE_EXECUTION, 'A'},
|
||||
{FALSE, EXCEPTION_CONTINUE_SEARCH, 'A'},
|
||||
{TRUE, EXCEPTION_CONTINUE_EXECUTION, 'W'},
|
||||
{TRUE, EXCEPTION_CONTINUE_SEARCH, ('W' << 8) | 'A'},
|
||||
};
|
||||
int i;
|
||||
|
||||
if (!pWaitForDebugEventEx)
|
||||
{
|
||||
skip("Unsupported new unicode debug string model\n");
|
||||
return;
|
||||
}
|
||||
if (!pRtlAddVectoredExceptionHandler || !pRtlRemoveVectoredExceptionHandler)
|
||||
{
|
||||
skip("RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &outputdebugstring_new_model_vectored_handler);
|
||||
ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tests); i++)
|
||||
{
|
||||
outputdebugstring_exceptions_newmodel_order = 0;
|
||||
outputdebugstring_newmodel_return = tests[i].ret_code;
|
||||
|
||||
if (tests[i].unicode)
|
||||
OutputDebugStringW(L"Hello World");
|
||||
else
|
||||
OutputDebugStringA("Hello World");
|
||||
|
||||
ok(outputdebugstring_exceptions_newmodel_order == tests[i].exceptions_order,
|
||||
"OutputDebugString%c/%u generated exceptions %04lxs, expected %04lx\n",
|
||||
tests[i].unicode ? 'W' : 'A', i,
|
||||
outputdebugstring_exceptions_newmodel_order, tests[i].exceptions_order);
|
||||
}
|
||||
|
||||
pRtlRemoveVectoredExceptionHandler(vectored_handler);
|
||||
}
|
||||
|
@ -11044,6 +11162,7 @@ START_TEST(exception)
|
|||
X(LocateXStateFeature);
|
||||
X(SetXStateFeaturesMask);
|
||||
X(GetXStateFeaturesMask);
|
||||
X(WaitForDebugEventEx);
|
||||
#undef X
|
||||
|
||||
if (pRtlAddVectoredExceptionHandler && pRtlRemoveVectoredExceptionHandler)
|
||||
|
@ -11092,9 +11211,9 @@ START_TEST(exception)
|
|||
else skip( "RtlRaiseException not found\n" );
|
||||
#endif
|
||||
test_stage = 3;
|
||||
test_outputdebugstring(0, FALSE);
|
||||
test_outputdebugstring(FALSE, 0, FALSE, 0);
|
||||
test_stage = 4;
|
||||
test_outputdebugstring(2, TRUE); /* is this a Windows bug? */
|
||||
test_outputdebugstring(FALSE, 2, TRUE, 0); /* is 2 a Windows bug? */
|
||||
test_stage = 5;
|
||||
test_ripevent(0);
|
||||
test_stage = 6;
|
||||
|
@ -11209,7 +11328,9 @@ START_TEST(exception)
|
|||
test_debugger(DBG_EXCEPTION_HANDLED);
|
||||
test_debugger(DBG_CONTINUE);
|
||||
test_thread_context();
|
||||
test_outputdebugstring(1, FALSE);
|
||||
test_outputdebugstring(FALSE, 1, FALSE, 0);
|
||||
test_outputdebugstring(TRUE, 1, FALSE, 1);
|
||||
test_outputdebugstring_newmodel();
|
||||
test_ripevent(1);
|
||||
test_fastfail();
|
||||
test_breakpoint(1);
|
||||
|
|
Loading…
Reference in a new issue