mirror of
https://github.com/wine-mirror/wine
synced 2024-06-29 06:14:34 +00:00
Compare commits
124 Commits
bfb4a96210
...
e828bdc018
Author | SHA1 | Date | |
---|---|---|---|
|
e828bdc018 | ||
|
f9af971bd7 | ||
|
f9a8f2f1a3 | ||
|
e2100e3f1e | ||
|
ac4e478015 | ||
|
d1a62e862e | ||
|
c165459699 | ||
|
425ef9cb23 | ||
|
cd8306db83 | ||
|
d010f52241 | ||
|
b80657c0a5 | ||
|
cbf1310f87 | ||
|
c483e5d456 | ||
|
794e1f1884 | ||
|
9dd9c455d3 | ||
|
62d8d3415c | ||
|
215478fc46 | ||
|
490d8ed663 | ||
|
7c0aa6fd8c | ||
|
0fb9e616bc | ||
|
f0ee51026b | ||
|
13159b0767 | ||
|
58de2dec08 | ||
|
ef7f9fed60 | ||
|
834da273c1 | ||
|
e9ca13a6f7 | ||
|
2f5456316c | ||
|
fc4b9c645a | ||
|
3a8aad4834 | ||
|
f45588c57f | ||
|
8ad0923515 | ||
|
b34b5d84a6 | ||
|
235d527fa5 | ||
|
9d046996cb | ||
|
73a501ab46 | ||
|
5dcb879df1 | ||
|
7053e0f641 | ||
|
5eafe53e54 | ||
|
0db0f6180d | ||
|
0a42bd290d | ||
|
c133f14fe6 | ||
|
d140164d76 | ||
|
7e3293107f | ||
|
8fee7e8b7c | ||
|
2a6e7ab4ed | ||
|
1d58a4674c | ||
|
32e2ede0df | ||
|
6c5d17af07 | ||
|
08c0978f0b | ||
|
fe6af4fb9e | ||
|
f477eca789 | ||
|
4aab3e42c1 | ||
|
6dca99a713 | ||
|
bd36ac98c0 | ||
|
01d0027739 | ||
|
411cce36b1 | ||
|
844d6b553a | ||
|
2ec70835fc | ||
|
9a7408e771 | ||
|
2eeb4d5192 | ||
|
d5b4458c8d | ||
|
534aff4a63 | ||
|
5b013260d1 | ||
|
472ce7fd1d | ||
|
496f663157 | ||
|
33a9097bb4 | ||
|
c77a217d34 | ||
|
7dad7e87a9 | ||
|
1dee9881e2 | ||
|
86be09ac0b | ||
|
98b99b6569 | ||
|
5f76f07bff | ||
|
0e928ccaea | ||
|
b2017a48dc | ||
|
0051e102cc | ||
|
7f53949a49 | ||
|
7830153c38 | ||
|
7b82f507bd | ||
|
5da03c7a60 | ||
|
266e95a21b | ||
|
9669cd56f4 | ||
|
1f79e7697b | ||
|
f5a739ce62 | ||
|
dea96222b4 | ||
|
53d03fb0a5 | ||
|
5a903c0f1a | ||
|
2030973a3f | ||
|
2804012993 | ||
|
4792d3dd2d | ||
|
ffe88e3b0d | ||
|
68b62ecdc9 | ||
|
657cc2a9f6 | ||
|
0525a996a4 | ||
|
9954c6b7fb | ||
|
8c64979dcb | ||
|
6e526d19f7 | ||
|
ec17fc4ca3 | ||
|
7b95b93c42 | ||
|
005e164751 | ||
|
bea627b646 | ||
|
81eafa9b78 | ||
|
5488d99b3e | ||
|
728049d6fa | ||
|
eb63ac74dc | ||
|
20f4c9af0f | ||
|
1e10e3a1c0 | ||
|
f82b1c1fcf | ||
|
fac940dfac | ||
|
96d682e5f7 | ||
|
96762f12e7 | ||
|
f98077591f | ||
|
0ca28d3a70 | ||
|
6e82d33eb7 | ||
|
0d5936563d | ||
|
b7a3023ca1 | ||
|
9f8d4d0b0a | ||
|
417b4cb453 | ||
|
9dfc402cc3 | ||
|
85fd5e283a | ||
|
867af68b17 | ||
|
802a52cb1b | ||
|
51561300b2 | ||
|
bf9f100d62 | ||
|
a18d9f55c5 |
|
@ -158,7 +158,7 @@ M: Marcus Meissner <marcus@jet.franken.de>
|
|||
F: dlls/gphoto2.ds/
|
||||
|
||||
GStreamer multimedia backend
|
||||
M: Elizabeth Figura <zfigura@codeweavers.com>
|
||||
P: Elizabeth Figura <zfigura@codeweavers.com>
|
||||
P: Rémi Bernon <rbernon@codeweavers.com>
|
||||
F: dlls/winegstreamer/
|
||||
|
||||
|
|
99
configure
vendored
99
configure
vendored
|
@ -868,9 +868,6 @@ CFLAGS
|
|||
CC
|
||||
SET_MAKE
|
||||
srcdir
|
||||
nlsdir
|
||||
fontdir
|
||||
dlldir
|
||||
host_os
|
||||
host_vendor
|
||||
host_cpu
|
||||
|
@ -1006,6 +1003,7 @@ enable_authz
|
|||
enable_avicap32
|
||||
enable_avifil32
|
||||
enable_avrt
|
||||
enable_bcp47langs
|
||||
enable_bcrypt
|
||||
enable_bcryptprimitives
|
||||
enable_bluetoothapis
|
||||
|
@ -1369,6 +1367,7 @@ enable_pidgen
|
|||
enable_powrprof
|
||||
enable_printui
|
||||
enable_prntvpt
|
||||
enable_profapi
|
||||
enable_propsys
|
||||
enable_psapi
|
||||
enable_pstorec
|
||||
|
@ -1388,6 +1387,7 @@ enable_regapi
|
|||
enable_resutils
|
||||
enable_riched20
|
||||
enable_riched32
|
||||
enable_rometadata
|
||||
enable_rpcrt4
|
||||
enable_rsabase
|
||||
enable_rsaenh
|
||||
|
@ -4674,12 +4674,6 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
|
|||
|
||||
|
||||
|
||||
dlldir=\${libdir}/wine
|
||||
|
||||
fontdir=\${datadir}/wine/fonts
|
||||
|
||||
nlsdir=\${datadir}/wine/nls
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -6474,7 +6468,7 @@ MAKEDEP=$wine_makedep
|
|||
|
||||
RUNTESTFLAGS="-q -P wine"
|
||||
|
||||
SED_CMD="LC_ALL=C sed -e 's,@bindir@,\${bindir},g' -e 's,@dlldir@,\${dlldir},g' -e 's,@PACKAGE_STRING@,$PACKAGE_STRING,g' -e 's,@PACKAGE_VERSION@,$PACKAGE_VERSION,g'"
|
||||
SED_CMD="LC_ALL=C sed -e 's,@bindir@,\${bindir},g' -e 's,@PACKAGE_STRING@,$PACKAGE_STRING,g' -e 's,@PACKAGE_VERSION@,$PACKAGE_VERSION,g'"
|
||||
|
||||
|
||||
if test -n "$host_alias" -a "$host_alias" != "$build_alias"
|
||||
|
@ -9529,14 +9523,47 @@ fi
|
|||
SYSTEMCONFIGURATION_LIBS="-framework SystemConfiguration"
|
||||
|
||||
|
||||
WINELOADER_LDFLAGS="-Wl,-pie,-segalign,0x1000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist"
|
||||
WINELOADER_LDFLAGS="-Wl,-segalign,0x1000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist"
|
||||
|
||||
case $HOST_ARCH in
|
||||
i386|x86_64) wine_can_build_preloader=yes ;;
|
||||
*) wine_can_build_preloader=no ;;
|
||||
i386) wine_use_preloader=yes ;;
|
||||
x86_64)
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -Wl,-no_huge" >&5
|
||||
printf %s "checking whether the compiler supports -Wl,-no_huge... " >&6; }
|
||||
if test ${ac_cv_cflags__Wl__no_huge+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_wine_try_cflags_saved=$CFLAGS
|
||||
CFLAGS="$CFLAGS -Wl,-no_huge"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
int main(int argc, char **argv) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_cflags__Wl__no_huge=yes
|
||||
else $as_nop
|
||||
ac_cv_cflags__Wl__no_huge=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags__Wl__no_huge" >&5
|
||||
printf "%s\n" "$ac_cv_cflags__Wl__no_huge" >&6; }
|
||||
if test "x$ac_cv_cflags__Wl__no_huge" = xyes
|
||||
then :
|
||||
wine_use_preloader=no
|
||||
WINELOADER_LDFLAGS="$WINELOADER_LDFLAGS -Wl,-no_pie,-image_base,0x200000000,-no_huge,-no_fixup_chains,-segalign,0x1000,-segaddr,WINE_RESERVE,0x1000,-segaddr,WINE_TOP_DOWN,0x7ff000000000"
|
||||
else $as_nop
|
||||
wine_use_preloader=yes
|
||||
fi
|
||||
;;
|
||||
*) wine_use_preloader=no ;;
|
||||
esac
|
||||
|
||||
if test "$wine_can_build_preloader" = "yes"
|
||||
if test "$wine_use_preloader" = "yes"
|
||||
then
|
||||
WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs -e _start -ldylib1.o -mmacosx-version-min=10.7 -Wl,-no_new_main,-segalign,0x1000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -Wl,-no_pie" >&5
|
||||
|
@ -9576,8 +9603,6 @@ fi
|
|||
;;
|
||||
esac
|
||||
WINELOADER_LDFLAGS="$WINELOADER_LDFLAGS -mmacosx-version-min=10.7"
|
||||
else
|
||||
as_fn_append wine_warnings "|can't build Wine preloader; many programs won't work"
|
||||
fi
|
||||
|
||||
if test "x$with_coreaudio" != "xno";
|
||||
|
@ -20448,19 +20473,20 @@ case $host_os in
|
|||
linux*)
|
||||
if test $HOST_ARCH != unknown
|
||||
then
|
||||
test "$wine_binary" = wine || as_fn_append CONFIGURE_TARGETS " loader/wine-preloader"
|
||||
WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader"
|
||||
fi
|
||||
;;
|
||||
darwin*|macosx*)
|
||||
if test "$wine_can_build_preloader" = "yes"
|
||||
then
|
||||
test "$wine_binary" = wine || as_fn_append CONFIGURE_TARGETS " loader/wine-preloader"
|
||||
WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader"
|
||||
wine_use_preloader=yes
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$wine_use_preloader" = "yes"
|
||||
then
|
||||
test "$wine_binary" = wine || as_fn_append CONFIGURE_TARGETS " loader/wine-preloader"
|
||||
WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader"
|
||||
|
||||
printf "%s\n" "#define HAVE_WINE_PRELOADER 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
|
||||
printf %s "checking for library containing dlopen... " >&6; }
|
||||
|
@ -21951,6 +21977,7 @@ wine_fn_config_makefile dlls/avifil32 enable_avifil32
|
|||
wine_fn_config_makefile dlls/avifil32/tests enable_tests
|
||||
wine_fn_config_makefile dlls/avifile.dll16 enable_win16
|
||||
wine_fn_config_makefile dlls/avrt enable_avrt
|
||||
wine_fn_config_makefile dlls/bcp47langs enable_bcp47langs
|
||||
wine_fn_config_makefile dlls/bcrypt enable_bcrypt
|
||||
wine_fn_config_makefile dlls/bcrypt/tests enable_tests
|
||||
wine_fn_config_makefile dlls/bcryptprimitives enable_bcryptprimitives
|
||||
|
@ -22517,6 +22544,7 @@ wine_fn_config_makefile dlls/powrprof enable_powrprof
|
|||
wine_fn_config_makefile dlls/printui enable_printui
|
||||
wine_fn_config_makefile dlls/prntvpt enable_prntvpt
|
||||
wine_fn_config_makefile dlls/prntvpt/tests enable_tests
|
||||
wine_fn_config_makefile dlls/profapi enable_profapi
|
||||
wine_fn_config_makefile dlls/propsys enable_propsys
|
||||
wine_fn_config_makefile dlls/propsys/tests enable_tests
|
||||
wine_fn_config_makefile dlls/psapi enable_psapi
|
||||
|
@ -22550,6 +22578,8 @@ wine_fn_config_makefile dlls/riched20 enable_riched20
|
|||
wine_fn_config_makefile dlls/riched20/tests enable_tests
|
||||
wine_fn_config_makefile dlls/riched32 enable_riched32
|
||||
wine_fn_config_makefile dlls/riched32/tests enable_tests
|
||||
wine_fn_config_makefile dlls/rometadata enable_rometadata
|
||||
wine_fn_config_makefile dlls/rometadata/tests enable_tests
|
||||
wine_fn_config_makefile dlls/rpcrt4 enable_rpcrt4
|
||||
wine_fn_config_makefile dlls/rpcrt4/tests enable_tests
|
||||
wine_fn_config_makefile dlls/rsabase enable_rsabase
|
||||
|
@ -23073,7 +23103,6 @@ test "$wine_binary" = wine || as_fn_append CONFIGURE_TARGETS " loader/wine"
|
|||
|
||||
if test "x$enable_tools" != xno
|
||||
then
|
||||
as_fn_append CONFIGURE_TARGETS " tools/makedep$ac_exeext"
|
||||
ac_config_commands="$ac_config_commands tools/makedep"
|
||||
|
||||
fi
|
||||
|
@ -23115,18 +23144,6 @@ include/stamp-h.in: configure.ac aclocal.m4
|
|||
@echo timestamp > \$@"
|
||||
fi
|
||||
|
||||
if test "x$enable_tools" != xno
|
||||
then
|
||||
as_fn_append wine_rules "
|
||||
tools/makedep$ac_exeext: ${wine_srcdir}tools/makedep.c include/config.h config.status
|
||||
@./config.status tools/makedep
|
||||
Makefile: tools/makedep$ac_exeext"
|
||||
else
|
||||
as_fn_append wine_rules "
|
||||
\$(MAKEDEP):
|
||||
@echo \"You need to run make in $toolsdir first\" && false"
|
||||
fi
|
||||
|
||||
|
||||
if test -n "$with_wine64"
|
||||
then
|
||||
|
@ -23878,7 +23895,8 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
|||
wine_fn_output_makedep ()
|
||||
{
|
||||
as_dir=tools; as_fn_mkdir_p
|
||||
$CC -I${wine_srcdir}tools -Iinclude -I${wine_srcdir}include -D__WINESRC__ -DWINE_UNIX_LIB $EXTRACFLAGS $CPPFLAGS $CFLAGS -o tools/makedep$ac_exeext ${wine_srcdir}tools/makedep.c $LDFLAGS
|
||||
$CC -c -I${wine_srcdir}tools -Iinclude -I${wine_srcdir}include -D__WINESRC__ -DWINE_UNIX_LIB $EXTRACFLAGS $CPPFLAGS $CFLAGS -o tools/makedep.o ${wine_srcdir}tools/makedep.c
|
||||
$CC -o tools/makedep$ac_exeext tools/makedep.o $LDFLAGS
|
||||
}
|
||||
wine_fn_output_makefile ()
|
||||
{
|
||||
|
@ -23945,9 +23963,6 @@ host = $host
|
|||
host_cpu = $host_cpu
|
||||
host_vendor = $host_vendor
|
||||
host_os = $host_os
|
||||
dlldir = $dlldir
|
||||
fontdir = $fontdir
|
||||
nlsdir = $nlsdir
|
||||
srcdir = $srcdir
|
||||
SET_MAKE = $SET_MAKE
|
||||
CC = $CC
|
||||
|
|
59
configure.ac
59
configure.ac
|
@ -91,9 +91,6 @@ AC_ARG_WITH(wine64, AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine i
|
|||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
AC_SUBST(dlldir,[\${libdir}/wine])
|
||||
AC_SUBST(fontdir,[\${datadir}/wine/fonts])
|
||||
AC_SUBST(nlsdir,[\${datadir}/wine/nls])
|
||||
AC_SUBST(srcdir)
|
||||
|
||||
dnl **** Check for some programs ****
|
||||
|
@ -198,7 +195,7 @@ fi
|
|||
AC_SUBST(toolsdir,[$wine_cv_toolsdir])
|
||||
AC_SUBST(MAKEDEP,[$wine_makedep])
|
||||
AC_SUBST(RUNTESTFLAGS,["-q -P wine"])
|
||||
AC_SUBST(SED_CMD,["LC_ALL=C sed -e 's,@bindir@,\${bindir},g' -e 's,@dlldir@,\${dlldir},g' -e 's,@PACKAGE_STRING@,$PACKAGE_STRING,g' -e 's,@PACKAGE_VERSION@,$PACKAGE_VERSION,g'"])
|
||||
AC_SUBST(SED_CMD,["LC_ALL=C sed -e 's,@bindir@,\${bindir},g' -e 's,@PACKAGE_STRING@,$PACKAGE_STRING,g' -e 's,@PACKAGE_VERSION@,$PACKAGE_VERSION,g'"])
|
||||
|
||||
if test -n "$host_alias" -a "$host_alias" != "$build_alias"
|
||||
then
|
||||
|
@ -637,14 +634,21 @@ case $host_os in
|
|||
AC_SUBST(SECURITY_LIBS,"-framework Security -framework CoreFoundation")
|
||||
AC_SUBST(SYSTEMCONFIGURATION_LIBS,"-framework SystemConfiguration")
|
||||
|
||||
WINELOADER_LDFLAGS="-Wl,-pie,-segalign,0x1000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist"
|
||||
WINELOADER_LDFLAGS="-Wl,-segalign,0x1000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist"
|
||||
|
||||
case $HOST_ARCH in
|
||||
i386|x86_64) wine_can_build_preloader=yes ;;
|
||||
*) wine_can_build_preloader=no ;;
|
||||
i386) wine_use_preloader=yes ;;
|
||||
x86_64)
|
||||
dnl If the -no_huge linker option is present (added in Xcode 15.3), use zerofill sections instead of the preloader
|
||||
WINE_TRY_CFLAGS([-Wl,-no_huge],
|
||||
[wine_use_preloader=no
|
||||
WINELOADER_LDFLAGS="$WINELOADER_LDFLAGS -Wl,-no_pie,-image_base,0x200000000,-no_huge,-no_fixup_chains,-segalign,0x1000,-segaddr,WINE_RESERVE,0x1000,-segaddr,WINE_TOP_DOWN,0x7ff000000000"],
|
||||
[wine_use_preloader=yes])
|
||||
;;
|
||||
*) wine_use_preloader=no ;;
|
||||
esac
|
||||
|
||||
if test "$wine_can_build_preloader" = "yes"
|
||||
if test "$wine_use_preloader" = "yes"
|
||||
then
|
||||
WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs -e _start -ldylib1.o -mmacosx-version-min=10.7 -Wl,-no_new_main,-segalign,0x1000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist"
|
||||
WINE_TRY_CFLAGS([-Wl,-no_pie],
|
||||
|
@ -659,8 +663,6 @@ case $host_os in
|
|||
esac
|
||||
dnl If preloader is used, the loader needs to be an LC_UNIXTHREAD binary to avoid AppKit/Core Animation problems.
|
||||
WINELOADER_LDFLAGS="$WINELOADER_LDFLAGS -mmacosx-version-min=10.7"
|
||||
else
|
||||
WINE_WARNING([can't build Wine preloader; many programs won't work])
|
||||
fi
|
||||
|
||||
if test "x$with_coreaudio" != "xno";
|
||||
|
@ -2035,19 +2037,18 @@ case $host_os in
|
|||
linux*)
|
||||
if test $HOST_ARCH != unknown
|
||||
then
|
||||
test "$wine_binary" = wine || WINE_IGNORE_FILE(loader/wine-preloader)
|
||||
WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader"
|
||||
fi
|
||||
;;
|
||||
darwin*|macosx*)
|
||||
if test "$wine_can_build_preloader" = "yes"
|
||||
then
|
||||
test "$wine_binary" = wine || WINE_IGNORE_FILE(loader/wine-preloader)
|
||||
WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader"
|
||||
wine_use_preloader=yes
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$wine_use_preloader" = "yes"
|
||||
then
|
||||
test "$wine_binary" = wine || WINE_IGNORE_FILE(loader/wine-preloader)
|
||||
WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader"
|
||||
AC_DEFINE(HAVE_WINE_PRELOADER, 1, [Define to 1 if the Wine preloader is being used.])
|
||||
fi
|
||||
|
||||
dnl **** Check for functions ****
|
||||
|
||||
dnl Check for -ldl
|
||||
|
@ -2459,6 +2460,7 @@ WINE_CONFIG_MAKEFILE(dlls/avifil32)
|
|||
WINE_CONFIG_MAKEFILE(dlls/avifil32/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/avifile.dll16,enable_win16)
|
||||
WINE_CONFIG_MAKEFILE(dlls/avrt)
|
||||
WINE_CONFIG_MAKEFILE(dlls/bcp47langs)
|
||||
WINE_CONFIG_MAKEFILE(dlls/bcrypt)
|
||||
WINE_CONFIG_MAKEFILE(dlls/bcrypt/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/bcryptprimitives)
|
||||
|
@ -3025,6 +3027,7 @@ WINE_CONFIG_MAKEFILE(dlls/powrprof)
|
|||
WINE_CONFIG_MAKEFILE(dlls/printui)
|
||||
WINE_CONFIG_MAKEFILE(dlls/prntvpt)
|
||||
WINE_CONFIG_MAKEFILE(dlls/prntvpt/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/profapi)
|
||||
WINE_CONFIG_MAKEFILE(dlls/propsys)
|
||||
WINE_CONFIG_MAKEFILE(dlls/propsys/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/psapi)
|
||||
|
@ -3058,6 +3061,8 @@ WINE_CONFIG_MAKEFILE(dlls/riched20)
|
|||
WINE_CONFIG_MAKEFILE(dlls/riched20/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/riched32)
|
||||
WINE_CONFIG_MAKEFILE(dlls/riched32/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/rometadata)
|
||||
WINE_CONFIG_MAKEFILE(dlls/rometadata/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/rpcrt4)
|
||||
WINE_CONFIG_MAKEFILE(dlls/rpcrt4/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/rsabase)
|
||||
|
@ -3583,12 +3588,12 @@ test "$wine_binary" = wine || WINE_IGNORE_FILE(loader/wine)
|
|||
|
||||
if test "x$enable_tools" != xno
|
||||
then
|
||||
WINE_IGNORE_FILE(tools/makedep$ac_exeext)
|
||||
AC_CONFIG_COMMANDS([tools/makedep],[wine_fn_output_makedep || AS_EXIT],
|
||||
[wine_fn_output_makedep ()
|
||||
{
|
||||
AS_MKDIR_P(tools)
|
||||
$CC -I${wine_srcdir}tools -Iinclude -I${wine_srcdir}include -D__WINESRC__ -DWINE_UNIX_LIB $EXTRACFLAGS $CPPFLAGS $CFLAGS -o tools/makedep$ac_exeext ${wine_srcdir}tools/makedep.c $LDFLAGS
|
||||
$CC -c -I${wine_srcdir}tools -Iinclude -I${wine_srcdir}include -D__WINESRC__ -DWINE_UNIX_LIB $EXTRACFLAGS $CPPFLAGS $CFLAGS -o tools/makedep.o ${wine_srcdir}tools/makedep.c
|
||||
$CC -o tools/makedep$ac_exeext tools/makedep.o $LDFLAGS
|
||||
}])
|
||||
fi
|
||||
|
||||
|
@ -3652,18 +3657,6 @@ include/stamp-h.in: configure.ac aclocal.m4
|
|||
@echo timestamp > \$[@]])
|
||||
fi
|
||||
|
||||
if test "x$enable_tools" != xno
|
||||
then
|
||||
WINE_APPEND_RULE(
|
||||
[tools/makedep$ac_exeext: ${wine_srcdir}tools/makedep.c include/config.h config.status
|
||||
@./config.status tools/makedep
|
||||
Makefile: tools/makedep$ac_exeext])
|
||||
else
|
||||
WINE_APPEND_RULE(
|
||||
[\$(MAKEDEP):
|
||||
@echo \"You need to run make in $toolsdir first\" && false])
|
||||
fi
|
||||
|
||||
dnl Rules for wineloader
|
||||
|
||||
if test -n "$with_wine64"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
apiset api-ms-win-appmodel-runtime-internal-l1-1-1 = kernelbase.dll
|
||||
apiset api-ms-win-appmodel-runtime-l1-1-2 = kernelbase.dll
|
||||
apiset api-ms-win-base-bootconfig-l1-1-0 = advapi32.dll
|
||||
apiset api-ms-win-base-util-l1-1-0 = advapi32.dll
|
||||
|
|
2
dlls/bcp47langs/Makefile.in
Normal file
2
dlls/bcp47langs/Makefile.in
Normal file
|
@ -0,0 +1,2 @@
|
|||
MODULE = bcp47langs.dll
|
||||
IMPORTLIB = bcp47langs
|
71
dlls/bcp47langs/bcp47langs.spec
Normal file
71
dlls/bcp47langs/bcp47langs.spec
Normal file
|
@ -0,0 +1,71 @@
|
|||
1 stub GetUnIsoRegionCode
|
||||
@ stub AppendUserLanguageInputMethods
|
||||
@ stub AppendUserLanguageInternal
|
||||
@ stub AppendUserLanguages
|
||||
@ stub Bcp47BufferFromLcid
|
||||
@ stub Bcp47FindClosestLanguage
|
||||
@ stub Bcp47FromCompactTagInternal
|
||||
@ stub Bcp47FromHkl
|
||||
@ stub Bcp47FromLcid
|
||||
@ stub Bcp47GetAbbreviation
|
||||
@ stub Bcp47GetDirectionality
|
||||
@ stub Bcp47GetDistance
|
||||
@ stub Bcp47GetExtensionSingletons
|
||||
@ stub Bcp47GetExtensionSubstring
|
||||
@ stub Bcp47GetIsoLanguageCode
|
||||
@ stub Bcp47GetIsoScriptCode
|
||||
@ stub Bcp47GetLanguageName
|
||||
@ stub Bcp47GetMuiForm
|
||||
@ stub Bcp47GetNeutralForm
|
||||
@ stub Bcp47GetNlsForm
|
||||
@ stub Bcp47GetSubtagMapInternal
|
||||
@ stub Bcp47GetUnIsoRegionCode
|
||||
@ stub Bcp47IsWellFormed
|
||||
@ stub Bcp47Normalize
|
||||
@ stub ClearApplicationLanguageOverride
|
||||
@ stub ClearApplicationManifestLanguages
|
||||
@ stub ClearHttpAcceptLanguageOptOut
|
||||
@ stub ClearUserDisplayLanguageOverride
|
||||
@ stub ClearUserLocaleFromLanguageProfileOptOut
|
||||
@ stub CompactTagFromBcp47Internal
|
||||
@ stub DllGetActivationFactory
|
||||
@ stub DllGetClassObject
|
||||
@ stub GetApplicationLanguageOverride
|
||||
@ stub GetApplicationLanguages
|
||||
@ stub GetApplicationManifestLanguages
|
||||
@ stub GetAppropriateUserLocaleForUserLanguages
|
||||
@ stub GetAppropriateUserPreferredAndDisplayLanguagesForUser
|
||||
@ stub GetClosestMatchingUserLanguage
|
||||
@ stub GetDisplayLanguagesForAllUsers
|
||||
@ stub GetFontFallbackLanguageList
|
||||
@ stub GetHttpAcceptLanguageOptOut
|
||||
@ stub GetInputMethodOverrideForUser
|
||||
@ stub GetPendingUserDisplayLanguage
|
||||
@ stub GetRelevantLocalesFromLanguageTags
|
||||
@ stub GetSerializedUserLanguageProfile
|
||||
@ stub GetSerializedUserLanguagesForUser
|
||||
@ stub GetStartingUserDisplayLanguage
|
||||
@ stub GetUserDisplayLanguageOverride
|
||||
@ stub GetUserLanguageInputMethods
|
||||
@ stub GetUserLanguageInputMethodsForUser
|
||||
@ stub GetUserLanguages
|
||||
@ stub GetUserLanguagesForAllUsers
|
||||
@ stub GetUserLanguagesForUser
|
||||
@ stub GetUserLocaleFromLanguageProfileOptOut
|
||||
@ stub IsTransientLcid
|
||||
@ stub LanguageListAsMuiForm
|
||||
@ stub LcidFromBcp47
|
||||
@ stub RemoveInputsForAllLanguagesInternal
|
||||
@ stub RemoveUserLanguageInputMethods
|
||||
@ stub ResolveLanguages
|
||||
@ stub SetApplicationLanguageOverride
|
||||
@ stub SetApplicationManifestLanguages
|
||||
@ stub SetHttpAcceptLanguageOptOut
|
||||
@ stub SetInputMethodOverride
|
||||
@ stub SetPreviousUserDisplayLanguages
|
||||
@ stub SetStartingUserDisplayLanguage
|
||||
@ stub SetUserDisplayLanguageOverride
|
||||
@ stub SetUserLanguageInputMethods
|
||||
@ stub SetUserLanguagesInternal
|
||||
@ stub SetUserLanguagesInternalCore
|
||||
@ stub SetUserLocaleFromLanguageProfileOptOut
|
|
@ -158,6 +158,7 @@
|
|||
@ stdcall ApplicationRecoveryFinished(long)
|
||||
@ stdcall ApplicationRecoveryInProgress(ptr)
|
||||
@ stdcall AppPolicyGetMediaFoundationCodecLoading(ptr ptr) kernelbase.AppPolicyGetMediaFoundationCodecLoading
|
||||
@ stdcall AppPolicyGetWindowingModel(ptr ptr) kernelbase.AppPolicyGetWindowingModel
|
||||
@ stdcall -import AreFileApisANSI()
|
||||
@ stdcall AssignProcessToJobObject(ptr ptr)
|
||||
@ stdcall -import AttachConsole(long)
|
||||
|
|
|
@ -520,6 +520,298 @@ static void test_internal_structure(void)
|
|||
ok( EndUpdateResourceW( res, TRUE ), "EndUpdateResourceW failed\n");
|
||||
}
|
||||
|
||||
static const struct
|
||||
{
|
||||
IMAGE_DOS_HEADER dos;
|
||||
IMAGE_NT_HEADERS nt;
|
||||
IMAGE_SECTION_HEADER section;
|
||||
} dll_image =
|
||||
{
|
||||
{ IMAGE_DOS_SIGNATURE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 }, 0, 0, { 0 },
|
||||
sizeof(IMAGE_DOS_HEADER) },
|
||||
{
|
||||
IMAGE_NT_SIGNATURE, /* Signature */
|
||||
{
|
||||
#if defined __i386__
|
||||
IMAGE_FILE_MACHINE_I386, /* Machine */
|
||||
#elif defined __x86_64__
|
||||
IMAGE_FILE_MACHINE_AMD64, /* Machine */
|
||||
#elif defined __arm__
|
||||
IMAGE_FILE_MACHINE_ARMNT, /* Machine */
|
||||
#elif defined __aarch64__
|
||||
IMAGE_FILE_MACHINE_ARM64, /* Machine */
|
||||
#else
|
||||
# error You must specify the machine type
|
||||
#endif
|
||||
1, /* NumberOfSections */
|
||||
0, /* TimeDateStamp */
|
||||
0, /* PointerToSymbolTable */
|
||||
0, /* NumberOfSymbols */
|
||||
sizeof(IMAGE_OPTIONAL_HEADER), /* SizeOfOptionalHeader */
|
||||
IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL /* Characteristics */
|
||||
},
|
||||
{ IMAGE_NT_OPTIONAL_HDR_MAGIC, /* Magic */
|
||||
1, /* MajorLinkerVersion */
|
||||
0, /* MinorLinkerVersion */
|
||||
0, /* SizeOfCode */
|
||||
0, /* SizeOfInitializedData */
|
||||
0, /* SizeOfUninitializedData */
|
||||
0, /* AddressOfEntryPoint */
|
||||
0x1000, /* BaseOfCode */
|
||||
#ifndef _WIN64
|
||||
0, /* BaseOfData */
|
||||
#endif
|
||||
0x10000000, /* ImageBase */
|
||||
0x1000, /* SectionAlignment */
|
||||
0x1000, /* FileAlignment */
|
||||
4, /* MajorOperatingSystemVersion */
|
||||
0, /* MinorOperatingSystemVersion */
|
||||
1, /* MajorImageVersion */
|
||||
0, /* MinorImageVersion */
|
||||
4, /* MajorSubsystemVersion */
|
||||
0, /* MinorSubsystemVersion */
|
||||
0, /* Win32VersionValue */
|
||||
0x3000, /* SizeOfImage */
|
||||
sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS),
|
||||
0, /* CheckSum */
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */
|
||||
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT, /* DllCharacteristics */
|
||||
0, /* SizeOfStackReserve */
|
||||
0, /* SizeOfStackCommit */
|
||||
0, /* SizeOfHeapReserve */
|
||||
0, /* SizeOfHeapCommit */
|
||||
0, /* LoaderFlags */
|
||||
IMAGE_FILE_RESOURCE_DIRECTORY + 1, /* NumberOfRvaAndSizes */
|
||||
{ { 0 }, { 0 }, { 0x1000, 0x1000 } } /* DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] */
|
||||
}
|
||||
},
|
||||
{ ".rsrc\0\0", { 0 }, 0x1000, 0x1000, 0, 0, 0, 0, 0,
|
||||
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ }
|
||||
};
|
||||
|
||||
static void create_test_dll( const WCHAR *name )
|
||||
{
|
||||
DWORD dummy;
|
||||
HANDLE handle = CreateFileW( name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
|
||||
ok( handle != INVALID_HANDLE_VALUE, "failed to create file err %lu\n", GetLastError() );
|
||||
WriteFile( handle, &dll_image, sizeof(dll_image), &dummy, NULL );
|
||||
SetFilePointer( handle, dll_image.nt.OptionalHeader.SizeOfImage, NULL, FILE_BEGIN );
|
||||
SetEndOfFile( handle );
|
||||
CloseHandle( handle );
|
||||
}
|
||||
|
||||
static struct mui_res
|
||||
{
|
||||
DWORD signature;
|
||||
DWORD size;
|
||||
DWORD version;
|
||||
DWORD path_type;
|
||||
DWORD file_type;
|
||||
DWORD system_attributes;
|
||||
DWORD fallback_location;
|
||||
BYTE service_checksum[16];
|
||||
BYTE checksum[16];
|
||||
DWORD unk1[2];
|
||||
DWORD mui_path_off;
|
||||
DWORD mui_path_size;
|
||||
DWORD unk2[2];
|
||||
DWORD ln_type_name_off;
|
||||
DWORD ln_type_name_size;
|
||||
DWORD ln_type_id_off;
|
||||
DWORD ln_type_id_size;
|
||||
DWORD mui_type_name_off;
|
||||
DWORD mui_type_name_size;
|
||||
DWORD mui_type_id_off;
|
||||
DWORD mui_type_id_size;
|
||||
DWORD lang_off;
|
||||
DWORD lang_size;
|
||||
DWORD fallback_lang_off;
|
||||
DWORD fallback_lang_size;
|
||||
WCHAR ln_type_names[8];
|
||||
DWORD ln_type_ids[1];
|
||||
WCHAR mui_type_names[8];
|
||||
DWORD mui_type_ids[1];
|
||||
WCHAR lang[8];
|
||||
WCHAR fallback_lang[8];
|
||||
} ln_mui_res = {
|
||||
0xfecdfecd, sizeof(ln_mui_res), 0x10000, 0,
|
||||
MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN >> 1,
|
||||
0, 0, {'s','c'}, {'c'}, {0}, 0, 0, {0},
|
||||
offsetof(struct mui_res, ln_type_names), sizeof(L"MUI\0"),
|
||||
offsetof(struct mui_res, ln_type_ids), sizeof(ln_mui_res.ln_type_ids),
|
||||
offsetof(struct mui_res, mui_type_names), sizeof(L"MUI\0"),
|
||||
offsetof(struct mui_res, mui_type_ids), sizeof(ln_mui_res.mui_type_ids), 0, 0,
|
||||
offsetof(struct mui_res, fallback_lang), sizeof(L"en-US"),
|
||||
{'M','U','I',0,0}, {RT_CURSOR}, {'M','U','I',0,0}, {RT_STRING}, {0}, {'e','n','-','U','S',0},
|
||||
}, en_mui_res = {
|
||||
0xfecdfecd, sizeof(ln_mui_res), 0x10000, 0,
|
||||
MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI >> 1,
|
||||
0, 0, {'s','c'}, {'c'}, {0}, 0, 0, {0},
|
||||
offsetof(struct mui_res, ln_type_names), sizeof(L"MUI\0"),
|
||||
offsetof(struct mui_res, ln_type_ids), sizeof(ln_mui_res.ln_type_ids),
|
||||
0, 0, 0, 0, offsetof(struct mui_res, lang), sizeof(L"en-US"), 0, 0,
|
||||
{'M','U','I',0,0}, {RT_STRING}, {0}, {0}, {'e','n','-','U','S',0}
|
||||
};
|
||||
|
||||
static void test_mui(void)
|
||||
{
|
||||
static const WCHAR ln_dll[] = L"test_mui.dll";
|
||||
static const WCHAR en_dll[] = L"en-US\\test_mui.dll.mui";
|
||||
static const BYTE zeros[16] = { 0 };
|
||||
BYTE buf[1024];
|
||||
FILEMUIINFO *info = (FILEMUIINFO *)buf;
|
||||
const WCHAR *str;
|
||||
DWORD size, *id;
|
||||
HANDLE res;
|
||||
BOOL r;
|
||||
|
||||
size = 0;
|
||||
r = GetFileMUIInfo( 0, ln_dll, NULL, &size);
|
||||
ok( !r, "GetFileMUIInfo succeeded\n" );
|
||||
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() = %ld\n", GetLastError() );
|
||||
|
||||
create_test_dll( ln_dll );
|
||||
CreateDirectoryW( L"en-US", NULL );
|
||||
create_test_dll( en_dll );
|
||||
|
||||
size = 0;
|
||||
r = GetFileMUIInfo( 0, ln_dll, NULL, &size );
|
||||
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
|
||||
ok( size == sizeof(*info), "unexpected size: %ld\n", size );
|
||||
|
||||
memset( buf, 0xfe, sizeof(buf) );
|
||||
size = sizeof(buf);
|
||||
info->dwSize = sizeof(buf);
|
||||
info->dwVersion = 0;
|
||||
r = GetFileMUIInfo( 0, ln_dll, info, &size );
|
||||
ok( !r, "GetFileMUIInfo succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %ld\n", GetLastError() );
|
||||
ok( !size, "size = %ld\n", size );
|
||||
|
||||
size = sizeof(buf);
|
||||
info->dwVersion = MUI_FILEINFO_VERSION;
|
||||
r = GetFileMUIInfo( 0, ln_dll, info, &size );
|
||||
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
|
||||
ok( info->dwSize == sizeof(buf), "dwSize = %ld\n", info->dwSize );
|
||||
ok( info->dwVersion == MUI_FILEINFO_VERSION, "dwVersion = %ld\n", info->dwVersion );
|
||||
ok( info->dwFileType == MUI_FILETYPE_NOT_LANGUAGE_NEUTRAL, "dwFileType = %ld\n", info->dwFileType );
|
||||
ok( !memcmp(info->pChecksum, zeros, sizeof(info->pChecksum)), "pChecksum = %s\n",
|
||||
wine_dbgstr_an((char *)info->pChecksum, sizeof(info->pChecksum)) );
|
||||
ok( !memcmp(info->pServiceChecksum, zeros, sizeof(info->pServiceChecksum)), "pServiceChecksum = %s\n",
|
||||
wine_dbgstr_an((char *)info->pServiceChecksum, sizeof(info->pServiceChecksum)) );
|
||||
ok( !info->dwLanguageNameOffset, "dwLanguageNameOffset = %ld\n", info->dwLanguageNameOffset );
|
||||
ok( !info->dwTypeIDMainSize, "dwTypeIDMainSize = %ld\n", info->dwTypeIDMainSize );
|
||||
ok( !info->dwTypeIDMainOffset, "dwTypeIDMainOffset = %ld\n", info->dwTypeIDMainOffset );
|
||||
ok( !info->dwTypeNameMainOffset, "dwTypeNameMainOffset = %ld\n", info->dwTypeNameMainOffset );
|
||||
ok( !info->dwTypeIDMUISize, "dwTypeIDMUISize = %ld\n", info->dwTypeIDMUISize );
|
||||
ok( !info->dwTypeIDMUIOffset, "dwTypeIDMUIOffset = %ld\n", info->dwTypeIDMUIOffset );
|
||||
ok( !info->dwTypeNameMUIOffset, "dwTypeNameMUIOffset = %ld\n", info->dwTypeNameMUIOffset );
|
||||
ok( !memcmp(info->abBuffer, zeros, sizeof(info->abBuffer)), "abBuffer = %s\n",
|
||||
wine_dbgstr_an((char *)info->abBuffer, sizeof(info->abBuffer)) );
|
||||
|
||||
res = BeginUpdateResourceW( ln_dll, TRUE );
|
||||
ok( res != NULL, "BeginUpdateResourceW failed: %ld\n", GetLastError() );
|
||||
r = UpdateResourceW( res, L"MUI", MAKEINTRESOURCEW(1), 0, &ln_mui_res, 4 );
|
||||
ok( r, "UpdateResource failed: %ld\n", GetLastError() );
|
||||
ok( EndUpdateResourceW( res, FALSE ), "EndUpdateResourceW failed: %ld\n", GetLastError() );
|
||||
|
||||
size = 0;
|
||||
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
|
||||
| MUI_QUERY_RESOURCE_TYPES, ln_dll, NULL, &size );
|
||||
ok( !r, "GetFileMUIInfo succeeded\n" );
|
||||
ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "GetLastError() = %ld\n", GetLastError() );
|
||||
|
||||
res = BeginUpdateResourceW( ln_dll, TRUE );
|
||||
ok( res != NULL, "BeginUpdateResourceW failed: %ld\n", GetLastError() );
|
||||
r = UpdateResourceW( res, L"MUI", MAKEINTRESOURCEW(1), 0, &ln_mui_res, sizeof(ln_mui_res) );
|
||||
ok( r, "UpdateResource failed: %ld\n", GetLastError() );
|
||||
ok( EndUpdateResourceW( res, FALSE ), "EndUpdateResourceW failed: %ld\n", GetLastError() );
|
||||
|
||||
size = 0;
|
||||
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
|
||||
| MUI_QUERY_RESOURCE_TYPES, ln_dll, NULL, &size );
|
||||
ok( !r, "GetFileMUIInfo succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() = %ld\n", GetLastError() );
|
||||
ok( size, "size was not set\n" );
|
||||
|
||||
memset( buf, 0xfe, sizeof(buf) );
|
||||
size = sizeof(buf);
|
||||
info->dwSize = sizeof(buf);
|
||||
info->dwVersion = MUI_FILEINFO_VERSION;
|
||||
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
|
||||
| MUI_QUERY_RESOURCE_TYPES, ln_dll, info, &size );
|
||||
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
|
||||
ok( info->dwSize == sizeof(buf), "dwSize = %ld\n", info->dwSize );
|
||||
ok( info->dwVersion == MUI_FILEINFO_VERSION, "dwVersion = %ld\n", info->dwVersion );
|
||||
ok( info->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN, "dwFileType = %ld\n", info->dwFileType );
|
||||
ok( info->pChecksum[0] == 'c', "pChecksum = %s\n",
|
||||
wine_dbgstr_an((char *)info->pChecksum, sizeof(info->pChecksum)) );
|
||||
ok( info->pServiceChecksum[0] == 's', "pServiceChecksum = %s\n",
|
||||
wine_dbgstr_an((char *)info->pServiceChecksum, sizeof(info->pServiceChecksum)) );
|
||||
ok( info->dwLanguageNameOffset == 72, "dwLanguageNameOffset = %ld\n", info->dwLanguageNameOffset );
|
||||
str = (WCHAR *)(buf + info->dwLanguageNameOffset);
|
||||
ok( !wcscmp(str, L"en-US"), "language name = %s\n", wine_dbgstr_w(str) );
|
||||
ok( info->dwTypeIDMainSize == 1, "dwTypeIDMainSize = %ld\n", info->dwTypeIDMainSize );
|
||||
ok( info->dwTypeIDMainOffset == 84, "dwTypeIDMainOffset = %ld\n", info->dwTypeIDMainOffset );
|
||||
id = (DWORD *)(buf + info->dwTypeIDMainOffset);
|
||||
ok( id[0] == RT_CURSOR, "type ID main[0] = %ld\n", id[0] );
|
||||
ok( info->dwTypeNameMainOffset == 88, "dwTypeNameMainOffset = %ld\n", info->dwTypeNameMainOffset );
|
||||
str = (WCHAR *)(buf + info->dwTypeNameMainOffset);
|
||||
ok( !wcscmp(str, L"MUI"), "type name main[0] = %s\n", wine_dbgstr_w(str) );
|
||||
str += wcslen(str) + 1;
|
||||
ok( !str[0], "string list is not NULL terminated: %s\n", wine_dbgstr_w(str) );
|
||||
ok( info->dwTypeIDMUISize == 1, "dwTypeIDMUISize = %ld\n", info->dwTypeIDMUISize );
|
||||
ok( info->dwTypeIDMUIOffset == 98, "dwTypeIDMUIOffset = %ld\n", info->dwTypeIDMUIOffset );
|
||||
id = (DWORD *)(buf + info->dwTypeIDMUIOffset);
|
||||
ok( id[0] == RT_STRING, "type ID MUI[0] = %ld\n", id[0] );
|
||||
ok( info->dwTypeNameMUIOffset == 102, "dwTypeNameMUIOffset = %ld\n", info->dwTypeNameMUIOffset );
|
||||
str = (WCHAR *)(buf + info->dwTypeNameMUIOffset);
|
||||
ok( !wcscmp(str, L"MUI"), "type name MUI[0] = %s\n", wine_dbgstr_w(str) );
|
||||
str += wcslen(str) + 1;
|
||||
ok( !str[0], "string list is not NULL terminated: %s\n", wine_dbgstr_w(str) );
|
||||
|
||||
res = BeginUpdateResourceW( en_dll, TRUE );
|
||||
ok( res != NULL, "BeginUpdateResourceW failed: %ld\n", GetLastError() );
|
||||
r = UpdateResourceW( res, L"MUI", MAKEINTRESOURCEW(1), 0, &en_mui_res, sizeof(en_mui_res) );
|
||||
ok( r, "UpdateResource failed: %ld\n", GetLastError() );
|
||||
ok( EndUpdateResourceW( res, FALSE ), "EndUpdateResourceW failed: %ld\n", GetLastError() );
|
||||
|
||||
memset( buf, 0xfe, sizeof(buf) );
|
||||
size = sizeof(buf);
|
||||
info->dwSize = sizeof(buf);
|
||||
info->dwVersion = MUI_FILEINFO_VERSION;
|
||||
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
|
||||
| MUI_QUERY_RESOURCE_TYPES, en_dll, info, &size );
|
||||
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
|
||||
ok( info->dwSize == sizeof(buf), "dwSize = %ld\n", info->dwSize );
|
||||
ok( info->dwVersion == MUI_FILEINFO_VERSION, "dwVersion = %ld\n", info->dwVersion );
|
||||
ok( info->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI, "dwFileType = %ld\n", info->dwFileType );
|
||||
ok( info->pChecksum[0] == 'c', "pChecksum = %s\n",
|
||||
wine_dbgstr_an((char *)info->pChecksum, sizeof(info->pChecksum)) );
|
||||
ok( info->pServiceChecksum[0] == 's', "pServiceChecksum = %s\n",
|
||||
wine_dbgstr_an((char *)info->pServiceChecksum, sizeof(info->pServiceChecksum)) );
|
||||
ok( info->dwLanguageNameOffset == 72, "dwLanguageNameOffset = %ld\n", info->dwLanguageNameOffset );
|
||||
str = (WCHAR *)(buf + info->dwLanguageNameOffset);
|
||||
ok( !wcscmp(str, L"en-US"), "language name = %s\n", wine_dbgstr_w(str) );
|
||||
ok( !info->dwTypeIDMainSize, "dwTypeIDMainSize = %ld\n", info->dwTypeIDMainSize );
|
||||
ok( !info->dwTypeIDMainOffset, "dwTypeIDMainOffset = %ld\n", info->dwTypeIDMainOffset );
|
||||
ok( !info->dwTypeNameMainOffset, "dwTypeNameMainOffset = %ld\n", info->dwTypeNameMainOffset );
|
||||
ok( info->dwTypeIDMUISize == 1, "dwTypeIDMUISize = %ld\n", info->dwTypeIDMUISize );
|
||||
ok( info->dwTypeIDMUIOffset == 84, "dwTypeIDMUIOffset = %ld\n", info->dwTypeIDMUIOffset );
|
||||
id = (DWORD *)(buf + info->dwTypeIDMUIOffset);
|
||||
ok( id[0] == RT_STRING, "type ID MUI[0] = %ld\n", id[0] );
|
||||
ok( info->dwTypeNameMUIOffset == 88, "dwTypeNameMUIOffset = %ld\n", info->dwTypeNameMUIOffset );
|
||||
str = (WCHAR *)(buf + info->dwTypeNameMUIOffset);
|
||||
ok( !wcscmp(str, L"MUI"), "type name MUI[0] = %s\n", wine_dbgstr_w(str) );
|
||||
str += wcslen(str) + 1;
|
||||
ok( !str[0], "string list is not NULL terminated: %s\n", wine_dbgstr_w(str) );
|
||||
|
||||
DeleteFileW( ln_dll );
|
||||
DeleteFileW( en_dll );
|
||||
RemoveDirectoryW( L"en-US" );
|
||||
}
|
||||
|
||||
START_TEST(resource)
|
||||
{
|
||||
DWORD i;
|
||||
|
@ -552,4 +844,5 @@ START_TEST(resource)
|
|||
DeleteFileA( filename );
|
||||
}
|
||||
test_find_resource();
|
||||
test_mui();
|
||||
}
|
||||
|
|
|
@ -5719,15 +5719,221 @@ done:
|
|||
}
|
||||
|
||||
|
||||
#define MUI_SIGNATURE 0xfecdfecd
|
||||
struct mui_resource
|
||||
{
|
||||
DWORD signature;
|
||||
DWORD size;
|
||||
DWORD version;
|
||||
DWORD path_type;
|
||||
DWORD file_type;
|
||||
DWORD system_attributes;
|
||||
DWORD fallback_location;
|
||||
BYTE service_checksum[16];
|
||||
BYTE checksum[16];
|
||||
DWORD unk1[2];
|
||||
DWORD mui_path_off;
|
||||
DWORD mui_path_size;
|
||||
DWORD unk2[2];
|
||||
DWORD ln_type_name_off;
|
||||
DWORD ln_type_name_size;
|
||||
DWORD ln_type_id_off;
|
||||
DWORD ln_type_id_size;
|
||||
DWORD mui_type_name_off;
|
||||
DWORD mui_type_name_size;
|
||||
DWORD mui_type_id_off;
|
||||
DWORD mui_type_id_size;
|
||||
DWORD lang_off;
|
||||
DWORD lang_size;
|
||||
DWORD fallback_lang_off;
|
||||
DWORD fallback_lang_size;
|
||||
};
|
||||
|
||||
|
||||
static BOOL validate_mui_resource(struct mui_resource *mui, DWORD size)
|
||||
{
|
||||
if (size >= sizeof(DWORD) && mui->signature != MUI_SIGNATURE)
|
||||
{
|
||||
SetLastError(ERROR_MUI_INVALID_RC_CONFIG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size = min( size, mui->size );
|
||||
if (size < sizeof(*mui) ||
|
||||
mui->ln_type_name_off >= size || mui->ln_type_name_size > size - mui->ln_type_name_off ||
|
||||
mui->ln_type_id_off >= size || mui->ln_type_id_size > size - mui->ln_type_id_off ||
|
||||
mui->mui_type_name_off >= size || mui->mui_type_name_size > size - mui->mui_type_name_off ||
|
||||
mui->mui_type_id_off >= size || mui->mui_type_id_size > size - mui->mui_type_id_off ||
|
||||
mui->lang_off >= size || mui->lang_size > size - mui->lang_off ||
|
||||
mui->fallback_lang_off >= size || mui->fallback_lang_size > size - mui->fallback_lang_off)
|
||||
{
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetFileMUIInfo (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI /* DECLSPEC_HOTPATCH */ GetFileMUIInfo( DWORD flags, const WCHAR *path,
|
||||
FILEMUIINFO *info, DWORD *size )
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH GetFileMUIInfo( DWORD flags, const WCHAR *path,
|
||||
FILEMUIINFO *info, DWORD *size )
|
||||
{
|
||||
FIXME( "stub: %lu, %s, %p, %p\n", flags, debugstr_w(path), info, size );
|
||||
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
|
||||
return FALSE;
|
||||
DWORD off, mui_size, type = MUI_FILETYPE_NOT_LANGUAGE_NEUTRAL;
|
||||
struct mui_resource *mui = NULL;
|
||||
HMODULE hmod;
|
||||
HRSRC hrsrc;
|
||||
|
||||
TRACE( "%lu, %s, %p, %p\n", flags, debugstr_w(path), info, size );
|
||||
|
||||
if (!path || !size || (*size && !info) ||
|
||||
(info && (*size < sizeof(*info) || info->dwSize != *size ||
|
||||
info->dwVersion != MUI_FILEINFO_VERSION)))
|
||||
{
|
||||
if (size) *size = 0;
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!flags) flags = MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM;
|
||||
|
||||
hmod = LoadLibraryExW( path, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE );
|
||||
if (!hmod) return FALSE;
|
||||
|
||||
hrsrc = FindResourceW( hmod, MAKEINTRESOURCEW(1), L"MUI" );
|
||||
if (hrsrc)
|
||||
{
|
||||
mui = LockResource( LoadResource(hmod, hrsrc) );
|
||||
if (mui) mui_size = SizeofResource( hmod, hrsrc );
|
||||
if (!mui || !validate_mui_resource( mui, mui_size ))
|
||||
{
|
||||
FreeLibrary( hmod );
|
||||
return FALSE;
|
||||
}
|
||||
if (mui->file_type & (MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN >> 1))
|
||||
type = MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN;
|
||||
else if (mui->file_type & (MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI >> 1))
|
||||
type = MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI;
|
||||
}
|
||||
if (type == MUI_FILETYPE_NOT_LANGUAGE_NEUTRAL)
|
||||
{
|
||||
FreeLibrary( hmod );
|
||||
|
||||
if (!info)
|
||||
{
|
||||
*size = sizeof(*info);
|
||||
return TRUE;
|
||||
}
|
||||
if (info->dwSize < sizeof(*info))
|
||||
{
|
||||
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset( info, 0, sizeof(*info) );
|
||||
info->dwSize = *size;
|
||||
info->dwVersion = MUI_FILEINFO_VERSION;
|
||||
if (flags & MUI_QUERY_TYPE) info->dwFileType = type;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
off = offsetof(FILEMUIINFO, abBuffer);
|
||||
if (flags & MUI_QUERY_LANGUAGE_NAME)
|
||||
{
|
||||
off += type == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN ?
|
||||
mui->fallback_lang_size : mui->lang_size;
|
||||
}
|
||||
if (flags & MUI_QUERY_RESOURCE_TYPES)
|
||||
{
|
||||
if (type == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN)
|
||||
off += mui->ln_type_name_size + mui->ln_type_id_size;
|
||||
off += mui->mui_type_name_size + mui->mui_type_id_size;
|
||||
}
|
||||
if (off < sizeof(*info)) off = sizeof(*info);
|
||||
|
||||
if (!info || info->dwSize < off)
|
||||
{
|
||||
FreeLibrary( hmod );
|
||||
*size = off;
|
||||
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
off = 0;
|
||||
memset( info, 0, sizeof(*info) );
|
||||
info->dwSize = *size;
|
||||
info->dwVersion = MUI_FILEINFO_VERSION;
|
||||
if (flags & MUI_QUERY_TYPE) info->dwFileType = type;
|
||||
if (flags & MUI_QUERY_CHECKSUM)
|
||||
{
|
||||
memcpy( info->pChecksum, mui->checksum, sizeof(info->pChecksum) );
|
||||
memcpy( info->pServiceChecksum, mui->service_checksum, sizeof(info->pServiceChecksum) );
|
||||
}
|
||||
if (flags & MUI_QUERY_LANGUAGE_NAME)
|
||||
{
|
||||
if (type == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN && mui->fallback_lang_off)
|
||||
{
|
||||
info->dwLanguageNameOffset = offsetof(FILEMUIINFO, abBuffer);
|
||||
memcpy(info->abBuffer, ((BYTE *)mui) + mui->fallback_lang_off,
|
||||
mui->fallback_lang_size);
|
||||
off += mui->fallback_lang_size;
|
||||
}
|
||||
if (type == MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI && mui->lang_off)
|
||||
{
|
||||
info->dwLanguageNameOffset = offsetof(FILEMUIINFO, abBuffer);
|
||||
memcpy(info->abBuffer, ((BYTE *)mui) + mui->lang_off, mui->lang_size);
|
||||
off += mui->lang_size;
|
||||
}
|
||||
}
|
||||
if (flags & MUI_QUERY_RESOURCE_TYPES && type & MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN)
|
||||
{
|
||||
if (mui->ln_type_id_size && mui->ln_type_id_off)
|
||||
{
|
||||
info->dwTypeIDMainSize = mui->ln_type_id_size / sizeof(DWORD);
|
||||
info->dwTypeIDMainOffset = offsetof(FILEMUIINFO, abBuffer[off]);
|
||||
memcpy(info->abBuffer + off, ((BYTE *)mui) + mui->ln_type_id_off, mui->ln_type_id_size);
|
||||
off += mui->ln_type_id_size;
|
||||
}
|
||||
if (mui->ln_type_name_off)
|
||||
{
|
||||
info->dwTypeNameMainOffset = offsetof(FILEMUIINFO, abBuffer[off]);
|
||||
memcpy(info->abBuffer + off, ((BYTE *)mui) + mui->ln_type_name_off, mui->ln_type_name_size);
|
||||
off += mui->ln_type_name_size;
|
||||
}
|
||||
if (mui->mui_type_id_size && mui->mui_type_id_off)
|
||||
{
|
||||
info->dwTypeIDMUISize = mui->mui_type_id_size / sizeof(DWORD);
|
||||
info->dwTypeIDMUIOffset = offsetof(FILEMUIINFO, abBuffer[off]);
|
||||
memcpy(info->abBuffer + off, ((BYTE *)mui) + mui->mui_type_id_off, mui->mui_type_id_size);
|
||||
off += mui->mui_type_id_size;
|
||||
}
|
||||
if (mui->mui_type_name_off)
|
||||
{
|
||||
info->dwTypeNameMUIOffset = offsetof(FILEMUIINFO, abBuffer[off]);
|
||||
memcpy(info->abBuffer + off, ((BYTE *)mui) + mui->mui_type_name_off, mui->mui_type_name_size);
|
||||
off += mui->mui_type_name_size;
|
||||
}
|
||||
}
|
||||
else if(flags & MUI_QUERY_RESOURCE_TYPES)
|
||||
{
|
||||
if (mui->ln_type_id_size && mui->ln_type_id_off)
|
||||
{
|
||||
info->dwTypeIDMUISize = mui->ln_type_id_size / sizeof(DWORD);
|
||||
info->dwTypeIDMUIOffset = offsetof(FILEMUIINFO, abBuffer[off]);
|
||||
memcpy(info->abBuffer + off, ((BYTE *)mui) + mui->ln_type_id_off, mui->ln_type_id_size);
|
||||
off += mui->ln_type_id_size;
|
||||
}
|
||||
if (mui->ln_type_name_off)
|
||||
{
|
||||
info->dwTypeNameMUIOffset = offsetof(FILEMUIINFO, abBuffer[off]);
|
||||
memcpy(info->abBuffer + off, ((BYTE *)mui) + mui->ln_type_name_off, mui->ln_type_name_size);
|
||||
off += mui->ln_type_name_size;
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary( hmod );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -694,8 +694,9 @@ static void check_mft_set_input_type_required_(int line, IMFTransform *transform
|
|||
ok_(__FILE__, line)(!ref, "Release returned %lu\n", ref);
|
||||
}
|
||||
|
||||
#define check_mft_set_input_type(a, b) check_mft_set_input_type_(__LINE__, a, b, FALSE)
|
||||
static void check_mft_set_input_type_(int line, IMFTransform *transform, const struct attribute_desc *attributes, BOOL todo)
|
||||
#define check_mft_set_input_type(a, b, c) check_mft_set_input_type_(__LINE__, a, b, c, FALSE)
|
||||
static void check_mft_set_input_type_(int line, IMFTransform *transform, const struct attribute_desc *attributes,
|
||||
HRESULT expect_hr, BOOL todo)
|
||||
{
|
||||
IMFMediaType *media_type;
|
||||
HRESULT hr;
|
||||
|
@ -705,10 +706,10 @@ static void check_mft_set_input_type_(int line, IMFTransform *transform, const s
|
|||
init_media_type(media_type, attributes, -1);
|
||||
|
||||
hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
|
||||
ok_(__FILE__, line)(hr == S_OK, "SetInputType returned %#lx.\n", hr);
|
||||
ok_(__FILE__, line)(hr == expect_hr, "SetInputType returned %#lx.\n", hr);
|
||||
hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
|
||||
todo_wine_if(todo)
|
||||
ok_(__FILE__, line)(hr == S_OK, "SetInputType returned %#lx.\n", hr);
|
||||
ok_(__FILE__, line)(hr == expect_hr, "SetInputType returned %#lx.\n", hr);
|
||||
|
||||
IMFMediaType_Release(media_type);
|
||||
}
|
||||
|
@ -2154,7 +2155,7 @@ static void test_aac_encoder(void)
|
|||
check_mft_get_output_current_type(transform, expect_output_type_desc);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type(transform, expect_input_type_desc);
|
||||
|
||||
check_mft_get_input_stream_info(transform, S_OK, &input_info);
|
||||
|
@ -2412,7 +2413,7 @@ static void test_aac_decoder_subtype(const struct attribute_desc *input_type_des
|
|||
check_mft_get_output_current_type(transform, NULL);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type(transform, input_type_desc);
|
||||
|
||||
/* check new output media types */
|
||||
|
@ -2920,7 +2921,7 @@ static void test_wma_encoder(void)
|
|||
check_mft_get_output_current_type(transform, expect_output_type_desc);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type(transform, expect_input_type_desc);
|
||||
|
||||
check_mft_get_input_stream_info(transform, S_OK, &input_info);
|
||||
|
@ -3235,7 +3236,7 @@ static void test_wma_decoder(void)
|
|||
check_mft_get_output_current_type_(__LINE__, transform, NULL, TRUE, FALSE);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type_(__LINE__, transform, expect_input_type_desc, TRUE, FALSE);
|
||||
|
||||
check_mft_get_input_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL);
|
||||
|
@ -3809,6 +3810,32 @@ static void test_h264_encoder(void)
|
|||
{.subtype = &MFVideoFormat_H264},
|
||||
},
|
||||
};
|
||||
static const media_type_desc default_outputs[] =
|
||||
{
|
||||
{
|
||||
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
|
||||
ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_H264),
|
||||
},
|
||||
};
|
||||
static const media_type_desc default_inputs[] =
|
||||
{
|
||||
{
|
||||
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
|
||||
ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_IYUV),
|
||||
},
|
||||
{
|
||||
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
|
||||
ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YV12),
|
||||
},
|
||||
{
|
||||
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
|
||||
ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12),
|
||||
},
|
||||
{
|
||||
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
|
||||
ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2),
|
||||
},
|
||||
};
|
||||
static const struct attribute_desc expect_transform_attributes[] =
|
||||
{
|
||||
ATTR_UINT32(MFT_ENCODER_SUPPORTS_CONFIG_EVENT, 1),
|
||||
|
@ -3854,9 +3881,11 @@ static void test_h264_encoder(void)
|
|||
static const MFT_OUTPUT_STREAM_INFO expect_output_info = {.cbSize = 0x8000};
|
||||
MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_H264};
|
||||
MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_NV12};
|
||||
IMFMediaType *media_type;
|
||||
IMFTransform *transform;
|
||||
HRESULT hr;
|
||||
ULONG ret;
|
||||
DWORD i;
|
||||
|
||||
hr = CoInitialize(NULL);
|
||||
ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr);
|
||||
|
@ -3874,7 +3903,10 @@ static void test_h264_encoder(void)
|
|||
check_mft_get_info(class_id, &expect_mft_info);
|
||||
|
||||
hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "CoCreateInstance returned %#lx.\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto failed;
|
||||
|
||||
check_interface(transform, &IID_IMFTransform, TRUE);
|
||||
check_interface(transform, &IID_IMediaObject, FALSE);
|
||||
|
@ -3885,17 +3917,49 @@ static void test_h264_encoder(void)
|
|||
check_mft_get_input_stream_info(transform, S_OK, NULL);
|
||||
check_mft_get_output_stream_info(transform, S_OK, NULL);
|
||||
|
||||
/* No input type is available before an output type is set. */
|
||||
hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type);
|
||||
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetInputAvailableType returned %#lx\n", hr);
|
||||
check_mft_set_input_type(transform, input_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET);
|
||||
check_mft_get_input_current_type(transform, NULL);
|
||||
|
||||
/* Check available output types. */
|
||||
i = -1;
|
||||
while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &media_type)))
|
||||
{
|
||||
winetest_push_context("out %lu", i);
|
||||
ok(hr == S_OK, "GetOutputAvailableType returned %#lx.\n", hr);
|
||||
check_media_type(media_type, default_outputs[i], -1);
|
||||
ret = IMFMediaType_Release(media_type);
|
||||
ok(ret == 0, "Release returned %lu\n", ret);
|
||||
winetest_pop_context();
|
||||
}
|
||||
ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx.\n", hr);
|
||||
ok(i == ARRAY_SIZE(default_outputs), "%lu output media types.\n", i);
|
||||
|
||||
check_mft_set_output_type_required(transform, output_type_desc);
|
||||
check_mft_set_output_type(transform, output_type_desc, S_OK);
|
||||
check_mft_get_output_current_type(transform, expect_output_type_desc);
|
||||
check_mft_get_output_stream_info(transform, S_OK, &expect_output_info);
|
||||
|
||||
/* Input types can now be enumerated. */
|
||||
i = -1;
|
||||
while (SUCCEEDED(hr = IMFTransform_GetInputAvailableType(transform, 0, ++i, &media_type)))
|
||||
{
|
||||
winetest_push_context("out %lu", i);
|
||||
ok(hr == S_OK, "IMFTransform_GetInputAvailableType returned %#lx\n", hr);
|
||||
check_media_type(media_type, default_inputs[i], -1);
|
||||
ret = IMFMediaType_Release(media_type);
|
||||
ok(ret == 0, "Release returned %lu\n", ret);
|
||||
winetest_pop_context();
|
||||
}
|
||||
ok(hr == MF_E_NO_MORE_TYPES, "IMFTransform_GetInputAvailableType returned %#lx\n", hr);
|
||||
ok(i == ARRAY_SIZE(default_inputs), "%lu input media types\n", i);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type(transform, expect_input_type_desc);
|
||||
|
||||
check_mft_get_output_current_type(transform, expect_output_type_desc);
|
||||
|
||||
check_mft_get_input_stream_info(transform, S_OK, NULL);
|
||||
check_mft_get_output_stream_info(transform, S_OK, &expect_output_info);
|
||||
|
||||
ret = IMFTransform_Release(transform);
|
||||
ok(ret == 0, "Release returned %lu\n", ret);
|
||||
|
@ -4294,7 +4358,7 @@ static void test_h264_decoder(void)
|
|||
ok(i == 2 || broken(i == 1) /* Win7 */, "%lu input media types\n", i);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type_(__LINE__, transform, expect_input_type_desc, FALSE, TRUE);
|
||||
|
||||
check_mft_get_input_stream_info(transform, S_OK, &input_info);
|
||||
|
@ -4971,7 +5035,7 @@ static void test_audio_convert(void)
|
|||
check_mft_get_output_current_type(transform, NULL);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type_(__LINE__, transform, expect_input_type_desc, FALSE, TRUE);
|
||||
|
||||
check_mft_get_input_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL);
|
||||
|
@ -5446,7 +5510,7 @@ static void test_wmv_encoder(void)
|
|||
check_mft_get_output_current_type(transform, NULL);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type_(__LINE__, transform, expect_input_type_desc, FALSE, TRUE);
|
||||
|
||||
check_mft_set_output_type_required(transform, output_type_desc);
|
||||
|
@ -6034,7 +6098,7 @@ static void test_wmv_decoder(void)
|
|||
check_mft_get_output_current_type(transform, NULL);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type_(__LINE__, transform, expect_input_type_desc, FALSE, TRUE);
|
||||
|
||||
i = -1;
|
||||
|
@ -7159,7 +7223,7 @@ static void test_color_convert(void)
|
|||
ok(i == 20, "%lu input media types\n", i);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type_(__LINE__, transform, expect_input_type_desc, FALSE, TRUE);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(color_conversion_tests); i++)
|
||||
|
@ -7939,7 +8003,7 @@ static void test_video_processor(void)
|
|||
ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr);
|
||||
|
||||
/* MFVideoFormat_ABGR32 isn't supported by the video processor in non-D3D mode */
|
||||
check_mft_set_input_type(transform, nv12_default_stride);
|
||||
check_mft_set_input_type(transform, nv12_default_stride, S_OK);
|
||||
|
||||
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
|
||||
ok(hr == S_OK, "got %#lx\n", hr);
|
||||
|
@ -7961,7 +8025,7 @@ static void test_video_processor(void)
|
|||
winetest_push_context("transform #%lu", i);
|
||||
|
||||
check_mft_set_input_type_required(transform, test->input_type_desc);
|
||||
check_mft_set_input_type(transform, test->input_type_desc);
|
||||
check_mft_set_input_type(transform, test->input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type(transform, test->input_type_desc);
|
||||
|
||||
if (i >= 15)
|
||||
|
@ -8111,13 +8175,13 @@ skip_test:
|
|||
&IID_IMFTransform, (void **)&transform);
|
||||
ok(hr == S_OK, "got hr %#lx\n", hr);
|
||||
|
||||
check_mft_set_input_type(transform, nv12_no_aperture);
|
||||
check_mft_set_input_type(transform, nv12_no_aperture, S_OK);
|
||||
check_mft_get_input_current_type(transform, nv12_no_aperture);
|
||||
|
||||
check_mft_set_output_type(transform, rgb32_no_aperture, S_OK);
|
||||
check_mft_get_output_current_type(transform, rgb32_no_aperture);
|
||||
|
||||
check_mft_set_input_type_(__LINE__, transform, nv12_with_aperture, TRUE);
|
||||
check_mft_set_input_type_(__LINE__, transform, nv12_with_aperture, S_OK, TRUE);
|
||||
check_mft_get_input_current_type_(__LINE__, transform, nv12_with_aperture, TRUE, FALSE);
|
||||
|
||||
/* output type is the same as before */
|
||||
|
@ -8376,7 +8440,7 @@ static void test_mp3_decoder(void)
|
|||
check_mft_get_output_current_type(transform, NULL);
|
||||
|
||||
check_mft_set_input_type_required(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc);
|
||||
check_mft_set_input_type(transform, input_type_desc, S_OK);
|
||||
check_mft_get_input_current_type(transform, expect_input_type_desc);
|
||||
|
||||
check_mft_get_input_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL);
|
||||
|
@ -9427,7 +9491,7 @@ static void test_video_processor_with_dxgi_manager(void)
|
|||
|
||||
/* check RGB32 output aperture cropping with D3D buffers */
|
||||
|
||||
check_mft_set_input_type(transform, nv12_with_aperture);
|
||||
check_mft_set_input_type(transform, nv12_with_aperture, S_OK);
|
||||
check_mft_set_output_type_(__LINE__, transform, rgb32_no_aperture, S_OK, TRUE);
|
||||
|
||||
load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len);
|
||||
|
@ -9495,7 +9559,7 @@ static void test_video_processor_with_dxgi_manager(void)
|
|||
skip_rgb32:
|
||||
/* check ABGR32 output with D3D buffers */
|
||||
|
||||
check_mft_set_input_type(transform, nv12_with_aperture);
|
||||
check_mft_set_input_type(transform, nv12_with_aperture, S_OK);
|
||||
check_mft_set_output_type_(__LINE__, transform, abgr32_no_aperture, S_OK, TRUE);
|
||||
|
||||
load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len);
|
||||
|
|
|
@ -117,7 +117,7 @@ static HRESULT get_periods(struct audio_client *client,
|
|||
return params.result;
|
||||
}
|
||||
|
||||
static HRESULT adjust_timing(struct audio_client *client,
|
||||
static HRESULT adjust_timing(struct audio_client *client, const BOOLEAN force_def_period,
|
||||
REFERENCE_TIME *duration, REFERENCE_TIME *period,
|
||||
const AUDCLNT_SHAREMODE mode, const DWORD flags,
|
||||
const WAVEFORMATEX *fmt)
|
||||
|
@ -133,28 +133,31 @@ static HRESULT adjust_timing(struct audio_client *client,
|
|||
TRACE("Device periods: %lu default and %lu minimum\n", (ULONG)def_period, (ULONG)min_period);
|
||||
|
||||
if (mode == AUDCLNT_SHAREMODE_SHARED) {
|
||||
*period = def_period;
|
||||
if (*period == 0 || force_def_period)
|
||||
*period = def_period;
|
||||
else if (*period < min_period)
|
||||
return AUDCLNT_E_INVALID_DEVICE_PERIOD;
|
||||
if (*duration < 3 * *period)
|
||||
*duration = 3 * *period;
|
||||
} else {
|
||||
const WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE *)fmt;
|
||||
if (fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
|
||||
(fmtex->dwChannelMask == 0 || fmtex->dwChannelMask & SPEAKER_RESERVED))
|
||||
hr = AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||
else {
|
||||
if (*period == 0)
|
||||
*period = def_period;
|
||||
if (*period < min_period || *period > 5000000)
|
||||
hr = AUDCLNT_E_INVALID_DEVICE_PERIOD;
|
||||
return AUDCLNT_E_INVALID_DEVICE_PERIOD;
|
||||
else if (*duration > 20000000) /* The smaller the period, the lower this limit. */
|
||||
hr = AUDCLNT_E_BUFFER_SIZE_ERROR;
|
||||
return AUDCLNT_E_BUFFER_SIZE_ERROR;
|
||||
else if (flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) {
|
||||
if (*duration != *period)
|
||||
hr = AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL;
|
||||
return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL;
|
||||
|
||||
FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
|
||||
|
||||
hr = AUDCLNT_E_DEVICE_IN_USE;
|
||||
return AUDCLNT_E_DEVICE_IN_USE;
|
||||
} else if (*duration < 8 * *period)
|
||||
*duration = 8 * *period; /* May grow above 2s. */
|
||||
}
|
||||
|
@ -355,6 +358,100 @@ skip:
|
|||
return wcsdup(name);
|
||||
}
|
||||
|
||||
static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_period,
|
||||
const AUDCLNT_SHAREMODE mode, const DWORD flags,
|
||||
REFERENCE_TIME duration, REFERENCE_TIME period,
|
||||
const WAVEFORMATEX *fmt, const GUID *sessionguid)
|
||||
{
|
||||
struct create_stream_params params;
|
||||
UINT32 i, channel_count;
|
||||
stream_handle stream;
|
||||
WCHAR *name;
|
||||
|
||||
if (!fmt)
|
||||
return E_POINTER;
|
||||
|
||||
dump_fmt(fmt);
|
||||
|
||||
if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS |
|
||||
AUDCLNT_STREAMFLAGS_LOOPBACK |
|
||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK |
|
||||
AUDCLNT_STREAMFLAGS_NOPERSIST |
|
||||
AUDCLNT_STREAMFLAGS_RATEADJUST |
|
||||
AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED |
|
||||
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE |
|
||||
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED |
|
||||
AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY |
|
||||
AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM)) {
|
||||
FIXME("Unknown flags: %08lx\n", flags);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (FAILED(params.result = adjust_timing(client, force_def_period, &duration, &period, mode, flags, fmt)))
|
||||
return params.result;
|
||||
|
||||
sessions_lock();
|
||||
|
||||
if (client->stream) {
|
||||
sessions_unlock();
|
||||
return AUDCLNT_E_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
if (FAILED(params.result = main_loop_start())) {
|
||||
sessions_unlock();
|
||||
return params.result;
|
||||
}
|
||||
|
||||
params.name = name = get_application_name();
|
||||
params.device = client->device_name;
|
||||
params.flow = client->dataflow;
|
||||
params.share = mode;
|
||||
params.flags = flags;
|
||||
params.duration = duration;
|
||||
params.period = period;
|
||||
params.fmt = fmt;
|
||||
params.channel_count = &channel_count;
|
||||
params.stream = &stream;
|
||||
|
||||
wine_unix_call(create_stream, ¶ms);
|
||||
|
||||
free(name);
|
||||
|
||||
if (FAILED(params.result)) {
|
||||
sessions_unlock();
|
||||
return params.result;
|
||||
}
|
||||
|
||||
if (!(client->vols = malloc(channel_count * sizeof(*client->vols)))) {
|
||||
params.result = E_OUTOFMEMORY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < channel_count; i++)
|
||||
client->vols[i] = 1.f;
|
||||
|
||||
params.result = get_audio_session(sessionguid, client->parent, channel_count, &client->session);
|
||||
|
||||
exit:
|
||||
if (FAILED(params.result)) {
|
||||
stream_release(stream, NULL);
|
||||
free(client->vols);
|
||||
client->vols = NULL;
|
||||
} else {
|
||||
list_add_tail(&client->session->clients, &client->entry);
|
||||
client->stream = stream;
|
||||
client->channel_count = channel_count;
|
||||
set_stream_volumes(client);
|
||||
}
|
||||
|
||||
sessions_unlock();
|
||||
|
||||
return params.result;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI capture_QueryInterface(IAudioCaptureClient *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
struct audio_client *This = impl_from_IAudioCaptureClient(iface);
|
||||
|
@ -537,97 +634,12 @@ static HRESULT WINAPI client_Initialize(IAudioClient3 *iface, AUDCLNT_SHAREMODE
|
|||
const WAVEFORMATEX *fmt, const GUID *sessionguid)
|
||||
{
|
||||
struct audio_client *This = impl_from_IAudioClient3(iface);
|
||||
struct create_stream_params params;
|
||||
UINT32 i, channel_count;
|
||||
stream_handle stream;
|
||||
WCHAR *name;
|
||||
|
||||
TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, wine_dbgstr_longlong(duration),
|
||||
wine_dbgstr_longlong(period), fmt,
|
||||
debugstr_guid(sessionguid));
|
||||
|
||||
if (!fmt)
|
||||
return E_POINTER;
|
||||
|
||||
dump_fmt(fmt);
|
||||
|
||||
if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS |
|
||||
AUDCLNT_STREAMFLAGS_LOOPBACK |
|
||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK |
|
||||
AUDCLNT_STREAMFLAGS_NOPERSIST |
|
||||
AUDCLNT_STREAMFLAGS_RATEADJUST |
|
||||
AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED |
|
||||
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE |
|
||||
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED |
|
||||
AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY |
|
||||
AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM)) {
|
||||
FIXME("Unknown flags: %08lx\n", flags);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (FAILED(params.result = adjust_timing(This, &duration, &period, mode, flags, fmt)))
|
||||
return params.result;
|
||||
|
||||
sessions_lock();
|
||||
|
||||
if (This->stream) {
|
||||
sessions_unlock();
|
||||
return AUDCLNT_E_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
if (FAILED(params.result = main_loop_start())) {
|
||||
sessions_unlock();
|
||||
return params.result;
|
||||
}
|
||||
|
||||
params.name = name = get_application_name();
|
||||
params.device = This->device_name;
|
||||
params.flow = This->dataflow;
|
||||
params.share = mode;
|
||||
params.flags = flags;
|
||||
params.duration = duration;
|
||||
params.period = period;
|
||||
params.fmt = fmt;
|
||||
params.channel_count = &channel_count;
|
||||
params.stream = &stream;
|
||||
|
||||
wine_unix_call(create_stream, ¶ms);
|
||||
|
||||
free(name);
|
||||
|
||||
if (FAILED(params.result)) {
|
||||
sessions_unlock();
|
||||
return params.result;
|
||||
}
|
||||
|
||||
if (!(This->vols = malloc(channel_count * sizeof(*This->vols)))) {
|
||||
params.result = E_OUTOFMEMORY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < channel_count; i++)
|
||||
This->vols[i] = 1.f;
|
||||
|
||||
params.result = get_audio_session(sessionguid, This->parent, channel_count, &This->session);
|
||||
|
||||
exit:
|
||||
if (FAILED(params.result)) {
|
||||
stream_release(stream, NULL);
|
||||
free(This->vols);
|
||||
This->vols = NULL;
|
||||
} else {
|
||||
list_add_tail(&This->session->clients, &This->entry);
|
||||
This->stream = stream;
|
||||
This->channel_count = channel_count;
|
||||
set_stream_volumes(This);
|
||||
}
|
||||
|
||||
sessions_unlock();
|
||||
|
||||
return params.result;
|
||||
return stream_init(This, TRUE, mode, flags, duration, period, fmt, sessionguid);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI client_GetBufferSize(IAudioClient3 *iface, UINT32 *out)
|
||||
|
@ -990,17 +1002,23 @@ static HRESULT WINAPI client_GetSharedModeEnginePeriod(IAudioClient3 *iface,
|
|||
UINT32 *max_period_frames)
|
||||
{
|
||||
struct audio_client *This = impl_from_IAudioClient3(iface);
|
||||
FIXME("(%p)->(%p, %p, %p, %p, %p) - partial stub\n",
|
||||
REFERENCE_TIME def_period, min_period;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%p, %p, %p, %p, %p)\n",
|
||||
This, format, default_period_frames,
|
||||
unit_period_frames, min_period_frames,
|
||||
max_period_frames);
|
||||
|
||||
*default_period_frames =
|
||||
*min_period_frames =
|
||||
*max_period_frames =
|
||||
format->nSamplesPerSec / 100; /* ~10ms */
|
||||
*unit_period_frames = 1;
|
||||
return S_OK;
|
||||
if (FAILED(hr = get_periods(This, &def_period, &min_period)))
|
||||
return hr;
|
||||
|
||||
*default_period_frames = def_period * format->nSamplesPerSec / (REFERENCE_TIME)10000000;
|
||||
*min_period_frames = min_period * format->nSamplesPerSec / (REFERENCE_TIME)10000000;
|
||||
*max_period_frames = *default_period_frames;
|
||||
*unit_period_frames = 1;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI client_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface,
|
||||
|
@ -1008,8 +1026,18 @@ static HRESULT WINAPI client_GetCurrentSharedModeEnginePeriod(IAudioClient3 *ifa
|
|||
UINT32 *cur_period_frames)
|
||||
{
|
||||
struct audio_client *This = impl_from_IAudioClient3(iface);
|
||||
FIXME("(%p)->(%p, %p) - stub\n", This, cur_format, cur_period_frames);
|
||||
return E_NOTIMPL;
|
||||
UINT32 dummy;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames);
|
||||
|
||||
if (!cur_format || !cur_period_frames)
|
||||
return E_POINTER;
|
||||
|
||||
if (FAILED(hr = client_GetMixFormat(iface, cur_format)))
|
||||
return hr;
|
||||
|
||||
return client_GetSharedModeEnginePeriod(iface, *cur_format, cur_period_frames, &dummy, &dummy, &dummy);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI client_InitializeSharedAudioStream(IAudioClient3 *iface, DWORD flags,
|
||||
|
@ -1018,14 +1046,16 @@ static HRESULT WINAPI client_InitializeSharedAudioStream(IAudioClient3 *iface, D
|
|||
const GUID *session_guid)
|
||||
{
|
||||
struct audio_client *This = impl_from_IAudioClient3(iface);
|
||||
REFERENCE_TIME duration;
|
||||
FIXME("(%p)->(0x%lx, %u, %p, %s) - partial stub\n", This, flags, period_frames, format, debugstr_guid(session_guid));
|
||||
REFERENCE_TIME period;
|
||||
|
||||
TRACE("(%p)->(0x%lx, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid));
|
||||
|
||||
if (!format)
|
||||
return E_POINTER;
|
||||
|
||||
duration = period_frames * (REFERENCE_TIME)10000000 / format->nSamplesPerSec;
|
||||
return client_Initialize(iface, AUDCLNT_SHAREMODE_SHARED, flags, duration, 0, format, session_guid);
|
||||
period = period_frames * (REFERENCE_TIME)10000000 / format->nSamplesPerSec;
|
||||
|
||||
return stream_init(This, FALSE, AUDCLNT_SHAREMODE_SHARED, flags, 0, period, format, session_guid);
|
||||
}
|
||||
|
||||
const IAudioClient3Vtbl AudioClient3_Vtbl =
|
||||
|
|
|
@ -50,6 +50,8 @@ struct recordset
|
|||
CursorTypeEnum cursor_type;
|
||||
IRowset *row_set;
|
||||
EditModeEnum editmode;
|
||||
LONG cache_size;
|
||||
ADO_LONGPTR max_records;
|
||||
VARIANT filter;
|
||||
|
||||
DBTYPE *columntypes;
|
||||
|
@ -1449,14 +1451,20 @@ static HRESULT WINAPI recordset_put_Bookmark( _Recordset *iface, VARIANT bookmar
|
|||
|
||||
static HRESULT WINAPI recordset_get_CacheSize( _Recordset *iface, LONG *size )
|
||||
{
|
||||
FIXME( "%p, %p\n", iface, size );
|
||||
return E_NOTIMPL;
|
||||
struct recordset *recordset = impl_from_Recordset( iface );
|
||||
TRACE( "%p, %p\n", iface, size );
|
||||
|
||||
*size = recordset->cache_size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI recordset_put_CacheSize( _Recordset *iface, LONG size )
|
||||
{
|
||||
FIXME( "%p, %ld\n", iface, size );
|
||||
return E_NOTIMPL;
|
||||
struct recordset *recordset = impl_from_Recordset( iface );
|
||||
TRACE( "%p, %ld\n", iface, size );
|
||||
|
||||
recordset->cache_size = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI recordset_get_CursorType( _Recordset *iface, CursorTypeEnum *cursor_type )
|
||||
|
@ -1525,14 +1533,20 @@ static HRESULT WINAPI recordset_put_LockType( _Recordset *iface, LockTypeEnum lo
|
|||
|
||||
static HRESULT WINAPI recordset_get_MaxRecords( _Recordset *iface, ADO_LONGPTR *max_records )
|
||||
{
|
||||
FIXME( "%p, %p\n", iface, max_records );
|
||||
return E_NOTIMPL;
|
||||
struct recordset *recordset = impl_from_Recordset( iface );
|
||||
TRACE( "%p, %p\n", iface, max_records );
|
||||
|
||||
*max_records = recordset->max_records;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI recordset_put_MaxRecords( _Recordset *iface, ADO_LONGPTR max_records )
|
||||
{
|
||||
FIXME( "%p, %Id\n", iface, max_records );
|
||||
return E_NOTIMPL;
|
||||
struct recordset *recordset = impl_from_Recordset( iface );
|
||||
TRACE( "%p, %Id\n", iface, max_records );
|
||||
|
||||
recordset->max_records = max_records;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI recordset_get_RecordCount( _Recordset *iface, ADO_LONGPTR *count )
|
||||
|
@ -2792,6 +2806,8 @@ HRESULT Recordset_create( void **obj )
|
|||
recordset->cursor_type = adOpenForwardOnly;
|
||||
recordset->row_set = NULL;
|
||||
recordset->editmode = adEditNone;
|
||||
recordset->cache_size = 1;
|
||||
recordset->max_records = 0;
|
||||
VariantInit( &recordset->filter );
|
||||
recordset->columntypes = NULL;
|
||||
recordset->haccessors = NULL;
|
||||
|
|
|
@ -53,7 +53,7 @@ static void test_Recordset(void)
|
|||
Properties *props;
|
||||
Property *prop;
|
||||
LONG count, state;
|
||||
ADO_LONGPTR rec_count;
|
||||
ADO_LONGPTR rec_count, max_records;
|
||||
VARIANT missing, val, index;
|
||||
CursorLocationEnum location;
|
||||
CursorTypeEnum cursor;
|
||||
|
@ -61,6 +61,7 @@ static void test_Recordset(void)
|
|||
HRESULT hr;
|
||||
VARIANT bookmark, filter, active;
|
||||
EditModeEnum editmode;
|
||||
LONG cache_size;
|
||||
|
||||
hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
|
@ -111,6 +112,36 @@ static void test_Recordset(void)
|
|||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
ok( cursor == adOpenForwardOnly, "got %d\n", cursor );
|
||||
|
||||
cache_size = 0;
|
||||
hr = _Recordset_get_CacheSize( recordset, &cache_size );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
ok( cache_size == 1, "got %ld\n", cache_size );
|
||||
|
||||
hr = _Recordset_put_CacheSize( recordset, 5 );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
|
||||
hr = _Recordset_get_CacheSize( recordset, &cache_size );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
ok( cache_size == 5, "got %ld\n", cache_size );
|
||||
|
||||
hr = _Recordset_put_CacheSize( recordset, 1 );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
|
||||
max_records = 0;
|
||||
hr = _Recordset_get_MaxRecords( recordset, &max_records );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
ok( max_records == 0, "got %Id\n", max_records );
|
||||
|
||||
hr = _Recordset_put_MaxRecords( recordset, 5 );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
|
||||
hr = _Recordset_get_MaxRecords( recordset, &max_records );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
ok( max_records == 5, "got %Id\n", max_records );
|
||||
|
||||
hr = _Recordset_put_MaxRecords( recordset, 0 );
|
||||
ok( hr == S_OK, "got %08lx\n", hr );
|
||||
|
||||
editmode = -1;
|
||||
hr = _Recordset_get_EditMode( recordset, &editmode );
|
||||
ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
|
||||
|
|
|
@ -787,7 +787,7 @@ static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags,
|
|||
return hres;
|
||||
}
|
||||
|
||||
hres = IDispatchEx_QueryInterface(&This->IDispatchEx_iface, tid_ids[func->tid], (void**)&unk);
|
||||
hres = IWineJSDispatchHost_QueryInterface(&This->IWineJSDispatchHost_iface, tid_ids[func->tid], (void**)&unk);
|
||||
if(FAILED(hres)) {
|
||||
ERR("Could not get iface %s: %08lx\n", debugstr_mshtml_guid(tid_ids[func->tid]), hres);
|
||||
return E_FAIL;
|
||||
|
@ -799,6 +799,138 @@ static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags,
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT get_disp_prop(IDispatchEx *dispex, const WCHAR *name, LCID lcid, VARIANT *res,
|
||||
EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
DISPPARAMS dp = { 0 };
|
||||
DISPID dispid;
|
||||
HRESULT hres;
|
||||
BSTR bstr;
|
||||
|
||||
if(!(bstr = SysAllocString(name)))
|
||||
return E_OUTOFMEMORY;
|
||||
hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &dispid);
|
||||
SysFreeString(bstr);
|
||||
if(SUCCEEDED(hres))
|
||||
hres = IDispatchEx_InvokeEx(dispex, dispid, lcid, DISPATCH_PROPERTYGET, &dp, res, ei, caller);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT function_apply(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
IWineJSDispatchHost *this_iface;
|
||||
DISPPARAMS params = { 0 };
|
||||
IDispatchEx *array = NULL;
|
||||
UINT argc = 0;
|
||||
VARIANT *arg;
|
||||
HRESULT hres;
|
||||
|
||||
arg = dp->rgvarg + dp->cArgs - 1;
|
||||
if(dp->cArgs < 1 || V_VT(arg) != VT_DISPATCH || !V_DISPATCH(arg))
|
||||
return CTL_E_ILLEGALFUNCTIONCALL;
|
||||
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(arg), &IID_IWineJSDispatchHost, (void**)&this_iface);
|
||||
if(FAILED(hres))
|
||||
return CTL_E_ILLEGALFUNCTIONCALL;
|
||||
|
||||
if(dp->cArgs >= 2) {
|
||||
VARIANT length;
|
||||
|
||||
arg--;
|
||||
if(V_VT(arg) != VT_DISPATCH) {
|
||||
hres = CTL_E_ILLEGALFUNCTIONCALL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* FIXME: Native checks if it's an acual JS array. */
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(arg), &IID_IDispatchEx, (void**)&array);
|
||||
if(FAILED(hres))
|
||||
goto fail;
|
||||
|
||||
V_VT(&length) = VT_EMPTY;
|
||||
hres = get_disp_prop(array, L"length", lcid, &length, ei, caller);
|
||||
if(FAILED(hres)) {
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = CTL_E_ILLEGALFUNCTIONCALL;
|
||||
goto fail;
|
||||
}
|
||||
if(V_VT(&length) != VT_I4) {
|
||||
VARIANT tmp = length;
|
||||
hres = change_type(&length, &tmp, VT_I4, caller);
|
||||
if(FAILED(hres)) {
|
||||
hres = CTL_E_ILLEGALFUNCTIONCALL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if(V_I4(&length) < 0) {
|
||||
hres = CTL_E_ILLEGALFUNCTIONCALL;
|
||||
goto fail;
|
||||
}
|
||||
params.cArgs = V_I4(&length);
|
||||
|
||||
/* alloc new params */
|
||||
if(params.cArgs) {
|
||||
if(!(params.rgvarg = malloc(params.cArgs * sizeof(VARIANTARG)))) {
|
||||
hres = E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
for(argc = 0; argc < params.cArgs; argc++) {
|
||||
WCHAR buf[12];
|
||||
|
||||
arg = params.rgvarg + params.cArgs - argc - 1;
|
||||
swprintf(buf, ARRAY_SIZE(buf), L"%u", argc);
|
||||
hres = get_disp_prop(array, buf, lcid, arg, ei, caller);
|
||||
if(FAILED(hres)) {
|
||||
if(hres == DISP_E_UNKNOWNNAME) {
|
||||
V_VT(arg) = VT_EMPTY;
|
||||
continue;
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, ¶ms, res, ei, caller);
|
||||
|
||||
fail:
|
||||
while(argc--)
|
||||
VariantClear(¶ms.rgvarg[params.cArgs - argc - 1]);
|
||||
free(params.rgvarg);
|
||||
if(array)
|
||||
IDispatchEx_Release(array);
|
||||
IWineJSDispatchHost_Release(this_iface);
|
||||
return hres == E_UNEXPECTED ? CTL_E_ILLEGALFUNCTIONCALL : hres;
|
||||
}
|
||||
|
||||
static HRESULT function_call(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
DISPPARAMS params = { dp->rgvarg, NULL, dp->cArgs - 1, 0 };
|
||||
IWineJSDispatchHost *this_iface;
|
||||
VARIANT *arg;
|
||||
HRESULT hres;
|
||||
|
||||
arg = dp->rgvarg + dp->cArgs - 1;
|
||||
if(dp->cArgs < 1 || V_VT(arg) != VT_DISPATCH || !V_DISPATCH(arg))
|
||||
return CTL_E_ILLEGALFUNCTIONCALL;
|
||||
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(arg), &IID_IWineJSDispatchHost, (void**)&this_iface);
|
||||
if(FAILED(hres))
|
||||
return CTL_E_ILLEGALFUNCTIONCALL;
|
||||
|
||||
hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, ¶ms, res, ei, caller);
|
||||
IWineJSDispatchHost_Release(this_iface);
|
||||
return (hres == E_UNEXPECTED) ? CTL_E_ILLEGALFUNCTIONCALL : hres;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const WCHAR *name;
|
||||
HRESULT (*invoke)(func_disp_t*,DISPPARAMS*,LCID,VARIANT*,EXCEPINFO*,IServiceProvider*);
|
||||
} function_props[] = {
|
||||
{ L"apply", function_apply },
|
||||
{ L"call", function_call }
|
||||
};
|
||||
|
||||
static inline func_disp_t *impl_from_DispatchEx(DispatchEx *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, func_disp_t, dispex);
|
||||
|
@ -866,9 +998,58 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT function_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(function_props); i++) {
|
||||
if((flags & fdexNameCaseInsensitive) ? wcsicmp(name, function_props[i].name) : wcscmp(name, function_props[i].name))
|
||||
continue;
|
||||
*dispid = MSHTML_DISPID_CUSTOM_MIN + i;
|
||||
return S_OK;
|
||||
}
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
||||
static HRESULT function_get_name(DispatchEx *dispex, DISPID id, BSTR *name)
|
||||
{
|
||||
DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN;
|
||||
|
||||
if(idx >= ARRAY_SIZE(function_props))
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
return (*name = SysAllocString(function_props[idx].name)) ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
static HRESULT function_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
|
||||
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
func_disp_t *This = impl_from_DispatchEx(dispex);
|
||||
DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN;
|
||||
|
||||
if(idx >= ARRAY_SIZE(function_props))
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
if(!res)
|
||||
return E_INVALIDARG;
|
||||
/* fall through */
|
||||
case DISPATCH_METHOD:
|
||||
return function_props[idx].invoke(This, params, lcid, res, ei, caller);
|
||||
default:
|
||||
return MSHTML_E_INVALID_PROPERTY;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const dispex_static_data_vtbl_t function_dispex_vtbl = {
|
||||
.destructor = function_destructor,
|
||||
.value = function_value,
|
||||
.get_dispid = function_get_dispid,
|
||||
.get_name = function_get_name,
|
||||
.invoke = function_invoke
|
||||
};
|
||||
|
||||
static const tid_t function_iface_tids[] = {0};
|
||||
|
@ -916,7 +1097,7 @@ static HRESULT invoke_disp_value(DispatchEx *This, IDispatch *func_disp, LCID lc
|
|||
memcpy(new_dp.rgvarg+1, dp->rgvarg, dp->cArgs*sizeof(VARIANTARG));
|
||||
|
||||
V_VT(new_dp.rgvarg) = VT_DISPATCH;
|
||||
V_DISPATCH(new_dp.rgvarg) = (IDispatch*)&This->IDispatchEx_iface;
|
||||
V_DISPATCH(new_dp.rgvarg) = (IDispatch*)&This->IWineJSDispatchHost_iface;
|
||||
|
||||
hres = IDispatch_QueryInterface(func_disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
TRACE(">>>\n");
|
||||
|
@ -957,9 +1138,9 @@ static HRESULT get_func_obj_entry(DispatchEx *This, func_info_t *func, func_obj_
|
|||
if(!entry->func_obj)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
IDispatchEx_AddRef(&entry->func_obj->dispex.IDispatchEx_iface);
|
||||
IWineJSDispatchHost_AddRef(&entry->func_obj->dispex.IWineJSDispatchHost_iface);
|
||||
V_VT(&entry->val) = VT_DISPATCH;
|
||||
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface;
|
||||
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
|
||||
}
|
||||
|
||||
*ret = entry;
|
||||
|
@ -1082,7 +1263,7 @@ static HRESULT builtin_propget(DispatchEx *This, func_info_t *func, DISPPARAMS *
|
|||
|
||||
assert(func->get_vtbl_off);
|
||||
|
||||
hres = IDispatchEx_QueryInterface(&This->IDispatchEx_iface, tid_ids[func->tid], (void**)&iface);
|
||||
hres = IWineJSDispatchHost_QueryInterface(&This->IWineJSDispatchHost_iface, tid_ids[func->tid], (void**)&iface);
|
||||
if(SUCCEEDED(hres)) {
|
||||
switch(func->prop_vt) {
|
||||
#define CASE_VT(vt,type,access) \
|
||||
|
@ -1139,7 +1320,7 @@ static HRESULT builtin_propput(DispatchEx *This, func_info_t *func, DISPPARAMS *
|
|||
v = &tmpv;
|
||||
}
|
||||
|
||||
hres = IDispatchEx_QueryInterface(&This->IDispatchEx_iface, tid_ids[func->tid], (void**)&iface);
|
||||
hres = IWineJSDispatchHost_QueryInterface(&This->IWineJSDispatchHost_iface, tid_ids[func->tid], (void**)&iface);
|
||||
if(SUCCEEDED(hres)) {
|
||||
switch(func->prop_vt) {
|
||||
#define CASE_VT(vt,type,access) \
|
||||
|
@ -1161,8 +1342,8 @@ static HRESULT builtin_propput(DispatchEx *This, func_info_t *func, DISPPARAMS *
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp,
|
||||
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||
static HRESULT call_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp,
|
||||
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
VARIANT arg_buf[MAX_ARGS], *arg_ptrs[MAX_ARGS], *arg, retv, ret_ref, vhres;
|
||||
unsigned i, nconv = 0;
|
||||
|
@ -1183,7 +1364,7 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
hres = IDispatchEx_QueryInterface(&This->IDispatchEx_iface, tid_ids[func->tid], (void**)&iface);
|
||||
hres = IWineJSDispatchHost_QueryInterface(&This->IWineJSDispatchHost_iface, tid_ids[func->tid], (void**)&iface);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -1268,7 +1449,7 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP
|
|||
return V_ERROR(&vhres);
|
||||
}
|
||||
|
||||
static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res,
|
||||
static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res,
|
||||
EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
@ -1288,7 +1469,7 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if((IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface != V_DISPATCH(&entry->val)) {
|
||||
if((IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface != V_DISPATCH(&entry->val)) {
|
||||
if(!V_DISPATCH(&entry->val)) {
|
||||
FIXME("Calling null\n");
|
||||
return E_FAIL;
|
||||
|
@ -1299,7 +1480,7 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
|
|||
}
|
||||
}
|
||||
|
||||
hres = invoke_builtin_function(This, func, dp, res, ei, caller);
|
||||
hres = call_builtin_function(This, func, dp, res, ei, caller);
|
||||
break;
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
func_obj_entry_t *entry;
|
||||
|
@ -1365,7 +1546,7 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD
|
|||
return hres;
|
||||
|
||||
if(func->func_disp_idx >= 0)
|
||||
return function_invoke(This, func, flags, dp, res, ei, caller);
|
||||
return invoke_builtin_function(This, func, flags, dp, res, ei, caller);
|
||||
|
||||
if(func->hook) {
|
||||
hres = func->hook(This, flags, dp, res, ei, caller);
|
||||
|
@ -1422,7 +1603,7 @@ HRESULT dispex_call_builtin(DispatchEx *dispex, DISPID id, DISPPARAMS *dp,
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return invoke_builtin_function(dispex, func, dp, res, ei, caller);
|
||||
return call_builtin_function(dispex, func, dp, res, ei, caller);
|
||||
}
|
||||
|
||||
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
||||
|
@ -1464,14 +1645,14 @@ HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
|||
|
||||
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.IDispatchEx_iface) {
|
||||
&& 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.IDispatchEx_iface;
|
||||
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
|
||||
IDispatch_AddRef(V_DISPATCH(&entry->val));
|
||||
*success = VARIANT_TRUE;
|
||||
return S_OK;
|
||||
|
@ -1549,14 +1730,14 @@ static BOOL ensure_real_info(DispatchEx *dispex)
|
|||
return dispex->info != NULL;
|
||||
}
|
||||
|
||||
static inline DispatchEx *impl_from_IDispatchEx(IDispatchEx *iface)
|
||||
static inline DispatchEx *impl_from_IWineJSDispatchHost(IWineJSDispatchHost *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, DispatchEx, IDispatchEx_iface);
|
||||
return CONTAINING_RECORD(iface, DispatchEx, IWineJSDispatchHost_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
static HRESULT WINAPI DispatchEx_QueryInterface(IWineJSDispatchHost *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("%s (%p)->(%s %p)\n", This->info->desc->name, This, debugstr_mshtml_guid(riid), ppv);
|
||||
|
||||
|
@ -1567,12 +1748,14 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid,
|
|||
}
|
||||
|
||||
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IDispatchEx, riid))
|
||||
*ppv = &This->IDispatchEx_iface;
|
||||
*ppv = &This->IWineJSDispatchHost_iface;
|
||||
else if(IsEqualGUID(&IID_IWineJSDispatchHost, riid))
|
||||
*ppv = &This->IWineJSDispatchHost_iface;
|
||||
else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) {
|
||||
*ppv = &dispex_ccp;
|
||||
return S_OK;
|
||||
}else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) {
|
||||
*ppv = &This->IDispatchEx_iface;
|
||||
*ppv = &This->IWineJSDispatchHost_iface;
|
||||
return S_OK;
|
||||
}else if(IsEqualGUID(&IID_IDispatchJS, riid) ||
|
||||
IsEqualGUID(&IID_UndocumentedScriptIface, riid) ||
|
||||
|
@ -1587,24 +1770,24 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid,
|
|||
}
|
||||
|
||||
ret:
|
||||
IDispatchEx_AddRef(&This->IDispatchEx_iface);
|
||||
IWineJSDispatchHost_AddRef(&This->IWineJSDispatchHost_iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
|
||||
static ULONG WINAPI DispatchEx_AddRef(IWineJSDispatchHost *iface)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
LONG ref = ccref_incr(&This->ccref, (nsISupports*)&This->IDispatchEx_iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
LONG ref = ccref_incr(&This->ccref, (nsISupports*)&This->IWineJSDispatchHost_iface);
|
||||
|
||||
TRACE("%s (%p) ref=%ld\n", This->info->desc->name, This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
|
||||
static ULONG WINAPI DispatchEx_Release(IWineJSDispatchHost *iface)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
LONG ref = ccref_decr(&This->ccref, (nsISupports*)&This->IDispatchEx_iface, &dispex_ccp);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
LONG ref = ccref_decr(&This->ccref, (nsISupports*)&This->IWineJSDispatchHost_iface, &dispex_ccp);
|
||||
|
||||
TRACE("%s (%p) ref=%ld\n", This->info->desc->name, This, ref);
|
||||
|
||||
|
@ -1612,17 +1795,17 @@ static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
|
|||
* an extra care for objects that need an immediate clean up. See Gecko's
|
||||
* NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE_WITH_LAST_RELEASE for details. */
|
||||
if(!ref && This->info->desc->vtbl->last_release) {
|
||||
ccref_incr(&This->ccref, (nsISupports*)&This->IDispatchEx_iface);
|
||||
ccref_incr(&This->ccref, (nsISupports*)&This->IWineJSDispatchHost_iface);
|
||||
This->info->desc->vtbl->last_release(This);
|
||||
ccref_decr(&This->ccref, (nsISupports*)&This->IDispatchEx_iface, &dispex_ccp);
|
||||
ccref_decr(&This->ccref, (nsISupports*)&This->IWineJSDispatchHost_iface, &dispex_ccp);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
|
||||
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IWineJSDispatchHost *iface, UINT *pctinfo)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("%s (%p)->(%p)\n", This->info->desc->name, This, pctinfo);
|
||||
|
||||
|
@ -1630,10 +1813,10 @@ static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pcti
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
|
||||
LCID lcid, ITypeInfo **ppTInfo)
|
||||
static HRESULT WINAPI DispatchEx_GetTypeInfo(IWineJSDispatchHost *iface, UINT iTInfo,
|
||||
LCID lcid, ITypeInfo **ppTInfo)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("%s (%p)->(%u %lu %p)\n", This->info->desc->name, This, iTInfo, lcid, ppTInfo);
|
||||
|
@ -1646,11 +1829,11 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
|
||||
LPOLESTR *rgszNames, UINT cNames,
|
||||
LCID lcid, DISPID *rgDispId)
|
||||
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IWineJSDispatchHost *iface, REFIID riid,
|
||||
LPOLESTR *rgszNames, UINT cNames,
|
||||
LCID lcid, DISPID *rgDispId)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("%s (%p)->(%s %p %u %lu %p)\n", This->info->desc->name, This, debugstr_guid(riid), rgszNames,
|
||||
|
@ -1658,27 +1841,27 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
|
|||
|
||||
/* Native ignores all cNames > 1, and doesn't even fill them */
|
||||
if(cNames)
|
||||
hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[0], 0, rgDispId);
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->IWineJSDispatchHost_iface, rgszNames[0], 0, rgDispId);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
|
||||
static HRESULT WINAPI DispatchEx_Invoke(IWineJSDispatchHost *iface, DISPID dispIdMember,
|
||||
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
|
||||
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("%s (%p)->(%ld %s %ld %d %p %p %p %p)\n", This->info->desc->name, This, dispIdMember,
|
||||
debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
||||
|
||||
return IDispatchEx_InvokeEx(&This->IDispatchEx_iface, dispIdMember, lcid, wFlags, pDispParams,
|
||||
return IWineJSDispatchHost_InvokeEx(&This->IWineJSDispatchHost_iface, dispIdMember, lcid, wFlags, pDispParams,
|
||||
pVarResult, pExcepInfo, NULL);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
static HRESULT WINAPI DispatchEx_GetDispID(IWineJSDispatchHost *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
dynamic_prop_t *dprop = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -1711,10 +1894,10 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
static HRESULT WINAPI DispatchEx_InvokeEx(IWineJSDispatchHost *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("%s (%p)->(%lx %lx %x %p %p %p %p)\n", This->info->desc->name, This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
|
||||
|
@ -1803,9 +1986,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR name, DWORD grfdex)
|
||||
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IWineJSDispatchHost *iface, BSTR name, DWORD grfdex)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
DISPID id;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -1814,7 +1997,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR nam
|
|||
if(dispex_compat_mode(This) < COMPAT_MODE_IE8 && !This->info->desc->vtbl->delete)
|
||||
return E_NOTIMPL;
|
||||
|
||||
hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, name, grfdex & ~fdexNameEnsure, &id);
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->IWineJSDispatchHost_iface, name, grfdex & ~fdexNameEnsure, &id);
|
||||
if(FAILED(hres)) {
|
||||
compat_mode_t compat_mode = dispex_compat_mode(This);
|
||||
TRACE("property %s not found\n", debugstr_w(name));
|
||||
|
@ -1822,12 +2005,12 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR nam
|
|||
compat_mode < COMPAT_MODE_IE9 ? hres : S_OK;
|
||||
}
|
||||
|
||||
return IDispatchEx_DeleteMemberByDispID(&This->IDispatchEx_iface, id);
|
||||
return IWineJSDispatchHost_DeleteMemberByDispID(&This->IWineJSDispatchHost_iface, id);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
|
||||
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatchHost *iface, DISPID id)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("%s (%p)->(%lx)\n", This->info->desc->name, This, id);
|
||||
|
||||
|
@ -1855,16 +2038,16 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
static HRESULT WINAPI DispatchEx_GetMemberProperties(IWineJSDispatchHost *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
FIXME("%s (%p)->(%lx %lx %p)\n", This->info->desc->name, This, id, grfdexFetch, pgrfdex);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
|
||||
static HRESULT WINAPI DispatchEx_GetMemberName(IWineJSDispatchHost *iface, DISPID id, BSTR *pbstrName)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
func_info_t *func;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -1917,9 +2100,9 @@ static HRESULT next_dynamic_id(DispatchEx *dispex, DWORD idx, DISPID *ret_id)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
|
||||
static HRESULT WINAPI DispatchEx_GetNextDispID(IWineJSDispatchHost *iface, DWORD grfdex, DISPID id, DISPID *pid)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
func_info_t *func;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -1971,14 +2154,31 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex,
|
|||
return S_FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
|
||||
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IWineJSDispatchHost *iface, IUnknown **ppunk)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(iface);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
FIXME("%s (%p)->(%p)\n", This->info->desc->name, This, ppunk);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static IDispatchExVtbl DispatchExVtbl = {
|
||||
static HRESULT WINAPI DispatchEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret,
|
||||
EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
||||
func_info_t *func;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("%s (%p)->(%lx %x %p %p %p %p)\n", This->info->desc->name, This, id, iid, dp, ret, ei, caller);
|
||||
|
||||
hres = get_builtin_func(This->info, id, &func);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(func->tid != iid || func->func_disp_idx < 0)
|
||||
return E_UNEXPECTED;
|
||||
return call_builtin_function(This, func, dp, ret, ei, caller);
|
||||
}
|
||||
|
||||
static IWineJSDispatchHostVtbl JSDispatchHostVtbl = {
|
||||
DispatchEx_QueryInterface,
|
||||
DispatchEx_AddRef,
|
||||
DispatchEx_Release,
|
||||
|
@ -1993,12 +2193,13 @@ static IDispatchExVtbl DispatchExVtbl = {
|
|||
DispatchEx_GetMemberProperties,
|
||||
DispatchEx_GetMemberName,
|
||||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent
|
||||
DispatchEx_GetNameSpaceParent,
|
||||
DispatchEx_CallFunction,
|
||||
};
|
||||
|
||||
static nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(p);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(p);
|
||||
dynamic_prop_t *prop;
|
||||
|
||||
describe_cc_node(&This->ccref, This->info->desc->name, cb);
|
||||
|
@ -2018,7 +2219,7 @@ static nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTrave
|
|||
for(iter = This->dynamic_data->func_disps; iter < end; iter++) {
|
||||
if(!iter->func_obj)
|
||||
continue;
|
||||
note_cc_edge((nsISupports*)&iter->func_obj->dispex.IDispatchEx_iface, "func_obj", cb);
|
||||
note_cc_edge((nsISupports*)&iter->func_obj->dispex.IWineJSDispatchHost_iface, "func_obj", cb);
|
||||
traverse_variant(&iter->val, "func_val", cb);
|
||||
}
|
||||
}
|
||||
|
@ -2045,7 +2246,7 @@ void dispex_props_unlink(DispatchEx *This)
|
|||
if(!iter->func_obj)
|
||||
continue;
|
||||
iter->func_obj->obj = NULL;
|
||||
IDispatchEx_Release(&iter->func_obj->dispex.IDispatchEx_iface);
|
||||
IWineJSDispatchHost_Release(&iter->func_obj->dispex.IWineJSDispatchHost_iface);
|
||||
VariantClear(&iter->val);
|
||||
}
|
||||
|
||||
|
@ -2056,7 +2257,7 @@ void dispex_props_unlink(DispatchEx *This)
|
|||
|
||||
static nsresult NSAPI dispex_unlink(void *p)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(p);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(p);
|
||||
|
||||
if(This->info->desc->vtbl->unlink)
|
||||
This->info->desc->vtbl->unlink(This);
|
||||
|
@ -2067,7 +2268,7 @@ static nsresult NSAPI dispex_unlink(void *p)
|
|||
|
||||
static void NSAPI dispex_delete_cycle_collectable(void *p)
|
||||
{
|
||||
DispatchEx *This = impl_from_IDispatchEx(p);
|
||||
DispatchEx *This = impl_from_IWineJSDispatchHost(p);
|
||||
dynamic_prop_t *prop;
|
||||
|
||||
if(This->info->desc->vtbl->unlink)
|
||||
|
@ -2089,7 +2290,7 @@ static void NSAPI dispex_delete_cycle_collectable(void *p)
|
|||
for(iter = This->dynamic_data->func_disps; iter < This->dynamic_data->func_disps + This->info->func_disp_cnt; iter++) {
|
||||
if(iter->func_obj) {
|
||||
iter->func_obj->obj = NULL;
|
||||
IDispatchEx_Release(&iter->func_obj->dispex.IDispatchEx_iface);
|
||||
IWineJSDispatchHost_Release(&iter->func_obj->dispex.IWineJSDispatchHost_iface);
|
||||
}
|
||||
VariantClear(&iter->val);
|
||||
}
|
||||
|
@ -2122,7 +2323,7 @@ void init_dispatch(DispatchEx *dispex, dispex_static_data_t *data, compat_mode_t
|
|||
{
|
||||
assert(compat_mode < COMPAT_MODE_CNT);
|
||||
|
||||
dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
|
||||
dispex->IWineJSDispatchHost_iface.lpVtbl = &JSDispatchHostVtbl;
|
||||
dispex->dynamic_data = NULL;
|
||||
ccref_init(&dispex->ccref, 1);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ static HRESULT WINAPI HTMLDOMAttribute_get_nodeName(IHTMLDOMAttribute *iface, BS
|
|||
return *p ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return IDispatchEx_GetMemberName(&This->elem->node.event_target.dispex.IDispatchEx_iface, This->dispid, p);
|
||||
return IWineJSDispatchHost_GetMemberName(&This->elem->node.event_target.dispex.IWineJSDispatchHost_iface, This->dispid, p);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLDOMAttribute_put_nodeValue(IHTMLDOMAttribute *iface, VARIANT v)
|
||||
|
@ -73,7 +73,7 @@ static HRESULT WINAPI HTMLDOMAttribute_put_nodeValue(IHTMLDOMAttribute *iface, V
|
|||
|
||||
memset(&ei, 0, sizeof(ei));
|
||||
|
||||
return IDispatchEx_InvokeEx(&This->elem->node.event_target.dispex.IDispatchEx_iface, This->dispid, LOCALE_SYSTEM_DEFAULT,
|
||||
return IWineJSDispatchHost_InvokeEx(&This->elem->node.event_target.dispex.IWineJSDispatchHost_iface, This->dispid, LOCALE_SYSTEM_DEFAULT,
|
||||
DISPATCH_PROPERTYPUT, &dp, &ret, &ei, NULL);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, V
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
hres = IDispatchEx_GetMemberName(&This->elem->node.event_target.dispex.IDispatchEx_iface, This->dispid, &name);
|
||||
hres = IWineJSDispatchHost_GetMemberName(&This->elem->node.event_target.dispex.IWineJSDispatchHost_iface, This->dispid, &name);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -4739,8 +4739,18 @@ static HRESULT WINAPI MarkupServices_CreateMarkupPointer(IMarkupServices *iface,
|
|||
static HRESULT WINAPI MarkupServices_CreateMarkupContainer(IMarkupServices *iface, IMarkupContainer **ppMarkupContainer)
|
||||
{
|
||||
HTMLDocumentNode *This = impl_from_IMarkupServices(iface);
|
||||
FIXME("(%p)->(%p)\n", This, ppMarkupContainer);
|
||||
return E_NOTIMPL;
|
||||
IHTMLDocument2 *frag;
|
||||
HRESULT hres;
|
||||
TRACE("(%p)->(%p)\n", This, ppMarkupContainer);
|
||||
|
||||
hres = IHTMLDocument3_createDocumentFragment(&This->IHTMLDocument3_iface, &frag);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
IHTMLDocument2_QueryInterface(frag, &IID_IMarkupContainer, (void**)ppMarkupContainer);
|
||||
IHTMLDocument2_Release(frag);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MarkupServices_CreateElement(IMarkupServices *iface,
|
||||
|
@ -4813,9 +4823,53 @@ static HRESULT WINAPI MarkupServices_ParseString(IMarkupServices *iface,
|
|||
OLECHAR *pchHTML, DWORD dwFlags, IMarkupContainer **ppContainerResult,
|
||||
IMarkupPointer *pPointerStart, IMarkupPointer *pPointerFinish)
|
||||
{
|
||||
HRESULT hres;
|
||||
IMarkupContainer *container;
|
||||
IHTMLDocument2 *doc;
|
||||
IHTMLDOMNode *node, *html_node, *new_html_node = NULL;
|
||||
IHTMLElement *html, *body;
|
||||
HTMLDocumentNode *This = impl_from_IMarkupServices(iface);
|
||||
FIXME("(%p)->(%s,%lx,%p,%p,%p)\n", This, debugstr_w(pchHTML), dwFlags, ppContainerResult, pPointerStart, pPointerFinish);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p)->(%s,%lx,%p,%p,%p)\n", This, debugstr_w(pchHTML), dwFlags, ppContainerResult, pPointerStart, pPointerFinish);
|
||||
|
||||
if(dwFlags != 0)
|
||||
FIXME("flags %lx not implemented.\n", dwFlags);
|
||||
if(pPointerStart || pPointerFinish) {
|
||||
FIXME("Pointers not implemented.\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
hres = IMarkupServices_CreateMarkupContainer(iface, &container);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
IMarkupContainer_QueryInterface(container, &IID_IHTMLDocument2, (void**)&doc);
|
||||
IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDOMNode, (void**)&node);
|
||||
IHTMLDocument2_createElement(&This->IHTMLDocument2_iface, (BSTR)L"html", &html);
|
||||
|
||||
IHTMLElement_put_innerHTML(html, (BSTR)L"<head><title></title></head><body></body>");
|
||||
IHTMLElement_QueryInterface(html, &IID_IHTMLDOMNode, (void**)&html_node);
|
||||
IHTMLElement_Release(html);
|
||||
|
||||
IHTMLDOMNode_appendChild(node, html_node, &new_html_node);
|
||||
IHTMLDOMNode_Release(node);
|
||||
IHTMLDOMNode_Release(html_node);
|
||||
IHTMLDOMNode_Release(new_html_node);
|
||||
|
||||
IHTMLDocument2_get_body(doc, &body);
|
||||
hres = IHTMLElement_put_innerHTML(body, pchHTML);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
ERR("Failed put_innerHTML hr %#lx\n", hres);
|
||||
IMarkupContainer_Release(container);
|
||||
container = NULL;
|
||||
}
|
||||
|
||||
IHTMLDocument2_Release(doc);
|
||||
IHTMLElement_Release(body);
|
||||
|
||||
*ppContainerResult = container;
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MarkupServices_ParseGlobal(IMarkupServices *iface,
|
||||
|
@ -5529,8 +5583,8 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI
|
|||
if(!This->window->base.outer_window)
|
||||
return E_FAIL;
|
||||
|
||||
return IDispatchEx_InvokeEx(&This->window->event_target.dispex.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION,
|
||||
0, flags, dp, res, ei, caller);
|
||||
return IWineJSDispatchHost_InvokeEx(&This->window->event_target.dispex.IWineJSDispatchHost_iface,
|
||||
DISPID_IHTMLWINDOW2_LOCATION, 0, flags, dp, res, ei, caller);
|
||||
}
|
||||
|
||||
static HRESULT HTMLDocumentNode_pre_handle_event(DispatchEx* dispex, DOMEvent *event)
|
||||
|
|
|
@ -1170,7 +1170,7 @@ static HRESULT set_elem_attr_value_by_dispid(HTMLElement *elem, DISPID dispid, V
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
return IDispatchEx_InvokeEx(&elem->node.event_target.dispex.IDispatchEx_iface, dispid,
|
||||
return IWineJSDispatchHost_InvokeEx(&elem->node.event_target.dispex.IWineJSDispatchHost_iface, dispid,
|
||||
LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
|
||||
}
|
||||
|
||||
|
@ -1189,7 +1189,7 @@ static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttr
|
|||
TRACE("(%p)->(%s %s %08lx)\n", This, debugstr_w(strAttributeName), debugstr_variant(&AttributeValue), lFlags);
|
||||
|
||||
if(compat_mode < COMPAT_MODE_IE9 || !This->dom_element) {
|
||||
hres = IDispatchEx_GetDispID(&This->node.event_target.dispex.IDispatchEx_iface, translate_attr_name(strAttributeName, compat_mode),
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->node.event_target.dispex.IWineJSDispatchHost_iface, translate_attr_name(strAttributeName, compat_mode),
|
||||
(lFlags&ATTRFLAG_CASESENSITIVE ? fdexNameCaseSensitive : fdexNameCaseInsensitive) | fdexNameEnsure, &dispid);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -1241,7 +1241,7 @@ HRESULT get_elem_attr_value_by_dispid(HTMLElement *elem, DISPID dispid, VARIANT
|
|||
DISPPARAMS dispParams = {NULL, NULL, 0, 0};
|
||||
EXCEPINFO excep;
|
||||
|
||||
return IDispatchEx_InvokeEx(&elem->node.event_target.dispex.IDispatchEx_iface, dispid, LOCALE_SYSTEM_DEFAULT,
|
||||
return IWineJSDispatchHost_InvokeEx(&elem->node.event_target.dispex.IWineJSDispatchHost_iface, dispid, LOCALE_SYSTEM_DEFAULT,
|
||||
DISPATCH_PROPERTYGET, &dispParams, ret, &excep, NULL);
|
||||
}
|
||||
|
||||
|
@ -1288,7 +1288,7 @@ static HRESULT WINAPI HTMLElement_getAttribute(IHTMLElement *iface, BSTR strAttr
|
|||
FIXME("Unsupported flags %lx\n", lFlags);
|
||||
|
||||
if(compat_mode < COMPAT_MODE_IE9 || !This->dom_element) {
|
||||
hres = IDispatchEx_GetDispID(&This->node.event_target.dispex.IDispatchEx_iface, translate_attr_name(strAttributeName, compat_mode),
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->node.event_target.dispex.IWineJSDispatchHost_iface, translate_attr_name(strAttributeName, compat_mode),
|
||||
lFlags&ATTRFLAG_CASESENSITIVE ? fdexNameCaseSensitive : fdexNameCaseInsensitive, &dispid);
|
||||
if(FAILED(hres)) {
|
||||
V_VT(AttributeValue) = VT_NULL;
|
||||
|
@ -1336,7 +1336,7 @@ static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strA
|
|||
TRACE("(%p)->(%s %lx %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
|
||||
|
||||
if(compat_mode < COMPAT_MODE_IE9 || !This->dom_element) {
|
||||
hres = IDispatchEx_GetDispID(&This->node.event_target.dispex.IDispatchEx_iface, translate_attr_name(strAttributeName, compat_mode),
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->node.event_target.dispex.IWineJSDispatchHost_iface, translate_attr_name(strAttributeName, compat_mode),
|
||||
lFlags&ATTRFLAG_CASESENSITIVE ? fdexNameCaseSensitive : fdexNameCaseInsensitive, &id);
|
||||
if(hres == DISP_E_UNKNOWNNAME) {
|
||||
*pfSuccess = VARIANT_FALSE;
|
||||
|
@ -2483,7 +2483,7 @@ static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
|
|||
if(!String)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hres = IDispatchEx_InvokeEx(&This->node.event_target.dispex.IDispatchEx_iface, DISPID_VALUE,
|
||||
hres = IWineJSDispatchHost_InvokeEx(&This->node.event_target.dispex.IWineJSDispatchHost_iface, DISPID_VALUE,
|
||||
LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, NULL, &var, NULL, NULL);
|
||||
if(SUCCEEDED(hres)) {
|
||||
assert(V_VT(&var) == VT_BSTR);
|
||||
|
@ -4429,7 +4429,7 @@ static HRESULT WINAPI HTMLElement4_setAttributeNode(IHTMLElement4 *iface, IHTMLD
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
hres = IDispatchEx_GetDispID(&This->node.event_target.dispex.IDispatchEx_iface,
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->node.event_target.dispex.IWineJSDispatchHost_iface,
|
||||
attr->name, fdexNameCaseInsensitive|fdexNameEnsure, &dispid);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -6399,7 +6399,7 @@ HRESULT HTMLElement_populate_props(DispatchEx *dispex)
|
|||
continue;
|
||||
}
|
||||
|
||||
hres = IDispatchEx_GetDispID(&dispex->IDispatchEx_iface, name, fdexNameCaseInsensitive, &id);
|
||||
hres = IWineJSDispatchHost_GetDispID(&dispex->IWineJSDispatchHost_iface, name, fdexNameCaseInsensitive, &id);
|
||||
if(hres != DISP_E_UNKNOWNNAME) {
|
||||
nsIDOMAttr_Release(attr);
|
||||
SysFreeString(name);
|
||||
|
@ -7544,7 +7544,7 @@ static HRESULT create_filters_collection(compat_mode_t compat_mode, IHTMLFilters
|
|||
|
||||
static HRESULT get_attr_dispid_by_relative_idx(HTMLAttributeCollection *This, LONG *idx, DISPID start, DISPID *dispid)
|
||||
{
|
||||
IDispatchEx *dispex = &This->elem->node.event_target.dispex.IDispatchEx_iface;
|
||||
IWineJSDispatchHost *dispex = &This->elem->node.event_target.dispex.IWineJSDispatchHost_iface;
|
||||
DISPID id = start;
|
||||
LONG len = -1;
|
||||
HRESULT hres;
|
||||
|
@ -7552,7 +7552,7 @@ static HRESULT get_attr_dispid_by_relative_idx(HTMLAttributeCollection *This, LO
|
|||
FIXME("filter non-enumerable attributes out\n");
|
||||
|
||||
while(1) {
|
||||
hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, id, &id);
|
||||
hres = IWineJSDispatchHost_GetNextDispID(dispex, fdexEnumAll, id, &id);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
else if(hres == S_FALSE)
|
||||
|
@ -7593,7 +7593,7 @@ static inline HRESULT get_attr_dispid_by_name(HTMLAttributeCollection *This, BST
|
|||
}
|
||||
}
|
||||
|
||||
hres = IDispatchEx_GetDispID(&This->elem->node.event_target.dispex.IDispatchEx_iface,
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->elem->node.event_target.dispex.IWineJSDispatchHost_iface,
|
||||
name, fdexNameCaseInsensitive, id);
|
||||
return hres;
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ static BOOL is_elem_name(HTMLElement *elem, LPCWSTR name)
|
|||
static HRESULT get_item_idx(HTMLElementCollection *This, UINT idx, IDispatch **ret)
|
||||
{
|
||||
if(idx < This->len) {
|
||||
*ret = (IDispatch*)&This->elems[idx]->node.event_target.dispex.IDispatchEx_iface;
|
||||
*ret = (IDispatch*)&This->elems[idx]->node.event_target.dispex.IWineJSDispatchHost_iface;
|
||||
IDispatch_AddRef(*ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -2056,7 +2056,7 @@ static HRESULT WINAPI DOMEvent_get_srcElement(IDOMEvent *iface, IHTMLElement **p
|
|||
TRACE("(%p)->(%p)\n", This, p);
|
||||
|
||||
if(This->target)
|
||||
IDispatchEx_QueryInterface(&This->target->dispex.IDispatchEx_iface, &IID_IHTMLElement, (void**)p);
|
||||
IWineJSDispatchHost_QueryInterface(&This->target->dispex.IWineJSDispatchHost_iface, &IID_IHTMLElement, (void**)p);
|
||||
else
|
||||
*p = NULL;
|
||||
return S_OK;
|
||||
|
@ -4167,7 +4167,7 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event, disp
|
|||
skip_onevent_listener = TRUE;
|
||||
|
||||
V_VT(&arg) = VT_DISPATCH;
|
||||
V_DISPATCH(&arg) = (IDispatch*)&event_target->dispex.IDispatchEx_iface;
|
||||
V_DISPATCH(&arg) = (IDispatch*)&event_target->dispex.IWineJSDispatchHost_iface;
|
||||
V_VT(&v) = VT_EMPTY;
|
||||
if(vtbl->get_dispatch_this)
|
||||
V_DISPATCH(&arg) = vtbl->get_dispatch_this(&event_target->dispex);
|
||||
|
@ -4249,7 +4249,7 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event, disp
|
|||
DISPPARAMS dp = {args, &named_arg, 2, 1};
|
||||
|
||||
V_VT(args) = VT_DISPATCH;
|
||||
V_DISPATCH(args) = (IDispatch*)&event_target->dispex.IDispatchEx_iface;
|
||||
V_DISPATCH(args) = (IDispatch*)&event_target->dispex.IWineJSDispatchHost_iface;
|
||||
if(vtbl->get_dispatch_this)
|
||||
V_DISPATCH(args) = vtbl->get_dispatch_this(&event_target->dispex);
|
||||
IDispatch_AddRef(V_DISPATCH(args));
|
||||
|
|
|
@ -893,7 +893,7 @@ static HRESULT HTMLFrameElement_invoke(DispatchEx *dispex, DISPID id, LCID lcid,
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
return IDispatchEx_InvokeEx(&This->framebase.content_window->IDispatchEx_iface, id, lcid,
|
||||
return IWineJSDispatchHost_InvokeEx(&This->framebase.content_window->IWineJSDispatchHost_iface, id, lcid,
|
||||
flags, params, res, ei, caller);
|
||||
}
|
||||
|
||||
|
@ -1330,7 +1330,7 @@ static HRESULT HTMLIFrame_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
return IDispatchEx_InvokeEx(&This->framebase.content_window->IDispatchEx_iface, id, lcid,
|
||||
return IWineJSDispatchHost_InvokeEx(&This->framebase.content_window->IWineJSDispatchHost_iface, id, lcid,
|
||||
flags, params, res, ei, caller);
|
||||
}
|
||||
|
||||
|
|
|
@ -2917,7 +2917,7 @@ static HRESULT WINAPI HTMLStyle_removeAttribute(IHTMLStyle *iface, BSTR strAttri
|
|||
DISPID dispid;
|
||||
unsigned i;
|
||||
|
||||
hres = IDispatchEx_GetDispID(&This->css_style.dispex.IDispatchEx_iface, strAttributeName,
|
||||
hres = IWineJSDispatchHost_GetDispID(&This->css_style.dispex.IWineJSDispatchHost_iface, strAttributeName,
|
||||
(lFlags&1) ? fdexNameCaseSensitive : fdexNameCaseInsensitive, &dispid);
|
||||
if(hres != S_OK) {
|
||||
*pfSuccess = VARIANT_FALSE;
|
||||
|
|
|
@ -211,8 +211,8 @@ static HRESULT WINAPI outer_window_QueryInterface(IHTMLWindow2 *iface, REFIID ri
|
|||
}else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) {
|
||||
*ppv = &This->base.IHTMLWindow2_iface;
|
||||
return S_OK;
|
||||
}else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
|
||||
*ppv = &This->IDispatchEx_iface;
|
||||
}else if(IsEqualGUID(&IID_IDispatchEx, riid) || IsEqualGUID(&IID_IWineJSDispatchHost, riid)) {
|
||||
*ppv = &This->IWineJSDispatchHost_iface;
|
||||
}else if(IsEqualGUID(&IID_IEventTarget, riid)) {
|
||||
if(!This->base.inner_window->doc || This->base.inner_window->doc->document_mode < COMPAT_MODE_IE9)
|
||||
return E_NOINTERFACE;
|
||||
|
@ -3277,34 +3277,34 @@ static const IWineHTMLWindowCompatPrivateVtbl WineHTMLWindowCompatPrivateVtbl =
|
|||
window_compat_private_get_performance,
|
||||
};
|
||||
|
||||
static inline HTMLOuterWindow *impl_from_IDispatchEx(IDispatchEx *iface)
|
||||
static inline HTMLOuterWindow *impl_from_IWineJSDispatchHost(IWineJSDispatchHost *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, HTMLOuterWindow, IDispatchEx_iface);
|
||||
return CONTAINING_RECORD(iface, HTMLOuterWindow, IWineJSDispatchHost_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
static HRESULT WINAPI WindowDispEx_QueryInterface(IWineJSDispatchHost *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
return IHTMLWindow2_QueryInterface(&This->base.IHTMLWindow2_iface, riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI WindowDispEx_AddRef(IDispatchEx *iface)
|
||||
static ULONG WINAPI WindowDispEx_AddRef(IWineJSDispatchHost *iface)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
return IHTMLWindow2_AddRef(&This->base.IHTMLWindow2_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI WindowDispEx_Release(IDispatchEx *iface)
|
||||
static ULONG WINAPI WindowDispEx_Release(IWineJSDispatchHost *iface)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
return IHTMLWindow2_Release(&This->base.IHTMLWindow2_iface);
|
||||
}
|
||||
|
||||
DISPEX_IDISPATCH_NOUNK_IMPL(WindowDispEx, IDispatchEx,
|
||||
impl_from_IDispatchEx(iface)->base.inner_window->event_target.dispex)
|
||||
DISPEX_IDISPATCH_NOUNK_IMPL(WindowDispEx, IWineJSDispatchHost,
|
||||
impl_from_IWineJSDispatchHost(iface)->base.inner_window->event_target.dispex)
|
||||
|
||||
static global_prop_t *alloc_global_prop(HTMLInnerWindow *This, global_prop_type_t type, BSTR name)
|
||||
{
|
||||
|
@ -3369,69 +3369,70 @@ HRESULT search_window_props(HTMLInnerWindow *This, BSTR bstrName, DWORD grfdex,
|
|||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
static HRESULT WINAPI WindowDispEx_GetDispID(IWineJSDispatchHost *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
return IDispatchEx_GetDispID(&This->base.inner_window->event_target.dispex.IDispatchEx_iface, bstrName, grfdex, pid);
|
||||
return IWineJSDispatchHost_GetDispID(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, bstrName, grfdex, pid);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
static HRESULT WINAPI WindowDispEx_InvokeEx(IWineJSDispatchHost *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
return IDispatchEx_InvokeEx(&This->base.inner_window->event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
return IWineJSDispatchHost_InvokeEx(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id, lcid, wFlags,
|
||||
pdp, pvarRes, pei, pspCaller);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
|
||||
static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IWineJSDispatchHost *iface, BSTR bstrName, DWORD grfdex)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("(%p)->(%s %lx)\n", This, debugstr_w(bstrName), grfdex);
|
||||
|
||||
return IDispatchEx_DeleteMemberByName(&This->base.inner_window->event_target.dispex.IDispatchEx_iface, bstrName, grfdex);
|
||||
return IWineJSDispatchHost_DeleteMemberByName(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, bstrName, grfdex);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
|
||||
static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IWineJSDispatchHost *iface, DISPID id)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("(%p)->(%lx)\n", This, id);
|
||||
|
||||
return IDispatchEx_DeleteMemberByDispID(&This->base.inner_window->event_target.dispex.IDispatchEx_iface, id);
|
||||
return IWineJSDispatchHost_DeleteMemberByDispID(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
static HRESULT WINAPI WindowDispEx_GetMemberProperties(IWineJSDispatchHost *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
|
||||
|
||||
return IDispatchEx_GetMemberProperties(&This->base.inner_window->event_target.dispex.IDispatchEx_iface, id, grfdexFetch,
|
||||
return IWineJSDispatchHost_GetMemberProperties(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id, grfdexFetch,
|
||||
pgrfdex);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
|
||||
static HRESULT WINAPI WindowDispEx_GetMemberName(IWineJSDispatchHost *iface, DISPID id, BSTR *pbstrName)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("(%p)->(%lx %p)\n", This, id, pbstrName);
|
||||
|
||||
return IDispatchEx_GetMemberName(&This->base.inner_window->event_target.dispex.IDispatchEx_iface, id, pbstrName);
|
||||
return IWineJSDispatchHost_GetMemberName(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id, pbstrName);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
|
||||
static HRESULT WINAPI WindowDispEx_GetNextDispID(IWineJSDispatchHost *iface, DWORD grfdex, DISPID id, DISPID *pid)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("(%p)->(%lx %lx %p)\n", This, grfdex, id, pid);
|
||||
|
||||
return IDispatchEx_GetNextDispID(&This->base.inner_window->event_target.dispex.IDispatchEx_iface, grfdex, id, pid);
|
||||
return IWineJSDispatchHost_GetNextDispID(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, grfdex, id, pid);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
|
||||
static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IWineJSDispatchHost *iface, IUnknown **ppunk)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IDispatchEx(iface);
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, ppunk);
|
||||
|
||||
|
@ -3439,7 +3440,16 @@ static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnkno
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static const IDispatchExVtbl WindowDispExVtbl = {
|
||||
static HRESULT WINAPI WindowDispEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret,
|
||||
EXCEPINFO *ei, IServiceProvider *caller)
|
||||
{
|
||||
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
|
||||
|
||||
return IWineJSDispatchHost_CallFunction(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface,
|
||||
id, iid, dp, ret, ei, caller);
|
||||
}
|
||||
|
||||
static const IWineJSDispatchHostVtbl WindowDispExVtbl = {
|
||||
WindowDispEx_QueryInterface,
|
||||
WindowDispEx_AddRef,
|
||||
WindowDispEx_Release,
|
||||
|
@ -3454,7 +3464,8 @@ static const IDispatchExVtbl WindowDispExVtbl = {
|
|||
WindowDispEx_GetMemberProperties,
|
||||
WindowDispEx_GetMemberName,
|
||||
WindowDispEx_GetNextDispID,
|
||||
WindowDispEx_GetNameSpaceParent
|
||||
WindowDispEx_GetNameSpaceParent,
|
||||
WindowDispEx_CallFunction,
|
||||
};
|
||||
|
||||
static inline HTMLOuterWindow *impl_from_IEventTarget(IEventTarget *iface)
|
||||
|
@ -3810,7 +3821,7 @@ static HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD
|
|||
|
||||
prop->type = GLOBAL_DISPEXVAR;
|
||||
prop->id = dispex_id;
|
||||
return IDispatchEx_InvokeEx(&This->event_target.dispex.IDispatchEx_iface, dispex_id, 0, flags, params, res, ei, caller);
|
||||
return IWineJSDispatchHost_InvokeEx(&This->event_target.dispex.IWineJSDispatchHost_iface, dispex_id, 0, flags, params, res, ei, caller);
|
||||
}
|
||||
default:
|
||||
FIXME("Not supported flags: %x\n", flags);
|
||||
|
@ -3838,7 +3849,7 @@ static HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
case GLOBAL_DISPEXVAR:
|
||||
return IDispatchEx_InvokeEx(&This->event_target.dispex.IDispatchEx_iface, prop->id, 0, flags, params, res, ei, caller);
|
||||
return IWineJSDispatchHost_InvokeEx(&This->event_target.dispex.IWineJSDispatchHost_iface, prop->id, 0, flags, params, res, ei, caller);
|
||||
default:
|
||||
ERR("invalid type %d\n", prop->type);
|
||||
hres = DISP_E_MEMBERNOTFOUND;
|
||||
|
@ -3901,7 +3912,7 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller);
|
||||
hres = IWineJSDispatchHost_InvokeEx(&location->dispex.IWineJSDispatchHost_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller);
|
||||
IHTMLLocation_Release(&location->IHTMLLocation_iface);
|
||||
return hres;
|
||||
}
|
||||
|
@ -4204,7 +4215,7 @@ HRESULT create_outer_window(GeckoBrowser *browser, mozIDOMWindowProxy *mozwindow
|
|||
if(!window)
|
||||
return E_OUTOFMEMORY;
|
||||
window->base.IHTMLWindow2_iface.lpVtbl = &outer_window_HTMLWindow2Vtbl;
|
||||
window->IDispatchEx_iface.lpVtbl = &WindowDispExVtbl;
|
||||
window->IWineJSDispatchHost_iface.lpVtbl = &WindowDispExVtbl;
|
||||
window->IEventTarget_iface.lpVtbl = &EventTargetVtbl;
|
||||
|
||||
window->base.outer_window = window;
|
||||
|
|
|
@ -413,7 +413,7 @@ typedef struct {
|
|||
} dispex_hook_t;
|
||||
|
||||
struct DispatchEx {
|
||||
IDispatchEx IDispatchEx_iface;
|
||||
IWineJSDispatchHost IWineJSDispatchHost_iface;
|
||||
|
||||
nsCycleCollectingAutoRefCnt ccref;
|
||||
|
||||
|
@ -424,38 +424,38 @@ struct DispatchEx {
|
|||
#define DISPEX_IDISPATCH_NOUNK_IMPL(prefix, iface_name, dispex) \
|
||||
static HRESULT WINAPI prefix##_GetTypeInfoCount(iface_name *iface, UINT *count) \
|
||||
{ \
|
||||
return IDispatchEx_GetTypeInfoCount(&(dispex).IDispatchEx_iface, count); \
|
||||
return IWineJSDispatchHost_GetTypeInfoCount(&(dispex).IWineJSDispatchHost_iface, count); \
|
||||
} \
|
||||
static HRESULT WINAPI prefix##_GetTypeInfo(iface_name *iface, \
|
||||
UINT index, LCID lcid, ITypeInfo **ret) \
|
||||
{ \
|
||||
return IDispatchEx_GetTypeInfo(&(dispex).IDispatchEx_iface, index, lcid, ret); \
|
||||
return IWineJSDispatchHost_GetTypeInfo(&(dispex).IWineJSDispatchHost_iface, index, lcid, ret); \
|
||||
} \
|
||||
static HRESULT WINAPI prefix##_GetIDsOfNames(iface_name *iface, REFIID riid, \
|
||||
LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid) \
|
||||
{ \
|
||||
return IDispatchEx_GetIDsOfNames(&(dispex).IDispatchEx_iface, \
|
||||
return IWineJSDispatchHost_GetIDsOfNames(&(dispex).IWineJSDispatchHost_iface, \
|
||||
riid, names, count, lcid, dispid); \
|
||||
} \
|
||||
static HRESULT WINAPI prefix##_Invoke(iface_name *iface, DISPID dispid, REFIID riid, \
|
||||
LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, UINT *err) \
|
||||
{ \
|
||||
return IDispatchEx_Invoke(&(dispex).IDispatchEx_iface, dispid, \
|
||||
return IWineJSDispatchHost_Invoke(&(dispex).IWineJSDispatchHost_iface, dispid, \
|
||||
riid, lcid, flags, params, res, ei, err); \
|
||||
}
|
||||
|
||||
#define DISPEX_IDISPATCH_IMPL(prefix, iface_name, dispex) \
|
||||
static HRESULT WINAPI prefix##_QueryInterface(iface_name *iface, REFIID riid, void **ppv) \
|
||||
{ \
|
||||
return IDispatchEx_QueryInterface(&(dispex).IDispatchEx_iface, riid, ppv); \
|
||||
return IWineJSDispatchHost_QueryInterface(&(dispex).IWineJSDispatchHost_iface, riid, ppv); \
|
||||
} \
|
||||
static ULONG WINAPI prefix##_AddRef(iface_name *iface) \
|
||||
{ \
|
||||
return IDispatchEx_AddRef(&(dispex).IDispatchEx_iface); \
|
||||
return IWineJSDispatchHost_AddRef(&(dispex).IWineJSDispatchHost_iface); \
|
||||
} \
|
||||
static ULONG WINAPI prefix##_Release(iface_name *iface) \
|
||||
{ \
|
||||
return IDispatchEx_Release(&(dispex).IDispatchEx_iface); \
|
||||
return IWineJSDispatchHost_Release(&(dispex).IWineJSDispatchHost_iface); \
|
||||
} \
|
||||
DISPEX_IDISPATCH_NOUNK_IMPL(prefix, iface_name, dispex)
|
||||
|
||||
|
@ -594,7 +594,7 @@ struct HTMLWindow {
|
|||
struct HTMLOuterWindow {
|
||||
HTMLWindow base;
|
||||
IEventTarget IEventTarget_iface;
|
||||
IDispatchEx IDispatchEx_iface;
|
||||
IWineJSDispatchHost IWineJSDispatchHost_iface;
|
||||
|
||||
nsCycleCollectingAutoRefCnt ccref;
|
||||
LONG task_magic;
|
||||
|
|
|
@ -258,3 +258,13 @@ interface IWineXMLHttpRequestPrivate : IDispatch
|
|||
}
|
||||
|
||||
} /* library MSHTML_private */
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(d359f2fe-5531-741b-a41a-5cf92edc971b),
|
||||
local
|
||||
]
|
||||
interface IWineJSDispatchHost : IDispatchEx
|
||||
{
|
||||
HRESULT CallFunction(DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller);
|
||||
}
|
||||
|
|
|
@ -1301,6 +1301,6 @@ HRESULT create_mutation_observer_ctor(compat_mode_t compat_mode, IDispatch **ret
|
|||
|
||||
init_dispatch(&obj->dispex, &mutation_observer_ctor_dispex, compat_mode);
|
||||
|
||||
*ret = (IDispatch *)&obj->dispex.IDispatchEx_iface;
|
||||
*ret = (IDispatch *)&obj->dispex.IWineJSDispatchHost_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -3542,7 +3542,7 @@ static HRESULT WINAPI DocObjDispatchEx_GetDispID(IDispatchEx *iface, BSTR name,
|
|||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_GetDispID(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, name, grfdex, pid);
|
||||
return IWineJSDispatchHost_GetDispID(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, name, grfdex, pid);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DocObjDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
|
@ -3550,29 +3550,29 @@ static HRESULT WINAPI DocObjDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, L
|
|||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_InvokeEx(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, id, lcid,
|
||||
wFlags, pdp, pvarRes, pei, pspCaller);
|
||||
return IWineJSDispatchHost_InvokeEx(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, id, lcid,
|
||||
wFlags, pdp, pvarRes, pei, pspCaller);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DocObjDispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
|
||||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_DeleteMemberByName(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, bstrName, grfdex);
|
||||
return IWineJSDispatchHost_DeleteMemberByName(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, bstrName, grfdex);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DocObjDispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
|
||||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_DeleteMemberByDispID(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, id);
|
||||
return IWineJSDispatchHost_DeleteMemberByDispID(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, id);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DocObjDispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_GetMemberProperties(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, id, grfdexFetch,
|
||||
return IWineJSDispatchHost_GetMemberProperties(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, id, grfdexFetch,
|
||||
pgrfdex);
|
||||
}
|
||||
|
||||
|
@ -3580,21 +3580,21 @@ static HRESULT WINAPI DocObjDispatchEx_GetMemberName(IDispatchEx *iface, DISPID
|
|||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_GetMemberName(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, id, name);
|
||||
return IWineJSDispatchHost_GetMemberName(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, id, name);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DocObjDispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
|
||||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_GetNextDispID(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, grfdex, id, pid);
|
||||
return IWineJSDispatchHost_GetNextDispID(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, grfdex, id, pid);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DocObjDispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
|
||||
{
|
||||
HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
|
||||
|
||||
return IDispatchEx_GetNameSpaceParent(&This->doc_node->node.event_target.dispex.IDispatchEx_iface, ppunk);
|
||||
return IWineJSDispatchHost_GetNameSpaceParent(&This->doc_node->node.event_target.dispex.IWineJSDispatchHost_iface, ppunk);
|
||||
}
|
||||
|
||||
static const IDispatchExVtbl DocObjDispatchExVtbl = {
|
||||
|
|
|
@ -2313,7 +2313,7 @@ static nsresult NSAPI media_query_list_callback_HandleChange(nsIDOMMediaQueryLis
|
|||
DISPPARAMS dp = { args, NULL, 1, 0 };
|
||||
|
||||
V_VT(args) = VT_DISPATCH;
|
||||
V_DISPATCH(args) = (IDispatch*)&media_query_list->dispex.IDispatchEx_iface;
|
||||
V_DISPATCH(args) = (IDispatch*)&media_query_list->dispex.IWineJSDispatchHost_iface;
|
||||
V_VT(&v) = VT_EMPTY;
|
||||
|
||||
TRACE("%p >>>\n", media_query_list);
|
||||
|
|
|
@ -1573,7 +1573,7 @@ static EventTarget *find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *
|
|||
}else if(!wcscmp(target_id, L"window")) {
|
||||
if(doc->window) {
|
||||
event_target = &doc->window->event_target;
|
||||
IDispatchEx_AddRef(&event_target->dispex.IDispatchEx_iface);
|
||||
IWineJSDispatchHost_AddRef(&event_target->dispex.IWineJSDispatchHost_iface);
|
||||
}
|
||||
}else {
|
||||
HTMLElement *target_elem;
|
||||
|
@ -1731,14 +1731,14 @@ void bind_event_scripts(HTMLDocumentNode *doc)
|
|||
if(event_disp) {
|
||||
event_target = find_event_target(doc, script_elem);
|
||||
if(event_target) {
|
||||
hres = IDispatchEx_QueryInterface(&event_target->dispex.IDispatchEx_iface, &IID_HTMLPluginContainer,
|
||||
hres = IWineJSDispatchHost_QueryInterface(&event_target->dispex.IWineJSDispatchHost_iface, &IID_HTMLPluginContainer,
|
||||
(void**)&plugin_container);
|
||||
if(SUCCEEDED(hres))
|
||||
bind_activex_event(doc, plugin_container, event, event_disp);
|
||||
else
|
||||
bind_target_event(doc, event_target, event, event_disp);
|
||||
|
||||
IDispatchEx_Release(&event_target->dispex.IDispatchEx_iface);
|
||||
IWineJSDispatchHost_Release(&event_target->dispex.IWineJSDispatchHost_iface);
|
||||
if(plugin_container)
|
||||
node_release(&plugin_container->element.node);
|
||||
}
|
||||
|
|
|
@ -352,6 +352,73 @@ sync_test("builtin_toString", function() {
|
|||
}
|
||||
});
|
||||
|
||||
sync_test("builtin_obj", function() {
|
||||
var v = document.documentMode;
|
||||
var f = document.createElement;
|
||||
var e;
|
||||
|
||||
if(v < 9) {
|
||||
ok(!(window instanceof Object), "window instance of Object");
|
||||
ok(!(document instanceof Object), "document instance of Object");
|
||||
ok(!("arguments" in f), "arguments in f");
|
||||
ok(!("length" in f), "length in f");
|
||||
e = 0;
|
||||
try {
|
||||
f.toString();
|
||||
}catch(ex) {
|
||||
e = ex.number;
|
||||
}
|
||||
ok(e === 0xa01b6 - 0x80000000, "[f.toString] e = " + e);
|
||||
try {
|
||||
window.toString.call(null);
|
||||
ok(false, "expected exception calling window.toString with null context");
|
||||
}catch(ex) {}
|
||||
}
|
||||
|
||||
e = 0;
|
||||
try {
|
||||
f.call(Object, "div");
|
||||
}catch(ex) {
|
||||
e = ex.number;
|
||||
}
|
||||
todo_wine_if(v >= 9).
|
||||
ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(Object, 'div')] e = " + e);
|
||||
|
||||
e = 0;
|
||||
try {
|
||||
f.call(null, "div");
|
||||
}catch(ex) {
|
||||
e = ex.number;
|
||||
}
|
||||
todo_wine_if(v >= 9).
|
||||
ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(null, 'div')] e = " + e);
|
||||
|
||||
var elem1 = f.call(document, "div");
|
||||
var elem2 = f.call(document, "br");
|
||||
document.body.appendChild(elem1);
|
||||
document.body.appendChild(elem2);
|
||||
elem1.onclick = function() { ok(false, "unexpected elem1.onclick"); };
|
||||
var clicked = false;
|
||||
elem2.onclick = function() { clicked = true; };
|
||||
elem1.click.call(elem2);
|
||||
ok(clicked === true, "elem2.onclick not called");
|
||||
|
||||
elem1 = f.apply(document, ["div"]);
|
||||
elem2 = f.apply(document, ["br"]);
|
||||
document.body.appendChild(elem1);
|
||||
document.body.appendChild(elem2);
|
||||
elem1.onclick = function() { ok(false, "unexpected elem1.onclick"); };
|
||||
clicked = false;
|
||||
elem2.onclick = function() { clicked = true; };
|
||||
elem1.click.apply(elem2);
|
||||
ok(clicked === true, "elem2.onclick not called");
|
||||
|
||||
try {
|
||||
elem1.click.apply(elem2, { length: -1 });
|
||||
ok(false, "exception expected");
|
||||
}catch(ex) {}
|
||||
});
|
||||
|
||||
sync_test("elem_props", function() {
|
||||
var elem = document.documentElement;
|
||||
|
||||
|
|
|
@ -8358,6 +8358,121 @@ static void test_MHTMLDocument(void)
|
|||
release_document(doc);
|
||||
}
|
||||
|
||||
static LONG get_document_elements_count(IHTMLDocument2 *doc)
|
||||
{
|
||||
LONG elements_count;
|
||||
IHTMLElementCollection *elements = NULL;
|
||||
|
||||
IHTMLDocument2_get_all(doc, &elements);
|
||||
IHTMLElementCollection_get_length(elements, &elements_count);
|
||||
|
||||
IHTMLElementCollection_Release(elements);
|
||||
return elements_count;
|
||||
}
|
||||
|
||||
static void test_MarkupContainer(IMarkupServices *markup_services)
|
||||
{
|
||||
IHTMLDOMNode *doc_node;
|
||||
IHTMLDocument2 *markup_container_doc;
|
||||
ITargetContainer *target_container_doc;
|
||||
IInternetSecurityManager *sec_manager;
|
||||
IMarkupContainer *container = NULL;
|
||||
ICustomDoc *custom_doc;
|
||||
IHTMLLocation *location = NULL;
|
||||
IHTMLElement *body = NULL;
|
||||
LONG elements_count;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IMarkupServices_CreateMarkupContainer(markup_services, &container);
|
||||
ok(hres == S_OK, "got 0x%08lx\n", hres);
|
||||
ok(container != NULL, "MarkupContainer is null.\n");
|
||||
if (!container) return;
|
||||
|
||||
hres = IMarkupContainer_QueryInterface(container, &IID_IHTMLDocument2, (void**)&markup_container_doc);
|
||||
ok(hres == S_OK, "got 0x%08lx\n", hres);
|
||||
|
||||
hres = IHTMLDocument2_get_location(markup_container_doc, &location);
|
||||
ok(hres == E_UNEXPECTED, "expected E_UNEXPECTED, got 0x%08lx\n", hres);
|
||||
ok(location == NULL, "expected null location\n");
|
||||
|
||||
hres = IHTMLDocument2_get_body(markup_container_doc, &body);
|
||||
ok(hres == S_OK, "got 0x%08lx\n", hres);
|
||||
ok(body == NULL, "expected null body\n");
|
||||
|
||||
elements_count = get_document_elements_count(markup_container_doc);
|
||||
ok(elements_count == 0, "expected document to not have elements\n");
|
||||
|
||||
hres = IMarkupContainer_QueryInterface(container, &IID_IHTMLDOMNode, (void**)&doc_node);
|
||||
todo_wine ok(hres == E_NOINTERFACE, "expected to fail with E_NOINTERFACE got 0x%08lx\n", hres);
|
||||
|
||||
hres = IHTMLDocument2_QueryInterface(markup_container_doc, &IID_IInternetSecurityManager, (void**)&sec_manager);
|
||||
ok(hres == E_NOINTERFACE, "expected to fail with E_NOINTERFACE got 0x%08lx\n", hres);
|
||||
|
||||
hres = IHTMLDocument2_QueryInterface(markup_container_doc, &IID_ITargetContainer, (void**)&target_container_doc);
|
||||
ok(hres == E_NOINTERFACE, "expected to fail with E_NOINTERFACE got 0x%08lx\n", hres);
|
||||
|
||||
hres = IHTMLDocument2_QueryInterface(markup_container_doc, &IID_ICustomDoc, (void**)&custom_doc);
|
||||
ok(hres == E_NOINTERFACE, "expected to fail with E_NOINTERFACE got 0x%08lx\n", hres);
|
||||
|
||||
IHTMLDocument2_Release(markup_container_doc);
|
||||
IMarkupContainer_Release(container);
|
||||
}
|
||||
|
||||
static void test_MarkupServices_ParseString(IMarkupServices *markup_services, IHTMLDocument2 *doc)
|
||||
{
|
||||
HRESULT hres;
|
||||
LONG document_elements_count, markup_container_elements_count;
|
||||
IHTMLElement *body;
|
||||
BSTR inner_text;
|
||||
IHTMLDocument2 *markup_container_doc = NULL;
|
||||
IMarkupContainer *markup_container = NULL;
|
||||
|
||||
hres = IMarkupServices_ParseString(markup_services, (OLECHAR*)L"<div>Hello World</div>", 0, &markup_container, NULL, NULL);
|
||||
ok(hres == S_OK, "got 0x%08lx\n", hres);
|
||||
ok(markup_container != NULL, "MarkupContainer is null.\n");
|
||||
if (!markup_container) return;
|
||||
|
||||
hres = IMarkupContainer_QueryInterface(markup_container, &IID_IHTMLDocument2, (void**)&markup_container_doc);
|
||||
ok(hres == S_OK, "failed to query interface of MarkupContainer 0x%08lx\n", hres);
|
||||
|
||||
markup_container_elements_count = get_document_elements_count(markup_container_doc);
|
||||
ok(markup_container_elements_count == 5, "expected markup container to have 5 elements but got %ld\n",
|
||||
markup_container_elements_count);
|
||||
|
||||
document_elements_count = get_document_elements_count(doc);
|
||||
ok(document_elements_count != markup_container_elements_count,
|
||||
"expected document to not have the same elements count of the markup container %ld == %ld\n",
|
||||
document_elements_count, markup_container_elements_count);
|
||||
|
||||
hres = IHTMLDocument2_get_body(markup_container_doc, &body);
|
||||
ok(hres == S_OK, "got 0x%08lx\n", hres);
|
||||
ok(body != NULL, "got null body\n");
|
||||
|
||||
hres = IHTMLElement_get_innerText(body, &inner_text);
|
||||
ok(hres == S_OK, "failed to get inner text error 0x%08lx\n", hres);
|
||||
ok(inner_text != NULL, "got a null pointer for inner text\n");
|
||||
ok(!wcscmp(inner_text, L"Hello World"), "strings don't match, got %ls\n", inner_text);
|
||||
|
||||
SysFreeString(inner_text);
|
||||
IHTMLElement_Release(body);
|
||||
IHTMLDocument2_Release(markup_container_doc);
|
||||
IMarkupContainer_Release(markup_container);
|
||||
}
|
||||
|
||||
static void test_MarkupServices(IHTMLDocument2 *doc)
|
||||
{
|
||||
HRESULT hres;
|
||||
IMarkupServices *markup_services = NULL;
|
||||
|
||||
hres = IHTMLDocument2_QueryInterface(doc, &IID_IMarkupServices, (void**)&markup_services);
|
||||
ok(hres == S_OK, "got 0x%08lx\n", hres);
|
||||
|
||||
test_MarkupContainer(markup_services);
|
||||
test_MarkupServices_ParseString(markup_services, doc);
|
||||
|
||||
IMarkupServices_Release(markup_services);
|
||||
}
|
||||
|
||||
static void test_HTMLDocument_hlink(DWORD status)
|
||||
{
|
||||
IHTMLDocument2 *doc;
|
||||
|
@ -8524,6 +8639,7 @@ static void test_HTMLDocument_http(BOOL with_wbapp)
|
|||
test_travellog(doc);
|
||||
test_binding_ui((IUnknown*)doc);
|
||||
test_doc_domain(doc);
|
||||
test_MarkupServices(doc);
|
||||
|
||||
nav_url = nav_serv_url = L"http://test.winehq.org/tests/winehq_snapshot/"; /* for valid prev nav_url */
|
||||
if(support_wbapp) {
|
||||
|
|
|
@ -76,5 +76,5 @@ EXTRA_OBJS = unix/version.o
|
|||
unix_loader_EXTRADEFS = \
|
||||
-DBINDIR=\"${bindir}\" \
|
||||
-DSYSTEMDLLPATH=\"${system_dllpath}\" \
|
||||
-DDLL_TO_BINDIR=\"`${MAKEDEP} -R ${dlldir} ${bindir}`\" \
|
||||
-DDLL_TO_BINDIR=\"`${MAKEDEP} -R ${libdir}/wine ${bindir}`\" \
|
||||
-DBIN_TO_DATADIR=\"`${MAKEDEP} -R ${bindir} ${datadir}/wine`\"
|
||||
|
|
|
@ -340,7 +340,7 @@
|
|||
@ stdcall -syscall NtQueueApcThread(long ptr long long long)
|
||||
@ stdcall -syscall NtQueueApcThreadEx(long long ptr long long long)
|
||||
@ stdcall -syscall NtRaiseException(ptr ptr long)
|
||||
@ stdcall -syscall NtRaiseHardError(long long ptr ptr long ptr)
|
||||
@ stdcall -syscall NtRaiseHardError(long long long ptr long ptr)
|
||||
@ stdcall -syscall NtReadFile(long long ptr ptr ptr ptr long ptr ptr)
|
||||
@ stdcall -syscall NtReadFileScatter(long long ptr ptr ptr ptr long ptr ptr)
|
||||
# @ stub NtReadRequestData
|
||||
|
@ -650,7 +650,7 @@
|
|||
# @ stub RtlEnumerateGenericTableAvl
|
||||
# @ stub RtlEnumerateGenericTableLikeADirectory
|
||||
@ stdcall RtlEnumerateGenericTableWithoutSplaying(ptr ptr)
|
||||
# @ stub RtlEnumerateGenericTableWithoutSplayingAvl
|
||||
@ stdcall RtlEnumerateGenericTableWithoutSplayingAvl(ptr ptr)
|
||||
@ stub RtlEnumerateProperties
|
||||
@ stdcall RtlEqualComputerName(ptr ptr)
|
||||
@ stdcall RtlEqualDomainName(ptr ptr)
|
||||
|
@ -743,8 +743,7 @@
|
|||
# @ stub RtlGetLengthWithoutTrailingPathSeperators
|
||||
@ stdcall RtlGetLocaleFileMappingAddress(ptr ptr ptr)
|
||||
@ stdcall RtlGetLongestNtPathLength()
|
||||
@ stdcall -syscall -arch=win32 RtlGetNativeSystemInformation(long ptr long ptr) NtWow64GetNativeSystemInformation
|
||||
@ stdcall -syscall -arch=win64 RtlGetNativeSystemInformation(long ptr long ptr) NtQuerySystemInformation
|
||||
@ stdcall RtlGetNativeSystemInformation(long ptr long ptr)
|
||||
# @ stub RtlGetNextRange
|
||||
@ stdcall RtlGetNtGlobalFlags()
|
||||
@ stdcall RtlGetNtProductType(ptr)
|
||||
|
@ -899,7 +898,7 @@
|
|||
@ stdcall RtlNtStatusToDosError(long)
|
||||
@ stdcall RtlNtStatusToDosErrorNoTeb(long)
|
||||
@ stdcall RtlNumberGenericTableElements(ptr)
|
||||
# @ stub RtlNumberGenericTableElementsAvl
|
||||
@ stdcall RtlNumberGenericTableElementsAvl(ptr)
|
||||
@ stdcall RtlNumberOfClearBits(ptr)
|
||||
@ stdcall RtlNumberOfSetBits(ptr)
|
||||
@ stdcall RtlOemStringToUnicodeSize(ptr)
|
||||
|
@ -1390,7 +1389,7 @@
|
|||
@ stdcall -private -syscall ZwQueueApcThread(long ptr long long long) NtQueueApcThread
|
||||
@ stdcall -private -syscall ZwQueueApcThreadEx(long long ptr long long long) NtQueueApcThreadEx
|
||||
@ stdcall -private -syscall ZwRaiseException(ptr ptr long) NtRaiseException
|
||||
@ stdcall -private -syscall ZwRaiseHardError(long long ptr ptr long ptr) NtRaiseHardError
|
||||
@ stdcall -private -syscall ZwRaiseHardError(long long long ptr long ptr) NtRaiseHardError
|
||||
@ stdcall -private -syscall ZwReadFile(long long ptr ptr ptr ptr long ptr ptr) NtReadFile
|
||||
@ stdcall -private -syscall ZwReadFileScatter(long long ptr ptr ptr ptr long ptr ptr) NtReadFileScatter
|
||||
# @ stub ZwReadRequestData
|
||||
|
|
|
@ -249,7 +249,7 @@ NTSTATUS WINAPI RtlWow64GetThreadSelectorEntry( HANDLE handle, THREAD_DESCRIPTOR
|
|||
{
|
||||
/* hardcoded values */
|
||||
#ifdef __arm64ec__
|
||||
context.SegCs = 0x33;
|
||||
context.SegCs = 0x23;
|
||||
context.SegSs = 0x2b;
|
||||
context.SegFs = 0x53;
|
||||
#elif defined(__x86_64__)
|
||||
|
|
127
dlls/ntdll/reg.c
127
dlls/ntdll/reg.c
|
@ -243,58 +243,59 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo,
|
|||
PRTL_QUERY_REGISTRY_TABLE pQuery, PVOID pContext, PVOID pEnvironment)
|
||||
{
|
||||
PUNICODE_STRING str = pQuery->EntryContext;
|
||||
ULONG type, len, offset, count, res;
|
||||
UNICODE_STRING src, dst;
|
||||
WCHAR *data, *wstr;
|
||||
LONG *bin;
|
||||
ULONG offset;
|
||||
PWSTR wstr;
|
||||
DWORD res;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
ULONG len;
|
||||
|
||||
if (pInfo == NULL)
|
||||
if (pInfo)
|
||||
{
|
||||
ULONG default_size = pQuery->DefaultLength;
|
||||
if (!default_size && pQuery->DefaultType == REG_SZ && pQuery->DefaultData)
|
||||
default_size = (wcslen(pQuery->DefaultData) + 1) * sizeof(WCHAR);
|
||||
|
||||
if (pQuery->Flags & RTL_QUERY_REGISTRY_DIRECT)
|
||||
{
|
||||
if (pQuery->QueryRoutine)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (pQuery->DefaultType == REG_SZ || pQuery->DefaultType == REG_EXPAND_SZ ||
|
||||
pQuery->DefaultType == REG_MULTI_SZ || pQuery->DefaultType == REG_LINK)
|
||||
{
|
||||
if (!pQuery->DefaultData)
|
||||
return STATUS_DATA_OVERRUN;
|
||||
if (str->MaximumLength < default_size)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
memcpy(str->Buffer, pQuery->DefaultData, default_size);
|
||||
str->Length = default_size - sizeof(WCHAR);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (pQuery->QueryRoutine)
|
||||
{
|
||||
status = pQuery->QueryRoutine(pQuery->Name, pQuery->DefaultType, pQuery->DefaultData,
|
||||
default_size, pContext, pQuery->EntryContext);
|
||||
}
|
||||
return status;
|
||||
type = pInfo->Type;
|
||||
data = (WCHAR*)((char*)pInfo + pInfo->DataOffset);
|
||||
len = pInfo->DataLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = pQuery->DefaultType;
|
||||
data = pQuery->DefaultData;
|
||||
len = pQuery->DefaultLength;
|
||||
|
||||
if (!data)
|
||||
return STATUS_DATA_OVERRUN;
|
||||
|
||||
if (!len)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ:
|
||||
case REG_LINK:
|
||||
len = (wcslen(data) + 1) * sizeof(WCHAR);
|
||||
break;
|
||||
|
||||
case REG_MULTI_SZ:
|
||||
for (wstr = data; *wstr; wstr += count)
|
||||
{
|
||||
count = wcslen(wstr) + 1;
|
||||
len += count * sizeof(WCHAR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
len = pInfo->DataLength;
|
||||
|
||||
if (pQuery->Flags & RTL_QUERY_REGISTRY_DIRECT)
|
||||
{
|
||||
if (pQuery->QueryRoutine)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
switch(pInfo->Type)
|
||||
switch (type)
|
||||
{
|
||||
case REG_EXPAND_SZ:
|
||||
if (!(pQuery->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
|
||||
{
|
||||
RtlInitUnicodeString(&src, (WCHAR*)(((CHAR*)pInfo) + pInfo->DataOffset));
|
||||
RtlInitUnicodeString(&src, data);
|
||||
res = 0;
|
||||
dst.MaximumLength = 0;
|
||||
RtlExpandEnvironmentStrings_U(pEnvironment, &src, &dst, &res);
|
||||
|
@ -307,12 +308,12 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo,
|
|||
case REG_SZ:
|
||||
case REG_LINK:
|
||||
if (str->Buffer == NULL)
|
||||
RtlCreateUnicodeString(str, (WCHAR*)(((CHAR*)pInfo) + pInfo->DataOffset));
|
||||
RtlCreateUnicodeString(str, data);
|
||||
else
|
||||
{
|
||||
if (str->MaximumLength < len)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
memcpy(str->Buffer, (char*)pInfo + pInfo->DataOffset, len);
|
||||
memcpy(str->Buffer, data, len);
|
||||
str->Length = len - sizeof(WCHAR);
|
||||
}
|
||||
break;
|
||||
|
@ -327,48 +328,45 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo,
|
|||
str->Buffer = RtlAllocateHeap(GetProcessHeap(), 0, len);
|
||||
str->MaximumLength = len;
|
||||
}
|
||||
len = min(len, str->MaximumLength);
|
||||
else if (str->MaximumLength < len)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
len -= sizeof(WCHAR);
|
||||
memcpy(str->Buffer, ((CHAR*)pInfo) + pInfo->DataOffset, len);
|
||||
memcpy(str->Buffer, data, len);
|
||||
str->Buffer[len / sizeof(WCHAR)] = 0;
|
||||
str->Length = len;
|
||||
break;
|
||||
|
||||
default:
|
||||
bin = pQuery->EntryContext;
|
||||
if (pInfo->DataLength <= sizeof(ULONG))
|
||||
memcpy(bin, ((CHAR*)pInfo) + pInfo->DataOffset,
|
||||
pInfo->DataLength);
|
||||
if (len <= sizeof(ULONG))
|
||||
memcpy(bin, data, len);
|
||||
else
|
||||
{
|
||||
if (bin[0] <= sizeof(ULONG))
|
||||
if (bin[0] < 0)
|
||||
{
|
||||
memcpy(&bin[1], ((CHAR*)pInfo) + pInfo->DataOffset,
|
||||
min(-bin[0], pInfo->DataLength));
|
||||
if (len <= -bin[0])
|
||||
memcpy(bin, data, len);
|
||||
}
|
||||
else
|
||||
else if (len <= bin[0])
|
||||
{
|
||||
len = min(bin[0], pInfo->DataLength);
|
||||
bin[1] = len;
|
||||
bin[2] = pInfo->Type;
|
||||
memcpy(&bin[3], ((CHAR*)pInfo) + pInfo->DataOffset, len);
|
||||
bin[0] = len;
|
||||
bin[1] = type;
|
||||
memcpy(bin + 2, data, len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (pQuery->QueryRoutine)
|
||||
{
|
||||
if((pQuery->Flags & RTL_QUERY_REGISTRY_NOEXPAND) ||
|
||||
(pInfo->Type != REG_EXPAND_SZ && pInfo->Type != REG_MULTI_SZ))
|
||||
(type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
|
||||
{
|
||||
status = pQuery->QueryRoutine(pQuery->Name, pInfo->Type,
|
||||
((CHAR*)pInfo) + pInfo->DataOffset, pInfo->DataLength,
|
||||
pContext, pQuery->EntryContext);
|
||||
status = pQuery->QueryRoutine(pQuery->Name, type, data, len, pContext, pQuery->EntryContext);
|
||||
}
|
||||
else if (pInfo->Type == REG_EXPAND_SZ)
|
||||
else if (type == REG_EXPAND_SZ)
|
||||
{
|
||||
RtlInitUnicodeString(&src, (WCHAR*)(((CHAR*)pInfo) + pInfo->DataOffset));
|
||||
RtlInitUnicodeString(&src, data);
|
||||
res = 0;
|
||||
dst.MaximumLength = 0;
|
||||
RtlExpandEnvironmentStrings_U(pEnvironment, &src, &dst, &res);
|
||||
|
@ -376,17 +374,16 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo,
|
|||
dst.MaximumLength = res;
|
||||
dst.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, res * sizeof(WCHAR));
|
||||
RtlExpandEnvironmentStrings_U(pEnvironment, &src, &dst, &res);
|
||||
status = pQuery->QueryRoutine(pQuery->Name, pInfo->Type, dst.Buffer,
|
||||
dst.Length, pContext, pQuery->EntryContext);
|
||||
status = pQuery->QueryRoutine(pQuery->Name, REG_SZ, dst.Buffer, res, pContext, pQuery->EntryContext);
|
||||
RtlFreeHeap(GetProcessHeap(), 0, dst.Buffer);
|
||||
}
|
||||
else /* REG_MULTI_SZ */
|
||||
{
|
||||
for (offset = 0; offset < pInfo->DataLength; offset += len)
|
||||
for (offset = 0; offset < len; offset += count)
|
||||
{
|
||||
wstr = (WCHAR*)((char*)pInfo + pInfo->DataOffset + offset);
|
||||
len = (wcslen(wstr) + 1) * sizeof(WCHAR);
|
||||
status = pQuery->QueryRoutine(pQuery->Name, REG_SZ, wstr, len, pContext, pQuery->EntryContext);
|
||||
wstr = (WCHAR*)((char*)data + offset);
|
||||
count = (wcslen(wstr) + 1) * sizeof(WCHAR);
|
||||
status = pQuery->QueryRoutine(pQuery->Name, REG_SZ, wstr, count, pContext, pQuery->EntryContext);
|
||||
if (status != STATUS_SUCCESS && status != STATUS_BUFFER_TOO_SMALL)
|
||||
return status;
|
||||
}
|
||||
|
|
699
dlls/ntdll/rtl.c
699
dlls/ntdll/rtl.c
|
@ -27,22 +27,16 @@
|
|||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "winsock2.h"
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/exception.h"
|
||||
#include "ntdll_misc.h"
|
||||
#include "in6addr.h"
|
||||
#include "ddk/ntddk.h"
|
||||
#include "ddk/ntifs.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(debugstr);
|
||||
|
||||
#define htons(x) RtlUshortByteSwap(x)
|
||||
#define ntohs(x) RtlUshortByteSwap(x)
|
||||
|
||||
/* CRC polynomial 0xedb88320 */
|
||||
static const DWORD CRC_table[256] =
|
||||
{
|
||||
|
@ -91,16 +85,6 @@ static const DWORD CRC_table[256] =
|
|||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
static const int hex_table[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x20-0x2F */
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x40-0x4F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x50-0x5F */
|
||||
-1, 10, 11, 12, 13, 14, 15 /* 0x60-0x66 */
|
||||
};
|
||||
|
||||
|
||||
static LONG WINAPI debug_exception_handler( EXCEPTION_POINTERS *eptr )
|
||||
{
|
||||
|
@ -207,7 +191,7 @@ void WINAPI RtlInitializeGenericTable(RTL_GENERIC_TABLE *table, PRTL_GENERIC_COM
|
|||
/******************************************************************************
|
||||
* RtlEnumerateGenericTableWithoutSplaying [NTDLL.@]
|
||||
*/
|
||||
void * WINAPI RtlEnumerateGenericTableWithoutSplaying(RTL_GENERIC_TABLE *table, void *previous)
|
||||
void * WINAPI RtlEnumerateGenericTableWithoutSplaying(RTL_GENERIC_TABLE *table, PVOID *previous)
|
||||
{
|
||||
static int warn_once;
|
||||
|
||||
|
@ -419,632 +403,6 @@ ULONG WINAPI RtlRandomEx( ULONG *seed )
|
|||
return RtlRandom( seed );
|
||||
}
|
||||
|
||||
static BOOL parse_ipv4_component(const WCHAR **str, BOOL strict, ULONG *value)
|
||||
{
|
||||
int base = 10, d;
|
||||
WCHAR c;
|
||||
ULONG cur_value, prev_value = 0;
|
||||
BOOL success = FALSE;
|
||||
|
||||
if (**str == '.')
|
||||
{
|
||||
*str += 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((*str)[0] == '0')
|
||||
{
|
||||
if ((*str)[1] == 'x' || (*str)[1] == 'X')
|
||||
{
|
||||
*str += 2;
|
||||
if (strict) return FALSE;
|
||||
base = 16;
|
||||
}
|
||||
else if ((*str)[1] >= '0' && (*str)[1] <= '9')
|
||||
{
|
||||
*str += 1;
|
||||
if (strict) return FALSE;
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
|
||||
for (cur_value = 0; **str; *str += 1)
|
||||
{
|
||||
c = **str;
|
||||
if (c >= ARRAY_SIZE(hex_table)) break;
|
||||
d = hex_table[c];
|
||||
if (d == -1 || d >= base) break;
|
||||
cur_value = cur_value * base + d;
|
||||
success = TRUE;
|
||||
if (cur_value < prev_value) return FALSE; /* overflow */
|
||||
prev_value = cur_value;
|
||||
}
|
||||
|
||||
if (success) *value = cur_value;
|
||||
return success;
|
||||
}
|
||||
|
||||
static NTSTATUS ipv4_string_to_address(const WCHAR *str, BOOL strict,
|
||||
const WCHAR **terminator, IN_ADDR *address, USHORT *port)
|
||||
{
|
||||
ULONG fields[4];
|
||||
int n = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!parse_ipv4_component(&str, strict, &fields[n]))
|
||||
goto error;
|
||||
n++;
|
||||
if (*str != '.')
|
||||
break;
|
||||
if (n == 4)
|
||||
goto error;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (strict && n < 4)
|
||||
goto error;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 4:
|
||||
if (fields[0] > 0xFF || fields[1] > 0xFF || fields[2] > 0xFF || fields[3] > 0xFF)
|
||||
goto error;
|
||||
address->S_un.S_un_b.s_b1 = fields[0];
|
||||
address->S_un.S_un_b.s_b2 = fields[1];
|
||||
address->S_un.S_un_b.s_b3 = fields[2];
|
||||
address->S_un.S_un_b.s_b4 = fields[3];
|
||||
break;
|
||||
case 3:
|
||||
if (fields[0] > 0xFF || fields[1] > 0xFF || fields[2] > 0xFFFF)
|
||||
goto error;
|
||||
address->S_un.S_un_b.s_b1 = fields[0];
|
||||
address->S_un.S_un_b.s_b2 = fields[1];
|
||||
address->S_un.S_un_b.s_b3 = (fields[2] & 0xFF00) >> 8;
|
||||
address->S_un.S_un_b.s_b4 = (fields[2] & 0x00FF);
|
||||
break;
|
||||
case 2:
|
||||
if (fields[0] > 0xFF || fields[1] > 0xFFFFFF)
|
||||
goto error;
|
||||
address->S_un.S_un_b.s_b1 = fields[0];
|
||||
address->S_un.S_un_b.s_b2 = (fields[1] & 0xFF0000) >> 16;
|
||||
address->S_un.S_un_b.s_b3 = (fields[1] & 0x00FF00) >> 8;
|
||||
address->S_un.S_un_b.s_b4 = (fields[1] & 0x0000FF);
|
||||
break;
|
||||
case 1:
|
||||
address->S_un.S_un_b.s_b1 = (fields[0] & 0xFF000000) >> 24;
|
||||
address->S_un.S_un_b.s_b2 = (fields[0] & 0x00FF0000) >> 16;
|
||||
address->S_un.S_un_b.s_b3 = (fields[0] & 0x0000FF00) >> 8;
|
||||
address->S_un.S_un_b.s_b4 = (fields[0] & 0x000000FF);
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (terminator) *terminator = str;
|
||||
|
||||
if (*str == ':')
|
||||
{
|
||||
str++;
|
||||
if (!parse_ipv4_component(&str, FALSE, &fields[0]))
|
||||
goto error;
|
||||
if (!fields[0] || fields[0] > 0xFFFF || *str)
|
||||
goto error;
|
||||
if (port)
|
||||
{
|
||||
*port = htons(fields[0]);
|
||||
if (terminator) *terminator = str;
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminator && *str)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
if (terminator) *terminator = str;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressExW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressExW(const WCHAR *str, BOOLEAN strict, IN_ADDR *address, USHORT *port)
|
||||
{
|
||||
TRACE("(%s, %u, %p, %p)\n", debugstr_w(str), strict, address, port);
|
||||
if (!str || !address || !port) return STATUS_INVALID_PARAMETER;
|
||||
return ipv4_string_to_address(str, strict, NULL, address, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressW(const WCHAR *str, BOOLEAN strict, const WCHAR **terminator, IN_ADDR *address)
|
||||
{
|
||||
TRACE("(%s, %u, %p, %p)\n", debugstr_w(str), strict, terminator, address);
|
||||
return ipv4_string_to_address(str, strict, terminator, address, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressExA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressExA(const char *str, BOOLEAN strict, IN_ADDR *address, USHORT *port)
|
||||
{
|
||||
WCHAR wstr[32];
|
||||
|
||||
TRACE("(%s, %u, %p, %p)\n", debugstr_a(str), strict, address, port);
|
||||
|
||||
if (!str || !address || !port)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
return ipv4_string_to_address(wstr, strict, NULL, address, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressA(const char *str, BOOLEAN strict, const char **terminator, IN_ADDR *address)
|
||||
{
|
||||
WCHAR wstr[32];
|
||||
const WCHAR *wterminator;
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("(%s, %u, %p, %p)\n", debugstr_a(str), strict, terminator, address);
|
||||
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
ret = ipv4_string_to_address(wstr, strict, &wterminator, address, NULL);
|
||||
if (terminator) *terminator = str + (wterminator - wstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL parse_ipv6_component(const WCHAR **str, int base, ULONG *value)
|
||||
{
|
||||
WCHAR *terminator;
|
||||
if (**str >= ARRAY_SIZE(hex_table) || hex_table[**str] == -1) return FALSE;
|
||||
*value = min(wcstoul(*str, &terminator, base), 0x7FFFFFFF);
|
||||
if (*terminator == '0') terminator++; /* "0x" but nothing valid after */
|
||||
else if (terminator == *str) return FALSE;
|
||||
*str = terminator;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NTSTATUS ipv6_string_to_address(const WCHAR *str, BOOL ex,
|
||||
const WCHAR **terminator, IN6_ADDR *address, ULONG *scope, USHORT *port)
|
||||
{
|
||||
BOOL expecting_port = FALSE, has_0x = FALSE, too_big = FALSE;
|
||||
int n_bytes = 0, n_ipv4_bytes = 0, gap = -1;
|
||||
ULONG ip_component, scope_component = 0, port_component = 0;
|
||||
const WCHAR *prev_str;
|
||||
|
||||
if (str[0] == '[')
|
||||
{
|
||||
if (!ex) goto error;
|
||||
expecting_port = TRUE;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (str[0] == ':')
|
||||
{
|
||||
if (str[1] != ':') goto error;
|
||||
str++;
|
||||
address->u.Word[0] = 0;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!n_ipv4_bytes && *str == ':')
|
||||
{
|
||||
/* double colon */
|
||||
if (gap != -1) goto error;
|
||||
str++;
|
||||
prev_str = str;
|
||||
gap = n_bytes;
|
||||
if (n_bytes == 14 || !parse_ipv6_component(&str, 16, &ip_component)) break;
|
||||
str = prev_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_str = str;
|
||||
}
|
||||
|
||||
if (!n_ipv4_bytes && n_bytes <= (gap != -1 ? 10 : 12))
|
||||
{
|
||||
if (parse_ipv6_component(&str, 10, &ip_component) && *str == '.')
|
||||
n_ipv4_bytes = 1;
|
||||
str = prev_str;
|
||||
}
|
||||
|
||||
if (n_ipv4_bytes)
|
||||
{
|
||||
/* IPv4 component */
|
||||
if (!parse_ipv6_component(&str, 10, &ip_component)) goto error;
|
||||
if (str - prev_str > 3 || ip_component > 255)
|
||||
{
|
||||
too_big = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*str != '.' && (n_ipv4_bytes < 4 || (n_bytes < 15 && gap == -1))) goto error;
|
||||
address->u.Byte[n_bytes] = ip_component;
|
||||
n_bytes++;
|
||||
}
|
||||
if (n_ipv4_bytes == 4 || *str != '.') break;
|
||||
n_ipv4_bytes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* IPv6 component */
|
||||
if (!parse_ipv6_component(&str, 16, &ip_component)) goto error;
|
||||
if (prev_str[0] == '0' && (prev_str[1] == 'x' || prev_str[1] == 'X'))
|
||||
{
|
||||
/* Windows "feature": the last IPv6 component can start with "0x" and be longer than 4 digits */
|
||||
if (terminator) *terminator = prev_str + 1; /* Windows says that the "x" is the terminator */
|
||||
if (n_bytes < 14 && gap == -1) return STATUS_INVALID_PARAMETER;
|
||||
address->u.Word[n_bytes/2] = htons(ip_component);
|
||||
n_bytes += 2;
|
||||
has_0x = TRUE;
|
||||
goto fill_gap;
|
||||
}
|
||||
if (*str != ':' && n_bytes < 14 && gap == -1) goto error;
|
||||
if (str - prev_str > 4)
|
||||
too_big = TRUE;
|
||||
else
|
||||
address->u.Word[n_bytes/2] = htons(ip_component);
|
||||
n_bytes += 2;
|
||||
if (*str != ':' || (gap != -1 && str[1] == ':')) break;
|
||||
}
|
||||
if (n_bytes == (gap != -1 ? 14 : 16)) break;
|
||||
if (too_big) return STATUS_INVALID_PARAMETER;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (terminator) *terminator = str;
|
||||
if (too_big) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
fill_gap:
|
||||
if (gap == -1)
|
||||
{
|
||||
if (n_bytes < 16) goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(address->u.Byte + 16 - (n_bytes - gap), address->u.Byte + gap, n_bytes - gap);
|
||||
memset(address->u.Byte + gap, 0, 16 - n_bytes);
|
||||
}
|
||||
|
||||
if (ex)
|
||||
{
|
||||
if (has_0x) goto error;
|
||||
|
||||
if (*str == '%')
|
||||
{
|
||||
str++;
|
||||
if (!parse_ipv4_component(&str, TRUE, &scope_component)) goto error;
|
||||
}
|
||||
|
||||
if (expecting_port)
|
||||
{
|
||||
if (*str != ']') goto error;
|
||||
str++;
|
||||
if (*str == ':')
|
||||
{
|
||||
str++;
|
||||
if (!parse_ipv4_component(&str, FALSE, &port_component)) goto error;
|
||||
if (!port_component || port_component > 0xFFFF || *str) goto error;
|
||||
port_component = htons(port_component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminator && *str) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (scope) *scope = scope_component;
|
||||
if (port) *port = port_component;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
if (terminator) *terminator = str;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressExW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS NTAPI RtlIpv6StringToAddressExW(const WCHAR *str, IN6_ADDR *address, ULONG *scope, USHORT *port)
|
||||
{
|
||||
TRACE("(%s, %p, %p, %p)\n", debugstr_w(str), address, scope, port);
|
||||
if (!str || !address || !scope || !port) return STATUS_INVALID_PARAMETER;
|
||||
return ipv6_string_to_address(str, TRUE, NULL, address, scope, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6StringToAddressW(const WCHAR *str, const WCHAR **terminator, IN6_ADDR *address)
|
||||
{
|
||||
TRACE("(%s, %p, %p)\n", debugstr_w(str), terminator, address);
|
||||
return ipv6_string_to_address(str, FALSE, terminator, address, NULL, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressExA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6StringToAddressExA(const char *str, IN6_ADDR *address, ULONG *scope, USHORT *port)
|
||||
{
|
||||
WCHAR wstr[128];
|
||||
|
||||
TRACE("(%s, %p, %p, %p)\n", debugstr_a(str), address, scope, port);
|
||||
|
||||
if (!str || !address || !scope || !port)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
return ipv6_string_to_address(wstr, TRUE, NULL, address, scope, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6StringToAddressA(const char *str, const char **terminator, IN6_ADDR *address)
|
||||
{
|
||||
WCHAR wstr[128];
|
||||
const WCHAR *wterminator = NULL;
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("(%s, %p, %p)\n", debugstr_a(str), terminator, address);
|
||||
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
ret = ipv6_string_to_address(wstr, FALSE, &wterminator, address, NULL, NULL);
|
||||
if (terminator && wterminator) *terminator = str + (wterminator - wstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringExW [NTDLL.@]
|
||||
*
|
||||
* Convert the given ipv4 address and optional the port to a string
|
||||
*
|
||||
* PARAMS
|
||||
* pin [I] PTR to the ip address to convert (network byte order)
|
||||
* port [I] optional port to convert (network byte order)
|
||||
* buffer [O] destination buffer for the result
|
||||
* psize [IO] PTR to available/used size of the destination buffer
|
||||
*
|
||||
* RETURNS
|
||||
* Success: STATUS_SUCCESS
|
||||
* Failure: STATUS_INVALID_PARAMETER
|
||||
*
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *pin, USHORT port, LPWSTR buffer, PULONG psize)
|
||||
{
|
||||
WCHAR tmp_ip[32];
|
||||
ULONG needed;
|
||||
|
||||
if (!pin || !buffer || !psize)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
TRACE("(%p:0x%lx, %d, %p, %p:%ld)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
|
||||
|
||||
needed = swprintf(tmp_ip, ARRAY_SIZE(tmp_ip), L"%u.%u.%u.%u",
|
||||
pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
|
||||
pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
|
||||
|
||||
if (port) needed += swprintf(tmp_ip + needed, ARRAY_SIZE(tmp_ip) - needed, L":%u", ntohs(port));
|
||||
|
||||
if (*psize > needed) {
|
||||
*psize = needed + 1;
|
||||
wcscpy(buffer, tmp_ip);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
*psize = needed + 1;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringExA [NTDLL.@]
|
||||
*
|
||||
* Convert the given ipv4 address and optional the port to a string
|
||||
*
|
||||
* See RtlIpv4AddressToStringExW
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4AddressToStringExA(const IN_ADDR *pin, USHORT port, LPSTR buffer, PULONG psize)
|
||||
{
|
||||
CHAR tmp_ip[32];
|
||||
ULONG needed;
|
||||
|
||||
if (!pin || !buffer || !psize)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
TRACE("(%p:0x%lx, %d, %p, %p:%ld)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
|
||||
|
||||
needed = sprintf(tmp_ip, "%u.%u.%u.%u",
|
||||
pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
|
||||
pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
|
||||
|
||||
if (port) needed += sprintf(tmp_ip + needed, ":%u", ntohs(port));
|
||||
|
||||
if (*psize > needed) {
|
||||
*psize = needed + 1;
|
||||
strcpy(buffer, tmp_ip);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
*psize = needed + 1;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringW [NTDLL.@]
|
||||
*
|
||||
* Convert the given ipv4 address to a string
|
||||
*
|
||||
* PARAMS
|
||||
* pin [I] PTR to the ip address to convert (network byte order)
|
||||
* buffer [O] destination buffer for the result (at least 16 character)
|
||||
*
|
||||
* RETURNS
|
||||
* PTR to the 0 character at the end of the converted string
|
||||
*
|
||||
*/
|
||||
WCHAR * WINAPI RtlIpv4AddressToStringW(const IN_ADDR *pin, LPWSTR buffer)
|
||||
{
|
||||
ULONG size = 16;
|
||||
|
||||
if (RtlIpv4AddressToStringExW(pin, 0, buffer, &size)) size = 0;
|
||||
return buffer + size - 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringA [NTDLL.@]
|
||||
*
|
||||
* Convert the given ipv4 address to a string
|
||||
*
|
||||
* See RtlIpv4AddressToStringW
|
||||
*/
|
||||
CHAR * WINAPI RtlIpv4AddressToStringA(const IN_ADDR *pin, LPSTR buffer)
|
||||
{
|
||||
ULONG size = 16;
|
||||
|
||||
if (RtlIpv4AddressToStringExA(pin, 0, buffer, &size)) size = 0;
|
||||
return buffer + size - 1;
|
||||
}
|
||||
|
||||
static BOOL is_ipv4_in_ipv6(const IN6_ADDR *address)
|
||||
{
|
||||
if (address->s6_words[5] == htons(0x5efe) && (address->s6_words[4] & ~htons(0x200)) == 0)
|
||||
return TRUE;
|
||||
if (*(UINT64 *)address != 0)
|
||||
return FALSE;
|
||||
if (address->s6_words[4] != 0 && address->s6_words[4] != 0xffff)
|
||||
return FALSE;
|
||||
if (address->s6_words[4] == 0 && address->s6_words[5] != 0 && address->s6_words[5] != 0xffff)
|
||||
return FALSE;
|
||||
if (address->s6_words[4] == 0xffff && address->s6_words[5] != 0)
|
||||
return FALSE;
|
||||
if (address->s6_words[6] == 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringExA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6AddressToStringExA(const IN6_ADDR *address, ULONG scope, USHORT port, char *str, ULONG *size)
|
||||
{
|
||||
char buffer[64], *p = buffer;
|
||||
int i, len, gap = -1, gap_len = 1, ipv6_end = 8;
|
||||
ULONG needed;
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("(%p %lu %u %p %p)\n", address, scope, port, str, size);
|
||||
|
||||
if (!address || !str || !size)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (is_ipv4_in_ipv6(address))
|
||||
ipv6_end = 6;
|
||||
|
||||
for (i = 0; i < ipv6_end; i++)
|
||||
{
|
||||
len = 0;
|
||||
while (!address->s6_words[i] && i < ipv6_end)
|
||||
{
|
||||
i++;
|
||||
len++;
|
||||
}
|
||||
if (len > gap_len)
|
||||
{
|
||||
gap = i - len;
|
||||
gap_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
if (port) p += sprintf(p, "[");
|
||||
|
||||
i = 0;
|
||||
while (i < ipv6_end)
|
||||
{
|
||||
if (i == gap)
|
||||
{
|
||||
p += sprintf(p, ":");
|
||||
i += gap_len;
|
||||
if (i == ipv6_end) p += sprintf(p, ":");
|
||||
continue;
|
||||
}
|
||||
if (i > 0) p += sprintf(p, ":");
|
||||
p += sprintf(p, "%x", ntohs(address->s6_words[i]));
|
||||
i++;
|
||||
}
|
||||
|
||||
if (ipv6_end == 6)
|
||||
{
|
||||
if (p[-1] != ':') p += sprintf(p, ":");
|
||||
p = RtlIpv4AddressToStringA((IN_ADDR *)(address->s6_words + 6), p);
|
||||
}
|
||||
|
||||
if (scope) p += sprintf(p, "%%%lu", scope);
|
||||
|
||||
if (port) p += sprintf(p, "]:%u", ntohs(port));
|
||||
|
||||
needed = p - buffer + 1;
|
||||
|
||||
if (*size >= needed)
|
||||
{
|
||||
strcpy(str, buffer);
|
||||
ret = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*size = needed;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringA [NTDLL.@]
|
||||
*/
|
||||
char * WINAPI RtlIpv6AddressToStringA(const IN6_ADDR *address, char *str)
|
||||
{
|
||||
ULONG size = 46;
|
||||
if (!address || !str) return str - 1;
|
||||
str[45] = 0; /* this byte is set even though the string is always shorter */
|
||||
RtlIpv6AddressToStringExA(address, 0, 0, str, &size);
|
||||
return str + size - 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringExW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6AddressToStringExW(const IN6_ADDR *address, ULONG scope, USHORT port, WCHAR *str, ULONG *size)
|
||||
{
|
||||
char cstr[64];
|
||||
NTSTATUS ret = RtlIpv6AddressToStringExA(address, scope, port, cstr, size);
|
||||
if (ret == STATUS_SUCCESS) RtlMultiByteToUnicodeN(str, *size * sizeof(WCHAR), NULL, cstr, *size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringW [NTDLL.@]
|
||||
*/
|
||||
WCHAR * WINAPI RtlIpv6AddressToStringW(const IN6_ADDR *address, WCHAR *str)
|
||||
{
|
||||
ULONG size = 46;
|
||||
if (!address || !str) return str;
|
||||
str[45] = 0; /* this word is set even though the string is always shorter */
|
||||
if (RtlIpv6AddressToStringExW(address, 0, 0, str, &size) != STATUS_SUCCESS)
|
||||
return str;
|
||||
return str + size - 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_pointer_obfuscator (internal)
|
||||
*/
|
||||
|
@ -1421,40 +779,6 @@ void WINAPI RtlGetCurrentProcessorNumberEx(PROCESSOR_NUMBER *processor)
|
|||
processor->Reserved = 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIsProcessorFeaturePresent [NTDLL.@]
|
||||
*/
|
||||
BOOLEAN WINAPI RtlIsProcessorFeaturePresent( UINT feature )
|
||||
{
|
||||
#ifdef __aarch64__
|
||||
static const ULONGLONG arm64_features =
|
||||
(1ull << PF_COMPARE_EXCHANGE_DOUBLE) |
|
||||
(1ull << PF_NX_ENABLED) |
|
||||
(1ull << PF_ARM_VFP_32_REGISTERS_AVAILABLE) |
|
||||
(1ull << PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_SECOND_LEVEL_ADDRESS_TRANSLATION) |
|
||||
(1ull << PF_FASTFAIL_AVAILABLE) |
|
||||
(1ull << PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE) |
|
||||
(1ull << PF_ARM_64BIT_LOADSTORE_ATOMIC) |
|
||||
(1ull << PF_ARM_EXTERNAL_CACHE_AVAILABLE) |
|
||||
(1ull << PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V8_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE);
|
||||
|
||||
return (feature < PROCESSOR_FEATURE_MAX && (arm64_features & (1ull << feature)) &&
|
||||
user_shared_data->ProcessorFeatures[feature]);
|
||||
#elif defined _WIN64
|
||||
return feature < PROCESSOR_FEATURE_MAX && user_shared_data->ProcessorFeatures[feature];
|
||||
#else
|
||||
return NtWow64IsProcessorFeaturePresent( feature );
|
||||
#endif
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlInitializeGenericTableAvl (NTDLL.@)
|
||||
*/
|
||||
|
@ -1464,6 +788,27 @@ void WINAPI RtlInitializeGenericTableAvl(PRTL_AVL_TABLE table, PRTL_AVL_COMPARE_
|
|||
FIXME("%p %p %p %p %p: stub\n", table, compare, allocate, free, context);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlEnumerateGenericTableWithoutSplayingAvl (NTDLL.@)
|
||||
*/
|
||||
void * WINAPI RtlEnumerateGenericTableWithoutSplayingAvl(RTL_AVL_TABLE *table, PVOID *previous)
|
||||
{
|
||||
static int warn_once;
|
||||
|
||||
if (!warn_once++)
|
||||
FIXME("(%p, %p) stub!\n", table, previous);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlNumberGenericTableElementsAvl (NTDLL.@)
|
||||
*/
|
||||
ULONG WINAPI RtlNumberGenericTableElementsAvl(RTL_AVL_TABLE *table)
|
||||
{
|
||||
FIXME("(%p) stub!\n", table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlInsertElementGenericTableAvl (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "winsock2.h"
|
||||
#include "windef.h"
|
||||
#include "winnt.h"
|
||||
#include "winternl.h"
|
||||
#include "ddk/ntddk.h"
|
||||
#include "in6addr.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ntdll_misc.h"
|
||||
|
||||
|
@ -1943,3 +1945,606 @@ NTSTATUS WINAPI RtlFormatMessageEx( const WCHAR *src, ULONG width, BOOLEAN ignor
|
|||
*retsize = (buffer - start) * sizeof(WCHAR);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* IP addresses
|
||||
***********************************************************************/
|
||||
|
||||
#define htons(x) RtlUshortByteSwap(x)
|
||||
#define ntohs(x) RtlUshortByteSwap(x)
|
||||
|
||||
static const signed char hex_table[] =
|
||||
{
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x20-0x2F */
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x40-0x4F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x50-0x5F */
|
||||
-1, 10, 11, 12, 13, 14, 15 /* 0x60-0x66 */
|
||||
};
|
||||
|
||||
static BOOL parse_ipv4_component(const WCHAR **str, BOOL strict, ULONG *value)
|
||||
{
|
||||
int base = 10, d;
|
||||
WCHAR c;
|
||||
ULONG cur_value, prev_value = 0;
|
||||
BOOL success = FALSE;
|
||||
|
||||
if (**str == '.')
|
||||
{
|
||||
*str += 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((*str)[0] == '0')
|
||||
{
|
||||
if ((*str)[1] == 'x' || (*str)[1] == 'X')
|
||||
{
|
||||
*str += 2;
|
||||
if (strict) return FALSE;
|
||||
base = 16;
|
||||
}
|
||||
else if ((*str)[1] >= '0' && (*str)[1] <= '9')
|
||||
{
|
||||
*str += 1;
|
||||
if (strict) return FALSE;
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
|
||||
for (cur_value = 0; **str; *str += 1)
|
||||
{
|
||||
c = **str;
|
||||
if (c >= ARRAY_SIZE(hex_table)) break;
|
||||
d = hex_table[c];
|
||||
if (d == -1 || d >= base) break;
|
||||
cur_value = cur_value * base + d;
|
||||
success = TRUE;
|
||||
if (cur_value < prev_value) return FALSE; /* overflow */
|
||||
prev_value = cur_value;
|
||||
}
|
||||
|
||||
if (success) *value = cur_value;
|
||||
return success;
|
||||
}
|
||||
|
||||
static NTSTATUS ipv4_string_to_address(const WCHAR *str, BOOL strict,
|
||||
const WCHAR **terminator, IN_ADDR *address, USHORT *port)
|
||||
{
|
||||
ULONG fields[4];
|
||||
int n = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!parse_ipv4_component(&str, strict, &fields[n]))
|
||||
goto error;
|
||||
n++;
|
||||
if (*str != '.')
|
||||
break;
|
||||
if (n == 4)
|
||||
goto error;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (strict && n < 4)
|
||||
goto error;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 4:
|
||||
if (fields[0] > 0xFF || fields[1] > 0xFF || fields[2] > 0xFF || fields[3] > 0xFF)
|
||||
goto error;
|
||||
address->S_un.S_un_b.s_b1 = fields[0];
|
||||
address->S_un.S_un_b.s_b2 = fields[1];
|
||||
address->S_un.S_un_b.s_b3 = fields[2];
|
||||
address->S_un.S_un_b.s_b4 = fields[3];
|
||||
break;
|
||||
case 3:
|
||||
if (fields[0] > 0xFF || fields[1] > 0xFF || fields[2] > 0xFFFF)
|
||||
goto error;
|
||||
address->S_un.S_un_b.s_b1 = fields[0];
|
||||
address->S_un.S_un_b.s_b2 = fields[1];
|
||||
address->S_un.S_un_b.s_b3 = (fields[2] & 0xFF00) >> 8;
|
||||
address->S_un.S_un_b.s_b4 = (fields[2] & 0x00FF);
|
||||
break;
|
||||
case 2:
|
||||
if (fields[0] > 0xFF || fields[1] > 0xFFFFFF)
|
||||
goto error;
|
||||
address->S_un.S_un_b.s_b1 = fields[0];
|
||||
address->S_un.S_un_b.s_b2 = (fields[1] & 0xFF0000) >> 16;
|
||||
address->S_un.S_un_b.s_b3 = (fields[1] & 0x00FF00) >> 8;
|
||||
address->S_un.S_un_b.s_b4 = (fields[1] & 0x0000FF);
|
||||
break;
|
||||
case 1:
|
||||
address->S_un.S_un_b.s_b1 = (fields[0] & 0xFF000000) >> 24;
|
||||
address->S_un.S_un_b.s_b2 = (fields[0] & 0x00FF0000) >> 16;
|
||||
address->S_un.S_un_b.s_b3 = (fields[0] & 0x0000FF00) >> 8;
|
||||
address->S_un.S_un_b.s_b4 = (fields[0] & 0x000000FF);
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (terminator) *terminator = str;
|
||||
|
||||
if (*str == ':')
|
||||
{
|
||||
str++;
|
||||
if (!parse_ipv4_component(&str, FALSE, &fields[0]))
|
||||
goto error;
|
||||
if (!fields[0] || fields[0] > 0xFFFF || *str)
|
||||
goto error;
|
||||
if (port)
|
||||
{
|
||||
*port = htons(fields[0]);
|
||||
if (terminator) *terminator = str;
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminator && *str)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
if (terminator) *terminator = str;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressExW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressExW(const WCHAR *str, BOOLEAN strict, IN_ADDR *address, USHORT *port)
|
||||
{
|
||||
TRACE("(%s, %u, %p, %p)\n", debugstr_w(str), strict, address, port);
|
||||
if (!str || !address || !port) return STATUS_INVALID_PARAMETER;
|
||||
return ipv4_string_to_address(str, strict, NULL, address, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressW(const WCHAR *str, BOOLEAN strict, const WCHAR **terminator, IN_ADDR *address)
|
||||
{
|
||||
TRACE("(%s, %u, %p, %p)\n", debugstr_w(str), strict, terminator, address);
|
||||
return ipv4_string_to_address(str, strict, terminator, address, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressExA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressExA(const char *str, BOOLEAN strict, IN_ADDR *address, USHORT *port)
|
||||
{
|
||||
WCHAR wstr[32];
|
||||
|
||||
if (!str) return STATUS_INVALID_PARAMETER;
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
return RtlIpv4StringToAddressExW(wstr, strict, address, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4StringToAddressA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4StringToAddressA(const char *str, BOOLEAN strict, const char **terminator, IN_ADDR *address)
|
||||
{
|
||||
WCHAR wstr[32];
|
||||
const WCHAR *wterminator;
|
||||
NTSTATUS ret;
|
||||
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
ret = RtlIpv4StringToAddressW(wstr, strict, &wterminator, address);
|
||||
if (terminator) *terminator = str + (wterminator - wstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL parse_ipv6_component(const WCHAR **str, int base, ULONG *value)
|
||||
{
|
||||
WCHAR *terminator;
|
||||
if (**str >= ARRAY_SIZE(hex_table) || hex_table[**str] == -1) return FALSE;
|
||||
*value = min(wcstoul(*str, &terminator, base), 0x7FFFFFFF);
|
||||
if (*terminator == '0') terminator++; /* "0x" but nothing valid after */
|
||||
else if (terminator == *str) return FALSE;
|
||||
*str = terminator;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NTSTATUS ipv6_string_to_address(const WCHAR *str, BOOL ex,
|
||||
const WCHAR **terminator, IN6_ADDR *address, ULONG *scope, USHORT *port)
|
||||
{
|
||||
BOOL expecting_port = FALSE, has_0x = FALSE, too_big = FALSE;
|
||||
int n_bytes = 0, n_ipv4_bytes = 0, gap = -1;
|
||||
ULONG ip_component, scope_component = 0, port_component = 0;
|
||||
const WCHAR *prev_str;
|
||||
|
||||
if (str[0] == '[')
|
||||
{
|
||||
if (!ex) goto error;
|
||||
expecting_port = TRUE;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (str[0] == ':')
|
||||
{
|
||||
if (str[1] != ':') goto error;
|
||||
str++;
|
||||
address->u.Word[0] = 0;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!n_ipv4_bytes && *str == ':')
|
||||
{
|
||||
/* double colon */
|
||||
if (gap != -1) goto error;
|
||||
str++;
|
||||
prev_str = str;
|
||||
gap = n_bytes;
|
||||
if (n_bytes == 14 || !parse_ipv6_component(&str, 16, &ip_component)) break;
|
||||
str = prev_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_str = str;
|
||||
}
|
||||
|
||||
if (!n_ipv4_bytes && n_bytes <= (gap != -1 ? 10 : 12))
|
||||
{
|
||||
if (parse_ipv6_component(&str, 10, &ip_component) && *str == '.')
|
||||
n_ipv4_bytes = 1;
|
||||
str = prev_str;
|
||||
}
|
||||
|
||||
if (n_ipv4_bytes)
|
||||
{
|
||||
/* IPv4 component */
|
||||
if (!parse_ipv6_component(&str, 10, &ip_component)) goto error;
|
||||
if (str - prev_str > 3 || ip_component > 255)
|
||||
{
|
||||
too_big = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*str != '.' && (n_ipv4_bytes < 4 || (n_bytes < 15 && gap == -1))) goto error;
|
||||
address->u.Byte[n_bytes] = ip_component;
|
||||
n_bytes++;
|
||||
}
|
||||
if (n_ipv4_bytes == 4 || *str != '.') break;
|
||||
n_ipv4_bytes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* IPv6 component */
|
||||
if (!parse_ipv6_component(&str, 16, &ip_component)) goto error;
|
||||
if (prev_str[0] == '0' && (prev_str[1] == 'x' || prev_str[1] == 'X'))
|
||||
{
|
||||
/* Windows "feature": the last IPv6 component can start with "0x" and be longer than 4 digits */
|
||||
if (terminator) *terminator = prev_str + 1; /* Windows says that the "x" is the terminator */
|
||||
if (n_bytes < 14 && gap == -1) return STATUS_INVALID_PARAMETER;
|
||||
address->u.Word[n_bytes/2] = htons(ip_component);
|
||||
n_bytes += 2;
|
||||
has_0x = TRUE;
|
||||
goto fill_gap;
|
||||
}
|
||||
if (*str != ':' && n_bytes < 14 && gap == -1) goto error;
|
||||
if (str - prev_str > 4)
|
||||
too_big = TRUE;
|
||||
else
|
||||
address->u.Word[n_bytes/2] = htons(ip_component);
|
||||
n_bytes += 2;
|
||||
if (*str != ':' || (gap != -1 && str[1] == ':')) break;
|
||||
}
|
||||
if (n_bytes == (gap != -1 ? 14 : 16)) break;
|
||||
if (too_big) return STATUS_INVALID_PARAMETER;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (terminator) *terminator = str;
|
||||
if (too_big) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
fill_gap:
|
||||
if (gap == -1)
|
||||
{
|
||||
if (n_bytes < 16) goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(address->u.Byte + 16 - (n_bytes - gap), address->u.Byte + gap, n_bytes - gap);
|
||||
memset(address->u.Byte + gap, 0, 16 - n_bytes);
|
||||
}
|
||||
|
||||
if (ex)
|
||||
{
|
||||
if (has_0x) goto error;
|
||||
|
||||
if (*str == '%')
|
||||
{
|
||||
str++;
|
||||
if (!parse_ipv4_component(&str, TRUE, &scope_component)) goto error;
|
||||
}
|
||||
|
||||
if (expecting_port)
|
||||
{
|
||||
if (*str != ']') goto error;
|
||||
str++;
|
||||
if (*str == ':')
|
||||
{
|
||||
str++;
|
||||
if (!parse_ipv4_component(&str, FALSE, &port_component)) goto error;
|
||||
if (!port_component || port_component > 0xFFFF || *str) goto error;
|
||||
port_component = htons(port_component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminator && *str) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (scope) *scope = scope_component;
|
||||
if (port) *port = port_component;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
if (terminator) *terminator = str;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressExW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS NTAPI RtlIpv6StringToAddressExW(const WCHAR *str, IN6_ADDR *address, ULONG *scope, USHORT *port)
|
||||
{
|
||||
TRACE("(%s, %p, %p, %p)\n", debugstr_w(str), address, scope, port);
|
||||
if (!str || !address || !scope || !port) return STATUS_INVALID_PARAMETER;
|
||||
return ipv6_string_to_address(str, TRUE, NULL, address, scope, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6StringToAddressW(const WCHAR *str, const WCHAR **terminator, IN6_ADDR *address)
|
||||
{
|
||||
TRACE("(%s, %p, %p)\n", debugstr_w(str), terminator, address);
|
||||
return ipv6_string_to_address(str, FALSE, terminator, address, NULL, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressExA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6StringToAddressExA(const char *str, IN6_ADDR *address, ULONG *scope, USHORT *port)
|
||||
{
|
||||
WCHAR wstr[128];
|
||||
|
||||
if (!str) return STATUS_INVALID_PARAMETER;
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
return RtlIpv6StringToAddressExW(wstr, address, scope, port);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6StringToAddressA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6StringToAddressA(const char *str, const char **terminator, IN6_ADDR *address)
|
||||
{
|
||||
WCHAR wstr[128];
|
||||
const WCHAR *wterminator = NULL;
|
||||
NTSTATUS ret;
|
||||
|
||||
RtlMultiByteToUnicodeN(wstr, sizeof(wstr), NULL, str, strlen(str) + 1);
|
||||
wstr[ARRAY_SIZE(wstr) - 1] = 0;
|
||||
ret = RtlIpv6StringToAddressW(wstr, &wterminator, address);
|
||||
if (terminator && wterminator) *terminator = str + (wterminator - wstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringExW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *pin, USHORT port, LPWSTR buffer, PULONG psize)
|
||||
{
|
||||
WCHAR tmp_ip[32];
|
||||
ULONG needed;
|
||||
|
||||
if (!pin || !buffer || !psize)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
TRACE("(%p:0x%lx, %d, %p, %p:%ld)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
|
||||
|
||||
needed = swprintf(tmp_ip, ARRAY_SIZE(tmp_ip), L"%u.%u.%u.%u",
|
||||
pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
|
||||
pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
|
||||
|
||||
if (port) needed += swprintf(tmp_ip + needed, ARRAY_SIZE(tmp_ip) - needed, L":%u", ntohs(port));
|
||||
|
||||
if (*psize > needed) {
|
||||
*psize = needed + 1;
|
||||
wcscpy(buffer, tmp_ip);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
*psize = needed + 1;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringExA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv4AddressToStringExA(const IN_ADDR *pin, USHORT port, LPSTR buffer, PULONG psize)
|
||||
{
|
||||
CHAR tmp_ip[32];
|
||||
ULONG needed;
|
||||
|
||||
if (!pin || !buffer || !psize)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
TRACE("(%p:0x%lx, %d, %p, %p:%ld)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
|
||||
|
||||
needed = sprintf(tmp_ip, "%u.%u.%u.%u",
|
||||
pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
|
||||
pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
|
||||
|
||||
if (port) needed += sprintf(tmp_ip + needed, ":%u", ntohs(port));
|
||||
|
||||
if (*psize > needed) {
|
||||
*psize = needed + 1;
|
||||
strcpy(buffer, tmp_ip);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
*psize = needed + 1;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringW [NTDLL.@]
|
||||
*/
|
||||
WCHAR * WINAPI RtlIpv4AddressToStringW(const IN_ADDR *pin, LPWSTR buffer)
|
||||
{
|
||||
ULONG size = 16;
|
||||
|
||||
if (RtlIpv4AddressToStringExW(pin, 0, buffer, &size)) size = 0;
|
||||
return buffer + size - 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv4AddressToStringA [NTDLL.@]
|
||||
*/
|
||||
CHAR * WINAPI RtlIpv4AddressToStringA(const IN_ADDR *pin, LPSTR buffer)
|
||||
{
|
||||
ULONG size = 16;
|
||||
|
||||
if (RtlIpv4AddressToStringExA(pin, 0, buffer, &size)) size = 0;
|
||||
return buffer + size - 1;
|
||||
}
|
||||
|
||||
static BOOL is_ipv4_in_ipv6(const IN6_ADDR *address)
|
||||
{
|
||||
if (address->s6_words[5] == htons(0x5efe) && (address->s6_words[4] & ~htons(0x200)) == 0)
|
||||
return TRUE;
|
||||
if (*(UINT64 *)address != 0)
|
||||
return FALSE;
|
||||
if (address->s6_words[4] != 0 && address->s6_words[4] != 0xffff)
|
||||
return FALSE;
|
||||
if (address->s6_words[4] == 0 && address->s6_words[5] != 0 && address->s6_words[5] != 0xffff)
|
||||
return FALSE;
|
||||
if (address->s6_words[4] == 0xffff && address->s6_words[5] != 0)
|
||||
return FALSE;
|
||||
if (address->s6_words[6] == 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringExA [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6AddressToStringExA(const IN6_ADDR *address, ULONG scope, USHORT port,
|
||||
char *str, ULONG *size)
|
||||
{
|
||||
char buffer[64], *p = buffer;
|
||||
int i, len, gap = -1, gap_len = 1, ipv6_end = 8;
|
||||
ULONG needed;
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("(%p %lu %u %p %p)\n", address, scope, port, str, size);
|
||||
|
||||
if (!address || !str || !size)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (is_ipv4_in_ipv6(address))
|
||||
ipv6_end = 6;
|
||||
|
||||
for (i = 0; i < ipv6_end; i++)
|
||||
{
|
||||
len = 0;
|
||||
while (!address->s6_words[i] && i < ipv6_end)
|
||||
{
|
||||
i++;
|
||||
len++;
|
||||
}
|
||||
if (len > gap_len)
|
||||
{
|
||||
gap = i - len;
|
||||
gap_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
if (port) p += sprintf(p, "[");
|
||||
|
||||
i = 0;
|
||||
while (i < ipv6_end)
|
||||
{
|
||||
if (i == gap)
|
||||
{
|
||||
p += sprintf(p, ":");
|
||||
i += gap_len;
|
||||
if (i == ipv6_end) p += sprintf(p, ":");
|
||||
continue;
|
||||
}
|
||||
if (i > 0) p += sprintf(p, ":");
|
||||
p += sprintf(p, "%x", ntohs(address->s6_words[i]));
|
||||
i++;
|
||||
}
|
||||
|
||||
if (ipv6_end == 6)
|
||||
{
|
||||
if (p[-1] != ':') p += sprintf(p, ":");
|
||||
p = RtlIpv4AddressToStringA((IN_ADDR *)(address->s6_words + 6), p);
|
||||
}
|
||||
|
||||
if (scope) p += sprintf(p, "%%%lu", scope);
|
||||
|
||||
if (port) p += sprintf(p, "]:%u", ntohs(port));
|
||||
|
||||
needed = p - buffer + 1;
|
||||
|
||||
if (*size >= needed)
|
||||
{
|
||||
strcpy(str, buffer);
|
||||
ret = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*size = needed;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringA [NTDLL.@]
|
||||
*/
|
||||
char * WINAPI RtlIpv6AddressToStringA(const IN6_ADDR *address, char *str)
|
||||
{
|
||||
ULONG size = 46;
|
||||
if (!address || !str) return str - 1;
|
||||
str[45] = 0; /* this byte is set even though the string is always shorter */
|
||||
RtlIpv6AddressToStringExA(address, 0, 0, str, &size);
|
||||
return str + size - 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringExW [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI RtlIpv6AddressToStringExW(const IN6_ADDR *address, ULONG scope, USHORT port,
|
||||
WCHAR *str, ULONG *size)
|
||||
{
|
||||
char cstr[64];
|
||||
NTSTATUS ret = RtlIpv6AddressToStringExA(address, scope, port, cstr, size);
|
||||
if (ret == STATUS_SUCCESS) RtlMultiByteToUnicodeN(str, *size * sizeof(WCHAR), NULL, cstr, *size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIpv6AddressToStringW [NTDLL.@]
|
||||
*/
|
||||
WCHAR * WINAPI RtlIpv6AddressToStringW(const IN6_ADDR *address, WCHAR *str)
|
||||
{
|
||||
ULONG size = 46;
|
||||
if (!address || !str) return str;
|
||||
str[45] = 0; /* this word is set even though the string is always shorter */
|
||||
if (RtlIpv6AddressToStringExW(address, 0, 0, str, &size) != STATUS_SUCCESS)
|
||||
return str;
|
||||
return str + size - 1;
|
||||
}
|
||||
|
|
|
@ -556,6 +556,25 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlGetNativeSystemInformation (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI RtlGetNativeSystemInformation( SYSTEM_INFORMATION_CLASS class,
|
||||
void *info, ULONG size, ULONG *ret_size )
|
||||
{
|
||||
return NtWow64GetNativeSystemInformation( class, info, size, ret_size );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIsProcessorFeaturePresent [NTDLL.@]
|
||||
*/
|
||||
BOOLEAN WINAPI RtlIsProcessorFeaturePresent( UINT feature )
|
||||
{
|
||||
return NtWow64IsProcessorFeaturePresent( feature );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlWalkFrameChain (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "ddk/wdm.h"
|
||||
#include "wine/exception.h"
|
||||
#include "ntdll_misc.h"
|
||||
#include "wine/debug.h"
|
||||
|
@ -590,6 +591,45 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlGetNativeSystemInformation (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI RtlGetNativeSystemInformation( SYSTEM_INFORMATION_CLASS class,
|
||||
void *info, ULONG size, ULONG *ret_size )
|
||||
{
|
||||
return NtQuerySystemInformation( class, info, size, ret_size );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIsProcessorFeaturePresent [NTDLL.@]
|
||||
*/
|
||||
BOOLEAN WINAPI RtlIsProcessorFeaturePresent( UINT feature )
|
||||
{
|
||||
static const ULONGLONG arm64_features =
|
||||
(1ull << PF_COMPARE_EXCHANGE_DOUBLE) |
|
||||
(1ull << PF_NX_ENABLED) |
|
||||
(1ull << PF_ARM_VFP_32_REGISTERS_AVAILABLE) |
|
||||
(1ull << PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_SECOND_LEVEL_ADDRESS_TRANSLATION) |
|
||||
(1ull << PF_FASTFAIL_AVAILABLE) |
|
||||
(1ull << PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE) |
|
||||
(1ull << PF_ARM_64BIT_LOADSTORE_ATOMIC) |
|
||||
(1ull << PF_ARM_EXTERNAL_CACHE_AVAILABLE) |
|
||||
(1ull << PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V8_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) |
|
||||
(1ull << PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE);
|
||||
|
||||
return (feature < PROCESSOR_FEATURE_MAX && (arm64_features & (1ull << feature)) &&
|
||||
user_shared_data->ProcessorFeatures[feature]);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlWalkFrameChain (NTDLL.@)
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -451,6 +451,25 @@ __ASM_STDCALL_FUNC( RtlRaiseException, 4,
|
|||
"ret $4" ) /* actually never returns */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlGetNativeSystemInformation (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI RtlGetNativeSystemInformation( SYSTEM_INFORMATION_CLASS class,
|
||||
void *info, ULONG size, ULONG *ret_size )
|
||||
{
|
||||
return NtWow64GetNativeSystemInformation( class, info, size, ret_size );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIsProcessorFeaturePresent [NTDLL.@]
|
||||
*/
|
||||
BOOLEAN WINAPI RtlIsProcessorFeaturePresent( UINT feature )
|
||||
{
|
||||
return NtWow64IsProcessorFeaturePresent( feature );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlWalkFrameChain (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "ddk/wdm.h"
|
||||
#include "wine/exception.h"
|
||||
#include "wine/list.h"
|
||||
#include "ntdll_misc.h"
|
||||
|
@ -792,6 +793,25 @@ __ASM_GLOBAL_FUNC( RtlRaiseException,
|
|||
"call " __ASM_NAME("RtlRaiseStatus") /* does not return */ );
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlGetNativeSystemInformation (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI RtlGetNativeSystemInformation( SYSTEM_INFORMATION_CLASS class,
|
||||
void *info, ULONG size, ULONG *ret_size )
|
||||
{
|
||||
return NtQuerySystemInformation( class, info, size, ret_size );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlIsProcessorFeaturePresent [NTDLL.@]
|
||||
*/
|
||||
BOOLEAN WINAPI RtlIsProcessorFeaturePresent( UINT feature )
|
||||
{
|
||||
return feature < PROCESSOR_FEATURE_MAX && user_shared_data->ProcessorFeatures[feature];
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlWalkFrameChain (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -2553,6 +2553,7 @@ struct query_reg_values_test
|
|||
ULONG expected_type;
|
||||
const WCHAR *expected_data;
|
||||
ULONG expected_data_size;
|
||||
ULONG size_limit;
|
||||
};
|
||||
|
||||
static unsigned int query_routine_calls;
|
||||
|
@ -2623,7 +2624,25 @@ static NTSTATUS WINAPI query_routine(const WCHAR *value_name, ULONG value_type,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static UNICODE_STRING query_reg_values_direct_str;
|
||||
static WCHAR query_reg_values_direct_str_buf[32];
|
||||
static UNICODE_STRING query_reg_values_direct_str = {0, 0, query_reg_values_direct_str_buf};
|
||||
|
||||
static ULONG query_reg_values_direct_int;
|
||||
|
||||
static union
|
||||
{
|
||||
ULONG size;
|
||||
char data[32];
|
||||
}
|
||||
query_reg_values_direct_sized;
|
||||
|
||||
static struct
|
||||
{
|
||||
ULONG size;
|
||||
ULONG type;
|
||||
char data[32];
|
||||
}
|
||||
query_reg_values_direct_typed;
|
||||
|
||||
static struct query_reg_values_test query_reg_values_tests[] =
|
||||
{
|
||||
|
@ -2644,7 +2663,7 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
/* The query routine is called for every value in current key */
|
||||
{
|
||||
{{ query_routine }},
|
||||
STATUS_SUCCESS, 4, SKIP_NAME_CHECK | SKIP_DATA_CHECK
|
||||
STATUS_SUCCESS, 6, SKIP_NAME_CHECK | SKIP_DATA_CHECK
|
||||
},
|
||||
/* NOVALUE is ignored when the name is not null */
|
||||
{
|
||||
|
@ -2671,12 +2690,41 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", &query_reg_values_direct_str }},
|
||||
STATUS_SUCCESS, 0, 0, REG_SZ, L"C:"
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"C:"
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", &query_reg_values_direct_str }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"WindowsDrive",
|
||||
&query_reg_values_direct_str }},
|
||||
STATUS_SUCCESS, 0, 0, REG_SZ, L"%SYSTEMDRIVE%"
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"%SYSTEMDRIVE%"
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"WindowsDrive",
|
||||
&query_reg_values_direct_str }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife32", &query_reg_values_direct_int }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2a"
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_sized }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2a\0\0", sizeof(UINT64)
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_sized }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\xff", 1, 1
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_typed }},
|
||||
STATUS_SUCCESS, 0, 0, REG_QWORD, L"\x2a\0\0", sizeof(UINT64)
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_typed }},
|
||||
STATUS_SUCCESS, 0, 0, 0x23, L"\x23", 1, 1
|
||||
},
|
||||
/* DIRECT on a multi-string crashes on Windows without NOEXPAND */
|
||||
/* {
|
||||
|
@ -2686,7 +2734,12 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"CapitalsOfEurope",
|
||||
&query_reg_values_direct_str }},
|
||||
STATUS_SUCCESS, 0, 0, REG_SZ, L"Brussels\0Paris\0%PATH%\0", sizeof(L"Brussels\0Paris\0%PATH%\0")
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"Brussels\0Paris\0%PATH%\0", sizeof(L"Brussels\0Paris\0%PATH%\0")
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"CapitalsOfEurope",
|
||||
&query_reg_values_direct_str }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
|
||||
},
|
||||
/* DIRECT with a null buffer crashes on Windows */
|
||||
/* {
|
||||
|
@ -2730,11 +2783,11 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
},
|
||||
{
|
||||
{{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
|
||||
STATUS_SUCCESS, 1, WINE_TODO_TYPE | WINE_TODO_SIZE, REG_SZ, L"C:"
|
||||
STATUS_SUCCESS, 1, 0, REG_SZ, L"C:"
|
||||
},
|
||||
{
|
||||
{{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_MULTI_SZ, (WCHAR*)L"Brussels\0Paris\0%PATH%\0" }},
|
||||
STATUS_SUCCESS, 3, EXPECT_DEFAULT_DATA | SPLIT_MULTI | WINE_TODO_CALLS | WINE_TODO_TYPE | WINE_TODO_SIZE
|
||||
STATUS_SUCCESS, 3, EXPECT_DEFAULT_DATA | SPLIT_MULTI
|
||||
},
|
||||
{
|
||||
{{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_DWORD, (WCHAR*)0xdeadbeef }},
|
||||
|
@ -2752,19 +2805,74 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_str, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
|
||||
STATUS_SUCCESS, 0, WINE_TODO_SIZE | WINE_TODO_DATA, REG_EXPAND_SZ, L"C:"
|
||||
&query_reg_values_direct_str, REG_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
|
||||
},
|
||||
/* DIRECT with a multi-string default value crashes on Windows */
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_str, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"C:"
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_str, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_int, REG_DWORD, (WCHAR*)0xdeadbeef }},
|
||||
STATUS_SUCCESS, 0
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_int, REG_DWORD, (WCHAR*)L"\x2a", sizeof(DWORD) }},
|
||||
STATUS_SUCCESS, 0, EXPECT_DEFAULT_DATA
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_sized, REG_DWORD, (WCHAR*)L"Some default", sizeof(L"Some default") }},
|
||||
STATUS_SUCCESS, 0, EXPECT_DEFAULT_DATA
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_sized, REG_DWORD, (WCHAR*)L"Some default", sizeof(L"Some default") }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\xff", 1, 1
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_typed, REG_NONE, (WCHAR*)L"Some default", sizeof(L"Some default") }},
|
||||
STATUS_SUCCESS, 0, WINE_TODO_TYPE | WINE_TODO_SIZE, 0x23, NULL, -1
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_typed, REG_QWORD, (WCHAR*)L"Some default", sizeof(L"Some default") }},
|
||||
STATUS_SUCCESS, 0, WINE_TODO_TYPE | WINE_TODO_SIZE, 0x23, NULL, -1
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_typed, REG_QWORD, (WCHAR*)L"\x2a\0\0", sizeof(UINT64) }},
|
||||
STATUS_SUCCESS, 0, EXPECT_DEFAULT_DATA
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_typed, REG_QWORD, (WCHAR*)L"\x2a\0\0", sizeof(UINT64) }},
|
||||
STATUS_SUCCESS, 0, 0, 0x23, L"\x23", 1, 1
|
||||
},
|
||||
/* DIRECT with a multi-string default value crashes on Windows without NOEXPAND */
|
||||
/* {
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_str, REG_MULTI_SZ, (WCHAR*)L"A\0B\0C\0", sizeof(L"A\0B\0C\0") }},
|
||||
STATUS_SUCCESS, EXPECT_DEFAULT_DATA
|
||||
STATUS_SUCCESS, 0, EXPECT_DEFAULT_DATA
|
||||
}, */
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_str, REG_MULTI_SZ, (WCHAR*)L"A\0B\0C\0", sizeof(L"A\0B\0C\0") }},
|
||||
STATUS_SUCCESS, 0, EXPECT_DEFAULT_DATA | WINE_TODO_SIZE
|
||||
},
|
||||
/* The default value is not used if it is not valid */
|
||||
{
|
||||
{{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_SZ }},
|
||||
STATUS_DATA_OVERRUN, 0, EXPECT_DEFAULT_DATA | WINE_TODO_RET | WINE_TODO_CALLS
|
||||
STATUS_DATA_OVERRUN, 0, EXPECT_DEFAULT_DATA
|
||||
},
|
||||
{
|
||||
{{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_NONE, (WCHAR*)L"Some default" }},
|
||||
|
@ -2780,12 +2888,6 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
&query_reg_values_direct_str, REG_NONE, (WCHAR*)L"Some default" }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, NULL, -1
|
||||
},
|
||||
/* DIRECT additionally requires the default value to be a string */
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
|
||||
&query_reg_values_direct_str, REG_DWORD, (WCHAR*)0xdeadbeef }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, NULL, -1
|
||||
},
|
||||
/* REQUIRED fails if the value doesn't exist and there is no default */
|
||||
{
|
||||
{{ query_routine, RTL_QUERY_REGISTRY_REQUIRED, (WCHAR*)L"I don't exist",
|
||||
|
@ -2800,7 +2902,7 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
/* DELETE deletes the value after reading it */
|
||||
{
|
||||
{{ query_routine, RTL_QUERY_REGISTRY_DELETE, (WCHAR*)L"WindowsDrive" }},
|
||||
STATUS_SUCCESS, 1, WINE_TODO_TYPE | WINE_TODO_SIZE, REG_SZ, L"C:"
|
||||
STATUS_SUCCESS, 1, 0, REG_SZ, L"C:"
|
||||
},
|
||||
{
|
||||
{{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_SZ, (WCHAR*)L"Some default" }},
|
||||
|
@ -2821,13 +2923,17 @@ static void test_RtlQueryRegistryValues(void)
|
|||
L"Brussels\0Paris\0%PATH%", sizeof(L"Brussels\0Paris\0%PATH%"));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value CapitalsOfEurope: %lu\n", status);
|
||||
|
||||
status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest\\subkey", L"Color", REG_SZ,
|
||||
(void*)L"Yellow", sizeof(L"Yellow"));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value Color: %lu\n", status);
|
||||
status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"MeaningOfLife32", REG_DWORD,
|
||||
L"\x2a", sizeof(DWORD));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value MeaningOfLife32: %lu\n", status);
|
||||
|
||||
query_reg_values_direct_str.MaximumLength = 32 * sizeof(WCHAR);
|
||||
query_reg_values_direct_str.Buffer = pRtlAllocateHeap(GetProcessHeap(), 0,
|
||||
query_reg_values_direct_str.MaximumLength);
|
||||
status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"MeaningOfLife64", REG_QWORD,
|
||||
L"\x2a\0\0", sizeof(UINT64));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value MeaningOfLife64: %lu\n", status);
|
||||
|
||||
status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest\\subkey", L"Color", REG_SZ,
|
||||
L"Yellow", sizeof(L"Yellow"));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value Color: %lu\n", status);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(query_reg_values_tests); i++)
|
||||
{
|
||||
|
@ -2846,9 +2952,26 @@ static void test_RtlQueryRegistryValues(void)
|
|||
}
|
||||
|
||||
query_routine_calls = 0;
|
||||
query_reg_values_direct_str.Length = query_reg_values_direct_str.MaximumLength - sizeof(WCHAR);
|
||||
|
||||
query_reg_values_direct_str.MaximumLength = test->size_limit ? test->size_limit
|
||||
: sizeof(query_reg_values_direct_str_buf);
|
||||
if (query_reg_values_direct_str.MaximumLength >= sizeof(WCHAR))
|
||||
query_reg_values_direct_str.Length = query_reg_values_direct_str.MaximumLength - sizeof(WCHAR);
|
||||
else
|
||||
query_reg_values_direct_str.Length = 0;
|
||||
memset(query_reg_values_direct_str.Buffer, 0x23, query_reg_values_direct_str.Length);
|
||||
query_reg_values_direct_str.Buffer[query_reg_values_direct_str.Length] = 0;
|
||||
query_reg_values_direct_str.Buffer[query_reg_values_direct_str.Length / sizeof(WCHAR)] = 0;
|
||||
|
||||
query_reg_values_direct_int = 1;
|
||||
|
||||
memset(query_reg_values_direct_sized.data, 0x23, sizeof(query_reg_values_direct_sized));
|
||||
query_reg_values_direct_sized.size = test->size_limit ? -test->size_limit
|
||||
: -(LONG)sizeof(query_reg_values_direct_sized);
|
||||
|
||||
query_reg_values_direct_typed.size = test->size_limit ? test->size_limit
|
||||
: sizeof(query_reg_values_direct_typed.data);
|
||||
query_reg_values_direct_typed.type = 0x23;
|
||||
memset(query_reg_values_direct_typed.data, 0x23, sizeof(query_reg_values_direct_typed.data));
|
||||
|
||||
status = pRtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer, test->query_table, test, NULL);
|
||||
|
||||
|
@ -2877,22 +3000,62 @@ static void test_RtlQueryRegistryValues(void)
|
|||
expected_size = test->expected_data_size;
|
||||
}
|
||||
|
||||
if (!expected_size && expected_data && (expected_type == REG_SZ || expected_type == REG_EXPAND_SZ))
|
||||
expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR);
|
||||
else if (expected_size == -1)
|
||||
expected_size = query_reg_values_direct_str.MaximumLength;
|
||||
|
||||
todo_wine_if(test->flags & WINE_TODO_SIZE)
|
||||
ok(query_reg_values_direct_str.Length + sizeof(WCHAR) == expected_size,
|
||||
"Expected size %lu, got %Iu\n", expected_size,
|
||||
query_reg_values_direct_str.Length + sizeof(WCHAR));
|
||||
|
||||
if (expected_data)
|
||||
if (query->EntryContext == &query_reg_values_direct_str)
|
||||
{
|
||||
todo_wine_if(test->flags & WINE_TODO_DATA)
|
||||
ok(!memcmp(query_reg_values_direct_str.Buffer, expected_data, expected_size),
|
||||
"Expected data %s, got %s\n", debugstr_w(expected_data),
|
||||
debugstr_w(query_reg_values_direct_str.Buffer));
|
||||
if (!expected_size && expected_data)
|
||||
expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR);
|
||||
else if (expected_size == -1)
|
||||
expected_size = query_reg_values_direct_str.MaximumLength;
|
||||
|
||||
todo_wine_if(test->flags & WINE_TODO_SIZE)
|
||||
ok(query_reg_values_direct_str.Length + sizeof(WCHAR) == expected_size,
|
||||
"Expected size %lu, got %Iu\n", expected_size,
|
||||
query_reg_values_direct_str.Length + sizeof(WCHAR));
|
||||
|
||||
if (expected_data)
|
||||
{
|
||||
todo_wine_if(test->flags & WINE_TODO_DATA)
|
||||
ok(!memcmp(query_reg_values_direct_str.Buffer, expected_data, expected_size),
|
||||
"Expected data %s, got %s\n", debugstr_w(expected_data),
|
||||
debugstr_w(query_reg_values_direct_str.Buffer));
|
||||
}
|
||||
}
|
||||
else if (query->EntryContext == &query_reg_values_direct_int)
|
||||
{
|
||||
if (expected_data)
|
||||
{
|
||||
ok(!memcmp(&query_reg_values_direct_int, expected_data, expected_size),
|
||||
"Data does not match\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(query_reg_values_direct_int == 1,
|
||||
"Expected data to not change, got %lu\n", query_reg_values_direct_int);
|
||||
}
|
||||
}
|
||||
else if (query->EntryContext == &query_reg_values_direct_sized)
|
||||
{
|
||||
ok(!memcmp(query_reg_values_direct_sized.data, expected_data, expected_size),
|
||||
"Data does not match\n");
|
||||
}
|
||||
else if (query->EntryContext == &query_reg_values_direct_typed)
|
||||
{
|
||||
if (expected_size == -1)
|
||||
expected_size = sizeof(query_reg_values_direct_typed.data);
|
||||
|
||||
todo_wine_if(test->flags & WINE_TODO_SIZE)
|
||||
ok(query_reg_values_direct_typed.size == expected_size,
|
||||
"Expected size %lu, got %lu\n", expected_size, query_reg_values_direct_typed.size);
|
||||
|
||||
todo_wine_if(test->flags & WINE_TODO_TYPE)
|
||||
ok(query_reg_values_direct_typed.type == expected_type,
|
||||
"Expected type %lu, got %lu\n", expected_type, query_reg_values_direct_typed.type);
|
||||
|
||||
if (expected_data)
|
||||
{
|
||||
ok(!memcmp(query_reg_values_direct_typed.data, expected_data, expected_size),
|
||||
"Data does not match\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2902,8 +3065,6 @@ static void test_RtlQueryRegistryValues(void)
|
|||
|
||||
status = RegDeleteKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"WindowsDrive");
|
||||
ok(status == ERROR_FILE_NOT_FOUND, "Registry value WindowsDrive should have been deleted already\n");
|
||||
|
||||
pRtlFreeHeap(GetProcessHeap(), 0, query_reg_values_direct_str.Buffer);
|
||||
}
|
||||
|
||||
START_TEST(reg)
|
||||
|
|
|
@ -2822,18 +2822,13 @@ NTSTATUS cdrom_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc
|
|||
|
||||
TRACE( "%p %s %p %d %p %d %p\n", device, iocodex(code), in_buffer, in_size, out_buffer, out_size, io );
|
||||
|
||||
io->Information = 0;
|
||||
|
||||
if ((status = server_get_unix_fd( device, 0, &fd, &needs_close, NULL, NULL )))
|
||||
{
|
||||
if (status == STATUS_BAD_DEVICE_TYPE) return status; /* no associated fd */
|
||||
goto error;
|
||||
}
|
||||
return status;
|
||||
|
||||
if ((status = CDROM_Open(fd, &dev)))
|
||||
{
|
||||
if (needs_close) close( fd );
|
||||
goto error;
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -2847,16 +2842,13 @@ NTSTATUS cdrom_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc
|
|||
* Also for some reason it wants the fd to be closed before we even
|
||||
* open the parent if we're trying to eject the disk.
|
||||
*/
|
||||
if ((status = get_parent_device( fd, name, sizeof(name) ))) goto error;
|
||||
if ((status = get_parent_device( fd, name, sizeof(name) ))) return status;
|
||||
if (code == IOCTL_STORAGE_EJECT_MEDIA)
|
||||
NtClose( device );
|
||||
if (needs_close) close( fd );
|
||||
TRACE("opening parent %s\n", name );
|
||||
if ((fd = open( name, O_RDONLY )) == -1)
|
||||
{
|
||||
status = errno_to_status( errno );
|
||||
goto error;
|
||||
}
|
||||
return errno_to_status( errno );
|
||||
needs_close = 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -3117,13 +3109,10 @@ NTSTATUS cdrom_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc
|
|||
break;
|
||||
|
||||
default:
|
||||
if (needs_close) close( fd );
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
if (needs_close) close( fd );
|
||||
error:
|
||||
io->Status = status;
|
||||
io->Information = sz;
|
||||
if (event) NtSetEvent(event, NULL);
|
||||
if (!NT_ERROR(status))
|
||||
file_complete_async( device, event, apc, apc_user, io, status, sz );
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -5470,7 +5470,7 @@ static unsigned int register_async_file_read( HANDLE handle, HANDLE event,
|
|||
return status;
|
||||
}
|
||||
|
||||
void add_completion( HANDLE handle, ULONG_PTR value, NTSTATUS status, ULONG info, BOOL async )
|
||||
static void add_completion( HANDLE handle, ULONG_PTR value, NTSTATUS status, ULONG info, BOOL async )
|
||||
{
|
||||
SERVER_START_REQ( add_fd_completion )
|
||||
{
|
||||
|
@ -5484,6 +5484,20 @@ void add_completion( HANDLE handle, ULONG_PTR value, NTSTATUS status, ULONG info
|
|||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
/* complete async file I/O, signaling completion in all ways necessary */
|
||||
void file_complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
|
||||
IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR information )
|
||||
{
|
||||
ULONG_PTR iosb_ptr = iosb_client_ptr(io);
|
||||
|
||||
io->Status = status;
|
||||
io->Information = information;
|
||||
if (event) NtSetEvent( event, NULL );
|
||||
if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, iosb_ptr, 0 );
|
||||
else if (apc_user) add_completion( handle, (ULONG_PTR)apc_user, status, information, FALSE );
|
||||
}
|
||||
|
||||
|
||||
static unsigned int set_pending_write( HANDLE device )
|
||||
{
|
||||
unsigned int status;
|
||||
|
@ -6019,10 +6033,7 @@ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
|
|||
int result, unix_handle, needs_close;
|
||||
unsigned int options, status;
|
||||
UINT pos = 0, total = 0;
|
||||
client_ptr_t iosb_ptr = iosb_client_ptr(io);
|
||||
enum server_fd_type type;
|
||||
ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
|
||||
BOOL send_completion = FALSE;
|
||||
|
||||
TRACE( "(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p),partial stub!\n",
|
||||
file, event, apc, apc_user, io, segments, (int)length, offset, key );
|
||||
|
@ -6074,24 +6085,18 @@ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
|
|||
}
|
||||
}
|
||||
|
||||
send_completion = cvalue != 0;
|
||||
|
||||
done:
|
||||
if (needs_close) close( unix_handle );
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
io->Status = status;
|
||||
io->Information = total;
|
||||
file_complete_async( file, event, apc, apc_user, io, status, total );
|
||||
TRACE("= SUCCESS (%u)\n", total);
|
||||
if (event) NtSetEvent( event, NULL );
|
||||
if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, iosb_ptr, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("= 0x%08x\n", status);
|
||||
if (status != STATUS_PENDING && event) NtResetEvent( event, NULL );
|
||||
}
|
||||
if (send_completion) add_completion( file, cvalue, status, total, FALSE );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -6120,7 +6125,6 @@ NTSTATUS WINAPI NtDeviceIoControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUT
|
|||
case FILE_DEVICE_BEEP:
|
||||
case FILE_DEVICE_NETWORK:
|
||||
status = sock_ioctl( handle, event, apc, apc_context, io, code, in_buffer, in_size, out_buffer, out_size );
|
||||
if (status != STATUS_NOT_SUPPORTED && status != STATUS_BAD_DEVICE_TYPE) return status;
|
||||
break;
|
||||
case FILE_DEVICE_DISK:
|
||||
case FILE_DEVICE_CD_ROM:
|
||||
|
@ -6143,8 +6147,6 @@ NTSTATUS WINAPI NtDeviceIoControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUT
|
|||
if (status == STATUS_NOT_SUPPORTED || status == STATUS_BAD_DEVICE_TYPE)
|
||||
return server_ioctl_file( handle, event, apc, apc_context, io, code,
|
||||
in_buffer, in_size, out_buffer, out_size );
|
||||
|
||||
if (status != STATUS_PENDING && !NT_ERROR(status)) io->Status = status;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -6180,6 +6182,7 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
|||
IO_STATUS_BLOCK *io, ULONG code, void *in_buffer, ULONG in_size,
|
||||
void *out_buffer, ULONG out_size )
|
||||
{
|
||||
ULONG_PTR size = 0;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE( "(%p,%p,%p,%p,%p,0x%08x,%p,0x%08x,%p,0x%08x)\n",
|
||||
|
@ -6223,19 +6226,17 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
|||
buffer->StartingVcn.QuadPart = 1;
|
||||
buffer->Extents[0].NextVcn.QuadPart = 0;
|
||||
buffer->Extents[0].Lcn.QuadPart = 0;
|
||||
io->Information = sizeof(RETRIEVAL_POINTERS_BUFFER);
|
||||
size = sizeof(RETRIEVAL_POINTERS_BUFFER);
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
io->Information = 0;
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FSCTL_GET_REPARSE_POINT:
|
||||
io->Information = 0;
|
||||
if (out_buffer && out_size)
|
||||
{
|
||||
FIXME("FSCTL_GET_REPARSE_POINT semi-stub\n");
|
||||
|
@ -6250,7 +6251,6 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
|||
int fd, needs_close;
|
||||
struct stat st;
|
||||
|
||||
io->Information = 0;
|
||||
if (out_size >= sizeof(*info))
|
||||
{
|
||||
status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL );
|
||||
|
@ -6260,7 +6260,7 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
|||
memset( info, 0, sizeof(*info) );
|
||||
memcpy( info->ObjectId, &st.st_dev, sizeof(st.st_dev) );
|
||||
memcpy( info->ObjectId + 8, &st.st_ino, sizeof(st.st_ino) );
|
||||
io->Information = sizeof(*info);
|
||||
size = sizeof(*info);
|
||||
}
|
||||
else status = STATUS_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
|
@ -6268,7 +6268,6 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
|||
|
||||
case FSCTL_SET_SPARSE:
|
||||
TRACE("FSCTL_SET_SPARSE: Ignoring request\n");
|
||||
io->Information = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
|
@ -6276,7 +6275,8 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
|||
in_buffer, in_size, out_buffer, out_size );
|
||||
}
|
||||
|
||||
if (status != STATUS_PENDING) io->Status = status;
|
||||
if (!NT_ERROR(status) && status != STATUS_PENDING)
|
||||
file_complete_async( handle, event, apc, apc_context, io, status, size );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,12 +147,6 @@ SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4] =
|
|||
static void fatal_error( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
|
||||
#endif
|
||||
|
||||
#if defined(linux) || defined(__APPLE__)
|
||||
static const BOOL use_preloader = TRUE;
|
||||
#else
|
||||
static const BOOL use_preloader = FALSE;
|
||||
#endif
|
||||
|
||||
static const char *bin_dir;
|
||||
static const char *dll_dir;
|
||||
static const char *ntdll_dir;
|
||||
|
@ -500,31 +494,30 @@ char *get_alternate_wineloader( WORD machine )
|
|||
|
||||
static void preloader_exec( char **argv )
|
||||
{
|
||||
if (use_preloader)
|
||||
{
|
||||
static const char *preloader = "wine-preloader";
|
||||
char *p;
|
||||
#ifdef HAVE_WINE_PRELOADER
|
||||
static const char *preloader = "wine-preloader";
|
||||
char *p;
|
||||
|
||||
if (!(p = strrchr( argv[1], '/' ))) p = argv[1];
|
||||
else p++;
|
||||
if (!(p = strrchr( argv[1], '/' ))) p = argv[1];
|
||||
else p++;
|
||||
|
||||
if (strlen(p) > 2 && !strcmp( p + strlen(p) - 2, "64" )) preloader = "wine64-preloader";
|
||||
argv[0] = malloc( p - argv[1] + strlen(preloader) + 1 );
|
||||
memcpy( argv[0], argv[1], p - argv[1] );
|
||||
strcpy( argv[0] + (p - argv[1]), preloader );
|
||||
if (strlen(p) > 2 && !strcmp( p + strlen(p) - 2, "64" )) preloader = "wine64-preloader";
|
||||
argv[0] = malloc( p - argv[1] + strlen(preloader) + 1 );
|
||||
memcpy( argv[0], argv[1], p - argv[1] );
|
||||
strcpy( argv[0] + (p - argv[1]), preloader );
|
||||
|
||||
#ifdef __APPLE__
|
||||
{
|
||||
posix_spawnattr_t attr;
|
||||
posix_spawnattr_init( &attr );
|
||||
posix_spawnattr_setflags( &attr, POSIX_SPAWN_SETEXEC | _POSIX_SPAWN_DISABLE_ASLR );
|
||||
posix_spawn( NULL, argv[0], NULL, &attr, argv, *_NSGetEnviron() );
|
||||
posix_spawnattr_destroy( &attr );
|
||||
}
|
||||
#endif
|
||||
execv( argv[0], argv );
|
||||
free( argv[0] );
|
||||
{
|
||||
posix_spawnattr_t attr;
|
||||
posix_spawnattr_init( &attr );
|
||||
posix_spawnattr_setflags( &attr, POSIX_SPAWN_SETEXEC | _POSIX_SPAWN_DISABLE_ASLR );
|
||||
posix_spawn( NULL, argv[0], NULL, &attr, argv, *_NSGetEnviron() );
|
||||
posix_spawnattr_destroy( &attr );
|
||||
}
|
||||
#endif
|
||||
execv( argv[0], argv );
|
||||
free( argv[0] );
|
||||
#endif
|
||||
execv( argv[1], argv + 1 );
|
||||
}
|
||||
|
||||
|
@ -2035,18 +2028,7 @@ static void apple_main_thread(void)
|
|||
#endif /* __APPLE__ */
|
||||
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
static int pre_exec(void)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
return 1; /* we have a preloader */
|
||||
#else
|
||||
return 0; /* no exec needed */
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(__linux__) && (defined(__i386__) || defined(__arm__))
|
||||
#if defined(__linux__) && !defined(__ANDROID__) && (defined(__i386__) || defined(__arm__))
|
||||
|
||||
static void check_vmsplit( void *stack )
|
||||
{
|
||||
|
@ -2067,20 +2049,6 @@ static int pre_exec(void)
|
|||
return 1; /* we have a preloader on x86/arm */
|
||||
}
|
||||
|
||||
#elif defined(__linux__) && (defined(__x86_64__) || defined(__aarch64__))
|
||||
|
||||
static int pre_exec(void)
|
||||
{
|
||||
return 1; /* we have a preloader on x86-64/arm64 */
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
static int pre_exec(void)
|
||||
{
|
||||
return 1; /* we have a preloader */
|
||||
}
|
||||
|
||||
#elif (defined(__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__DragonFly__))
|
||||
|
||||
static int pre_exec(void)
|
||||
|
@ -2097,7 +2065,11 @@ static int pre_exec(void)
|
|||
|
||||
static int pre_exec(void)
|
||||
{
|
||||
#ifdef HAVE_WINE_PRELOADER
|
||||
return 1; /* we have a preloader */
|
||||
#else
|
||||
return 0; /* no exec needed */
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1261,14 +1261,12 @@ NTSTATUS serial_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE ap
|
|||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
io->Information = 0;
|
||||
|
||||
if ((status = server_get_unix_fd( device, access, &fd, &needs_close, &type, NULL ))) goto error;
|
||||
if ((status = server_get_unix_fd( device, access, &fd, &needs_close, &type, NULL )))
|
||||
return status;
|
||||
if (type != FD_TYPE_SERIAL)
|
||||
{
|
||||
if (needs_close) close( fd );
|
||||
status = STATUS_OBJECT_TYPE_MISMATCH;
|
||||
goto error;
|
||||
return STATUS_OBJECT_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
switch (code)
|
||||
|
@ -1455,11 +1453,11 @@ NTSTATUS serial_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE ap
|
|||
status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (needs_close) close( fd );
|
||||
error:
|
||||
io->Status = status;
|
||||
io->Information = sz;
|
||||
if (event) NtSetEvent(event, NULL);
|
||||
|
||||
if (!NT_ERROR(status))
|
||||
file_complete_async( device, event, apc, apc_user, io, status, sz );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -1252,9 +1252,9 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
|
|||
|
||||
"5:\tmovw r0, #0x000d\n\t" /* STATUS_INVALID_PARAMETER */
|
||||
"movt r0, #0xc000\n\t"
|
||||
"b " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t"
|
||||
".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n"
|
||||
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
|
||||
"b " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
|
||||
|
||||
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher_return,
|
||||
"mov r8, r0\n\t"
|
||||
"mov r0, r1\n\t"
|
||||
"b " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
|
||||
|
|
|
@ -1607,9 +1607,9 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
|
|||
"ret x16\n"
|
||||
"4:\tmov x0, #0xc0000000\n\t" /* STATUS_INVALID_PARAMETER */
|
||||
"movk x0, #0x000d\n\t"
|
||||
"b " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t"
|
||||
".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n"
|
||||
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
|
||||
"b " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
|
||||
|
||||
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher_return,
|
||||
"mov sp, x0\n\t"
|
||||
"mov x0, x1\n\t"
|
||||
"b " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
|
||||
|
|
|
@ -2768,10 +2768,9 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
|
|||
__ASM_CFI("\t.cfi_restore_state\n")
|
||||
|
||||
"6:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */
|
||||
"jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t"
|
||||
"jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
|
||||
|
||||
".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n"
|
||||
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
|
||||
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher_return,
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"movl 4(%esp),%esp\n\t"
|
||||
"jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
|
||||
|
|
|
@ -2876,9 +2876,9 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
|
|||
__ASM_CFI("\t.cfi_restore_state\n")
|
||||
"5:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */
|
||||
"movq %rsp,%rcx\n\t"
|
||||
"jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t"
|
||||
".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n"
|
||||
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
|
||||
"jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
|
||||
|
||||
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher_return,
|
||||
"movq %rdi,%rcx\n\t"
|
||||
"movl 0xb0(%rcx),%r14d\n\t" /* frame->syscall_flags */
|
||||
"movq %rsi,%rax\n\t"
|
||||
|
|
|
@ -1425,18 +1425,6 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
|
|||
return status;
|
||||
}
|
||||
|
||||
static void complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
|
||||
IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR information )
|
||||
{
|
||||
ULONG_PTR iosb_ptr = iosb_client_ptr(io);
|
||||
|
||||
io->Status = status;
|
||||
io->Information = information;
|
||||
if (event) NtSetEvent( event, NULL );
|
||||
if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, iosb_ptr, 0 );
|
||||
if (apc_user) add_completion( handle, (ULONG_PTR)apc_user, status, information, FALSE );
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS do_getsockopt( HANDLE handle, IO_STATUS_BLOCK *io, int level,
|
||||
int option, void *out_buffer, ULONG out_size )
|
||||
|
@ -1563,7 +1551,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
complete_async( handle, event, apc, apc_user, io, status, 0 );
|
||||
file_complete_async( handle, event, apc, apc_user, io, status, 0 );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1710,7 +1698,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
status = *(NTSTATUS *)in_buffer;
|
||||
complete_async( handle, event, apc, apc_user, io, status, 0 );
|
||||
file_complete_async( handle, event, apc, apc_user, io, status, 0 );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1736,7 +1724,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
{
|
||||
*(int *)out_buffer = 0;
|
||||
if (needs_close) close( fd );
|
||||
complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
file_complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -1749,7 +1737,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
}
|
||||
*(int *)out_buffer = value;
|
||||
if (needs_close) close( fd );
|
||||
complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
file_complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1788,7 +1776,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
*(int *)out_buffer = !value;
|
||||
}
|
||||
if (needs_close) close( fd );
|
||||
complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
file_complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1815,7 +1803,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
if (out_size < ret_size)
|
||||
{
|
||||
freeifaddrs( ifaddrs );
|
||||
complete_async( handle, event, apc, apc_user, io, STATUS_BUFFER_TOO_SMALL, 0 );
|
||||
file_complete_async( handle, event, apc, apc_user, io, STATUS_BUFFER_TOO_SMALL, 0 );
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
|
@ -1865,7 +1853,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
}
|
||||
|
||||
freeifaddrs( ifaddrs );
|
||||
complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, ret_size );
|
||||
file_complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, ret_size );
|
||||
return STATUS_PENDING;
|
||||
#else
|
||||
FIXME( "Interface list queries are currently not supported on this platform.\n" );
|
||||
|
@ -1920,7 +1908,7 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
|
|||
}
|
||||
|
||||
if (needs_close) close( fd );
|
||||
complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
file_complete_async( handle, event, apc, apc_user, io, STATUS_SUCCESS, 0 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -4073,10 +4073,10 @@ NTSTATUS WINAPI NtDisplayString( UNICODE_STRING *string )
|
|||
* NtRaiseHardError (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtRaiseHardError( NTSTATUS status, ULONG count,
|
||||
UNICODE_STRING *params_mask, void **params,
|
||||
ULONG params_mask, void **params,
|
||||
HARDERROR_RESPONSE_OPTION option, HARDERROR_RESPONSE *response )
|
||||
{
|
||||
FIXME( "%08x stub\n", (int)status );
|
||||
FIXME( "%#08x %u %#x %p %u %p: stub\n", (int)status, (int)count, (int)params_mask, params, option, response );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -528,9 +528,8 @@ NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc,
|
|||
TRACE( "%p %s %p %d %p %d %p\n", device, io2str(code),
|
||||
in_buffer, in_size, out_buffer, out_size, io );
|
||||
|
||||
io->Information = 0;
|
||||
|
||||
if ((status = server_get_unix_fd( device, 0, &fd, &needs_close, NULL, NULL ))) goto error;
|
||||
if ((status = server_get_unix_fd( device, 0, &fd, &needs_close, NULL, NULL )))
|
||||
return status;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
|
@ -580,9 +579,7 @@ NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc,
|
|||
|
||||
if (needs_close) close( fd );
|
||||
|
||||
error:
|
||||
io->Status = status;
|
||||
io->Information = sz;
|
||||
if (event) NtSetEvent( event, NULL );
|
||||
if (!NT_ERROR(status))
|
||||
file_complete_async( device, event, apc, apc_user, io, status, sz );
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -342,7 +342,8 @@ extern NTSTATUS open_unix_file( HANDLE *handle, const char *unix_name, ACCESS_MA
|
|||
extern NTSTATUS get_device_info( int fd, struct _FILE_FS_DEVICE_INFORMATION *info );
|
||||
extern void init_files(void);
|
||||
extern void init_cpu_info(void);
|
||||
extern void add_completion( HANDLE handle, ULONG_PTR value, NTSTATUS status, ULONG info, BOOL async );
|
||||
extern void file_complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
|
||||
IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR information );
|
||||
extern void set_async_direct_result( HANDLE *async_handle, NTSTATUS status, ULONG_PTR information, BOOL mark_pending );
|
||||
|
||||
extern NTSTATUS unixcall_wine_dbg_write( void *args );
|
||||
|
|
|
@ -3621,6 +3621,7 @@ static TEB *init_teb( void *ptr, BOOL is_wow )
|
|||
if (is_wow) teb64->WowTebOffset = teb_offset;
|
||||
#else
|
||||
teb = (TEB *)teb32;
|
||||
teb32->Tib.ExceptionList = ~0u;
|
||||
teb64->Peb = PtrToUlong( (char *)peb - page_size );
|
||||
teb64->Tib.Self = PtrToUlong( teb64 );
|
||||
teb64->Tib.ExceptionList = PtrToUlong( teb32 );
|
||||
|
@ -3639,7 +3640,6 @@ static TEB *init_teb( void *ptr, BOOL is_wow )
|
|||
#endif
|
||||
teb->Peb = peb;
|
||||
teb->Tib.Self = &teb->Tib;
|
||||
teb->Tib.ExceptionList = (void *)~0ul;
|
||||
teb->Tib.StackBase = (void *)~0ul;
|
||||
teb->ActivationContextStackPointer = &teb->ActivationContextStack;
|
||||
InitializeListHead( &teb->ActivationContextStack.FrameListCache );
|
||||
|
|
|
@ -3407,6 +3407,16 @@ PVOID WINAPI MmGetSystemRoutineAddress(PUNICODE_STRING SystemRoutineName)
|
|||
return pFunc;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MmGetPhysicalAddress (NTOSKRNL.EXE.@)
|
||||
*/
|
||||
PHYSICAL_ADDRESS WINAPI MmGetPhysicalAddress(PVOID BaseAddress)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return (PHYSICAL_ADDRESS) VirtualAddress;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MmIsThisAnNtAsSystem (NTOSKRNL.EXE.@)
|
||||
*/
|
||||
|
|
|
@ -1072,7 +1072,7 @@
|
|||
@ stub RtlEnumerateGenericTableAvl
|
||||
@ stub RtlEnumerateGenericTableLikeADirectory
|
||||
@ stdcall RtlEnumerateGenericTableWithoutSplaying(ptr ptr)
|
||||
@ stub RtlEnumerateGenericTableWithoutSplayingAvl
|
||||
@ stdcall RtlEnumerateGenericTableWithoutSplayingAvl(ptr ptr)
|
||||
@ stdcall RtlEqualLuid(ptr ptr)
|
||||
@ stdcall RtlEqualSid(ptr ptr)
|
||||
@ stdcall RtlEqualString(ptr ptr long)
|
||||
|
@ -1214,7 +1214,7 @@
|
|||
@ stdcall RtlNtStatusToDosError(long)
|
||||
@ stdcall RtlNtStatusToDosErrorNoTeb(long)
|
||||
@ stdcall RtlNumberGenericTableElements(ptr)
|
||||
@ stub RtlNumberGenericTableElementsAvl
|
||||
@ stdcall RtlNumberGenericTableElementsAvl(ptr)
|
||||
@ stdcall RtlNumberOfClearBits(ptr)
|
||||
@ stdcall RtlNumberOfSetBits(ptr)
|
||||
@ stub RtlOemStringToCountedUnicodeString
|
||||
|
|
|
@ -223,7 +223,6 @@ static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_leng
|
|||
|
||||
static HMODULE load_config_driver(const WCHAR *driver)
|
||||
{
|
||||
static WCHAR reg_driver[] = {'d','r','i','v','e','r',0};
|
||||
long ret;
|
||||
HMODULE hmod;
|
||||
WCHAR *filename = NULL;
|
||||
|
@ -236,7 +235,7 @@ static HMODULE load_config_driver(const WCHAR *driver)
|
|||
|
||||
if ((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
|
||||
{
|
||||
ret = RegGetValueW(hkeydriver, NULL, reg_driver, RRF_RT_REG_SZ, &type, NULL, &size);
|
||||
ret = RegGetValueW(hkeydriver, NULL, L"Setup", RRF_RT_REG_SZ, &type, NULL, &size);
|
||||
if(ret != ERROR_SUCCESS || type != REG_SZ)
|
||||
{
|
||||
RegCloseKey(hkeydriver);
|
||||
|
@ -255,7 +254,7 @@ static HMODULE load_config_driver(const WCHAR *driver)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
ret = RegGetValueW(hkeydriver, NULL, reg_driver, RRF_RT_REG_SZ, &type, filename, &size);
|
||||
ret = RegGetValueW(hkeydriver, NULL, L"Setup", RRF_RT_REG_SZ, &type, filename, &size);
|
||||
|
||||
RegCloseKey(hkeydriver);
|
||||
}
|
||||
|
@ -373,7 +372,7 @@ BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWST
|
|||
WORD mapped_request;
|
||||
|
||||
TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_w(driver), debugstr_w(attributes));
|
||||
if (TRACE_ON(odbc))
|
||||
if (TRACE_ON(odbc) && attributes)
|
||||
{
|
||||
const WCHAR *p;
|
||||
for (p = attributes; *p; p += lstrlenW(p) + 1)
|
||||
|
@ -418,7 +417,7 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a
|
|||
|
||||
TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_a(driver), debugstr_a(attributes));
|
||||
|
||||
if (TRACE_ON(odbc))
|
||||
if (TRACE_ON(odbc) && attributes)
|
||||
{
|
||||
const char *p;
|
||||
for (p = attributes; *p; p += lstrlenA(p) + 1)
|
||||
|
|
2
dlls/profapi/Makefile.in
Normal file
2
dlls/profapi/Makefile.in
Normal file
|
@ -0,0 +1,2 @@
|
|||
MODULE = profapi.dll
|
||||
IMPORTLIB = profapi
|
17
dlls/profapi/profapi.spec
Normal file
17
dlls/profapi/profapi.spec
Normal file
|
@ -0,0 +1,17 @@
|
|||
101 stub -noname @
|
||||
102 stub -noname @
|
||||
103 stub -noname @
|
||||
104 stub -noname @
|
||||
105 stub -noname @
|
||||
106 stub -noname @
|
||||
107 stub -noname @
|
||||
108 stub -noname @
|
||||
109 stub -noname @
|
||||
110 stub -noname @
|
||||
111 stub -noname @
|
||||
112 stub -noname @
|
||||
113 stub -noname @
|
||||
114 stub -noname @
|
||||
115 stub -noname @
|
||||
116 stub -noname @
|
||||
117 stub -noname @
|
6
dlls/rometadata/Makefile.in
Normal file
6
dlls/rometadata/Makefile.in
Normal file
|
@ -0,0 +1,6 @@
|
|||
MODULE = rometadata.dll
|
||||
IMPORTLIB = rometadata
|
||||
IMPORTS = combase
|
||||
|
||||
SOURCES = \
|
||||
main.c
|
194
dlls/rometadata/main.c
Normal file
194
dlls/rometadata/main.c
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright 2024 Zhiyi Zhang for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#include "initguid.h"
|
||||
#include "objbase.h"
|
||||
#include "cor.h"
|
||||
#include "rometadata.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rometadata);
|
||||
|
||||
struct metadata_dispenser
|
||||
{
|
||||
IMetaDataDispenserEx IMetaDataDispenserEx_iface;
|
||||
LONG refcount;
|
||||
};
|
||||
|
||||
static inline struct metadata_dispenser *impl_from_IMetaDataDispenserEx(IMetaDataDispenserEx *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct metadata_dispenser, IMetaDataDispenserEx_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_QueryInterface(IMetaDataDispenserEx *iface, REFIID riid, void **obj)
|
||||
{
|
||||
TRACE("%p %s %p\n", iface, debugstr_guid(riid), obj);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IMetaDataDispenserEx)
|
||||
|| IsEqualGUID(riid, &IID_IMetaDataDispenser)
|
||||
|| IsEqualGUID(riid, &IID_IUnknown))
|
||||
{
|
||||
*obj = iface;
|
||||
IMetaDataDispenserEx_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("Unsupported interface %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI MetaDataDispenser_AddRef(IMetaDataDispenserEx *iface)
|
||||
{
|
||||
struct metadata_dispenser *this = impl_from_IMetaDataDispenserEx(iface);
|
||||
ULONG ref = InterlockedIncrement(&this->refcount);
|
||||
|
||||
TRACE("%p ref=%lu\n", this, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI MetaDataDispenser_Release(IMetaDataDispenserEx *iface)
|
||||
{
|
||||
struct metadata_dispenser *this = impl_from_IMetaDataDispenserEx(iface);
|
||||
ULONG ref = InterlockedDecrement(&this->refcount);
|
||||
|
||||
TRACE("%p ref=%lu\n", this, ref);
|
||||
|
||||
if (ref == 0)
|
||||
free(this);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_DefineScope(IMetaDataDispenserEx *iface, REFCLSID rclsid,
|
||||
DWORD create_flags, REFIID riid, IUnknown **obj)
|
||||
{
|
||||
FIXME("%p %s %lx %s %p\n", iface, debugstr_guid(rclsid), create_flags, debugstr_guid(riid),
|
||||
obj);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_OpenScope(IMetaDataDispenserEx *iface, const WCHAR *scope,
|
||||
DWORD open_flags, REFIID riid, IUnknown **obj)
|
||||
{
|
||||
FIXME("%p %s %lx %s %p\n", iface, debugstr_w(scope), open_flags, debugstr_guid(riid), obj);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_OpenScopeOnMemory(IMetaDataDispenserEx *iface, const void *data,
|
||||
ULONG data_size, DWORD open_flags, REFIID riid,
|
||||
IUnknown **obj)
|
||||
{
|
||||
FIXME("%p %p %lu %lx %s %p\n", iface, data, data_size, open_flags, debugstr_guid(riid), obj);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_SetOption(IMetaDataDispenserEx *iface, REFGUID option_id, const VARIANT *value)
|
||||
{
|
||||
FIXME("%p %s %p\n", iface, debugstr_guid(option_id), debugstr_variant(value));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_GetOption(IMetaDataDispenserEx *iface, REFGUID optionid, VARIANT *value)
|
||||
{
|
||||
FIXME("%p %s %s\n", iface, debugstr_guid(optionid), debugstr_variant(value));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_OpenScopeOnITypeInfo(IMetaDataDispenserEx *iface, ITypeInfo *type_info,
|
||||
DWORD open_flags, REFIID riid, IUnknown **obj)
|
||||
{
|
||||
FIXME("%p %p %lu %s %p\n", iface, type_info, open_flags, debugstr_guid(riid), obj);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_GetCORSystemDirectory(IMetaDataDispenserEx *iface, WCHAR *buffer,
|
||||
DWORD buffer_size, DWORD *return_length)
|
||||
{
|
||||
FIXME("%p %p %lu %p\n", iface, buffer, buffer_size, return_length);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_FindAssembly(IMetaDataDispenserEx *iface, const WCHAR *app_base,
|
||||
const WCHAR *private_bin, const WCHAR *global_bin,
|
||||
const WCHAR *assembly_name, WCHAR *name, ULONG name_size,
|
||||
ULONG *return_length)
|
||||
{
|
||||
FIXME("%p %s %s %s %s %p %lu %p\n", iface, debugstr_w(app_base), debugstr_w(private_bin),
|
||||
debugstr_w(global_bin), debugstr_w(assembly_name), name, name_size, return_length);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MetaDataDispenser_FindAssemblyModule(IMetaDataDispenserEx *iface, const WCHAR *app_base,
|
||||
const WCHAR *private_bin, const WCHAR *global_bin,
|
||||
const WCHAR *assembly_name, const WCHAR *module_name,
|
||||
WCHAR *name, ULONG name_size, ULONG *return_length)
|
||||
{
|
||||
FIXME("%p %s %s %s %s %s %p %lu %p\n", iface, debugstr_w(app_base), debugstr_w(private_bin),
|
||||
debugstr_w(global_bin), debugstr_w(assembly_name), debugstr_w(module_name), name, name_size, return_length);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const struct IMetaDataDispenserExVtbl MetaDataDispenserExVtbl =
|
||||
{
|
||||
MetaDataDispenser_QueryInterface,
|
||||
MetaDataDispenser_AddRef,
|
||||
MetaDataDispenser_Release,
|
||||
MetaDataDispenser_DefineScope,
|
||||
MetaDataDispenser_OpenScope,
|
||||
MetaDataDispenser_OpenScopeOnMemory,
|
||||
MetaDataDispenser_SetOption,
|
||||
MetaDataDispenser_GetOption,
|
||||
MetaDataDispenser_OpenScopeOnITypeInfo,
|
||||
MetaDataDispenser_GetCORSystemDirectory,
|
||||
MetaDataDispenser_FindAssembly,
|
||||
MetaDataDispenser_FindAssemblyModule
|
||||
};
|
||||
|
||||
STDAPI MetaDataGetDispenser(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
{
|
||||
struct metadata_dispenser *dispenser;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), obj);
|
||||
|
||||
if (!IsEqualGUID(rclsid, &CLSID_CorMetaDataDispenser))
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
|
||||
dispenser = malloc(sizeof(*dispenser));
|
||||
if (!dispenser)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
dispenser->IMetaDataDispenserEx_iface.lpVtbl = &MetaDataDispenserExVtbl;
|
||||
dispenser->refcount = 1;
|
||||
|
||||
hr = IMetaDataDispenserEx_QueryInterface(&dispenser->IMetaDataDispenserEx_iface, riid, obj);
|
||||
IMetaDataDispenserEx_Release(&dispenser->IMetaDataDispenserEx_iface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
|
||||
{
|
||||
TRACE("inst %p, reason %lu, reserved %p.\n", inst, reason, reserved);
|
||||
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
DisableThreadLibraryCalls(inst);
|
||||
|
||||
return TRUE;
|
||||
}
|
1
dlls/rometadata/rometadata.spec
Normal file
1
dlls/rometadata/rometadata.spec
Normal file
|
@ -0,0 +1 @@
|
|||
@ stdcall MetaDataGetDispenser(ptr ptr ptr)
|
5
dlls/rometadata/tests/Makefile.in
Normal file
5
dlls/rometadata/tests/Makefile.in
Normal file
|
@ -0,0 +1,5 @@
|
|||
TESTDLL = rometadata.dll
|
||||
IMPORTS = combase rometadata
|
||||
|
||||
SOURCES = \
|
||||
rometadata.c
|
70
dlls/rometadata/tests/rometadata.c
Normal file
70
dlls/rometadata/tests/rometadata.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2024 Zhiyi Zhang for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#include <windows.h>
|
||||
#include "initguid.h"
|
||||
#include "cor.h"
|
||||
#include "roapi.h"
|
||||
#include "rometadata.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
static void test_MetaDataGetDispenser(void)
|
||||
{
|
||||
IMetaDataDispenserEx *dispenser_ex;
|
||||
IMetaDataDispenser *dispenser;
|
||||
IUnknown *unknown;
|
||||
HRESULT hr;
|
||||
|
||||
/* Invalid parameters */
|
||||
hr = MetaDataGetDispenser(&CLSID_NULL, &IID_IMetaDataDispenser, (void **)&dispenser);
|
||||
ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_NULL, (void **)&dispenser);
|
||||
ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
/* Normal calls */
|
||||
hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_IUnknown, (void **)&unknown);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
IUnknown_Release(unknown);
|
||||
|
||||
hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_IMetaDataDispenser, (void **)&dispenser);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
IMetaDataDispenser_Release(dispenser);
|
||||
|
||||
hr = MetaDataGetDispenser(&CLSID_CorMetaDataDispenser, &IID_IMetaDataDispenserEx, (void **)&dispenser_ex);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
IMetaDataDispenserEx_Release(dispenser_ex);
|
||||
}
|
||||
|
||||
START_TEST(rometadata)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = RoInitialize(RO_INIT_MULTITHREADED);
|
||||
ok(hr == S_OK, "RoInitialize failed, hr %#lx\n", hr);
|
||||
|
||||
test_MetaDataGetDispenser();
|
||||
|
||||
RoUninitialize();
|
||||
}
|
|
@ -59,6 +59,7 @@ TW_UINT16 sane_option_set_int(const char *option_name, int val, BOOL *needs_relo
|
|||
{
|
||||
struct option_descriptor opt;
|
||||
TW_UINT16 rc = sane_find_option(option_name, TYPE_INT, &opt);
|
||||
if (!opt.is_settable) return TWCC_OPERATIONERROR;
|
||||
|
||||
if (rc == TWCC_SUCCESS) rc = sane_option_set_value( opt.optno, &val, needs_reload );
|
||||
return rc;
|
||||
|
@ -77,6 +78,7 @@ TW_UINT16 sane_option_set_bool(const char *option_name, int val )
|
|||
{
|
||||
struct option_descriptor opt;
|
||||
TW_UINT16 rc = sane_find_option(option_name, TYPE_BOOL, &opt);
|
||||
if (!opt.is_settable) return TWCC_OPERATIONERROR;
|
||||
|
||||
if (rc == TWCC_SUCCESS) rc = sane_option_set_value( opt.optno, &val, NULL );
|
||||
return rc;
|
||||
|
@ -102,6 +104,7 @@ TW_UINT16 sane_option_set_str(const char *option_name, char *val, BOOL *needs_re
|
|||
{
|
||||
struct option_descriptor opt;
|
||||
TW_UINT16 rc = sane_find_option(option_name, TYPE_STRING, &opt);
|
||||
if (!opt.is_settable) return TWCC_OPERATIONERROR;
|
||||
|
||||
if (rc == TWCC_SUCCESS) rc = sane_option_set_value( opt.optno, val, needs_reload );
|
||||
return rc;
|
||||
|
|
|
@ -159,6 +159,7 @@ static void map_descr( struct option_descriptor *descr, const SANE_Option_Descri
|
|||
descr->constraint_type = map_constraint_type( opt->constraint_type );
|
||||
descr->size = opt->size;
|
||||
descr->is_active = SANE_OPTION_IS_ACTIVE( opt->cap );
|
||||
descr->is_settable = SANE_OPTION_IS_SETTABLE( opt->cap );
|
||||
if (opt->title) len = ntdll_umbstowcs( opt->title, strlen(opt->title),
|
||||
descr->title, ARRAY_SIZE(descr->title) );
|
||||
descr->title[len] = 0;
|
||||
|
|
|
@ -39,6 +39,7 @@ struct option_descriptor
|
|||
int optno;
|
||||
int size;
|
||||
int is_active;
|
||||
int is_settable;
|
||||
enum { TYPE_BOOL, TYPE_INT, TYPE_FIXED, TYPE_STRING, TYPE_BUTTON, TYPE_GROUP } type;
|
||||
enum { UNIT_NONE, UNIT_PIXEL, UNIT_BIT, UNIT_MM, UNIT_DPI, UNIT_PERCENT, UNIT_MICROSECOND } unit;
|
||||
enum { CONSTRAINT_NONE, CONSTRAINT_RANGE, CONSTRAINT_WORD_LIST, CONSTRAINT_STRING_LIST } constraint_type;
|
||||
|
|
|
@ -56,5 +56,3 @@ SOURCES = \
|
|||
vulkan.c \
|
||||
window.c \
|
||||
winstation.c
|
||||
|
||||
font_EXTRADEFS = -DWINE_FONT_DIR=\"`${MAKEDEP} -R ${datadir}/wine ${fontdir}`\"
|
||||
|
|
|
@ -65,7 +65,6 @@ static PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryPro
|
|||
static PFN_vkGetPhysicalDeviceMemoryProperties pvkGetPhysicalDeviceMemoryProperties;
|
||||
static PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR;
|
||||
static PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices;
|
||||
static const struct vulkan_funcs *vulkan_funcs;
|
||||
|
||||
static void d3dkmt_init_vulkan(void)
|
||||
{
|
||||
|
@ -94,7 +93,6 @@ static void d3dkmt_init_vulkan(void)
|
|||
if ((vr = p_vkCreateInstance( &create_info, NULL, &d3dkmt_vk_instance )))
|
||||
{
|
||||
WARN( "Failed to create a Vulkan instance, vr %d.\n", vr );
|
||||
vulkan_funcs = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -104,7 +102,7 @@ static void d3dkmt_init_vulkan(void)
|
|||
{ \
|
||||
WARN( "Failed to load " #f ".\n" ); \
|
||||
p_vkDestroyInstance( d3dkmt_vk_instance, NULL ); \
|
||||
vulkan_funcs = NULL; \
|
||||
d3dkmt_vk_instance = NULL; \
|
||||
return; \
|
||||
}
|
||||
LOAD_VK_FUNC( vkEnumeratePhysicalDevices )
|
||||
|
@ -118,7 +116,7 @@ static BOOL d3dkmt_use_vulkan(void)
|
|||
{
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
pthread_once( &once, d3dkmt_init_vulkan );
|
||||
return !!vulkan_funcs;
|
||||
return !!d3dkmt_vk_instance;
|
||||
}
|
||||
|
||||
/* d3dkmt_lock must be held */
|
||||
|
|
|
@ -462,10 +462,6 @@ static const struct nls_update_font_list
|
|||
|
||||
static pthread_mutex_t font_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#ifndef WINE_FONT_DIR
|
||||
#define WINE_FONT_DIR "fonts"
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define GET_BE_WORD(x) (x)
|
||||
#define GET_BE_DWORD(x) (x)
|
||||
|
@ -476,20 +472,12 @@ static pthread_mutex_t font_lock = PTHREAD_MUTEX_INITIALIZER;
|
|||
|
||||
static void get_fonts_data_dir_path( const WCHAR *file, WCHAR *path )
|
||||
{
|
||||
const char *dir;
|
||||
const char *dir = ntdll_get_build_dir();
|
||||
ULONG len = MAX_PATH;
|
||||
|
||||
if ((dir = ntdll_get_data_dir()))
|
||||
{
|
||||
wine_unix_to_nt_file_name( dir, path, &len );
|
||||
asciiz_to_unicode( path + len - 1, "\\" WINE_FONT_DIR "\\" );
|
||||
}
|
||||
else if ((dir = ntdll_get_build_dir()))
|
||||
{
|
||||
wine_unix_to_nt_file_name( dir, path, &len );
|
||||
asciiz_to_unicode( path + len - 1, "\\fonts\\" );
|
||||
}
|
||||
|
||||
if (!dir) dir = ntdll_get_data_dir();
|
||||
wine_unix_to_nt_file_name( dir, path, &len );
|
||||
asciiz_to_unicode( path + len - 1, "\\fonts\\" );
|
||||
if (file) lstrcatW( path, file );
|
||||
}
|
||||
|
||||
|
|
|
@ -345,8 +345,6 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz
|
|||
if (params != info) free( params );
|
||||
}
|
||||
|
||||
if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL)
|
||||
InterlockedIncrement( &global_key_state_counter ); /* force refreshing the key state cache */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -406,7 +406,6 @@ static const KBDTABLES kbdus_tables =
|
|||
|
||||
static LONG clipping_cursor; /* clipping thread counter */
|
||||
|
||||
LONG global_key_state_counter = 0;
|
||||
BOOL grab_pointer = TRUE;
|
||||
BOOL grab_fullscreen = FALSE;
|
||||
|
||||
|
@ -740,22 +739,22 @@ BOOL WINAPI NtUserSetCursorPos( INT x, INT y )
|
|||
*/
|
||||
BOOL get_cursor_pos( POINT *pt )
|
||||
{
|
||||
struct object_lock lock = OBJECT_LOCK_INIT;
|
||||
const desktop_shm_t *desktop_shm;
|
||||
BOOL ret;
|
||||
DWORD last_change;
|
||||
DWORD last_change = 0;
|
||||
NTSTATUS status;
|
||||
UINT dpi;
|
||||
|
||||
if (!pt) return FALSE;
|
||||
|
||||
SERVER_START_REQ( set_cursor )
|
||||
while ((status = get_shared_desktop( &lock, &desktop_shm )) == STATUS_PENDING)
|
||||
{
|
||||
if ((ret = !wine_server_call( req )))
|
||||
{
|
||||
pt->x = reply->new_x;
|
||||
pt->y = reply->new_y;
|
||||
last_change = reply->last_change;
|
||||
}
|
||||
pt->x = desktop_shm->cursor.x;
|
||||
pt->y = desktop_shm->cursor.y;
|
||||
last_change = desktop_shm->cursor.last_change;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
ret = !status;
|
||||
|
||||
/* query new position from graphics driver if we haven't updated recently */
|
||||
if (ret && NtGetTickCount() - last_change > 100) ret = user_driver->pGetCursorPos( pt );
|
||||
|
@ -810,52 +809,31 @@ static void check_for_events( UINT flags )
|
|||
*/
|
||||
SHORT WINAPI NtUserGetAsyncKeyState( INT key )
|
||||
{
|
||||
struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
|
||||
INT counter = global_key_state_counter;
|
||||
BYTE prev_key_state;
|
||||
SHORT ret;
|
||||
const desktop_shm_t *desktop_shm;
|
||||
struct object_lock lock = OBJECT_LOCK_INIT;
|
||||
NTSTATUS status;
|
||||
BYTE state = 0;
|
||||
SHORT ret = 0;
|
||||
|
||||
if (key < 0 || key >= 256) return 0;
|
||||
|
||||
check_for_events( QS_INPUT );
|
||||
|
||||
if (key_state_info && !(key_state_info->state[key] & 0xc0) &&
|
||||
key_state_info->counter == counter && NtGetTickCount() - key_state_info->time < 50)
|
||||
{
|
||||
/* use cached value */
|
||||
return 0;
|
||||
}
|
||||
else if (!key_state_info)
|
||||
{
|
||||
key_state_info = calloc( 1, sizeof(*key_state_info) );
|
||||
get_user_thread_info()->key_state = key_state_info;
|
||||
}
|
||||
while ((status = get_shared_desktop( &lock, &desktop_shm )) == STATUS_PENDING)
|
||||
state = desktop_shm->keystate[key];
|
||||
|
||||
ret = 0;
|
||||
if (status) return 0;
|
||||
if (!(state & 0x40)) return (state & 0x80) << 8;
|
||||
|
||||
/* Need to make a server call to reset the last pressed bit */
|
||||
SERVER_START_REQ( get_key_state )
|
||||
{
|
||||
req->async = 1;
|
||||
req->key = key;
|
||||
if (key_state_info)
|
||||
{
|
||||
prev_key_state = key_state_info->state[key];
|
||||
wine_server_set_reply( req, key_state_info->state, sizeof(key_state_info->state) );
|
||||
}
|
||||
if (!wine_server_call( req ))
|
||||
{
|
||||
if (reply->state & 0x40) ret |= 0x0001;
|
||||
if (reply->state & 0x80) ret |= 0x8000;
|
||||
if (key_state_info)
|
||||
{
|
||||
/* force refreshing the key state cache - some multithreaded programs
|
||||
* (like Adobe Photoshop CS5) expect that changes to the async key state
|
||||
* are also immediately available in other threads. */
|
||||
if (prev_key_state != key_state_info->state[key])
|
||||
counter = InterlockedIncrement( &global_key_state_counter );
|
||||
|
||||
key_state_info->time = NtGetTickCount();
|
||||
key_state_info->counter = counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -2555,24 +2533,21 @@ BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_P
|
|||
|
||||
BOOL get_clip_cursor( RECT *rect, UINT dpi )
|
||||
{
|
||||
BOOL ret;
|
||||
struct object_lock lock = OBJECT_LOCK_INIT;
|
||||
const desktop_shm_t *desktop_shm;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!rect) return FALSE;
|
||||
|
||||
SERVER_START_REQ( set_cursor )
|
||||
{
|
||||
req->flags = 0;
|
||||
if ((ret = !wine_server_call( req )))
|
||||
*rect = wine_server_get_rect( reply->new_clip );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
while ((status = get_shared_desktop( &lock, &desktop_shm )) == STATUS_PENDING)
|
||||
*rect = wine_server_get_rect( desktop_shm->cursor.clip );
|
||||
|
||||
if (ret)
|
||||
if (!status)
|
||||
{
|
||||
HMONITOR monitor = monitor_from_rect( rect, MONITOR_DEFAULTTOPRIMARY, 0 );
|
||||
*rect = map_dpi_rect( *rect, get_monitor_dpi( monitor ), dpi );
|
||||
}
|
||||
return ret;
|
||||
return !status;
|
||||
}
|
||||
|
||||
BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset )
|
||||
|
|
|
@ -3469,7 +3469,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA
|
|||
struct send_message_info info;
|
||||
int prev_x, prev_y, new_x, new_y;
|
||||
NTSTATUS ret;
|
||||
BOOL wait, affects_key_state = FALSE;
|
||||
BOOL wait;
|
||||
|
||||
info.type = MSG_HARDWARE;
|
||||
info.dest_tid = 0;
|
||||
|
@ -3495,10 +3495,6 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA
|
|||
req->input.mouse.flags = input->mi.dwFlags;
|
||||
req->input.mouse.time = input->mi.time;
|
||||
req->input.mouse.info = input->mi.dwExtraInfo;
|
||||
affects_key_state = !!(input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP |
|
||||
MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP |
|
||||
MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP |
|
||||
MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP));
|
||||
break;
|
||||
case INPUT_KEYBOARD:
|
||||
if (input->ki.dwFlags & KEYEVENTF_SCANCODE)
|
||||
|
@ -3523,7 +3519,6 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA
|
|||
req->input.kbd.flags = input->ki.dwFlags & ~KEYEVENTF_SCANCODE;
|
||||
req->input.kbd.time = input->ki.time;
|
||||
req->input.kbd.info = input->ki.dwExtraInfo;
|
||||
affects_key_state = TRUE;
|
||||
break;
|
||||
case INPUT_HARDWARE:
|
||||
req->input.hw.msg = input->hi.uMsg;
|
||||
|
@ -3553,13 +3548,8 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA
|
|||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
if (affects_key_state)
|
||||
InterlockedIncrement( &global_key_state_counter ); /* force refreshing the key state cache */
|
||||
if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y))
|
||||
user_driver->pSetCursorPos( new_x, new_y );
|
||||
}
|
||||
if (!ret && (flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y))
|
||||
user_driver->pSetCursorPos( new_x, new_y );
|
||||
|
||||
if (wait)
|
||||
{
|
||||
|
|
|
@ -116,7 +116,6 @@ struct user_thread_info
|
|||
HHOOK hook; /* Current hook */
|
||||
UINT active_hooks; /* Bitmap of active hooks */
|
||||
struct received_message_info *receive_info; /* Message being currently received */
|
||||
struct user_key_state_info *key_state; /* Cache of global key state */
|
||||
struct imm_thread_data *imm_thread_data; /* IMM thread data */
|
||||
HKL kbd_layout; /* Current keyboard layout */
|
||||
UINT kbd_layout_id; /* Current keyboard layout ID */
|
||||
|
@ -124,6 +123,7 @@ struct user_thread_info
|
|||
UINT spy_indent; /* Current spy indent */
|
||||
BOOL clipping_cursor; /* thread is currently clipping */
|
||||
DWORD clipping_reset; /* time when clipping was last reset */
|
||||
struct session_thread_data *session_data; /* shared session thread data */
|
||||
};
|
||||
|
||||
C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo) );
|
||||
|
@ -133,13 +133,6 @@ static inline struct user_thread_info *get_user_thread_info(void)
|
|||
return CONTAINING_RECORD( NtUserGetThreadInfo(), struct user_thread_info, client_info );
|
||||
}
|
||||
|
||||
struct user_key_state_info
|
||||
{
|
||||
UINT time; /* Time of last key state refresh */
|
||||
INT counter; /* Counter to invalidate the key state */
|
||||
BYTE state[256]; /* State for each key */
|
||||
};
|
||||
|
||||
struct hook_extra_info
|
||||
{
|
||||
HHOOK handle;
|
||||
|
|
|
@ -6334,12 +6334,11 @@ static void thread_detach(void)
|
|||
destroy_thread_windows();
|
||||
user_driver->pThreadDetach();
|
||||
|
||||
free( thread_info->key_state );
|
||||
thread_info->key_state = 0;
|
||||
free( thread_info->rawinput );
|
||||
|
||||
cleanup_imm_thread();
|
||||
NtClose( thread_info->server_queue );
|
||||
free( thread_info->session_data );
|
||||
|
||||
exiting_thread_id = 0;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ extern void unregister_imm_window( HWND hwnd );
|
|||
extern BOOL grab_pointer;
|
||||
extern BOOL grab_fullscreen;
|
||||
extern BOOL destroy_caret(void);
|
||||
extern LONG global_key_state_counter;
|
||||
extern HWND get_active_window(void);
|
||||
extern HWND get_capture(void);
|
||||
extern BOOL get_cursor_pos( POINT *pt );
|
||||
|
@ -205,6 +204,22 @@ extern void free_vulkan_gpu( struct vulkan_gpu *gpu );
|
|||
extern BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid );
|
||||
|
||||
/* winstation.c */
|
||||
|
||||
struct object_lock
|
||||
{
|
||||
UINT64 id;
|
||||
UINT64 seq;
|
||||
};
|
||||
#define OBJECT_LOCK_INIT {0}
|
||||
|
||||
/* Get shared session object's data pointer, must be called in a loop while STATUS_PENDING
|
||||
* is returned, lock must be initialized with OBJECT_LOCK_INIT.
|
||||
*
|
||||
* The data read from the objects may be transient and no logic should be executed based
|
||||
* on it, within the loop, or after, unless the function has returned STATUS_SUCCESS.
|
||||
*/
|
||||
extern NTSTATUS get_shared_desktop( struct object_lock *lock, const desktop_shm_t **desktop_shm );
|
||||
|
||||
extern BOOL is_virtual_desktop(void);
|
||||
|
||||
/* window.c */
|
||||
|
|
|
@ -22,9 +22,14 @@
|
|||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "ntuser.h"
|
||||
|
@ -40,6 +45,180 @@ WINE_DECLARE_DEBUG_CHANNEL(win);
|
|||
|
||||
#define DESKTOP_ALL_ACCESS 0x01ff
|
||||
|
||||
struct session_thread_data
|
||||
{
|
||||
const shared_object_t *shared_desktop; /* thread desktop shared session cached object */
|
||||
};
|
||||
|
||||
struct session_block
|
||||
{
|
||||
struct list entry; /* entry in the session block list */
|
||||
const char *data; /* base pointer for the mmaped data */
|
||||
SIZE_T offset; /* offset of data in the session shared mapping */
|
||||
SIZE_T size; /* size of the mmaped data */
|
||||
};
|
||||
|
||||
static pthread_mutex_t session_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static struct list session_blocks = LIST_INIT(session_blocks);
|
||||
|
||||
static struct session_thread_data *get_session_thread_data(void)
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
if (!thread_info->session_data) thread_info->session_data = calloc(1, sizeof(*thread_info->session_data));
|
||||
return thread_info->session_data;
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
/* this prevents compilers from incorrectly reordering non-volatile reads (e.g., memcpy) from shared memory */
|
||||
#define __SHARED_READ_FENCE do { __asm__ __volatile__( "" ::: "memory" ); } while (0)
|
||||
#else
|
||||
#define __SHARED_READ_FENCE __atomic_thread_fence( __ATOMIC_ACQUIRE )
|
||||
#endif
|
||||
|
||||
static void shared_object_acquire_seqlock( const shared_object_t *object, UINT64 *seq )
|
||||
{
|
||||
while ((*seq = ReadNoFence64( &object->seq )) & 1) YieldProcessor();
|
||||
__SHARED_READ_FENCE;
|
||||
}
|
||||
|
||||
static BOOL shared_object_release_seqlock( const shared_object_t *object, UINT64 seq )
|
||||
{
|
||||
__SHARED_READ_FENCE;
|
||||
return ReadNoFence64( &object->seq ) == seq;
|
||||
}
|
||||
|
||||
static object_id_t shared_object_get_id( const shared_object_t *object )
|
||||
{
|
||||
struct object_lock lock = OBJECT_LOCK_INIT;
|
||||
do
|
||||
{
|
||||
shared_object_acquire_seqlock( object, &lock.seq );
|
||||
lock.id = object->id;
|
||||
} while (!shared_object_release_seqlock( object, lock.seq ));
|
||||
return lock.id;
|
||||
}
|
||||
|
||||
static NTSTATUS map_shared_session_block( SIZE_T offset, SIZE_T size, struct session_block **ret )
|
||||
{
|
||||
static const WCHAR nameW[] =
|
||||
{
|
||||
'\\','K','e','r','n','e','l','O','b','j','e','c','t','s','\\',
|
||||
'_','_','w','i','n','e','_','s','e','s','s','i','o','n',0
|
||||
};
|
||||
UNICODE_STRING name = RTL_CONSTANT_STRING( nameW );
|
||||
LARGE_INTEGER off = {.QuadPart = offset - (offset % system_info.AllocationGranularity)};
|
||||
struct session_block *block;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
unsigned int status;
|
||||
HANDLE handle;
|
||||
|
||||
assert( offset + size > offset );
|
||||
|
||||
if (!(block = calloc( 1, sizeof(*block) ))) return STATUS_NO_MEMORY;
|
||||
|
||||
InitializeObjectAttributes( &attr, &name, 0, NULL, NULL );
|
||||
if ((status = NtOpenSection( &handle, SECTION_MAP_READ, &attr )))
|
||||
WARN( "Failed to open shared session section, status %#x\n", status );
|
||||
else
|
||||
{
|
||||
if ((status = NtMapViewOfSection( handle, GetCurrentProcess(), (void **)&block->data, 0, 0,
|
||||
&off, &block->size, ViewUnmap, 0, PAGE_READONLY )))
|
||||
WARN( "Failed to map shared session block, status %#x\n", status );
|
||||
else
|
||||
{
|
||||
list_add_tail( &session_blocks, &block->entry );
|
||||
block->offset = off.QuadPart;
|
||||
assert( block->offset + block->size > block->offset );
|
||||
}
|
||||
NtClose( handle );
|
||||
}
|
||||
|
||||
if (status) free( block );
|
||||
else *ret = block;
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS find_shared_session_block( SIZE_T offset, SIZE_T size, struct session_block **ret )
|
||||
{
|
||||
struct session_block *block;
|
||||
UINT status;
|
||||
|
||||
assert( offset + size > offset );
|
||||
|
||||
pthread_mutex_lock( &session_lock );
|
||||
|
||||
LIST_FOR_EACH_ENTRY( block, &session_blocks, struct session_block, entry )
|
||||
{
|
||||
if (block->offset < offset && offset + size <= block->offset + block->size)
|
||||
{
|
||||
*ret = block;
|
||||
pthread_mutex_unlock( &session_lock );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if ((status = map_shared_session_block( offset, size, ret )))
|
||||
{
|
||||
WARN( "Failed to map session block for offset %s, size %s, status %#x\n",
|
||||
wine_dbgstr_longlong(offset), wine_dbgstr_longlong(size), status );
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &session_lock );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static const shared_object_t *find_shared_session_object( obj_locator_t locator )
|
||||
{
|
||||
const shared_object_t *object;
|
||||
struct session_block *block;
|
||||
NTSTATUS status;
|
||||
|
||||
if (locator.id && !(status = find_shared_session_block( locator.offset, sizeof(*object), &block )))
|
||||
{
|
||||
object = (const shared_object_t *)(block->data + locator.offset - block->offset);
|
||||
if (locator.id == shared_object_get_id( object )) return object;
|
||||
WARN( "Session object id doesn't match expected id %s\n", wine_dbgstr_longlong(locator.id) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS get_shared_desktop( struct object_lock *lock, const desktop_shm_t **desktop_shm )
|
||||
{
|
||||
struct session_thread_data *data = get_session_thread_data();
|
||||
const shared_object_t *object;
|
||||
|
||||
TRACE( "lock %p, desktop_shm %p\n", lock, desktop_shm );
|
||||
|
||||
if (!(object = data->shared_desktop))
|
||||
{
|
||||
obj_locator_t locator;
|
||||
|
||||
SERVER_START_REQ( get_thread_desktop )
|
||||
{
|
||||
req->tid = GetCurrentThreadId();
|
||||
wine_server_call( req );
|
||||
locator = reply->locator;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
data->shared_desktop = find_shared_session_object( locator );
|
||||
if (!(object = data->shared_desktop)) return STATUS_INVALID_HANDLE;
|
||||
memset( lock, 0, sizeof(*lock) );
|
||||
}
|
||||
|
||||
if (!lock->id || !shared_object_release_seqlock( object, lock->seq ))
|
||||
{
|
||||
shared_object_acquire_seqlock( object, &lock->seq );
|
||||
*desktop_shm = &object->shm.desktop;
|
||||
lock->id = object->id;
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL is_virtual_desktop(void)
|
||||
{
|
||||
HANDLE desktop = NtUserGetThreadDesktop( GetCurrentThreadId() );
|
||||
|
@ -249,21 +428,22 @@ HDESK WINAPI NtUserGetThreadDesktop( DWORD thread )
|
|||
BOOL WINAPI NtUserSetThreadDesktop( HDESK handle )
|
||||
{
|
||||
BOOL ret, was_virtual_desktop = is_virtual_desktop();
|
||||
obj_locator_t locator;
|
||||
|
||||
SERVER_START_REQ( set_thread_desktop )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
ret = !wine_server_call_err( req );
|
||||
locator = reply->locator;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (ret) /* reset the desktop windows */
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
struct user_key_state_info *key_state_info = thread_info->key_state;
|
||||
get_session_thread_data()->shared_desktop = find_shared_session_object( locator );
|
||||
thread_info->client_info.top_window = 0;
|
||||
thread_info->client_info.msg_window = 0;
|
||||
if (key_state_info) key_state_info->time = 0;
|
||||
if (was_virtual_desktop != is_virtual_desktop()) update_display_cache( FALSE );
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -29,5 +29,8 @@ import "windows.storage.idl";
|
|||
import "windows.system.idl";
|
||||
|
||||
#define DO_NO_IMPORTS
|
||||
#define _WINDOWS_APPLICATIONMODEL
|
||||
#include "windows.applicationmodel.core.idl"
|
||||
#include "windows.applicationmodel.idl"
|
||||
#include "windows.applicationmodel.activation.idl"
|
||||
#include "windows.applicationmodel.background.idl"
|
||||
|
|
|
@ -19,6 +19,7 @@ SOURCES = \
|
|||
rsrc.rc \
|
||||
unixlib.c \
|
||||
video_decoder.c \
|
||||
video_encoder.c \
|
||||
video_processor.c \
|
||||
wg_allocator.c \
|
||||
wg_format.c \
|
||||
|
|
|
@ -167,6 +167,8 @@ HRESULT aac_decoder_create(REFIID riid, void **ret);
|
|||
HRESULT h264_decoder_create(REFIID riid, void **ret);
|
||||
HRESULT video_processor_create(REFIID riid, void **ret);
|
||||
|
||||
HRESULT h264_encoder_create(REFIID riid, void **ret);
|
||||
|
||||
extern const GUID MFAudioFormat_RAW_AAC;
|
||||
|
||||
#endif /* __GST_PRIVATE_INCLUDED__ */
|
||||
|
|
|
@ -728,6 +728,7 @@ static HRESULT media_stream_send_sample(struct media_stream *stream, const struc
|
|||
|
||||
if (!wg_parser_stream_copy_buffer(stream->wg_stream, data, 0, wg_buffer->size))
|
||||
{
|
||||
hr = S_FALSE;
|
||||
wg_parser_stream_release_buffer(stream->wg_stream);
|
||||
IMFMediaBuffer_Unlock(buffer);
|
||||
goto out;
|
||||
|
@ -789,8 +790,12 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token)
|
|||
|
||||
TRACE("%p, %p\n", stream, token);
|
||||
|
||||
if (wg_parser_stream_get_buffer(source->wg_parser, stream->wg_stream, &buffer))
|
||||
return media_stream_send_sample(stream, &buffer, token);
|
||||
while (wg_parser_stream_get_buffer(source->wg_parser, stream->wg_stream, &buffer))
|
||||
{
|
||||
HRESULT hr = media_stream_send_sample(stream, &buffer, token);
|
||||
if (hr != S_FALSE)
|
||||
return hr;
|
||||
}
|
||||
|
||||
return media_stream_send_eos(source, stream);
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ class_objects[] =
|
|||
{ &CLSID_GStreamerByteStreamHandler, &gstreamer_byte_stream_handler_create },
|
||||
{ &CLSID_MSAACDecMFT, &aac_decoder_create },
|
||||
{ &CLSID_MSH264DecoderMFT, &h264_decoder_create },
|
||||
{ &CLSID_MSH264EncoderMFT, &h264_encoder_create },
|
||||
};
|
||||
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
|
@ -208,6 +209,18 @@ HRESULT mfplat_DllRegisterServer(void)
|
|||
{MFMediaType_Video, MFVideoFormat_YUY2},
|
||||
};
|
||||
|
||||
MFT_REGISTER_TYPE_INFO h264_encoder_input_types[] =
|
||||
{
|
||||
{MFMediaType_Video, MFVideoFormat_IYUV},
|
||||
{MFMediaType_Video, MFVideoFormat_YV12},
|
||||
{MFMediaType_Video, MFVideoFormat_NV12},
|
||||
{MFMediaType_Video, MFVideoFormat_YUY2},
|
||||
};
|
||||
MFT_REGISTER_TYPE_INFO h264_encoder_output_types[] =
|
||||
{
|
||||
{MFMediaType_Video, MFVideoFormat_H264},
|
||||
};
|
||||
|
||||
MFT_REGISTER_TYPE_INFO video_processor_input_types[] =
|
||||
{
|
||||
{MFMediaType_Video, MFVideoFormat_IYUV},
|
||||
|
@ -371,6 +384,16 @@ HRESULT mfplat_DllRegisterServer(void)
|
|||
ARRAY_SIZE(h264_decoder_output_types),
|
||||
h264_decoder_output_types,
|
||||
},
|
||||
{
|
||||
CLSID_MSH264EncoderMFT,
|
||||
MFT_CATEGORY_VIDEO_ENCODER,
|
||||
L"H264 Encoder MFT",
|
||||
MFT_ENUM_FLAG_SYNCMFT,
|
||||
ARRAY_SIZE(h264_encoder_input_types),
|
||||
h264_encoder_input_types,
|
||||
ARRAY_SIZE(h264_encoder_output_types),
|
||||
h264_encoder_output_types,
|
||||
},
|
||||
{
|
||||
CLSID_WMVDecoderMFT,
|
||||
MFT_CATEGORY_VIDEO_DECODER,
|
||||
|
|
338
dlls/winegstreamer/video_encoder.c
Normal file
338
dlls/winegstreamer/video_encoder.c
Normal file
|
@ -0,0 +1,338 @@
|
|||
/* Generic Video Encoder Transform
|
||||
*
|
||||
* Copyright 2024 Ziqing Hui for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "gst_private.h"
|
||||
|
||||
#include "mfapi.h"
|
||||
#include "mferror.h"
|
||||
#include "mfobjects.h"
|
||||
#include "mftransform.h"
|
||||
#include "mediaerr.h"
|
||||
#include "wmcodecdsp.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "initguid.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
||||
struct video_encoder
|
||||
{
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
|
||||
IMFAttributes *attributes;
|
||||
};
|
||||
|
||||
static inline struct video_encoder *impl_from_IMFTransform(IMFTransform *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct video_encoder, IMFTransform_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_QueryInterface(IMFTransform *iface, REFIID iid, void **out)
|
||||
{
|
||||
struct video_encoder *encoder = impl_from_IMFTransform(iface);
|
||||
|
||||
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
||||
|
||||
if (IsEqualGUID(iid, &IID_IMFTransform) || IsEqualGUID(iid, &IID_IUnknown))
|
||||
*out = &encoder->IMFTransform_iface;
|
||||
else
|
||||
{
|
||||
*out = NULL;
|
||||
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*out);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI transform_AddRef(IMFTransform *iface)
|
||||
{
|
||||
struct video_encoder *encoder = impl_from_IMFTransform(iface);
|
||||
ULONG refcount = InterlockedIncrement(&encoder->refcount);
|
||||
|
||||
TRACE("iface %p increasing refcount to %lu.\n", encoder, refcount);
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static ULONG WINAPI transform_Release(IMFTransform *iface)
|
||||
{
|
||||
struct video_encoder *encoder = impl_from_IMFTransform(iface);
|
||||
ULONG refcount = InterlockedDecrement(&encoder->refcount);
|
||||
|
||||
TRACE("iface %p decreasing refcount to %lu.\n", encoder, refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
IMFAttributes_Release(encoder->attributes);
|
||||
free(encoder);
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum,
|
||||
DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum)
|
||||
{
|
||||
TRACE("iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p.\n",
|
||||
iface, input_minimum, input_maximum, output_minimum, output_maximum);
|
||||
*input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
|
||||
{
|
||||
TRACE("iface %p, inputs %p, outputs %p.\n", iface, inputs, outputs);
|
||||
*inputs = *outputs = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
|
||||
DWORD output_size, DWORD *outputs)
|
||||
{
|
||||
FIXME("iface %p, input_size %lu, inputs %p, output_size %lu, outputs %p.\n", iface,
|
||||
input_size, inputs, output_size, outputs);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, info %p.\n", iface, id, info);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, info %p.\n", iface, id, info);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
|
||||
{
|
||||
struct video_encoder *encoder = impl_from_IMFTransform(iface);
|
||||
|
||||
TRACE("iface %p, attributes %p.\n", iface, attributes);
|
||||
|
||||
if (!attributes)
|
||||
return E_POINTER;
|
||||
|
||||
IMFAttributes_AddRef((*attributes = encoder->attributes));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, attributes %p.\n", iface, id, attributes);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, attributes %p.\n", iface, id, attributes);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_DeleteInputStream(IMFTransform *iface, DWORD id)
|
||||
{
|
||||
FIXME("iface %p, id %#lx.\n", iface, id);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
|
||||
{
|
||||
FIXME("iface %p, streams %lu, ids %p.\n", iface, streams, ids);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
IMFMediaType **type)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id,
|
||||
DWORD index, IMFMediaType **type)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, type %p\n", iface, id, type);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, type %p\n", iface, id, type);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, flags %p.\n", iface, id, flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetOutputStatus(IMFTransform *iface, DWORD *flags)
|
||||
{
|
||||
FIXME("iface %p, flags %p stub!\n", iface, flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
|
||||
{
|
||||
FIXME("iface %p, lower %I64d, upper %I64d.\n", iface, lower, upper);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, event %p stub!\n", iface, id, event);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
|
||||
{
|
||||
FIXME("iface %p, message %#x, param %Ix.\n", iface, message, param);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
|
||||
{
|
||||
FIXME("iface %p, id %#lx, sample %p, flags %#lx.\n", iface, id, sample, flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
|
||||
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
|
||||
{
|
||||
FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface, flags, count, samples, status);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IMFTransformVtbl transform_vtbl =
|
||||
{
|
||||
transform_QueryInterface,
|
||||
transform_AddRef,
|
||||
transform_Release,
|
||||
transform_GetStreamLimits,
|
||||
transform_GetStreamCount,
|
||||
transform_GetStreamIDs,
|
||||
transform_GetInputStreamInfo,
|
||||
transform_GetOutputStreamInfo,
|
||||
transform_GetAttributes,
|
||||
transform_GetInputStreamAttributes,
|
||||
transform_GetOutputStreamAttributes,
|
||||
transform_DeleteInputStream,
|
||||
transform_AddInputStreams,
|
||||
transform_GetInputAvailableType,
|
||||
transform_GetOutputAvailableType,
|
||||
transform_SetInputType,
|
||||
transform_SetOutputType,
|
||||
transform_GetInputCurrentType,
|
||||
transform_GetOutputCurrentType,
|
||||
transform_GetInputStatus,
|
||||
transform_GetOutputStatus,
|
||||
transform_SetOutputBounds,
|
||||
transform_ProcessEvent,
|
||||
transform_ProcessMessage,
|
||||
transform_ProcessInput,
|
||||
transform_ProcessOutput,
|
||||
};
|
||||
|
||||
static HRESULT video_encoder_create(struct video_encoder **out)
|
||||
{
|
||||
struct video_encoder *encoder;
|
||||
HRESULT hr;
|
||||
|
||||
if (!(encoder = calloc(1, sizeof(*encoder))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
encoder->IMFTransform_iface.lpVtbl = &transform_vtbl;
|
||||
encoder->refcount = 1;
|
||||
|
||||
if (FAILED(hr = MFCreateAttributes(&encoder->attributes, 16)))
|
||||
goto failed;
|
||||
if (FAILED(hr = IMFAttributes_SetUINT32(encoder->attributes, &MFT_ENCODER_SUPPORTS_CONFIG_EVENT, TRUE)))
|
||||
goto failed;
|
||||
|
||||
*out = encoder;
|
||||
TRACE("Created video encoder %p\n", encoder);
|
||||
return S_OK;
|
||||
|
||||
failed:
|
||||
if (encoder->attributes)
|
||||
IMFAttributes_Release(encoder->attributes);
|
||||
free(encoder);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT h264_encoder_create(REFIID riid, void **out)
|
||||
{
|
||||
const MFVIDEOFORMAT input_format =
|
||||
{
|
||||
.dwSize = sizeof(MFVIDEOFORMAT),
|
||||
.videoInfo = {.dwWidth = 1920, .dwHeight = 1080},
|
||||
.guidFormat = MFVideoFormat_NV12,
|
||||
};
|
||||
const MFVIDEOFORMAT output_format =
|
||||
{
|
||||
.dwSize = sizeof(MFVIDEOFORMAT),
|
||||
.videoInfo = {.dwWidth = 1920, .dwHeight = 1080},
|
||||
.guidFormat = MFVideoFormat_H264,
|
||||
};
|
||||
struct video_encoder *encoder;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("riid %s, out %p.\n", debugstr_guid(riid), out);
|
||||
|
||||
if (FAILED(hr = check_video_transform_support(&input_format, &output_format)))
|
||||
{
|
||||
ERR_(winediag)("GStreamer doesn't support H.264 encoding, please install appropriate plugins\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (FAILED(hr = video_encoder_create(&encoder)))
|
||||
return hr;
|
||||
|
||||
TRACE("Created h264 encoder transform %p.\n", &encoder->IMFTransform_iface);
|
||||
|
||||
hr = IMFTransform_QueryInterface(&encoder->IMFTransform_iface, riid, out);
|
||||
IMFTransform_Release(&encoder->IMFTransform_iface);
|
||||
return hr;
|
||||
}
|
|
@ -412,11 +412,12 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args)
|
|||
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
|
||||
assert(stream->buffer);
|
||||
|
||||
gst_buffer_unmap(stream->buffer, &stream->map_info);
|
||||
gst_buffer_unref(stream->buffer);
|
||||
stream->buffer = NULL;
|
||||
if (stream->buffer)
|
||||
{
|
||||
gst_buffer_unmap(stream->buffer, &stream->map_info);
|
||||
gst_buffer_unref(stream->buffer);
|
||||
stream->buffer = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
pthread_cond_signal(&stream->event_empty_cond);
|
||||
|
@ -576,24 +577,20 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
|
|||
switch (event->type)
|
||||
{
|
||||
case GST_EVENT_SEGMENT:
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
if (stream->enabled)
|
||||
{
|
||||
const GstSegment *segment;
|
||||
|
||||
gst_event_parse_segment(event, &segment);
|
||||
if (segment->format != GST_FORMAT_TIME)
|
||||
{
|
||||
const GstSegment *segment;
|
||||
|
||||
gst_event_parse_segment(event, &segment);
|
||||
|
||||
if (segment->format != GST_FORMAT_TIME)
|
||||
{
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
GST_FIXME("Unhandled format \"%s\".", gst_format_get_name(segment->format));
|
||||
break;
|
||||
}
|
||||
|
||||
gst_segment_copy_into(segment, &stream->segment);
|
||||
GST_FIXME("Unhandled format \"%s\".", gst_format_get_name(segment->format));
|
||||
break;
|
||||
}
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
gst_segment_copy_into(segment, &stream->segment);
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
case GST_EVENT_EOS:
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
|
@ -608,17 +605,14 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
|
|||
case GST_EVENT_FLUSH_START:
|
||||
pthread_mutex_lock(&parser->mutex);
|
||||
|
||||
if (stream->enabled)
|
||||
{
|
||||
stream->flushing = true;
|
||||
pthread_cond_signal(&stream->event_empty_cond);
|
||||
stream->flushing = true;
|
||||
pthread_cond_signal(&stream->event_empty_cond);
|
||||
|
||||
if (stream->buffer)
|
||||
{
|
||||
gst_buffer_unmap(stream->buffer, &stream->map_info);
|
||||
gst_buffer_unref(stream->buffer);
|
||||
stream->buffer = NULL;
|
||||
}
|
||||
if (stream->buffer)
|
||||
{
|
||||
gst_buffer_unmap(stream->buffer, &stream->map_info);
|
||||
gst_buffer_unref(stream->buffer);
|
||||
stream->buffer = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
|
@ -636,8 +630,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
|
|||
pthread_mutex_lock(&parser->mutex);
|
||||
|
||||
stream->eos = false;
|
||||
if (stream->enabled)
|
||||
stream->flushing = false;
|
||||
stream->flushing = false;
|
||||
|
||||
pthread_mutex_unlock(&parser->mutex);
|
||||
break;
|
||||
|
|
|
@ -107,6 +107,12 @@ coclass CWMVDecMediaObject {}
|
|||
]
|
||||
coclass CMSH264DecoderMFT {}
|
||||
|
||||
[
|
||||
threading(both),
|
||||
uuid(6ca50344-051a-4ded-9779-a43305165e35)
|
||||
]
|
||||
coclass CMSH264EncoderMFT {}
|
||||
|
||||
[
|
||||
threading(both),
|
||||
uuid(f447b69e-1884-4a7e-8055-346f74d6edb3)
|
||||
|
|
|
@ -207,10 +207,7 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p
|
|||
extern macdrv_window macdrv_get_cocoa_window(HWND hwnd, BOOL require_on_screen);
|
||||
extern RGNDATA *get_region_data(HRGN hrgn, HDC hdc_lptodp);
|
||||
extern void activate_on_following_focus(void);
|
||||
extern struct window_surface *create_surface(HWND hwnd, macdrv_window window, const RECT *rect,
|
||||
struct window_surface *old_surface, BOOL use_alpha);
|
||||
extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha);
|
||||
extern void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect);
|
||||
|
||||
extern void macdrv_handle_event(const macdrv_event *event);
|
||||
|
||||
|
|
|
@ -127,8 +127,8 @@ static struct macdrv_window_surface *get_mac_surface(struct window_surface *surf
|
|||
/***********************************************************************
|
||||
* create_surface
|
||||
*/
|
||||
struct window_surface *create_surface(HWND hwnd, macdrv_window window, const RECT *rect,
|
||||
struct window_surface *old_surface, BOOL use_alpha)
|
||||
static struct window_surface *create_surface(HWND hwnd, macdrv_window window, const RECT *rect,
|
||||
struct window_surface *old_surface, BOOL use_alpha)
|
||||
{
|
||||
struct macdrv_window_surface *surface;
|
||||
int width = rect->right - rect->left, height = rect->bottom - rect->top;
|
||||
|
@ -265,7 +265,7 @@ done:
|
|||
* Intersect the accumulated drawn region with a new visible rect,
|
||||
* effectively discarding stale drawing in the surface slack area.
|
||||
*/
|
||||
void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect)
|
||||
static void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect)
|
||||
{
|
||||
struct macdrv_window_surface *surface = get_mac_surface(window_surface);
|
||||
RECT rect = *visible_rect;
|
||||
|
@ -277,3 +277,95 @@ void surface_clip_to_visible_rect(struct window_surface *window_surface, const R
|
|||
intersect_rect(&window_surface->bounds, &window_surface->bounds, &rect);
|
||||
window_surface_unlock(window_surface);
|
||||
}
|
||||
|
||||
|
||||
static inline RECT get_surface_rect(const RECT *visible_rect)
|
||||
{
|
||||
RECT rect = *visible_rect;
|
||||
|
||||
OffsetRect(&rect, -visible_rect->left, -visible_rect->top);
|
||||
rect.left &= ~127;
|
||||
rect.top &= ~127;
|
||||
rect.right = max(rect.left + 128, (rect.right + 127) & ~127);
|
||||
rect.bottom = max(rect.top + 128, (rect.bottom + 127) & ~127);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateWindowSurface (MACDRV.@)
|
||||
*/
|
||||
BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface)
|
||||
{
|
||||
struct macdrv_win_data *data;
|
||||
DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE);
|
||||
RECT surface_rect;
|
||||
|
||||
TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
|
||||
|
||||
if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */
|
||||
|
||||
if (*surface) window_surface_release(*surface);
|
||||
*surface = NULL;
|
||||
|
||||
surface_rect = get_surface_rect(visible_rect);
|
||||
if (data->surface)
|
||||
{
|
||||
if (EqualRect(&data->surface->rect, &surface_rect))
|
||||
{
|
||||
/* existing surface is good enough */
|
||||
surface_clip_to_visible_rect(data->surface, visible_rect);
|
||||
window_surface_add_ref(data->surface);
|
||||
*surface = data->surface;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (!(swp_flags & SWP_SHOWWINDOW) && !(style & WS_VISIBLE)) goto done;
|
||||
|
||||
*surface = create_surface(data->hwnd, data->cocoa_window, &surface_rect, data->surface, FALSE);
|
||||
|
||||
done:
|
||||
release_win_data(data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateLayeredWindow (MACDRV.@)
|
||||
*/
|
||||
BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF color_key,
|
||||
struct window_surface **window_surface)
|
||||
{
|
||||
struct window_surface *surface;
|
||||
struct macdrv_win_data *data;
|
||||
RECT rect;
|
||||
|
||||
if (!(data = get_win_data(hwnd))) return FALSE;
|
||||
|
||||
data->layered = TRUE;
|
||||
data->ulw_layered = TRUE;
|
||||
|
||||
rect = *window_rect;
|
||||
OffsetRect(&rect, -window_rect->left, -window_rect->top);
|
||||
|
||||
surface = data->surface;
|
||||
if (!surface || !EqualRect(&surface->rect, &rect))
|
||||
{
|
||||
data->surface = create_surface(data->hwnd, data->cocoa_window, &rect, NULL, TRUE);
|
||||
macdrv_set_window_surface(data->cocoa_window, data->surface);
|
||||
if (surface) window_surface_release(surface);
|
||||
surface = data->surface;
|
||||
if (data->unminimized_surface)
|
||||
{
|
||||
window_surface_release(data->unminimized_surface);
|
||||
data->unminimized_surface = NULL;
|
||||
}
|
||||
}
|
||||
else set_surface_use_alpha(surface, TRUE);
|
||||
|
||||
if ((*window_surface = surface)) window_surface_add_ref(surface);
|
||||
|
||||
release_win_data(data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1890,46 +1890,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateLayeredWindow (MACDRV.@)
|
||||
*/
|
||||
BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF color_key,
|
||||
struct window_surface **window_surface)
|
||||
{
|
||||
struct window_surface *surface;
|
||||
struct macdrv_win_data *data;
|
||||
RECT rect;
|
||||
|
||||
if (!(data = get_win_data(hwnd))) return FALSE;
|
||||
|
||||
data->layered = TRUE;
|
||||
data->ulw_layered = TRUE;
|
||||
|
||||
rect = *window_rect;
|
||||
OffsetRect(&rect, -window_rect->left, -window_rect->top);
|
||||
|
||||
surface = data->surface;
|
||||
if (!surface || !EqualRect(&surface->rect, &rect))
|
||||
{
|
||||
data->surface = create_surface(data->hwnd, data->cocoa_window, &rect, NULL, TRUE);
|
||||
macdrv_set_window_surface(data->cocoa_window, data->surface);
|
||||
if (surface) window_surface_release(surface);
|
||||
surface = data->surface;
|
||||
if (data->unminimized_surface)
|
||||
{
|
||||
window_surface_release(data->unminimized_surface);
|
||||
data->unminimized_surface = NULL;
|
||||
}
|
||||
}
|
||||
else set_surface_use_alpha(surface, TRUE);
|
||||
|
||||
if ((*window_surface = surface)) window_surface_add_ref(surface);
|
||||
|
||||
release_win_data(data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UpdateLayeredWindow (MACDRV.@)
|
||||
*/
|
||||
|
@ -1984,19 +1944,6 @@ LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||
}
|
||||
|
||||
|
||||
static inline RECT get_surface_rect(const RECT *visible_rect)
|
||||
{
|
||||
RECT rect = *visible_rect;
|
||||
|
||||
OffsetRect(&rect, -visible_rect->left, -visible_rect->top);
|
||||
rect.left &= ~127;
|
||||
rect.top &= ~127;
|
||||
rect.right = max(rect.left + 128, (rect.right + 127) & ~127);
|
||||
rect.bottom = max(rect.top + 128, (rect.bottom + 127) & ~127);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WindowPosChanging (MACDRV.@)
|
||||
*/
|
||||
|
@ -2028,44 +1975,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateWindowSurface (MACDRV.@)
|
||||
*/
|
||||
BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface)
|
||||
{
|
||||
struct macdrv_win_data *data;
|
||||
DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE);
|
||||
RECT surface_rect;
|
||||
|
||||
TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
|
||||
|
||||
if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */
|
||||
|
||||
if (*surface) window_surface_release(*surface);
|
||||
*surface = NULL;
|
||||
|
||||
surface_rect = get_surface_rect(visible_rect);
|
||||
if (data->surface)
|
||||
{
|
||||
if (EqualRect(&data->surface->rect, &surface_rect))
|
||||
{
|
||||
/* existing surface is good enough */
|
||||
surface_clip_to_visible_rect(data->surface, visible_rect);
|
||||
window_surface_add_ref(data->surface);
|
||||
*surface = data->surface;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (!(swp_flags & SWP_SHOWWINDOW) && !(style & WS_VISIBLE)) goto done;
|
||||
|
||||
*surface = create_surface(data->hwnd, data->cocoa_window, &surface_rect, data->surface, FALSE);
|
||||
|
||||
done:
|
||||
release_win_data(data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WindowPosChanged (MACDRV.@)
|
||||
*/
|
||||
|
|
|
@ -272,11 +272,34 @@ void wayland_shm_buffer_unref(struct wayland_shm_buffer *shm_buffer);
|
|||
* Wayland window surface
|
||||
*/
|
||||
|
||||
struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect);
|
||||
void wayland_window_surface_update_wayland_surface(struct window_surface *surface,
|
||||
struct wayland_surface *wayland_surface);
|
||||
void wayland_window_flush(HWND hwnd);
|
||||
|
||||
/**********************************************************************
|
||||
* Wayland Window
|
||||
*/
|
||||
|
||||
/* private window data */
|
||||
struct wayland_win_data
|
||||
{
|
||||
struct rb_entry entry;
|
||||
/* hwnd that this private data belongs to */
|
||||
HWND hwnd;
|
||||
/* wayland surface (if any) for this window */
|
||||
struct wayland_surface *wayland_surface;
|
||||
/* wine window_surface backing this window */
|
||||
struct window_surface *window_surface;
|
||||
/* USER window rectangle relative to win32 parent window client area */
|
||||
RECT window_rect;
|
||||
/* USER client rectangle relative to win32 parent window client area */
|
||||
RECT client_rect;
|
||||
BOOL managed;
|
||||
};
|
||||
|
||||
struct wayland_win_data *wayland_win_data_get(HWND hwnd);
|
||||
void wayland_win_data_release(struct wayland_win_data *data);
|
||||
|
||||
/**********************************************************************
|
||||
* Wayland Keyboard
|
||||
*/
|
||||
|
|
|
@ -56,23 +56,6 @@ static BOOL set_window_pos(HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy,
|
|||
}
|
||||
|
||||
|
||||
/* private window data */
|
||||
struct wayland_win_data
|
||||
{
|
||||
struct rb_entry entry;
|
||||
/* hwnd that this private data belongs to */
|
||||
HWND hwnd;
|
||||
/* wayland surface (if any) for this window */
|
||||
struct wayland_surface *wayland_surface;
|
||||
/* wine window_surface backing this window */
|
||||
struct window_surface *window_surface;
|
||||
/* USER window rectangle relative to win32 parent window client area */
|
||||
RECT window_rect;
|
||||
/* USER client rectangle relative to win32 parent window client area */
|
||||
RECT client_rect;
|
||||
BOOL managed;
|
||||
};
|
||||
|
||||
static int wayland_win_data_cmp_rb(const void *key,
|
||||
const struct rb_entry *entry)
|
||||
{
|
||||
|
@ -153,7 +136,7 @@ static void wayland_win_data_destroy(struct wayland_win_data *data)
|
|||
*
|
||||
* Lock and return the data structure associated with a window.
|
||||
*/
|
||||
static struct wayland_win_data *wayland_win_data_get(HWND hwnd)
|
||||
struct wayland_win_data *wayland_win_data_get(HWND hwnd)
|
||||
{
|
||||
struct rb_entry *rb_entry;
|
||||
|
||||
|
@ -172,7 +155,7 @@ static struct wayland_win_data *wayland_win_data_get(HWND hwnd)
|
|||
*
|
||||
* Release the data returned by wayland_win_data_get.
|
||||
*/
|
||||
static void wayland_win_data_release(struct wayland_win_data *data)
|
||||
void wayland_win_data_release(struct wayland_win_data *data)
|
||||
{
|
||||
assert(data);
|
||||
pthread_mutex_unlock(&win_data_mutex);
|
||||
|
@ -471,42 +454,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WAYLAND_CreateWindowSurface
|
||||
*/
|
||||
BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface)
|
||||
{
|
||||
struct wayland_win_data *data;
|
||||
RECT surface_rect;
|
||||
|
||||
TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
|
||||
|
||||
if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */
|
||||
|
||||
/* Release the dummy surface wine provides for toplevels. */
|
||||
if (*surface) window_surface_release(*surface);
|
||||
*surface = NULL;
|
||||
|
||||
surface_rect = *visible_rect;
|
||||
OffsetRect(&surface_rect, -surface_rect.left, -surface_rect.top);
|
||||
|
||||
/* Check if we can reuse our current window surface. */
|
||||
if (data->window_surface &&
|
||||
EqualRect(&data->window_surface->rect, &surface_rect))
|
||||
{
|
||||
window_surface_add_ref(data->window_surface);
|
||||
*surface = data->window_surface;
|
||||
TRACE("reusing surface %p\n", *surface);
|
||||
goto done;
|
||||
}
|
||||
|
||||
*surface = wayland_window_surface_create(data->hwnd, &surface_rect);
|
||||
|
||||
done:
|
||||
wayland_win_data_release(data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* WAYLAND_WindowPosChanged
|
||||
*/
|
||||
|
|
|
@ -449,7 +449,7 @@ static const struct window_surface_funcs wayland_window_surface_funcs =
|
|||
/***********************************************************************
|
||||
* wayland_window_surface_create
|
||||
*/
|
||||
struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect)
|
||||
static struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect)
|
||||
{
|
||||
char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
|
||||
BITMAPINFO *info = (BITMAPINFO *)buffer;
|
||||
|
@ -516,3 +516,40 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window
|
|||
|
||||
window_surface_unlock(window_surface);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WAYLAND_CreateWindowSurface
|
||||
*/
|
||||
BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface)
|
||||
{
|
||||
struct wayland_win_data *data;
|
||||
RECT surface_rect;
|
||||
|
||||
TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
|
||||
|
||||
if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */
|
||||
|
||||
/* Release the dummy surface wine provides for toplevels. */
|
||||
if (*surface) window_surface_release(*surface);
|
||||
*surface = NULL;
|
||||
|
||||
surface_rect = *visible_rect;
|
||||
OffsetRect(&surface_rect, -surface_rect.left, -surface_rect.top);
|
||||
|
||||
/* Check if we can reuse our current window surface. */
|
||||
if (data->window_surface &&
|
||||
EqualRect(&data->window_surface->rect, &surface_rect))
|
||||
{
|
||||
window_surface_add_ref(data->window_surface);
|
||||
*surface = data->window_surface;
|
||||
TRACE("reusing surface %p\n", *surface);
|
||||
goto done;
|
||||
}
|
||||
|
||||
*surface = wayland_window_surface_create(data->hwnd, &surface_rect);
|
||||
|
||||
done:
|
||||
wayland_win_data_release(data);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -2054,8 +2054,8 @@ static const struct window_surface_funcs x11drv_surface_funcs =
|
|||
/***********************************************************************
|
||||
* create_surface
|
||||
*/
|
||||
struct window_surface *create_surface( HWND hwnd, Window window, const XVisualInfo *vis, const RECT *rect,
|
||||
COLORREF color_key, BOOL use_alpha )
|
||||
static struct window_surface *create_surface( HWND hwnd, Window window, const XVisualInfo *vis, const RECT *rect,
|
||||
COLORREF color_key, BOOL use_alpha )
|
||||
{
|
||||
const XPixmapFormatValues *format = pixmap_formats[vis->depth];
|
||||
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||
|
@ -2182,3 +2182,99 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect )
|
|||
window_surface_unlock( window_surface );
|
||||
return region;
|
||||
}
|
||||
|
||||
|
||||
BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect )
|
||||
{
|
||||
*surface_rect = NtUserGetVirtualScreenRect();
|
||||
|
||||
if (!intersect_rect( surface_rect, surface_rect, visible_rect )) return FALSE;
|
||||
OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top );
|
||||
surface_rect->left &= ~31;
|
||||
surface_rect->top &= ~31;
|
||||
surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 );
|
||||
surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateWindowSurface (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface )
|
||||
{
|
||||
struct x11drv_win_data *data;
|
||||
RECT surface_rect;
|
||||
DWORD flags;
|
||||
COLORREF key;
|
||||
BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
|
||||
|
||||
TRACE( "hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( visible_rect ), surface );
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
|
||||
|
||||
if (*surface) window_surface_release( *surface );
|
||||
*surface = NULL; /* indicate that we want to draw directly to the window */
|
||||
|
||||
if (data->embedded) goto done; /* draw directly to the window */
|
||||
if (data->whole_window == root_window) goto done; /* draw directly to the window */
|
||||
if (data->client_window) goto done; /* draw directly to the window */
|
||||
if (!client_side_graphics && !layered) goto done; /* draw directly to the window */
|
||||
|
||||
if (!get_surface_rect( visible_rect, &surface_rect )) goto done;
|
||||
if (data->surface)
|
||||
{
|
||||
if (EqualRect( &data->surface->rect, &surface_rect ))
|
||||
{
|
||||
/* existing surface is good enough */
|
||||
window_surface_add_ref( data->surface );
|
||||
*surface = data->surface;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (!(swp_flags & SWP_SHOWWINDOW) && !(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) goto done;
|
||||
|
||||
if (!layered || !NtUserGetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY))
|
||||
key = CLR_INVALID;
|
||||
|
||||
*surface = create_surface( data->hwnd, data->whole_window, &data->vis, &surface_rect, key, FALSE );
|
||||
|
||||
done:
|
||||
release_win_data( data );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* CreateLayeredWindow (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key,
|
||||
struct window_surface **window_surface )
|
||||
{
|
||||
struct window_surface *surface;
|
||||
struct x11drv_win_data *data;
|
||||
RECT rect;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
|
||||
data->layered = TRUE;
|
||||
if (!data->embedded && argb_visual.visualid) set_window_visual( data, &argb_visual, TRUE );
|
||||
|
||||
rect = *window_rect;
|
||||
OffsetRect( &rect, -window_rect->left, -window_rect->top );
|
||||
|
||||
surface = data->surface;
|
||||
if (!surface || !EqualRect( &surface->rect, &rect ))
|
||||
{
|
||||
data->surface = create_surface( data->hwnd, data->whole_window, &data->vis, &rect,
|
||||
color_key, data->use_alpha );
|
||||
if (surface) window_surface_release( surface );
|
||||
surface = data->surface;
|
||||
}
|
||||
else set_surface_color_key( surface, color_key );
|
||||
|
||||
if ((*window_surface = surface)) window_surface_add_ref( surface );
|
||||
release_win_data( data );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -2576,20 +2576,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
static inline BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect )
|
||||
{
|
||||
*surface_rect = NtUserGetVirtualScreenRect();
|
||||
|
||||
if (!intersect_rect( surface_rect, surface_rect, visible_rect )) return FALSE;
|
||||
OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top );
|
||||
surface_rect->left &= ~31;
|
||||
surface_rect->top &= ~31;
|
||||
surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 );
|
||||
surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WindowPosChanging (X11DRV.@)
|
||||
*/
|
||||
|
@ -2626,53 +2612,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateWindowSurface (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface )
|
||||
{
|
||||
struct x11drv_win_data *data;
|
||||
RECT surface_rect;
|
||||
DWORD flags;
|
||||
COLORREF key;
|
||||
BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
|
||||
|
||||
TRACE( "hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( visible_rect ), surface );
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
|
||||
|
||||
if (*surface) window_surface_release( *surface );
|
||||
*surface = NULL; /* indicate that we want to draw directly to the window */
|
||||
|
||||
if (data->embedded) goto done; /* draw directly to the window */
|
||||
if (data->whole_window == root_window) goto done; /* draw directly to the window */
|
||||
if (data->client_window) goto done; /* draw directly to the window */
|
||||
if (!client_side_graphics && !layered) goto done; /* draw directly to the window */
|
||||
|
||||
if (!get_surface_rect( visible_rect, &surface_rect )) goto done;
|
||||
if (data->surface)
|
||||
{
|
||||
if (EqualRect( &data->surface->rect, &surface_rect ))
|
||||
{
|
||||
/* existing surface is good enough */
|
||||
window_surface_add_ref( data->surface );
|
||||
*surface = data->surface;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (!(swp_flags & SWP_SHOWWINDOW) && !(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) goto done;
|
||||
|
||||
if (!layered || !NtUserGetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY))
|
||||
key = CLR_INVALID;
|
||||
|
||||
*surface = create_surface( data->hwnd, data->whole_window, &data->vis, &surface_rect, key, FALSE );
|
||||
|
||||
done:
|
||||
release_win_data( data );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WindowPosChanged (X11DRV.@)
|
||||
*/
|
||||
|
@ -2983,41 +2922,6 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO
|
|||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* CreateLayeredWindow (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key,
|
||||
struct window_surface **window_surface )
|
||||
{
|
||||
struct window_surface *surface;
|
||||
struct x11drv_win_data *data;
|
||||
RECT rect;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
|
||||
data->layered = TRUE;
|
||||
if (!data->embedded && argb_visual.visualid) set_window_visual( data, &argb_visual, TRUE );
|
||||
|
||||
rect = *window_rect;
|
||||
OffsetRect( &rect, -window_rect->left, -window_rect->top );
|
||||
|
||||
surface = data->surface;
|
||||
if (!surface || !EqualRect( &surface->rect, &rect ))
|
||||
{
|
||||
data->surface = create_surface( data->hwnd, data->whole_window, &data->vis, &rect,
|
||||
color_key, data->use_alpha );
|
||||
if (surface) window_surface_release( surface );
|
||||
surface = data->surface;
|
||||
}
|
||||
else set_surface_color_key( surface, color_key );
|
||||
|
||||
if ((*window_surface = surface)) window_surface_add_ref( surface );
|
||||
release_win_data( data );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* UpdateLayeredWindow (X11DRV.@)
|
||||
*/
|
||||
|
|
|
@ -266,8 +266,6 @@ extern Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const B
|
|||
const struct gdi_image_bits *bits, UINT coloruse );
|
||||
extern DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis,
|
||||
BITMAPINFO *info, struct gdi_image_bits *bits );
|
||||
extern struct window_surface *create_surface( HWND hwnd, Window window, const XVisualInfo *vis, const RECT *rect,
|
||||
COLORREF color_key, BOOL use_alpha );
|
||||
extern void set_surface_color_key( struct window_surface *window_surface, COLORREF color_key );
|
||||
extern HRGN expose_surface( struct window_surface *window_surface, const RECT *rect );
|
||||
|
||||
|
@ -687,6 +685,7 @@ typedef int (*x11drv_error_callback)( Display *display, XErrorEvent *event, void
|
|||
|
||||
extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg );
|
||||
extern int X11DRV_check_error(void);
|
||||
extern BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect );
|
||||
extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, int y, int cx, int cy );
|
||||
extern POINT virtual_screen_to_root( INT x, INT y );
|
||||
extern POINT root_to_virtual_screen( INT x, INT y );
|
||||
|
|
|
@ -48,9 +48,14 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
|||
#include "wine/vulkan.h"
|
||||
#include "wine/vulkan_driver.h"
|
||||
|
||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR)
|
||||
|
||||
static void *xrandr_handle;
|
||||
static void *vulkan_handle;
|
||||
static void *(*p_vkGetInstanceProcAddr)(VkInstance, const char *);
|
||||
|
||||
static VkInstance vk_instance; /* Vulkan instance for XRandR functions */
|
||||
static VkResult (*p_vkGetRandROutputDisplayEXT)( VkPhysicalDevice, Display *, RROutput, VkDisplayKHR * );
|
||||
static PFN_vkGetPhysicalDeviceProperties2KHR p_vkGetPhysicalDeviceProperties2KHR;
|
||||
static PFN_vkEnumeratePhysicalDevices p_vkEnumeratePhysicalDevices;
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
|
||||
MAKE_FUNCPTR(XRRConfigCurrentConfiguration)
|
||||
|
@ -140,8 +145,31 @@ sym_not_found:
|
|||
|
||||
#ifdef SONAME_LIBVULKAN
|
||||
|
||||
static void *vulkan_handle;
|
||||
static void *(*p_vkGetInstanceProcAddr)(VkInstance, const char *);
|
||||
|
||||
static void vulkan_init_once(void)
|
||||
{
|
||||
static const char *extensions[] =
|
||||
{
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
|
||||
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
|
||||
"VK_EXT_acquire_xlib_display",
|
||||
"VK_EXT_direct_mode_display",
|
||||
"VK_KHR_display",
|
||||
VK_KHR_SURFACE_EXTENSION_NAME,
|
||||
};
|
||||
VkInstanceCreateInfo create_info =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.ppEnabledExtensionNames = extensions,
|
||||
.enabledExtensionCount = ARRAY_SIZE(extensions),
|
||||
};
|
||||
|
||||
PFN_vkDestroyInstance p_vkDestroyInstance;
|
||||
PFN_vkCreateInstance p_vkCreateInstance;
|
||||
VkResult vr;
|
||||
|
||||
if (!(vulkan_handle = dlopen( SONAME_LIBVULKAN, RTLD_NOW )))
|
||||
{
|
||||
ERR( "Failed to load %s\n", SONAME_LIBVULKAN );
|
||||
|
@ -153,12 +181,33 @@ static void vulkan_init_once(void)
|
|||
{ \
|
||||
ERR( "Failed to find " #f "\n" ); \
|
||||
dlclose( vulkan_handle ); \
|
||||
vulkan_handle = NULL; \
|
||||
return; \
|
||||
}
|
||||
|
||||
LOAD_FUNCPTR( vkGetInstanceProcAddr );
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
p_vkCreateInstance = p_vkGetInstanceProcAddr( NULL, "vkCreateInstance" );
|
||||
if ((vr = p_vkCreateInstance( &create_info, NULL, &vk_instance )))
|
||||
{
|
||||
WARN( "Failed to create a Vulkan instance, vr %d.\n", vr );
|
||||
return;
|
||||
}
|
||||
|
||||
p_vkDestroyInstance = p_vkGetInstanceProcAddr( vk_instance, "vkDestroyInstance" );
|
||||
#define LOAD_VK_FUNC(f) \
|
||||
if (!(p_##f = (void *)p_vkGetInstanceProcAddr( vk_instance, #f ))) \
|
||||
{ \
|
||||
WARN("Failed to load " #f ".\n"); \
|
||||
p_vkDestroyInstance( vk_instance, NULL ); \
|
||||
vk_instance = NULL; \
|
||||
return; \
|
||||
}
|
||||
|
||||
LOAD_VK_FUNC( vkEnumeratePhysicalDevices )
|
||||
LOAD_VK_FUNC( vkGetPhysicalDeviceProperties2KHR )
|
||||
LOAD_VK_FUNC( vkGetRandROutputDisplayEXT )
|
||||
#undef LOAD_VK_FUNC
|
||||
}
|
||||
|
||||
#else /* SONAME_LIBVULKAN */
|
||||
|
@ -174,7 +223,7 @@ static BOOL vulkan_init(void)
|
|||
{
|
||||
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
|
||||
pthread_once( &init_once, vulkan_init_once );
|
||||
return !!vulkan_handle;
|
||||
return !!vk_instance;
|
||||
}
|
||||
|
||||
static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
|
||||
|
@ -668,65 +717,20 @@ static BOOL is_crtc_primary( RECT primary, const XRRCrtcInfo *crtc )
|
|||
crtc->y + crtc->height == primary.bottom;
|
||||
}
|
||||
|
||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR)
|
||||
|
||||
static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRProviderInfo *provider_info,
|
||||
struct x11drv_gpu *prev_gpus, int prev_gpu_count )
|
||||
{
|
||||
static const char *extensions[] =
|
||||
{
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
|
||||
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
|
||||
"VK_EXT_acquire_xlib_display",
|
||||
"VK_EXT_direct_mode_display",
|
||||
"VK_KHR_display",
|
||||
VK_KHR_SURFACE_EXTENSION_NAME,
|
||||
};
|
||||
VkResult (*pvkGetRandROutputDisplayEXT)( VkPhysicalDevice, Display *, RROutput, VkDisplayKHR * );
|
||||
PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR;
|
||||
PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices;
|
||||
uint32_t device_count, device_idx, output_idx, i;
|
||||
PFN_vkDestroyInstance pvkDestroyInstance = NULL;
|
||||
VkPhysicalDevice *vk_physical_devices = NULL;
|
||||
VkPhysicalDeviceProperties2 properties2;
|
||||
PFN_vkCreateInstance pvkCreateInstance;
|
||||
VkInstanceCreateInfo create_info;
|
||||
VkPhysicalDeviceIDProperties id;
|
||||
VkInstance vk_instance = NULL;
|
||||
VkDisplayKHR vk_display;
|
||||
BOOL ret = FALSE;
|
||||
VkResult vr;
|
||||
|
||||
if (!vulkan_init()) goto done;
|
||||
|
||||
memset( &create_info, 0, sizeof(create_info) );
|
||||
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
create_info.enabledExtensionCount = ARRAY_SIZE(extensions);
|
||||
create_info.ppEnabledExtensionNames = extensions;
|
||||
|
||||
#define LOAD_VK_FUNC(f) \
|
||||
if (!(p##f = (void *)p_vkGetInstanceProcAddr( vk_instance, #f ))) \
|
||||
{ \
|
||||
WARN("Failed to load " #f ".\n"); \
|
||||
goto done; \
|
||||
}
|
||||
|
||||
LOAD_VK_FUNC( vkCreateInstance )
|
||||
|
||||
vr = pvkCreateInstance( &create_info, NULL, &vk_instance );
|
||||
if (vr != VK_SUCCESS)
|
||||
{
|
||||
WARN( "Failed to create a Vulkan instance, vr %d.\n", vr );
|
||||
goto done;
|
||||
}
|
||||
|
||||
LOAD_VK_FUNC(vkEnumeratePhysicalDevices)
|
||||
LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR)
|
||||
LOAD_VK_FUNC(vkGetRandROutputDisplayEXT)
|
||||
LOAD_VK_FUNC(vkDestroyInstance)
|
||||
#undef LOAD_VK_FUNC
|
||||
|
||||
vr = pvkEnumeratePhysicalDevices( vk_instance, &device_count, NULL );
|
||||
vr = p_vkEnumeratePhysicalDevices( vk_instance, &device_count, NULL );
|
||||
if (vr != VK_SUCCESS || !device_count)
|
||||
{
|
||||
WARN("No Vulkan device found, vr %d, device_count %d.\n", vr, device_count);
|
||||
|
@ -736,7 +740,7 @@ static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRPro
|
|||
if (!(vk_physical_devices = calloc( device_count, sizeof(*vk_physical_devices) )))
|
||||
goto done;
|
||||
|
||||
vr = pvkEnumeratePhysicalDevices( vk_instance, &device_count, vk_physical_devices );
|
||||
vr = p_vkEnumeratePhysicalDevices( vk_instance, &device_count, vk_physical_devices );
|
||||
if (vr != VK_SUCCESS)
|
||||
{
|
||||
WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr);
|
||||
|
@ -749,8 +753,8 @@ static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRPro
|
|||
{
|
||||
for (output_idx = 0; output_idx < provider_info->noutputs; ++output_idx)
|
||||
{
|
||||
vr = pvkGetRandROutputDisplayEXT( vk_physical_devices[device_idx], gdi_display,
|
||||
provider_info->outputs[output_idx], &vk_display );
|
||||
vr = p_vkGetRandROutputDisplayEXT( vk_physical_devices[device_idx], gdi_display,
|
||||
provider_info->outputs[output_idx], &vk_display );
|
||||
if (vr != VK_SUCCESS || vk_display == VK_NULL_HANDLE)
|
||||
continue;
|
||||
|
||||
|
@ -759,7 +763,7 @@ static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRPro
|
|||
properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
properties2.pNext = &id;
|
||||
|
||||
pvkGetPhysicalDeviceProperties2KHR( vk_physical_devices[device_idx], &properties2 );
|
||||
p_vkGetPhysicalDeviceProperties2KHR( vk_physical_devices[device_idx], &properties2 );
|
||||
for (i = 0; i < prev_gpu_count; ++i)
|
||||
{
|
||||
if (!memcmp( &prev_gpus[i].vulkan_uuid, &id.deviceUUID, sizeof(id.deviceUUID) ))
|
||||
|
@ -788,7 +792,6 @@ static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRPro
|
|||
|
||||
done:
|
||||
free( vk_physical_devices );
|
||||
if (vk_instance && pvkDestroyInstance) pvkDestroyInstance( vk_instance, NULL );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -521,6 +521,18 @@ NTSTATUS WINAPI wow64_NtSetInformationToken( UINT *args )
|
|||
|
||||
switch (class)
|
||||
{
|
||||
case TokenIntegrityLevel: /* TOKEN_MANDATORY_LABEL */
|
||||
if (len >= sizeof(TOKEN_MANDATORY_LABEL32))
|
||||
{
|
||||
TOKEN_MANDATORY_LABEL32 *label32 = ptr;
|
||||
TOKEN_MANDATORY_LABEL label;
|
||||
|
||||
label.Label.Sid = ULongToPtr( label32->Label.Sid );
|
||||
label.Label.Attributes = label32->Label.Attributes;
|
||||
return NtSetInformationToken( handle, class, &label, sizeof(label) );
|
||||
}
|
||||
else return STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
||||
case TokenSessionId: /* ULONG */
|
||||
return NtSetInformationToken( handle, class, ptr, len );
|
||||
|
||||
|
|
|
@ -367,6 +367,11 @@ typedef struct
|
|||
DWORD Attributes;
|
||||
} SID_AND_ATTRIBUTES32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SID_AND_ATTRIBUTES32 Label;
|
||||
} TOKEN_MANDATORY_LABEL32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG DefaultDacl;
|
||||
|
|
|
@ -662,6 +662,7 @@ SOURCES = \
|
|||
rmxftmpl.x \
|
||||
roapi.h \
|
||||
roerrorapi.h \
|
||||
rometadata.h \
|
||||
rometadataresolution.h \
|
||||
roparameterizediid.idl \
|
||||
row.idl \
|
||||
|
@ -825,12 +826,15 @@ SOURCES = \
|
|||
windef.h \
|
||||
windns.h \
|
||||
windot11.h \
|
||||
windows.applicationmodel.activation.idl \
|
||||
windows.applicationmodel.background.idl \
|
||||
windows.applicationmodel.core.idl \
|
||||
windows.applicationmodel.idl \
|
||||
windows.devices.bluetooth.idl \
|
||||
windows.devices.enumeration.idl \
|
||||
windows.devices.geolocation.idl \
|
||||
windows.devices.haptics.idl \
|
||||
windows.devices.input.idl \
|
||||
windows.devices.power.idl \
|
||||
windows.devices.radios.idl \
|
||||
windows.devices.usb.idl \
|
||||
|
@ -849,6 +853,7 @@ SOURCES = \
|
|||
windows.graphics.directx.idl \
|
||||
windows.graphics.effects.idl \
|
||||
windows.graphics.holographic.idl \
|
||||
windows.graphics.idl \
|
||||
windows.graphics.imaging.idl \
|
||||
windows.h \
|
||||
windows.management.deployment.idl \
|
||||
|
@ -885,6 +890,7 @@ SOURCES = \
|
|||
windows.ui.composition.interop.idl \
|
||||
windows.ui.core.idl \
|
||||
windows.ui.idl \
|
||||
windows.ui.input.idl \
|
||||
windows.ui.viewmanagement.idl \
|
||||
windows.ui.xaml.hosting.desktopwindowxamlsource.idl \
|
||||
windowscontracts.idl \
|
||||
|
|
|
@ -642,6 +642,9 @@
|
|||
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
|
||||
#undef HAVE_VALGRIND_VALGRIND_H
|
||||
|
||||
/* Define to 1 if the Wine preloader is being used. */
|
||||
#undef HAVE_WINE_PRELOADER
|
||||
|
||||
/* Define to 1 if you have the <X11/extensions/shape.h> header file. */
|
||||
#undef HAVE_X11_EXTENSIONS_SHAPE_H
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user