Push 0x7fff to the stack in __wine_syscall_dispatcher to recreate side effect of KiUserCallbackDispatcher needed by Skyrim Special Edition: Creation Kit to fix a menu resolution bug.
Wine Bug: https://bugs.winehq.org/show_bug.cgi?id=58003
-- v3: Revert "Merge branch wine:master into master"
From: Keaton Ens kae514@usask.ca
--- dlls/ntdll/unix/signal_x86_64.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 26b540bd629..bf520618cb6 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2728,6 +2728,12 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, #else "movq %gs:0x328,%rcx\n\t" /* amd64_thread_data()->syscall_frame */ #endif + /* Skyrim Special Edition: Creation Kit depends on internal function calls + * in KiUserCallbackDispatcher to push 0x7fff onto the stack to initialize a + * local variable.*/ + "sub $0x4c,%rsp\n\t" + "movl $0x7fff,(%rsp)\n\t" + "add $0x4c,%rsp\n\t" "popq 0x70(%rcx)\n\t" /* frame->rip */ __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") __ASM_CFI_REG_IS_AT2(rip, rcx, 0xf0,0x00)
From: Keaton Ens fx-8350-8@hotmail.com
This reverts commit 3908a8d9ce9a555de5d665d68ef6818030124292 --- dlls/comctl32/edit.c | 4 -- dlls/comctl32/listbox.c | 2 +- dlls/comctl32/propsheet.c | 2 - dlls/comctl32/tests/edit.c | 57 -------------------- dlls/comctl32/tests/listbox.c | 33 ------------ dlls/kernelbase/process.c | 8 +-- dlls/kernelbase/thread.c | 2 +- dlls/msvcrt/file.c | 2 - dlls/msvcrt/tests/file.c | 14 ++--- dlls/ntdll/tests/info.c | 24 ++++----- dlls/ntdll/unix/process.c | 4 +- dlls/ntdll/unix/thread.c | 20 ++----- dlls/ntdll/unix/virtual.c | 5 +- dlls/user32/listbox.c | 2 +- dlls/user32/tests/listbox.c | 32 ----------- dlls/wined3d/cs.c | 29 ---------- dlls/wined3d/ffp_gl.c | 29 ++++++---- dlls/wined3d/glsl_shader.c | 79 ++++++++++++++++++++++----- dlls/wined3d/shader.c | 4 +- dlls/wined3d/shader_spirv.c | 6 +++ dlls/wined3d/stateblock.c | 79 +-------------------------- dlls/wined3d/utils.c | 44 ++++++++++++++- dlls/wined3d/wined3d_private.h | 30 ++++------- dlls/winex11.drv/event.c | 10 ---- dlls/winex11.drv/window.c | 44 +++++++++++++-- dlls/wow64/process.c | 1 - dlls/wow64/security.c | 2 +- include/wine/server_protocol.h | 24 ++++----- server/fd.c | 14 ++--- server/process.c | 3 +- server/process.h | 1 - server/protocol.def | 22 ++++---- server/request_handlers.h | 8 ++- server/request_trace.h | 6 +-- server/thread.c | 36 ++++--------- server/thread.h | 2 - tools/winegcc/winegcc.c | 98 +++++++++++++++++----------------- 37 files changed, 302 insertions(+), 480 deletions(-)
diff --git a/dlls/comctl32/edit.c b/dlls/comctl32/edit.c index 71577a69d00..3fe84816141 100644 --- a/dlls/comctl32/edit.c +++ b/dlls/comctl32/edit.c @@ -2639,8 +2639,6 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r if (!notify_parent(es, EN_CHANGE)) return; } EDIT_InvalidateUniscribeData(es); - - NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, es->hwndSelf, OBJID_CLIENT, 0); }
@@ -2910,7 +2908,6 @@ static BOOL EDIT_EM_Undo(EDITSTATE *es) EDIT_EM_ScrollCaret(es); Free(utext);
- NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, es->hwndSelf, OBJID_CLIENT, 0); TRACE("after UNDO:insertion length = %d, deletion buffer = %s\n", es->undo_insert_count, debugstr_w(es->undo_text)); return TRUE; @@ -3847,7 +3844,6 @@ static void EDIT_WM_SetText(EDITSTATE *es, LPCWSTR text) EDIT_EM_ScrollCaret(es); EDIT_UpdateScrollInfo(es); EDIT_InvalidateUniscribeData(es); - NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, es->hwndSelf, OBJID_CLIENT, 0); }
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index bb37af8f10e..951b85856aa 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -610,7 +610,7 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, if (index < descr->nb_items) { item_str = get_item_string(descr, index); - selected = !(descr->style & LBS_NOSEL) && is_item_selected(descr, index); + selected = is_item_selected(descr, index); }
focused = !ignoreFocus && descr->focus_item == index && descr->caret_on && descr->in_focus; diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c index d397f85870d..44b24a56a07 100644 --- a/dlls/comctl32/propsheet.c +++ b/dlls/comctl32/propsheet.c @@ -3326,8 +3326,6 @@ static BOOL PROPSHEET_DoCommand(HWND hwnd, WORD wID) { PropSheetInfo* psInfo = GetPropW(hwnd, PropSheetInfoStr);
- if (psInfo == NULL) break; - /* don't overwrite ID_PSRESTARTWINDOWS or ID_PSREBOOTSYSTEM */ if (psInfo->result == 0) psInfo->result = IDOK; diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index ec74311909b..92091df8fa6 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -48,47 +48,6 @@ enum msg_id
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
-static void CALLBACK msg_winevent_proc(HWINEVENTHOOK hevent, - DWORD event, - HWND hwnd, - LONG object_id, - LONG child_id, - DWORD thread_id, - DWORD event_time) -{ - struct message msg = {0}; - char class_name[256]; - - /* ignore window and other system events */ - if (object_id != OBJID_CLIENT) return; - - /* ignore events not from an edit control */ - if (!GetClassNameA(hwnd, class_name, ARRAY_SIZE(class_name)) || - strcmp(class_name, WC_EDITA) != 0) - return; - - msg.message = event; - msg.flags = winevent_hook|wparam|lparam; - msg.wParam = object_id; - msg.lParam = child_id; - add_message(sequences, COMBINED_SEQ_INDEX, &msg); -} - -static void init_winevent_hook(void) { - hwineventhook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandleA(0), msg_winevent_proc, - 0, GetCurrentThreadId(), WINEVENT_INCONTEXT); - if (!hwineventhook) - win_skip( "no win event hook support\n" ); -} - -static void uninit_winevent_hook(void) { - if (!hwineventhook) - return; - - UnhookWinEvent(hwineventhook); - hwineventhook = 0; -} - struct edit_notify { int en_change, en_maxtext, en_update; }; @@ -3450,7 +3409,6 @@ static void test_wordbreak_proc(void) static const struct message setfocus_combined_seq[] = { { WM_KILLFOCUS, sent|id, 0, 0, PARENT_ID }, - { EVENT_OBJECT_FOCUS, winevent_hook|lparam, 0, 0 }, { WM_SETFOCUS, sent|id, 0, 0, EDIT_ID }, { WM_COMMAND, sent|wparam|id, MAKEWPARAM(1, EN_SETFOCUS), 0, PARENT_ID }, { WM_PAINT, sent|id, 0, 0, EDIT_ID }, @@ -3472,7 +3430,6 @@ static const struct message killfocus_combined_seq[] = static const struct message setfocus_sent_only_combined_seq[] = { { WM_KILLFOCUS, sent|id, 0, 0, PARENT_ID }, - { EVENT_OBJECT_FOCUS, winevent_hook|lparam, 0, 0 }, { WM_SETFOCUS, sent|id, 0, 0, EDIT_ID }, { WM_COMMAND, sent|wparam|id, MAKEWPARAM(1, EN_SETFOCUS), 0, PARENT_ID }, { 0 } @@ -3625,13 +3582,9 @@ static const struct message wm_ime_composition_seq[] = {WM_IME_CHAR, sent | wparam | defwinproc, 'e'}, {WM_IME_ENDCOMPOSITION, sent}, {WM_CHAR, sent | wparam, 'W'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {WM_CHAR, sent | wparam, 'i'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {WM_CHAR, sent | wparam, 'n'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {WM_CHAR, sent | wparam, 'e'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {0} };
@@ -3644,13 +3597,9 @@ static const struct message wm_ime_composition_korean_seq[] = {WM_IME_CHAR, sent | wparam | defwinproc, 'n'}, {WM_IME_CHAR, sent | wparam | defwinproc, 'e'}, {WM_CHAR, sent | wparam, 'W'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {WM_CHAR, sent | wparam, 'i'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {WM_CHAR, sent | wparam, 'n'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {WM_CHAR, sent | wparam, 'e'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {0} };
@@ -3658,7 +3607,6 @@ static const struct message wm_ime_char_seq[] = { {WM_IME_CHAR, sent | wparam, '0'}, {WM_CHAR, sent | wparam, '0'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {0} };
@@ -3666,7 +3614,6 @@ static const struct message eimes_getcompstratonce_seq[] = { {WM_IME_STARTCOMPOSITION, sent}, {WM_IME_COMPOSITION, sent | wparam, 'W'}, - {EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam, 0, 0}, {WM_IME_ENDCOMPOSITION, sent}, {0} }; @@ -3903,8 +3850,6 @@ START_TEST(edit)
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
- init_winevent_hook(); - hinst = GetModuleHandleA(NULL); b = register_classes(); ok(b, "Failed to register test classes.\n"); @@ -3945,7 +3890,5 @@ START_TEST(edit)
UnregisterWindowClasses();
- uninit_winevent_hook(); - unload_v6_module(ctx_cookie, hCtx); } diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index 9993031fb5f..399df20cb6d 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -751,39 +751,6 @@ static void test_LB_SETCURSEL(void) ok(ret == -1, "Unexpected anchor index %d.\n", ret);
DestroyWindow(hLB); - - /* LBS_NOSEL */ - hLB = create_listbox(LBS_NOSEL, 0); - ok(hLB != NULL, "Failed to create ListBox window.\n"); - - ret = SendMessageA(hLB, LB_GETCURSEL, 0, 0); - ok(ret == -1, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETSEL, 0, 0); - ok(!ret, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0); - todo_wine - ok(ret == 2, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETSEL, 2, 0); - ok(ret == 1, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETCURSEL, 0, 0); - ok(ret == 2, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_SETCURSEL, 3, 0); - todo_wine - ok(ret == 3, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETSEL, 3, 0); - ok(ret == 1, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETCURSEL, 0, 0); - ok(ret == 3, "Unexpected return value %d.\n", ret); - - DestroyWindow(hLB); - DestroyWindow(parent); }
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index a47e2dcc01a..df3447a9014 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -821,13 +821,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetHandleInformation( HANDLE handle, DWORD *flags */ DWORD WINAPI DECLSPEC_HOTPATCH GetPriorityClass( HANDLE process ) { - PROCESS_PRIORITY_CLASS priority; + PROCESS_BASIC_INFORMATION pbi;
- if (!set_ntstatus( NtQueryInformationProcess( process, ProcessPriorityClass, - &priority, sizeof(priority), NULL ))) + if (!set_ntstatus( NtQueryInformationProcess( process, ProcessBasicInformation, + &pbi, sizeof(pbi), NULL ))) return 0;
- switch (priority.PriorityClass) + switch (pbi.BasePriority) { case PROCESS_PRIOCLASS_IDLE: return IDLE_PRIORITY_CLASS; case PROCESS_PRIOCLASS_BELOW_NORMAL: return BELOW_NORMAL_PRIORITY_CLASS; diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index 82ade671d1a..82096fd45f3 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -274,7 +274,7 @@ INT WINAPI DECLSPEC_HOTPATCH GetThreadPriority( HANDLE thread ) if (!set_ntstatus( NtQueryInformationThread( thread, ThreadBasicInformation, &info, sizeof(info), NULL ))) return THREAD_PRIORITY_ERROR_RETURN; - return info.BasePriority; + return info.Priority; }
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 97bfc746abc..98df53be77d 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -4101,8 +4101,6 @@ int CDECL _flsbuf(int c, FILE* file) int res = 0;
if(file->_cnt <= 0) { - if(!file->_cnt && get_ioinfo_nolock(file->_file)->wxflag & WX_APPEND) - _lseek(file->_file, 0, FILE_END); res = msvcrt_flush_buffer(file); if(res) return res; diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c index 6ead01e9e2d..9ce3654bebe 100644 --- a/dlls/msvcrt/tests/file.c +++ b/dlls/msvcrt/tests/file.c @@ -695,9 +695,11 @@ static void test_fputc( void )
static void test_flsbuf( void ) { - int bufmode, ret, c, pos; char* tempf; FILE *tempfh; + int c; + int ret; + int bufmode; static const int bufmodes[] = {_IOFBF,_IONBF};
tempf=_tempnam(".","wne"); @@ -754,16 +756,6 @@ static void test_flsbuf( void ) ok(c == EOF, "there should only be one byte\n"); fclose(tempfh);
- tempfh = fopen(tempf,"ab"); - ok(tempfh != NULL, "fopen failed\n"); - pos = _lseek(_fileno(tempfh), 0, SEEK_CUR); - ok(!pos, "incorrect stream position: %d\n", pos); - ret = _flsbuf(0, tempfh); - ok(!ret, "_flsbuf returned %x\n", ret); - pos = _lseek(_fileno(tempfh), 0, SEEK_CUR); - ok(pos == 1, "incorrect stream position: %d\n", pos); - fclose(tempfh); - unlink(tempf); free(tempf); } diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index c95da44b8cf..b92d421891f 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -3334,8 +3334,8 @@ static void test_priority(void) thread_base_priority, tbi.BasePriority ); status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL ); expected_nt_priority = pbi.BasePriority + THREAD_PRIORITY_HIGHEST; - ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", - tbi.Priority, expected_nt_priority ); + todo_wine ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", + tbi.Priority, expected_nt_priority );
/* Test setting the thread priority to THREAD_PRIORITY_LOWEST now, but using * pNtSetInformationThread, also testing NT priority directly afterwards. */ @@ -3349,21 +3349,21 @@ static void test_priority(void) ok( nt_thread_priority == tbi.BasePriority, "After setting, BasePriority (%ld) does not match set BasePriority (%ld)\n", nt_thread_priority, tbi.BasePriority ); expected_nt_priority = pbi.BasePriority + THREAD_PRIORITY_LOWEST; - ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", - tbi.Priority, expected_nt_priority ); + todo_wine ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", + tbi.Priority, expected_nt_priority ); /* Now set NT thread priority directly to 12, a value normally impossible to * reach in NORMAL_PRIORITY_CLASS without boost. */ nt_thread_priority = 12; status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - ok( status == STATUS_SUCCESS, "NtSetInformationThread(ThreadPriority) failed: %08lx\n", status ); + todo_wine ok( status == STATUS_SUCCESS, "NtSetInformationThread(ThreadPriority) failed: %08lx\n", status ); /* Effective thread priority should be now 12, BasePriority should be * unchanged. */ status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL ); ok( status == STATUS_SUCCESS, "NtQueryInformationThread failed after setting priority: %08lx\n", status ); ok( THREAD_PRIORITY_LOWEST == tbi.BasePriority, "After setting, BasePriority (%ld) does not match set BasePriority THREAD_PRIORITY_LOWEST.\n", tbi.BasePriority ); - ok( nt_thread_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %lu.\n", - tbi.Priority, nt_thread_priority ); + todo_wine ok( nt_thread_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %lu.\n", + tbi.Priority, nt_thread_priority ); /* Changing process priority recalculates all priorities again and * overwrites our custom priority of 12. */ ret = SetPriorityClass( GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS ); @@ -3374,20 +3374,20 @@ static void test_priority(void) ok( status == STATUS_SUCCESS, "NtQueryInformationThread failed after setting priority: %08lx\n", status ); status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL ); expected_nt_priority = pbi.BasePriority + THREAD_PRIORITY_LOWEST; - ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", - tbi.Priority, expected_nt_priority ); + todo_wine ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", + tbi.Priority, expected_nt_priority ); /* Setting an out of range priority above HIGH_PRIORITY (31) or LOW_PRIORITY (0) * and lower fails. */ nt_thread_priority = 42; status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); + todo_wine ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); nt_thread_priority = 0; /* 0 also fails in addition to negative values. */ status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); + todo_wine ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); /* Moving a thread into the realtime band is normally not possible in a non-realtime process. */ nt_thread_priority = 24; status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - ok( status == STATUS_PRIVILEGE_NOT_HELD, "got %08lx, expected STATUS_PRIVILEGE_NOT_HELD.\n", status ); + todo_wine ok( status == STATUS_PRIVILEGE_NOT_HELD, "got %08lx, expected STATUS_PRIVILEGE_NOT_HELD.\n", status );
/* Restore thread priority and boosting behaviour back to normal */ SetThreadPriorityBoost( GetCurrentThread(), FALSE ); diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 4d5d23c47bb..533940280e6 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -1159,7 +1159,7 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class pbi.ExitStatus = reply->exit_code; pbi.PebBaseAddress = wine_server_get_ptr( reply->peb ); pbi.AffinityMask = reply->affinity & affinity_mask; - pbi.BasePriority = reply->base_priority; + pbi.BasePriority = reply->priority; pbi.UniqueProcessId = reply->pid; pbi.InheritedFromUniqueProcessId = reply->ppid; if (is_old_wow64()) @@ -1653,7 +1653,7 @@ NTSTATUS WINAPI NtWow64QueryInformationProcess64( HANDLE handle, PROCESSINFOCLAS pbi.ExitStatus = reply->exit_code; pbi.PebBaseAddress = (ULONG)wine_server_get_ptr( reply->peb ); pbi.AffinityMask = reply->affinity & affinity_mask; - pbi.BasePriority = reply->base_priority; + pbi.BasePriority = reply->priority; pbi.UniqueProcessId = reply->pid; pbi.InheritedFromUniqueProcessId = reply->ppid; } diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 1dd7faecb14..b31f8969c21 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2061,7 +2061,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, info.ClientId.UniqueThread = ULongToHandle(reply->tid); info.AffinityMask = reply->affinity & affinity_mask; info.Priority = reply->priority; - info.BasePriority = reply->base_priority; + info.BasePriority = reply->priority; /* FIXME */ } } SERVER_END_REQ; @@ -2153,7 +2153,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, status = wine_server_call( req ); if (status == STATUS_SUCCESS) { - ULONG last = !!(reply->flags & GET_THREAD_INFO_FLAG_LAST); + ULONG last = reply->last; if (data) memcpy( data, &last, sizeof(last) ); if (ret_len) *ret_len = sizeof(last); } @@ -2371,21 +2371,6 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, return status; }
- case ThreadPriority: - { - const DWORD *priority = data; - if (length != sizeof(DWORD)) return STATUS_INVALID_PARAMETER; - SERVER_START_REQ( set_thread_info ) - { - req->handle = wine_server_obj_handle( handle ); - req->priority = *priority; - req->mask = SET_THREAD_INFO_PRIORITY; - status = wine_server_call( req ); - } - SERVER_END_REQ; - return status; - } - case ThreadBasePriority: { const DWORD *base_priority = data; @@ -2563,6 +2548,7 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
case ThreadBasicInformation: case ThreadTimes: + case ThreadPriority: case ThreadDescriptorTableEntry: case ThreadEventPair_Reusable: case ThreadPerformanceCount: diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 9c6dce2c076..bb196c57155 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2753,7 +2753,7 @@ static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filena struct stat st; char *header_end; char *ptr = view->base; - SIZE_T header_size, header_map_size, total_size = view->size; + SIZE_T header_size, total_size = view->size; SIZE_T align_mask = max( image_info->alignment - 1, page_mask ); INT_PTR delta;
@@ -2763,8 +2763,7 @@ static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filena
fstat( fd, &st ); header_size = min( image_info->header_size, st.st_size ); - header_map_size = min( image_info->header_map_size, ROUND_SIZE( 0, st.st_size, page_mask )); - if ((status = map_pe_header( view->base, header_size, header_map_size, fd, &removable ))) + if ((status = map_pe_header( view->base, header_size, image_info->header_map_size, fd, &removable ))) return status;
status = STATUS_INVALID_IMAGE_FORMAT; /* generic error */ diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c index c7e9fd783ec..9d6ad8a3c75 100644 --- a/dlls/user32/listbox.c +++ b/dlls/user32/listbox.c @@ -608,7 +608,7 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, if (index < descr->nb_items) { item_str = get_item_string(descr, index); - selected = !(descr->style & LBS_NOSEL) && is_item_selected(descr, index); + selected = is_item_selected(descr, index); }
focused = !ignoreFocus && descr->focus_item == index && descr->caret_on && descr->in_focus; diff --git a/dlls/user32/tests/listbox.c b/dlls/user32/tests/listbox.c index 3adaaa0999e..747e3dae192 100644 --- a/dlls/user32/tests/listbox.c +++ b/dlls/user32/tests/listbox.c @@ -618,38 +618,6 @@ static void test_LB_SETCURSEL(void) ok(ret == -1, "Unexpected anchor index %d.\n", ret);
DestroyWindow(hLB); - - /* LBS_NOSEL */ - hLB = create_listbox(LBS_NOSEL, 0); - ok(hLB != NULL, "Failed to create ListBox window.\n"); - - ret = SendMessageA(hLB, LB_GETCURSEL, 0, 0); - ok(ret == -1, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETSEL, 0, 0); - ok(!ret, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0); - todo_wine - ok(ret == 2, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETSEL, 2, 0); - ok(ret == 1, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETCURSEL, 0, 0); - ok(ret == 2, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_SETCURSEL, 3, 0); - todo_wine - ok(ret == 3, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETSEL, 3, 0); - ok(ret == 1, "Unexpected return value %d.\n", ret); - - ret = SendMessageA(hLB, LB_GETCURSEL, 0, 0); - ok(ret == 3, "Unexpected return value %d.\n", ret); - - DestroyWindow(hLB); }
static void test_LB_SETSEL(void) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 0404674fa9d..9bac7afdba2 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -123,7 +123,6 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_COLOR_KEY, WINED3D_CS_OP_SET_LIGHT, WINED3D_CS_OP_SET_LIGHT_ENABLE, - WINED3D_CS_OP_SET_EXTRA_PS_ARGS, WINED3D_CS_OP_SET_FEATURE_LEVEL, WINED3D_CS_OP_PUSH_CONSTANTS, WINED3D_CS_OP_RESET_STATE, @@ -406,12 +405,6 @@ struct wined3d_cs_set_light_enable BOOL enable; };
-struct wined3d_cs_set_extra_ps_args -{ - enum wined3d_cs_op opcode; - struct wined3d_extra_ps_args args; -}; - struct wined3d_cs_set_feature_level { enum wined3d_cs_op opcode; @@ -616,7 +609,6 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_COLOR_KEY); WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT); WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT_ENABLE); - WINED3D_TO_STR(WINED3D_CS_OP_SET_EXTRA_PS_ARGS); WINED3D_TO_STR(WINED3D_CS_OP_SET_FEATURE_LEVEL); WINED3D_TO_STR(WINED3D_CS_OP_PUSH_CONSTANTS); WINED3D_TO_STR(WINED3D_CS_OP_RESET_STATE); @@ -2127,26 +2119,6 @@ void wined3d_device_context_emit_set_light_enable(struct wined3d_device_context wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_extra_ps_args(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_extra_ps_args *op = data; - - cs->state.extra_ps_args = op->args; - device_invalidate_state(cs->c.device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); -} - -void wined3d_device_context_emit_set_extra_ps_args(struct wined3d_device_context *context, - const struct wined3d_extra_ps_args *args) -{ - struct wined3d_cs_set_extra_ps_args *op; - - op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_EXTRA_PS_ARGS; - op->args = *args; - - wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); -} - static void wined3d_cs_exec_set_feature_level(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_feature_level *op = data; @@ -3020,7 +2992,6 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, - /* WINED3D_CS_OP_SET_EXTRA_PS_ARGS */ wined3d_cs_exec_set_extra_ps_args, /* WINED3D_CS_OP_SET_FEATURE_LEVEL */ wined3d_cs_exec_set_feature_level, /* WINED3D_CS_OP_PUSH_CONSTANTS */ wined3d_cs_exec_push_constants, /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index a0411214733..61b4244c15f 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -100,15 +100,22 @@ void state_shademode(struct wined3d_context *context, const struct wined3d_state { const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
- if (state->extra_ps_args.flat_shading) + switch (state->render_states[WINED3D_RS_SHADEMODE]) { - gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT); - checkGLcall("glShadeModel(GL_FLAT)"); - } - else - { - gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH); - checkGLcall("glShadeModel(GL_SMOOTH)"); + case WINED3D_SHADE_FLAT: + gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT); + checkGLcall("glShadeModel(GL_FLAT)"); + break; + case WINED3D_SHADE_GOURAUD: + /* WINED3D_SHADE_PHONG in practice is the same as WINED3D_SHADE_GOURAUD + * in D3D. */ + case WINED3D_SHADE_PHONG: + gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH); + checkGLcall("glShadeModel(GL_SMOOTH)"); + break; + default: + FIXME("Unrecognized shade mode %#x.\n", + state->render_states[WINED3D_RS_SHADEMODE]); } }
@@ -1563,15 +1570,15 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 11, 14}, { 16, 24}, { 27, 27}, - { 30, 34}, - { 36, 40}, + { 30, 33}, + { 39, 40}, { 42, 47}, { 49, 135}, {138, 139}, {144, 144}, {149, 150}, {153, 153}, - {156, 160}, + {157, 160}, {162, 165}, {167, 193}, {195, 209}, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 48943dbbe2a..b2e89704933 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1682,17 +1682,26 @@ static void shader_glsl_pointsize_uniform(struct wined3d_context_gl *context_gl, checkGLcall("glUniform1f"); }
-static void shader_glsl_load_fog_uniform(struct wined3d_context_gl *context_gl, +static void shader_glsl_load_fog_uniform(const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, struct glsl_shader_prog_link *prog) { - const struct wined3d_ffp_ps_constants *constants = wined3d_buffer_load_sysmem( - context_gl->c.device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], &context_gl->c); const struct wined3d_gl_info *gl_info = context_gl->gl_info; - - GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, &constants->fog.colour.r)); - GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, constants->fog.density)); - GL_EXTCALL(glUniform1f(prog->ps.fog_end_location, constants->fog.end)); - GL_EXTCALL(glUniform1f(prog->ps.fog_scale_location, constants->fog.scale)); + struct wined3d_color color; + float start, end, scale; + union + { + DWORD d; + float f; + } tmpvalue; + + wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_FOGCOLOR]); + GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, &color.r)); + tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY]; + GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, tmpvalue.f)); + get_fog_start_end(&context_gl->c, state, &start, &end); + scale = 1.0f / (end - start); + GL_EXTCALL(glUniform1f(prog->ps.fog_end_location, end)); + GL_EXTCALL(glUniform1f(prog->ps.fog_scale_location, scale)); checkGLcall("fog emulation uniforms"); }
@@ -12074,10 +12083,43 @@ static void glsl_fragment_pipe_shader(struct wined3d_context *context, context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; }
+static void glsl_fragment_pipe_fogparams(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG; +} + static void glsl_fragment_pipe_fog(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { + BOOL use_vshader = use_vs(state) && !state->shader[WINED3D_SHADER_TYPE_VERTEX]->is_ffp_vs; + enum fogsource new_source; + DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART]; + DWORD fogend = state->render_states[WINED3D_RS_FOGEND]; + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; + + if (!state->render_states[WINED3D_RS_FOGENABLE]) + return; + + if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE) + { + if (use_vshader || state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE + || context->stream_info.position_transformed) + new_source = FOGSOURCE_VS; + else + new_source = FOGSOURCE_FFP; + } + else + { + new_source = FOGSOURCE_FFP; + } + + if (new_source != context->fog_source || fogstart == fogend) + { + context->fog_source = new_source; + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG; + } }
static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, @@ -12088,6 +12130,9 @@ static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, /* Because of settings->texcoords_initialized and args->texcoords_initialized. */ if (!shader_glsl_full_ffp_varyings(gl_info)) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; + + if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE))) + glsl_fragment_pipe_fog(context, state, state_id); }
static void glsl_fragment_pipe_vs(struct wined3d_context *context, @@ -12150,6 +12195,12 @@ static void glsl_fragment_pipe_alpha_test(struct wined3d_context_gl *context_gl, } }
+static void glsl_fragment_pipe_shademode(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; +} + static const struct wined3d_state_entry_template glsl_fragment_pipe_state_template[] = { {STATE_VDECL, {STATE_VDECL, glsl_fragment_pipe_vdecl }, WINED3D_GL_EXT_NONE }, @@ -12160,8 +12211,14 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_srgbwrite }, ARB_FRAMEBUFFER_SRGB}, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), glsl_fragment_pipe_fogparams }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, ARB_POINT_SPRITE }, + {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), glsl_fragment_pipe_shader }, WINED3D_GL_VERSION_2_0}, {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), NULL }, WINED3D_GL_EXT_NONE }, @@ -12242,6 +12299,8 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GLSL_130 }, + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE }, };
@@ -12270,10 +12329,6 @@ const struct wined3d_fragment_pipe_ops glsl_fragment_pipe =
static void shader_glsl_update_legacy_states(struct wined3d_context_gl *context_gl, const struct wined3d_state *state) { - if (!context_gl->gl_info->supported[WINED3D_GLSL_130] - && (context_gl->c.shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL))) - state_shademode(&context_gl->c, state, STATE_RENDER(WINED3D_RS_SHADEMODE)); - if (!context_gl->gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) return;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 1c0aada0681..bbf873954b8 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3109,7 +3109,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 args->texcoords_initialized = wined3d_mask_from_size(WINED3D_MAX_FFP_TEXTURES); }
- args->pointsprite = state->extra_ps_args.point_sprite + args->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] && state->primitive_type == WINED3D_PT_POINTLIST;
if (d3d_info->ffp_alpha_test) @@ -3120,7 +3120,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 : WINED3D_CMP_ALWAYS) - 1;
if (d3d_info->emulated_flatshading) - args->flatshading = state->extra_ps_args.flat_shading; + args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT;
for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i) { diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index a033c69feec..51cfe58e255 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -1283,11 +1283,17 @@ static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context *
static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states[] = { + {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_nop}}, {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}}, + {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), state_nop}}, + {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_nop}}, + {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGEND), state_nop}}, + {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}}, + {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}}, {0}, /* Terminate */ }; diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index cb26f01a0b9..1407565aed5 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -69,8 +69,6 @@ struct wined3d_saved_states uint32_t rasterizer_state : 1; uint32_t position_transformed : 1; uint32_t bumpenv_constants : 1; - uint32_t fog_constants : 1; - uint32_t extra_ps_args : 1; };
struct stage_state @@ -329,8 +327,6 @@ void CDECL wined3d_stateblock_primary_dirtify_all_states(struct wined3d_device * states->rasterizer_state = 1; states->position_transformed = 1; states->bumpenv_constants = 1; - states->fog_constants = 1; - states->extra_ps_args = 1;
list_init(&stateblock->changed.changed_lights); RB_FOR_EACH_ENTRY(light, lights_tree, struct wined3d_light_info, entry) @@ -1671,6 +1667,8 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb case WINED3D_RS_DIFFUSEMATERIALSOURCE: case WINED3D_RS_EMISSIVEMATERIALSOURCE: case WINED3D_RS_FOGENABLE: + case WINED3D_RS_FOGTABLEMODE: + case WINED3D_RS_FOGVERTEXMODE: case WINED3D_RS_LIGHTING: case WINED3D_RS_LOCALVIEWER: case WINED3D_RS_NORMALIZENORMALS: @@ -1697,24 +1695,6 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb stateblock->changed.rasterizer_state = 1; break;
- case WINED3D_RS_FOGCOLOR: - case WINED3D_RS_FOGDENSITY: - case WINED3D_RS_FOGEND: - case WINED3D_RS_FOGSTART: - stateblock->changed.fog_constants = 1; - break; - - case WINED3D_RS_FOGTABLEMODE: - case WINED3D_RS_FOGVERTEXMODE: - stateblock->changed.ffp_vs_settings = 1; - stateblock->changed.fog_constants = 1; - break; - - case WINED3D_RS_POINTSPRITEENABLE: - case WINED3D_RS_SHADEMODE: - stateblock->changed.extra_ps_args = 1; - break; - default: break; } @@ -2466,7 +2446,6 @@ static void wined3d_stateblock_invalidate_initial_states(struct wined3d_stateblo stateblock->changed.ffp_vs_settings = 1; stateblock->changed.ffp_ps_settings = 1; stateblock->changed.bumpenv_constants = 1; - stateblock->changed.fog_constants = 1; }
static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const struct wined3d_stateblock *device_state, @@ -3203,11 +3182,6 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, case WINED3D_RS_POINTSCALE_C: case WINED3D_RS_TEXTUREFACTOR: case WINED3D_RS_ALPHAREF: - case WINED3D_RS_FOGCOLOR: - case WINED3D_RS_FOGDENSITY: - case WINED3D_RS_FOGEND: - case WINED3D_RS_FOGSTART: - case WINED3D_RS_POINTSPRITEENABLE: break;
case WINED3D_RS_ANTIALIAS: @@ -3948,15 +3922,6 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, WINED3D_SHADER_CONST_FFP_PS, 0, offsetof(struct wined3d_ffp_ps_constants, color_key), &constants); }
- if (changed->extra_ps_args) - { - struct wined3d_extra_ps_args args; - - args.point_sprite = state->rs[WINED3D_RS_POINTSPRITEENABLE]; - args.flat_shading = state->rs[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; - wined3d_device_context_emit_set_extra_ps_args(context, &args); - } - if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_ALPHAREF)) { float f = (state->rs[WINED3D_RS_ALPHAREF] & 0xff) / 255.0f; @@ -3966,46 +3931,6 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, offsetof(struct wined3d_ffp_ps_constants, alpha_test_ref), sizeof(f), &f); }
- if (changed->fog_constants || changed->ffp_vs_settings || changed->position_transformed) - { - bool rhw = state->vertex_declaration && state->vertex_declaration->position_transformed; - struct wined3d_ffp_fog_constants fog; - - wined3d_color_from_d3dcolor(&fog.colour, state->rs[WINED3D_RS_FOGCOLOR]); - fog.density = int_to_float(state->rs[WINED3D_RS_FOGDENSITY]); - - if (state->rs[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE - || (state->rs[WINED3D_RS_FOGVERTEXMODE] != WINED3D_FOG_NONE && !state->vs && !rhw)) - { - float start = int_to_float(state->rs[WINED3D_RS_FOGSTART]); - float end = int_to_float(state->rs[WINED3D_RS_FOGEND]); - - if (start == end) - { - /* With vertex fog, everything is fogged. - * With pixel fog, coordinates < start are unfogged, - * and coordinates > start are fogged. - * Windows drivers disagree when coord == start. */ - fog.end = 0.0f; - fog.scale = 0.0f; - } - else - { - fog.end = end; - fog.scale = 1.0f / (end - start); - } - } - else - { - fog.end = 0.0f; - fog.scale = -1.0f; - } - - wined3d_device_context_push_constants(context, - WINED3D_PUSH_CONSTANTS_PS_FFP, WINED3D_SHADER_CONST_PS_FOG, - offsetof(struct wined3d_ffp_ps_constants, fog), sizeof(fog), &fog); - } - if (changed->vertexShader) { wined3d_device_context_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, state->vs); diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index f068c6ebf77..f176e09fa3c 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5786,6 +5786,46 @@ void get_pointsize_minmax(const struct wined3d_context *context, const struct wi *out_max = max.f; }
+void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state, + float *start, float *end) +{ + union + { + DWORD d; + float f; + } tmpvalue; + + switch (context->fog_source) + { + case FOGSOURCE_VS: + *start = 1.0f; + *end = 0.0f; + break; + + case FOGSOURCE_FFP: + tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART]; + *start = tmpvalue.f; + tmpvalue.d = state->render_states[WINED3D_RS_FOGEND]; + *end = tmpvalue.f; + /* Special handling for fog_start == fog_end. In d3d with vertex + * fog, everything is fogged. With table fog, everything with + * fog_coord < fog_start is unfogged, and fog_coord > fog_start + * is fogged. Windows drivers disagree when fog_coord == fog_start. */ + if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE && *start == *end) + { + *start = -INFINITY; + *end = 0.0f; + } + break; + + default: + /* This should not happen, context->fog_source is set in wined3d, not the app. */ + ERR("Unexpected fog coordinate source.\n"); + *start = 0.0f; + *end = 0.0f; + } +} + static BOOL wined3d_get_primary_display(WCHAR *display) { DISPLAY_DEVICEW display_device; @@ -6446,7 +6486,7 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_state *state, settings->texcoords_initialized = wined3d_mask_from_size(WINED3D_MAX_FFP_TEXTURES); }
- settings->pointsprite = state->extra_ps_args.point_sprite + settings->pointsprite = state->render_states[WINED3D_RS_POINTSPRITEENABLE] && state->primitive_type == WINED3D_PT_POINTLIST;
if (d3d_info->ffp_alpha_test) @@ -6457,7 +6497,7 @@ void wined3d_ffp_get_fs_settings(const struct wined3d_state *state, : WINED3D_CMP_ALWAYS) - 1;
if (d3d_info->emulated_flatshading) - settings->flatshading = state->extra_ps_args.flat_shading; + settings->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; else settings->flatshading = FALSE; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9a391475ba8..e73ba018929 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1811,6 +1811,11 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state #define STATE_UNORDERED_ACCESS_VIEW_BINDING(a) ((a) == WINED3D_PIPELINE_GRAPHICS ? \ STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING : STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING)
+enum fogsource { + FOGSOURCE_FFP, + FOGSOURCE_VS, +}; + /* Direct3D terminology with little modifications. We do not have an issued * state because only the driver knows about it, but we have a created state * because D3D allows GetData() on a created query, but OpenGL doesn't. */ @@ -1910,6 +1915,8 @@ struct wined3d_context
DWORD constant_update_mask; DWORD numbered_array_mask; + enum fogsource fog_source; +
void *shader_backend_data;
@@ -2841,13 +2848,7 @@ struct wined3d_ffp_ps_constants
/* States not used by the HLSL pipeline. */ float alpha_test_ref; - struct wined3d_ffp_fog_constants - { - float scale; - float end; - float density; - struct wined3d_color colour; - } fog; + float padding[3]; /* to align to 16 bytes */ };
/* Float/int/bool constants are bound to VKD3D_SHADER_D3DBC_*_CONSTANT_REGISTER @@ -2869,16 +2870,6 @@ enum wined3d_push_constants WINED3D_PUSH_CONSTANTS_COUNT, };
-/* Pixel shader states part of the Direct3D 1-9 FFP, which are also used when - * using shaders, which are not implemented as uniforms. - * These eventually make their way into vs_compile_args / ps_compile_args, but - * those structs also include states other than the FFP states. */ -struct wined3d_extra_ps_args -{ - bool point_sprite; - bool flat_shading; -}; - struct wined3d_blend_state { LONG refcount; @@ -2979,7 +2970,6 @@ struct wined3d_state uint32_t sample_mask; struct wined3d_depth_stencil_state *depth_stencil_state; unsigned int stencil_ref; - struct wined3d_extra_ps_args extra_ps_args; bool depth_bounds_enable; float depth_bounds_min, depth_bounds_max; struct wined3d_rasterizer_state *rasterizer_state; @@ -3767,8 +3757,6 @@ void wined3d_device_context_emit_set_depth_stencil_state(struct wined3d_device_c struct wined3d_depth_stencil_state *state, unsigned int stencil_ref); void wined3d_device_context_emit_set_depth_stencil_view(struct wined3d_device_context *context, struct wined3d_rendertarget_view *view); -void wined3d_device_context_emit_set_extra_ps_args(struct wined3d_device_context *context, - const struct wined3d_extra_ps_args *args); void wined3d_device_context_emit_set_feature_level(struct wined3d_device_context *context, enum wined3d_feature_level level); void wined3d_device_context_emit_set_index_buffer(struct wined3d_device_context *context, struct wined3d_buffer *buffer, @@ -4477,6 +4465,8 @@ void get_texture_matrix(const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat); void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state, float *out_min, float *out_max); +void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state, + float *start, float *end);
struct wined3d_palette { diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 583afd8e94a..b1797cea24a 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -595,18 +595,8 @@ DWORD EVENT_x11_time_to_win32_time(Time time) static inline BOOL can_activate_window( HWND hwnd ) { LONG style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); - struct x11drv_win_data *data; RECT rect;
- if ((data = get_win_data( hwnd ))) - { - style = style & ~(WS_VISIBLE | WS_MINIMIZE | WS_MAXIMIZE); - if (data->current_state.wm_state != WithdrawnState) style |= WS_VISIBLE; - if (data->current_state.wm_state == IconicState) style |= WS_MINIMIZE; - if (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) style |= WS_MAXIMIZE; - release_win_data( data ); - } - if (!(style & WS_VISIBLE)) return FALSE; if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; if (style & WS_MINIMIZE) return FALSE; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 305757e6371..0e617d41316 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1122,6 +1122,35 @@ void update_user_time( Time time ) XUnlockDisplay( gdi_display ); }
+static void update_desktop_fullscreen( Display *display ) +{ + XEvent xev; + + if (!is_virtual_desktop()) return; + + xev.xclient.type = ClientMessage; + xev.xclient.window = root_window; + xev.xclient.message_type = x11drv_atom(_NET_WM_STATE); + xev.xclient.serial = 0; + xev.xclient.display = display; + xev.xclient.send_event = True; + xev.xclient.format = 32; + xev.xclient.data.l[0] = is_desktop_fullscreen() ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_FULLSCREEN); + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 1; + + TRACE("action=%li\n", xev.xclient.data.l[0]); + + XSendEvent( display, DefaultRootWindow(display), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev ); + + xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_VERT); + xev.xclient.data.l[2] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_HORZ); + XSendEvent( display, DefaultRootWindow(display), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev ); +} + /* Update _NET_WM_FULLSCREEN_MONITORS when _NET_WM_STATE_FULLSCREEN is set to support fullscreen * windows spanning multiple monitors */ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) @@ -1299,18 +1328,18 @@ static void window_set_config( struct x11drv_win_data *data, const RECT *new_rec */ static void update_net_wm_states( struct x11drv_win_data *data ) { - static const UINT fullscreen_mask = (1 << NET_WM_STATE_MAXIMIZED) | (1 << NET_WM_STATE_FULLSCREEN); UINT style, ex_style, new_state = 0;
if (!data->managed || data->embedded) return; if (data->whole_window == root_window) { - if (is_virtual_desktop()) window_set_net_wm_state( data, is_desktop_fullscreen() ? fullscreen_mask : 0 ); + update_desktop_fullscreen(data->display); return; }
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); - if (style & WS_MINIMIZE) new_state |= data->desired_state.net_wm_state & fullscreen_mask; + if (style & WS_MINIMIZE) + new_state |= data->desired_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); if (data->is_fullscreen) { if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) @@ -2315,7 +2344,6 @@ BOOL X11DRV_DestroyNotify( HWND hwnd, XEvent *event ) /* initialize the desktop window id in the desktop manager process */ static BOOL create_desktop_win_data( Window win, HWND hwnd ) { - static const UINT fullscreen_mask = (1 << NET_WM_STATE_MAXIMIZED) | (1 << NET_WM_STATE_FULLSCREEN); struct x11drv_thread_data *thread_data = x11drv_thread_data(); Display *display = thread_data->display; struct x11drv_win_data *data; @@ -2325,7 +2353,6 @@ static BOOL create_desktop_win_data( Window win, HWND hwnd ) window_set_managed( data, TRUE ); NtUserSetProp( data->hwnd, whole_window_prop, (HANDLE)win ); set_initial_wm_hints( display, win ); - if (is_desktop_fullscreen()) window_set_net_wm_state( data, fullscreen_mask ); release_win_data( data ); if (thread_data->clip_window) XReparentWindow( display, thread_data->clip_window, win, 0, 0 ); return TRUE; @@ -2370,6 +2397,13 @@ void X11DRV_SetDesktopWindow( HWND hwnd ) ERR( "Failed to create virtual desktop window data\n" ); root_window = DefaultRootWindow( gdi_display ); } + else if (is_desktop_fullscreen()) + { + Display *display = x11drv_thread_data()->display; + TRACE("setting desktop to fullscreen\n"); + XChangeProperty( display, root_window, x11drv_atom(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace, + (unsigned char*)&x11drv_atom(_NET_WM_STATE_FULLSCREEN), 1 ); + } } else { diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index be8c1fe2b03..a77f2d6d5b4 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -986,7 +986,6 @@ NTSTATUS WINAPI wow64_NtSetInformationThread( UINT *args ) switch (class) { case ThreadZeroTlsCell: /* ULONG */ - case ThreadPriority: /* ULONG */ case ThreadBasePriority: /* ULONG */ case ThreadHideFromDebugger: /* void */ case ThreadEnableAlignmentFaultFixup: /* BOOLEAN */ diff --git a/dlls/wow64/security.c b/dlls/wow64/security.c index a7616331600..49f4adea3c1 100644 --- a/dlls/wow64/security.c +++ b/dlls/wow64/security.c @@ -471,7 +471,7 @@ NTSTATUS WINAPI wow64_NtQueryInformationToken( UINT *args ) if (!status) { dacl32->DefaultDacl = dacl->DefaultDacl ? PtrToUlong( dacl32 + 1 ) : 0; - if (dacl->DefaultDacl) memcpy( dacl32 + 1, dacl->DefaultDacl, ret_size - sizeof(*dacl) ); + memcpy( dacl32 + 1, dacl->DefaultDacl, ret_size - sizeof(*dacl) ); } if (retlen) *retlen = ret_size + sizeof(*dacl32) - sizeof(*dacl); return status; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 3cdc9375e2d..7929be7b17b 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1205,9 +1205,9 @@ struct get_process_info_reply unsigned int session_id; int exit_code; int priority; - unsigned short base_priority; unsigned short machine; /* VARARG(image,pe_image_info); */ + char __pad_62[2]; };
@@ -1299,7 +1299,7 @@ struct get_thread_info_reply affinity_t affinity; int exit_code; int priority; - int base_priority; + int last; int suspend_count; unsigned int flags; data_size_t desc_len; @@ -1307,7 +1307,6 @@ struct get_thread_info_reply }; #define GET_THREAD_INFO_FLAG_DBG_HIDDEN 0x01 #define GET_THREAD_INFO_FLAG_TERMINATED 0x02 -#define GET_THREAD_INFO_FLAG_LAST 0x04
@@ -1331,25 +1330,24 @@ struct set_thread_info_request { struct request_header __header; obj_handle_t handle; - int priority; + int mask; int base_priority; affinity_t affinity; client_ptr_t entry_point; obj_handle_t token; - unsigned int mask; /* VARARG(desc,unicode_str); */ + char __pad_44[4]; }; struct set_thread_info_reply { struct reply_header __header; }; -#define SET_THREAD_INFO_PRIORITY 0x01 -#define SET_THREAD_INFO_BASE_PRIORITY 0x02 -#define SET_THREAD_INFO_AFFINITY 0x04 -#define SET_THREAD_INFO_TOKEN 0x08 -#define SET_THREAD_INFO_ENTRYPOINT 0x10 -#define SET_THREAD_INFO_DESCRIPTION 0x20 -#define SET_THREAD_INFO_DBG_HIDDEN 0x40 +#define SET_THREAD_INFO_BASE_PRIORITY 0x01 +#define SET_THREAD_INFO_AFFINITY 0x02 +#define SET_THREAD_INFO_TOKEN 0x04 +#define SET_THREAD_INFO_ENTRYPOINT 0x08 +#define SET_THREAD_INFO_DESCRIPTION 0x10 +#define SET_THREAD_INFO_DBG_HIDDEN 0x20
@@ -6798,6 +6796,6 @@ union generic_reply struct set_keyboard_repeat_reply set_keyboard_repeat_reply; };
-#define SERVER_PROTOCOL_VERSION 863 +#define SERVER_PROTOCOL_VERSION 859
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/fd.c b/server/fd.c index bb0e90d99d0..e1b969a0439 100644 --- a/server/fd.c +++ b/server/fd.c @@ -566,9 +566,6 @@ static inline void main_loop_epoll(void) int i, ret, timeout; struct timespec ts; struct epoll_event events[128]; -#ifdef HAVE_EPOLL_PWAIT2 - static int failed_epoll_pwait2 = 0; -#endif
assert( POLLIN == EPOLLIN ); assert( POLLOUT == EPOLLOUT ); @@ -585,15 +582,10 @@ static inline void main_loop_epoll(void) if (epoll_fd == -1) break; /* an error occurred with epoll */
#ifdef HAVE_EPOLL_PWAIT2 - if (!failed_epoll_pwait2) - { - ret = epoll_pwait2( epoll_fd, events, ARRAY_SIZE( events ), timeout == -1 ? NULL : &ts, NULL ); - if (ret == -1 && errno == ENOSYS) - failed_epoll_pwait2 = 1; - } - if (failed_epoll_pwait2) + ret = epoll_pwait2( epoll_fd, events, ARRAY_SIZE( events ), timeout == -1 ? NULL : &ts, NULL ); +#else + ret = epoll_wait( epoll_fd, events, ARRAY_SIZE( events ), timeout ); #endif - ret = epoll_wait( epoll_fd, events, ARRAY_SIZE( events ), timeout );
set_current_time();
diff --git a/server/process.c b/server/process.c index b161e3394ba..1980e2ca777 100644 --- a/server/process.c +++ b/server/process.c @@ -1512,7 +1512,6 @@ DECL_HANDLER(get_process_info) reply->ppid = process->parent_id; reply->exit_code = process->exit_code; reply->priority = process->priority; - reply->base_priority = priority_from_class_and_level( process->priority, THREAD_PRIORITY_NORMAL ); reply->affinity = process->affinity; reply->peb = process->peb; reply->start_time = process->start_time; @@ -2015,7 +2014,7 @@ DECL_HANDLER(list_processes) thread_info->start_time = thread->creation_time; thread_info->tid = thread->id; thread_info->base_priority = thread->base_priority; - thread_info->current_priority = thread->priority; + thread_info->current_priority = thread->base_priority; /* FIXME */ thread_info->unix_tid = thread->unix_tid; thread_info->entry_point = thread->entry_point; thread_info->teb = thread->teb; diff --git a/server/process.h b/server/process.h index e49529b06fa..9238d638f15 100644 --- a/server/process.h +++ b/server/process.h @@ -116,7 +116,6 @@ extern void kill_process( struct process *process, int violent_death ); extern void kill_console_processes( struct thread *renderer, int exit_code ); extern void detach_debugged_processes( struct debug_obj *debug_obj, int exit_code ); extern void enum_processes( int (*cb)(struct process*, void*), void *user); -extern int priority_from_class_and_level( int priority_class, int priority_level ); extern void set_process_priority( struct process *process, int priority );
/* console functions */ diff --git a/server/protocol.def b/server/protocol.def index 63bb0111473..36056c00e24 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1158,7 +1158,6 @@ struct obj_locator unsigned int session_id; /* process session id */ int exit_code; /* process exit code */ int priority; /* priority class */ - unsigned short base_priority; /* process base priority */ unsigned short machine; /* process architecture */ VARARG(image,pe_image_info); /* image info for main exe */ @END @@ -1222,8 +1221,8 @@ struct obj_locator client_ptr_t entry_point; /* thread entry point */ affinity_t affinity; /* thread affinity mask */ int exit_code; /* thread exit code */ - int priority; /* current thread priority */ - int base_priority; /* base priority level (relative to process base priority class) */ + int priority; /* thread priority level */ + int last; /* last thread in process */ int suspend_count; /* thread suspend count */ unsigned int flags; /* GET_THREAD_INFO_FLAG_ flags */ data_size_t desc_len; /* description length in bytes */ @@ -1231,7 +1230,6 @@ struct obj_locator @END #define GET_THREAD_INFO_FLAG_DBG_HIDDEN 0x01 #define GET_THREAD_INFO_FLAG_TERMINATED 0x02 -#define GET_THREAD_INFO_FLAG_LAST 0x04
/* Retrieve information about thread times */ @@ -1248,21 +1246,19 @@ struct obj_locator /* Set a thread information */ @REQ(set_thread_info) obj_handle_t handle; /* thread handle */ - int priority; /* current thread priority */ + int mask; /* setting mask (see below) */ int base_priority;/* base priority level (relative to process base priority class) */ affinity_t affinity; /* affinity mask */ client_ptr_t entry_point; /* thread entry point */ obj_handle_t token; /* impersonation token */ - unsigned int mask; /* setting mask (see below) */ VARARG(desc,unicode_str); /* description string */ @END -#define SET_THREAD_INFO_PRIORITY 0x01 -#define SET_THREAD_INFO_BASE_PRIORITY 0x02 -#define SET_THREAD_INFO_AFFINITY 0x04 -#define SET_THREAD_INFO_TOKEN 0x08 -#define SET_THREAD_INFO_ENTRYPOINT 0x10 -#define SET_THREAD_INFO_DESCRIPTION 0x20 -#define SET_THREAD_INFO_DBG_HIDDEN 0x40 +#define SET_THREAD_INFO_BASE_PRIORITY 0x01 +#define SET_THREAD_INFO_AFFINITY 0x02 +#define SET_THREAD_INFO_TOKEN 0x04 +#define SET_THREAD_INFO_ENTRYPOINT 0x08 +#define SET_THREAD_INFO_DESCRIPTION 0x10 +#define SET_THREAD_INFO_DBG_HIDDEN 0x20
/* Suspend a thread */ diff --git a/server/request_handlers.h b/server/request_handlers.h index 2afc9707869..fa2817c9a76 100644 --- a/server/request_handlers.h +++ b/server/request_handlers.h @@ -730,8 +730,7 @@ C_ASSERT( offsetof(struct get_process_info_reply, end_time) == 40 ); C_ASSERT( offsetof(struct get_process_info_reply, session_id) == 48 ); C_ASSERT( offsetof(struct get_process_info_reply, exit_code) == 52 ); C_ASSERT( offsetof(struct get_process_info_reply, priority) == 56 ); -C_ASSERT( offsetof(struct get_process_info_reply, base_priority) == 60 ); -C_ASSERT( offsetof(struct get_process_info_reply, machine) == 62 ); +C_ASSERT( offsetof(struct get_process_info_reply, machine) == 60 ); C_ASSERT( sizeof(struct get_process_info_reply) == 64 ); C_ASSERT( offsetof(struct get_process_debug_info_request, handle) == 12 ); C_ASSERT( sizeof(struct get_process_debug_info_request) == 16 ); @@ -769,7 +768,7 @@ C_ASSERT( offsetof(struct get_thread_info_reply, entry_point) == 24 ); C_ASSERT( offsetof(struct get_thread_info_reply, affinity) == 32 ); C_ASSERT( offsetof(struct get_thread_info_reply, exit_code) == 40 ); C_ASSERT( offsetof(struct get_thread_info_reply, priority) == 44 ); -C_ASSERT( offsetof(struct get_thread_info_reply, base_priority) == 48 ); +C_ASSERT( offsetof(struct get_thread_info_reply, last) == 48 ); C_ASSERT( offsetof(struct get_thread_info_reply, suspend_count) == 52 ); C_ASSERT( offsetof(struct get_thread_info_reply, flags) == 56 ); C_ASSERT( offsetof(struct get_thread_info_reply, desc_len) == 60 ); @@ -782,12 +781,11 @@ C_ASSERT( offsetof(struct get_thread_times_reply, unix_pid) == 24 ); C_ASSERT( offsetof(struct get_thread_times_reply, unix_tid) == 28 ); C_ASSERT( sizeof(struct get_thread_times_reply) == 32 ); C_ASSERT( offsetof(struct set_thread_info_request, handle) == 12 ); -C_ASSERT( offsetof(struct set_thread_info_request, priority) == 16 ); +C_ASSERT( offsetof(struct set_thread_info_request, mask) == 16 ); C_ASSERT( offsetof(struct set_thread_info_request, base_priority) == 20 ); C_ASSERT( offsetof(struct set_thread_info_request, affinity) == 24 ); C_ASSERT( offsetof(struct set_thread_info_request, entry_point) == 32 ); C_ASSERT( offsetof(struct set_thread_info_request, token) == 40 ); -C_ASSERT( offsetof(struct set_thread_info_request, mask) == 44 ); C_ASSERT( sizeof(struct set_thread_info_request) == 48 ); C_ASSERT( offsetof(struct suspend_thread_request, handle) == 12 ); C_ASSERT( sizeof(struct suspend_thread_request) == 16 ); diff --git a/server/request_trace.h b/server/request_trace.h index bd961791024..91483965e8f 100644 --- a/server/request_trace.h +++ b/server/request_trace.h @@ -204,7 +204,6 @@ static void dump_get_process_info_reply( const struct get_process_info_reply *re fprintf( stderr, ", session_id=%08x", req->session_id ); fprintf( stderr, ", exit_code=%d", req->exit_code ); fprintf( stderr, ", priority=%d", req->priority ); - fprintf( stderr, ", base_priority=%04x", req->base_priority ); fprintf( stderr, ", machine=%04x", req->machine ); dump_varargs_pe_image_info( ", image=", cur_size ); } @@ -273,7 +272,7 @@ static void dump_get_thread_info_reply( const struct get_thread_info_reply *req dump_uint64( ", affinity=", &req->affinity ); fprintf( stderr, ", exit_code=%d", req->exit_code ); fprintf( stderr, ", priority=%d", req->priority ); - fprintf( stderr, ", base_priority=%d", req->base_priority ); + fprintf( stderr, ", last=%d", req->last ); fprintf( stderr, ", suspend_count=%d", req->suspend_count ); fprintf( stderr, ", flags=%08x", req->flags ); fprintf( stderr, ", desc_len=%u", req->desc_len ); @@ -296,12 +295,11 @@ static void dump_get_thread_times_reply( const struct get_thread_times_reply *re static void dump_set_thread_info_request( const struct set_thread_info_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); - fprintf( stderr, ", priority=%d", req->priority ); + fprintf( stderr, ", mask=%d", req->mask ); fprintf( stderr, ", base_priority=%d", req->base_priority ); dump_uint64( ", affinity=", &req->affinity ); dump_uint64( ", entry_point=", &req->entry_point ); fprintf( stderr, ", token=%04x", req->token ); - fprintf( stderr, ", mask=%08x", req->mask ); dump_varargs_unicode_str( ", desc=", cur_size ); }
diff --git a/server/thread.c b/server/thread.c index 27a40ce38ad..8797af32648 100644 --- a/server/thread.c +++ b/server/thread.c @@ -405,7 +405,6 @@ static inline void init_thread_structure( struct thread *thread ) thread->wait_fd = NULL; thread->state = RUNNING; thread->exit_code = 0; - thread->priority = 0; thread->base_priority = 0; thread->suspend = 0; thread->dbg_hidden = 0; @@ -772,22 +771,7 @@ affinity_t get_thread_affinity( struct thread *thread ) return mask; }
-unsigned int set_thread_priority( struct thread *thread, int priority ) -{ - int priority_class = thread->process->priority; - - if (priority < LOW_PRIORITY + 1 || priority > HIGH_PRIORITY) return STATUS_INVALID_PARAMETER; - if (priority_class != PROCESS_PRIOCLASS_REALTIME && priority >= LOW_REALTIME_PRIORITY) return STATUS_PRIVILEGE_NOT_HELD; - - thread->priority = priority; - - /* if thread is gone or hasn't started yet, this will be called again from init_thread with a unix_tid */ - if (thread->state == RUNNING && thread->unix_tid != -1) apply_thread_priority( thread, priority ); - - return STATUS_SUCCESS; -} - -int priority_from_class_and_level( int priority_class, int priority_level ) +static int priority_from_class_and_level( int priority_class, int priority_level ) { /* offsets taken from https://learn.microsoft.com/en-us/windows/win32/procthread/scheduling-priori... */ static const int class_offsets[] = { 4, 8, 13, 24, 6, 10 }; @@ -828,18 +812,18 @@ unsigned int set_thread_base_priority( struct thread *thread, int base_priority return STATUS_INVALID_PARAMETER;
thread->base_priority = base_priority; - return set_thread_priority( thread, priority_from_class_and_level( priority_class, base_priority ) ); + + /* if thread is gone or hasn't started yet, this will be called again from init_thread with a unix_tid */ + if (thread->state == RUNNING && thread->unix_tid != -1) + apply_thread_priority( thread, priority_from_class_and_level( priority_class, base_priority ) ); + + return STATUS_SUCCESS; }
/* set all information about a thread */ static void set_thread_info( struct thread *thread, const struct set_thread_info_request *req ) { - if (req->mask & SET_THREAD_INFO_PRIORITY) - { - unsigned int status = set_thread_priority( thread, req->priority ); - if (status) set_error( status ); - } if (req->mask & SET_THREAD_INFO_BASE_PRIORITY) { unsigned int status = set_thread_base_priority( thread, req->base_priority ); @@ -1725,9 +1709,9 @@ DECL_HANDLER(get_thread_info) reply->teb = thread->teb; reply->entry_point = thread->entry_point; reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STATUS_PENDING; - reply->priority = thread->priority; - reply->base_priority = thread->base_priority; + reply->priority = thread->base_priority; reply->affinity = thread->affinity; + reply->last = thread->process->running_threads == 1; reply->suspend_count = thread->suspend; reply->desc_len = thread->desc_len; reply->flags = 0; @@ -1735,8 +1719,6 @@ DECL_HANDLER(get_thread_info) reply->flags |= GET_THREAD_INFO_FLAG_DBG_HIDDEN; if (thread->state == TERMINATED) reply->flags |= GET_THREAD_INFO_FLAG_TERMINATED; - if (thread->process->running_threads == 1) - reply->flags |= GET_THREAD_INFO_FLAG_LAST;
if (thread->desc && get_reply_max_size()) { diff --git a/server/thread.h b/server/thread.h index 7fdae3a629f..33d150df9cb 100644 --- a/server/thread.h +++ b/server/thread.h @@ -81,7 +81,6 @@ struct thread client_ptr_t teb; /* TEB address (in client address space) */ client_ptr_t entry_point; /* entry point (in client address space) */ affinity_t affinity; /* affinity mask */ - int priority; /* current thread priority */ int base_priority; /* base priority level (relative to process base priority class) */ int suspend; /* suspend count */ int dbg_hidden; /* hidden from debugger */ @@ -123,7 +122,6 @@ extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum extern int thread_add_inflight_fd( struct thread *thread, int client, int server ); extern int thread_get_inflight_fd( struct thread *thread, int client ); extern struct token *thread_get_impersonation_token( struct thread *thread ); -extern unsigned int set_thread_priority( struct thread *thread, int priority ); extern unsigned int set_thread_base_priority( struct thread *thread, int base_priority ); extern int set_thread_affinity( struct thread *thread, affinity_t affinity ); extern int suspend_thread( struct thread *thread ); diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index cb982de5204..0e9ad6bcab2 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -142,7 +142,6 @@ static const char* app_loader_template = static const char *output_file_name; static const char *output_debug_file; static const char *output_implib; -static const char *output; static int keep_generated = 0; static int verbose; const char *temp_dir = NULL; @@ -168,7 +167,6 @@ static enum processor { proc_cc, proc_cxx, proc_cpp } processor = proc_cc; enum file_type { file_na, file_other, file_obj, file_res, file_rc, file_arh, file_dll, file_so, file_spec };
static bool is_pe; -static bool is_static; static bool is_shared; static bool is_gui_app; static bool is_unicode_app; @@ -187,8 +185,6 @@ static bool large_address_aware; static bool wine_builtin; static bool unwind_tables; static bool strip; -static bool compile_only; -static bool skip_link; static bool no_default_config; static int force_pointer_size;
@@ -198,7 +194,6 @@ static const char *file_align; static const char *subsystem; static const char *entry_point; static const char *native_arch; -static struct strarray file_args; static struct strarray linker_args; static struct strarray compiler_args; static struct strarray winebuild_args; @@ -515,8 +510,6 @@ static struct strarray get_link_args( const char *output_name ) strarray_add( &flags, "-image_base" ); strarray_add( &flags, image_base ); } - /* On Mac, change -s into -Wl,-x. ld's -s switch is deprecated, - * and it doesn't work on Tiger with MH_BUNDLEs anyway */ if (strip) strarray_add( &flags, "-Wl,-x" ); strarray_addall( &link_args, flags ); return link_args; @@ -568,8 +561,6 @@ static struct strarray get_link_args( const char *output_name ) if (output_implib) strarray_add(&link_args, strmake("-Wl,--out-implib,%s", output_implib));
- if (strip) strarray_add( &link_args, "-s" ); - if (!try_link( link_args, "-Wl,--file-alignment,0x1000" )) strarray_add( &link_args, strmake( "-Wl,--file-alignment,%s", file_align )); else if (!try_link( link_args, "-Wl,-Xlink=-filealign:0x1000" )) @@ -582,7 +573,7 @@ static struct strarray get_link_args( const char *output_name )
case PLATFORM_WINDOWS: strarray_add( &link_args, "-nodefaultlibs" ); - strarray_add( &link_args, "-nostdlib" ); + strarray_add( &link_args, "-nostartfiles" );
if (is_shared || is_win16_app) { @@ -602,9 +593,7 @@ static struct strarray get_link_args( const char *output_name ) strarray_add(&link_args, "-Wl,-debug"); strarray_add(&link_args, strmake("-Wl,-pdb:%s", output_debug_file)); } - else if (strip) - strarray_add( &link_args, "-s" ); - else + else if (!strip) strarray_add(&link_args, "-Wl,-debug:dwarf");
if (use_build_id) @@ -636,7 +625,6 @@ static struct strarray get_link_args( const char *output_name )
/* generic Unix shared library flags */
- if (strip) strarray_add( &link_args, "-s" ); strarray_add( &link_args, "-shared" ); strarray_add( &link_args, "-Wl,-Bsymbolic" ); if (!noshortwchar && target.cpu == CPU_ARM) @@ -845,7 +833,7 @@ static struct strarray get_compat_defines( int gcc_defs ) return args; }
-static void compile( struct strarray files, const char *output_name, int compile_only ) +static void compile( struct strarray files, const char* lang, const char *output_name, int compile_only ) { struct strarray comp_args = get_translator(); unsigned int i, j; @@ -892,15 +880,15 @@ static void compile( struct strarray files, const char *output_name, int compile /* the rest of the pass-through parameters */ strarray_addall(&comp_args, compiler_args);
+ /* the language option, if any */ + if (lang && strcmp(lang, "-xnone")) + strarray_add(&comp_args, lang); + /* last, but not least, the files */ for ( j = 0; j < files.count; j++ ) { - if (files.str[j][0] == '-') - { - /* keep -x and bare '-' (i.e. stdin) options */ - if (files.str[j][1] && files.str[j][1] != 'x') continue; - } - strarray_add(&comp_args, files.str[j]); + if (files.str[j][0] != '-' || !files.str[j][1]) /* not an option or bare '-' (i.e. stdin) */ + strarray_add(&comp_args, files.str[j]); }
/* standard includes come last in the include search path */ @@ -944,9 +932,8 @@ static const char* compile_to_object(const char* file, const char* lang) char *output_name = make_temp_file(get_basename_noext(file), ".o"); struct strarray files = empty_strarray;
- if (lang) strarray_add(&files, lang); strarray_add(&files, file); - compile(files, output_name, 1); + compile(files, lang, output_name, 1); return output_name; }
@@ -1228,8 +1215,6 @@ static void build(struct strarray input_files, const char *output) return; }
- if (is_static) error("Static linking is not supported\n"); - /* generate app loader only for .exe */ if (is_shared || is_pe || strendswith(output_file, ".so")) generate_app_loader = 0; @@ -1564,6 +1549,12 @@ static int is_linker_arg(const char* arg) return 0; }
+static void parse_target_option( const char *name ) +{ + target_alias = xstrdup( name ); + if (!parse_target( name, &target )) error( "Invalid target specification '%s'\n", name ); +} + static int is_option( struct strarray args, int i, const char *option, const char **option_arg ) { if (!strcmp( args.str[i], option )) @@ -1582,10 +1573,14 @@ static int is_option( struct strarray args, int i, const char *option, const cha
int main(int argc, char **argv) { - int i, c, next_is_arg = 0; + int i, c, next_is_arg = 0, linking = 1; int raw_compiler_arg, raw_linker_arg, raw_winebuild_arg; + int compile_only = 0; struct strarray args = empty_strarray; + struct strarray files = empty_strarray; + const char *output_name = NULL; const char* option_arg; + char* lang = 0; char* str;
init_signals( exit_on_signal ); @@ -1720,7 +1715,7 @@ int main(int argc, char **argv) raw_linker_arg = 1; break; case 'b': - target_alias = option_arg; + parse_target_option( option_arg ); raw_compiler_arg = 0; break; case 'V': @@ -1729,11 +1724,11 @@ int main(int argc, char **argv) break; case 'c': /* compile or assemble */ raw_compiler_arg = 0; - if (args.str[i][2] == 0) compile_only = true; - break; + if (args.str[i][2] == 0) compile_only = 1; + /* fall through */ case 'S': /* generate assembler code */ case 'E': /* preprocess only */ - if (args.str[i][2] == 0) skip_link = true; + if (args.str[i][2] == 0) linking = 0; break; case 'f': if (strcmp("-fno-short-wchar", args.str[i]) == 0) @@ -1753,7 +1748,7 @@ int main(int argc, char **argv) if (!strcmp( "-isysroot", args.str[i] )) isysroot = args.str[i + 1]; break; case 'l': - strarray_add(&file_args, strmake("-l%s", option_arg)); + strarray_add(&files, strmake("-l%s", option_arg)); raw_compiler_arg = 0; break; case 'L': @@ -1761,7 +1756,7 @@ int main(int argc, char **argv) raw_compiler_arg = 0; break; case 'M': /* map file generation */ - skip_link = true; + linking = 0; break; case 'm': if (strcmp("-mno-cygwin", args.str[i]) == 0) @@ -1835,7 +1830,7 @@ int main(int argc, char **argv) nostartfiles = true; break; case 'o': - output = option_arg; + output_name = option_arg; raw_compiler_arg = 0; break; case 'p': @@ -1847,7 +1842,7 @@ int main(int argc, char **argv) break; case 's': if (strcmp("-static", args.str[i]) == 0) - is_static = true; + linking = -1; else if(strcmp("-save-temps", args.str[i]) == 0) keep_generated = 1; else if (strncmp("-specs=", args.str[i], 7) == 0) @@ -1857,8 +1852,12 @@ int main(int argc, char **argv) is_shared = true; raw_compiler_arg = raw_linker_arg = 0; } - else if (strcmp("-s", args.str[i]) == 0) + else if (strcmp("-s", args.str[i]) == 0 && target.platform == PLATFORM_APPLE) { + /* On Mac, change -s into -Wl,-x. ld's -s switch + * is deprecated, and it doesn't work on Tiger with + * MH_BUNDLEs anyway + */ strip = true; raw_linker_arg = 0; } @@ -1866,7 +1865,7 @@ int main(int argc, char **argv) case 't': if (is_option( args, i, "-target", &option_arg )) { - target_alias = option_arg; + parse_target_option( option_arg ); raw_compiler_arg = raw_linker_arg = 0; } break; @@ -1930,7 +1929,7 @@ int main(int argc, char **argv) !strcmp(Wl.str[j], "--start-group") || !strcmp(Wl.str[j], "--end-group")) { - strarray_add( &file_args, strmake( "-Wl,%s", Wl.str[j] )); + strarray_add( &files, strmake( "-Wl,%s", Wl.str[j] )); continue; } if (!strcmp(Wl.str[j], "--out-implib")) @@ -1943,7 +1942,7 @@ int main(int argc, char **argv) use_build_id = true; continue; } - if (!strcmp(Wl.str[j], "-static")) is_static = true; + if (!strcmp(Wl.str[j], "-static")) linking = -1; strarray_add(&linker_args, strmake("-Wl,%s",Wl.str[j])); } raw_compiler_arg = raw_linker_arg = 0; @@ -1962,13 +1961,14 @@ int main(int argc, char **argv) } break; case 'x': - strarray_add(&file_args, args.str[i]); + lang = strmake("-x%s", option_arg); + strarray_add(&files, lang); /* we'll pass these flags ourselves, explicitly */ raw_compiler_arg = raw_linker_arg = 0; break; case '-': if (strcmp("-static", args.str[i]+1) == 0) - is_static = true; + linking = -1; else if (!strcmp( "-no-default-config", args.str[i] + 1 )) { no_default_config = true; @@ -1981,7 +1981,7 @@ int main(int argc, char **argv) } else if (is_option( args, i, "--target", &option_arg )) { - target_alias = option_arg; + parse_target_option( option_arg ); raw_compiler_arg = raw_linker_arg = 0; } else if (is_option( args, i, "--wine-objdir", &option_arg )) @@ -2027,19 +2027,17 @@ int main(int argc, char **argv) } else { - strarray_add( &file_args, args.str[i] ); + strarray_add( &files, args.str[i] ); } }
- if (target_alias && !parse_target( target_alias, &target )) - error( "Invalid target specification '%s'\n", target_alias ); if (force_pointer_size) set_target_ptr_size( &target, force_pointer_size ); - - if (processor == proc_cpp) skip_link = true; + if (processor == proc_cpp) linking = 0; + if (linking == -1) error("Static linking is not supported\n");
is_pe = is_pe_target( target ); if (is_pe) use_msvcrt = true; - if (output && strendswith( output, ".fake" )) fake_module = true; + if (strendswith( output_name, ".fake" )) fake_module = true;
if (!section_align) section_align = "0x1000"; if (!file_align) file_align = section_align; @@ -2053,9 +2051,9 @@ int main(int argc, char **argv) else winebuild = "winebuild"; } } - if (file_args.count == 0 && !fake_module) forward(); - else if (!skip_link && !compile_only) build(file_args, output); - else compile(file_args, output, compile_only); + if (files.count == 0 && !fake_module) forward(); + else if (linking) build(files, output_name); + else compile(files, lang, output_name, compile_only);
output_file_name = NULL; output_debug_file = NULL;
I think there is no way a syscall modifies user stack on Windows that way. Syscall nowadays is executed with 'syscall' instruction on Windows and doesn't touch anything at all on the stack.
This is a before and after of the memory past the end of the stack in the effected CreationKit.exe
`Thread 1 "MainThrd" hit Breakpoint 4, 0x00007ffff8bb1b10 in win32u!NtUserShowWindow ()`
` from C:\Windows\System32\win32u.dll`
`(gdb) set $stack = $rsp-0x54`
`(gdb) print *(int*)($stack)@21`
`$28 = {0, 5768082, 0, 0, 0, -170837133, 32767, 0, 0, -769188256, 32767, -769188256, 32767, 0, 0, 0, 0, -1, -1, 1073808195, 0}`
`(gdb) si`
`0x00007ffffadf1350 in ntdll!KiUserCallbackDispatcher () from C:\Windows\SYSTEM32\ntdll.dll`
`(gdb) print *(int*)($stack)@21`
`$29 = {32767, 5768082, 0, 0, 0, 1356840, 0, 0, 0, 14282256, 0, 24, 0, 0, 0, 0, 0, -771237456, 32767, -86060064, 32767}`
This normally does not affect the program since memory below the stack pointer isn't supposed to be used but this application keeps a pointer to memory outside the stack. This is definitely a bug in the creation kit but it works consistently on Windows 10 and never works on Wine.
This is the specific instance that the syscall needs to push data onto the stack to create a working menu in the creation kit.
`Dump of assembler code for function win32u!NtUserShowWindow:`
`=> 0x00007ffff8bb1b10 <+0>: mov %rcx,%r10`
` 0x00007ffff8bb1b13 <+3>: mov $0x1057,%eax`
` 0x00007ffff8bb1b18 <+8>: testb $0x1,0x7ffe0308`
` 0x00007ffff8bb1b20 <+16>: jne 0x7ffff8bb1b25 <win32u!NtUserShowWindow+21>`
` 0x00007ffff8bb1b22 <+18>: syscall`
` 0x00007ffff8bb1b24 <+20>: ret`
` 0x00007ffff8bb1b25 <+21>: int $0x2e`
` 0x00007ffff8bb1b27 <+23>: ret`
` 0x00007ffff8bb1b28 <+24>: nopl 0x0(%rax,%rax,1)`
`End of assembler dump.`
`$10 = 0x0`
`(gdb) set $stack = $rsp-0x54`
`(gdb) si`
`0x00007ffff8bb1b13 in win32u!NtUserShowWindow () from C:\Windows\System32\win32u.dll`
`(gdb) si`
`0x00007ffff8bb1b13 in win32u!NtUserShowWindow () from C:\Windows\System32\win32u.dll`
`(gdb) si`
`0x00007ffff8bb1b13 in win32u!NtUserShowWindow () from C:\Windows\System32\win32u.dll`
`(gdb) si`
`0x00007ffff8bb1b13 in win32u!NtUserShowWindow () from C:\Windows\System32\win32u.dll`
`(gdb) si`
`0x00007ffffadf1350 in ntdll!KiUserCallbackDispatcher () from C:\Windows\SYSTEM32\ntdll.dll`
`(gdb) print/x *(int*)$stack`
`$11 = 0x7fff`
Please don't look at disassembly or step into Microsoft's dlls.
In any case that's most likely a side-effect of the stack usage of some Windows function, we can't replicate that.
I wasn't sure what would be an acceptable way to fix this issue or if a patch specifically for one program would be accepted. This patch recreates the exact value and memory address relative to the stack that is set after the syscall in Windows, but the program will work as long as the bad pointer points to an invalid RECT. Would changing NtUserShowWindow to just zero out the memory past the stack be an acceptable way to make CreationKit work?
Have you tried reporting this to the CreationKit developers?
I have not because they do not support linux, they have no place to report issues with modding tools just the base game, and given past experience I doubt they will do anything it crashes usually about every hour on Windows, it is a known issue that it often cant load the .dll file this bug is in at all, and crashes if you try to unzip the script files it ships with. These are all bugs that have been known for years some over a decade and they will not fix them. Despite all of this, this is a problem that does not occur on Windows only Wine.
It sounds like something that would also break on Windows as soon as Microsoft make changes to the code or to the compiler. I don't think there's a reasonable way to fix this.
This merge request was closed by Keaton Ens.