Add mirror 'wine-tkg-git' at '97dec06'

This commit is contained in:
Nathan 2022-10-07 13:55:35 -05:00
parent e428cb8860
commit 11cf41df16
1375 changed files with 5046584 additions and 0 deletions

View File

@ -21,6 +21,11 @@
"branch": "master",
"revision": "3e101247f521a7f75825d165613ca406b3f41d41"
},
"wine-tkg-git": {
"url": "https://github.com/Frogging-Family/wine-tkg-git.git",
"branch": "master",
"revision": "97dec067447ffc844d85869c24f30635176a0039"
},
"zfs-dkms": {
"url": "https://aur.archlinux.org/zfs-dkms.git",
"branch": "master",

15
wine-tkg-git/.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
# wine-tkg
*.mypatch linguist-language=Diff
*.myrevert linguist-language=Diff
*.myearlypatch linguist-language=Diff
*.myearlyrevert linguist-language=Diff
*.mystagingpatch linguist-language=Diff
*.mystagingrevert linguist-language=Diff
# proton-tkg
*.myprotonpatch linguist-language=Diff
*.myprotonrevert linguist-language=Diff
*.mydxvkpatch linguist-language=Diff
*.mydxvkrevert linguist-language=Diff
*.myvkd3dpatch linguist-language=Diff
*.myvkd3drevert linguist-language=Diff

2
wine-tkg-git/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
patreon: tkglitch
custom: ["https://www.paypal.me/TkGlitch"]

View File

@ -0,0 +1,36 @@
name: Proton nopackage Arch Linux CI
on:
schedule:
- cron: '25 9,21 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- uses: actions/checkout@v2
- name: Compile
run: |
echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
pacman -Syu --noconfirm base-devel sudo lib32-jack2
useradd user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chown user -R ..
chown user -R /tmp
export CARGO_HOME="$PWD"
cd proton-tkg
sed -i 's/distro=""/distro="archlinux"/' proton-tkg.cfg
sed -i 's/uninstaller="false"/uninstaller="true"/' proton-tkg.cfg
sed -i 's/autoinstall="false"/autoinstall="true"/' proton-tkg.cfg
sed -i 's/LOCAL_PRESET=""/LOCAL_PRESET="none"/' proton-tkg.cfg
sed -i 's/build_gstreamer="false"/build_gstreamer="true"/' proton-tkg.cfg
sed -i 's/lib32_gstreamer="false"/lib32_gstreamer="true"/' proton-tkg.cfg
touch tarplz
yes|./proton-tkg.sh
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: proton-tkg-build
path: proton-tkg/built/*.tar

View File

@ -0,0 +1,28 @@
name: Proton Arch Linux CI
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- uses: actions/checkout@v2
- name: Compile
run: |
echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
pacman -Syu --noconfirm base-devel sudo lib32-jack2
useradd user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chown user -R ..
chown user -R /tmp
export CARGO_HOME="$PWD"
cd proton-tkg
su user -c "yes ''|PKGDEST=/tmp/proton-tkg makepkg --noconfirm -s"
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: proton-tkg-build
path: /tmp/proton-tkg

View File

@ -0,0 +1,33 @@
name: Proton nopackage Ubuntu CI
on:
schedule:
- cron: '25 9,21 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Compile
run: |
sudo dpkg --add-architecture i386 && sudo apt update
sudo apt install aptitude
sudo aptitude remove -y '?narrow(?installed,?version(deb.sury.org))'
export CARGO_HOME="$PWD"
cd proton-tkg
sed -i 's/distro=""/distro="debuntu"/' proton-tkg.cfg
sed -i 's/uninstaller="false"/uninstaller="true"/' proton-tkg.cfg
sed -i 's/autoinstall="false"/autoinstall="true"/' proton-tkg.cfg
sed -i 's/LOCAL_PRESET=""/LOCAL_PRESET="none"/' proton-tkg.cfg
sed -i 's/build_gstreamer="false"/build_gstreamer="true"/' proton-tkg.cfg
sed -i 's/lib32_gstreamer="false"/lib32_gstreamer="true"/' proton-tkg.cfg
touch tarplz
yes|./proton-tkg.sh
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: proton-tkg-build
path: proton-tkg/built/*.tar

View File

@ -0,0 +1,35 @@
name: Proton Valve xbe nopackage Arch Linux CI
on:
schedule:
- cron: '45 8,20 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- uses: actions/checkout@v2
- name: Compile
run: |
echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
pacman -Syu --noconfirm base-devel sudo lib32-jack2
useradd user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chown user -R ..
chown user -R /tmp
export CARGO_HOME="$PWD"
cd proton-tkg
sed -i 's/distro=""/distro="archlinux"/' proton-tkg.cfg
sed -i 's/uninstaller="false"/uninstaller="true"/' proton-tkg.cfg
sed -i 's/autoinstall="false"/autoinstall="true"/' proton-tkg.cfg
sed -i 's/build_gstreamer="false"/build_gstreamer="true"/' proton-tkg.cfg
sed -i 's/lib32_gstreamer="false"/lib32_gstreamer="true"/' proton-tkg.cfg
touch tarplz
yes|./proton-tkg.sh
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: proton-tkg-build
path: proton-tkg/built/*.tar

View File

@ -0,0 +1,30 @@
name: Wine Arch Linux CI
on:
schedule:
- cron: '45 8,20 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- uses: actions/checkout@v2
- name: Compile
run: |
echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
pacman -Syu --noconfirm base-devel sudo
useradd user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chown user -R . && cd wine-tkg-git
# Workaround for jack&jack2 conflict https://github.com/Frogging-Family/wine-tkg-git/issues/237
sed -i "/'jack2' 'lib32-jack2'/d" PKGBUILD
sed -i "/'gst-plugins-good' 'lib32-gst-plugins-good'/d" PKGBUILD
su user -c "yes|PKGDEST=/tmp/wine-tkg makepkg --noconfirm -s"
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: wine-tkg-build
path: /tmp/wine-tkg

View File

@ -0,0 +1,26 @@
name: Wine Fedora CI
on:
schedule:
- cron: '25 9,21 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container: fedora:latest
steps:
- uses: actions/checkout@v2
- name: Compilation
run: |
sudo dnf -y -q update
cd wine-tkg-git
sed -i 's/distro=""/distro="fedora"/' customization.cfg
touch tarplz
yes|./non-makepkg-build.sh
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: wine-tkg-build
path: wine-tkg-git/non-makepkg-builds

View File

@ -0,0 +1,29 @@
name: Wine LoL CI
on:
schedule:
- cron: '25 9,21 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Compilation
run: |
sudo dpkg --add-architecture i386 && sudo apt update
sudo apt install aptitude
sudo aptitude remove -y '?narrow(?installed,?version(deb.sury.org))'
cd wine-tkg-git
sed -i 's/distro=""/distro="debuntu"/' customization.cfg
sed -i 's/lol920_fix="false"/lol920_fix="true"/' customization.cfg
touch tarplz
yes|./non-makepkg-build.sh
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: wine-tkg-build
path: wine-tkg-git/non-makepkg-builds

View File

@ -0,0 +1,28 @@
name: Wine Ubuntu CI
on:
schedule:
- cron: '25 9,21 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Compilation
run: |
sudo dpkg --add-architecture i386 && sudo apt update
sudo apt install aptitude
sudo aptitude remove -y '?narrow(?installed,?version(deb.sury.org))'
cd wine-tkg-git
sed -i 's/distro=""/distro="debuntu"/' customization.cfg
touch tarplz
yes|./non-makepkg-build.sh
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: wine-tkg-build
path: wine-tkg-git/non-makepkg-builds

View File

@ -0,0 +1,31 @@
name: Wine Valve exp bleeding edge Pacman CI
on:
schedule:
- cron: '45 8,20 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- uses: actions/checkout@v2
- name: Compile
run: |
echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
pacman -Syu --noconfirm base-devel sudo
useradd user -G wheel && echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chown user -R . && cd wine-tkg-git
# Workaround for jack&jack2 conflict https://github.com/Frogging-Family/wine-tkg-git/issues/237
sed -i "/'jack2' 'lib32-jack2'/d" PKGBUILD
sed -i "/'gst-plugins-good' 'lib32-gst-plugins-good'/d" PKGBUILD
sed -i 's/LOCAL_PRESET=""/LOCAL_PRESET="valve-exp-bleeding"/' customization.cfg
su user -c "yes|PKGDEST=/tmp/wine-tkg makepkg --noconfirm -s"
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: wine-tkg-build
path: /tmp/wine-tkg

View File

@ -0,0 +1,29 @@
name: Wine Valve exp bleeding edge CI
on:
schedule:
- cron: '25 9,21 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Compilation
run: |
sudo dpkg --add-architecture i386 && sudo apt update
sudo apt install aptitude
sudo aptitude remove -y '?narrow(?installed,?version(deb.sury.org))'
cd wine-tkg-git
sed -i 's/distro=""/distro="debuntu"/' customization.cfg
sed -i 's/LOCAL_PRESET=""/LOCAL_PRESET="valve-exp-bleeding"/' customization.cfg
touch tarplz
yes|./non-makepkg-build.sh
- name: Archive the artifacts
uses: actions/upload-artifact@v2
with:
name: wine-tkg-build
path: wine-tkg-git/non-makepkg-builds

42
wine-tkg-git/.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
!.gitattributes
!.gitignore
*~
*.orig
*.log
*.run
*.tgz
*.xz
*.pkg
*.bak
*.tar.gz
*.tar.zst
*.deb
*.old
*.db
*.files
*/src/
*/pkg/
wine-tkg-git/wine-staging-git/
wine-tkg-git/wine-git/
wine-tkg-git/wine-mirror-git/
wine-tkg-git/ValveSoftware-wine/
wine-tkg-git/ValveSoftware-winegit/
wine-tkg-git/wine-tkg-userpatches/
!wine-tkg-git/wine-tkg-userpatches/README.md
wine-tkg-git/dxvk/
wine-tkg-git/d9vk/
wine-tkg-git/non-makepkg-builds/
wine-tkg-git/proton_dist/
proton-tkg/Proton/
proton-tkg/liberation-fonts/
proton-tkg/vkd3d-fork-build/
proton-tkg/vkd3d-proton/
proton-tkg/proton_template/share/fonts/
proton-tkg/dxvk/
proton-tkg/dxvk-tools/
proton-tkg/d9vk/
proton-tkg/mono/
proton-tkg/gecko/
proton-tkg/proton_tkg_token
proton-tkg/external-resources
proton-tkg/gst/

61
wine-tkg-git/README.md Normal file
View File

@ -0,0 +1,61 @@
# Wine to rule them all !
## Wine nightly builds
- wine-staging patchset applied
Wine | [Arch Linux](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/wine-arch.yml) | [Fedora](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/wine-fedora.yml) | [Ubuntu](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/wine-ubuntu.yml) | [LoL](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/wine-lol.yml) |
-------------|--------|--------|-------|-------|
Valve Wine | [Exp Bleeding Edge Arch Linux](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/wine-valvexbe-pacman.yml) | [Exp Bleeding Edge Other distro](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/wine-valvexbe.yml) |
-------------|--------|--------|
*The Exp Bleeding Edge Other distro and LoL versions are built on Ubuntu latest, which should work fine on most distros not using years old packages*
*! The LoL version should only be used for League of Legends !*
## Proton nightly builds
- wine-staging patchset applied
- built on Arch current, making glibc 2.36 a requirement
Proton | [Valve Exp Bleeding Edge](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/proton-valvexbe-arch-nopackage.yml) | [Wine Master](https://github.com/Frogging-Family/wine-tkg-git/actions/workflows/proton-arch-nopackage.yml) |
-------------|--------|--------|
(drop the extracted folder in `/$HOME/.steam/root/compatibilitytools.d/` or, for Ubuntu/Debian based, the `/$HOME/.steam/compatibilitytools.d/` dir)
## PLEASE DO NOT REPORT BUGS ENCOUNTERED WITH THIS AT WINEHQ OR VALVESOFTWARE, REPORT HERE INSTEAD !
Wine-tkg is a build-system aiming at easier custom wine builds creation. You can now easily get the "plain wine + pba + steam fix" build you've been dreaming about!
It can also make custom Proton builds with its wrapping script: https://github.com/Frogging-Family/wine-tkg-git/tree/master/proton-tkg
**By default, it'll pull current wine/wine-staging git versions. You can target a specific release or commit in the .cfg if needed.**
A comfortable selection of patches is available to you, with some of them being enabled by default for your convenience (see [this sample config file](https://github.com/Frogging-Family/wine-tkg-git/blob/master/wine-tkg-git/wine-tkg-profiles/sample-external-config.cfg) for the full list and details)
An ever evolving selection of staging, experimental and/or hacky patches are also available [in the community-patches](https://github.com/Frogging-Family/community-patches/tree/master/wine-tkg-git)
**Can be built with your own patches - See [README in wine-tkg-git/wine-tkg-userpatches](https://github.com/Frogging-Family/wine-tkg-git/blob/master/wine-tkg-git/wine-tkg-userpatches/README.md) for instructions**
### Generated Wine-tkg sources (staging-based):
- Wine-tkg : https://github.com/Tk-Glitch/wine-tkg
- Proton-tkg : https://github.com/Tk-Glitch/wine-proton-tkg
Wine : https://github.com/wine-mirror/wine
Wine-staging : https://github.com/wine-staging/wine-staging
Wine esync : https://github.com/zfigura/wine/tree/esync
Wine fsync : https://github.com/zfigura/wine/tree/fsync
Proton : https://github.com/ValveSoftware/Proton
Wine-pba (Only working correctly up to 3.18 - Force disabled on newer wine bases due to regressions) : https://github.com/acomminos/wine-pba
Thanks to @Firerat and @bobwya for their rebase work :
- https://gitlab.com/Firer4t/wine-pba
- https://github.com/bobwya/gentoo-wine-pba
For Gallium 9 support, use https://github.com/iXit/wine-nine-standalone (available from winetricks and AUR) - Legacy nine support can still be turned on if you're building a 4.1 base or older.

View File

@ -0,0 +1,235 @@
# Created by: Tk-Glitch <ti3nou at gmail dot com>
pkgname=proton-tkg-git
pkgver=0
pkgrel=1
_frogwhere="$PWD"
# Arch chroot workaround
if [[ "${_frogwhere}" != "/startdir" ]]; then
export BUILDDIR="${_frogwhere}" # Override makepkg BUILDDIR path and use PKGBUILDs dirs instead
fi
arch=('x86_64')
pkgdesc='Custom Proton build with even more frog spice'
url='https://github.com/Tk-Glitch/PKGBUILDS/tree/master/proton-tkg'
options=(staticlibs !lto !strip !ccache)
license=('LGPL')
depends=(
'attr' 'lib32-attr'
'fontconfig' 'lib32-fontconfig'
'lcms2' 'lib32-lcms2'
'libxml2' 'lib32-libxml2'
'libxcursor' 'lib32-libxcursor'
'libxrandr' 'lib32-libxrandr'
'libxdamage' 'lib32-libxdamage'
'libxi' 'lib32-libxi'
'gettext' 'lib32-gettext'
'freetype2' 'lib32-freetype2'
'glu' 'lib32-glu'
'libsm' 'lib32-libsm'
'gcc-libs' 'lib32-gcc-libs'
'libpcap' 'lib32-libpcap'
'faudio' 'lib32-faudio'
'desktop-file-utils' 'tk'
'vulkan-icd-loader' 'lib32-vulkan-icd-loader'
'jxrlib' 'gst-plugins-ugly'
)
makedepends=(
'git' 'autoconf'
'ncurses' 'bison'
'perl' 'fontforge'
'flex' 'python-fonttools'
'gcc>=4.5.0-2' 'pkgconf'
'giflib' 'lib32-giflib'
'libpng' 'lib32-libpng'
'gnutls' 'lib32-gnutls'
'libxinerama' 'lib32-libxinerama'
'libxcomposite' 'lib32-libxcomposite'
'libxmu' 'lib32-libxmu'
'libxxf86vm' 'lib32-libxxf86vm'
'libldap' 'lib32-libldap'
'mpg123' 'lib32-mpg123'
'openal' 'lib32-openal'
'v4l-utils' 'lib32-v4l-utils'
'alsa-lib' 'lib32-alsa-lib'
'libxcomposite' 'lib32-libxcomposite'
'mesa' 'lib32-mesa'
'libgl' 'lib32-libgl'
'libxslt' 'lib32-libxslt'
'libpulse' 'lib32-libpulse'
'libva' 'lib32-libva'
'gtk3' 'lib32-gtk3'
'gst-plugins-base-libs' 'lib32-gst-plugins-base-libs'
'gst-plugins-good' 'lib32-gst-plugins-good'
'vulkan-icd-loader' 'lib32-vulkan-icd-loader'
'sdl2' 'lib32-sdl2'
'libcups' 'lib32-libcups'
'samba' 'schedtool'
'meson' 'ninja'
'glslang' 'wget'
'ocl-icd' 'lib32-ocl-icd'
'opencl-headers' 'mingw-w64-gcc'
'vulkan-headers' 'jack'
'lib32-jack' 'python-pefile'
'rust' 'lib32-rust-libs'
$_user_makedeps
)
optdepends=(
'giflib' 'lib32-giflib'
'libpng' 'lib32-libpng'
'libldap' 'lib32-libldap'
'gnutls' 'lib32-gnutls'
'mpg123' 'lib32-mpg123'
'openal' 'lib32-openal'
'v4l-utils' 'lib32-v4l-utils'
'libpulse' 'lib32-libpulse'
'alsa-plugins' 'lib32-alsa-plugins'
'alsa-lib' 'lib32-alsa-lib'
'libjpeg-turbo' 'lib32-libjpeg-turbo'
'libxcomposite' 'lib32-libxcomposite'
'libxinerama' 'lib32-libxinerama'
'ncurses' 'lib32-ncurses'
'libxslt' 'lib32-libxslt'
'libva' 'lib32-libva'
'gtk3' 'lib32-gtk3'
'gst-plugins-base-libs' 'lib32-gst-plugins-base-libs'
'sdl2' 'lib32-sdl2'
'cups' 'zapcc'
'samba' 'clang'
'dosbox' 'ccache'
)
if msg2; then # Arch chroot workaround for even more looping fun
# Remove gst-editing-services
if pacman -Qq gst-editing-services &> /dev/null; then
warning '! found gst-editing-services package, known to break wine prefix creation !'
read -rp " Uninstall it?"$'\n> N/y : ' _gst_editing_services;
if [[ "$_gst_editing_services" =~ [yY] ]]; then
sudo pacman -R gst-editing-services
fi
fi
fi
exit_cleanup() {
if [ "$pkgver" != "0" ]; then
sed -i "s/pkgver=$pkgver.*/pkgver=0/g" "${_frogwhere}"/PKGBUILD
fi
rm -rf src
remove_deps
msg2 'exit cleanup done'
}
recursive_installer() {
for _f in $1; do
if [ -f "$_f" ]; then
install -v -D "$_f" "$2"/"$_f"
elif [ -d "$_f" ]; then
recursive_installer "$_f/*" "$2"
fi
done
}
pkgver() {
cd "${_frogwhere}/../wine-tkg-git/${_pkgvertargdir}"
git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g;s/^v//;s/\.rc/rc/;s/^wine\.//'
}
prepare() {
# Arch chroot workaround
if [[ "${_frogwhere}" = "/startdir" ]]; then
msg2 "Arch chroot detected!"
export _frogwhere=/build/proton-tkg-git
git clone https://github.com/Frogging-Family/wine-tkg-git.git || true
if [ -d wine-tkg-git/wine-tkg-git ]; then
mv wine-tkg-git/wine-tkg-git /build/wine-tkg-git
fi
if [ -d wine-tkg-git/proton-tkg ]; then
mv wine-tkg-git/proton-tkg/* /build/proton-tkg-git/
fi
fi
# overcomplicated BS
_srcdirlock="${_frogwhere}/../wine-tkg-git"
warning "The next step might take some time, please be patient..."
source "${_frogwhere}"/proton-tkg.cfg
source "${_frogwhere}"/proton-tkg-profiles/advanced-customization.cfg
if [ -e "$_EXT_CONFIG_PATH" ]; then
source "$_EXT_CONFIG_PATH"
fi
if [ -n "$_LOCAL_PRESET" ] && [ -e "${_frogwhere}"/../wine-tkg-git/wine-tkg-profiles/wine-tkg-"$_LOCAL_PRESET".cfg ]; then
source "${_frogwhere}"/../wine-tkg-git/wine-tkg-profiles/wine-tkg.cfg && source "${_frogwhere}"/../wine-tkg-git/wine-tkg-profiles/wine-tkg-"$_LOCAL_PRESET".cfg
fi
if [ -n "$_custom_wine_source" ]; then
_winesrcdir=$( sed 's|/|-|g' <<< $(sed 's|.*://.[^/]*/||g' <<< $_custom_wine_source))
else
if [ "$_plain_mirrorsrc" = "true" ]; then
_winesrcdir="wine-mirror-git"
_winesrctarget="https://github.com/wine-mirror/wine.git"
else
_winesrcdir="wine-git"
_winesrctarget="git://source.winehq.org/git/wine.git"
fi
fi
cd "${_srcdirlock}"
_pkgvertargdir="${_winesrcdir}"
# Empty clone failsafe
git clone --mirror "${_winesrctarget}" "$_winesrcdir" || true
if [ "$_use_staging" = "true" ]; then
_stgsrcdir='wine-staging-git'
_pkgvertargdir="${_stgsrcdir}"
# Empty clone failsafe
git clone --mirror https://github.com/wine-staging/wine-staging.git "$_stgsrcdir" || true
fi
cd "${_srcdirlock}/${_pkgvertargdir}"
git fetch --all -p >/dev/null 2>&1
rm -rf "${_srcdirlock}/src/${_pkgvertargdir}" && git clone "${_srcdirlock}/${_pkgvertargdir}" "${_srcdirlock}/src/${_pkgvertargdir}" >/dev/null 2>&1
cd "${_srcdirlock}/src/${_pkgvertargdir}"
git checkout --force --no-track -B makepkg origin/HEAD
if [ -n "$_plain_version" ] && [ "$_use_staging" != "true" ]; then
git checkout "${_plain_version}"
fi
if [ -n "$_staging_version" ] && [ "$_use_staging" = "true" ]; then
git checkout "${_staging_version}"
fi
cd "${_frogwhere}"
if [ ! -d "${_frogwhere}/external-resources" ]; then
mkdir -p "${_frogwhere}/external-resources"
fi
ln -s -f "${_frogwhere}/external-resources" "${srcdir}/"
ln -s -f "${_frogwhere}/proton_template" "${srcdir}/"
ln -s -f "${_frogwhere}/proton-tkg.cfg" "${srcdir}/"
ln -s -f "${_frogwhere}/proton-tkg.sh" "${srcdir}/"
ln -s -f "${_frogwhere}/proton-tkg-userpatches" "${srcdir}/"
ln -s -f "${_frogwhere}/proton-tkg-profiles" "${srcdir}/"
}
build() {
warning "Using this PKGBUILD is not the recommended way to build proton-tkg."
warning "Unless you really want a package, please favor the proton-tkg.sh script route instead."
warning "Also note that SteamVR support is forcefully disabled when using the PKGBUILD,"
warning "independently of its functioning state in proton-tkg."
sleep 2
cd "${srcdir}"
_ispkgbuild="true" ./proton-tkg.sh
}
package() {
provides=("$pkgname=$pkgver")
conflicts=("$pkgname")
cd "${srcdir}"
rm -f proton_tkg_token
recursive_installer proton_tkg_* "${pkgdir}/usr/share/steam/compatibilitytools.d" >>"${_frogwhere}"/proton-tkg.log 2>&1
cd "${pkgdir}"/usr/share/steam/compatibilitytools.d/proton_tkg_*
ln -s -f "/tmp" "__pycache__"
}
trap exit_cleanup EXIT

View File

@ -0,0 +1,124 @@
# Proton-tkg
## PLEASE DO NOT REPORT BUGS ENCOUNTERED WITH THIS AT WINEHQ OR VALVESOFTWARE, REPORT HERE INSTEAD !
This is an addon script for [wine-tkg-git](https://github.com/Frogging-Family/wine-tkg-git/tree/master/wine-tkg-git).
It can create Steamplay compatible wine builds based on wine-tkg-git + additional proton patches and libraries. Wine-staging based? Latest master? Yup, you can.
( **Older than 3.16 wine bases are untested, and some commits or commit ranges might prove problematic with certain combinations of patches.** )
### This is not standalone and requires Steam. If you want a standalone wine build, please see [wine-tkg-git](https://github.com/Frogging-Family/wine-tkg-git/tree/master/wine-tkg-git) instead.
# Quick how-to :
(for dependencies, see the [wiki page](https://github.com/Tk-Glitch/PKGBUILDS/wiki/wine-tkg-git) )
## Download the source :
* Clone the repo (allows you to use `git pull` to get updates) :
```
git clone https://github.com/Frogging-Family/wine-tkg-git.git
```
## Configuration/customization :
If you want to customize the patches and features of your builds, you can find basic settings in [proton-tkg.cfg](https://github.com/Frogging-Family/wine-tkg-git/blob/master/proton-tkg/proton-tkg.cfg) and advanced settings in [proton-tkg-profiles/advanced-customization.cfg](https://github.com/Frogging-Family/wine-tkg-git/blob/master/proton-tkg/proton-tkg-profiles/advanced-customization.cfg).
You can also create an external configuration file that will contain all settings in a centralized way and survive repo updates. A sample file for this can be found [here](https://github.com/Frogging-Family/wine-tkg-git/blob/master/proton-tkg/proton-tkg-profiles/sample-external-config.cfg). The default path for this file is `~/.config/frogminer/proton-tkg.cfg` and can be changed in `proton-tkg-profiles/advanced-customization.cfg` with the `_EXT_CONFIG_PATH` option.
## Building :
* We need to get into the proton-tkg dir first:
```
cd proton-tkg
```
### For Arch (and other pacman/makepkg distros) :
**You have two options on pacman based distros. You can either make a pacman package (with a few limitations), or use a more powerful but also less user-friendly way.**
#### Unpackaged, vanilla way :
This is the recommended way and doesn't have the limitations of the makepkg path below.
* From the `proton-tkg` directory (where the PKGBUILD is located), run the following command in a terminal to start the building process :
```
./proton-tkg.sh
```
#### Pacman package way :
Using this option will enforce a "proton-tkg-makepkg" naming scheme in Steam, and prevents having multiple versions installed side-by-side. This option also disables steamvr support currently.
* From the `proton-tkg` directory (where the PKGBUILD is located), run the following command in a terminal to start the building process :
```
makepkg -si
```
### For other distros (make sure to check the [wiki page](https://github.com/Tk-Glitch/PKGBUILDS/wiki/wine-tkg-git)) :
* From the `proton-tkg` directory (where the PKGBUILD is located), running the proton-tkg.sh script will launch the usual wine-tkg-git building process... with extra spice :
```
./proton-tkg.sh
```
### How to uninstall superfluous builds the easy way when not using a pacman package :
```
./proton-tkg.sh clean
```
*In its current form, the uninstaller will only handle Proton-tkg builds, and requires that at least one Proton-tkg build is left after uninstalling (meaning you need two beforehand).*
**The following wine-tkg-git options will be enforced (might change in the future):**
- `_EXTERNAL_INSTALL="true"`
- `_EXTERNAL_INSTALL_TYPE="proton"`
- `_EXTERNAL_NOVER="false"`
- `_use_faudio="true"`
**All other wine-tkg-git settings can be tweaked such as wine version, staging, esync, game fixes (etc.) and the userpatches functionality is kept intact.**
You can find all your usual options in the proton-tkg.cfg file. If you create a proton-tkg.cfg file in ~/.config/frogminer dir, it'll be used as an override.
## The prebuilt DXVK "problem"
By default, proton-tkg will download latest official DXVK release from github. You have nothing to do, it's all good. **However, if you want to build/use a development or modified version of DXVK, it's recommended to use [dxvk-tools](https://github.com/Frogging-Family/dxvk-tools)**
### If you're not using dxvk-tools/can't build DXVK/D9VK :
When `_use_dxvk` is set to `"prebuilt"`, you'll need to put your prebuilt DXVK dlls inside a dxvk folder, in the `external-resources` folder of proton-tkg:
```
proton-tkg
|
|__external-resources
|
|
--dxvk___x64--> d3d11.dll, dxgi.dll etc.
|
|__x32--> d3d11.dll, dxgi.dll etc.
```
## Special options and builtin features :
Proton-tkg builds are coming with special additional features you can enable/disable post install in the `user_settings.py` file found in your build's folder (`~/.steam/root/compatibilitytools.d/proton_tkg_*`), such as:
- `PROTON_NVAPI_DISABLE` - Option disabled by default, it'll set nvapi and nvapi64 dlls to disabled. It is a common fix for many games.
- `PROTON_WINEDBG_DISABLE` - Option disabled by default, it'll set winedbg.exe to disabled. It's a known fix for GTA V online.
- `PROTON_PULSE_LOWLATENCY` - Option disabled by default, it'll set Pulseaudio latency to 60ms. This usually helps with audio crackling issues on some setups.
- `PROTON_DXVK_ASYNC` - Disabled by default, it'll enable DXVK's async pipecompiler on a compatible DXVK build (official/default DXVK build doesn't support it). Known as the "poe hack", that option *could* be unsafe for anticheats, so beware.
- `PROTON_USE_CUSTOMD3D9` - Disabled by default, it'll enable you to use a custom d3d9 lib that's not already available in proton-tkg (namely d9vk and wined3d), like Gallium9 for example.
- `PROTON_WINETRICKS` - Enabled by default, the built-in winetricks integration will show a popup on game launch asking if you want to run winetricks (against your game's prefix). It requires that you have both the `winetricks` and `tk` (`python3-tk` on some distros) packages installed.
You can also change their default values before building in your `proton-tkg.cfg` file.
## Other things to know :
- Proton doesn't like running games from NTFS. Consider symlinking your compatdata dir(s) (usually found in /SteamApps) to some place on an EXT4 partition if you want to play games from a NTFS partition.
- Proton-tkg **can** handle 32-bit prefixes. However you'll have to create such a prefix by hand as the Steam client doesn't offer such an option. Also, that prefix will have to be deleted if you want to use an official Proton build with the game bound to it.
- Proton-tkg builds will get installed in `~/.steam/root/compatibilitytools.d` directory. If no game is bound to use a specific Proton-tkg build, you can safely delete it. **IT IS HIGHLY RECOMMENDED TO USE THE UNINSTALL FUNCTION OF THE SCRIPT TO REMOVE SUPERFLUOUS BUILDS**

View File

@ -0,0 +1,242 @@
# 'Wine-to-rule-them-all' - Proton-TkG advanced config file
##
## This config file contains advanced settings for your build.
## For the basic configuration, see ../proton-tkg.cfg
##
# This is a simplified config file with minimal comments. See ../../wine-tkg-git/wine-tkg-profiles/sample-external-config.cfg for more details.
# Some options will be missing from this config file compared to wine-tkg-git as they are enforced.
# Proton branch to target for lsteamclient libs and steam helper on 4.x+ - When using a Wine 3.x base, "proton_3.16" branch will be enforced
_proton_branch="experimental_7.0"
# Set to "true" to use the "noruntime" proton toolmanifest if available
# Set to "sniper" to use the experimental sniper runtime
_nosteamruntime="false"
# Proton SDL Joystick support, xinput hacks and other gamepad additions. _gamepad_additions depends on _sdl_joy_support.
# This might be required for some FFB steering wheels, but can break gamepad support in some games.
_sdl_joy_support="false"
# ! _gamepad_additions="true" can sometimes break more than it fixes depending on the game, so feel free to tweak this !
_gamepad_additions="true"
# Proton non-vr-related wined3d additions - Disabled on staging independently of this setting
_wined3d_additions="true"
# Disable nvapi and nvapi64 - Common fix for various games when using a Nvidia GPU
# Might create issues on some native vulkan game calling nvapi for some extremely dumb reason, such as Doom Eternal
_proton_nvapi_disable="true"
# Disable winedbg - (Used to fix GTA V online crash before Proton 5.0-4 02951753)
_proton_winedbg_disable="true"
# Disable conhost - Workaround for potential stalled conhost.exe process affecting performance negatively
# Some games or launchers might need the functionality but I couldn't find one
# Seems to be fixed as of 14b50ee1 & 8a47ef28 (Wine 6.0rc2)
_proton_conhost_disable="false"
# Enforce IMAGE_FILE_LARGE_ADDRESS_AWARE - Fixes 32-bit games hitting address space limitations.
# *Some* games might not like that (only known case so far is System Shock 2).
_proton_force_LAA="true"
# Enforce driver shader cache path when Steam's shader pre-caching is disabled
_proton_shadercache_path=""
# Enable the use of winelib steam.exe to launch games that checks if Steam is running such as Assetto Corsa - Only works with a Wine 4.0+ base
# Will disable "server-Desktop_Refcount" and "ws2_32-TransmitFile" patchsets on staging past 4e7071e4 (4.7+) to prevent crashing issues
_proton_use_steamhelper="true"
# Set to true to disable proton's steamclient lib substitution. Allows running windows steam client in proton (only affects 4.19+)
# ! This will prevent most Steam games to run directly from proton - You only want to use this as a secondary build for non-steam games or running windows steam/games from windows steam !
_steamclient_noswap="false"
# Enable DXVK's async pipecompiler on a compatible DXVK build. Also known as the "poe hack", that option *could* be unsafe regarding anticheats, so beware !
_proton_dxvk_async="false"
# Proton wined3d-interop and friends for SteamVR support - Depends on _proton_fs_hack="true"
_steamvr_support="true"
# Until supported in wine, WMA playback needs external FAudio. Set to "false" to use wine builtin implementation
_prefer_external_faudio="true"
# COMPILER/BUILD OPTIONS
# External config file to use - If the given file exists in path, it will override default config - Default is ~/.config/frogminer/proton-tkg.cfg
_EXT_CONFIG_PATH=~/.config/frogminer/proton-tkg.cfg
# Set to a desired additional tag to differentiate builds
_PROTON_NAME_ADDON=""
# Custom compiler root dirs - Leave empty to use system compilers
# Example: CUSTOM_MINGW_PATH="/home/frog/PKGBUILDS/mostlyportable-gcc/mingw-mostlyportable-9.2.0"
# Example: CUSTOM_GCC_PATH="/home/frog/PKGBUILDS/mostlyportable-gcc/gcc-mostlyportable-9.2.0"
CUSTOM_MINGW_PATH=""
CUSTOM_GCC_PATH=""
_LOCAL_OPTIMIZED="true"
_GCC_FLAGS="-O2 -ftree-vectorize"
_LD_FLAGS="-Wl,-O1,--sort-common,--as-needed"
_CROSS_FLAGS="-O2 -ftree-vectorize"
_CROSS_LD_FLAGS="-Wl,-O1,--sort-common,--as-needed"
_NUKR="true"
_NOCOMPILE="false"
_NOINITIALPROMPT="false"
# Set the method used to do PE files fixups to please some DRMs and other checks - Default is "objcopy", alternative is "py" (which will run legacy pefixup.py proton script)
# !!! the "py" method allows Destiny 2 checks to pass but will get you banned !!!
_pefixup="objcopy"
# Set to true to forcefully disable using ccache (else it'll be used if detected).
_NOCCACHE="false"
# Optionally set additional make dependencies for makepkg builds. Multiple elements should be separated by a space.
# Only affects makepkg
_user_makedeps=""
# Strip libs for smaller footprint (--strip-unneeded) - Not recommended for debugging
_pkg_strip="true"
# Set to "true" to generate patchsets for each parts of the tree patching steps, found in `src/wine source dir` (default src/wine-mirror-git)
# 01-reverts - 02-pre-staging - 03-staging - 04-post-staging - 05-hotfixes - 06-userpatches - 07-tags-n-polish
_generate_patchsets="false"
# Set to "true" to log compiler warnings and errors to a debug.log file
_log_errors_to_file="false"
# Set to true to remove trailing patchmsg strings in logs - Useful to review the list of patches used without fluff
_nopatchmsg="false"
# WINE FLAVOUR SETTINGS
# Set to the path of a custom wine source repo if desired (i.e. https://github.com/ValveSoftware/wine). Leave empty to use official wine source.
# Use the _plain_version option to target a specific commit for this source
# ! Make sure to disable staging if your source isn't compatible with it or it will fail to apply !
_custom_wine_source=""
# Add a configurable spin count to fsync - might help performance but can introduce stability issues/hanging. Try setting WINEFSYNC_SPINCOUNT=100 envvar
_fsync_spincounts="true"
_plain_mirrorsrc="true"
# Sets custom configure-args for 64-bit, separated by a space (example: "--without-mingw --with-vkd3d")
_configure_userargs64="--with-x --with-gstreamer --with-xattr"
# Sets custom configure-args for 32-bit, separated by a space (example: "--without-mingw --with-vkd3d")
_configure_userargs32="--with-x --with-gstreamer --with-xattr"
# Set to false to add DXVK configuration support to Wine's DXGI, allowing for VKD3D to run while keeping DXVK dxgi functionalities.
# !! For DXVK to work properly with this option set to false, you'll need a DXVK build that comes with dxvk_config.dll !!
# Keep in mind Wine's dxgi can be more unstable and less compatible when used with DXVK.
_dxvk_dxgi="true"
# Specify DXVK release version, ex: "v1.6.1", default is "latest"
_dxvk_version=""
_dxvk_async="false"
# staging
# You can optionally uncomment the _staging_userargs="" option below to disable desired wine-staging patchsets.
# For example, to disable the 'wined3d-Indexed_Vertex_Blending' patchset, the line below would look like this : _staging_userargs="-W wined3d-Indexed_Vertex_Blending"
# You can also disable multiple patchsets ('wined3d-WINED3D_RS_COLORWRITEENABLE' and 'wined3d-Indexed_Vertex_Blending'
# in the following example : _staging_userargs="-W wined3d-WINED3D_RS_COLORWRITEENABLE -W wined3d-Indexed_Vertex_Blending"
_staging_userargs="-W ntdll-NtAlertThreadByThreadId"
# VKD3D
# vkd3dlib - We don't want to use vkd3d native library by default to allow for vkd3d-proton usage
# Set to "true" to enable explicit mainline vkd3d library support - default is "false"
_use_vkd3dlib="false"
# GAME-SPECIFIC PATCHES
_warframelauncher_fix="true"
_staging_pulse_disable="false"
# OTHER PATCHES
_CSMT_toggle="true"
_GLSL_toggle="false"
_MIME_NOPE="true"
_lowlatency_audio="false"
_launch_with_dedicated_gpu="false"
_clock_monotonic="true"
_large_address_aware="true"
_stg_shared_mem_default="false"
_proton_rawinput="true"
# Proton Bcrypt patches - Fixes RDR2 online, notably - Replaces Staging's bcrypt-ECDHSecretAgreement
_proton_bcrypt="true"
# Enforce mscvrt Dlls to native then builtin - from Proton - Can be detrimental on 4.3+
_msvcrt_nativebuiltin="true"
# Set the default wine version to win10 (instead of win7)
_win10_default="true"
#### LEGACY PATCHES - These are for older than current master - Some are enabled by default on such trees as they are considered harmless
# Sets the value of an additional fake refresh rate in virtual desktop mode. Leave empty to keep default - Deprecated as of 6f305dd8 (5.14-devel) unless FS hack is also enabled
_fake_refresh_rate=""
# legacy gallium nine - This is only available for 4.1-devel (prior to e24b162) and older wine versions - Use nine standalone instead for newer wine
_use_legacy_gallium_nine="false"
# pba - Enable with PBA_ENABLE=1 envvar, force-disabled on 3.19 & higher due to known broken state
_use_pba="true"
# The Sims 2 fix - On staging, disables wined3d-WINED3D_RS_COLORWRITEENABLE and wined3d-Indexed_Vertex_Blending patchsets - https://bugs.winehq.org/show_bug.cgi?id=8051 - Obsoleted by D9VK
_sims2_fix="false"
# Disable server-send_hardware_message staging patchset if found - Fixes FFXIV/Warframe/Crysis 3 (etc.) mouse jittering on 3.19 staging and lower. Will cause GTA V to freeze for a second or two on first keyboard input
_server_send_hwmsg_disable="true"
# Path of exile - Fixes DX11 mode not working - Doesn't seem to be needed anymore since Wine 4.1, supposedly since a game patch - https://bugs.winehq.org/show_bug.cgi?id=42695
_poe_fix="false"
# Overwatch mf crash fix from Guy1524 - https://bugs.winehq.org/show_bug.cgi?id=47385 - This will only apply against a wine tree missing b182ba882cfcce7b8769470f49f0fba216095c45, and ignored otherwise
_OW_fix="true"
# Python fix for <=3.18 (backported from zzhiyi's patches) - fix for python and needed for "The Sims 4" to work - replaces staging partial implementation - https://bugs.winehq.org/show_bug.cgi?id=44999 - This will only apply against a wine tree missing 3ebd2f0be30611e6cf00468c2980c5092f91b5b5, and ignored otherwise
_318python_fix="true"
# Workaround for F4SE/SkyrimSE Script Extender - This is a hack and could break stuff - https://github.com/hdmap/wine-hackery/tree/master/f4se - It was fixed upstream with 1aa963ef - 6672fc9d (4.13-devel)
_f4skyrimse_fix="false"
# steam crossover hack for store/web functionality - https://bugs.winehq.org/show_bug.cgi?id=39403
_steam_fix="true"
# Fix crashes or perf issues related to high core count setups - Fixed in 4.0 - https://bugs.winehq.org/show_bug.cgi?id=45453
_highcorecount_fix="true"
# Reverts c6b6935 due to https://bugs.winehq.org/show_bug.cgi?id=47752 - Fixed upstream with cb70373
_c6b6935_revert="true"
# Native dotnet workaround for 4.13+ - https://bugs.winehq.org/show_bug.cgi?id=47633
_nativedotnet_fix="true"
# USVFS (Mod Organizer 2's virtual filesystem) support patch - https://github.com/Tk-Glitch/PKGBUILDS/issues/300 - https://bugs.winehq.org/show_bug.cgi?id=47833
_usvfs_fix="false"
# Faudio - Use the currently installed Faudio packages (both 32 and 64-bit) for xaudio2 - Fixes sound issues in various games. Disables xaudio2 & winepulse staging patchsets
# Support is enabled by default in Wine 4.3+ as well as Wine-staging 4.13+, independently of this setting
_use_faudio="true"
# Revert moving various funcs to kernelbase & ntdll to fix some dll loading issues and ntdll crashes (with Cemu and Blizzard games notably)
# Deprecated as of b7db0b5 - Force-enabled on proton-tkg when using older than b7db0b5 tree
_kernelbase_reverts="false"
# Update winevulkan to whatever version I have pushed last, til next time, for new shiny and tasty vk extensions support. Thanks dadドイツ人 !
_update_winevulkan="false"
_proton_mf_hacks="false"
_plasma_systray_fix="false"
# Allow making use of the futex2 kernel interface for fsync - Requires a patched kernel such as linux-tkg - https://gitlab.collabora.com/tonyk/wine/-/commits/experimental_5.13
_fsync_futex2="true"

View File

@ -0,0 +1,385 @@
# 'Wine-to-rule-them-all' - Proton-TkG config file - external config example
##
## This config file is an example of external config (typical path: ~/.config/frogminer/proton-tkg.cfg)
## It contains most available options in a centralized way - The few missing options are part of wine-tkg-git and mostly not interesting for proton-tkg
##
# This is a simplified config file with minimal comments. See ../../wine-tkg-git/wine-tkg-profiles/sample-external-config.cfg for more details.
# Some options will be missing from this config file compared to wine-tkg-git as they are enforced.
#### NON-MAKEPKG OPTIONS (Won't affect makepkg builds) ####
# Set to true to get a prompt after the 64-bit part is built, enabling package switching before building the 32-bit side.
# This is a workaround for distros shipping broken devel packages that can't coexist as multilib
_nomakepkg_midbuild_prompt="false"
# Set to the distro of your choice to attempt dependency resolution. Valid options are "debuntu" (for debian, ubuntu and similar), "fedora" or "archlinux".
_nomakepkg_dep_resolution_distro=""
# Set to true if you want to skip the uninstaller at the end of proton-tkg building
_skip_uninstaller="false"
# Set to true if you do not want your build to be automatically moved to your compatibilitytools.d dir
_no_autoinstall="false"
####
# PROTON-TKG OPTIONS
# Proton branch to target for lsteamclient libs and steam helper on 4.x+ - When using a Wine 3.x base, "proton_3.16" branch will be enforced
_proton_branch="experimental_7.0"
# Proton SDL Joystick support, xinput hacks and other gamepad additions. _gamepad_additions depends on _sdl_joy_support.
# This might be required for some FFB steering wheels, but can break gamepad support in some games.
_sdl_joy_support="false"
# ! _gamepad_additions="true" can sometimes break more than it fixes depending on the game, so feel free to tweak this !
_gamepad_additions="true"
# SteamDeck support additions
_tabtip="true"
# Proton non-vr-related wined3d additions - Disabled on staging independently of this setting
_wined3d_additions="true"
# Proton wined3d-interop and friends for SteamVR support - Depends on _proton_fs_hack="true"
_steamvr_support="true"
# Disable nvapi and nvapi64 - Common fix for various games when using a Nvidia GPU
# Might create issues on some native vulkan game calling nvapi for some extremely dumb reason, such as Doom Eternal
_proton_nvapi_disable="false"
# Disable winedbg - (Used to fix GTA V online crash before Proton 5.0-4 02951753)
_proton_winedbg_disable="false"
# Disable conhost - Workaround for potential stalled conhost.exe process affecting performance negatively
# Some games or launchers might need the functionality but I couldn't find one
# Seems to be fixed as of 14b50ee1 & 8a47ef28 (Wine 6.0rc2)
_proton_conhost_disable="false"
# Enforce IMAGE_FILE_LARGE_ADDRESS_AWARE - Fixes 32-bit games hitting address space limitations.
# *Some* games might not like that (only known case so far is System Shock 2).
_proton_force_LAA="true"
# Set Pulseaudio latency to 60ms - Can help with sound crackling issues on some configs
_proton_pulse_lowlat="false"
# Until supported in wine, WMA playback needs external FAudio. Set to "false" to use wine builtin implementation
_prefer_external_faudio="true"
# Enforce driver shader cache path when Steam's shader pre-caching is disabled
_proton_shadercache_path=""
# Enable the use of winelib steam.exe to launch games that checks if Steam is running such as Assetto Corsa - Only works with a Wine 4.0+ base
# Will disable "server-Desktop_Refcount" and "ws2_32-TransmitFile" patchsets on staging past 4e7071e4 (4.7+)
_proton_use_steamhelper="true"
# Set to true to disable proton's steamclient lib substitution. Allows running windows steam client in proton (only affects 4.19+)
# ! This will prevent most Steam games to run directly from proton - You only want to use this as a secondary build for non-steam games or running windows steam/games from windows steam !
_steamclient_noswap="false"
# Enable Winetricks prompt on game launch - Will use your system winetricks, so you need it installed
_proton_winetricks="false"
# Enable DXVK's async pipecompiler on a compatible DXVK build. Also known as the "poe hack", that option *could* be unsafe regarding anticheats, so beware !
_proton_dxvk_async="false"
# DXVK options
# hud : https://github.com/doitsujin/dxvk#hud
# configfile : https://github.com/doitsujin/dxvk/wiki/Configuration#configuration-file
_proton_dxvk_hud=""
_proton_dxvk_configfile=""
# COMPILER/BUILD OPTIONS
# Custom compiler root dirs - Leave empty to use system compilers
# Example: CUSTOM_MINGW_PATH="/home/frog/PKGBUILDS/mostlyportable-gcc/mingw-mostlyportable-9.2.0"
# Example: CUSTOM_GCC_PATH="/home/frog/PKGBUILDS/mostlyportable-gcc/gcc-mostlyportable-9.2.0"
CUSTOM_MINGW_PATH=""
CUSTOM_GCC_PATH=""
_LOCAL_OPTIMIZED="true"
_GCC_FLAGS="-O2 -ftree-vectorize"
_LD_FLAGS="-Wl,-O1,--sort-common,--as-needed"
_CROSS_FLAGS="-O2 -ftree-vectorize"
_CROSS_LD_FLAGS="-Wl,-O1,--sort-common,--as-needed"
_NUKR="true"
_NOCOMPILE="false"
_NOINITIALPROMPT="false"
# Set the method used to do PE files fixups to please some DRMs and other checks - Default is "objcopy", alternative is "py" (which will run legacy pefixup.py proton script)
# !!! the "py" method allows Destiny 2 checks to pass but will get you banned !!!
_pefixup="objcopy"
# Set to true to forcefully disable using ccache (else it'll be used if detected).
_NOCCACHE="false"
# Optionally set additional make dependencies for makepkg builds. Multiple elements should be separated by a space.
# Only affects makepkg
_user_makedeps=""
# Strip libs for smaller footprint (--strip-unneeded) - Not recommended for debugging
_pkg_strip="true"
# Set to "true" to generate patchsets for each parts of the tree patching steps, found in `src/wine source dir` (default src/wine-mirror-git)
# 01-reverts - 02-pre-staging - 03-staging - 04-post-staging - 05-hotfixes - 06-userpatches - 07-tags-n-polish
_generate_patchsets="false"
# Set to "true" to log compiler warnings and errors to a debug.log file
_log_errors_to_file="false"
# Set to true to remove trailing patchmsg strings in logs - Useful to review the list of patches used without fluff
_nopatchmsg="false"
# Set to a desired additional tag to differentiate builds
_PROTON_NAME_ADDON=""
# WINE FLAVOUR SETTINGS
# Override config with one of the presets from /wine-tkg-profiles dir. Leave empty to be prompted.
# Custom presets for proton :
# "valve" (builds against current valve proton tree)
# "valve-exp" (builds against current valve proton-experimental tree)
# "valve-exp-bleeding" (builds against current valve proton-experimental-bleeding-edge tree)
# "none" - Silence the prompt
_LOCAL_PRESET=""
# Add GloriousEggroll game patches and hotfixes when using a Valve profile with staging enabled
# ! This will only affect Valve + staging trees !
# List of patches applied with this option enabled: assettocorsa-hud killer-instinct-winevulkan_fix FFVII-and-SpecialK-powerprof 65-proton-fake_current_res_patches unity_crash_hotfix Fix-regression-introduced-by-0e7fd41 15aa8c6-fix-star-citizen-bug-52956 0001-winex11.drv-Define-ControlMask-when-not-available 0002-include-Add-THREAD_POWER_THROTTLING_STATE-type 0003-ntdll-Fake-success-for-ThreadPowerThrottlingState
_use_GE_patches="true"
# Set to the path of a custom wine source repo if desired (i.e. https://github.com/ValveSoftware/wine). Leave empty to use official wine source.
# Use the _plain_version option to target a specific commit for this source
# ! Make sure to disable staging if your source isn't compatible with it or it will fail to apply !
_custom_wine_source=""
# fastsync - disable at runtime with WINE_DISABLE_FAST_SYNC=1 envvar - Set to true to enable winesync/fastsync support - https://repo.or.cz/wine/zf.git/shortlog/refs/heads/fastsync4
# !! on plain: Disables esync / fsync support !!
# !! on staging: Requires fsync support !!
_use_fastsync="false"
_use_esync="true"
_use_fsync="true"
# Allow making use of the futex2 kernel interface for fsync - Requires a patched kernel such as linux-tkg - https://gitlab.collabora.com/tonyk/wine/-/commits/experimental_5.13
_fsync_futex2="true"
# futex_waitv() API for fsync - Requires 5.16 kernel or kernel with backported patches - https://github.com/ValveSoftware/wine/pull/128
# !! Replaces previous fsync interfaces support !!
_fsync_futex_waitv="true"
# Add a configurable spin count to fsync - might help performance but can introduce stability issues/hanging. Try setting WINEFSYNC_SPINCOUNT=100 envvar
_fsync_spincounts="true"
_plain_version=""
_plain_mirrorsrc="true"
# Sets custom configure-args for 64-bit, separated by a space (example: "--without-mingw --with-vkd3d")
_configure_userargs64="--with-x --with-gstreamer --with-xattr"
# Sets custom configure-args for 32-bit, separated by a space (example: "--without-mingw --with-vkd3d")
_configure_userargs32="--with-x --with-gstreamer --with-xattr"
_use_staging="true"
_staging_version=""
# You can set _use_dxvk to either "prebuilt" (for builds made with dxvk-tools for example), "release" (using github's latest) or "false" (disabled)
# Setting it to "true" will default to "release"
_use_dxvk="git"
# Set to false to add DXVK configuration support to Wine's DXGI, allowing for VKD3D to run while keeping DXVK dxgi functionalities.
# !! For DXVK to work properly with this option set to false, you'll need a DXVK build that comes with dxvk_config.dll !!
# Keep in mind Wine's dxgi can be more unstable and less compatible when used with DXVK.
_dxvk_dxgi="true"
# Specify DXVK release version, ex: "v1.6.1", default is "latest"
_dxvk_version=""
_dxvk_async="false"
# staging
# You can optionally uncomment the _staging_userargs="" option below to disable desired wine-staging patchsets.
# For example, to disable the 'wined3d-Indexed_Vertex_Blending' patchset, the line below would look like this : _staging_userargs="-W wined3d-Indexed_Vertex_Blending"
# You can also disable multiple patchsets ('wined3d-WINED3D_RS_COLORWRITEENABLE' and 'wined3d-Indexed_Vertex_Blending'
# in the following example : _staging_userargs="-W wined3d-WINED3D_RS_COLORWRITEENABLE -W wined3d-Indexed_Vertex_Blending"
_staging_userargs="-W ntdll-NtAlertThreadByThreadId"
# vkd3dlib - We don't want to use vkd3d native library by default to allow for vkd3d-proton usage
# Set to "true" to enable explicit mainline vkd3d library support - default is "false"
_use_vkd3dlib="false"
# GAME-SPECIFIC PATCHES
# Enable support for Proton's Battleye runtime - Needs the package to be installed in Steam
_proton_battleye_support="true"
# Enable support for Proton's EAC bridge - Needs the package to be installed in Steam
_proton_eac_support="true"
_warframelauncher_fix="true"
_ffxivlauncher_fix="false"
_sims3_fix="false"
_mtga_fix="false"
_mwo_fix="false"
_childwindow_fix="true"
_lol920_fix="false"
_assettocorsa_hudperf_fix="true"
_staging_pulse_disable="false"
# Shared gpu resources support:
# Shared texture resources for d3d9 and d3d11 - https://github.com/doitsujin/dxvk/pull/2516
# Requires DXVK 1.10.1+
# ID3D11Fence and ID3D12Fence sharing - https://github.com/doitsujin/dxvk/pull/2608 https://github.com/HansKristian-Work/vkd3d-proton/pull/1175
# Requires DXVK 1.10.3+, VKD3D-Proton 2.7+
_shared_gpu_resources="false"
# Fixes for Mortal Kombat 11 - Requires staging, _proton_fs_hack="true", native mfplat (win7) or staging mfplat support and a different GPU driver than RADV
# On Wine 5.2 (up to b1c748c8) and lower, it needs to be toogled on with the WINE_LOW_USER_SPACE_LIMIT=1 envvar
_mk11_fix="true"
# ! _re4_fix="true" requires _wined3d_additions="false" or it will get ignored !
_re4_fix="false"
# Background music on King of Fighters 98 and 2002 is silent on Wine-staging and the `xactengine-initial` patchset was found to introduce the issue. Set to "true" to disable it as a workaround.
_kof98_2002_BGM_fix="false"
# Fix for Quake Champions by Paul Gofman for Proton - Depends on _protonify="true" and _use_staging="true"
# This patchset breaks Genshin Impact
_quake_champions_fix="true"
# OTHER PATCHES
# Set to "false" to disable building proton media converter - This is helpful for some games using unsupported video formats such as Resident Evil 8
# We're only supporting 64-bit version of the lib in -tkg at this point - https://github.com/ValveSoftware/Proton/tree/proton_6.3/media-converter
_build_mediaconv="true"
# Set to "true" to re-use previoulsy built gst-related libs (mediaconverter, gstreamer, ffmpeg, faudio)
# Set to "false" to explicitly not re-use previoulsy built gst-related libs
# Default (empty value) will prompt if an existing gst dir is found
# !!! There is not detection regarding what was and wasn't built, the previously built gst dir will be used as it was on last successfuly build, independently of the below options !!!
# !!! If you want to add features you didn't build before (for example ffmpeg or lib32), you'll need to enable those and rebuild without this option first !!!
_reuse_built_gst=""
# Set to "true" to enable building 64-bit patched gstreamer & plugins - This is helpful to support video formats no covered by your distro packages
# Will build orc, gstreamer, gst-plugins-base, gst-plugins-good, gst-plugins-bad, gst-plugins-ugly, gst-libav
# _build_mediaconv can be set to false when this is enabled and Steam's shader precaching is disabled
_build_gstreamer="false"
# Set to "true" to also enable building 32-bit patched gstreamer & plugins
# Depends on _build_gstreamer="true"
_lib32_gstreamer="false"
# Set to "true" to enable building ffmpeg
# Depends on _build_gstreamer="true"
# Enabling _lib32_gstreamer above will also enable lib32 for this option
_build_ffmpeg="true"
# Set to "true" to enable building FAudio
# Depends on _build_gstreamer="true"
# Enabling _lib32_gstreamer above will also enable lib32 for this option
_build_faudio="true"
_CSMT_toggle="true"
_GLSL_toggle="false"
_MIME_NOPE="true"
_lowlatency_audio="false"
_launch_with_dedicated_gpu="false"
_clock_monotonic="true"
_FS_bypass_compositor="true"
_proton_fs_hack="true"
_large_address_aware="true"
_stg_shared_mem_default="false"
_proton_mf_hacks="false"
_proton_rawinput="true"
# Joshua Ashton's take on making wine dialogs and menus less win95-ish - https://github.com/Joshua-Ashton/wine/tree/wine-better-theme
_use_josh_flat_theme="true"
# Enforce mscvrt Dlls to native then builtin - from Proton - Can be detrimental on 4.3+
_msvcrt_nativebuiltin="true"
# Set the default wine version to win10 (instead of win7)
_win10_default="true"
# Other misc proton patches and hacks - Notably contains fixes for some native vk games (such as Doom Eternal) as well as Rockstar launcher
# Also enables some winevulkan performance optimizations - https://github.com/Joshua-Ashton/proton-wine/tree/winevulkan-opt (fs hack) - https://github.com/Joshua-Ashton/wine/commits/winevulkan-opt-mainline (no fs hack)
_protonify="true"
#### LEGACY PATCHES - These are for older than current master - Some are enabled by default on such trees as they are considered harmless
# Sets the value of an additional fake refresh rate in virtual desktop mode. Leave empty to keep default - Deprecated as of 6f305dd8 (5.14-devel) unless FS hack is also enabled
_fake_refresh_rate=""
# legacy gallium nine - This is only available for 4.1-devel (prior to e24b162) and older wine versions - Use nine standalone instead for newer wine
_use_legacy_gallium_nine="false"
# pba - Enable with PBA_ENABLE=1 envvar, force-disabled on 3.19 & higher due to known broken state
_use_pba="true"
# The Sims 2 fix - On staging, disables wined3d-WINED3D_RS_COLORWRITEENABLE and wined3d-Indexed_Vertex_Blending patchsets - https://bugs.winehq.org/show_bug.cgi?id=8051 - Obsoleted by D9VK
_sims2_fix="false"
# Disable server-send_hardware_message staging patchset if found - Fixes FFXIV/Warframe/Crysis 3 (etc.) mouse jittering on 3.19 staging and lower. Will cause GTA V to freeze for a second or two on first keyboard input
_server_send_hwmsg_disable="true"
# Path of exile - Fixes DX11 mode not working - Doesn't seem to be needed anymore since Wine 4.1, supposedly since a game patch - https://bugs.winehq.org/show_bug.cgi?id=42695
_poe_fix="false"
# Overwatch mf crash fix from Guy1524 - https://bugs.winehq.org/show_bug.cgi?id=47385 - This will only apply against a wine tree missing b182ba882cfcce7b8769470f49f0fba216095c45, and ignored otherwise
_OW_fix="true"
# Python fix for <=3.18 (backported from zzhiyi's patches) - fix for python and needed for "The Sims 4" to work - replaces staging partial implementation - https://bugs.winehq.org/show_bug.cgi?id=44999 - This will only apply against a wine tree missing 3ebd2f0be30611e6cf00468c2980c5092f91b5b5, and ignored otherwise
_318python_fix="true"
# Workaround for F4SE/SkyrimSE Script Extender - This is a hack and could break stuff - https://github.com/hdmap/wine-hackery/tree/master/f4se - It was fixed upstream with 1aa963ef - 6672fc9d (4.13-devel)
_f4skyrimse_fix="false"
# steam crossover hack for store/web functionality - https://bugs.winehq.org/show_bug.cgi?id=39403
_steam_fix="true"
# Fix crashes or perf issues related to high core count setups - Fixed in 4.0 - https://bugs.winehq.org/show_bug.cgi?id=45453
_highcorecount_fix="true"
# Reverts c6b6935 due to https://bugs.winehq.org/show_bug.cgi?id=47752 - Fixed upstream with cb70373
_c6b6935_revert="true"
# Native dotnet workaround for 4.13+ - https://bugs.winehq.org/show_bug.cgi?id=47633
_nativedotnet_fix="true"
# USVFS (Mod Organizer 2's virtual filesystem) support patch - https://github.com/Tk-Glitch/PKGBUILDS/issues/300 - https://bugs.winehq.org/show_bug.cgi?id=47833
_usvfs_fix="false"
# Faudio - Use the currently installed Faudio packages (both 32 and 64-bit) for xaudio2 - Fixes sound issues in various games. Disables xaudio2 & winepulse staging patchsets
# Support is enabled by default in Wine 4.3+ as well as Wine-staging 4.13+, independently of this setting
_use_faudio="true"
# Revert moving various funcs to kernelbase & ntdll to fix some dll loading issues and ntdll crashes (with Cemu and Blizzard games notably)
# Deprecated as of b7db0b5 - Force-enabled on proton-tkg when using older than b7db0b5 tree
_kernelbase_reverts="false"
# Update winevulkan to whatever version I have pushed last, til next time, for new shiny and tasty vk extensions support. Thanks dadドイツ人 !
_update_winevulkan="false"
_plasma_systray_fix="false"
# Allow making use of the futex2 kernel interface for fsync - Requires a patched kernel such as linux-tkg - https://gitlab.collabora.com/tonyk/wine/-/commits/experimental_5.13
_fsync_futex2="true"
# USER PATCHES
# community patches - add patches (separated by a space) of your choice by name from the community-patches dir - https://github.com/Frogging-Family/community-patches - proton-tkg, just like wine-tkg-git, uses the wine-tkg-git patches subdir
# example: _community_patches="amdags.mypatch GNUTLShack.mypatch"
_community_patches="amdags-proton.mypatch atiadlxx-proton.mypatch FinalFantasyXVHack.mypatch ntdll_Map_top-down_if_dll_characteristics_include_DYNAMIC_BASE.mypatch Shell32-CreateDirectoryInDestinationInFileOp-Move-multiop.mypatch winex11_limit_resources-nmode.mypatch unhide-prefix-update-window.mypatch"
_user_patches="true"
_user_patches_no_confirm="false"
# Set to "false" to prompt about all non-critical hotfix patches at build time, or "ignore" to ignore all non-critical hotfix patches without confirmation
# Default ("true") will apply all non-critical hotfix patches without confirmation
_hotfixes_no_confirm="true"
# Set to false to disable staging mfplat restoration in case a hotfix is available and _hotfixes_no_confirm is set to "true"
_hotfixansw_staging_mfplat=""
# Set to false to disable staging pulseaudio restoration in case a hotfix is available and _hotfixes_no_confirm is set to "true"
_hotfixansw_staging_pulse=""

View File

@ -0,0 +1,30 @@
# Proton-tkg userpatches
You can make use of your own patches to the Proton, dxvk and vkd3d-proton trees by putting them in this folder before running proton-tkg.sh or makepkg.
You can also symlink them from an external place by running the following command from proton-tkg's root dir:
```ln -s /absolute/path/to/your/userpatches/dir/* proton-tkg-userpatches/```
*For example :* `ln -s /home/tkg/.config/frogminer/proton-tkg-userpatches/* proton-tkg-userpatches/`
They need to be diffs against the targeted tree.
You need to give your patch the appropriate extension :
**!! Patches with unrecognized extension will get ignored !!**
### Proton tree
** Those patches need to target the Proton tree directly and not wine. For wine patches handling, see https://github.com/Frogging-Family/wine-tkg-git/tree/master/wine-tkg-git/wine-tkg-userpatches**
- You can use your own proton patches by giving them the .myprotonpatch extension.
- You can also revert proton patches by giving them the .myprotonrevert extension.
### DXVK tree
- You can use your own dxvk patches by giving them the .mydxvkpatch extension.
- You can also revert dxvk patches by giving them the .mydxvkrevert extension.
### vkd3d-proton tree
- You can use your own vkd3d-proton patches by giving them the .myvkd3dpatch extension.
- You can also revert vkd3d-proton patches by giving them the .myvkd3drevert extension.

View File

@ -0,0 +1,36 @@
From 07b43c727c9a2f273dccb9af8061e646c79ea0a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= <tim@centricular.com>
Date: Tue, 13 Apr 2021 01:07:15 +0100
Subject: [PATCH] avdemux: fix build with FFmpeg 4.4
Direct access to avstream->index_entries was removed
in favour of the newly added avformat_index_get_entry()
and friends.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-libav/-/issues/85
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-libav/-/merge_requests/127>
---
ext/libav/gstavdemux.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ext/libav/gstavdemux.c b/ext/libav/gstavdemux.c
index 21b46aa..80a0920 100644
--- a/ext/libav/gstavdemux.c
+++ b/ext/libav/gstavdemux.c
@@ -483,7 +483,11 @@ gst_ffmpegdemux_do_seek (GstFFMpegDemux * demux, GstSegment * segment)
GST_LOG_OBJECT (demux, "keyframeidx: %d", keyframeidx);
if (keyframeidx >= 0) {
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58,78,0)
+ fftarget = avformat_index_get_entry (stream, keyframeidx)->timestamp;
+#else
fftarget = stream->index_entries[keyframeidx].timestamp;
+#endif
target = gst_ffmpeg_time_ff_to_gst (fftarget, stream->time_base);
GST_LOG_OBJECT (demux,
--
GitLab

View File

@ -0,0 +1,13 @@
diff --git a/ext/openexr/gstopenexrdec.cpp b/ext/openexr/gstopenexrdec.cpp
index eeb316cb189d470b298b28787cdf160bc09de65f..32b1d03c388a441cb1293fc261a1eec634c3e5f0 100644
--- a/ext/openexr/gstopenexrdec.cpp
+++ b/ext/openexr/gstopenexrdec.cpp
@@ -29,6 +29,7 @@
#include <ImfRgbaFile.h>
#include <ImfIO.h>
+#include <ImfInt64.h>
using namespace Imf;
using namespace Imath;

View File

@ -0,0 +1,14 @@
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c
index aa0ec5035..d9d7130f8 100644
--- a/gst/playback/gstdecodebin2.c
+++ b/gst/playback/gstdecodebin2.c
@@ -241,7 +241,7 @@ enum
/* automatic sizes, while prerolling we buffer up to 2MB, we ignore time
* and buffers in this case. */
-#define AUTO_PREROLL_SIZE_BYTES 2 * 1024 * 1024
+#define AUTO_PREROLL_SIZE_BYTES 10 * 1024 * 1024
#define AUTO_PREROLL_SIZE_BUFFERS 0
#define AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME 10 * GST_SECOND
#define AUTO_PREROLL_SEEKABLE_SIZE_TIME 0

View File

@ -0,0 +1,63 @@
From 17a175e0514d5f01b3a9d196235906b53b7c2eaf Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Fri, 17 Apr 2020 11:32:52 -0500
Subject: [PATCH] asfdemux: Re-initialize demux->adapter in
gst_asf_demux_reset.
---
gst/asfdemux/gstasfdemux.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/gst/asfdemux/gstasfdemux.c b/gst/asfdemux/gstasfdemux.c
index 6a6e3876..824a4355 100644
--- a/gst/asfdemux/gstasfdemux.c
+++ b/gst/asfdemux/gstasfdemux.c
@@ -208,11 +208,15 @@ gst_asf_demux_reset (GstASFDemux * demux, gboolean chain_reset)
gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
demux->segment_running = FALSE;
- if (demux->adapter && !chain_reset) {
- gst_adapter_clear (demux->adapter);
- g_object_unref (demux->adapter);
- demux->adapter = NULL;
+ if (!chain_reset) {
+ if (demux->adapter)
+ {
+ gst_adapter_clear (demux->adapter);
+ g_object_unref (demux->adapter);
+ }
+ demux->adapter = gst_adapter_new();
}
+
if (demux->taglist) {
gst_tag_list_unref (demux->taglist);
demux->taglist = NULL;
@@ -4816,6 +4820,9 @@ gst_asf_demux_finalize (GObject * object)
{
GstASFDemux *demux = GST_ASF_DEMUX (object);
+ if (demux->adapter)
+ demux->adapter = NULL;
+
if (demux->metadata)
gst_caps_unref (demux->metadata);
demux->metadata = NULL;
--
2.24.1
diff --git a/gst/asfdemux/gstasfdemux.c b/gst/asfdemux/gstasfdemux.c
index 7444fc14..30dfc20e 100644
--- a/gst/asfdemux/gstasfdemux.c
+++ b/gst/asfdemux/gstasfdemux.c
@@ -206,7 +206,7 @@ gst_asf_demux_reset (GstASFDemux * demux, gboolean chain_reset)
{
GST_LOG_OBJECT (demux, "resetting");
- gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
+ gst_segment_init (&demux->segment, GST_FORMAT_TIME);
demux->segment_running = FALSE;
if (!chain_reset) {
if (demux->adapter)

View File

@ -0,0 +1,186 @@
# 'Wine-to-rule-them-all' - Proton-TkG simple config file
##
## This config file contains the basic settings of your build.
## For deeper configuration, see proton-tkg-profiles/advanced-customization.cfg
##
# This is a simplified config file with minimal comments. See ../wine-tkg-git/customization.cfg for more details.
# Some options will be missing from this config file compared to wine-tkg-git as they are enforced.
#### NON-MAKEPKG OPTIONS (Won't affect makepkg builds) ####
# Set to true to get a prompt after the 64-bit part is built, enabling package switching before building the 32-bit side.
# This is a workaround for distros shipping broken devel packages that can't coexist as multilib
_nomakepkg_midbuild_prompt="false"
# Set to the distro of your choice to attempt dependency resolution. Valid options are "debuntu" (for debian, ubuntu and similar), "fedora" or "archlinux".
_nomakepkg_dep_resolution_distro=""
# Set to true if you want to skip the uninstaller at the end of proton-tkg building
_skip_uninstaller="false"
# Set to true if you do not want your build to be automatically moved to your compatibilitytools.d dir
_no_autoinstall="false"
####
# PROTON-TKG-MISC OPTIONS
# SteamDeck support additions
_tabtip="true"
# Set Pulseaudio latency to 60ms - Can help with sound crackling issues on some configs (and introduce crackling on others)
_proton_pulse_lowlat="false"
# Enable Winetricks prompt on game launch - Will use your system winetricks, so you need it installed
_proton_winetricks="false"
# DXVK
# Valid options::
# "git" - Recommended and default - Will build current master with dxvk_config patch to allow for enhanced vkd3d compatibility
# "prebuilt" - For builds made with dxvk-tools for example
# "release" - using github's latest
# "false" - disabled
# Setting it to "true" will default to "release"
_use_dxvk="git"
# hud : https://github.com/doitsujin/dxvk#hud
# configfile : https://github.com/doitsujin/dxvk/wiki/Configuration#configuration-file
_proton_dxvk_hud=""
_proton_dxvk_configfile=""
# WINE FLAVOUR SETTINGS
# Override config with one of the presets from /wine-tkg-profiles dir. Leave empty to be prompted.
# Custom presets for proton :
# "valve" (builds against current valve proton tree)
# "valve-exp" (builds against current valve proton-experimental tree)
# "valve-exp-bleeding" (builds against current valve proton-experimental-bleeding-edge tree)
# "none" - Silence the prompt
_LOCAL_PRESET=""
# Add GloriousEggroll game patches and hotfixes when using a Valve profile with staging enabled
# ! This will only affect Valve + staging trees !
# List of patches applied with this option enabled: assettocorsa-hud killer-instinct-winevulkan_fix FFVII-and-SpecialK-powerprof 65-proton-fake_current_res_patches unity_crash_hotfix Fix-regression-introduced-by-0e7fd41 15aa8c6-fix-star-citizen-bug-52956 0001-winex11.drv-Define-ControlMask-when-not-available 0002-include-Add-THREAD_POWER_THROTTLING_STATE-type 0003-ntdll-Fake-success-for-ThreadPowerThrottlingState
_use_GE_patches="true"
# fastsync - disable at runtime with WINE_DISABLE_FAST_SYNC=1 envvar - Set to true to enable winesync/fastsync support - https://repo.or.cz/wine/zf.git/shortlog/refs/heads/fastsync4
# !! on plain: Disables esync / fsync support !!
# !! on staging: Requires fsync support !!
_use_fastsync="false"
_use_esync="true"
_use_fsync="true"
# futex_waitv() API for fsync - Requires 5.16 kernel or kernel with backported patches - https://github.com/ValveSoftware/wine/pull/128
# !! Replaces previous fsync interfaces support !!
_fsync_futex_waitv="true"
_plain_version=""
_use_staging="true"
_staging_version=""
# GAME-SPECIFIC PATCHES
# Enable support for Proton's Battleye runtime - Needs the package to be installed in Steam
_proton_battleye_support="true"
# Enable support for Proton's EAC bridge - Needs the package to be installed in Steam
_proton_eac_support="true"
_ffxivlauncher_fix="false"
_sims3_fix="false"
_mtga_fix="false"
_mwo_fix="false"
_childwindow_fix="true"
_lol920_fix="false"
# Shared gpu resources support:
# Shared texture resources for d3d9 and d3d11 - https://github.com/doitsujin/dxvk/pull/2516
# Requires DXVK 1.10.1+
# ID3D11Fence and ID3D12Fence sharing - https://github.com/doitsujin/dxvk/pull/2608 https://github.com/HansKristian-Work/vkd3d-proton/pull/1175
# Requires DXVK 1.10.3+, VKD3D-Proton 2.7+
_shared_gpu_resources="false"
# Fix for Assetto Corsa performance drop when HUD elements are displayed - https://bugs.winehq.org/show_bug.cgi?id=46955
_assettocorsa_hudperf_fix="true"
# Fixes for Mortal Kombat 11 - Requires staging, _proton_fs_hack="true", native mfplat (win7) or staging mfplat support and a different GPU driver than RADV
# On Wine 5.2 (up to b1c748c8) and lower, it needs to be toogled on with the WINE_LOW_USER_SPACE_LIMIT=1 envvar
_mk11_fix="true"
# ! _re4_fix="true" requires _wined3d_additions="false" or it will get ignored ! - Not needed when using DXVK
_re4_fix="false"
# Background music on King of Fighters 98 and 2002 is silent on Wine-staging and the `xactengine-initial` patchset was found to introduce the issue. Set to "true" to disable it as a workaround.
_kof98_2002_BGM_fix="false"
# Fix for Quake Champions by Paul Gofman for Proton - Depends on _protonify="true" and _use_staging="true"
# This patchset breaks Genshin Impact
_quake_champions_fix="true"
# OTHER PATCHES
# Set to "false" to disable building proton media converter - This is helpful for some games using unsupported video formats such as Resident Evil 8
# We're only supporting 64-bit version of the lib in -tkg at this point - https://github.com/ValveSoftware/Proton/tree/proton_6.3/media-converter
_build_mediaconv="true"
# Set to "true" to re-use previoulsy built gst-related libs (mediaconverter, gstreamer, ffmpeg, faudio)
# Set to "false" to explicitly not re-use previoulsy built gst-related libs
# Default (empty value) will prompt if an existing gst dir is found
# !!! There is not detection regarding what was and wasn't built, the previously built gst dir will be used as it was on last successfuly build, independently of the below options !!!
# !!! If you want to add features you didn't build before (for example ffmpeg or lib32), you'll need to enable those and rebuild without this option first !!!
_reuse_built_gst=""
# Set to "true" to enable building 64-bit patched gstreamer & plugins - This is helpful to support video formats no covered by your distro packages
# Will build orc, gstreamer, gst-plugins-base, gst-plugins-good, gst-plugins-bad, gst-plugins-ugly, gst-libav
# _build_mediaconv can be set to false when this is enabled and Steam's shader precaching is disabled
_build_gstreamer="false"
# Set to "true" to also enable building 32-bit patched gstreamer & plugins
# Depends on _build_gstreamer="true"
_lib32_gstreamer="false"
# Set to "true" to enable building ffmpeg
# Depends on _build_gstreamer="true"
# Enabling _lib32_gstreamer above will also enable lib32 for this option
_build_ffmpeg="true"
# Set to "true" to enable building FAudio
# Depends on _build_gstreamer="true"
# Enabling _lib32_gstreamer above will also enable lib32 for this option
_build_faudio="true"
_FS_bypass_compositor="true"
_proton_fs_hack="true"
# Joshua Ashton's take on making wine dialogs and menus less win95-ish - https://github.com/Joshua-Ashton/wine/tree/wine-better-theme
_use_josh_flat_theme="true"
# Other misc proton patches and hacks - Notably contains fixes for some native vk games (such as Doom Eternal) as well as Rockstar launcher
# Also enables some winevulkan performance optimizations - https://github.com/Joshua-Ashton/proton-wine/tree/winevulkan-opt (fs hack) - https://github.com/Joshua-Ashton/wine/commits/winevulkan-opt-mainline (no fs hack)
_protonify="true"
# USER PATCHES
# community patches - add patches (separated by a space) of your choice by name from the community-patches dir - https://github.com/Frogging-Family/community-patches - proton-tkg, just like wine-tkg-git, uses the wine-tkg-git patches subdir
# example: _community_patches="amdags.mypatch GNUTLShack.mypatch"
_community_patches="amd_fsr_fshack-alternative.mypatch amdags-proton.mypatch atiadlxx-proton.mypatch 0002-proton_QPC.mypatch ntdll_Map_top-down_if_dll_characteristics_include_DYNAMIC_BASE.mypatch EA_desktop_fix.mypatch Shell32-CreateDirectoryInDestinationInFileOp-Move-multiop.mypatch"
_user_patches="true"
_user_patches_no_confirm="false"
# Set to "false" to prompt about all non-critical hotfix patches at build time, or "ignore" to ignore all non-critical hotfix patches without confirmation
# Default ("true") will apply all non-critical hotfix patches without confirmation
_hotfixes_no_confirm="true"
# Set to false to disable staging mfplat restoration in case a hotfix is available and _hotfixes_no_confirm is set to "true"
_hotfixansw_staging_mfplat=""
# Set to false to disable staging pulseaudio restoration in case a hotfix is available and _hotfixes_no_confirm is set to "true"
_hotfixansw_staging_pulse=""

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
diff --git a/src/LiberationMono-Regular.sfd b/src/LiberationMono-Regular.sfd
index 0cedbd4..13b9a63 100644
--- a/src/LiberationMono-Regular.sfd
+++ b/src/LiberationMono-Regular.sfd
@@ -3931,6 +3931,10 @@ ShortTable: maxp 16
3
1
EndShort
+TtfTable: VDMX 94
+!!!!"!!**$!<E0/!"B2J!!iQ/s8E!)!"&](!"&]4s8;p*!"8i*!"8i9s8;p,!"Ao*!"Ju<s82j-
+!"Ju+!"],?s82j/!"],,!"o8Bs8)d0!"f2-!#,DFs8)cr
+EndTtf
LangName: 1033 "" "" "Regular" "Ascender - Liberation Mono" "" "Version 2.00.3" "" "Liberation is a trademark of Red Hat, Inc. registered in U.S. Patent and Trademark Office and certain other jurisdictions." "Ascender Corporation" "Steve Matteson" "Based on Cousine, which was designed by Steve Matteson as an innovative, refreshing sans serif design that is metrically compatible with Courier New+ISIA. Cousine offers improved on-screen readability characteristics and the pan-European WGL character set and solves the needs of developers looking for width-compatible fonts to address document portability across platforms." "http://www.ascendercorp.com/" "http://www.ascendercorp.com/typedesigners.html" "Licensed under the SIL Open Font License, Version 1.1" "http://scripts.sil.org/OFL"
GaspTable: 3 8 2 17 1 65535 3 0
Encoding: UnicodeBmp

View File

@ -0,0 +1,75 @@
Copyright (c) 2018, Valve Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Browse the source code for more information
https://github.com/ValveSoftware/Proton/
---- ---- ---- ----
This software contains Wine licensed under the LGPL 2.1. Wine is
Copyright (c) 1993-2018 the Wine project authors
Browse the source code for more information
https://github.com/ValveSoftware/wine/
---- ---- ---- ----
This software contains DXVK licensed under the zlib/libpng license. DXVK is
Copyright (c) 2017 Philip Rebohle
Visit DXVK at
https://github.com/doitsujin/dxvk/
---- ---- ---- ----
Parts of this software are based on the OpenVR SDK, which is
Copyright (c) 2015, Valve Corporation
Visit OpenVR at
https://github.com/ValveSoftware/openvr/
---- ---- ---- ----
This software contains openal-soft licensed under the LGPL 2.
Visit openal-soft at
https://github.com/kcat/openal-soft/
---- ---- ---- ----
Parts of this software are based on the AMD AGS library, which is
Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.

View File

@ -0,0 +1,22 @@
"compatibilitytools"
{
"compat_tools"
{
"TKG-proton-TKGVERSION" // Internal name of this tool
{
// Can register this tool with Steam in two ways:
//
// - The tool can be placed as a subdirectory in compatibilitytools.d, in which case this
// should be '.'
//
// - This manifest can be placed directly in compatibilitytools.d, in which case this should
// be the relative or absolute path to the tool's dist directory.
"install_path" "."
"display_name" "TKG-proton-TKGVERSION"
"from_oslist" "windows"
"to_oslist" "linux"
}
}
}

View File

@ -0,0 +1,451 @@
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org>
"""
A platform independent file lock that supports the with-statement.
"""
# Modules
# ------------------------------------------------
import logging
import os
import threading
import time
try:
import warnings
except ImportError:
warnings = None
try:
import msvcrt
except ImportError:
msvcrt = None
try:
import fcntl
except ImportError:
fcntl = None
# Backward compatibility
# ------------------------------------------------
try:
TimeoutError
except NameError:
TimeoutError = OSError
# Data
# ------------------------------------------------
__all__ = [
"Timeout",
"BaseFileLock",
"WindowsFileLock",
"UnixFileLock",
"SoftFileLock",
"FileLock"
]
__version__ = "3.0.12"
_logger = None
def logger():
"""Returns the logger instance used in this module."""
global _logger
_logger = _logger or logging.getLogger(__name__)
return _logger
# Exceptions
# ------------------------------------------------
class Timeout(TimeoutError):
"""
Raised when the lock could not be acquired in *timeout*
seconds.
"""
def __init__(self, lock_file):
"""
"""
#: The path of the file lock.
self.lock_file = lock_file
return None
def __str__(self):
temp = "The file lock '{}' could not be acquired."\
.format(self.lock_file)
return temp
# Classes
# ------------------------------------------------
# This is a helper class which is returned by :meth:`BaseFileLock.acquire`
# and wraps the lock to make sure __enter__ is not called twice when entering
# the with statement.
# If we would simply return *self*, the lock would be acquired again
# in the *__enter__* method of the BaseFileLock, but not released again
# automatically.
#
# :seealso: issue #37 (memory leak)
class _Acquire_ReturnProxy(object):
def __init__(self, lock):
self.lock = lock
return None
def __enter__(self):
return self.lock
def __exit__(self, exc_type, exc_value, traceback):
self.lock.release()
return None
class BaseFileLock(object):
"""
Implements the base class of a file lock.
"""
def __init__(self, lock_file, timeout = -1):
"""
"""
# The path to the lock file.
self._lock_file = lock_file
# The file descriptor for the *_lock_file* as it is returned by the
# os.open() function.
# This file lock is only NOT None, if the object currently holds the
# lock.
self._lock_file_fd = None
# The default timeout value.
self.timeout = timeout
# We use this lock primarily for the lock counter.
self._thread_lock = threading.Lock()
# The lock counter is used for implementing the nested locking
# mechanism. Whenever the lock is acquired, the counter is increased and
# the lock is only released, when this value is 0 again.
self._lock_counter = 0
return None
@property
def lock_file(self):
"""
The path to the lock file.
"""
return self._lock_file
@property
def timeout(self):
"""
You can set a default timeout for the filelock. It will be used as
fallback value in the acquire method, if no timeout value (*None*) is
given.
If you want to disable the timeout, set it to a negative value.
A timeout of 0 means, that there is exactly one attempt to acquire the
file lock.
.. versionadded:: 2.0.0
"""
return self._timeout
@timeout.setter
def timeout(self, value):
"""
"""
self._timeout = float(value)
return None
# Platform dependent locking
# --------------------------------------------
def _acquire(self):
"""
Platform dependent. If the file lock could be
acquired, self._lock_file_fd holds the file descriptor
of the lock file.
"""
raise NotImplementedError()
def _release(self):
"""
Releases the lock and sets self._lock_file_fd to None.
"""
raise NotImplementedError()
# Platform independent methods
# --------------------------------------------
@property
def is_locked(self):
"""
True, if the object holds the file lock.
.. versionchanged:: 2.0.0
This was previously a method and is now a property.
"""
return self._lock_file_fd is not None
def acquire(self, timeout=None, poll_intervall=0.05):
"""
Acquires the file lock or fails with a :exc:`Timeout` error.
.. code-block:: python
# You can use this method in the context manager (recommended)
with lock.acquire():
pass
# Or use an equivalent try-finally construct:
lock.acquire()
try:
pass
finally:
lock.release()
:arg float timeout:
The maximum time waited for the file lock.
If ``timeout < 0``, there is no timeout and this method will
block until the lock could be acquired.
If ``timeout`` is None, the default :attr:`~timeout` is used.
:arg float poll_intervall:
We check once in *poll_intervall* seconds if we can acquire the
file lock.
:raises Timeout:
if the lock could not be acquired in *timeout* seconds.
.. versionchanged:: 2.0.0
This method returns now a *proxy* object instead of *self*,
so that it can be used in a with statement without side effects.
"""
# Use the default timeout, if no timeout is provided.
if timeout is None:
timeout = self.timeout
# Increment the number right at the beginning.
# We can still undo it, if something fails.
with self._thread_lock:
self._lock_counter += 1
lock_id = id(self)
lock_filename = self._lock_file
start_time = time.time()
try:
while True:
with self._thread_lock:
if not self.is_locked:
logger().debug('Attempting to acquire lock %s on %s', lock_id, lock_filename)
self._acquire()
if self.is_locked:
logger().info('Lock %s acquired on %s', lock_id, lock_filename)
break
elif timeout >= 0 and time.time() - start_time > timeout:
logger().debug('Timeout on acquiring lock %s on %s', lock_id, lock_filename)
raise Timeout(self._lock_file)
else:
logger().debug(
'Lock %s not acquired on %s, waiting %s seconds ...',
lock_id, lock_filename, poll_intervall
)
time.sleep(poll_intervall)
except:
# Something did go wrong, so decrement the counter.
with self._thread_lock:
self._lock_counter = max(0, self._lock_counter - 1)
raise
return _Acquire_ReturnProxy(lock = self)
def release(self, force = False):
"""
Releases the file lock.
Please note, that the lock is only completly released, if the lock
counter is 0.
Also note, that the lock file itself is not automatically deleted.
:arg bool force:
If true, the lock counter is ignored and the lock is released in
every case.
"""
with self._thread_lock:
if self.is_locked:
self._lock_counter -= 1
if self._lock_counter == 0 or force:
lock_id = id(self)
lock_filename = self._lock_file
logger().debug('Attempting to release lock %s on %s', lock_id, lock_filename)
self._release()
self._lock_counter = 0
logger().info('Lock %s released on %s', lock_id, lock_filename)
return None
def __enter__(self):
self.acquire()
return self
def __exit__(self, exc_type, exc_value, traceback):
self.release()
return None
def __del__(self):
self.release(force = True)
return None
# Windows locking mechanism
# ~~~~~~~~~~~~~~~~~~~~~~~~~
class WindowsFileLock(BaseFileLock):
"""
Uses the :func:`msvcrt.locking` function to hard lock the lock file on
windows systems.
"""
def _acquire(self):
open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC
try:
fd = os.open(self._lock_file, open_mode)
except OSError:
pass
else:
try:
msvcrt.locking(fd, msvcrt.LK_NBLCK, 1)
except (IOError, OSError):
os.close(fd)
else:
self._lock_file_fd = fd
return None
def _release(self):
fd = self._lock_file_fd
self._lock_file_fd = None
msvcrt.locking(fd, msvcrt.LK_UNLCK, 1)
os.close(fd)
try:
os.remove(self._lock_file)
# Probably another instance of the application
# that acquired the file lock.
except OSError:
pass
return None
# Unix locking mechanism
# ~~~~~~~~~~~~~~~~~~~~~~
class UnixFileLock(BaseFileLock):
"""
Uses the :func:`fcntl.flock` to hard lock the lock file on unix systems.
"""
def _acquire(self):
open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC
fd = os.open(self._lock_file, open_mode)
try:
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
except (IOError, OSError):
os.close(fd)
else:
self._lock_file_fd = fd
return None
def _release(self):
# Do not remove the lockfile:
#
# https://github.com/benediktschmitt/py-filelock/issues/31
# https://stackoverflow.com/questions/17708885/flock-removing-locked-file-without-race-condition
fd = self._lock_file_fd
self._lock_file_fd = None
fcntl.flock(fd, fcntl.LOCK_UN)
os.close(fd)
return None
# Soft lock
# ~~~~~~~~~
class SoftFileLock(BaseFileLock):
"""
Simply watches the existence of the lock file.
"""
def _acquire(self):
open_mode = os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
try:
fd = os.open(self._lock_file, open_mode)
except (IOError, OSError):
pass
else:
self._lock_file_fd = fd
return None
def _release(self):
os.close(self._lock_file_fd)
self._lock_file_fd = None
try:
os.remove(self._lock_file)
# The file is already deleted and that's what we want.
except OSError:
pass
return None
# Platform filelock
# ~~~~~~~~~~~~~~~~~
#: Alias for the lock, which should be used for the current platform. On
#: Windows, this is an alias for :class:`WindowsFileLock`, on Unix for
#: :class:`UnixFileLock` and otherwise for :class:`SoftFileLock`.
FileLock = None
if msvcrt:
FileLock = WindowsFileLock
elif fcntl:
FileLock = UnixFileLock
else:
FileLock = SoftFileLock
if warnings is not None:
warnings.warn("only soft file lock is available")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
"manifest"
{
"commandline" "/proton run"
"commandline_getnativepath" "/proton getnativepath"
"commandline_getcompatpath" "/proton getcompatpath"
"commandline_waitforexitandrun" "/proton waitforexitandrun"
}

View File

@ -0,0 +1,110 @@
#Settings here will take effect for all games run in this Proton version.
user_settings = {
#By default, logs are saved to $HOME/steam-<STEAM_GAME_ID>.log, overwriting any previous log with that name.
#Log directory can be overridden with $PROTON_LOG_DIR.
#Wine debug logging
# "WINEDEBUG": "+timestamp,+pid,+tid,+seh,+debugstr,+loaddll,+mscoree",
#DXVK debug logging
# "DXVK_LOG_LEVEL": "info",
#wine-mono debug logging (Wine's .NET replacement)
# "WINE_MONO_TRACE": "E:System.NotImplementedException",
# "MONO_LOG_LEVEL": "info",
#Set DXVK custom config path
# "DXVK_CONFIG_FILE": "",
#Enable DXVK Async pipecompiler
# "PROTON_DXVK_ASYNC": "1",
#Enable DXVK's HUD
# "DXVK_HUD": "devinfo,fps",
#Enable AMD FSR
"WINE_FULLSCREEN_FSR": "1",
"WINE_FULLSCREEN_FSR_STRENGTH": "2",
#Write the command proton sends to wine for targeted prefix (/prefix/path/launch_command) - Helpful to track bound executable
"PROTON_LOG_COMMAND_TO_PREFIX": "1",
#Alternative way to run executables directly with wine binary instead of using steam.exe. This is the preffered way when using proton standalone.
# "PROTON_STANDALONE_START": "1",
#Enable nvapi support through nvidia provided nvngx.dll (Requires nvidia driver 470+) - Needed for DLSS support
# "PROTON_ENABLE_NVAPI": "1",
#Disable nvapi and nvapi64
"PROTON_NVAPI_DISABLE": "1",
#Pass "--use-gl=osmesa" to the command line. Fixes various launchers showing up with a black window (Star Citizen, Warframe, etc..). Might give poor perf on native opengl games, so disable in case of issues.
"PROTON_GL_OSMESA": "1",
#Set a wine override to disable libglesv2. Fixes various launchers showing up with a black window (Star Citizen, Warframe, etc..). Alternative to running an app with `--use-gl=osmesa`, but more extreme.
#Known to break at least the Rockstar Games Launcher, so only use if the PROTON_GL_OSMESA option above doesn't fix your issue.
#We used to have a revert for that, but it would only affect upstream builds. This is a more universal solution - https://bugs.winehq.org/show_bug.cgi?id=44985
# "PROTON_GLES2_DISABLE": "1",
#Disable winedbg
"PROTON_WINEDBG_DISABLE": "1",
#Disable conhost
"PROTON_CONHOST_DISABLE": "1",
#Disable IMAGE_FILE_LARGE_ADDRESS_AWARE override - In case it breaks your (32-bit) game - System Shock 2 is known to break with LAA enabled
# "PROTON_DISABLE_LARGE_ADDRESS_AWARE": "1",
#Reduce Pulse Latency
"PROTON_PULSE_LOWLATENCY": "1",
#Enable Winetricks prompt on game launch
# "PROTON_WINETRICKS": "1",
#Enable seccomp-bpf filter to emulate native syscalls, required for some DRM protections to work. Requires staging on proton-tkg.
# "PROTON_USE_SECCOMP": "1",
#Disable support for memory write watches in ntdll. This is a very dangerous hack and should only be applied if you have verified that the game can operate without write watches.
#This improves performance for some very specific games (e.g. CoreRT-based games).
# "PROTON_NO_WRITE_WATCH": "1",
#Spoof d3d12 feature level supported by vkd3d. Needed for some d3d12 games to work.
"VKD3D_FEATURE_LEVEL": "12_0",
#Use OpenGL-based wined3d for d3d11/d3d10/d3d9 instead of Vulkan-based DXVK & D9VK
# "PROTON_USE_WINED3D": "1",
#Use OpenGL-based wined3d for d3d11/10 only (keeping D9VK enabled). Comment out to use Vulkan-based DXVK instead.
# "PROTON_USE_WINED3D11": "1",
#Enable custom d3d9 dll usage. This is the option you want to enable to use Gallium 9. Builtin D9VK won't be used with this option enabled.
# "PROTON_USE_CUSTOMD3D9": "1",
#Use OpenGL-based wined3d for d3d9 only (keeping DXVK enabled). Comment out to use Vulkan-based D9VK or custom d3d9 dll instead.
"PROTON_USE_WINED3D9": "1",
#Use Wine DXGI instead of DXVK's. This is needed to make use of VKD3D when DXVK is enabled. It will prevent the use of DXVK's DXGI functions.
# "PROTON_USE_WINE_DXGI": "1",
#Disable d3d11 entirely !!!
# "PROTON_NO_D3D11": "1",
#Disable d3d10 entirely !!!
# "PROTON_NO_D3D10": "1",
#Disable d3d9 entirely !!!
# "PROTON_NO_D3D9": "1",
#Disable eventfd-based in-process synchronization primitives
# "PROTON_NO_ESYNC": "1",
#Disable futex-based in-process synchronization primitives
# "PROTON_NO_FSYNC": "1",
#Disable futex2-based in-process synchronization primitives
# "PROTON_NO_FUTEX2": "1",
#Enforce driver shader cache path when Steam's shader pre-caching is disabled
# "PROTON_BYPASS_SHADERCACHE_PATH": "",
}

View File

@ -0,0 +1,118 @@
#!/usr/bin/env python3
# usage: default_pfx.py path/to/default_pfx_dir path/to/dist
"Helper module for building the default prefix"
import os
import subprocess
def file_is_wine_builtin_dll(path):
if not os.path.exists(path):
return False
try:
sfile = open(path, "rb")
sfile.seek(0x40)
tag = sfile.read(20)
return tag.startswith((b"Wine placeholder DLL", b"Wine builtin DLL"))
except IOError:
return False
def little_endian_bytes_to_uint(b):
result = 0
multiplier = 1
for i in b:
result += i * multiplier
multiplier <<= 8
return result
def dll_bitness(path):
if not os.path.exists(path):
return 0
try:
sfile = open(path, "rb")
sfile.seek(0x3c)
ntheader_ofs = little_endian_bytes_to_uint(sfile.read(4))
sfile.seek(0x18 + ntheader_ofs)
magic = sfile.read(2)
if magic == bytes((11, 1)):
return 32
if magic == bytes((11, 2)):
return 64
return 0
except IOError:
return 0
def make_relative_symlink(target, linkname):
target = os.path.abspath(target)
linkname = os.path.abspath(linkname)
rel = os.path.relpath(target, os.path.dirname(linkname))
os.symlink(rel, linkname)
def setup_dll_symlinks(default_pfx_dir, dist_dir):
skip_dlls = [ 'amd_ags_x64.dll' ]
for walk_dir, dirs, files in os.walk(default_pfx_dir):
for file_ in files:
filename = os.path.join(walk_dir, file_)
if file_ in skip_dlls:
continue
if os.path.isfile(filename) and file_is_wine_builtin_dll(filename):
bitness = dll_bitness(filename)
if bitness == 32:
libdir = os.path.join(dist_dir, 'lib/wine')
newlibdir = os.path.join(dist_dir, 'lib/wine/i386-windows')
elif bitness == 64:
libdir = os.path.join(dist_dir, 'lib64/wine')
newlibdir = os.path.join(dist_dir, 'lib64/wine/x86_64-windows')
else:
continue
if os.path.exists(os.path.join(libdir, file_)):
target = os.path.join(libdir, file_)
elif os.path.exists(os.path.join(libdir, 'fakedlls', file_)):
target = os.path.join(libdir, 'fakedlls', file_)
elif os.path.exists(os.path.join(newlibdir, file_)):
target = os.path.join(newlibdir, file_)
else:
continue
os.unlink(filename)
make_relative_symlink(target, filename)
#steampipe can't handle filenames with colons, so we remove them here
#and restore them in the proton script
def fixup_drive_links(default_pfx_dir):
for walk_dir, dirs, files in os.walk(os.path.join(default_pfx_dir, "dosdevices")):
for dir_ in dirs:
if ":" in dir_:
os.remove(os.path.join(walk_dir, dir_))
def make_default_pfx(default_pfx_dir, dist_dir, runtime):
local_env = dict(os.environ)
ld_path = dist_dir + "/lib64:" + dist_dir + "/lib:" + dist_dir + "/lib64/x86_64-unix:" + dist_dir + "/lib/i386-unix"
if runtime is None:
local_env["LD_LIBRARY_PATH"] = ld_path
local_env["WINEPREFIX"] = default_pfx_dir
local_env["WINEDEBUG"] = "-all"
runtime_args = []
else:
#the runtime clears the environment, so we pass it in on the CL via env
runtime_args = runtime + ["env",
"LD_LIBRARY_PATH=" + ld_path,
"WINEPREFIX=" + default_pfx_dir,
"WINEDEBUG=-all"]
subprocess.run(runtime_args + ["/bin/bash", "-c",
os.path.join(dist_dir, 'bin', 'wine') + " wineboot && " +
os.path.join(dist_dir, 'bin', 'wineserver') + " -w"],
env=local_env, check=True)
setup_dll_symlinks(default_pfx_dir, dist_dir)
fixup_drive_links(default_pfx_dir)
if __name__ == '__main__':
import sys
if len(sys.argv) > 3:
make_default_pfx(sys.argv[1], sys.argv[2], sys.argv[3:])
else:
make_default_pfx(sys.argv[1], sys.argv[2], None)

View File

@ -0,0 +1,23 @@
From f319dc029be11156c22429c8e0892b4c0e3d0657 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 23 Mar 2020 22:24:54 +0100
Subject: dxvk_config lib support
diff --git a/proton b/proton
index be3586d..75e2e93 100755
--- a/proton
+++ b/proton
@@ -333,10 +333,10 @@ class CompatData:
try_copy(srcfile, dstfile)
if use_wined3d:
- dxvkfiles = []
+ dxvkfiles = ["dxvk_config"]
wined3dfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "d3d9"]
else:
- dxvkfiles = ["d3d11", "d3d10core", "d3d9"]
+ dxvkfiles = ["dxvk_config", "d3d11", "d3d10core", "d3d9"]
wined3dfiles = []
#if the user asked for dxvk's dxgi (dxgi=n), then copy it into place

View File

@ -0,0 +1,19 @@
From 1b6e416742d381d786c88603046a93feec261808 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Sun, 22 Mar 2020 02:08:35 +0100
Subject: Remove d3d10 and d3d10_1 for dxvk 1.6 and wine 5.3+
diff --git a/proton b/proton
index be3586d..2d8a659 100755
--- a/proton
+++ b/proton
@@ -333,7 +333,7 @@ class CompatData:
dxvkfiles = ["dxvk_config"]
wined3dfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "d3d9"]
else:
- dxvkfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "d3d9"]
+ dxvkfiles = ["d3d11", "d3d10core", "d3d9"]
wined3dfiles = []
#if the user asked for dxvk's dxgi (dxgi=n), then copy it into place

View File

@ -0,0 +1,500 @@
#!/bin/bash
_nowhere="$(dirname "$PWD")"
#_nowhere="$PWD"
source "$_nowhere/proton_tkg_token" || source "$_nowhere/src/proton_tkg_token"
cd "$_nowhere"/external-resources
git clone https://github.com/GStreamer/gstreamer.git || true # It'll complain the path already exists on subsequent builds
cd gstreamer
git reset --hard HEAD
git clean -xdf
git pull origin main
#git checkout f0b045a69bb0b36515b84e3b64df9dc30c8f1e1a
cd ..
git clone https://github.com/FFmpeg/FFmpeg.git || true # It'll complain the path already exists on subsequent builds
cd FFmpeg
git reset --hard HEAD
git clean -xdf
git pull origin master
#git checkout a77521c
cd ..
if [ "$_build_faudio" = "true" ]; then
git clone https://github.com/FNA-XNA/FAudio.git || true # It'll complain the path already exists on subsequent builds
cd FAudio
git reset --hard HEAD
git clean -xdf
git checkout d6b3e87720691bddd421673e4a9ea47a690b8fab # Last commit before gstreamer support removal - which we currently still need for wma playback
cd ..
rm -rf FAudio32 && cp -R FAudio FAudio32
rm -rf "$_nowhere"/Proton/build/faudio*
fi
rm -rf "$_nowhere"/Proton/{gstreamer,FFmpeg,FAudio}
ln -s "$_nowhere"/external-resources/{gstreamer,FFmpeg,FAudio} "$_nowhere"/Proton/
rm -rf "$_nowhere"/Proton/build/gst*
##### 64
# If /usr/lib32 doesn't exist (such as on Fedora), make sure we're using /usr/lib64 for 64-bit pkgconfig path
if [ ! -d '/usr/lib32' ]; then
export PKG_CONFIG_PATH="$_proton_tkg_path/gst/lib64/pkgconfig:/usr/lib64/pkgconfig"
else
export PKG_CONFIG_PATH="$_proton_tkg_path/gst/lib64/pkgconfig"
fi
if [ "$_build_ffmpeg" = "true" ]; then
mkdir -p "$_nowhere"/Proton/build/FFmpeg64 && cd "$_nowhere"/Proton/build/FFmpeg64
"$_nowhere"/Proton/FFmpeg/configure \
--prefix="$_nowhere/gst" \
--libdir="$_nowhere/gst/lib64" \
--enable-shared \
--disable-static \
--disable-everything \
--disable-programs \
--disable-doc \
--enable-decoder=mpeg4 \
--enable-decoder=msmpeg4v1 \
--enable-decoder=msmpeg4v2 \
--enable-decoder=msmpeg4v3 \
--enable-decoder=vc1 \
--enable-decoder=wmav1 \
--enable-decoder=wmav2 \
--enable-decoder=wmapro \
--enable-decoder=wmalossless \
--enable-decoder=xma1 \
--enable-decoder=xma2 \
--enable-decoder=wmv3image \
--enable-decoder=wmv3 \
--enable-decoder=wmv2 \
--enable-decoder=wmv1 \
--enable-decoder=h264 \
--enable-decoder=aac \
--enable-demuxer=xwma
make && make install
fi
cd "$_nowhere"/Proton/gstreamer
mkdir -p "$_nowhere"/Proton/build/gst64
meson_options=(
-D devtools=disabled
-D tests=disabled
-D doc=disabled
-D examples=disabled
-D python=disabled
-D ges=disabled
-D gpl=enabled
-D gst-examples=disabled
-D libnice=disabled
-D vaapi=disabled
-D introspection=disabled
-D gstreamer:dbghelp=disabled
-D gstreamer:gobject-cast-checks=disabled
-D gstreamer:ptp-helper-permissions=capabilities
-D gstreamer:introspection=disabled
-D gstreamer:gst_parse=false
-D gstreamer:benchmarks=disabled
-D gstreamer:tools=disabled
-D gstreamer:bash-completion=disabled
-D gstreamer:examples=disabled
-D gstreamer:tests=disabled
-D gstreamer:glib-asserts=disabled
-D gstreamer:glib-checks=disabled
-D gstreamer:nls=disabled
-D gst-plugins-base:gobject-cast-checks=disabled
-D gst-plugins-base:tremor=disabled
-D gst-plugins-base:theora=disabled
-D gst-plugins-base:alsa=disabled
-D gst-plugins-base:audiomixer=disabled
-D gst-plugins-base:audiorate=disabled
-D gst-plugins-base:audiotestsrc=disabled
-D gst-plugins-base:cdparanoia=disabled
-D gst-plugins-base:compositor=disabled
-D gst-plugins-base:encoding=disabled
-D gst-plugins-base:gio=disabled
-D gst-plugins-base:gl=disabled
-D gst-plugins-base:libvisual=disabled
-D gst-plugins-base:overlaycomposition=disabled
-D gst-plugins-base:pango=disabled
-D gst-plugins-base:rawparse=disabled
-D gst-plugins-base:subparse=disabled
-D gst-plugins-base:tcp=disabled
-D gst-plugins-base:videorate=disabled
-D gst-plugins-base:videotestsrc=disabled
-D gst-plugins-base:volume=disabled
-D gst-plugins-base:x11=disabled
-D gst-plugins-base:xshm=disabled
-D gst-plugins-base:xvideo=disabled
-D gst-plugins-base:tools=disabled
-D gst-plugins-base:examples=disabled
-D gst-plugins-base:tests=disabled
-D gst-plugins-base:introspection=disabled
-D gst-plugins-base:gobject-cast-checks=disabled
-D gst-plugins-base:glib-asserts=disabled
-D gst-plugins-base:glib-checks=disabled
-D gst-plugins-base:nls=disabled
-D gst-plugins-good:gobject-cast-checks=disabled
-D gst-plugins-good:rpicamsrc=disabled
-D gst-plugins-good:aalib=disabled
-D gst-plugins-good:alpha=disabled
-D gst-plugins-good:apetag=disabled
-D gst-plugins-good:audiofx=disabled
-D gst-plugins-good:auparse=disabled
-D gst-plugins-good:cairo=disabled
-D gst-plugins-good:cutter=disabled
-D gst-plugins-good:dtmf=disabled
-D gst-plugins-good:effectv=disabled
-D gst-plugins-good:equalizer=disabled
-D gst-plugins-good:gdk-pixbuf=disabled
-D gst-plugins-good:gtk3=disabled
-D gst-plugins-good:goom=disabled
-D gst-plugins-good:goom2k1=disabled
-D gst-plugins-good:icydemux=disabled
-D gst-plugins-good:imagefreeze=disabled
-D gst-plugins-good:interleave=disabled
-D gst-plugins-good:jack=disabled
-D gst-plugins-good:law=disabled
-D gst-plugins-good:level=disabled
-D gst-plugins-good:libcaca=disabled
-D gst-plugins-good:monoscope=disabled
-D gst-plugins-good:multifile=disabled
-D gst-plugins-good:multipart=disabled
-D gst-plugins-good:oss=disabled
-D gst-plugins-good:oss4=disabled
-D gst-plugins-good:png=disabled
-D gst-plugins-good:pulse=disabled
-D gst-plugins-good:qt5=disabled
-D gst-plugins-good:replaygain=disabled
-D gst-plugins-good:rtp=disabled
-D gst-plugins-good:rtpmanager=disabled
-D gst-plugins-good:rtsp=disabled
-D gst-plugins-good:shapewipe=disabled
-D gst-plugins-good:shout2=disabled
-D gst-plugins-good:smpte=disabled
-D gst-plugins-good:soup=disabled
-D gst-plugins-good:spectrum=disabled
-D gst-plugins-good:taglib=disabled
-D gst-plugins-good:udp=disabled
-D gst-plugins-good:v4l2=disabled
-D gst-plugins-good:videocrop=disabled
-D gst-plugins-good:videomixer=disabled
-D gst-plugins-good:wavenc=disabled
-D gst-plugins-good:ximagesrc=disabled
-D gst-plugins-good:y4m=disabled
-D gst-plugins-bad:directfb=disabled
-D gst-plugins-bad:flite=disabled
-D gst-plugins-bad:gobject-cast-checks=disabled
-D gst-plugins-bad:gs=disabled
-D gst-plugins-bad:iqa=disabled
-D gst-plugins-bad:isac=disabled
-D gst-plugins-bad:magicleap=disabled
-D gst-plugins-bad:onnx=disabled
-D gst-plugins-bad:openh264=disabled
-D gst-plugins-bad:openni2=disabled
-D gst-plugins-bad:opensles=disabled
-D gst-plugins-bad:tinyalsa=disabled
-D gst-plugins-bad:voaacenc=disabled
-D gst-plugins-bad:voamrwbenc=disabled
-D gst-plugins-bad:wasapi2=disabled
-D gst-plugins-bad:wasapi=disabled
-D gst-plugins-bad:fbdev=disabled
-D gst-plugins-bad:decklink=disabled
-D gst-plugins-bad:dts=disabled
-D gst-plugins-bad:faac=disabled
-D gst-plugins-bad:faad=disabled
-D gst-plugins-bad:mpeg2enc=disabled
-D gst-plugins-bad:mplex=disabled
-D gst-plugins-bad:neon=disabled
-D gst-plugins-bad:rtmp=disabled
-D gst-plugins-bad:flite=disabled
-D gst-plugins-bad:vulkan=disabled
-D gst-plugins-bad:sbc=disabled
-D gst-plugins-bad:opencv=disabled
-D gst-plugins-bad:voamrwbenc=disabled
-D gst-plugins-bad:x265=disabled
-D gst-plugins-bad:openexr=disabled
-D gst-plugins-ugly:gobject-cast-checks=disabled
-D gst-rtsp-server:gobject-cast-checks=disabled
-D gst-editing-services:validate=disabled
)
meson "$_nowhere"/Proton/build/gst64 --prefix="$_nowhere/gst" --libdir="lib64" --buildtype=plain -Dpkg_config_path="$_nowhere/gst/lib64/pkgconfig" "${meson_options[@]}"
meson compile -C "$_nowhere"/Proton/build/gst64
meson install -C "$_nowhere"/Proton/build/gst64
# FAudio
if [ "$_build_faudio" = "true" ]; then
mkdir -p "$_nowhere"/Proton/build/faudio64/build
cp -a "$_nowhere"/Proton/FAudio/* "$_nowhere"/Proton/build/faudio64 && cd "$_nowhere"/Proton/build/faudio64/build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-Dpkg_config_path="$_nowhere"/gst/lib64/pkgconfig \
-DCMAKE_INSTALL_PREFIX="$_nowhere"/gst \
-DCMAKE_INSTALL_LIBDIR=lib64 \
-DCMAKE_INSTALL_INCLUDEDIR=include/FAudio \
-DGSTREAMER=ON
make && make install
fi
strip --strip-unneeded "$_nowhere"/gst/lib64/*.so
##### 32
if [ "$_lib32_gstreamer" = "true" ]; then
(
if [ -d '/usr/lib32/pkgconfig' ]; then # Typical Arch path
export PKG_CONFIG_PATH="$_proton_tkg_path/gst/lib/pkgconfig:/usr/lib32/pkgconfig"
elif [ -d '/usr/lib/i386-linux-gnu/pkgconfig' ]; then # Ubuntu 18.04/19.04 path
export PKG_CONFIG_PATH="$_proton_tkg_path/gst/lib/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig"
else
export PKG_CONFIG_PATH="$_proton_tkg_path/gst/lib/pkgconfig:/usr/lib/pkgconfig" # Pretty common path, possibly helpful for OpenSuse & Fedora
fi
export CC="gcc -m32"
export CXX="g++ -m32"
if [ "$_build_ffmpeg" = "true" ]; then
mkdir -p "$_nowhere"/Proton/build/FFmpeg32 && cd "$_nowhere"/Proton/build/FFmpeg32
"$_nowhere"/Proton/FFmpeg/configure \
--cc="$CC" \
--prefix="$_nowhere/gst" \
--libdir="$_nowhere/gst/lib" \
--enable-shared \
--disable-static \
--disable-everything \
--disable-programs \
--disable-doc \
--enable-decoder=mpeg4 \
--enable-decoder=msmpeg4v1 \
--enable-decoder=msmpeg4v2 \
--enable-decoder=msmpeg4v3 \
--enable-decoder=vc1 \
--enable-decoder=wmav1 \
--enable-decoder=wmav2 \
--enable-decoder=wmapro \
--enable-decoder=wmalossless \
--enable-decoder=xma1 \
--enable-decoder=xma2 \
--enable-decoder=wmv3image \
--enable-decoder=wmv3 \
--enable-decoder=wmv2 \
--enable-decoder=wmv1 \
--enable-decoder=h264 \
--enable-decoder=aac \
--enable-demuxer=xwma
make && make install
fi
cd "$_nowhere"/Proton/gstreamer
mkdir -p "$_nowhere"/Proton/build/gst32
meson32_options=(
-D devtools=disabled
-D tests=disabled
-D doc=disabled
-D examples=disabled
-D python=disabled
-D ges=disabled
-D gpl=enabled
-D gst-examples=disabled
-D libnice=disabled
-D vaapi=disabled
-D introspection=disabled
-D gstreamer:dbghelp=disabled
-D gstreamer:gobject-cast-checks=disabled
-D gstreamer:ptp-helper-permissions=capabilities
-D gstreamer:introspection=disabled
-D gstreamer:gst_parse=false
-D gstreamer:benchmarks=disabled
-D gstreamer:tools=disabled
-D gstreamer:bash-completion=disabled
-D gstreamer:examples=disabled
-D gstreamer:tests=disabled
-D gstreamer:glib-asserts=disabled
-D gstreamer:glib-checks=disabled
-D gstreamer:nls=disabled
-D gst-plugins-base:gobject-cast-checks=disabled
-D gst-plugins-base:tremor=disabled
-D gst-plugins-base:theora=disabled
-D gst-plugins-base:alsa=disabled
-D gst-plugins-base:audiomixer=disabled
-D gst-plugins-base:audiorate=disabled
-D gst-plugins-base:audiotestsrc=disabled
-D gst-plugins-base:cdparanoia=disabled
-D gst-plugins-base:compositor=disabled
-D gst-plugins-base:encoding=disabled
-D gst-plugins-base:gio=disabled
-D gst-plugins-base:gl=disabled
-D gst-plugins-base:libvisual=disabled
-D gst-plugins-base:overlaycomposition=disabled
-D gst-plugins-base:pango=disabled
-D gst-plugins-base:rawparse=disabled
-D gst-plugins-base:subparse=disabled
-D gst-plugins-base:tcp=disabled
-D gst-plugins-base:videorate=disabled
-D gst-plugins-base:videotestsrc=disabled
-D gst-plugins-base:volume=disabled
-D gst-plugins-base:x11=disabled
-D gst-plugins-base:xshm=disabled
-D gst-plugins-base:xvideo=disabled
-D gst-plugins-base:tools=disabled
-D gst-plugins-base:examples=disabled
-D gst-plugins-base:tests=disabled
-D gst-plugins-base:introspection=disabled
-D gst-plugins-base:gobject-cast-checks=disabled
-D gst-plugins-base:glib-asserts=disabled
-D gst-plugins-base:glib-checks=disabled
-D gst-plugins-base:nls=disabled
-D gst-plugins-good:gobject-cast-checks=disabled
-D gst-plugins-good:rpicamsrc=disabled
-D gst-plugins-good:aalib=disabled
-D gst-plugins-good:alpha=disabled
-D gst-plugins-good:apetag=disabled
-D gst-plugins-good:audiofx=disabled
-D gst-plugins-good:auparse=disabled
-D gst-plugins-good:cairo=disabled
-D gst-plugins-good:cutter=disabled
-D gst-plugins-good:dtmf=disabled
-D gst-plugins-good:effectv=disabled
-D gst-plugins-good:equalizer=disabled
-D gst-plugins-good:gdk-pixbuf=disabled
-D gst-plugins-good:gtk3=disabled
-D gst-plugins-good:goom=disabled
-D gst-plugins-good:goom2k1=disabled
-D gst-plugins-good:icydemux=disabled
-D gst-plugins-good:imagefreeze=disabled
-D gst-plugins-good:interleave=disabled
-D gst-plugins-good:jack=disabled
-D gst-plugins-good:lame=disabled
-D gst-plugins-good:law=disabled
-D gst-plugins-good:level=disabled
-D gst-plugins-good:libcaca=disabled
-D gst-plugins-good:monoscope=disabled
-D gst-plugins-good:multifile=disabled
-D gst-plugins-good:multipart=disabled
-D gst-plugins-good:oss=disabled
-D gst-plugins-good:oss4=disabled
-D gst-plugins-good:png=disabled
-D gst-plugins-good:pulse=disabled
-D gst-plugins-good:qt5=disabled
-D gst-plugins-good:replaygain=disabled
-D gst-plugins-good:rtp=disabled
-D gst-plugins-good:rtpmanager=disabled
-D gst-plugins-good:rtsp=disabled
-D gst-plugins-good:shapewipe=disabled
-D gst-plugins-good:shout2=disabled
-D gst-plugins-good:smpte=disabled
-D gst-plugins-good:soup=disabled
-D gst-plugins-good:spectrum=disabled
-D gst-plugins-good:taglib=disabled
-D gst-plugins-good:udp=disabled
-D gst-plugins-good:v4l2=disabled
-D gst-plugins-good:videocrop=disabled
-D gst-plugins-good:videomixer=disabled
-D gst-plugins-good:wavenc=disabled
-D gst-plugins-good:ximagesrc=disabled
-D gst-plugins-good:y4m=disabled
-D gst-plugins-bad:directfb=disabled
-D gst-plugins-bad:flite=disabled
-D gst-plugins-bad:gobject-cast-checks=disabled
-D gst-plugins-bad:gs=disabled
-D gst-plugins-bad:iqa=disabled
-D gst-plugins-bad:isac=disabled
-D gst-plugins-bad:magicleap=disabled
-D gst-plugins-bad:onnx=disabled
-D gst-plugins-bad:openh264=disabled
-D gst-plugins-bad:openni2=disabled
-D gst-plugins-bad:opensles=disabled
-D gst-plugins-bad:tinyalsa=disabled
-D gst-plugins-bad:voaacenc=disabled
-D gst-plugins-bad:voamrwbenc=disabled
-D gst-plugins-bad:wasapi2=disabled
-D gst-plugins-bad:wasapi=disabled
-D gst-plugins-bad:fbdev=disabled
-D gst-plugins-bad:decklink=disabled
-D gst-plugins-bad:dts=disabled
-D gst-plugins-bad:faac=disabled
-D gst-plugins-bad:faad=disabled
-D gst-plugins-bad:mpeg2enc=disabled
-D gst-plugins-bad:mplex=disabled
-D gst-plugins-bad:neon=disabled
-D gst-plugins-bad:rtmp=disabled
-D gst-plugins-bad:flite=disabled
-D gst-plugins-bad:vulkan=disabled
-D gst-plugins-bad:sbc=disabled
-D gst-plugins-bad:opencv=disabled
-D gst-plugins-bad:voamrwbenc=disabled
-D gst-plugins-bad:x265=disabled
-D gst-plugins-bad:openexr=disabled
-D gst-plugins-bad:fbdev=disabled
-D gst-plugins-bad:decklink=disabled
-D gst-plugins-bad:dts=disabled
-D gst-plugins-bad:faac=disabled
-D gst-plugins-bad:faad=disabled
-D gst-plugins-bad:libmms=disabled
-D gst-plugins-bad:mpeg2enc=disabled
-D gst-plugins-bad:mplex=disabled
-D gst-plugins-bad:neon=disabled
-D gst-plugins-bad:rtmp=disabled
-D gst-plugins-bad:flite=disabled
-D gst-plugins-bad:vulkan=disabled
-D gst-plugins-bad:sbc=disabled
-D gst-plugins-bad:opencv=disabled
-D gst-plugins-bad:voamrwbenc=disabled
-D gst-plugins-bad:x265=disabled
-D gst-plugins-bad:msdk=disabled
-D gst-plugins-bad:chromaprint=disabled
-D gst-plugins-bad:avtp=disabled
-D gst-plugins-bad:kate=disabled
-D gst-plugins-bad:openexr=disabled
-D gst-plugins-bad:ladspa=disabled
-D gst-plugins-bad:ofa=disabled
-D gst-plugins-bad:microdns=disabled
-D gst-plugins-bad:openh264=disabled
-D gst-plugins-bad:resindvd=disabled
-D gst-plugins-bad:spandsp=disabled
-D gst-plugins-bad:svthevcenc=disabled
-D gst-plugins-bad:srtp=disabled
-D gst-plugins-bad:wildmidi=disabled
-D gst-plugins-bad:zbar=disabled
-D gst-plugins-bad:zxing=disabled
-D gst-plugins-bad:webrtc=disabled
-D gst-plugins-bad:webrtcdsp=disabled
-D gst-plugins-bad:openmpt=disabled
-D gst-plugins-bad:bluez=disabled
-D gst-plugins-bad:bs2b=disabled
-D gst-plugins-bad:timecode=disabled
-D gst-plugins-ugly:gobject-cast-checks=disabled
-D gst-rtsp-server:gobject-cast-checks=disabled
-D gst-editing-services:validate=disabled
)
meson "$_nowhere"/Proton/build/gst32 --prefix="$_nowhere/gst" --libdir="lib" --buildtype=plain "${meson32_options[@]}"
meson compile -C "$_nowhere"/Proton/build/gst32
meson install -C "$_nowhere"/Proton/build/gst32
# FAudio
if [ "$_build_faudio" = "true" ]; then
mkdir -p "$_nowhere"/Proton/build/faudio32/build
cp -a "$_nowhere"/Proton/FAudio/* "$_nowhere"/Proton/build/faudio32 && cd "$_nowhere"/Proton/build/faudio32/build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$_nowhere"/gst \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_INSTALL_INCLUDEDIR=include/FAudio \
-DGSTREAMER=ON
make && make install
fi
strip --strip-unneeded "$_nowhere"/gst/lib/*.so
)
fi
cd "$_nowhere"

View File

@ -0,0 +1,57 @@
From 68621c9d55a19a6820b3f4ca3e9fb1a2464412c5 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Tue, 11 Feb 2020 11:23:10 +0100
Subject: proton-tkg: makepkg build adjustments
diff --git a/proton b/proton
index 811de5e..7aacb34 100755
--- a/proton
+++ b/proton
@@ -103,7 +103,7 @@ class Proton:
self.wine_bin = self.bin_dir + "wine"
self.wineserver_bin = self.bin_dir + "wineserver"
self.winetricks_bin = self.base_dir + "/files/share/winetricks/winetricks_runner"
- self.dist_lock = FileLock(self.path("dist.lock"), timeout=-1)
+ self.dist_lock = FileLock("/tmp/dist.lock", timeout=-1)
def path(self, d):
return self.base_dir + d
@@ -401,12 +401,6 @@ def setup_prefix(self):
self.migrate_user_paths()
- if not file_exists(self.prefix_dir + "/dosdevices/c:", follow_symlinks=False):
- os.symlink("../drive_c", self.prefix_dir + "/dosdevices/c:")
-
- if not file_exists(self.prefix_dir + "/dosdevices/z:", follow_symlinks=False):
- os.symlink("/", self.prefix_dir + "/dosdevices/z:")
-
# collect configuration info
if "STEAM_COMPAT_CLIENT_INSTALL_PATH" in os.environ:
#modern steam client sets this
@@ -789,6 +789,7 @@ class Session:
if local_env is None:
local_env = self.env
return subprocess.call(args, env=local_env, stderr=self.log_file, stdout=self.log_file)
+ self.env["PYTHONPYCACHEPREFIX"] = "/tmp"
def run(self):
if "PROTON_DUMP_DEBUG_COMMANDS" in self.env and nonzero(self.env["PROTON_DUMP_DEBUG_COMMANDS"]):
@@ -1208,7 +1208,6 @@ if __name__ == "__main__":
g_proton = Proton(os.path.dirname(sys.argv[0]))
g_proton.cleanup_legacy_dist()
- g_proton.do_steampipe_fixups()
g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"])
@@ -1217,8 +1217,6 @@ if __name__ == "__main__":
g_session.init_wine()
- if g_proton.missing_default_prefix():
- g_proton.make_default_prefix()
g_session.init_session()

View File

@ -0,0 +1,31 @@
From 8e24bfacdc8c29852511b40ae58c63e894d3f679 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 3 May 2021 13:29:25 +0200
Subject: Adapt to new lib paths in wine 6.7-devel
diff --git a/proton b/proton
index 1375736..4cc8429 100755
--- a/proton
+++ b/proton
@@ -301,7 +305,7 @@ class CompatData:
def pfx_copy(self, src, dst, dll_copy=False):
if os.path.islink(src):
contents = os.readlink(src)
- if os.path.dirname(contents).endswith(('/lib/wine', '/lib/wine/fakedlls', '/lib64/wine', '/lib64/wine/fakedlls')):
+ if os.path.dirname(contents).endswith(('/lib/wine/i386-windows', '/lib64/wine/x86_64-windows')):
# wine builtin dll
# make the destination an absolute symlink
contents = os.path.normpath(os.path.join(os.path.dirname(src), contents))
@@ -625,9 +629,9 @@ class Session:
# Allow wine to restore this when calling an external app.
self.env['ORIG_'+ld_path_var] = os.environ.get(ld_path_var, '')
- prepend_to_env_str(self.env, ld_path_var, g_proton.lib64_dir + ":" + g_proton.lib_dir, ":")
+ prepend_to_env_str(self.env, ld_path_var, g_proton.lib64_dir + ":" + g_proton.lib_dir + ":" + g_proton.lib64_dir + "x86_64-unix/:" + g_proton.lib_dir + "i386-unix/", ":")
- self.env["WINEDLLPATH"] = g_proton.lib64_dir + "/wine:" + g_proton.lib_dir + "/wine"
+ self.env["WINEDLLPATH"] = g_proton.lib64_dir + ":" + g_proton.lib_dir
prepend_to_env_str(self.env, "PATH", g_proton.bin_dir, ":")

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python3
import sys
import os
import stat
import pefile
for path in sys.argv[1:]:
pe = pefile.PE(path)
for section in pe.sections:
if section.Name.decode("utf-8")[0:5] == ".text":
section.Characteristics &= ~pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_CNT_INITIALIZED_DATA']
section.Characteristics &= ~pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_ALIGN_MASK']
pe.FILE_HEADER.TimeDateStamp = 1622588288
pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()
perm = stat.S_IMODE(os.stat(path).st_mode)
if (perm & stat.S_IWUSR) == 0:
os.chmod(path, perm | stat.S_IWUSR)
pe.write(path)
if (perm & stat.S_IWUSR) == 0:
os.chmod(path, perm)
print("Fixed up PE: ", path)

View File

@ -0,0 +1,3 @@
#!/bin/bash
LD_PRELOAD="" PATH="${PATH//\/steam-runtime\/amd64\/usr\/bin/}" WINEPREFIX=$WINEPREFIX winetricks

View File

@ -0,0 +1,18 @@
From 39105fd384e65f5dc2951d9d065d7fc7bdfc7c7d Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Wed, 8 Apr 2020 01:21:47 +0200
Subject: lsteamclient: Get rid of wine/library.h dep
diff --git a/lsteamclient/steamclient_main.c b/lsteamclient/steamclient_main.c
index de54021..d952d2d 100644
--- a/lsteamclient/steamclient_main.c
+++ b/lsteamclient/steamclient_main.c
@@ -14,7 +14,6 @@
#include "winbase.h"
#include "winnls.h"
#include "wine/debug.h"
-#include "wine/library.h"
#include "wine/list.h"
#include "steam_defs.h"

View File

@ -0,0 +1,56 @@
From 39105fd384e65f5dc2951d9d065d7fc7bdfc7c7d Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Wed, 8 Apr 2020 01:21:47 +0200
Subject: lsteamclient: Use standard dlopen() instead of the libwine wrappers
Following b87256cd1db21a59484248a193b6ad12ca2853ca
diff --git a/lsteamclient/steamclient_main.c b/lsteamclient/steamclient_main.c
index de54021..d952d2d 100644
--- a/lsteamclient/steamclient_main.c
+++ b/lsteamclient/steamclient_main.c
@@ -555,37 +555,37 @@ static int load_steamclient(void)
path[PATH_MAX - 1] = 0;
}
#endif
- steamclient_lib = wine_dlopen(path, RTLD_NOW, NULL, 0);
+ steamclient_lib = dlopen(path, RTLD_NOW);
if(!steamclient_lib){
ERR("unable to load native steamclient library\n");
return 0;
}
- steamclient_CreateInterface = wine_dlsym(steamclient_lib, "CreateInterface", NULL, 0);
+ steamclient_CreateInterface = dlsym(steamclient_lib, "CreateInterface");
if(!steamclient_CreateInterface){
ERR("unable to load CreateInterface method\n");
return 0;
}
- steamclient_BGetCallback = wine_dlsym(steamclient_lib, "Steam_BGetCallback", NULL, 0);
+ steamclient_BGetCallback = dlsym(steamclient_lib, "Steam_BGetCallback");
if(!steamclient_BGetCallback){
ERR("unable to load BGetCallback method\n");
return 0;
}
- steamclient_GetAPICallResult = wine_dlsym(steamclient_lib, "Steam_GetAPICallResult", NULL, 0);
+ steamclient_GetAPICallResult = dlsym(steamclient_lib, "Steam_GetAPICallResult");
if(!steamclient_GetAPICallResult){
ERR("unable to load GetAPICallResult method\n");
return 0;
}
- steamclient_FreeLastCallback = wine_dlsym(steamclient_lib, "Steam_FreeLastCallback", NULL, 0);
+ steamclient_FreeLastCallback = dlsym(steamclient_lib, "Steam_FreeLastCallback");
if(!steamclient_FreeLastCallback){
ERR("unable to load FreeLastCallback method\n");
return 0;
}
- steamclient_ReleaseThreadLocalMemory = wine_dlsym(steamclient_lib, "Steam_ReleaseThreadLocalMemory", NULL, 0);
+ steamclient_ReleaseThreadLocalMemory = dlsym(steamclient_lib, "Steam_ReleaseThreadLocalMemory");
if(!steamclient_ReleaseThreadLocalMemory){
ERR("unable to load ReleaseThreadLocalMemory method\n");
return 0;

View File

@ -0,0 +1,27 @@
diff --git a/steam_helper/steam.cpp b/steam_helper/steam.cpp
--- a/steam_helper/steam.cpp
+++ b/steam_helper/steam.cpp
@@ -33,6 +33,7 @@
* Windows version of Steam running. */
#include <windows.h>
+#include <winternl.h>
#include <shlobj.h>
#include <string.h>
#include <stdio.h>
@@ -52,7 +52,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(steam);
-EXTERN_C HANDLE CDECL __wine_make_process_system(void);
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
@@ -1177,7 +1177,7 @@ int main(int argc, char *argv[])
setup_steam_registry();
setup_steam_files();
- wait_handle = __wine_make_process_system();
+ NtSetInformationProcess(GetCurrentProcess(), (PROCESS_INFORMATION_CLASS)1000 /*ProcessWineMakeProcessSystem*/, &wait_handle, sizeof(HANDLE));
game_process = TRUE;
}

View File

@ -0,0 +1,20 @@
diff --git a/steam_helper/steam.cpp b/steam_helper/steam.cpp
--- a/steam_helper/steam.cpp
+++ b/steam_helper/steam.cpp
@@ -52,7 +52,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(steam);
-EXTERN_C HANDLE CDECL __wine_make_process_system(void);
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
@@ -1177,7 +1177,7 @@ int main(int argc, char *argv[])
}
if (game_process)
- wait_handle = __wine_make_process_system();
+ NtSetInformationProcess(GetCurrentProcess(), (PROCESS_INFORMATION_CLASS)1000 /*ProcessWineMakeProcessSystem*/, &wait_handle, sizeof(HANDLE));
if(wait_handle != INVALID_HANDLE_VALUE)
{

View File

@ -0,0 +1,426 @@
diff --git a/steam_helper/steam.cpp b/steam_helper/steam.cpp
index 8cb8559b..4f6e825c 100644
--- a/steam_helper/steam.cpp
+++ b/steam_helper/steam.cpp
@@ -559,6 +559,7 @@ static DWORD WINAPI initialize_vr_data(void *arg)
unsigned int app_id;
unsigned int length;
void *lib_vrclient;
+ DWORD hmd_present;
int return_code;
LSTATUS status;
unsigned int i;
@@ -604,6 +605,11 @@ static DWORD WINAPI initialize_vr_data(void *arg)
}
vr_initialized = TRUE;
+ hmd_present = !!client_core->BIsHmdPresent();
+ WINE_TRACE("hmd_present %#x.\n", hmd_present);
+ if ((status = RegSetValueExA(vr_key, "is_hmd_present", 0, REG_DWORD, (BYTE *)&hmd_present, sizeof(hmd_present))))
+ WINE_ERR("Could not set is_hmd_present value, status %#x.\n", status);
+
compositor = reinterpret_cast<vr::IVRCompositor*>(client_core->GetGenericInterface(vr::IVRCompositor_Version, &error));
if (!compositor)
{
diff --git a/steam_helper/steam.cpp b/steam_helper/steam.cpp
index 2554a526..8cb8559b 100644
--- a/steam_helper/steam.cpp
+++ b/steam_helper/steam.cpp
@@ -36,6 +36,8 @@
#include <shlobj.h>
#include <string.h>
#include <stdio.h>
+#include <limits.h>
+#include <dlfcn.h>
#pragma push_macro("_WIN32")
#pragma push_macro("__cdecl")
@@ -49,6 +51,11 @@
#include "json/json.h"
+#include "wine/heap.h"
+#include "wine/vulkan.h"
+#include "openvr.h"
+#include "../src/ivrclientcore.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(steam);
EXTERN_C HANDLE CDECL __wine_make_process_system(void);
@@ -417,6 +426,349 @@ static void setup_vrpaths(void)
}
}
+static BOOL set_vr_status(HKEY key, DWORD value)
+{
+ LSTATUS status;
+
+ if ((status = RegSetValueExA(key, "state", 0, REG_DWORD, (BYTE *)&value, sizeof(value))))
+ {
+ WINE_ERR("Could not set state value, status %#x.\n", status);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void* load_vrclient(void)
+{
+ WCHAR pathW[PATH_MAX];
+ char *pathU;
+ DWORD sz;
+
+#ifdef _WIN64
+ static const char append_path[] = "/bin/linux64/vrclient.so";
+#else
+ static const char append_path[] = "/bin/vrclient.so";
+#endif
+
+ /* PROTON_VR_RUNTIME is provided by the proton setup script */
+ if(!GetEnvironmentVariableW(L"PROTON_VR_RUNTIME", pathW, ARRAY_SIZE(pathW)))
+ {
+ WINE_TRACE("Linux OpenVR runtime is not available\n");
+ return 0;
+ }
+
+ sz = WideCharToMultiByte(CP_UNIXCP, 0, pathW, -1, NULL, 0, NULL, NULL);
+ if(!sz)
+ {
+ WINE_ERR("Can't convert path to unixcp! %s\n", wine_dbgstr_w(pathW));
+ return NULL;
+ }
+
+ pathU = (char *)HeapAlloc(GetProcessHeap(), 0, sz + sizeof(append_path));
+
+ sz = WideCharToMultiByte(CP_UNIXCP, 0, pathW, -1, pathU, sz, NULL, NULL);
+ if(!sz)
+ {
+ WINE_ERR("Can't convert path to unixcp! %s\n", wine_dbgstr_w(pathW));
+ return NULL;
+ }
+
+ strcat(pathU, append_path);
+
+ WINE_TRACE("got openvr runtime path: %s\n", pathU);
+
+ return dlopen(pathU, RTLD_NOW);
+}
+
+static char *strdupA(const char *s)
+{
+ size_t l = strlen(s) + 1;
+ char *r = (char *)heap_alloc(l);
+ memcpy(r, s, l);
+ return r;
+}
+
+static void parse_extensions(const char *in, uint32_t *out_count,
+ char ***out_strs)
+{
+ char *iter, *start;
+ char **list, *str = strdupA(in);
+ uint32_t extension_count = 0, o = 0;
+
+ iter = str;
+ while(*iter){
+ if(*iter++ == ' ')
+ extension_count++;
+ }
+ /* count the one ending in NUL */
+ if(iter != str)
+ extension_count++;
+ if(!extension_count){
+ *out_count = 0;
+ *out_strs = NULL;
+ return;
+ }
+
+ list = (char **)heap_alloc(extension_count * sizeof(*list));
+
+ start = iter = str;
+ do{
+ if(*iter == ' '){
+ *iter = 0;
+ list[o++] = start;
+ WINE_TRACE("added %s to list\n", list[o-1]);
+ iter++;
+ start = iter;
+ }else if(*iter == 0){
+ list[o++] = start;
+ WINE_TRACE("added %s to list\n", list[o-1]);
+ break;
+ }else{
+ iter++;
+ }
+ }while(1);
+
+ *out_count = extension_count;
+ *out_strs = list;
+}
+
+extern "C"
+{
+ VkPhysicalDevice WINAPI __wine_get_native_VkPhysicalDevice(VkPhysicalDevice phys_dev);
+};
+
+static DWORD WINAPI initialize_vr_data(void *arg)
+{
+ vr::IVRClientCore* (*vrclient_VRClientCoreFactory)(const char *name, int *return_code);
+ uint32_t instance_extensions_count, device_count;
+ VkPhysicalDevice *phys_devices = NULL;
+ VkPhysicalDeviceProperties prop = {};
+ VkInstanceCreateInfo inst_info = {};
+ char **instance_extensions = NULL;
+ VkApplicationInfo app_info = {};
+ char *buffer = NULL, *new_buffer;
+ vr::IVRClientCore* client_core;
+ vr::IVRCompositor* compositor;
+ VkInstance vk_instance = NULL;
+ BOOL vr_initialized = FALSE;
+ HKEY vr_key = (HKEY)arg;
+ vr::EVRInitError error;
+ HMODULE hvulkan = NULL;
+ DWORD vr_status = ~0u;
+ const char *env_str;
+ unsigned int app_id;
+ unsigned int length;
+ void *lib_vrclient;
+ int return_code;
+ LSTATUS status;
+ unsigned int i;
+ VkResult res;
+
+ WINE_TRACE("Starting VR info initialization.\n");
+
+ if (!(lib_vrclient = load_vrclient()))
+ {
+ WINE_ERR("Could not load libopenvr_api.so.\n");
+ set_vr_status(vr_key, ~0u);
+ RegCloseKey(vr_key);
+ return 0;
+ }
+
+ if (!(vrclient_VRClientCoreFactory = reinterpret_cast<decltype(vrclient_VRClientCoreFactory)>
+ (dlsym(lib_vrclient, "VRClientCoreFactory"))))
+ {
+ WINE_ERR("Could not find function %s.\n", vrclient_VRClientCoreFactory);
+ goto done;
+ }
+ if (!(client_core = vrclient_VRClientCoreFactory(vr::IVRClientCore_Version, &return_code)))
+ {
+ WINE_ERR("Could not get IVRClientCore, error %d.\n", return_code);
+ }
+
+ /* Without overriding the app_key vrclient waits 2 seconds for a valid appkey before returning. */
+ error = client_core->Init(vr::VRApplication_Background, NULL);
+ if (error != vr::VRInitError_None)
+ {
+ if (error == vr::VRInitError_Init_NoServerForBackgroundApp)
+ WINE_TRACE("VR server is not available.\n");
+ else
+ WINE_ERR("VR init failed, error %u.\n", error);
+ goto done;
+ }
+ vr_initialized = TRUE;
+
+ compositor = reinterpret_cast<vr::IVRCompositor*>(client_core->GetGenericInterface(vr::IVRCompositor_Version, &error));
+ if (!compositor)
+ {
+ WINE_ERR("Could not get compositor, error %u.\n", error);
+ goto done;
+ }
+
+ length = compositor->GetVulkanInstanceExtensionsRequired(nullptr, 0);
+ if (!(buffer = (char *)heap_alloc(length)))
+ {
+ WINE_ERR("No memory.\n");
+ goto done;
+ }
+ *buffer = 0;
+ compositor->GetVulkanInstanceExtensionsRequired(buffer, length);
+ WINE_TRACE("Instance extensions %s.\n", buffer);
+
+ if ((status = RegSetValueExA(vr_key, "openvr_vulkan_instance_extensions", 0, REG_SZ, (BYTE *)buffer, length)))
+ {
+ WINE_ERR("Could not set openvr_vulkan_instance_extensions value, status %#x.\n", status);
+ return FALSE;
+ }
+
+ if (!(hvulkan = LoadLibraryA("winevulkan.dll")))
+ {
+ WINE_ERR("Could not load winevulkan.\n");
+ goto done;
+ }
+
+#define USE_VULKAN_PROC(name) decltype(name) *p##name;\
+ if (!(p##name = reinterpret_cast<decltype(name) *>(GetProcAddress(hvulkan, "wine_"#name)))\
+ && !(p##name = reinterpret_cast<decltype(name) *>(GetProcAddress(hvulkan, #name))))\
+ {\
+ WINE_ERR("Could not find function %s.\n", #name);\
+ goto done;\
+ }
+ USE_VULKAN_PROC(vkCreateInstance)
+ USE_VULKAN_PROC(vkDestroyInstance)
+ USE_VULKAN_PROC(vkEnumeratePhysicalDevices)
+ USE_VULKAN_PROC(vkGetPhysicalDeviceProperties)
+ USE_VULKAN_PROC(__wine_get_native_VkPhysicalDevice)
+#undef USE_OPENVR_PROC
+
+ parse_extensions(buffer, &instance_extensions_count, &instance_extensions);
+
+ app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ app_info.pApplicationName = "proton_vrhelper";
+ app_info.applicationVersion = 1;
+ app_info.pEngineName = "proton_vrhelper";
+ app_info.engineVersion = 1;
+ app_info.apiVersion = VK_MAKE_VERSION(1, 1, 0);
+
+ inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ inst_info.pApplicationInfo = &app_info;
+ inst_info.enabledExtensionCount = instance_extensions_count;
+ inst_info.ppEnabledExtensionNames = instance_extensions;
+
+ if ((res = pvkCreateInstance(&inst_info, NULL, &vk_instance)) != VK_SUCCESS)
+ {
+ WINE_ERR("Could not create VK instance, res %d.\n", res);
+ goto done;
+ }
+
+ if ((res = pvkEnumeratePhysicalDevices(vk_instance, &device_count, NULL)) != VK_SUCCESS)
+ {
+ WINE_ERR("Could not enumerate physical devices, res %d.\n", res);
+ goto done;
+ }
+ if (!(phys_devices = (VkPhysicalDevice *)heap_alloc(device_count * sizeof(*phys_devices))))
+ {
+ WINE_ERR("No memory.\n");
+ goto done;
+ }
+ if ((res = pvkEnumeratePhysicalDevices(vk_instance, &device_count, phys_devices)) != VK_SUCCESS)
+ {
+ WINE_ERR("Could not enumerate physical devices, res %d.\n", res);
+ goto done;
+ }
+
+ for (i = 0; i < device_count; ++i)
+ {
+ char name[256];
+ LUID luid;
+
+ pvkGetPhysicalDeviceProperties(phys_devices[i], &prop);
+ if (prop.apiVersion < VK_MAKE_VERSION(1, 1, 0))
+ {
+ WINE_TRACE("Skipping Vulkan 1.0 adapter %s.\n", prop.deviceName);
+ continue;
+ }
+
+ length = compositor->GetVulkanDeviceExtensionsRequired(p__wine_get_native_VkPhysicalDevice(phys_devices[i]), nullptr, 0);
+ if (!(new_buffer = (char *)heap_realloc(buffer, length)))
+ {
+ WINE_ERR("No memory.\n");
+ goto done;
+ }
+ buffer = new_buffer;
+ compositor->GetVulkanDeviceExtensionsRequired(p__wine_get_native_VkPhysicalDevice(phys_devices[i]), buffer, length);
+ sprintf(name, "PCIID:%04x:%04x", prop.vendorID, prop.deviceID);
+ WINE_TRACE("%s: %s.\n", name, buffer);
+
+ if ((status = RegSetValueExA(vr_key, name, 0, REG_SZ, (BYTE *)buffer, length)))
+ {
+ WINE_ERR("Could not set %s value, status %#x.\n", name, status);
+ return FALSE;
+ }
+ }
+
+ vr_status = 1;
+
+done:
+ set_vr_status(vr_key, vr_status);
+
+ heap_free(phys_devices);
+
+ if (vk_instance)
+ pvkDestroyInstance(vk_instance, NULL);
+
+ if (instance_extensions)
+ {
+ heap_free(instance_extensions[0]);
+ heap_free(instance_extensions);
+ }
+ if (hvulkan)
+ FreeLibrary(hvulkan);
+ heap_free(buffer);
+ if (vr_initialized)
+ client_core->Cleanup();
+ WINE_TRACE("Completed VR info initialization.\n");
+ dlclose(lib_vrclient);
+ RegCloseKey(vr_key);
+ return 0;
+}
+
+static void setup_vr_registry(void)
+{
+ LSTATUS status;
+ HANDLE thread;
+ HKEY vr_key;
+ DWORD disp;
+
+ if ((status = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\VR", 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &vr_key, &disp)))
+ {
+ WINE_ERR("Could not create key, status %#x.\n", status);
+ return;
+ }
+ if (disp != REG_CREATED_NEW_KEY)
+ {
+ WINE_ERR("VR key already exists, disp %#x.\n", disp);
+ RegCloseKey(vr_key);
+ return;
+ }
+
+ if (!set_vr_status(vr_key, 0))
+ {
+ RegCloseKey(vr_key);
+ return;
+ }
+
+ if (!(thread = CreateThread(NULL, 0, initialize_vr_data, (void *)vr_key, 0, NULL)))
+ {
+ WINE_ERR("Could not create thread, error %u.\n", GetLastError());
+ RegCloseKey(vr_key);
+ return;
+ }
+ CloseHandle(thread);
+
+ WINE_TRACE("Queued VR info initialization.\n");
+}
+
static WCHAR *strchrW(WCHAR *h, WCHAR n)
{
do
@@ -656,6 +1015,7 @@ int main(int argc, char *argv[])
{
HANDLE wait_handle = INVALID_HANDLE_VALUE;
HANDLE event = INVALID_HANDLE_VALUE;
+ BOOL game_process = FALSE;
WINE_TRACE("\n");
@@ -670,6 +1030,7 @@ int main(int argc, char *argv[])
setup_steam_registry();
wait_handle = __wine_make_process_system();
+ game_process = TRUE;
}
if (argc > 1)
@@ -679,6 +1040,9 @@ int main(int argc, char *argv[])
setup_vrpaths();
+ if (game_process)
+ setup_vr_registry();
+
child = run_process(&should_await);
if (should_await)

View File

@ -0,0 +1,426 @@
diff --git a/steam_helper/steam.cpp b/steam_helper/steam.cpp
index 8cb8559b..4f6e825c 100644
--- a/steam_helper/steam.cpp
+++ b/steam_helper/steam.cpp
@@ -559,6 +559,7 @@ static DWORD WINAPI initialize_vr_data(void *arg)
unsigned int app_id;
unsigned int length;
void *lib_vrclient;
+ DWORD hmd_present;
int return_code;
LSTATUS status;
unsigned int i;
@@ -604,6 +605,11 @@ static DWORD WINAPI initialize_vr_data(void *arg)
}
vr_initialized = TRUE;
+ hmd_present = !!client_core->BIsHmdPresent();
+ WINE_TRACE("hmd_present %#x.\n", hmd_present);
+ if ((status = RegSetValueExA(vr_key, "is_hmd_present", 0, REG_DWORD, (BYTE *)&hmd_present, sizeof(hmd_present))))
+ WINE_ERR("Could not set is_hmd_present value, status %#x.\n", status);
+
compositor = reinterpret_cast<vr::IVRCompositor*>(client_core->GetGenericInterface(vr::IVRCompositor_Version, &error));
if (!compositor)
{
diff --git a/steam_helper/steam.cpp b/steam_helper/steam.cpp
index 2554a526..8cb8559b 100644
--- a/steam_helper/steam.cpp
+++ b/steam_helper/steam.cpp
@@ -36,6 +36,8 @@
#include <shlobj.h>
#include <string.h>
#include <stdio.h>
+#include <limits.h>
+#include <dlfcn.h>
#pragma push_macro("_WIN32")
#pragma push_macro("__cdecl")
@@ -49,6 +51,11 @@
#include "json/json.h"
+#include "wine/heap.h"
+#include "wine/vulkan.h"
+#include "openvr.h"
+#include "../src/ivrclientcore.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(steam);
EXTERN_C HANDLE CDECL __wine_make_process_system(void);
@@ -417,6 +426,349 @@ static void setup_vrpaths(void)
}
}
+static BOOL set_vr_status(HKEY key, DWORD value)
+{
+ LSTATUS status;
+
+ if ((status = RegSetValueExA(key, "state", 0, REG_DWORD, (BYTE *)&value, sizeof(value))))
+ {
+ WINE_ERR("Could not set state value, status %#x.\n", status);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void* load_vrclient(void)
+{
+ WCHAR pathW[PATH_MAX];
+ char *pathU;
+ DWORD sz;
+
+#ifdef _WIN64
+ static const char append_path[] = "/bin/linux64/vrclient.so";
+#else
+ static const char append_path[] = "/bin/vrclient.so";
+#endif
+
+ /* PROTON_VR_RUNTIME is provided by the proton setup script */
+ if(!GetEnvironmentVariableW(L"PROTON_VR_RUNTIME", pathW, ARRAY_SIZE(pathW)))
+ {
+ WINE_TRACE("Linux OpenVR runtime is not available\n");
+ return 0;
+ }
+
+ sz = WideCharToMultiByte(CP_UNIXCP, 0, pathW, -1, NULL, 0, NULL, NULL);
+ if(!sz)
+ {
+ WINE_ERR("Can't convert path to unixcp! %s\n", wine_dbgstr_w(pathW));
+ return NULL;
+ }
+
+ pathU = (char *)HeapAlloc(GetProcessHeap(), 0, sz + sizeof(append_path));
+
+ sz = WideCharToMultiByte(CP_UNIXCP, 0, pathW, -1, pathU, sz, NULL, NULL);
+ if(!sz)
+ {
+ WINE_ERR("Can't convert path to unixcp! %s\n", wine_dbgstr_w(pathW));
+ return NULL;
+ }
+
+ strcat(pathU, append_path);
+
+ WINE_TRACE("got openvr runtime path: %s\n", pathU);
+
+ return dlopen(pathU, RTLD_NOW);
+}
+
+static char *strdupA(const char *s)
+{
+ size_t l = strlen(s) + 1;
+ char *r = (char *)heap_alloc(l);
+ memcpy(r, s, l);
+ return r;
+}
+
+static void parse_extensions(const char *in, uint32_t *out_count,
+ char ***out_strs)
+{
+ char *iter, *start;
+ char **list, *str = strdupA(in);
+ uint32_t extension_count = 0, o = 0;
+
+ iter = str;
+ while(*iter){
+ if(*iter++ == ' ')
+ extension_count++;
+ }
+ /* count the one ending in NUL */
+ if(iter != str)
+ extension_count++;
+ if(!extension_count){
+ *out_count = 0;
+ *out_strs = NULL;
+ return;
+ }
+
+ list = (char **)heap_alloc(extension_count * sizeof(*list));
+
+ start = iter = str;
+ do{
+ if(*iter == ' '){
+ *iter = 0;
+ list[o++] = start;
+ WINE_TRACE("added %s to list\n", list[o-1]);
+ iter++;
+ start = iter;
+ }else if(*iter == 0){
+ list[o++] = start;
+ WINE_TRACE("added %s to list\n", list[o-1]);
+ break;
+ }else{
+ iter++;
+ }
+ }while(1);
+
+ *out_count = extension_count;
+ *out_strs = list;
+}
+
+extern "C"
+{
+ VkPhysicalDevice WINAPI __wine_get_native_VkPhysicalDevice(VkPhysicalDevice phys_dev);
+};
+
+static DWORD WINAPI initialize_vr_data(void *arg)
+{
+ vr::IVRClientCore* (*vrclient_VRClientCoreFactory)(const char *name, int *return_code);
+ uint32_t instance_extensions_count, device_count;
+ VkPhysicalDevice *phys_devices = NULL;
+ VkPhysicalDeviceProperties prop = {};
+ VkInstanceCreateInfo inst_info = {};
+ char **instance_extensions = NULL;
+ VkApplicationInfo app_info = {};
+ char *buffer = NULL, *new_buffer;
+ vr::IVRClientCore* client_core;
+ vr::IVRCompositor* compositor;
+ VkInstance vk_instance = NULL;
+ BOOL vr_initialized = FALSE;
+ HKEY vr_key = (HKEY)arg;
+ vr::EVRInitError error;
+ HMODULE hvulkan = NULL;
+ DWORD vr_status = ~0u;
+ const char *env_str;
+ unsigned int app_id;
+ unsigned int length;
+ void *lib_vrclient;
+ int return_code;
+ LSTATUS status;
+ unsigned int i;
+ VkResult res;
+
+ WINE_TRACE("Starting VR info initialization.\n");
+
+ if (!(lib_vrclient = load_vrclient()))
+ {
+ WINE_ERR("Could not load libopenvr_api.so.\n");
+ set_vr_status(vr_key, ~0u);
+ RegCloseKey(vr_key);
+ return 0;
+ }
+
+ if (!(vrclient_VRClientCoreFactory = reinterpret_cast<decltype(vrclient_VRClientCoreFactory)>
+ (dlsym(lib_vrclient, "VRClientCoreFactory"))))
+ {
+ WINE_ERR("Could not find function %s.\n", vrclient_VRClientCoreFactory);
+ goto done;
+ }
+ if (!(client_core = vrclient_VRClientCoreFactory(vr::IVRClientCore_Version, &return_code)))
+ {
+ WINE_ERR("Could not get IVRClientCore, error %d.\n", return_code);
+ }
+
+ /* Without overriding the app_key vrclient waits 2 seconds for a valid appkey before returning. */
+ error = client_core->Init(vr::VRApplication_Background, NULL);
+ if (error != vr::VRInitError_None)
+ {
+ if (error == vr::VRInitError_Init_NoServerForBackgroundApp)
+ WINE_TRACE("VR server is not available.\n");
+ else
+ WINE_ERR("VR init failed, error %u.\n", error);
+ goto done;
+ }
+ vr_initialized = TRUE;
+
+ compositor = reinterpret_cast<vr::IVRCompositor*>(client_core->GetGenericInterface(vr::IVRCompositor_Version, &error));
+ if (!compositor)
+ {
+ WINE_ERR("Could not get compositor, error %u.\n", error);
+ goto done;
+ }
+
+ length = compositor->GetVulkanInstanceExtensionsRequired(nullptr, 0);
+ if (!(buffer = (char *)heap_alloc(length)))
+ {
+ WINE_ERR("No memory.\n");
+ goto done;
+ }
+ *buffer = 0;
+ compositor->GetVulkanInstanceExtensionsRequired(buffer, length);
+ WINE_TRACE("Instance extensions %s.\n", buffer);
+
+ if ((status = RegSetValueExA(vr_key, "openvr_vulkan_instance_extensions", 0, REG_SZ, (BYTE *)buffer, length)))
+ {
+ WINE_ERR("Could not set openvr_vulkan_instance_extensions value, status %#x.\n", status);
+ return FALSE;
+ }
+
+ if (!(hvulkan = LoadLibraryA("winevulkan.dll")))
+ {
+ WINE_ERR("Could not load winevulkan.\n");
+ goto done;
+ }
+
+#define USE_VULKAN_PROC(name) decltype(name) *p##name;\
+ if (!(p##name = reinterpret_cast<decltype(name) *>(GetProcAddress(hvulkan, "wine_"#name)))\
+ && !(p##name = reinterpret_cast<decltype(name) *>(GetProcAddress(hvulkan, #name))))\
+ {\
+ WINE_ERR("Could not find function %s.\n", #name);\
+ goto done;\
+ }
+ USE_VULKAN_PROC(vkCreateInstance)
+ USE_VULKAN_PROC(vkDestroyInstance)
+ USE_VULKAN_PROC(vkEnumeratePhysicalDevices)
+ USE_VULKAN_PROC(vkGetPhysicalDeviceProperties)
+ USE_VULKAN_PROC(__wine_get_native_VkPhysicalDevice)
+#undef USE_OPENVR_PROC
+
+ parse_extensions(buffer, &instance_extensions_count, &instance_extensions);
+
+ app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ app_info.pApplicationName = "proton_vrhelper";
+ app_info.applicationVersion = 1;
+ app_info.pEngineName = "proton_vrhelper";
+ app_info.engineVersion = 1;
+ app_info.apiVersion = VK_MAKE_VERSION(1, 1, 0);
+
+ inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ inst_info.pApplicationInfo = &app_info;
+ inst_info.enabledExtensionCount = instance_extensions_count;
+ inst_info.ppEnabledExtensionNames = instance_extensions;
+
+ if ((res = pvkCreateInstance(&inst_info, NULL, &vk_instance)) != VK_SUCCESS)
+ {
+ WINE_ERR("Could not create VK instance, res %d.\n", res);
+ goto done;
+ }
+
+ if ((res = pvkEnumeratePhysicalDevices(vk_instance, &device_count, NULL)) != VK_SUCCESS)
+ {
+ WINE_ERR("Could not enumerate physical devices, res %d.\n", res);
+ goto done;
+ }
+ if (!(phys_devices = (VkPhysicalDevice *)heap_alloc(device_count * sizeof(*phys_devices))))
+ {
+ WINE_ERR("No memory.\n");
+ goto done;
+ }
+ if ((res = pvkEnumeratePhysicalDevices(vk_instance, &device_count, phys_devices)) != VK_SUCCESS)
+ {
+ WINE_ERR("Could not enumerate physical devices, res %d.\n", res);
+ goto done;
+ }
+
+ for (i = 0; i < device_count; ++i)
+ {
+ char name[256];
+ LUID luid;
+
+ pvkGetPhysicalDeviceProperties(phys_devices[i], &prop);
+ if (prop.apiVersion < VK_MAKE_VERSION(1, 1, 0))
+ {
+ WINE_TRACE("Skipping Vulkan 1.0 adapter %s.\n", prop.deviceName);
+ continue;
+ }
+
+ length = compositor->GetVulkanDeviceExtensionsRequired(p__wine_get_native_VkPhysicalDevice(phys_devices[i]), nullptr, 0);
+ if (!(new_buffer = (char *)heap_realloc(buffer, length)))
+ {
+ WINE_ERR("No memory.\n");
+ goto done;
+ }
+ buffer = new_buffer;
+ compositor->GetVulkanDeviceExtensionsRequired(p__wine_get_native_VkPhysicalDevice(phys_devices[i]), buffer, length);
+ sprintf(name, "PCIID:%04x:%04x", prop.vendorID, prop.deviceID);
+ WINE_TRACE("%s: %s.\n", name, buffer);
+
+ if ((status = RegSetValueExA(vr_key, name, 0, REG_SZ, (BYTE *)buffer, length)))
+ {
+ WINE_ERR("Could not set %s value, status %#x.\n", name, status);
+ return FALSE;
+ }
+ }
+
+ vr_status = 1;
+
+done:
+ set_vr_status(vr_key, vr_status);
+
+ heap_free(phys_devices);
+
+ if (vk_instance)
+ pvkDestroyInstance(vk_instance, NULL);
+
+ if (instance_extensions)
+ {
+ heap_free(instance_extensions[0]);
+ heap_free(instance_extensions);
+ }
+ if (hvulkan)
+ FreeLibrary(hvulkan);
+ heap_free(buffer);
+ if (vr_initialized)
+ client_core->Cleanup();
+ WINE_TRACE("Completed VR info initialization.\n");
+ dlclose(lib_vrclient);
+ RegCloseKey(vr_key);
+ return 0;
+}
+
+static void setup_vr_registry(void)
+{
+ LSTATUS status;
+ HANDLE thread;
+ HKEY vr_key;
+ DWORD disp;
+
+ if ((status = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\VR", 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &vr_key, &disp)))
+ {
+ WINE_ERR("Could not create key, status %#x.\n", status);
+ return;
+ }
+ if (disp != REG_CREATED_NEW_KEY)
+ {
+ WINE_ERR("VR key already exists, disp %#x.\n", disp);
+ RegCloseKey(vr_key);
+ return;
+ }
+
+ if (!set_vr_status(vr_key, 0))
+ {
+ RegCloseKey(vr_key);
+ return;
+ }
+
+ if (!(thread = CreateThread(NULL, 0, initialize_vr_data, (void *)vr_key, 0, NULL)))
+ {
+ WINE_ERR("Could not create thread, error %u.\n", GetLastError());
+ RegCloseKey(vr_key);
+ return;
+ }
+ CloseHandle(thread);
+
+ WINE_TRACE("Queued VR info initialization.\n");
+}
+
static WCHAR *strchrW(WCHAR *h, WCHAR n)
{
do
@@ -656,6 +1015,7 @@ int main(int argc, char *argv[])
{
HANDLE wait_handle = INVALID_HANDLE_VALUE;
HANDLE event = INVALID_HANDLE_VALUE;
+ BOOL game_process = FALSE;
WINE_TRACE("\n");
@@ -670,6 +1030,7 @@ int main(int argc, char *argv[])
setup_steam_registry();
NtSetInformationProcess(GetCurrentProcess(), (PROCESS_INFORMATION_CLASS)1000 /*ProcessWineMakeProcessSystem*/, &wait_handle, sizeof(HANDLE));
+ game_process = TRUE;
}
if (argc > 1)
@@ -679,6 +1040,9 @@ int main(int argc, char *argv[])
setup_vrpaths();
+ if (game_process)
+ setup_vr_registry();
+
child = run_process(&should_await);
if (should_await)

View File

@ -0,0 +1,116 @@
#!/usr/bin/env python3
#Steampipe doesn't support certain unix-y things which may be required by
#native Linux applications. This file will process a directory of Linux files
#and store the file properties into a manifest file. After a round trip through
#Steampipe, the original file properties can be restored using this same
#script.
import json
import os
import secrets
import stat
DEFAULT_MANIFEST_NAME = "steampipe_fixups.json"
def usage():
print("Usage:")
print("\t" + sys.argv[0] + "\tprepare\t<path to directory to process>\t[manifest output file]")
print("\t\tProcess the given path and output the manifest file to the given path, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
print("")
print("\t" + sys.argv[0] + "\trestore\t<path to directory to process>\t[manifest file]")
print("\t\tRestore the given path using the manifest file, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
empty_dirs = []
no_write_paths = []
def canonicalize(path, prefix):
return path.replace(prefix, "", 1).lstrip('/')
def process_dir(path):
for root, subdirs, files in os.walk(path):
if len(subdirs) == 0 and len(files) == 0:
empty_dirs.append(canonicalize(root, path))
for file_ in files:
this_file = os.path.join(root, file_)
stat_result = os.lstat(this_file)
if (stat_result.st_mode & stat.S_IWUSR) == 0:
no_write_paths.append(canonicalize(this_file, path))
return 0
def write_manifest(manifest):
out = open(manifest, "w")
json.dump(
{
"id": str(secrets.randbits(32)), #we need steampipe to update this file for every build
"empty_dirs": empty_dirs,
"no_write_paths": no_write_paths,
},
out,
indent = 4,
sort_keys = True
)
return 0
def do_process(path, manifest):
if os.path.exists(manifest):
os.remove(manifest)
ret = process_dir(path)
if ret != 0:
return ret
#output should be deterministic
empty_dirs.sort()
no_write_paths.sort()
ret = write_manifest(manifest)
if ret != 0:
return ret
return 0
def do_restore(path, manifest):
loaded = json.load(open(manifest, "r"))
empty_dirs = loaded["empty_dirs"]
no_write_paths = loaded["no_write_paths"]
for empty_dir in empty_dirs:
try:
os.makedirs(os.path.join(path, empty_dir))
except OSError:
#already exists
pass
for file_ in no_write_paths:
this_file = os.path.join(path, file_)
stat_result = os.lstat(this_file)
os.chmod(this_file,
stat_result.st_mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
return 0
if __name__ == '__main__':
import sys
if len(sys.argv) < 3 or len(sys.argv) > 4:
usage()
sys.exit(1)
verb = sys.argv[1]
path = sys.argv[2]
if len(sys.argv) >= 4:
manifest = sys.argv[3]
else:
manifest = os.path.join(path, DEFAULT_MANIFEST_NAME)
if verb == "process":
sys.exit(do_process(path, manifest))
if verb == "restore":
sys.exit(do_restore(path, manifest))
usage()
sys.exit(1)

View File

@ -0,0 +1,39 @@
From 5c5a18438870d10c31933061b2721477658931c9 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 3 Feb 2020 07:17:25 +0100
Subject: proton-tkg: initial vr support
diff --git a/proton b/proton
index 811de5e..028e7dd 100755
--- a/proton
+++ b/proton
@@ -481,6 +481,18 @@ class CompatData:
#create font files symlinks
self.create_fonts_symlinks()
+ #copy openvr files into place
+ dst = self.prefix_dir + "/drive_c/vrclient/bin/"
+ makedirs(dst)
+ try_copy(g_proton.lib_dir + "wine/fakedlls/vrclient.dll", dst)
+ try_copy(g_proton.lib64_dir + "wine/fakedlls/vrclient_x64.dll", dst)
+
+ try_copy(g_proton.lib_dir + "wine/dxvk/openvr_api_dxvk.dll", self.prefix_dir + "/drive_c/windows/syswow64/")
+ try_copy(g_proton.lib64_dir + "wine/dxvk/openvr_api_dxvk.dll", self.prefix_dir + "/drive_c/windows/system32/")
+
+ #makedirs(self.prefix_dir + "/drive_c/openxr/")
+ #try_copy(g_proton.default_pfx_dir + "drive_c/openxr/wineopenxr64.json", self.prefix_dir + "/drive_c/openxr/")
+
with open(self.tracked_files_file, "a") as tracked_files:
#copy steam files into place
steam_dir = "drive_c/Program Files (x86)/Steam/"
@@ -671,9 +671,6 @@ class Session:
if "noconhost" in self.compat_config:
self.dlloverrides["conhost.exe"] = "d"
- # Disable openvr lib as we don't support it
- self.dlloverrides["openvr_api_dxvk"] = "d"
-
s = ""
for dll in self.dlloverrides:
setting = self.dlloverrides[dll]

View File

@ -0,0 +1,18 @@
From 802436bbef59b1d5ff17a8fbd4d5fc0294cb3525 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Wed, 8 Apr 2020 05:33:48 +0200
Subject: vrclient: Get rid of wine/library.h dep
diff --git a/vrclient_x64/vrclient_x64/vrclient_main.c b/vrclient_x64/vrclient_x64/vrclient_main.c
index ea8e375..cf5888f 100644
--- a/vrclient_x64/vrclient_x64/vrclient_main.c
+++ b/vrclient_x64/vrclient_x64/vrclient_main.c
@@ -9,7 +9,6 @@
#include "winbase.h"
#include "winnls.h"
#include "wine/debug.h"
-#include "wine/library.h"
#include "vrclient_defs.h"
#include "vrclient_private.h"

View File

@ -0,0 +1,35 @@
From 802436bbef59b1d5ff17a8fbd4d5fc0294cb3525 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Wed, 8 Apr 2020 05:33:48 +0200
Subject: vrclient: Use standard dlopen() instead of the libwine wrappers
Following b87256cd1db21a59484248a193b6ad12ca2853ca
diff --git a/vrclient_x64/vrclient_x64/vrclient_main.c b/vrclient_x64/vrclient_x64/vrclient_main.c
index ea8e375..cf5888f 100644
--- a/vrclient_x64/vrclient_x64/vrclient_main.c
+++ b/vrclient_x64/vrclient_x64/vrclient_main.c
@@ -258,19 +257,19 @@ static int load_vrclient(void)
TRACE("got openvr runtime path: %s\n", pathU);
- vrclient_lib = wine_dlopen(pathU, RTLD_NOW, NULL, 0);
+ vrclient_lib = dlopen(pathU, RTLD_NOW);
if(!vrclient_lib){
TRACE("unable to load vrclient.so\n");
return 0;
}
- vrclient_HmdSystemFactory = wine_dlsym(vrclient_lib, "HmdSystemFactory", NULL, 0);
+ vrclient_HmdSystemFactory = dlsym(vrclient_lib, "HmdSystemFactory");
if(!vrclient_HmdSystemFactory){
ERR("unable to load HmdSystemFactory method\n");
return 0;
}
- vrclient_VRClientCoreFactory = wine_dlsym(vrclient_lib, "VRClientCoreFactory", NULL, 0);
+ vrclient_VRClientCoreFactory = dlsym(vrclient_lib, "VRClientCoreFactory");
if(!vrclient_VRClientCoreFactory){
ERR("unable to load VRClientCoreFactory method\n");
return 0;

View File

@ -0,0 +1,417 @@
# Created by: Tk-Glitch <ti3nou at gmail dot com>
pkgname=wine-tkg
pkgver=0
# workaround for pkgrel overwritten on regen
pkgrel=1
eval pkgrel=327
_stgsrcdir='wine-staging-git'
_esyncsrcdir='esync'
export _where="$PWD" # track basedir as different Arch based distros are moving srcdir around
_configure_args=() # additional args to ./configure will be added during prepare()
_makepkg_options=()
# load functions
source "$_where"/wine-tkg-scripts/prepare.sh
source "$_where"/wine-tkg-scripts/build.sh
exit_cleanup() {
_exit_cleanup
remove_deps || true
}
# init steps
if msg2; then # Arch chroot workaround for even more looping fun
_init
fi
if [ -z "$_localbuild" ]; then
_pkgnaming
fi
# custom plain wine commit to pass to git
if [ -n "$_plain_version" ]; then
if [ "$_use_staging" = "false" ] || ( [ "$_use_staging" = "true" ] && [ "$_staging_upstreamignore" = "true" ] ); then
_plain_commit="#commit=$_plain_version"
fi
fi
# custom staging commit to pass to git
if [ "$_use_staging" = "true" ] && [ -n "$_staging_version" ]; then
_staging_commit="#commit=$_staging_version"
fi
pkgdesc='This "Wine to rule them all" package is the result of some random pkgbuild found online. Looks safe to me, amirite? Some variants of it can be found in lutris runners.'
url='https://github.com/Tk-Glitch/PKGBUILDS/tree/master/wine-tkg-git'
arch=('x86_64')
_makepkg_options+=('!strip')
_makepkg_options+=('!ccache')
# Only pass the staticlibs option to system-wide installs
if [ "$_EXTERNAL_INSTALL" != "true" ]; then
_makepkg_options+=(staticlibs)
fi
if [ "$_NOCCACHE" != "true" ]; then
if msg2; then # Arch chroot workaround for even more looping fun
# Use ccache if available
if pacman -Qq ccache &> /dev/null; then
msg2 'ccache was found and will be used'
else
msg2 'ccache was not found and will not be used'
fi
fi
fi
options=(${_makepkg_options[@]} !lto)
license=('LGPL')
depends=(
'attr' 'lib32-attr'
'fontconfig' 'lib32-fontconfig'
'lcms2' 'lib32-lcms2'
'libxml2' 'lib32-libxml2'
'libxcursor' 'lib32-libxcursor'
'libxrandr' 'lib32-libxrandr'
'libxdamage' 'lib32-libxdamage'
'libxi' 'lib32-libxi'
'gettext' 'lib32-gettext'
'freetype2' 'lib32-freetype2'
'glu' 'lib32-glu'
'libsm' 'lib32-libsm'
'gcc-libs' 'lib32-gcc-libs'
'libpcap' 'lib32-libpcap'
'faudio' 'lib32-faudio'
'desktop-file-utils' 'jxrlib'
$_user_deps
)
makedepends=('git' 'autoconf' 'ncurses' 'bison' 'perl' 'fontforge' 'flex'
'gcc>=4.5.0-2' 'pkgconf'
'giflib' 'lib32-giflib'
'libpng' 'lib32-libpng'
'gnutls' 'lib32-gnutls'
'libxinerama' 'lib32-libxinerama'
'libxcomposite' 'lib32-libxcomposite'
'libxmu' 'lib32-libxmu'
'libxxf86vm' 'lib32-libxxf86vm'
'libldap' 'lib32-libldap'
'mpg123' 'lib32-mpg123'
'openal' 'lib32-openal'
'v4l-utils' 'lib32-v4l-utils'
'alsa-lib' 'lib32-alsa-lib'
'libxcomposite' 'lib32-libxcomposite'
'mesa' 'lib32-mesa'
'libgl' 'lib32-libgl'
'libxslt' 'lib32-libxslt'
'libpulse' 'lib32-libpulse'
'libva' 'lib32-libva'
'gtk3' 'lib32-gtk3'
'gst-plugins-base-libs' 'lib32-gst-plugins-base-libs'
'gst-plugins-good' 'lib32-gst-plugins-good'
'vulkan-icd-loader' 'lib32-vulkan-icd-loader'
'sdl2' 'lib32-sdl2'
'libcups' 'lib32-libcups'
'samba' 'opencl-headers'
'meson' 'ninja'
'glslang' 'wget'
'ocl-icd' 'lib32-ocl-icd'
'jack' 'lib32-jack'
$_user_makedeps
)
# mingw
if [ -z "${CUSTOM_MINGW_PATH}" ]; then
makedepends+=('mingw-w64-gcc')
fi
# proton-tkg deps
if [ -e "$_where"/proton_tkg_token ]; then
makedepends+=('fontforge' 'python-fonttools')
depends+=('tk')
fi
if [ "$_build_mediaconv" = "true" ]; then
depends+=('gst-plugins-ugly')
fi
# wine-mono deps
if [ "$_use_mono" = "true" ]; then
depends+=('wine-mono')
fi
optdepends=(
'giflib' 'lib32-giflib'
'libpng' 'lib32-libpng'
'libldap' 'lib32-libldap'
'gnutls' 'lib32-gnutls'
'mpg123' 'lib32-mpg123'
'openal' 'lib32-openal'
'v4l-utils' 'lib32-v4l-utils'
'libpulse' 'lib32-libpulse'
'alsa-plugins' 'lib32-alsa-plugins'
'alsa-lib' 'lib32-alsa-lib'
'libjpeg-turbo' 'lib32-libjpeg-turbo'
'libxcomposite' 'lib32-libxcomposite'
'libxinerama' 'lib32-libxinerama'
'ncurses' 'lib32-ncurses'
'libxslt' 'lib32-libxslt'
'libva' 'lib32-libva'
'gtk3' 'lib32-gtk3'
'gst-plugins-base-libs' 'lib32-gst-plugins-base-libs'
'vulkan-icd-loader' 'lib32-vulkan-icd-loader'
'sdl2' 'lib32-sdl2'
'cups' 'zapcc'
'samba' 'clang'
'dosbox' 'ccache'
'faudio' 'lib32-faudio'
'schedtool'
)
# Wine source
if [ -n "$_custom_wine_source" ]; then
_winesrcdir=$( sed 's|/|-|g' <<< $(sed 's|.*://.[^/]*/||g' <<< ${_custom_wine_source//./}))
if [[ "$_custom_wine_source" = https* ]]; then
_winesrctarget="git+$_custom_wine_source"
else
_winesrctarget="$_custom_wine_source"
fi
else
if [ "$_plain_mirrorsrc" = "true" ]; then
_winesrcdir="wine-mirror-git"
_winesrctarget="git+https://github.com/wine-mirror/wine.git"
else
_winesrcdir="wine-git"
_winesrctarget="git://source.winehq.org/git/wine.git"
fi
fi
if [ ! -e "$_where"/BIG_UGLY_FROGMINER ]; then
find "$_where"/wine-tkg-patches -type f '(' -iname '*patch' -or -iname '*.conf' ')' -not -path "*hotfixes*" -exec cp -n {} "$_where" \; && # copy patches inside the PKGBUILD's dir to preserve makepkg sourcing and md5sum checking
cp "$_where"/wine-tkg-userpatches/*.my* "$_where" 2>/dev/null # copy userpatches inside the PKGBUILD's dir
fi
# Handle unbranched bleeding version
if [[ "$_LOCAL_PRESET" = valve* ]] && [ -n "$_bleeding_tag" ]; then
_plain_commit="${_bleeding_tag}"
fi
source=("$_winesrcdir"::"${_winesrctarget}${_plain_commit}"
"$_stgsrcdir"::"git+https://github.com/wine-staging/wine-staging.git${_staging_commit}"
# misc
'30-win32-aliases.conf' # 32-bit font antialiasing
'wine-binfmt.conf' # Enables launching windows executables directly
)
md5sums=('SKIP'
'SKIP'
'1ff4e467f59409272088d92173a0f801'
'cff441678d798466a13a0d03b01e23d7'
)
if [ "$_EXTERNAL_INSTALL" = "true" ]; then
provides=(
"$pkgname=$pkgver"
)
conflicts=("$pkgname")
else
provides=(
"wine=$pkgver"
"wine-wow64=$pkgver"
"wine-staging=$pkgver"
"wine-esync=$pkgver"
)
conflicts=('wine' 'wine-wow64' 'wine-staging' 'wine-esync')
if [[ "$pkgname" == *-git ]]; then
replaces=("${pkgname/%-git/-faudio-git}")
fi
fi
if [ -n "$_localbuild" ]; then
_winesrcdir="$_localbuild"
_use_staging="false"
pkgname="$_localbuild"
if [ -n "$_PKGNAME_OVERRIDE" ]; then
if [ "$_PKGNAME_OVERRIDE" = "none" ]; then
pkgname="${pkgname}"
else
pkgname="${pkgname}-${_PKGNAME_OVERRIDE}"
fi
if msg2; then # Arch chroot workaround for even more looping fun
msg2 "Overriding default pkgname. New pkgname: ${pkgname}"
fi
fi
fi
makedepends=("${makedepends[@]}" "${depends[@]}")
nonuser_patcher() {
if [ "$_NUKR" != "debug" ] || [[ "$_DEBUGANSW1" =~ [yY] ]]; then
if [ "$_nopatchmsg" != "true" ]; then
_fullpatchmsg=" -- ( $_patchmsg )"
fi
msg2 "Applying ${_patchname}"
echo -e "\n${_patchname}${_fullpatchmsg}" >> "$_where"/prepare.log
patch -Np1 < ../"$_patchname" >> "$_where"/prepare.log || (error "Patch application has failed. The error was logged to $_where/prepare.log for your convenience." && exit 1)
echo -e "${_patchname}${_fullpatchmsg}" >> "$_where"/last_build_config.log
fi
}
pkgver() {
if [ "$_use_staging" = "true" ] && [[ "$_custom_wine_source" != *"ValveSoftware"* ]]; then
cd "${srcdir}/${_stgsrcdir}"
else
cd "${srcdir}/${_winesrcdir}"
fi
# retrieve current wine version - if staging is enabled, staging version will be used instead
_ismakepkg="true" _describe_wine
}
prepare() {
# Handle unbranched bleeding version
if [ "$_LOCAL_PRESET" = "valve-exp-bleeding" ]; then
(
cd "${srcdir}/${_winesrcdir}"
if [ -z "$_bleeding_tag" ]; then
_bleeding_tag=$(git tag -l --sort=-v:refname | grep "bleeding" | head -n 1)
echo "_bleeding_tag='$_bleeding_tag'" >> "$_where"/temp
fi
_bleeding_commit=$(git rev-list -n 1 "${_bleeding_tag}")
_plain_commit="${_bleeding_commit}"
git -c advice.detachedHead=false checkout "${_bleeding_commit}"
)
fi
if msg2; then # Arch chroot workaround for even more looping fun
# Remove gst-editing-services
if pacman -Qq gst-editing-services &> /dev/null; then
warning '! found gst-editing-services package, known to break wine prefix creation !'
read -rp " Uninstall it?"$'\n> N/y : ' _gst_editing_services;
if [[ "$_gst_editing_services" =~ [yY] ]]; then
sudo pacman -R gst-editing-services
fi
fi
fi
# Symlink legacy patches to srcdir
if [ "$_NUKR" != "debug" ] || [[ "$_DEBUGANSW1" =~ [yY] ]]; then
for _sympatch in "$_where"/*.patch; do
if [[ ! "${source[@]##*/}" =~ "${_sympatch##*/}" ]]; then
ln -s "$_sympatch" "$srcdir/"
fi
done
fi
# state tracker start - FEAR THE MIGHTY FROG MINER
touch "${_where}"/BIG_UGLY_FROGMINER
# prepare steps
if [ -z "$_localbuild" ]; then
_source_cleanup > "$_where"/prepare.log
_prepare
else
echo -e "Building local source $_localbuild" > "$_where"/prepare.log
fi
_polish
_makedirs
if [ "$_allow_server_rt_prio" = "true" ] || [ "$_allow_wine_net_raw" = "true" ]; then
if [ "$_EXTERNAL_INSTALL" = "true" ]; then
if [ "$_EXTERNAL_NOVER" = "true" ]; then
_serverpath="$_DEFAULT_EXTERNAL_PATH/$pkgname/bin/wineserver"
_preloaderpath="$_DEFAULT_EXTERNAL_PATH/$pkgname/bin/wine-preloader"
_preloader64path="$_DEFAULT_EXTERNAL_PATH/$pkgname/bin/wine64-preloader"
else
if [ "$_use_staging" = "true" ]; then
cd "$srcdir/$_stgsrcdir"
else
cd "$srcdir/$_winesrcdir"
fi
_realwineversion=$(_describe_wine)
_serverpath="$_DEFAULT_EXTERNAL_PATH/$pkgname-$_realwineversion/bin/wineserver"
_preloaderpath="$_DEFAULT_EXTERNAL_PATH/$pkgname-$_realwineversion/bin/wine-preloader"
_preloader64path="$_DEFAULT_EXTERNAL_PATH/$pkgname-$_realwineversion/bin/wine64-preloader"
fi
else
_serverpath="/usr/bin/wineserver"
_preloaderpath="/usr/bin/wine-preloader"
_preloader64path="/usr/bin/wine64-preloader"
fi
cp "$_where"/wine.install "$_where"/wine-tkg.install
sed -i "s|#echo \"Setting wineserver and/or wine-preloader capabilities\"|echo \"Setting wineserver and/or wine-preloader capabilities\"|g" "$_where"/wine-tkg.install
if [ "$_allow_server_rt_prio" = "true" ] && [ "$_allow_wine_net_raw" != "true" ]; then
sed -i "s|#setcap cap_net_raw+eip /usr/bin/wineserver 2>/dev/null|setcap cap_sys_nice+ep $_serverpath 2>/dev/null|g" "$_where"/wine-tkg.install
fi
if [ "$_allow_wine_net_raw" = "true" ] && [ "$_allow_server_rt_prio" != "true" ]; then
sed -i "s|#setcap cap_net_raw+eip /usr/bin/wineserver 2>/dev/null|setcap cap_net_raw+eip $_serverpath 2>/dev/null|g" "$_where"/wine-tkg.install
fi
if [ "$_allow_wine_net_raw" = "true" ] && [ "$_allow_server_rt_prio" = "true" ]; then
sed -i "s|#setcap cap_net_raw+eip /usr/bin/wineserver 2>/dev/null|setcap cap_sys_nice,cap_net_raw+eip $_serverpath 2>/dev/null|g" "$_where"/wine-tkg.install
fi
if [ "$_allow_wine_net_raw" = "true" ]; then
sed -i "s|#setcap cap_net_raw+eip /usr/bin/wine-preloader 2>/dev/null|setcap cap_net_raw+eip $_preloaderpath 2>/dev/null|g" "$_where"/wine-tkg.install
sed -i "s|#setcap cap_net_raw+eip /usr/bin/wine64-preloader 2>/dev/null|setcap cap_net_raw+eip $_preloader64path 2>/dev/null|g" "$_where"/wine-tkg.install
fi
fi
}
build() {
_prebuild_common
local _prefix=/usr
local _lib32name="lib32"
local _lib64name="lib"
# configure args
if [ -n "$_configure_userargs64" ]; then
_configure_args64+=($_configure_userargs64)
fi
if [ -n "$_configure_userargs32" ]; then
_configure_args32+=($_configure_userargs32)
fi
# External install
if [ "$_EXTERNAL_INSTALL" = "true" ]; then
_lib32name="lib" && _lib64name="lib64"
if [ "$_EXTERNAL_NOVER" = "true" ]; then
_prefix="$_DEFAULT_EXTERNAL_PATH/$pkgname"
else
if [ "$_use_staging" = "true" ]; then
cd "$srcdir/$_stgsrcdir"
else
cd "$srcdir/$_winesrcdir"
fi
_realwineversion=$(_describe_wine)
_prefix="$_DEFAULT_EXTERNAL_PATH/$pkgname-$_realwineversion"
fi
_configure_args64+=(--libdir="$_prefix/$_lib64name")
_configure_args32+=(--libdir="$_prefix/$_lib32name")
elif [ "$_EXTERNAL_INSTALL" = "proton" ]; then
_prefix="$_where"
_configure_args+=(--without-curses)
else
_configure_args64+=(--libdir="$_prefix/$_lib64name")
_configure_args32+=(--libdir="$_prefix/$_lib32name")
fi
if [ "$_SKIPBUILDING" != "true" ] && [ "$_NOCOMPILE" != "true" ]; then
_build
fi
}
package() {
if [ "$_allow_server_rt_prio" = "true" ]; then
install=wine-tkg.install
else
install=wine.install
fi
if [ "$_NOCOMPILE" != "true" ]; then
_package_makepkg
fi
}
trap exit_cleanup EXIT

View File

@ -0,0 +1,52 @@
# Wine to rule them all !
## PLEASE DO NOT REPORT BUGS ENCOUNTERED WITH THIS AT WINEHQ OR VALVESOFTWARE, REPORT HERE INSTEAD !
Wine-tkg is a build-system aiming at easier custom wine builds creation.
# Quick how-to :
(for dependencies, see the [wiki page](https://github.com/Tk-Glitch/PKGBUILDS/wiki/wine-tkg-git) )
**Independently of the distro used, you'll want MinGW compiler to build recent wine as it fails to build more often than not without it these days.**
## Download the source :
* Clone the repo (allows you to use `git pull` to get updates) :
```
git clone https://github.com/Frogging-Family/wine-tkg-git.git
```
## Configuration/customization :
If you want to customize the patches and features of your builds, you can find basic settings in [customization.cfg](https://github.com/Frogging-Family/wine-tkg-git/blob/master/wine-tkg-git/customization.cfg) and advanced settings in [wine-tkg-profiles/advanced-customization.cfg](https://github.com/Frogging-Family/wine-tkg-git/blob/master/wine-tkg-git/wine-tkg-profiles/advanced-customization.cfg).
You can also create an external configuration file that will contain all settings in a centralized way and survive repo updates. A sample file for this can be found [here](https://github.com/Frogging-Family/wine-tkg-git/blob/master/wine-tkg-git/wine-tkg-profiles/sample-external-config.cfg). The default path for this file is `~/.config/frogminer/wine-tkg.cfg` and can be changed in `wine-tkg-profiles/advanced-customization.cfg` with the `_EXT_CONFIG_PATH` option.
## Building :
* We need to get into the wine-tkg-git dir first:
```
cd wine-tkg-git
```
### For Arch (and other pacman/makepkg distros) :
* From the `wine-tkg-git` directory (where the PKGBUILD is located), run the following command in a terminal to start the building process :
```
makepkg -si
```
### For other distros (make sure to check the [wiki page](https://github.com/Tk-Glitch/PKGBUILDS/wiki/wine-tkg-git)) :
* From the `wine-tkg-git` directory (where the PKGBUILD is located), run the following command in a terminal to start the building process :
```
./non-makepkg-build.sh
```
**Your build will be found in the `PKGBUILD/wine-tkg-git/non-makepkg-builds` dir (independently of the chosen configuration)**
Note for Ubuntu users who want to use docker instead: https://github.com/Tk-Glitch/PKGBUILDS/issues/69#issuecomment-450548800 Thanks to @yuiiio

View File

@ -0,0 +1,180 @@
# 'Wine-to-rule-them-all' - Wine-TkG simple config file
##
## This config file contains the basic settings of your build.
## For deeper configuration, see wine-tkg-profiles/advanced-customization.cfg
##
#### NON-MAKEPKG OPTIONS (Won't affect makepkg builds) ####
# Set to the desired installation path for your build(s). A versioned dir containing your build will be created inside that target.
# Example: _nomakepkg_prefix_path="/home/frog" will install your build in /home/frog/wine-tkg-********
_nomakepkg_prefix_path=""
# Set to true to get a prompt after the 64-bit part is built, enabling package switching before building the 32-bit side.
# This is a workaround for distros shipping broken devel packages that can't coexist as multilib
_nomakepkg_midbuild_prompt="false"
# Set to the distro of your choice to attempt dependency resolution. Valid options are "debuntu" (for debian, ubuntu and similar), "fedora" or "archlinux".
_nomakepkg_dep_resolution_distro=""
#### EXTERNAL INSTALLATION SETTINGS - !! ONLY AFFECTS MAKEPKG !! ####
# Set to true to install into external path instead of /usr. This allows you to install multiple different versions in parallel.
# !!! Don't forget that you'll have to use /opt/wine-something/bin/wine instead of just wine (same for winecfg etc.) !!!
_EXTERNAL_INSTALL="false"
#### GENERATE DEBIAN PACKAGE ####
# Set to true if you want to generate a debian package after building. Currently doesn't work with _EXTERNAL_INSTALL option.
# This generates a debian package from build files ready to be packaged.
_GENERATE_DEBIAN_PACKAGE="false"
#### WINE FLAVOUR SETTINGS ####
# Override config with one of the presets from /wine-tkg-profiles dir - Leave empty to get a prompt (legacy profiles won't be listed)
# Set to "none" to silence the prompt
# Custom presets : "fo4", "legacy", "mwo", "sims2", "oldnvidia-sims3", "protonified", "unity".
# Valve presets : "valve" (builds against current valve proton tree), "valve-exp" (builds against current valve proton-experimental tree), "valve-exp-bleeding" (builds against current valve proton-experimental-bleeding-edge tree)
# Clean presets (untouched) : "mainline", "staging".
_LOCAL_PRESET=""
# Add GloriousEggroll game patches and hotfixes when using a Valve profile with staging enabled
# ! This will only affect Valve + staging trees !
# List of patches applied with this option enabled: assettocorsa-hud killer-instinct-winevulkan_fix FFVII-and-SpecialK-powerprof 65-proton-fake_current_res_patches unity_crash_hotfix Fix-regression-introduced-by-0e7fd41 15aa8c6-fix-star-citizen-bug-52956 0001-winex11.drv-Define-ControlMask-when-not-available 0002-include-Add-THREAD_POWER_THROTTLING_STATE-type 0003-ntdll-Fake-success-for-ThreadPowerThrottlingState
_use_GE_patches="true"
# plain wine commit or version tag if you want to use a specific wine version. Can use e.g. "64d9f30", "wine-3.16" or "wine-4.0"
# !!! Only affects non-staging builds (you want to edit the staging_version below for staging builds) !!!
# Leave empty to use latest master - https://github.com/wine-mirror/wine/commits/master
_plain_version=""
# staging
_use_staging="true"
# staging commit or version tag if you want to use a specific staging version. Can use e.g. "7cfceb7", "v3.16" or "v4.0"
# Leave empty to use latest master - https://github.com/wine-staging/wine-staging/commits/master
_staging_version=""
# fastsync - disable at runtime with WINE_DISABLE_FAST_SYNC=1 envvar - Set to true to enable winesync/fastsync support - https://repo.or.cz/wine/zf.git/shortlog/refs/heads/fastsync4
# !! on plain: Disables esync / fsync support !!
# !! on staging: Requires fsync support !!
_use_fastsync="false"
# esync - Enable with WINEESYNC=1 envvar - Set to true to enable esync support on plain wine or wine-staging <4.6 (it got merged in wine-staging 4.6). The option is ignored on wine-staging 4.6+
# You may need to raise your fd limits -> https://github.com/zfigura/wine/blob/esync/README.esync
_use_esync="true"
# fsync - Enable with WINEFSYNC=1 envvar - Set to true to enable fsync support, an experimental replacement for esync introduced with Proton 4.11-1 - Requires Wine Mainline 4.7.r168.g29914d583f / Staging 4.9.r7.g197e08b4 or newer
# https://steamcommunity.com/games/221410/announcements/detail/2957094910196249305
_use_fsync="true"
# futex_waitv() API for fsync - Requires 5.16 kernel or kernel with backported patches - https://github.com/ValveSoftware/wine/pull/128
# !! Replaces previous fsync interfaces support !!
_fsync_futex_waitv="true"
# vkd3dlib - We don't want to use vkd3d native library by default to allow for vkd3d-proton usage
# Set to "true" to enable explicit mainline vkd3d library support - default is "false"
_use_vkd3dlib="false"
# Set to false to add DXVK configuration support to Wine's DXGI, allowing for VKD3D to run while keeping DXVK dxgi functionalities.
# !! For DXVK to work properly with this option set to false, you'll need a DXVK build that comes with dxvk_config.dll !!
# Keep in mind Wine's dxgi can be more unstable and less compatible when used with DXVK.
_dxvk_dxgi="true"
#### GAME-SPECIFIC PATCHES ####
# Enable support for Proton's Battleye runtime - Depends on Battleye runtime
_proton_battleye_support="true"
# Enable support for Proton's EAC bridge - Depends on Easy Anti Cheat runtime
_proton_eac_support="true"
# Fix for Warframe Launcher failing to update itself - https://bugs.winehq.org/show_bug.cgi?id=33845 https://bugs.winehq.org/show_bug.cgi?id=45701
# https://www.winehq.org/pipermail/wine-devel/2018-October/133068.html - Merged in staging 8b930ae (4.6 devel)
# It made a comeback with 5.5 (5e218fe7)
_warframelauncher_fix="true"
# Mechwarrior Online fix - https://mwomercs.com/forums/topic/268847-running-the-game-on-ubuntu-steam-play/page__st__20__p__6195387#entry6195387
_mwo_fix="false"
# Resident Evil 4 hack - https://bugs.winehq.org/show_bug.cgi?id=46336
_re4_fix="false"
# Child window support for vk - Fixes World of Final Fantasy, CEMU vulkan renderer and others - https://bugs.winehq.org/show_bug.cgi?id=45277
_childwindow_fix="true"
# Shared gpu resources support:
# Shared texture resources for d3d9 and d3d11 - https://github.com/doitsujin/dxvk/pull/2516
# Requires DXVK 1.10.1+
# ID3D11Fence and ID3D12Fence sharing - https://github.com/doitsujin/dxvk/pull/2608 https://github.com/HansKristian-Work/vkd3d-proton/pull/1175
# Requires DXVK 1.10.3+, VKD3D-Proton 2.7+
_shared_gpu_resources="false"
# Fix for LoL 9.20+ crashing - Depends on _use_staging="true" - https://bugs.winehq.org/show_bug.cgi?id=47198 & https://bugs.winehq.org/show_bug.cgi?id=47915 - Requires vdso32 disabled (as root: `echo 0 > /proc/sys/abi/vsyscall32`)
# lol depends on the following staging patches :
# winebuild-Fake_Dlls, ntdll-RtlCreateUserThread, ntdll-NtContinue, ntdll-SystemExtendedProcessInformation, ntdll-SystemModuleInformation, ntdll-ThreadHideFromDebugger, wow64cpu-Wow64Transition, user32-InternalGetWindowIcon, ntdll-Pipe_SpecialCharacters, ntdll-NtDevicePath, ntdll-NtQueryVirtualMemory, fonts-Missing_Fonts, crypt32-CMS_Certificates, bcrypt-ECDHSecretAgreement, winex11-ime-check-thread-data
_lol920_fix="false"
# Fix for Assetto Corsa performance drop when HUD elements are displayed - https://bugs.winehq.org/show_bug.cgi?id=46955 - Create all kind of issues since b7b1ad0 (5.9 devel), so be careful with that.
_assettocorsa_hudperf_fix="false"
# Fixes for Mortal Kombat 11 - Requires staging, _proton_fs_hack="true", native mfplat (win7) or staging mfplat support and a different GPU driver than RADV
# On Wine 5.2 (up to b1c748c8) and lower, it needs to be toogled on with the WINE_LOW_USER_SPACE_LIMIT=1 envvar
_mk11_fix="true"
# Workaround for Final Fantasy XIV Launcher 404 error - Thanks @varris1 ! - Fixed by d535df42f665a097ec721b10fb49d7b18f899be9 (4.10)
# Found to also enable the new launcher (that came with the 5.1 update) to work *with issues*
_ffxivlauncher_fix="false"
# Background music on King of Fighters 98 and 2002 is silent on Wine-staging and the `xactengine-initial` patchset was found to introduce the issue. Set to "true" to disable it as a workaround.
_kof98_2002_BGM_fix="false"
# Fix for Quake Champions by Paul Gofman for Proton - Depends on _protonify="true" and _use_staging="true"
# This patchset breaks Genshin Impact
_quake_champions_fix="false"
#### OTHER PATCHES ####
# launch with dedicated gpu desktop entry patch - makes an additional desktop entry which launches app with DRI_PRIME set to 1 (only for switchable graphics with mesa drivers)
_launch_with_dedicated_gpu="false"
# Update winevulkan to whatever version I have pushed last, til next time, for new shiny and tasty vk extensions support. Thanks dadドイツ人 !
_update_winevulkan="false"
# Joshua Ashton's take on making wine dialogs and menus less win95-ish - https://github.com/Joshua-Ashton/wine/tree/wine-better-theme
_use_josh_flat_theme="true"
#### PROTON PATCHES ####
# Bypass compositor in fullscreen modes - Typically reduces stuttering and improves performance - https://github.com/ValveSoftware/wine/commit/141ba5cf73029029a5a0bd2cdcfd5f9f9ab7ee7b
_FS_bypass_compositor="false"
# Proton Fullscreen patch - Requires 3.16+ for staging and 5.0+ for mainline - Allows resolution changes for fullscreen games without changing desktop resolution
# You can optionally use nearest neighbour upscaling with the WINE_FULLSCREEN_INTEGER_SCALING envvar
_proton_fs_hack="false"
# Proton compatible rawinput patchset - Only effective when _proton_fs_hack is set to "true" - Requires a tree containing 6d7828e8df68178ca662bc618f7598254afcfbe1 (4.20+)
_proton_rawinput="true"
# Enforce mscvrt Dlls to native then builtin - from Proton
_msvcrt_nativebuiltin="false"
# Set the default wine version to win10 (instead of win7) - Necessary to enable d3d12 (for use with vkd3d) in some games
_win10_default="false"
# Other misc proton patches and hacks - Notably contains fixes for some native vk games (such as Doom Eternal) as well as Rockstar launcher
# Also enables some winevulkan performance optimizations - https://github.com/Joshua-Ashton/proton-wine/tree/winevulkan-opt (fs hack) - https://github.com/Joshua-Ashton/wine/commits/winevulkan-opt-mainline (no fs hack)
_protonify="false"
#### USER PATCHES - See README in ./wine-tkg-userpatches dir for instructions ####
# community patches - add patches (separated by a space) of your choice by name from the community-patches dir - https://github.com/Frogging-Family/community-patches
# example: _community_patches="amdags.mypatch GNUTLShack.mypatch"
_community_patches=""
# Automatically update community-patches from git - set to false if you don't want this behaviour, useful for example if you have your own fork.
_community_patches_auto_update="true"

View File

@ -0,0 +1,306 @@
#!/bin/bash
# Created by: Tk-Glitch <ti3nou at gmail dot com>
# This script replaces the wine-tkg PKGBUILD's function for use outside of makepkg or on non-pacman distros
## You can check for missing dependencies by running this script with either `--deps64` argument for 64-bit dependencies or `--deps32` argument for 32-bit dependencies :
# ./non-makepkg-build.sh --deps64
# ./non-makepkg-build.sh --deps32
## On a stock Ubuntu 19.04 install, you'll need the following deps as bare minimum to build default wine-tkg (without Faudio/winevulkan):
# pkg-config (or pkgconf) bison flex schedtool libfreetype6-dev xserver-xorg-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
# For 32-bit support : gcc-multilib g++-multilib libfreetype6-dev:i386 xserver-xorg-dev:i386 libgstreamer1.0-dev:i386 libgstreamer-plugins-base1.0-dev:i386
## For proton-tkg, the 32-bit dependencies above are required as well as the following additions:
# curl fontforge fonttools libsdl2-dev python3-tk
# !!! _sdl_joy_support="true" (default setting) would require libsdl2-dev:i386 but due to a conflict between libsdl2-dev:i386 and libmirclientcpp-dev (at least on 19.04) you're kinda frogged and should set _sdl_joy_support to "false" to build successfully. You'll lose SDL2 support on 32-bit apps !!!
## You're on your own to resolve additional dependencies you might want to build with, such as Faudio.
pkgname=wine-tkg
_build_in_tmpfs="true"
_stgsrcdir='wine-staging-git'
_esyncsrcdir='esync'
_where="$PWD" # track basedir as different Arch based distros are moving srcdir around
# set srcdir, Arch style
if [ "$_build_in_tmpfs" = "true" ]; then
rm -rf "$_where"/src
mkdir -p /tmp/wine-tkg/src
ln -s /tmp/wine-tkg/src "$_where"
else
mkdir -p "$_where"/src
fi
srcdir="$_where"/src
# use msg2, error and pkgver funcs for compat
msg2() {
echo -e " \033[1;34m->\033[1;0m \033[1;1m$1\033[1;0m" >&2
}
error() {
echo -e " \033[1;31m==> ERROR: $1\033[1;0m" >&2
}
warning() {
echo -e " \033[1;33m==> WARNING: $1\033[1;0m" >&2
}
pkgver() {
if [ -d "${srcdir}/${_winesrcdir}" ]; then
if [ "$_use_staging" = "true" ] && [ -d "${srcdir}/${_stgsrcdir}" ] && [[ "$_custom_wine_source" != *"ValveSoftware"* ]]; then
cd "${srcdir}/${_stgsrcdir}"
else
cd "${srcdir}/${_winesrcdir}"
fi
# retrieve current wine version - if staging is enabled, staging version will be used instead
_describe_wine
fi
}
# The dependency "helper" (running configure) doesn't have to go through the initial prompt, so skip it
if [ "$1" = "--deps64" ] || [ "$1" = "--deps32" ]; then
_DEPSHELPER=1
fi
# load functions
source "$_where"/wine-tkg-scripts/prepare.sh
source "$_where"/wine-tkg-scripts/build.sh
msg2 "Non-makepkg build script will be used.\n"
# init step
_init
# deps
if [ -n "$_nomakepkg_dep_resolution_distro" ]; then
source "$_where"/wine-tkg-scripts/deps
if [ "$_nomakepkg_dep_resolution_distro" = "debuntu" ]; then
_debuntu_64
elif [ "$_nomakepkg_dep_resolution_distro" = "fedora" ]; then
_fedora_6432
elif [ "$_nomakepkg_dep_resolution_distro" = "archlinux" ]; then
_archlinux_6432
fi
fi
# this script makes external builds already and we don't want the specific pacman-related stuff to interfere, so enforce _EXTERNAL_INSTALL="false" when not building proton-tkg
if [ "$_EXTERNAL_INSTALL" = "true" ]; then
_EXTERNAL_INSTALL="false"
fi
# disable faudio check so we don't fail to build even if faudio libs are missing
_faudio_ignorecheck="true"
if [ -z "$_localbuild" ]; then
_pkgnaming
fi
# remove the faudio pkgname tag as we can't be sure it'll get used even if enabled
pkgname="${pkgname/-faudio-git/}"
# init step end
_nomakepkgsrcinit() {
# Wine source
if [ -n "$_custom_wine_source" ]; then
_winesrcdir=$( sed 's|/|-|g' <<< $(sed 's|.*://.[^/]*/||g' <<< ${_custom_wine_source//./}))
_winesrctarget="$_custom_wine_source"
else
if [ "$_plain_mirrorsrc" = "true" ]; then
_winesrcdir="wine-mirror-git"
_winesrctarget="https://github.com/wine-mirror/wine.git"
else
_winesrcdir="wine-git"
_winesrctarget="git://source.winehq.org/git/wine.git"
fi
fi
if [ "$_NUKR" != "debug" ]; then
$( find "$_where"/wine-tkg-patches -type f '(' -iname '*patch' -or -iname '*.conf' ')' -not -path "*hotfixes*" -exec cp -n {} "$_where" \; ) # copy patches inside the PKGBUILD's dir to preserve makepkg sourcing and md5sum checking
$( find "$_where"/wine-tkg-userpatches -type f -name "*.my*" -exec cp -n {} "$_where" \; ) # copy userpatches inside the PKGBUILD's dir
## Handle git repos similarly to makepkg to preserve repositories when building both with and without makepkg on Arch
# Wine source
cd "$_where"
git clone --mirror "${_winesrctarget}" "$_winesrcdir" || true
# Wine staging source
git clone --mirror https://github.com/wine-staging/wine-staging.git "$_stgsrcdir" || true
pushd "$srcdir" &>/dev/null
# Wine staging update and checkout
cd "$_where"/"${_stgsrcdir}"
if [[ "https://github.com/wine-staging/wine-staging.git" != "$(git config --get remote.origin.url)" ]] ; then
echo "${_stgsrcdir} is not a clone of ${_stgsrcdir}. Please delete ${_winesrcdir} and src dirs and try again."
exit 1
fi
git fetch --all -p
rm -rf "${srcdir}/${_stgsrcdir}" && git clone "$_where"/"${_stgsrcdir}" "${srcdir}/${_stgsrcdir}"
cd "${srcdir}"/"${_stgsrcdir}"
git -c advice.detachedHead=false checkout --force --no-track -B makepkg origin/HEAD
if [ -n "$_staging_version" ] && [ "$_use_staging" = "true" ]; then
git -c advice.detachedHead=false checkout "${_staging_version}"
fi
# Wine update and checkout
cd "$_where"/"${_winesrcdir}"
if [[ "${_winesrctarget}" != "$(git config --get remote.origin.url)" ]] ; then
echo "${_winesrcdir} is not a clone of ${_winesrcdir}. Please delete ${_winesrcdir} and src dirs and try again."
exit 1
fi
git fetch --all -p
rm -rf "${srcdir}/${_winesrcdir}" && git clone "$_where"/"${_winesrcdir}" "${srcdir}/${_winesrcdir}"
cd "${srcdir}"/"${_winesrcdir}"
git -c advice.detachedHead=false checkout --force --no-track -B makepkg origin/HEAD
if [ -n "$_plain_version" ] && [ "$_use_staging" != "true" ] || [ "$_LOCAL_PRESET" = "valve-exp-bleeding" ]; then
git -c advice.detachedHead=false checkout "${_plain_version}"
if [ "$_LOCAL_PRESET" = "valve-exp-bleeding" ]; then
if [ -z "$_bleeding_tag" ]; then
_bleeding_tag=$(git tag -l --sort=-v:refname | grep "bleeding" | head -n 1)
fi
echo -e "Bleeding edge tag: ${_bleeding_tag}" >> "$_where"/prepare.log
_bleeding_commit=$(git rev-list -n 1 "${_bleeding_tag}")
echo -e "Bleeding edge commit: ${_bleeding_commit}" >> "$_where"/prepare.log
git -c advice.detachedHead=false checkout "${_bleeding_tag}"
fi
fi
popd &>/dev/null
fi
}
nonuser_patcher() {
if [ "$_NUKR" != "debug" ] || [[ "$_DEBUGANSW1" =~ [yY] ]]; then
if [ "$_nopatchmsg" != "true" ]; then
_fullpatchmsg=" -- ( $_patchmsg )"
fi
msg2 "Applying ${_patchname}"
echo -e "\n${_patchname}${_fullpatchmsg}" >> "$_where"/prepare.log
patch -Np1 < "$_where"/"$_patchname" >> "$_where"/prepare.log || (error "Patch application has failed. The error was logged to $_where/prepare.log for your convenience." && exit 1)
echo -e "${_patchname}${_fullpatchmsg}" >> "$_where"/last_build_config.log
fi
}
build_wine_tkg() {
set -e
## prepare step
cd "$srcdir"
# state tracker start - FEAR THE MIGHTY FROG MINER
touch "${_where}"/BIG_UGLY_FROGMINER
if [ "$_SKIPBUILDING" != "true" ]; then
msg2 "Cloning and preparing sources... Please be patient."
if [ -z "$_localbuild" ]; then
_nomakepkgsrcinit > "$_where"/prepare.log 2>&1
_source_cleanup >> "$_where"/prepare.log
_prepare
else
_winesrcdir="$_localbuild"
_use_staging="false"
pkgname="$_localbuild"
echo -e "Building local source $_localbuild" > "$_where"/prepare.log
if [ -n "$_PKGNAME_OVERRIDE" ]; then
if [ "$_PKGNAME_OVERRIDE" = "none" ]; then
pkgname="${pkgname}"
else
pkgname="${pkgname}-${_PKGNAME_OVERRIDE}"
fi
msg2 "Overriding default pkgname. New pkgname: ${pkgname}"
fi
fi
## prepare step end
fi
pkgver=$(pkgver)
_polish
_makedirs
_prebuild_common
if [ "$_nomakepkg_nover" = "true" ] ; then
_nomakepkg_pkgname="${pkgname}"
else
_nomakepkg_pkgname="${pkgname}-${pkgver}"
fi
if [ -z "$_nomakepkg_prefix_path" ]; then
local _prefix="$_where/${_nomakepkg_pkgname}"
else
local _prefix="${_nomakepkg_prefix_path}/${_nomakepkg_pkgname}"
fi
if [ -e /lib ] && [ -e /lib64 ] && [ -d /usr/lib ] && [ -d /usr/lib32 ] && [ "$_EXTERNAL_INSTALL" != "proton" ]; then
local _lib32name="lib32"
local _lib64name="lib"
else
local _lib32name="lib"
local _lib64name="lib64"
fi
# configure args
if [ -n "$_configure_userargs64" ]; then
_configure_args64+=($_configure_userargs64)
fi
if [ -n "$_configure_userargs32" ]; then
_configure_args32+=($_configure_userargs32)
fi
# External install
if [ "$_EXTERNAL_INSTALL" = "true" ]; then
if [ "$_EXTERNAL_NOVER" = "true" ]; then
_prefix="$_DEFAULT_EXTERNAL_PATH/$pkgname"
else
if [ "$_use_staging" = "true" ]; then
cd "$srcdir/$_stgsrcdir"
else
cd "$srcdir/$_winesrcdir"
fi
_realwineversion=$(_describe_wine)
_prefix="$_DEFAULT_EXTERNAL_PATH/$pkgname-$_realwineversion"
fi
else
_configure_args64+=(--libdir="$_prefix/$_lib64name")
_configure_args32+=(--libdir="$_prefix/$_lib32name")
fi
if [ "$_SKIPBUILDING" != "true" ] && [ "$_NOCOMPILE" != "true" ]; then
_build
fi
if [ "$_NOCOMPILE" != "true" ]; then
_package_nomakepkg
fi
}
if [ "$1" = "--deps64" ]; then
_nomakepkgsrcinit
cd "${srcdir}"/"${_winesrcdir}"
./configure --enable-win64
msg2 "You might find help regarding dependencies here: https://github.com/Tk-Glitch/PKGBUILDS/wiki/wine-tkg-git#dependencies"
elif [ "$1" = "--deps32" ]; then
_nomakepkgsrcinit
cd "${srcdir}"/"${_winesrcdir}"
./configure
msg2 "You might find help regarding dependencies here: https://github.com/Tk-Glitch/PKGBUILDS/wiki/wine-tkg-git#dependencies"
else
# If $1 contains a path, and it exists, use it as default for config
if [ -n "$1" ]; then
_EXT_CONFIG_PATH="$(readlink -m $1)"
if [ ! -f "$_EXT_CONFIG_PATH" ]; then
echo "User-supplied external config file '${_EXT_CONFIG_PATH}' not found! Please fix your passed path!"
exit 0
fi
sed -i -e "s|_EXT_CONFIG_PATH.*|_EXT_CONFIG_PATH=${_EXT_CONFIG_PATH}|" "$_where"/wine-tkg-profiles/advanced-customization.cfg
fi
build_wine_tkg
fi
trap _exit_cleanup EXIT

View File

@ -0,0 +1,10 @@
#!/bin/bash
# Fix for Assetto Corsa performance drop when HUD elements are displayed - https://bugs.winehq.org/show_bug.cgi?id=46955
if [ "$_assettocorsa_hudperf_fix" = "true" ] && git merge-base --is-ancestor d19e34d8f072514cb903bda89767996ba078bae4 HEAD; then
if [ "$_EXTERNAL_INSTALL" = "proton" ] && [ "$_unfrog" != "true" ]; then
_patchname='assettocorsa_hud_perf-proton.patch' && _patchmsg="Applied Assetto Corsa HUD performance fix (proton edition)" && nonuser_patcher
else
_patchname='assettocorsa_hud_perf.patch' && _patchmsg="Applied Assetto Corsa HUD performance fix" && nonuser_patcher
fi
fi

View File

@ -0,0 +1,26 @@
From 488290d912e4c40f159249f0df2f994355fab398 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 1 Jul 2019 05:05:56 +0200
Subject: dwrite: Don't release file streams when building collections. Fixes
Assetto Corsa performance drop when HUD elements are displayed. This
effectively reverts d19e34d8f072514cb903bda89767996ba078bae4
Signed-off-by: Tk-Glitch <ti3nou@gmail.com>
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 5f4abc7ee6..69413cdde5 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -4348,7 +4348,11 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat
break;
}
- IDWriteFontFileStream_Release(stream);
+ const char *sgi = getenv("SteamGameId");
+
+ if ((!sgi) | (sgi && strcmp(sgi, "244210"))) {
+ IDWriteFontFileStream_Release(stream);
+ }
}
LIST_FOR_EACH_ENTRY_SAFE(fileenum, fileenum2, &scannedfiles, struct fontfile_enum, entry) {

View File

@ -0,0 +1,22 @@
From 488290d912e4c40f159249f0df2f994355fab398 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 1 Jul 2019 05:05:56 +0200
Subject: dwrite: Don't release file streams when building collections. Fixes
Assetto Corsa performance drop when HUD elements are displayed. This
effectively reverts d19e34d8f072514cb903bda89767996ba078bae4
Signed-off-by: Tk-Glitch <ti3nou@gmail.com>
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 5f4abc7ee6..69413cdde5 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -3900,8 +3900,6 @@ HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerat
if (FAILED(hr))
break;
}
-
- IDWriteFontFileStream_Release(stream);
}
LIST_FOR_EACH_ENTRY_SAFE(fileenum, fileenum2, &scannedfiles, struct fontfile_enum, entry) {

View File

@ -0,0 +1,20 @@
#!/bin/bash
# Workaround for F4SE/SkyrimSE Script Extender
# https://github.com/hdmap/wine-hackery/tree/master/f4se
if [ "$_f4skyrimse_fix" = "true" ]; then
if ! git merge-base --is-ancestor 12be24af8cab0e5f78795b164ec8847bafc30852 HEAD; then
_patchname='f4skyrimse-fix-1.patch' && _patchmsg="Applied F4/SkyrimSE Script Extender fix (1)" && nonuser_patcher
fi
if ! git merge-base --is-ancestor 1aa963efd7c7c7f91423f5edb9811f6ff95c06c0 HEAD; then
if git merge-base --is-ancestor 4c750a35c3c087d1fa9b0882fb0bdd6804296473 HEAD; then
_patchname='f4skyrimse-fix-2.patch' && _patchmsg="Applied F4/SkyrimSE Script Extender fix (2)" && nonuser_patcher
elif git merge-base --is-ancestor be48a56e700d47f2221d983a37ef70228508c11b HEAD; then
_patchname='f4skyrimse-fix-2-4c750a3.patch' && _patchmsg="Applied F4/SkyrimSE Script Extender fix (2)" && nonuser_patcher
elif git merge-base --is-ancestor 00451d5edf9a13fd8f414a0d06869e38cf66b754 HEAD; then
_patchname='f4skyrimse-fix-2-be48a56.patch' && _patchmsg="Applied F4/SkyrimSE Script Extender fix (2)" && nonuser_patcher
else
_patchname='f4skyrimse-fix-2-00451d5.patch' && _patchmsg="Applied F4/SkyrimSE Script Extender fix (2)" && nonuser_patcher
fi
fi
fi

View File

@ -0,0 +1,20 @@
This is one of two patches to get Fallout 4 Script Extender working in wine. f4se allocates memory for trampolines in the spaces before the Fallout4 exe image and the f4se dll image. This patch:
Fix VirtualQuery rejecting any blocks before the image as already allocated (it looks like get_free_mem_state_callback sees blocks before the exe base address as overlapping the exe base from calculating the block end address as block start address + size, ie a 256 byte block starting at 0x100 would "end" at 0x200).
Apparently it also get SkyrimSE script extender working, but I don't own that so I can't test that.
https://github.com/hdmap/wine-hackery
--- a/dlls/ntdll/virtual.c 2018-05-15 12:07:53.839882299 -0400
+++ a/dlls/ntdll/virtual.c 2018-05-15 14:51:22.632513314 -0400
@@ -2750,7 +2753,7 @@ static int get_free_mem_state_callback(
MEMORY_BASIC_INFORMATION *info = arg;
void *end = (char *)start + size;
- if ((char *)info->BaseAddress + info->RegionSize < (char *)start) return 0;
+ if ((char *)info->BaseAddress + info->RegionSize <= (char *)start) return 0;
if (info->BaseAddress >= end)
{

View File

@ -0,0 +1,23 @@
This is one of two patches to get Fallout 4 Script Extender working in wine. f4se allocates memory for trampolines in the spaces before the Fallout4 exe image and the f4se dll image. This patch:
Switches dlls not loaded at their preferred address to be loaded at high addresses rather than low ones to work around code in f4se that gives up allocating the trampolines (it compares the address being queried to a lowest acceptable address computed by subtracting 0x78000000 from the module address, which will wrap around and fail with lower addresses even if there's free space).
Apparently it also get SkyrimSE script extender working, but I don't own that so I can't test that.
https://github.com/hdmap/wine-hackery
--- a/dlls/ntdll/virtual.c 2018-05-15 12:07:53.839882299 -0400
+++ a/dlls/ntdll/virtual.c 2018-05-16 16:29:00.753042766 -0400
@@ -1387,11 +1387,11 @@ static NTSTATUS map_image( HANDLE hmappi
server_enter_uninterrupted_section( &csVirtual, &sigset );
if (base >= (char *)address_space_start) /* make sure the DOS area remains free */
- status = map_view( &view, base, total_size, mask, FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, base, total_size, mask, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY );
if (status != STATUS_SUCCESS)
- status = map_view( &view, NULL, total_size, mask, FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, NULL, total_size, mask, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY );

View File

@ -0,0 +1,23 @@
This is one of two patches to get Fallout 4 Script Extender working in wine. f4se allocates memory for trampolines in the spaces before the Fallout4 exe image and the f4se dll image. This patch:
Switches dlls not loaded at their preferred address to be loaded at high addresses rather than low ones to work around code in f4se that gives up allocating the trampolines (it compares the address being queried to a lowest acceptable address computed by subtracting 0x78000000 from the module address, which will wrap around and fail with lower addresses even if there's free space).
Apparently it also get SkyrimSE script extender working, but I don't own that so I can't test that.
https://github.com/hdmap/wine-hackery
--- a/dlls/ntdll/virtual.c 2018-05-15 12:07:53.839882299 -0400
+++ a/dlls/ntdll/virtual.c 2018-05-16 16:29:00.753042766 -0400
@@ -1387,11 +1387,11 @@ static NTSTATUS map_image( HANDLE hmappi
server_enter_uninterrupted_section( &csVirtual, &sigset );
if (base >= (char *)address_space_start) /* make sure the DOS area remains free */
- status = map_view( &view, base, total_size, get_mask( 0 ), FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, base, total_size, get_mask( 0 ), TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, zero_bits );
if (status != STATUS_SUCCESS)
- status = map_view( &view, NULL, total_size, get_mask( 0 ), FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, NULL, total_size, get_mask( 0 ), TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, zero_bits );

View File

@ -0,0 +1,23 @@
This is one of two patches to get Fallout 4 Script Extender working in wine. f4se allocates memory for trampolines in the spaces before the Fallout4 exe image and the f4se dll image. This patch:
Switches dlls not loaded at their preferred address to be loaded at high addresses rather than low ones to work around code in f4se that gives up allocating the trampolines (it compares the address being queried to a lowest acceptable address computed by subtracting 0x78000000 from the module address, which will wrap around and fail with lower addresses even if there's free space).
Apparently it also get SkyrimSE script extender working, but I don't own that so I can't test that.
https://github.com/hdmap/wine-hackery
--- a/dlls/ntdll/virtual.c 2018-05-15 12:07:53.839882299 -0400
+++ a/dlls/ntdll/virtual.c 2018-05-16 16:29:00.753042766 -0400
@@ -1387,11 +1387,11 @@ static NTSTATUS map_image( HANDLE hmappi
server_enter_uninterrupted_section( &csVirtual, &sigset );
if (base >= (char *)address_space_start) /* make sure the DOS area remains free */
- status = map_view( &view, base, total_size, mask, FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, base, total_size, mask, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, 0 );
if (status != STATUS_SUCCESS)
- status = map_view( &view, NULL, total_size, mask, FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, NULL, total_size, mask, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, 0 );

View File

@ -0,0 +1,23 @@
This is one of two patches to get Fallout 4 Script Extender working in wine. f4se allocates memory for trampolines in the spaces before the Fallout4 exe image and the f4se dll image. This patch:
Switches dlls not loaded at their preferred address to be loaded at high addresses rather than low ones to work around code in f4se that gives up allocating the trampolines (it compares the address being queried to a lowest acceptable address computed by subtracting 0x78000000 from the module address, which will wrap around and fail with lower addresses even if there's free space).
Apparently it also get SkyrimSE script extender working, but I don't own that so I can't test that.
https://github.com/hdmap/wine-hackery
--- a/dlls/ntdll/virtual.c 2018-05-15 12:07:53.839882299 -0400
+++ a/dlls/ntdll/virtual.c 2018-05-16 16:29:00.753042766 -0400
@@ -1387,11 +1387,11 @@ static NTSTATUS map_image( HANDLE hmappi
server_enter_uninterrupted_section( &csVirtual, &sigset );
if (base >= (char *)address_space_start) /* make sure the DOS area remains free */
- status = map_view( &view, base, total_size, 0, FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, base, total_size, 0, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, zero_bits );
if (status != STATUS_SUCCESS)
- status = map_view( &view, NULL, total_size, 0, FALSE, SEC_IMAGE | SEC_FILE |
+ status = map_view( &view, NULL, total_size, 0, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, zero_bits );

View File

@ -0,0 +1,14 @@
#!/bin/bash
# Workaround for Final Fantasy XIV Launcher 404 error - Thanks @varris1 ! - Fixed by d535df42f665a097ec721b10fb49d7b18f899be9 (4.10)
if [ "$_ffxivlauncher_fix" = "true" ]; then
if ( cd "${srcdir}"/"${_winesrcdir}" && git merge-base --is-ancestor 9bf46d5ce608a97e264681d2637ff3105e42c363 HEAD ); then
_patchname='ffxiv-launcher-workaround.patch' && _patchmsg="Applied Final Fantasy XIV Launcher fix" && nonuser_patcher
elif ( cd "${srcdir}"/"${_winesrcdir}" && git merge-base --is-ancestor 0c249e6125fc9dc6ee86b4ef6ae0d9fa2fc6291b HEAD ); then
_patchname='ffxiv-launcher-workaround-9bf46d5.patch' && _patchmsg="Applied Final Fantasy XIV Launcher fix" && nonuser_patcher
elif ( cd "${srcdir}"/"${_stgsrcdir}" && git merge-base --is-ancestor 4e6a477acd32651dd571205786132666505aeb5b HEAD ); then
_patchname='ffxiv-launcher-workaround-0c249e6.patch' && _patchmsg="Applied Final Fantasy XIV Launcher fix" && nonuser_patcher
else
_patchname='ffxiv-launcher-workaround-4e6a477.patch' && _patchmsg="Applied Final Fantasy XIV Launcher fix" && nonuser_patcher
fi
fi

View File

@ -0,0 +1,23 @@
diff -urN a/dlls/ntdll/misc.c a/dlls/ntdll/misc.c
--- a/dlls/ntdll/misc.c 2019-04-13 03:10:12 +0900
+++ a/dlls/ntdll/misc.c 2019-04-24 19:10:44 +0900
@@ -524,3 +524,10 @@
*present = TRUE;
return TRUE;
}
+
+BOOL IsTransgaming(void)
+{
+ static int call_count = -1;
+ call_count++;
+ return call_count == 1;
+}
diff -urN a/dlls/ntdll/ntdll.spec a/dlls/ntdll/ntdll.spec
--- a/dlls/ntdll/ntdll.spec 2019-04-24 18:23:50 +0900
+++ a/dlls/ntdll/ntdll.spec 2019-04-24 18:48:37 +0900
@@ -1630,3 +1631,5 @@
# Filesystem
@ stdcall -syscall wine_nt_to_unix_file_name(ptr ptr ptr long)
@ stdcall -syscall wine_unix_to_nt_file_name(str ptr ptr)
+
+@ cdecl IsTransgaming()

View File

@ -0,0 +1,26 @@
diff -urN a/dlls/ntdll/misc.c a/dlls/ntdll/misc.c
--- a/dlls/ntdll/misc.c 2019-04-13 03:10:12 +0900
+++ a/dlls/ntdll/misc.c 2019-04-24 19:10:44 +0900
@@ -524,3 +524,10 @@
*present = TRUE;
return TRUE;
}
+
+BOOL IsTransgaming(void)
+{
+ static int call_count = -1;
+ call_count++;
+ return call_count == 1;
+}
diff -urN a/dlls/ntdll/ntdll.spec a/dlls/ntdll/ntdll.spec
--- a/dlls/ntdll/ntdll.spec 2019-04-24 18:23:50 +0900
+++ a/dlls/ntdll/ntdll.spec 2019-04-24 18:48:37 +0900
@@ -1537,6 +1537,8 @@
# signal handling
@ cdecl __wine_set_signal_handler(long ptr)
+
+@ cdecl IsTransgaming()
# Filesystem
@ cdecl wine_nt_to_unix_file_name(ptr ptr long long)

View File

@ -0,0 +1,23 @@
diff -urN a/dlls/ntdll/misc.c a/dlls/ntdll/misc.c
--- a/dlls/ntdll/misc.c 2019-04-13 03:10:12 +0900
+++ a/dlls/ntdll/misc.c 2019-04-24 19:10:44 +0900
@@ -524,3 +524,10 @@
*present = TRUE;
return TRUE;
}
+
+BOOL IsTransgaming(void)
+{
+ static int call_count = -1;
+ call_count++;
+ return call_count == 1;
+}
diff -urN a/dlls/ntdll/ntdll.spec a/dlls/ntdll/ntdll.spec
--- a/dlls/ntdll/ntdll.spec 2019-04-24 18:23:50 +0900
+++ a/dlls/ntdll/ntdll.spec 2019-04-24 18:48:37 +0900
@@ -1537,3 +1537,5 @@
# User shared data
@ cdecl __wine_user_shared_data()
+
+@ cdecl IsTransgaming()

View File

@ -0,0 +1,23 @@
diff -urN a/dlls/ntdll/misc.c a/dlls/ntdll/misc.c
--- a/dlls/ntdll/misc.c 2019-04-13 03:10:12 +0900
+++ a/dlls/ntdll/misc.c 2019-04-24 19:10:44 +0900
@@ -524,3 +524,10 @@
*present = TRUE;
return TRUE;
}
+
+BOOL IsTransgaming(void)
+{
+ static int call_count = -1;
+ call_count++;
+ return call_count == 1;
+}
diff -urN a/dlls/ntdll/ntdll.spec a/dlls/ntdll/ntdll.spec
--- a/dlls/ntdll/ntdll.spec 2019-04-24 18:23:50 +0900
+++ a/dlls/ntdll/ntdll.spec 2019-04-24 18:48:37 +0900
@@ -1630,3 +1631,5 @@
# Filesystem
@ cdecl -syscall wine_nt_to_unix_file_name(ptr ptr ptr long)
@ cdecl -syscall wine_unix_to_nt_file_name(str ptr ptr)
+
+@ cdecl IsTransgaming()

View File

@ -0,0 +1,30 @@
#!/bin/bash
# Fix for LoL 9.20+ crashing - https://bugs.winehq.org/show_bug.cgi?id=47198
if [ "$_lol920_fix" = "true" ] && [ "$_use_staging" = "true" ]; then
if ( cd "${srcdir}"/"${_stgsrcdir}" && git merge-base --is-ancestor 766e1ee8f8876f21b64b3bbd5c9322a476abc5bd HEAD ); then
_patchname='leagueoflolfix.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32 and disabling libglesv2 dll)" && nonuser_patcher
elif git merge-base --is-ancestor 3513a176fd325492e5b5e498e4eebf3f820f8cc6 HEAD; then
_patchname='leagueoflolfix-766e1ee.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor 7f144646ffac6f3632d0c39b217dbd433c1154a0 HEAD; then
_patchname='leagueoflolfix-3513a17.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor bd9a1e23f2a1eb97492ff977dcb0d96fde8ab2ad HEAD; then
_patchname='leagueoflolfix-7f14464.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor 98682cfd01aca9be2755e4279db87d54e3642f0b HEAD; then
_patchname='leagueoflolfix-bd9a1e2.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor 18273d5e71e25575bdbdba1d252df72be3373f6d HEAD; then
_patchname='leagueoflolfix-98682cf.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor b87256cd1db21a59484248a193b6ad12ca2853ca HEAD; then
_patchname='leagueoflolfix-18273d5.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor 3b16f35413f3a6641df42b782ead294f343e7d5e HEAD; then
_patchname='leagueoflolfix-b87256c.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor b8f0e32b9f00f63abee6ca31e190ff794c053b67 HEAD; then
_patchname='leagueoflolfix-3b16f35.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor 39138478fdd93cc0dfc1e83b85784bc468e8d237 HEAD; then
_patchname='leagueoflolfix-b8f0e32.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
elif git merge-base --is-ancestor 944c4e8f760460ca6a260573d87c454052caad2c HEAD; then
_patchname='leagueoflolfix-3913847.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
else
_patchname='leagueoflolfix-944c4e8.patch' && _patchmsg="Applied LoL 9.20+ fix - Requires vdso32 disabled (echo 0 > /proc/sys/abi/vsyscall32)" && nonuser_patcher
fi
fi

View File

@ -0,0 +1,208 @@
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index c876d51f8e6..654c84de587 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1401,19 +1401,9 @@ void output_syscalls( DLLSPEC *spec )
switch (target.cpu)
{
case CPU_i386:
- if (UsePIC)
- {
- output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
- output( "1:\tmovl %s-1b(%%eax),%%edx\n", asm_name("__wine_syscall_dispatcher") );
- output( "\tmovl $%u,%%eax\n", id );
- needs_get_pc_thunk = 1;
- }
- else
- {
- output( "\tmovl $%u,%%eax\n", id );
- output( "\tmovl $%s,%%edx\n", asm_name("__wine_syscall") );
- }
- output( "\tcall *%%edx\n" );
+ output( "\t.byte 0xb8\n" ); /* mov eax, SYSCALL */
+ output( "\t.long %d\n", id );
+ output( "\t.byte 0x64,0xff,0x15,0xc0,0x00,0x00,0x00\n" ); /* call dword ptr fs:[0C0h] */
output( "\tret $%u\n", odp->type == TYPE_STDCALL ? get_args_size( odp ) : 0 );
break;
case CPU_x86_64:
--- a/dlls/ntdll/unix/signal_i386.c
+++ a/dlls/ntdll/unix/signal_i386.c
@@ -415,6 +415,8 @@ static inline int set_thread_area( struc
static ULONG first_ldt_entry = 32;
+static int wine_cs;
+
enum i386_trap_code
{
#if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
@@ -528,6 +530,11 @@ static inline WORD get_cs(void) { WORD r
static inline WORD get_ds(void) { WORD res; __asm__( "movw %%ds,%0" : "=r" (res) ); return res; }
static inline WORD get_fs(void) { WORD res; __asm__( "movw %%fs,%0" : "=r" (res) ); return res; }
static inline WORD get_gs(void) { WORD res; __asm__( "movw %%gs,%0" : "=r" (res) ); return res; }
+static CDECL void __attribute((naked)) set_cs( DWORD val ) {
+ asm ( "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "lret"); }
static inline void set_fs( WORD val ) { __asm__( "mov %0,%%fs" :: "r" (val)); }
static inline void set_gs( WORD val ) { __asm__( "mov %0,%%gs" :: "r" (val)); }
@@ -694,7 +701,8 @@ static inline void *init_handler( const
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) ||
+ !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1185,7 +1193,7 @@ static inline DWORD is_privileged_instr(
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1252,7 +1260,7 @@ static inline BOOL check_invalid_gs( uco
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return FALSE;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1489,7 +1497,7 @@ C_ASSERT( (offsetof(struct stack_layout,
EIP_sig(sigcontext) = (DWORD)pKiUserExceptionDispatcher;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_ds();
FS_sig(sigcontext) = get_fs();
@@ -2108,6 +2116,36 @@ static void ldt_set_entry( WORD sel, LDT
LDT_FLAGS_ALLOCATED);
}
+static WORD internal_ldt_alloc_entry(void)
+{
+ for (int idx = first_ldt_entry; idx < LDT_SIZE; idx++)
+ {
+ if (__wine_ldt_copy.flags[idx] & LDT_FLAGS_ALLOCATED) continue;
+
+ /* mark selector as allocated */
+ __wine_ldt_copy.flags[idx] |= LDT_FLAGS_ALLOCATED;
+ return (idx << 3) | 7;
+ }
+ return 0;
+}
+
+static inline void cs_init( int first_thread )
+{
+ LDT_ENTRY entry;
+ sigset_t sigset;
+
+ /* no locking for first thread */
+ if (!first_thread) server_enter_uninterrupted_section( &ldt_mutex, &sigset );
+ if (!wine_cs)
+ wine_cs = internal_ldt_alloc_entry();
+
+ entry = ldt_make_entry( 0, (UINT_PTR)-1, LDT_FLAGS_CODE|LDT_FLAGS_32BIT );
+ ldt_set_entry( wine_cs, entry );
+
+ if (!first_thread) server_leave_uninterrupted_section( &ldt_mutex, &sigset );
+ set_cs( wine_cs );
+}
+
static void ldt_set_fs( WORD sel, TEB *teb )
{
if (sel == gdt_fs_sel)
@@ -2223,38 +2261,35 @@ void signal_init_threading(void)
NTSTATUS signal_alloc_thread( TEB *teb )
{
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
+ static int first_thread = 1;
if (!gdt_fs_sel)
{
- static int first_thread = 1;
sigset_t sigset;
- int idx;
+ WORD sel;
LDT_ENTRY entry = ldt_make_entry( teb, page_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
if (first_thread) /* no locking for first thread */
{
/* leave some space if libc is using the LDT for %gs */
if (!is_gdt_sel( get_gs() )) first_ldt_entry = 512;
- idx = first_ldt_entry;
- ldt_set_entry( (idx << 3) | 7, entry );
- first_thread = 0;
+ sel = (first_ldt_entry << 3) | 7;
+ ldt_set_entry( sel, entry );
}
else
{
server_enter_uninterrupted_section( &ldt_mutex, &sigset );
- for (idx = first_ldt_entry; idx < LDT_SIZE; idx++)
- {
- if (__wine_ldt_copy.flags[idx]) continue;
- ldt_set_entry( (idx << 3) | 7, entry );
- break;
- }
+ sel = internal_ldt_alloc_entry();
+ if (sel) ldt_set_entry( sel, entry );
server_leave_uninterrupted_section( &ldt_mutex, &sigset );
- if (idx == LDT_SIZE) return STATUS_TOO_MANY_THREADS;
+ if (!sel) return STATUS_TOO_MANY_THREADS;
}
- thread_data->fs = (idx << 3) | 7;
+ thread_data->fs = sel;
}
else thread_data->fs = gdt_fs_sel;
+ cs_init( first_thread );
+ first_thread = 0;
teb->WOW32Reserved = __wine_syscall_dispatcher;
return STATUS_SUCCESS;
}
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 3d0c2deca35..b0c03d992d4 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2516,6 +2516,17 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr,
TRACE( "read %p, write %p, except %p, timeout %p\n", read_ptr, write_ptr, except_ptr, timeout );
+ static int is_RCS = -1;
+ if (is_RCS < 0) {
+ is_RCS = GetModuleHandleA(NULL) == GetModuleHandleA("RiotClientServices.exe");
+ }
+ const struct timeval zero_tv = { 0, 1000 };
+ if (is_RCS && read_ptr && write_ptr && except_ptr && timeout && timeout->tv_sec == 1 && timeout->tv_usec == 0) {
+ if (read_ptr->fd_count >= 4 && read_ptr->fd_count <= 8 && write_ptr->fd_count == 0 && except_ptr->fd_count == 1) {
+ timeout = &zero_tv;
+ }
+ }
+
if (!(sync_event = get_sync_event())) return -1;
if (read_ptr) poll_count += read_ptr->fd_count;
diff --git a/loader/preloader.c b/loader/preloader.c
index d88964e9c4b..1ac8b9bd16b 100644
--- a/loader/preloader.c
+++ b/loader/preloader.c
@@ -1460,7 +1460,7 @@ void* wld_start( void **stack )
i = 0;
/* delete sysinfo values if addresses conflict */
- if (is_in_preload_range( av, AT_SYSINFO ) || is_in_preload_range( av, AT_SYSINFO_EHDR ))
+ if (1)
{
delete_av[i++].a_type = AT_SYSINFO;
delete_av[i++].a_type = AT_SYSINFO_EHDR;

View File

@ -0,0 +1,687 @@
From 834e7d5da1ff024429c3e8b84ab7201babdd7ebf Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Sat, 4 Apr 2020 13:05:43 +0200
Subject: Revert "libwine: Make the LDT functions obsolete."
This reverts commit 3b16f35413f3a6641df42b782ead294f343e7d5e.
diff --git a/include/wine/library.h b/include/wine/library.h
index f338c4da19..a6fe28059f 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -76,6 +76,116 @@ extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
extern int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg),
void *arg, int top_down );
+#ifdef __i386__
+
+/* LDT management */
+
+extern void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) );
+extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
+extern int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry );
+extern int wine_ldt_is_system( unsigned short sel );
+extern void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset );
+extern unsigned short wine_ldt_alloc_entries( int count );
+extern unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount );
+extern void wine_ldt_free_entries( unsigned short sel, int count );
+extern unsigned short wine_ldt_alloc_fs(void);
+extern void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry );
+extern void wine_ldt_free_fs( unsigned short sel );
+
+/* the local copy of the LDT */
+extern struct __wine_ldt_copy
+{
+ void *base[8192]; /* base address or 0 if entry is free */
+ unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
+ unsigned char flags[8192]; /* flags (defined below) */
+} wine_ldt_copy;
+
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
+#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
+#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
+static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
+{
+ return (void *)(ent->BaseLow |
+ (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
+ (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
+}
+static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
+{
+ unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
+ if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
+ return limit;
+}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
+
+/* segment register access */
+
+# if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
+# define __DEFINE_GET_SEG(seg) \
+ static FORCEINLINE unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm__ __volatile__("movw %%" #seg ",%w0" : "=r"(res)); return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static FORCEINLINE void wine_set_##seg(int val) \
+ { __asm__("movw %w0,%%" #seg : : "r" (val)); }
+# elif defined(_MSC_VER)
+# define __DEFINE_GET_SEG(seg) \
+ static inline unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm { mov res, seg } return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static inline void wine_set_##seg(unsigned short val) { __asm { mov seg, val } }
+# else /* __GNUC__ || _MSC_VER */
+# define __DEFINE_GET_SEG(seg) extern unsigned short wine_get_##seg(void);
+# define __DEFINE_SET_SEG(seg) extern void wine_set_##seg(unsigned int);
+# endif /* __GNUC__ || _MSC_VER */
+
+__DEFINE_GET_SEG(cs)
+__DEFINE_GET_SEG(ds)
+__DEFINE_GET_SEG(es)
+__DEFINE_GET_SEG(fs)
+__DEFINE_GET_SEG(gs)
+__DEFINE_GET_SEG(ss)
+__DEFINE_SET_SEG(fs)
+__DEFINE_SET_SEG(gs)
+#undef __DEFINE_GET_SEG
+#undef __DEFINE_SET_SEG
+
+#endif /* __i386__ */
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index a8f4925019..5fabd1968d 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -31,73 +31,11 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/library.h"
#include "wine/asm.h"
#ifdef __i386__
-#ifdef __ASM_OBSOLETE
-
-/* the local copy of the LDT */
-struct __wine_ldt_copy
-{
- void *base[8192]; /* base address or 0 if entry is free */
- unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
- unsigned char flags[8192]; /* flags (defined below) */
-} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
-
-#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
-#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
-#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
-#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
-#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
-#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
-
-/* helper functions to manipulate the LDT_ENTRY structure */
-static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
-{
- ent->BaseLow = (WORD)(ULONG_PTR)base;
- ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
- ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
-}
-static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
-{
- if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- ent->LimitLow = (WORD)limit;
- ent->HighWord.Bits.LimitHi = (limit >> 16);
-}
-static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
-{
- return (void *)(ent->BaseLow |
- (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
- (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
-}
-static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
-{
- unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
- if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
- return limit;
-}
-static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
-{
- ent->HighWord.Bits.Dpl = 3;
- ent->HighWord.Bits.Pres = 1;
- ent->HighWord.Bits.Type = flags;
- ent->HighWord.Bits.Sys = 0;
- ent->HighWord.Bits.Reserved_0 = 0;
- ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
-}
-static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
-{
- unsigned char ret = ent->HighWord.Bits.Type;
- if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
- return ret;
-}
-static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
-{
- const DWORD *dw = (const DWORD *)ent;
- return (dw[0] | dw[1]) == 0;
-}
-
#ifdef __linux__
#ifdef HAVE_SYS_SYSCALL_H
@@ -164,6 +102,13 @@ static inline int set_thread_area( struct modify_ldt_s *ptr )
#include <i386/user_ldt.h>
#endif
+/* local copy of the LDT */
+#ifdef __APPLE__
+struct __wine_ldt_copy wine_ldt_copy = { { 0, 0, 0 } };
+#else
+struct __wine_ldt_copy wine_ldt_copy;
+#endif
+
static const LDT_ENTRY null_entry; /* all-zeros, used to clear LDT entries */
#define LDT_FIRST_ENTRY 512
@@ -183,7 +128,7 @@ static inline int is_gdt_sel( unsigned short sel ) { return !(sel & 4); }
*
* Set the LDT locking/unlocking functions.
*/
-void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func)(void) )
+void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) )
{
lock_ldt = lock_func;
unlock_ldt = unlock_func;
@@ -195,7 +140,7 @@ void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func
*
* Retrieve an LDT entry. Return a null entry if selector is not allocated.
*/
-void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
+void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry )
{
int index = sel >> 3;
@@ -205,11 +150,11 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
return;
}
lock_ldt();
- if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
+ if (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
- wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
- wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
+ wine_ldt_set_base( entry, wine_ldt_copy.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
@@ -274,9 +219,9 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
if (ret >= 0)
{
- wine_ldt_copy_obsolete.base[index] = wine_ldt_get_base(entry);
- wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
- wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
+ wine_ldt_copy.base[index] = wine_ldt_get_base(entry);
+ wine_ldt_copy.limit[index] = wine_ldt_get_limit(entry);
+ wine_ldt_copy.flags[index] = (entry->HighWord.Bits.Type |
(entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
WINE_LDT_FLAGS_ALLOCATED);
}
@@ -289,7 +234,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
*
* Set an LDT entry.
*/
-int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
int ret;
@@ -305,7 +250,7 @@ int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Check if the selector is a system selector (i.e. not managed by Wine).
*/
-int wine_ldt_is_system_obsolete( unsigned short sel )
+int wine_ldt_is_system( unsigned short sel )
{
return is_gdt_sel(sel) || ((sel >> 3) < LDT_FIRST_ENTRY);
}
@@ -317,7 +262,7 @@ int wine_ldt_is_system_obsolete( unsigned short sel )
* Convert a segment:offset pair to a linear pointer.
* Note: we don't lock the LDT since this has to be fast.
*/
-void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
+void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset )
{
int index;
@@ -325,8 +270,8 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
return (void *)offset;
if ((index = (sel >> 3)) < LDT_FIRST_ENTRY) /* system selector */
return (void *)offset;
- if (!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
- return (char *)wine_ldt_copy_obsolete.base[index] + offset;
+ if (!(wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
+ return (char *)wine_ldt_copy.base[index] + offset;
}
@@ -336,7 +281,7 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
* Allocate a number of consecutive ldt entries, without setting the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_alloc_entries_obsolete( int count )
+unsigned short wine_ldt_alloc_entries( int count )
{
int i, index, size = 0;
@@ -344,13 +289,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
lock_ldt();
for (i = LDT_FIRST_ENTRY; i < LDT_SIZE; i++)
{
- if (wine_ldt_copy_obsolete.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
+ if (wine_ldt_copy.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
else if (++size >= count) /* found a large enough block */
{
index = i - size + 1;
/* mark selectors as allocated */
- for (i = 0; i < count; i++) wine_ldt_copy_obsolete.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
+ for (i = 0; i < count; i++) wine_ldt_copy.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
unlock_ldt();
return (index << 3) | 7;
}
@@ -360,15 +305,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
}
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count );
-
/***********************************************************************
* wine_ldt_realloc_entries
*
* Reallocate a number of consecutive ldt entries, without changing the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcount, int newcount )
+unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount )
{
int i;
@@ -381,23 +324,23 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
if (index + newcount > LDT_SIZE) i = oldcount;
else
for (i = oldcount; i < newcount; i++)
- if (wine_ldt_copy_obsolete.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
+ if (wine_ldt_copy.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
if (i < newcount) /* they are not free */
{
- wine_ldt_free_entries_obsolete( sel, oldcount );
- sel = wine_ldt_alloc_entries_obsolete( newcount );
+ wine_ldt_free_entries( sel, oldcount );
+ sel = wine_ldt_alloc_entries( newcount );
}
else /* mark the selectors as allocated */
{
for (i = oldcount; i < newcount; i++)
- wine_ldt_copy_obsolete.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
+ wine_ldt_copy.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
}
unlock_ldt();
}
else if (oldcount > newcount) /* we need to remove selectors */
{
- wine_ldt_free_entries_obsolete( sel + (newcount << 3), newcount - oldcount );
+ wine_ldt_free_entries( sel + (newcount << 3), newcount - oldcount );
}
return sel;
}
@@ -408,7 +351,7 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
*
* Free a number of consecutive ldt entries and clear their contents.
*/
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
+void wine_ldt_free_entries( unsigned short sel, int count )
{
int index;
@@ -416,7 +359,7 @@ void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
for (index = sel >> 3; count > 0; count--, index++)
{
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[index] = 0;
+ wine_ldt_copy.flags[index] = 0;
}
unlock_ldt();
}
@@ -430,7 +373,7 @@ static int global_fs_sel = -1; /* global selector for %fs shared among all thre
* Allocate an LDT entry for a %fs selector, reusing a global
* GDT selector if possible. Return the selector value.
*/
-unsigned short wine_ldt_alloc_fs_obsolete(void)
+unsigned short wine_ldt_alloc_fs(void)
{
if (global_fs_sel == -1)
{
@@ -457,7 +400,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
#endif
}
if (global_fs_sel > 0) return global_fs_sel;
- return wine_ldt_alloc_entries_obsolete( 1 );
+ return wine_ldt_alloc_entries( 1 );
}
@@ -469,7 +412,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
*
* Note: this runs in the context of the new thread, so cannot acquire locks.
*/
-void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry )
{
if ((sel & ~3) == (global_fs_sel & ~3))
{
@@ -497,7 +440,7 @@ void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Free a %fs selector returned by wine_ldt_alloc_fs.
*/
-void wine_ldt_free_fs_obsolete( unsigned short sel )
+void wine_ldt_free_fs( unsigned short sel )
{
WORD fs;
@@ -508,46 +451,22 @@ void wine_ldt_free_fs_obsolete( unsigned short sel )
/* FIXME: if freeing current %fs we cannot acquire locks */
__asm__( "mov %0,%%fs" :: "r" (0) );
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[sel >> 3] = 0;
+ wine_ldt_copy.flags[sel >> 3] = 0;
}
- else wine_ldt_free_entries_obsolete( sel, 1 );
+ else wine_ldt_free_entries( sel, 1 );
}
/***********************************************************************
* selector access functions
*/
-__ASM_GLOBAL_FUNC( wine_get_cs_obsolete, "movw %cs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ds_obsolete, "movw %ds,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_es_obsolete, "movw %es,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_fs_obsolete, "movw %fs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_gs_obsolete, "movw %gs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ss_obsolete, "movw %ss,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_fs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_gs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
-
-
-__ASM_OBSOLETE(wine_ldt_alloc_entries);
-__ASM_OBSOLETE(wine_ldt_alloc_fs);
-__ASM_OBSOLETE(wine_ldt_copy);
-__ASM_OBSOLETE(wine_ldt_free_entries);
-__ASM_OBSOLETE(wine_ldt_free_fs);
-__ASM_OBSOLETE(wine_ldt_get_entry);
-__ASM_OBSOLETE(wine_ldt_get_ptr);
-__ASM_OBSOLETE(wine_ldt_init_fs);
-__ASM_OBSOLETE(wine_ldt_init_locking);
-__ASM_OBSOLETE(wine_ldt_is_system);
-__ASM_OBSOLETE(wine_ldt_realloc_entries);
-__ASM_OBSOLETE(wine_ldt_set_entry);
-__ASM_OBSOLETE(wine_get_cs);
-__ASM_OBSOLETE(wine_get_ds);
-__ASM_OBSOLETE(wine_get_es);
-__ASM_OBSOLETE(wine_get_fs);
-__ASM_OBSOLETE(wine_get_gs);
-__ASM_OBSOLETE(wine_get_ss);
-__ASM_OBSOLETE(wine_set_fs);
-__ASM_OBSOLETE(wine_set_gs);
-
-#endif /* __ASM_OBSOLETE */
+__ASM_GLOBAL_FUNC( wine_get_cs, "movw %cs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ds, "movw %ds,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
#endif /* __i386__ */
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 7ea849b908..3f2c430fa8 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -18,21 +18,41 @@ WINE_1.0
wine_get_build_dir;
wine_get_build_id;
wine_get_config_dir;
+ wine_get_cs;
wine_get_data_dir;
+ wine_get_ds;
+ wine_get_es;
+ wine_get_fs;
+ wine_get_gs;
wine_get_server_dir;
+ wine_get_ss;
wine_get_user_name;
wine_get_version;
wine_get_patches;
wine_init;
wine_init_argv0_path;
+ wine_ldt_alloc_entries;
+ wine_ldt_alloc_fs;
+ wine_ldt_copy;
+ wine_ldt_free_entries;
+ wine_ldt_free_fs;
+ wine_ldt_get_entry;
+ wine_ldt_get_ptr;
+ wine_ldt_init_fs;
+ wine_ldt_init_locking;
+ wine_ldt_is_system;
+ wine_ldt_realloc_entries;
+ wine_ldt_set_entry;
wine_mmap_add_reserved_area;
wine_mmap_enum_reserved_areas;
wine_mmap_is_in_reserved_area;
wine_mmap_remove_reserved_area;
wine_mmap_add_free_area;
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_fs;
+ wine_set_gs;
wine_wctype_table;
/* the following functions are obsolete and only exported for backwards compatibility */
@@ -93,30 +113,10 @@ WINE_1.0
wine_dll_load_main_exe;
wine_dll_unload;
wine_fold_string;
- wine_get_cs;
- wine_get_ds;
- wine_get_es;
- wine_get_fs;
- wine_get_gs;
wine_get_sortkey;
- wine_get_ss;
wine_is_dbcs_leadbyte;
- wine_ldt_alloc_entries;
- wine_ldt_alloc_fs;
- wine_ldt_copy;
- wine_ldt_free_entries;
- wine_ldt_free_fs;
- wine_ldt_get_entry;
- wine_ldt_get_ptr;
- wine_ldt_init_fs;
- wine_ldt_init_locking;
- wine_ldt_is_system;
- wine_ldt_realloc_entries;
- wine_ldt_set_entry;
wine_pthread_get_functions;
wine_pthread_set_functions;
- wine_set_fs;
- wine_set_gs;
wine_switch_to_stack;
wine_utf8_mbstowcs;
wine_utf8_wcstombs;
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) || !ldt_is_system(SS_sig(sigcontext)))
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_es();
FS_sig(sigcontext) = get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;

View File

@ -0,0 +1,171 @@
--- a/tools/winebuild/import.c
+++ a/tools/winebuild/import.c
@@ -1951,19 +1951,9 @@ void output_syscalls( DLLSPEC *spec )
switch (target_cpu)
{
case CPU_x86:
- if (UsePIC)
- {
- output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
- output( "1:\tmovl %s-1b(%%eax),%%edx\n", asm_name("__wine_syscall_dispatcher") );
- output( "\tmovl $%u,%%eax\n", i );
- needs_get_pc_thunk = 1;
- }
- else
- {
- output( "\tmovl $%u,%%eax\n", i );
- output( "\tmovl $%s,%%edx\n", asm_name("__wine_syscall") );
- }
- output( "\tcall *%%edx\n" );
+ output( "\t.byte 0xb8\n" ); /* mov eax, SYSCALL */
+ output( "\t.long %d\n", i );
+ output( "\t.byte 0x64,0xff,0x15,0xc0,0x00,0x00,0x00\n" ); /* call dword ptr fs:[0C0h] */
output( "\tret $%u\n", odp->type == TYPE_STDCALL ? get_args_size( odp ) : 0 );
break;
case CPU_x86_64:
--- a/dlls/ntdll/unix/signal_i386.c
+++ a/dlls/ntdll/unix/signal_i386.c
@@ -415,6 +415,8 @@ static inline int set_thread_area( struc
static ULONG first_ldt_entry = 32;
+static int wine_cs;
+
enum i386_trap_code
{
#if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
@@ -528,6 +530,11 @@ static inline WORD get_cs(void) { WORD r
static inline WORD get_ds(void) { WORD res; __asm__( "movw %%ds,%0" : "=r" (res) ); return res; }
static inline WORD get_fs(void) { WORD res; __asm__( "movw %%fs,%0" : "=r" (res) ); return res; }
static inline WORD get_gs(void) { WORD res; __asm__( "movw %%gs,%0" : "=r" (res) ); return res; }
+static CDECL void __attribute((naked)) set_cs( DWORD val ) {
+ asm ( "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "lret"); }
static inline void set_fs( WORD val ) { __asm__( "mov %0,%%fs" :: "r" (val)); }
static inline void set_gs( WORD val ) { __asm__( "mov %0,%%gs" :: "r" (val)); }
@@ -694,7 +701,8 @@ static inline void *init_handler( const
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) ||
+ !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1185,7 +1193,7 @@ static inline DWORD is_privileged_instr(
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1252,7 +1260,7 @@ static inline BOOL check_invalid_gs( uco
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return FALSE;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1489,7 +1497,7 @@ C_ASSERT( (offsetof(struct stack_layout,
EIP_sig(sigcontext) = (DWORD)pKiUserExceptionDispatcher;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_ds();
FS_sig(sigcontext) = get_fs();
@@ -2108,6 +2116,36 @@ static void ldt_set_entry( WORD sel, LDT
LDT_FLAGS_ALLOCATED);
}
+static WORD internal_ldt_alloc_entry(void)
+{
+ for (int idx = first_ldt_entry; idx < LDT_SIZE; idx++)
+ {
+ if (__wine_ldt_copy.flags[idx] & LDT_FLAGS_ALLOCATED) continue;
+
+ /* mark selector as allocated */
+ __wine_ldt_copy.flags[idx] |= LDT_FLAGS_ALLOCATED;
+ return (idx << 3) | 7;
+ }
+ return 0;
+}
+
+static inline void cs_init( int first_thread )
+{
+ LDT_ENTRY entry;
+ sigset_t sigset;
+
+ /* no locking for first thread */
+ if (!first_thread) server_enter_uninterrupted_section( &ldt_mutex, &sigset );
+ if (!wine_cs)
+ wine_cs = internal_ldt_alloc_entry();
+
+ entry = ldt_make_entry( 0, (UINT_PTR)-1, LDT_FLAGS_CODE|LDT_FLAGS_32BIT );
+ ldt_set_entry( wine_cs, entry );
+
+ if (!first_thread) server_leave_uninterrupted_section( &ldt_mutex, &sigset );
+ set_cs( wine_cs );
+}
+
static void ldt_set_fs( WORD sel, TEB *teb )
{
if (sel == gdt_fs_sel)
@@ -2223,38 +2261,35 @@ void signal_init_threading(void)
NTSTATUS signal_alloc_thread( TEB *teb )
{
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
+ static int first_thread = 1;
if (!gdt_fs_sel)
{
- static int first_thread = 1;
sigset_t sigset;
- int idx;
+ WORD sel;
LDT_ENTRY entry = ldt_make_entry( teb, page_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
if (first_thread) /* no locking for first thread */
{
/* leave some space if libc is using the LDT for %gs */
if (!is_gdt_sel( get_gs() )) first_ldt_entry = 512;
- idx = first_ldt_entry;
- ldt_set_entry( (idx << 3) | 7, entry );
- first_thread = 0;
+ sel = (first_ldt_entry << 3) | 7;
+ ldt_set_entry( sel, entry );
}
else
{
server_enter_uninterrupted_section( &ldt_mutex, &sigset );
- for (idx = first_ldt_entry; idx < LDT_SIZE; idx++)
- {
- if (__wine_ldt_copy.flags[idx]) continue;
- ldt_set_entry( (idx << 3) | 7, entry );
- break;
- }
+ sel = internal_ldt_alloc_entry();
+ if (sel) ldt_set_entry( sel, entry );
server_leave_uninterrupted_section( &ldt_mutex, &sigset );
- if (idx == LDT_SIZE) return STATUS_TOO_MANY_THREADS;
+ if (!sel) return STATUS_TOO_MANY_THREADS;
}
- thread_data->fs = (idx << 3) | 7;
+ thread_data->fs = sel;
}
else thread_data->fs = gdt_fs_sel;
+ cs_init( first_thread );
+ first_thread = 0;
teb->WOW32Reserved = __wine_syscall_dispatcher;
return STATUS_SUCCESS;
}

View File

@ -0,0 +1,120 @@
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
/* convert from straight ASCII to Unicode without depending on the current codepage */
static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
{
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) ||
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
{
/*
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!wine_ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!wine_ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = wine_get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = wine_get_ds();
ES_sig(sigcontext) = wine_get_es();
FS_sig(sigcontext) = wine_get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_remove_reserved_area;
wine_pthread_get_functions;
wine_pthread_set_functions;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_switch_to_stack;

View File

@ -0,0 +1,121 @@
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) || !ldt_is_system(SS_sig(sigcontext)))
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = wine_get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = wine_get_ds();
ES_sig(sigcontext) = wine_get_es();
FS_sig(sigcontext) = wine_get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;

View File

@ -0,0 +1,171 @@
--- a/tools/winebuild/import.c
+++ a/tools/winebuild/import.c
@@ -1951,19 +1951,9 @@ void output_syscalls( DLLSPEC *spec )
switch (target_cpu)
{
case CPU_x86:
- if (UsePIC)
- {
- output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
- output( "1:\tmovl %s-1b(%%eax),%%edx\n", asm_name("__wine_syscall_dispatcher") );
- output( "\tmovl $%u,%%eax\n", id );
- needs_get_pc_thunk = 1;
- }
- else
- {
- output( "\tmovl $%u,%%eax\n", id );
- output( "\tmovl $%s,%%edx\n", asm_name("__wine_syscall") );
- }
- output( "\tcall *%%edx\n" );
+ output( "\t.byte 0xb8\n" ); /* mov eax, SYSCALL */
+ output( "\t.long %d\n", i );
+ output( "\t.byte 0x64,0xff,0x15,0xc0,0x00,0x00,0x00\n" ); /* call dword ptr fs:[0C0h] */
output( "\tret $%u\n", odp->type == TYPE_STDCALL ? get_args_size( odp ) : 0 );
break;
case CPU_x86_64:
--- a/dlls/ntdll/unix/signal_i386.c
+++ a/dlls/ntdll/unix/signal_i386.c
@@ -415,6 +415,8 @@ static inline int set_thread_area( struc
static ULONG first_ldt_entry = 32;
+static int wine_cs;
+
enum i386_trap_code
{
#if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
@@ -528,6 +530,11 @@ static inline WORD get_cs(void) { WORD r
static inline WORD get_ds(void) { WORD res; __asm__( "movw %%ds,%0" : "=r" (res) ); return res; }
static inline WORD get_fs(void) { WORD res; __asm__( "movw %%fs,%0" : "=r" (res) ); return res; }
static inline WORD get_gs(void) { WORD res; __asm__( "movw %%gs,%0" : "=r" (res) ); return res; }
+static CDECL void __attribute((naked)) set_cs( DWORD val ) {
+ asm ( "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "lret"); }
static inline void set_fs( WORD val ) { __asm__( "mov %0,%%fs" :: "r" (val)); }
static inline void set_gs( WORD val ) { __asm__( "mov %0,%%gs" :: "r" (val)); }
@@ -694,7 +701,8 @@ static inline void *init_handler( const
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) ||
+ !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1185,7 +1193,7 @@ static inline DWORD is_privileged_instr(
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1252,7 +1260,7 @@ static inline BOOL check_invalid_gs( uco
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return FALSE;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1489,7 +1497,7 @@ C_ASSERT( (offsetof(struct stack_layout,
EIP_sig(sigcontext) = (DWORD)pKiUserExceptionDispatcher;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_ds();
FS_sig(sigcontext) = get_fs();
@@ -2108,6 +2116,36 @@ static void ldt_set_entry( WORD sel, LDT
LDT_FLAGS_ALLOCATED);
}
+static WORD internal_ldt_alloc_entry(void)
+{
+ for (int idx = first_ldt_entry; idx < LDT_SIZE; idx++)
+ {
+ if (__wine_ldt_copy.flags[idx] & LDT_FLAGS_ALLOCATED) continue;
+
+ /* mark selector as allocated */
+ __wine_ldt_copy.flags[idx] |= LDT_FLAGS_ALLOCATED;
+ return (idx << 3) | 7;
+ }
+ return 0;
+}
+
+static inline void cs_init( int first_thread )
+{
+ LDT_ENTRY entry;
+ sigset_t sigset;
+
+ /* no locking for first thread */
+ if (!first_thread) server_enter_uninterrupted_section( &ldt_mutex, &sigset );
+ if (!wine_cs)
+ wine_cs = internal_ldt_alloc_entry();
+
+ entry = ldt_make_entry( 0, (UINT_PTR)-1, LDT_FLAGS_CODE|LDT_FLAGS_32BIT );
+ ldt_set_entry( wine_cs, entry );
+
+ if (!first_thread) server_leave_uninterrupted_section( &ldt_mutex, &sigset );
+ set_cs( wine_cs );
+}
+
static void ldt_set_fs( WORD sel, TEB *teb )
{
if (sel == gdt_fs_sel)
@@ -2223,38 +2261,35 @@ void signal_init_threading(void)
NTSTATUS signal_alloc_thread( TEB *teb )
{
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
+ static int first_thread = 1;
if (!gdt_fs_sel)
{
- static int first_thread = 1;
sigset_t sigset;
- int idx;
+ WORD sel;
LDT_ENTRY entry = ldt_make_entry( teb, page_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
if (first_thread) /* no locking for first thread */
{
/* leave some space if libc is using the LDT for %gs */
if (!is_gdt_sel( get_gs() )) first_ldt_entry = 512;
- idx = first_ldt_entry;
- ldt_set_entry( (idx << 3) | 7, entry );
- first_thread = 0;
+ sel = (first_ldt_entry << 3) | 7;
+ ldt_set_entry( sel, entry );
}
else
{
server_enter_uninterrupted_section( &ldt_mutex, &sigset );
- for (idx = first_ldt_entry; idx < LDT_SIZE; idx++)
- {
- if (__wine_ldt_copy.flags[idx]) continue;
- ldt_set_entry( (idx << 3) | 7, entry );
- break;
- }
+ sel = internal_ldt_alloc_entry();
+ if (sel) ldt_set_entry( sel, entry );
server_leave_uninterrupted_section( &ldt_mutex, &sigset );
- if (idx == LDT_SIZE) return STATUS_TOO_MANY_THREADS;
+ if (!sel) return STATUS_TOO_MANY_THREADS;
}
- thread_data->fs = (idx << 3) | 7;
+ thread_data->fs = sel;
}
else thread_data->fs = gdt_fs_sel;
+ cs_init( first_thread );
+ first_thread = 0;
teb->WOW32Reserved = __wine_syscall_dispatcher;
return STATUS_SUCCESS;
}

View File

@ -0,0 +1,712 @@
From bff63e4de27f2ef1287e7ff3f8c0cd2e13e6875d Mon Sep 17 00:00:00 2001
From: yuiiio <atbjyk@protonmail.com>
Date: Thu, 1 Oct 2020 23:35:35 +0900
Subject: [PATCH 1/2] Revert "libwine: Remove some no longer needed helper
functions."
This reverts commit 18273d5e71e25575bdbdba1d252df72be3373f6d.
---
libs/wine/ldt.c | 55 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 40 insertions(+), 15 deletions(-)
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index 30d9b945f73..5e85c1137c8 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -45,9 +45,26 @@ struct __wine_ldt_copy
unsigned char flags[8192]; /* flags (defined below) */
} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
{
return (void *)(ent->BaseLow |
@@ -60,6 +77,26 @@ static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
return limit;
}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
#ifdef __linux__
@@ -170,21 +207,9 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
lock_ldt();
if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- ULONG_PTR base = (ULONG_PTR)wine_ldt_copy_obsolete.base[index];
- ULONG limit = wine_ldt_copy_obsolete.limit[index];
-
- entry->BaseLow = (WORD)base;
- entry->HighWord.Bits.BaseMid = (BYTE)(base >> 16);
- entry->HighWord.Bits.BaseHi = (BYTE)(base >> 24);
- if ((entry->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- entry->LimitLow = (WORD)limit;
- entry->HighWord.Bits.LimitHi = (limit >> 16);
- entry->HighWord.Bits.Dpl = 3;
- entry->HighWord.Bits.Pres = 1;
- entry->HighWord.Bits.Type = wine_ldt_copy_obsolete.flags[index];
- entry->HighWord.Bits.Sys = 0;
- entry->HighWord.Bits.Reserved_0 = 0;
- entry->HighWord.Bits.Default_Big = !!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT);
+ wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
--
2.28.0
From 992d96a7464b533358aa03ea1b616f5402241a99 Mon Sep 17 00:00:00 2001
From: yuiiio <atbjyk@protonmail.com>
Date: Thu, 1 Oct 2020 23:41:43 +0900
Subject: [PATCH 2/2] Revert "libwine: Make the LDT functions obsolete."
This reverts commit 3b16f35413f3a6641df42b782ead294f343e7d5e.
---
include/wine/library.h | 110 ++++++++++++++++++++++++++
libs/wine/ldt.c | 175 +++++++++++------------------------------
libs/wine/wine.map | 38 +++++----
3 files changed, 181 insertions(+), 142 deletions(-)
diff --git a/include/wine/library.h b/include/wine/library.h
index b8a4a2df576..2e0f6dc1bad 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -63,6 +63,116 @@ extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
extern int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg),
void *arg, int top_down );
+#ifdef __i386__
+
+/* LDT management */
+
+extern void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) );
+extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
+extern int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry );
+extern int wine_ldt_is_system( unsigned short sel );
+extern void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset );
+extern unsigned short wine_ldt_alloc_entries( int count );
+extern unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount );
+extern void wine_ldt_free_entries( unsigned short sel, int count );
+extern unsigned short wine_ldt_alloc_fs(void);
+extern void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry );
+extern void wine_ldt_free_fs( unsigned short sel );
+
+/* the local copy of the LDT */
+extern struct __wine_ldt_copy
+{
+ void *base[8192]; /* base address or 0 if entry is free */
+ unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
+ unsigned char flags[8192]; /* flags (defined below) */
+} wine_ldt_copy;
+
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
+#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
+#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
+static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
+{
+ return (void *)(ent->BaseLow |
+ (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
+ (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
+}
+static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
+{
+ unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
+ if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
+ return limit;
+}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
+
+/* segment register access */
+
+# if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
+# define __DEFINE_GET_SEG(seg) \
+ static FORCEINLINE unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm__ __volatile__("movw %%" #seg ",%w0" : "=r"(res)); return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static FORCEINLINE void wine_set_##seg(int val) \
+ { __asm__("movw %w0,%%" #seg : : "r" (val)); }
+# elif defined(_MSC_VER)
+# define __DEFINE_GET_SEG(seg) \
+ static inline unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm { mov res, seg } return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static inline void wine_set_##seg(unsigned short val) { __asm { mov seg, val } }
+# else /* __GNUC__ || _MSC_VER */
+# define __DEFINE_GET_SEG(seg) extern unsigned short wine_get_##seg(void);
+# define __DEFINE_SET_SEG(seg) extern void wine_set_##seg(unsigned int);
+# endif /* __GNUC__ || _MSC_VER */
+
+__DEFINE_GET_SEG(cs)
+__DEFINE_GET_SEG(ds)
+__DEFINE_GET_SEG(es)
+__DEFINE_GET_SEG(fs)
+__DEFINE_GET_SEG(gs)
+__DEFINE_GET_SEG(ss)
+__DEFINE_SET_SEG(fs)
+__DEFINE_SET_SEG(gs)
+#undef __DEFINE_GET_SEG
+#undef __DEFINE_SET_SEG
+
+#endif /* __i386__ */
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index 5e85c1137c8..15ce11f2074 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -31,73 +31,11 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/library.h"
#include "wine/asm.h"
#ifdef __i386__
-#ifdef __ASM_OBSOLETE
-
-/* the local copy of the LDT */
-struct __wine_ldt_copy
-{
- void *base[8192]; /* base address or 0 if entry is free */
- unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
- unsigned char flags[8192]; /* flags (defined below) */
-} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
-
-#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
-#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
-#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
-#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
-#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
-#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
-
-/* helper functions to manipulate the LDT_ENTRY structure */
-static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
-{
- ent->BaseLow = (WORD)(ULONG_PTR)base;
- ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
- ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
-}
-static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
-{
- if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- ent->LimitLow = (WORD)limit;
- ent->HighWord.Bits.LimitHi = (limit >> 16);
-}
-static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
-{
- return (void *)(ent->BaseLow |
- (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
- (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
-}
-static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
-{
- unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
- if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
- return limit;
-}
-static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
-{
- ent->HighWord.Bits.Dpl = 3;
- ent->HighWord.Bits.Pres = 1;
- ent->HighWord.Bits.Type = flags;
- ent->HighWord.Bits.Sys = 0;
- ent->HighWord.Bits.Reserved_0 = 0;
- ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
-}
-static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
-{
- unsigned char ret = ent->HighWord.Bits.Type;
- if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
- return ret;
-}
-static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
-{
- const DWORD *dw = (const DWORD *)ent;
- return (dw[0] | dw[1]) == 0;
-}
-
#ifdef __linux__
#ifdef HAVE_SYS_SYSCALL_H
@@ -164,6 +102,13 @@ static inline int set_thread_area( struct modify_ldt_s *ptr )
#include <i386/user_ldt.h>
#endif
+/* local copy of the LDT */
+#ifdef __APPLE__
+struct __wine_ldt_copy wine_ldt_copy = { { 0, 0, 0 } };
+#else
+struct __wine_ldt_copy wine_ldt_copy;
+#endif
+
static const LDT_ENTRY null_entry; /* all-zeros, used to clear LDT entries */
#define LDT_FIRST_ENTRY 512
@@ -183,7 +128,7 @@ static inline int is_gdt_sel( unsigned short sel ) { return !(sel & 4); }
*
* Set the LDT locking/unlocking functions.
*/
-void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func)(void) )
+void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) )
{
lock_ldt = lock_func;
unlock_ldt = unlock_func;
@@ -195,7 +140,7 @@ void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func
*
* Retrieve an LDT entry. Return a null entry if selector is not allocated.
*/
-void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
+void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry )
{
int index = sel >> 3;
@@ -205,11 +150,11 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
return;
}
lock_ldt();
- if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
+ if (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
- wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
- wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
+ wine_ldt_set_base( entry, wine_ldt_copy.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
@@ -272,9 +217,9 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
if (ret >= 0)
{
- wine_ldt_copy_obsolete.base[index] = wine_ldt_get_base(entry);
- wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
- wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
+ wine_ldt_copy.base[index] = wine_ldt_get_base(entry);
+ wine_ldt_copy.limit[index] = wine_ldt_get_limit(entry);
+ wine_ldt_copy.flags[index] = (entry->HighWord.Bits.Type |
(entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
WINE_LDT_FLAGS_ALLOCATED);
}
@@ -287,7 +232,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
*
* Set an LDT entry.
*/
-int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
int ret;
@@ -303,7 +248,7 @@ int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Check if the selector is a system selector (i.e. not managed by Wine).
*/
-int wine_ldt_is_system_obsolete( unsigned short sel )
+int wine_ldt_is_system( unsigned short sel )
{
return is_gdt_sel(sel) || ((sel >> 3) < LDT_FIRST_ENTRY);
}
@@ -315,7 +260,7 @@ int wine_ldt_is_system_obsolete( unsigned short sel )
* Convert a segment:offset pair to a linear pointer.
* Note: we don't lock the LDT since this has to be fast.
*/
-void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
+void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset )
{
int index;
@@ -323,8 +268,8 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
return (void *)offset;
if ((index = (sel >> 3)) < LDT_FIRST_ENTRY) /* system selector */
return (void *)offset;
- if (!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
- return (char *)wine_ldt_copy_obsolete.base[index] + offset;
+ if (!(wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
+ return (char *)wine_ldt_copy.base[index] + offset;
}
@@ -334,7 +279,7 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
* Allocate a number of consecutive ldt entries, without setting the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_alloc_entries_obsolete( int count )
+unsigned short wine_ldt_alloc_entries( int count )
{
int i, index, size = 0;
@@ -342,13 +287,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
lock_ldt();
for (i = LDT_FIRST_ENTRY; i < LDT_SIZE; i++)
{
- if (wine_ldt_copy_obsolete.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
+ if (wine_ldt_copy.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
else if (++size >= count) /* found a large enough block */
{
index = i - size + 1;
/* mark selectors as allocated */
- for (i = 0; i < count; i++) wine_ldt_copy_obsolete.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
+ for (i = 0; i < count; i++) wine_ldt_copy.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
unlock_ldt();
return (index << 3) | 7;
}
@@ -358,15 +303,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
}
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count );
-
/***********************************************************************
* wine_ldt_realloc_entries
*
* Reallocate a number of consecutive ldt entries, without changing the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcount, int newcount )
+unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount )
{
int i;
@@ -379,23 +322,23 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
if (index + newcount > LDT_SIZE) i = oldcount;
else
for (i = oldcount; i < newcount; i++)
- if (wine_ldt_copy_obsolete.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
+ if (wine_ldt_copy.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
if (i < newcount) /* they are not free */
{
- wine_ldt_free_entries_obsolete( sel, oldcount );
- sel = wine_ldt_alloc_entries_obsolete( newcount );
+ wine_ldt_free_entries( sel, oldcount );
+ sel = wine_ldt_alloc_entries( newcount );
}
else /* mark the selectors as allocated */
{
for (i = oldcount; i < newcount; i++)
- wine_ldt_copy_obsolete.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
+ wine_ldt_copy.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
}
unlock_ldt();
}
else if (oldcount > newcount) /* we need to remove selectors */
{
- wine_ldt_free_entries_obsolete( sel + (newcount << 3), newcount - oldcount );
+ wine_ldt_free_entries( sel + (newcount << 3), newcount - oldcount );
}
return sel;
}
@@ -406,7 +349,7 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
*
* Free a number of consecutive ldt entries and clear their contents.
*/
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
+void wine_ldt_free_entries( unsigned short sel, int count )
{
int index;
@@ -414,7 +357,7 @@ void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
for (index = sel >> 3; count > 0; count--, index++)
{
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[index] = 0;
+ wine_ldt_copy.flags[index] = 0;
}
unlock_ldt();
}
@@ -428,7 +371,7 @@ static int global_fs_sel = -1; /* global selector for %fs shared among all thre
* Allocate an LDT entry for a %fs selector, reusing a global
* GDT selector if possible. Return the selector value.
*/
-unsigned short wine_ldt_alloc_fs_obsolete(void)
+unsigned short wine_ldt_alloc_fs(void)
{
if (global_fs_sel == -1)
{
@@ -455,7 +398,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
#endif
}
if (global_fs_sel > 0) return global_fs_sel;
- return wine_ldt_alloc_entries_obsolete( 1 );
+ return wine_ldt_alloc_entries( 1 );
}
@@ -467,7 +410,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
*
* Note: this runs in the context of the new thread, so cannot acquire locks.
*/
-void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry )
{
if ((sel & ~3) == (global_fs_sel & ~3))
{
@@ -495,7 +438,7 @@ void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Free a %fs selector returned by wine_ldt_alloc_fs.
*/
-void wine_ldt_free_fs_obsolete( unsigned short sel )
+void wine_ldt_free_fs( unsigned short sel )
{
WORD fs;
@@ -506,46 +449,22 @@ void wine_ldt_free_fs_obsolete( unsigned short sel )
/* FIXME: if freeing current %fs we cannot acquire locks */
__asm__( "mov %0,%%fs" :: "r" (0) );
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[sel >> 3] = 0;
+ wine_ldt_copy.flags[sel >> 3] = 0;
}
- else wine_ldt_free_entries_obsolete( sel, 1 );
+ else wine_ldt_free_entries( sel, 1 );
}
/***********************************************************************
* selector access functions
*/
-__ASM_GLOBAL_FUNC( wine_get_cs_obsolete, "movw %cs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ds_obsolete, "movw %ds,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_es_obsolete, "movw %es,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_fs_obsolete, "movw %fs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_gs_obsolete, "movw %gs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ss_obsolete, "movw %ss,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_fs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_gs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
-
-
-__ASM_OBSOLETE(wine_ldt_alloc_entries);
-__ASM_OBSOLETE(wine_ldt_alloc_fs);
-__ASM_OBSOLETE(wine_ldt_copy);
-__ASM_OBSOLETE(wine_ldt_free_entries);
-__ASM_OBSOLETE(wine_ldt_free_fs);
-__ASM_OBSOLETE(wine_ldt_get_entry);
-__ASM_OBSOLETE(wine_ldt_get_ptr);
-__ASM_OBSOLETE(wine_ldt_init_fs);
-__ASM_OBSOLETE(wine_ldt_init_locking);
-__ASM_OBSOLETE(wine_ldt_is_system);
-__ASM_OBSOLETE(wine_ldt_realloc_entries);
-__ASM_OBSOLETE(wine_ldt_set_entry);
-__ASM_OBSOLETE(wine_get_cs);
-__ASM_OBSOLETE(wine_get_ds);
-__ASM_OBSOLETE(wine_get_es);
-__ASM_OBSOLETE(wine_get_fs);
-__ASM_OBSOLETE(wine_get_gs);
-__ASM_OBSOLETE(wine_get_ss);
-__ASM_OBSOLETE(wine_set_fs);
-__ASM_OBSOLETE(wine_set_gs);
-
-#endif /* __ASM_OBSOLETE */
+__ASM_GLOBAL_FUNC( wine_get_cs, "movw %cs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ds, "movw %ds,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
#endif /* __i386__ */
--
2.28.0
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) || !ldt_is_system(SS_sig(sigcontext)))
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_es();
FS_sig(sigcontext) = get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,8 @@ NTSTATUS signal_alloc_thread( TEB *teb )
teb->WOW32Reserved = __wine_syscall_dispatcher;
teb->Spare2 = __wine_fakedll_dispatcher;
+
+ signal_init_cs();
return STATUS_SUCCESS;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -116,6 +116,7 @@ WINE_1.0
wine_ldt_set_entry;
wine_pthread_get_functions;
wine_pthread_set_functions;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;

View File

@ -0,0 +1,150 @@
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
/* convert from straight ASCII to Unicode without depending on the current codepage */
static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
{
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) ||
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
{
/*
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
const BYTE *instr;
unsigned int prefix_count = 0;
- if (!wine_ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
instr = (BYTE *)context->Eip;
for (;;) switch(*instr)
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!wine_ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = wine_get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = wine_get_ds();
ES_sig(sigcontext) = wine_get_es();
FS_sig(sigcontext) = wine_get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_remove_reserved_area;
wine_pthread_get_functions;
wine_pthread_set_functions;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_switch_to_stack;
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index f9a4ae26df..2c4d0d252a 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -444,6 +444,7 @@
@ stdcall InsertMenuItemA(long long long ptr)
@ stdcall InsertMenuItemW(long long long ptr)
@ stdcall InsertMenuW(long long long long ptr)
+@ stdcall InternalGetWindowIcon(long long)
@ stdcall InternalGetWindowText(long long long)
@ stdcall IntersectRect(ptr ptr ptr)
@ stdcall InvalidateRect(long ptr long)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 3323ed3e41..8231acc0f1 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -2887,6 +2887,13 @@ INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
return strlen(lpString);
}
+/*******************************************************************
+ * InternalGetWindowIcon (USER32.@)
+ */
+INT WINAPI InternalGetWindowIcon(HWND hwnd, UINT iconType )
+{
+ return NULL;
+}
/*******************************************************************
* InternalGetWindowText (USER32.@)

View File

@ -0,0 +1,778 @@
From 834e7d5da1ff024429c3e8b84ab7201babdd7ebf Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Thu, 9 Apr 2020 12:20:12 +0200
Subject: Revert "libwine: Remove some no longer needed helper functions."
This reverts commit 18273d5e71e25575bdbdba1d252df72be3373f6d.
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index a8f4925019b..18b0b9be9bf 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -45,9 +45,26 @@ struct __wine_ldt_copy
unsigned char flags[8192]; /* flags (defined below) */
} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
{
return (void *)(ent->BaseLow |
@@ -77,6 +60,26 @@ static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
return limit;
}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
#ifdef __linux__
@@ -207,21 +170,9 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
lock_ldt();
if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
+ wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
- ULONG_PTR base = (ULONG_PTR)wine_ldt_copy_obsolete.base[index];
- ULONG limit = wine_ldt_copy_obsolete.limit[index];
-
- entry->BaseLow = (WORD)base;
- entry->HighWord.Bits.BaseMid = (BYTE)(base >> 16);
- entry->HighWord.Bits.BaseHi = (BYTE)(base >> 24);
- if ((entry->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- entry->LimitLow = (WORD)limit;
- entry->HighWord.Bits.LimitHi = (limit >> 16);
- entry->HighWord.Bits.Dpl = 3;
- entry->HighWord.Bits.Pres = 1;
- entry->HighWord.Bits.Type = wine_ldt_copy_obsolete.flags[index];
- entry->HighWord.Bits.Sys = 0;
- entry->HighWord.Bits.Reserved_0 = 0;
- entry->HighWord.Bits.Default_Big = !!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT);
}
else *entry = null_entry;
unlock_ldt();
From 834e7d5da1ff024429c3e8b84ab7201babdd7ebf Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Sat, 4 Apr 2020 13:05:43 +0200
Subject: Revert "libwine: Make the LDT functions obsolete."
This reverts commit 3b16f35413f3a6641df42b782ead294f343e7d5e.
diff --git a/include/wine/library.h b/include/wine/library.h
index f338c4da19..a6fe28059f 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -76,6 +76,116 @@ extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
extern int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg),
void *arg, int top_down );
+#ifdef __i386__
+
+/* LDT management */
+
+extern void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) );
+extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
+extern int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry );
+extern int wine_ldt_is_system( unsigned short sel );
+extern void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset );
+extern unsigned short wine_ldt_alloc_entries( int count );
+extern unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount );
+extern void wine_ldt_free_entries( unsigned short sel, int count );
+extern unsigned short wine_ldt_alloc_fs(void);
+extern void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry );
+extern void wine_ldt_free_fs( unsigned short sel );
+
+/* the local copy of the LDT */
+extern struct __wine_ldt_copy
+{
+ void *base[8192]; /* base address or 0 if entry is free */
+ unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
+ unsigned char flags[8192]; /* flags (defined below) */
+} wine_ldt_copy;
+
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
+#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
+#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
+static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
+{
+ return (void *)(ent->BaseLow |
+ (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
+ (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
+}
+static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
+{
+ unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
+ if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
+ return limit;
+}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
+
+/* segment register access */
+
+# if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
+# define __DEFINE_GET_SEG(seg) \
+ static FORCEINLINE unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm__ __volatile__("movw %%" #seg ",%w0" : "=r"(res)); return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static FORCEINLINE void wine_set_##seg(int val) \
+ { __asm__("movw %w0,%%" #seg : : "r" (val)); }
+# elif defined(_MSC_VER)
+# define __DEFINE_GET_SEG(seg) \
+ static inline unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm { mov res, seg } return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static inline void wine_set_##seg(unsigned short val) { __asm { mov seg, val } }
+# else /* __GNUC__ || _MSC_VER */
+# define __DEFINE_GET_SEG(seg) extern unsigned short wine_get_##seg(void);
+# define __DEFINE_SET_SEG(seg) extern void wine_set_##seg(unsigned int);
+# endif /* __GNUC__ || _MSC_VER */
+
+__DEFINE_GET_SEG(cs)
+__DEFINE_GET_SEG(ds)
+__DEFINE_GET_SEG(es)
+__DEFINE_GET_SEG(fs)
+__DEFINE_GET_SEG(gs)
+__DEFINE_GET_SEG(ss)
+__DEFINE_SET_SEG(fs)
+__DEFINE_SET_SEG(gs)
+#undef __DEFINE_GET_SEG
+#undef __DEFINE_SET_SEG
+
+#endif /* __i386__ */
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index a8f4925019..5fabd1968d 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -31,73 +31,11 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/library.h"
#include "wine/asm.h"
#ifdef __i386__
-#ifdef __ASM_OBSOLETE
-
-/* the local copy of the LDT */
-struct __wine_ldt_copy
-{
- void *base[8192]; /* base address or 0 if entry is free */
- unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
- unsigned char flags[8192]; /* flags (defined below) */
-} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
-
-#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
-#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
-#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
-#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
-#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
-#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
-
-/* helper functions to manipulate the LDT_ENTRY structure */
-static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
-{
- ent->BaseLow = (WORD)(ULONG_PTR)base;
- ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
- ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
-}
-static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
-{
- if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- ent->LimitLow = (WORD)limit;
- ent->HighWord.Bits.LimitHi = (limit >> 16);
-}
-static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
-{
- return (void *)(ent->BaseLow |
- (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
- (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
-}
-static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
-{
- unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
- if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
- return limit;
-}
-static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
-{
- ent->HighWord.Bits.Dpl = 3;
- ent->HighWord.Bits.Pres = 1;
- ent->HighWord.Bits.Type = flags;
- ent->HighWord.Bits.Sys = 0;
- ent->HighWord.Bits.Reserved_0 = 0;
- ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
-}
-static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
-{
- unsigned char ret = ent->HighWord.Bits.Type;
- if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
- return ret;
-}
-static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
-{
- const DWORD *dw = (const DWORD *)ent;
- return (dw[0] | dw[1]) == 0;
-}
-
#ifdef __linux__
#ifdef HAVE_SYS_SYSCALL_H
@@ -164,6 +102,13 @@ static inline int set_thread_area( struct modify_ldt_s *ptr )
#include <i386/user_ldt.h>
#endif
+/* local copy of the LDT */
+#ifdef __APPLE__
+struct __wine_ldt_copy wine_ldt_copy = { { 0, 0, 0 } };
+#else
+struct __wine_ldt_copy wine_ldt_copy;
+#endif
+
static const LDT_ENTRY null_entry; /* all-zeros, used to clear LDT entries */
#define LDT_FIRST_ENTRY 512
@@ -183,7 +128,7 @@ static inline int is_gdt_sel( unsigned short sel ) { return !(sel & 4); }
*
* Set the LDT locking/unlocking functions.
*/
-void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func)(void) )
+void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) )
{
lock_ldt = lock_func;
unlock_ldt = unlock_func;
@@ -195,7 +140,7 @@ void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func
*
* Retrieve an LDT entry. Return a null entry if selector is not allocated.
*/
-void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
+void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry )
{
int index = sel >> 3;
@@ -205,11 +150,11 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
return;
}
lock_ldt();
- if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
+ if (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
- wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
- wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
+ wine_ldt_set_base( entry, wine_ldt_copy.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
@@ -274,9 +219,9 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
if (ret >= 0)
{
- wine_ldt_copy_obsolete.base[index] = wine_ldt_get_base(entry);
- wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
- wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
+ wine_ldt_copy.base[index] = wine_ldt_get_base(entry);
+ wine_ldt_copy.limit[index] = wine_ldt_get_limit(entry);
+ wine_ldt_copy.flags[index] = (entry->HighWord.Bits.Type |
(entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
WINE_LDT_FLAGS_ALLOCATED);
}
@@ -289,7 +234,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
*
* Set an LDT entry.
*/
-int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
int ret;
@@ -305,7 +250,7 @@ int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Check if the selector is a system selector (i.e. not managed by Wine).
*/
-int wine_ldt_is_system_obsolete( unsigned short sel )
+int wine_ldt_is_system( unsigned short sel )
{
return is_gdt_sel(sel) || ((sel >> 3) < LDT_FIRST_ENTRY);
}
@@ -317,7 +262,7 @@ int wine_ldt_is_system_obsolete( unsigned short sel )
* Convert a segment:offset pair to a linear pointer.
* Note: we don't lock the LDT since this has to be fast.
*/
-void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
+void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset )
{
int index;
@@ -325,8 +270,8 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
return (void *)offset;
if ((index = (sel >> 3)) < LDT_FIRST_ENTRY) /* system selector */
return (void *)offset;
- if (!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
- return (char *)wine_ldt_copy_obsolete.base[index] + offset;
+ if (!(wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
+ return (char *)wine_ldt_copy.base[index] + offset;
}
@@ -336,7 +281,7 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
* Allocate a number of consecutive ldt entries, without setting the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_alloc_entries_obsolete( int count )
+unsigned short wine_ldt_alloc_entries( int count )
{
int i, index, size = 0;
@@ -344,13 +289,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
lock_ldt();
for (i = LDT_FIRST_ENTRY; i < LDT_SIZE; i++)
{
- if (wine_ldt_copy_obsolete.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
+ if (wine_ldt_copy.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
else if (++size >= count) /* found a large enough block */
{
index = i - size + 1;
/* mark selectors as allocated */
- for (i = 0; i < count; i++) wine_ldt_copy_obsolete.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
+ for (i = 0; i < count; i++) wine_ldt_copy.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
unlock_ldt();
return (index << 3) | 7;
}
@@ -360,15 +305,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
}
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count );
-
/***********************************************************************
* wine_ldt_realloc_entries
*
* Reallocate a number of consecutive ldt entries, without changing the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcount, int newcount )
+unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount )
{
int i;
@@ -381,23 +324,23 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
if (index + newcount > LDT_SIZE) i = oldcount;
else
for (i = oldcount; i < newcount; i++)
- if (wine_ldt_copy_obsolete.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
+ if (wine_ldt_copy.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
if (i < newcount) /* they are not free */
{
- wine_ldt_free_entries_obsolete( sel, oldcount );
- sel = wine_ldt_alloc_entries_obsolete( newcount );
+ wine_ldt_free_entries( sel, oldcount );
+ sel = wine_ldt_alloc_entries( newcount );
}
else /* mark the selectors as allocated */
{
for (i = oldcount; i < newcount; i++)
- wine_ldt_copy_obsolete.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
+ wine_ldt_copy.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
}
unlock_ldt();
}
else if (oldcount > newcount) /* we need to remove selectors */
{
- wine_ldt_free_entries_obsolete( sel + (newcount << 3), newcount - oldcount );
+ wine_ldt_free_entries( sel + (newcount << 3), newcount - oldcount );
}
return sel;
}
@@ -408,7 +351,7 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
*
* Free a number of consecutive ldt entries and clear their contents.
*/
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
+void wine_ldt_free_entries( unsigned short sel, int count )
{
int index;
@@ -416,7 +359,7 @@ void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
for (index = sel >> 3; count > 0; count--, index++)
{
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[index] = 0;
+ wine_ldt_copy.flags[index] = 0;
}
unlock_ldt();
}
@@ -430,7 +373,7 @@ static int global_fs_sel = -1; /* global selector for %fs shared among all thre
* Allocate an LDT entry for a %fs selector, reusing a global
* GDT selector if possible. Return the selector value.
*/
-unsigned short wine_ldt_alloc_fs_obsolete(void)
+unsigned short wine_ldt_alloc_fs(void)
{
if (global_fs_sel == -1)
{
@@ -457,7 +400,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
#endif
}
if (global_fs_sel > 0) return global_fs_sel;
- return wine_ldt_alloc_entries_obsolete( 1 );
+ return wine_ldt_alloc_entries( 1 );
}
@@ -469,7 +412,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
*
* Note: this runs in the context of the new thread, so cannot acquire locks.
*/
-void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry )
{
if ((sel & ~3) == (global_fs_sel & ~3))
{
@@ -497,7 +440,7 @@ void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Free a %fs selector returned by wine_ldt_alloc_fs.
*/
-void wine_ldt_free_fs_obsolete( unsigned short sel )
+void wine_ldt_free_fs( unsigned short sel )
{
WORD fs;
@@ -508,46 +451,22 @@ void wine_ldt_free_fs_obsolete( unsigned short sel )
/* FIXME: if freeing current %fs we cannot acquire locks */
__asm__( "mov %0,%%fs" :: "r" (0) );
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[sel >> 3] = 0;
+ wine_ldt_copy.flags[sel >> 3] = 0;
}
- else wine_ldt_free_entries_obsolete( sel, 1 );
+ else wine_ldt_free_entries( sel, 1 );
}
/***********************************************************************
* selector access functions
*/
-__ASM_GLOBAL_FUNC( wine_get_cs_obsolete, "movw %cs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ds_obsolete, "movw %ds,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_es_obsolete, "movw %es,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_fs_obsolete, "movw %fs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_gs_obsolete, "movw %gs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ss_obsolete, "movw %ss,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_fs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_gs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
-
-
-__ASM_OBSOLETE(wine_ldt_alloc_entries);
-__ASM_OBSOLETE(wine_ldt_alloc_fs);
-__ASM_OBSOLETE(wine_ldt_copy);
-__ASM_OBSOLETE(wine_ldt_free_entries);
-__ASM_OBSOLETE(wine_ldt_free_fs);
-__ASM_OBSOLETE(wine_ldt_get_entry);
-__ASM_OBSOLETE(wine_ldt_get_ptr);
-__ASM_OBSOLETE(wine_ldt_init_fs);
-__ASM_OBSOLETE(wine_ldt_init_locking);
-__ASM_OBSOLETE(wine_ldt_is_system);
-__ASM_OBSOLETE(wine_ldt_realloc_entries);
-__ASM_OBSOLETE(wine_ldt_set_entry);
-__ASM_OBSOLETE(wine_get_cs);
-__ASM_OBSOLETE(wine_get_ds);
-__ASM_OBSOLETE(wine_get_es);
-__ASM_OBSOLETE(wine_get_fs);
-__ASM_OBSOLETE(wine_get_gs);
-__ASM_OBSOLETE(wine_get_ss);
-__ASM_OBSOLETE(wine_set_fs);
-__ASM_OBSOLETE(wine_set_gs);
-
-#endif /* __ASM_OBSOLETE */
+__ASM_GLOBAL_FUNC( wine_get_cs, "movw %cs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ds, "movw %ds,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
#endif /* __i386__ */
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 7ea849b908..3f2c430fa8 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -18,21 +18,41 @@ WINE_1.0
wine_get_build_dir;
wine_get_build_id;
wine_get_config_dir;
+ wine_get_cs;
wine_get_data_dir;
+ wine_get_ds;
+ wine_get_es;
+ wine_get_fs;
+ wine_get_gs;
wine_get_server_dir;
+ wine_get_ss;
wine_get_user_name;
wine_get_version;
wine_get_patches;
wine_init;
wine_init_argv0_path;
+ wine_ldt_alloc_entries;
+ wine_ldt_alloc_fs;
+ wine_ldt_copy;
+ wine_ldt_free_entries;
+ wine_ldt_free_fs;
+ wine_ldt_get_entry;
+ wine_ldt_get_ptr;
+ wine_ldt_init_fs;
+ wine_ldt_init_locking;
+ wine_ldt_is_system;
+ wine_ldt_realloc_entries;
+ wine_ldt_set_entry;
wine_mmap_add_reserved_area;
wine_mmap_enum_reserved_areas;
wine_mmap_is_in_reserved_area;
wine_mmap_remove_reserved_area;
wine_mmap_add_free_area;
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_fs;
+ wine_set_gs;
wine_wctype_table;
/* the following functions are obsolete and only exported for backwards compatibility */
@@ -93,30 +113,10 @@ WINE_1.0
wine_dll_load_main_exe;
wine_dll_unload;
wine_fold_string;
- wine_get_cs;
- wine_get_ds;
- wine_get_es;
- wine_get_fs;
- wine_get_gs;
wine_get_sortkey;
- wine_get_ss;
wine_is_dbcs_leadbyte;
- wine_ldt_alloc_entries;
- wine_ldt_alloc_fs;
- wine_ldt_copy;
- wine_ldt_free_entries;
- wine_ldt_free_fs;
- wine_ldt_get_entry;
- wine_ldt_get_ptr;
- wine_ldt_init_fs;
- wine_ldt_init_locking;
- wine_ldt_is_system;
- wine_ldt_realloc_entries;
- wine_ldt_set_entry;
wine_pthread_get_functions;
wine_pthread_set_functions;
- wine_set_fs;
- wine_set_gs;
wine_switch_to_stack;
wine_utf8_mbstowcs;
wine_utf8_wcstombs;
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) || !ldt_is_system(SS_sig(sigcontext)))
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_es();
FS_sig(sigcontext) = get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;

View File

@ -0,0 +1,688 @@
From 834e7d5da1ff024429c3e8b84ab7201babdd7ebf Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Sat, 4 Apr 2020 13:05:43 +0200
Subject: Revert "libwine: Make the LDT functions obsolete."
This reverts commit 3b16f35413f3a6641df42b782ead294f343e7d5e.
diff --git a/include/wine/library.h b/include/wine/library.h
index f338c4da19..a6fe28059f 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -76,6 +76,116 @@ extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
extern int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg),
void *arg, int top_down );
+#ifdef __i386__
+
+/* LDT management */
+
+extern void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) );
+extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
+extern int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry );
+extern int wine_ldt_is_system( unsigned short sel );
+extern void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset );
+extern unsigned short wine_ldt_alloc_entries( int count );
+extern unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount );
+extern void wine_ldt_free_entries( unsigned short sel, int count );
+extern unsigned short wine_ldt_alloc_fs(void);
+extern void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry );
+extern void wine_ldt_free_fs( unsigned short sel );
+
+/* the local copy of the LDT */
+extern struct __wine_ldt_copy
+{
+ void *base[8192]; /* base address or 0 if entry is free */
+ unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
+ unsigned char flags[8192]; /* flags (defined below) */
+} wine_ldt_copy;
+
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
+#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
+#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
+static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
+{
+ return (void *)(ent->BaseLow |
+ (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
+ (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
+}
+static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
+{
+ unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
+ if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
+ return limit;
+}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
+
+/* segment register access */
+
+# if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
+# define __DEFINE_GET_SEG(seg) \
+ static FORCEINLINE unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm__ __volatile__("movw %%" #seg ",%w0" : "=r"(res)); return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static FORCEINLINE void wine_set_##seg(int val) \
+ { __asm__("movw %w0,%%" #seg : : "r" (val)); }
+# elif defined(_MSC_VER)
+# define __DEFINE_GET_SEG(seg) \
+ static inline unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm { mov res, seg } return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static inline void wine_set_##seg(unsigned short val) { __asm { mov seg, val } }
+# else /* __GNUC__ || _MSC_VER */
+# define __DEFINE_GET_SEG(seg) extern unsigned short wine_get_##seg(void);
+# define __DEFINE_SET_SEG(seg) extern void wine_set_##seg(unsigned int);
+# endif /* __GNUC__ || _MSC_VER */
+
+__DEFINE_GET_SEG(cs)
+__DEFINE_GET_SEG(ds)
+__DEFINE_GET_SEG(es)
+__DEFINE_GET_SEG(fs)
+__DEFINE_GET_SEG(gs)
+__DEFINE_GET_SEG(ss)
+__DEFINE_SET_SEG(fs)
+__DEFINE_SET_SEG(gs)
+#undef __DEFINE_GET_SEG
+#undef __DEFINE_SET_SEG
+
+#endif /* __i386__ */
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index a8f4925019..5fabd1968d 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -31,73 +31,11 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/library.h"
#include "wine/asm.h"
#ifdef __i386__
-#ifdef __ASM_OBSOLETE
-
-/* the local copy of the LDT */
-struct __wine_ldt_copy
-{
- void *base[8192]; /* base address or 0 if entry is free */
- unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
- unsigned char flags[8192]; /* flags (defined below) */
-} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
-
-#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
-#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
-#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
-#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
-#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
-#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
-
-/* helper functions to manipulate the LDT_ENTRY structure */
-static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
-{
- ent->BaseLow = (WORD)(ULONG_PTR)base;
- ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
- ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
-}
-static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
-{
- if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- ent->LimitLow = (WORD)limit;
- ent->HighWord.Bits.LimitHi = (limit >> 16);
-}
-static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
-{
- return (void *)(ent->BaseLow |
- (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
- (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
-}
-static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
-{
- unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
- if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
- return limit;
-}
-static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
-{
- ent->HighWord.Bits.Dpl = 3;
- ent->HighWord.Bits.Pres = 1;
- ent->HighWord.Bits.Type = flags;
- ent->HighWord.Bits.Sys = 0;
- ent->HighWord.Bits.Reserved_0 = 0;
- ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
-}
-static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
-{
- unsigned char ret = ent->HighWord.Bits.Type;
- if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
- return ret;
-}
-static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
-{
- const DWORD *dw = (const DWORD *)ent;
- return (dw[0] | dw[1]) == 0;
-}
-
#ifdef __linux__
#ifdef HAVE_SYS_SYSCALL_H
@@ -164,6 +102,13 @@ static inline int set_thread_area( struct modify_ldt_s *ptr )
#include <i386/user_ldt.h>
#endif
+/* local copy of the LDT */
+#ifdef __APPLE__
+struct __wine_ldt_copy wine_ldt_copy = { { 0, 0, 0 } };
+#else
+struct __wine_ldt_copy wine_ldt_copy;
+#endif
+
static const LDT_ENTRY null_entry; /* all-zeros, used to clear LDT entries */
#define LDT_FIRST_ENTRY 512
@@ -183,7 +128,7 @@ static inline int is_gdt_sel( unsigned short sel ) { return !(sel & 4); }
*
* Set the LDT locking/unlocking functions.
*/
-void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func)(void) )
+void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) )
{
lock_ldt = lock_func;
unlock_ldt = unlock_func;
@@ -195,7 +140,7 @@ void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func
*
* Retrieve an LDT entry. Return a null entry if selector is not allocated.
*/
-void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
+void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry )
{
int index = sel >> 3;
@@ -205,11 +150,11 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
return;
}
lock_ldt();
- if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
+ if (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
- wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
- wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
+ wine_ldt_set_base( entry, wine_ldt_copy.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
@@ -274,9 +219,9 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
if (ret >= 0)
{
- wine_ldt_copy_obsolete.base[index] = wine_ldt_get_base(entry);
- wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
- wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
+ wine_ldt_copy.base[index] = wine_ldt_get_base(entry);
+ wine_ldt_copy.limit[index] = wine_ldt_get_limit(entry);
+ wine_ldt_copy.flags[index] = (entry->HighWord.Bits.Type |
(entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
WINE_LDT_FLAGS_ALLOCATED);
}
@@ -289,7 +234,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
*
* Set an LDT entry.
*/
-int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
int ret;
@@ -305,7 +250,7 @@ int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Check if the selector is a system selector (i.e. not managed by Wine).
*/
-int wine_ldt_is_system_obsolete( unsigned short sel )
+int wine_ldt_is_system( unsigned short sel )
{
return is_gdt_sel(sel) || ((sel >> 3) < LDT_FIRST_ENTRY);
}
@@ -317,7 +262,7 @@ int wine_ldt_is_system_obsolete( unsigned short sel )
* Convert a segment:offset pair to a linear pointer.
* Note: we don't lock the LDT since this has to be fast.
*/
-void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
+void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset )
{
int index;
@@ -325,8 +270,8 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
return (void *)offset;
if ((index = (sel >> 3)) < LDT_FIRST_ENTRY) /* system selector */
return (void *)offset;
- if (!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
- return (char *)wine_ldt_copy_obsolete.base[index] + offset;
+ if (!(wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
+ return (char *)wine_ldt_copy.base[index] + offset;
}
@@ -336,7 +281,7 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
* Allocate a number of consecutive ldt entries, without setting the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_alloc_entries_obsolete( int count )
+unsigned short wine_ldt_alloc_entries( int count )
{
int i, index, size = 0;
@@ -344,13 +289,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
lock_ldt();
for (i = LDT_FIRST_ENTRY; i < LDT_SIZE; i++)
{
- if (wine_ldt_copy_obsolete.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
+ if (wine_ldt_copy.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
else if (++size >= count) /* found a large enough block */
{
index = i - size + 1;
/* mark selectors as allocated */
- for (i = 0; i < count; i++) wine_ldt_copy_obsolete.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
+ for (i = 0; i < count; i++) wine_ldt_copy.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
unlock_ldt();
return (index << 3) | 7;
}
@@ -360,15 +305,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
}
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count );
-
/***********************************************************************
* wine_ldt_realloc_entries
*
* Reallocate a number of consecutive ldt entries, without changing the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcount, int newcount )
+unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount )
{
int i;
@@ -381,23 +324,23 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
if (index + newcount > LDT_SIZE) i = oldcount;
else
for (i = oldcount; i < newcount; i++)
- if (wine_ldt_copy_obsolete.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
+ if (wine_ldt_copy.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
if (i < newcount) /* they are not free */
{
- wine_ldt_free_entries_obsolete( sel, oldcount );
- sel = wine_ldt_alloc_entries_obsolete( newcount );
+ wine_ldt_free_entries( sel, oldcount );
+ sel = wine_ldt_alloc_entries( newcount );
}
else /* mark the selectors as allocated */
{
for (i = oldcount; i < newcount; i++)
- wine_ldt_copy_obsolete.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
+ wine_ldt_copy.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
}
unlock_ldt();
}
else if (oldcount > newcount) /* we need to remove selectors */
{
- wine_ldt_free_entries_obsolete( sel + (newcount << 3), newcount - oldcount );
+ wine_ldt_free_entries( sel + (newcount << 3), newcount - oldcount );
}
return sel;
}
@@ -408,7 +351,7 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
*
* Free a number of consecutive ldt entries and clear their contents.
*/
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
+void wine_ldt_free_entries( unsigned short sel, int count )
{
int index;
@@ -416,7 +359,7 @@ void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
for (index = sel >> 3; count > 0; count--, index++)
{
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[index] = 0;
+ wine_ldt_copy.flags[index] = 0;
}
unlock_ldt();
}
@@ -430,7 +373,7 @@ static int global_fs_sel = -1; /* global selector for %fs shared among all thre
* Allocate an LDT entry for a %fs selector, reusing a global
* GDT selector if possible. Return the selector value.
*/
-unsigned short wine_ldt_alloc_fs_obsolete(void)
+unsigned short wine_ldt_alloc_fs(void)
{
if (global_fs_sel == -1)
{
@@ -457,7 +400,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
#endif
}
if (global_fs_sel > 0) return global_fs_sel;
- return wine_ldt_alloc_entries_obsolete( 1 );
+ return wine_ldt_alloc_entries( 1 );
}
@@ -469,7 +412,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
*
* Note: this runs in the context of the new thread, so cannot acquire locks.
*/
-void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry )
{
if ((sel & ~3) == (global_fs_sel & ~3))
{
@@ -497,7 +440,7 @@ void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Free a %fs selector returned by wine_ldt_alloc_fs.
*/
-void wine_ldt_free_fs_obsolete( unsigned short sel )
+void wine_ldt_free_fs( unsigned short sel )
{
WORD fs;
@@ -508,46 +451,22 @@ void wine_ldt_free_fs_obsolete( unsigned short sel )
/* FIXME: if freeing current %fs we cannot acquire locks */
__asm__( "mov %0,%%fs" :: "r" (0) );
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[sel >> 3] = 0;
+ wine_ldt_copy.flags[sel >> 3] = 0;
}
- else wine_ldt_free_entries_obsolete( sel, 1 );
+ else wine_ldt_free_entries( sel, 1 );
}
/***********************************************************************
* selector access functions
*/
-__ASM_GLOBAL_FUNC( wine_get_cs_obsolete, "movw %cs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ds_obsolete, "movw %ds,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_es_obsolete, "movw %es,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_fs_obsolete, "movw %fs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_gs_obsolete, "movw %gs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ss_obsolete, "movw %ss,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_fs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_gs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
-
-
-__ASM_OBSOLETE(wine_ldt_alloc_entries);
-__ASM_OBSOLETE(wine_ldt_alloc_fs);
-__ASM_OBSOLETE(wine_ldt_copy);
-__ASM_OBSOLETE(wine_ldt_free_entries);
-__ASM_OBSOLETE(wine_ldt_free_fs);
-__ASM_OBSOLETE(wine_ldt_get_entry);
-__ASM_OBSOLETE(wine_ldt_get_ptr);
-__ASM_OBSOLETE(wine_ldt_init_fs);
-__ASM_OBSOLETE(wine_ldt_init_locking);
-__ASM_OBSOLETE(wine_ldt_is_system);
-__ASM_OBSOLETE(wine_ldt_realloc_entries);
-__ASM_OBSOLETE(wine_ldt_set_entry);
-__ASM_OBSOLETE(wine_get_cs);
-__ASM_OBSOLETE(wine_get_ds);
-__ASM_OBSOLETE(wine_get_es);
-__ASM_OBSOLETE(wine_get_fs);
-__ASM_OBSOLETE(wine_get_gs);
-__ASM_OBSOLETE(wine_get_ss);
-__ASM_OBSOLETE(wine_set_fs);
-__ASM_OBSOLETE(wine_set_gs);
-
-#endif /* __ASM_OBSOLETE */
+__ASM_GLOBAL_FUNC( wine_get_cs, "movw %cs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ds, "movw %ds,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
#endif /* __i386__ */
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 7ea849b908..3f2c430fa8 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -18,22 +18,42 @@ WINE_1.0
wine_get_build_dir;
wine_get_build_id;
wine_get_config_dir;
+ wine_get_cs;
wine_get_data_dir;
wine_get_libs;
+ wine_get_ds;
+ wine_get_es;
+ wine_get_fs;
+ wine_get_gs;
wine_get_server_dir;
+ wine_get_ss;
wine_get_user_name;
wine_get_version;
wine_get_patches;
wine_init;
wine_init_argv0_path;
+ wine_ldt_alloc_entries;
+ wine_ldt_alloc_fs;
+ wine_ldt_copy;
+ wine_ldt_free_entries;
+ wine_ldt_free_fs;
+ wine_ldt_get_entry;
+ wine_ldt_get_ptr;
+ wine_ldt_init_fs;
+ wine_ldt_init_locking;
+ wine_ldt_is_system;
+ wine_ldt_realloc_entries;
+ wine_ldt_set_entry;
wine_mmap_add_reserved_area;
wine_mmap_enum_reserved_areas;
wine_mmap_is_in_reserved_area;
wine_mmap_remove_reserved_area;
wine_mmap_add_free_area;
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_fs;
+ wine_set_gs;
wine_wctype_table;
/* the following functions are obsolete and only exported for backwards compatibility */
@@ -93,30 +113,10 @@ WINE_1.0
wine_dll_load_main_exe;
wine_dll_unload;
wine_fold_string;
- wine_get_cs;
- wine_get_ds;
- wine_get_es;
- wine_get_fs;
- wine_get_gs;
wine_get_sortkey;
- wine_get_ss;
wine_is_dbcs_leadbyte;
- wine_ldt_alloc_entries;
- wine_ldt_alloc_fs;
- wine_ldt_copy;
- wine_ldt_free_entries;
- wine_ldt_free_fs;
- wine_ldt_get_entry;
- wine_ldt_get_ptr;
- wine_ldt_init_fs;
- wine_ldt_init_locking;
- wine_ldt_is_system;
- wine_ldt_realloc_entries;
- wine_ldt_set_entry;
wine_pthread_get_functions;
wine_pthread_set_functions;
- wine_set_fs;
- wine_set_gs;
wine_switch_to_stack;
wine_utf8_mbstowcs;
wine_utf8_wcstombs;
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) || !ldt_is_system(SS_sig(sigcontext)))
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_es();
FS_sig(sigcontext) = get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;

View File

@ -0,0 +1,120 @@
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) ||
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
{
/*
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!wine_ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!wine_ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = wine_get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = wine_get_ds();
ES_sig(sigcontext) = wine_get_es();
FS_sig(sigcontext) = wine_get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;

View File

@ -0,0 +1,778 @@
From 834e7d5da1ff024429c3e8b84ab7201babdd7ebf Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Thu, 9 Apr 2020 12:20:12 +0200
Subject: Revert "libwine: Remove some no longer needed helper functions."
This reverts commit 18273d5e71e25575bdbdba1d252df72be3373f6d.
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index a8f4925019b..18b0b9be9bf 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -45,9 +45,26 @@ struct __wine_ldt_copy
unsigned char flags[8192]; /* flags (defined below) */
} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
{
return (void *)(ent->BaseLow |
@@ -77,6 +60,26 @@ static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
return limit;
}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
#ifdef __linux__
@@ -207,21 +170,9 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
lock_ldt();
if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
+ wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
- ULONG_PTR base = (ULONG_PTR)wine_ldt_copy_obsolete.base[index];
- ULONG limit = wine_ldt_copy_obsolete.limit[index];
-
- entry->BaseLow = (WORD)base;
- entry->HighWord.Bits.BaseMid = (BYTE)(base >> 16);
- entry->HighWord.Bits.BaseHi = (BYTE)(base >> 24);
- if ((entry->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- entry->LimitLow = (WORD)limit;
- entry->HighWord.Bits.LimitHi = (limit >> 16);
- entry->HighWord.Bits.Dpl = 3;
- entry->HighWord.Bits.Pres = 1;
- entry->HighWord.Bits.Type = wine_ldt_copy_obsolete.flags[index];
- entry->HighWord.Bits.Sys = 0;
- entry->HighWord.Bits.Reserved_0 = 0;
- entry->HighWord.Bits.Default_Big = !!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT);
}
else *entry = null_entry;
unlock_ldt();
From 834e7d5da1ff024429c3e8b84ab7201babdd7ebf Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Sat, 4 Apr 2020 13:05:43 +0200
Subject: Revert "libwine: Make the LDT functions obsolete."
This reverts commit 3b16f35413f3a6641df42b782ead294f343e7d5e.
diff --git a/include/wine/library.h b/include/wine/library.h
index f338c4da19..a6fe28059f 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -76,6 +76,116 @@ extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
extern int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg),
void *arg, int top_down );
+#ifdef __i386__
+
+/* LDT management */
+
+extern void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) );
+extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
+extern int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry );
+extern int wine_ldt_is_system( unsigned short sel );
+extern void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset );
+extern unsigned short wine_ldt_alloc_entries( int count );
+extern unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount );
+extern void wine_ldt_free_entries( unsigned short sel, int count );
+extern unsigned short wine_ldt_alloc_fs(void);
+extern void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry );
+extern void wine_ldt_free_fs( unsigned short sel );
+
+/* the local copy of the LDT */
+extern struct __wine_ldt_copy
+{
+ void *base[8192]; /* base address or 0 if entry is free */
+ unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
+ unsigned char flags[8192]; /* flags (defined below) */
+} wine_ldt_copy;
+
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
+#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
+#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
+static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
+{
+ return (void *)(ent->BaseLow |
+ (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
+ (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
+}
+static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
+{
+ unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
+ if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
+ return limit;
+}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
+
+/* segment register access */
+
+# if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
+# define __DEFINE_GET_SEG(seg) \
+ static FORCEINLINE unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm__ __volatile__("movw %%" #seg ",%w0" : "=r"(res)); return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static FORCEINLINE void wine_set_##seg(int val) \
+ { __asm__("movw %w0,%%" #seg : : "r" (val)); }
+# elif defined(_MSC_VER)
+# define __DEFINE_GET_SEG(seg) \
+ static inline unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm { mov res, seg } return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static inline void wine_set_##seg(unsigned short val) { __asm { mov seg, val } }
+# else /* __GNUC__ || _MSC_VER */
+# define __DEFINE_GET_SEG(seg) extern unsigned short wine_get_##seg(void);
+# define __DEFINE_SET_SEG(seg) extern void wine_set_##seg(unsigned int);
+# endif /* __GNUC__ || _MSC_VER */
+
+__DEFINE_GET_SEG(cs)
+__DEFINE_GET_SEG(ds)
+__DEFINE_GET_SEG(es)
+__DEFINE_GET_SEG(fs)
+__DEFINE_GET_SEG(gs)
+__DEFINE_GET_SEG(ss)
+__DEFINE_SET_SEG(fs)
+__DEFINE_SET_SEG(gs)
+#undef __DEFINE_GET_SEG
+#undef __DEFINE_SET_SEG
+
+#endif /* __i386__ */
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index a8f4925019..5fabd1968d 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -31,73 +31,11 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/library.h"
#include "wine/asm.h"
#ifdef __i386__
-#ifdef __ASM_OBSOLETE
-
-/* the local copy of the LDT */
-struct __wine_ldt_copy
-{
- void *base[8192]; /* base address or 0 if entry is free */
- unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
- unsigned char flags[8192]; /* flags (defined below) */
-} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
-
-#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
-#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
-#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
-#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
-#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
-#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
-
-/* helper functions to manipulate the LDT_ENTRY structure */
-static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
-{
- ent->BaseLow = (WORD)(ULONG_PTR)base;
- ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
- ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
-}
-static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
-{
- if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- ent->LimitLow = (WORD)limit;
- ent->HighWord.Bits.LimitHi = (limit >> 16);
-}
-static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
-{
- return (void *)(ent->BaseLow |
- (ULONG_PTR)ent->HighWord.Bits.BaseMid << 16 |
- (ULONG_PTR)ent->HighWord.Bits.BaseHi << 24);
-}
-static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
-{
- unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
- if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
- return limit;
-}
-static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
-{
- ent->HighWord.Bits.Dpl = 3;
- ent->HighWord.Bits.Pres = 1;
- ent->HighWord.Bits.Type = flags;
- ent->HighWord.Bits.Sys = 0;
- ent->HighWord.Bits.Reserved_0 = 0;
- ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
-}
-static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
-{
- unsigned char ret = ent->HighWord.Bits.Type;
- if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
- return ret;
-}
-static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
-{
- const DWORD *dw = (const DWORD *)ent;
- return (dw[0] | dw[1]) == 0;
-}
-
#ifdef __linux__
#ifdef HAVE_SYS_SYSCALL_H
@@ -164,6 +102,13 @@ static inline int set_thread_area( struct modify_ldt_s *ptr )
#include <i386/user_ldt.h>
#endif
+/* local copy of the LDT */
+#ifdef __APPLE__
+struct __wine_ldt_copy wine_ldt_copy = { { 0, 0, 0 } };
+#else
+struct __wine_ldt_copy wine_ldt_copy;
+#endif
+
static const LDT_ENTRY null_entry; /* all-zeros, used to clear LDT entries */
#define LDT_FIRST_ENTRY 512
@@ -183,7 +128,7 @@ static inline int is_gdt_sel( unsigned short sel ) { return !(sel & 4); }
*
* Set the LDT locking/unlocking functions.
*/
-void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func)(void) )
+void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) )
{
lock_ldt = lock_func;
unlock_ldt = unlock_func;
@@ -195,7 +140,7 @@ void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func
*
* Retrieve an LDT entry. Return a null entry if selector is not allocated.
*/
-void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
+void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry )
{
int index = sel >> 3;
@@ -205,11 +150,11 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
return;
}
lock_ldt();
- if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
+ if (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
- wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
- wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
+ wine_ldt_set_base( entry, wine_ldt_copy.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
@@ -274,9 +219,9 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
if (ret >= 0)
{
- wine_ldt_copy_obsolete.base[index] = wine_ldt_get_base(entry);
- wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
- wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
+ wine_ldt_copy.base[index] = wine_ldt_get_base(entry);
+ wine_ldt_copy.limit[index] = wine_ldt_get_limit(entry);
+ wine_ldt_copy.flags[index] = (entry->HighWord.Bits.Type |
(entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
WINE_LDT_FLAGS_ALLOCATED);
}
@@ -289,7 +234,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
*
* Set an LDT entry.
*/
-int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
int ret;
@@ -305,7 +250,7 @@ int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Check if the selector is a system selector (i.e. not managed by Wine).
*/
-int wine_ldt_is_system_obsolete( unsigned short sel )
+int wine_ldt_is_system( unsigned short sel )
{
return is_gdt_sel(sel) || ((sel >> 3) < LDT_FIRST_ENTRY);
}
@@ -317,7 +262,7 @@ int wine_ldt_is_system_obsolete( unsigned short sel )
* Convert a segment:offset pair to a linear pointer.
* Note: we don't lock the LDT since this has to be fast.
*/
-void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
+void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset )
{
int index;
@@ -325,8 +270,8 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
return (void *)offset;
if ((index = (sel >> 3)) < LDT_FIRST_ENTRY) /* system selector */
return (void *)offset;
- if (!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
- return (char *)wine_ldt_copy_obsolete.base[index] + offset;
+ if (!(wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
+ return (char *)wine_ldt_copy.base[index] + offset;
}
@@ -336,7 +281,7 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
* Allocate a number of consecutive ldt entries, without setting the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_alloc_entries_obsolete( int count )
+unsigned short wine_ldt_alloc_entries( int count )
{
int i, index, size = 0;
@@ -344,13 +289,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
lock_ldt();
for (i = LDT_FIRST_ENTRY; i < LDT_SIZE; i++)
{
- if (wine_ldt_copy_obsolete.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
+ if (wine_ldt_copy.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
else if (++size >= count) /* found a large enough block */
{
index = i - size + 1;
/* mark selectors as allocated */
- for (i = 0; i < count; i++) wine_ldt_copy_obsolete.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
+ for (i = 0; i < count; i++) wine_ldt_copy.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
unlock_ldt();
return (index << 3) | 7;
}
@@ -360,15 +305,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
}
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count );
-
/***********************************************************************
* wine_ldt_realloc_entries
*
* Reallocate a number of consecutive ldt entries, without changing the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcount, int newcount )
+unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount )
{
int i;
@@ -381,23 +324,23 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
if (index + newcount > LDT_SIZE) i = oldcount;
else
for (i = oldcount; i < newcount; i++)
- if (wine_ldt_copy_obsolete.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
+ if (wine_ldt_copy.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
if (i < newcount) /* they are not free */
{
- wine_ldt_free_entries_obsolete( sel, oldcount );
- sel = wine_ldt_alloc_entries_obsolete( newcount );
+ wine_ldt_free_entries( sel, oldcount );
+ sel = wine_ldt_alloc_entries( newcount );
}
else /* mark the selectors as allocated */
{
for (i = oldcount; i < newcount; i++)
- wine_ldt_copy_obsolete.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
+ wine_ldt_copy.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
}
unlock_ldt();
}
else if (oldcount > newcount) /* we need to remove selectors */
{
- wine_ldt_free_entries_obsolete( sel + (newcount << 3), newcount - oldcount );
+ wine_ldt_free_entries( sel + (newcount << 3), newcount - oldcount );
}
return sel;
}
@@ -408,7 +351,7 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
*
* Free a number of consecutive ldt entries and clear their contents.
*/
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
+void wine_ldt_free_entries( unsigned short sel, int count )
{
int index;
@@ -416,7 +359,7 @@ void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
for (index = sel >> 3; count > 0; count--, index++)
{
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[index] = 0;
+ wine_ldt_copy.flags[index] = 0;
}
unlock_ldt();
}
@@ -430,7 +373,7 @@ static int global_fs_sel = -1; /* global selector for %fs shared among all thre
* Allocate an LDT entry for a %fs selector, reusing a global
* GDT selector if possible. Return the selector value.
*/
-unsigned short wine_ldt_alloc_fs_obsolete(void)
+unsigned short wine_ldt_alloc_fs(void)
{
if (global_fs_sel == -1)
{
@@ -457,7 +400,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
#endif
}
if (global_fs_sel > 0) return global_fs_sel;
- return wine_ldt_alloc_entries_obsolete( 1 );
+ return wine_ldt_alloc_entries( 1 );
}
@@ -469,7 +412,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
*
* Note: this runs in the context of the new thread, so cannot acquire locks.
*/
-void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry )
{
if ((sel & ~3) == (global_fs_sel & ~3))
{
@@ -497,7 +440,7 @@ void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Free a %fs selector returned by wine_ldt_alloc_fs.
*/
-void wine_ldt_free_fs_obsolete( unsigned short sel )
+void wine_ldt_free_fs( unsigned short sel )
{
WORD fs;
@@ -508,46 +451,22 @@ void wine_ldt_free_fs_obsolete( unsigned short sel )
/* FIXME: if freeing current %fs we cannot acquire locks */
__asm__( "mov %0,%%fs" :: "r" (0) );
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[sel >> 3] = 0;
+ wine_ldt_copy.flags[sel >> 3] = 0;
}
- else wine_ldt_free_entries_obsolete( sel, 1 );
+ else wine_ldt_free_entries( sel, 1 );
}
/***********************************************************************
* selector access functions
*/
-__ASM_GLOBAL_FUNC( wine_get_cs_obsolete, "movw %cs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ds_obsolete, "movw %ds,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_es_obsolete, "movw %es,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_fs_obsolete, "movw %fs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_gs_obsolete, "movw %gs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ss_obsolete, "movw %ss,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_fs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_gs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
-
-
-__ASM_OBSOLETE(wine_ldt_alloc_entries);
-__ASM_OBSOLETE(wine_ldt_alloc_fs);
-__ASM_OBSOLETE(wine_ldt_copy);
-__ASM_OBSOLETE(wine_ldt_free_entries);
-__ASM_OBSOLETE(wine_ldt_free_fs);
-__ASM_OBSOLETE(wine_ldt_get_entry);
-__ASM_OBSOLETE(wine_ldt_get_ptr);
-__ASM_OBSOLETE(wine_ldt_init_fs);
-__ASM_OBSOLETE(wine_ldt_init_locking);
-__ASM_OBSOLETE(wine_ldt_is_system);
-__ASM_OBSOLETE(wine_ldt_realloc_entries);
-__ASM_OBSOLETE(wine_ldt_set_entry);
-__ASM_OBSOLETE(wine_get_cs);
-__ASM_OBSOLETE(wine_get_ds);
-__ASM_OBSOLETE(wine_get_es);
-__ASM_OBSOLETE(wine_get_fs);
-__ASM_OBSOLETE(wine_get_gs);
-__ASM_OBSOLETE(wine_get_ss);
-__ASM_OBSOLETE(wine_set_fs);
-__ASM_OBSOLETE(wine_set_gs);
-
-#endif /* __ASM_OBSOLETE */
+__ASM_GLOBAL_FUNC( wine_get_cs, "movw %cs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ds, "movw %ds,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
#endif /* __i386__ */
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 7ea849b908..3f2c430fa8 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -18,18 +18,38 @@ WINE_1.0
wine_dll_set_callback;
wine_exec_wine_binary;
wine_get_build_id;
+ wine_get_cs;
+ wine_get_ds;
+ wine_get_es;
+ wine_get_fs;
+ wine_get_gs;
+ wine_get_ss;
wine_get_version;
wine_get_patches;
wine_init;
wine_init_argv0_path;
+ wine_ldt_alloc_entries;
+ wine_ldt_alloc_fs;
+ wine_ldt_copy;
+ wine_ldt_free_entries;
+ wine_ldt_free_fs;
+ wine_ldt_get_entry;
+ wine_ldt_get_ptr;
+ wine_ldt_init_fs;
+ wine_ldt_init_locking;
+ wine_ldt_is_system;
+ wine_ldt_realloc_entries;
+ wine_ldt_set_entry;
wine_mmap_add_reserved_area;
wine_mmap_enum_reserved_areas;
wine_mmap_is_in_reserved_area;
wine_mmap_remove_reserved_area;
wine_mmap_add_free_area;
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_fs;
+ wine_set_gs;
wine_wctype_table;
/* the following functions are obsolete and only exported for backwards compatibility */
@@ -93,33 +113,13 @@ WINE_1.0
wine_fold_string;
wine_get_build_dir;
wine_get_config_dir;
- wine_get_cs;
wine_get_data_dir;
- wine_get_ds;
- wine_get_es;
- wine_get_fs;
- wine_get_gs;
wine_get_server_dir;
wine_get_sortkey;
- wine_get_ss;
wine_get_user_name;
wine_is_dbcs_leadbyte;
- wine_ldt_alloc_entries;
- wine_ldt_alloc_fs;
- wine_ldt_copy;
- wine_ldt_free_entries;
- wine_ldt_free_fs;
- wine_ldt_get_entry;
- wine_ldt_get_ptr;
- wine_ldt_init_fs;
- wine_ldt_init_locking;
- wine_ldt_is_system;
- wine_ldt_realloc_entries;
- wine_ldt_set_entry;
wine_pthread_get_functions;
wine_pthread_set_functions;
- wine_set_fs;
- wine_set_gs;
wine_switch_to_stack;
wine_utf8_mbstowcs;
wine_utf8_wcstombs;
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) || !ldt_is_system(SS_sig(sigcontext)))
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_es();
FS_sig(sigcontext) = get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
status = STATUS_TOO_MANY_THREADS;
}
}
+
+ signal_init_cs();
+
return status;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -114,6 +114,7 @@ WINE_1.0
wine_mmap_enum_free_areas;
wine_mmap_is_in_free_area;
wine_mmap_remove_free_area;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;

View File

@ -0,0 +1,247 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
configure | 2 ++
configure.ac | 1 +
dlls/gfesdk/Makefile.in | 7 ++++
dlls/gfesdk/gfesdk.spec | 16 +++++++++
dlls/gfesdk/gfesdk_main.c | 70 ++++++++++++++++++++++++++++++++++++++
dlls/gfesdk/nvgsdk.h | 30 ++++++++++++++++
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/wbemprox/builtin.c | 8 +++--
dlls/ws2_32/Makefile.in | 1 +
9 files changed, 148 insertions(+), 22 deletions(-)
create mode 100644 dlls/gfesdk/Makefile.in
create mode 100644 dlls/gfesdk/gfesdk.spec
create mode 100644 dlls/gfesdk/gfesdk_main.c
create mode 100644 dlls/gfesdk/nvgsdk.h
diff --git a/configure b/configure
index 6c4a5f21b5d..0483ccfeda8 100755
--- a/configure
+++ b/configure
@@ -1343,6 +1342,7 @@ enable_fwpuclnt
enable_gameux
enable_gdi32
enable_gdiplus
+enable_gfesdk
enable_glu32
enable_gphoto2_ds
enable_gpkcsp
@@ -20623,6 +20612,7 @@ wine_fn_config_makefile dlls/gdi32 enable_gdi32
wine_fn_config_makefile dlls/gdi32/tests enable_tests
wine_fn_config_makefile dlls/gdiplus enable_gdiplus
wine_fn_config_makefile dlls/gdiplus/tests enable_tests
+wine_fn_config_makefile dlls/gfesdk enable_gfesdk
wine_fn_config_makefile dlls/glu32 enable_glu32
wine_fn_config_makefile dlls/gphoto2.ds enable_gphoto2_ds
wine_fn_config_makefile dlls/gpkcsp enable_gpkcsp
diff --git a/configure.ac b/configure.ac
index 37e3445a342..7700e998067 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3313,6 +3313,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 00000000000..339ccfd7e71
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 00000000000..816f5bc8aa3
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 00000000000..f0af7e7568d
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 00000000000..457f2340738
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2431,12 +2431,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)

View File

@ -0,0 +1,337 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
configure | 2 ++
configure.ac | 1 +
dlls/gfesdk/Makefile.in | 7 ++++
dlls/gfesdk/gfesdk.spec | 16 +++++++++
dlls/gfesdk/gfesdk_main.c | 70 ++++++++++++++++++++++++++++++++++++++
dlls/gfesdk/nvgsdk.h | 30 ++++++++++++++++
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/wbemprox/builtin.c | 8 +++--
dlls/ws2_32/Makefile.in | 1 +
9 files changed, 148 insertions(+), 22 deletions(-)
create mode 100644 dlls/gfesdk/Makefile.in
create mode 100644 dlls/gfesdk/gfesdk.spec
create mode 100644 dlls/gfesdk/gfesdk_main.c
create mode 100644 dlls/gfesdk/nvgsdk.h
diff --git a/configure b/configure
index 6c4a5f21b5d..0483ccfeda8 100755
--- a/configure
+++ b/configure
@@ -1343,6 +1342,7 @@ enable_fwpuclnt
enable_gameux
enable_gdi32
enable_gdiplus
+enable_gfesdk
enable_glu32
enable_gphoto2_ds
enable_gpkcsp
@@ -20623,6 +20612,7 @@ wine_fn_config_makefile dlls/gdi32 enable_gdi32
wine_fn_config_makefile dlls/gdi32/tests enable_tests
wine_fn_config_makefile dlls/gdiplus enable_gdiplus
wine_fn_config_makefile dlls/gdiplus/tests enable_tests
+wine_fn_config_makefile dlls/gfesdk enable_gfesdk
wine_fn_config_makefile dlls/glu32 enable_glu32
wine_fn_config_makefile dlls/gphoto2.ds enable_gphoto2_ds
wine_fn_config_makefile dlls/gpkcsp enable_gpkcsp
diff --git a/configure.ac b/configure.ac
index 37e3445a342..7700e998067 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3313,6 +3313,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 00000000000..339ccfd7e71
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 00000000000..816f5bc8aa3
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 00000000000..f0af7e7568d
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 00000000000..457f2340738
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2431,12 +2431,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 24badb7bf92..e5d8b2400aa 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -374,6 +374,7 @@ static const struct column col_sounddevice[] =
{ L"Name", CIM_STRING },
{ L"ProductName", CIM_STRING },
{ L"StatusInfo", CIM_UINT16 },
+ { L"Manufacturer", CIM_STRING },
};
static const struct column col_stdregprov[] =
{
@@ -759,6 +760,7 @@ struct record_sounddevice
const WCHAR *name;
const WCHAR *productname;
UINT16 statusinfo;
+ const WCHAR *manufacturer;
};
struct record_stdregprov
{
@@ -876,7 +878,7 @@ static const struct record_quickfixengineering data_quickfixengineering[] =
};
static const struct record_sounddevice data_sounddevice[] =
{
- { L"Wine Audio Device", L"Wine Audio Device", 3 /* enabled */ }
+ { L"Wine Audio Device", L"Wine Audio Device", 3 /* enabled */, L"The Wine Project" }
};
static const struct record_stdregprov data_stdregprov[] =
{
@@ -2868,7 +2870,7 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
rec->devicelocator = L"DIMM 0";
rec->formfactor = 8; /* DIMM */
rec->memorytype = 9; /* RAM */
- rec->partnumber = NULL;
+ rec->partnumber = L"BLS8G3D1609DS1S00";
rec->serial = NULL;
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
else row++;
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)
From f445a9f05e4ad097c55d690f08fd5f1e71940d79 Mon Sep 17 00:00:00 2001
From: Pnevmoslon <psn8402@gmail.com>
Date: Wed, 27 May 2020 12:23:59 +0300
Subject: [PATCH] mk11 gamepad fix
---
dlls/wbemprox/class.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/dlls/wbemprox/class.c b/dlls/wbemprox/class.c
index ba7720b098..6cc439c6fb 100644
--- a/dlls/wbemprox/class.c
+++ b/dlls/wbemprox/class.c
@@ -116,6 +116,7 @@ static HRESULT WINAPI enum_class_object_Next(
struct table *table;
static int once = 0;
HRESULT hr;
+ ULONG i;
TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
@@ -124,16 +125,18 @@ static HRESULT WINAPI enum_class_object_Next(
if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
*puReturned = 0;
- if (ec->index >= view->result_count) return WBEM_S_FALSE;
-
- table = get_view_table( view, ec->index );
- hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
- if (hr != S_OK) return hr;
-
- ec->index++;
- *puReturned = 1;
- if (ec->index == view->result_count && uCount > 1) return WBEM_S_FALSE;
- if (uCount > 1) return WBEM_S_TIMEDOUT;
+
+ for (i=0; i<uCount; ++i)
+ {
+ if (ec->index >= view->result_count) return WBEM_S_FALSE;
+ table = get_view_table( view, ec->index );
+ hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
+ if (hr != S_OK) return hr;
+
+ apObjects++;
+ ec->index++;
+ ++*puReturned;
+ }
return WBEM_S_NO_ERROR;
}
--
2.26.2

View File

@ -0,0 +1,76 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/ws2_32/Makefile.in | 1 +
3 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -425,6 +425,8 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
@@ -433,6 +435,13 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,5 +1,6 @@
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = dnsapi advapi32 iphlpapi user32
C_SRCS = \
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index b4b3981da0a..1ea738ce547 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -606,6 +797,14 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
RegCloseKey(hkey);
+ /* This is needed for MK11, but breaks Hitman 2, so we use a specific check for MK11 */
+ const char *sgi = getenv("SteamGameId");
+ if ((sgi && !strcmp(sgi, "976310"))) {
+ /* Create device key */
+ hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL);
+ RegCloseKey(hkey);
+ }
+
/* FIXME:
* Following properties are Wine specific, see comments in X11DRV_InitAdapter for details */
/* StateFlags */

View File

@ -0,0 +1,260 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
configure | 2 ++
configure.ac | 1 +
dlls/gfesdk/Makefile.in | 7 ++++
dlls/gfesdk/gfesdk.spec | 16 +++++++++
dlls/gfesdk/gfesdk_main.c | 70 ++++++++++++++++++++++++++++++++++++++
dlls/gfesdk/nvgsdk.h | 30 ++++++++++++++++
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/wbemprox/builtin.c | 8 +++--
dlls/ws2_32/Makefile.in | 1 +
9 files changed, 148 insertions(+), 22 deletions(-)
create mode 100644 dlls/gfesdk/Makefile.in
create mode 100644 dlls/gfesdk/gfesdk.spec
create mode 100644 dlls/gfesdk/gfesdk_main.c
create mode 100644 dlls/gfesdk/nvgsdk.h
diff --git a/configure b/configure
index 6c4a5f21b5d..0483ccfeda8 100755
--- a/configure
+++ b/configure
@@ -1343,6 +1342,7 @@ enable_fwpuclnt
enable_gameux
enable_gdi32
enable_gdiplus
+enable_gfesdk
enable_glu32
enable_gphoto2_ds
enable_gpkcsp
@@ -20623,6 +20612,7 @@ wine_fn_config_makefile dlls/gdi32 enable_gdi32
wine_fn_config_makefile dlls/gdi32/tests enable_tests
wine_fn_config_makefile dlls/gdiplus enable_gdiplus
wine_fn_config_makefile dlls/gdiplus/tests enable_tests
+wine_fn_config_makefile dlls/gfesdk enable_gfesdk
wine_fn_config_makefile dlls/glu32 enable_glu32
wine_fn_config_makefile dlls/gphoto2.ds enable_gphoto2_ds
wine_fn_config_makefile dlls/gpkcsp enable_gpkcsp
diff --git a/configure.ac b/configure.ac
index 37e3445a342..7700e998067 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3313,6 +3313,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 00000000000..339ccfd7e71
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 00000000000..816f5bc8aa3
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 00000000000..f0af7e7568d
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 00000000000..457f2340738
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2431,12 +2431,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 24badb7bf92..e5d8b2400aa 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -2868,7 +2870,7 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
rec->devicelocator = L"DIMM 0";
rec->formfactor = 8; /* DIMM */
rec->memorytype = 9; /* RAM */
- rec->partnumber = NULL;
+ rec->partnumber = L"BLS8G3D1609DS1S00";
rec->serial = NULL;
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
else row++;
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)

View File

@ -0,0 +1,292 @@
commit 585b6f89affa3482caee9bf17f20dad77dc82d07
Author: Derek Lesho <dlesho@codeweavers.com>
Date: Wed Oct 2 09:10:26 2019 -0500
Vincent's Changes
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 96d1e0b850..423d47bd24 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -792,7 +792,8 @@ static const struct column col_sounddevice[] =
{
{ prop_nameW, CIM_STRING },
{ prop_productnameW, CIM_STRING },
- { prop_statusinfoW, CIM_UINT16 }
+ { prop_statusinfoW, CIM_UINT16 },
+ { prop_manufacturerW, CIM_STRING }
};
static const struct column col_stdregprov[] =
{
@@ -933,6 +934,10 @@ static const WCHAR quickfixengineering_captionW[] =
{'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
static const WCHAR quickfixengineering_hotfixidW[] =
{'K','B','1','2','3','4','5','6','7',0};
+static const WCHAR physicalmemory_partnumberW[] =
+ {'B','L','S','8','G','3','D','1','6','0','9','D','S','1','S','0','0','.',0};
+static const WCHAR sounddevice_manufacturerW[] =
+ {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
static const WCHAR sounddevice_productnameW[] =
{'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
static const WCHAR systemenclosure_systemenclosureW[] =
@@ -1272,6 +1277,7 @@ struct record_sounddevice
const WCHAR *name;
const WCHAR *productname;
UINT16 statusinfo;
+ const WCHAR *manufacturer;
};
struct record_stdregprov
{
@@ -1388,7 +1394,7 @@ static const struct record_quickfixengineering data_quickfixengineering[] =
};
static const struct record_sounddevice data_sounddevice[] =
{
- { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ }
+ { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */, sounddevice_manufacturerW }
};
static const struct record_stdregprov data_stdregprov[] =
{
@@ -3349,11 +3355,11 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
rec = (struct record_physicalmemory *)table->data;
rec->capacity = get_total_physical_memory();
- rec->configuredclockspeed = 0;
+ rec->configuredclockspeed = 1600;
rec->devicelocator = dimm0W;
rec->formfactor = 8; /* DIMM */
rec->memorytype = 9; /* RAM */
- rec->partnumber = NULL;
+ rec->partnumber = physicalmemory_partnumberW;
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
else row++;
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3..c7f24168da 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)
commit f4d63311736e7a5db2e9c327a3fbbc21d8cf9c7c
Author: Derek Lesho <dlesho@codeweavers.com>
Date: Wed Oct 2 09:11:03 2019 -0500
gfesdk stub
diff --git a/configure.ac b/configure.ac
index b9339b90aa..81995b05a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3330,6 +3330,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 0000000000..339ccfd7e7
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 0000000000..816f5bc8aa
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 0000000000..f0af7e7568
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 0000000000..457f234073
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
From: Derek Lesho <dlesho@codeweavers.com>
Subject: [PATCH] ntdll: Only call wine handlers if they're in the same stack.
Message-Id: <20191002154547.878669-1-dlesho@codeweavers.com>
Date: Wed, 2 Oct 2019 10:45:47 -0500
In Mortal Kombat 11, the game creates its own stack, with an address higher
than the default wine stack. Because of this, when we unwind a C++ exception,
we assume we are inside a wine frame, and we crash trying to unwind to it.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/ntdll/signal_x86_64.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 427a4a0e05..8d6f351f4b 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2427,12 +2427,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2478,7 +2487,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
--
2.23.0

View File

@ -0,0 +1,76 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/ws2_32/Makefile.in | 1 +
3 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -425,6 +425,8 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
@@ -433,6 +435,13 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,5 +1,6 @@
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = advapi32 iphlpapi user32
EXTRALIBS = $(POLL_LIBS)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index b4b3981da0a..1ea738ce547 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -606,6 +797,14 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
RegCloseKey(hkey);
+ /* This is needed for MK11, but breaks Hitman 2, so we use a specific check for MK11 */
+ const char *sgi = getenv("SteamGameId");
+ if ((sgi && !strcmp(sgi, "976310"))) {
+ /* Create device key */
+ hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL);
+ RegCloseKey(hkey);
+ }
+
/* FIXME:
* Following properties are Wine specific, see comments in X11DRV_InitAdapter for details */
/* StateFlags */

View File

@ -0,0 +1,312 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
configure | 2 ++
configure.ac | 1 +
dlls/gfesdk/Makefile.in | 7 ++++
dlls/gfesdk/gfesdk.spec | 16 +++++++++
dlls/gfesdk/gfesdk_main.c | 70 ++++++++++++++++++++++++++++++++++++++
dlls/gfesdk/nvgsdk.h | 30 ++++++++++++++++
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/wbemprox/builtin.c | 8 +++--
dlls/ws2_32/Makefile.in | 1 +
9 files changed, 148 insertions(+), 22 deletions(-)
create mode 100644 dlls/gfesdk/Makefile.in
create mode 100644 dlls/gfesdk/gfesdk.spec
create mode 100644 dlls/gfesdk/gfesdk_main.c
create mode 100644 dlls/gfesdk/nvgsdk.h
diff --git a/configure b/configure
index 6c4a5f21b5d..0483ccfeda8 100755
--- a/configure
+++ b/configure
@@ -1343,6 +1342,7 @@ enable_fwpuclnt
enable_gameux
enable_gdi32
enable_gdiplus
+enable_gfesdk
enable_glu32
enable_gphoto2_ds
enable_gpkcsp
@@ -20623,6 +20612,7 @@ wine_fn_config_makefile dlls/gdi32 enable_gdi32
wine_fn_config_makefile dlls/gdi32/tests enable_tests
wine_fn_config_makefile dlls/gdiplus enable_gdiplus
wine_fn_config_makefile dlls/gdiplus/tests enable_tests
+wine_fn_config_makefile dlls/gfesdk enable_gfesdk
wine_fn_config_makefile dlls/glu32 enable_glu32
wine_fn_config_makefile dlls/gphoto2.ds enable_gphoto2_ds
wine_fn_config_makefile dlls/gpkcsp enable_gpkcsp
diff --git a/configure.ac b/configure.ac
index 37e3445a342..7700e998067 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3313,6 +3313,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 00000000000..339ccfd7e71
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 00000000000..816f5bc8aa3
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 00000000000..f0af7e7568d
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 00000000000..457f2340738
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2431,12 +2431,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 24badb7bf92..e5d8b2400aa 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -2868,7 +2870,7 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
rec->devicelocator = L"DIMM 0";
rec->formfactor = 8; /* DIMM */
rec->memorytype = 9; /* RAM */
- rec->partnumber = NULL;
+ rec->partnumber = L"BLS8G3D1609DS1S00";
rec->serial = NULL;
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
else row++;
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)
From f445a9f05e4ad097c55d690f08fd5f1e71940d79 Mon Sep 17 00:00:00 2001
From: Pnevmoslon <psn8402@gmail.com>
Date: Wed, 27 May 2020 12:23:59 +0300
Subject: [PATCH] mk11 gamepad fix
---
dlls/wbemprox/class.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/dlls/wbemprox/class.c b/dlls/wbemprox/class.c
index ba7720b098..6cc439c6fb 100644
--- a/dlls/wbemprox/class.c
+++ b/dlls/wbemprox/class.c
@@ -116,6 +116,7 @@ static HRESULT WINAPI enum_class_object_Next(
struct table *table;
static int once = 0;
HRESULT hr;
+ ULONG i;
TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
@@ -124,16 +125,18 @@ static HRESULT WINAPI enum_class_object_Next(
if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
*puReturned = 0;
- if (ec->index >= view->result_count) return WBEM_S_FALSE;
-
- table = get_view_table( view, ec->index );
- hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
- if (hr != S_OK) return hr;
-
- ec->index++;
- *puReturned = 1;
- if (ec->index == view->result_count && uCount > 1) return WBEM_S_FALSE;
- if (uCount > 1) return WBEM_S_TIMEDOUT;
+
+ for (i=0; i<uCount; ++i)
+ {
+ if (ec->index >= view->result_count) return WBEM_S_FALSE;
+ table = get_view_table( view, ec->index );
+ hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
+ if (hr != S_OK) return hr;
+
+ apObjects++;
+ ec->index++;
+ ++*puReturned;
+ }
return WBEM_S_NO_ERROR;
}
--
2.26.2

View File

@ -0,0 +1,58 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/ws2_32/Makefile.in | 1 +
3 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -425,6 +425,8 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
@@ -433,6 +435,13 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)

View File

@ -0,0 +1,344 @@
commit 585b6f89affa3482caee9bf17f20dad77dc82d07
Author: Derek Lesho <dlesho@codeweavers.com>
Date: Wed Oct 2 09:10:26 2019 -0500
Vincent's Changes
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 96d1e0b850..423d47bd24 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -792,7 +792,8 @@ static const struct column col_sounddevice[] =
{
{ prop_nameW, CIM_STRING },
{ prop_productnameW, CIM_STRING },
- { prop_statusinfoW, CIM_UINT16 }
+ { prop_statusinfoW, CIM_UINT16 },
+ { prop_manufacturerW, CIM_STRING }
};
static const struct column col_stdregprov[] =
{
@@ -933,6 +934,10 @@ static const WCHAR quickfixengineering_captionW[] =
{'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
static const WCHAR quickfixengineering_hotfixidW[] =
{'K','B','1','2','3','4','5','6','7',0};
+static const WCHAR physicalmemory_partnumberW[] =
+ {'B','L','S','8','G','3','D','1','6','0','9','D','S','1','S','0','0','.',0};
+static const WCHAR sounddevice_manufacturerW[] =
+ {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
static const WCHAR sounddevice_productnameW[] =
{'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
static const WCHAR systemenclosure_systemenclosureW[] =
@@ -1272,6 +1277,7 @@ struct record_sounddevice
const WCHAR *name;
const WCHAR *productname;
UINT16 statusinfo;
+ const WCHAR *manufacturer;
};
struct record_stdregprov
{
@@ -1388,7 +1394,7 @@ static const struct record_quickfixengineering data_quickfixengineering[] =
};
static const struct record_sounddevice data_sounddevice[] =
{
- { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ }
+ { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */, sounddevice_manufacturerW }
};
static const struct record_stdregprov data_stdregprov[] =
{
@@ -3349,10 +3355,10 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
rec = (struct record_physicalmemory *)table->data;
rec->capacity = get_total_physical_memory();
- rec->configuredclockspeed = 0;
+ rec->configuredclockspeed = 1600;
rec->devicelocator = dimm0W;
rec->memorytype = 9; /* RAM */
- rec->partnumber = NULL;
+ rec->partnumber = physicalmemory_partnumberW;
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
else row++;
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3..c7f24168da 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)
commit f4d63311736e7a5db2e9c327a3fbbc21d8cf9c7c
Author: Derek Lesho <dlesho@codeweavers.com>
Date: Wed Oct 2 09:11:03 2019 -0500
gfesdk stub
diff --git a/configure.ac b/configure.ac
index b9339b90aa..81995b05a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3330,6 +3330,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 0000000000..339ccfd7e7
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 0000000000..816f5bc8aa
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 0000000000..f0af7e7568
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 0000000000..457f234073
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
From: Derek Lesho <dlesho@codeweavers.com>
Subject: RFC: Limit addresses to 43 bits on 64-bit.
Message-Id: <20191002153838.878501-1-dlesho@codeweavers.com>
Date: Wed, 2 Oct 2019 10:38:38 -0500
Mortal Kombat 11 allocates memory, with zero_bits set to 0, and applies
a 43-bit mask on the pointer. This would have worked in Windows 7, as
MSDN says that 43-bits was the maximum pointer size, but the game
exhibits this same behavior in wine even when the windows version is
set to 8+. This is probably not an issue on Windows, as the allocator
may return a much lower address.
Original patch modified by GloriousEggroll to be togglable with the
"WINE_LOW_USER_SPACE_LIMIT" environment variable.
---
dlls/ntdll/virtual.c | 6 ++++++
1 file changed, 6 insertions(+), 0 deletion(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 7bc4d89184..9b57956183 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1932,6 +1932,7 @@ static int alloc_virtual_heap( void *base, size_t size, void *arg )
void virtual_init(void)
{
const char *preload;
+ const char *wine_low_user_space_limit = getenv("WINE_LOW_USER_SPACE_LIMIT");
struct alloc_virtual_heap alloc_views;
size_t size;
@@ -1962,6 +1963,10 @@ void virtual_init(void)
}
}
+ if (wine_low_user_space_limit) {
+ user_space_limit = (void *)0x7ffffff0000;
+ }
+
/* try to find space in a reserved area for the views and pages protection table */
#ifdef _WIN64
pages_vprot_size = ((size_t)address_space_limit >> page_shift >> pages_vprot_shift) + 1;
@@ -2625,6 +2625,7 @@ void virtual_set_large_address_space(void)
{
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
+ if (is_win64) return;
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)) return;
/* no large address space on win9x */
if (NtCurrentTeb()->Peb->OSPlatformId != VER_PLATFORM_WIN32_NT) return;
--
2.23.0
From: Derek Lesho <dlesho@codeweavers.com>
Subject: [PATCH] ntdll: Only call wine handlers if they're in the same stack.
Message-Id: <20191002154547.878669-1-dlesho@codeweavers.com>
Date: Wed, 2 Oct 2019 10:45:47 -0500
In Mortal Kombat 11, the game creates its own stack, with an address higher
than the default wine stack. Because of this, when we unwind a C++ exception,
we assume we are inside a wine frame, and we crash trying to unwind to it.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/ntdll/signal_x86_64.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 427a4a0e05..8d6f351f4b 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2427,12 +2427,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2478,7 +2487,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
--
2.23.0

View File

@ -0,0 +1,291 @@
commit 585b6f89affa3482caee9bf17f20dad77dc82d07
Author: Derek Lesho <dlesho@codeweavers.com>
Date: Wed Oct 2 09:10:26 2019 -0500
Vincent's Changes
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 96d1e0b850..423d47bd24 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -792,7 +792,8 @@ static const struct column col_sounddevice[] =
{
{ prop_nameW, CIM_STRING },
{ prop_productnameW, CIM_STRING },
- { prop_statusinfoW, CIM_UINT16 }
+ { prop_statusinfoW, CIM_UINT16 },
+ { prop_manufacturerW, CIM_STRING }
};
static const struct column col_stdregprov[] =
{
@@ -933,6 +934,10 @@ static const WCHAR quickfixengineering_captionW[] =
{'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
static const WCHAR quickfixengineering_hotfixidW[] =
{'K','B','1','2','3','4','5','6','7',0};
+static const WCHAR physicalmemory_partnumberW[] =
+ {'B','L','S','8','G','3','D','1','6','0','9','D','S','1','S','0','0','.',0};
+static const WCHAR sounddevice_manufacturerW[] =
+ {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
static const WCHAR sounddevice_productnameW[] =
{'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
static const WCHAR systemenclosure_systemenclosureW[] =
@@ -1272,6 +1277,7 @@ struct record_sounddevice
const WCHAR *name;
const WCHAR *productname;
UINT16 statusinfo;
+ const WCHAR *manufacturer;
};
struct record_stdregprov
{
@@ -1388,7 +1394,7 @@ static const struct record_quickfixengineering data_quickfixengineering[] =
};
static const struct record_sounddevice data_sounddevice[] =
{
- { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ }
+ { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */, sounddevice_manufacturerW }
};
static const struct record_stdregprov data_stdregprov[] =
{
@@ -3349,10 +3355,10 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
rec = (struct record_physicalmemory *)table->data;
rec->capacity = get_total_physical_memory();
- rec->configuredclockspeed = 0;
+ rec->configuredclockspeed = 1600;
rec->devicelocator = dimm0W;
rec->memorytype = 9; /* RAM */
- rec->partnumber = NULL;
+ rec->partnumber = physicalmemory_partnumberW;
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
else row++;
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3..c7f24168da 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)
commit f4d63311736e7a5db2e9c327a3fbbc21d8cf9c7c
Author: Derek Lesho <dlesho@codeweavers.com>
Date: Wed Oct 2 09:11:03 2019 -0500
gfesdk stub
diff --git a/configure.ac b/configure.ac
index b9339b90aa..81995b05a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3330,6 +3330,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 0000000000..339ccfd7e7
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 0000000000..816f5bc8aa
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 0000000000..f0af7e7568
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 0000000000..457f234073
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
From: Derek Lesho <dlesho@codeweavers.com>
Subject: [PATCH] ntdll: Only call wine handlers if they're in the same stack.
Message-Id: <20191002154547.878669-1-dlesho@codeweavers.com>
Date: Wed, 2 Oct 2019 10:45:47 -0500
In Mortal Kombat 11, the game creates its own stack, with an address higher
than the default wine stack. Because of this, when we unwind a C++ exception,
we assume we are inside a wine frame, and we crash trying to unwind to it.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/ntdll/signal_x86_64.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 427a4a0e05..8d6f351f4b 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2427,12 +2427,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2478,7 +2487,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
--
2.23.0

View File

@ -0,0 +1,342 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
configure | 2 ++
configure.ac | 1 +
dlls/gfesdk/Makefile.in | 7 ++++
dlls/gfesdk/gfesdk.spec | 16 +++++++++
dlls/gfesdk/gfesdk_main.c | 70 ++++++++++++++++++++++++++++++++++++++
dlls/gfesdk/nvgsdk.h | 30 ++++++++++++++++
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/wbemprox/builtin.c | 8 +++--
dlls/ws2_32/Makefile.in | 1 +
9 files changed, 148 insertions(+), 22 deletions(-)
create mode 100644 dlls/gfesdk/Makefile.in
create mode 100644 dlls/gfesdk/gfesdk.spec
create mode 100644 dlls/gfesdk/gfesdk_main.c
create mode 100644 dlls/gfesdk/nvgsdk.h
diff --git a/configure b/configure
index 6c4a5f21b5d..0483ccfeda8 100755
--- a/configure
+++ b/configure
@@ -1343,6 +1342,7 @@ enable_fwpuclnt
enable_gameux
enable_gdi32
enable_gdiplus
+enable_gfesdk
enable_glu32
enable_gphoto2_ds
enable_gpkcsp
@@ -20623,6 +20612,7 @@ wine_fn_config_makefile dlls/gdi32 enable_gdi32
wine_fn_config_makefile dlls/gdi32/tests enable_tests
wine_fn_config_makefile dlls/gdiplus enable_gdiplus
wine_fn_config_makefile dlls/gdiplus/tests enable_tests
+wine_fn_config_makefile dlls/gfesdk enable_gfesdk
wine_fn_config_makefile dlls/glu32 enable_glu32
wine_fn_config_makefile dlls/gphoto2.ds enable_gphoto2_ds
wine_fn_config_makefile dlls/gpkcsp enable_gpkcsp
diff --git a/configure.ac b/configure.ac
index 37e3445a342..7700e998067 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3313,6 +3313,7 @@ WINE_CONFIG_MAKEFILE(dlls/gdi32)
WINE_CONFIG_MAKEFILE(dlls/gdi32/tests)
WINE_CONFIG_MAKEFILE(dlls/gdiplus)
WINE_CONFIG_MAKEFILE(dlls/gdiplus/tests)
+WINE_CONFIG_MAKEFILE(dlls/gfesdk)
WINE_CONFIG_MAKEFILE(dlls/glu32)
WINE_CONFIG_MAKEFILE(dlls/gphoto2.ds)
WINE_CONFIG_MAKEFILE(dlls/gpkcsp)
diff --git a/dlls/gfesdk/Makefile.in b/dlls/gfesdk/Makefile.in
new file mode 100644
index 00000000000..339ccfd7e71
--- /dev/null
+++ b/dlls/gfesdk/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = gfesdk.dll
+IMPORTLIB = gfesdk
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ gfesdk_main.c
diff --git a/dlls/gfesdk/gfesdk.spec b/dlls/gfesdk/gfesdk.spec
new file mode 100644
index 00000000000..816f5bc8aa3
--- /dev/null
+++ b/dlls/gfesdk/gfesdk.spec
@@ -0,0 +1,16 @@
+@ cdecl NVGSDK_AttachLogListener(ptr)
+@ cdecl NVGSDK_Create(ptr ptr ptr)
+@ cdecl NVGSDK_GetUILanguageAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_CloseGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_ConfigureAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetNumberOfHighlightsAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_GetUserSettingsAsync(ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenGroupAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_OpenSummaryAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetScreenshotHighlightAsync(ptr ptr ptr ptr)
+#@ cdecl NVGSDK_Highlights_SetVideoHighlightAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_Poll(ptr)
+@ cdecl NVGSDK_Release(ptr)
+@ cdecl NVGSDK_RequestPermissionsAsync(ptr ptr ptr ptr)
+@ cdecl NVGSDK_SetListenerLogLevel(long)
+@ cdecl NVGSDK_SetLogLevel(long)
diff --git a/dlls/gfesdk/gfesdk_main.c b/dlls/gfesdk/gfesdk_main.c
new file mode 100644
index 00000000000..f0af7e7568d
--- /dev/null
+++ b/dlls/gfesdk/gfesdk_main.c
@@ -0,0 +1,70 @@
+#include <windef.h>
+
+#include "wine/debug.h"
+
+#include "nvgsdk.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gfesdk);
+
+NVGSDK_RetCode CDECL NVGSDK_Create(NVGSDK_HANDLE **handle, NVGSDK_CreateInputParams const *params, NVGSDK_CreateResponse *response)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, response);
+
+ /* SDK specifies "On fatal error, this will be NULL", which I assume means we clean it? */
+ if (response)
+ {
+ //memset(response, 0, sizeof(*response));
+ }
+
+ return NVGSDK_ERR_LOAD_LIBRARY;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Release(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_Poll(NVGSDK_HANDLE *handle)
+{
+ FIXME("stub(%p)\n", handle);
+
+ /* SDK doesn't document failure of this function */
+ return NVGSDK_ERR_INVALID_PARAMETER;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n", lvl);
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_AttachLogListener(NVGSDK_LoggingCallback callback)
+{
+ FIXME("stub(%p)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+NVGSDK_RetCode CDECL NVGSDK_SetListenerLogLevel(NVGSDK_LogLevel lvl)
+{
+ FIXME("stub(%u)\n");
+
+ return NVGSDK_SUCCESS;
+}
+
+void CDECL NVGSDK_RequestPermissionsAsync(NVGSDK_HANDLE *handle, NVGSDK_RequestPermissionsParams const *params, NVGSDK_EmptyCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p %p)\n", handle, params, callback, context);
+
+ callback(NVGSDK_SUCCESS, context);
+}
+
+void CDECL NVGSDK_GetUILanguageAsync(NVGSDK_HANDLE *handle, NVGSDK_GetUILanguageCallback callback, void *context)
+{
+ FIXME("stub(%p %p %p)\n", handle, callback, context);
+
+ callback(NVGSDK_ERR_NOT_SET, NULL, context);
+}
diff --git a/dlls/gfesdk/nvgsdk.h b/dlls/gfesdk/nvgsdk.h
new file mode 100644
index 00000000000..457f2340738
--- /dev/null
+++ b/dlls/gfesdk/nvgsdk.h
@@ -0,0 +1,30 @@
+#include <windef.h>
+
+typedef struct _NVGSDK_HANDLE NVGSDK_HANDLE;
+
+typedef struct _NVGSDK_CreateInputParams NVGSDK_CreateInputParams;
+
+typedef struct _NVGSDK_CreateResponse NVGSDK_CreateResponse;
+
+typedef struct _NVGSDK_RequestPermissionsParams NVGSDK_RequestPermissionsParams;
+
+typedef struct _NVGSDK_Language NVGSDK_Language;
+
+typedef enum _NVGSDK_LogLevel
+{
+ NVGSDK_LOG_NONE = 0,
+} NVGSDK_LogLevel;
+
+typedef enum _NVGSDK_RetCode
+{
+ NVGSDK_SUCCESS = 0,
+ NVGSDK_ERR_INVALID_PARAMETER = -1005,
+ NVGSDK_ERR_NOT_SET = -1006,
+ NVGSDK_ERR_LOAD_LIBRARY = -1022,
+} NVGSDK_RetCode;
+
+typedef void (CALLBACK *NVGSDK_LoggingCallback)(NVGSDK_LogLevel lvl, char const *msg);
+
+typedef void(CALLBACK *NVGSDK_EmptyCallback)(NVGSDK_RetCode ret, void *context);
+
+typedef void(CALLBACK *NVGSDK_GetUILanguageCallback)(NVGSDK_RetCode ret, NVGSDK_Language const *lang, void *context);
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2431,12 +2431,21 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 24badb7bf92..e5d8b2400aa 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -374,6 +374,7 @@ static const struct column col_sounddevice[] =
{ L"Name", CIM_STRING },
{ L"ProductName", CIM_STRING },
{ L"StatusInfo", CIM_UINT16 },
+ { L"Manufacturer", CIM_STRING },
};
static const struct column col_stdregprov[] =
{
@@ -759,6 +760,7 @@ struct record_sounddevice
const WCHAR *name;
const WCHAR *productname;
UINT16 statusinfo;
+ const WCHAR *manufacturer;
};
struct record_stdregprov
{
@@ -876,7 +878,7 @@ static const struct record_quickfixengineering data_quickfixengineering[] =
};
static const struct record_sounddevice data_sounddevice[] =
{
- { L"Wine Audio Device", L"Wine Audio Device", 3 /* enabled */ }
+ { L"Wine Audio Device", L"Wine Audio Device", 3 /* enabled */, L"The Wine Project" }
};
static const struct record_stdregprov data_stdregprov[] =
{
@@ -2868,11 +2870,11 @@ static enum fill_status fill_physicalmemory( struct table *table, const struct e
rec = (struct record_physicalmemory *)table->data;
rec->capacity = get_total_physical_memory();
- rec->configuredclockspeed = 0;
+ rec->configuredclockspeed = 1600;
rec->devicelocator = L"DIMM 0";
rec->formfactor = 8; /* DIMM */
rec->memorytype = 9; /* RAM */
- rec->partnumber = NULL;
+ rec->partnumber = L"BLS8G3D1609DS1S00";
if (!match_row( table, row, cond, &status )) free_row_values( table, row );
else row++;
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,6 +1,7 @@
EXTRADEFS = -DUSE_WS_PREFIX
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = iphlpapi user32
EXTRALIBS = $(POLL_LIBS)
From f445a9f05e4ad097c55d690f08fd5f1e71940d79 Mon Sep 17 00:00:00 2001
From: Pnevmoslon <psn8402@gmail.com>
Date: Wed, 27 May 2020 12:23:59 +0300
Subject: [PATCH] mk11 gamepad fix
---
dlls/wbemprox/class.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/dlls/wbemprox/class.c b/dlls/wbemprox/class.c
index ba7720b098..6cc439c6fb 100644
--- a/dlls/wbemprox/class.c
+++ b/dlls/wbemprox/class.c
@@ -116,6 +116,7 @@ static HRESULT WINAPI enum_class_object_Next(
struct table *table;
static int once = 0;
HRESULT hr;
+ ULONG i;
TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
@@ -124,16 +125,18 @@ static HRESULT WINAPI enum_class_object_Next(
if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
*puReturned = 0;
- if (ec->index >= view->result_count) return WBEM_S_FALSE;
-
- table = get_view_table( view, ec->index );
- hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
- if (hr != S_OK) return hr;
-
- ec->index++;
- *puReturned = 1;
- if (ec->index == view->result_count && uCount > 1) return WBEM_S_FALSE;
- if (uCount > 1) return WBEM_S_TIMEDOUT;
+
+ for (i=0; i<uCount; ++i)
+ {
+ if (ec->index >= view->result_count) return WBEM_S_FALSE;
+ table = get_view_table( view, ec->index );
+ hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
+ if (hr != S_OK) return hr;
+
+ apObjects++;
+ ec->index++;
+ ++*puReturned;
+ }
return WBEM_S_NO_ERROR;
}
--
2.26.2

View File

@ -0,0 +1,56 @@
#!/bin/bash
# Fix for Mortal Kombat 11 - Requires staging, native mfplat (win7) and a different GPU driver than RADV
if [ "$_mk11_fix" = "true" ] && [ "$_use_staging" = "true" ] && [ "$_proton_fs_hack" = "true" ]; then
if git merge-base --is-ancestor 548bc54bf396d74b5b928bf9be835272ddda1886 HEAD; then
_patchname='mk11.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor 7c39ce0a6cf8a3df1337a0768045c43044fce2f6 HEAD; then
_patchname='mk11-548bc54.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor 8504e40d5b5e7076b998b36e6291515b863482cb HEAD; then
_patchname='mk11-7c39ce0.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor 0c249e6125fc9dc6ee86b4ef6ae0d9fa2fc6291b HEAD; then
_patchname='mk11-8504e40.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor 75fb68e42423362ae945c0c0554f0dcd4d2e169b HEAD; then
_patchname='mk11-0c249e6.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor 84d85adeea578cac37bded97984409f44c7985ba HEAD; then
_patchname='mk11-75fb68e.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor 2ea3e40465f0530ad71c31e77c9727c00673d91f HEAD; then
_patchname='mk11-84d85ad.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor fb7cc99f8a8c5a1594cfa780807d5e75f4b9539e HEAD; then
_patchname='mk11-2ea3e40.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor 78e9b02cebf4b107aba69aa9a845ab661a7daf10 HEAD; then
_patchname='mk11-fb7cc99.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
elif git merge-base --is-ancestor b1c748c85205970b97cd31b4347a751c58b2d72e HEAD; then
_patchname='mk11-78e9b02.patch' && _patchmsg="Applied Mortal Kombat 11 fix" && nonuser_patcher
else
if [ "$_large_address_aware" = "true" ]; then
for _f in "$_where"/LAA-stagin*.patch ; do
patch "${_f}" << 'EOM'
@@ -220,15 +220,16 @@ diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index c008db78066..6163761a466 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
-@@ -2442,11 +2442,12 @@ void virtual_release_address_space(void)
+@@ -2442,12 +2442,13 @@ void virtual_release_address_space(void)
*
* Enable use of a large address space when allowed by the application.
*/
-void virtual_set_large_address_space(void)
+void virtual_set_large_address_space(BOOL force_large_address)
{
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
+ if (is_win64) return;
- if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)) return;
+ if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) && !force_large_address) return;
+
EOM
done
fi
if ( cd "${srcdir}"/"${_stgsrcdir}" && git merge-base --is-ancestor 89af635b941cf450ae371395e7b28d09161f3a36 HEAD ); then
_patchname='mk11-b1c748c.patch' && _patchmsg="Applied Mortal Kombat 11 fix (<b1c748c)" && nonuser_patcher
else
_patchname='mk11-89af635.patch' && _patchmsg="Applied Mortal Kombat 11 fix (<89af635)" && nonuser_patcher
fi
fi
fi

View File

@ -0,0 +1,57 @@
From e8f6ed261e213ced6c0c762988b6fc3446ef510a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 22 Apr 2020 10:45:46 -0500
Subject: [PATCH 1/8] mk11_base
---
dlls/ntdll/signal_x86_64.c | 11 +++++-
dlls/ws2_32/Makefile.in | 1 +
3 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 89caca9f30f..6fb16333397 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -425,6 +425,8 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
UNWIND_HISTORY_TABLE table;
DISPATCHER_CONTEXT dispatch;
CONTEXT context;
+ MEMORY_BASIC_INFORMATION wine_frame_stack_info, current_stack_info;
+ int is_teb_frame_in_current_stack = 1;
NTSTATUS status;
context = *orig_context;
@@ -433,6 +435,13 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
dispatch.TargetIp = 0;
dispatch.ContextRecord = &context;
dispatch.HistoryTable = &table;
+
+ if ( !(NtQueryVirtualMemory(NtCurrentProcess(), teb_frame, MemoryBasicInformation, &wine_frame_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)) &&
+ !(NtQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &current_stack_info, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
+ {
+ is_teb_frame_in_current_stack = wine_frame_stack_info.AllocationBase == current_stack_info.AllocationBase;
+ }
+
for (;;)
{
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -2482,7 +2491,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
}
/* hack: call wine handlers registered in the tib list */
- else while ((ULONG64)teb_frame < context.Rsp)
+ else if (is_teb_frame_in_current_stack) while ((ULONG64)teb_frame < context.Rsp)
{
TRACE( "found wine frame %p rsp %lx handler %p\n",
teb_frame, context.Rsp, teb_frame->Handler );
diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in
index 9d7dfafeb3c..c7f24168dac 100644
--- a/dlls/ws2_32/Makefile.in
+++ b/dlls/ws2_32/Makefile.in
@@ -1,5 +1,6 @@
MODULE = ws2_32.dll
IMPORTLIB = ws2_32
+IMPORTS = kernelbase
DELAYIMPORTS = dnsapi advapi32 iphlpapi user32
C_SRCS = \

View File

@ -0,0 +1,13 @@
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 5a88c147e0..47c0de61e0 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -87,6 +87,8 @@ static BOOL is_obsoleted_by_patch( MSIPACKAGE *package, MSIFILE *file )
static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *file )
{
+ return msifs_overwrite;
+
MSICOMPONENT *comp = file->Component;
VS_FIXEDFILEINFO *file_version;
WCHAR *font_version;

View File

@ -0,0 +1,30 @@
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 9f4a08fdb9..035ad680eb 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -778,7 +778,7 @@ NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self
NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self )
{
NTSTATUS ret;
- DWORD dummy, i;
+ DWORD dummy;
SERVER_START_REQ( get_thread_context )
{
@@ -793,7 +793,7 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
if (ret == STATUS_PENDING)
{
- for (i = 0; i < 100; i++)
+ while (TRUE)
{
SERVER_START_REQ( get_thread_context )
{
@@ -813,7 +813,6 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
else break;
}
NtResumeThread( handle, &dummy );
- if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
}
return ret;
}

View File

@ -0,0 +1,445 @@
From 2d71f3c8dc379809a953ac5322db05fc34f18f49 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 27 Apr 2020 14:22:06 +0200
Subject: Revert "server: Don't wait for client thread to enter suspended state
in set_thread_context."
This reverts commit aa0c4bb5e72caf290b6588bc1f9931cc89a9feb6.
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index b8c270c16d..ee3c925f91 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -787,16 +787,42 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self )
{
NTSTATUS ret;
+ DWORD dummy, i;
SERVER_START_REQ( set_thread_context )
{
req->handle = wine_server_obj_handle( handle );
+ req->suspend = 1;
wine_server_add_data( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
}
SERVER_END_REQ;
+ if (ret == STATUS_PENDING)
+ {
+ for (i = 0; i < 100; i++)
+ {
+ SERVER_START_REQ( set_thread_context )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->suspend = 0;
+ wine_server_add_data( req, context, sizeof(*context) );
+ ret = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ if (ret == STATUS_PENDING)
+ {
+ LARGE_INTEGER timeout;
+ timeout.QuadPart = -10000;
+ NtDelayExecution( FALSE, &timeout );
+ }
+ else break;
+ }
+ NtResumeThread( handle, &dummy );
+ if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
+ }
+
return ret;
}
diff --git a/server/thread.c b/server/thread.c
index de508c6ace..07be868d48 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1859,21 +1859,35 @@ DECL_HANDLER(set_thread_context)
if (!(thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) return;
reply->self = (thread == current);
- if (thread->state == TERMINATED) set_error( STATUS_UNSUCCESSFUL );
- else if (context->cpu != thread->process->cpu) set_error( STATUS_INVALID_PARAMETER );
- else
+ if (thread != current && (!thread->context || thread->context->status == STATUS_PENDING))
+ {
+ /* thread is not suspended, retry (if it's still running) */
+ if (thread->state == RUNNING)
+ {
+ set_error( STATUS_PENDING );
+ if (req->suspend)
+ {
+ release_object( thread );
+ /* make sure we have suspend access */
+ if (!(thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) return;
+ suspend_thread( thread );
+ }
+ }
+ else set_error( STATUS_UNSUCCESSFUL );
+ }
+ else if (context->cpu == thread->process->cpu)
{
unsigned int system_flags = get_context_system_regs(context->cpu) & context->flags;
unsigned int client_flags = context->flags & ~system_flags;
if (system_flags) set_thread_context( thread, context, system_flags );
- if (thread != current && !get_error()) stop_thread( thread );
if (thread->context && !get_error())
{
copy_context( &thread->context->regs, context, context->flags );
thread->context->regs.flags |= client_flags;
}
}
+ else set_error( STATUS_INVALID_PARAMETER );
release_object( thread );
}
From b89abf5e64f991ed6b40bfb9c8ad10018293b8b5 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 27 Apr 2020 14:22:00 +0200
Subject: Revert "server: Block by waiting on context handle in
get_thread_context."
This reverts commit c4dab9b76eb7397f6e5325ff4bdf792cf500e571.
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index e27b3a0c6d..b8c270c16d 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -807,35 +807,42 @@ NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self
NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self )
{
NTSTATUS ret;
+ DWORD dummy, i;
SERVER_START_REQ( get_thread_context )
{
req->handle = wine_server_obj_handle( handle );
req->flags = flags;
+ req->suspend = 1;
wine_server_set_reply( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
- handle = wine_server_ptr_handle( reply->handle );
}
SERVER_END_REQ;
if (ret == STATUS_PENDING)
{
- LARGE_INTEGER timeout;
- timeout.QuadPart = -1000000;
- if (NtWaitForSingleObject( handle, FALSE, &timeout ))
+ for (i = 0; i < 100; i++)
{
- NtClose( handle );
- return STATUS_ACCESS_DENIED;
- }
- SERVER_START_REQ( get_thread_context )
- {
- req->handle = wine_server_obj_handle( handle );
- req->flags = flags;
- wine_server_set_reply( req, context, sizeof(*context) );
- ret = wine_server_call( req );
+ SERVER_START_REQ( get_thread_context )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->flags = flags;
+ req->suspend = 0;
+ wine_server_set_reply( req, context, sizeof(*context) );
+ ret = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ if (ret == STATUS_PENDING)
+ {
+ LARGE_INTEGER timeout;
+ timeout.QuadPart = -10000;
+ NtDelayExecution( FALSE, &timeout );
+ }
+ else break;
}
- SERVER_END_REQ;
+ NtResumeThread( handle, &dummy );
+ if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
}
return ret;
}
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index dfcb22143b..9cdb9c765f 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2900,14 +2900,14 @@ struct get_thread_context_request
struct request_header __header;
obj_handle_t handle;
unsigned int flags;
- char __pad_20[4];
+ int suspend;
};
struct get_thread_context_reply
{
struct reply_header __header;
int self;
- obj_handle_t handle;
/* VARARG(context,context); */
+ char __pad_12[4];
};
@@ -2916,7 +2916,9 @@ struct set_thread_context_request
{
struct request_header __header;
obj_handle_t handle;
+ int suspend;
/* VARARG(context,context); */
+ char __pad_20[4];
};
struct set_thread_context_reply
{
diff --git a/server/protocol.def b/server/protocol.def
index 06a29b153e..1413021a39 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2157,11 +2157,11 @@ enum char_info_mode
/* Retrieve the current context of a thread */
@REQ(get_thread_context)
- obj_handle_t handle; /* thread or context handle */
+ obj_handle_t handle; /* thread handle */
unsigned int flags; /* context flags */
+ int suspend; /* suspend the thread if needed */
@REPLY
int self; /* was it a handle to the current thread? */
- obj_handle_t handle; /* pending context handle */
VARARG(context,context); /* thread context */
@END
@@ -2169,6 +2169,7 @@ enum char_info_mode
/* Set the current context of a thread */
@REQ(set_thread_context)
obj_handle_t handle; /* thread handle */
+ int suspend; /* suspend the thread if needed */
VARARG(context,context); /* thread context */
@REPLY
int self; /* was it a handle to the current thread? */
diff --git a/server/request.h b/server/request.h
index b472603e59..0d4c083460 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1484,12 +1484,13 @@ C_ASSERT( FIELD_OFFSET(struct get_timer_info_reply, signaled) == 16 );
C_ASSERT( sizeof(struct get_timer_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, flags) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, suspend) == 20 );
C_ASSERT( sizeof(struct get_thread_context_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, self) == 8 );
-C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 );
C_ASSERT( sizeof(struct get_thread_context_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, handle) == 12 );
-C_ASSERT( sizeof(struct set_thread_context_request) == 16 );
+C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, suspend) == 16 );
+C_ASSERT( sizeof(struct set_thread_context_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_thread_context_reply, self) == 8 );
C_ASSERT( sizeof(struct set_thread_context_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_selector_entry_request, handle) == 12 );
diff --git a/server/thread.c b/server/thread.c
index cfdf42c756..de508c6ace 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -136,7 +136,6 @@ struct context
};
static void dump_context( struct object *obj, int verbose );
-static int context_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops context_ops =
{
@@ -145,7 +144,7 @@ static const struct object_ops context_ops =
no_get_type, /* get_type */
add_queue, /* add_queue */
remove_queue, /* remove_queue */
- context_signaled, /* signaled */
+ NULL, /* signaled */
NULL, /* get_esync_fd */
NULL, /* get_fsync_fd */
no_satisfied, /* satisfied */
@@ -268,13 +267,6 @@ static void dump_context( struct object *obj, int verbose )
}
-static int context_signaled( struct object *obj, struct wait_queue_entry *entry )
-{
- struct context *context = (struct context *)obj;
- return context->status != STATUS_PENDING;
-}
-
-
static struct context *create_thread_context( struct thread *thread )
{
struct context *context;
@@ -385,7 +377,6 @@ static void cleanup_thread( struct thread *thread )
if (thread->context)
{
thread->context->status = STATUS_ACCESS_DENIED;
- wake_up( &thread->context->obj, 0 );
release_object( thread->context );
thread->context = NULL;
}
@@ -1628,11 +1619,9 @@ DECL_HANDLER(select)
}
if (!current->context && !(current->context = create_thread_context( current ))) return;
- copy_context( &current->context->regs, context,
- context->flags & ~(current->context->regs.flags | get_context_system_regs(current->process->cpu)) );
+ copy_context( &current->context->regs, context, context->flags & ~current->context->regs.flags );
current->context->status = STATUS_SUCCESS;
current->suspend_cookie = req->cookie;
- wake_up( &current->context->obj, 0 );
}
if (!req->cookie)
@@ -1813,8 +1802,6 @@ DECL_HANDLER(get_apc_result)
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
{
- struct context *thread_context = NULL;
- unsigned int system_flags;
struct thread *thread;
context_t *context;
@@ -1823,58 +1810,39 @@ DECL_HANDLER(get_thread_context)
set_error( STATUS_INVALID_PARAMETER );
return;
}
+ if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
+ reply->self = (thread == current);
- if ((thread_context = (struct context *)get_handle_obj( current->process, req->handle, 0, &context_ops )))
+ if (thread != current && (!thread->context || thread->context->status == STATUS_PENDING))
{
- close_handle( current->process, req->handle ); /* avoid extra server call */
- system_flags = get_context_system_regs( thread_context->regs.cpu );
- }
- else if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
- {
- clear_error();
- system_flags = get_context_system_regs( thread->process->cpu );
+ /* thread is not suspended, retry (if it's still running) */
if (thread->state == RUNNING)
{
- reply->self = (thread == current);
- if (thread != current) stop_thread( thread );
- if (thread->context)
+ set_error( STATUS_PENDING );
+ if (req->suspend)
{
- /* make sure that system regs are valid in thread context */
- if (req->flags & system_flags & ~thread->context->regs.flags)
- get_thread_context( thread, &thread->context->regs, req->flags & system_flags );
- if (!get_error()) thread_context = (struct context *)grab_object( thread->context );
- }
- else if (!get_error() && (context = set_reply_data_size( sizeof(context_t) )))
- {
- assert( reply->self );
- memset( context, 0, sizeof(context_t) );
- context->cpu = thread_context->regs.cpu;
- if (req->flags & system_flags)
- {
- get_thread_context( thread, context, req->flags & system_flags );
- context->flags |= req->flags & system_flags;
- }
+ release_object( thread );
+ /* make sure we have suspend access */
+ if (!(thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) return;
+ suspend_thread( thread );
}
}
else set_error( STATUS_UNSUCCESSFUL );
- release_object( thread );
}
- if (get_error() || !thread_context) return;
-
- set_error( thread_context->status );
- if (!thread_context->status && (context = set_reply_data_size( sizeof(context_t) )))
+ else if ((context = set_reply_data_size( sizeof(context_t) )))
{
+ unsigned int flags = get_context_system_regs( thread->process->cpu );
+
memset( context, 0, sizeof(context_t) );
- context->cpu = thread_context->regs.cpu;
- copy_context( context, &thread_context->regs, req->flags );
- context->flags = req->flags;
- }
- else if (thread_context->status == STATUS_PENDING)
- {
- reply->handle = alloc_handle( current->process, thread_context, SYNCHRONIZE, 0 );
+ context->cpu = thread->process->cpu;
+ if (thread->context)
+ {
+ copy_context( context, &thread->context->regs, req->flags & ~flags );
+ context->flags |= req->flags & ~flags;
+ }
+ if (req->flags & flags) get_thread_context( thread, context, req->flags & flags );
}
-
- release_object( thread_context );
+ release_object( thread );
}
/* set the current context of a thread */
diff --git a/server/trace.c b/server/trace.c
index 2b58ed9fd2..dd63b166f3 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2675,18 +2675,19 @@ static void dump_get_thread_context_request( const struct get_thread_context_req
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", flags=%08x", req->flags );
+ fprintf( stderr, ", suspend=%d", req->suspend );
}
static void dump_get_thread_context_reply( const struct get_thread_context_reply *req )
{
fprintf( stderr, " self=%d", req->self );
- fprintf( stderr, ", handle=%04x", req->handle );
dump_varargs_context( ", context=", cur_size );
}
static void dump_set_thread_context_request( const struct set_thread_context_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
+ fprintf( stderr, ", suspend=%d", req->suspend );
dump_varargs_context( ", context=", cur_size );
}
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 9f4a08fdb9..035ad680eb 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -778,7 +778,7 @@ NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self
NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self )
{
NTSTATUS ret;
- DWORD dummy, i;
+ DWORD dummy;
SERVER_START_REQ( get_thread_context )
{
@@ -793,7 +793,7 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
if (ret == STATUS_PENDING)
{
- for (i = 0; i < 100; i++)
+ while (TRUE)
{
SERVER_START_REQ( get_thread_context )
{
@@ -813,7 +813,6 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
else break;
}
NtResumeThread( handle, &dummy );
- if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
}
return ret;
}

View File

@ -0,0 +1,445 @@
From 2d71f3c8dc379809a953ac5322db05fc34f18f49 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 27 Apr 2020 14:22:06 +0200
Subject: Revert "server: Don't wait for client thread to enter suspended state
in set_thread_context."
This reverts commit aa0c4bb5e72caf290b6588bc1f9931cc89a9feb6.
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index b8c270c16d..ee3c925f91 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -787,16 +787,42 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self )
{
NTSTATUS ret;
+ DWORD dummy, i;
SERVER_START_REQ( set_thread_context )
{
req->handle = wine_server_obj_handle( handle );
+ req->suspend = 1;
wine_server_add_data( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
}
SERVER_END_REQ;
+ if (ret == STATUS_PENDING)
+ {
+ for (i = 0; i < 100; i++)
+ {
+ SERVER_START_REQ( set_thread_context )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->suspend = 0;
+ wine_server_add_data( req, context, sizeof(*context) );
+ ret = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ if (ret == STATUS_PENDING)
+ {
+ LARGE_INTEGER timeout;
+ timeout.QuadPart = -10000;
+ NtDelayExecution( FALSE, &timeout );
+ }
+ else break;
+ }
+ NtResumeThread( handle, &dummy );
+ if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
+ }
+
return ret;
}
diff --git a/server/thread.c b/server/thread.c
index de508c6ace..07be868d48 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1859,21 +1859,35 @@ DECL_HANDLER(set_thread_context)
if (!(thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) return;
reply->self = (thread == current);
- if (thread->state == TERMINATED) set_error( STATUS_UNSUCCESSFUL );
- else if (context->cpu != thread->process->cpu) set_error( STATUS_INVALID_PARAMETER );
- else
+ if (thread != current && (!thread->context || thread->context->status == STATUS_PENDING))
+ {
+ /* thread is not suspended, retry (if it's still running) */
+ if (thread->state == RUNNING)
+ {
+ set_error( STATUS_PENDING );
+ if (req->suspend)
+ {
+ release_object( thread );
+ /* make sure we have suspend access */
+ if (!(thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) return;
+ suspend_thread( thread );
+ }
+ }
+ else set_error( STATUS_UNSUCCESSFUL );
+ }
+ else if (context->cpu == thread->process->cpu)
{
unsigned int system_flags = get_context_system_regs(context->cpu) & context->flags;
unsigned int client_flags = context->flags & ~system_flags;
if (system_flags) set_thread_context( thread, context, system_flags );
- if (thread != current && !get_error()) stop_thread( thread );
if (thread->context && !get_error())
{
copy_context( &thread->context->regs, context, context->flags );
thread->context->regs.flags |= client_flags;
}
}
+ else set_error( STATUS_INVALID_PARAMETER );
release_object( thread );
}
From b89abf5e64f991ed6b40bfb9c8ad10018293b8b5 Mon Sep 17 00:00:00 2001
From: Tk-Glitch <ti3nou@gmail.com>
Date: Mon, 27 Apr 2020 14:22:00 +0200
Subject: Revert "server: Block by waiting on context handle in
get_thread_context."
This reverts commit c4dab9b76eb7397f6e5325ff4bdf792cf500e571.
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index e27b3a0c6d..b8c270c16d 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -807,35 +807,42 @@ NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self
NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self )
{
NTSTATUS ret;
+ DWORD dummy, i;
SERVER_START_REQ( get_thread_context )
{
req->handle = wine_server_obj_handle( handle );
req->flags = flags;
+ req->suspend = 1;
wine_server_set_reply( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
- handle = wine_server_ptr_handle( reply->handle );
}
SERVER_END_REQ;
if (ret == STATUS_PENDING)
{
- LARGE_INTEGER timeout;
- timeout.QuadPart = -1000000;
- if (NtWaitForSingleObject( handle, FALSE, &timeout ))
+ for (i = 0; i < 100; i++)
{
- NtClose( handle );
- return STATUS_ACCESS_DENIED;
- }
- SERVER_START_REQ( get_thread_context )
- {
- req->handle = wine_server_obj_handle( handle );
- req->flags = flags;
- wine_server_set_reply( req, context, sizeof(*context) );
- ret = wine_server_call( req );
+ SERVER_START_REQ( get_thread_context )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->flags = flags;
+ req->suspend = 0;
+ wine_server_set_reply( req, context, sizeof(*context) );
+ ret = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ if (ret == STATUS_PENDING)
+ {
+ LARGE_INTEGER timeout;
+ timeout.QuadPart = -10000;
+ NtDelayExecution( FALSE, &timeout );
+ }
+ else break;
}
- SERVER_END_REQ;
+ NtResumeThread( handle, &dummy );
+ if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
}
return ret;
}
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index dfcb22143b..9cdb9c765f 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2900,14 +2900,14 @@ struct get_thread_context_request
struct request_header __header;
obj_handle_t handle;
unsigned int flags;
- char __pad_20[4];
+ int suspend;
};
struct get_thread_context_reply
{
struct reply_header __header;
int self;
- obj_handle_t handle;
/* VARARG(context,context); */
+ char __pad_12[4];
};
@@ -2916,7 +2916,9 @@ struct set_thread_context_request
{
struct request_header __header;
obj_handle_t handle;
+ int suspend;
/* VARARG(context,context); */
+ char __pad_20[4];
};
struct set_thread_context_reply
{
diff --git a/server/protocol.def b/server/protocol.def
index 06a29b153e..1413021a39 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2157,11 +2157,11 @@ enum char_info_mode
/* Retrieve the current context of a thread */
@REQ(get_thread_context)
- obj_handle_t handle; /* thread or context handle */
+ obj_handle_t handle; /* thread handle */
unsigned int flags; /* context flags */
+ int suspend; /* suspend the thread if needed */
@REPLY
int self; /* was it a handle to the current thread? */
- obj_handle_t handle; /* pending context handle */
VARARG(context,context); /* thread context */
@END
@@ -2169,6 +2169,7 @@ enum char_info_mode
/* Set the current context of a thread */
@REQ(set_thread_context)
obj_handle_t handle; /* thread handle */
+ int suspend; /* suspend the thread if needed */
VARARG(context,context); /* thread context */
@REPLY
int self; /* was it a handle to the current thread? */
diff --git a/server/request.h b/server/request.h
index b472603e59..0d4c083460 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1484,12 +1484,13 @@ C_ASSERT( FIELD_OFFSET(struct get_timer_info_reply, signaled) == 16 );
C_ASSERT( sizeof(struct get_timer_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, flags) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, suspend) == 20 );
C_ASSERT( sizeof(struct get_thread_context_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, self) == 8 );
-C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 );
C_ASSERT( sizeof(struct get_thread_context_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, handle) == 12 );
-C_ASSERT( sizeof(struct set_thread_context_request) == 16 );
+C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, suspend) == 16 );
+C_ASSERT( sizeof(struct set_thread_context_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_thread_context_reply, self) == 8 );
C_ASSERT( sizeof(struct set_thread_context_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_selector_entry_request, handle) == 12 );
diff --git a/server/thread.c b/server/thread.c
index cfdf42c756..de508c6ace 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -136,7 +136,6 @@ struct context
};
static void dump_context( struct object *obj, int verbose );
-static int context_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops context_ops =
{
@@ -145,7 +144,7 @@ static const struct object_ops context_ops =
no_get_type, /* get_type */
add_queue, /* add_queue */
remove_queue, /* remove_queue */
- context_signaled, /* signaled */
+ NULL, /* signaled */
NULL, /* get_esync_fd */
NULL, /* get_fsync_fd */
no_satisfied, /* satisfied */
@@ -268,13 +267,6 @@ static void dump_context( struct object *obj, int verbose )
}
-static int context_signaled( struct object *obj, struct wait_queue_entry *entry )
-{
- struct context *context = (struct context *)obj;
- return context->status != STATUS_PENDING;
-}
-
-
static struct context *create_thread_context( struct thread *thread )
{
struct context *context;
@@ -385,7 +377,6 @@ static void cleanup_thread( struct thread *thread )
if (thread->context)
{
thread->context->status = STATUS_ACCESS_DENIED;
- wake_up( &thread->context->obj, 0 );
release_object( thread->context );
thread->context = NULL;
}
@@ -1628,11 +1619,9 @@ DECL_HANDLER(select)
}
if (!current->context && !(current->context = create_thread_context( current ))) return;
- copy_context( &current->context->regs, context,
- context->flags & ~(current->context->regs.flags | get_context_system_regs(current->process->cpu)) );
+ copy_context( &current->context->regs, context, context->flags & ~current->context->regs.flags );
current->context->status = STATUS_SUCCESS;
current->suspend_cookie = req->cookie;
- wake_up( &current->context->obj, 0 );
}
if (!req->cookie)
@@ -1813,8 +1802,6 @@ DECL_HANDLER(get_apc_result)
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
{
- struct context *thread_context = NULL;
- unsigned int system_flags;
struct thread *thread;
context_t *context;
@@ -1823,58 +1810,39 @@ DECL_HANDLER(get_thread_context)
set_error( STATUS_INVALID_PARAMETER );
return;
}
+ if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
+ reply->self = (thread == current);
- if ((thread_context = (struct context *)get_handle_obj( current->process, req->handle, 0, &context_ops )))
+ if (thread != current && (!thread->context || thread->context->status == STATUS_PENDING))
{
- close_handle( current->process, req->handle ); /* avoid extra server call */
- system_flags = get_context_system_regs( thread_context->regs.cpu );
- }
- else if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
- {
- clear_error();
- system_flags = get_context_system_regs( thread->process->cpu );
+ /* thread is not suspended, retry (if it's still running) */
if (thread->state == RUNNING)
{
- reply->self = (thread == current);
- if (thread != current) stop_thread( thread );
- if (thread->context)
+ set_error( STATUS_PENDING );
+ if (req->suspend)
{
- /* make sure that system regs are valid in thread context */
- if (req->flags & system_flags & ~thread->context->regs.flags)
- get_thread_context( thread, &thread->context->regs, req->flags & system_flags );
- if (!get_error()) thread_context = (struct context *)grab_object( thread->context );
- }
- else if (!get_error() && (context = set_reply_data_size( sizeof(context_t) )))
- {
- assert( reply->self );
- memset( context, 0, sizeof(context_t) );
- context->cpu = thread_context->regs.cpu;
- if (req->flags & system_flags)
- {
- get_thread_context( thread, context, req->flags & system_flags );
- context->flags |= req->flags & system_flags;
- }
+ release_object( thread );
+ /* make sure we have suspend access */
+ if (!(thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) return;
+ suspend_thread( thread );
}
}
else set_error( STATUS_UNSUCCESSFUL );
- release_object( thread );
}
- if (get_error() || !thread_context) return;
-
- set_error( thread_context->status );
- if (!thread_context->status && (context = set_reply_data_size( sizeof(context_t) )))
+ else if ((context = set_reply_data_size( sizeof(context_t) )))
{
+ unsigned int flags = get_context_system_regs( thread->process->cpu );
+
memset( context, 0, sizeof(context_t) );
- context->cpu = thread_context->regs.cpu;
- copy_context( context, &thread_context->regs, req->flags );
- context->flags = req->flags;
- }
- else if (thread_context->status == STATUS_PENDING)
- {
- reply->handle = alloc_handle( current->process, thread_context, SYNCHRONIZE, 0 );
+ context->cpu = thread->process->cpu;
+ if (thread->context)
+ {
+ copy_context( context, &thread->context->regs, req->flags & ~flags );
+ context->flags |= req->flags & ~flags;
+ }
+ if (req->flags & flags) get_thread_context( thread, context, req->flags & flags );
}
-
- release_object( thread_context );
+ release_object( thread );
}
/* set the current context of a thread */
diff --git a/server/trace.c b/server/trace.c
index 2b58ed9fd2..dd63b166f3 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2675,18 +2675,19 @@ static void dump_get_thread_context_request( const struct get_thread_context_req
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", flags=%08x", req->flags );
+ fprintf( stderr, ", suspend=%d", req->suspend );
}
static void dump_get_thread_context_reply( const struct get_thread_context_reply *req )
{
fprintf( stderr, " self=%d", req->self );
- fprintf( stderr, ", handle=%04x", req->handle );
dump_varargs_context( ", context=", cur_size );
}
static void dump_set_thread_context_request( const struct set_thread_context_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
+ fprintf( stderr, ", suspend=%d", req->suspend );
dump_varargs_context( ", context=", cur_size );
}
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 9f4a08fdb9..035ad680eb 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -778,7 +778,7 @@ NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self
NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self )
{
NTSTATUS ret;
- DWORD dummy, i;
+ DWORD dummy;
SERVER_START_REQ( get_thread_context )
{
@@ -793,7 +793,7 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
if (ret == STATUS_PENDING)
{
- for (i = 0; i < 100; i++)
+ while (TRUE)
{
SERVER_START_REQ( get_thread_context )
{
@@ -813,7 +813,6 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
else break;
}
NtResumeThread( handle, &dummy );
- if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
}
return ret;
}

Some files were not shown because too many files have changed in this diff Show More