mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
Compare commits
123 commits
8254263c8c
...
192224e5b5
Author | SHA1 | Date | |
---|---|---|---|
|
192224e5b5 | ||
|
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 | ||
|
ae6366b33c | ||
|
d9cf4678a1 | ||
|
da936bcf35 | ||
|
e75192fe72 | ||
|
0dc7e40468 | ||
|
700ee59470 | ||
|
c76a192bf6 | ||
|
9acdc03128 | ||
|
8b121591be | ||
|
5a23afb34d | ||
|
6a01532899 | ||
|
e5b0ead2b5 | ||
|
b9c06c4474 | ||
|
a57eedec86 | ||
|
9212706ede | ||
|
40b314cf34 | ||
|
aa24458086 | ||
|
576d7e24cd | ||
|
305ec347dc | ||
|
4c0103e58c | ||
|
1137a10ef7 | ||
|
eae7db4fa4 | ||
|
75e2ec479b | ||
|
45953cdbec | ||
|
126c54cd25 | ||
|
ab40b7fd86 | ||
|
0bd49a68dc | ||
|
50683f7b32 | ||
|
48bb5f90a2 | ||
|
7352196f6a | ||
|
4eefc0b9a9 | ||
|
51f6839395 | ||
|
b240f8ea93 | ||
|
54b9f68b8e | ||
|
5a7a4b7f1a | ||
|
698ab75a59 | ||
|
8e2442584c | ||
|
6d1df55bf3 | ||
|
9f8ef43991 | ||
|
5c597119a0 | ||
|
c20bf25556 | ||
|
194ada7583 | ||
|
8a87ce3c4f | ||
|
f47da4307f | ||
|
0f84798246 | ||
|
0eda6a76c7 | ||
|
38f1ce3210 | ||
|
9b264c948f | ||
|
055bf9f5a2 | ||
|
18aefb5dcf | ||
|
85331da430 | ||
|
5947a66f4c | ||
|
12755eeb1c | ||
|
e3258e7620 | ||
|
968ab4e79a | ||
|
b1dd7da806 | ||
|
199274d420 | ||
|
7ac35f13cb | ||
|
1f42d452aa | ||
|
96c37c23f6 | ||
|
f588fec26c | ||
|
70258a160f | ||
|
b02b73673b | ||
|
a5de8d85d3 | ||
|
5b10f924fa | ||
|
ea3c73b12d | ||
|
a93623eced | ||
|
194901b592 | ||
|
484c43c9e9 | ||
|
1125bb8f71 | ||
|
19018abf86 | ||
|
32be056558 | ||
|
e3db89aa9d | ||
|
61d8e74e72 | ||
|
427f8fae20 | ||
|
71b4377e68 | ||
|
a7b1e5d5dc | ||
|
dd6e73428d | ||
|
3181ae039e | ||
|
786cf5a20b | ||
|
9accb76341 | ||
|
6208d61055 | ||
|
966cec7a63 | ||
|
23db166ec8 | ||
|
6dd7cd59d9 | ||
|
c4c3b5b7db |
157 changed files with 11761 additions and 8814 deletions
64
.gitattributes
vendored
Normal file
64
.gitattributes
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
[attr]generated gitlab-generated linguist-generated=true
|
||||
|
||||
# generated by autotools
|
||||
configure generated
|
||||
include/config.h.in generated
|
||||
|
||||
# generated by dlls/dsound/make_fir
|
||||
dlls/dsound/fir.h generated
|
||||
|
||||
# generated by dlls/opencl/make_opencl
|
||||
dlls/opencl/opencl.spec generated
|
||||
dlls/opencl/opencl_types.h generated
|
||||
dlls/opencl/pe_thunks.c generated
|
||||
dlls/opencl/unix_thunks.c generated
|
||||
dlls/opencl/unixlib.h generated
|
||||
|
||||
# generated by dlls/opengl32/make_opengl
|
||||
dlls/opengl32/opengl32.spec generated
|
||||
dlls/opengl32/thunks.c generated
|
||||
dlls/opengl32/unix_thunks.c generated
|
||||
dlls/opengl32/unixlib.h generated
|
||||
include/wine/wgl.h generated
|
||||
include/wine/wgl_driver.h generated
|
||||
|
||||
# generated by dlls/winevulkan/make_vulkan
|
||||
dlls/vulkan-1/vulkan-1.spec generated
|
||||
dlls/winevulkan/loader_thunks.c generated
|
||||
dlls/winevulkan/loader_thunks.h generated
|
||||
dlls/winevulkan/vulkan_thunks.c generated
|
||||
dlls/winevulkan/vulkan_thunks.h generated
|
||||
dlls/winevulkan/winevulkan.json generated
|
||||
dlls/winevulkan/winevulkan.spec generated
|
||||
include/wine/vulkan.h generated
|
||||
include/wine/vulkan_driver.h generated
|
||||
|
||||
# generated by tools/make_requests
|
||||
include/wine/server_protocol.h generated
|
||||
server/request_handlers.h generated
|
||||
server/request_trace.h generated
|
||||
|
||||
# generated by tools/make_specfiles
|
||||
dlls/ntdll/ntsyscalls.h generated
|
||||
dlls/win32u/win32syscalls.h generated
|
||||
|
||||
# generated by tools/make_unicode
|
||||
dlls/dwrite/bracket.c generated
|
||||
dlls/dwrite/direction.c generated
|
||||
dlls/dwrite/linebreak.c generated
|
||||
dlls/dwrite/mirror.c generated
|
||||
dlls/dwrite/scripts.c generated
|
||||
dlls/dwrite/scripts.h generated
|
||||
dlls/dwrite/shapers/arabic_table.c generated
|
||||
dlls/gdi32/uniscribe/bracket.c generated
|
||||
dlls/gdi32/uniscribe/direction.c generated
|
||||
dlls/gdi32/uniscribe/indicsyllable.c generated
|
||||
dlls/gdi32/uniscribe/linebreak.c generated
|
||||
dlls/gdi32/uniscribe/mirror.c generated
|
||||
dlls/gdi32/uniscribe/shaping.c generated
|
||||
dlls/kernelbase/kernelbase.rgs generated
|
||||
dlls/tzres/tzres.rc generated
|
||||
dlls/win32u/vertical.c generated
|
||||
dlls/wineps.drv/direction.c generated
|
||||
dlls/wineps.drv/vertical.c generated
|
||||
nls/*.nls generated
|
3
aclocal.m4
vendored
3
aclocal.m4
vendored
|
@ -198,6 +198,9 @@ ac_wine_try_cflags_saved_exeext=$ac_exeext
|
|||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs $1"
|
||||
ac_exeext=".exe"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }]])],
|
||||
[AS_VAR_SET(ac_var,yes)], [AS_VAR_SET(ac_var,no)])
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
|
|
186
configure
generated
vendored
186
configure
generated
vendored
|
@ -10407,6 +10407,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10444,6 +10447,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10660,6 +10666,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10696,6 +10705,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10732,6 +10744,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10768,6 +10783,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10804,6 +10822,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10840,6 +10861,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10876,6 +10900,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10912,6 +10939,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10948,6 +10978,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -10984,6 +11017,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11020,6 +11056,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11056,6 +11095,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11092,6 +11134,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11128,6 +11173,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11164,6 +11212,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11200,6 +11251,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11236,6 +11290,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11272,6 +11329,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11308,6 +11368,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11344,6 +11407,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11380,6 +11446,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11403,6 +11472,86 @@ then :
|
|||
as_fn_append ${wine_arch}_EXTRACFLAGS " -Wenum-conversion"
|
||||
fi } ;;
|
||||
esac
|
||||
fi }
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-ffunction-sections" | sed "$as_sed_sh"`
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -ffunction-sections" >&5
|
||||
printf %s "checking whether $CC supports -ffunction-sections... " >&6; }
|
||||
if eval test \${$as_ac_var+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else case e in #(
|
||||
e) ac_wine_try_cflags_saved=$CFLAGS
|
||||
ac_wine_try_cflags_saved_exeext=$ac_exeext
|
||||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -ffunction-sections"
|
||||
ac_exeext=".exe"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
eval "$as_ac_var=yes"
|
||||
else case e in #(
|
||||
e) eval "$as_ac_var=no" ;;
|
||||
esac
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
ac_exeext=$ac_wine_try_cflags_saved_exeext ;;
|
||||
esac
|
||||
fi
|
||||
eval ac_res=\$$as_ac_var
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"
|
||||
then :
|
||||
as_fn_append ${wine_arch}_EXTRACFLAGS " -ffunction-sections"
|
||||
fi }
|
||||
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-fms-hotpatch -DMIN_CLANG_VERSION=18" | sed "$as_sed_sh"`
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -fms-hotpatch -DMIN_CLANG_VERSION=18" >&5
|
||||
printf %s "checking whether $CC supports -fms-hotpatch -DMIN_CLANG_VERSION=18... " >&6; }
|
||||
if eval test \${$as_ac_var+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else case e in #(
|
||||
e) ac_wine_try_cflags_saved=$CFLAGS
|
||||
ac_wine_try_cflags_saved_exeext=$ac_exeext
|
||||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -fms-hotpatch -DMIN_CLANG_VERSION=18"
|
||||
ac_exeext=".exe"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
eval "$as_ac_var=yes"
|
||||
else case e in #(
|
||||
e) eval "$as_ac_var=no" ;;
|
||||
esac
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
ac_exeext=$ac_wine_try_cflags_saved_exeext ;;
|
||||
esac
|
||||
fi
|
||||
eval ac_res=\$$as_ac_var
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"
|
||||
then :
|
||||
as_fn_append ${wine_arch}_EXTRACFLAGS " -fms-hotpatch"
|
||||
as_fn_append ${wine_arch}_LDFLAGS " -fms-hotpatch"
|
||||
fi }
|
||||
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-flarge-source-files -Wmisleading-indentation" | sed "$as_sed_sh"`
|
||||
|
@ -11419,6 +11568,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11457,6 +11609,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11493,6 +11648,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11529,6 +11687,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11565,6 +11726,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11601,6 +11765,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11637,6 +11804,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11673,6 +11843,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11732,6 +11905,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11768,6 +11944,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11808,6 +11987,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -11844,6 +12026,9 @@ ac_exeext=".exe"
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
|
||||
#error Too old clang version
|
||||
#endif
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
|
@ -22885,6 +23070,7 @@ wine_fn_config_makefile programs/msidb enable_msidb
|
|||
wine_fn_config_makefile programs/msiexec enable_msiexec
|
||||
wine_fn_config_makefile programs/msinfo32 enable_msinfo32
|
||||
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/netstat enable_netstat
|
||||
wine_fn_config_makefile programs/ngen enable_ngen
|
||||
|
|
|
@ -961,6 +961,12 @@ This is an error since --enable-archs=$wine_arch was requested.])])
|
|||
WINE_TRY_PE_CFLAGS([-Wlogical-op])
|
||||
WINE_TRY_PE_CFLAGS([-Wabsolute-value])
|
||||
WINE_TRY_PE_CFLAGS([-Wenum-enum-conversion],[:],WINE_TRY_PE_CFLAGS([-Wenum-conversion]))
|
||||
WINE_TRY_PE_CFLAGS([-ffunction-sections])
|
||||
|
||||
dnl clang had broken -fms-hotpatch support before version 18 (https://github.com/llvm/llvm-project/pull/77245)
|
||||
WINE_TRY_PE_CFLAGS([-fms-hotpatch -DMIN_CLANG_VERSION=18],
|
||||
[AS_VAR_APPEND([${wine_arch}_EXTRACFLAGS],[" -fms-hotpatch"])
|
||||
AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -fms-hotpatch"])])
|
||||
|
||||
dnl GCC can't handle large files when -Wmisleading-indentation is enabled (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89549)
|
||||
WINE_TRY_PE_CFLAGS([-flarge-source-files -Wmisleading-indentation],[AS_VAR_APPEND(${wine_arch}_EXTRACFLAGS,[" -Wno-misleading-indentation"])])
|
||||
|
@ -3462,6 +3468,7 @@ WINE_CONFIG_MAKEFILE(programs/msidb)
|
|||
WINE_CONFIG_MAKEFILE(programs/msiexec)
|
||||
WINE_CONFIG_MAKEFILE(programs/msinfo32)
|
||||
WINE_CONFIG_MAKEFILE(programs/net)
|
||||
WINE_CONFIG_MAKEFILE(programs/net/tests)
|
||||
WINE_CONFIG_MAKEFILE(programs/netsh)
|
||||
WINE_CONFIG_MAKEFILE(programs/netstat)
|
||||
WINE_CONFIG_MAKEFILE(programs/ngen)
|
||||
|
|
|
@ -4150,6 +4150,7 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||
/* see if we are supposed to be tracking mouse hovering */
|
||||
if (LISTVIEW_IsHotTracking(infoPtr)) {
|
||||
TRACKMOUSEEVENT trackinfo;
|
||||
NMLISTVIEW nmlv = { 0 };
|
||||
DWORD flags;
|
||||
|
||||
trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
|
@ -4170,6 +4171,15 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||
/* call TRACKMOUSEEVENT so we receive WM_MOUSEHOVER messages */
|
||||
_TrackMouseEvent(&trackinfo);
|
||||
}
|
||||
|
||||
ht.pt = pt;
|
||||
LISTVIEW_HitTest(infoPtr, &ht, TRUE, TRUE);
|
||||
|
||||
nmlv.iItem = ht.iItem;
|
||||
nmlv.iSubItem = ht.iSubItem;
|
||||
nmlv.ptAction = pt;
|
||||
|
||||
notify_listview(infoPtr, LVN_HOTTRACK, &nmlv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -9585,6 +9595,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, const CREATESTRUCTW *
|
|||
infoPtr->iVersion = COMCTL32_VERSION;
|
||||
infoPtr->colRectsDirty = FALSE;
|
||||
infoPtr->selected_column = -1;
|
||||
infoPtr->hHotCursor = LoadCursorW(NULL, (LPWSTR)IDC_HAND);
|
||||
|
||||
/* get default font (icon title) */
|
||||
SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
|
||||
|
|
|
@ -7255,6 +7255,19 @@ static void test_LVM_GETNEXTITEM(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_LVM_GETHOTCURSOR(void)
|
||||
{
|
||||
HCURSOR cursor;
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = create_listview_control(LVS_REPORT);
|
||||
|
||||
cursor = (HCURSOR)SendMessageA(hwnd, LVM_GETHOTCURSOR, 0, 0);
|
||||
ok(!!cursor, "Unexpected cursor %p.\n", cursor);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(listview)
|
||||
{
|
||||
ULONG_PTR ctx_cookie;
|
||||
|
@ -7322,6 +7335,7 @@ START_TEST(listview)
|
|||
test_LVM_SETBKIMAGE(FALSE);
|
||||
test_custom_sort();
|
||||
test_LVM_GETNEXTITEM();
|
||||
test_LVM_GETHOTCURSOR();
|
||||
|
||||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
{
|
||||
|
@ -7372,6 +7386,7 @@ START_TEST(listview)
|
|||
test_LVM_GETNEXTITEMINDEX();
|
||||
test_LVM_GETNEXTITEM();
|
||||
test_LVM_SETBKIMAGE(TRUE);
|
||||
test_LVM_GETHOTCURSOR();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
|
||||
|
|
|
@ -300,20 +300,6 @@ BOOL WINAPI SymGetSearchPath(HANDLE hProcess, PSTR szSearchPath,
|
|||
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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
pcs->loader = &empty_loader_ops;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -510,8 +499,9 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP
|
|||
if (check_live_target(pcs, wow64, child_wow64))
|
||||
{
|
||||
if (fInvadeProcess)
|
||||
EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess);
|
||||
if (pcs->loader) pcs->loader->synchronize_module_list(pcs);
|
||||
module_refresh_list(pcs);
|
||||
else
|
||||
pcs->loader->synchronize_module_list(pcs);
|
||||
}
|
||||
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 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_refresh_list(struct process *pcs);
|
||||
|
||||
/* msc.c */
|
||||
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");
|
||||
module_remove(pcs, elf_info.module);
|
||||
pcs->loader = &empty_loader_ops;
|
||||
return FALSE;
|
||||
}
|
||||
TRACE("Found ELF debug header %#I64x\n", elf_info.dbg_hdr_addr);
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "dbghelp_private.h"
|
||||
#include "image_private.h"
|
||||
#include "psapi.h"
|
||||
|
@ -1317,7 +1319,11 @@ BOOL WINAPI EnumerateLoadedModulesW64(HANDLE process,
|
|||
size_t sysdir_len = 0, wowdir_len = 0;
|
||||
|
||||
/* 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) &&
|
||||
pcs_machine != IMAGE_FILE_MACHINE_UNKNOWN &&
|
||||
(dbghelp_options & SYMOPT_INCLUDE_32BIT_MODULES);
|
||||
|
@ -1600,18 +1606,41 @@ void module_reset_debug_info(struct module* module)
|
|||
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.@)
|
||||
*/
|
||||
BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
|
||||
{
|
||||
struct process* pcs;
|
||||
struct process *pcs;
|
||||
|
||||
TRACE("(%p)\n", hProcess);
|
||||
|
||||
if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
|
||||
|
||||
return pcs->loader->synchronize_module_list(pcs);
|
||||
return module_refresh_list(pcs);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -4379,7 +4379,13 @@ static BOOL codeview_process_info(const struct process *pcs,
|
|||
|
||||
TRACE("Got RSDS type of PDB file: guid=%s age=%08x name=%s\n",
|
||||
wine_dbgstr_guid(&rsds->guid), rsds->age, debugstr_a(rsds->name));
|
||||
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
|
||||
/* gcc/mingw and clang can emit build-id information, but with an empty PDB filename.
|
||||
* Don't search for the .pdb file in that case.
|
||||
*/
|
||||
if (rsds->name[0])
|
||||
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
|
||||
else
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -4487,7 +4493,7 @@ typedef struct _FPO_DATA
|
|||
__ENDTRY
|
||||
|
||||
/* we haven't found yet any debug information, fallback to unmatched pdb */
|
||||
if (module->module.SymType == SymDeferred)
|
||||
if (!ret && module->module.SymType == SymDeferred)
|
||||
{
|
||||
SYMSRV_INDEX_INFOW info = {.sizeofstruct = sizeof(info)};
|
||||
char buffer[MAX_PATH];
|
||||
|
@ -4549,38 +4555,35 @@ DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* debug_dir
|
|||
num_misc_records++;
|
||||
}
|
||||
}
|
||||
return info->stripped && !num_misc_records ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
|
||||
return (!num_dir || (info->stripped && !num_misc_records)) ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
||||
{
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER *header;
|
||||
IMAGE_DEBUG_DIRECTORY *dbg;
|
||||
DWORD num_directories;
|
||||
|
||||
if (size < sizeof(*header)) return ERROR_BAD_EXE_FORMAT;
|
||||
if (size < sizeof(*header)) return ERROR_BAD_FORMAT;
|
||||
header = image;
|
||||
if (header->Signature != 0x4944 /* DI */ ||
|
||||
size < sizeof(*header) + header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + header->ExportedNamesSize + header->DebugDirectorySize)
|
||||
return ERROR_BAD_EXE_FORMAT;
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
info->size = header->SizeOfImage;
|
||||
/* seems to use header's timestamp, not debug_directory one */
|
||||
info->timestamp = header->TimeDateStamp;
|
||||
info->stripped = FALSE; /* FIXME */
|
||||
|
||||
/* header is followed by:
|
||||
* - header->NumberOfSections of IMAGE_SECTION_HEADER
|
||||
* - header->ExportedNameSize
|
||||
* - then num_directories of IMAGE_DEBUG_DIRECTORY
|
||||
*/
|
||||
dbg = (IMAGE_DEBUG_DIRECTORY*)((char*)(header + 1) +
|
||||
header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
|
||||
header->ExportedNamesSize);
|
||||
num_directories = header->DebugDirectorySize / sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
if (!num_directories) return ERROR_BAD_EXE_FORMAT;
|
||||
|
||||
info->age = 0;
|
||||
memset(&info->guid, 0, sizeof(info->guid));
|
||||
info->sig = 0;
|
||||
info->dbgfile[0] = L'\0';
|
||||
info->pdbfile[0] = L'\0';
|
||||
info->size = header->SizeOfImage;
|
||||
/* seems to use header's timestamp, not debug_directory one */
|
||||
info->timestamp = header->TimeDateStamp;
|
||||
info->stripped = FALSE; /* FIXME */
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
return msc_get_file_indexinfo(image, dbg, num_directories, info);
|
||||
}
|
||||
|
|
|
@ -832,7 +832,7 @@ BOOL WINAPI SymSrvGetFileIndexInfoW(const WCHAR *file, SYMSRV_INDEX_INFOW* info,
|
|||
if (hMap) CloseHandle(hMap);
|
||||
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
|
||||
|
||||
if (ret == ERROR_SUCCESS) wcscpy(info->file, file_name(file)); /* overflow? */
|
||||
if (ret == ERROR_SUCCESS || ret == ERROR_BAD_EXE_FORMAT) wcscpy(info->file, file_name(file)); /* overflow? */
|
||||
SetLastError(ret);
|
||||
return ret == ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -656,8 +656,8 @@ static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* mod
|
|||
if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC ||
|
||||
misc->DataType != IMAGE_DEBUG_MISC_EXENAME)
|
||||
{
|
||||
ERR("-Debug info stripped, but no .DBG file in module %s\n",
|
||||
debugstr_w(module->modulename));
|
||||
WARN("-Debug info stripped, but no .DBG file in module %s\n",
|
||||
debugstr_w(module->modulename));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1019,7 +1019,7 @@ DWORD pe_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
|||
if (!(nthdr = RtlImageNtHeader(image))) return ERROR_BAD_FORMAT;
|
||||
|
||||
dbg = RtlImageDirectoryEntryToData(image, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &dirsize);
|
||||
if (!dbg || dirsize < sizeof(dbg)) return ERROR_BAD_EXE_FORMAT;
|
||||
if (!dbg) dirsize = 0;
|
||||
|
||||
/* fill in information from NT header */
|
||||
info->timestamp = nthdr->FileHeader.TimeDateStamp;
|
||||
|
|
|
@ -372,6 +372,29 @@ static unsigned get_native_module_count(HANDLE proc)
|
|||
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
|
||||
{
|
||||
HANDLE proc;
|
||||
|
@ -424,6 +447,28 @@ static BOOL wrapper_EnumerateLoadedModulesW64(HANDLE proc, PENUMLOADED_MODULES_C
|
|||
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)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -492,6 +537,7 @@ static BOOL test_modules(void)
|
|||
|
||||
ret = SymRefreshModuleList(dummy);
|
||||
ok(!ret, "SymRefreshModuleList should have failed\n");
|
||||
ok(GetLastError() == STATUS_INVALID_CID, "Unexpected last error %lx\n", GetLastError());
|
||||
|
||||
count = get_module_count(dummy);
|
||||
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());
|
||||
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 */
|
||||
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
||||
ok(ret, "CreateProcess failed: %lu\n", GetLastError());
|
||||
|
@ -885,9 +936,10 @@ static void test_loaded_modules(void)
|
|||
|
||||
pcskind = get_process_kind(pi.hProcess);
|
||||
|
||||
ret = SymRefreshModuleList(pi.hProcess);
|
||||
todo_wine_if(pcskind == PCSKIND_WOW64)
|
||||
ok(ret || broken(GetLastError() == STATUS_PARTIAL_COPY /* Win11 in some cases */), "SymRefreshModuleList failed: %lu\n", GetLastError());
|
||||
ret = wrapper_SymRefreshModuleList(pi.hProcess);
|
||||
ok(ret || broken(GetLastError() == STATUS_PARTIAL_COPY /* Win11 in some cases */ ||
|
||||
GetLastError() == STATUS_INFO_LENGTH_MISMATCH /* Win11 in some cases */),
|
||||
"SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||
|
||||
if (!strcmp(winetest_platform, "wine"))
|
||||
{
|
||||
|
@ -945,8 +997,8 @@ static void test_loaded_modules(void)
|
|||
"Wrong directory aggregation count %u %u\n",
|
||||
aggregation.count_systemdir, aggregation.count_wowdir);
|
||||
}
|
||||
ret = SymRefreshModuleList(pi.hProcess);
|
||||
ok(ret, "SymRefreshModuleList failed: %lu\n", GetLastError());
|
||||
ret = wrapper_SymRefreshModuleList(pi.hProcess);
|
||||
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||
|
||||
if (!strcmp(winetest_platform, "wine"))
|
||||
{
|
||||
|
@ -1007,8 +1059,8 @@ static void test_loaded_modules(void)
|
|||
break;
|
||||
}
|
||||
|
||||
ret = SymRefreshModuleList(pi.hProcess);
|
||||
ok(ret, "SymRefreshModuleList failed: %lu\n", GetLastError());
|
||||
ret = wrapper_SymRefreshModuleList(pi.hProcess);
|
||||
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||
|
||||
if (!strcmp(winetest_platform, "wine"))
|
||||
{
|
||||
|
@ -1529,6 +1581,75 @@ static void test_function_tables(void)
|
|||
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)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -1559,6 +1680,7 @@ START_TEST(dbghelp)
|
|||
test_modules_overlap();
|
||||
test_loaded_modules();
|
||||
test_live_modules();
|
||||
test_refresh_modules();
|
||||
}
|
||||
test_function_tables();
|
||||
}
|
||||
|
|
|
@ -671,20 +671,22 @@ static BOOL create_test_pdb_ds(const WCHAR* pdb_name, const GUID* guid, DWORD ag
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp, DWORD size)
|
||||
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD charac, DWORD timestamp, DWORD size, struct debug_directory_blob *blob)
|
||||
{
|
||||
HANDLE hfile;
|
||||
|
||||
/* minimalistic .dbg made of a header and a DEBUG_DIRECTORY without any data */
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER header = {.Signature = 0x4944 /* DI */,
|
||||
.Flags = 0, .Machine = machine, .Characteristics = 0x010E, .TimeDateStamp = timestamp,
|
||||
IMAGE_SEPARATE_DEBUG_HEADER header =
|
||||
{
|
||||
.Signature = 0x4944 /* DI */,
|
||||
.Flags = 0, .Machine = machine, .Characteristics = charac, .TimeDateStamp = timestamp,
|
||||
.CheckSum = 0, .ImageBase = 0x00040000, .SizeOfImage = size, .NumberOfSections = 0,
|
||||
.ExportedNamesSize = 0, .DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY)};
|
||||
const IMAGE_DEBUG_DIRECTORY debug_dir = {.Characteristics = 0, .TimeDateStamp = timestamp + 1,
|
||||
.MajorVersion = 0, .MinorVersion = 0, .Type = IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
.SizeOfData = 0, .AddressOfRawData = 0,
|
||||
.PointerToRawData = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
|
||||
header.DebugDirectorySize};
|
||||
.ExportedNamesSize = 0, .DebugDirectorySize = 0
|
||||
};
|
||||
DWORD where, expected_size;
|
||||
|
||||
if (blob)
|
||||
header.DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
hfile = CreateFileW(dbg_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
|
||||
ok(hfile != INVALID_HANDLE_VALUE, "failed to create %ls err %lu\n", dbg_name, GetLastError());
|
||||
|
@ -692,8 +694,18 @@ static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp
|
|||
|
||||
check_write_file(hfile, &header, sizeof(header));
|
||||
/* FIXME: 0 sections... as header.NumberOfSections */
|
||||
check_write_file(hfile, &debug_dir, sizeof(debug_dir));
|
||||
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == debug_dir.PointerToRawData, "mismatch\n");
|
||||
if (blob)
|
||||
{
|
||||
where = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
|
||||
blob->debug_directory.PointerToRawData = (blob->debug_directory.SizeOfData) ?
|
||||
where + sizeof(IMAGE_DEBUG_DIRECTORY) : 0;
|
||||
check_write_file(hfile, &blob->debug_directory, sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
check_write_file(hfile, blob->content, blob->debug_directory.SizeOfData);
|
||||
}
|
||||
expected_size = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
|
||||
if (blob)
|
||||
expected_size += sizeof(IMAGE_DEBUG_DIRECTORY) + blob->debug_directory.SizeOfData;
|
||||
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == expected_size, "Incorrect file length\n");
|
||||
|
||||
CloseHandle(hfile);
|
||||
return TRUE;
|
||||
|
@ -725,16 +737,16 @@ static void test_srvgetindexes_pe(void)
|
|||
DWORD sig;
|
||||
WCHAR pdb_name[16];
|
||||
WCHAR dbg_name[16];
|
||||
BOOL in_error;
|
||||
DWORD last_error;
|
||||
}
|
||||
indexes[] =
|
||||
{
|
||||
/* error cases */
|
||||
/* 0 */{0, {-1, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, .in_error = TRUE}, /* not 100% logical ! */
|
||||
/* 0 */{0, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, 124, &guid1, 0, .pdb_name = L"pdbds.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT}, /* not 100% logical ! */
|
||||
/* success */
|
||||
/* 5 */{0, { 0, -1, -1}, 0, &null_guid, 0 },
|
||||
{0, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb"},
|
||||
|
@ -796,16 +808,16 @@ static void test_srvgetindexes_pe(void)
|
|||
memset(&ssii, 0xa5, sizeof(ssii));
|
||||
ssii.sizeofstruct = sizeof(ssii);
|
||||
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
|
||||
if (indexes[i].in_error)
|
||||
if (indexes[i].last_error)
|
||||
{
|
||||
ok(!ret, "SymSrvGetFileIndexInfo should have failed\n");
|
||||
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Mismatch in GetLastError: %lu\n", GetLastError());
|
||||
ok(GetLastError() == indexes[i].last_error, "Mismatch in GetLastError: %lu\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
|
||||
if (ret || indexes[i].last_error == ERROR_BAD_EXE_FORMAT)
|
||||
{
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lu\n", ssii.age);
|
||||
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
|
||||
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
|
||||
|
||||
|
@ -882,48 +894,69 @@ static void test_srvgetindexes_dbg(void)
|
|||
WCHAR filename[128];
|
||||
SYMSRV_INDEX_INFOW ssii;
|
||||
BOOL ret;
|
||||
struct debug_directory_blob *blob_refs[1];
|
||||
|
||||
static struct
|
||||
{
|
||||
/* input parameters */
|
||||
WORD machine;
|
||||
DWORD timestamp;
|
||||
DWORD imagesize;
|
||||
WORD machine;
|
||||
DWORD characteristics;
|
||||
DWORD timestamp;
|
||||
DWORD imagesize;
|
||||
int blob;
|
||||
/* output parameters */
|
||||
DWORD age;
|
||||
const GUID *guid;
|
||||
WCHAR pdbname[16];
|
||||
WCHAR dbgname[16];
|
||||
DWORD last_error;
|
||||
}
|
||||
indexes[] =
|
||||
{
|
||||
{IMAGE_FILE_MACHINE_I386, 0x1234, 0x00560000},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0x1235, 0x00570000},
|
||||
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
|
||||
};
|
||||
|
||||
blob_refs[0] = make_pdb_ds_blob(0x1226, &guid1, 123, "foo.pdb");
|
||||
for (i = 0; i < ARRAY_SIZE(indexes); i++)
|
||||
{
|
||||
winetest_push_context("dbg#%02u", i);
|
||||
|
||||
/* create dll */
|
||||
swprintf(filename, ARRAY_SIZE(filename), L"winetest%02u.dbg", i);
|
||||
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].timestamp, indexes[i].imagesize);
|
||||
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].characteristics,
|
||||
indexes[i].timestamp, indexes[i].imagesize,
|
||||
indexes[i].blob == -1 ? NULL : blob_refs[indexes[i].blob]);
|
||||
ok(ret, "Couldn't create dbg file %ls\n", filename);
|
||||
|
||||
memset(&ssii, 0x45, sizeof(ssii));
|
||||
ssii.sizeofstruct = sizeof(ssii);
|
||||
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
if (indexes[i].last_error)
|
||||
{
|
||||
ok(!ret, "SymSrvGetFileIndexInfo should have\n");
|
||||
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Unexpected last error: %lu\n", GetLastError());
|
||||
}
|
||||
else
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
|
||||
ok(ssii.age == 0, "Mismatch in age: %lx\n", ssii.age);
|
||||
ok(!memcmp(&ssii.guid, &null_guid, sizeof(GUID)),
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
|
||||
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
|
||||
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
|
||||
|
||||
ok(ssii.sig == 0, "Mismatch in sig: %lx\n", ssii.sig);
|
||||
ok(ssii.size == indexes[i].imagesize, "Mismatch in size: %lx\n", ssii.size);
|
||||
ok(!ssii.stripped, "Mismatch in stripped: %x\n", ssii.stripped);
|
||||
ok(ssii.timestamp == indexes[i].timestamp, "Mismatch in timestamp: %lx\n", ssii.timestamp);
|
||||
ok(!wcscmp(ssii.file, filename), "Mismatch in file: %ls\n", ssii.file);
|
||||
ok(!ssii.pdbfile[0], "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
|
||||
ok(!ssii.dbgfile[0], "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
|
||||
ok(!wcscmp(ssii.pdbfile, indexes[i].pdbname), "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
|
||||
ok(!wcscmp(ssii.dbgfile, indexes[i].dbgname), "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
|
||||
|
||||
DeleteFileW(filename);
|
||||
winetest_pop_context();
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(blob_refs); i++) free(blob_refs[i]);
|
||||
}
|
||||
|
||||
static void make_path(WCHAR file[MAX_PATH], const WCHAR* topdir, const WCHAR* subdir, const WCHAR* base)
|
||||
|
@ -1533,7 +1566,8 @@ static void test_load_modules_path(void)
|
|||
if (test_files[val].guid)
|
||||
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
|
||||
else
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
|
||||
/*create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, blob); */
|
||||
ok(0, "not supported yet\n");
|
||||
}
|
||||
else ok(0, "Unrecognized file reference %c\n", *ptr);
|
||||
}
|
||||
|
@ -1754,7 +1788,7 @@ static void test_load_modules_details(void)
|
|||
if (test_files[val].guid)
|
||||
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
|
||||
else
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, NULL);
|
||||
}
|
||||
else ok(0, "Unrecognized file reference %c\n", *ptr);
|
||||
}
|
||||
|
|
|
@ -306,20 +306,13 @@ static void warp_check( struct mouse *impl, BOOL force )
|
|||
|
||||
if (force || (impl->need_warp && (now - impl->last_warped > interval)))
|
||||
{
|
||||
RECT rect, new_rect;
|
||||
POINT mapped_center;
|
||||
RECT rect;
|
||||
|
||||
impl->last_warped = now;
|
||||
impl->need_warp = FALSE;
|
||||
if (!GetClientRect( impl->base.win, &rect )) return;
|
||||
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)
|
||||
{
|
||||
/* 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.bottom = min( rect.bottom, rect.top + GetSystemMetrics( SM_CYVIRTUALSCREEN ) - 2 );
|
||||
TRACE("Clipping mouse to %s\n", wine_dbgstr_rect( &rect ));
|
||||
ClipCursor( &rect );
|
||||
impl->clipped = GetClipCursor( &new_rect ) && EqualRect( &rect, &new_rect );
|
||||
impl->clipped = ClipCursor( &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;
|
||||
}
|
||||
|
||||
static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, const DPNAME *lpName,
|
||||
DWORD dwFlags, DPID idParent, 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 )
|
||||
{
|
||||
struct GroupList *groupList = NULL;
|
||||
struct GroupData *parent = NULL;
|
||||
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 */
|
||||
lpGData = calloc( 1, sizeof( *lpGData ) );
|
||||
|
||||
if( lpGData == NULL )
|
||||
{
|
||||
return NULL;
|
||||
return DPERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
DPQ_INIT(lpGData->groups);
|
||||
|
@ -1304,7 +1315,7 @@ static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, cons
|
|||
if ( !lpGData->name )
|
||||
{
|
||||
free( lpGData );
|
||||
return NULL;
|
||||
return DPERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
lpGData->nameA = DP_DuplicateName( lpName, TRUE, bAnsi );
|
||||
|
@ -1312,11 +1323,10 @@ static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, cons
|
|||
{
|
||||
free( lpGData->name );
|
||||
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? */
|
||||
lpGData->dwFlags = dwFlags;
|
||||
|
@ -1328,12 +1338,83 @@ static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, cons
|
|||
free( lpGData->nameA );
|
||||
free( lpGData->name );
|
||||
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 );
|
||||
|
||||
return lpGData;
|
||||
return DP_OK;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
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",
|
||||
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,
|
||||
DPID_NOPARENT_GROUP, bAnsi );
|
||||
hr = DP_CreateGroup( This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
|
||||
DPID_NOPARENT_GROUP, bAnsi );
|
||||
|
||||
if( lpGData == NULL )
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
return DPERR_CANTADDPLAYER; /* yes player not group */
|
||||
}
|
||||
|
||||
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 );
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
BOOL bAnsi )
|
||||
{
|
||||
lpGroupData lpGParentData;
|
||||
lpGroupList lpGList;
|
||||
lpGroupData lpGData;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
|
||||
This, idParentGroup, lpidGroup, lpGroupName, lpData,
|
||||
|
@ -4471,48 +4501,12 @@ static HRESULT DP_IF_CreateGroupInGroup( IDirectPlayImpl *This, void *lpMsgHdr,
|
|||
return DPERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
/* Verify that the specified parent is valid */
|
||||
if( ( lpGParentData = DP_FindAnyGroup(This, idParentGroup ) ) == NULL )
|
||||
return DPERR_INVALIDGROUP;
|
||||
hr = DP_CreateGroup(This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
|
||||
idParentGroup, bAnsi );
|
||||
|
||||
lpGData = DP_CreateGroup(This, lpidGroup, lpGroupName, dwFlags, idParentGroup, bAnsi );
|
||||
|
||||
if( lpGData == NULL )
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
return DPERR_CANTADDPLAYER; /* yes player not group */
|
||||
}
|
||||
|
||||
/* 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 );
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
void *data, DWORD dataSize, void *spData, DWORD spDataSize, DWORD dwFlags,
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
|
|
|
@ -1224,12 +1224,14 @@ static void checkGameMessage_( int line, GameMessage *message, DPID expectedFrom
|
|||
static unsigned short receiveEnumSessionsRequest_( int line, SOCKET sock, const GUID *expectedAppGuid,
|
||||
const WCHAR *expectedPassword, DWORD expectedFlags )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
EnumSessionsRequest request;
|
||||
WCHAR password[ 256 ];
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
DWORD expectedPasswordSize;
|
||||
unsigned short port;
|
||||
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 )
|
||||
static void sendEnumSessionsReply_( int line, SOCKET sock, unsigned short port, const DPSESSIONDESC2 *dpsd )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
|
@ -1295,6 +1298,7 @@ static void sendEnumSessionsReply_( int line, SOCKET sock, unsigned short port,
|
|||
.nameOffset = sizeof( reply.reply ),
|
||||
},
|
||||
};
|
||||
#include "poppack.h"
|
||||
DWORD passwordSize;
|
||||
int wsResult;
|
||||
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 )
|
||||
static unsigned short receiveRequestPlayerId_( int line, SOCKET sock, DWORD expectedFlags )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
RequestPlayerId request;
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
unsigned short port;
|
||||
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 )
|
||||
static void sendRequestPlayerReply_( int line, SOCKET sock, unsigned short port, DPID id, HRESULT result )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
|
@ -1362,6 +1369,7 @@ static void sendRequestPlayerReply_( int line, SOCKET sock, unsigned short port,
|
|||
.result = result,
|
||||
},
|
||||
};
|
||||
#include "poppack.h"
|
||||
int wsResult;
|
||||
|
||||
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,
|
||||
unsigned short *udpPort )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
AddForwardRequest request;
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
DWORD expectedPasswordSize;
|
||||
WCHAR password[ 256 ];
|
||||
unsigned short port;
|
||||
|
@ -1427,25 +1437,53 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
|||
{
|
||||
#define SHORT_NAME L"short name"
|
||||
#define LONG_NAME L"long name"
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
SuperEnumPlayersReply reply;
|
||||
DPSESSIONDESC2 dpsd;
|
||||
WCHAR sessionName[ 256 ];
|
||||
SuperPackedPlayer superPackedPlayer0;
|
||||
BYTE spDataLength0;
|
||||
SpData spData0;
|
||||
SuperPackedPlayer superPackedPlayer1;
|
||||
BYTE spDataLength1;
|
||||
SpData spData1;
|
||||
SuperPackedPlayer superPackedPlayer2;
|
||||
WCHAR shortName[ ARRAYSIZE( SHORT_NAME ) ];
|
||||
WCHAR longName[ ARRAYSIZE( LONG_NAME ) ];
|
||||
BYTE playerDataLength2;
|
||||
BYTE playerData[ 4 ];
|
||||
BYTE spDataLength2;
|
||||
SpData spData2;
|
||||
struct
|
||||
{
|
||||
SuperPackedPlayer superPackedPlayer;
|
||||
BYTE spDataLength;
|
||||
SpData spData;
|
||||
} player0;
|
||||
struct
|
||||
{
|
||||
SuperPackedPlayer superPackedPlayer;
|
||||
BYTE spDataLength;
|
||||
SpData spData;
|
||||
} player1;
|
||||
struct
|
||||
{
|
||||
SuperPackedPlayer superPackedPlayer;
|
||||
WCHAR shortName[ ARRAYSIZE( SHORT_NAME ) ];
|
||||
WCHAR longName[ ARRAYSIZE( LONG_NAME ) ];
|
||||
BYTE playerDataLength;
|
||||
BYTE playerData[ 4 ];
|
||||
BYTE spDataLength;
|
||||
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 =
|
||||
{
|
||||
.spHeader =
|
||||
|
@ -1465,8 +1503,8 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
|||
.command = 41,
|
||||
.version = 14,
|
||||
},
|
||||
.playerCount = 3,
|
||||
.groupCount = 0,
|
||||
.playerCount = 4,
|
||||
.groupCount = 1,
|
||||
.packedOffset = sizeof( reply.reply ) + sizeof( reply.dpsd ) + sizeof( reply.sessionName ),
|
||||
.shortcutCount = 0,
|
||||
.descriptionOffset = sizeof( reply.reply ),
|
||||
|
@ -1474,77 +1512,143 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc
|
|||
.passwordOffset = 0,
|
||||
},
|
||||
.dpsd = *dpsd,
|
||||
.superPackedPlayer0 =
|
||||
.player0 =
|
||||
{
|
||||
.size = 16,
|
||||
.flags = 0x5,
|
||||
.id = 0x12345678,
|
||||
.infoMask = 0x4,
|
||||
.versionOrSystemPlayerId = 14,
|
||||
},
|
||||
.spDataLength0 = sizeof( SpData ),
|
||||
.spData0 =
|
||||
{
|
||||
.tcpAddr =
|
||||
.superPackedPlayer =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( tcpPort ),
|
||||
.size = 16,
|
||||
.flags = 0x5,
|
||||
.id = 0x12345678,
|
||||
.infoMask = 0x4,
|
||||
.versionOrSystemPlayerId = 14,
|
||||
},
|
||||
.udpAddr =
|
||||
.spDataLength = sizeof( SpData ),
|
||||
.spData =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( udpPort ),
|
||||
.tcpAddr =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( tcpPort ),
|
||||
},
|
||||
.udpAddr =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( udpPort ),
|
||||
},
|
||||
},
|
||||
},
|
||||
.superPackedPlayer1 =
|
||||
.player1 =
|
||||
{
|
||||
.size = 16,
|
||||
.flags = 0xf,
|
||||
.id = 0x51573,
|
||||
.infoMask = 0x4,
|
||||
.versionOrSystemPlayerId = 14,
|
||||
},
|
||||
.spDataLength1 = sizeof( SpData ),
|
||||
.spData1 =
|
||||
{
|
||||
.tcpAddr =
|
||||
.superPackedPlayer =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( tcpPort ),
|
||||
.size = 16,
|
||||
.flags = 0xf,
|
||||
.id = 0x51573,
|
||||
.infoMask = 0x4,
|
||||
.versionOrSystemPlayerId = 14,
|
||||
},
|
||||
.udpAddr =
|
||||
.spDataLength = sizeof( SpData ),
|
||||
.spData =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( udpPort ),
|
||||
.tcpAddr =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( tcpPort ),
|
||||
},
|
||||
.udpAddr =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( udpPort ),
|
||||
},
|
||||
},
|
||||
},
|
||||
.superPackedPlayer2 =
|
||||
.player2 =
|
||||
{
|
||||
.size = 16,
|
||||
.flags = 0x8,
|
||||
.id = 0x1337,
|
||||
.infoMask = 0x17,
|
||||
.versionOrSystemPlayerId = 0x51573,
|
||||
.superPackedPlayer =
|
||||
{
|
||||
.size = 16,
|
||||
.flags = 0x8,
|
||||
.id = 0x1337,
|
||||
.infoMask = 0x17,
|
||||
.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 ),
|
||||
},
|
||||
},
|
||||
},
|
||||
.shortName = SHORT_NAME,
|
||||
.longName = LONG_NAME,
|
||||
.playerDataLength2 = 4,
|
||||
.playerData = { 1, 2, 3, 4, },
|
||||
.spDataLength2 = sizeof( SpData ),
|
||||
.spData2 =
|
||||
.player3 =
|
||||
{
|
||||
.tcpAddr =
|
||||
.superPackedPlayer =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( tcpPort ),
|
||||
.size = 16,
|
||||
.flags = 0x8,
|
||||
.id = 0xd00de,
|
||||
.infoMask = 0x4,
|
||||
.versionOrSystemPlayerId = 0x51573,
|
||||
},
|
||||
.udpAddr =
|
||||
.spDataLength = sizeof( SpData ),
|
||||
.spData =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons( udpPort ),
|
||||
.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 SHORT_NAME
|
||||
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 )
|
||||
static void sendAddForwardReply_( int line, SOCKET sock, unsigned short port, HRESULT result )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
|
@ -1587,6 +1692,7 @@ static void sendAddForwardReply_( int line, SOCKET sock, unsigned short port, HR
|
|||
.result = result,
|
||||
},
|
||||
};
|
||||
#include "poppack.h"
|
||||
int wsResult;
|
||||
|
||||
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 )
|
||||
static void sendAddForward_( int line, SOCKET sock, unsigned short port, unsigned short tcpPort, unsigned short udpPort )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
|
@ -1653,6 +1760,7 @@ static void sendAddForward_( int line, SOCKET sock, unsigned short port, unsigne
|
|||
},
|
||||
},
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
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 )
|
||||
static unsigned short receiveAddForwardAck_( int line, SOCKET sock, DPID expectedPlayerId )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
AddForwardAck request;
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
unsigned short port;
|
||||
int wsResult;
|
||||
|
||||
|
@ -1688,11 +1798,13 @@ static unsigned short receiveCreatePlayer_( int line, SOCKET sock, DPID expected
|
|||
const WCHAR *expectedShortName, const WCHAR *expectedLongName,
|
||||
void *expectedPlayerData, DWORD expectedPlayerDataSize )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
CreatePlayer request;
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
DWORD expectedShortNameSize;
|
||||
DWORD expectedLongNameSize;
|
||||
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,
|
||||
const WCHAR *shortName, const WCHAR *longName, void *playerData, DWORD playerDataSize )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
|
@ -1820,6 +1933,7 @@ static void sendCreatePlayer_( int line, SOCKET sock, unsigned short tcpPort, un
|
|||
},
|
||||
},
|
||||
};
|
||||
#include "poppack.h"
|
||||
SpData spData = {
|
||||
.tcpAddr.sin_family = AF_INET,
|
||||
.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,
|
||||
void *expectedData, DWORD expectedDataSize )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
GameMessage request;
|
||||
BYTE data[ 256 ];
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
unsigned short port;
|
||||
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,
|
||||
DWORD expectedDataSize )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
GameMessage request;
|
||||
BYTE data[ 256 ];
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
int wsResult;
|
||||
|
||||
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,
|
||||
DWORD dataSize )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
|
@ -1945,6 +2064,7 @@ static void sendGuaranteedGameMessage_( int line, SOCKET sock, unsigned short po
|
|||
.toId = toId,
|
||||
}
|
||||
};
|
||||
#include "poppack.h"
|
||||
int wsResult;
|
||||
|
||||
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 )
|
||||
static void sendGameMessage_( int line, SOCKET sock, DPID fromId, DPID toId, void *data, DWORD dataSize )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
GameMessage request;
|
||||
|
@ -1970,6 +2091,7 @@ static void sendGameMessage_( int line, SOCKET sock, DPID fromId, DPID toId, voi
|
|||
.toId = toId,
|
||||
}
|
||||
};
|
||||
#include "poppack.h"
|
||||
int wsResult;
|
||||
DWORD size;
|
||||
|
||||
|
@ -1985,6 +2107,7 @@ static void sendGameMessage_( int line, SOCKET sock, DPID fromId, DPID toId, voi
|
|||
sendPing_( __LINE__, sock, port, fromId, tickCount )
|
||||
static void sendPing_( int line, SOCKET sock, unsigned short port, DPID fromId, DWORD tickCount )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
|
@ -2012,6 +2135,7 @@ static void sendPing_( int line, SOCKET sock, unsigned short port, DPID fromId,
|
|||
.tickCount = tickCount,
|
||||
}
|
||||
};
|
||||
#include "poppack.h"
|
||||
int wsResult;
|
||||
|
||||
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 )
|
||||
static unsigned short receivePingReply_( int line, SOCKET sock, DPID expectedFromId, DWORD expectedTickCount )
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct
|
||||
{
|
||||
SpHeader spHeader;
|
||||
Ping request;
|
||||
} request;
|
||||
#include "poppack.h"
|
||||
unsigned short port;
|
||||
int wsResult;
|
||||
|
||||
|
@ -2704,7 +2830,7 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const
|
|||
HRESULT hr;
|
||||
|
||||
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",
|
||||
playerType );
|
||||
if ( player->expectedShortName )
|
||||
|
@ -2727,20 +2853,28 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const
|
|||
ok_( __FILE__, data->line )( !name->lpszLongNameA, "got long name %s.\n",
|
||||
wine_dbgstr_a( name->lpszLongNameA ) );
|
||||
}
|
||||
ok_( __FILE__, data->line )( flags == player->expectedFlags, "got flags %#lx.\n", flags );
|
||||
todo_wine_if( playerType == DPPLAYERTYPE_GROUP && flags == DPENUMPLAYERS_LOCAL )
|
||||
ok_( __FILE__, data->line )( flags == player->expectedFlags, "got flags %#lx.\n", flags );
|
||||
|
||||
memset( &playerData, 0xcc, sizeof( playerData ) );
|
||||
playerDataSize = sizeof( playerData );
|
||||
hr = IDirectPlayX_GetPlayerData( data->dp, dpid, playerData, &playerDataSize, DPGET_REMOTE );
|
||||
if ( playerType == DPPLAYERTYPE_PLAYER )
|
||||
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 )( playerDataSize == player->expectedPlayerDataSize,
|
||||
"got player data size %lu.\n", playerDataSize );
|
||||
todo_wine_if( playerType == DPPLAYERTYPE_GROUP )
|
||||
ok_( __FILE__, data->line )( playerDataSize == player->expectedPlayerDataSize,
|
||||
"got player data size %lu.\n", playerDataSize );
|
||||
ok_( __FILE__, data->line )( !memcmp( playerData, player->expectedPlayerData, player->expectedPlayerDataSize ),
|
||||
"player data doesn't match.\n" );
|
||||
|
||||
memset( &nameData, 0xcc, sizeof( nameData ) );
|
||||
nameDataSize = sizeof( nameData );
|
||||
hr = IDirectPlayX_GetPlayerName( data->dp, dpid, &nameData, &nameDataSize );
|
||||
if ( playerType == DPPLAYERTYPE_PLAYER )
|
||||
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 )( ((DPNAME *) nameData)->dwSize == sizeof( DPNAME ),
|
||||
"got name size %lu.\n", ((DPNAME *) nameData)->dwSize );
|
||||
|
@ -2796,7 +2930,8 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const
|
|||
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 )
|
||||
{
|
||||
CheckPlayerListCallbackData data = {
|
||||
|
@ -2817,6 +2952,51 @@ static void checkPlayerList_( int line, IDirectPlay4 *dp, ExpectedPlayer *expect
|
|||
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, \
|
||||
expectedPlayerData, expectedPlayerDataSize ) \
|
||||
checkPlayerExists_( __LINE__, dp, expectedDpid, expectedPlayerType, expectedShortName, expectedLongName, \
|
||||
|
@ -2918,9 +3098,36 @@ static void check_Open_( int line, IDirectPlay4A *dp, DPSESSIONDESC2 *dpsd, cons
|
|||
.expectedPlayerData = 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 ) );
|
||||
checkGroupList_( line, dp, expectedGroups, ARRAYSIZE( expectedGroups ) );
|
||||
checkGroupPlayerList_( line, 0x5e7, dp, expectedGroupPlayers, ARRAYSIZE( expectedGroupPlayers ) );
|
||||
|
||||
hr = IDirectPlayX_Close( dp );
|
||||
checkHR( DP_OK, hr );
|
||||
|
@ -4648,20 +4855,20 @@ static void test_CreatePlayer(void)
|
|||
|
||||
/* Player name */
|
||||
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;
|
||||
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.dwSize = 1;
|
||||
dpid = 0xdeadbeef;
|
||||
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;
|
||||
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 */
|
||||
dpid = 0xdeadbeef;
|
||||
|
@ -4669,11 +4876,11 @@ static void test_CreatePlayer(void)
|
|||
|
||||
/* Flags */
|
||||
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;
|
||||
check_CreatePlayer( dp, &dpid, NULL, DPPLAYER_SPECTATOR, DP_OK, 7, recvSock, TRUE, 0x208, NULL, NULL, NULL, NULL,
|
||||
6 );
|
||||
7 );
|
||||
|
||||
closesocket( recvSock );
|
||||
closesocket( sendSock );
|
||||
|
@ -4920,7 +5127,7 @@ static void test_CREATEPLAYER(void)
|
|||
checkPlayerExists( dp, 0x07734, DPPLAYERTYPE_PLAYER, "new player short name", "new player long name",
|
||||
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 );
|
||||
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, 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 ) );
|
||||
todo_wine ok( hr == DPERR_INVALIDPARAM, "got hr %#lx.\n", hr );
|
||||
|
@ -8289,7 +8496,7 @@ static void test_Receive(void)
|
|||
waitResult = WaitForSingleObject( event0, 2000 );
|
||||
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, 0x14, data1, sizeof( data1 ) );
|
||||
|
|
|
@ -897,7 +897,7 @@ static HRESULT layout_shape_get_user_features(const struct dwrite_textlayout *la
|
|||
feature_count = IDWriteTypography_GetFontFeatureCount(typography);
|
||||
if (!feature_count)
|
||||
{
|
||||
i = range->h.range.length - i + 1;
|
||||
i = range->h.range.startPosition + range->h.range.length;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -656,7 +656,13 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val)
|
|||
TRACE("no prop_put\n");
|
||||
return S_OK;
|
||||
}
|
||||
return This->builtin_info->prop_put(This, prop->u.id, val);
|
||||
hres = This->builtin_info->prop_put(This, prop->u.id, val);
|
||||
if(hres != S_FALSE)
|
||||
return hres;
|
||||
prop->type = PROP_JSVAL;
|
||||
prop->flags = PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE;
|
||||
prop->u.val = jsval_undefined();
|
||||
break;
|
||||
default:
|
||||
ERR("type %d\n", prop->type);
|
||||
return E_FAIL;
|
||||
|
@ -2322,8 +2328,21 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatch *iface, DI
|
|||
static HRESULT WINAPI DispatchEx_GetMemberProperties(IWineJSDispatch *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
{
|
||||
jsdisp_t *This = impl_from_IWineJSDispatch(iface);
|
||||
FIXME("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
|
||||
return E_NOTIMPL;
|
||||
dispex_prop_t *prop;
|
||||
|
||||
TRACE("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
|
||||
|
||||
prop = get_prop(This, id);
|
||||
if(!prop)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
*pgrfdex = 0;
|
||||
|
||||
if(grfdexFetch) {
|
||||
FIXME("unimplemented flags %08lx\n", grfdexFetch);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetMemberName(IWineJSDispatch *iface, DISPID id, BSTR *pbstrName)
|
||||
|
@ -2369,7 +2388,19 @@ static void WINAPI WineJSDispatch_Free(IWineJSDispatch *iface)
|
|||
{
|
||||
jsdisp_t *This = impl_from_IWineJSDispatch(iface);
|
||||
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)
|
||||
{
|
||||
|
@ -2403,6 +2434,7 @@ static IWineJSDispatchVtbl DispatchExVtbl = {
|
|||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent,
|
||||
WineJSDispatch_Free,
|
||||
WineJSDispatch_GetPropertyFlags,
|
||||
WineJSDispatch_GetScriptGlobal,
|
||||
};
|
||||
|
||||
|
@ -3263,8 +3295,14 @@ HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t
|
|||
if(desc->explicit_value) {
|
||||
if(prop->type == PROP_JSVAL)
|
||||
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;
|
||||
}
|
||||
hres = jsval_copy(desc->value, &prop->u.val);
|
||||
if(FAILED(hres)) {
|
||||
prop->u.val = jsval_undefined();
|
||||
|
|
|
@ -943,7 +943,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -952,7 +952,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -961,7 +961,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -970,7 +970,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -979,7 +979,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -988,7 +988,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -997,42 +997,42 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(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));
|
||||
if(FAILED(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));
|
||||
if(FAILED(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));
|
||||
if(FAILED(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));
|
||||
if(FAILED(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));
|
||||
if(FAILED(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));
|
||||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1041,7 +1041,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1050,7 +1050,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1059,7 +1059,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1068,7 +1068,7 @@ static HRESULT init_constructors(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(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));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1105,7 +1105,7 @@ HRESULT init_global(script_ctx_t *ctx)
|
|||
if(FAILED(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);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1117,7 +1117,7 @@ HRESULT init_global(script_ctx_t *ctx)
|
|||
if(FAILED(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);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1127,7 +1127,7 @@ HRESULT init_global(script_ctx_t *ctx)
|
|||
if(FAILED(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));
|
||||
jsdisp_release(constr);
|
||||
if(FAILED(hres))
|
||||
|
|
|
@ -51,6 +51,7 @@ interface IWineJSDispatchHost;
|
|||
interface IWineJSDispatch : IDispatchEx
|
||||
{
|
||||
void Free();
|
||||
HRESULT GetPropertyFlags(DISPID id, UINT32 *ret);
|
||||
HRESULT GetScriptGlobal(IWineJSDispatchHost **ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -903,7 +903,7 @@ HRESULT init_set_constructor(script_ctx_t *ctx)
|
|||
if(FAILED(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));
|
||||
jsdisp_release(constructor);
|
||||
if(FAILED(hres))
|
||||
|
@ -918,7 +918,7 @@ HRESULT init_set_constructor(script_ctx_t *ctx)
|
|||
if(FAILED(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));
|
||||
jsdisp_release(constructor);
|
||||
if(FAILED(hres))
|
||||
|
@ -933,7 +933,7 @@ HRESULT init_set_constructor(script_ctx_t *ctx)
|
|||
if(FAILED(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));
|
||||
jsdisp_release(constructor);
|
||||
return hres;
|
||||
|
|
|
@ -3641,6 +3641,85 @@ static void test_invokeex(void)
|
|||
IActiveScript_Release(script);
|
||||
}
|
||||
|
||||
static void test_members(void)
|
||||
{
|
||||
DISPID func_id, prop_id;
|
||||
IActiveScript *script;
|
||||
IDispatchEx *dispex;
|
||||
DWORD propflags;
|
||||
HRESULT hres;
|
||||
VARIANT v;
|
||||
BSTR str;
|
||||
|
||||
hres = parse_script_expr(L"var o = { func: function() {}, prop: 1 }; o", &v, &script);
|
||||
ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
|
||||
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
|
||||
ok(hres == S_OK, "Could not get IDispatchEx iface: %08lx\n", hres);
|
||||
VariantClear(&v);
|
||||
|
||||
str = SysAllocString(L"func");
|
||||
hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
|
||||
SysFreeString(str);
|
||||
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
|
||||
|
||||
str = SysAllocString(L"prop");
|
||||
hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id);
|
||||
SysFreeString(str);
|
||||
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, func_id, &str);
|
||||
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
|
||||
ok(!wcscmp(str, L"func"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
|
||||
SysFreeString(str);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
|
||||
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
|
||||
ok(!wcscmp(str, L"prop"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
|
||||
SysFreeString(str);
|
||||
|
||||
propflags = 0xdeadbeef;
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, func_id, 0, &propflags);
|
||||
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
|
||||
ok(propflags == 0, "propflags = %08lx", propflags);
|
||||
|
||||
propflags = 0xdeadbeef;
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
|
||||
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
|
||||
ok(propflags == 0, "propflags = %08lx", propflags);
|
||||
|
||||
hres = IDispatchEx_DeleteMemberByDispID(dispex, func_id);
|
||||
ok(hres == S_OK, "DeleteMemberByDispID failed: %08lx\n", hres);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, func_id, &str);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberName failed: %08lx\n", hres);
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, func_id, 0, &propflags);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberProperties failed: %08lx\n", hres);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
|
||||
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
|
||||
ok(!wcscmp(str, L"prop"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
|
||||
SysFreeString(str);
|
||||
propflags = 0xdeadbeef;
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
|
||||
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
|
||||
ok(propflags == 0, "propflags = %08lx", propflags);
|
||||
|
||||
str = SysAllocString(L"prop");
|
||||
hres = IDispatchEx_DeleteMemberByName(dispex, str, 0);
|
||||
ok(hres == S_OK, "DeleteMemberByName failed: %08lx\n", hres);
|
||||
SysFreeString(str);
|
||||
|
||||
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberName failed: %08lx\n", hres);
|
||||
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
|
||||
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberProperties failed: %08lx\n", hres);
|
||||
|
||||
IDispatchEx_Release(dispex);
|
||||
IActiveScript_Release(script);
|
||||
}
|
||||
|
||||
static void test_destructors(void)
|
||||
{
|
||||
static const WCHAR cyclic_refs[] = L"(function() {\n"
|
||||
|
@ -4299,6 +4378,7 @@ static BOOL run_tests(void)
|
|||
|
||||
test_script_exprs();
|
||||
test_invokeex();
|
||||
test_members();
|
||||
test_destructors();
|
||||
test_eval();
|
||||
test_error_reports();
|
||||
|
|
|
@ -217,7 +217,6 @@ static void test_HeapCreate(void)
|
|||
count = GetProcessHeaps( ARRAY_SIZE(heaps), heaps );
|
||||
ok( count == heap_count + 2, "GetProcessHeaps returned %lu\n", count );
|
||||
ok( heaps[0] == GetProcessHeap(), "got wrong heap\n" );
|
||||
todo_wine
|
||||
ok( heaps[heap_count + 0] == heap, "got wrong heap\n" );
|
||||
todo_wine
|
||||
ok( heaps[heap_count + 1] == heap1, "got wrong heap\n" );
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winternl.h"
|
||||
#include "appmodel.h"
|
||||
|
||||
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
|
||||
static UINT (WINAPI * pEnumSystemFirmwareTables)(DWORD, void *, DWORD);
|
||||
static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, void *, DWORD);
|
||||
static LONG (WINAPI * pPackageIdFromFullName)(const WCHAR *, UINT32, UINT32 *, BYTE *);
|
||||
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
|
||||
|
@ -44,6 +47,7 @@ static void init_function_pointers(void)
|
|||
hmod = GetModuleHandleA("kernel32.dll");
|
||||
|
||||
GET_PROC(GetProductInfo);
|
||||
GET_PROC(EnumSystemFirmwareTables);
|
||||
GET_PROC(GetSystemFirmwareTable);
|
||||
GET_PROC(PackageIdFromFullName);
|
||||
|
||||
|
@ -701,17 +705,18 @@ static void test_VerifyVersionInfo(void)
|
|||
ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_GetSystemFirmwareTable(void)
|
||||
static void test_SystemFirmwareTable(void)
|
||||
{
|
||||
static const ULONG min_sfti_len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
|
||||
ULONG expected_len;
|
||||
UINT len;
|
||||
NTSTATUS status;
|
||||
SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
|
||||
UCHAR *smbios_table;
|
||||
|
||||
if (!pGetSystemFirmwareTable)
|
||||
if (!pGetSystemFirmwareTable || !pEnumSystemFirmwareTables)
|
||||
{
|
||||
win_skip("GetSystemFirmwareTable not available\n");
|
||||
win_skip("SystemFirmwareTable functions not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -720,18 +725,21 @@ static void test_GetSystemFirmwareTable(void)
|
|||
sfti->ProviderSignature = RSMB;
|
||||
sfti->Action = SystemFirmwareTable_Get;
|
||||
sfti->TableID = 0;
|
||||
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
|
||||
if (expected_len == 0) /* xp, 2003 */
|
||||
{
|
||||
win_skip("SystemFirmwareTableInformation is not available\n");
|
||||
HeapFree(GetProcessHeap(), 0, sfti);
|
||||
return;
|
||||
}
|
||||
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
|
||||
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
|
||||
ok(!!sfti, "Failed to allocate memory\n");
|
||||
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
|
||||
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
|
||||
|
||||
expected_len -= min_sfti_len;
|
||||
ok( sfti->TableBufferLength == expected_len, "wrong len %lu/%lx\n",
|
||||
sfti->TableBufferLength, expected_len );
|
||||
len = pGetSystemFirmwareTable(RSMB, 0, NULL, 0);
|
||||
ok(len == expected_len, "Expected length %lu, got %u\n", expected_len, len);
|
||||
|
||||
|
@ -744,9 +752,27 @@ static void test_GetSystemFirmwareTable(void)
|
|||
sfti->TableBuffer[3], sfti->TableBuffer[4], sfti->TableBuffer[5],
|
||||
smbios_table[0], smbios_table[1], smbios_table[2],
|
||||
smbios_table[3], smbios_table[4], smbios_table[5]);
|
||||
HeapFree(GetProcessHeap(), 0, smbios_table);
|
||||
|
||||
sfti->Action = SystemFirmwareTable_Enumerate;
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
|
||||
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
|
||||
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
|
||||
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
|
||||
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
|
||||
ok( expected_len == min_sfti_len + sizeof(UINT), "wrong len %lu\n", expected_len );
|
||||
ok( sfti->TableBufferLength == sizeof(UINT), "wrong len %lu\n", sfti->TableBufferLength );
|
||||
ok( *(UINT *)sfti->TableBuffer == 0, "wrong table id %x\n", *(UINT *)sfti->TableBuffer );
|
||||
|
||||
len = pEnumSystemFirmwareTables( RSMB, NULL, 0 );
|
||||
ok( len == sizeof(UINT), "wrong len %u\n", len );
|
||||
smbios_table = malloc( len );
|
||||
len = pEnumSystemFirmwareTables( RSMB, smbios_table, len );
|
||||
ok( len == sizeof(UINT), "wrong len %u\n", len );
|
||||
ok( *(UINT *)smbios_table == 0, "wrong table id %x\n", *(UINT *)smbios_table );
|
||||
free( smbios_table );
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, sfti);
|
||||
HeapFree(GetProcessHeap(), 0, smbios_table);
|
||||
}
|
||||
|
||||
static const struct
|
||||
|
@ -1100,6 +1126,6 @@ START_TEST(version)
|
|||
test_GetVersionEx();
|
||||
test_VerifyVersionInfo();
|
||||
test_pe_os_version();
|
||||
test_GetSystemFirmwareTable();
|
||||
test_SystemFirmwareTable();
|
||||
test_PackageIdFromFullName();
|
||||
}
|
||||
|
|
|
@ -1785,27 +1785,12 @@ BOOL WINAPI GetXStateFeaturesMask( CONTEXT *context, DWORD64 *feature_mask )
|
|||
* Firmware functions
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* EnumSystemFirmwareTable (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI EnumSystemFirmwareTables( DWORD provider, void *buffer, DWORD size )
|
||||
{
|
||||
FIXME( "(0x%08lx, %p, %ld)\n", provider, buffer, size );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetSystemFirmwareTable (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWORD size )
|
||||
static UINT get_firmware_table( DWORD provider, SYSTEM_FIRMWARE_TABLE_ACTION action, DWORD id,
|
||||
void *buffer, DWORD size )
|
||||
{
|
||||
SYSTEM_FIRMWARE_TABLE_INFORMATION *info;
|
||||
ULONG buffer_size = offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer ) + size;
|
||||
|
||||
TRACE( "(0x%08lx, 0x%08lx, %p, %ld)\n", provider, id, buffer, size );
|
||||
|
||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, buffer_size )))
|
||||
{
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
|
@ -1813,7 +1798,7 @@ UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWOR
|
|||
}
|
||||
|
||||
info->ProviderSignature = provider;
|
||||
info->Action = SystemFirmwareTable_Get;
|
||||
info->Action = action;
|
||||
info->TableID = id;
|
||||
|
||||
set_ntstatus( NtQuerySystemInformation( SystemFirmwareTableInformation,
|
||||
|
@ -1824,3 +1809,23 @@ UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWOR
|
|||
HeapFree( GetProcessHeap(), 0, info );
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EnumSystemFirmwareTables (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI EnumSystemFirmwareTables( DWORD provider, void *buffer, DWORD size )
|
||||
{
|
||||
TRACE( "(0x%08lx, %p, %ld)\n", provider, buffer, size );
|
||||
|
||||
return get_firmware_table( provider, SystemFirmwareTable_Enumerate, 0, buffer, size );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetSystemFirmwareTable (kernelbase.@)
|
||||
*/
|
||||
UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWORD size )
|
||||
{
|
||||
TRACE( "(0x%08lx, 0x%08lx, %p, %ld)\n", provider, id, buffer, size );
|
||||
|
||||
return get_firmware_table( provider, SystemFirmwareTable_Get, id, buffer, size );
|
||||
}
|
||||
|
|
|
@ -1764,6 +1764,26 @@ HRESULT dispex_call_builtin(DispatchEx *dispex, DISPID id, DISPPARAMS *dp,
|
|||
return call_builtin_function(dispex, func, dp, res, ei, caller);
|
||||
}
|
||||
|
||||
static VARIANT_BOOL reset_builtin_func(DispatchEx *dispex, func_info_t *func)
|
||||
{
|
||||
func_obj_entry_t *entry;
|
||||
|
||||
if(!dispex->dynamic_data || !dispex->dynamic_data->func_disps ||
|
||||
!dispex->dynamic_data->func_disps[func->func_disp_idx].func_obj)
|
||||
return VARIANT_FALSE;
|
||||
|
||||
entry = dispex->dynamic_data->func_disps + func->func_disp_idx;
|
||||
if(V_VT(&entry->val) == VT_DISPATCH &&
|
||||
V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface)
|
||||
return VARIANT_FALSE;
|
||||
|
||||
VariantClear(&entry->val);
|
||||
V_VT(&entry->val) = VT_DISPATCH;
|
||||
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
|
||||
IDispatch_AddRef(V_DISPATCH(&entry->val));
|
||||
return VARIANT_TRUE;
|
||||
}
|
||||
|
||||
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
||||
{
|
||||
switch(get_dispid_type(id)) {
|
||||
|
@ -1793,26 +1813,7 @@ HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
|||
|
||||
/* For builtin functions, we set their value to the original function. */
|
||||
if(func->func_disp_idx >= 0) {
|
||||
func_obj_entry_t *entry;
|
||||
|
||||
if(!This->dynamic_data || !This->dynamic_data->func_disps
|
||||
|| !This->dynamic_data->func_disps[func->func_disp_idx].func_obj) {
|
||||
*success = VARIANT_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
entry = This->dynamic_data->func_disps + func->func_disp_idx;
|
||||
if(V_VT(&entry->val) == VT_DISPATCH
|
||||
&& V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface) {
|
||||
*success = VARIANT_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
VariantClear(&entry->val);
|
||||
V_VT(&entry->val) = VT_DISPATCH;
|
||||
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
|
||||
IDispatch_AddRef(V_DISPATCH(&entry->val));
|
||||
*success = VARIANT_TRUE;
|
||||
*success = reset_builtin_func(This, func);
|
||||
return S_OK;
|
||||
}
|
||||
*success = VARIANT_TRUE;
|
||||
|
@ -2304,7 +2305,8 @@ static HRESULT dispex_prop_delete(DispatchEx *dispex, DISPID id)
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(is_dynamic_dispid(id)) {
|
||||
switch(get_dispid_type(id)) {
|
||||
case DISPEXPROP_DYNAMIC: {
|
||||
DWORD idx = id - DISPID_DYNPROP_0;
|
||||
dynamic_prop_t *prop;
|
||||
|
||||
|
@ -2316,6 +2318,24 @@ static HRESULT dispex_prop_delete(DispatchEx *dispex, DISPID id)
|
|||
prop->flags |= DYNPROP_DELETED;
|
||||
return S_OK;
|
||||
}
|
||||
case DISPEXPROP_BUILTIN: {
|
||||
func_info_t *func;
|
||||
HRESULT hres;
|
||||
|
||||
if(!ensure_real_info(dispex))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = get_builtin_func(dispex->info, id, &func);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(func->func_disp_idx >= 0)
|
||||
reset_builtin_func(dispex, func);
|
||||
return S_OK;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ IDispatch *script_parse_event(HTMLInnerWindow*,LPCWSTR);
|
|||
HRESULT exec_script(HTMLInnerWindow*,const WCHAR*,const WCHAR*,VARIANT*);
|
||||
void update_browser_script_mode(GeckoBrowser*,IUri*);
|
||||
BOOL find_global_prop(HTMLInnerWindow*,const WCHAR*,DWORD,ScriptHost**,DISPID*);
|
||||
HRESULT global_prop_still_exists(HTMLInnerWindow*,global_prop_t*);
|
||||
IDispatch *get_script_disp(ScriptHost*);
|
||||
IWineJSDispatch *get_script_jsdisp(ScriptHost*);
|
||||
IActiveScriptSite *get_first_script_site(HTMLInnerWindow*);
|
||||
void initialize_script_global(HTMLInnerWindow*);
|
||||
|
|
|
@ -3302,7 +3302,7 @@ static global_prop_t *alloc_global_prop(HTMLInnerWindow *This, global_prop_type_
|
|||
This->global_prop_size = new_size;
|
||||
}
|
||||
|
||||
This->global_props[This->global_prop_cnt].name = wcsdup(name);
|
||||
This->global_props[This->global_prop_cnt].name = SysAllocString(name);
|
||||
if(!This->global_props[This->global_prop_cnt].name)
|
||||
return NULL;
|
||||
|
||||
|
@ -3324,8 +3324,10 @@ HRESULT search_window_props(HTMLInnerWindow *This, const WCHAR *name, DWORD grfd
|
|||
for(i=0; i < This->global_prop_cnt; i++) {
|
||||
/* FIXME: case sensitivity */
|
||||
if(!wcscmp(This->global_props[i].name, name)) {
|
||||
*pid = MSHTML_DISPID_CUSTOM_MIN+i;
|
||||
return S_OK;
|
||||
HRESULT hres = global_prop_still_exists(This, &This->global_props[i]);
|
||||
if(hres == S_OK)
|
||||
*pid = MSHTML_DISPID_CUSTOM_MIN + i;
|
||||
return (hres == DISP_E_MEMBERNOTFOUND) ? DISP_E_UNKNOWNNAME : hres;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3364,18 +3366,34 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IWineJSDispatchHost *iface, DISPID i
|
|||
static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IWineJSDispatchHost *iface, BSTR bstrName, DWORD grfdex)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
compat_mode_t compat_mode = dispex_compat_mode(&This->base.inner_window->event_target.dispex);
|
||||
|
||||
TRACE("(%p)->(%s %lx)\n", This, debugstr_w(bstrName), grfdex);
|
||||
|
||||
if(compat_mode < COMPAT_MODE_IE8) {
|
||||
/* Not implemented by IE */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
if(compat_mode == COMPAT_MODE_IE8)
|
||||
return MSHTML_E_INVALID_ACTION;
|
||||
|
||||
return IWineJSDispatchHost_DeleteMemberByName(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, bstrName, grfdex);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IWineJSDispatchHost *iface, DISPID id)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
compat_mode_t compat_mode = dispex_compat_mode(&This->base.inner_window->event_target.dispex);
|
||||
|
||||
TRACE("(%p)->(%lx)\n", This, id);
|
||||
|
||||
if(compat_mode < COMPAT_MODE_IE8) {
|
||||
/* Not implemented by IE */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
if(compat_mode == COMPAT_MODE_IE8)
|
||||
return MSHTML_E_INVALID_ACTION;
|
||||
|
||||
return IWineJSDispatchHost_DeleteMemberByDispID(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id);
|
||||
}
|
||||
|
||||
|
@ -3763,7 +3781,7 @@ static void HTMLWindow_destructor(DispatchEx *dispex)
|
|||
VariantClear(&This->performance);
|
||||
|
||||
for(i = 0; i < This->global_prop_cnt; i++)
|
||||
free(This->global_props[i].name);
|
||||
SysFreeString(This->global_props[i].name);
|
||||
free(This->global_props);
|
||||
|
||||
if(This->mon)
|
||||
|
@ -3910,6 +3928,9 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags,
|
|||
case DISPATCH_PROPERTYPUT: {
|
||||
DISPID dispex_id;
|
||||
|
||||
if(This->event_target.dispex.jsdisp)
|
||||
return S_FALSE;
|
||||
|
||||
hres = dispex_get_dynid(&This->event_target.dispex, prop->name, TRUE, &dispex_id);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -3953,6 +3974,44 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags,
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT HTMLWindow_delete(DispatchEx *dispex, DISPID id)
|
||||
{
|
||||
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
|
||||
DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN;
|
||||
global_prop_t *prop;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
if(idx >= This->global_prop_cnt)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
prop = This->global_props + idx;
|
||||
switch(prop->type) {
|
||||
case GLOBAL_SCRIPTVAR: {
|
||||
IDispatchEx *iface;
|
||||
IDispatch *disp;
|
||||
|
||||
disp = get_script_disp(prop->script_host);
|
||||
if(!disp)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&iface);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_DeleteMemberByDispID(iface, prop->id);
|
||||
IDispatchEx_Release(iface);
|
||||
}else {
|
||||
WARN("No IDispatchEx, so can't delete\n");
|
||||
hres = S_OK;
|
||||
}
|
||||
IDispatch_Release(disp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT HTMLWindow_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pid)
|
||||
{
|
||||
DWORD idx = (id == DISPID_STARTENUM) ? 0 : id - MSHTML_DISPID_CUSTOM_MIN + 1;
|
||||
|
@ -3970,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)
|
||||
{
|
||||
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
|
||||
IWineJSDispatch *jsdisp;
|
||||
global_prop_t *prop;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
if(id - MSHTML_DISPID_CUSTOM_MIN >= This->global_prop_cnt)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
@ -3979,10 +4040,22 @@ HRESULT HTMLWindow_get_prop_desc(DispatchEx *dispex, DISPID id, struct property_
|
|||
desc->name = prop->name;
|
||||
desc->id = id;
|
||||
desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE;
|
||||
if(prop->type == GLOBAL_DISPEXVAR)
|
||||
desc->flags |= PROPF_ENUMERABLE;
|
||||
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)
|
||||
|
@ -4179,6 +4252,7 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = {
|
|||
.lookup_dispid = HTMLWindow_lookup_dispid,
|
||||
.find_dispid = HTMLWindow_find_dispid,
|
||||
.invoke = HTMLWindow_invoke,
|
||||
.delete = HTMLWindow_delete,
|
||||
.next_dispid = HTMLWindow_next_dispid,
|
||||
.get_prop_desc = HTMLWindow_get_prop_desc,
|
||||
.get_script_global = HTMLWindow_get_script_global,
|
||||
|
|
|
@ -656,7 +656,7 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
global_prop_type_t type;
|
||||
WCHAR *name;
|
||||
BSTR name;
|
||||
ScriptHost *script_host;
|
||||
DISPID id;
|
||||
} global_prop_t;
|
||||
|
|
|
@ -85,6 +85,7 @@ struct ScriptHost {
|
|||
SCRIPTSTATE script_state;
|
||||
|
||||
HTMLInnerWindow *window;
|
||||
IWineJSDispatch *script_jsdisp;
|
||||
|
||||
GUID guid;
|
||||
struct list entry;
|
||||
|
@ -255,6 +256,18 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script)
|
|||
if(is_second_init)
|
||||
set_script_prop(first_host->script, SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION, &var);
|
||||
}
|
||||
|
||||
if(IsEqualGUID(&script_host->guid, &CLSID_JScript)) {
|
||||
IDispatch *script_disp;
|
||||
|
||||
hres = IActiveScript_GetScriptDispatch(script, NULL, &script_disp);
|
||||
if(FAILED(hres))
|
||||
WARN("GetScriptDispatch failed: %08lx\n", hres);
|
||||
else {
|
||||
IDispatch_QueryInterface(script_disp, &IID_IWineJSDispatch, (void**)&script_host->script_jsdisp);
|
||||
IDispatch_Release(script_disp);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
WARN("AddNamedItem failed: %08lx\n", hres);
|
||||
}
|
||||
|
@ -288,6 +301,8 @@ static void release_script_engine(ScriptHost *This)
|
|||
unlink_ref(&This->parse);
|
||||
}
|
||||
|
||||
if(This->script_jsdisp)
|
||||
IWineJSDispatch_Release(This->script_jsdisp);
|
||||
IActiveScript_Release(This->script);
|
||||
This->script = NULL;
|
||||
This->script_state = SCRIPTSTATE_UNINITIALIZED;
|
||||
|
@ -1573,6 +1588,11 @@ IDispatch *get_script_disp(ScriptHost *script_host)
|
|||
return disp;
|
||||
}
|
||||
|
||||
IWineJSDispatch *get_script_jsdisp(ScriptHost *script_host)
|
||||
{
|
||||
return script_host->script_jsdisp;
|
||||
}
|
||||
|
||||
IActiveScriptSite *get_first_script_site(HTMLInnerWindow *window)
|
||||
{
|
||||
if(list_empty(&window->script_hosts)) {
|
||||
|
@ -1825,6 +1845,48 @@ BOOL find_global_prop(HTMLInnerWindow *window, const WCHAR *name, DWORD flags, S
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT global_prop_still_exists(HTMLInnerWindow *window, global_prop_t *prop)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
switch(prop->type) {
|
||||
case GLOBAL_SCRIPTVAR: {
|
||||
DWORD properties;
|
||||
|
||||
if(!prop->script_host->script)
|
||||
return E_UNEXPECTED;
|
||||
if(!prop->script_host->script_jsdisp)
|
||||
return S_OK;
|
||||
return IWineJSDispatch_GetMemberProperties(prop->script_host->script_jsdisp, prop->id, 0, &properties);
|
||||
}
|
||||
case GLOBAL_ELEMENTVAR: {
|
||||
IHTMLElement *elem;
|
||||
|
||||
hres = IHTMLDocument3_getElementById(&window->doc->IHTMLDocument3_iface, prop->name, &elem);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!elem)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
IHTMLElement_Release(elem);
|
||||
return S_OK;
|
||||
}
|
||||
case GLOBAL_FRAMEVAR: {
|
||||
HTMLOuterWindow *frame;
|
||||
|
||||
hres = get_frame_by_name(window->base.outer_window, prop->name, FALSE, &frame);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return frame ? S_OK : DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static BOOL is_jscript_available(void)
|
||||
{
|
||||
static BOOL available, checked;
|
||||
|
|
|
@ -1301,7 +1301,7 @@ sync_test("navigator", function() {
|
|||
|
||||
sync_test("delete_prop", function() {
|
||||
var v = document.documentMode;
|
||||
var obj = document.createElement("div"), r, obj2;
|
||||
var obj = document.createElement("div"), r, obj2, func, prop;
|
||||
|
||||
obj.prop1 = true;
|
||||
r = false;
|
||||
|
@ -1317,6 +1317,40 @@ sync_test("delete_prop", function() {
|
|||
ok(!r, "got an unexpected exception");
|
||||
ok(!("prop1" in obj), "prop1 is still in obj");
|
||||
|
||||
/* builtin properties don't throw any exception, but are not really deleted */
|
||||
r = (delete obj.tagName);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("tagName" in obj, "tagName deleted from obj");
|
||||
ok(obj.tagName === "DIV", "tagName = " + obj.tagName);
|
||||
|
||||
prop = obj.id;
|
||||
r = (delete obj.id);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("id" in obj, "id deleted from obj");
|
||||
ok(obj.id === prop, "id = " + obj.id);
|
||||
|
||||
obj.id = "1234";
|
||||
ok(obj.id === "1234", "id after set to 1234 = " + obj.id);
|
||||
r = (delete obj.id);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("id" in obj, "id deleted from obj");
|
||||
ok(obj.id === "1234", "id = " + obj.id);
|
||||
|
||||
/* builtin functions get reset to their original values */
|
||||
func = function() { }
|
||||
prop = obj.setAttribute;
|
||||
r = (delete obj.setAttribute);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("setAttribute" in obj, "setAttribute deleted from obj");
|
||||
ok(obj.setAttribute === prop, "setAttribute = " + obj.setAttribute);
|
||||
|
||||
obj.setAttribute = func;
|
||||
ok(obj.setAttribute === func, "setAttribute after set to func = " + obj.setAttribute);
|
||||
r = (delete obj.setAttribute);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("setAttribute" in obj, "setAttribute deleted from obj");
|
||||
ok(obj.setAttribute === prop, "setAttribute = " + obj.setAttribute);
|
||||
|
||||
/* again, this time prop1 does not exist */
|
||||
r = false;
|
||||
try {
|
||||
|
@ -1326,7 +1360,6 @@ sync_test("delete_prop", function() {
|
|||
}
|
||||
if(v < 9) {
|
||||
ok(r, "did not get an expected exception");
|
||||
return;
|
||||
}else {
|
||||
ok(!r, "got an unexpected exception");
|
||||
ok(!("prop1" in obj), "prop1 is still in obj");
|
||||
|
@ -1337,12 +1370,6 @@ sync_test("delete_prop", function() {
|
|||
ok("className" in obj, "className deleted from obj");
|
||||
ok(obj.className === "", "className = " + obj.className);
|
||||
|
||||
/* builtin propertiles don't throw any exception, but are not really deleted */
|
||||
r = (delete obj.tagName);
|
||||
ok(r, "delete returned " + r);
|
||||
ok("tagName" in obj, "tagName deleted from obj");
|
||||
ok(obj.tagName === "DIV", "tagName = " + obj.tagName);
|
||||
|
||||
obj = document.querySelectorAll("*");
|
||||
ok("0" in obj, "0 is not in obj");
|
||||
obj2 = obj[0];
|
||||
|
@ -1353,12 +1380,27 @@ sync_test("delete_prop", function() {
|
|||
/* test window object and its global scope handling */
|
||||
obj = window;
|
||||
|
||||
ok("encodeURIComponent" in obj, "encodeURIComponent not in obj");
|
||||
try {
|
||||
prop = window.encodeURIComponent;
|
||||
r = (delete window.encodeURIComponent);
|
||||
ok(v >= 9, "did not get an expect exception deleting encodeURIComponent");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(!("encodeURIComponent" in obj), "encodeURIComponent is still in obj");
|
||||
window.encodeURIComponent = prop;
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting encodeURIComponent");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting encodeURIComponent threw " + ex.number);
|
||||
ok("encodeURIComponent" in obj, "encodeURIComponent is not in obj");
|
||||
}
|
||||
|
||||
obj.globalprop1 = true;
|
||||
ok(globalprop1, "globalprop1 = " + globalprop1);
|
||||
r = false;
|
||||
try {
|
||||
delete obj.globalprop1;
|
||||
}catch(ex) {
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop1 threw " + ex.number);
|
||||
r = true;
|
||||
}
|
||||
if(v < 9) {
|
||||
|
@ -1374,13 +1416,13 @@ sync_test("delete_prop", function() {
|
|||
try {
|
||||
delete obj.globalprop2;
|
||||
}catch(ex) {
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop2 threw " + ex.number);
|
||||
r = true;
|
||||
}
|
||||
if(v < 9) {
|
||||
ok(r, "did not get an expected globalprop2 exception");
|
||||
}else {
|
||||
ok(!r, "got an unexpected exception");
|
||||
todo_wine.
|
||||
ok(!("globalprop2" in obj), "globalprop2 is still in obj");
|
||||
}
|
||||
|
||||
|
@ -1390,6 +1432,7 @@ sync_test("delete_prop", function() {
|
|||
try {
|
||||
delete globalprop3;
|
||||
}catch(ex) {
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop3 threw " + ex.number);
|
||||
r = true;
|
||||
}
|
||||
if(v < 9) {
|
||||
|
@ -1404,8 +1447,88 @@ sync_test("delete_prop", function() {
|
|||
ok(obj.globalprop4, "globalprop4 = " + globalprop4);
|
||||
r = (delete globalprop4);
|
||||
ok(r, "delete returned " + r);
|
||||
todo_wine.
|
||||
ok(!("globalprop4" in obj), "globalprop4 is still in obj");
|
||||
|
||||
globalprop5 = true;
|
||||
ok(obj.globalprop5, "globalprop5 = " + globalprop5);
|
||||
try {
|
||||
r = (delete window.globalprop5);
|
||||
ok(v >= 9, "did not get an expected exception deleting globalprop5");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(!("globalprop5" in obj), "globalprop5 is still in obj");
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting globalprop5");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop5 threw " + ex.number);
|
||||
ok("globalprop5" in obj, "globalprop5 is not in obj");
|
||||
}
|
||||
|
||||
document.body.innerHTML = '<div id="winetest"/>';
|
||||
ok("winetest" in obj, "winetest not in obj");
|
||||
try {
|
||||
r = (delete window.winetest);
|
||||
ok(v >= 9, "did not get an expected exception deleting winetest");
|
||||
ok(r, "delete returned " + r);
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting winetest");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting winetest threw " + ex.number);
|
||||
}
|
||||
ok("winetest" in obj, "winetest is not in obj");
|
||||
document.body.innerHTML = "";
|
||||
ok(!("winetest" in obj), "winetest is still in obj");
|
||||
|
||||
document.body.innerHTML = '<div id="foobar"/>';
|
||||
ok("foobar" in obj, "foobar not in obj");
|
||||
window.foobar = "1234";
|
||||
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
|
||||
document.body.innerHTML = "";
|
||||
ok("foobar" in obj, "foobar is not in obj");
|
||||
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
|
||||
try {
|
||||
r = (delete window.foobar);
|
||||
ok(v >= 9, "did not get an expected exception deleting foobar");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(!("foobar" in obj), "foobar is still in obj");
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting foobar");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting foobar threw " + ex.number);
|
||||
ok("foobar" in obj, "foobar is not in obj");
|
||||
}
|
||||
|
||||
document.body.innerHTML = '<div id="barfoo"/>';
|
||||
ok("barfoo" in obj, "barfoo not in obj");
|
||||
window.barfoo = "5678";
|
||||
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
|
||||
try {
|
||||
r = (delete window.barfoo);
|
||||
ok(v >= 9, "did not get an expected exception deleting barfoo");
|
||||
ok(r, "delete returned " + r);
|
||||
ok(obj.barfoo !== "5678", "barfoo is still 5678");
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting barfoo");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting barfoo threw " + ex.number);
|
||||
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
|
||||
}
|
||||
ok("barfoo" in obj, "barfoo is not in obj");
|
||||
document.body.innerHTML = "";
|
||||
if(v < 9)
|
||||
ok("barfoo" in obj, "barfoo is not in obj");
|
||||
else
|
||||
ok(!("barfoo" in obj), "barfoo is still in obj");
|
||||
|
||||
document.body.innerHTML = '<iframe id="testwine"/>';
|
||||
ok("testwine" in obj, "testwine not in obj");
|
||||
try {
|
||||
r = (delete window.testwine);
|
||||
ok(v >= 9, "did not get an expected exception deleting testwine");
|
||||
ok(r, "delete returned " + r);
|
||||
}catch(ex) {
|
||||
ok(v < 9, "expected exception deleting testwine");
|
||||
ok(ex.number === 0xa01bd - 0x80000000, "deleting testwine threw " + ex.number);
|
||||
}
|
||||
ok("testwine" in obj, "testwine is not in obj");
|
||||
|
||||
document.body.innerHTML = "";
|
||||
ok(!("testwine" in obj), "testwine is still in obj");
|
||||
});
|
||||
|
||||
sync_test("detached arguments", function() {
|
||||
|
|
|
@ -23,6 +23,7 @@ var JS_E_NUMBER_EXPECTED = 0x800a1389;
|
|||
var JS_E_FUNCTION_EXPECTED = 0x800a138a;
|
||||
var JS_E_DATE_EXPECTED = 0x800a138e;
|
||||
var JS_E_OBJECT_EXPECTED = 0x800a138f;
|
||||
var JS_E_UNDEFINED_VARIABLE = 0x800a1391;
|
||||
var JS_E_BOOLEAN_EXPECTED = 0x800a1392;
|
||||
var JS_E_VBARRAY_EXPECTED = 0x800a1395;
|
||||
var JS_E_ENUMERATOR_EXPECTED = 0x800a1397;
|
||||
|
@ -2153,6 +2154,109 @@ sync_test("builtin_context", function() {
|
|||
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() {
|
||||
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);
|
||||
|
|
|
@ -125,7 +125,7 @@ static NTSTATUS RtlpAllocateSomeHandles(RTL_HANDLE_TABLE * HandleTable)
|
|||
}
|
||||
if (!HandleTable->NextFree)
|
||||
{
|
||||
SIZE_T Offset, CommitSize = 4096; /* one page */
|
||||
SIZE_T Offset, CommitSize = page_size;
|
||||
RTL_HANDLE * FreeHandle = NULL;
|
||||
PVOID NextAvailAddr = HandleTable->ReservedMemory;
|
||||
|
||||
|
|
|
@ -400,6 +400,7 @@
|
|||
@ stdcall -syscall NtSetInformationVirtualMemory(long long ptr ptr ptr long)
|
||||
@ stdcall -syscall NtSetIntervalProfile(long long)
|
||||
@ stdcall -syscall NtSetIoCompletion(ptr long long long long)
|
||||
@ stdcall -syscall NtSetIoCompletionEx(ptr ptr long long long long)
|
||||
@ stdcall -syscall NtSetLdtEntries(long int64 long int64)
|
||||
# @ stub NtSetLowEventPair
|
||||
# @ stub NtSetLowWaitHighEventPair
|
||||
|
@ -1460,6 +1461,7 @@
|
|||
@ stdcall -private -syscall ZwSetInformationVirtualMemory(long long ptr ptr ptr long) NtSetInformationVirtualMemory
|
||||
@ stdcall -private -syscall ZwSetIntervalProfile(long long) NtSetIntervalProfile
|
||||
@ stdcall -private -syscall ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
|
||||
@ stdcall -private -syscall ZwSetIoCompletionEx(ptr ptr long long long long) NtSetIoCompletionEx
|
||||
@ stdcall -private -syscall ZwSetLdtEntries(long int64 long int64) NtSetLdtEntries
|
||||
# @ stub ZwSetLowEventPair
|
||||
# @ stub ZwSetLowWaitHighEventPair
|
||||
|
|
158
dlls/ntdll/ntsyscalls.h
generated
158
dlls/ntdll/ntsyscalls.h
generated
|
@ -203,48 +203,49 @@
|
|||
SYSCALL_ENTRY( 0x00c7, NtSetInformationVirtualMemory, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00c8, NtSetIntervalProfile, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00c9, NtSetIoCompletion, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetLdtEntries, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetSecurityObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSystemInformation, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemTime, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetThreadExecutionState, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetTimer, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimerResolution, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetValueKey, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetVolumeInformationFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtShutdownSystem, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtSignalAndWaitForSingleObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSuspendProcess, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSystemDebugControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtTerminateJobObject, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTraceControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtUnloadDriver, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadKey, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnlockFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockVirtualMemory, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnmapViewOfSection, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSectionEx, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtWaitForAlertByThreadId, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForDebugEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForKeyedEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForMultipleObjects, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForSingleObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWow64AllocateVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWow64GetNativeSystemInformation, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWow64IsProcessorFeaturePresent, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtWow64QueryInformationProcess64, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, NtWow64ReadVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, NtWow64WriteVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ee, NtWriteFile, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00ef, NtWriteFileGather, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00f0, NtWriteVirtualMemory, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00f1, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00f2, wine_nt_to_unix_file_name, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00f3, wine_unix_to_nt_file_name, 12 )
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetIoCompletionEx, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetLdtEntries, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSecurityObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemInformation, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetSystemTime, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetThreadExecutionState, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimer, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetTimerResolution, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetValueKey, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtSetVolumeInformationFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtShutdownSystem, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSignalAndWaitForSingleObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendProcess, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSuspendThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtSystemDebugControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateJobObject, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTerminateThread, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtTraceControl, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadDriver, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnloadKey, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockFile, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnlockVirtualMemory, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSection, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtUnmapViewOfSectionEx, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForAlertByThreadId, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForDebugEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForKeyedEvent, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForMultipleObjects, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWaitForSingleObject, 12 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWow64AllocateVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWow64GetNativeSystemInformation, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtWow64IsProcessorFeaturePresent, 4 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, NtWow64QueryInformationProcess64, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, NtWow64ReadVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ee, NtWow64WriteVirtualMemory64, 28 ) \
|
||||
SYSCALL_ENTRY( 0x00ef, NtWriteFile, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00f0, NtWriteFileGather, 36 ) \
|
||||
SYSCALL_ENTRY( 0x00f1, NtWriteVirtualMemory, 20 ) \
|
||||
SYSCALL_ENTRY( 0x00f2, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00f3, wine_nt_to_unix_file_name, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00f4, wine_unix_to_nt_file_name, 12 )
|
||||
|
||||
#define ALL_SYSCALLS64 \
|
||||
SYSCALL_ENTRY( 0x0000, NtAcceptConnectPort, 48 ) \
|
||||
|
@ -449,39 +450,40 @@
|
|||
SYSCALL_ENTRY( 0x00c7, NtSetInformationVirtualMemory, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00c8, NtSetIntervalProfile, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00c9, NtSetIoCompletion, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetLdtEntries, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetSecurityObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSystemInformation, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemTime, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetThreadExecutionState, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetTimer, 56 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimerResolution, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetValueKey, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetVolumeInformationFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtShutdownSystem, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtSignalAndWaitForSingleObject, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSuspendProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSystemDebugControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtTerminateJobObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateProcess, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTraceControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtUnloadDriver, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadKey, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnlockFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockVirtualMemory, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnmapViewOfSection, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSectionEx, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtWaitForAlertByThreadId, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForDebugEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForKeyedEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForMultipleObjects, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForSingleObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWriteFile, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWriteFileGather, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWriteVirtualMemory, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, wine_nt_to_unix_file_name, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, wine_unix_to_nt_file_name, 24 )
|
||||
SYSCALL_ENTRY( 0x00ca, NtSetIoCompletionEx, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00cb, NtSetLdtEntries, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00cc, NtSetSecurityObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00cd, NtSetSystemInformation, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00ce, NtSetSystemTime, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00cf, NtSetThreadExecutionState, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d0, NtSetTimer, 56 ) \
|
||||
SYSCALL_ENTRY( 0x00d1, NtSetTimerResolution, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00d2, NtSetValueKey, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d3, NtSetVolumeInformationFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00d4, NtShutdownSystem, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d5, NtSignalAndWaitForSingleObject, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00d6, NtSuspendProcess, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00d7, NtSuspendThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00d8, NtSystemDebugControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00d9, NtTerminateJobObject, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00da, NtTerminateProcess, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00db, NtTerminateThread, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00dc, NtTestAlert, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00dd, NtTraceControl, 48 ) \
|
||||
SYSCALL_ENTRY( 0x00de, NtUnloadDriver, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00df, NtUnloadKey, 8 ) \
|
||||
SYSCALL_ENTRY( 0x00e0, NtUnlockFile, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e1, NtUnlockVirtualMemory, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSection, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e3, NtUnmapViewOfSectionEx, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e4, NtWaitForAlertByThreadId, 16 ) \
|
||||
SYSCALL_ENTRY( 0x00e5, NtWaitForDebugEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e6, NtWaitForKeyedEvent, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00e7, NtWaitForMultipleObjects, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00e8, NtWaitForSingleObject, 24 ) \
|
||||
SYSCALL_ENTRY( 0x00e9, NtWriteFile, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00ea, NtWriteFileGather, 72 ) \
|
||||
SYSCALL_ENTRY( 0x00eb, NtWriteVirtualMemory, 40 ) \
|
||||
SYSCALL_ENTRY( 0x00ec, NtYieldExecution, 0 ) \
|
||||
SYSCALL_ENTRY( 0x00ed, wine_nt_to_unix_file_name, 32 ) \
|
||||
SYSCALL_ENTRY( 0x00ee, wine_unix_to_nt_file_name, 24 )
|
||||
|
|
|
@ -443,6 +443,7 @@ DEFINE_SYSCALL(NtSetInformationToken, (HANDLE token, TOKEN_INFORMATION_CLASS cla
|
|||
DEFINE_SYSCALL(NtSetInformationVirtualMemory, (HANDLE process, VIRTUAL_MEMORY_INFORMATION_CLASS info_class, ULONG_PTR count, PMEMORY_RANGE_ENTRY addresses, PVOID ptr, ULONG size))
|
||||
DEFINE_SYSCALL(NtSetIntervalProfile, (ULONG interval, KPROFILE_SOURCE source))
|
||||
DEFINE_SYSCALL(NtSetIoCompletion, (HANDLE handle, ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count))
|
||||
DEFINE_SYSCALL(NtSetIoCompletionEx, (HANDLE completion_handle, HANDLE completion_reserve_handle, ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count))
|
||||
DEFINE_SYSCALL(NtSetLdtEntries, (ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2))
|
||||
DEFINE_SYSCALL(NtSetSecurityObject, (HANDLE handle, SECURITY_INFORMATION info, PSECURITY_DESCRIPTOR descr))
|
||||
DEFINE_SYSCALL(NtSetSystemInformation, (SYSTEM_INFORMATION_CLASS class, void *info, ULONG length))
|
||||
|
|
|
@ -51,6 +51,7 @@ static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
|
|||
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* );
|
||||
static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG, ULONG * );
|
||||
|
||||
static NTSTATUS (WINAPI *pNtAllocateReserveObject)( HANDLE *, const OBJECT_ATTRIBUTES *, MEMORY_RESERVE_OBJECT_TYPE );
|
||||
static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
|
||||
ULONG, ULONG, ULONG, PLARGE_INTEGER );
|
||||
static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG);
|
||||
|
@ -76,6 +77,7 @@ static NTSTATUS (WINAPI *pNtQueryIoCompletion)(HANDLE, IO_COMPLETION_INFORMATION
|
|||
static NTSTATUS (WINAPI *pNtRemoveIoCompletion)(HANDLE, PULONG_PTR, PULONG_PTR, PIO_STATUS_BLOCK, PLARGE_INTEGER);
|
||||
static NTSTATUS (WINAPI *pNtRemoveIoCompletionEx)(HANDLE,FILE_IO_COMPLETION_INFORMATION*,ULONG,ULONG*,LARGE_INTEGER*,BOOLEAN);
|
||||
static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
|
||||
static NTSTATUS (WINAPI *pNtSetIoCompletionEx)(HANDLE, HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
|
||||
static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
|
||||
static NTSTATUS (WINAPI *pNtQueryAttributesFile)(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*);
|
||||
static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
|
||||
|
@ -5932,6 +5934,62 @@ static void test_reparse_points(void)
|
|||
CloseHandle( handle );
|
||||
}
|
||||
|
||||
static void test_set_io_completion_ex(void)
|
||||
{
|
||||
HANDLE completion, completion_reserve, apc_reserve;
|
||||
LARGE_INTEGER timeout = {{0}};
|
||||
IO_STATUS_BLOCK iosb;
|
||||
ULONG_PTR key, value;
|
||||
NTSTATUS status;
|
||||
SIZE_T size = 3;
|
||||
|
||||
if (!pNtSetIoCompletionEx || !pNtAllocateReserveObject)
|
||||
{
|
||||
win_skip("NtSetIoCompletionEx() or NtAllocateReserveObject() is unavailable.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32;
|
||||
|
||||
status = pNtCreateIoCompletion(&completion, IO_COMPLETION_ALL_ACCESS, NULL, 0);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
status = pNtAllocateReserveObject(&completion_reserve, NULL, MemoryReserveObjectTypeIoCompletion);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
status = pNtAllocateReserveObject(&apc_reserve, NULL, MemoryReserveObjectTypeUserApc);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
/* Parameter checks */
|
||||
status = pNtSetIoCompletionEx(NULL, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(INVALID_HANDLE_VALUE, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(completion, NULL, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(completion, INVALID_HANDLE_VALUE, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtSetIoCompletionEx(completion, apc_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
/* Normal call */
|
||||
status = pNtSetIoCompletionEx(completion, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
|
||||
status = pNtRemoveIoCompletion(completion, &key, &value, &iosb, &timeout);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
|
||||
ok(key == CKEY_FIRST, "Invalid completion key: %#Ix\n", key);
|
||||
ok(iosb.Information == size, "Invalid iosb.Information: %Iu\n", iosb.Information);
|
||||
ok(iosb.Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid iosb.Status: %#lx\n", iosb.Status);
|
||||
ok(value == CVALUE_FIRST, "Invalid completion value: %#Ix\n", value);
|
||||
|
||||
CloseHandle(apc_reserve);
|
||||
CloseHandle(completion_reserve);
|
||||
CloseHandle(completion);
|
||||
}
|
||||
|
||||
START_TEST(file)
|
||||
{
|
||||
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||
|
@ -5949,6 +6007,7 @@ START_TEST(file)
|
|||
pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
|
||||
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
|
||||
pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll, "RtlWow64EnableFsRedirectionEx");
|
||||
pNtAllocateReserveObject= (void *)GetProcAddress(hntdll, "NtAllocateReserveObject");
|
||||
pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
|
||||
pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
|
||||
pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
|
||||
|
@ -5965,6 +6024,7 @@ START_TEST(file)
|
|||
pNtRemoveIoCompletion = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletion");
|
||||
pNtRemoveIoCompletionEx = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletionEx");
|
||||
pNtSetIoCompletion = (void *)GetProcAddress(hntdll, "NtSetIoCompletion");
|
||||
pNtSetIoCompletionEx = (void *)GetProcAddress(hntdll, "NtSetIoCompletionEx");
|
||||
pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile");
|
||||
pNtQueryAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryAttributesFile");
|
||||
pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
|
||||
|
@ -5983,6 +6043,7 @@ START_TEST(file)
|
|||
append_file_test();
|
||||
nt_mailslot_test();
|
||||
test_set_io_completion();
|
||||
test_set_io_completion_ex();
|
||||
test_file_io_completion();
|
||||
test_file_basic_information();
|
||||
test_file_all_information();
|
||||
|
|
|
@ -4052,10 +4052,9 @@ static void test_user_procs(void)
|
|||
status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
|
||||
if (!status) break;
|
||||
ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
|
||||
status = pRtlResetNtUserPfn();
|
||||
ok( status == STATUS_INVALID_PARAMETER, "RtlResetNtUserPfn failed %lx\n", status );
|
||||
}
|
||||
trace( "got sizes %lx %lx %lx\n", size_A, size_W, size_workers );
|
||||
if (!size_workers) return; /* something went wrong */
|
||||
ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by init\n" );
|
||||
|
||||
/* can't set twice without a reset */
|
||||
|
|
|
@ -354,7 +354,7 @@ static int wait_select_reply( void *cookie )
|
|||
/***********************************************************************
|
||||
* invoke_user_apc
|
||||
*/
|
||||
static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTATUS status )
|
||||
static NTSTATUS invoke_user_apc( CONTEXT *context, const struct user_apc *apc, NTSTATUS status )
|
||||
{
|
||||
return call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2],
|
||||
wine_server_get_ptr( apc->func ), status );
|
||||
|
@ -364,7 +364,7 @@ static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTAT
|
|||
/***********************************************************************
|
||||
* invoke_system_apc
|
||||
*/
|
||||
static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOOL self )
|
||||
static void invoke_system_apc( const union apc_call *call, union apc_result *result, BOOL self )
|
||||
{
|
||||
SIZE_T size, bits;
|
||||
void *addr;
|
||||
|
@ -687,20 +687,20 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
|||
/***********************************************************************
|
||||
* server_select
|
||||
*/
|
||||
unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc )
|
||||
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 )
|
||||
{
|
||||
unsigned int ret;
|
||||
int cookie;
|
||||
obj_handle_t apc_handle = 0;
|
||||
BOOL suspend_context = !!context;
|
||||
apc_result_t result;
|
||||
union apc_result result;
|
||||
sigset_t old_set;
|
||||
int signaled;
|
||||
data_size_t reply_size;
|
||||
struct
|
||||
{
|
||||
apc_call_t call;
|
||||
union apc_call call;
|
||||
context_t context[2];
|
||||
} reply_data;
|
||||
|
||||
|
@ -740,7 +740,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
|||
|
||||
/* don't signal multiple times */
|
||||
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 );
|
||||
if (signaled) break;
|
||||
|
@ -763,12 +763,12 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
|||
/***********************************************************************
|
||||
* 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 )
|
||||
{
|
||||
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
||||
unsigned int ret;
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
|
||||
if (abs_timeout < 0)
|
||||
{
|
||||
|
@ -794,7 +794,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
|
|||
*/
|
||||
NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
|
||||
{
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
NTSTATUS status;
|
||||
|
||||
if (alertable)
|
||||
|
@ -811,7 +811,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
|
|||
*/
|
||||
NTSTATUS WINAPI NtTestAlert(void)
|
||||
{
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
NTSTATUS status;
|
||||
|
||||
status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, &apc );
|
||||
|
@ -823,7 +823,7 @@ NTSTATUS WINAPI NtTestAlert(void)
|
|||
/***********************************************************************
|
||||
* server_queue_process_apc
|
||||
*/
|
||||
unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result )
|
||||
unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call, union apc_result *result )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1759,8 +1759,8 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source, HANDLE
|
|||
|
||||
if ((options & DUPLICATE_CLOSE_SOURCE) && source_process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
|
|
@ -993,7 +993,7 @@ NTSTATUS WINAPI NtSetInformationDebugObject( HANDLE handle, DEBUGOBJECTINFOCLASS
|
|||
|
||||
|
||||
/* 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;
|
||||
|
||||
|
@ -1098,7 +1098,7 @@ static NTSTATUS get_image_machine( HANDLE handle, USHORT *machine )
|
|||
NTSTATUS WINAPI NtWaitForDebugEvent( HANDLE handle, BOOLEAN alertable, LARGE_INTEGER *timeout,
|
||||
DBGUI_WAIT_STATE_CHANGE *state )
|
||||
{
|
||||
debug_event_t data;
|
||||
union debug_event_data data;
|
||||
unsigned int ret;
|
||||
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,
|
||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||
{
|
||||
select_op_t select_op;
|
||||
union select_op select_op;
|
||||
UINT i, flags = SELECT_INTERRUPTIBLE;
|
||||
|
||||
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;
|
||||
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] );
|
||||
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,
|
||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||
{
|
||||
select_op_t select_op;
|
||||
union select_op select_op;
|
||||
UINT flags = SELECT_INTERRUPTIBLE;
|
||||
|
||||
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,
|
||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||
{
|
||||
select_op_t select_op;
|
||||
union select_op select_op;
|
||||
UINT flags = SELECT_INTERRUPTIBLE;
|
||||
|
||||
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,
|
||||
BOOLEAN alertable, const LARGE_INTEGER *timeout )
|
||||
{
|
||||
select_op_t select_op;
|
||||
union select_op select_op;
|
||||
UINT flags = SELECT_INTERRUPTIBLE;
|
||||
|
||||
if (!handle) handle = keyed_event;
|
||||
|
@ -1992,6 +1992,35 @@ NTSTATUS WINAPI NtSetIoCompletion( HANDLE handle, ULONG_PTR key, ULONG_PTR value
|
|||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtSetIoCompletionEx (NTDLL.@)
|
||||
*
|
||||
* completion_reserve_handle is a handle allocated by NtAllocateReserveObject() for pre-allocating
|
||||
* memory for completion objects to deal with low-memory situations. It's not in use for now.
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetIoCompletionEx( HANDLE completion_handle, HANDLE completion_reserve_handle,
|
||||
ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count )
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
TRACE( "(%p, %p, %lx, %lx, %x, %lx)\n", completion_handle, completion_reserve_handle,
|
||||
key, value, (int)status, count );
|
||||
|
||||
if (!completion_reserve_handle) return STATUS_INVALID_HANDLE;
|
||||
|
||||
SERVER_START_REQ( add_completion )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( completion_handle );
|
||||
req->ckey = key;
|
||||
req->cvalue = value;
|
||||
req->status = status;
|
||||
req->information = count;
|
||||
req->reserve_handle = wine_server_obj_handle( completion_reserve_handle );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtRemoveIoCompletion (NTDLL.@)
|
||||
|
|
|
@ -2131,6 +2131,26 @@ static struct smbios_prologue *create_smbios_data(void)
|
|||
|
||||
#endif
|
||||
|
||||
static NTSTATUS enum_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG available_len,
|
||||
ULONG *required_len )
|
||||
{
|
||||
ULONG len;
|
||||
|
||||
switch (sfti->ProviderSignature)
|
||||
{
|
||||
case RSMB:
|
||||
sfti->TableBufferLength = len = sizeof(UINT);
|
||||
*required_len = offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer[len] );
|
||||
if (available_len < *required_len) return STATUS_BUFFER_TOO_SMALL;
|
||||
*(UINT *)sfti->TableBuffer = 0;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
default:
|
||||
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION provider %08x\n", (unsigned int)sfti->ProviderSignature);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS get_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG available_len,
|
||||
ULONG *required_len )
|
||||
{
|
||||
|
@ -3459,14 +3479,17 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
|
|||
ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
}
|
||||
len = 0;
|
||||
|
||||
switch (sfti->Action)
|
||||
{
|
||||
case SystemFirmwareTable_Enumerate:
|
||||
ret = enum_firmware_info(sfti, size, &len);
|
||||
break;
|
||||
case SystemFirmwareTable_Get:
|
||||
ret = get_firmware_info(sfti, size, &len);
|
||||
break;
|
||||
default:
|
||||
len = 0;
|
||||
ret = STATUS_NOT_IMPLEMENTED;
|
||||
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION action %d\n", sfti->Action);
|
||||
}
|
||||
|
|
|
@ -1323,8 +1323,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -1512,7 +1512,7 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
|
|||
DWORD i;
|
||||
obj_handle_t handle = 0;
|
||||
client_ptr_t params[EXCEPTION_MAXIMUM_PARAMETERS];
|
||||
select_op_t select_op;
|
||||
union select_op select_op;
|
||||
sigset_t old_set;
|
||||
|
||||
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 );
|
||||
server_contexts[0].flags |= SERVER_CTX_EXEC_SPACE;
|
||||
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 );
|
||||
|
||||
SERVER_START_REQ( get_exception_status )
|
||||
|
@ -1712,7 +1712,7 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1
|
|||
ULONG_PTR arg2, ULONG_PTR arg3 )
|
||||
{
|
||||
unsigned int ret;
|
||||
apc_call_t call;
|
||||
union apc_call call;
|
||||
|
||||
SERVER_START_REQ( queue_apc )
|
||||
{
|
||||
|
|
|
@ -208,12 +208,12 @@ extern void start_server( BOOL debug );
|
|||
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_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,
|
||||
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc );
|
||||
extern unsigned int server_wait( 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 );
|
||||
extern unsigned int server_wait( const union select_op *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout );
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call,
|
||||
apc_result_t *result );
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call,
|
||||
union apc_result *result );
|
||||
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type, unsigned int *options );
|
||||
extern void wine_server_send_fd( int fd );
|
||||
|
@ -436,10 +436,10 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
|
|||
if (!process_exiting) pthread_mutex_unlock( mutex );
|
||||
}
|
||||
|
||||
static inline async_data_t server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
|
||||
PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
|
||||
static inline struct async_data server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
|
||||
PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
|
||||
{
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
async.handle = wine_server_obj_handle( handle );
|
||||
async.user = wine_server_client_ptr( user );
|
||||
async.iosb = iosb;
|
||||
|
|
|
@ -4671,8 +4671,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
unsigned int status;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
@ -4817,8 +4817,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -4864,8 +4864,8 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -4962,8 +4962,8 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5146,8 +5146,8 @@ static unsigned int get_basic_memory_info( HANDLE process, LPCVOID addr,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5559,8 +5559,8 @@ NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5596,8 +5596,8 @@ NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5672,8 +5672,8 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5744,8 +5744,8 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5788,8 +5788,8 @@ static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr, ULONG flags )
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5973,8 +5973,8 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -6359,8 +6359,8 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
|
|
@ -506,7 +506,7 @@ static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp,
|
|||
|
||||
struct dispatch_context
|
||||
{
|
||||
irp_params_t params;
|
||||
union irp_params params;
|
||||
HANDLE handle;
|
||||
struct irp_data *irp_data;
|
||||
ULONG in_size;
|
||||
|
|
|
@ -1525,6 +1525,7 @@
|
|||
@ stdcall -private ZwSetInformationToken(long long ptr long) NtSetInformationToken
|
||||
@ stdcall -private ZwSetIntervalProfile(long long) NtSetIntervalProfile
|
||||
@ stdcall -private ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
|
||||
@ stdcall -private ZwSetIoCompletionEx(ptr ptr long long long long) NtSetIoCompletionEx
|
||||
@ stdcall -private ZwSetSecurityObject(long long ptr) NtSetSecurityObject
|
||||
@ stdcall -private ZwSetSystemInformation(long ptr long) NtSetSystemInformation
|
||||
@ stdcall -private ZwSetSystemTime(ptr ptr) NtSetSystemTime
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -525,11 +525,19 @@ void find_domain_name(const WCHAR *host, DWORD host_len,
|
|||
return;
|
||||
}
|
||||
} else if(last_tld-host < 3)
|
||||
/* Anything less than 3 characters is considered part
|
||||
{
|
||||
/* Anything less than 3 ASCII characters is considered part
|
||||
* of the TLD name.
|
||||
* Ex: ak.uk -> Has no domain name.
|
||||
*/
|
||||
return;
|
||||
for(p = host; p < last_tld; p++) {
|
||||
if(!is_ascii(*p))
|
||||
break;
|
||||
}
|
||||
|
||||
if(p == last_tld)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise the domain name is the whole host name. */
|
||||
*domain_start = 0;
|
||||
|
@ -1339,11 +1347,21 @@ static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD extras) {
|
|||
/* If the host is empty, then it's an unknown host type. */
|
||||
if(data->host_len == 0 || is_res)
|
||||
data->host_type = Uri_HOST_UNKNOWN;
|
||||
else
|
||||
else {
|
||||
unsigned int i;
|
||||
|
||||
data->host_type = Uri_HOST_DNS;
|
||||
|
||||
TRACE("(%p %p %lx): Parsed reg-name. host=%s len=%ld\n", ptr, data, extras,
|
||||
debugstr_wn(data->host, data->host_len), data->host_len);
|
||||
for(i = 0; i < data->host_len; i++) {
|
||||
if(!is_ascii(data->host[i])) {
|
||||
data->host_type = Uri_HOST_IDN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("(%p %p %lx): Parsed reg-name. host=%s len=%ld type=%d\n", ptr, data, extras,
|
||||
debugstr_wn(data->host, data->host_len), data->host_len, data->host_type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2276,6 +2294,13 @@ static BOOL canonicalize_host(const parse_data *data, Uri *uri, DWORD flags, BOO
|
|||
|
||||
uri->host_type = Uri_HOST_IPV6;
|
||||
break;
|
||||
|
||||
case Uri_HOST_IDN:
|
||||
uri->host_type = Uri_HOST_IDN;
|
||||
if(!canonicalize_reg_name(data, uri, flags, computeOnly))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
case Uri_HOST_UNKNOWN:
|
||||
if(data->host_len > 0 || data->scheme_type != URL_SCHEME_FILE) {
|
||||
uri->host_start = uri->canon_len;
|
||||
|
@ -3873,17 +3898,37 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
/* Don't have support for flags yet. */
|
||||
if(dwFlags) {
|
||||
FIXME("(%p)->(%d %p %lx)\n", This, uriProp, pbstrProperty, dwFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
if(dwFlags != 0 && dwFlags != Uri_DISPLAY_NO_FRAGMENT && dwFlags != Uri_PUNYCODE_IDN_HOST
|
||||
&& dwFlags != Uri_DISPLAY_IDN_HOST)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if((dwFlags == Uri_DISPLAY_NO_FRAGMENT && uriProp != Uri_PROPERTY_DISPLAY_URI)
|
||||
|| (dwFlags == Uri_PUNYCODE_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST)
|
||||
|| (dwFlags == Uri_DISPLAY_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST))
|
||||
return E_INVALIDARG;
|
||||
|
||||
switch(uriProp) {
|
||||
case Uri_PROPERTY_ABSOLUTE_URI:
|
||||
if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
|
||||
*pbstrProperty = SysAllocStringLen(NULL, 0);
|
||||
hres = S_FALSE;
|
||||
}
|
||||
/* Uri_PUNYCODE_IDN_HOST doesn't remove user info containing only "@" and ":@" */
|
||||
else if (dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1) {
|
||||
unsigned int punycode_host_len;
|
||||
|
||||
punycode_host_len = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
*pbstrProperty = SysAllocStringLen(NULL, This->canon_len-This->host_len+punycode_host_len);
|
||||
hres = S_OK;
|
||||
if(*pbstrProperty) {
|
||||
memcpy(*pbstrProperty, This->canon_uri, This->host_start*sizeof(WCHAR));
|
||||
IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, *pbstrProperty+This->host_start, punycode_host_len);
|
||||
memcpy(*pbstrProperty+This->host_start+punycode_host_len,
|
||||
This->canon_uri+This->host_start+This->host_len,
|
||||
(This->canon_len-This->host_start-This->host_len)*sizeof(WCHAR));
|
||||
}
|
||||
} else {
|
||||
if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
|
||||
if(This->userinfo_len == 0) {
|
||||
|
@ -3944,18 +3989,32 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
* scheme types.
|
||||
*/
|
||||
if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
|
||||
*pbstrProperty = SysAllocStringLen(NULL, This->canon_len-This->userinfo_len);
|
||||
unsigned int length = This->canon_len-This->userinfo_len;
|
||||
|
||||
/* Skip fragment if Uri_DISPLAY_NO_FRAGMENT is specified */
|
||||
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
|
||||
length -= This->fragment_len;
|
||||
|
||||
*pbstrProperty = SysAllocStringLen(NULL, length);
|
||||
|
||||
if(*pbstrProperty) {
|
||||
/* Copy everything before the userinfo over. */
|
||||
memcpy(*pbstrProperty, This->canon_uri, This->userinfo_start*sizeof(WCHAR));
|
||||
|
||||
/* Copy everything after the userinfo over. */
|
||||
length -= This->userinfo_start+1;
|
||||
memcpy(*pbstrProperty+This->userinfo_start,
|
||||
This->canon_uri+This->userinfo_start+This->userinfo_len+1,
|
||||
(This->canon_len-(This->userinfo_start+This->userinfo_len+1))*sizeof(WCHAR));
|
||||
This->canon_uri+This->userinfo_start+This->userinfo_len+1, length*sizeof(WCHAR));
|
||||
}
|
||||
} else
|
||||
*pbstrProperty = SysAllocString(This->canon_uri);
|
||||
} else {
|
||||
unsigned int length = This->canon_len;
|
||||
|
||||
/* Skip fragment if Uri_DISPLAY_NO_FRAGMENT is specified */
|
||||
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
|
||||
length -= This->fragment_len;
|
||||
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri, length);
|
||||
}
|
||||
|
||||
if(!(*pbstrProperty))
|
||||
hres = E_OUTOFMEMORY;
|
||||
|
@ -3965,8 +4024,20 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
break;
|
||||
case Uri_PROPERTY_DOMAIN:
|
||||
if(This->domain_offset > -1) {
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset);
|
||||
if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN) {
|
||||
unsigned int punycode_length;
|
||||
|
||||
punycode_length = IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset, NULL, 0);
|
||||
*pbstrProperty = SysAllocStringLen(NULL, punycode_length);
|
||||
if (*pbstrProperty)
|
||||
IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset, *pbstrProperty, punycode_length);
|
||||
} else {
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+This->domain_offset,
|
||||
This->host_len-This->domain_offset);
|
||||
}
|
||||
|
||||
hres = S_OK;
|
||||
} else {
|
||||
*pbstrProperty = SysAllocStringLen(NULL, 0);
|
||||
|
@ -4009,6 +4080,14 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
|
|||
/* The '[' and ']' aren't included for IPv6 addresses. */
|
||||
if(This->host_type == Uri_HOST_IPV6)
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+1, This->host_len-2);
|
||||
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN) {
|
||||
unsigned int punycode_length;
|
||||
|
||||
punycode_length = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
*pbstrProperty = SysAllocStringLen(NULL, punycode_length);
|
||||
if (*pbstrProperty)
|
||||
IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, *pbstrProperty, punycode_length);
|
||||
}
|
||||
else
|
||||
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start, This->host_len);
|
||||
|
||||
|
@ -4156,10 +4235,10 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
if(uriProp > Uri_PROPERTY_STRING_LAST)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Don't have support for flags yet. */
|
||||
if(dwFlags) {
|
||||
FIXME("(%p)->(%d %p %lx)\n", This, uriProp, pcchProperty, dwFlags);
|
||||
return E_NOTIMPL;
|
||||
if(dwFlags != 0 && dwFlags != Uri_DISPLAY_NO_FRAGMENT && dwFlags != Uri_PUNYCODE_IDN_HOST
|
||||
&& dwFlags != Uri_DISPLAY_IDN_HOST) {
|
||||
*pcchProperty = 0;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
switch(uriProp) {
|
||||
|
@ -4167,6 +4246,12 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
|
||||
*pcchProperty = 0;
|
||||
hres = S_FALSE;
|
||||
}
|
||||
/* Uri_PUNYCODE_IDN_HOST doesn't remove user info containing only "@" and ":@" */
|
||||
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1) {
|
||||
unsigned int punycode_host_len = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
*pcchProperty = This->canon_len - This->host_len + punycode_host_len;
|
||||
hres = S_OK;
|
||||
} else {
|
||||
if(This->scheme_type != URL_SCHEME_UNKNOWN) {
|
||||
if(This->userinfo_start > -1 && This->userinfo_len == 0)
|
||||
|
@ -4201,11 +4286,18 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
else
|
||||
*pcchProperty = This->canon_len;
|
||||
|
||||
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
|
||||
*pcchProperty -= This->fragment_len;
|
||||
|
||||
hres = S_OK;
|
||||
break;
|
||||
case Uri_PROPERTY_DOMAIN:
|
||||
if(This->domain_offset > -1)
|
||||
*pcchProperty = This->host_len - This->domain_offset;
|
||||
if(This->domain_offset > -1) {
|
||||
if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN)
|
||||
*pcchProperty = IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset, This->host_len-This->domain_offset, NULL, 0);
|
||||
else
|
||||
*pcchProperty = This->host_len - This->domain_offset;
|
||||
}
|
||||
else
|
||||
*pcchProperty = 0;
|
||||
|
||||
|
@ -4231,6 +4323,8 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
/* '[' and ']' aren't included in the length. */
|
||||
if(This->host_type == Uri_HOST_IPV6)
|
||||
*pcchProperty -= 2;
|
||||
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1)
|
||||
*pcchProperty = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
|
||||
|
||||
hres = (This->host_start > -1) ? S_OK : S_FALSE;
|
||||
break;
|
||||
|
@ -4274,6 +4368,16 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
|
|||
hres = E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(hres == S_OK
|
||||
&& ((dwFlags == Uri_DISPLAY_NO_FRAGMENT && uriProp != Uri_PROPERTY_DISPLAY_URI)
|
||||
|| (dwFlags == Uri_PUNYCODE_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST)
|
||||
|| (dwFlags == Uri_DISPLAY_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
|
||||
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST))) {
|
||||
*pcchProperty = 0;
|
||||
hres = E_INVALIDARG;
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
|
|
@ -6187,6 +6187,13 @@ static const struct message WmMove_mouse[] = {
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message WmMove_mouse2[] = {
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOACTIVATE },
|
||||
{ WM_GETTEXT, sent|optional },
|
||||
{ WM_GETMINMAXINFO, sent|defwinproc },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void test_setwindowpos(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
|
@ -6253,6 +6260,11 @@ static void test_setwindowpos(void)
|
|||
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
|
||||
flush_events();
|
||||
ok_sequence(WmMove_mouse, "MouseMove", FALSE);
|
||||
/* if the window and client rects were not changed WM_MOUSEMOVE is not sent. */
|
||||
res = SetWindowPos( hwnd, 0, 205, 205, 200, 200, SWP_NOZORDER | SWP_NOACTIVATE );
|
||||
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
|
||||
flush_events();
|
||||
ok_sequence(WmMove_mouse2, "MouseMove2", FALSE);
|
||||
ignore_mouse_messages = TRUE;
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
|
|
@ -4067,11 +4067,8 @@ static void test_SetForegroundWindow(HWND hwnd)
|
|||
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
|
||||
if (0) check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
|
||||
|
||||
/* FIXME: these tests are failing because of a race condition
|
||||
* between internal focus state applied immediately and X11 focus
|
||||
* 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());
|
||||
ok(GetActiveWindow() == hwnd2, "Expected active window %p, got %p.\n", hwnd2, GetActiveWindow());
|
||||
ok(GetFocus() == hwnd2, "Expected focus window %p, got %p.\n", hwnd2, GetFocus());
|
||||
|
||||
SetForegroundWindow(hwnd);
|
||||
check_wnd_state(hwnd, hwnd, hwnd, 0);
|
||||
|
|
|
@ -558,7 +558,7 @@
|
|||
@ stdcall GetDlgItemTextA(long long ptr long)
|
||||
@ stdcall GetDlgItemTextW(long long ptr long)
|
||||
@ stdcall GetDoubleClickTime() NtUserGetDoubleClickTime
|
||||
# @ stub GetDpiAwarenessContextForProcess
|
||||
@ stdcall GetDpiAwarenessContextForProcess(ptr)
|
||||
@ stdcall GetDpiForMonitorInternal(long long ptr ptr) NtUserGetDpiForMonitor
|
||||
@ stdcall GetDpiForSystem()
|
||||
@ stdcall GetDpiForWindow(long)
|
||||
|
|
|
@ -615,6 +615,13 @@ DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( HWND hwnd )
|
|||
return LongToHandle( NtUserGetWindowDpiAwarenessContext( hwnd ) );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetDpiAwarenessContextForProcess (USER32.@)
|
||||
*/
|
||||
DPI_AWARENESS_CONTEXT WINAPI GetDpiAwarenessContextForProcess(HANDLE process)
|
||||
{
|
||||
return LongToHandle( NtUserGetProcessDpiAwarenessContext( process ) );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetWindowDpiHostingBehavior (USER32.@)
|
||||
|
|
|
@ -2729,7 +2729,7 @@ int peek_message( MSG *msg, const struct peek_message_filter *filter )
|
|||
{
|
||||
NTSTATUS res;
|
||||
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;
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
struct packed_message data;
|
||||
message_data_t msg_data;
|
||||
union message_data msg_data;
|
||||
unsigned int res;
|
||||
int i;
|
||||
timeout_t timeout = TIMEOUT_INFINITE;
|
||||
|
|
|
@ -275,10 +275,11 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
|
|||
.serialnumber = {'0','0','0','0',0},
|
||||
};
|
||||
struct iohid_device *impl;
|
||||
USAGE_AND_PAGE usages;
|
||||
CFStringRef str;
|
||||
|
||||
desc.usages.UsagePage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsagePageKey)));
|
||||
desc.usages.Usage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsageKey)));
|
||||
usages.UsagePage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsagePageKey)));
|
||||
usages.Usage = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDPrimaryUsageKey)));
|
||||
|
||||
desc.vid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVendorIDKey)));
|
||||
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) ||
|
||||
!CFStringCompare(str, CFSTR(kIOHIDTransportBluetoothLowEnergyValue), 0);
|
||||
|
||||
if (desc.usages.UsagePage != HID_USAGE_PAGE_GENERIC ||
|
||||
!(desc.usages.Usage == HID_USAGE_GENERIC_JOYSTICK || desc.usages.Usage == HID_USAGE_GENERIC_GAMEPAD))
|
||||
if (usages.UsagePage != HID_USAGE_PAGE_GENERIC ||
|
||||
!(usages.Usage == HID_USAGE_GENERIC_JOYSTICK || usages.Usage == HID_USAGE_GENERIC_GAMEPAD))
|
||||
{
|
||||
/* winebus isn't currently meant to handle anything but these, and
|
||||
* 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);
|
||||
}
|
||||
|
||||
static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
||||
static BOOL descriptor_add_haptic(struct sdl_device *impl, BOOL force)
|
||||
{
|
||||
USHORT i, count = 0;
|
||||
USAGE usages[16];
|
||||
|
@ -227,16 +227,16 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
|||
if ((impl->effect_support & EFFECT_SUPPORT_PHYSICAL))
|
||||
{
|
||||
/* SDL_HAPTIC_SQUARE doesn't exist */
|
||||
if (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 (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 (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 (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 (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_SINE)) usages[count++] = PID_USAGE_ET_SINE;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_TRIANGLE)) usages[count++] = PID_USAGE_ET_TRIANGLE;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_SAWTOOTHUP)) usages[count++] = PID_USAGE_ET_SAWTOOTH_UP;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_SAWTOOTHDOWN)) usages[count++] = PID_USAGE_ET_SAWTOOTH_DOWN;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_SPRING)) usages[count++] = PID_USAGE_ET_SPRING;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_DAMPER)) usages[count++] = PID_USAGE_ET_DAMPER;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_INERTIA)) usages[count++] = PID_USAGE_ET_INERTIA;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_FRICTION)) usages[count++] = PID_USAGE_ET_FRICTION;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_CONSTANT)) usages[count++] = PID_USAGE_ET_CONSTANT_FORCE;
|
||||
if (force || (impl->effect_support & SDL_HAPTIC_RAMP)) usages[count++] = PID_USAGE_ET_RAMP;
|
||||
|
||||
if (!hid_device_add_physical(&impl->unix_device, usages, count))
|
||||
return FALSE;
|
||||
|
@ -360,7 +360,7 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
|
|||
if (!hid_device_end_input_report(iface))
|
||||
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;
|
||||
|
||||
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))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
if (!descriptor_add_haptic(impl))
|
||||
if (!descriptor_add_haptic(impl, FALSE))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
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)
|
||||
{
|
||||
struct sdl_device *impl = impl_from_unix_device(iface);
|
||||
NTSTATUS status;
|
||||
|
||||
pthread_mutex_lock(&sdl_cs);
|
||||
|
||||
if (impl->sdl_controller) status = build_controller_report_descriptor(iface);
|
||||
else status = build_joystick_report_descriptor(iface);
|
||||
impl->started = !status;
|
||||
|
||||
impl->started = TRUE;
|
||||
pthread_mutex_unlock(&sdl_cs);
|
||||
|
||||
return status;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (impl->effect_ids[index] < 0) return STATUS_UNSUCCESSFUL;
|
||||
if (id < 0) return STATUS_SUCCESS;
|
||||
|
||||
switch (control)
|
||||
{
|
||||
|
@ -991,8 +986,6 @@ static void sdl_add_device(unsigned int index)
|
|||
if (controller)
|
||||
{
|
||||
desc.is_gamepad = TRUE;
|
||||
desc.usages.UsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
desc.usages.Usage = HID_USAGE_GENERIC_GAMEPAD;
|
||||
axis_count = 6;
|
||||
}
|
||||
else
|
||||
|
@ -1000,12 +993,12 @@ static void sdl_add_device(unsigned int index)
|
|||
int button_count = pSDL_JoystickNumButtons(joystick);
|
||||
axis_count = pSDL_JoystickNumAxes(joystick);
|
||||
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))
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (!axis_offset) strcpy(buffer, product);
|
||||
else snprintf(buffer, ARRAY_SIZE(buffer), "%s %d", product, axis_offset / 6);
|
||||
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->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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -728,12 +728,6 @@ static void lnxev_device_destroy(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);
|
||||
start_polling_device(iface);
|
||||
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
|
||||
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};
|
||||
struct input_id device_id = {0};
|
||||
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)
|
||||
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
|
||||
|
||||
desc.usages = device_usage;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1321,6 +1312,13 @@ static void udev_add_device(struct udev_device *dev, int fd)
|
|||
strcpy(impl->devnode, devnode);
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -417,7 +417,7 @@ static DWORD check_bus_option(const WCHAR *option, DWORD 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])];
|
||||
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_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");
|
||||
if (!NtQueryValueKey(driver_key, &str, KeyValuePartialInformation, info,
|
||||
sizeof(buffer) - sizeof(WCHAR), &size))
|
||||
|
@ -684,22 +726,41 @@ static NTSTATUS get_device_descriptors(UINT64 unix_device, BYTE **report_desc, U
|
|||
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;
|
||||
USAGE_AND_PAGE usages = {0};
|
||||
UINT report_desc_length;
|
||||
UINT i, count = 0, report_desc_length;
|
||||
HIDP_BUTTON_CAPS *button_caps;
|
||||
BYTE *report_desc;
|
||||
NTSTATUS status;
|
||||
HIDP_CAPS caps;
|
||||
|
||||
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.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);
|
||||
RtlFreeHeap(GetProcessHeap(), 0, report_desc);
|
||||
}
|
||||
|
||||
*buttons = count;
|
||||
return usages;
|
||||
}
|
||||
|
||||
|
@ -749,18 +810,21 @@ static DWORD CALLBACK bus_main_thread(void *args)
|
|||
case BUS_EVENT_TYPE_DEVICE_CREATED:
|
||||
{
|
||||
struct device_desc desc = event->device_created.desc;
|
||||
if (desc.is_hidraw && !desc.usages.UsagePage) desc.usages = get_hidraw_device_usages(event->device);
|
||||
if (!desc.is_hidraw != !is_hidraw_enabled(desc.vid, desc.pid, &desc.usages))
|
||||
USAGE_AND_PAGE 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};
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -123,9 +115,21 @@ static const struct device_desc mouse_device_desc =
|
|||
|
||||
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 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->device = (UINT_PTR)hid_device_create(&mouse_vtbl, sizeof(struct mouse_device));
|
||||
params->device = (UINT_PTR)iface;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -140,14 +144,6 @@ static void keyboard_destroy(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;
|
||||
}
|
||||
|
||||
|
@ -214,9 +210,21 @@ static const struct device_desc keyboard_device_desc =
|
|||
|
||||
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 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->device = (UINT_PTR)hid_device_create(&keyboard_vtbl, sizeof(struct keyboard_device));
|
||||
params->device = (UINT_PTR)iface;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ struct device_desc
|
|||
UINT version;
|
||||
UINT input;
|
||||
UINT uid;
|
||||
USAGE_AND_PAGE usages;
|
||||
BOOL is_gamepad;
|
||||
BOOL is_hidraw;
|
||||
BOOL is_bluetooth;
|
||||
|
@ -151,8 +150,8 @@ enum unix_funcs
|
|||
static inline const char *debugstr_device_desc(struct device_desc *desc)
|
||||
{
|
||||
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}",
|
||||
desc->vid, desc->pid, desc->version, desc->input, desc->uid, desc->usages.UsagePage, desc->usages.Usage,
|
||||
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->is_gamepad, desc->is_hidraw, desc->is_bluetooth);
|
||||
}
|
||||
|
||||
|
|
|
@ -7366,7 +7366,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
|
|||
}
|
||||
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
|
||||
{
|
||||
shader_addline(buffer, "%s = clamp(outputs[%u].%c, 0.0, 1.0);\n",
|
||||
shader_addline(buffer, "%s = outputs[%u].%c;\n",
|
||||
legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord",
|
||||
output->register_idx, reg_mask[1]);
|
||||
}
|
||||
|
@ -11402,6 +11402,8 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s
|
|||
|
||||
TRACE("Shader model %u.\n", shader_model);
|
||||
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
|
||||
caps->vs_version = min(wined3d_settings.max_sm_vs, shader_model);
|
||||
caps->hs_version = min(wined3d_settings.max_sm_hs, shader_model);
|
||||
caps->ds_version = min(wined3d_settings.max_sm_ds, shader_model);
|
||||
|
@ -11743,6 +11745,8 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter,
|
|||
{
|
||||
const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl_const(adapter)->gl_info;
|
||||
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
|
||||
caps->emulated_flatshading = !needs_legacy_glsl_syntax(gl_info);
|
||||
caps->max_active_lights = WINED3D_MAX_ACTIVE_LIGHTS;
|
||||
caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
|
||||
|
|
|
@ -1065,6 +1065,8 @@ static void shader_spirv_init_context_state(struct wined3d_context *context)
|
|||
|
||||
static void shader_spirv_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps)
|
||||
{
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
|
||||
caps->vs_version = min(wined3d_settings.max_sm_vs, 5);
|
||||
caps->hs_version = min(wined3d_settings.max_sm_hs, 5);
|
||||
caps->ds_version = min(wined3d_settings.max_sm_ds, 5);
|
||||
|
@ -1196,6 +1198,7 @@ static void spirv_fragment_pipe_vk_fp_disable(const struct wined3d_context *cont
|
|||
static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps)
|
||||
{
|
||||
memset(caps, 0, sizeof(*caps));
|
||||
caps->max_blend_stages = WINED3D_MAX_FFP_TEXTURES;
|
||||
}
|
||||
|
||||
static unsigned int spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_adapter *adapter)
|
||||
|
|
|
@ -3697,14 +3697,9 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
|
|||
if (changed->texture_matrices)
|
||||
{
|
||||
struct wined3d_ffp_vs_constants constants;
|
||||
struct wined3d_stream_info si;
|
||||
|
||||
/* FIXME: This is a bit fragile. Ideally we should be calculating
|
||||
* stream info from the stateblock state. */
|
||||
wined3d_stream_info_from_declaration(&si, context->state, &device->adapter->d3d_info);
|
||||
|
||||
for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i)
|
||||
get_texture_matrix(&si, state, i, &constants.texture_matrices[i]);
|
||||
get_texture_matrix(state, i, &constants.texture_matrices[i]);
|
||||
wined3d_device_context_push_constants(context,
|
||||
WINED3D_PUSH_CONSTANTS_VS_FFP, WINED3D_SHADER_CONST_FFP_TEXMATRIX,
|
||||
offsetof(struct wined3d_ffp_vs_constants, texture_matrices),
|
||||
|
|
|
@ -5608,38 +5608,43 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t
|
|||
|
||||
mat = *matrix;
|
||||
|
||||
/* Under Direct3D the R/Z coord can be used for translation, under
|
||||
* OpenGL we use the Q coord instead. */
|
||||
/* When less than 4 components are provided for an attribute, the remaining
|
||||
* components are filled with (..., 0, 0, 1). This is the case when using
|
||||
* shaders in Direct3D as well as in GL and Vulkan.
|
||||
*
|
||||
* However, when using the Direct3D fixed function vertex pipeline, the
|
||||
* texture coordinates transformed by texture matrices effectively have
|
||||
* 1 in the first "default" component and 0 in the others (e.g. for
|
||||
* R32_FLOAT the coordinates are (..., 1, 0, 0).
|
||||
*
|
||||
* We could approximate this by modifying the shader, but modifying uniforms
|
||||
* is generally cheaper, so instead we change the matrix, copying the 2nd or
|
||||
* 3rd column to the 4th. That is, whichever coefficients expect a value of
|
||||
* 1 will instead be used as the coefficients for the 4th column, which
|
||||
* actually has a value of 1. The coefficients for other columns don't need
|
||||
* to be modified, since the corresponding texcoord components are zero. */
|
||||
|
||||
if (!(flags & WINED3D_TTFF_PROJECTED) && !calculated_coords)
|
||||
{
|
||||
switch (format_id)
|
||||
{
|
||||
/* Direct3D passes the default 1.0 in the 2nd coord, while GL
|
||||
* passes it in the 4th. Swap 2nd and 4th coord. No need to
|
||||
* store the value of mat._41 in mat._21 because the input
|
||||
* value to the transformation will be 0, so the matrix value
|
||||
* is irrelevant. */
|
||||
case WINED3DFMT_R32_FLOAT:
|
||||
mat._41 = mat._21;
|
||||
mat._42 = mat._22;
|
||||
mat._43 = mat._23;
|
||||
mat._44 = mat._24;
|
||||
break;
|
||||
/* See above, just 3rd and 4th coord. */
|
||||
|
||||
case WINED3DFMT_R32G32_FLOAT:
|
||||
mat._41 = mat._31;
|
||||
mat._42 = mat._32;
|
||||
mat._43 = mat._33;
|
||||
mat._44 = mat._34;
|
||||
break;
|
||||
case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
|
||||
case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
|
||||
|
||||
/* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
|
||||
* into a bad place. The division elimination below will apply to make sure the
|
||||
* 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
|
||||
*/
|
||||
case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
|
||||
case WINED3DFMT_R32G32B32_FLOAT:
|
||||
case WINED3DFMT_R32G32B32A32_FLOAT:
|
||||
case WINED3DFMT_UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
FIXME("Unexpected fixed function texture coord input\n");
|
||||
|
@ -5649,23 +5654,29 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t
|
|||
*out_matrix = mat;
|
||||
}
|
||||
|
||||
void get_texture_matrix(const struct wined3d_stream_info *si,
|
||||
const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat)
|
||||
static enum wined3d_format_id get_texcoord_format(const struct wined3d_vertex_declaration *decl, unsigned int index)
|
||||
{
|
||||
for (unsigned int i = 0; i < decl->element_count; ++i)
|
||||
{
|
||||
if (decl->elements[i].usage == WINED3D_DECL_USAGE_TEXCOORD
|
||||
&& decl->elements[i].usage_idx == index)
|
||||
return decl->elements[i].format->id;
|
||||
}
|
||||
|
||||
return WINED3DFMT_UNKNOWN;
|
||||
}
|
||||
|
||||
void get_texture_matrix(const struct wined3d_stateblock_state *state,
|
||||
const unsigned int tex, struct wined3d_matrix *mat)
|
||||
{
|
||||
BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
|
||||
!= WINED3DTSS_TCI_PASSTHRU;
|
||||
unsigned int coord_idx = min(state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0x0000ffff,
|
||||
WINED3D_MAX_FFP_TEXTURES - 1);
|
||||
enum wined3d_format_id attribute_format;
|
||||
|
||||
if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))
|
||||
attribute_format = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->id;
|
||||
else
|
||||
attribute_format = WINED3DFMT_UNKNOWN;
|
||||
|
||||
compute_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + tex],
|
||||
state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
|
||||
generated, attribute_format, mat);
|
||||
generated, get_texcoord_format(state->vertex_declaration, coord_idx), mat);
|
||||
}
|
||||
|
||||
void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state,
|
||||
|
|
|
@ -4376,8 +4376,8 @@ static inline BOOL shader_sampler_is_shadow(const struct wined3d_shader *shader,
|
|||
|
||||
void get_identity_matrix(struct wined3d_matrix *mat);
|
||||
void get_modelview_matrix(const struct wined3d_stateblock_state *state, unsigned int index, struct wined3d_matrix *mat);
|
||||
void get_texture_matrix(const struct wined3d_stream_info *si,
|
||||
const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat);
|
||||
void get_texture_matrix(const struct wined3d_stateblock_state *state,
|
||||
const unsigned int tex, struct wined3d_matrix *mat);
|
||||
void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state,
|
||||
float *out_min, float *out_max);
|
||||
void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state,
|
||||
|
|
|
@ -696,57 +696,72 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
|
|||
static const struct {
|
||||
WCHAR wchar;
|
||||
DWORD vkey;
|
||||
/* Mac virtual key code that must match wchar under the current layout.
|
||||
* A value of -1 means match-any.
|
||||
* TODO: replace -1 with the actual mac virtual key codes for all mappings
|
||||
* and their respective layouts to avoid false matches, when possible. */
|
||||
int mac_keyc;
|
||||
} symbol_vkeys[] = {
|
||||
{ '-', VK_OEM_MINUS },
|
||||
{ '+', VK_OEM_PLUS },
|
||||
{ '_', VK_OEM_MINUS },
|
||||
{ ',', VK_OEM_COMMA },
|
||||
{ '.', VK_OEM_PERIOD },
|
||||
{ '=', VK_OEM_PLUS },
|
||||
{ '>', VK_OEM_PERIOD },
|
||||
{ '<', VK_OEM_COMMA },
|
||||
{ '|', VK_OEM_5 },
|
||||
{ '\\', VK_OEM_5 },
|
||||
{ '`', VK_OEM_3 },
|
||||
{ '[', VK_OEM_4 },
|
||||
{ '~', VK_OEM_3 },
|
||||
{ 0x00DF, VK_OEM_4 }, /* 0x00DF is ESZETT */
|
||||
{ 0x00FC, VK_OEM_1 }, /* 0x00FC is German U Umlaut */
|
||||
{ 0x00F6, VK_OEM_3 }, /* 0x00F6 is German O Umlaut */
|
||||
{ 0x00E4, VK_OEM_7 }, /* 0x00B4 is German A Umlaut */
|
||||
{ '?', VK_OEM_2 },
|
||||
{ ']', VK_OEM_6 },
|
||||
{ '/', VK_OEM_2 },
|
||||
{ ':', VK_OEM_1 },
|
||||
{ '}', VK_OEM_6 },
|
||||
{ '{', VK_OEM_4 },
|
||||
{ ';', VK_OEM_1 },
|
||||
{ '\'', VK_OEM_7 },
|
||||
{ ':', VK_OEM_PERIOD },
|
||||
{ ';', VK_OEM_COMMA },
|
||||
{ '"', VK_OEM_7 },
|
||||
{ 0x00B4, VK_OEM_4 }, /* 0x00B4 is ACUTE ACCENT */
|
||||
{ '\'', VK_OEM_2 },
|
||||
{ 0x00A7, VK_OEM_5 }, /* 0x00A7 is SECTION SIGN */
|
||||
{ '*', VK_OEM_PLUS },
|
||||
{ 0x00B4, VK_OEM_7 },
|
||||
{ '`', VK_OEM_4 },
|
||||
{ '[', VK_OEM_6 },
|
||||
{ '/', VK_OEM_5 },
|
||||
{ '^', VK_OEM_6 },
|
||||
{ '*', VK_OEM_2 },
|
||||
{ '{', VK_OEM_6 },
|
||||
{ 0x00B4, VK_OEM_6 },
|
||||
{ '~', VK_OEM_1 },
|
||||
{ '?', VK_OEM_PLUS },
|
||||
{ '?', VK_OEM_4 },
|
||||
{ 0x00B4, VK_OEM_3 },
|
||||
{ '?', VK_OEM_COMMA },
|
||||
{ '~', VK_OEM_PLUS },
|
||||
{ ']', VK_OEM_4 },
|
||||
{ '\'', VK_OEM_3 },
|
||||
{ 0x00A7, VK_OEM_7 },
|
||||
{ '<', VK_OEM_102 },
|
||||
{ '-', VK_OEM_PLUS, kVK_ANSI_Equal },
|
||||
{ '-', VK_OEM_MINUS, -1 },
|
||||
{ '+', VK_OEM_PLUS, -1 },
|
||||
{ '_', VK_OEM_MINUS, -1 },
|
||||
{ ',', VK_OEM_COMMA, -1 },
|
||||
{ '.', VK_OEM_PERIOD, -1 },
|
||||
{ '=', VK_OEM_8, kVK_ANSI_Slash },
|
||||
{ '=', VK_OEM_PLUS, -1 },
|
||||
{ '!', VK_OEM_8, kVK_ANSI_Slash },
|
||||
{ 0x00F9, VK_OEM_3, kVK_ANSI_Quote }, /* 0x00F9 is French U accent grave */
|
||||
{ '$', VK_OEM_1, kVK_ANSI_RightBracket },
|
||||
{ ':', VK_OEM_2, kVK_ANSI_Period },
|
||||
{ '*', VK_OEM_5, kVK_ANSI_Backslash },
|
||||
{ '`', VK_OEM_5, kVK_ANSI_Backslash },
|
||||
{ ';', VK_OEM_PERIOD, kVK_ANSI_Comma },
|
||||
{ ')', VK_OEM_4, kVK_ANSI_Minus },
|
||||
{ '>', VK_OEM_PERIOD, -1 },
|
||||
{ '<', VK_OEM_COMMA, -1 },
|
||||
{ '|', VK_OEM_5, -1 },
|
||||
{ '\\', VK_OEM_5, -1 },
|
||||
{ '`', VK_OEM_3, -1 },
|
||||
{ '[', VK_OEM_4, -1 },
|
||||
{ '~', VK_OEM_3, -1 },
|
||||
{ 0x00DF, VK_OEM_4, kVK_ANSI_Minus }, /* 0x00DF is ESZETT */
|
||||
{ 0x00FC, VK_OEM_1, kVK_ANSI_LeftBracket }, /* 0x00FC is German U Umlaut */
|
||||
{ 0x00F6, VK_OEM_3, kVK_ANSI_Semicolon }, /* 0x00F6 is German O Umlaut */
|
||||
{ 0x00E4, VK_OEM_7, kVK_ANSI_Quote }, /* 0x00B4 is German A Umlaut */
|
||||
{ '?', VK_OEM_2, -1 },
|
||||
{ ']', VK_OEM_6, -1 },
|
||||
{ '/', VK_OEM_2, -1 },
|
||||
{ ':', VK_OEM_1, -1 },
|
||||
{ '}', VK_OEM_6, -1 },
|
||||
{ '{', VK_OEM_4, },
|
||||
{ ';', VK_OEM_1, -1 },
|
||||
{ '\'', VK_OEM_7, -1 },
|
||||
{ ':', VK_OEM_PERIOD, -1 },
|
||||
{ ';', VK_OEM_COMMA, -1 },
|
||||
{ '"', VK_OEM_7, -1 },
|
||||
{ 0x00B4, VK_OEM_4, kVK_ANSI_Equal }, /* 0x00B4 is ACUTE ACCENT */
|
||||
{ '\'', VK_OEM_2, -1 },
|
||||
{ 0x00A7, VK_OEM_5, -1 }, /* 0x00A7 is SECTION SIGN */
|
||||
{ '*', VK_OEM_PLUS, -1 },
|
||||
{ 0x00B4, VK_OEM_7, -1 },
|
||||
{ '`', VK_OEM_4, -1 },
|
||||
{ '[', VK_OEM_6, -1 },
|
||||
{ '/', VK_OEM_5, -1 },
|
||||
{ '^', VK_OEM_6, -1 },
|
||||
{ '*', VK_OEM_2, -1 },
|
||||
{ '{', VK_OEM_6, -1 },
|
||||
{ 0x00B4, VK_OEM_6, -1 },
|
||||
{ '~', VK_OEM_1, -1 },
|
||||
{ '?', VK_OEM_PLUS, -1 },
|
||||
{ '?', VK_OEM_4, -1 },
|
||||
{ 0x00B4, VK_OEM_3, -1 },
|
||||
{ '?', VK_OEM_COMMA, -1 },
|
||||
{ '~', VK_OEM_PLUS, -1 },
|
||||
{ ']', VK_OEM_4, -1 },
|
||||
{ '\'', VK_OEM_3, -1 },
|
||||
{ 0x00A7, VK_OEM_7, -1 },
|
||||
{ '<', VK_OEM_102, -1 },
|
||||
};
|
||||
int i;
|
||||
|
||||
|
@ -915,6 +930,8 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
|
|||
if (!thread_data->keyc2scan[keyc]) continue; /* not a known Mac key code */
|
||||
if (thread_data->keyc2vkey[keyc] || !map[keyc][combo][0])
|
||||
continue;
|
||||
if (symbol_vkeys[i].mac_keyc != -1 && symbol_vkeys[i].mac_keyc != keyc)
|
||||
continue;
|
||||
|
||||
if (char_matches_string(symbol_vkeys[i].wchar, map[keyc][combo], collatorRef))
|
||||
{
|
||||
|
|
|
@ -73,7 +73,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height )
|
|||
|
||||
/* Create window */
|
||||
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 );
|
||||
|
||||
if (default_visual.visual != DefaultVisual( display, DefaultScreen(display) ))
|
||||
|
|
|
@ -171,13 +171,49 @@ static inline void free_event_data( XEvent *event )
|
|||
#endif
|
||||
}
|
||||
|
||||
static BOOL host_window_filter_event( XEvent *event )
|
||||
static void host_window_send_configure_events( struct host_window *win, Display *display, unsigned long serial, XEvent *previous )
|
||||
{
|
||||
XConfigureEvent configure = {.type = ConfigureNotify, .serial = serial, .display = display};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < win->children_count; i++)
|
||||
{
|
||||
RECT rect = win->children[i].rect;
|
||||
struct x11drv_win_data *data;
|
||||
HWND hwnd;
|
||||
|
||||
configure.event = win->children[i].window;
|
||||
configure.window = configure.event;
|
||||
configure.x = rect.left;
|
||||
configure.y = rect.top;
|
||||
configure.width = rect.right - rect.left;
|
||||
configure.height = rect.bottom - rect.top;
|
||||
configure.send_event = 0;
|
||||
|
||||
/* Only send a fake event if we're not expecting one from a state/config request.
|
||||
* We may know what was requested, but not what the WM will decide to reply, and our
|
||||
* fake event might trigger some undesired changes before the real ConfigureNotify.
|
||||
*/
|
||||
if (!XFindContext( configure.display, configure.window, winContext, (char **)&hwnd ) &&
|
||||
(data = get_win_data( hwnd )))
|
||||
{
|
||||
/* embedded windows won't receive synthetic ConfigureNotify and are positioned by the WM */
|
||||
BOOL has_serial = !data->embedded && (data->wm_state_serial || data->configure_serial);
|
||||
release_win_data( data );
|
||||
if (has_serial) continue;
|
||||
}
|
||||
|
||||
if (previous->type == ConfigureNotify && previous->xconfigure.window == configure.window) continue;
|
||||
TRACE( "generating ConfigureNotify for window %p/%lx, rect %s\n", hwnd, configure.window, wine_dbgstr_rect(&rect) );
|
||||
XPutBackEvent( configure.display, (XEvent *)&configure );
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL host_window_filter_event( XEvent *event, XEvent *previous )
|
||||
{
|
||||
struct host_window *win;
|
||||
RECT old_rect;
|
||||
|
||||
if (!(win = get_host_window( event->xany.window, FALSE ))) return FALSE;
|
||||
old_rect = win->rect;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
|
@ -190,6 +226,7 @@ static BOOL host_window_filter_event( XEvent *event )
|
|||
XReparentEvent *reparent = (XReparentEvent *)event;
|
||||
TRACE( "host window %p/%lx ReparentNotify, parent %lx\n", win, win->window, reparent->parent );
|
||||
host_window_set_parent( win, reparent->parent );
|
||||
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
|
||||
break;
|
||||
}
|
||||
case GravityNotify:
|
||||
|
@ -198,6 +235,7 @@ static BOOL host_window_filter_event( XEvent *event )
|
|||
OffsetRect( &win->rect, gravity->x - win->rect.left, gravity->y - win->rect.top );
|
||||
if (win->parent) win->rect = host_window_configure_child( win->parent, win->window, win->rect, FALSE );
|
||||
TRACE( "host window %p/%lx GravityNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) );
|
||||
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
|
||||
break;
|
||||
}
|
||||
case ConfigureNotify:
|
||||
|
@ -206,44 +244,11 @@ static BOOL host_window_filter_event( XEvent *event )
|
|||
SetRect( &win->rect, configure->x, configure->y, configure->x + configure->width, configure->y + configure->height );
|
||||
if (win->parent) win->rect = host_window_configure_child( win->parent, win->window, win->rect, configure->send_event );
|
||||
TRACE( "host window %p/%lx ConfigureNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) );
|
||||
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (old_rect.left != win->rect.left || old_rect.top != win->rect.top)
|
||||
{
|
||||
XConfigureEvent configure = {.type = ConfigureNotify, .serial = event->xany.serial, .display = event->xany.display};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < win->children_count; i++)
|
||||
{
|
||||
RECT rect = win->children[i].rect;
|
||||
struct x11drv_win_data *data;
|
||||
BOOL has_serial;
|
||||
HWND hwnd;
|
||||
|
||||
/* Only send a fake event if we're not expecting one from a state/config request.
|
||||
* We may know what was requested, but not what the WM will decide to reply, and our
|
||||
* fake event might trigger some undesired changes before the real ConfigureNotify.
|
||||
*/
|
||||
if (XFindContext( event->xany.display, event->xany.window, winContext, (char **)&hwnd )) continue;
|
||||
if (!(data = get_win_data( hwnd ))) continue;
|
||||
has_serial = data->wm_state_serial || data->configure_serial;
|
||||
release_win_data( data );
|
||||
if (has_serial) continue;
|
||||
|
||||
configure.event = win->children[i].window;
|
||||
configure.window = configure.event;
|
||||
configure.x = rect.left;
|
||||
configure.y = rect.top;
|
||||
configure.width = rect.right - rect.left;
|
||||
configure.height = rect.bottom - rect.top;
|
||||
configure.send_event = 0;
|
||||
|
||||
XPutBackEvent( configure.display, (XEvent *)&configure );
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -521,7 +526,7 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X
|
|||
continue; /* filtered, ignore it */
|
||||
}
|
||||
|
||||
if (host_window_filter_event( &event )) continue;
|
||||
if (host_window_filter_event( &event, &prev_event )) continue;
|
||||
|
||||
get_event_data( &event );
|
||||
if (prev_event.type) action = merge_events( &prev_event, &event );
|
||||
|
@ -756,12 +761,20 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
|
|||
}
|
||||
else if (protocol == x11drv_atom(WM_TAKE_FOCUS))
|
||||
{
|
||||
HWND last_focus = x11drv_thread_data()->last_focus;
|
||||
HWND last_focus = x11drv_thread_data()->last_focus, foreground = NtUserGetForegroundWindow();
|
||||
|
||||
TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08x), focus=%p, active=%p, fg=%p, last=%p\n",
|
||||
hwnd, NtUserIsWindowEnabled(hwnd), NtUserIsWindowVisible(hwnd),
|
||||
(int)NtUserGetWindowLongW(hwnd, GWL_STYLE),
|
||||
get_focus(), get_active_window(), NtUserGetForegroundWindow(), last_focus );
|
||||
if (window_has_pending_wm_state( hwnd, -1 ))
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, event_time, foreground );
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p\n", hwnd, event->window,
|
||||
event->serial, event_time, foreground );
|
||||
TRACE( " enabled %u, visible %u, style %#x, focus %p, active %p, last %p\n",
|
||||
NtUserIsWindowEnabled( hwnd ), NtUserIsWindowVisible( hwnd ), (int)NtUserGetWindowLongW( hwnd, GWL_STYLE ),
|
||||
get_focus(), get_active_window(), last_focus );
|
||||
|
||||
if (can_activate_window(hwnd))
|
||||
{
|
||||
|
@ -778,7 +791,7 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
|
|||
}
|
||||
else if (hwnd == NtUserGetDesktopWindow())
|
||||
{
|
||||
hwnd = NtUserGetForegroundWindow();
|
||||
hwnd = foreground;
|
||||
if (!hwnd) hwnd = last_focus;
|
||||
if (!hwnd) hwnd = NtUserGetDesktopWindow();
|
||||
set_focus( event->display, hwnd, event_time );
|
||||
|
@ -840,14 +853,23 @@ BOOL is_current_process_focused(void)
|
|||
*/
|
||||
static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev )
|
||||
{
|
||||
HWND foreground = NtUserGetForegroundWindow();
|
||||
XFocusChangeEvent *event = &xev->xfocus;
|
||||
BOOL was_grabbed;
|
||||
|
||||
if (event->detail == NotifyPointer) return FALSE;
|
||||
if (!hwnd) return FALSE;
|
||||
|
||||
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
|
||||
if (window_has_pending_wm_state( hwnd, -1 ))
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
|
||||
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
|
||||
if (event->detail == NotifyPointer) return FALSE;
|
||||
/* when focusing in the virtual desktop window, re-apply the cursor clipping rect */
|
||||
if (is_virtual_desktop() && hwnd == NtUserGetDesktopWindow()) reapply_cursor_clipping();
|
||||
if (hwnd == NtUserGetDesktopWindow()) return FALSE;
|
||||
|
@ -916,10 +938,9 @@ static void focus_out( Display *display , HWND hwnd )
|
|||
*/
|
||||
static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
||||
{
|
||||
HWND foreground = NtUserGetForegroundWindow();
|
||||
XFocusChangeEvent *event = &xev->xfocus;
|
||||
|
||||
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
|
||||
|
||||
if (event->detail == NotifyPointer)
|
||||
{
|
||||
if (!hwnd && event->window == x11drv_thread_data()->clip_window)
|
||||
|
@ -933,6 +954,16 @@ static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
|||
}
|
||||
if (!hwnd) return FALSE;
|
||||
|
||||
if (window_has_pending_wm_state( hwnd, NormalState )) /* ignore FocusOut only if the window is being shown */
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
|
||||
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
|
||||
/* in virtual desktop mode or when keyboard is grabbed, release any cursor grab but keep the clipping rect */
|
||||
keyboard_grabbed = event->mode == NotifyGrab || event->mode == NotifyWhileGrabbed;
|
||||
if (is_virtual_desktop() || keyboard_grabbed) ungrab_clipping_window();
|
||||
|
@ -1073,9 +1104,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
|||
struct x11drv_win_data *data;
|
||||
RECT rect;
|
||||
POINT pos = {event->x, event->y};
|
||||
UINT flags;
|
||||
int cx, cy, x, y;
|
||||
DWORD style;
|
||||
UINT config_cmd, state_cmd;
|
||||
|
||||
if (!hwnd) return FALSE;
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
|
@ -1094,80 +1123,24 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
|||
SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height );
|
||||
window_configure_notify( data, event->serial, &rect );
|
||||
|
||||
if (!data->mapped || data->iconic) goto done;
|
||||
if (!data->whole_window || !data->managed) goto done;
|
||||
if (data->configure_serial && (long)(data->configure_serial - event->serial) > 0)
|
||||
{
|
||||
TRACE( "win %p/%lx event %d,%d,%dx%d ignoring old serial %lu/%lu\n",
|
||||
hwnd, data->whole_window, event->x, event->y, event->width, event->height,
|
||||
event->serial, data->configure_serial );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rect = window_rect_from_visible( &data->rects, rect );
|
||||
|
||||
TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n",
|
||||
hwnd, data->whole_window, (int)rect.left, (int)rect.top,
|
||||
(int)(rect.right-rect.left), (int)(rect.bottom-rect.top),
|
||||
event->x, event->y, event->width, event->height );
|
||||
|
||||
/* Compare what has changed */
|
||||
|
||||
x = rect.left;
|
||||
y = rect.top;
|
||||
cx = rect.right - rect.left;
|
||||
cy = rect.bottom - rect.top;
|
||||
flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
|
||||
if (!data->whole_window) flags |= SWP_NOCOPYBITS; /* we can't copy bits of foreign windows */
|
||||
|
||||
if (data->rects.window.left == x && data->rects.window.top == y) flags |= SWP_NOMOVE;
|
||||
else
|
||||
TRACE( "%p moving from (%d,%d) to (%d,%d)\n",
|
||||
hwnd, (int)data->rects.window.left, (int)data->rects.window.top, x, y );
|
||||
|
||||
if ((data->rects.window.right - data->rects.window.left == cx &&
|
||||
data->rects.window.bottom - data->rects.window.top == cy) ||
|
||||
IsRectEmpty( &data->rects.window ))
|
||||
flags |= SWP_NOSIZE;
|
||||
else
|
||||
TRACE( "%p resizing from (%dx%d) to (%dx%d)\n",
|
||||
hwnd, (int)(data->rects.window.right - data->rects.window.left),
|
||||
(int)(data->rects.window.bottom - data->rects.window.top), cx, cy );
|
||||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
if ((style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
||||
{
|
||||
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
|
||||
if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if (!(style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "win %p/%lx is maximized\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( data->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (style & WS_MAXIMIZE)
|
||||
{
|
||||
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( data->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
|
||||
{
|
||||
release_win_data( data );
|
||||
NtUserSetRawWindowPos( hwnd, rect, flags, FALSE );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
done:
|
||||
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 );
|
||||
return FALSE;
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
return config_cmd || state_cmd;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1227,85 +1200,33 @@ static int get_window_xembed_info( Display *display, Window window )
|
|||
*
|
||||
* 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;
|
||||
UINT style, value = 0;
|
||||
UINT value = 0, state_cmd = 0, config_cmd = 0;
|
||||
RECT rect;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return;
|
||||
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)
|
||||
{
|
||||
case PropertyDelete:
|
||||
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;
|
||||
/* ignore the initial state transition out of withdrawn state */
|
||||
/* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */
|
||||
if (!old_state) goto done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
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 );
|
||||
|
||||
if (!update_window || !data->managed || !data->mapped) goto done;
|
||||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
|
||||
if (data->iconic && data->wm_state == NormalState) /* restore window */
|
||||
{
|
||||
data->iconic = FALSE;
|
||||
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
|
||||
if ((style & WS_CAPTION) == WS_CAPTION && (data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
|
||||
return;
|
||||
}
|
||||
TRACE( "not restoring to max win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
if ((style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE))
|
||||
NtUserSetActiveWindow( hwnd );
|
||||
send_message( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
|
||||
return;
|
||||
}
|
||||
TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
}
|
||||
else if (!data->iconic && data->wm_state == IconicState)
|
||||
{
|
||||
data->iconic = TRUE;
|
||||
if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
release_win_data( data );
|
||||
send_message( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
|
||||
return;
|
||||
}
|
||||
TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
|
||||
}
|
||||
done:
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event )
|
||||
|
@ -1322,12 +1243,30 @@ static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event )
|
|||
static void handle_net_wm_state_notify( HWND hwnd, XPropertyEvent *event )
|
||||
{
|
||||
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 (event->state == PropertyNewValue) value = get_window_net_wm_state( event->display, event->window );
|
||||
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 );
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1338,79 +1277,13 @@ static BOOL X11DRV_PropertyNotify( HWND hwnd, XEvent *xev )
|
|||
XPropertyEvent *event = &xev->xproperty;
|
||||
|
||||
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(_NET_WM_STATE)) handle_net_wm_state_notify( hwnd, event );
|
||||
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.@)
|
||||
*
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "winnls.h"
|
||||
#include "ime.h"
|
||||
#include "kbd.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
|
|
@ -1160,7 +1160,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data )
|
|||
long monitors[4];
|
||||
XEvent xev;
|
||||
|
||||
if (!(data->net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
|
||||
if (!(data->pending_state.net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
|
||||
|| NtUserGetWindowLongW( data->hwnd, GWL_STYLE ) & WS_MINIMIZE)
|
||||
return;
|
||||
|
||||
|
@ -1211,10 +1211,15 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data )
|
|||
|
||||
static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_state )
|
||||
{
|
||||
UINT i, count;
|
||||
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->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 (data->pending_state.wm_state == IconicState) return; /* window is iconic, don't update its state now */
|
||||
if (!data->mapped) /* set the _NET_WM_STATE atom directly */
|
||||
{
|
||||
Atom atoms[NB_NET_WM_STATES + 1];
|
||||
|
@ -1250,6 +1255,8 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
|
|||
|
||||
for (i = 0; i < NB_NET_WM_STATES; i++)
|
||||
{
|
||||
if (!((old_state ^ new_state) & (1 << i))) continue;
|
||||
|
||||
xev.xclient.data.l[0] = (new_state & (1 << i)) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
||||
xev.xclient.data.l[1] = X11DRV_Atoms[net_wm_state_atoms[i] - FIRST_XATOM];
|
||||
xev.xclient.data.l[2] = ((net_wm_state_atoms[i] == XATOM__NET_WM_STATE_MAXIMIZED_VERT) ?
|
||||
|
@ -1263,14 +1270,19 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
|
|||
SubstructureRedirectMask | SubstructureNotifyMask, &xev );
|
||||
}
|
||||
}
|
||||
|
||||
XFlush( data->display );
|
||||
}
|
||||
|
||||
static void window_set_config( struct x11drv_win_data *data, const RECT *new_rect, BOOL above )
|
||||
{
|
||||
UINT style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), mask = 0;
|
||||
const RECT *old_rect = &data->pending_state.rect;
|
||||
XWindowChanges changes;
|
||||
|
||||
data->desired_state.rect = *new_rect;
|
||||
if (!data->whole_window) return; /* no window, nothing to update */
|
||||
if (EqualRect( old_rect, new_rect )) return; /* rects are the same, nothing to update */
|
||||
|
||||
/* resizing a managed maximized window is not allowed */
|
||||
if (!(style & WS_MAXIMIZE) || !data->managed)
|
||||
|
@ -1322,7 +1334,7 @@ static void update_net_wm_states( struct x11drv_win_data *data )
|
|||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
if (style & WS_MINIMIZE)
|
||||
new_state |= data->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 ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
|
||||
|
@ -1346,7 +1358,6 @@ static void update_net_wm_states( struct x11drv_win_data *data )
|
|||
}
|
||||
|
||||
window_set_net_wm_state( data, new_state );
|
||||
data->net_wm_state = new_state;
|
||||
update_net_wm_fullscreen_monitors( data );
|
||||
}
|
||||
|
||||
|
@ -1407,13 +1418,15 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_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->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 */
|
||||
|
||||
data->pending_state.wm_state = new_state;
|
||||
data->wm_state_serial = NextRequest( data->display );
|
||||
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu\n", data->hwnd, data->whole_window,
|
||||
old_state, new_state, data->wm_state_serial );
|
||||
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu, foreground %p\n", data->hwnd, data->whole_window,
|
||||
old_state, new_state, data->wm_state_serial, NtUserGetForegroundWindow() );
|
||||
|
||||
switch (MAKELONG(old_state, new_state))
|
||||
{
|
||||
|
@ -1433,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 );
|
||||
break;
|
||||
}
|
||||
|
||||
/* override redirect windows won't receive WM_STATE property changes */
|
||||
if (!data->managed) data->wm_state_serial = 0;
|
||||
|
||||
XFlush( data->display );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1444,7 +1462,6 @@ static void map_window( HWND hwnd, DWORD new_style )
|
|||
struct x11drv_win_data *data;
|
||||
|
||||
make_owner_managed( hwnd );
|
||||
wait_for_withdrawn_state( hwnd, TRUE );
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return;
|
||||
|
||||
|
@ -1458,7 +1475,6 @@ static void map_window( HWND hwnd, DWORD new_style )
|
|||
sync_window_style( data );
|
||||
|
||||
window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState );
|
||||
XFlush( data->display );
|
||||
|
||||
data->mapped = TRUE;
|
||||
data->iconic = (new_style & WS_MINIMIZE) != 0;
|
||||
|
@ -1475,8 +1491,6 @@ static void unmap_window( HWND hwnd )
|
|||
{
|
||||
struct x11drv_win_data *data;
|
||||
|
||||
wait_for_withdrawn_state( hwnd, FALSE );
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return;
|
||||
|
||||
if (data->mapped)
|
||||
|
@ -1484,14 +1498,96 @@ static void unmap_window( HWND hwnd )
|
|||
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
window_set_wm_state( data, WithdrawnState );
|
||||
data->mapped = FALSE;
|
||||
data->net_wm_state = 0;
|
||||
}
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
UINT window_update_client_state( struct x11drv_win_data *data )
|
||||
{
|
||||
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
|
||||
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->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 */
|
||||
{
|
||||
data->iconic = FALSE;
|
||||
if ((old_style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if ((old_style & WS_MAXIMIZEBOX) && !(old_style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return SC_MAXIMIZE;
|
||||
}
|
||||
}
|
||||
else if (old_style & (WS_MINIMIZE | WS_MAXIMIZE))
|
||||
{
|
||||
BOOL activate = (old_style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE);
|
||||
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return MAKELONG(SC_RESTORE, activate);
|
||||
}
|
||||
}
|
||||
else if (!data->iconic && data->current_state.wm_state == IconicState)
|
||||
{
|
||||
data->iconic = TRUE;
|
||||
if ((old_style & WS_MINIMIZEBOX) && !(old_style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return SC_MINIMIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT window_update_client_config( struct x11drv_win_data *data )
|
||||
{
|
||||
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), flags;
|
||||
RECT rect, old_rect = data->rects.window, new_rect;
|
||||
|
||||
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
|
||||
if (!data->mapped) return 0; /* ignore config changes on invisible 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 ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
||||
{
|
||||
if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(old_style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window );
|
||||
return SC_MAXIMIZE;
|
||||
}
|
||||
if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (old_style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
|
||||
return SC_RESTORE;
|
||||
}
|
||||
}
|
||||
|
||||
flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
rect = new_rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||
if (new_rect.left == old_rect.left && new_rect.top == old_rect.top) flags |= SWP_NOMOVE;
|
||||
else OffsetRect( &rect, old_rect.left - new_rect.left, old_rect.top - new_rect.top );
|
||||
if (rect.right == old_rect.right && rect.bottom == old_rect.bottom) flags |= SWP_NOSIZE;
|
||||
else if (IsRectEmpty( &rect )) flags |= SWP_NOSIZE;
|
||||
|
||||
if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) return 0;
|
||||
|
||||
TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window,
|
||||
wine_dbgstr_rect(&old_rect), wine_dbgstr_rect(&new_rect), flags );
|
||||
return MAKELONG(SC_MOVE, flags);
|
||||
}
|
||||
|
||||
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;
|
||||
const char *reason = NULL, *expected, *received;
|
||||
|
||||
|
@ -1516,16 +1612,20 @@ void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial,
|
|||
else
|
||||
{
|
||||
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;
|
||||
*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 )
|
||||
{
|
||||
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;
|
||||
const char *reason = NULL, *expected, *received;
|
||||
|
||||
|
@ -1548,16 +1648,20 @@ void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long ser
|
|||
else
|
||||
{
|
||||
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;
|
||||
*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 )
|
||||
{
|
||||
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;
|
||||
const char *reason = NULL, *expected, *received;
|
||||
|
||||
|
@ -1580,13 +1684,26 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial
|
|||
else
|
||||
{
|
||||
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;
|
||||
*expect_serial = 0;
|
||||
}
|
||||
|
||||
BOOL window_has_pending_wm_state( HWND hwnd, UINT state )
|
||||
{
|
||||
struct x11drv_win_data *data;
|
||||
BOOL pending;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
if (state != -1 && data->desired_state.wm_state != state) pending = FALSE;
|
||||
else pending = !!data->wm_state_serial;
|
||||
release_win_data( data );
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* make_window_embedded
|
||||
*/
|
||||
|
@ -1594,7 +1711,6 @@ void make_window_embedded( struct x11drv_win_data *data )
|
|||
{
|
||||
/* the window cannot be mapped before being embedded */
|
||||
window_set_wm_state( data, WithdrawnState );
|
||||
data->net_wm_state = 0;
|
||||
data->embedded = TRUE;
|
||||
data->managed = TRUE;
|
||||
sync_window_style( data );
|
||||
|
@ -1951,6 +2067,7 @@ static void create_whole_window( struct x11drv_win_data *data )
|
|||
if (!data->whole_window) goto done;
|
||||
SetRect( &data->current_state.rect, pos.x, pos.y, pos.x + cx, pos.y + cy );
|
||||
data->pending_state.rect = data->current_state.rect;
|
||||
data->desired_state.rect = data->current_state.rect;
|
||||
|
||||
x11drv_xinput2_enable( data->display, data->whole_window );
|
||||
set_initial_wm_hints( data->display, data->whole_window );
|
||||
|
@ -2005,10 +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 );
|
||||
data->whole_window = data->client_window = 0;
|
||||
data->whole_colormap = 0;
|
||||
data->wm_state = WithdrawnState;
|
||||
data->net_wm_state = 0;
|
||||
data->mapped = FALSE;
|
||||
|
||||
memset( &data->desired_state, 0, sizeof(data->desired_state) );
|
||||
memset( &data->pending_state, 0, sizeof(data->pending_state) );
|
||||
memset( &data->current_state, 0, sizeof(data->current_state) );
|
||||
data->wm_state_serial = 0;
|
||||
|
@ -2314,7 +2430,12 @@ void set_window_parent( struct x11drv_win_data *data, Window parent )
|
|||
if (!data->whole_window) return; /* only keep track of parent if we have a toplevel */
|
||||
TRACE( "window %p/%lx, parent %lx\n", data->hwnd, data->whole_window, parent );
|
||||
host_window_reparent( &data->parent, parent, data->whole_window );
|
||||
if (data->parent) host_window_configure_child( data->parent, data->whole_window, data->rects.visible, TRUE );
|
||||
if (data->parent)
|
||||
{
|
||||
RECT rect = data->rects.visible;
|
||||
OffsetRect( &rect, -rect.left, -rect.top );
|
||||
host_window_configure_child( data->parent, data->whole_window, rect, TRUE );
|
||||
}
|
||||
data->parent_invalid = 0;
|
||||
}
|
||||
|
||||
|
@ -2468,6 +2589,7 @@ BOOL X11DRV_SystrayDockInsert( HWND hwnd, UINT cx, UINT cy, void *icon )
|
|||
window = data->whole_window;
|
||||
release_win_data( data );
|
||||
|
||||
NtUserSetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOZORDER );
|
||||
NtUserShowWindow( hwnd, SW_SHOWNA );
|
||||
|
||||
TRACE_(systray)( "icon window %p/%lx\n", hwnd, window );
|
||||
|
|
|
@ -236,7 +236,7 @@ typedef struct tagWTI_DEVICES_INFO
|
|||
#define CSR_TYPE_OTHER 0x000
|
||||
|
||||
typedef struct tagWTPACKET {
|
||||
HCTX pkContext;
|
||||
UINT pkContext;
|
||||
UINT pkStatus;
|
||||
LONG pkTime;
|
||||
WTPKT pkChanged;
|
||||
|
|
|
@ -633,14 +633,13 @@ struct x11drv_win_data
|
|||
UINT net_wm_fullscreen_monitors_set : 1; /* is _NET_WM_FULLSCREEN_MONITORS set */
|
||||
UINT is_fullscreen : 1; /* is the window visible rect fullscreen */
|
||||
UINT parent_invalid : 1; /* is the parent host window possibly invalid */
|
||||
int wm_state; /* current value of the WM_STATE property */
|
||||
DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */
|
||||
Window embedder; /* window id of embedder */
|
||||
Pixmap icon_pixmap;
|
||||
Pixmap icon_mask;
|
||||
unsigned long *icon_bits;
|
||||
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 current_state; /* window state tracking the current X11 state */
|
||||
unsigned long wm_state_serial; /* serial of last pending WM_STATE request */
|
||||
|
@ -659,10 +658,13 @@ extern void set_gl_drawable_parent( HWND hwnd, HWND parent );
|
|||
extern void destroy_gl_drawable( HWND hwnd );
|
||||
extern void destroy_vk_surface( HWND hwnd );
|
||||
|
||||
extern BOOL window_has_pending_wm_state( HWND hwnd, UINT state );
|
||||
extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
|
||||
extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
|
||||
extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect );
|
||||
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set );
|
||||
extern UINT window_update_client_state( struct x11drv_win_data *data );
|
||||
extern UINT window_update_client_config( struct x11drv_win_data *data );
|
||||
|
||||
extern Window init_clip_window(void);
|
||||
extern void update_user_time( Time time );
|
||||
extern UINT get_window_net_wm_state( Display *display, Window window );
|
||||
|
|
|
@ -811,12 +811,6 @@ C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
|
|||
|
||||
#ifdef _WIN64
|
||||
|
||||
static NTSTATUS x11drv_wow64_tablet_get_packet( void *arg )
|
||||
{
|
||||
FIXME( "%p\n", arg );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS x11drv_wow64_tablet_info( void *arg )
|
||||
{
|
||||
struct
|
||||
|
@ -837,7 +831,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
|
|||
{
|
||||
x11drv_init,
|
||||
x11drv_tablet_attach_queue,
|
||||
x11drv_wow64_tablet_get_packet,
|
||||
x11drv_tablet_get_packet,
|
||||
x11drv_wow64_tablet_info,
|
||||
x11drv_tablet_load_info,
|
||||
};
|
||||
|
|
|
@ -3886,26 +3886,23 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
|
|||
}
|
||||
else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME && lpBuffer)
|
||||
{
|
||||
time_t tmpTime;
|
||||
struct tm tmpTM;
|
||||
SYSTEMTIME *STHook;
|
||||
SYSTEMTIME st;
|
||||
|
||||
tmpTime = ConvertTimeString(lphttpHdr->lpszValue);
|
||||
|
||||
tmpTM = *gmtime(&tmpTime);
|
||||
STHook = (SYSTEMTIME *)lpBuffer;
|
||||
STHook->wDay = tmpTM.tm_mday;
|
||||
STHook->wHour = tmpTM.tm_hour;
|
||||
STHook->wMilliseconds = 0;
|
||||
STHook->wMinute = tmpTM.tm_min;
|
||||
STHook->wDayOfWeek = tmpTM.tm_wday;
|
||||
STHook->wMonth = tmpTM.tm_mon + 1;
|
||||
STHook->wSecond = tmpTM.tm_sec;
|
||||
STHook->wYear = 1900+tmpTM.tm_year;
|
||||
|
||||
TRACE(" returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n",
|
||||
STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek,
|
||||
STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds);
|
||||
if (!InternetTimeToSystemTimeW(lphttpHdr->lpszValue, &st, 0))
|
||||
{
|
||||
LeaveCriticalSection( &request->headers_section );
|
||||
return ERROR_HTTP_INVALID_HEADER;
|
||||
}
|
||||
if (*lpdwBufferLength < sizeof(st))
|
||||
{
|
||||
*lpdwBufferLength = sizeof(st);
|
||||
LeaveCriticalSection( &request->headers_section );
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
TRACE(" returning time: %04u/%02u/%02u - %u - %02u:%02u:%02u.%02u\n",
|
||||
st.wYear, st.wMonth, st.wDay, st.wDayOfWeek, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
memcpy(lpBuffer, &st, sizeof(st));
|
||||
*lpdwBufferLength = sizeof(st);
|
||||
}
|
||||
else if (lphttpHdr->lpszValue)
|
||||
{
|
||||
|
@ -4521,7 +4518,7 @@ static BOOL HTTP_ParseDateAsAsctime(LPCWSTR value, FILETIME *ft)
|
|||
/* asctime() doesn't report a timezone, but some web servers do, so accept
|
||||
* with or without GMT.
|
||||
*/
|
||||
if (*ptr && wcscmp(ptr, L"GMT"))
|
||||
if (*ptr && (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC")))
|
||||
{
|
||||
ERR("unexpected timezone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
@ -4598,7 +4595,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
|
|||
while (iswspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
if (wcscmp(ptr, L"GMT"))
|
||||
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
|
||||
{
|
||||
ERR("unexpected time zone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
@ -4715,7 +4712,7 @@ static BOOL HTTP_ParseRfc850Date(LPCWSTR value, FILETIME *ft)
|
|||
while (iswspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
if (wcscmp(ptr, L"GMT"))
|
||||
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
|
||||
{
|
||||
ERR("unexpected time zone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
|
|
@ -2412,6 +2412,7 @@ static const char okmsg2[] =
|
|||
"Content-Length: 0\r\n"
|
||||
"Set-Cookie: one\r\n"
|
||||
"Set-Cookie: two\r\n"
|
||||
"Last-Modified: Mon, 01 Dec 2008 13:44:34 UTC\r\n"
|
||||
"\r\n";
|
||||
|
||||
static DWORD64 content_length;
|
||||
|
@ -4566,9 +4567,11 @@ static void test_head_request(int port)
|
|||
|
||||
static void test_HttpQueryInfo(int port)
|
||||
{
|
||||
static const SYSTEMTIME expect = {2008, 12, 1, 1, 13, 44, 34};
|
||||
test_request_t req;
|
||||
DWORD size, index, error;
|
||||
char buffer[1024];
|
||||
SYSTEMTIME st;
|
||||
BOOL ret;
|
||||
|
||||
open_simple_request(&req, "localhost", port, NULL, "/testD");
|
||||
|
@ -4589,9 +4592,27 @@ static void test_HttpQueryInfo(int port)
|
|||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(buffer);
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index);
|
||||
size = 0;
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(st) + 1;
|
||||
memset(&st, 0, sizeof(st));
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
|
||||
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(st);
|
||||
memset(&st, 0, sizeof(st));
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
|
||||
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
|
|
|
@ -1116,9 +1116,11 @@ static void test_InternetTimeToSystemTime(void)
|
|||
test_data[] =
|
||||
{
|
||||
{ "Fri, 07 Jan 2005 12:06:35 GMT", &expect1, TRUE },
|
||||
{ "Fri, 07 Jan 2005 12:06:35 UTC", &expect1, TRUE },
|
||||
{ " fri, 7 jan 2005 12 06 35", &expect1, TRUE },
|
||||
{ "Fri, 07-01-2005 12:06:35", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 UTC", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT;", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT123", &expect1, TRUE },
|
||||
{ "2, 11 01 2022 11 13 05", &expect2, TRUE },
|
||||
|
@ -1126,6 +1128,9 @@ static void test_InternetTimeToSystemTime(void)
|
|||
{ "2, 11*01/2022 11+13=05", &expect2, TRUE },
|
||||
{ "2, 11-Jan-2022 11:13:05", &expect2, TRUE },
|
||||
{ "Fr", NULL, FALSE },
|
||||
{ "Fri Jan 7 12:06:35 2005", &expect1, TRUE, TRUE },
|
||||
{ "Fri Jan 7 12:06:35 2005 GMT", &expect1, TRUE, TRUE },
|
||||
{ "Fri Jan 7 12:06:35 2005 UTC", &expect1, TRUE, TRUE },
|
||||
};
|
||||
|
||||
ret = pInternetTimeToSystemTimeA(NULL, NULL, 0);
|
||||
|
|
|
@ -39,92 +39,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
||||
|
||||
#define TIME_STRING_LEN 30
|
||||
|
||||
time_t ConvertTimeString(LPCWSTR asctime)
|
||||
{
|
||||
WCHAR tmpChar[TIME_STRING_LEN];
|
||||
WCHAR *tmpChar2;
|
||||
struct tm t;
|
||||
int timelen = lstrlenW(asctime);
|
||||
|
||||
if(!timelen)
|
||||
return 0;
|
||||
|
||||
/* FIXME: the atoiWs below rely on that tmpChar is \0 padded */
|
||||
memset( tmpChar, 0, sizeof(tmpChar) );
|
||||
lstrcpynW(tmpChar, asctime, TIME_STRING_LEN);
|
||||
|
||||
/* Assert that the string is the expected length */
|
||||
if (lstrlenW(asctime) >= TIME_STRING_LEN) FIXME("\n");
|
||||
|
||||
/* Convert a time such as 'Mon, 15 Nov 1999 16:09:35 GMT' into a SYSTEMTIME structure
|
||||
* We assume the time is in this format
|
||||
* and divide it into easy to swallow chunks
|
||||
*/
|
||||
tmpChar[3]='\0';
|
||||
tmpChar[7]='\0';
|
||||
tmpChar[11]='\0';
|
||||
tmpChar[16]='\0';
|
||||
tmpChar[19]='\0';
|
||||
tmpChar[22]='\0';
|
||||
tmpChar[25]='\0';
|
||||
|
||||
memset( &t, 0, sizeof(t) );
|
||||
t.tm_year = wcstol(tmpChar+12, NULL, 10) - 1900;
|
||||
t.tm_mday = wcstol(tmpChar+5, NULL, 10);
|
||||
t.tm_hour = wcstol(tmpChar+17, NULL, 10);
|
||||
t.tm_min = wcstol(tmpChar+20, NULL, 10);
|
||||
t.tm_sec = wcstol(tmpChar+23, NULL, 10);
|
||||
|
||||
/* and month */
|
||||
tmpChar2 = tmpChar + 8;
|
||||
switch(tmpChar2[2])
|
||||
{
|
||||
case 'n':
|
||||
if(tmpChar2[1]=='a')
|
||||
t.tm_mon = 0;
|
||||
else
|
||||
t.tm_mon = 5;
|
||||
break;
|
||||
case 'b':
|
||||
t.tm_mon = 1;
|
||||
break;
|
||||
case 'r':
|
||||
if(tmpChar2[1]=='a')
|
||||
t.tm_mon = 2;
|
||||
else
|
||||
t.tm_mon = 3;
|
||||
break;
|
||||
case 'y':
|
||||
t.tm_mon = 4;
|
||||
break;
|
||||
case 'l':
|
||||
t.tm_mon = 6;
|
||||
break;
|
||||
case 'g':
|
||||
t.tm_mon = 7;
|
||||
break;
|
||||
case 'p':
|
||||
t.tm_mon = 8;
|
||||
break;
|
||||
case 't':
|
||||
t.tm_mon = 9;
|
||||
break;
|
||||
case 'v':
|
||||
t.tm_mon = 10;
|
||||
break;
|
||||
case 'c':
|
||||
t.tm_mon = 11;
|
||||
break;
|
||||
default:
|
||||
FIXME("\n");
|
||||
}
|
||||
|
||||
return mktime(&t);
|
||||
}
|
||||
|
||||
|
||||
BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str)
|
||||
{
|
||||
ADDRINFOW *res, hints;
|
||||
|
|
|
@ -102,7 +102,7 @@ static const char* DUMPBITS(int x)
|
|||
|
||||
static inline void DUMPPACKET(WTPACKET packet)
|
||||
{
|
||||
TRACE("pkContext: %p pkStatus: 0x%x pkTime : 0x%lx pkChanged: 0x%lx pkSerialNumber: 0x%x pkCursor : %i pkButtons: %lx pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
|
||||
TRACE("pkContext: 0x%x pkStatus: 0x%x pkTime : 0x%lx pkChanged: 0x%lx pkSerialNumber: 0x%x pkCursor : %i pkButtons: %lx pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
|
||||
packet.pkContext, packet.pkStatus, packet.pkTime, packet.pkChanged, packet.pkSerialNumber,
|
||||
packet.pkCursor, packet.pkButtons, packet.pkX, packet.pkY, packet.pkZ,
|
||||
packet.pkNormalPressure, packet.pkTangentPressure,
|
||||
|
@ -205,7 +205,7 @@ LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
|
|||
|
||||
tgt = ptr->PacketsQueued;
|
||||
|
||||
packet->pkContext = ptr->handle;
|
||||
packet->pkContext = HandleToULong(ptr->handle);
|
||||
|
||||
/* translate packet data to the context */
|
||||
packet->pkChanged = packet->pkChanged & ptr->context.lcPktData;
|
||||
|
@ -296,12 +296,15 @@ static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
|
|||
LPWTPACKET wtp)
|
||||
{
|
||||
LPBYTE ptr;
|
||||
HCTX ctx;
|
||||
|
||||
ptr = lpPkt;
|
||||
TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData));
|
||||
|
||||
ctx = ULongToHandle(wtp->pkContext);
|
||||
|
||||
if (context->context.lcPktData & PK_CONTEXT)
|
||||
ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
|
||||
ptr+=CopyTabletData(ptr,&ctx,sizeof(HCTX));
|
||||
if (context->context.lcPktData & PK_STATUS)
|
||||
ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
|
||||
if (context->context.lcPktData & PK_TIME)
|
||||
|
|
|
@ -117,7 +117,7 @@ typedef struct tagWTI_EXTENSIONS_INFO
|
|||
} WTI_EXTENSIONS_INFO, *LPWTI_EXTENSIONS_INFO;
|
||||
|
||||
typedef struct tagWTPACKET {
|
||||
HCTX pkContext;
|
||||
UINT pkContext;
|
||||
UINT pkStatus;
|
||||
LONG pkTime;
|
||||
WTPKT pkChanged;
|
||||
|
|
|
@ -1240,3 +1240,211 @@ HRESULT WINAPI RoResolveNamespace(HSTRING name, HSTRING windowsMetaDataDir,
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow64);
|
||||
|
||||
test_IApiInformationStatics();
|
||||
test_IPropertyValueStatics();
|
||||
test_RoParseTypeName();
|
||||
test_RoResolveNamespace();
|
||||
}
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
@ stub RoGetMetaDataFile
|
||||
@ stdcall RoIsApiContractMajorVersionPresent(wstr long ptr)
|
||||
@ stub RoIsApiContractPresent
|
||||
@ stub RoParseTypeName
|
||||
@ stdcall RoParseTypeName(ptr ptr ptr)
|
||||
@ stdcall RoResolveNamespace(ptr ptr long ptr ptr ptr ptr ptr)
|
||||
|
|
|
@ -1449,6 +1449,22 @@ NTSTATUS WINAPI wow64_NtSetIoCompletion( UINT *args )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtSetIoCompletionEx
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtSetIoCompletionEx( UINT *args )
|
||||
{
|
||||
HANDLE completion_handle = get_handle( &args );
|
||||
HANDLE completion_reserve_handle = get_handle( &args );
|
||||
ULONG_PTR key = get_ulong( &args );
|
||||
ULONG_PTR value = get_ulong( &args );
|
||||
NTSTATUS status = get_ulong( &args );
|
||||
SIZE_T count = get_ulong( &args );
|
||||
|
||||
return NtSetIoCompletionEx( completion_handle, completion_reserve_handle, key, value, status, count );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtSetTimer
|
||||
*/
|
||||
|
|
|
@ -343,4 +343,19 @@ typedef struct tagKbdLayer
|
|||
#error "Unsupported KBD_TYPE"
|
||||
#endif
|
||||
|
||||
#define VK_DBE_ALPHANUMERIC 0x0f0
|
||||
#define VK_DBE_KATAKANA 0x0f1
|
||||
#define VK_DBE_HIRAGANA 0x0f2
|
||||
#define VK_DBE_SBCSCHAR 0x0f3
|
||||
#define VK_DBE_DBCSCHAR 0x0f4
|
||||
#define VK_DBE_ROMAN 0x0f5
|
||||
#define VK_DBE_NOROMAN 0x0f6
|
||||
#define VK_DBE_ENTERWORDREGISTERMODE 0x0f7
|
||||
#define VK_DBE_ENTERIMECONFIGMODE 0x0f8
|
||||
#define VK_DBE_FLUSHSTRING 0x0f9
|
||||
#define VK_DBE_CODEINPUT 0x0fa
|
||||
#define VK_DBE_NOCODEINPUT 0x0fb
|
||||
#define VK_DBE_DETERMINESTRING 0x0fc
|
||||
#define VK_DBE_ENTERDLGCONVERSIONMODE 0x0fd
|
||||
|
||||
#endif /* __WINE_KBD_H */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <hstring.h>
|
||||
|
||||
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 **);
|
||||
|
||||
#endif /* _ROMETADATARESOLUTION_H */
|
||||
|
|
|
@ -430,6 +430,36 @@ library UIAutomationClient {
|
|||
const long UIA_AppBarControlTypeId = 50040;
|
||||
}
|
||||
|
||||
[dllname("<no entry points>")]
|
||||
module UIA_AnnotationTypes
|
||||
{
|
||||
const long AnnotationType_Unknown = 60000;
|
||||
const long AnnotationType_SpellingError = 60001;
|
||||
const long AnnotationType_GrammarError = 60002;
|
||||
const long AnnotationType_Comment = 60003;
|
||||
const long AnnotationType_FormulaError = 60004;
|
||||
const long AnnotationType_TrackChanges = 60005;
|
||||
const long AnnotationType_Header = 60006;
|
||||
const long AnnotationType_Footer = 60007;
|
||||
const long AnnotationType_Highlighted = 60008;
|
||||
const long AnnotationType_Endnote = 60009;
|
||||
const long AnnotationType_Footnote = 60010;
|
||||
const long AnnotationType_InsertionChange = 60011;
|
||||
const long AnnotationType_DeletionChange = 60012;
|
||||
const long AnnotationType_MoveChange = 60013;
|
||||
const long AnnotationType_FormatChange = 60014;
|
||||
const long AnnotationType_UnsyncedChange = 60015;
|
||||
const long AnnotationType_EditingLockedChange = 60016;
|
||||
const long AnnotationType_ExternalChange = 60017;
|
||||
const long AnnotationType_ConflictingChange = 60018;
|
||||
const long AnnotationType_Author = 60019;
|
||||
const long AnnotationType_AdvancedProofingIssue = 60020;
|
||||
const long AnnotationType_DataValidationError = 60021;
|
||||
const long AnnotationType_CircularReferenceError = 60022;
|
||||
const long AnnotationType_Mathematics = 60023;
|
||||
const long AnnotationType_Sensitive = 60024;
|
||||
}
|
||||
|
||||
[dllname("<no entry points>")]
|
||||
module UIA_LandmarkTypeIds
|
||||
{
|
||||
|
|
80
include/wine/server_protocol.h
generated
80
include/wine/server_protocol.h
generated
|
@ -57,7 +57,7 @@ struct request_max_size
|
|||
|
||||
|
||||
|
||||
typedef union
|
||||
union debug_event_data
|
||||
{
|
||||
int code;
|
||||
struct
|
||||
|
@ -109,7 +109,7 @@ typedef union
|
|||
int __pad;
|
||||
mod_handle_t base;
|
||||
} unload_dll;
|
||||
} debug_event_t;
|
||||
};
|
||||
|
||||
|
||||
enum context_exec_space
|
||||
|
@ -260,7 +260,7 @@ typedef struct
|
|||
} rectangle_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
struct async_data
|
||||
{
|
||||
obj_handle_t handle;
|
||||
obj_handle_t event;
|
||||
|
@ -268,7 +268,7 @@ typedef struct
|
|||
client_ptr_t user;
|
||||
client_ptr_t apc;
|
||||
apc_param_t apc_context;
|
||||
} async_data_t;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -312,7 +312,7 @@ struct winevent_msg_data
|
|||
|
||||
};
|
||||
|
||||
typedef union
|
||||
union hw_input
|
||||
{
|
||||
int type;
|
||||
struct
|
||||
|
@ -342,15 +342,15 @@ typedef union
|
|||
lparam_t lparam;
|
||||
struct hid_input hid;
|
||||
} hw;
|
||||
} hw_input_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union message_data
|
||||
{
|
||||
unsigned char bytes[1];
|
||||
struct hardware_msg_data hardware;
|
||||
struct callback_msg_data callback;
|
||||
struct winevent_msg_data winevent;
|
||||
} message_data_t;
|
||||
};
|
||||
|
||||
|
||||
struct filesystem_event
|
||||
|
@ -435,7 +435,7 @@ struct object_type_info
|
|||
|
||||
};
|
||||
|
||||
enum select_op
|
||||
enum select_opcode
|
||||
{
|
||||
SELECT_NONE,
|
||||
SELECT_WAIT,
|
||||
|
@ -445,28 +445,28 @@ enum select_op
|
|||
SELECT_KEYED_EVENT_RELEASE
|
||||
};
|
||||
|
||||
typedef union
|
||||
union select_op
|
||||
{
|
||||
enum select_op op;
|
||||
enum select_opcode op;
|
||||
struct
|
||||
{
|
||||
enum select_op op;
|
||||
enum select_opcode op;
|
||||
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
||||
int __pad;
|
||||
} wait;
|
||||
struct
|
||||
{
|
||||
enum select_op op;
|
||||
enum select_opcode op;
|
||||
obj_handle_t wait;
|
||||
obj_handle_t signal;
|
||||
} signal_and_wait;
|
||||
struct
|
||||
{
|
||||
enum select_op op;
|
||||
enum select_opcode op;
|
||||
obj_handle_t handle;
|
||||
client_ptr_t key;
|
||||
} keyed_event;
|
||||
} select_op_t;
|
||||
};
|
||||
|
||||
enum apc_type
|
||||
{
|
||||
|
@ -488,18 +488,18 @@ enum apc_type
|
|||
APC_DUP_HANDLE
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct user_apc
|
||||
{
|
||||
enum apc_type type;
|
||||
int __pad;
|
||||
client_ptr_t func;
|
||||
apc_param_t args[3];
|
||||
} user_apc_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_call
|
||||
{
|
||||
enum apc_type type;
|
||||
user_apc_t user;
|
||||
struct user_apc user;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
|
@ -620,9 +620,9 @@ typedef union
|
|||
unsigned int attributes;
|
||||
unsigned int options;
|
||||
} dup_handle;
|
||||
} apc_call_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_result
|
||||
{
|
||||
enum apc_type type;
|
||||
struct
|
||||
|
@ -732,7 +732,7 @@ typedef union
|
|||
enum apc_type type;
|
||||
unsigned int status;
|
||||
} break_process;
|
||||
} apc_result_t;
|
||||
};
|
||||
|
||||
enum irp_type
|
||||
{
|
||||
|
@ -748,7 +748,7 @@ enum irp_type
|
|||
IRP_CALL_CANCEL
|
||||
};
|
||||
|
||||
typedef union
|
||||
union irp_params
|
||||
{
|
||||
enum irp_type type;
|
||||
struct
|
||||
|
@ -816,7 +816,7 @@ typedef union
|
|||
int __pad;
|
||||
client_ptr_t irp;
|
||||
} cancel;
|
||||
} irp_params_t;
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
|
@ -1343,7 +1343,7 @@ struct get_apc_result_request
|
|||
struct get_apc_result_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
apc_result_t result;
|
||||
union apc_result result;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1829,7 +1829,7 @@ struct flush_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct flush_reply
|
||||
{
|
||||
|
@ -1857,7 +1857,7 @@ struct get_volume_info_request
|
|||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
unsigned int info_class;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -1906,7 +1906,7 @@ struct recv_socket_request
|
|||
{
|
||||
struct request_header __header;
|
||||
int oob;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
int force_async;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -1925,7 +1925,7 @@ struct send_socket_request
|
|||
{
|
||||
struct request_header __header;
|
||||
unsigned int flags;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct send_socket_reply
|
||||
{
|
||||
|
@ -2016,7 +2016,7 @@ struct read_directory_changes_request
|
|||
unsigned int filter;
|
||||
int subtree;
|
||||
int want_data;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct read_directory_changes_reply
|
||||
{
|
||||
|
@ -2970,7 +2970,7 @@ struct send_hardware_message_request
|
|||
{
|
||||
struct request_header __header;
|
||||
user_handle_t win;
|
||||
hw_input_t input;
|
||||
union hw_input input;
|
||||
unsigned int flags;
|
||||
/* VARARG(report,bytes); */
|
||||
char __pad_60[4];
|
||||
|
@ -3152,7 +3152,7 @@ struct register_async_request
|
|||
{
|
||||
struct request_header __header;
|
||||
int type;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
int count;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -3216,7 +3216,7 @@ struct read_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
file_pos_t pos;
|
||||
};
|
||||
struct read_reply
|
||||
|
@ -3233,7 +3233,7 @@ struct write_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
file_pos_t pos;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
|
@ -3252,7 +3252,7 @@ struct ioctl_request
|
|||
{
|
||||
struct request_header __header;
|
||||
ioctl_code_t code;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
/* VARARG(in_data,bytes); */
|
||||
};
|
||||
struct ioctl_reply
|
||||
|
@ -5239,7 +5239,7 @@ struct get_next_device_request_request
|
|||
struct get_next_device_request_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
irp_params_t params;
|
||||
union irp_params params;
|
||||
obj_handle_t next;
|
||||
thread_id_t client_tid;
|
||||
client_ptr_t client_thread;
|
||||
|
@ -5412,8 +5412,8 @@ struct add_completion_request
|
|||
apc_param_t ckey;
|
||||
apc_param_t cvalue;
|
||||
apc_param_t information;
|
||||
obj_handle_t reserve_handle;
|
||||
unsigned int status;
|
||||
char __pad_44[4];
|
||||
};
|
||||
struct add_completion_reply
|
||||
{
|
||||
|
@ -6758,10 +6758,6 @@ union generic_reply
|
|||
struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
|
||||
};
|
||||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 847
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
#define SERVER_PROTOCOL_VERSION 848
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -4675,6 +4675,7 @@ NTSYSAPI NTSTATUS WINAPI NtSetInformationToken(HANDLE,TOKEN_INFORMATION_CLASS,P
|
|||
NTSYSAPI NTSTATUS WINAPI NtSetInformationVirtualMemory(HANDLE,VIRTUAL_MEMORY_INFORMATION_CLASS,ULONG_PTR,PMEMORY_RANGE_ENTRY,PVOID,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetIntervalProfile(ULONG,KPROFILE_SOURCE);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetIoCompletion(HANDLE,ULONG_PTR,ULONG_PTR,NTSTATUS,SIZE_T);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetIoCompletionEx(HANDLE,HANDLE,ULONG_PTR,ULONG_PTR,NTSTATUS,SIZE_T);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetLdtEntries(ULONG,LDT_ENTRY,ULONG,LDT_ENTRY);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetLowEventPair(HANDLE);
|
||||
NTSYSAPI NTSTATUS WINAPI NtSetLowWaitHighEventPair(HANDLE);
|
||||
|
|
|
@ -40,8 +40,11 @@ summary of contributions.
|
|||
changes and bug fixes and got the synthesizer to actually work. Most
|
||||
importantly, he used it on stage to make music.
|
||||
|
||||
* S. Christian Collins did much testing of FluidSynth in regards to
|
||||
EMU10K1 compatibility and provided many synthesis fixes in that regard.
|
||||
* S. Christian Collins provided many tests and fixes on EMU10K1
|
||||
compatibility. He also supplied reference chorus and reverb settings for
|
||||
developing the default ones.
|
||||
|
||||
* Alberto Salvia Novella developed the default chorus and reverb settings.
|
||||
|
||||
* Stephane Letz from Grame wrote most of the MidiShare driver, all of
|
||||
the PortAudio driver, ported iiwusynth to MacOS X, and sent in many
|
||||
|
|
|
@ -57,6 +57,15 @@ enum fluid_mod_flags
|
|||
FLUID_MOD_SIN = 0x80, /**< Custom non-standard sinus mapping function */
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform types for the SoundFont2 modulators as defined by SoundFont 2.04 section 8.3.
|
||||
*/
|
||||
enum fluid_mod_transforms
|
||||
{
|
||||
FLUID_MOD_TRANSFORM_LINEAR = 0, /**< Linear: directly add the computed value to summing node */
|
||||
FLUID_MOD_TRANSFORM_ABS = 2 /**< Abs: add the absolute value of the computed to summing node */
|
||||
};
|
||||
|
||||
/**
|
||||
* General controller (if #FLUID_MOD_GC in flags). This
|
||||
* corresponds to SoundFont 2.04 PDF section 8.2.1
|
||||
|
@ -83,6 +92,7 @@ FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t *mod, int src, int flags);
|
|||
FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t *mod, int src, int flags);
|
||||
FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t *mod, int dst);
|
||||
FLUIDSYNTH_API void fluid_mod_set_amount(fluid_mod_t *mod, double amount);
|
||||
FLUIDSYNTH_API void fluid_mod_set_transform(fluid_mod_t *mod, int type);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_get_source1(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_flags1(const fluid_mod_t *mod);
|
||||
|
@ -90,6 +100,7 @@ FLUIDSYNTH_API int fluid_mod_get_source2(const fluid_mod_t *mod);
|
|||
FLUIDSYNTH_API int fluid_mod_get_flags2(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_dest(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API double fluid_mod_get_amount(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_transform(fluid_mod_t *mod);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_test_identity(const fluid_mod_t *mod1, const fluid_mod_t *mod2);
|
||||
FLUIDSYNTH_API int fluid_mod_has_source(const fluid_mod_t *mod, int cc, int ctrl);
|
||||
|
|
|
@ -357,8 +357,13 @@ fluid_midi_file_read_mthd(fluid_midi_file *mf)
|
|||
}
|
||||
|
||||
mf->type = mthd[9];
|
||||
mf->ntracks = (unsigned) mthd[11];
|
||||
mf->ntracks += (unsigned int)(mthd[10]) << 16;
|
||||
if(!(mf->type == 0 || mf->type == 1))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR,
|
||||
"Sorry, but MIDI Format %d is not supported by this player", mf->type);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
mf->ntracks = (signed)((unsigned)(mthd[10]) << 8 | (unsigned) mthd[11]);
|
||||
|
||||
if((signed char)mthd[12] < 0)
|
||||
{
|
||||
|
@ -1062,7 +1067,7 @@ fluid_midi_file_get_division(fluid_midi_file *midifile)
|
|||
* @return New MIDI event structure or NULL when out of memory.
|
||||
*/
|
||||
fluid_midi_event_t *
|
||||
new_fluid_midi_event()
|
||||
new_fluid_midi_event(void)
|
||||
{
|
||||
fluid_midi_event_t *evt;
|
||||
evt = FLUID_NEW(fluid_midi_event_t);
|
||||
|
@ -2696,7 +2701,7 @@ int fluid_player_get_midi_tempo(fluid_player_t *player)
|
|||
* new_fluid_midi_parser
|
||||
*/
|
||||
fluid_midi_parser_t *
|
||||
new_fluid_midi_parser()
|
||||
new_fluid_midi_parser(void)
|
||||
{
|
||||
fluid_midi_parser_t *parser;
|
||||
parser = FLUID_NEW(fluid_midi_parser_t);
|
||||
|
|
|
@ -65,7 +65,6 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
|
|||
fluid_real_t dsp_a2 = iir_filter->a2;
|
||||
fluid_real_t dsp_b02 = iir_filter->b02;
|
||||
fluid_real_t dsp_b1 = iir_filter->b1;
|
||||
int dsp_filter_coeff_incr_count = iir_filter->filter_coeff_incr_count;
|
||||
|
||||
fluid_real_t dsp_centernode;
|
||||
int dsp_i;
|
||||
|
@ -83,51 +82,18 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
|
|||
* doesn't change.
|
||||
*/
|
||||
|
||||
if(dsp_filter_coeff_incr_count > 0)
|
||||
for(dsp_i = 0; dsp_i < count; dsp_i++)
|
||||
{
|
||||
fluid_real_t dsp_a1_incr = iir_filter->a1_incr;
|
||||
fluid_real_t dsp_a2_incr = iir_filter->a2_incr;
|
||||
fluid_real_t dsp_b02_incr = iir_filter->b02_incr;
|
||||
fluid_real_t dsp_b1_incr = iir_filter->b1_incr;
|
||||
|
||||
|
||||
/* Increment is added to each filter coefficient filter_coeff_incr_count times. */
|
||||
for(dsp_i = 0; dsp_i < count; dsp_i++)
|
||||
{
|
||||
/* The filter is implemented in Direct-II form. */
|
||||
dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
|
||||
dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
|
||||
dsp_hist2 = dsp_hist1;
|
||||
dsp_hist1 = dsp_centernode;
|
||||
|
||||
if(dsp_filter_coeff_incr_count-- > 0)
|
||||
{
|
||||
fluid_real_t old_b02 = dsp_b02;
|
||||
dsp_a1 += dsp_a1_incr;
|
||||
dsp_a2 += dsp_a2_incr;
|
||||
dsp_b02 += dsp_b02_incr;
|
||||
dsp_b1 += dsp_b1_incr;
|
||||
|
||||
/* Compensate history to avoid the filter going havoc with large frequency changes */
|
||||
if(iir_filter->compensate_incr && FLUID_FABS(dsp_b02) > 0.001f)
|
||||
{
|
||||
fluid_real_t compensate = old_b02 / dsp_b02;
|
||||
dsp_hist1 *= compensate;
|
||||
dsp_hist2 *= compensate;
|
||||
}
|
||||
}
|
||||
} /* for dsp_i */
|
||||
}
|
||||
else /* The filter parameters are constant. This is duplicated to save time. */
|
||||
{
|
||||
for(dsp_i = 0; dsp_i < count; dsp_i++)
|
||||
{
|
||||
/* The filter is implemented in Direct-II form. */
|
||||
dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
|
||||
dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
|
||||
dsp_hist2 = dsp_hist1;
|
||||
dsp_hist1 = dsp_centernode;
|
||||
}
|
||||
/* The filter is implemented in Direct-II form. */
|
||||
dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
|
||||
dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
|
||||
dsp_hist2 = dsp_hist1;
|
||||
dsp_hist1 = dsp_centernode;
|
||||
/* Alternatively, it could be implemented in Transposed Direct Form II */
|
||||
// fluid_real_t dsp_input = dsp_buf[dsp_i];
|
||||
// dsp_buf[dsp_i] = dsp_b02 * dsp_input + dsp_hist1;
|
||||
// dsp_hist1 = dsp_b1 * dsp_input - dsp_a1 * dsp_buf[dsp_i] + dsp_hist2;
|
||||
// dsp_hist2 = dsp_b02 * dsp_input - dsp_a2 * dsp_buf[dsp_i];
|
||||
}
|
||||
|
||||
iir_filter->hist1 = dsp_hist1;
|
||||
|
@ -136,7 +102,6 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
|
|||
iir_filter->a2 = dsp_a2;
|
||||
iir_filter->b02 = dsp_b02;
|
||||
iir_filter->b1 = dsp_b1;
|
||||
iir_filter->filter_coeff_incr_count = dsp_filter_coeff_incr_count;
|
||||
|
||||
fluid_check_fpe("voice_filter");
|
||||
}
|
||||
|
@ -320,47 +285,11 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter,
|
|||
return;
|
||||
}
|
||||
|
||||
iir_filter->compensate_incr = 0;
|
||||
|
||||
if(iir_filter->filter_startup || (transition_samples == 0))
|
||||
{
|
||||
/* The filter is calculated, because the voice was started up.
|
||||
* In this case set the filter coefficients without delay.
|
||||
*/
|
||||
iir_filter->a1 = a1_temp;
|
||||
iir_filter->a2 = a2_temp;
|
||||
iir_filter->b02 = b02_temp;
|
||||
iir_filter->b1 = b1_temp;
|
||||
iir_filter->filter_coeff_incr_count = 0;
|
||||
iir_filter->filter_startup = 0;
|
||||
// printf("Setting initial filter coefficients.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* The filter frequency is changed. Calculate an increment
|
||||
* factor, so that the new setting is reached after one buffer
|
||||
* length. x_incr is added to the current value FLUID_BUFSIZE
|
||||
* times. The length is arbitrarily chosen. Longer than one
|
||||
* buffer will sacrifice some performance, though. Note: If
|
||||
* the filter is still too 'grainy', then increase this number
|
||||
* at will.
|
||||
*/
|
||||
|
||||
iir_filter->a1_incr = (a1_temp - iir_filter->a1) / transition_samples;
|
||||
iir_filter->a2_incr = (a2_temp - iir_filter->a2) / transition_samples;
|
||||
iir_filter->b02_incr = (b02_temp - iir_filter->b02) / transition_samples;
|
||||
iir_filter->b1_incr = (b1_temp - iir_filter->b1) / transition_samples;
|
||||
|
||||
if(FLUID_FABS(iir_filter->b02) > 0.0001f)
|
||||
{
|
||||
fluid_real_t quota = b02_temp / iir_filter->b02;
|
||||
iir_filter->compensate_incr = quota < 0.5f || quota > 2.f;
|
||||
}
|
||||
|
||||
/* Have to add the increments filter_coeff_incr_count times. */
|
||||
iir_filter->filter_coeff_incr_count = transition_samples;
|
||||
}
|
||||
iir_filter->a1 = a1_temp;
|
||||
iir_filter->a2 = a2_temp;
|
||||
iir_filter->b02 = b02_temp;
|
||||
iir_filter->b1 = b1_temp;
|
||||
iir_filter->filter_startup = 0;
|
||||
|
||||
fluid_check_fpe("voice_write filter calculation");
|
||||
}
|
||||
|
@ -376,9 +305,6 @@ void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
|
|||
/* calculate the frequency of the resonant filter in Hz */
|
||||
fres = fluid_ct2hz(iir_filter->fres + fres_mod);
|
||||
|
||||
/* FIXME - Still potential for a click during turn on, can we interpolate
|
||||
between 20khz cutoff and 0 Q? */
|
||||
|
||||
/* I removed the optimization of turning the filter off when the
|
||||
* resonance frequency is above the maximum frequency. Instead, the
|
||||
* filter frequency is set to a maximum of 0.45 times the sampling
|
||||
|
@ -398,6 +324,7 @@ void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
|
|||
fres = 5.f;
|
||||
}
|
||||
|
||||
// FLUID_LOG(FLUID_INFO, "%f + %f cents = %f cents = %f Hz | Q: %f", iir_filter->fres, fres_mod, iir_filter->fres + fres_mod, fres, iir_filter->q_lin);
|
||||
/* if filter enabled and there is a significant frequency change.. */
|
||||
if(iir_filter->type != FLUID_IIR_DISABLED && FLUID_FABS(fres - iir_filter->last_fres) > 0.01f)
|
||||
{
|
||||
|
|
|
@ -53,12 +53,6 @@ struct _fluid_iir_filter_t
|
|||
fluid_real_t a1; /* a0 / a0 */
|
||||
fluid_real_t a2; /* a1 / a0 */
|
||||
|
||||
fluid_real_t b02_incr;
|
||||
fluid_real_t b1_incr;
|
||||
fluid_real_t a1_incr;
|
||||
fluid_real_t a2_incr;
|
||||
int filter_coeff_incr_count;
|
||||
int compensate_incr; /* Flag: If set, must compensate history */
|
||||
fluid_real_t hist1, hist2; /* Sample history for the IIR filter */
|
||||
int filter_startup; /* Flag: If set, the filter will be set directly.
|
||||
Else it changes smoothly. */
|
||||
|
|
|
@ -354,11 +354,13 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
/******************* amplitude **********************/
|
||||
|
||||
count = fluid_rvoice_calc_amp(voice);
|
||||
|
||||
if(count <= 0)
|
||||
if(count == 0)
|
||||
{
|
||||
return count; /* return -1 if voice is quiet, 0 if voice has finished */
|
||||
// Voice has finished, remove from dsp loop
|
||||
return 0;
|
||||
}
|
||||
// else if count is negative, still process the voice
|
||||
|
||||
|
||||
/******************* phase **********************/
|
||||
|
||||
|
@ -420,6 +422,14 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
voice->dsp.phase_incr = 1;
|
||||
}
|
||||
|
||||
/* loop mode release? if not in release, the voice is silent
|
||||
* note: this intentionally processes the volenv before returning silence,
|
||||
* since that's what polyphone does (PR #1400) */
|
||||
if(voice->dsp.samplemode == FLUID_START_ON_RELEASE && fluid_adsr_env_get_section(&voice->envlfo.volenv) < FLUID_VOICE_ENVRELEASE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* voice is currently looping? */
|
||||
is_looping = voice->dsp.samplemode == FLUID_LOOP_DURING_RELEASE
|
||||
|| (voice->dsp.samplemode == FLUID_LOOP_UNTIL_RELEASE
|
||||
|
@ -431,6 +441,19 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
* Depending on the position in the loop and the loop size, this
|
||||
* may require several runs. */
|
||||
|
||||
if(count < 0)
|
||||
{
|
||||
// The voice is quite, i.e. either in delay phase or zero volume.
|
||||
// We need to update the rvoice's dsp phase, as the delay phase shall not "postpone" the sound, rather
|
||||
// it should be played silently, see https://github.com/FluidSynth/fluidsynth/issues/1312
|
||||
//
|
||||
// Currently, this does access the sample buffers, which is redundant and could be optimized away.
|
||||
// On the other hand, entering this if-clause is not supposed to happen often.
|
||||
//
|
||||
// Also note, that we're returning directly without running the IIR filter below.
|
||||
return fluid_rvoice_dsp_interpolate_none(&voice->dsp, dsp_buf, is_looping);
|
||||
}
|
||||
|
||||
switch(voice->dsp.interp_method)
|
||||
{
|
||||
case FLUID_INTERP_NONE:
|
||||
|
@ -455,6 +478,7 @@ fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf)
|
|||
|
||||
if(count == 0)
|
||||
{
|
||||
// voice has finished
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ enum fluid_loop
|
|||
{
|
||||
FLUID_UNLOOPED = 0,
|
||||
FLUID_LOOP_DURING_RELEASE = 1,
|
||||
FLUID_NOTUSED = 2,
|
||||
FLUID_START_ON_RELEASE = 2, /* this is a looping mode introduced by Polyphone, see #1398 for more info */
|
||||
FLUID_LOOP_UNTIL_RELEASE = 3
|
||||
};
|
||||
|
||||
|
|
|
@ -954,7 +954,6 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
|
||||
for(i = 0; i < GEN_LAST; i++)
|
||||
{
|
||||
|
||||
/* SF 2.01 section 9.4 'bullet' 4:
|
||||
*
|
||||
* A generator in a local instrument zone supersedes a
|
||||
|
@ -977,7 +976,6 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
* Do nothing, leave it at the default.
|
||||
*/
|
||||
}
|
||||
|
||||
} /* for all generators */
|
||||
|
||||
/* Adds instrument zone modulators (global and local) to the voice.*/
|
||||
|
@ -991,7 +989,7 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
|
||||
for(i = 0; i < GEN_LAST; i++)
|
||||
{
|
||||
|
||||
fluid_real_t awe_val;
|
||||
/* SF 2.01 section 8.5 page 58: If some generators are
|
||||
encountered at preset level, they should be ignored.
|
||||
However this check is not necessary when the soundfont
|
||||
|
@ -1026,6 +1024,12 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
|
|||
* Do nothing, leave it unchanged.
|
||||
*/
|
||||
}
|
||||
|
||||
/* ...unless the default value has been overridden by an AWE32 NRPN */
|
||||
if (fluid_channel_get_override_gen_default(synth->channel[chan], i, &awe_val))
|
||||
{
|
||||
fluid_voice_gen_set(voice, i, awe_val);
|
||||
}
|
||||
} /* for all generators */
|
||||
|
||||
/* Adds preset zone modulators (global and local) to the voice.*/
|
||||
|
@ -1614,18 +1618,6 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
|
|||
mod_dest->amount = 0;
|
||||
}
|
||||
|
||||
/* Note: When primary source input (src1) is set to General Controller 'No Controller',
|
||||
output will be forced to 0.0 at synthesis time (see fluid_mod_get_value()).
|
||||
That means that the minimum value of the modulator will be always 0.0.
|
||||
We need to force amount value to 0 to ensure a correct evaluation of the minimum
|
||||
value later (see fluid_voice_get_lower_boundary_for_attenuation()).
|
||||
*/
|
||||
if(((mod_dest->flags1 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
|
||||
(mod_dest->src1 == FLUID_MOD_NONE))
|
||||
{
|
||||
mod_dest->amount = 0;
|
||||
}
|
||||
|
||||
/* *** Dest *** */
|
||||
mod_dest->dest = mod_src->dest; /* index of controlled generator */
|
||||
|
||||
|
@ -1636,25 +1628,20 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
|
|||
* Deactivate the modulator by setting the amount to 0. */
|
||||
mod_dest->amount = 0;
|
||||
}
|
||||
/* Note: When secondary source input (src2) is set to General Controller 'No Controller',
|
||||
output will be forced to +1.0 at synthesis time (see fluid_mod_get_value()).
|
||||
That means that this source will behave unipolar only. We need to force the
|
||||
unipolar flag to ensure to ensure a correct evaluation of the minimum
|
||||
value later (see fluid_voice_get_lower_boundary_for_attenuation()).
|
||||
*/
|
||||
if(((mod_dest->flags2 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
|
||||
(mod_dest->src2 == FLUID_MOD_NONE))
|
||||
{
|
||||
mod_dest->flags2 &= ~FLUID_MOD_BIPOLAR;
|
||||
}
|
||||
|
||||
/* *** Transform *** */
|
||||
/* SF2.01 only uses the 'linear' transform (0).
|
||||
* Deactivate the modulator by setting the amount to 0 in any other case.
|
||||
/**
|
||||
* *** Transform Type ***
|
||||
* Only 2 types of transform are defined in the sf2 specification.
|
||||
*/
|
||||
if(mod_src->trans != 0)
|
||||
if(mod_src->trans != FLUID_MOD_TRANSFORM_LINEAR && mod_src->trans != FLUID_MOD_TRANSFORM_ABS)
|
||||
{
|
||||
/* disable the modulator as the transform is invalid */
|
||||
mod_dest->amount = 0;
|
||||
mod_dest->trans = FLUID_MOD_TRANSFORM_LINEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
mod_dest->trans = mod_src->trans;
|
||||
}
|
||||
|
||||
/* Store the new modulator in the zone The order of modulators
|
||||
|
|
|
@ -66,7 +66,7 @@ struct _fluid_zone_range_t
|
|||
};
|
||||
|
||||
/* Stored on a preset zone to keep track of the inst zones that could start a voice
|
||||
* and their combined preset zone/instument zone ranges */
|
||||
* and their combined preset zone/instrument zone ranges */
|
||||
struct _fluid_voice_zone_t
|
||||
{
|
||||
fluid_inst_zone_t *inst_zone;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue