mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
Compare commits
42 commits
e287fe3b26
...
a1757b7ad6
Author | SHA1 | Date | |
---|---|---|---|
|
a1757b7ad6 | ||
|
67c1c3c255 | ||
|
c4630993fb | ||
|
10cf578898 | ||
|
12925e9113 | ||
|
bce1213281 | ||
|
0cda918561 | ||
|
d8b5a3ae12 | ||
|
03738c3f22 | ||
|
8bbc193178 | ||
|
03457ece24 | ||
|
be6902d072 | ||
|
6ac127ebc6 | ||
|
b1e54a5f04 | ||
|
3f7c85f7a3 | ||
|
0eb2f18166 | ||
|
18a7362940 | ||
|
be022f350d | ||
|
1b9b7a5e65 | ||
|
46b79b1856 | ||
|
696ef034db | ||
|
ac1ff67cfd | ||
|
ab399468c2 | ||
|
6f5e34ad14 | ||
|
180ba49cee | ||
|
ce946e57db | ||
|
446f3b207f | ||
|
90ffd6c7dc | ||
|
3ca383e34e | ||
|
c5a726e8a3 | ||
|
a10ea7e662 | ||
|
b787e0654a | ||
|
29226ef249 | ||
|
933b885ce7 | ||
|
c3b1f1430c | ||
|
a308076081 | ||
|
6e79260df0 | ||
|
59e0ef1ed7 | ||
|
1ee98ca657 | ||
|
a598a24982 | ||
|
0fea32aa75 | ||
|
9f9481f194 |
59 changed files with 1658 additions and 572 deletions
1
configure
generated
vendored
1
configure
generated
vendored
|
@ -23070,6 +23070,7 @@ wine_fn_config_makefile programs/msidb enable_msidb
|
||||||
wine_fn_config_makefile programs/msiexec enable_msiexec
|
wine_fn_config_makefile programs/msiexec enable_msiexec
|
||||||
wine_fn_config_makefile programs/msinfo32 enable_msinfo32
|
wine_fn_config_makefile programs/msinfo32 enable_msinfo32
|
||||||
wine_fn_config_makefile programs/net enable_net
|
wine_fn_config_makefile programs/net enable_net
|
||||||
|
wine_fn_config_makefile programs/net/tests enable_tests
|
||||||
wine_fn_config_makefile programs/netsh enable_netsh
|
wine_fn_config_makefile programs/netsh enable_netsh
|
||||||
wine_fn_config_makefile programs/netstat enable_netstat
|
wine_fn_config_makefile programs/netstat enable_netstat
|
||||||
wine_fn_config_makefile programs/ngen enable_ngen
|
wine_fn_config_makefile programs/ngen enable_ngen
|
||||||
|
|
|
@ -3468,6 +3468,7 @@ WINE_CONFIG_MAKEFILE(programs/msidb)
|
||||||
WINE_CONFIG_MAKEFILE(programs/msiexec)
|
WINE_CONFIG_MAKEFILE(programs/msiexec)
|
||||||
WINE_CONFIG_MAKEFILE(programs/msinfo32)
|
WINE_CONFIG_MAKEFILE(programs/msinfo32)
|
||||||
WINE_CONFIG_MAKEFILE(programs/net)
|
WINE_CONFIG_MAKEFILE(programs/net)
|
||||||
|
WINE_CONFIG_MAKEFILE(programs/net/tests)
|
||||||
WINE_CONFIG_MAKEFILE(programs/netsh)
|
WINE_CONFIG_MAKEFILE(programs/netsh)
|
||||||
WINE_CONFIG_MAKEFILE(programs/netstat)
|
WINE_CONFIG_MAKEFILE(programs/netstat)
|
||||||
WINE_CONFIG_MAKEFILE(programs/ngen)
|
WINE_CONFIG_MAKEFILE(programs/ngen)
|
||||||
|
|
|
@ -300,20 +300,6 @@ BOOL WINAPI SymGetSearchPath(HANDLE hProcess, PSTR szSearchPath,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* invade_process
|
|
||||||
*
|
|
||||||
* SymInitialize helper: loads in dbghelp all known (and loaded modules)
|
|
||||||
* this assumes that hProcess is a handle on a valid process
|
|
||||||
*/
|
|
||||||
static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user)
|
|
||||||
{
|
|
||||||
HANDLE hProcess = user;
|
|
||||||
|
|
||||||
SymLoadModuleExW(hProcess, 0, name, NULL, base, size, NULL, 0);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const WCHAR *process_getenv(const struct process *process, const WCHAR *name)
|
const WCHAR *process_getenv(const struct process *process, const WCHAR *name)
|
||||||
{
|
{
|
||||||
size_t name_len;
|
size_t name_len;
|
||||||
|
@ -432,7 +418,10 @@ static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64)
|
||||||
|
|
||||||
TRACE("got debug info address %#I64x from PEB %p\n", base, pbi.PebBaseAddress);
|
TRACE("got debug info address %#I64x from PEB %p\n", base, pbi.PebBaseAddress);
|
||||||
if (!elf_read_wine_loader_dbg_info(pcs, base) && !macho_read_wine_loader_dbg_info(pcs, base))
|
if (!elf_read_wine_loader_dbg_info(pcs, base) && !macho_read_wine_loader_dbg_info(pcs, base))
|
||||||
|
{
|
||||||
WARN("couldn't load process debug info at %#I64x\n", base);
|
WARN("couldn't load process debug info at %#I64x\n", base);
|
||||||
|
pcs->loader = &empty_loader_ops;
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,8 +499,9 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP
|
||||||
if (check_live_target(pcs, wow64, child_wow64))
|
if (check_live_target(pcs, wow64, child_wow64))
|
||||||
{
|
{
|
||||||
if (fInvadeProcess)
|
if (fInvadeProcess)
|
||||||
EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess);
|
module_refresh_list(pcs);
|
||||||
if (pcs->loader) pcs->loader->synchronize_module_list(pcs);
|
else
|
||||||
|
pcs->loader->synchronize_module_list(pcs);
|
||||||
}
|
}
|
||||||
else if (fInvadeProcess)
|
else if (fInvadeProcess)
|
||||||
{
|
{
|
||||||
|
|
|
@ -743,6 +743,7 @@ extern BOOL module_remove(struct process* pcs,
|
||||||
extern void module_set_module(struct module* module, const WCHAR* name);
|
extern void module_set_module(struct module* module, const WCHAR* name);
|
||||||
extern WCHAR* get_wine_loader_name(struct process *pcs) __WINE_DEALLOC(HeapFree, 3) __WINE_MALLOC;
|
extern WCHAR* get_wine_loader_name(struct process *pcs) __WINE_DEALLOC(HeapFree, 3) __WINE_MALLOC;
|
||||||
extern BOOL module_is_wine_host(const WCHAR* module_name, const WCHAR* ext);
|
extern BOOL module_is_wine_host(const WCHAR* module_name, const WCHAR* ext);
|
||||||
|
extern BOOL module_refresh_list(struct process *pcs);
|
||||||
|
|
||||||
/* msc.c */
|
/* msc.c */
|
||||||
extern BOOL pe_load_debug_directory(const struct process* pcs,
|
extern BOOL pe_load_debug_directory(const struct process* pcs,
|
||||||
|
|
|
@ -1785,7 +1785,6 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs, ULONG_PTR addr)
|
||||||
{
|
{
|
||||||
ERR("Unable to access ELF libraries (outside 32bit limit)\n");
|
ERR("Unable to access ELF libraries (outside 32bit limit)\n");
|
||||||
module_remove(pcs, elf_info.module);
|
module_remove(pcs, elf_info.module);
|
||||||
pcs->loader = &empty_loader_ops;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
TRACE("Found ELF debug header %#I64x\n", elf_info.dbg_hdr_addr);
|
TRACE("Found ELF debug header %#I64x\n", elf_info.dbg_hdr_addr);
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
#include "dbghelp_private.h"
|
#include "dbghelp_private.h"
|
||||||
#include "image_private.h"
|
#include "image_private.h"
|
||||||
#include "psapi.h"
|
#include "psapi.h"
|
||||||
|
@ -1317,7 +1319,11 @@ BOOL WINAPI EnumerateLoadedModulesW64(HANDLE process,
|
||||||
size_t sysdir_len = 0, wowdir_len = 0;
|
size_t sysdir_len = 0, wowdir_len = 0;
|
||||||
|
|
||||||
/* process might not be a handle to a live process */
|
/* process might not be a handle to a live process */
|
||||||
if (!IsWow64Process2(process, &pcs_machine, &native_machine)) return FALSE;
|
if (!IsWow64Process2(process, &pcs_machine, &native_machine))
|
||||||
|
{
|
||||||
|
SetLastError(STATUS_INVALID_CID);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
with_32bit_modules = sizeof(void*) > sizeof(int) &&
|
with_32bit_modules = sizeof(void*) > sizeof(int) &&
|
||||||
pcs_machine != IMAGE_FILE_MACHINE_UNKNOWN &&
|
pcs_machine != IMAGE_FILE_MACHINE_UNKNOWN &&
|
||||||
(dbghelp_options & SYMOPT_INCLUDE_32BIT_MODULES);
|
(dbghelp_options & SYMOPT_INCLUDE_32BIT_MODULES);
|
||||||
|
@ -1600,6 +1606,30 @@ void module_reset_debug_info(struct module* module)
|
||||||
module->sources = NULL;
|
module->sources = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user)
|
||||||
|
{
|
||||||
|
HANDLE hProcess = user;
|
||||||
|
|
||||||
|
/* Note: this follows native behavior:
|
||||||
|
* If a PE module has been unloaded from debuggee, it's not immediately removed
|
||||||
|
* from module list in dbghelp.
|
||||||
|
* Removal may eventually happen when loading a another module with SymLoadModule:
|
||||||
|
* if the module to be loaded overlaps an existing one, SymLoadModule will
|
||||||
|
* automatically unload the eldest one.
|
||||||
|
*/
|
||||||
|
SymLoadModuleExW(hProcess, 0, name, NULL, base, size, NULL, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL module_refresh_list(struct process *pcs)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
ret = pcs->loader->synchronize_module_list(pcs);
|
||||||
|
ret = EnumerateLoadedModulesW64(pcs->handle, process_invade_cb, pcs->handle) && ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* SymRefreshModuleList (DBGHELP.@)
|
* SymRefreshModuleList (DBGHELP.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1610,8 +1640,7 @@ BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
|
||||||
TRACE("(%p)\n", hProcess);
|
TRACE("(%p)\n", hProcess);
|
||||||
|
|
||||||
if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
|
if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
|
||||||
|
return module_refresh_list(pcs);
|
||||||
return pcs->loader->synchronize_module_list(pcs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -372,6 +372,29 @@ static unsigned get_native_module_count(HANDLE proc)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct module_present
|
||||||
|
{
|
||||||
|
const WCHAR* module_name;
|
||||||
|
BOOL found;
|
||||||
|
};
|
||||||
|
|
||||||
|
static BOOL CALLBACK is_module_present_cb(const WCHAR* name, DWORD64 base, void* usr)
|
||||||
|
{
|
||||||
|
struct module_present* present = usr;
|
||||||
|
if (!wcsicmp(name, present->module_name))
|
||||||
|
{
|
||||||
|
present->found = TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL is_module_present(HANDLE proc, const WCHAR* module_name)
|
||||||
|
{
|
||||||
|
struct module_present present = { .module_name = module_name };
|
||||||
|
return SymEnumerateModulesW64(proc, is_module_present_cb, &present) && present.found;
|
||||||
|
}
|
||||||
|
|
||||||
struct nth_module
|
struct nth_module
|
||||||
{
|
{
|
||||||
HANDLE proc;
|
HANDLE proc;
|
||||||
|
@ -424,6 +447,28 @@ static BOOL wrapper_EnumerateLoadedModulesW64(HANDLE proc, PENUMLOADED_MODULES_C
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wrapper around SymRefreshModuleList which sometimes fails (it's very likely implemented on top
|
||||||
|
* of EnumerateLoadedModulesW64 on native too)
|
||||||
|
*/
|
||||||
|
static BOOL wrapper_SymRefreshModuleList(HANDLE proc)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
int retry;
|
||||||
|
int retry_count = !strcmp(winetest_platform, "wine") ? 1 : 5;
|
||||||
|
|
||||||
|
for (retry = retry_count - 1; retry >= 0; retry--)
|
||||||
|
{
|
||||||
|
ret = SymRefreshModuleList(proc);
|
||||||
|
if (ret || (GetLastError() != STATUS_INFO_LENGTH_MISMATCH && GetLastError() == STATUS_PARTIAL_COPY))
|
||||||
|
break;
|
||||||
|
Sleep(10);
|
||||||
|
}
|
||||||
|
if (retry + 1 < retry_count)
|
||||||
|
trace("used wrapper retry: ret=%d retry=%d top=%d\n", ret, retry, retry_count);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL test_modules(void)
|
static BOOL test_modules(void)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -492,6 +537,7 @@ static BOOL test_modules(void)
|
||||||
|
|
||||||
ret = SymRefreshModuleList(dummy);
|
ret = SymRefreshModuleList(dummy);
|
||||||
ok(!ret, "SymRefreshModuleList should have failed\n");
|
ok(!ret, "SymRefreshModuleList should have failed\n");
|
||||||
|
ok(GetLastError() == STATUS_INVALID_CID, "Unexpected last error %lx\n", GetLastError());
|
||||||
|
|
||||||
count = get_module_count(dummy);
|
count = get_module_count(dummy);
|
||||||
ok(count == 0, "Unexpected count (%u instead of 0)\n", count);
|
ok(count == 0, "Unexpected count (%u instead of 0)\n", count);
|
||||||
|
@ -825,6 +871,11 @@ static void test_loaded_modules(void)
|
||||||
ok(ret, "got error %lu\n", GetLastError());
|
ok(ret, "got error %lu\n", GetLastError());
|
||||||
strcat(buffer, "\\msinfo32.exe");
|
strcat(buffer, "\\msinfo32.exe");
|
||||||
|
|
||||||
|
/* testing invalid process handle */
|
||||||
|
ret = wrapper_EnumerateLoadedModulesW64((HANDLE)(ULONG_PTR)0xffffffc0, NULL, FALSE);
|
||||||
|
ok(!ret, "EnumerateLoadedModulesW64 should have failed\n");
|
||||||
|
ok(GetLastError() == STATUS_INVALID_CID, "Unexpected last error %lx\n", GetLastError());
|
||||||
|
|
||||||
/* testing with child process of different machines */
|
/* testing with child process of different machines */
|
||||||
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
||||||
ok(ret, "CreateProcess failed: %lu\n", GetLastError());
|
ok(ret, "CreateProcess failed: %lu\n", GetLastError());
|
||||||
|
@ -885,9 +936,10 @@ static void test_loaded_modules(void)
|
||||||
|
|
||||||
pcskind = get_process_kind(pi.hProcess);
|
pcskind = get_process_kind(pi.hProcess);
|
||||||
|
|
||||||
ret = SymRefreshModuleList(pi.hProcess);
|
ret = wrapper_SymRefreshModuleList(pi.hProcess);
|
||||||
todo_wine_if(pcskind == PCSKIND_WOW64)
|
ok(ret || broken(GetLastError() == STATUS_PARTIAL_COPY /* Win11 in some cases */ ||
|
||||||
ok(ret || broken(GetLastError() == STATUS_PARTIAL_COPY /* Win11 in some cases */), "SymRefreshModuleList failed: %lu\n", GetLastError());
|
GetLastError() == STATUS_INFO_LENGTH_MISMATCH /* Win11 in some cases */),
|
||||||
|
"SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||||
|
|
||||||
if (!strcmp(winetest_platform, "wine"))
|
if (!strcmp(winetest_platform, "wine"))
|
||||||
{
|
{
|
||||||
|
@ -945,8 +997,8 @@ static void test_loaded_modules(void)
|
||||||
"Wrong directory aggregation count %u %u\n",
|
"Wrong directory aggregation count %u %u\n",
|
||||||
aggregation.count_systemdir, aggregation.count_wowdir);
|
aggregation.count_systemdir, aggregation.count_wowdir);
|
||||||
}
|
}
|
||||||
ret = SymRefreshModuleList(pi.hProcess);
|
ret = wrapper_SymRefreshModuleList(pi.hProcess);
|
||||||
ok(ret, "SymRefreshModuleList failed: %lu\n", GetLastError());
|
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||||
|
|
||||||
if (!strcmp(winetest_platform, "wine"))
|
if (!strcmp(winetest_platform, "wine"))
|
||||||
{
|
{
|
||||||
|
@ -1007,8 +1059,8 @@ static void test_loaded_modules(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = SymRefreshModuleList(pi.hProcess);
|
ret = wrapper_SymRefreshModuleList(pi.hProcess);
|
||||||
ok(ret, "SymRefreshModuleList failed: %lu\n", GetLastError());
|
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||||
|
|
||||||
if (!strcmp(winetest_platform, "wine"))
|
if (!strcmp(winetest_platform, "wine"))
|
||||||
{
|
{
|
||||||
|
@ -1529,6 +1581,75 @@ static void test_function_tables(void)
|
||||||
SymCleanup(GetCurrentProcess());
|
SymCleanup(GetCurrentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_refresh_modules(void)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
unsigned count, count_current;
|
||||||
|
HMODULE hmod;
|
||||||
|
IMAGEHLP_MODULEW64 module_info = { .SizeOfStruct = sizeof(module_info) };
|
||||||
|
|
||||||
|
/* pick a DLL: which isn't already loaded by test, and that will not load other DLLs for deps */
|
||||||
|
static const WCHAR* unused_dll = L"psapi";
|
||||||
|
|
||||||
|
ret = SymInitialize(GetCurrentProcess(), 0, TRUE);
|
||||||
|
ok(ret, "SymInitialize failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
|
count = get_module_count(GetCurrentProcess());
|
||||||
|
ok(count, "Unexpected module count %u\n", count);
|
||||||
|
|
||||||
|
ret = SymCleanup(GetCurrentProcess());
|
||||||
|
ok(ret, "SymCleanup failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
|
ret = SymInitialize(GetCurrentProcess(), 0, FALSE);
|
||||||
|
ok(ret, "SymInitialize failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
|
count_current = get_module_count(GetCurrentProcess());
|
||||||
|
ok(!count_current, "Unexpected module count %u\n", count_current);
|
||||||
|
|
||||||
|
ret = wrapper_SymRefreshModuleList(GetCurrentProcess());
|
||||||
|
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||||
|
|
||||||
|
count_current = get_module_count(GetCurrentProcess());
|
||||||
|
ok(count == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||||
|
|
||||||
|
hmod = GetModuleHandleW(unused_dll);
|
||||||
|
ok(hmod == NULL, "Expecting DLL %ls not be loaded\n", unused_dll);
|
||||||
|
|
||||||
|
hmod = LoadLibraryW(unused_dll);
|
||||||
|
ok(hmod != NULL, "LoadLibraryW failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
|
count_current = get_module_count(GetCurrentProcess());
|
||||||
|
ok(count == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||||
|
ret = is_module_present(GetCurrentProcess(), unused_dll);
|
||||||
|
ok(!ret, "Couldn't find module %ls\n", unused_dll);
|
||||||
|
|
||||||
|
ret = wrapper_SymRefreshModuleList(GetCurrentProcess());
|
||||||
|
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||||
|
|
||||||
|
count_current = get_module_count(GetCurrentProcess());
|
||||||
|
ok(count + 1 == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||||
|
ret = is_module_present(GetCurrentProcess(), unused_dll);
|
||||||
|
ok(ret, "Couldn't find module %ls\n", unused_dll);
|
||||||
|
|
||||||
|
ret = FreeLibrary(hmod);
|
||||||
|
ok(ret, "LoadLibraryW failed: %lu\n", GetLastError());
|
||||||
|
|
||||||
|
count_current = get_module_count(GetCurrentProcess());
|
||||||
|
ok(count + 1 == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||||
|
|
||||||
|
ret = wrapper_SymRefreshModuleList(GetCurrentProcess());
|
||||||
|
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||||
|
|
||||||
|
/* SymRefreshModuleList() doesn't remove the unloaded modules... */
|
||||||
|
count_current = get_module_count(GetCurrentProcess());
|
||||||
|
ok(count + 1 == count_current, "Unexpected module count %u != %u\n", count, count_current);
|
||||||
|
ret = is_module_present(GetCurrentProcess(), unused_dll);
|
||||||
|
ok(ret, "Couldn't find module %ls\n", unused_dll);
|
||||||
|
|
||||||
|
ret = SymCleanup(GetCurrentProcess());
|
||||||
|
ok(ret, "SymCleanup failed: %lu\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(dbghelp)
|
START_TEST(dbghelp)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -1559,6 +1680,7 @@ START_TEST(dbghelp)
|
||||||
test_modules_overlap();
|
test_modules_overlap();
|
||||||
test_loaded_modules();
|
test_loaded_modules();
|
||||||
test_live_modules();
|
test_live_modules();
|
||||||
|
test_refresh_modules();
|
||||||
}
|
}
|
||||||
test_function_tables();
|
test_function_tables();
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,20 +306,13 @@ static void warp_check( struct mouse *impl, BOOL force )
|
||||||
|
|
||||||
if (force || (impl->need_warp && (now - impl->last_warped > interval)))
|
if (force || (impl->need_warp && (now - impl->last_warped > interval)))
|
||||||
{
|
{
|
||||||
RECT rect, new_rect;
|
|
||||||
POINT mapped_center;
|
POINT mapped_center;
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
impl->last_warped = now;
|
impl->last_warped = now;
|
||||||
impl->need_warp = FALSE;
|
impl->need_warp = FALSE;
|
||||||
if (!GetClientRect( impl->base.win, &rect )) return;
|
if (!GetClientRect( impl->base.win, &rect )) return;
|
||||||
MapWindowPoints( impl->base.win, 0, (POINT *)&rect, 2 );
|
MapWindowPoints( impl->base.win, 0, (POINT *)&rect, 2 );
|
||||||
if (!impl->clipped)
|
|
||||||
{
|
|
||||||
mapped_center.x = (rect.left + rect.right) / 2;
|
|
||||||
mapped_center.y = (rect.top + rect.bottom) / 2;
|
|
||||||
TRACE( "Warping mouse to x %+ld, y %+ld.\n", mapped_center.x, mapped_center.y );
|
|
||||||
SetCursorPos( mapped_center.x, mapped_center.y );
|
|
||||||
}
|
|
||||||
if (impl->base.dwCoopLevel & DISCL_EXCLUSIVE)
|
if (impl->base.dwCoopLevel & DISCL_EXCLUSIVE)
|
||||||
{
|
{
|
||||||
/* make sure we clip even if the window covers the whole screen */
|
/* make sure we clip even if the window covers the whole screen */
|
||||||
|
@ -328,8 +321,14 @@ static void warp_check( struct mouse *impl, BOOL force )
|
||||||
rect.right = min( rect.right, rect.left + GetSystemMetrics( SM_CXVIRTUALSCREEN ) - 2 );
|
rect.right = min( rect.right, rect.left + GetSystemMetrics( SM_CXVIRTUALSCREEN ) - 2 );
|
||||||
rect.bottom = min( rect.bottom, rect.top + GetSystemMetrics( SM_CYVIRTUALSCREEN ) - 2 );
|
rect.bottom = min( rect.bottom, rect.top + GetSystemMetrics( SM_CYVIRTUALSCREEN ) - 2 );
|
||||||
TRACE("Clipping mouse to %s\n", wine_dbgstr_rect( &rect ));
|
TRACE("Clipping mouse to %s\n", wine_dbgstr_rect( &rect ));
|
||||||
ClipCursor( &rect );
|
impl->clipped = ClipCursor( &rect );
|
||||||
impl->clipped = GetClipCursor( &new_rect ) && EqualRect( &rect, &new_rect );
|
}
|
||||||
|
if (!impl->clipped)
|
||||||
|
{
|
||||||
|
mapped_center.x = (rect.left + rect.right) / 2;
|
||||||
|
mapped_center.y = (rect.top + rect.bottom) / 2;
|
||||||
|
TRACE( "Warping mouse to x %+ld, y %+ld.\n", mapped_center.x, mapped_center.y );
|
||||||
|
SetCursorPos( mapped_center.x, mapped_center.y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1281,17 +1281,28 @@ static HRESULT WINAPI IDirectPlay4Impl_Close( IDirectPlay4 *iface )
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, const DPNAME *lpName,
|
HRESULT DP_CreateGroup( IDirectPlayImpl *This, void *msgHeader, const DPID *lpid,
|
||||||
DWORD dwFlags, DPID idParent, BOOL bAnsi )
|
const DPNAME *lpName, void *data, DWORD dataSize, DWORD dwFlags, DPID idParent,
|
||||||
|
BOOL bAnsi )
|
||||||
{
|
{
|
||||||
|
struct GroupList *groupList = NULL;
|
||||||
|
struct GroupData *parent = NULL;
|
||||||
lpGroupData lpGData;
|
lpGroupData lpGData;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if( DPID_SYSTEM_GROUP != *lpid )
|
||||||
|
{
|
||||||
|
parent = DP_FindAnyGroup( This, idParent );
|
||||||
|
if( !parent )
|
||||||
|
return DPERR_INVALIDGROUP;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate the new space and add to end of high level group list */
|
/* Allocate the new space and add to end of high level group list */
|
||||||
lpGData = calloc( 1, sizeof( *lpGData ) );
|
lpGData = calloc( 1, sizeof( *lpGData ) );
|
||||||
|
|
||||||
if( lpGData == NULL )
|
if( lpGData == NULL )
|
||||||
{
|
{
|
||||||
return NULL;
|
return DPERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPQ_INIT(lpGData->groups);
|
DPQ_INIT(lpGData->groups);
|
||||||
|
@ -1304,7 +1315,7 @@ static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, cons
|
||||||
if ( !lpGData->name )
|
if ( !lpGData->name )
|
||||||
{
|
{
|
||||||
free( lpGData );
|
free( lpGData );
|
||||||
return NULL;
|
return DPERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpGData->nameA = DP_DuplicateName( lpName, TRUE, bAnsi );
|
lpGData->nameA = DP_DuplicateName( lpName, TRUE, bAnsi );
|
||||||
|
@ -1312,10 +1323,9 @@ static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, cons
|
||||||
{
|
{
|
||||||
free( lpGData->name );
|
free( lpGData->name );
|
||||||
free( lpGData );
|
free( lpGData );
|
||||||
return NULL;
|
return DPERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Should we check that the parent exists? */
|
|
||||||
lpGData->parent = idParent;
|
lpGData->parent = idParent;
|
||||||
|
|
||||||
/* FIXME: Should we validate the dwFlags? */
|
/* FIXME: Should we validate the dwFlags? */
|
||||||
|
@ -1328,12 +1338,83 @@ static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, cons
|
||||||
free( lpGData->nameA );
|
free( lpGData->nameA );
|
||||||
free( lpGData->name );
|
free( lpGData->name );
|
||||||
free( lpGData );
|
free( lpGData );
|
||||||
return NULL;
|
return DPERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( DPID_SYSTEM_GROUP == *lpid )
|
||||||
|
{
|
||||||
|
This->dp2->lpSysGroup = lpGData;
|
||||||
|
TRACE( "Inserting system group\n" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Insert into the parent group */
|
||||||
|
groupList = calloc( 1, sizeof( *groupList ) );
|
||||||
|
if( !groupList )
|
||||||
|
{
|
||||||
|
free( lpGData->nameA );
|
||||||
|
free( lpGData->name );
|
||||||
|
free( lpGData );
|
||||||
|
return DPERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
groupList->lpGData = lpGData;
|
||||||
|
|
||||||
|
DPQ_INSERT( parent->groups, groupList, groups );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Something is now referencing this data */
|
||||||
|
lpGData->uRef++;
|
||||||
|
|
||||||
|
DP_SetGroupData( lpGData, DPSET_REMOTE, data, dataSize );
|
||||||
|
|
||||||
|
/* FIXME: We should only create the system group if GetCaps returns
|
||||||
|
* DPCAPS_GROUPOPTIMIZED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Let the SP know that we've created this group */
|
||||||
|
if( This->dp2->spData.lpCB->CreateGroup )
|
||||||
|
{
|
||||||
|
DPSP_CREATEGROUPDATA data;
|
||||||
|
DWORD dwCreateFlags = 0;
|
||||||
|
|
||||||
|
TRACE( "Calling SP CreateGroup\n" );
|
||||||
|
|
||||||
|
if( !parent )
|
||||||
|
dwCreateFlags |= DPLAYI_GROUP_SYSGROUP;
|
||||||
|
|
||||||
|
if( !msgHeader )
|
||||||
|
dwCreateFlags |= DPLAYI_PLAYER_PLAYERLOCAL;
|
||||||
|
|
||||||
|
if( dwFlags & DPGROUP_HIDDEN )
|
||||||
|
dwCreateFlags |= DPLAYI_GROUP_HIDDEN;
|
||||||
|
|
||||||
|
data.idGroup = *lpid;
|
||||||
|
data.dwFlags = dwCreateFlags;
|
||||||
|
data.lpSPMessageHeader = msgHeader;
|
||||||
|
data.lpISP = This->dp2->spData.lpISP;
|
||||||
|
|
||||||
|
hr = (*This->dp2->spData.lpCB->CreateGroup)( &data );
|
||||||
|
if( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
if( groupList )
|
||||||
|
{
|
||||||
|
DPQ_REMOVE( parent->groups, groupList, groups );
|
||||||
|
free( groupList );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
This->dp2->lpSysGroup = NULL;
|
||||||
|
}
|
||||||
|
free( lpGData->nameA );
|
||||||
|
free( lpGData->name );
|
||||||
|
free( lpGData );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE( "Created group id 0x%08lx\n", *lpid );
|
TRACE( "Created group id 0x%08lx\n", *lpid );
|
||||||
|
|
||||||
return lpGData;
|
return DP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This method assumes that all links to it are already deleted */
|
/* This method assumes that all links to it are already deleted */
|
||||||
|
@ -1394,7 +1475,7 @@ static lpGroupData DP_FindAnyGroup( IDirectPlayImpl *This, DPID dpid )
|
||||||
static HRESULT DP_IF_CreateGroup( IDirectPlayImpl *This, void *lpMsgHdr, DPID *lpidGroup,
|
static HRESULT DP_IF_CreateGroup( IDirectPlayImpl *This, void *lpMsgHdr, DPID *lpidGroup,
|
||||||
DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi )
|
DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi )
|
||||||
{
|
{
|
||||||
lpGroupData lpGData;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "(%p)->(%p,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
|
TRACE( "(%p)->(%p,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
|
||||||
This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize,
|
This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize,
|
||||||
|
@ -1421,61 +1502,12 @@ static HRESULT DP_IF_CreateGroup( IDirectPlayImpl *This, void *lpMsgHdr, DPID *l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lpGData = DP_CreateGroup( This, lpidGroup, lpGroupName, dwFlags,
|
hr = DP_CreateGroup( This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
|
||||||
DPID_NOPARENT_GROUP, bAnsi );
|
DPID_NOPARENT_GROUP, bAnsi );
|
||||||
|
|
||||||
if( lpGData == NULL )
|
if( FAILED( hr ) )
|
||||||
{
|
{
|
||||||
return DPERR_CANTADDPLAYER; /* yes player not group */
|
return hr;
|
||||||
}
|
|
||||||
|
|
||||||
if( DPID_SYSTEM_GROUP == *lpidGroup )
|
|
||||||
{
|
|
||||||
This->dp2->lpSysGroup = lpGData;
|
|
||||||
TRACE( "Inserting system group\n" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Insert into the system group */
|
|
||||||
lpGroupList lpGroup = calloc( 1, sizeof( *lpGroup ) );
|
|
||||||
lpGroup->lpGData = lpGData;
|
|
||||||
|
|
||||||
DPQ_INSERT( This->dp2->lpSysGroup->groups, lpGroup, groups );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Something is now referencing this data */
|
|
||||||
lpGData->uRef++;
|
|
||||||
|
|
||||||
/* Set all the important stuff for the group */
|
|
||||||
DP_SetGroupData( lpGData, DPSET_REMOTE, lpData, dwDataSize );
|
|
||||||
|
|
||||||
/* FIXME: We should only create the system group if GetCaps returns
|
|
||||||
* DPCAPS_GROUPOPTIMIZED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Let the SP know that we've created this group */
|
|
||||||
if( This->dp2->spData.lpCB->CreateGroup )
|
|
||||||
{
|
|
||||||
DPSP_CREATEGROUPDATA data;
|
|
||||||
DWORD dwCreateFlags = 0;
|
|
||||||
|
|
||||||
TRACE( "Calling SP CreateGroup\n" );
|
|
||||||
|
|
||||||
if( *lpidGroup == DPID_NOPARENT_GROUP )
|
|
||||||
dwCreateFlags |= DPLAYI_GROUP_SYSGROUP;
|
|
||||||
|
|
||||||
if( lpMsgHdr == NULL )
|
|
||||||
dwCreateFlags |= DPLAYI_PLAYER_PLAYERLOCAL;
|
|
||||||
|
|
||||||
if( dwFlags & DPGROUP_HIDDEN )
|
|
||||||
dwCreateFlags |= DPLAYI_GROUP_HIDDEN;
|
|
||||||
|
|
||||||
data.idGroup = *lpidGroup;
|
|
||||||
data.dwFlags = dwCreateFlags;
|
|
||||||
data.lpSPMessageHeader = lpMsgHdr;
|
|
||||||
data.lpISP = This->dp2->spData.lpISP;
|
|
||||||
|
|
||||||
(*This->dp2->spData.lpCB->CreateGroup)( &data );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inform all other peers of the creation of a new group. If there are
|
/* Inform all other peers of the creation of a new group. If there are
|
||||||
|
@ -4458,9 +4490,7 @@ static HRESULT DP_IF_CreateGroupInGroup( IDirectPlayImpl *This, void *lpMsgHdr,
|
||||||
DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags,
|
DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags,
|
||||||
BOOL bAnsi )
|
BOOL bAnsi )
|
||||||
{
|
{
|
||||||
lpGroupData lpGParentData;
|
HRESULT hr;
|
||||||
lpGroupList lpGList;
|
|
||||||
lpGroupData lpGData;
|
|
||||||
|
|
||||||
TRACE( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
|
TRACE( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
|
||||||
This, idParentGroup, lpidGroup, lpGroupName, lpData,
|
This, idParentGroup, lpidGroup, lpGroupName, lpData,
|
||||||
|
@ -4471,48 +4501,12 @@ static HRESULT DP_IF_CreateGroupInGroup( IDirectPlayImpl *This, void *lpMsgHdr,
|
||||||
return DPERR_UNINITIALIZED;
|
return DPERR_UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that the specified parent is valid */
|
hr = DP_CreateGroup(This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
|
||||||
if( ( lpGParentData = DP_FindAnyGroup(This, idParentGroup ) ) == NULL )
|
idParentGroup, bAnsi );
|
||||||
return DPERR_INVALIDGROUP;
|
|
||||||
|
|
||||||
lpGData = DP_CreateGroup(This, lpidGroup, lpGroupName, dwFlags, idParentGroup, bAnsi );
|
if( FAILED( hr ) )
|
||||||
|
|
||||||
if( lpGData == NULL )
|
|
||||||
{
|
{
|
||||||
return DPERR_CANTADDPLAYER; /* yes player not group */
|
return hr;
|
||||||
}
|
|
||||||
|
|
||||||
/* Something else is referencing this data */
|
|
||||||
lpGData->uRef++;
|
|
||||||
|
|
||||||
DP_SetGroupData( lpGData, DPSET_REMOTE, lpData, dwDataSize );
|
|
||||||
|
|
||||||
/* The list has now been inserted into the interface group list. We now
|
|
||||||
need to put a "shortcut" to this group in the parent group */
|
|
||||||
lpGList = calloc( 1, sizeof( *lpGList ) );
|
|
||||||
if( lpGList == NULL )
|
|
||||||
{
|
|
||||||
FIXME( "Memory leak\n" );
|
|
||||||
return DPERR_CANTADDPLAYER; /* yes player not group */
|
|
||||||
}
|
|
||||||
|
|
||||||
lpGList->lpGData = lpGData;
|
|
||||||
|
|
||||||
DPQ_INSERT( lpGParentData->groups, lpGList, groups );
|
|
||||||
|
|
||||||
/* Let the SP know that we've created this group */
|
|
||||||
if( This->dp2->spData.lpCB->CreateGroup )
|
|
||||||
{
|
|
||||||
DPSP_CREATEGROUPDATA data;
|
|
||||||
|
|
||||||
TRACE( "Calling SP CreateGroup\n" );
|
|
||||||
|
|
||||||
data.idGroup = *lpidGroup;
|
|
||||||
data.dwFlags = dwFlags;
|
|
||||||
data.lpSPMessageHeader = lpMsgHdr;
|
|
||||||
data.lpISP = This->dp2->spData.lpISP;
|
|
||||||
|
|
||||||
(*This->dp2->spData.lpCB->CreateGroup)( &data );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inform all other peers of the creation of a new group. If there are
|
/* Inform all other peers of the creation of a new group. If there are
|
||||||
|
|
|
@ -218,6 +218,9 @@ HRESULT DP_HandleGameMessage( IDirectPlayImpl *This, void *messageBody, DWORD me
|
||||||
HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPNAME *lpName,
|
HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPNAME *lpName,
|
||||||
void *data, DWORD dataSize, void *spData, DWORD spDataSize, DWORD dwFlags,
|
void *data, DWORD dataSize, void *spData, DWORD spDataSize, DWORD dwFlags,
|
||||||
HANDLE hEvent, struct PlayerData **playerData, BOOL bAnsi );
|
HANDLE hEvent, struct PlayerData **playerData, BOOL bAnsi );
|
||||||
|
HRESULT DP_CreateGroup( IDirectPlayImpl *This, void *msgHeader, const DPID *lpid,
|
||||||
|
const DPNAME *lpName, void *data, DWORD dataSize, DWORD dwFlags,
|
||||||
|
DPID idParent, BOOL bAnsi );
|
||||||
|
|
||||||
/* DP SP external interfaces into DirectPlay */
|
/* DP SP external interfaces into DirectPlay */
|
||||||
extern HRESULT DP_GetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData );
|
extern HRESULT DP_GetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData );
|
||||||
|
|
|
@ -676,6 +676,30 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlayImpl *This, DPID dpidServer, WC
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for( i = 0; i < enumPlayersReply->groupCount; ++i )
|
||||||
|
{
|
||||||
|
DPPLAYERINFO playerInfo;
|
||||||
|
|
||||||
|
hr = DP_MSG_ReadSuperPackedPlayer( (char *) enumPlayersReply, &offset, dwMsgSize,
|
||||||
|
&playerInfo );
|
||||||
|
if( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
free( msgHeader );
|
||||||
|
free( lpMsg );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = DP_CreateGroup( This, msgHeader, &playerInfo.id, &playerInfo.name,
|
||||||
|
playerInfo.playerData, playerInfo.playerDataLength,
|
||||||
|
playerInfo.flags & ~DPLAYI_PLAYER_PLAYERLOCAL, playerInfo.parentId,
|
||||||
|
FALSE );
|
||||||
|
if( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
free( msgHeader );
|
||||||
|
free( lpMsg );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( envelope->wCommandId == DPMSGCMD_GETNAMETABLEREPLY )
|
else if( envelope->wCommandId == DPMSGCMD_GETNAMETABLEREPLY )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1224,12 +1224,14 @@ static void checkGameMessage_( int line, GameMessage *message, DPID expectedFrom
|
||||||
static unsigned short receiveEnumSessionsRequest_( int line, SOCKET sock, const GUID *expectedAppGuid,
|
static unsigned short receiveEnumSessionsRequest_( int line, SOCKET sock, const GUID *expectedAppGuid,
|
||||||
const WCHAR *expectedPassword, DWORD expectedFlags )
|
const WCHAR *expectedPassword, DWORD expectedFlags )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
EnumSessionsRequest request;
|
EnumSessionsRequest request;
|
||||||
WCHAR password[ 256 ];
|
WCHAR password[ 256 ];
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
DWORD expectedPasswordSize;
|
DWORD expectedPasswordSize;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
DWORD expectedSize;
|
DWORD expectedSize;
|
||||||
|
@ -1267,6 +1269,7 @@ static unsigned short receiveEnumSessionsRequest_( int line, SOCKET sock, const
|
||||||
#define sendEnumSessionsReply( sock, port, dpsd ) sendEnumSessionsReply_( __LINE__, sock, port, dpsd )
|
#define sendEnumSessionsReply( sock, port, dpsd ) sendEnumSessionsReply_( __LINE__, sock, port, dpsd )
|
||||||
static void sendEnumSessionsReply_( int line, SOCKET sock, unsigned short port, const DPSESSIONDESC2 *dpsd )
|
static void sendEnumSessionsReply_( int line, SOCKET sock, unsigned short port, const DPSESSIONDESC2 *dpsd )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
|
@ -1295,6 +1298,7 @@ static void sendEnumSessionsReply_( int line, SOCKET sock, unsigned short port,
|
||||||
.nameOffset = sizeof( reply.reply ),
|
.nameOffset = sizeof( reply.reply ),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
DWORD passwordSize;
|
DWORD passwordSize;
|
||||||
int wsResult;
|
int wsResult;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
@ -1314,11 +1318,13 @@ static void sendEnumSessionsReply_( int line, SOCKET sock, unsigned short port,
|
||||||
#define receiveRequestPlayerId( sock, expectedFlags, flagsTodo ) receiveRequestPlayerId_( __LINE__, sock, expectedFlags, flagsTodo )
|
#define receiveRequestPlayerId( sock, expectedFlags, flagsTodo ) receiveRequestPlayerId_( __LINE__, sock, expectedFlags, flagsTodo )
|
||||||
static unsigned short receiveRequestPlayerId_( int line, SOCKET sock, DWORD expectedFlags )
|
static unsigned short receiveRequestPlayerId_( int line, SOCKET sock, DWORD expectedFlags )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
RequestPlayerId request;
|
RequestPlayerId request;
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
|
@ -1335,6 +1341,7 @@ static unsigned short receiveRequestPlayerId_( int line, SOCKET sock, DWORD expe
|
||||||
#define sendRequestPlayerReply( sock, port, id, result ) sendRequestPlayerReply_( __LINE__, sock, port, id, result )
|
#define sendRequestPlayerReply( sock, port, id, result ) sendRequestPlayerReply_( __LINE__, sock, port, id, result )
|
||||||
static void sendRequestPlayerReply_( int line, SOCKET sock, unsigned short port, DPID id, HRESULT result )
|
static void sendRequestPlayerReply_( int line, SOCKET sock, unsigned short port, DPID id, HRESULT result )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
|
@ -1362,6 +1369,7 @@ static void sendRequestPlayerReply_( int line, SOCKET sock, unsigned short port,
|
||||||
.result = result,
|
.result = result,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
wsResult = send( sock, (char *) &reply, sizeof( reply ), 0 );
|
wsResult = send( sock, (char *) &reply, sizeof( reply ), 0 );
|
||||||
|
@ -1374,11 +1382,13 @@ static unsigned short receiveAddForwardRequest_( int line, SOCKET sock, DPID exp
|
||||||
const WCHAR *expectedPassword, DWORD expectedTickCount,
|
const WCHAR *expectedPassword, DWORD expectedTickCount,
|
||||||
unsigned short *udpPort )
|
unsigned short *udpPort )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
AddForwardRequest request;
|
AddForwardRequest request;
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
DWORD expectedPasswordSize;
|
DWORD expectedPasswordSize;
|
||||||
WCHAR password[ 256 ];
|
WCHAR password[ 256 ];
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
|
@ -1427,25 +1437,53 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
{
|
{
|
||||||
#define SHORT_NAME L"short name"
|
#define SHORT_NAME L"short name"
|
||||||
#define LONG_NAME L"long name"
|
#define LONG_NAME L"long name"
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
SuperEnumPlayersReply reply;
|
SuperEnumPlayersReply reply;
|
||||||
DPSESSIONDESC2 dpsd;
|
DPSESSIONDESC2 dpsd;
|
||||||
WCHAR sessionName[ 256 ];
|
WCHAR sessionName[ 256 ];
|
||||||
SuperPackedPlayer superPackedPlayer0;
|
struct
|
||||||
BYTE spDataLength0;
|
{
|
||||||
SpData spData0;
|
SuperPackedPlayer superPackedPlayer;
|
||||||
SuperPackedPlayer superPackedPlayer1;
|
BYTE spDataLength;
|
||||||
BYTE spDataLength1;
|
SpData spData;
|
||||||
SpData spData1;
|
} player0;
|
||||||
SuperPackedPlayer superPackedPlayer2;
|
struct
|
||||||
|
{
|
||||||
|
SuperPackedPlayer superPackedPlayer;
|
||||||
|
BYTE spDataLength;
|
||||||
|
SpData spData;
|
||||||
|
} player1;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
SuperPackedPlayer superPackedPlayer;
|
||||||
WCHAR shortName[ ARRAYSIZE( SHORT_NAME ) ];
|
WCHAR shortName[ ARRAYSIZE( SHORT_NAME ) ];
|
||||||
WCHAR longName[ ARRAYSIZE( LONG_NAME ) ];
|
WCHAR longName[ ARRAYSIZE( LONG_NAME ) ];
|
||||||
BYTE playerDataLength2;
|
BYTE playerDataLength;
|
||||||
BYTE playerData[ 4 ];
|
BYTE playerData[ 4 ];
|
||||||
BYTE spDataLength2;
|
BYTE spDataLength;
|
||||||
SpData spData2;
|
SpData spData;
|
||||||
|
} player2;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
SuperPackedPlayer superPackedPlayer;
|
||||||
|
BYTE spDataLength;
|
||||||
|
SpData spData;
|
||||||
|
} player3;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
SuperPackedPlayer superPackedPlayer;
|
||||||
|
WCHAR shortName[ ARRAYSIZE( SHORT_NAME ) ];
|
||||||
|
WCHAR longName[ ARRAYSIZE( LONG_NAME ) ];
|
||||||
|
BYTE playerDataLength;
|
||||||
|
BYTE playerData[ 4 ];
|
||||||
|
BYTE spDataLength;
|
||||||
|
SpData spData;
|
||||||
|
BYTE playerCount;
|
||||||
|
DPID playerIds[ 1 ];
|
||||||
|
} group0;
|
||||||
} reply =
|
} reply =
|
||||||
{
|
{
|
||||||
.spHeader =
|
.spHeader =
|
||||||
|
@ -1465,8 +1503,8 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
.command = 41,
|
.command = 41,
|
||||||
.version = 14,
|
.version = 14,
|
||||||
},
|
},
|
||||||
.playerCount = 3,
|
.playerCount = 4,
|
||||||
.groupCount = 0,
|
.groupCount = 1,
|
||||||
.packedOffset = sizeof( reply.reply ) + sizeof( reply.dpsd ) + sizeof( reply.sessionName ),
|
.packedOffset = sizeof( reply.reply ) + sizeof( reply.dpsd ) + sizeof( reply.sessionName ),
|
||||||
.shortcutCount = 0,
|
.shortcutCount = 0,
|
||||||
.descriptionOffset = sizeof( reply.reply ),
|
.descriptionOffset = sizeof( reply.reply ),
|
||||||
|
@ -1474,7 +1512,9 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
.passwordOffset = 0,
|
.passwordOffset = 0,
|
||||||
},
|
},
|
||||||
.dpsd = *dpsd,
|
.dpsd = *dpsd,
|
||||||
.superPackedPlayer0 =
|
.player0 =
|
||||||
|
{
|
||||||
|
.superPackedPlayer =
|
||||||
{
|
{
|
||||||
.size = 16,
|
.size = 16,
|
||||||
.flags = 0x5,
|
.flags = 0x5,
|
||||||
|
@ -1482,8 +1522,8 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
.infoMask = 0x4,
|
.infoMask = 0x4,
|
||||||
.versionOrSystemPlayerId = 14,
|
.versionOrSystemPlayerId = 14,
|
||||||
},
|
},
|
||||||
.spDataLength0 = sizeof( SpData ),
|
.spDataLength = sizeof( SpData ),
|
||||||
.spData0 =
|
.spData =
|
||||||
{
|
{
|
||||||
.tcpAddr =
|
.tcpAddr =
|
||||||
{
|
{
|
||||||
|
@ -1496,7 +1536,10 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
.sin_port = htons( udpPort ),
|
.sin_port = htons( udpPort ),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.superPackedPlayer1 =
|
},
|
||||||
|
.player1 =
|
||||||
|
{
|
||||||
|
.superPackedPlayer =
|
||||||
{
|
{
|
||||||
.size = 16,
|
.size = 16,
|
||||||
.flags = 0xf,
|
.flags = 0xf,
|
||||||
|
@ -1504,8 +1547,8 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
.infoMask = 0x4,
|
.infoMask = 0x4,
|
||||||
.versionOrSystemPlayerId = 14,
|
.versionOrSystemPlayerId = 14,
|
||||||
},
|
},
|
||||||
.spDataLength1 = sizeof( SpData ),
|
.spDataLength = sizeof( SpData ),
|
||||||
.spData1 =
|
.spData =
|
||||||
{
|
{
|
||||||
.tcpAddr =
|
.tcpAddr =
|
||||||
{
|
{
|
||||||
|
@ -1518,7 +1561,10 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
.sin_port = htons( udpPort ),
|
.sin_port = htons( udpPort ),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.superPackedPlayer2 =
|
},
|
||||||
|
.player2 =
|
||||||
|
{
|
||||||
|
.superPackedPlayer =
|
||||||
{
|
{
|
||||||
.size = 16,
|
.size = 16,
|
||||||
.flags = 0x8,
|
.flags = 0x8,
|
||||||
|
@ -1528,10 +1574,10 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
},
|
},
|
||||||
.shortName = SHORT_NAME,
|
.shortName = SHORT_NAME,
|
||||||
.longName = LONG_NAME,
|
.longName = LONG_NAME,
|
||||||
.playerDataLength2 = 4,
|
.playerDataLength = 4,
|
||||||
.playerData = { 1, 2, 3, 4, },
|
.playerData = { 1, 2, 3, 4, },
|
||||||
.spDataLength2 = sizeof( SpData ),
|
.spDataLength = sizeof( SpData ),
|
||||||
.spData2 =
|
.spData =
|
||||||
{
|
{
|
||||||
.tcpAddr =
|
.tcpAddr =
|
||||||
{
|
{
|
||||||
|
@ -1544,7 +1590,65 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
.sin_port = htons( udpPort ),
|
.sin_port = htons( udpPort ),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
.player3 =
|
||||||
|
{
|
||||||
|
.superPackedPlayer =
|
||||||
|
{
|
||||||
|
.size = 16,
|
||||||
|
.flags = 0x8,
|
||||||
|
.id = 0xd00de,
|
||||||
|
.infoMask = 0x4,
|
||||||
|
.versionOrSystemPlayerId = 0x51573,
|
||||||
|
},
|
||||||
|
.spDataLength = sizeof( SpData ),
|
||||||
|
.spData =
|
||||||
|
{
|
||||||
|
.tcpAddr =
|
||||||
|
{
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_port = htons( tcpPort ),
|
||||||
|
},
|
||||||
|
.udpAddr =
|
||||||
|
{
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_port = htons( udpPort ),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.group0 =
|
||||||
|
{
|
||||||
|
.superPackedPlayer =
|
||||||
|
{
|
||||||
|
.size = 16,
|
||||||
|
.flags = 0x48,
|
||||||
|
.id = 0x5e7,
|
||||||
|
.infoMask = 0x57,
|
||||||
|
.versionOrSystemPlayerId = 0x51573,
|
||||||
|
},
|
||||||
|
.shortName = SHORT_NAME,
|
||||||
|
.longName = LONG_NAME,
|
||||||
|
.playerDataLength = 4,
|
||||||
|
.playerData = { 1, 2, 3, 4, },
|
||||||
|
.spDataLength = sizeof( SpData ),
|
||||||
|
.spData =
|
||||||
|
{
|
||||||
|
.tcpAddr =
|
||||||
|
{
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_port = htons( tcpPort ),
|
||||||
|
},
|
||||||
|
.udpAddr =
|
||||||
|
{
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_port = htons( udpPort ),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.playerCount = 1,
|
||||||
|
.playerIds = { 0xd00de, },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
#undef LONG_NAME
|
#undef LONG_NAME
|
||||||
#undef SHORT_NAME
|
#undef SHORT_NAME
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
@ -1561,6 +1665,7 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
||||||
#define sendAddForwardReply( sock, port, result ) sendAddForwardReply_( __LINE__, sock, port, result )
|
#define sendAddForwardReply( sock, port, result ) sendAddForwardReply_( __LINE__, sock, port, result )
|
||||||
static void sendAddForwardReply_( int line, SOCKET sock, unsigned short port, HRESULT result )
|
static void sendAddForwardReply_( int line, SOCKET sock, unsigned short port, HRESULT result )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
|
@ -1587,6 +1692,7 @@ static void sendAddForwardReply_( int line, SOCKET sock, unsigned short port, HR
|
||||||
.result = result,
|
.result = result,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
wsResult = send( sock, (char *) &reply, sizeof( reply ), 0 );
|
wsResult = send( sock, (char *) &reply, sizeof( reply ), 0 );
|
||||||
|
@ -1596,6 +1702,7 @@ static void sendAddForwardReply_( int line, SOCKET sock, unsigned short port, HR
|
||||||
#define sendAddForward( sock, port, tcpPort, udpPort ) sendAddForward_( __LINE__, sock, port, tcpPort, udpPort )
|
#define sendAddForward( sock, port, tcpPort, udpPort ) sendAddForward_( __LINE__, sock, port, tcpPort, udpPort )
|
||||||
static void sendAddForward_( int line, SOCKET sock, unsigned short port, unsigned short tcpPort, unsigned short udpPort )
|
static void sendAddForward_( int line, SOCKET sock, unsigned short port, unsigned short tcpPort, unsigned short udpPort )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
|
@ -1653,6 +1760,7 @@ static void sendAddForward_( int line, SOCKET sock, unsigned short port, unsigne
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
|
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
|
@ -1663,11 +1771,13 @@ static void sendAddForward_( int line, SOCKET sock, unsigned short port, unsigne
|
||||||
#define receiveAddForwardAck( sock, expectedPlayerId ) receiveAddForwardAck_( __LINE__, sock, expectedPlayerId )
|
#define receiveAddForwardAck( sock, expectedPlayerId ) receiveAddForwardAck_( __LINE__, sock, expectedPlayerId )
|
||||||
static unsigned short receiveAddForwardAck_( int line, SOCKET sock, DPID expectedPlayerId )
|
static unsigned short receiveAddForwardAck_( int line, SOCKET sock, DPID expectedPlayerId )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
AddForwardAck request;
|
AddForwardAck request;
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
|
@ -1688,11 +1798,13 @@ static unsigned short receiveCreatePlayer_( int line, SOCKET sock, DPID expected
|
||||||
const WCHAR *expectedShortName, const WCHAR *expectedLongName,
|
const WCHAR *expectedShortName, const WCHAR *expectedLongName,
|
||||||
void *expectedPlayerData, DWORD expectedPlayerDataSize )
|
void *expectedPlayerData, DWORD expectedPlayerDataSize )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
CreatePlayer request;
|
CreatePlayer request;
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
DWORD expectedShortNameSize;
|
DWORD expectedShortNameSize;
|
||||||
DWORD expectedLongNameSize;
|
DWORD expectedLongNameSize;
|
||||||
WCHAR shortName[ 256 ];
|
WCHAR shortName[ 256 ];
|
||||||
|
@ -1775,6 +1887,7 @@ static unsigned short receiveCreatePlayer_( int line, SOCKET sock, DPID expected
|
||||||
static void sendCreatePlayer_( int line, SOCKET sock, unsigned short tcpPort, unsigned short udpPort,
|
static void sendCreatePlayer_( int line, SOCKET sock, unsigned short tcpPort, unsigned short udpPort,
|
||||||
const WCHAR *shortName, const WCHAR *longName, void *playerData, DWORD playerDataSize )
|
const WCHAR *shortName, const WCHAR *longName, void *playerData, DWORD playerDataSize )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
|
@ -1820,6 +1933,7 @@ static void sendCreatePlayer_( int line, SOCKET sock, unsigned short tcpPort, un
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
SpData spData = {
|
SpData spData = {
|
||||||
.tcpAddr.sin_family = AF_INET,
|
.tcpAddr.sin_family = AF_INET,
|
||||||
.tcpAddr.sin_port = htons( tcpPort ),
|
.tcpAddr.sin_port = htons( tcpPort ),
|
||||||
|
@ -1877,12 +1991,14 @@ static void sendCreatePlayer_( int line, SOCKET sock, unsigned short tcpPort, un
|
||||||
static unsigned short receiveGuaranteedGameMessage_( int line, SOCKET sock, DPID expectedFromId, DPID expectedToId,
|
static unsigned short receiveGuaranteedGameMessage_( int line, SOCKET sock, DPID expectedFromId, DPID expectedToId,
|
||||||
void *expectedData, DWORD expectedDataSize )
|
void *expectedData, DWORD expectedDataSize )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
GameMessage request;
|
GameMessage request;
|
||||||
BYTE data[ 256 ];
|
BYTE data[ 256 ];
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
|
@ -1903,11 +2019,13 @@ static unsigned short receiveGuaranteedGameMessage_( int line, SOCKET sock, DPID
|
||||||
static void receiveGameMessage_( int line, SOCKET sock, DPID expectedFromId, DPID expectedToId, void *expectedData,
|
static void receiveGameMessage_( int line, SOCKET sock, DPID expectedFromId, DPID expectedToId, void *expectedData,
|
||||||
DWORD expectedDataSize )
|
DWORD expectedDataSize )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
GameMessage request;
|
GameMessage request;
|
||||||
BYTE data[ 256 ];
|
BYTE data[ 256 ];
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
DWORD expectedSize = sizeof( request.request ) + expectedDataSize;
|
DWORD expectedSize = sizeof( request.request ) + expectedDataSize;
|
||||||
|
@ -1924,6 +2042,7 @@ static void receiveGameMessage_( int line, SOCKET sock, DPID expectedFromId, DPI
|
||||||
static void sendGuaranteedGameMessage_( int line, SOCKET sock, unsigned short port, DPID fromId, DPID toId, void *data,
|
static void sendGuaranteedGameMessage_( int line, SOCKET sock, unsigned short port, DPID fromId, DPID toId, void *data,
|
||||||
DWORD dataSize )
|
DWORD dataSize )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
|
@ -1945,6 +2064,7 @@ static void sendGuaranteedGameMessage_( int line, SOCKET sock, unsigned short po
|
||||||
.toId = toId,
|
.toId = toId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
wsResult = send( sock, (char *) &request, sizeof( request ), 0 );
|
wsResult = send( sock, (char *) &request, sizeof( request ), 0 );
|
||||||
|
@ -1958,6 +2078,7 @@ static void sendGuaranteedGameMessage_( int line, SOCKET sock, unsigned short po
|
||||||
sendGameMessage_( __LINE__, sock, fromId, toId, data, dataSize )
|
sendGameMessage_( __LINE__, sock, fromId, toId, data, dataSize )
|
||||||
static void sendGameMessage_( int line, SOCKET sock, DPID fromId, DPID toId, void *data, DWORD dataSize )
|
static void sendGameMessage_( int line, SOCKET sock, DPID fromId, DPID toId, void *data, DWORD dataSize )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
GameMessage request;
|
GameMessage request;
|
||||||
|
@ -1970,6 +2091,7 @@ static void sendGameMessage_( int line, SOCKET sock, DPID fromId, DPID toId, voi
|
||||||
.toId = toId,
|
.toId = toId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
int wsResult;
|
int wsResult;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
|
@ -1985,6 +2107,7 @@ static void sendGameMessage_( int line, SOCKET sock, DPID fromId, DPID toId, voi
|
||||||
sendPing_( __LINE__, sock, port, fromId, tickCount )
|
sendPing_( __LINE__, sock, port, fromId, tickCount )
|
||||||
static void sendPing_( int line, SOCKET sock, unsigned short port, DPID fromId, DWORD tickCount )
|
static void sendPing_( int line, SOCKET sock, unsigned short port, DPID fromId, DWORD tickCount )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
|
@ -2012,6 +2135,7 @@ static void sendPing_( int line, SOCKET sock, unsigned short port, DPID fromId,
|
||||||
.tickCount = tickCount,
|
.tickCount = tickCount,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#include "poppack.h"
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
wsResult = send( sock, (char *) &request, sizeof( request ), 0 );
|
wsResult = send( sock, (char *) &request, sizeof( request ), 0 );
|
||||||
|
@ -2022,11 +2146,13 @@ static void sendPing_( int line, SOCKET sock, unsigned short port, DPID fromId,
|
||||||
receivePingReply_( __LINE__, sock, expectedFromId, expectedTickCount )
|
receivePingReply_( __LINE__, sock, expectedFromId, expectedTickCount )
|
||||||
static unsigned short receivePingReply_( int line, SOCKET sock, DPID expectedFromId, DWORD expectedTickCount )
|
static unsigned short receivePingReply_( int line, SOCKET sock, DPID expectedFromId, DWORD expectedTickCount )
|
||||||
{
|
{
|
||||||
|
#include "pshpack1.h"
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
SpHeader spHeader;
|
SpHeader spHeader;
|
||||||
Ping request;
|
Ping request;
|
||||||
} request;
|
} request;
|
||||||
|
#include "poppack.h"
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
int wsResult;
|
int wsResult;
|
||||||
|
|
||||||
|
@ -2704,7 +2830,7 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if ( player->actualCount )
|
if ( player->actualCount )
|
||||||
ok_( __FILE__, data->line )( 0, "duplicate player dpid %#lx.\n", dpid );
|
todo_wine ok_( __FILE__, data->line )( 0, "duplicate player dpid %#lx.\n", dpid );
|
||||||
ok_( __FILE__, data->line )( playerType == player->expectedPlayerType, "got player type %lu.\n",
|
ok_( __FILE__, data->line )( playerType == player->expectedPlayerType, "got player type %lu.\n",
|
||||||
playerType );
|
playerType );
|
||||||
if ( player->expectedShortName )
|
if ( player->expectedShortName )
|
||||||
|
@ -2727,12 +2853,17 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const
|
||||||
ok_( __FILE__, data->line )( !name->lpszLongNameA, "got long name %s.\n",
|
ok_( __FILE__, data->line )( !name->lpszLongNameA, "got long name %s.\n",
|
||||||
wine_dbgstr_a( name->lpszLongNameA ) );
|
wine_dbgstr_a( name->lpszLongNameA ) );
|
||||||
}
|
}
|
||||||
|
todo_wine_if( playerType == DPPLAYERTYPE_GROUP && flags == DPENUMPLAYERS_LOCAL )
|
||||||
ok_( __FILE__, data->line )( flags == player->expectedFlags, "got flags %#lx.\n", flags );
|
ok_( __FILE__, data->line )( flags == player->expectedFlags, "got flags %#lx.\n", flags );
|
||||||
|
|
||||||
memset( &playerData, 0xcc, sizeof( playerData ) );
|
memset( &playerData, 0xcc, sizeof( playerData ) );
|
||||||
playerDataSize = sizeof( playerData );
|
playerDataSize = sizeof( playerData );
|
||||||
|
if ( playerType == DPPLAYERTYPE_PLAYER )
|
||||||
hr = IDirectPlayX_GetPlayerData( data->dp, dpid, playerData, &playerDataSize, DPGET_REMOTE );
|
hr = IDirectPlayX_GetPlayerData( data->dp, dpid, playerData, &playerDataSize, DPGET_REMOTE );
|
||||||
|
else
|
||||||
|
hr = IDirectPlayX_GetGroupData( data->dp, dpid, playerData, &playerDataSize, DPGET_REMOTE );
|
||||||
ok_( __FILE__, data->line )( hr == DP_OK, "GetPlayerData() returned %#lx.\n", hr );
|
ok_( __FILE__, data->line )( hr == DP_OK, "GetPlayerData() returned %#lx.\n", hr );
|
||||||
|
todo_wine_if( playerType == DPPLAYERTYPE_GROUP )
|
||||||
ok_( __FILE__, data->line )( playerDataSize == player->expectedPlayerDataSize,
|
ok_( __FILE__, data->line )( playerDataSize == player->expectedPlayerDataSize,
|
||||||
"got player data size %lu.\n", playerDataSize );
|
"got player data size %lu.\n", playerDataSize );
|
||||||
ok_( __FILE__, data->line )( !memcmp( playerData, player->expectedPlayerData, player->expectedPlayerDataSize ),
|
ok_( __FILE__, data->line )( !memcmp( playerData, player->expectedPlayerData, player->expectedPlayerDataSize ),
|
||||||
|
@ -2740,7 +2871,10 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const
|
||||||
|
|
||||||
memset( &nameData, 0xcc, sizeof( nameData ) );
|
memset( &nameData, 0xcc, sizeof( nameData ) );
|
||||||
nameDataSize = sizeof( nameData );
|
nameDataSize = sizeof( nameData );
|
||||||
|
if ( playerType == DPPLAYERTYPE_PLAYER )
|
||||||
hr = IDirectPlayX_GetPlayerName( data->dp, dpid, &nameData, &nameDataSize );
|
hr = IDirectPlayX_GetPlayerName( data->dp, dpid, &nameData, &nameDataSize );
|
||||||
|
else
|
||||||
|
hr = IDirectPlayX_GetGroupName( data->dp, dpid, &nameData, &nameDataSize );
|
||||||
ok_( __FILE__, data->line )( hr == DP_OK, "GetPlayerName() returned %#lx.\n", hr );
|
ok_( __FILE__, data->line )( hr == DP_OK, "GetPlayerName() returned %#lx.\n", hr );
|
||||||
ok_( __FILE__, data->line )( ((DPNAME *) nameData)->dwSize == sizeof( DPNAME ),
|
ok_( __FILE__, data->line )( ((DPNAME *) nameData)->dwSize == sizeof( DPNAME ),
|
||||||
"got name size %lu.\n", ((DPNAME *) nameData)->dwSize );
|
"got name size %lu.\n", ((DPNAME *) nameData)->dwSize );
|
||||||
|
@ -2796,7 +2930,8 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define checkPlayerList( dp, expectedPlayers, expectedPlayerCount ) checkPlayerList_( __LINE__, dp, expectedPlayers, expectedPlayerCount )
|
#define checkPlayerList( dp, expectedPlayers, expectedPlayerCount ) \
|
||||||
|
checkPlayerList_( __LINE__, dp, expectedPlayers, expectedPlayerCount )
|
||||||
static void checkPlayerList_( int line, IDirectPlay4 *dp, ExpectedPlayer *expectedPlayers, int expectedPlayerCount )
|
static void checkPlayerList_( int line, IDirectPlay4 *dp, ExpectedPlayer *expectedPlayers, int expectedPlayerCount )
|
||||||
{
|
{
|
||||||
CheckPlayerListCallbackData data = {
|
CheckPlayerListCallbackData data = {
|
||||||
|
@ -2817,6 +2952,51 @@ static void checkPlayerList_( int line, IDirectPlay4 *dp, ExpectedPlayer *expect
|
||||||
data.actualPlayerCount );
|
data.actualPlayerCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define checkGroupPlayerList( dp, group, expectedPlayers, expectedPlayerCount ) \
|
||||||
|
checkGroupPlayerList_( __LINE__, dp, group, expectedPlayers, expectedPlayerCount )
|
||||||
|
static void checkGroupPlayerList_( int line, DPID group, IDirectPlay4 *dp, ExpectedPlayer *expectedPlayers,
|
||||||
|
int expectedPlayerCount )
|
||||||
|
{
|
||||||
|
CheckPlayerListCallbackData data = {
|
||||||
|
.line = line,
|
||||||
|
.dp = dp,
|
||||||
|
.expectedPlayers = expectedPlayers,
|
||||||
|
.expectedPlayerCount = expectedPlayerCount,
|
||||||
|
};
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = IDirectPlayX_EnumGroupPlayers( dp, group, NULL, checkPlayerListCallback, &data, DPENUMPLAYERS_LOCAL );
|
||||||
|
ok_( __FILE__, line )( hr == DP_OK, "EnumGroupPlayers() returned %#lx.\n", hr );
|
||||||
|
|
||||||
|
hr = IDirectPlayX_EnumGroupPlayers( dp, group, NULL, checkPlayerListCallback, &data, DPENUMPLAYERS_REMOTE );
|
||||||
|
ok_( __FILE__, line )( hr == DP_OK, "EnumGroupPlayers() returned %#lx.\n", hr );
|
||||||
|
|
||||||
|
todo_wine ok_( __FILE__, line )( data.actualPlayerCount == data.expectedPlayerCount, "got player count %d.\n",
|
||||||
|
data.actualPlayerCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
#define checkGroupList( dp, expectedGroups, expectedGroupCount ) \
|
||||||
|
checkGroupList_( __LINE__, dp, expectedGroups, expectedGroupCount )
|
||||||
|
static void checkGroupList_( int line, IDirectPlay4 *dp, ExpectedPlayer *expectedGroups, int expectedGroupCount )
|
||||||
|
{
|
||||||
|
CheckPlayerListCallbackData data = {
|
||||||
|
.line = line,
|
||||||
|
.dp = dp,
|
||||||
|
.expectedPlayers = expectedGroups,
|
||||||
|
.expectedPlayerCount = expectedGroupCount,
|
||||||
|
};
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = IDirectPlayX_EnumGroups( dp, NULL, checkPlayerListCallback, &data, DPENUMGROUPS_LOCAL );
|
||||||
|
ok_( __FILE__, line )( hr == DP_OK, "EnumGroups() returned %#lx.\n", hr );
|
||||||
|
|
||||||
|
hr = IDirectPlayX_EnumGroups( dp, NULL, checkPlayerListCallback, &data, DPENUMGROUPS_REMOTE );
|
||||||
|
ok_( __FILE__, line )( hr == DP_OK, "EnumGroups() returned %#lx.\n", hr );
|
||||||
|
|
||||||
|
todo_wine ok_( __FILE__, line )( data.actualPlayerCount == data.expectedPlayerCount, "got group count %d.\n",
|
||||||
|
data.actualPlayerCount );
|
||||||
|
}
|
||||||
|
|
||||||
#define checkPlayerExists( dp, expectedDpid, expectedPlayerType, expectedShortName, expectedLongName, expectedFlags, \
|
#define checkPlayerExists( dp, expectedDpid, expectedPlayerType, expectedShortName, expectedLongName, expectedFlags, \
|
||||||
expectedPlayerData, expectedPlayerDataSize ) \
|
expectedPlayerData, expectedPlayerDataSize ) \
|
||||||
checkPlayerExists_( __LINE__, dp, expectedDpid, expectedPlayerType, expectedShortName, expectedLongName, \
|
checkPlayerExists_( __LINE__, dp, expectedDpid, expectedPlayerType, expectedShortName, expectedLongName, \
|
||||||
|
@ -2918,9 +3098,36 @@ static void check_Open_( int line, IDirectPlay4A *dp, DPSESSIONDESC2 *dpsd, cons
|
||||||
.expectedPlayerData = expectedPlayerData,
|
.expectedPlayerData = expectedPlayerData,
|
||||||
.expectedPlayerDataSize = sizeof( expectedPlayerData ),
|
.expectedPlayerDataSize = sizeof( expectedPlayerData ),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.expectedDpid = 0xd00de,
|
||||||
|
.expectedPlayerType = DPPLAYERTYPE_PLAYER,
|
||||||
|
.expectedFlags = DPENUMPLAYERS_REMOTE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ExpectedPlayer expectedGroups[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.expectedDpid = 0x5e7,
|
||||||
|
.expectedPlayerType = DPPLAYERTYPE_GROUP,
|
||||||
|
.expectedShortName = "short name",
|
||||||
|
.expectedLongName = "long name",
|
||||||
|
.expectedFlags = DPENUMPLAYERS_REMOTE,
|
||||||
|
.expectedPlayerData = expectedPlayerData,
|
||||||
|
.expectedPlayerDataSize = sizeof( expectedPlayerData ),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ExpectedPlayer expectedGroupPlayers[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.expectedDpid = 0xd00de,
|
||||||
|
.expectedPlayerType = DPPLAYERTYPE_PLAYER,
|
||||||
|
.expectedFlags = DPENUMPLAYERS_REMOTE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
checkPlayerList_( line, dp, expectedPlayers, ARRAYSIZE( expectedPlayers ) );
|
checkPlayerList_( line, dp, expectedPlayers, ARRAYSIZE( expectedPlayers ) );
|
||||||
|
checkGroupList_( line, dp, expectedGroups, ARRAYSIZE( expectedGroups ) );
|
||||||
|
checkGroupPlayerList_( line, 0x5e7, dp, expectedGroupPlayers, ARRAYSIZE( expectedGroupPlayers ) );
|
||||||
|
|
||||||
hr = IDirectPlayX_Close( dp );
|
hr = IDirectPlayX_Close( dp );
|
||||||
checkHR( DP_OK, hr );
|
checkHR( DP_OK, hr );
|
||||||
|
@ -4648,20 +4855,20 @@ static void test_CreatePlayer(void)
|
||||||
|
|
||||||
/* Player name */
|
/* Player name */
|
||||||
dpid = 0xdeadbeef;
|
dpid = 0xdeadbeef;
|
||||||
check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 2, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 1 );
|
check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 2, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 2 );
|
||||||
|
|
||||||
dpid = 0xdeadbeef;
|
dpid = 0xdeadbeef;
|
||||||
check_CreatePlayer( dp, &dpid, &fullName, 0, DP_OK, 3, recvSock, TRUE, 0x8, L"short player name",
|
check_CreatePlayer( dp, &dpid, &fullName, 0, DP_OK, 3, recvSock, TRUE, 0x8, L"short player name",
|
||||||
"short player name", L"long player name", "long player name", 2 );
|
"short player name", L"long player name", "long player name", 3 );
|
||||||
|
|
||||||
name = fullName;
|
name = fullName;
|
||||||
name.dwSize = 1;
|
name.dwSize = 1;
|
||||||
dpid = 0xdeadbeef;
|
dpid = 0xdeadbeef;
|
||||||
check_CreatePlayer( dp, &dpid, &name, 0, DP_OK, 4, recvSock, TRUE, 0x8, L"short player name", "short player name",
|
check_CreatePlayer( dp, &dpid, &name, 0, DP_OK, 4, recvSock, TRUE, 0x8, L"short player name", "short player name",
|
||||||
L"long player name", "long player name", 3 );
|
L"long player name", "long player name", 4 );
|
||||||
|
|
||||||
dpid = 0xdeadbeef;
|
dpid = 0xdeadbeef;
|
||||||
check_CreatePlayer( dp, &dpid, &nullName, 0, DP_OK, 5, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 4 );
|
check_CreatePlayer( dp, &dpid, &nullName, 0, DP_OK, 5, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 5 );
|
||||||
|
|
||||||
/* Null dpid */
|
/* Null dpid */
|
||||||
dpid = 0xdeadbeef;
|
dpid = 0xdeadbeef;
|
||||||
|
@ -4669,11 +4876,11 @@ static void test_CreatePlayer(void)
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
dpid = 0xdeadbeef;
|
dpid = 0xdeadbeef;
|
||||||
check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 6, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 5 );
|
check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 6, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 6 );
|
||||||
|
|
||||||
dpid = 0xdeadbeef;
|
dpid = 0xdeadbeef;
|
||||||
check_CreatePlayer( dp, &dpid, NULL, DPPLAYER_SPECTATOR, DP_OK, 7, recvSock, TRUE, 0x208, NULL, NULL, NULL, NULL,
|
check_CreatePlayer( dp, &dpid, NULL, DPPLAYER_SPECTATOR, DP_OK, 7, recvSock, TRUE, 0x208, NULL, NULL, NULL, NULL,
|
||||||
6 );
|
7 );
|
||||||
|
|
||||||
closesocket( recvSock );
|
closesocket( recvSock );
|
||||||
closesocket( sendSock );
|
closesocket( sendSock );
|
||||||
|
@ -4920,7 +5127,7 @@ static void test_CREATEPLAYER(void)
|
||||||
checkPlayerExists( dp, 0x07734, DPPLAYERTYPE_PLAYER, "new player short name", "new player long name",
|
checkPlayerExists( dp, 0x07734, DPPLAYERTYPE_PLAYER, "new player short name", "new player long name",
|
||||||
DPENUMPLAYERS_REMOTE, playerData, sizeof( playerData ) );
|
DPENUMPLAYERS_REMOTE, playerData, sizeof( playerData ) );
|
||||||
|
|
||||||
dpid = checkCreatePlayerOrGroupMessage( dp, DPPLAYERTYPE_PLAYER, 0x07734, 3, playerData, sizeof( playerData ),
|
dpid = checkCreatePlayerOrGroupMessage( dp, DPPLAYERTYPE_PLAYER, 0x07734, 4, playerData, sizeof( playerData ),
|
||||||
"new player short name", "new player long name", 0, 0 );
|
"new player short name", "new player long name", 0, 0 );
|
||||||
ok( dpid == 0x11223344, "got destination id %#lx.\n", dpid );
|
ok( dpid == 0x11223344, "got destination id %#lx.\n", dpid );
|
||||||
|
|
||||||
|
@ -7852,7 +8059,7 @@ static void test_Send(void)
|
||||||
createPlayer( dp, 0x07734, NULL, NULL, 0, 0, sendSock, recvSock );
|
createPlayer( dp, 0x07734, NULL, NULL, 0, 0, sendSock, recvSock );
|
||||||
createPlayer( dp, 0x14, NULL, NULL, 0, 0, sendSock, recvSock );
|
createPlayer( dp, 0x14, NULL, NULL, 0, 0, sendSock, recvSock );
|
||||||
|
|
||||||
checkCreatePlayerOrGroupMessage( dp, DPPLAYERTYPE_PLAYER, 0x14, 2, NULL, 0, NULL, NULL, 0, DPPLAYER_LOCAL );
|
checkCreatePlayerOrGroupMessage( dp, DPPLAYERTYPE_PLAYER, 0x14, 3, NULL, 0, NULL, NULL, 0, DPPLAYER_LOCAL );
|
||||||
|
|
||||||
hr = IDirectPlayX_Send( dp, 0x07734, 0xdeadbeef, DPSEND_GUARANTEED, data, sizeof( data ) );
|
hr = IDirectPlayX_Send( dp, 0x07734, 0xdeadbeef, DPSEND_GUARANTEED, data, sizeof( data ) );
|
||||||
todo_wine ok( hr == DPERR_INVALIDPARAM, "got hr %#lx.\n", hr );
|
todo_wine ok( hr == DPERR_INVALIDPARAM, "got hr %#lx.\n", hr );
|
||||||
|
@ -8289,7 +8496,7 @@ static void test_Receive(void)
|
||||||
waitResult = WaitForSingleObject( event0, 2000 );
|
waitResult = WaitForSingleObject( event0, 2000 );
|
||||||
ok( waitResult == WAIT_OBJECT_0, "message wait returned %lu\n", waitResult );
|
ok( waitResult == WAIT_OBJECT_0, "message wait returned %lu\n", waitResult );
|
||||||
|
|
||||||
checkCreatePlayerOrGroupMessage( dp, DPPLAYERTYPE_PLAYER, 0x14, 2, NULL, 0, NULL, NULL, 0, DPPLAYER_LOCAL );
|
checkCreatePlayerOrGroupMessage( dp, DPPLAYERTYPE_PLAYER, 0x14, 3, NULL, 0, NULL, NULL, 0, DPPLAYER_LOCAL );
|
||||||
|
|
||||||
sendGuaranteedGameMessage( sendSock, 2349, 0x1337, 0x07734, data0, sizeof( data0 ) );
|
sendGuaranteedGameMessage( sendSock, 2349, 0x1337, 0x07734, data0, sizeof( data0 ) );
|
||||||
sendGuaranteedGameMessage( sendSock, 2349, 0x1337, 0x14, data1, sizeof( data1 ) );
|
sendGuaranteedGameMessage( sendSock, 2349, 0x1337, 0x14, data1, sizeof( data1 ) );
|
||||||
|
|
|
@ -2390,6 +2390,18 @@ static void WINAPI WineJSDispatch_Free(IWineJSDispatch *iface)
|
||||||
jsdisp_free(This);
|
jsdisp_free(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI WineJSDispatch_GetPropertyFlags(IWineJSDispatch *iface, DISPID id, UINT32 *ret)
|
||||||
|
{
|
||||||
|
jsdisp_t *This = impl_from_IWineJSDispatch(iface);
|
||||||
|
dispex_prop_t *prop = get_prop(This, id);
|
||||||
|
|
||||||
|
if(!prop || prop->type == PROP_DELETED || prop->type == PROP_PROTREF)
|
||||||
|
return DISP_E_MEMBERNOTFOUND;
|
||||||
|
|
||||||
|
*ret = prop->flags & PROPF_PUBLIC_MASK;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI WineJSDispatch_GetScriptGlobal(IWineJSDispatch *iface, IWineJSDispatchHost **ret)
|
static HRESULT WINAPI WineJSDispatch_GetScriptGlobal(IWineJSDispatch *iface, IWineJSDispatchHost **ret)
|
||||||
{
|
{
|
||||||
jsdisp_t *This = impl_from_IWineJSDispatch(iface);
|
jsdisp_t *This = impl_from_IWineJSDispatch(iface);
|
||||||
|
@ -2422,6 +2434,7 @@ static IWineJSDispatchVtbl DispatchExVtbl = {
|
||||||
DispatchEx_GetNextDispID,
|
DispatchEx_GetNextDispID,
|
||||||
DispatchEx_GetNameSpaceParent,
|
DispatchEx_GetNameSpaceParent,
|
||||||
WineJSDispatch_Free,
|
WineJSDispatch_Free,
|
||||||
|
WineJSDispatch_GetPropertyFlags,
|
||||||
WineJSDispatch_GetScriptGlobal,
|
WineJSDispatch_GetScriptGlobal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3282,8 +3295,14 @@ HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t
|
||||||
if(desc->explicit_value) {
|
if(desc->explicit_value) {
|
||||||
if(prop->type == PROP_JSVAL)
|
if(prop->type == PROP_JSVAL)
|
||||||
jsval_release(prop->u.val);
|
jsval_release(prop->u.val);
|
||||||
else
|
else {
|
||||||
|
if(prop->type == PROP_EXTERN && obj->builtin_info->prop_delete) {
|
||||||
|
hres = obj->builtin_info->prop_delete(obj, prop->u.id);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
prop->type = PROP_JSVAL;
|
prop->type = PROP_JSVAL;
|
||||||
|
}
|
||||||
hres = jsval_copy(desc->value, &prop->u.val);
|
hres = jsval_copy(desc->value, &prop->u.val);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
prop->u.val = jsval_undefined();
|
prop->u.val = jsval_undefined();
|
||||||
|
|
|
@ -943,7 +943,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Function", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Function", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->function_constr));
|
jsval_obj(ctx->function_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -952,7 +952,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Object", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Object", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->object_constr));
|
jsval_obj(ctx->object_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -961,7 +961,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Array", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Array", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->array_constr));
|
jsval_obj(ctx->array_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -970,7 +970,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Boolean", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Boolean", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->bool_constr));
|
jsval_obj(ctx->bool_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -979,7 +979,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Date", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Date", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->date_constr));
|
jsval_obj(ctx->date_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -988,7 +988,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Enumerator", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Enumerator", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->enumerator_constr));
|
jsval_obj(ctx->enumerator_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -997,42 +997,42 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Error", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Error", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->error_constr));
|
jsval_obj(ctx->error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"EvalError", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"EvalError", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->eval_error_constr));
|
jsval_obj(ctx->eval_error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"RangeError", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"RangeError", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->range_error_constr));
|
jsval_obj(ctx->range_error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"ReferenceError", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"ReferenceError", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->reference_error_constr));
|
jsval_obj(ctx->reference_error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"RegExpError", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"RegExpError", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->regexp_error_constr));
|
jsval_obj(ctx->regexp_error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"SyntaxError", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"SyntaxError", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->syntax_error_constr));
|
jsval_obj(ctx->syntax_error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"TypeError", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"TypeError", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->type_error_constr));
|
jsval_obj(ctx->type_error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"URIError", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"URIError", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->uri_error_constr));
|
jsval_obj(ctx->uri_error_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1041,7 +1041,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Number", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Number", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->number_constr));
|
jsval_obj(ctx->number_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1050,7 +1050,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"RegExp", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"RegExp", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->regexp_constr));
|
jsval_obj(ctx->regexp_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1059,7 +1059,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"String", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"String", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->string_constr));
|
jsval_obj(ctx->string_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1068,7 +1068,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"VBArray", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"VBArray", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(ctx->vbarray_constr));
|
jsval_obj(ctx->vbarray_constr));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1105,7 +1105,7 @@ HRESULT init_global(script_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Math", PROPF_WRITABLE, jsval_obj(math));
|
hres = jsdisp_define_data_property(ctx->global, L"Math", PROPF_CONFIGURABLE | PROPF_WRITABLE, jsval_obj(math));
|
||||||
jsdisp_release(math);
|
jsdisp_release(math);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1117,7 +1117,7 @@ HRESULT init_global(script_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"JSON", PROPF_WRITABLE, jsval_obj(json));
|
hres = jsdisp_define_data_property(ctx->global, L"JSON", PROPF_CONFIGURABLE | PROPF_WRITABLE, jsval_obj(json));
|
||||||
jsdisp_release(json);
|
jsdisp_release(json);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1127,7 +1127,7 @@ HRESULT init_global(script_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"ActiveXObject", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"ActiveXObject", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(constr));
|
jsval_obj(constr));
|
||||||
jsdisp_release(constr);
|
jsdisp_release(constr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
|
|
|
@ -51,6 +51,7 @@ interface IWineJSDispatchHost;
|
||||||
interface IWineJSDispatch : IDispatchEx
|
interface IWineJSDispatch : IDispatchEx
|
||||||
{
|
{
|
||||||
void Free();
|
void Free();
|
||||||
|
HRESULT GetPropertyFlags(DISPID id, UINT32 *ret);
|
||||||
HRESULT GetScriptGlobal(IWineJSDispatchHost **ret);
|
HRESULT GetScriptGlobal(IWineJSDispatchHost **ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -903,7 +903,7 @@ HRESULT init_set_constructor(script_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Set", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Set", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(constructor));
|
jsval_obj(constructor));
|
||||||
jsdisp_release(constructor);
|
jsdisp_release(constructor);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
|
@ -918,7 +918,7 @@ HRESULT init_set_constructor(script_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"Map", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"Map", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(constructor));
|
jsval_obj(constructor));
|
||||||
jsdisp_release(constructor);
|
jsdisp_release(constructor);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
|
@ -933,7 +933,7 @@ HRESULT init_set_constructor(script_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_define_data_property(ctx->global, L"WeakMap", PROPF_WRITABLE,
|
hres = jsdisp_define_data_property(ctx->global, L"WeakMap", PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
||||||
jsval_obj(constructor));
|
jsval_obj(constructor));
|
||||||
jsdisp_release(constructor);
|
jsdisp_release(constructor);
|
||||||
return hres;
|
return hres;
|
||||||
|
|
|
@ -986,12 +986,14 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected
|
||||||
ok(hr == S_OK, "Failed to get value of event, hr %#lx.\n", hr);
|
ok(hr == S_OK, "Failed to get value of event, hr %#lx.\n", hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMFMediaEvent_Release(callback->media_event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (callback->media_event)
|
if (callback->media_event)
|
||||||
IMFMediaEvent_Release(callback->media_event);
|
IMFMediaEvent_Release(callback->media_event);
|
||||||
|
}
|
||||||
|
|
||||||
IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
|
IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1319,8 +1321,10 @@ static void test_source_resolver(void)
|
||||||
ok(mediasource != NULL, "got %p\n", mediasource);
|
ok(mediasource != NULL, "got %p\n", mediasource);
|
||||||
ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
|
ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
|
||||||
|
|
||||||
|
/* Test that no extra refs to mediasource are held if Start() was not called */
|
||||||
|
EXPECT_REF(mediasource, 1);
|
||||||
|
|
||||||
refcount = IMFMediaSource_Release(mediasource);
|
refcount = IMFMediaSource_Release(mediasource);
|
||||||
todo_wine
|
|
||||||
ok(!refcount, "Unexpected refcount %ld\n", refcount);
|
ok(!refcount, "Unexpected refcount %ld\n", refcount);
|
||||||
IMFByteStream_Release(stream);
|
IMFByteStream_Release(stream);
|
||||||
|
|
||||||
|
@ -1407,15 +1411,21 @@ static void test_source_resolver(void)
|
||||||
ok(mediasource != NULL, "got %p\n", mediasource);
|
ok(mediasource != NULL, "got %p\n", mediasource);
|
||||||
ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
|
ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
|
||||||
|
|
||||||
|
EXPECT_REF(mediasource, 1);
|
||||||
|
|
||||||
check_interface(mediasource, &IID_IMFGetService, TRUE);
|
check_interface(mediasource, &IID_IMFGetService, TRUE);
|
||||||
check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
|
check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
|
||||||
|
|
||||||
hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service);
|
hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service);
|
||||||
ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
|
ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
EXPECT_REF(mediasource, 2);
|
||||||
|
|
||||||
hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support);
|
hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support);
|
||||||
ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
|
ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
EXPECT_REF(mediasource, 3);
|
||||||
|
|
||||||
hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
|
hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
|
||||||
ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
|
ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
|
||||||
ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
|
ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
|
||||||
|
@ -1504,6 +1514,11 @@ static void test_source_resolver(void)
|
||||||
hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
|
hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
|
||||||
ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
|
ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
/* The stream holds a reference. It is unclear which object holds the fifth
|
||||||
|
* reference in Windows, but it's released after MENewStream is retrieved. */
|
||||||
|
todo_wine
|
||||||
|
EXPECT_REF(mediasource, 5);
|
||||||
|
|
||||||
video_stream = NULL;
|
video_stream = NULL;
|
||||||
if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
|
if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
|
||||||
{
|
{
|
||||||
|
@ -1511,6 +1526,8 @@ static void test_source_resolver(void)
|
||||||
video_stream = (IMFMediaStream *)var.punkVal;
|
video_stream = (IMFMediaStream *)var.punkVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPECT_REF(mediasource, 4);
|
||||||
|
|
||||||
hr = IMFMediaSource_Pause(mediasource);
|
hr = IMFMediaSource_Pause(mediasource);
|
||||||
ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
|
ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
|
||||||
if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
|
if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
|
||||||
|
@ -1610,7 +1627,6 @@ static void test_source_resolver(void)
|
||||||
|
|
||||||
get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
|
get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
|
||||||
|
|
||||||
IMFMediaStream_Release(video_stream);
|
|
||||||
IMFMediaTypeHandler_Release(handler);
|
IMFMediaTypeHandler_Release(handler);
|
||||||
IMFPresentationDescriptor_Release(descriptor);
|
IMFPresentationDescriptor_Release(descriptor);
|
||||||
|
|
||||||
|
@ -1619,14 +1635,24 @@ static void test_source_resolver(void)
|
||||||
hr = IMFMediaSource_Shutdown(mediasource);
|
hr = IMFMediaSource_Shutdown(mediasource);
|
||||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
/* During shutdown, circular references such as source <-> stream should be released. */
|
||||||
|
EXPECT_REF(mediasource, 3);
|
||||||
|
|
||||||
ok(bytestream_closed, "Missing IMFByteStream::Close call\n");
|
ok(bytestream_closed, "Missing IMFByteStream::Close call\n");
|
||||||
|
|
||||||
hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
|
hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
|
||||||
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
|
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
IMFRateSupport_Release(rate_support);
|
IMFRateSupport_Release(rate_support);
|
||||||
|
|
||||||
|
EXPECT_REF(mediasource, 2);
|
||||||
|
|
||||||
IMFGetService_Release(get_service);
|
IMFGetService_Release(get_service);
|
||||||
IMFMediaSource_Release(mediasource);
|
|
||||||
|
/* Holding a reference to the video stream does not prevent release of the media source. */
|
||||||
|
refcount = IMFMediaSource_Release(mediasource);
|
||||||
|
ok(!refcount, "Unexpected refcount %ld\n", refcount);
|
||||||
|
|
||||||
IMFByteStream_Release(stream);
|
IMFByteStream_Release(stream);
|
||||||
|
|
||||||
/* Create directly through scheme handler. */
|
/* Create directly through scheme handler. */
|
||||||
|
@ -1659,6 +1685,12 @@ static void test_source_resolver(void)
|
||||||
|
|
||||||
IMFSourceResolver_Release(resolver);
|
IMFSourceResolver_Release(resolver);
|
||||||
|
|
||||||
|
hr = IMFMediaStream_GetMediaSource(video_stream, &mediasource);
|
||||||
|
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
refcount = IMFMediaStream_Release(video_stream);
|
||||||
|
ok(!refcount, "Unexpected refcount %ld\n", refcount);
|
||||||
|
|
||||||
hr = MFShutdown();
|
hr = MFShutdown();
|
||||||
ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
|
ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
|
|
@ -50,5 +50,6 @@ void update_browser_script_mode(GeckoBrowser*,IUri*);
|
||||||
BOOL find_global_prop(HTMLInnerWindow*,const WCHAR*,DWORD,ScriptHost**,DISPID*);
|
BOOL find_global_prop(HTMLInnerWindow*,const WCHAR*,DWORD,ScriptHost**,DISPID*);
|
||||||
HRESULT global_prop_still_exists(HTMLInnerWindow*,global_prop_t*);
|
HRESULT global_prop_still_exists(HTMLInnerWindow*,global_prop_t*);
|
||||||
IDispatch *get_script_disp(ScriptHost*);
|
IDispatch *get_script_disp(ScriptHost*);
|
||||||
|
IWineJSDispatch *get_script_jsdisp(ScriptHost*);
|
||||||
IActiveScriptSite *get_first_script_site(HTMLInnerWindow*);
|
IActiveScriptSite *get_first_script_site(HTMLInnerWindow*);
|
||||||
void initialize_script_global(HTMLInnerWindow*);
|
void initialize_script_global(HTMLInnerWindow*);
|
||||||
|
|
|
@ -4029,7 +4029,9 @@ static HRESULT HTMLWindow_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pid
|
||||||
HRESULT HTMLWindow_get_prop_desc(DispatchEx *dispex, DISPID id, struct property_info *desc)
|
HRESULT HTMLWindow_get_prop_desc(DispatchEx *dispex, DISPID id, struct property_info *desc)
|
||||||
{
|
{
|
||||||
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
|
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
|
||||||
|
IWineJSDispatch *jsdisp;
|
||||||
global_prop_t *prop;
|
global_prop_t *prop;
|
||||||
|
HRESULT hres = S_OK;
|
||||||
|
|
||||||
if(id - MSHTML_DISPID_CUSTOM_MIN >= This->global_prop_cnt)
|
if(id - MSHTML_DISPID_CUSTOM_MIN >= This->global_prop_cnt)
|
||||||
return DISP_E_MEMBERNOTFOUND;
|
return DISP_E_MEMBERNOTFOUND;
|
||||||
|
@ -4038,10 +4040,22 @@ HRESULT HTMLWindow_get_prop_desc(DispatchEx *dispex, DISPID id, struct property_
|
||||||
desc->name = prop->name;
|
desc->name = prop->name;
|
||||||
desc->id = id;
|
desc->id = id;
|
||||||
desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE;
|
desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE;
|
||||||
if(prop->type == GLOBAL_DISPEXVAR)
|
|
||||||
desc->flags |= PROPF_ENUMERABLE;
|
|
||||||
desc->iid = 0;
|
desc->iid = 0;
|
||||||
return S_OK;
|
|
||||||
|
switch(prop->type) {
|
||||||
|
case GLOBAL_SCRIPTVAR: {
|
||||||
|
if((jsdisp = get_script_jsdisp(prop->script_host)))
|
||||||
|
hres = IWineJSDispatch_GetPropertyFlags(jsdisp, prop->id, &desc->flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GLOBAL_DISPEXVAR:
|
||||||
|
desc->flags |= PROPF_ENUMERABLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HTMLInnerWindow *HTMLWindow_get_script_global(DispatchEx *dispex)
|
static HTMLInnerWindow *HTMLWindow_get_script_global(DispatchEx *dispex)
|
||||||
|
|
|
@ -85,7 +85,7 @@ struct ScriptHost {
|
||||||
SCRIPTSTATE script_state;
|
SCRIPTSTATE script_state;
|
||||||
|
|
||||||
HTMLInnerWindow *window;
|
HTMLInnerWindow *window;
|
||||||
IDispatchEx *script_dispex;
|
IWineJSDispatch *script_jsdisp;
|
||||||
|
|
||||||
GUID guid;
|
GUID guid;
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
@ -264,7 +264,7 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
WARN("GetScriptDispatch failed: %08lx\n", hres);
|
WARN("GetScriptDispatch failed: %08lx\n", hres);
|
||||||
else {
|
else {
|
||||||
IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&script_host->script_dispex);
|
IDispatch_QueryInterface(script_disp, &IID_IWineJSDispatch, (void**)&script_host->script_jsdisp);
|
||||||
IDispatch_Release(script_disp);
|
IDispatch_Release(script_disp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,8 +301,8 @@ static void release_script_engine(ScriptHost *This)
|
||||||
unlink_ref(&This->parse);
|
unlink_ref(&This->parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(This->script_dispex)
|
if(This->script_jsdisp)
|
||||||
IDispatchEx_Release(This->script_dispex);
|
IWineJSDispatch_Release(This->script_jsdisp);
|
||||||
IActiveScript_Release(This->script);
|
IActiveScript_Release(This->script);
|
||||||
This->script = NULL;
|
This->script = NULL;
|
||||||
This->script_state = SCRIPTSTATE_UNINITIALIZED;
|
This->script_state = SCRIPTSTATE_UNINITIALIZED;
|
||||||
|
@ -1588,6 +1588,11 @@ IDispatch *get_script_disp(ScriptHost *script_host)
|
||||||
return disp;
|
return disp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IWineJSDispatch *get_script_jsdisp(ScriptHost *script_host)
|
||||||
|
{
|
||||||
|
return script_host->script_jsdisp;
|
||||||
|
}
|
||||||
|
|
||||||
IActiveScriptSite *get_first_script_site(HTMLInnerWindow *window)
|
IActiveScriptSite *get_first_script_site(HTMLInnerWindow *window)
|
||||||
{
|
{
|
||||||
if(list_empty(&window->script_hosts)) {
|
if(list_empty(&window->script_hosts)) {
|
||||||
|
@ -1850,9 +1855,9 @@ HRESULT global_prop_still_exists(HTMLInnerWindow *window, global_prop_t *prop)
|
||||||
|
|
||||||
if(!prop->script_host->script)
|
if(!prop->script_host->script)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
if(!prop->script_host->script_dispex)
|
if(!prop->script_host->script_jsdisp)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
return IDispatchEx_GetMemberProperties(prop->script_host->script_dispex, prop->id, 0, &properties);
|
return IWineJSDispatch_GetMemberProperties(prop->script_host->script_jsdisp, prop->id, 0, &properties);
|
||||||
}
|
}
|
||||||
case GLOBAL_ELEMENTVAR: {
|
case GLOBAL_ELEMENTVAR: {
|
||||||
IHTMLElement *elem;
|
IHTMLElement *elem;
|
||||||
|
|
|
@ -23,6 +23,7 @@ var JS_E_NUMBER_EXPECTED = 0x800a1389;
|
||||||
var JS_E_FUNCTION_EXPECTED = 0x800a138a;
|
var JS_E_FUNCTION_EXPECTED = 0x800a138a;
|
||||||
var JS_E_DATE_EXPECTED = 0x800a138e;
|
var JS_E_DATE_EXPECTED = 0x800a138e;
|
||||||
var JS_E_OBJECT_EXPECTED = 0x800a138f;
|
var JS_E_OBJECT_EXPECTED = 0x800a138f;
|
||||||
|
var JS_E_UNDEFINED_VARIABLE = 0x800a1391;
|
||||||
var JS_E_BOOLEAN_EXPECTED = 0x800a1392;
|
var JS_E_BOOLEAN_EXPECTED = 0x800a1392;
|
||||||
var JS_E_VBARRAY_EXPECTED = 0x800a1395;
|
var JS_E_VBARRAY_EXPECTED = 0x800a1395;
|
||||||
var JS_E_ENUMERATOR_EXPECTED = 0x800a1397;
|
var JS_E_ENUMERATOR_EXPECTED = 0x800a1397;
|
||||||
|
@ -2153,6 +2154,109 @@ sync_test("builtin_context", function() {
|
||||||
ok(obj.length === 1, "obj.length = " + obj.length);
|
ok(obj.length === 1, "obj.length = " + obj.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sync_test("globals override", function() {
|
||||||
|
wineprop = 1337; /* global */
|
||||||
|
ok(window.hasOwnProperty("wineprop"), "wineprop not a prop of window");
|
||||||
|
ok(window.wineprop === 1337, "window.wineprop = " + window.wineprop);
|
||||||
|
ok(wineprop === 1337, "wineprop = " + wineprop);
|
||||||
|
|
||||||
|
var i, desc, r = Object.defineProperty(window, "wineprop", { value: 42, configurable: true });
|
||||||
|
ok(r === window, "defineProperty(window.wineprop) returned " + r);
|
||||||
|
ok(window.hasOwnProperty("wineprop"), "wineprop not a prop of window after override");
|
||||||
|
ok(window.wineprop === 42, "window.wineprop after override = " + window.wineprop);
|
||||||
|
ok(wineprop === 42, "wineprop after override = " + wineprop);
|
||||||
|
|
||||||
|
r = (delete window.wineprop);
|
||||||
|
ok(r === true, "delete window.wineprop returned " + r);
|
||||||
|
ok(!("wineprop" in window), "wineprop in window after delete");
|
||||||
|
|
||||||
|
/* configurable */
|
||||||
|
var builtins = [
|
||||||
|
"ActiveXObject",
|
||||||
|
"Array",
|
||||||
|
"ArrayBuffer",
|
||||||
|
"Boolean",
|
||||||
|
"CollectGarbage",
|
||||||
|
"DataView",
|
||||||
|
"Date",
|
||||||
|
"decodeURI",
|
||||||
|
"decodeURIComponent",
|
||||||
|
"encodeURI",
|
||||||
|
"encodeURIComponent",
|
||||||
|
"Enumerator",
|
||||||
|
"Error",
|
||||||
|
"escape",
|
||||||
|
"EvalError",
|
||||||
|
"Function",
|
||||||
|
"isFinite",
|
||||||
|
"isNaN",
|
||||||
|
"JSON",
|
||||||
|
"Map",
|
||||||
|
"Math",
|
||||||
|
"Number",
|
||||||
|
"parseFloat",
|
||||||
|
"parseInt",
|
||||||
|
"RangeError",
|
||||||
|
"ReferenceError",
|
||||||
|
"RegExp",
|
||||||
|
"ScriptEngine",
|
||||||
|
"ScriptEngineBuildVersion",
|
||||||
|
"ScriptEngineMajorVersion",
|
||||||
|
"ScriptEngineMinorVersion",
|
||||||
|
"Set",
|
||||||
|
"String",
|
||||||
|
"SyntaxError",
|
||||||
|
"TypeError",
|
||||||
|
"unescape",
|
||||||
|
"URIError",
|
||||||
|
"VBArray",
|
||||||
|
"WeakMap"
|
||||||
|
];
|
||||||
|
for(i = 0; i < builtins.length; i++) {
|
||||||
|
desc = Object.getOwnPropertyDescriptor(window, builtins[i]);
|
||||||
|
ok(desc !== undefined, "getOwnPropertyDescriptor('" + builtins[i] + "' returned undefined");
|
||||||
|
ok(desc.configurable === true, builtins[i] + " not configurable");
|
||||||
|
ok(desc.enumerable === false, builtins[i] + " is enumerable");
|
||||||
|
ok(desc.writable === true, builtins[i] + " not writable");
|
||||||
|
|
||||||
|
r = Object.defineProperty(window, builtins[i], { value: 12, configurable: true, writable: true });
|
||||||
|
ok(r === window, "defineProperty('" + builtins[i] + "' returned " + r);
|
||||||
|
r = Object.getOwnPropertyDescriptor(window, builtins[i]);
|
||||||
|
ok(r !== undefined, "getOwnPropertyDescriptor('" + builtins[i] + "' after override returned undefined");
|
||||||
|
ok(r.value === 12, builtins[i] + " value = " + r.value);
|
||||||
|
|
||||||
|
r = eval(builtins[i]);
|
||||||
|
ok(r === window[builtins[i]], "Global " + builtins[i] + " does not match redefined window." + builtins[i]);
|
||||||
|
r = (delete window[builtins[i]]);
|
||||||
|
ok(r === true, "delete window." + builtins[i] + " returned " + r);
|
||||||
|
ok(!(builtins[i] in window), builtins[i] + " in window after delete");
|
||||||
|
try {
|
||||||
|
eval(builtins[i]);
|
||||||
|
ok(false, "expected exception retrieving global " + builtins[i] + " after delete.");
|
||||||
|
}catch(ex) {
|
||||||
|
r = ex.number >>> 0;
|
||||||
|
ok(r === JS_E_UNDEFINED_VARIABLE, "retrieving global " + builtins[i] + " after delete threw " + r);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = Object.defineProperty(window, builtins[i], desc);
|
||||||
|
ok(r === window, "defineProperty('" + builtins[i] + "' to restore returned " + r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non-configurable */
|
||||||
|
builtins = [
|
||||||
|
"undefined",
|
||||||
|
"Infinity",
|
||||||
|
"NaN"
|
||||||
|
];
|
||||||
|
for(i = 0; i < builtins.length; i++) {
|
||||||
|
desc = Object.getOwnPropertyDescriptor(window, builtins[i]);
|
||||||
|
ok(desc !== undefined, "getOwnPropertyDescriptor('" + builtins[i] + "' returned undefined");
|
||||||
|
ok(desc.configurable === false, builtins[i] + " is configurable");
|
||||||
|
ok(desc.enumerable === false, builtins[i] + " is enumerable");
|
||||||
|
ok(desc.writable === false, builtins[i] + " is writable");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
sync_test("host this", function() {
|
sync_test("host this", function() {
|
||||||
var tests = [ undefined, null, external.nullDisp, function() {}, [0], "foobar", true, 42, new Number(42), external.testHostContext(true), window, document ];
|
var tests = [ undefined, null, external.nullDisp, function() {}, [0], "foobar", true, 42, new Number(42), external.testHostContext(true), window, document ];
|
||||||
var i, obj = Object.create(Function.prototype);
|
var i, obj = Object.create(Function.prototype);
|
||||||
|
|
|
@ -687,7 +687,7 @@ static void invoke_system_apc( const union apc_call *call, union apc_result *res
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* server_select
|
* server_select
|
||||||
*/
|
*/
|
||||||
unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
unsigned int server_select( const union select_op *select_op, data_size_t size, UINT flags,
|
||||||
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc )
|
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc )
|
||||||
{
|
{
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
@ -740,7 +740,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
|
|
||||||
/* don't signal multiple times */
|
/* don't signal multiple times */
|
||||||
if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
|
if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
|
||||||
size = offsetof( select_op_t, signal_and_wait.signal );
|
size = offsetof( union select_op, signal_and_wait.signal );
|
||||||
}
|
}
|
||||||
pthread_sigmask( SIG_SETMASK, &old_set, NULL );
|
pthread_sigmask( SIG_SETMASK, &old_set, NULL );
|
||||||
if (signaled) break;
|
if (signaled) break;
|
||||||
|
@ -763,7 +763,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* server_wait
|
* server_wait
|
||||||
*/
|
*/
|
||||||
unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
unsigned int server_wait( const union select_op *select_op, data_size_t size, UINT flags,
|
||||||
const LARGE_INTEGER *timeout )
|
const LARGE_INTEGER *timeout )
|
||||||
{
|
{
|
||||||
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
||||||
|
|
|
@ -993,7 +993,7 @@ NTSTATUS WINAPI NtSetInformationDebugObject( HANDLE handle, DEBUGOBJECTINFOCLASS
|
||||||
|
|
||||||
|
|
||||||
/* convert the server event data to an NT state change; helper for NtWaitForDebugEvent */
|
/* convert the server event data to an NT state change; helper for NtWaitForDebugEvent */
|
||||||
static NTSTATUS event_data_to_state_change( const debug_event_t *data, DBGUI_WAIT_STATE_CHANGE *state )
|
static NTSTATUS event_data_to_state_change( const union debug_event_data *data, DBGUI_WAIT_STATE_CHANGE *state )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1098,7 +1098,7 @@ static NTSTATUS get_image_machine( HANDLE handle, USHORT *machine )
|
||||||
NTSTATUS WINAPI NtWaitForDebugEvent( HANDLE handle, BOOLEAN alertable, LARGE_INTEGER *timeout,
|
NTSTATUS WINAPI NtWaitForDebugEvent( HANDLE handle, BOOLEAN alertable, LARGE_INTEGER *timeout,
|
||||||
DBGUI_WAIT_STATE_CHANGE *state )
|
DBGUI_WAIT_STATE_CHANGE *state )
|
||||||
{
|
{
|
||||||
debug_event_t data;
|
union debug_event_data data;
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
BOOL wait = TRUE;
|
BOOL wait = TRUE;
|
||||||
|
|
||||||
|
@ -1572,7 +1572,7 @@ NTSTATUS WINAPI NtQueryTimer( HANDLE handle, TIMER_INFORMATION_CLASS class,
|
||||||
NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
|
NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
|
||||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||||
{
|
{
|
||||||
select_op_t select_op;
|
union select_op select_op;
|
||||||
UINT i, flags = SELECT_INTERRUPTIBLE;
|
UINT i, flags = SELECT_INTERRUPTIBLE;
|
||||||
|
|
||||||
if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
|
if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
|
||||||
|
@ -1580,7 +1580,7 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BO
|
||||||
if (alertable) flags |= SELECT_ALERTABLE;
|
if (alertable) flags |= SELECT_ALERTABLE;
|
||||||
select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL;
|
select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL;
|
||||||
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
|
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
|
||||||
return server_wait( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout );
|
return server_wait( &select_op, offsetof( union select_op, wait.handles[count] ), flags, timeout );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1599,7 +1599,7 @@ NTSTATUS WINAPI NtWaitForSingleObject( HANDLE handle, BOOLEAN alertable, const L
|
||||||
NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait,
|
NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait,
|
||||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||||
{
|
{
|
||||||
select_op_t select_op;
|
union select_op select_op;
|
||||||
UINT flags = SELECT_INTERRUPTIBLE;
|
UINT flags = SELECT_INTERRUPTIBLE;
|
||||||
|
|
||||||
if (!signal) return STATUS_INVALID_HANDLE;
|
if (!signal) return STATUS_INVALID_HANDLE;
|
||||||
|
@ -1883,7 +1883,7 @@ NTSTATUS WINAPI NtOpenKeyedEvent( HANDLE *handle, ACCESS_MASK access, const OBJE
|
||||||
NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key,
|
NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key,
|
||||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||||
{
|
{
|
||||||
select_op_t select_op;
|
union select_op select_op;
|
||||||
UINT flags = SELECT_INTERRUPTIBLE;
|
UINT flags = SELECT_INTERRUPTIBLE;
|
||||||
|
|
||||||
if (!handle) handle = keyed_event;
|
if (!handle) handle = keyed_event;
|
||||||
|
@ -1902,7 +1902,7 @@ NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key,
|
||||||
NTSTATUS WINAPI NtReleaseKeyedEvent( HANDLE handle, const void *key,
|
NTSTATUS WINAPI NtReleaseKeyedEvent( HANDLE handle, const void *key,
|
||||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||||
{
|
{
|
||||||
select_op_t select_op;
|
union select_op select_op;
|
||||||
UINT flags = SELECT_INTERRUPTIBLE;
|
UINT flags = SELECT_INTERRUPTIBLE;
|
||||||
|
|
||||||
if (!handle) handle = keyed_event;
|
if (!handle) handle = keyed_event;
|
||||||
|
|
|
@ -1512,7 +1512,7 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
|
||||||
DWORD i;
|
DWORD i;
|
||||||
obj_handle_t handle = 0;
|
obj_handle_t handle = 0;
|
||||||
client_ptr_t params[EXCEPTION_MAXIMUM_PARAMETERS];
|
client_ptr_t params[EXCEPTION_MAXIMUM_PARAMETERS];
|
||||||
select_op_t select_op;
|
union select_op select_op;
|
||||||
sigset_t old_set;
|
sigset_t old_set;
|
||||||
|
|
||||||
if (!peb->BeingDebugged) return 0; /* no debugger present */
|
if (!peb->BeingDebugged) return 0; /* no debugger present */
|
||||||
|
@ -1545,7 +1545,7 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
|
||||||
contexts_to_server( server_contexts, context );
|
contexts_to_server( server_contexts, context );
|
||||||
server_contexts[0].flags |= SERVER_CTX_EXEC_SPACE;
|
server_contexts[0].flags |= SERVER_CTX_EXEC_SPACE;
|
||||||
server_contexts[0].exec_space.space.space = exception ? EXEC_SPACE_EXCEPTION : EXEC_SPACE_SYSCALL;
|
server_contexts[0].exec_space.space.space = exception ? EXEC_SPACE_EXCEPTION : EXEC_SPACE_SYSCALL;
|
||||||
server_select( &select_op, offsetof( select_op_t, wait.handles[1] ), SELECT_INTERRUPTIBLE,
|
server_select( &select_op, offsetof( union select_op, wait.handles[1] ), SELECT_INTERRUPTIBLE,
|
||||||
TIMEOUT_INFINITE, server_contexts, NULL );
|
TIMEOUT_INFINITE, server_contexts, NULL );
|
||||||
|
|
||||||
SERVER_START_REQ( get_exception_status )
|
SERVER_START_REQ( get_exception_status )
|
||||||
|
|
|
@ -208,9 +208,9 @@ extern void start_server( BOOL debug );
|
||||||
extern unsigned int server_call_unlocked( void *req_ptr );
|
extern unsigned int server_call_unlocked( void *req_ptr );
|
||||||
extern void server_enter_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
extern void server_enter_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
||||||
extern void server_leave_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
extern void server_leave_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
||||||
extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
extern unsigned int server_select( const union select_op *select_op, data_size_t size, UINT flags,
|
||||||
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc );
|
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc );
|
||||||
extern unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
extern unsigned int server_wait( const union select_op *select_op, data_size_t size, UINT flags,
|
||||||
const LARGE_INTEGER *timeout );
|
const LARGE_INTEGER *timeout );
|
||||||
extern unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call,
|
extern unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call,
|
||||||
union apc_result *result );
|
union apc_result *result );
|
||||||
|
|
|
@ -506,7 +506,7 @@ static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp,
|
||||||
|
|
||||||
struct dispatch_context
|
struct dispatch_context
|
||||||
{
|
{
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
struct irp_data *irp_data;
|
struct irp_data *irp_data;
|
||||||
ULONG in_size;
|
ULONG in_size;
|
||||||
|
|
|
@ -4067,11 +4067,8 @@ static void test_SetForegroundWindow(HWND hwnd)
|
||||||
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||||
if (0) check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
|
if (0) check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
|
||||||
|
|
||||||
/* FIXME: these tests are failing because of a race condition
|
ok(GetActiveWindow() == hwnd2, "Expected active window %p, got %p.\n", hwnd2, GetActiveWindow());
|
||||||
* between internal focus state applied immediately and X11 focus
|
ok(GetFocus() == hwnd2, "Expected focus window %p, got %p.\n", hwnd2, GetFocus());
|
||||||
* message coming late */
|
|
||||||
todo_wine ok(GetActiveWindow() == hwnd2, "Expected active window %p, got %p.\n", hwnd2, GetActiveWindow());
|
|
||||||
todo_wine ok(GetFocus() == hwnd2, "Expected focus window %p, got %p.\n", hwnd2, GetFocus());
|
|
||||||
|
|
||||||
SetForegroundWindow(hwnd);
|
SetForegroundWindow(hwnd);
|
||||||
check_wnd_state(hwnd, hwnd, hwnd, 0);
|
check_wnd_state(hwnd, hwnd, hwnd, 0);
|
||||||
|
|
|
@ -2729,7 +2729,7 @@ int peek_message( MSG *msg, const struct peek_message_filter *filter )
|
||||||
{
|
{
|
||||||
NTSTATUS res;
|
NTSTATUS res;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
const message_data_t *msg_data = buffer;
|
const union message_data *msg_data = buffer;
|
||||||
UINT wake_mask, signal_bits, wake_bits, changed_bits, clear_bits = 0;
|
UINT wake_mask, signal_bits, wake_bits, changed_bits, clear_bits = 0;
|
||||||
|
|
||||||
/* use the same logic as in server/queue.c get_message */
|
/* use the same logic as in server/queue.c get_message */
|
||||||
|
@ -3320,7 +3320,7 @@ BOOL WINAPI NtUserGetMessage( MSG *msg, HWND hwnd, UINT first, UINT last )
|
||||||
static BOOL put_message_in_queue( const struct send_message_info *info, size_t *reply_size )
|
static BOOL put_message_in_queue( const struct send_message_info *info, size_t *reply_size )
|
||||||
{
|
{
|
||||||
struct packed_message data;
|
struct packed_message data;
|
||||||
message_data_t msg_data;
|
union message_data msg_data;
|
||||||
unsigned int res;
|
unsigned int res;
|
||||||
int i;
|
int i;
|
||||||
timeout_t timeout = TIMEOUT_INFINITE;
|
timeout_t timeout = TIMEOUT_INFINITE;
|
||||||
|
|
|
@ -275,10 +275,11 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
|
||||||
.serialnumber = {'0','0','0','0',0},
|
.serialnumber = {'0','0','0','0',0},
|
||||||
};
|
};
|
||||||
struct iohid_device *impl;
|
struct iohid_device *impl;
|
||||||
|
USAGE_AND_PAGE usages;
|
||||||
CFStringRef str;
|
CFStringRef str;
|
||||||
|
|
||||||
desc.usages.UsagePage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsagePageKey)));
|
usages.UsagePage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsagePageKey)));
|
||||||
desc.usages.Usage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsageKey)));
|
usages.Usage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsageKey)));
|
||||||
|
|
||||||
desc.vid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVendorIDKey)));
|
desc.vid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVendorIDKey)));
|
||||||
desc.pid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductIDKey)));
|
desc.pid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductIDKey)));
|
||||||
|
@ -289,8 +290,8 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
|
||||||
desc.is_bluetooth = !CFStringCompare(str, CFSTR(kIOHIDTransportBluetoothValue), 0) ||
|
desc.is_bluetooth = !CFStringCompare(str, CFSTR(kIOHIDTransportBluetoothValue), 0) ||
|
||||||
!CFStringCompare(str, CFSTR(kIOHIDTransportBluetoothLowEnergyValue), 0);
|
!CFStringCompare(str, CFSTR(kIOHIDTransportBluetoothLowEnergyValue), 0);
|
||||||
|
|
||||||
if (desc.usages.UsagePage != HID_USAGE_PAGE_GENERIC ||
|
if (usages.UsagePage != HID_USAGE_PAGE_GENERIC ||
|
||||||
!(desc.usages.Usage == HID_USAGE_GENERIC_JOYSTICK || desc.usages.Usage == HID_USAGE_GENERIC_GAMEPAD))
|
!(usages.Usage == HID_USAGE_GENERIC_JOYSTICK || usages.Usage == HID_USAGE_GENERIC_GAMEPAD))
|
||||||
{
|
{
|
||||||
/* winebus isn't currently meant to handle anything but these, and
|
/* winebus isn't currently meant to handle anything but these, and
|
||||||
* opening keyboards, mice, or the Touch Bar on older MacBooks triggers
|
* opening keyboards, mice, or the Touch Bar on older MacBooks triggers
|
||||||
|
|
|
@ -198,7 +198,7 @@ static void set_hat_value(struct unix_device *iface, int index, int value)
|
||||||
hid_device_set_hatswitch_y(iface, index, y);
|
hid_device_set_hatswitch_y(iface, index, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
static BOOL descriptor_add_haptic(struct sdl_device *impl, BOOL force)
|
||||||
{
|
{
|
||||||
USHORT i, count = 0;
|
USHORT i, count = 0;
|
||||||
USAGE usages[16];
|
USAGE usages[16];
|
||||||
|
@ -227,16 +227,16 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
||||||
if ((impl->effect_support & EFFECT_SUPPORT_PHYSICAL))
|
if ((impl->effect_support & EFFECT_SUPPORT_PHYSICAL))
|
||||||
{
|
{
|
||||||
/* SDL_HAPTIC_SQUARE doesn't exist */
|
/* SDL_HAPTIC_SQUARE doesn't exist */
|
||||||
if (impl->effect_support & SDL_HAPTIC_SINE) usages[count++] = PID_USAGE_ET_SINE;
|
if (force || (impl->effect_support & SDL_HAPTIC_SINE)) usages[count++] = PID_USAGE_ET_SINE;
|
||||||
if (impl->effect_support & SDL_HAPTIC_TRIANGLE) usages[count++] = PID_USAGE_ET_TRIANGLE;
|
if (force || (impl->effect_support & SDL_HAPTIC_TRIANGLE)) usages[count++] = PID_USAGE_ET_TRIANGLE;
|
||||||
if (impl->effect_support & SDL_HAPTIC_SAWTOOTHUP) usages[count++] = PID_USAGE_ET_SAWTOOTH_UP;
|
if (force || (impl->effect_support & SDL_HAPTIC_SAWTOOTHUP)) usages[count++] = PID_USAGE_ET_SAWTOOTH_UP;
|
||||||
if (impl->effect_support & SDL_HAPTIC_SAWTOOTHDOWN) usages[count++] = PID_USAGE_ET_SAWTOOTH_DOWN;
|
if (force || (impl->effect_support & SDL_HAPTIC_SAWTOOTHDOWN)) usages[count++] = PID_USAGE_ET_SAWTOOTH_DOWN;
|
||||||
if (impl->effect_support & SDL_HAPTIC_SPRING) usages[count++] = PID_USAGE_ET_SPRING;
|
if (force || (impl->effect_support & SDL_HAPTIC_SPRING)) usages[count++] = PID_USAGE_ET_SPRING;
|
||||||
if (impl->effect_support & SDL_HAPTIC_DAMPER) usages[count++] = PID_USAGE_ET_DAMPER;
|
if (force || (impl->effect_support & SDL_HAPTIC_DAMPER)) usages[count++] = PID_USAGE_ET_DAMPER;
|
||||||
if (impl->effect_support & SDL_HAPTIC_INERTIA) usages[count++] = PID_USAGE_ET_INERTIA;
|
if (force || (impl->effect_support & SDL_HAPTIC_INERTIA)) usages[count++] = PID_USAGE_ET_INERTIA;
|
||||||
if (impl->effect_support & SDL_HAPTIC_FRICTION) usages[count++] = PID_USAGE_ET_FRICTION;
|
if (force || (impl->effect_support & SDL_HAPTIC_FRICTION)) usages[count++] = PID_USAGE_ET_FRICTION;
|
||||||
if (impl->effect_support & SDL_HAPTIC_CONSTANT) usages[count++] = PID_USAGE_ET_CONSTANT_FORCE;
|
if (force || (impl->effect_support & SDL_HAPTIC_CONSTANT)) usages[count++] = PID_USAGE_ET_CONSTANT_FORCE;
|
||||||
if (impl->effect_support & SDL_HAPTIC_RAMP) usages[count++] = PID_USAGE_ET_RAMP;
|
if (force || (impl->effect_support & SDL_HAPTIC_RAMP)) usages[count++] = PID_USAGE_ET_RAMP;
|
||||||
|
|
||||||
if (!hid_device_add_physical(&impl->unix_device, usages, count))
|
if (!hid_device_add_physical(&impl->unix_device, usages, count))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -360,7 +360,7 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
|
||||||
if (!hid_device_end_input_report(iface))
|
if (!hid_device_end_input_report(iface))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if (!descriptor_add_haptic(impl))
|
if (!descriptor_add_haptic(impl, physical_usage.Usage == HID_USAGE_SIMULATION_AUTOMOBILE_SIMULATION_DEVICE))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if (!hid_device_end_report_descriptor(iface))
|
if (!hid_device_end_report_descriptor(iface))
|
||||||
|
@ -414,7 +414,7 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
|
||||||
if (!hid_device_end_input_report(iface))
|
if (!hid_device_end_input_report(iface))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if (!descriptor_add_haptic(impl))
|
if (!descriptor_add_haptic(impl, FALSE))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if (!hid_device_end_report_descriptor(iface))
|
if (!hid_device_end_report_descriptor(iface))
|
||||||
|
@ -443,17 +443,12 @@ static void sdl_device_destroy(struct unix_device *iface)
|
||||||
static NTSTATUS sdl_device_start(struct unix_device *iface)
|
static NTSTATUS sdl_device_start(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
struct sdl_device *impl = impl_from_unix_device(iface);
|
struct sdl_device *impl = impl_from_unix_device(iface);
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&sdl_cs);
|
pthread_mutex_lock(&sdl_cs);
|
||||||
|
impl->started = TRUE;
|
||||||
if (impl->sdl_controller) status = build_controller_report_descriptor(iface);
|
|
||||||
else status = build_joystick_report_descriptor(iface);
|
|
||||||
impl->started = !status;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&sdl_cs);
|
pthread_mutex_unlock(&sdl_cs);
|
||||||
|
|
||||||
return status;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdl_device_stop(struct unix_device *iface)
|
static void sdl_device_stop(struct unix_device *iface)
|
||||||
|
@ -595,7 +590,7 @@ static NTSTATUS sdl_device_physical_effect_control(struct unix_device *iface, BY
|
||||||
|
|
||||||
TRACE("iface %p, index %u, control %04x, iterations %u.\n", iface, index, control, iterations);
|
TRACE("iface %p, index %u, control %04x, iterations %u.\n", iface, index, control, iterations);
|
||||||
|
|
||||||
if (impl->effect_ids[index] < 0) return STATUS_UNSUCCESSFUL;
|
if (id < 0) return STATUS_SUCCESS;
|
||||||
|
|
||||||
switch (control)
|
switch (control)
|
||||||
{
|
{
|
||||||
|
@ -991,8 +986,6 @@ static void sdl_add_device(unsigned int index)
|
||||||
if (controller)
|
if (controller)
|
||||||
{
|
{
|
||||||
desc.is_gamepad = TRUE;
|
desc.is_gamepad = TRUE;
|
||||||
desc.usages.UsagePage = HID_USAGE_PAGE_GENERIC;
|
|
||||||
desc.usages.Usage = HID_USAGE_GENERIC_GAMEPAD;
|
|
||||||
axis_count = 6;
|
axis_count = 6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1000,12 +993,12 @@ static void sdl_add_device(unsigned int index)
|
||||||
int button_count = pSDL_JoystickNumButtons(joystick);
|
int button_count = pSDL_JoystickNumButtons(joystick);
|
||||||
axis_count = pSDL_JoystickNumAxes(joystick);
|
axis_count = pSDL_JoystickNumAxes(joystick);
|
||||||
desc.is_gamepad = (axis_count == 6 && button_count >= 14);
|
desc.is_gamepad = (axis_count == 6 && button_count >= 14);
|
||||||
desc.usages.UsagePage = HID_USAGE_PAGE_GENERIC;
|
|
||||||
desc.usages.Usage = HID_USAGE_GENERIC_JOYSTICK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (axis_offset = 0; axis_offset < axis_count; axis_offset += (options.split_controllers ? 6 : axis_count))
|
for (axis_offset = 0; axis_offset < axis_count; axis_offset += (options.split_controllers ? 6 : axis_count))
|
||||||
{
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!axis_offset) strcpy(buffer, product);
|
if (!axis_offset) strcpy(buffer, product);
|
||||||
else snprintf(buffer, ARRAY_SIZE(buffer), "%s %d", product, axis_offset / 6);
|
else snprintf(buffer, ARRAY_SIZE(buffer), "%s %d", product, axis_offset / 6);
|
||||||
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.product, ARRAY_SIZE(desc.product));
|
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.product, ARRAY_SIZE(desc.product));
|
||||||
|
@ -1019,6 +1012,15 @@ static void sdl_add_device(unsigned int index)
|
||||||
impl->id = id;
|
impl->id = id;
|
||||||
impl->axis_offset = axis_offset;
|
impl->axis_offset = axis_offset;
|
||||||
|
|
||||||
|
if (impl->sdl_controller) status = build_controller_report_descriptor(&impl->unix_device);
|
||||||
|
else status = build_joystick_report_descriptor(&impl->unix_device);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
list_remove(&impl->unix_device.entry);
|
||||||
|
impl->unix_device.vtbl->destroy(&impl->unix_device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bus_event_queue_device_created(&event_queue, &impl->unix_device, &desc);
|
bus_event_queue_device_created(&event_queue, &impl->unix_device, &desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -728,12 +728,6 @@ static void lnxev_device_destroy(struct unix_device *iface)
|
||||||
|
|
||||||
static NTSTATUS lnxev_device_start(struct unix_device *iface)
|
static NTSTATUS lnxev_device_start(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
|
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
if ((status = build_report_descriptor(iface, impl->base.udev_device)))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&udev_cs);
|
pthread_mutex_lock(&udev_cs);
|
||||||
start_polling_device(iface);
|
start_polling_device(iface);
|
||||||
pthread_mutex_unlock(&udev_cs);
|
pthread_mutex_unlock(&udev_cs);
|
||||||
|
@ -1254,7 +1248,6 @@ static void udev_add_device(struct udev_device *dev, int fd)
|
||||||
#ifdef HAS_PROPER_INPUT_HEADER
|
#ifdef HAS_PROPER_INPUT_HEADER
|
||||||
else if (!strcmp(subsystem, "input"))
|
else if (!strcmp(subsystem, "input"))
|
||||||
{
|
{
|
||||||
const USAGE_AND_PAGE device_usage = *what_am_I(dev, fd);
|
|
||||||
static const WCHAR evdev[] = {'e','v','d','e','v',0};
|
static const WCHAR evdev[] = {'e','v','d','e','v',0};
|
||||||
struct input_id device_id = {0};
|
struct input_id device_id = {0};
|
||||||
char buffer[MAX_PATH];
|
char buffer[MAX_PATH];
|
||||||
|
@ -1275,8 +1268,6 @@ static void udev_add_device(struct udev_device *dev, int fd)
|
||||||
|
|
||||||
if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(buffer)), buffer) >= 0)
|
if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(buffer)), buffer) >= 0)
|
||||||
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
|
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
|
||||||
|
|
||||||
desc.usages = device_usage;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1321,6 +1312,13 @@ static void udev_add_device(struct udev_device *dev, int fd)
|
||||||
strcpy(impl->devnode, devnode);
|
strcpy(impl->devnode, devnode);
|
||||||
impl->device_fd = fd;
|
impl->device_fd = fd;
|
||||||
|
|
||||||
|
if (build_report_descriptor(&impl->unix_device, impl->udev_device))
|
||||||
|
{
|
||||||
|
list_remove(&impl->unix_device.entry);
|
||||||
|
impl->unix_device.vtbl->destroy(&impl->unix_device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bus_event_queue_device_created(&event_queue, &impl->unix_device, &desc);
|
bus_event_queue_device_created(&event_queue, &impl->unix_device, &desc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -417,7 +417,7 @@ static DWORD check_bus_option(const WCHAR *option, DWORD default_value)
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL is_hidraw_enabled(WORD vid, WORD pid, const USAGE_AND_PAGE *usages)
|
static BOOL is_hidraw_enabled(WORD vid, WORD pid, const USAGE_AND_PAGE *usages, UINT buttons)
|
||||||
{
|
{
|
||||||
char buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[1024])];
|
char buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[1024])];
|
||||||
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
|
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
|
||||||
|
@ -436,6 +436,48 @@ static BOOL is_hidraw_enabled(WORD vid, WORD pid, const USAGE_AND_PAGE *usages)
|
||||||
if (is_dualshock4_gamepad(vid, pid)) prefer_hidraw = TRUE;
|
if (is_dualshock4_gamepad(vid, pid)) prefer_hidraw = TRUE;
|
||||||
if (is_dualsense_gamepad(vid, pid)) prefer_hidraw = TRUE;
|
if (is_dualsense_gamepad(vid, pid)) prefer_hidraw = TRUE;
|
||||||
|
|
||||||
|
switch (vid)
|
||||||
|
{
|
||||||
|
case 0x044f:
|
||||||
|
if (pid == 0xb679) prefer_hidraw = TRUE; /* ThrustMaster T-Rudder */
|
||||||
|
if (pid == 0xb687) prefer_hidraw = TRUE; /* ThrustMaster TWCS Throttle */
|
||||||
|
if (pid == 0xb10a) prefer_hidraw = TRUE; /* ThrustMaster T.16000M Joystick */
|
||||||
|
break;
|
||||||
|
case 0x16d0:
|
||||||
|
if (pid == 0x0d61) prefer_hidraw = TRUE; /* Simucube 2 Sport */
|
||||||
|
if (pid == 0x0d60) prefer_hidraw = TRUE; /* Simucube 2 Pro */
|
||||||
|
if (pid == 0x0d5f) prefer_hidraw = TRUE; /* Simucube 2 Ultimate */
|
||||||
|
if (pid == 0x0d5a) prefer_hidraw = TRUE; /* Simucube 1 */
|
||||||
|
break;
|
||||||
|
case 0x0eb7:
|
||||||
|
if (pid == 0x183b) prefer_hidraw = TRUE; /* Fanatec ClubSport Pedals v3 */
|
||||||
|
if (pid == 0x1839) prefer_hidraw = TRUE; /* Fanatec ClubSport Pedals v1/v2 */
|
||||||
|
break;
|
||||||
|
case 0x231d:
|
||||||
|
/* comes with 128 buttons in the default configuration */
|
||||||
|
if (buttons == 128) prefer_hidraw = TRUE;
|
||||||
|
/* if customized, less than 128 buttons may be shown, decide by PID */
|
||||||
|
if (pid == 0x0200) prefer_hidraw = TRUE; /* VKBsim Gladiator EVO Right Grip */
|
||||||
|
if (pid == 0x0201) prefer_hidraw = TRUE; /* VKBsim Gladiator EVO Left Grip */
|
||||||
|
if (pid == 0x0126) prefer_hidraw = TRUE; /* VKB-Sim Space Gunfighter */
|
||||||
|
if (pid == 0x0127) prefer_hidraw = TRUE; /* VKB-Sim Space Gunfighter L */
|
||||||
|
break;
|
||||||
|
case 0x3344:
|
||||||
|
/* comes with 31 buttons in the default configuration, or 128 max */
|
||||||
|
if ((buttons == 31) || (buttons == 128)) prefer_hidraw = TRUE;
|
||||||
|
/* users may have configured button limits, usually 32/50/64 */
|
||||||
|
if ((buttons == 32) || (buttons == 50) || (buttons == 64)) prefer_hidraw = TRUE;
|
||||||
|
/* if customized, arbitrary amount of buttons may be shown, decide by PID */
|
||||||
|
if (pid == 0x412f) prefer_hidraw = TRUE; /* Virpil Constellation ALPHA-R */
|
||||||
|
if (pid == 0x812c) prefer_hidraw = TRUE; /* Virpil Constellation ALPHA-L */
|
||||||
|
break;
|
||||||
|
case 0x03eb:
|
||||||
|
/* users may have configured button limits, usually 32/50/64 */
|
||||||
|
if ((buttons == 32) || (buttons == 50) || (buttons == 64)) prefer_hidraw = TRUE;
|
||||||
|
if (pid == 0x2055) prefer_hidraw = TRUE; /* ATMEL/VIRPIL/200325 VPC Throttle MT-50 CM2 */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
RtlInitUnicodeString(&str, L"EnableHidraw");
|
RtlInitUnicodeString(&str, L"EnableHidraw");
|
||||||
if (!NtQueryValueKey(driver_key, &str, KeyValuePartialInformation, info,
|
if (!NtQueryValueKey(driver_key, &str, KeyValuePartialInformation, info,
|
||||||
sizeof(buffer) - sizeof(WCHAR), &size))
|
sizeof(buffer) - sizeof(WCHAR), &size))
|
||||||
|
@ -684,22 +726,41 @@ static NTSTATUS get_device_descriptors(UINT64 unix_device, BYTE **report_desc, U
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static USAGE_AND_PAGE get_hidraw_device_usages(UINT64 unix_device)
|
static USAGE_AND_PAGE get_device_usages(UINT64 unix_device, UINT *buttons)
|
||||||
{
|
{
|
||||||
HIDP_DEVICE_DESC device_desc;
|
HIDP_DEVICE_DESC device_desc;
|
||||||
USAGE_AND_PAGE usages = {0};
|
USAGE_AND_PAGE usages = {0};
|
||||||
UINT report_desc_length;
|
UINT i, count = 0, report_desc_length;
|
||||||
|
HIDP_BUTTON_CAPS *button_caps;
|
||||||
BYTE *report_desc;
|
BYTE *report_desc;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
HIDP_CAPS caps;
|
||||||
|
|
||||||
if (!(status = get_device_descriptors(unix_device, &report_desc, &report_desc_length, &device_desc)))
|
if (!(status = get_device_descriptors(unix_device, &report_desc, &report_desc_length, &device_desc)))
|
||||||
{
|
{
|
||||||
|
PHIDP_PREPARSED_DATA preparsed = device_desc.CollectionDesc[0].PreparsedData;
|
||||||
usages.UsagePage = device_desc.CollectionDesc[0].UsagePage;
|
usages.UsagePage = device_desc.CollectionDesc[0].UsagePage;
|
||||||
usages.Usage = device_desc.CollectionDesc[0].Usage;
|
usages.Usage = device_desc.CollectionDesc[0].Usage;
|
||||||
|
|
||||||
|
if ((status = HidP_GetCaps(preparsed, &caps)) == HIDP_STATUS_SUCCESS &&
|
||||||
|
(button_caps = malloc(sizeof(*button_caps) * caps.NumberInputButtonCaps)))
|
||||||
|
{
|
||||||
|
status = HidP_GetButtonCaps(HidP_Input, button_caps, &caps.NumberInputButtonCaps, preparsed);
|
||||||
|
if (status != HIDP_STATUS_SUCCESS) WARN("HidP_GetButtonCaps returned %#lx\n", status);
|
||||||
|
else for (i = 0; i < caps.NumberInputButtonCaps; i++)
|
||||||
|
{
|
||||||
|
if (button_caps[i].UsagePage != HID_USAGE_PAGE_BUTTON) continue;
|
||||||
|
if (button_caps[i].IsRange) count = max(count, button_caps[i].Range.UsageMax);
|
||||||
|
else count = max(count, button_caps[i].NotRange.Usage);
|
||||||
|
}
|
||||||
|
free(button_caps);
|
||||||
|
}
|
||||||
|
|
||||||
HidP_FreeCollectionDescription(&device_desc);
|
HidP_FreeCollectionDescription(&device_desc);
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, report_desc);
|
RtlFreeHeap(GetProcessHeap(), 0, report_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*buttons = count;
|
||||||
return usages;
|
return usages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,18 +810,21 @@ static DWORD CALLBACK bus_main_thread(void *args)
|
||||||
case BUS_EVENT_TYPE_DEVICE_CREATED:
|
case BUS_EVENT_TYPE_DEVICE_CREATED:
|
||||||
{
|
{
|
||||||
struct device_desc desc = event->device_created.desc;
|
struct device_desc desc = event->device_created.desc;
|
||||||
if (desc.is_hidraw && !desc.usages.UsagePage) desc.usages = get_hidraw_device_usages(event->device);
|
USAGE_AND_PAGE usages;
|
||||||
if (!desc.is_hidraw != !is_hidraw_enabled(desc.vid, desc.pid, &desc.usages))
|
UINT buttons;
|
||||||
|
|
||||||
|
usages = get_device_usages(event->device, &buttons);
|
||||||
|
if (!desc.is_hidraw != !is_hidraw_enabled(desc.vid, desc.pid, &usages, buttons))
|
||||||
{
|
{
|
||||||
struct device_remove_params params = {.device = event->device};
|
struct device_remove_params params = {.device = event->device};
|
||||||
WARN("ignoring %shidraw device %04x:%04x with usages %04x:%04x\n", desc.is_hidraw ? "" : "non-",
|
WARN("ignoring %shidraw device %04x:%04x with usages %04x:%04x\n", desc.is_hidraw ? "" : "non-",
|
||||||
desc.vid, desc.pid, desc.usages.UsagePage, desc.usages.Usage);
|
desc.vid, desc.pid, usages.UsagePage, usages.Usage);
|
||||||
winebus_call(device_remove, ¶ms);
|
winebus_call(device_remove, ¶ms);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("creating %shidraw device %04x:%04x with usages %04x:%04x\n", desc.is_hidraw ? "" : "non-",
|
TRACE("creating %shidraw device %04x:%04x with usages %04x:%04x\n", desc.is_hidraw ? "" : "non-",
|
||||||
desc.vid, desc.pid, desc.usages.UsagePage, desc.usages.Usage);
|
desc.vid, desc.pid, usages.UsagePage, usages.Usage);
|
||||||
|
|
||||||
device = bus_create_hid_device(&event->device_created.desc, event->device);
|
device = bus_create_hid_device(&event->device_created.desc, event->device);
|
||||||
if (device) IoInvalidateDeviceRelations(bus_pdo, BusRelations);
|
if (device) IoInvalidateDeviceRelations(bus_pdo, BusRelations);
|
||||||
|
|
|
@ -49,14 +49,6 @@ static void mouse_destroy(struct unix_device *iface)
|
||||||
|
|
||||||
static NTSTATUS mouse_start(struct unix_device *iface)
|
static NTSTATUS mouse_start(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_MOUSE};
|
|
||||||
if (!hid_device_begin_report_descriptor(iface, &device_usage))
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, 3))
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
if (!hid_device_end_report_descriptor(iface))
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +115,21 @@ static const struct device_desc mouse_device_desc =
|
||||||
|
|
||||||
static NTSTATUS mouse_device_create(void *args)
|
static NTSTATUS mouse_device_create(void *args)
|
||||||
{
|
{
|
||||||
|
const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_MOUSE};
|
||||||
struct device_create_params *params = args;
|
struct device_create_params *params = args;
|
||||||
|
struct unix_device *iface;
|
||||||
|
|
||||||
|
if (!(iface = hid_device_create(&mouse_vtbl, sizeof(struct mouse_device))))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
if (!hid_device_begin_report_descriptor(iface, &device_usage))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, 3))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
if (!hid_device_end_report_descriptor(iface))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
params->desc = mouse_device_desc;
|
params->desc = mouse_device_desc;
|
||||||
params->device = (UINT_PTR)hid_device_create(&mouse_vtbl, sizeof(struct mouse_device));
|
params->device = (UINT_PTR)iface;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,14 +144,6 @@ static void keyboard_destroy(struct unix_device *iface)
|
||||||
|
|
||||||
static NTSTATUS keyboard_start(struct unix_device *iface)
|
static NTSTATUS keyboard_start(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_KEYBOARD};
|
|
||||||
if (!hid_device_begin_report_descriptor(iface, &device_usage))
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_KEYBOARD, 0, 101))
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
if (!hid_device_end_report_descriptor(iface))
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,9 +210,21 @@ static const struct device_desc keyboard_device_desc =
|
||||||
|
|
||||||
static NTSTATUS keyboard_device_create(void *args)
|
static NTSTATUS keyboard_device_create(void *args)
|
||||||
{
|
{
|
||||||
|
const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_KEYBOARD};
|
||||||
struct device_create_params *params = args;
|
struct device_create_params *params = args;
|
||||||
|
struct unix_device *iface;
|
||||||
|
|
||||||
|
if (!(iface = hid_device_create(&keyboard_vtbl, sizeof(struct keyboard_device))))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
if (!hid_device_begin_report_descriptor(iface, &device_usage))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_KEYBOARD, 0, 101))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
if (!hid_device_end_report_descriptor(iface))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
params->desc = keyboard_device_desc;
|
params->desc = keyboard_device_desc;
|
||||||
params->device = (UINT_PTR)hid_device_create(&keyboard_vtbl, sizeof(struct keyboard_device));
|
params->device = (UINT_PTR)iface;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ struct device_desc
|
||||||
UINT version;
|
UINT version;
|
||||||
UINT input;
|
UINT input;
|
||||||
UINT uid;
|
UINT uid;
|
||||||
USAGE_AND_PAGE usages;
|
|
||||||
BOOL is_gamepad;
|
BOOL is_gamepad;
|
||||||
BOOL is_hidraw;
|
BOOL is_hidraw;
|
||||||
BOOL is_bluetooth;
|
BOOL is_bluetooth;
|
||||||
|
@ -151,8 +150,8 @@ enum unix_funcs
|
||||||
static inline const char *debugstr_device_desc(struct device_desc *desc)
|
static inline const char *debugstr_device_desc(struct device_desc *desc)
|
||||||
{
|
{
|
||||||
if (!desc) return "(null)";
|
if (!desc) return "(null)";
|
||||||
return wine_dbg_sprintf("{vid %04x, pid %04x, version %04x, input %d, uid %08x, usage %04x:%04x, is_gamepad %u, is_hidraw %u, is_bluetooth %u}",
|
return wine_dbg_sprintf("{vid %04x, pid %04x, version %04x, input %d, uid %08x, is_gamepad %u, is_hidraw %u, is_bluetooth %u}",
|
||||||
desc->vid, desc->pid, desc->version, desc->input, desc->uid, desc->usages.UsagePage, desc->usages.Usage,
|
desc->vid, desc->pid, desc->version, desc->input, desc->uid,
|
||||||
desc->is_gamepad, desc->is_hidraw, desc->is_bluetooth);
|
desc->is_gamepad, desc->is_hidraw, desc->is_bluetooth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,7 @@ struct media_source
|
||||||
UINT64 duration;
|
UINT64 duration;
|
||||||
|
|
||||||
IMFStreamDescriptor **descriptors;
|
IMFStreamDescriptor **descriptors;
|
||||||
|
wg_parser_stream_t *wg_streams;
|
||||||
struct media_stream **streams;
|
struct media_stream **streams;
|
||||||
ULONG stream_count;
|
ULONG stream_count;
|
||||||
|
|
||||||
|
@ -542,6 +543,8 @@ static void flush_token_queue(struct media_stream *stream, BOOL send)
|
||||||
IUnknown *op;
|
IUnknown *op;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
assert(stream->media_source);
|
||||||
|
|
||||||
if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_REQUEST_SAMPLE, &op)))
|
if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_REQUEST_SAMPLE, &op)))
|
||||||
{
|
{
|
||||||
struct source_async_command *command = impl_from_async_command_IUnknown(op);
|
struct source_async_command *command = impl_from_async_command_IUnknown(op);
|
||||||
|
@ -582,6 +585,9 @@ static HRESULT media_stream_start(struct media_stream *stream, BOOL active, BOOL
|
||||||
&GUID_NULL, S_OK, position);
|
&GUID_NULL, S_OK, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT media_stream_create(IMFMediaSource *source, IMFStreamDescriptor *descriptor,
|
||||||
|
wg_parser_stream_t wg_stream, struct media_stream **out);
|
||||||
|
|
||||||
static HRESULT media_source_start(struct media_source *source, IMFPresentationDescriptor *descriptor,
|
static HRESULT media_source_start(struct media_source *source, IMFPresentationDescriptor *descriptor,
|
||||||
GUID *format, PROPVARIANT *position)
|
GUID *format, PROPVARIANT *position)
|
||||||
{
|
{
|
||||||
|
@ -596,6 +602,26 @@ static HRESULT media_source_start(struct media_source *source, IMFPresentationDe
|
||||||
if (source->state == SOURCE_SHUTDOWN)
|
if (source->state == SOURCE_SHUTDOWN)
|
||||||
return MF_E_SHUTDOWN;
|
return MF_E_SHUTDOWN;
|
||||||
|
|
||||||
|
/* if starting for the first time, create the streams */
|
||||||
|
if (source->stream_count && !source->streams[0])
|
||||||
|
{
|
||||||
|
assert(source->state == SOURCE_STOPPED);
|
||||||
|
|
||||||
|
for (i = 0; i < source->stream_count; ++i)
|
||||||
|
{
|
||||||
|
wg_parser_stream_t wg_stream = source->wg_streams[i];
|
||||||
|
struct media_stream *stream;
|
||||||
|
|
||||||
|
if (FAILED(hr = media_stream_create(&source->IMFMediaSource_iface,
|
||||||
|
source->descriptors[i], wg_stream, &stream)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
source->streams[i] = stream;
|
||||||
|
}
|
||||||
|
free(source->wg_streams);
|
||||||
|
source->wg_streams = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* seek to beginning on stop->play */
|
/* seek to beginning on stop->play */
|
||||||
if (source->state == SOURCE_STOPPED && position->vt == VT_EMPTY)
|
if (source->state == SOURCE_STOPPED && position->vt == VT_EMPTY)
|
||||||
{
|
{
|
||||||
|
@ -961,8 +987,12 @@ static ULONG WINAPI media_stream_Release(IMFMediaStream *iface)
|
||||||
TRACE("%p, refcount %lu.\n", iface, ref);
|
TRACE("%p, refcount %lu.\n", iface, ref);
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
|
{
|
||||||
|
if (stream->media_source)
|
||||||
{
|
{
|
||||||
IMFMediaSource_Release(stream->media_source);
|
IMFMediaSource_Release(stream->media_source);
|
||||||
|
stream->media_source = NULL;
|
||||||
|
}
|
||||||
IMFStreamDescriptor_Release(stream->descriptor);
|
IMFStreamDescriptor_Release(stream->descriptor);
|
||||||
IMFMediaEventQueue_Release(stream->event_queue);
|
IMFMediaEventQueue_Release(stream->event_queue);
|
||||||
flush_token_queue(stream, FALSE);
|
flush_token_queue(stream, FALSE);
|
||||||
|
@ -1012,13 +1042,24 @@ static HRESULT WINAPI media_stream_QueueEvent(IMFMediaStream *iface, MediaEventT
|
||||||
static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMediaSource **out)
|
static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMediaSource **out)
|
||||||
{
|
{
|
||||||
struct media_stream *stream = impl_from_IMFMediaStream(iface);
|
struct media_stream *stream = impl_from_IMFMediaStream(iface);
|
||||||
struct media_source *source = impl_from_IMFMediaSource(stream->media_source);
|
IMFMediaSource *source_iface = stream->media_source;
|
||||||
|
struct media_source *source;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
TRACE("%p, %p.\n", iface, out);
|
TRACE("%p, %p.\n", iface, out);
|
||||||
|
|
||||||
|
if (!source_iface)
|
||||||
|
return MF_E_SHUTDOWN;
|
||||||
|
|
||||||
|
source = impl_from_IMFMediaSource(source_iface);
|
||||||
|
|
||||||
EnterCriticalSection(&source->cs);
|
EnterCriticalSection(&source->cs);
|
||||||
|
|
||||||
|
/* A shutdown state can occur here if shutdown was in progress in another
|
||||||
|
* thread when we got the source pointer above. The source object must
|
||||||
|
* still exist and we cannot reasonably handle a case where the source has
|
||||||
|
* been destroyed at this point in a get/request method without introducing
|
||||||
|
* a critical section into the stream object. */
|
||||||
if (source->state == SOURCE_SHUTDOWN)
|
if (source->state == SOURCE_SHUTDOWN)
|
||||||
hr = MF_E_SHUTDOWN;
|
hr = MF_E_SHUTDOWN;
|
||||||
else
|
else
|
||||||
|
@ -1035,11 +1076,17 @@ static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMedi
|
||||||
static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IMFStreamDescriptor **descriptor)
|
static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IMFStreamDescriptor **descriptor)
|
||||||
{
|
{
|
||||||
struct media_stream *stream = impl_from_IMFMediaStream(iface);
|
struct media_stream *stream = impl_from_IMFMediaStream(iface);
|
||||||
struct media_source *source = impl_from_IMFMediaSource(stream->media_source);
|
IMFMediaSource *source_iface = stream->media_source;
|
||||||
|
struct media_source *source;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
TRACE("%p, %p.\n", iface, descriptor);
|
TRACE("%p, %p.\n", iface, descriptor);
|
||||||
|
|
||||||
|
if (!source_iface)
|
||||||
|
return MF_E_SHUTDOWN;
|
||||||
|
|
||||||
|
source = impl_from_IMFMediaSource(source_iface);
|
||||||
|
|
||||||
EnterCriticalSection(&source->cs);
|
EnterCriticalSection(&source->cs);
|
||||||
|
|
||||||
if (source->state == SOURCE_SHUTDOWN)
|
if (source->state == SOURCE_SHUTDOWN)
|
||||||
|
@ -1058,12 +1105,18 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM
|
||||||
static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token)
|
static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token)
|
||||||
{
|
{
|
||||||
struct media_stream *stream = impl_from_IMFMediaStream(iface);
|
struct media_stream *stream = impl_from_IMFMediaStream(iface);
|
||||||
struct media_source *source = impl_from_IMFMediaSource(stream->media_source);
|
IMFMediaSource *source_iface = stream->media_source;
|
||||||
|
struct media_source *source;
|
||||||
IUnknown *op;
|
IUnknown *op;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("%p, %p.\n", iface, token);
|
TRACE("%p, %p.\n", iface, token);
|
||||||
|
|
||||||
|
if (!source_iface)
|
||||||
|
return MF_E_SHUTDOWN;
|
||||||
|
|
||||||
|
source = impl_from_IMFMediaSource(source_iface);
|
||||||
|
|
||||||
EnterCriticalSection(&source->cs);
|
EnterCriticalSection(&source->cs);
|
||||||
|
|
||||||
if (source->state == SOURCE_SHUTDOWN)
|
if (source->state == SOURCE_SHUTDOWN)
|
||||||
|
@ -1569,10 +1622,18 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
|
||||||
{
|
{
|
||||||
struct media_stream *stream = source->streams[source->stream_count];
|
struct media_stream *stream = source->streams[source->stream_count];
|
||||||
IMFStreamDescriptor_Release(source->descriptors[source->stream_count]);
|
IMFStreamDescriptor_Release(source->descriptors[source->stream_count]);
|
||||||
|
if (stream)
|
||||||
|
{
|
||||||
IMFMediaEventQueue_Shutdown(stream->event_queue);
|
IMFMediaEventQueue_Shutdown(stream->event_queue);
|
||||||
|
/* Media Foundation documentation says circular references such as
|
||||||
|
* those between the source and its streams should be released here. */
|
||||||
|
IMFMediaSource_Release(stream->media_source);
|
||||||
|
stream->media_source = NULL;
|
||||||
IMFMediaStream_Release(&stream->IMFMediaStream_iface);
|
IMFMediaStream_Release(&stream->IMFMediaStream_iface);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free(source->descriptors);
|
free(source->descriptors);
|
||||||
|
free(source->wg_streams);
|
||||||
free(source->streams);
|
free(source->streams);
|
||||||
|
|
||||||
LeaveCriticalSection(&source->cs);
|
LeaveCriticalSection(&source->cs);
|
||||||
|
@ -1606,13 +1667,12 @@ static void media_source_init_descriptors(struct media_source *source)
|
||||||
|
|
||||||
for (i = 0; i < source->stream_count; i++)
|
for (i = 0; i < source->stream_count; i++)
|
||||||
{
|
{
|
||||||
struct media_stream *stream = source->streams[i];
|
IMFStreamDescriptor *descriptor = source->descriptors[i];
|
||||||
IMFStreamDescriptor *descriptor = stream->descriptor;
|
|
||||||
|
|
||||||
if (FAILED(hr = stream_descriptor_set_tag(descriptor, stream->wg_stream,
|
if (FAILED(hr = stream_descriptor_set_tag(descriptor, source->wg_streams[i],
|
||||||
&MF_SD_LANGUAGE, WG_PARSER_TAG_LANGUAGE)))
|
&MF_SD_LANGUAGE, WG_PARSER_TAG_LANGUAGE)))
|
||||||
WARN("Failed to set stream descriptor language, hr %#lx\n", hr);
|
WARN("Failed to set stream descriptor language, hr %#lx\n", hr);
|
||||||
if (FAILED(hr = stream_descriptor_set_tag(descriptor, stream->wg_stream,
|
if (FAILED(hr = stream_descriptor_set_tag(descriptor, source->wg_streams[i],
|
||||||
&MF_SD_STREAM_NAME, WG_PARSER_TAG_NAME)))
|
&MF_SD_STREAM_NAME, WG_PARSER_TAG_NAME)))
|
||||||
WARN("Failed to set stream descriptor name, hr %#lx\n", hr);
|
WARN("Failed to set stream descriptor name, hr %#lx\n", hr);
|
||||||
}
|
}
|
||||||
|
@ -1665,6 +1725,7 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc
|
||||||
stream_count = wg_parser_get_stream_count(parser);
|
stream_count = wg_parser_get_stream_count(parser);
|
||||||
|
|
||||||
if (!(object->descriptors = calloc(stream_count, sizeof(*object->descriptors)))
|
if (!(object->descriptors = calloc(stream_count, sizeof(*object->descriptors)))
|
||||||
|
|| !(object->wg_streams = calloc(stream_count, sizeof(*object->wg_streams)))
|
||||||
|| !(object->streams = calloc(stream_count, sizeof(*object->streams))))
|
|| !(object->streams = calloc(stream_count, sizeof(*object->streams))))
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
|
@ -1673,24 +1734,23 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc
|
||||||
|
|
||||||
for (i = 0; i < stream_count; ++i)
|
for (i = 0; i < stream_count; ++i)
|
||||||
{
|
{
|
||||||
|
/* It is valid to create and release a MF source without ever calling Start() and
|
||||||
|
* Shutdown(). Each MF stream holds a reference to the source, and that ref should
|
||||||
|
* be released in Shutdown(), so streams are not created here.
|
||||||
|
* The wg streams are needed now to get the format and duration. Their buffer is
|
||||||
|
* freed in Start(). */
|
||||||
wg_parser_stream_t wg_stream = wg_parser_get_stream(object->wg_parser, i);
|
wg_parser_stream_t wg_stream = wg_parser_get_stream(object->wg_parser, i);
|
||||||
IMFStreamDescriptor *descriptor;
|
IMFStreamDescriptor *descriptor;
|
||||||
struct media_stream *stream;
|
|
||||||
struct wg_format format;
|
struct wg_format format;
|
||||||
|
|
||||||
wg_parser_stream_get_current_format(wg_stream, &format);
|
wg_parser_stream_get_current_format(wg_stream, &format);
|
||||||
if (FAILED(hr = stream_descriptor_create(i, &format, &descriptor)))
|
if (FAILED(hr = stream_descriptor_create(i, &format, &descriptor)))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (FAILED(hr = media_stream_create(&object->IMFMediaSource_iface, descriptor, wg_stream, &stream)))
|
|
||||||
{
|
|
||||||
IMFStreamDescriptor_Release(descriptor);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
object->duration = max(object->duration, wg_parser_stream_get_duration(wg_stream));
|
object->duration = max(object->duration, wg_parser_stream_get_duration(wg_stream));
|
||||||
IMFStreamDescriptor_AddRef(descriptor);
|
IMFStreamDescriptor_AddRef(descriptor);
|
||||||
object->descriptors[i] = descriptor;
|
object->descriptors[i] = descriptor;
|
||||||
object->streams[i] = stream;
|
object->wg_streams[i] = wg_stream;
|
||||||
object->stream_count++;
|
object->stream_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1704,13 +1764,12 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc
|
||||||
fail:
|
fail:
|
||||||
WARN("Failed to construct MFMediaSource, hr %#lx.\n", hr);
|
WARN("Failed to construct MFMediaSource, hr %#lx.\n", hr);
|
||||||
|
|
||||||
while (object->streams && object->stream_count--)
|
while (object->descriptors && object->stream_count--)
|
||||||
{
|
{
|
||||||
struct media_stream *stream = object->streams[object->stream_count];
|
|
||||||
IMFStreamDescriptor_Release(object->descriptors[object->stream_count]);
|
IMFStreamDescriptor_Release(object->descriptors[object->stream_count]);
|
||||||
IMFMediaStream_Release(&stream->IMFMediaStream_iface);
|
|
||||||
}
|
}
|
||||||
free(object->descriptors);
|
free(object->descriptors);
|
||||||
|
free(object->wg_streams);
|
||||||
free(object->streams);
|
free(object->streams);
|
||||||
|
|
||||||
if (stream_count != UINT_MAX)
|
if (stream_count != UINT_MAX)
|
||||||
|
|
|
@ -73,7 +73,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height )
|
||||||
|
|
||||||
/* Create window */
|
/* Create window */
|
||||||
win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | EnterWindowMask |
|
win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | EnterWindowMask |
|
||||||
PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask;
|
PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
|
||||||
|
PropertyChangeMask;
|
||||||
win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
|
win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
|
||||||
|
|
||||||
if (default_visual.visual != DefaultVisual( display, DefaultScreen(display) ))
|
if (default_visual.visual != DefaultVisual( display, DefaultScreen(display) ))
|
||||||
|
|
|
@ -1104,7 +1104,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
||||||
struct x11drv_win_data *data;
|
struct x11drv_win_data *data;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
POINT pos = {event->x, event->y};
|
POINT pos = {event->x, event->y};
|
||||||
UINT config_cmd;
|
UINT config_cmd, state_cmd;
|
||||||
|
|
||||||
if (!hwnd) return FALSE;
|
if (!hwnd) return FALSE;
|
||||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||||
|
@ -1123,17 +1123,24 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
||||||
SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height );
|
SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height );
|
||||||
window_configure_notify( data, event->serial, &rect );
|
window_configure_notify( data, event->serial, &rect );
|
||||||
|
|
||||||
|
state_cmd = window_update_client_state( data );
|
||||||
config_cmd = window_update_client_config( data );
|
config_cmd = window_update_client_config( data );
|
||||||
rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||||
release_win_data( data );
|
release_win_data( data );
|
||||||
|
|
||||||
|
if (state_cmd)
|
||||||
|
{
|
||||||
|
if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd );
|
||||||
|
send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
if (config_cmd)
|
if (config_cmd)
|
||||||
{
|
{
|
||||||
if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE );
|
if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE );
|
||||||
else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 );
|
else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!config_cmd;
|
return config_cmd || state_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1193,36 +1200,19 @@ static int get_window_xembed_info( Display *display, Window window )
|
||||||
*
|
*
|
||||||
* Handle a PropertyNotify for WM_STATE.
|
* Handle a PropertyNotify for WM_STATE.
|
||||||
*/
|
*/
|
||||||
static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window )
|
static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event )
|
||||||
{
|
{
|
||||||
struct x11drv_win_data *data;
|
struct x11drv_win_data *data;
|
||||||
UINT value = 0, state_cmd = 0;
|
UINT value = 0, state_cmd = 0, config_cmd = 0;
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
if (!(data = get_win_data( hwnd ))) return;
|
if (!(data = get_win_data( hwnd ))) return;
|
||||||
if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window );
|
if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window );
|
||||||
if (update_window) window_wm_state_notify( data, event->serial, value );
|
window_wm_state_notify( data, event->serial, value );
|
||||||
|
|
||||||
switch(event->state)
|
state_cmd = window_update_client_state( data );
|
||||||
{
|
config_cmd = window_update_client_config( data );
|
||||||
case PropertyDelete:
|
rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||||
TRACE( "%p/%lx: WM_STATE deleted from %d\n", data->hwnd, data->whole_window, data->wm_state );
|
|
||||||
data->wm_state = WithdrawnState;
|
|
||||||
break;
|
|
||||||
case PropertyNewValue:
|
|
||||||
{
|
|
||||||
int old_state = data->wm_state;
|
|
||||||
int new_state = get_window_wm_state( event->display, data->whole_window );
|
|
||||||
if (new_state != -1 && new_state != data->wm_state)
|
|
||||||
{
|
|
||||||
TRACE( "%p/%lx: new WM_STATE %d from %d\n",
|
|
||||||
data->hwnd, data->whole_window, new_state, old_state );
|
|
||||||
data->wm_state = new_state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update_window) state_cmd = window_update_client_state( data );
|
|
||||||
|
|
||||||
release_win_data( data );
|
release_win_data( data );
|
||||||
|
|
||||||
|
@ -1231,6 +1221,12 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
|
||||||
if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd );
|
if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd );
|
||||||
send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 );
|
send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config_cmd)
|
||||||
|
{
|
||||||
|
if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE );
|
||||||
|
else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event )
|
static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event )
|
||||||
|
@ -1247,12 +1243,30 @@ static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event )
|
||||||
static void handle_net_wm_state_notify( HWND hwnd, XPropertyEvent *event )
|
static void handle_net_wm_state_notify( HWND hwnd, XPropertyEvent *event )
|
||||||
{
|
{
|
||||||
struct x11drv_win_data *data;
|
struct x11drv_win_data *data;
|
||||||
UINT value = 0;
|
UINT value = 0, state_cmd = 0, config_cmd = 0;
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
if (!(data = get_win_data( hwnd ))) return;
|
if (!(data = get_win_data( hwnd ))) return;
|
||||||
if (event->state == PropertyNewValue) value = get_window_net_wm_state( event->display, event->window );
|
if (event->state == PropertyNewValue) value = get_window_net_wm_state( event->display, event->window );
|
||||||
window_net_wm_state_notify( data, event->serial, value );
|
window_net_wm_state_notify( data, event->serial, value );
|
||||||
|
|
||||||
|
state_cmd = window_update_client_state( data );
|
||||||
|
config_cmd = window_update_client_config( data );
|
||||||
|
rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||||
|
|
||||||
release_win_data( data );
|
release_win_data( data );
|
||||||
|
|
||||||
|
if (state_cmd)
|
||||||
|
{
|
||||||
|
if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd );
|
||||||
|
send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_cmd)
|
||||||
|
{
|
||||||
|
if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE );
|
||||||
|
else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1263,79 +1277,13 @@ static BOOL X11DRV_PropertyNotify( HWND hwnd, XEvent *xev )
|
||||||
XPropertyEvent *event = &xev->xproperty;
|
XPropertyEvent *event = &xev->xproperty;
|
||||||
|
|
||||||
if (!hwnd) return FALSE;
|
if (!hwnd) return FALSE;
|
||||||
if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( hwnd, event, TRUE );
|
if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( hwnd, event );
|
||||||
if (event->atom == x11drv_atom(_XEMBED_INFO)) handle_xembed_info_notify( hwnd, event );
|
if (event->atom == x11drv_atom(_XEMBED_INFO)) handle_xembed_info_notify( hwnd, event );
|
||||||
if (event->atom == x11drv_atom(_NET_WM_STATE)) handle_net_wm_state_notify( hwnd, event );
|
if (event->atom == x11drv_atom(_NET_WM_STATE)) handle_net_wm_state_notify( hwnd, event );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* event filter to wait for a WM_STATE change notification on a window */
|
|
||||||
static Bool is_wm_state_notify( Display *display, XEvent *event, XPointer arg )
|
|
||||||
{
|
|
||||||
if (event->xany.window != (Window)arg) return 0;
|
|
||||||
return (event->type == DestroyNotify ||
|
|
||||||
(event->type == PropertyNotify && event->xproperty.atom == x11drv_atom(WM_STATE)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* wait_for_withdrawn_state
|
|
||||||
*/
|
|
||||||
void wait_for_withdrawn_state( HWND hwnd, BOOL set )
|
|
||||||
{
|
|
||||||
Display *display = thread_display();
|
|
||||||
struct x11drv_win_data *data;
|
|
||||||
DWORD end = NtGetTickCount() + 2000;
|
|
||||||
|
|
||||||
TRACE( "waiting for window %p to become %swithdrawn\n", hwnd, set ? "" : "not " );
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
XEvent event;
|
|
||||||
Window window;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (!(data = get_win_data( hwnd ))) break;
|
|
||||||
if (!data->managed || data->embedded || data->display != display) break;
|
|
||||||
if (!(window = data->whole_window)) break;
|
|
||||||
if (!data->mapped == !set)
|
|
||||||
{
|
|
||||||
TRACE( "window %p/%lx now %smapped\n", hwnd, window, data->mapped ? "" : "un" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((data->wm_state == WithdrawnState) != !set)
|
|
||||||
{
|
|
||||||
TRACE( "window %p/%lx state now %d\n", hwnd, window, data->wm_state );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
release_win_data( data );
|
|
||||||
|
|
||||||
while (XCheckIfEvent( display, &event, is_wm_state_notify, (char *)window ))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
if (XFilterEvent( &event, None )) continue; /* filtered, ignore it */
|
|
||||||
if (event.type == DestroyNotify) call_event_handler( display, &event );
|
|
||||||
else handle_wm_state_notify( hwnd, &event.xproperty, FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!count)
|
|
||||||
{
|
|
||||||
struct pollfd pfd;
|
|
||||||
int timeout = end - NtGetTickCount();
|
|
||||||
|
|
||||||
pfd.fd = ConnectionNumber(display);
|
|
||||||
pfd.events = POLLIN;
|
|
||||||
if (timeout <= 0 || poll( &pfd, 1, timeout ) != 1)
|
|
||||||
{
|
|
||||||
FIXME( "window %p/%lx wait timed out\n", hwnd, window );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
release_win_data( data );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
* SetFocus (X11DRV.@)
|
* SetFocus (X11DRV.@)
|
||||||
*
|
*
|
||||||
|
|
|
@ -1213,7 +1213,10 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
|
||||||
{
|
{
|
||||||
UINT i, count, old_state = data->pending_state.net_wm_state;
|
UINT i, count, old_state = data->pending_state.net_wm_state;
|
||||||
|
|
||||||
|
data->desired_state.net_wm_state = new_state;
|
||||||
if (!data->whole_window) return; /* no window, nothing to update */
|
if (!data->whole_window) return; /* no window, nothing to update */
|
||||||
|
if (data->wm_state_serial) return; /* another WM_STATE update is pending, wait for it to complete */
|
||||||
|
/* we ignore and override previous _NET_WM_STATE update requests */
|
||||||
if (old_state == new_state) return; /* states are the same, nothing to update */
|
if (old_state == new_state) return; /* states are the same, nothing to update */
|
||||||
|
|
||||||
if (data->pending_state.wm_state == IconicState) return; /* window is iconic, don't update its state now */
|
if (data->pending_state.wm_state == IconicState) return; /* window is iconic, don't update its state now */
|
||||||
|
@ -1267,6 +1270,8 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
|
||||||
SubstructureRedirectMask | SubstructureNotifyMask, &xev );
|
SubstructureRedirectMask | SubstructureNotifyMask, &xev );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XFlush( data->display );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void window_set_config( struct x11drv_win_data *data, const RECT *new_rect, BOOL above )
|
static void window_set_config( struct x11drv_win_data *data, const RECT *new_rect, BOOL above )
|
||||||
|
@ -1275,6 +1280,7 @@ static void window_set_config( struct x11drv_win_data *data, const RECT *new_rec
|
||||||
const RECT *old_rect = &data->pending_state.rect;
|
const RECT *old_rect = &data->pending_state.rect;
|
||||||
XWindowChanges changes;
|
XWindowChanges changes;
|
||||||
|
|
||||||
|
data->desired_state.rect = *new_rect;
|
||||||
if (!data->whole_window) return; /* no window, nothing to update */
|
if (!data->whole_window) return; /* no window, nothing to update */
|
||||||
if (EqualRect( old_rect, new_rect )) return; /* rects are the same, nothing to update */
|
if (EqualRect( old_rect, new_rect )) return; /* rects are the same, nothing to update */
|
||||||
|
|
||||||
|
@ -1328,7 +1334,7 @@ static void update_net_wm_states( struct x11drv_win_data *data )
|
||||||
|
|
||||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||||
if (style & WS_MINIMIZE)
|
if (style & WS_MINIMIZE)
|
||||||
new_state |= data->pending_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
|
new_state |= data->desired_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
|
||||||
if (data->is_fullscreen)
|
if (data->is_fullscreen)
|
||||||
{
|
{
|
||||||
if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
|
if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
|
||||||
|
@ -1412,7 +1418,9 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state )
|
||||||
{
|
{
|
||||||
UINT old_state = data->pending_state.wm_state;
|
UINT old_state = data->pending_state.wm_state;
|
||||||
|
|
||||||
|
data->desired_state.wm_state = new_state;
|
||||||
if (!data->whole_window) return; /* no window, nothing to update */
|
if (!data->whole_window) return; /* no window, nothing to update */
|
||||||
|
if (data->wm_state_serial) return; /* another WM_STATE update is pending, wait for it to complete */
|
||||||
if (old_state == new_state) return; /* states are the same, nothing to update */
|
if (old_state == new_state) return; /* states are the same, nothing to update */
|
||||||
|
|
||||||
data->pending_state.wm_state = new_state;
|
data->pending_state.wm_state = new_state;
|
||||||
|
@ -1438,6 +1446,11 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state )
|
||||||
if (!data->embedded) XIconifyWindow( data->display, data->whole_window, data->vis.screen );
|
if (!data->embedded) XIconifyWindow( data->display, data->whole_window, data->vis.screen );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* override redirect windows won't receive WM_STATE property changes */
|
||||||
|
if (!data->managed) data->wm_state_serial = 0;
|
||||||
|
|
||||||
|
XFlush( data->display );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1449,7 +1462,6 @@ static void map_window( HWND hwnd, DWORD new_style )
|
||||||
struct x11drv_win_data *data;
|
struct x11drv_win_data *data;
|
||||||
|
|
||||||
make_owner_managed( hwnd );
|
make_owner_managed( hwnd );
|
||||||
wait_for_withdrawn_state( hwnd, TRUE );
|
|
||||||
|
|
||||||
if (!(data = get_win_data( hwnd ))) return;
|
if (!(data = get_win_data( hwnd ))) return;
|
||||||
|
|
||||||
|
@ -1463,7 +1475,6 @@ static void map_window( HWND hwnd, DWORD new_style )
|
||||||
sync_window_style( data );
|
sync_window_style( data );
|
||||||
|
|
||||||
window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState );
|
window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState );
|
||||||
XFlush( data->display );
|
|
||||||
|
|
||||||
data->mapped = TRUE;
|
data->mapped = TRUE;
|
||||||
data->iconic = (new_style & WS_MINIMIZE) != 0;
|
data->iconic = (new_style & WS_MINIMIZE) != 0;
|
||||||
|
@ -1480,8 +1491,6 @@ static void unmap_window( HWND hwnd )
|
||||||
{
|
{
|
||||||
struct x11drv_win_data *data;
|
struct x11drv_win_data *data;
|
||||||
|
|
||||||
wait_for_withdrawn_state( hwnd, FALSE );
|
|
||||||
|
|
||||||
if (!(data = get_win_data( hwnd ))) return;
|
if (!(data = get_win_data( hwnd ))) return;
|
||||||
|
|
||||||
if (data->mapped)
|
if (data->mapped)
|
||||||
|
@ -1500,6 +1509,10 @@ UINT window_update_client_state( struct x11drv_win_data *data )
|
||||||
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
|
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
|
||||||
if (!data->mapped) return 0; /* ignore state changes on invisible windows */
|
if (!data->mapped) return 0; /* ignore state changes on invisible windows */
|
||||||
|
|
||||||
|
if (data->wm_state_serial) return 0; /* another WM_STATE update is pending, wait for it to complete */
|
||||||
|
if (data->net_wm_state_serial) return 0; /* another _NET_WM_STATE update is pending, wait for it to complete */
|
||||||
|
if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
|
||||||
|
|
||||||
if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */
|
if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */
|
||||||
{
|
{
|
||||||
data->iconic = FALSE;
|
data->iconic = FALSE;
|
||||||
|
@ -1540,6 +1553,8 @@ UINT window_update_client_config( struct x11drv_win_data *data )
|
||||||
if (!data->mapped) return 0; /* ignore config changes on invisible windows */
|
if (!data->mapped) return 0; /* ignore config changes on invisible windows */
|
||||||
if (data->iconic) return 0; /* ignore config changes on minimized windows */
|
if (data->iconic) return 0; /* ignore config changes on minimized windows */
|
||||||
|
|
||||||
|
if (data->wm_state_serial) return 0; /* another WM_STATE update is pending, wait for it to complete */
|
||||||
|
if (data->net_wm_state_serial) return 0; /* another _NET_WM_STATE update is pending, wait for it to complete */
|
||||||
if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
|
if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
|
||||||
|
|
||||||
if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
||||||
|
@ -1572,7 +1587,7 @@ UINT window_update_client_config( struct x11drv_win_data *data )
|
||||||
|
|
||||||
void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value )
|
void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value )
|
||||||
{
|
{
|
||||||
UINT *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state;
|
UINT *desired = &data->desired_state.wm_state, *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state;
|
||||||
unsigned long *expect_serial = &data->wm_state_serial;
|
unsigned long *expect_serial = &data->wm_state_serial;
|
||||||
const char *reason = NULL, *expected, *received;
|
const char *reason = NULL, *expected, *received;
|
||||||
|
|
||||||
|
@ -1597,16 +1612,20 @@ void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected );
|
WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected );
|
||||||
*pending = value; /* avoid requesting the same state again */
|
*desired = *pending = value; /* avoid requesting the same state again */
|
||||||
}
|
}
|
||||||
|
|
||||||
*current = value;
|
*current = value;
|
||||||
*expect_serial = 0;
|
*expect_serial = 0;
|
||||||
|
|
||||||
|
/* send any pending changes from the desired state */
|
||||||
|
window_set_wm_state( data, data->desired_state.wm_state );
|
||||||
|
window_set_net_wm_state( data, data->desired_state.net_wm_state );
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value )
|
void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value )
|
||||||
{
|
{
|
||||||
UINT *pending = &data->pending_state.net_wm_state, *current = &data->current_state.net_wm_state;
|
UINT *desired = &data->desired_state.net_wm_state, *pending = &data->pending_state.net_wm_state, *current = &data->current_state.net_wm_state;
|
||||||
unsigned long *expect_serial = &data->net_wm_state_serial;
|
unsigned long *expect_serial = &data->net_wm_state_serial;
|
||||||
const char *reason = NULL, *expected, *received;
|
const char *reason = NULL, *expected, *received;
|
||||||
|
|
||||||
|
@ -1629,16 +1648,20 @@ void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long ser
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected );
|
WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected );
|
||||||
*pending = value; /* avoid requesting the same state again */
|
*desired = *pending = value; /* avoid requesting the same state again */
|
||||||
}
|
}
|
||||||
|
|
||||||
*current = value;
|
*current = value;
|
||||||
*expect_serial = 0;
|
*expect_serial = 0;
|
||||||
|
|
||||||
|
/* send any pending changes from the desired state */
|
||||||
|
window_set_wm_state( data, data->desired_state.wm_state );
|
||||||
|
window_set_net_wm_state( data, data->desired_state.net_wm_state );
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *value )
|
void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *value )
|
||||||
{
|
{
|
||||||
RECT *pending = &data->pending_state.rect, *current = &data->current_state.rect;
|
RECT *desired = &data->desired_state.rect, *pending = &data->pending_state.rect, *current = &data->current_state.rect;
|
||||||
unsigned long *expect_serial = &data->configure_serial;
|
unsigned long *expect_serial = &data->configure_serial;
|
||||||
const char *reason = NULL, *expected, *received;
|
const char *reason = NULL, *expected, *received;
|
||||||
|
|
||||||
|
@ -1661,7 +1684,7 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected );
|
WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected );
|
||||||
*pending = *value; /* avoid requesting the same state again */
|
*desired = *pending = *value; /* avoid requesting the same state again */
|
||||||
}
|
}
|
||||||
|
|
||||||
*current = *value;
|
*current = *value;
|
||||||
|
@ -1674,7 +1697,7 @@ BOOL window_has_pending_wm_state( HWND hwnd, UINT state )
|
||||||
BOOL pending;
|
BOOL pending;
|
||||||
|
|
||||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||||
if (state != -1 && data->pending_state.wm_state != state) pending = FALSE;
|
if (state != -1 && data->desired_state.wm_state != state) pending = FALSE;
|
||||||
else pending = !!data->wm_state_serial;
|
else pending = !!data->wm_state_serial;
|
||||||
release_win_data( data );
|
release_win_data( data );
|
||||||
|
|
||||||
|
@ -2044,6 +2067,7 @@ static void create_whole_window( struct x11drv_win_data *data )
|
||||||
if (!data->whole_window) goto done;
|
if (!data->whole_window) goto done;
|
||||||
SetRect( &data->current_state.rect, pos.x, pos.y, pos.x + cx, pos.y + cy );
|
SetRect( &data->current_state.rect, pos.x, pos.y, pos.x + cx, pos.y + cy );
|
||||||
data->pending_state.rect = data->current_state.rect;
|
data->pending_state.rect = data->current_state.rect;
|
||||||
|
data->desired_state.rect = data->current_state.rect;
|
||||||
|
|
||||||
x11drv_xinput2_enable( data->display, data->whole_window );
|
x11drv_xinput2_enable( data->display, data->whole_window );
|
||||||
set_initial_wm_hints( data->display, data->whole_window );
|
set_initial_wm_hints( data->display, data->whole_window );
|
||||||
|
@ -2098,9 +2122,9 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
|
||||||
if (data->whole_colormap) XFreeColormap( data->display, data->whole_colormap );
|
if (data->whole_colormap) XFreeColormap( data->display, data->whole_colormap );
|
||||||
data->whole_window = data->client_window = 0;
|
data->whole_window = data->client_window = 0;
|
||||||
data->whole_colormap = 0;
|
data->whole_colormap = 0;
|
||||||
data->wm_state = WithdrawnState;
|
|
||||||
data->mapped = FALSE;
|
data->mapped = FALSE;
|
||||||
|
|
||||||
|
memset( &data->desired_state, 0, sizeof(data->desired_state) );
|
||||||
memset( &data->pending_state, 0, sizeof(data->pending_state) );
|
memset( &data->pending_state, 0, sizeof(data->pending_state) );
|
||||||
memset( &data->current_state, 0, sizeof(data->current_state) );
|
memset( &data->current_state, 0, sizeof(data->current_state) );
|
||||||
data->wm_state_serial = 0;
|
data->wm_state_serial = 0;
|
||||||
|
|
|
@ -633,13 +633,13 @@ struct x11drv_win_data
|
||||||
UINT net_wm_fullscreen_monitors_set : 1; /* is _NET_WM_FULLSCREEN_MONITORS set */
|
UINT net_wm_fullscreen_monitors_set : 1; /* is _NET_WM_FULLSCREEN_MONITORS set */
|
||||||
UINT is_fullscreen : 1; /* is the window visible rect fullscreen */
|
UINT is_fullscreen : 1; /* is the window visible rect fullscreen */
|
||||||
UINT parent_invalid : 1; /* is the parent host window possibly invalid */
|
UINT parent_invalid : 1; /* is the parent host window possibly invalid */
|
||||||
int wm_state; /* current value of the WM_STATE property */
|
|
||||||
Window embedder; /* window id of embedder */
|
Window embedder; /* window id of embedder */
|
||||||
Pixmap icon_pixmap;
|
Pixmap icon_pixmap;
|
||||||
Pixmap icon_mask;
|
Pixmap icon_mask;
|
||||||
unsigned long *icon_bits;
|
unsigned long *icon_bits;
|
||||||
unsigned int icon_size;
|
unsigned int icon_size;
|
||||||
|
|
||||||
|
struct window_state desired_state; /* window state tracking the desired / win32 state */
|
||||||
struct window_state pending_state; /* window state tracking the pending / requested state */
|
struct window_state pending_state; /* window state tracking the pending / requested state */
|
||||||
struct window_state current_state; /* window state tracking the current X11 state */
|
struct window_state current_state; /* window state tracking the current X11 state */
|
||||||
unsigned long wm_state_serial; /* serial of last pending WM_STATE request */
|
unsigned long wm_state_serial; /* serial of last pending WM_STATE request */
|
||||||
|
@ -665,7 +665,6 @@ extern void window_configure_notify( struct x11drv_win_data *data, unsigned long
|
||||||
extern UINT window_update_client_state( struct x11drv_win_data *data );
|
extern UINT window_update_client_state( struct x11drv_win_data *data );
|
||||||
extern UINT window_update_client_config( struct x11drv_win_data *data );
|
extern UINT window_update_client_config( struct x11drv_win_data *data );
|
||||||
|
|
||||||
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set );
|
|
||||||
extern Window init_clip_window(void);
|
extern Window init_clip_window(void);
|
||||||
extern void update_user_time( Time time );
|
extern void update_user_time( Time time );
|
||||||
extern UINT get_window_net_wm_state( Display *display, Window window );
|
extern UINT get_window_net_wm_state( Display *display, Window window );
|
||||||
|
|
|
@ -1240,3 +1240,211 @@ HRESULT WINAPI RoResolveNamespace(HSTRING name, HSTRING windowsMetaDataDir,
|
||||||
|
|
||||||
return RO_E_METADATA_NAME_NOT_FOUND;
|
return RO_E_METADATA_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct parse_type_context
|
||||||
|
{
|
||||||
|
DWORD allocated_parts_count;
|
||||||
|
DWORD parts_count;
|
||||||
|
HSTRING *parts;
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT add_part(struct parse_type_context *context, const WCHAR *part, size_t length)
|
||||||
|
{
|
||||||
|
DWORD new_parts_count;
|
||||||
|
HSTRING *new_parts;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (context->parts_count == context->allocated_parts_count)
|
||||||
|
{
|
||||||
|
new_parts_count = context->allocated_parts_count ? context->allocated_parts_count * 2 : 4;
|
||||||
|
new_parts = CoTaskMemRealloc(context->parts, new_parts_count * sizeof(*context->parts));
|
||||||
|
if (!new_parts)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
context->allocated_parts_count = new_parts_count;
|
||||||
|
context->parts = new_parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = WindowsCreateString(part, length, &context->parts[context->parts_count])))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
context->parts_count++;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT parse_part(struct parse_type_context *context, const WCHAR *input, unsigned int length)
|
||||||
|
{
|
||||||
|
const WCHAR *start, *end, *ptr;
|
||||||
|
|
||||||
|
start = input;
|
||||||
|
end = start + length;
|
||||||
|
|
||||||
|
/* Remove leading spaces */
|
||||||
|
while (start < end && *start == ' ')
|
||||||
|
start++;
|
||||||
|
|
||||||
|
/* Remove trailing spaces */
|
||||||
|
while (end - 1 >= start && end[-1] == ' ')
|
||||||
|
end--;
|
||||||
|
|
||||||
|
/* Only contains spaces */
|
||||||
|
if (start == end)
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
|
||||||
|
/* Has spaces in the middle */
|
||||||
|
for (ptr = start; ptr < end; ptr++)
|
||||||
|
{
|
||||||
|
if (*ptr == ' ')
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return add_part(context, start, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT parse_type(struct parse_type_context *context, const WCHAR *input, unsigned int length)
|
||||||
|
{
|
||||||
|
unsigned int i, parameter_count, nested_level;
|
||||||
|
const WCHAR *start, *end, *part_start, *ptr;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
start = input;
|
||||||
|
end = start + length;
|
||||||
|
part_start = start;
|
||||||
|
ptr = start;
|
||||||
|
|
||||||
|
/* Read until the end of input or '`' or '<' or '>' or ',' */
|
||||||
|
while (ptr < end && *ptr != '`' && *ptr != '<' && *ptr != '>' && *ptr != ',')
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
/* If the type name has '`' and there are characters before '`' */
|
||||||
|
if (ptr > start && ptr < end && *ptr == '`')
|
||||||
|
{
|
||||||
|
/* Move past the '`' */
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
/* Read the number of type parameters, expecting '1' to '9' */
|
||||||
|
if (!(ptr < end && *ptr >= '1' && *ptr <= '9'))
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
parameter_count = *ptr - '0';
|
||||||
|
|
||||||
|
/* Move past the number of type parameters, expecting '<' */
|
||||||
|
ptr++;
|
||||||
|
if (!(ptr < end && *ptr == '<'))
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
|
||||||
|
/* Add the name of parameterized interface, e.g., the "interface`1" in "interface`1<parameter>" */
|
||||||
|
if (FAILED(hr = parse_part(context, part_start, ptr - part_start)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
/* Move past the '<' */
|
||||||
|
ptr++;
|
||||||
|
nested_level = 1;
|
||||||
|
|
||||||
|
/* Read parameters inside brackets, e.g., the "p1" and "p2" in "interface`2<p1, p2>" */
|
||||||
|
for (i = 0; i < parameter_count; i++)
|
||||||
|
{
|
||||||
|
/* Read a new parameter */
|
||||||
|
part_start = ptr;
|
||||||
|
|
||||||
|
/* Read until ','. The comma must be at the same nested bracket level */
|
||||||
|
while (ptr < end)
|
||||||
|
{
|
||||||
|
if (*ptr == '<')
|
||||||
|
{
|
||||||
|
nested_level++;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
else if (*ptr == '>')
|
||||||
|
{
|
||||||
|
/* The last parameter before '>' */
|
||||||
|
if (i == parameter_count - 1 && nested_level == 1)
|
||||||
|
{
|
||||||
|
if (FAILED(hr = parse_type(context, part_start, ptr - part_start)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
nested_level--;
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
/* Finish reading all parameters */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_level--;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
else if (*ptr == ',' && nested_level == 1)
|
||||||
|
{
|
||||||
|
/* Parse the parameter, which can be another parameterized type */
|
||||||
|
if (FAILED(hr = parse_type(context, part_start, ptr - part_start)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
/* Move past the ',' */
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
/* Finish reading one parameter */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mismatching brackets or not enough parameters */
|
||||||
|
if (nested_level != 0 || i != parameter_count)
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
|
||||||
|
/* The remaining characters must be spaces */
|
||||||
|
while (ptr < end)
|
||||||
|
{
|
||||||
|
if (*ptr++ != ' ')
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
/* Contain invalid '`', '<', '>' or ',' */
|
||||||
|
else if (ptr != end)
|
||||||
|
{
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
}
|
||||||
|
/* Non-parameterized */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return parse_part(context, part_start, ptr - part_start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI RoParseTypeName(HSTRING type_name, DWORD *parts_count, HSTRING **parts)
|
||||||
|
{
|
||||||
|
struct parse_type_context context = {0};
|
||||||
|
const WCHAR *input;
|
||||||
|
unsigned int i;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE("%s %p %p.\n", debugstr_hstring(type_name), parts_count, parts);
|
||||||
|
|
||||||
|
/* Empty string */
|
||||||
|
if (!WindowsGetStringLen(type_name))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
input = WindowsGetStringRawBuffer(type_name, NULL);
|
||||||
|
/* The string has a leading space */
|
||||||
|
if (input[0] == ' ')
|
||||||
|
return RO_E_METADATA_INVALID_TYPE_FORMAT;
|
||||||
|
|
||||||
|
*parts_count = 0;
|
||||||
|
*parts = NULL;
|
||||||
|
if (FAILED(hr = parse_type(&context, input, wcslen(input))))
|
||||||
|
{
|
||||||
|
for (i = 0; i < context.parts_count; i++)
|
||||||
|
WindowsDeleteString(context.parts[i]);
|
||||||
|
CoTaskMemFree(context.parts);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*parts_count = context.parts_count;
|
||||||
|
*parts = context.parts;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -814,11 +814,159 @@ static void test_RoResolveNamespace(void)
|
||||||
RoUninitialize();
|
RoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_RoParseTypeName(void)
|
||||||
|
{
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
const WCHAR *type_name;
|
||||||
|
HRESULT hr;
|
||||||
|
DWORD parts_count;
|
||||||
|
const WCHAR *parts[16];
|
||||||
|
}
|
||||||
|
tests[] =
|
||||||
|
{
|
||||||
|
/* Invalid type names */
|
||||||
|
{L"", E_INVALIDARG},
|
||||||
|
{L" ", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"`", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"<", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L">", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L",", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"<>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"`<>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a b", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a,b", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"1<>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L" a", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L" a ", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a<", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a<>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`<>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`1<>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a<b>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`<b> ", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"`1<b>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L" a`1<b>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`1<b>c", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`1<b,>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`2<b, <c, d>>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`10<b1, b2, b3, b4, b5, b6, b7, b8, b9, b10>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`0xa<b1, b2, b3, b4, b5, b6, b7, b8, b9, b10>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
{L"a`a<b1, b2, b3, b4, b5, b6, b7, b8, b9, b10>", RO_E_METADATA_INVALID_TYPE_FORMAT},
|
||||||
|
/* Valid type names */
|
||||||
|
{L"1", S_OK, 1, {L"1"}},
|
||||||
|
{L"a", S_OK, 1, {L"a"}},
|
||||||
|
{L"-", S_OK, 1, {L"-"}},
|
||||||
|
{L"a ", S_OK, 1, {L"a"}},
|
||||||
|
{L"0`1<b>", S_OK, 2, {L"0`1", L"b"}},
|
||||||
|
{L"a`1<b>", S_OK, 2, {L"a`1", L"b"}},
|
||||||
|
{L"a`1<b> ", S_OK, 2, {L"a`1", L"b"}},
|
||||||
|
{L"a`1<b >", S_OK, 2, {L"a`1", L"b"}},
|
||||||
|
{L"a`1< b>", S_OK, 2, {L"a`1", L"b"}},
|
||||||
|
{L"a`1< b >", S_OK, 2, {L"a`1", L"b"}},
|
||||||
|
{L"a`2<b,c>", S_OK, 3, {L"a`2", L"b", L"c"}},
|
||||||
|
{L"a`2<b, c>", S_OK, 3, {L"a`2", L"b", L"c"}},
|
||||||
|
{L"a`2<b ,c>", S_OK, 3, {L"a`2", L"b", L"c"}},
|
||||||
|
{L"a`2<b , c>", S_OK, 3, {L"a`2", L"b", L"c"}},
|
||||||
|
{L"a`3<b, c, d>", S_OK, 4, {L"a`3", L"b", L"c", L"d"}},
|
||||||
|
{L"a`1<b`1<c>>", S_OK, 3, {L"a`1", L"b`1", L"c"}},
|
||||||
|
{L"a`1<b`2<c, d>>", S_OK, 4, {L"a`1", L"b`2", L"c", L"d"}},
|
||||||
|
{L"a`2<b`2<c, d>, e>", S_OK, 5, {L"a`2", L"b`2", L"c", L"d", L"e"}},
|
||||||
|
{L"a`2<b, c`2<d, e>>", S_OK, 5, {L"a`2", L"b", L"c`2", L"d", L"e"}},
|
||||||
|
{L"a`9<b1, b2, b3, b4, b5, b6, b7, b8, b9>", S_OK, 10, {L"a`9", L"b1", L"b2", L"b3", L"b4", L"b5", L"b6", L"b7", L"b8", L"b9"}},
|
||||||
|
{L"Windows.Foundation.IExtensionInformation", S_OK, 1, {L"Windows.Foundation.IExtensionInformation"}},
|
||||||
|
{L"Windows.Foundation.IReference`1<Windows.UI.Color>", S_OK, 2, {L"Windows.Foundation.IReference`1", L"Windows.UI.Color"}},
|
||||||
|
{L"Windows.Foundation.Collections.IIterator`1<Windows.Foundation.Collections.IMapView`2<Windows.Foundation.Collections.IVector`1<String>, String>>",
|
||||||
|
S_OK, 5, {L"Windows.Foundation.Collections.IIterator`1",
|
||||||
|
L"Windows.Foundation.Collections.IMapView`2",
|
||||||
|
L"Windows.Foundation.Collections.IVector`1",
|
||||||
|
L"String",
|
||||||
|
L"String"}},
|
||||||
|
};
|
||||||
|
HSTRING type_name, *parts;
|
||||||
|
const WCHAR *buffer;
|
||||||
|
DWORD parts_count;
|
||||||
|
unsigned int i, j;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
/* Parameter checks */
|
||||||
|
hr = WindowsCreateString(L"a", 1, &type_name);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
hr = RoParseTypeName(NULL, &parts_count, &parts);
|
||||||
|
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
/* Crash on Windows */
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
hr = RoParseTypeName(type_name, NULL, &parts);
|
||||||
|
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
hr = RoParseTypeName(type_name, &parts_count, NULL);
|
||||||
|
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = RoParseTypeName(type_name, &parts_count, &parts);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
ok(parts_count == 1, "Got unexpected %ld.\n", parts_count);
|
||||||
|
hr = WindowsDeleteString(parts[0]);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
CoTaskMemFree(parts);
|
||||||
|
hr = WindowsDeleteString(type_name);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
/* Parsing checks */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(tests); i++)
|
||||||
|
{
|
||||||
|
winetest_push_context("%s", wine_dbgstr_w(tests[i].type_name));
|
||||||
|
|
||||||
|
if (tests[i].type_name)
|
||||||
|
{
|
||||||
|
hr = WindowsCreateString(tests[i].type_name, wcslen(tests[i].type_name), &type_name);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type_name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
parts_count = 0;
|
||||||
|
hr = RoParseTypeName(type_name, &parts_count, &parts);
|
||||||
|
ok(hr == tests[i].hr, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
hr = WindowsDeleteString(type_name);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
winetest_pop_context();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ok(parts_count == tests[i].parts_count, "Got unexpected %lu.\n", parts_count);
|
||||||
|
|
||||||
|
for (j = 0; j < parts_count; j++)
|
||||||
|
{
|
||||||
|
winetest_push_context("%s", wine_dbgstr_w(tests[i].parts[j]));
|
||||||
|
|
||||||
|
buffer = WindowsGetStringRawBuffer(parts[j], NULL);
|
||||||
|
ok(!lstrcmpW(tests[i].parts[j], buffer), "Got unexpected %s.\n", wine_dbgstr_w(buffer));
|
||||||
|
hr = WindowsDeleteString(parts[j]);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
winetest_pop_context();
|
||||||
|
}
|
||||||
|
CoTaskMemFree(parts);
|
||||||
|
|
||||||
|
hr = WindowsDeleteString(type_name);
|
||||||
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
winetest_pop_context();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(wintypes)
|
START_TEST(wintypes)
|
||||||
{
|
{
|
||||||
IsWow64Process(GetCurrentProcess(), &is_wow64);
|
IsWow64Process(GetCurrentProcess(), &is_wow64);
|
||||||
|
|
||||||
test_IApiInformationStatics();
|
test_IApiInformationStatics();
|
||||||
test_IPropertyValueStatics();
|
test_IPropertyValueStatics();
|
||||||
|
test_RoParseTypeName();
|
||||||
test_RoResolveNamespace();
|
test_RoResolveNamespace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
@ stub RoGetMetaDataFile
|
@ stub RoGetMetaDataFile
|
||||||
@ stdcall RoIsApiContractMajorVersionPresent(wstr long ptr)
|
@ stdcall RoIsApiContractMajorVersionPresent(wstr long ptr)
|
||||||
@ stub RoIsApiContractPresent
|
@ stub RoIsApiContractPresent
|
||||||
@ stub RoParseTypeName
|
@ stdcall RoParseTypeName(ptr ptr ptr)
|
||||||
@ stdcall RoResolveNamespace(ptr ptr long ptr ptr ptr ptr ptr)
|
@ stdcall RoResolveNamespace(ptr ptr long ptr ptr ptr ptr ptr)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <hstring.h>
|
#include <hstring.h>
|
||||||
|
|
||||||
HRESULT WINAPI RoIsApiContractMajorVersionPresent(const WCHAR *, UINT16, BOOL *);
|
HRESULT WINAPI RoIsApiContractMajorVersionPresent(const WCHAR *, UINT16, BOOL *);
|
||||||
|
HRESULT WINAPI RoParseTypeName(HSTRING, DWORD *, HSTRING **);
|
||||||
HRESULT WINAPI RoResolveNamespace(HSTRING, HSTRING, DWORD, const HSTRING *, DWORD *, HSTRING **, DWORD *, HSTRING **);
|
HRESULT WINAPI RoResolveNamespace(HSTRING, HSTRING, DWORD, const HSTRING *, DWORD *, HSTRING **, DWORD *, HSTRING **);
|
||||||
|
|
||||||
#endif /* _ROMETADATARESOLUTION_H */
|
#endif /* _ROMETADATARESOLUTION_H */
|
||||||
|
|
34
include/wine/server_protocol.h
generated
34
include/wine/server_protocol.h
generated
|
@ -57,7 +57,7 @@ struct request_max_size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef union
|
union debug_event_data
|
||||||
{
|
{
|
||||||
int code;
|
int code;
|
||||||
struct
|
struct
|
||||||
|
@ -109,7 +109,7 @@ typedef union
|
||||||
int __pad;
|
int __pad;
|
||||||
mod_handle_t base;
|
mod_handle_t base;
|
||||||
} unload_dll;
|
} unload_dll;
|
||||||
} debug_event_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
enum context_exec_space
|
enum context_exec_space
|
||||||
|
@ -312,7 +312,7 @@ struct winevent_msg_data
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
union hw_input
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
struct
|
struct
|
||||||
|
@ -342,15 +342,15 @@ typedef union
|
||||||
lparam_t lparam;
|
lparam_t lparam;
|
||||||
struct hid_input hid;
|
struct hid_input hid;
|
||||||
} hw;
|
} hw;
|
||||||
} hw_input_t;
|
};
|
||||||
|
|
||||||
typedef union
|
union message_data
|
||||||
{
|
{
|
||||||
unsigned char bytes[1];
|
unsigned char bytes[1];
|
||||||
struct hardware_msg_data hardware;
|
struct hardware_msg_data hardware;
|
||||||
struct callback_msg_data callback;
|
struct callback_msg_data callback;
|
||||||
struct winevent_msg_data winevent;
|
struct winevent_msg_data winevent;
|
||||||
} message_data_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
struct filesystem_event
|
struct filesystem_event
|
||||||
|
@ -435,7 +435,7 @@ struct object_type_info
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum select_op
|
enum select_opcode
|
||||||
{
|
{
|
||||||
SELECT_NONE,
|
SELECT_NONE,
|
||||||
SELECT_WAIT,
|
SELECT_WAIT,
|
||||||
|
@ -445,28 +445,28 @@ enum select_op
|
||||||
SELECT_KEYED_EVENT_RELEASE
|
SELECT_KEYED_EVENT_RELEASE
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
union select_op
|
||||||
{
|
{
|
||||||
enum select_op op;
|
enum select_opcode op;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum select_op op;
|
enum select_opcode op;
|
||||||
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
||||||
int __pad;
|
int __pad;
|
||||||
} wait;
|
} wait;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum select_op op;
|
enum select_opcode op;
|
||||||
obj_handle_t wait;
|
obj_handle_t wait;
|
||||||
obj_handle_t signal;
|
obj_handle_t signal;
|
||||||
} signal_and_wait;
|
} signal_and_wait;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum select_op op;
|
enum select_opcode op;
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
client_ptr_t key;
|
client_ptr_t key;
|
||||||
} keyed_event;
|
} keyed_event;
|
||||||
} select_op_t;
|
};
|
||||||
|
|
||||||
enum apc_type
|
enum apc_type
|
||||||
{
|
{
|
||||||
|
@ -748,7 +748,7 @@ enum irp_type
|
||||||
IRP_CALL_CANCEL
|
IRP_CALL_CANCEL
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
union irp_params
|
||||||
{
|
{
|
||||||
enum irp_type type;
|
enum irp_type type;
|
||||||
struct
|
struct
|
||||||
|
@ -816,7 +816,7 @@ typedef union
|
||||||
int __pad;
|
int __pad;
|
||||||
client_ptr_t irp;
|
client_ptr_t irp;
|
||||||
} cancel;
|
} cancel;
|
||||||
} irp_params_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -2970,7 +2970,7 @@ struct send_hardware_message_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
user_handle_t win;
|
user_handle_t win;
|
||||||
hw_input_t input;
|
union hw_input input;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
/* VARARG(report,bytes); */
|
/* VARARG(report,bytes); */
|
||||||
char __pad_60[4];
|
char __pad_60[4];
|
||||||
|
@ -5239,7 +5239,7 @@ struct get_next_device_request_request
|
||||||
struct get_next_device_request_reply
|
struct get_next_device_request_reply
|
||||||
{
|
{
|
||||||
struct reply_header __header;
|
struct reply_header __header;
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
obj_handle_t next;
|
obj_handle_t next;
|
||||||
thread_id_t client_tid;
|
thread_id_t client_tid;
|
||||||
client_ptr_t client_thread;
|
client_ptr_t client_thread;
|
||||||
|
|
|
@ -365,7 +365,7 @@ int __cdecl wmain(int argc, const WCHAR* argv[])
|
||||||
if(arg_is(argv[2], L"/help"))
|
if(arg_is(argv[2], L"/help"))
|
||||||
output_string(STRING_STOP_USAGE);
|
output_string(STRING_STOP_USAGE);
|
||||||
else if(!net_service(NET_STOP, argv[2]))
|
else if(!net_service(NET_STOP, argv[2]))
|
||||||
return 1;
|
return 2;
|
||||||
}
|
}
|
||||||
else if(arg_is(argv[1], L"use"))
|
else if(arg_is(argv[1], L"use"))
|
||||||
{
|
{
|
||||||
|
|
4
programs/net/tests/Makefile.in
Normal file
4
programs/net/tests/Makefile.in
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
TESTDLL = net.exe
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
net.c
|
78
programs/net/tests/net.c
Normal file
78
programs/net/tests/net.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Fabian Maurer
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
static HANDLE nul_file;
|
||||||
|
|
||||||
|
#define check_exit_code(x) ok(r == (x), "got exit code %ld, expected %d\n", r, (x))
|
||||||
|
|
||||||
|
/* Copied and modified from the reg.exe tests */
|
||||||
|
#define run_net_exe(c,r) run_net_exe_(__FILE__,__LINE__,c,r)
|
||||||
|
static BOOL run_net_exe_(const char *file, unsigned line, const char *cmd, DWORD *rc)
|
||||||
|
{
|
||||||
|
STARTUPINFOA si = {sizeof(STARTUPINFOA)};
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
BOOL bret;
|
||||||
|
DWORD ret;
|
||||||
|
char cmdline[256];
|
||||||
|
|
||||||
|
si.dwFlags = STARTF_USESTDHANDLES;
|
||||||
|
si.hStdInput = nul_file;
|
||||||
|
si.hStdOutput = nul_file;
|
||||||
|
si.hStdError = nul_file;
|
||||||
|
|
||||||
|
strcpy(cmdline, cmd);
|
||||||
|
if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ret = WaitForSingleObject(pi.hProcess, 10000);
|
||||||
|
if (ret == WAIT_TIMEOUT)
|
||||||
|
TerminateProcess(pi.hProcess, 1);
|
||||||
|
|
||||||
|
bret = GetExitCodeProcess(pi.hProcess, rc);
|
||||||
|
ok_(__FILE__, line)(bret, "GetExitCodeProcess failed: %ld\n", GetLastError());
|
||||||
|
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
return bret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_stop(void)
|
||||||
|
{
|
||||||
|
DWORD r;
|
||||||
|
|
||||||
|
/* Stop non existing service */
|
||||||
|
|
||||||
|
run_net_exe("net stop non-existing-service", &r);
|
||||||
|
check_exit_code(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(net)
|
||||||
|
{
|
||||||
|
SECURITY_ATTRIBUTES secattr = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
|
||||||
|
|
||||||
|
nul_file = CreateFileA("NUL", GENERIC_READ | GENERIC_WRITE, 0, &secattr, OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
test_stop();
|
||||||
|
|
||||||
|
CloseHandle(nul_file);
|
||||||
|
}
|
|
@ -48,7 +48,7 @@ struct debug_event
|
||||||
struct file *file; /* file object for events that need one */
|
struct file *file; /* file object for events that need one */
|
||||||
enum debug_event_state state; /* event state */
|
enum debug_event_state state; /* event state */
|
||||||
int status; /* continuation status */
|
int status; /* continuation status */
|
||||||
debug_event_t data; /* event data */
|
union debug_event_data data; /* event data */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const WCHAR debug_obj_name[] = {'D','e','b','u','g','O','b','j','e','c','t'};
|
static const WCHAR debug_obj_name[] = {'D','e','b','u','g','O','b','j','e','c','t'};
|
||||||
|
@ -142,7 +142,7 @@ static client_ptr_t get_teb_user_ptr( struct thread *thread )
|
||||||
|
|
||||||
static void fill_exception_event( struct debug_event *event, const void *arg )
|
static void fill_exception_event( struct debug_event *event, const void *arg )
|
||||||
{
|
{
|
||||||
const debug_event_t *data = arg;
|
const union debug_event_data *data = arg;
|
||||||
event->data.exception = data->exception;
|
event->data.exception = data->exception;
|
||||||
event->data.exception.nb_params = min( event->data.exception.nb_params, EXCEPTION_MAXIMUM_PARAMETERS );
|
event->data.exception.nb_params = min( event->data.exception.nb_params, EXCEPTION_MAXIMUM_PARAMETERS );
|
||||||
}
|
}
|
||||||
|
@ -641,7 +641,7 @@ DECL_HANDLER(queue_exception_event)
|
||||||
reply->handle = 0;
|
reply->handle = 0;
|
||||||
if (debug_obj)
|
if (debug_obj)
|
||||||
{
|
{
|
||||||
debug_event_t data;
|
union debug_event_data data;
|
||||||
struct debug_event *event;
|
struct debug_event *event;
|
||||||
struct thread *thread = current;
|
struct thread *thread = current;
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct irp_call
|
||||||
struct device_file *file; /* file containing this irp */
|
struct device_file *file; /* file containing this irp */
|
||||||
struct thread *thread; /* thread that queued the irp */
|
struct thread *thread; /* thread that queued the irp */
|
||||||
struct async *async; /* pending async op */
|
struct async *async; /* pending async op */
|
||||||
irp_params_t params; /* irp parameters */
|
union irp_params params; /* irp parameters */
|
||||||
struct iosb *iosb; /* I/O status block */
|
struct iosb *iosb; /* I/O status block */
|
||||||
int canceled; /* the call was canceled */
|
int canceled; /* the call was canceled */
|
||||||
client_ptr_t user_ptr; /* client side pointer */
|
client_ptr_t user_ptr; /* client side pointer */
|
||||||
|
@ -348,7 +348,8 @@ static void irp_call_destroy( struct object *obj )
|
||||||
if (irp->thread) release_object( irp->thread );
|
if (irp->thread) release_object( irp->thread );
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irp_call *create_irp( struct device_file *file, const irp_params_t *params, struct async *async )
|
static struct irp_call *create_irp( struct device_file *file, const union irp_params *params,
|
||||||
|
struct async *async )
|
||||||
{
|
{
|
||||||
struct irp_call *irp;
|
struct irp_call *irp;
|
||||||
|
|
||||||
|
@ -455,7 +456,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
|
||||||
if (device->manager)
|
if (device->manager)
|
||||||
{
|
{
|
||||||
struct irp_call *irp;
|
struct irp_call *irp;
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
memset( ¶ms, 0, sizeof(params) );
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
params.create.type = IRP_CALL_CREATE;
|
params.create.type = IRP_CALL_CREATE;
|
||||||
|
@ -512,7 +513,7 @@ static int device_file_close_handle( struct object *obj, struct process *process
|
||||||
if (!file->closed && file->device->manager && obj->handle_count == 1) /* last handle */
|
if (!file->closed && file->device->manager && obj->handle_count == 1) /* last handle */
|
||||||
{
|
{
|
||||||
struct irp_call *irp;
|
struct irp_call *irp;
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
file->closed = 1;
|
file->closed = 1;
|
||||||
memset( ¶ms, 0, sizeof(params) );
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
|
@ -542,7 +543,7 @@ static void device_file_destroy( struct object *obj )
|
||||||
release_object( file->device );
|
release_object( file->device );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_irp_params( struct device_manager *manager, struct irp_call *irp, irp_params_t *params )
|
static int fill_irp_params( struct device_manager *manager, struct irp_call *irp, union irp_params *params )
|
||||||
{
|
{
|
||||||
switch (irp->params.type)
|
switch (irp->params.type)
|
||||||
{
|
{
|
||||||
|
@ -595,7 +596,7 @@ static void free_irp_params( struct irp_call *irp )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue an irp to the device */
|
/* queue an irp to the device */
|
||||||
static void queue_irp( struct device_file *file, const irp_params_t *params, struct async *async )
|
static void queue_irp( struct device_file *file, const union irp_params *params, struct async *async )
|
||||||
{
|
{
|
||||||
struct irp_call *irp = create_irp( file, params, async );
|
struct irp_call *irp = create_irp( file, params, async );
|
||||||
if (!irp) return;
|
if (!irp) return;
|
||||||
|
@ -615,7 +616,7 @@ static enum server_fd_type device_file_get_fd_type( struct fd *fd )
|
||||||
static void device_file_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class )
|
static void device_file_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class )
|
||||||
{
|
{
|
||||||
struct device_file *file = get_fd_user( fd );
|
struct device_file *file = get_fd_user( fd );
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
memset( ¶ms, 0, sizeof(params) );
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
params.volume.type = IRP_CALL_VOLUME;
|
params.volume.type = IRP_CALL_VOLUME;
|
||||||
|
@ -626,7 +627,7 @@ static void device_file_get_volume_info( struct fd *fd, struct async *async, uns
|
||||||
static void device_file_read( struct fd *fd, struct async *async, file_pos_t pos )
|
static void device_file_read( struct fd *fd, struct async *async, file_pos_t pos )
|
||||||
{
|
{
|
||||||
struct device_file *file = get_fd_user( fd );
|
struct device_file *file = get_fd_user( fd );
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
memset( ¶ms, 0, sizeof(params) );
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
params.read.type = IRP_CALL_READ;
|
params.read.type = IRP_CALL_READ;
|
||||||
|
@ -638,7 +639,7 @@ static void device_file_read( struct fd *fd, struct async *async, file_pos_t pos
|
||||||
static void device_file_write( struct fd *fd, struct async *async, file_pos_t pos )
|
static void device_file_write( struct fd *fd, struct async *async, file_pos_t pos )
|
||||||
{
|
{
|
||||||
struct device_file *file = get_fd_user( fd );
|
struct device_file *file = get_fd_user( fd );
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
memset( ¶ms, 0, sizeof(params) );
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
params.write.type = IRP_CALL_WRITE;
|
params.write.type = IRP_CALL_WRITE;
|
||||||
|
@ -650,7 +651,7 @@ static void device_file_write( struct fd *fd, struct async *async, file_pos_t po
|
||||||
static void device_file_flush( struct fd *fd, struct async *async )
|
static void device_file_flush( struct fd *fd, struct async *async )
|
||||||
{
|
{
|
||||||
struct device_file *file = get_fd_user( fd );
|
struct device_file *file = get_fd_user( fd );
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
memset( ¶ms, 0, sizeof(params) );
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
params.flush.type = IRP_CALL_FLUSH;
|
params.flush.type = IRP_CALL_FLUSH;
|
||||||
|
@ -660,7 +661,7 @@ static void device_file_flush( struct fd *fd, struct async *async )
|
||||||
static void device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
|
static void device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
|
||||||
{
|
{
|
||||||
struct device_file *file = get_fd_user( fd );
|
struct device_file *file = get_fd_user( fd );
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
memset( ¶ms, 0, sizeof(params) );
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
params.ioctl.type = IRP_CALL_IOCTL;
|
params.ioctl.type = IRP_CALL_IOCTL;
|
||||||
|
@ -671,7 +672,7 @@ static void device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *a
|
||||||
static void cancel_irp_call( struct irp_call *irp )
|
static void cancel_irp_call( struct irp_call *irp )
|
||||||
{
|
{
|
||||||
struct irp_call *cancel_irp;
|
struct irp_call *cancel_irp;
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
irp->canceled = 1;
|
irp->canceled = 1;
|
||||||
if (!irp->user_ptr || !irp->file || !irp->file->device->manager) return;
|
if (!irp->user_ptr || !irp->file || !irp->file->device->manager) return;
|
||||||
|
@ -842,7 +843,7 @@ void free_kernel_objects( struct object *obj )
|
||||||
{
|
{
|
||||||
struct kernel_object *kernel_object = LIST_ENTRY( ptr, struct kernel_object, list_entry );
|
struct kernel_object *kernel_object = LIST_ENTRY( ptr, struct kernel_object, list_entry );
|
||||||
struct irp_call *irp;
|
struct irp_call *irp;
|
||||||
irp_params_t params;
|
union irp_params params;
|
||||||
|
|
||||||
assert( !kernel_object->owned );
|
assert( !kernel_object->owned );
|
||||||
|
|
||||||
|
|
|
@ -248,7 +248,7 @@ static void keyed_event_dump( struct object *obj, int verbose )
|
||||||
fputs( "Keyed event\n", stderr );
|
fputs( "Keyed event\n", stderr );
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum select_op matching_op( enum select_op op )
|
static enum select_opcode matching_op( enum select_opcode op )
|
||||||
{
|
{
|
||||||
return op ^ (SELECT_KEYED_EVENT_WAIT ^ SELECT_KEYED_EVENT_RELEASE);
|
return op ^ (SELECT_KEYED_EVENT_WAIT ^ SELECT_KEYED_EVENT_RELEASE);
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *en
|
||||||
{
|
{
|
||||||
struct wait_queue_entry *ptr;
|
struct wait_queue_entry *ptr;
|
||||||
struct process *process;
|
struct process *process;
|
||||||
enum select_op select_op;
|
enum select_opcode select_op;
|
||||||
|
|
||||||
assert( obj->ops == &keyed_event_ops );
|
assert( obj->ops == &keyed_event_ops );
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct request_max_size
|
||||||
|
|
||||||
|
|
||||||
/* debug event data */
|
/* debug event data */
|
||||||
typedef union
|
union debug_event_data
|
||||||
{
|
{
|
||||||
int code; /* event code */
|
int code; /* event code */
|
||||||
struct
|
struct
|
||||||
|
@ -125,7 +125,7 @@ typedef union
|
||||||
int __pad;
|
int __pad;
|
||||||
mod_handle_t base; /* base address of the dll */
|
mod_handle_t base; /* base address of the dll */
|
||||||
} unload_dll;
|
} unload_dll;
|
||||||
} debug_event_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
enum context_exec_space
|
enum context_exec_space
|
||||||
|
@ -328,7 +328,7 @@ struct winevent_msg_data
|
||||||
/* followed by module name if any */
|
/* followed by module name if any */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
union hw_input
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
struct
|
struct
|
||||||
|
@ -358,15 +358,15 @@ typedef union
|
||||||
lparam_t lparam; /* parameters */
|
lparam_t lparam; /* parameters */
|
||||||
struct hid_input hid; /* defined in ntuser.h */
|
struct hid_input hid; /* defined in ntuser.h */
|
||||||
} hw;
|
} hw;
|
||||||
} hw_input_t;
|
};
|
||||||
|
|
||||||
typedef union
|
union message_data
|
||||||
{
|
{
|
||||||
unsigned char bytes[1]; /* raw data for sent messages */
|
unsigned char bytes[1]; /* raw data for sent messages */
|
||||||
struct hardware_msg_data hardware;
|
struct hardware_msg_data hardware;
|
||||||
struct callback_msg_data callback;
|
struct callback_msg_data callback;
|
||||||
struct winevent_msg_data winevent;
|
struct winevent_msg_data winevent;
|
||||||
} message_data_t;
|
};
|
||||||
|
|
||||||
/* structure returned in filesystem events */
|
/* structure returned in filesystem events */
|
||||||
struct filesystem_event
|
struct filesystem_event
|
||||||
|
@ -451,7 +451,7 @@ struct object_type_info
|
||||||
/* VARARG(name,unicode_str); */
|
/* VARARG(name,unicode_str); */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum select_op
|
enum select_opcode
|
||||||
{
|
{
|
||||||
SELECT_NONE,
|
SELECT_NONE,
|
||||||
SELECT_WAIT,
|
SELECT_WAIT,
|
||||||
|
@ -461,28 +461,28 @@ enum select_op
|
||||||
SELECT_KEYED_EVENT_RELEASE
|
SELECT_KEYED_EVENT_RELEASE
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
union select_op
|
||||||
{
|
{
|
||||||
enum select_op op;
|
enum select_opcode op;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum select_op op; /* SELECT_WAIT or SELECT_WAIT_ALL */
|
enum select_opcode op; /* SELECT_WAIT or SELECT_WAIT_ALL */
|
||||||
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
||||||
int __pad;
|
int __pad;
|
||||||
} wait;
|
} wait;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum select_op op; /* SELECT_SIGNAL_AND_WAIT */
|
enum select_opcode op; /* SELECT_SIGNAL_AND_WAIT */
|
||||||
obj_handle_t wait;
|
obj_handle_t wait;
|
||||||
obj_handle_t signal; /* must be last in the structure so we can remove it on retries */
|
obj_handle_t signal; /* must be last in the structure so we can remove it on retries */
|
||||||
} signal_and_wait;
|
} signal_and_wait;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum select_op op; /* SELECT_KEYED_EVENT_WAIT or SELECT_KEYED_EVENT_RELEASE */
|
enum select_opcode op; /* SELECT_KEYED_EVENT_WAIT or SELECT_KEYED_EVENT_RELEASE */
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
client_ptr_t key;
|
client_ptr_t key;
|
||||||
} keyed_event;
|
} keyed_event;
|
||||||
} select_op_t;
|
};
|
||||||
|
|
||||||
enum apc_type
|
enum apc_type
|
||||||
{
|
{
|
||||||
|
@ -764,7 +764,7 @@ enum irp_type
|
||||||
IRP_CALL_CANCEL
|
IRP_CALL_CANCEL
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
union irp_params
|
||||||
{
|
{
|
||||||
enum irp_type type; /* irp call type */
|
enum irp_type type; /* irp call type */
|
||||||
struct
|
struct
|
||||||
|
@ -832,7 +832,7 @@ typedef union
|
||||||
int __pad;
|
int __pad;
|
||||||
client_ptr_t irp; /* opaque ptr for canceled irp */
|
client_ptr_t irp; /* opaque ptr for canceled irp */
|
||||||
} cancel;
|
} cancel;
|
||||||
} irp_params_t;
|
};
|
||||||
|
|
||||||
/* information about a PE image mapping, roughly equivalent to SECTION_IMAGE_INFORMATION */
|
/* information about a PE image mapping, roughly equivalent to SECTION_IMAGE_INFORMATION */
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -2241,7 +2241,7 @@ enum message_type
|
||||||
/* Send a hardware message to a thread queue */
|
/* Send a hardware message to a thread queue */
|
||||||
@REQ(send_hardware_message)
|
@REQ(send_hardware_message)
|
||||||
user_handle_t win; /* window handle */
|
user_handle_t win; /* window handle */
|
||||||
hw_input_t input; /* input data */
|
union hw_input input; /* input data */
|
||||||
unsigned int flags; /* flags (see below) */
|
unsigned int flags; /* flags (see below) */
|
||||||
VARARG(report,bytes); /* HID report data */
|
VARARG(report,bytes); /* HID report data */
|
||||||
@REPLY
|
@REPLY
|
||||||
|
@ -3695,7 +3695,7 @@ typedef union
|
||||||
data_size_t result; /* IOSB result of the previous irp */
|
data_size_t result; /* IOSB result of the previous irp */
|
||||||
VARARG(data,bytes); /* output data of the previous irp */
|
VARARG(data,bytes); /* output data of the previous irp */
|
||||||
@REPLY
|
@REPLY
|
||||||
irp_params_t params; /* irp parameters */
|
union irp_params params; /* irp parameters */
|
||||||
obj_handle_t next; /* handle to the next irp */
|
obj_handle_t next; /* handle to the next irp */
|
||||||
thread_id_t client_tid; /* tid of thread calling irp */
|
thread_id_t client_tid; /* tid of thread calling irp */
|
||||||
client_ptr_t client_thread; /* pointer to thread object of calling irp */
|
client_ptr_t client_thread; /* pointer to thread object of calling irp */
|
||||||
|
|
|
@ -2106,7 +2106,7 @@ static void rawkeyboard_init( struct rawinput *rawinput, RAWKEYBOARD *keyboard,
|
||||||
keyboard->ExtraInformation = info;
|
keyboard->ExtraInformation = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rawhid_init( struct rawinput *rawinput, RAWHID *hid, const hw_input_t *input )
|
static void rawhid_init( struct rawinput *rawinput, RAWHID *hid, const union hw_input *input )
|
||||||
{
|
{
|
||||||
rawinput->type = RIM_TYPEHID;
|
rawinput->type = RIM_TYPEHID;
|
||||||
rawinput->device = input->hw.hid.device;
|
rawinput->device = input->hw.hid.device;
|
||||||
|
@ -2203,7 +2203,7 @@ static void dispatch_rawinput_message( struct desktop *desktop, struct rawinput_
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue a hardware message for a mouse event */
|
/* queue a hardware message for a mouse event */
|
||||||
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const union hw_input *input,
|
||||||
unsigned int origin, struct msg_queue *sender )
|
unsigned int origin, struct msg_queue *sender )
|
||||||
{
|
{
|
||||||
const desktop_shm_t *desktop_shm = desktop->shared;
|
const desktop_shm_t *desktop_shm = desktop->shared;
|
||||||
|
@ -2309,7 +2309,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||||
return wait;
|
return wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const union hw_input *input,
|
||||||
unsigned int origin, struct msg_queue *sender, int repeat );
|
unsigned int origin, struct msg_queue *sender, int repeat );
|
||||||
|
|
||||||
static void key_repeat_timeout( void *private )
|
static void key_repeat_timeout( void *private )
|
||||||
|
@ -2329,7 +2329,7 @@ static void stop_key_repeat( struct desktop *desktop )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue a hardware message for a keyboard event */
|
/* queue a hardware message for a keyboard event */
|
||||||
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const union hw_input *input,
|
||||||
unsigned int origin, struct msg_queue *sender, int repeat )
|
unsigned int origin, struct msg_queue *sender, int repeat )
|
||||||
{
|
{
|
||||||
const desktop_shm_t *desktop_shm = desktop->shared;
|
const desktop_shm_t *desktop_shm = desktop->shared;
|
||||||
|
@ -2502,7 +2502,7 @@ struct pointer
|
||||||
struct desktop *desktop;
|
struct desktop *desktop;
|
||||||
user_handle_t win;
|
user_handle_t win;
|
||||||
int primary;
|
int primary;
|
||||||
hw_input_t input;
|
union hw_input input;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void queue_pointer_message( struct pointer *pointer, int repeated );
|
static void queue_pointer_message( struct pointer *pointer, int repeated );
|
||||||
|
@ -2524,7 +2524,7 @@ static void queue_pointer_message( struct pointer *pointer, int repeated )
|
||||||
struct hw_msg_source source = { IMDT_UNAVAILABLE, IMDT_TOUCH };
|
struct hw_msg_source source = { IMDT_UNAVAILABLE, IMDT_TOUCH };
|
||||||
struct desktop *desktop = pointer->desktop;
|
struct desktop *desktop = pointer->desktop;
|
||||||
const desktop_shm_t *desktop_shm = desktop->shared;
|
const desktop_shm_t *desktop_shm = desktop->shared;
|
||||||
const hw_input_t *input = &pointer->input;
|
const union hw_input *input = &pointer->input;
|
||||||
unsigned int i, wparam = input->hw.wparam;
|
unsigned int i, wparam = input->hw.wparam;
|
||||||
timeout_t time = get_tick_count();
|
timeout_t time = get_tick_count();
|
||||||
user_handle_t win = pointer->win;
|
user_handle_t win = pointer->win;
|
||||||
|
@ -2600,7 +2600,7 @@ static struct pointer *find_pointer_from_id( struct desktop *desktop, unsigned i
|
||||||
|
|
||||||
/* queue a hardware message for a custom type of event */
|
/* queue a hardware message for a custom type of event */
|
||||||
static void queue_custom_hardware_message( struct desktop *desktop, user_handle_t win,
|
static void queue_custom_hardware_message( struct desktop *desktop, user_handle_t win,
|
||||||
unsigned int origin, const hw_input_t *input )
|
unsigned int origin, const union hw_input *input )
|
||||||
{
|
{
|
||||||
const desktop_shm_t *desktop_shm = desktop->shared;
|
const desktop_shm_t *desktop_shm = desktop->shared;
|
||||||
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
|
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
|
||||||
|
|
10
server/request_handlers.h
generated
10
server/request_handlers.h
generated
|
@ -604,16 +604,12 @@ C_ASSERT( sizeof(client_ptr_t) == 8 );
|
||||||
C_ASSERT( sizeof(context_t) == 1728 );
|
C_ASSERT( sizeof(context_t) == 1728 );
|
||||||
C_ASSERT( sizeof(cursor_pos_t) == 24 );
|
C_ASSERT( sizeof(cursor_pos_t) == 24 );
|
||||||
C_ASSERT( sizeof(data_size_t) == 4 );
|
C_ASSERT( sizeof(data_size_t) == 4 );
|
||||||
C_ASSERT( sizeof(debug_event_t) == 160 );
|
|
||||||
C_ASSERT( sizeof(file_pos_t) == 8 );
|
C_ASSERT( sizeof(file_pos_t) == 8 );
|
||||||
C_ASSERT( sizeof(generic_map_t) == 16 );
|
C_ASSERT( sizeof(generic_map_t) == 16 );
|
||||||
C_ASSERT( sizeof(hw_input_t) == 40 );
|
|
||||||
C_ASSERT( sizeof(int) == 4 );
|
C_ASSERT( sizeof(int) == 4 );
|
||||||
C_ASSERT( sizeof(ioctl_code_t) == 4 );
|
C_ASSERT( sizeof(ioctl_code_t) == 4 );
|
||||||
C_ASSERT( sizeof(irp_params_t) == 32 );
|
|
||||||
C_ASSERT( sizeof(lparam_t) == 8 );
|
C_ASSERT( sizeof(lparam_t) == 8 );
|
||||||
C_ASSERT( sizeof(mem_size_t) == 8 );
|
C_ASSERT( sizeof(mem_size_t) == 8 );
|
||||||
C_ASSERT( sizeof(message_data_t) == 48 );
|
|
||||||
C_ASSERT( sizeof(mod_handle_t) == 8 );
|
C_ASSERT( sizeof(mod_handle_t) == 8 );
|
||||||
C_ASSERT( sizeof(obj_handle_t) == 4 );
|
C_ASSERT( sizeof(obj_handle_t) == 4 );
|
||||||
C_ASSERT( sizeof(obj_locator_t) == 16 );
|
C_ASSERT( sizeof(obj_locator_t) == 16 );
|
||||||
|
@ -622,7 +618,6 @@ C_ASSERT( sizeof(pe_image_info_t) == 88 );
|
||||||
C_ASSERT( sizeof(process_id_t) == 4 );
|
C_ASSERT( sizeof(process_id_t) == 4 );
|
||||||
C_ASSERT( sizeof(property_data_t) == 16 );
|
C_ASSERT( sizeof(property_data_t) == 16 );
|
||||||
C_ASSERT( sizeof(rectangle_t) == 16 );
|
C_ASSERT( sizeof(rectangle_t) == 16 );
|
||||||
C_ASSERT( sizeof(select_op_t) == 264 );
|
|
||||||
C_ASSERT( sizeof(short int) == 2 );
|
C_ASSERT( sizeof(short int) == 2 );
|
||||||
C_ASSERT( sizeof(startup_info_t) == 96 );
|
C_ASSERT( sizeof(startup_info_t) == 96 );
|
||||||
C_ASSERT( sizeof(struct async_data) == 40 );
|
C_ASSERT( sizeof(struct async_data) == 40 );
|
||||||
|
@ -642,6 +637,11 @@ C_ASSERT( sizeof(timeout_t) == 8 );
|
||||||
C_ASSERT( sizeof(udp_endpoint) == 32 );
|
C_ASSERT( sizeof(udp_endpoint) == 32 );
|
||||||
C_ASSERT( sizeof(union apc_call) == 64 );
|
C_ASSERT( sizeof(union apc_call) == 64 );
|
||||||
C_ASSERT( sizeof(union apc_result) == 40 );
|
C_ASSERT( sizeof(union apc_result) == 40 );
|
||||||
|
C_ASSERT( sizeof(union debug_event_data) == 160 );
|
||||||
|
C_ASSERT( sizeof(union hw_input) == 40 );
|
||||||
|
C_ASSERT( sizeof(union irp_params) == 32 );
|
||||||
|
C_ASSERT( sizeof(union message_data) == 48 );
|
||||||
|
C_ASSERT( sizeof(union select_op) == 264 );
|
||||||
C_ASSERT( sizeof(unsigned __int64) == 8 );
|
C_ASSERT( sizeof(unsigned __int64) == 8 );
|
||||||
C_ASSERT( sizeof(unsigned char) == 1 );
|
C_ASSERT( sizeof(unsigned char) == 1 );
|
||||||
C_ASSERT( sizeof(unsigned int) == 4 );
|
C_ASSERT( sizeof(unsigned int) == 4 );
|
||||||
|
|
4
server/request_trace.h
generated
4
server/request_trace.h
generated
|
@ -9,9 +9,9 @@ static void dump_abstime( const char *prefix, const abstime_t *val );
|
||||||
static void dump_apc_result( const char *prefix, const union apc_result *val );
|
static void dump_apc_result( const char *prefix, const union apc_result *val );
|
||||||
static void dump_async_data( const char *prefix, const struct async_data *val );
|
static void dump_async_data( const char *prefix, const struct async_data *val );
|
||||||
static void dump_generic_map( const char *prefix, const generic_map_t *val );
|
static void dump_generic_map( const char *prefix, const generic_map_t *val );
|
||||||
static void dump_hw_input( const char *prefix, const hw_input_t *val );
|
static void dump_hw_input( const char *prefix, const union hw_input *val );
|
||||||
static void dump_ioctl_code( const char *prefix, const ioctl_code_t *val );
|
static void dump_ioctl_code( const char *prefix, const ioctl_code_t *val );
|
||||||
static void dump_irp_params( const char *prefix, const irp_params_t *val );
|
static void dump_irp_params( const char *prefix, const union irp_params *val );
|
||||||
static void dump_luid( const char *prefix, const struct luid *val );
|
static void dump_luid( const char *prefix, const struct luid *val );
|
||||||
static void dump_obj_locator( const char *prefix, const obj_locator_t *val );
|
static void dump_obj_locator( const char *prefix, const obj_locator_t *val );
|
||||||
static void dump_rectangle( const char *prefix, const rectangle_t *val );
|
static void dump_rectangle( const char *prefix, const rectangle_t *val );
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct thread_wait
|
||||||
int count; /* count of objects */
|
int count; /* count of objects */
|
||||||
int flags;
|
int flags;
|
||||||
int abandoned;
|
int abandoned;
|
||||||
enum select_op select;
|
enum select_opcode select;
|
||||||
client_ptr_t key; /* wait key for keyed events */
|
client_ptr_t key; /* wait key for keyed events */
|
||||||
client_ptr_t cookie; /* magic cookie to return to client */
|
client_ptr_t cookie; /* magic cookie to return to client */
|
||||||
abstime_t when;
|
abstime_t when;
|
||||||
|
@ -721,7 +721,7 @@ struct thread *get_wait_queue_thread( struct wait_queue_entry *entry )
|
||||||
return entry->wait->thread;
|
return entry->wait->thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum select_op get_wait_queue_select_op( struct wait_queue_entry *entry )
|
enum select_opcode get_wait_queue_select_op( struct wait_queue_entry *entry )
|
||||||
{
|
{
|
||||||
return entry->wait->select;
|
return entry->wait->select;
|
||||||
}
|
}
|
||||||
|
@ -775,7 +775,7 @@ static unsigned int end_wait( struct thread *thread, unsigned int status )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the thread wait structure */
|
/* build the thread wait structure */
|
||||||
static int wait_on( const select_op_t *select_op, unsigned int count, struct object *objects[],
|
static int wait_on( const union select_op *select_op, unsigned int count, struct object *objects[],
|
||||||
int flags, abstime_t when )
|
int flags, abstime_t when )
|
||||||
{
|
{
|
||||||
struct thread_wait *wait;
|
struct thread_wait *wait;
|
||||||
|
@ -812,7 +812,7 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj
|
||||||
return current->wait ? 1 : 0;
|
return current->wait ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_on_handles( const select_op_t *select_op, unsigned int count, const obj_handle_t *handles,
|
static int wait_on_handles( const union select_op *select_op, unsigned int count, const obj_handle_t *handles,
|
||||||
int flags, abstime_t when )
|
int flags, abstime_t when )
|
||||||
{
|
{
|
||||||
struct object *objects[MAXIMUM_WAIT_OBJECTS];
|
struct object *objects[MAXIMUM_WAIT_OBJECTS];
|
||||||
|
@ -981,7 +981,7 @@ static int signal_object( obj_handle_t handle )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select on a list of handles */
|
/* select on a list of handles */
|
||||||
static int select_on( const select_op_t *select_op, data_size_t op_size, client_ptr_t cookie,
|
static int select_on( const union select_op *select_op, data_size_t op_size, client_ptr_t cookie,
|
||||||
int flags, abstime_t when )
|
int flags, abstime_t when )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -996,8 +996,8 @@ static int select_on( const select_op_t *select_op, data_size_t op_size, client_
|
||||||
|
|
||||||
case SELECT_WAIT:
|
case SELECT_WAIT:
|
||||||
case SELECT_WAIT_ALL:
|
case SELECT_WAIT_ALL:
|
||||||
count = (op_size - offsetof( select_op_t, wait.handles )) / sizeof(select_op->wait.handles[0]);
|
count = (op_size - offsetof( union select_op, wait.handles )) / sizeof(select_op->wait.handles[0]);
|
||||||
if (op_size < offsetof( select_op_t, wait.handles ) || count > MAXIMUM_WAIT_OBJECTS)
|
if (op_size < offsetof( union select_op, wait.handles ) || count > MAXIMUM_WAIT_OBJECTS)
|
||||||
{
|
{
|
||||||
set_error( STATUS_INVALID_PARAMETER );
|
set_error( STATUS_INVALID_PARAMETER );
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1580,7 +1580,7 @@ DECL_HANDLER(resume_thread)
|
||||||
/* select on a handle list */
|
/* select on a handle list */
|
||||||
DECL_HANDLER(select)
|
DECL_HANDLER(select)
|
||||||
{
|
{
|
||||||
select_op_t select_op;
|
union select_op select_op;
|
||||||
data_size_t op_size, ctx_size;
|
data_size_t op_size, ctx_size;
|
||||||
struct context *ctx;
|
struct context *ctx;
|
||||||
struct thread_apc *apc;
|
struct thread_apc *apc;
|
||||||
|
|
|
@ -106,7 +106,7 @@ extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int
|
||||||
extern struct thread *get_thread_from_tid( int tid );
|
extern struct thread *get_thread_from_tid( int tid );
|
||||||
extern struct thread *get_thread_from_pid( int pid );
|
extern struct thread *get_thread_from_pid( int pid );
|
||||||
extern struct thread *get_wait_queue_thread( struct wait_queue_entry *entry );
|
extern struct thread *get_wait_queue_thread( struct wait_queue_entry *entry );
|
||||||
extern enum select_op get_wait_queue_select_op( struct wait_queue_entry *entry );
|
extern enum select_opcode get_wait_queue_select_op( struct wait_queue_entry *entry );
|
||||||
extern client_ptr_t get_wait_queue_key( struct wait_queue_entry *entry );
|
extern client_ptr_t get_wait_queue_key( struct wait_queue_entry *entry );
|
||||||
extern void make_wait_abandoned( struct wait_queue_entry *entry );
|
extern void make_wait_abandoned( struct wait_queue_entry *entry );
|
||||||
extern void set_wait_status( struct wait_queue_entry *entry, int status );
|
extern void set_wait_status( struct wait_queue_entry *entry, int status );
|
||||||
|
|
|
@ -387,7 +387,7 @@ static void dump_async_data( const char *prefix, const struct async_data *data )
|
||||||
fputc( '}', stderr );
|
fputc( '}', stderr );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_irp_params( const char *prefix, const irp_params_t *data )
|
static void dump_irp_params( const char *prefix, const union irp_params *data )
|
||||||
{
|
{
|
||||||
switch (data->type)
|
switch (data->type)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +449,7 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_hw_input( const char *prefix, const hw_input_t *input )
|
static void dump_hw_input( const char *prefix, const union hw_input *input )
|
||||||
{
|
{
|
||||||
switch (input->type)
|
switch (input->type)
|
||||||
{
|
{
|
||||||
|
@ -582,7 +582,7 @@ static void dump_varargs_apc_result( const char *prefix, data_size_t size )
|
||||||
|
|
||||||
static void dump_varargs_select_op( const char *prefix, data_size_t size )
|
static void dump_varargs_select_op( const char *prefix, data_size_t size )
|
||||||
{
|
{
|
||||||
select_op_t data;
|
union select_op data;
|
||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
{
|
{
|
||||||
|
@ -601,9 +601,9 @@ static void dump_varargs_select_op( const char *prefix, data_size_t size )
|
||||||
case SELECT_WAIT:
|
case SELECT_WAIT:
|
||||||
case SELECT_WAIT_ALL:
|
case SELECT_WAIT_ALL:
|
||||||
fprintf( stderr, "%s", data.op == SELECT_WAIT ? "WAIT" : "WAIT_ALL" );
|
fprintf( stderr, "%s", data.op == SELECT_WAIT ? "WAIT" : "WAIT_ALL" );
|
||||||
if (size > offsetof( select_op_t, wait.handles ))
|
if (size > offsetof( union select_op, wait.handles ))
|
||||||
dump_handles( ",handles=", data.wait.handles,
|
dump_handles( ",handles=", data.wait.handles,
|
||||||
min( size, sizeof(data.wait) ) - offsetof( select_op_t, wait.handles ));
|
min( size, sizeof(data.wait) ) - offsetof( union select_op, wait.handles ));
|
||||||
break;
|
break;
|
||||||
case SELECT_SIGNAL_AND_WAIT:
|
case SELECT_SIGNAL_AND_WAIT:
|
||||||
fprintf( stderr, "SIGNAL_AND_WAIT,signal=%04x,wait=%04x",
|
fprintf( stderr, "SIGNAL_AND_WAIT,signal=%04x,wait=%04x",
|
||||||
|
@ -887,7 +887,7 @@ static void dump_varargs_contexts( const char *prefix, data_size_t size )
|
||||||
|
|
||||||
static void dump_varargs_debug_event( const char *prefix, data_size_t size )
|
static void dump_varargs_debug_event( const char *prefix, data_size_t size )
|
||||||
{
|
{
|
||||||
debug_event_t event;
|
union debug_event_data event;
|
||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,7 @@ struct key_repeat
|
||||||
int enable; /* enable auto-repeat */
|
int enable; /* enable auto-repeat */
|
||||||
timeout_t delay; /* auto-repeat delay */
|
timeout_t delay; /* auto-repeat delay */
|
||||||
timeout_t period; /* auto-repeat period */
|
timeout_t period; /* auto-repeat period */
|
||||||
hw_input_t input; /* the input to repeat */
|
union hw_input input; /* the input to repeat */
|
||||||
user_handle_t win; /* target window for input event */
|
user_handle_t win; /* target window for input event */
|
||||||
struct timeout_user *timeout; /* timeout for repeat */
|
struct timeout_user *timeout; /* timeout for repeat */
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,33 +38,33 @@ my %formats =
|
||||||
"timeout_t" => [ 8, 8 ],
|
"timeout_t" => [ 8, 8 ],
|
||||||
"abstime_t" => [ 8, 8 ],
|
"abstime_t" => [ 8, 8 ],
|
||||||
"rectangle_t" => [ 16, 4 ],
|
"rectangle_t" => [ 16, 4 ],
|
||||||
"irp_params_t" => [ 32, 8 ],
|
|
||||||
"generic_map_t" => [ 16, 4 ],
|
"generic_map_t" => [ 16, 4 ],
|
||||||
"ioctl_code_t" => [ 4, 4 ],
|
"ioctl_code_t" => [ 4, 4 ],
|
||||||
"hw_input_t" => [ 40, 8 ],
|
|
||||||
"obj_locator_t" => [ 16, 8 ],
|
"obj_locator_t" => [ 16, 8 ],
|
||||||
# varargs-only structures
|
# varargs-only structures
|
||||||
"context_t" => [ 1728, 8 ],
|
"context_t" => [ 1728, 8 ],
|
||||||
"cursor_pos_t" => [ 24, 8 ],
|
"cursor_pos_t" => [ 24, 8 ],
|
||||||
"debug_event_t" => [ 160, 8 ],
|
|
||||||
"message_data_t" => [ 48, 8 ],
|
|
||||||
"pe_image_info_t" => [ 88, 8 ],
|
"pe_image_info_t" => [ 88, 8 ],
|
||||||
"property_data_t" => [ 16, 8 ],
|
"property_data_t" => [ 16, 8 ],
|
||||||
"select_op_t" => [ 264, 8 ],
|
|
||||||
"startup_info_t" => [ 96, 4 ],
|
"startup_info_t" => [ 96, 4 ],
|
||||||
"tcp_connection" => [ 60, 4 ],
|
"tcp_connection" => [ 60, 4 ],
|
||||||
"udp_endpoint" => [ 32, 4 ],
|
"udp_endpoint" => [ 32, 4 ],
|
||||||
"union apc_call" => [ 64, 8 ],
|
"union apc_call" => [ 64, 8 ],
|
||||||
"union apc_result" => [ 40, 8 ],
|
"union apc_result" => [ 40, 8 ],
|
||||||
"struct async_data" => [ 40, 8 ],
|
"struct async_data" => [ 40, 8 ],
|
||||||
|
"union debug_event_data" => [ 160, 8 ],
|
||||||
"struct filesystem_event" => [ 12, 4 ],
|
"struct filesystem_event" => [ 12, 4 ],
|
||||||
"struct handle_info" => [ 20, 4 ],
|
"struct handle_info" => [ 20, 4 ],
|
||||||
|
"union hw_input" => [ 40, 8 ],
|
||||||
|
"union irp_params" => [ 32, 8 ],
|
||||||
"struct luid" => [ 8, 4 ],
|
"struct luid" => [ 8, 4 ],
|
||||||
"struct luid_attr" => [ 12, 4 ],
|
"struct luid_attr" => [ 12, 4 ],
|
||||||
|
"union message_data" => [ 48, 8 ],
|
||||||
"struct object_attributes" => [ 16, 4 ],
|
"struct object_attributes" => [ 16, 4 ],
|
||||||
"struct object_type_info" => [ 44, 4 ],
|
"struct object_type_info" => [ 44, 4 ],
|
||||||
"struct process_info" => [ 40, 8 ],
|
"struct process_info" => [ 40, 8 ],
|
||||||
"struct rawinput_device" => [ 12, 4 ],
|
"struct rawinput_device" => [ 12, 4 ],
|
||||||
|
"union select_op" => [ 264, 8 ],
|
||||||
"struct thread_info" => [ 40, 8 ],
|
"struct thread_info" => [ 40, 8 ],
|
||||||
"struct user_apc" => [ 40, 8 ],
|
"struct user_apc" => [ 40, 8 ],
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue