You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Compare commits
124 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d787be6d20 | ||
|
c35db80eae | ||
|
4328f2e964 | ||
|
eecf7c4a68 | ||
|
4d01de8fcd | ||
|
f5ef032c89 | ||
|
f9eebd5599 | ||
|
48bbae3fb7 | ||
|
fdbc47e09e | ||
|
2b4093a0ea | ||
|
580ff7c1c5 | ||
|
454c09ddbe | ||
|
810202432b | ||
|
737eb1005a | ||
|
58eeb19b3e | ||
|
c8be20f3cf | ||
|
b6d34ea7d2 | ||
|
f6d14c47ec | ||
|
78d6102645 | ||
|
b862f600f5 | ||
|
e0b037b82a | ||
|
69b0f7ebd7 | ||
|
7c95fad661 | ||
|
67cc61ffca | ||
|
0df720506a | ||
|
68c91b3113 | ||
|
ac36f88de1 | ||
|
9fcd7e7113 | ||
|
903a8e54d4 | ||
|
3de6b17d8a | ||
|
74bd451363 | ||
|
22a1e1ff59 | ||
|
c781d177e1 | ||
|
f13c0f3cd8 | ||
|
9ebbbcfc9f | ||
|
d886426f50 | ||
|
d30bfe1a41 | ||
|
30825c59a9 | ||
|
7d03df647f | ||
|
a046f03792 | ||
|
b744f3d37b | ||
|
c52df465c1 | ||
|
09bfdcb009 | ||
|
2f449562d1 | ||
|
3c6c730333 | ||
|
809ee539f3 | ||
|
339892ffe6 | ||
|
2e7f83fbf8 | ||
|
9043eadbcb | ||
|
5386c7843d | ||
|
0675620019 | ||
|
552b6acf97 | ||
|
86c9842e64 | ||
|
d0e9447fb6 | ||
|
47ddb3a6d1 | ||
|
5a4ba9a546 | ||
|
b51c16c86a | ||
|
c1edf8d5c4 | ||
|
ebf2fb3d7d | ||
|
ca1e83ef3f | ||
|
054930fd52 | ||
|
56fd91825e | ||
|
a6b295029c | ||
|
ddf6dd7f6a | ||
|
524c64dd2a | ||
|
e470b33f7c | ||
|
556aa9335e | ||
|
0817bd1a57 | ||
|
2f7523bffe | ||
|
9fd0a6eb9d | ||
|
f5f50d333c | ||
|
2d3f9334f8 | ||
|
9466f14d52 | ||
|
79c4f4391e | ||
|
820cc2e861 | ||
|
29d69db459 | ||
|
7642c422ed | ||
|
d56138d8ec | ||
|
b5687dc502 | ||
|
7a15599a3a | ||
|
7e5038e76c | ||
|
30f3d023d5 | ||
|
a7a1f83013 | ||
|
53053927fd | ||
|
35cab4ef93 | ||
|
43b0d84ae9 | ||
|
825145217c | ||
|
99c6fe660f | ||
|
4a69f63a78 | ||
|
39fa530c33 | ||
|
564f8aeafc | ||
|
e77f05ee52 | ||
|
f352182c20 | ||
|
7bb4be5d03 | ||
|
ef956caf59 | ||
|
8e45d4c99f | ||
|
004109b3bd | ||
|
dd5b1514b2 | ||
|
34a6c25071 | ||
|
6dc4078d74 | ||
|
6fcc7f732d | ||
|
997c04f7f8 | ||
|
658fe4e3ae | ||
|
40aaeb61f8 | ||
|
6274002623 | ||
|
24af73d1d2 | ||
|
155a364280 | ||
|
9c1492069b | ||
|
c3d5bcab99 | ||
|
c3052d2e31 | ||
|
87fd81b9d8 | ||
|
062426558b | ||
|
1c6aeef3b4 | ||
|
f7de528788 | ||
|
8d45dc126d | ||
|
1a0d969d12 | ||
|
a926ab3deb | ||
|
d31a32b073 | ||
|
c21aa8beb3 | ||
|
67079f94ae | ||
|
c1dccff70a | ||
|
7b41306c4b | ||
|
2d7390de4b | ||
|
28bbb866f2 |
14
README.md
14
README.md
@@ -2,3 +2,17 @@ wine-compholio-daily
|
||||
====================
|
||||
|
||||
Daily updates for the Wine "Compholio" Edition.
|
||||
|
||||
Current patches include:
|
||||
* Support for interface change notifications (http://bugs.winehq.org/show_bug.cgi?id=32328)
|
||||
* Support for stored file ACLs (http://bugs.winehq.org/show_bug.cgi?id=31858)
|
||||
* Support for inherited file ACLs (http://bugs.winehq.org/show_bug.cgi?id=34406)
|
||||
* Support for Junction Points (http://bugs.winehq.org/show_bug.cgi?id=12401)
|
||||
* Support for TransmitFile (http://bugs.winehq.org/show_bug.cgi?id=5048)
|
||||
* Support for GetVolumePathName
|
||||
* Implement an Arial replacement font (http://bugs.winehq.org/show_bug.cgi?id=32323)
|
||||
* Workaround for TransactNamedPipe not being supported (http://bugs.winehq.org/show_bug.cgi?id=17273)
|
||||
* XEMBED support for embedding Wine windows inside Linux applications
|
||||
* Reduced SetTimer minimum value from 15 ms to 5 ms (improves Silverlight framerates)
|
||||
* Workaround for shlwapi URLs with relative paths
|
||||
* Support for PulseAudio backend for audio
|
||||
|
90
debian/changelog
vendored
90
debian/changelog
vendored
@@ -1,3 +1,93 @@
|
||||
wine-compholio (1.7.17) unstable; urgency=low
|
||||
* Split Arial replacement into two patches.
|
||||
* Removed dynamic unwind patches (accepted upstream).
|
||||
* Removed linguistic casing patches (accepted upstream).
|
||||
* ACL data is now stored in binary instead of converting it to ASCII.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 18 Apr 2014 16:03:57 -0600
|
||||
|
||||
wine-compholio (1.7.16-1) unstable; urgency=low
|
||||
* Fix build failure caused by dynamic unwind functions.
|
||||
* Dropped liblcms2-dev dependency for old Ubuntu versions.
|
||||
-- Sebastian Lackner <sebastian@fds-team.de> Sat, 05 Apr 2014 03:48:25 +0200
|
||||
|
||||
wine-compholio (1.7.16) unstable; urgency=low
|
||||
* Add stub for RtlInstallFunctionTableCallback.
|
||||
* Further split out the SIO_ADDRESS_LIST_CHANGE patches.
|
||||
* Add proper implementation for dynamic unwind functions, removed stub implementation.
|
||||
* Fix lcms dependency (Wine requires lcms2 instead of lcms1), add build dependency to libsane-dev.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 04 Apr 2014 17:27:52 -0600
|
||||
|
||||
wine-compholio (1.7.15-1) unstable; urgency=low
|
||||
* Build 64 bit version of Wine.
|
||||
* First SIO_ADDRESS_LIST_CHANGE patch accepted upstream.
|
||||
* Added stub dll for DirectX Video Acceleration (dxva2.dll).
|
||||
* Update DXVA2 patches (additional implementation details, parts accepted upstream).
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Tue, 25 Mar 2014 06:08:01 +0100
|
||||
|
||||
wine-compholio (1.7.15) unstable; urgency=low
|
||||
* Fixed build dependencies for Debian Sid.
|
||||
* Fixed free() of a const variable (Bug #1).
|
||||
* Removed get_dir_unix_fd (no longer used, fixes compiling with "-Werror").
|
||||
* Removed 'register user administrative tools shell folder' patch (accepted upstream).
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Sun, 23 Mar 2014 12:53:32 +0100
|
||||
|
||||
wine-compholio (1.7.14) unstable; urgency=low
|
||||
* Minor updates to the ACL patches.
|
||||
* Added Liberation Sans (SIL Open Font License) as an Arial replacement.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 07 Mar 2014 13:59:11 -0700
|
||||
|
||||
wine-compholio (1.7.13-1) unstable; urgency=low
|
||||
* Fixed a typo in the configure check for extended attributes.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 21 Feb 2014 09:00:00 -0700
|
||||
|
||||
wine-compholio (1.7.13) unstable; urgency=low
|
||||
* Added support for inherited file ACLs.
|
||||
* Further separated the file ACL patches.
|
||||
* Updated linguistic casing patches to include tests.
|
||||
* Updated the patch list template to be compatible with 'git am'.
|
||||
* Moved the patching code out of the debian rules into a Makefile.
|
||||
* Removed the named pipe security access patch (accepted upstream).
|
||||
* Explicitly run configure with '--with-xattr' when building debian packages.
|
||||
* Will now fail on configure when '--with-xattr' is passed and xattr.h cannot be found.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Thu, 20 Feb 2014 18:48:03 -0700
|
||||
|
||||
wine-compholio (1.7.12-1) unstable; urgency=low
|
||||
* Fixed PulseAudio patches to apply with 'git am'.
|
||||
* Fixed PulseAudio driver configure file for upstream Wine 1.7.12.
|
||||
* Fixed PulseAudio driver pthread dependency for upstream Wine 1.7.12.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 07 Feb 2014 17:52:32 -0700
|
||||
|
||||
wine-compholio (1.7.12) unstable; urgency=low
|
||||
* Added new patches to support GetVolumePathName.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 07 Feb 2014 14:57:33 -0700
|
||||
|
||||
wine-compholio (1.7.11) unstable; urgency=low
|
||||
* Added SRWLock patch.
|
||||
* Added new patches to support TransmitFile.
|
||||
* Added new patches to support Junction Points.
|
||||
* Moved pipelight-specific patches to a separate folder.
|
||||
* Removed SRWLock patch included in upstream Wine 1.7.11.
|
||||
* Reduced SetTimer minimum limitation from 15 ms to 5 ms.
|
||||
* Added support for security access parameters for named pipes.
|
||||
* Added WINE_STRICT_DRAW_ORDERING command line environment variable.
|
||||
* Fixed a path length bug in the ACL inheritance patch (assumed DOS limitation).
|
||||
* Added some workarounds for shlwapi url functions not handling relative paths well.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 17 Jan 2014 12:27:32 -0700
|
||||
|
||||
wine-compholio (1.7.10) unstable; urgency=low
|
||||
* Removed monitor enumeration patch included in upstream Wine 1.7.10.
|
||||
* Updated SIO_ADDRESS_LIST_CHANGE patch with latest proposed version.
|
||||
* Added new patch to support linux windowlessmode (required for Qt5 browsers).
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 03 Jan 2014 12:19:14 -0700
|
||||
|
||||
wine-compholio (1.7.9) unstable; urgency=low
|
||||
* Added a new patch for windowless mode for Qt5 browsers.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 27 Dec 2013 12:03:22 -0700
|
||||
|
||||
wine-compholio (1.7.8-1) unstable; urgency=low
|
||||
* Fixed several build problems.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Sat, 07 Dec 2013 10:49:03 -0700
|
||||
|
||||
wine-compholio (1.7.8) unstable; urgency=low
|
||||
* Added PulseAudio support patches.
|
||||
* Updated SIO_ADDRESS_LIST_CHANGE patches.
|
||||
|
182
debian/control
vendored
182
debian/control
vendored
@@ -5,27 +5,21 @@ Maintainer: Erich E. Hoover <ehoover@mines.edu>
|
||||
XSBC-Original-Maintainer: Scott Ritchie <scottritchie@ubuntu.com>
|
||||
Build-Depends: autotools-dev,
|
||||
autoconf,
|
||||
bind9-host,
|
||||
bison,
|
||||
bsdmainutils,
|
||||
coreutils,
|
||||
debhelper (>= 7),
|
||||
docbook-to-man,
|
||||
docbook-utils,
|
||||
docbook-xsl,
|
||||
flex,
|
||||
fontforge,
|
||||
gawk,
|
||||
gcc-4.5 | gcc-4.7 | ubuntu-desktop (<< 1.207),
|
||||
gcc-4.5-multilib [amd64] | ubuntu-desktop (<< 1.207) [amd64],
|
||||
gcc-multilib [amd64],
|
||||
gettext,
|
||||
ia32-libs [amd64],
|
||||
ia32-libs-dev [amd64] | ubuntu-desktop (<< 1.267) [amd64],
|
||||
ia32-libs-multiarch [amd64] | ubuntu-desktop (<< 1.267) [amd64],
|
||||
lib32asound2-dev [amd64],
|
||||
lib32ncurses5-dev [amd64],
|
||||
lib32z1-dev [amd64],
|
||||
gzip,
|
||||
libacl1-dev,
|
||||
libasound2-dev [i386 lpia],
|
||||
libc6-dev-i386 [amd64],
|
||||
libasound2-dev,
|
||||
libcapi20-dev,
|
||||
libcups2-dev,
|
||||
libdbus-1-dev,
|
||||
@@ -33,27 +27,27 @@ Build-Depends: autotools-dev,
|
||||
libesd0-dev,
|
||||
libfontconfig1-dev | libfontconfig-dev,
|
||||
libfreetype6-dev,
|
||||
libgif-dev | libungif4-dev,
|
||||
libgl1-mesa-dev | nvidia-glx-dev | fglrx-driver-dev | libgl-dev,
|
||||
libglu1-mesa-dev | libglu-dev,
|
||||
libgnutls-dev,
|
||||
libgphoto2-dev | libgphoto2-6-dev | libgphoto2-2-dev (>= 2.4.6),
|
||||
libgphoto2port-dev | ubuntu-desktop (>= 1.245) | debian-edu-config,
|
||||
libgsm1-dev,
|
||||
libgstreamer-plugins-base0.10-dev,
|
||||
libgstreamer0.10-dev,
|
||||
libice-dev,
|
||||
libjpeg-dev,
|
||||
liblcms1-dev, liblcms-dev,
|
||||
liblcms2-dev | ubuntu-desktop (<< 1.267),
|
||||
libldap2-dev, libldap-dev,
|
||||
libmpg123-dev,
|
||||
libncurses5-dev [i386] | libncurses-dev [i386],
|
||||
libncurses5-dev | libncurses-dev,
|
||||
libopenal-dev (>= 1:1.12) | ubuntu-desktop (<< 1.207),
|
||||
libpng12-dev,
|
||||
libpulse-dev,
|
||||
libsane-dev,
|
||||
libssl-dev,
|
||||
libstdc++6-4.5-dev | libstdc++-dev,
|
||||
libtiff4-dev,
|
||||
libv4l-dev [i386],
|
||||
libtiff5-dev | libtiff4-dev | libtiff-dev,
|
||||
libv4l-dev,
|
||||
libx11-dev,
|
||||
libxcomposite-dev,
|
||||
libxcursor-dev,
|
||||
@@ -68,30 +62,28 @@ Build-Depends: autotools-dev,
|
||||
libxxf86vm-dev,
|
||||
linux-kernel-headers,
|
||||
linux-libc-dev,
|
||||
prelink [i386 amd64],
|
||||
prelink,
|
||||
quilt (>= 0.46-7~),
|
||||
sharutils,
|
||||
unixodbc-dev,
|
||||
x11proto-xinerama-dev
|
||||
Standards-Version: 3.9.2
|
||||
|
||||
Package: wine-compholio
|
||||
Package: wine-compholio-i386
|
||||
Architecture: i386
|
||||
Multi-Arch: foreign
|
||||
Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends}
|
||||
Depends: ${shlibs:Depends},
|
||||
libasound2-plugins,
|
||||
libncurses5
|
||||
Recommends: gettext,
|
||||
libcapi20-3,
|
||||
Recommends: libcapi20-3,
|
||||
libcups2,
|
||||
libdbus-1-3,
|
||||
libfontconfig1 | libfontconfig,
|
||||
libfreetype6,
|
||||
libgif4,
|
||||
libgnutls26,
|
||||
libgphoto2-6 | libgphoto2-2 (>= 2.4.6),
|
||||
libgphoto2-port0 (>= 2.4.6),
|
||||
libgphoto2-port10 | libgphoto2-port0 (>= 2.4.6),
|
||||
libjpeg8,
|
||||
libopenal1 (>= 1:1.12),
|
||||
libosmesa6,
|
||||
@@ -99,7 +91,7 @@ Recommends: gettext,
|
||||
libpulse0,
|
||||
libsane,
|
||||
libssl1.0.0,
|
||||
libtiff4,
|
||||
libtiff5 | libtiff4,
|
||||
libv4l-0,
|
||||
libxcomposite1,
|
||||
libxcursor1,
|
||||
@@ -111,7 +103,93 @@ Recommends: gettext,
|
||||
libxt6,
|
||||
libxxf86vm1,
|
||||
unixodbc
|
||||
Provides: wine-compholio
|
||||
Section: otherosfs
|
||||
Priority: optional
|
||||
Replaces: wine-compholio (<< 1.7.15-1~)
|
||||
Breaks: wine-compholio (<< 1.7.15-1~)
|
||||
Description: The Compholio Edition is a special build of the popular Wine software
|
||||
with patches representing my current staging tree for Wine.
|
||||
Currently these patches fix:
|
||||
* Netflix on Firefox hangs with loading bar at 100% (Bug 31993).
|
||||
* Netflix on Firefox fails with Internet Connection Problem when loading bar is
|
||||
at 99% (Bug 31858).
|
||||
.
|
||||
Microsoft Windows Compatibility Layer (Binary Emulator and Library)
|
||||
Wine is a compatibility layer for running Windows applications on Linux.
|
||||
Applications are run at full speed without the need of cpu emulation. Wine
|
||||
does not require Microsoft Windows, however it can use native system dll
|
||||
files in place of its own if they are available.
|
||||
.
|
||||
This package provides support for loading 32-bit x86 Windows applications
|
||||
.
|
||||
This package is based on a recent Wine beta. While many more applications will
|
||||
work, there may be some loss of functionality compared with the stable release
|
||||
provided by the regular wine package.
|
||||
|
||||
Package: wine-compholio-amd64
|
||||
Architecture: amd64
|
||||
Multi-Arch: foreign
|
||||
Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends}
|
||||
Depends: ${shlibs:Depends},
|
||||
libasound2-plugins,
|
||||
libncurses5
|
||||
Recommends: libcapi20-3,
|
||||
libcups2,
|
||||
libdbus-1-3,
|
||||
libfontconfig1 | libfontconfig,
|
||||
libfreetype6,
|
||||
libgnutls26,
|
||||
libgphoto2-6 | libgphoto2-2 (>= 2.4.6),
|
||||
libgphoto2-port10 | libgphoto2-port0 (>= 2.4.6),
|
||||
libjpeg8,
|
||||
libopenal1 (>= 1:1.12),
|
||||
libosmesa6,
|
||||
libpng12-0,
|
||||
libpulse0,
|
||||
libsane,
|
||||
libssl1.0.0,
|
||||
libtiff5 | libtiff4,
|
||||
libv4l-0,
|
||||
libxcomposite1,
|
||||
libxcursor1,
|
||||
libxi6,
|
||||
libxinerama1,
|
||||
libxrandr2,
|
||||
libxrender1,
|
||||
libxslt1.1,
|
||||
libxt6,
|
||||
libxxf86vm1,
|
||||
unixodbc
|
||||
Section: otherosfs
|
||||
Priority: optional
|
||||
Replaces: wine-compholio (<< 1.7.15-1~)
|
||||
Breaks: wine-compholio (<< 1.7.15-1~)
|
||||
Description: The Compholio Edition is a special build of the popular Wine software
|
||||
with patches representing my current staging tree for Wine.
|
||||
Currently these patches fix:
|
||||
* Netflix on Firefox hangs with loading bar at 100% (Bug 31993).
|
||||
* Netflix on Firefox fails with Internet Connection Problem when loading bar is
|
||||
at 99% (Bug 31858).
|
||||
.
|
||||
Microsoft Windows Compatibility Layer (Binary Emulator and Library)
|
||||
Wine is a compatibility layer for running Windows applications on Linux.
|
||||
Applications are run at full speed without the need of cpu emulation. Wine
|
||||
does not require Microsoft Windows, however it can use native system dll
|
||||
files in place of its own if they are available.
|
||||
.
|
||||
This package provides support for loading 64-bit x86 Windows applications
|
||||
.
|
||||
This package is based on a recent Wine beta. While many more applications will
|
||||
work, there may be some loss of functionality compared with the stable release
|
||||
provided by the regular wine package.
|
||||
|
||||
Package: wine-compholio
|
||||
Architecture: i386 amd64
|
||||
Multi-Arch: foreign
|
||||
Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends}
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends},
|
||||
wine-compholio-i386 (= ${binary:Version}) [i386 amd64],
|
||||
wine-compholio-amd64 (= ${binary:Version}) [amd64],
|
||||
Section: otherosfs
|
||||
Priority: optional
|
||||
Description: The Compholio Edition is a special build of the popular Wine software
|
||||
@@ -134,3 +212,57 @@ Description: The Compholio Edition is a special build of the popular Wine softwa
|
||||
This package is based on a recent Wine beta. While many more applications will
|
||||
work, there may be some loss of functionality compared with the stable release
|
||||
provided by the regular wine package.
|
||||
|
||||
Package: wine-compholio-dev
|
||||
Architecture: i386 amd64
|
||||
Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends}
|
||||
Depends: libc6-dev,
|
||||
${shlibs:Depends},
|
||||
wine-compholio-i386 (= ${binary:Version}) [i386 amd64],
|
||||
wine-compholio-amd64 (= ${binary:Version}) [amd64],
|
||||
Section: libdevel
|
||||
Priority: optional
|
||||
Replaces: wine-compholio (<< 1.7.15-1~)
|
||||
Breaks: wine-compholio (<< 1.7.15-1~)
|
||||
Description: The Compholio Edition is a special build of the popular Wine software
|
||||
with patches representing my current staging tree for Wine.
|
||||
Currently these patches fix:
|
||||
* Netflix on Firefox hangs with loading bar at 100% (Bug 31993).
|
||||
* Netflix on Firefox fails with Internet Connection Problem when loading bar is
|
||||
at 99% (Bug 31858).
|
||||
.
|
||||
Microsoft Windows Compatibility Layer (Binary Emulator and Library)
|
||||
Wine is a compatibility layer for running Windows applications on Linux.
|
||||
Applications are run at full speed without the need of cpu emulation. Wine
|
||||
does not require Microsoft Windows, however it can use native system dll
|
||||
files in place of its own if they are available.
|
||||
.
|
||||
This package consists of the development files needed to compile programs
|
||||
using wine's free version of the Microsoft Windows API.
|
||||
|
||||
Package: wine-compholio-dbg
|
||||
Architecture: i386 amd64
|
||||
Multi-Arch: same
|
||||
Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends}
|
||||
Depends: ${shlibs:Depends},
|
||||
wine-compholio-i386 (= ${binary:Version}) [i386 amd64],
|
||||
wine-compholio-amd64 (= ${binary:Version}) [amd64],
|
||||
Section: debug
|
||||
Priority: optional
|
||||
Replaces: wine-compholio (<< 1.7.15-1~)
|
||||
Breaks: wine-compholio (<< 1.7.15-1~)
|
||||
Description: The Compholio Edition is a special build of the popular Wine software
|
||||
with patches representing my current staging tree for Wine.
|
||||
Currently these patches fix:
|
||||
* Netflix on Firefox hangs with loading bar at 100% (Bug 31993).
|
||||
* Netflix on Firefox fails with Internet Connection Problem when loading bar is
|
||||
at 99% (Bug 31858).
|
||||
.
|
||||
Microsoft Windows Compatibility Layer (Binary Emulator and Library)
|
||||
Wine is a compatibility layer for running Windows applications on Linux.
|
||||
Applications are run at full speed without the need of cpu emulation. Wine
|
||||
does not require Microsoft Windows, however it can use native system dll
|
||||
files in place of its own if they are available.
|
||||
.
|
||||
This package includes debugging symbols useful for reporting crashes and other
|
||||
failures.
|
||||
|
167
debian/rules
vendored
167
debian/rules
vendored
@@ -1,36 +1,4 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
|
||||
# These are used for cross-compiling and for saving the configure script
|
||||
# from having to guess our platform (since we know it already)
|
||||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
|
||||
CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
|
||||
else
|
||||
CROSS= --build $(DEB_BUILD_GNU_TYPE)
|
||||
endif
|
||||
|
||||
|
||||
# Apparently it's important to have an empty LDFLAGS, see:
|
||||
# http://www.winehq.org/pipermail/wine-bugs/2007-July/062505.html
|
||||
# For Wine 1.1.44 it's also important not to compile at -O0
|
||||
LDFLAGS =
|
||||
CFLAGS = -Wall -g -O2
|
||||
|
||||
# On amd64 the 32-bit libraries are in lib32 instead of lib
|
||||
ifeq ($(DEB_BUILD_ARCH), amd64)
|
||||
CONFFLAGS += --libdir=\$${prefix}/lib32
|
||||
endif
|
||||
|
||||
# Use gcc-4.5 if it's available
|
||||
ifeq ($(shell which gcc-4.5),)
|
||||
@@ -39,115 +7,40 @@ else
|
||||
CC = gcc-4.5
|
||||
endif
|
||||
|
||||
# Support passing of parallel=<n> in build options
|
||||
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
||||
NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
||||
MAKEFLAGS += -j$(NUMJOBS)
|
||||
endif
|
||||
%:
|
||||
dh $@ --parallel
|
||||
|
||||
configure:
|
||||
# Unpack the original Wine version
|
||||
tar -xjvf wine-*.tar.bz2
|
||||
mv wine-*/* .
|
||||
rm wine-*/.* || true
|
||||
rm wine-*.tar.bz2
|
||||
rmdir wine-*
|
||||
override_dh_auto_configure:
|
||||
|
||||
config.status: configure
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
|
||||
cp -f /usr/share/misc/config.sub config.sub
|
||||
endif
|
||||
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
|
||||
cp -f /usr/share/misc/config.guess config.guess
|
||||
endif
|
||||
# Apply our patches, reconfigure, and update the wineserver protocol request data
|
||||
make -C "$(CURDIR)/patches/" DESTDIR="$(CURDIR)" install
|
||||
|
||||
# Apply our patches to Wine
|
||||
for DIR in $(find $(CURDIR)/patches/ -type d | sort); do \
|
||||
for FILE in $(ls $$DIR | sort); do \
|
||||
patch -N -p0 --strip=1 < $$DIR/$$FILE || exit 1; \
|
||||
done \
|
||||
done
|
||||
|
||||
# Update the configure script
|
||||
autoreconf
|
||||
|
||||
# Configure
|
||||
CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/opt/wine-compholio --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info $(CONFFLAGS)
|
||||
|
||||
|
||||
|
||||
build: build-stamp
|
||||
|
||||
build-stamp: config.status
|
||||
dh_testdir
|
||||
|
||||
# Add here commands to compile the package.
|
||||
$(MAKE) depend
|
||||
$(MAKE) $(MAKEFLAGS)
|
||||
#docbook-to-man debian/wine-compholio.sgml > wine-compholio.1
|
||||
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
[ ! -f Makefile ] || $(MAKE) distclean
|
||||
rm -f config.sub config.guess
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/wine-compholio.
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/wine-compholio install
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
# dh_installchangelogs ChangeLog
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
# dh_install
|
||||
# dh_installmenu
|
||||
# dh_installdebconf
|
||||
# dh_installlogrotate
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installmime
|
||||
# dh_python
|
||||
# dh_installinit
|
||||
# dh_installcron
|
||||
# dh_installinfo
|
||||
dh_installman
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# dh_perl
|
||||
dh_makeshlibs
|
||||
dh_installdeb
|
||||
ifeq ($(DEB_BUILD_ARCH), amd64)
|
||||
dh_gencontrol -- -V"shlibs:Depends= ia32-libs (>= 1.6), lib32asound2 (>> 1.0.14), libc6-i386 (>= 2.6-1), lib32nss-mdns (>= 0.10-3)"
|
||||
./configure --prefix=/opt/wine-compholio --libdir=\$${prefix}/lib64 --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --enable-win64 --with-xattr $(CONFFLAGS)
|
||||
else
|
||||
LD_LIBRARY_PATH="$(CURDIR)/debian/wine-compholio/opt/wine-compholio/lib:${LD_LIBRARY_PATH}" dh_shlibdeps -L wine-compholio -l debian/wine-compholio/opt/wine-compholio/lib
|
||||
dh_gencontrol
|
||||
./configure --prefix=/opt/wine-compholio --libdir=\$${prefix}/lib --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-xattr $(CONFFLAGS)
|
||||
endif
|
||||
dh_md5sums
|
||||
dh_builddeb -- -Z lzma
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
override_dh_auto_test:
|
||||
# Wine's test suite does not pass on build daemons, skip it for now
|
||||
|
||||
override_dh_installdocs:
|
||||
dh_installdocs --link-doc=wine-compholio
|
||||
|
||||
override_dh_install:
|
||||
dh_install --fail-missing
|
||||
# These files will end up in multiple packages otherwise
|
||||
rm -f debian/wine-compholio/opt/wine-compholio/bin/wine
|
||||
rm -f debian/wine-compholio/opt/wine-compholio/bin/wine-preloader
|
||||
rm -f debian/wine-compholio/opt/wine-compholio/bin/wine64
|
||||
rm -f debian/wine-compholio/opt/wine-compholio/bin/wine64-preloader
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip -Xwine-pthread -Xwine-kthread --dbg-package=wine-compholio-dbg
|
||||
|
||||
override_dh_shlibdeps:
|
||||
ifeq ($(DEB_HOST_ARCH),amd64)
|
||||
dh_shlibdeps -l $(CURDIR)/debian/tmp/opt/wine-compholio/lib64/
|
||||
else
|
||||
dh_shlibdeps -l $(CURDIR)/debian/tmp/opt/wine-compholio/lib/
|
||||
endif
|
||||
|
29
patch-list-template.diff → debian/tools/generate-patchlist.sh
vendored
Normal file → Executable file
29
patch-list-template.diff → debian/tools/generate-patchlist.sh
vendored
Normal file → Executable file
@@ -1,3 +1,31 @@
|
||||
#!/bin/sh
|
||||
PATCH_DATA="";
|
||||
|
||||
for FILE in patches/*/*.def; do
|
||||
UUID=$(echo "${FILE}" | sed -e 's|^.*/||g' -e 's|\.def$||g');
|
||||
REVISION=$(cat "${FILE}" | sed -n 's|Revision: \(.*\)|\1|p');
|
||||
AUTHOR=$(cat "${FILE}" | sed -n 's|Author: \(.*\)|\1|p');
|
||||
TITLE=$(cat "${FILE}" | sed -n 's|Title: \(.*\)|\1|p');
|
||||
if [ "${AUTHOR}" = "" ] && [ "${TITLE}" = "" ]; then
|
||||
continue;
|
||||
fi
|
||||
if [ "${PATCH_DATA}" != "" ]; then
|
||||
PATCH_DATA="${PATCH_DATA}
|
||||
";
|
||||
fi
|
||||
PATCH_DATA="${PATCH_DATA}+ { \"${UUID}:${REVISION}\", \"${AUTHOR}\", \"${TITLE}\" },";
|
||||
done
|
||||
|
||||
PATCH_LINES=$(echo "${PATCH_DATA}" | wc -l);
|
||||
PATCH_LINES=$((${PATCH_LINES}+20));
|
||||
PATCH_DATA=$(echo "${PATCH_DATA}" | sed ':a;N;$!ba;s/\n/\\n/g');
|
||||
|
||||
cat <<EOF | sed -e "s|##PATCH_LINES##|${PATCH_LINES}|" \
|
||||
-e "s|##PATCH_DATA##|${PATCH_DATA}|"
|
||||
From: "FDS-Team" <webmaster@fds-team.de>
|
||||
Subject: Autogenerated patch list.
|
||||
|
||||
---
|
||||
diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c
|
||||
index 8bd4eb7..4b4c318 100644
|
||||
--- a/dlls/ntdll/misc.c
|
||||
@@ -135,3 +163,4 @@ index 242bb69..aa9e585 100644
|
||||
extern const char *wine_get_build_id(void);
|
||||
extern void wine_init_argv0_path( const char *argv0 );
|
||||
extern void wine_exec_wine_binary( const char *name, char **argv, const char *env_var );
|
||||
EOF
|
572
debian/tools/gitapply.sh
vendored
Executable file
572
debian/tools/gitapply.sh
vendored
Executable file
File diff suppressed because it is too large
Load Diff
4
debian/wine-compholio-amd64.install
vendored
Normal file
4
debian/wine-compholio-amd64.install
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/opt/wine-compholio/lib64/libwine.so*
|
||||
/opt/wine-compholio/lib64/wine
|
||||
/opt/wine-compholio/bin/wine64
|
||||
/opt/wine-compholio/bin/wine64-preloader
|
1
debian/wine-compholio-dev.install
vendored
Normal file
1
debian/wine-compholio-dev.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/opt/wine-compholio/include
|
4
debian/wine-compholio-i386.install
vendored
Normal file
4
debian/wine-compholio-i386.install
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/opt/wine-compholio/lib/libwine.so*
|
||||
/opt/wine-compholio/lib/wine
|
||||
/opt/wine-compholio/bin/wine
|
||||
/opt/wine-compholio/bin/wine-preloader
|
4
debian/wine-compholio.docs
vendored
Normal file
4
debian/wine-compholio.docs
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
documentation/README.*
|
||||
ANNOUNCE
|
||||
AUTHORS
|
||||
README
|
2
debian/wine-compholio.install
vendored
Normal file
2
debian/wine-compholio.install
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/opt/wine-compholio/bin
|
||||
/opt/wine-compholio/share
|
@@ -1,24 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATCH_DATA="";
|
||||
for FILE in patches/*/*.def; do
|
||||
UUID=$(echo "${FILE}" | sed -e 's|^.*/||g' -e 's|\.def$||g');
|
||||
REVISION=$(cat "${FILE}" | sed -n 's|Revision: \(.*\)|\1|p');
|
||||
AUTHOR=$(cat "${FILE}" | sed -n 's|Author: \(.*\)|\1|p');
|
||||
TITLE=$(cat "${FILE}" | sed -n 's|Title: \(.*\)|\1|p');
|
||||
if [ "${AUTHOR}" = "" ] && [ "${TITLE}" = "" ]; then
|
||||
continue;
|
||||
fi
|
||||
if [ "${PATCH_DATA}" != "" ]; then
|
||||
PATCH_DATA="${PATCH_DATA}
|
||||
";
|
||||
fi
|
||||
PATCH_DATA="${PATCH_DATA}+ { \"${UUID}:${REVISION}\", \"${AUTHOR}\", \"${TITLE}\" },";
|
||||
done
|
||||
PATCH_LINES=$(echo "${PATCH_DATA}" | grep -c '\n');
|
||||
PATCH_LINES=$((${PATCH_LINES}+20));
|
||||
PATCH_DATA=$(echo "${PATCH_DATA}" | sed ':a;N;$!ba;s/\n/\\n/g');
|
||||
cat patch-list-template.diff | sed \
|
||||
-e "s|##PATCH_LINES##|${PATCH_LINES}|" \
|
||||
-e "s|##PATCH_DATA##|${PATCH_DATA}|"
|
||||
#
|
@@ -0,0 +1,77 @@
|
||||
From a0625ca7d07703028fdad511c37c587e213ff481 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 3 Apr 2014 09:21:51 -0600
|
||||
Subject: server: Implement socket-specific ioctl() routine.
|
||||
|
||||
---
|
||||
server/sock.c | 26 ++++++++++++++++++++++----
|
||||
1 file changed, 22 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 5ffb1fe..3eb1bdf 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -49,6 +49,8 @@
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "winerror.h"
|
||||
+#define USE_WS_PREFIX
|
||||
+#include "winsock2.h"
|
||||
|
||||
#include "process.h"
|
||||
#include "file.h"
|
||||
@@ -83,9 +85,6 @@
|
||||
#define FD_WINE_RAW 0x80000000
|
||||
#define FD_WINE_INTERNAL 0xFFFF0000
|
||||
|
||||
-/* Constants for WSAIoctl() */
|
||||
-#define WSA_FLAG_OVERLAPPED 0x01
|
||||
-
|
||||
struct sock
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
@@ -117,6 +116,8 @@ static void sock_destroy( struct object *obj );
|
||||
static int sock_get_poll_events( struct fd *fd );
|
||||
static void sock_poll_event( struct fd *fd, int event );
|
||||
static enum server_fd_type sock_get_fd_type( struct fd *fd );
|
||||
+static obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
|
||||
+ int blocking, const void *data, data_size_t size );
|
||||
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
|
||||
static void sock_reselect_async( struct fd *fd, struct async_queue *queue );
|
||||
static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb );
|
||||
@@ -151,7 +152,7 @@ static const struct fd_ops sock_fd_ops =
|
||||
sock_poll_event, /* poll_event */
|
||||
no_flush, /* flush */
|
||||
sock_get_fd_type, /* get_fd_type */
|
||||
- default_fd_ioctl, /* ioctl */
|
||||
+ sock_ioctl, /* ioctl */
|
||||
sock_queue_async, /* queue_async */
|
||||
sock_reselect_async, /* reselect_async */
|
||||
sock_cancel_async /* cancel_async */
|
||||
@@ -518,6 +519,23 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd )
|
||||
return FD_TYPE_SOCKET;
|
||||
}
|
||||
|
||||
+obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
|
||||
+ int blocking, const void *data, data_size_t size )
|
||||
+{
|
||||
+ struct sock *sock = get_fd_user( fd );
|
||||
+
|
||||
+ assert( sock->obj.ops == &sock_ops );
|
||||
+
|
||||
+ switch(code)
|
||||
+ {
|
||||
+ case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||
+ /* intentional fallthrough, not yet supported */
|
||||
+ default:
|
||||
+ set_error( STATUS_NOT_SUPPORTED );
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
|
||||
{
|
||||
struct sock *sock = get_fd_user( fd );
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -1,97 +0,0 @@
|
||||
From 362ec39591ce54bcb5ce825c1baab8f5d0885193 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 5 Dec 2013 13:32:34 -0700
|
||||
Subject: ws2_32: Ask the server to process unsupported WSAIoctl operations.
|
||||
|
||||
---
|
||||
dlls/ws2_32/socket.c | 56 +++++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 49 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
|
||||
index 304b0eb..170dde7 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -3608,6 +3608,36 @@ static const char *debugstr_wsaioctl(DWORD ioctl)
|
||||
(USHORT)(ioctl & 0xffff));
|
||||
}
|
||||
|
||||
+/* do an ioctl call through the server */
|
||||
+static DWORD server_ioctl_sock( SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size,
|
||||
+ LPVOID out_buff, DWORD out_size, LPDWORD ret_size,
|
||||
+ LPWSAOVERLAPPED overlapped,
|
||||
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion )
|
||||
+{
|
||||
+ HANDLE event = overlapped ? overlapped->hEvent : 0;
|
||||
+ HANDLE handle = SOCKET2HANDLE( s );
|
||||
+ struct ws2_async *wsa;
|
||||
+ NTSTATUS status;
|
||||
+ PIO_STATUS_BLOCK io;
|
||||
+
|
||||
+ if (!(wsa = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*wsa) )))
|
||||
+ return WSA_NOT_ENOUGH_MEMORY;
|
||||
+ wsa->hSocket = handle;
|
||||
+ wsa->user_overlapped = overlapped;
|
||||
+ wsa->completion_func = completion;
|
||||
+ io = (overlapped ? (PIO_STATUS_BLOCK)overlapped : &wsa->local_iosb);
|
||||
+
|
||||
+ status = NtDeviceIoControlFile( handle, event, (PIO_APC_ROUTINE)ws2_async_apc, wsa, io, code,
|
||||
+ in_buff, in_size, out_buff, out_size );
|
||||
+ if (status == STATUS_NOT_SUPPORTED)
|
||||
+ FIXME("Unsupported ioctl %x (device=%x access=%x func=%x method=%x)\n",
|
||||
+ code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
|
||||
+
|
||||
+ if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, wsa );
|
||||
+
|
||||
+ return NtStatusToWSAError( status );
|
||||
+}
|
||||
+
|
||||
/**********************************************************************
|
||||
* WSAIoctl (WS2_32.50)
|
||||
*
|
||||
@@ -3799,12 +3829,6 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
|
||||
break;
|
||||
}
|
||||
|
||||
- case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||
- FIXME("-> SIO_ADDRESS_LIST_CHANGE request: stub\n");
|
||||
- /* FIXME: error and return code depend on whether socket was created
|
||||
- * with WSA_FLAG_OVERLAPPED, but there is no easy way to get this */
|
||||
- break;
|
||||
-
|
||||
case WS_SIO_ADDRESS_LIST_QUERY:
|
||||
{
|
||||
DWORD size;
|
||||
@@ -4040,11 +4064,29 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
|
||||
WSASetLastError(WSAEOPNOTSUPP);
|
||||
return SOCKET_ERROR;
|
||||
default:
|
||||
- FIXME("unsupported WS_IOCTL cmd (%s)\n", debugstr_wsaioctl(code));
|
||||
status = WSAEOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (status == WSAEOPNOTSUPP)
|
||||
+ {
|
||||
+ status = server_ioctl_sock(s, code, in_buff, in_size, out_buff, out_size, ret_size,
|
||||
+ overlapped, completion);
|
||||
+ if (status != WSAEOPNOTSUPP)
|
||||
+ {
|
||||
+ if (status == 0 || status == WSA_IO_PENDING)
|
||||
+ TRACE("-> %s request\n", debugstr_wsaioctl(code));
|
||||
+ else
|
||||
+ ERR("-> %s request failed with status 0x%x\n", debugstr_wsaioctl(code), status);
|
||||
+
|
||||
+ /* overlapped and completion operations will be handled by the server */
|
||||
+ completion = NULL;
|
||||
+ overlapped = NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ FIXME("unsupported WS_IOCTL cmd (%s)\n", debugstr_wsaioctl(code));
|
||||
+ }
|
||||
+
|
||||
if (completion)
|
||||
{
|
||||
FIXME( "completion routine %p not supported\n", completion );
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,114 @@
|
||||
From 45dfbd2ddb5ca2c64fcfd56392be9c55513abc4b Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 3 Apr 2014 09:23:02 -0600
|
||||
Subject: server: Add delayed processing for socket-specific ioctl().
|
||||
|
||||
---
|
||||
server/event.c | 13 +++++++++++++
|
||||
server/named_pipe.c | 13 -------------
|
||||
server/object.h | 1 +
|
||||
server/sock.c | 19 +++++++++++++++++--
|
||||
4 files changed, 31 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/server/event.c b/server/event.c
|
||||
index 4d3c562..0daa5b2 100644
|
||||
--- a/server/event.c
|
||||
+++ b/server/event.c
|
||||
@@ -124,6 +124,19 @@ struct event *create_event( struct directory *root, const struct unicode_str *na
|
||||
return event;
|
||||
}
|
||||
|
||||
+obj_handle_t alloc_wait_event( struct process *process )
|
||||
+{
|
||||
+ obj_handle_t handle = 0;
|
||||
+ struct event *event = create_event( NULL, NULL, 0, 1, 0, NULL );
|
||||
+
|
||||
+ if (event)
|
||||
+ {
|
||||
+ handle = alloc_handle( process, event, EVENT_ALL_ACCESS, 0 );
|
||||
+ release_object( event );
|
||||
+ }
|
||||
+ return handle;
|
||||
+}
|
||||
+
|
||||
struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access )
|
||||
{
|
||||
return (struct event *)get_handle_obj( process, handle, access, &event_ops );
|
||||
diff --git a/server/named_pipe.c b/server/named_pipe.c
|
||||
index 4c85104..6ba2145 100644
|
||||
--- a/server/named_pipe.c
|
||||
+++ b/server/named_pipe.c
|
||||
@@ -587,19 +587,6 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
|
||||
return FD_TYPE_PIPE;
|
||||
}
|
||||
|
||||
-static obj_handle_t alloc_wait_event( struct process *process )
|
||||
-{
|
||||
- obj_handle_t handle = 0;
|
||||
- struct event *event = create_event( NULL, NULL, 0, 1, 0, NULL );
|
||||
-
|
||||
- if (event)
|
||||
- {
|
||||
- handle = alloc_handle( process, event, EVENT_ALL_ACCESS, 0 );
|
||||
- release_object( event );
|
||||
- }
|
||||
- return handle;
|
||||
-}
|
||||
-
|
||||
static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
|
||||
int blocking, const void *data, data_size_t size )
|
||||
{
|
||||
diff --git a/server/object.h b/server/object.h
|
||||
index bb3ff21..bad162f 100644
|
||||
--- a/server/object.h
|
||||
+++ b/server/object.h
|
||||
@@ -159,6 +159,7 @@ extern struct event *create_event( struct directory *root, const struct unicode_
|
||||
const struct security_descriptor *sd );
|
||||
extern struct keyed_event *create_keyed_event( struct directory *root, const struct unicode_str *name,
|
||||
unsigned int attr, const struct security_descriptor *sd );
|
||||
+extern obj_handle_t alloc_wait_event( struct process *process );
|
||||
extern struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||
extern struct keyed_event *get_keyed_event_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||
extern void pulse_event( struct event *event );
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 3eb1bdf..05fc38b 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -523,17 +523,32 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
|
||||
int blocking, const void *data, data_size_t size )
|
||||
{
|
||||
struct sock *sock = get_fd_user( fd );
|
||||
+ obj_handle_t wait_handle = 0;
|
||||
+ async_data_t new_data;
|
||||
+ int error;
|
||||
|
||||
assert( sock->obj.ops == &sock_ops );
|
||||
|
||||
+ if (blocking)
|
||||
+ {
|
||||
+ if (!(wait_handle = alloc_wait_event( current->process ))) return 0;
|
||||
+ new_data = *async_data;
|
||||
+ new_data.event = wait_handle;
|
||||
+ async_data = &new_data;
|
||||
+ }
|
||||
switch(code)
|
||||
{
|
||||
case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||
/* intentional fallthrough, not yet supported */
|
||||
default:
|
||||
- set_error( STATUS_NOT_SUPPORTED );
|
||||
- return 0;
|
||||
+ error = STATUS_NOT_SUPPORTED;
|
||||
+ break;
|
||||
}
|
||||
+ set_error( error );
|
||||
+ if (error == STATUS_PENDING)
|
||||
+ return wait_handle;
|
||||
+ close_handle( current->process, wait_handle );
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -1,452 +0,0 @@
|
||||
From 8bd705add6a11c82faa1695656fd84c2611358c1 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 5 Dec 2013 13:45:15 -0700
|
||||
Subject: server: Implement an interface change notification object.
|
||||
|
||||
---
|
||||
server/event.c | 13 +++
|
||||
server/named_pipe.c | 13 ---
|
||||
server/object.h | 1 +
|
||||
server/sock.c | 303 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
4 files changed, 313 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/server/event.c b/server/event.c
|
||||
index b8515af..e8a3888 100644
|
||||
--- a/server/event.c
|
||||
+++ b/server/event.c
|
||||
@@ -124,6 +124,19 @@ struct event *create_event( struct directory *root, const struct unicode_str *na
|
||||
return event;
|
||||
}
|
||||
|
||||
+obj_handle_t alloc_wait_event( struct process *process )
|
||||
+{
|
||||
+ obj_handle_t handle = 0;
|
||||
+ struct event *event = create_event( NULL, NULL, 0, 1, 0, NULL );
|
||||
+
|
||||
+ if (event)
|
||||
+ {
|
||||
+ handle = alloc_handle( process, event, EVENT_ALL_ACCESS, 0 );
|
||||
+ release_object( event );
|
||||
+ }
|
||||
+ return handle;
|
||||
+}
|
||||
+
|
||||
struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access )
|
||||
{
|
||||
return (struct event *)get_handle_obj( process, handle, access, &event_ops );
|
||||
diff --git a/server/named_pipe.c b/server/named_pipe.c
|
||||
index 4c85104..6ba2145 100644
|
||||
--- a/server/named_pipe.c
|
||||
+++ b/server/named_pipe.c
|
||||
@@ -587,19 +587,6 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
|
||||
return FD_TYPE_PIPE;
|
||||
}
|
||||
|
||||
-static obj_handle_t alloc_wait_event( struct process *process )
|
||||
-{
|
||||
- obj_handle_t handle = 0;
|
||||
- struct event *event = create_event( NULL, NULL, 0, 1, 0, NULL );
|
||||
-
|
||||
- if (event)
|
||||
- {
|
||||
- handle = alloc_handle( process, event, EVENT_ALL_ACCESS, 0 );
|
||||
- release_object( event );
|
||||
- }
|
||||
- return handle;
|
||||
-}
|
||||
-
|
||||
static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
|
||||
int blocking, const void *data, data_size_t size )
|
||||
{
|
||||
diff --git a/server/object.h b/server/object.h
|
||||
index bb3ff21..bad162f 100644
|
||||
--- a/server/object.h
|
||||
+++ b/server/object.h
|
||||
@@ -159,6 +159,7 @@ extern struct event *create_event( struct directory *root, const struct unicode_
|
||||
const struct security_descriptor *sd );
|
||||
extern struct keyed_event *create_keyed_event( struct directory *root, const struct unicode_str *name,
|
||||
unsigned int attr, const struct security_descriptor *sd );
|
||||
+extern obj_handle_t alloc_wait_event( struct process *process );
|
||||
extern struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||
extern struct keyed_event *get_keyed_event_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||
extern void pulse_event( struct event *event );
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 1a3a8f7..a34d086 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -44,11 +44,17 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+# include <linux/rtnetlink.h>
|
||||
+#endif
|
||||
+
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "winerror.h"
|
||||
+#define USE_WS_PREFIX
|
||||
+#include "winsock2.h"
|
||||
|
||||
#include "process.h"
|
||||
#include "file.h"
|
||||
@@ -83,9 +89,6 @@
|
||||
#define FD_WINE_RAW 0x80000000
|
||||
#define FD_WINE_INTERNAL 0xFFFF0000
|
||||
|
||||
-/* Constants for WSAIoctl() */
|
||||
-#define WSA_FLAG_OVERLAPPED 0x01
|
||||
-
|
||||
struct sock
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
@@ -107,8 +110,19 @@ struct sock
|
||||
struct sock *deferred; /* socket that waits for a deferred accept */
|
||||
struct async_queue *read_q; /* queue for asynchronous reads */
|
||||
struct async_queue *write_q; /* queue for asynchronous writes */
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+ struct async_queue *ifchange_q; /* queue for interface change notifications */
|
||||
+ struct list ifchange_entry; /* entry in ifchange notification list */
|
||||
+#endif
|
||||
};
|
||||
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+/* only keep one ifchange object around, all sockets waiting for wakeups will look to it */
|
||||
+static struct object *ifchange_object = NULL;
|
||||
+
|
||||
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
|
||||
+#endif
|
||||
+
|
||||
static void sock_dump( struct object *obj, int verbose );
|
||||
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static struct fd *sock_get_fd( struct object *obj );
|
||||
@@ -117,6 +131,8 @@ static void sock_destroy( struct object *obj );
|
||||
static int sock_get_poll_events( struct fd *fd );
|
||||
static void sock_poll_event( struct fd *fd, int event );
|
||||
static enum server_fd_type sock_get_fd_type( struct fd *fd );
|
||||
+static obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
|
||||
+ int blocking, const void *data, data_size_t size );
|
||||
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
|
||||
static void sock_reselect_async( struct fd *fd, struct async_queue *queue );
|
||||
static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb );
|
||||
@@ -151,7 +167,7 @@ static const struct fd_ops sock_fd_ops =
|
||||
sock_poll_event, /* poll_event */
|
||||
no_flush, /* flush */
|
||||
sock_get_fd_type, /* get_fd_type */
|
||||
- default_fd_ioctl, /* ioctl */
|
||||
+ sock_ioctl, /* ioctl */
|
||||
sock_queue_async, /* queue_async */
|
||||
sock_reselect_async, /* reselect_async */
|
||||
sock_cancel_async /* cancel_async */
|
||||
@@ -518,6 +534,43 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd )
|
||||
return FD_TYPE_SOCKET;
|
||||
}
|
||||
|
||||
+obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
|
||||
+ int blocking, const void *data, data_size_t size )
|
||||
+{
|
||||
+ struct sock *sock = get_fd_user( fd );
|
||||
+ obj_handle_t wait_handle = 0;
|
||||
+ async_data_t new_data;
|
||||
+
|
||||
+ assert( sock->obj.ops == &sock_ops );
|
||||
+
|
||||
+ if (blocking)
|
||||
+ {
|
||||
+ if (!(wait_handle = alloc_wait_event( current->process ))) return 0;
|
||||
+ new_data = *async_data;
|
||||
+ new_data.event = wait_handle;
|
||||
+ async_data = &new_data;
|
||||
+ }
|
||||
+ switch(code)
|
||||
+ {
|
||||
+ case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+ if (sock_add_ifchange( sock, async_data ))
|
||||
+ {
|
||||
+ set_error( STATUS_PENDING );
|
||||
+ return wait_handle;
|
||||
+ }
|
||||
+#else
|
||||
+ set_error( STATUS_NOT_SUPPORTED );
|
||||
+#endif
|
||||
+ break;
|
||||
+ default:
|
||||
+ close_handle( current->process, wait_handle );
|
||||
+ return default_fd_ioctl(fd, code, async_data, blocking, data, size);
|
||||
+ }
|
||||
+ close_handle( current->process, wait_handle );
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
|
||||
{
|
||||
struct sock *sock = get_fd_user( fd );
|
||||
@@ -592,6 +645,14 @@ static void sock_destroy( struct object *obj )
|
||||
|
||||
free_async_queue( sock->read_q );
|
||||
free_async_queue( sock->write_q );
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+ if (sock->ifchange_q)
|
||||
+ {
|
||||
+ free_async_queue( sock->ifchange_q );
|
||||
+ list_remove( &sock->ifchange_entry );
|
||||
+ release_object( ifchange_object );
|
||||
+ }
|
||||
+#endif
|
||||
if (sock->event) release_object( sock->event );
|
||||
if (sock->fd)
|
||||
{
|
||||
@@ -618,6 +679,9 @@ static void init_sock(struct sock *sock)
|
||||
sock->deferred = NULL;
|
||||
sock->read_q = NULL;
|
||||
sock->write_q = NULL;
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+ sock->ifchange_q = NULL;
|
||||
+#endif
|
||||
memset( sock->errors, 0, sizeof(sock->errors) );
|
||||
}
|
||||
|
||||
@@ -906,6 +970,237 @@ static void sock_set_error(void)
|
||||
set_error( sock_get_ntstatus( errno ) );
|
||||
}
|
||||
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+
|
||||
+static void ifchange_dump( struct object *obj, int verbose );
|
||||
+static struct fd *ifchange_get_fd( struct object *obj );
|
||||
+static void ifchange_destroy( struct object *obj );
|
||||
+
|
||||
+static int ifchange_get_poll_events( struct fd *fd );
|
||||
+static void ifchange_poll_event( struct fd *fd, int event );
|
||||
+static void ifchange_reselect_async( struct fd *fd, struct async_queue *queue );
|
||||
+
|
||||
+struct ifchange
|
||||
+{
|
||||
+ struct object obj; /* object header */
|
||||
+ struct fd *fd; /* interface change file descriptor */
|
||||
+ struct list sockets; /* list of sockets to send interface change notifications */
|
||||
+};
|
||||
+
|
||||
+static const struct object_ops ifchange_ops =
|
||||
+{
|
||||
+ sizeof(struct ifchange), /* size */
|
||||
+ ifchange_dump, /* dump */
|
||||
+ no_get_type, /* get_type */
|
||||
+ add_queue, /* add_queue */
|
||||
+ NULL, /* remove_queue */
|
||||
+ NULL, /* signaled */
|
||||
+ no_satisfied, /* satisfied */
|
||||
+ no_signal, /* signal */
|
||||
+ ifchange_get_fd, /* get_fd */
|
||||
+ default_fd_map_access, /* map_access */
|
||||
+ default_get_sd, /* get_sd */
|
||||
+ default_set_sd, /* set_sd */
|
||||
+ no_lookup_name, /* lookup_name */
|
||||
+ no_open_file, /* open_file */
|
||||
+ no_close_handle, /* close_handle */
|
||||
+ ifchange_destroy /* destroy */
|
||||
+};
|
||||
+
|
||||
+static const struct fd_ops ifchange_fd_ops =
|
||||
+{
|
||||
+ ifchange_get_poll_events, /* get_poll_events */
|
||||
+ ifchange_poll_event, /* poll_event */
|
||||
+ NULL, /* flush */
|
||||
+ NULL, /* get_fd_type */
|
||||
+ NULL, /* ioctl */
|
||||
+ NULL, /* queue_async */
|
||||
+ ifchange_reselect_async, /* reselect_async */
|
||||
+ NULL /* cancel_async */
|
||||
+};
|
||||
+
|
||||
+static void ifchange_dump( struct object *obj, int verbose )
|
||||
+{
|
||||
+ assert( obj->ops == &ifchange_ops );
|
||||
+ printf( "ifchange\n" );
|
||||
+}
|
||||
+
|
||||
+static struct fd *ifchange_get_fd( struct object *obj )
|
||||
+{
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+ return (struct fd *)grab_object( ifchange->fd );
|
||||
+}
|
||||
+
|
||||
+static void ifchange_destroy( struct object *obj )
|
||||
+{
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+ assert( obj->ops == &ifchange_ops );
|
||||
+
|
||||
+ /* reset the global ifchange object so that it will be recreated if it is needed again */
|
||||
+ ifchange_object = NULL;
|
||||
+ /* shut the socket down to force pending poll() calls in the client to return */
|
||||
+ shutdown( get_unix_fd(ifchange->fd), SHUT_RDWR );
|
||||
+ release_object( ifchange->fd );
|
||||
+}
|
||||
+
|
||||
+static int ifchange_get_poll_events( struct fd *fd )
|
||||
+{
|
||||
+ return POLLIN;
|
||||
+}
|
||||
+
|
||||
+/* add a socket to the interface change notification's list of sockets */
|
||||
+void ifchange_add_sock( struct object *obj, struct sock *sock )
|
||||
+{
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+
|
||||
+ list_add_tail( &ifchange->sockets, &sock->ifchange_entry );
|
||||
+}
|
||||
+
|
||||
+static int init_ifchange( struct ifchange *ifchange )
|
||||
+{
|
||||
+ struct sockaddr_nl addr;
|
||||
+ int unix_fd;
|
||||
+
|
||||
+ list_init( &ifchange->sockets );
|
||||
+ unix_fd = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE );
|
||||
+ if (unix_fd == -1)
|
||||
+ {
|
||||
+ sock_set_error();
|
||||
+ return 0;
|
||||
+ }
|
||||
+ fcntl( unix_fd, F_SETFL, O_NONBLOCK ); /* make socket nonblocking */
|
||||
+ memset( &addr, 0, sizeof(addr) );
|
||||
+ addr.nl_family = AF_NETLINK;
|
||||
+ addr.nl_groups = RTMGRP_IPV4_IFADDR;
|
||||
+ /* bind the socket to the special netlink kernel interface */
|
||||
+ if (bind( unix_fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1)
|
||||
+ {
|
||||
+ sock_set_error();
|
||||
+ close( unix_fd );
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!(ifchange->fd = create_anonymous_fd( &ifchange_fd_ops, unix_fd, &ifchange->obj, 0 )))
|
||||
+ {
|
||||
+ close( unix_fd );
|
||||
+ return 0;
|
||||
+ }
|
||||
+ /* enable read wakeup on the file descriptor */
|
||||
+ set_fd_events( ifchange->fd, POLLIN );
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/* create a new ifchange notifier or, if one already exists, reuse the existing one */
|
||||
+static struct object *create_ifchange( void )
|
||||
+{
|
||||
+ struct ifchange *ifchange;
|
||||
+
|
||||
+ /* we only need one of these interface notification objects, all of the sockets dependent upon
|
||||
+ * it will wake up when a notification event occurs */
|
||||
+ if (ifchange_object)
|
||||
+ return grab_object( ifchange_object );
|
||||
+ if (!(ifchange = alloc_object( &ifchange_ops )))
|
||||
+ return NULL;
|
||||
+ if (!init_ifchange( ifchange ))
|
||||
+ {
|
||||
+ release_object( ifchange );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ ifchange_object = &ifchange->obj;
|
||||
+ return ifchange_object;
|
||||
+}
|
||||
+
|
||||
+/* wake up an ifchange notification queue for a socket and decrement the ifchange object refcount */
|
||||
+void sock_ifchange_wake_up( struct sock *sock, unsigned int status )
|
||||
+{
|
||||
+ assert( sock->ifchange_q );
|
||||
+ async_wake_up( sock->ifchange_q, status );
|
||||
+ free_async_queue( sock->ifchange_q );
|
||||
+ sock->ifchange_q = NULL;
|
||||
+ list_remove( &sock->ifchange_entry );
|
||||
+ release_object( ifchange_object );
|
||||
+}
|
||||
+
|
||||
+/* wake up all the sockets waiting for a change notification event */
|
||||
+static void ifchange_wake_up( struct object *obj, unsigned int status )
|
||||
+{
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+ struct list *ptr, *next;
|
||||
+
|
||||
+ assert( obj->ops == &ifchange_ops );
|
||||
+ LIST_FOR_EACH_SAFE( ptr, next, &ifchange->sockets )
|
||||
+ {
|
||||
+ struct sock *sock = LIST_ENTRY( ptr, struct sock, ifchange_entry );
|
||||
+
|
||||
+ sock_ifchange_wake_up( sock, status );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void ifchange_poll_event( struct fd *fd, int event )
|
||||
+{
|
||||
+ struct object *ifchange = get_fd_user( fd );
|
||||
+ unsigned int status = STATUS_PENDING;
|
||||
+ char buffer[0x1000];
|
||||
+ int r;
|
||||
+
|
||||
+ r = recv( get_unix_fd(fd), buffer, sizeof(buffer), MSG_DONTWAIT );
|
||||
+ if (r < 0)
|
||||
+ {
|
||||
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
|
||||
+ return; /* retry when poll() says the socket is ready */
|
||||
+ status = sock_get_ntstatus( errno );
|
||||
+ }
|
||||
+ else if (r != 0)
|
||||
+ {
|
||||
+ struct nlmsghdr *nlh;
|
||||
+
|
||||
+ for (nlh = (struct nlmsghdr*)buffer; NLMSG_OK(nlh, r); nlh = NLMSG_NEXT(nlh, r))
|
||||
+ {
|
||||
+ if (nlh->nlmsg_type == NLMSG_DONE)
|
||||
+ break;
|
||||
+ if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR)
|
||||
+ status = STATUS_SUCCESS;
|
||||
+ }
|
||||
+ }
|
||||
+ if (status != STATUS_PENDING)
|
||||
+ ifchange_wake_up( ifchange, status );
|
||||
+}
|
||||
+
|
||||
+static void ifchange_reselect_async( struct fd *fd, struct async_queue *queue )
|
||||
+{
|
||||
+ /* do nothing, this object is about to disappear */
|
||||
+}
|
||||
+
|
||||
+/* add interface change notification to a socket */
|
||||
+int sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
|
||||
+{
|
||||
+ struct object *ifchange = ifchange_object;
|
||||
+ struct async *async;
|
||||
+ struct fd *fd;
|
||||
+
|
||||
+ if (!sock->ifchange_q)
|
||||
+ {
|
||||
+ /* associate this socket with the interface change object */
|
||||
+ ifchange = create_ifchange();
|
||||
+ if (!ifchange) return FALSE;
|
||||
+ ifchange_add_sock( ifchange, sock ); /* add this socket to the change notification list */
|
||||
+ if (!(fd = ifchange_get_fd( ifchange ))) goto fail;
|
||||
+ sock->ifchange_q = create_async_queue( fd );
|
||||
+ release_object( fd );
|
||||
+ if (!sock->ifchange_q) goto fail;
|
||||
+ }
|
||||
+ if (!(async = create_async( current, sock->ifchange_q, async_data ))) goto fail;
|
||||
+ release_object( async );
|
||||
+ return TRUE;
|
||||
+
|
||||
+fail:
|
||||
+ free_async_queue( sock->ifchange_q );
|
||||
+ sock->ifchange_q = NULL;
|
||||
+ release_object( ifchange );
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/* create a socket */
|
||||
DECL_HANDLER(create_socket)
|
||||
{
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,150 @@
|
||||
From 69e77bd226057f486d1c076ccbebb963d3b750ee Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 3 Apr 2014 09:25:48 -0600
|
||||
Subject: server: Add socket-side support for the interface change
|
||||
notification object.
|
||||
|
||||
---
|
||||
server/sock.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 91 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 05fc38b..20d022f 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -106,12 +106,18 @@ struct sock
|
||||
struct sock *deferred; /* socket that waits for a deferred accept */
|
||||
struct async_queue *read_q; /* queue for asynchronous reads */
|
||||
struct async_queue *write_q; /* queue for asynchronous writes */
|
||||
+ struct async_queue *ifchange_q; /* queue for interface change notifications */
|
||||
+ struct object *ifchange_obj; /* the interface change notification object */
|
||||
+ struct list ifchange_entry; /* entry in ifchange notification list */
|
||||
};
|
||||
|
||||
static void sock_dump( struct object *obj, int verbose );
|
||||
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
|
||||
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static struct fd *sock_get_fd( struct object *obj );
|
||||
static void sock_destroy( struct object *obj );
|
||||
+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue );
|
||||
+static void sock_destroy_ifchange_q( struct sock *sock );
|
||||
|
||||
static int sock_get_poll_events( struct fd *fd );
|
||||
static void sock_poll_event( struct fd *fd, int event );
|
||||
@@ -539,7 +545,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
|
||||
switch(code)
|
||||
{
|
||||
case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||
- /* intentional fallthrough, not yet supported */
|
||||
+ error = sock_add_ifchange( sock, async_data );
|
||||
+ break;
|
||||
default:
|
||||
error = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
@@ -625,6 +632,7 @@ static void sock_destroy( struct object *obj )
|
||||
|
||||
free_async_queue( sock->read_q );
|
||||
free_async_queue( sock->write_q );
|
||||
+ sock_destroy_ifchange_q( sock );
|
||||
if (sock->event) release_object( sock->event );
|
||||
if (sock->fd)
|
||||
{
|
||||
@@ -651,6 +659,8 @@ static void init_sock(struct sock *sock)
|
||||
sock->deferred = NULL;
|
||||
sock->read_q = NULL;
|
||||
sock->write_q = NULL;
|
||||
+ sock->ifchange_q = NULL;
|
||||
+ sock->ifchange_obj = NULL;
|
||||
memset( sock->errors, 0, sizeof(sock->errors) );
|
||||
}
|
||||
|
||||
@@ -939,6 +949,86 @@ static void sock_set_error(void)
|
||||
set_error( sock_get_ntstatus( errno ) );
|
||||
}
|
||||
|
||||
+/* add interface change notification to a socket */
|
||||
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
|
||||
+{
|
||||
+ struct async_queue *ifchange_q = NULL;
|
||||
+ struct async *async;
|
||||
+ int error;
|
||||
+
|
||||
+ error = sock_get_ifchange_q( sock, &ifchange_q );
|
||||
+ if (error != STATUS_PENDING)
|
||||
+ return error;
|
||||
+
|
||||
+ if (!(async = create_async( current, ifchange_q, async_data )))
|
||||
+ {
|
||||
+ if (!async_queued( ifchange_q ))
|
||||
+ sock_destroy_ifchange_q( sock );
|
||||
+
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ release_object( async );
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+/* stub ifchange object */
|
||||
+static int get_ifchange( struct object **obj )
|
||||
+{
|
||||
+ return STATUS_NOT_SUPPORTED;
|
||||
+}
|
||||
+
|
||||
+/* stub ifchange add socket to list */
|
||||
+static void ifchange_add_sock( struct object *obj, struct sock *sock )
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+/* create a new ifchange queue for a specific socket or, if one already exists, reuse the existing one */
|
||||
+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue )
|
||||
+{
|
||||
+ struct object *ifchange = NULL;
|
||||
+ struct fd *fd;
|
||||
+ int error;
|
||||
+
|
||||
+ if (sock->ifchange_q) /* reuse existing ifchange_q for this socket */
|
||||
+ {
|
||||
+ *async_queue = sock->ifchange_q;
|
||||
+ return STATUS_PENDING;
|
||||
+ }
|
||||
+
|
||||
+ error = get_ifchange( &ifchange );
|
||||
+ if (error != STATUS_PENDING)
|
||||
+ return error;
|
||||
+
|
||||
+ /* create the ifchange notification queue */
|
||||
+ fd = ifchange->ops->get_fd( ifchange );
|
||||
+ sock->ifchange_q = create_async_queue( fd );
|
||||
+ release_object( fd );
|
||||
+ if (!sock->ifchange_q)
|
||||
+ {
|
||||
+ release_object( ifchange );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ /* add the socket to the ifchange notification list */
|
||||
+ ifchange_add_sock( ifchange, sock );
|
||||
+ sock->ifchange_obj = ifchange;
|
||||
+ *async_queue = sock->ifchange_q;
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+/* destroy an existing ifchange queue for a specific socket */
|
||||
+static void sock_destroy_ifchange_q( struct sock *sock )
|
||||
+{
|
||||
+ if (sock->ifchange_q)
|
||||
+ {
|
||||
+ list_remove( &sock->ifchange_entry );
|
||||
+ free_async_queue( sock->ifchange_q );
|
||||
+ sock->ifchange_q = NULL;
|
||||
+ release_object( sock->ifchange_obj );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* create a socket */
|
||||
DECL_HANDLER(create_socket)
|
||||
{
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,237 @@
|
||||
From 85d0475a493be336c340f25cab9895846e202f26 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 3 Apr 2014 09:26:34 -0600
|
||||
Subject: server: Implement the interface change notification object.
|
||||
|
||||
---
|
||||
server/sock.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 198 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 20d022f..82464f2 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -43,6 +43,10 @@
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
+#include <limits.h>
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+# include <linux/rtnetlink.h>
|
||||
+#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
@@ -972,15 +976,207 @@ static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data
|
||||
return error;
|
||||
}
|
||||
|
||||
-/* stub ifchange object */
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+
|
||||
+/* only keep one ifchange object around, all sockets waiting for wakeups will look to it */
|
||||
+static struct object *ifchange_object = NULL;
|
||||
+
|
||||
+static void ifchange_dump( struct object *obj, int verbose );
|
||||
+static struct fd *ifchange_get_fd( struct object *obj );
|
||||
+static void ifchange_destroy( struct object *obj );
|
||||
+
|
||||
+static int ifchange_get_poll_events( struct fd *fd );
|
||||
+static void ifchange_poll_event( struct fd *fd, int event );
|
||||
+static void ifchange_reselect_async( struct fd *fd, struct async_queue *queue );
|
||||
+
|
||||
+struct ifchange
|
||||
+{
|
||||
+ struct object obj; /* object header */
|
||||
+ struct fd *fd; /* interface change file descriptor */
|
||||
+ struct list sockets; /* list of sockets to send interface change notifications */
|
||||
+};
|
||||
+
|
||||
+static const struct object_ops ifchange_ops =
|
||||
+{
|
||||
+ sizeof(struct ifchange), /* size */
|
||||
+ ifchange_dump, /* dump */
|
||||
+ no_get_type, /* get_type */
|
||||
+ add_queue, /* add_queue */
|
||||
+ NULL, /* remove_queue */
|
||||
+ NULL, /* signaled */
|
||||
+ no_satisfied, /* satisfied */
|
||||
+ no_signal, /* signal */
|
||||
+ ifchange_get_fd, /* get_fd */
|
||||
+ default_fd_map_access, /* map_access */
|
||||
+ default_get_sd, /* get_sd */
|
||||
+ default_set_sd, /* set_sd */
|
||||
+ no_lookup_name, /* lookup_name */
|
||||
+ no_open_file, /* open_file */
|
||||
+ no_close_handle, /* close_handle */
|
||||
+ ifchange_destroy /* destroy */
|
||||
+};
|
||||
+
|
||||
+static const struct fd_ops ifchange_fd_ops =
|
||||
+{
|
||||
+ ifchange_get_poll_events, /* get_poll_events */
|
||||
+ ifchange_poll_event, /* poll_event */
|
||||
+ NULL, /* flush */
|
||||
+ NULL, /* get_fd_type */
|
||||
+ NULL, /* ioctl */
|
||||
+ NULL, /* queue_async */
|
||||
+ ifchange_reselect_async, /* reselect_async */
|
||||
+ NULL /* cancel_async */
|
||||
+};
|
||||
+
|
||||
+static void ifchange_dump( struct object *obj, int verbose )
|
||||
+{
|
||||
+ assert( obj->ops == &ifchange_ops );
|
||||
+ printf( "ifchange\n" );
|
||||
+}
|
||||
+
|
||||
+static struct fd *ifchange_get_fd( struct object *obj )
|
||||
+{
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+ return (struct fd *)grab_object( ifchange->fd );
|
||||
+}
|
||||
+
|
||||
+static void ifchange_destroy( struct object *obj )
|
||||
+{
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+ assert( obj->ops == &ifchange_ops );
|
||||
+
|
||||
+ if (ifchange->fd)
|
||||
+ {
|
||||
+ /* reset the global ifchange object so that it will be recreated if it is needed again */
|
||||
+ assert( obj == ifchange_object );
|
||||
+ ifchange_object = NULL;
|
||||
+
|
||||
+ /* shut the socket down to force pending poll() calls in the client to return */
|
||||
+ shutdown( get_unix_fd(ifchange->fd), SHUT_RDWR );
|
||||
+ release_object( ifchange->fd );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int ifchange_get_poll_events( struct fd *fd )
|
||||
+{
|
||||
+ return POLLIN;
|
||||
+}
|
||||
+
|
||||
+/* wake up all the sockets waiting for a change notification event */
|
||||
+static void ifchange_wake_up( struct object *obj, unsigned int status )
|
||||
+{
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+ struct list *ptr, *next;
|
||||
+ assert( obj->ops == &ifchange_ops );
|
||||
+ assert( obj == ifchange_object );
|
||||
+
|
||||
+ LIST_FOR_EACH_SAFE( ptr, next, &ifchange->sockets )
|
||||
+ {
|
||||
+ struct sock *sock = LIST_ENTRY( ptr, struct sock, ifchange_entry );
|
||||
+
|
||||
+ assert( sock->ifchange_q );
|
||||
+ async_wake_up( sock->ifchange_q, status ); /* issue ifchange notification for the socket */
|
||||
+ sock_destroy_ifchange_q( sock ); /* remove socket from list and decrement ifchange refcount */
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void ifchange_poll_event( struct fd *fd, int event )
|
||||
+{
|
||||
+ struct object *ifchange = get_fd_user( fd );
|
||||
+ unsigned int status = STATUS_PENDING;
|
||||
+ char buffer[PIPE_BUF];
|
||||
+ int r;
|
||||
+
|
||||
+ r = recv( get_unix_fd(fd), buffer, sizeof(buffer), MSG_DONTWAIT );
|
||||
+ if (r < 0)
|
||||
+ {
|
||||
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
|
||||
+ return; /* retry when poll() says the socket is ready */
|
||||
+ status = sock_get_ntstatus( errno );
|
||||
+ }
|
||||
+ else if (r > 0)
|
||||
+ {
|
||||
+ struct nlmsghdr *nlh;
|
||||
+
|
||||
+ for (nlh = (struct nlmsghdr *)buffer; NLMSG_OK(nlh, r); nlh = NLMSG_NEXT(nlh, r))
|
||||
+ {
|
||||
+ if (nlh->nlmsg_type == NLMSG_DONE)
|
||||
+ break;
|
||||
+ if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR)
|
||||
+ status = STATUS_SUCCESS;
|
||||
+ }
|
||||
+ }
|
||||
+ if (status != STATUS_PENDING)
|
||||
+ ifchange_wake_up( ifchange, status );
|
||||
+}
|
||||
+
|
||||
+static void ifchange_reselect_async( struct fd *fd, struct async_queue *queue )
|
||||
+{
|
||||
+ /* do nothing, this object is about to disappear */
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+/* we only need one of these interface notification objects, all of the sockets dependent upon
|
||||
+ * it will wake up when a notification event occurs */
|
||||
static int get_ifchange( struct object **obj )
|
||||
{
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+ struct ifchange *ifchange;
|
||||
+ struct sockaddr_nl addr;
|
||||
+ int unix_fd;
|
||||
+
|
||||
+ if (ifchange_object)
|
||||
+ {
|
||||
+ /* increment the refcount for each socket that uses the ifchange object */
|
||||
+ *obj = grab_object( ifchange_object );
|
||||
+ return STATUS_PENDING;
|
||||
+ }
|
||||
+
|
||||
+ /* create the socket we need for processing interface change notifications */
|
||||
+ unix_fd = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE );
|
||||
+ if (unix_fd == -1)
|
||||
+ return sock_get_ntstatus( errno );
|
||||
+ fcntl( unix_fd, F_SETFL, O_NONBLOCK ); /* make socket nonblocking */
|
||||
+ memset( &addr, 0, sizeof(addr) );
|
||||
+ addr.nl_family = AF_NETLINK;
|
||||
+ addr.nl_groups = RTMGRP_IPV4_IFADDR;
|
||||
+ /* bind the socket to the special netlink kernel interface */
|
||||
+ if (bind( unix_fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1)
|
||||
+ {
|
||||
+ close( unix_fd );
|
||||
+ return sock_get_ntstatus( errno );
|
||||
+ }
|
||||
+ if (!(ifchange = alloc_object( &ifchange_ops )))
|
||||
+ {
|
||||
+ close( unix_fd );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ }
|
||||
+ list_init( &ifchange->sockets );
|
||||
+ if (!(ifchange->fd = create_anonymous_fd( &ifchange_fd_ops, unix_fd, &ifchange->obj, 0 )))
|
||||
+ {
|
||||
+ release_object( ifchange );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ }
|
||||
+ set_fd_events( ifchange->fd, POLLIN ); /* enable read wakeup on the file descriptor */
|
||||
+
|
||||
+ /* the ifchange object is now successfully configured */
|
||||
+ ifchange_object = &ifchange->obj;
|
||||
+ *obj = &ifchange->obj;
|
||||
+ return STATUS_PENDING;
|
||||
+#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
+#endif
|
||||
}
|
||||
|
||||
-/* stub ifchange add socket to list */
|
||||
+/* add the socket to the interface change notification list */
|
||||
static void ifchange_add_sock( struct object *obj, struct sock *sock )
|
||||
{
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+ struct ifchange *ifchange = (struct ifchange *)obj;
|
||||
+
|
||||
+ list_add_tail( &ifchange->sockets, &sock->ifchange_entry );
|
||||
+#endif
|
||||
}
|
||||
|
||||
/* create a new ifchange queue for a specific socket or, if one already exists, reuse the existing one */
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -1,6 +1,6 @@
|
||||
From b3156dc253a94f9414a04569181728ec43608f2a Mon Sep 17 00:00:00 2001
|
||||
From 621fe55cd32221c542df779540d3bc8ea701821d Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Mon, 18 Nov 2013 17:22:14 -0700
|
||||
Date: Thu, 3 Apr 2014 09:26:45 -0600
|
||||
Subject: ws2_32: Add an interactive test for interface change notifications.
|
||||
|
||||
---
|
||||
@@ -8,10 +8,10 @@ Subject: ws2_32: Add an interactive test for interface change notifications.
|
||||
1 file changed, 68 insertions(+)
|
||||
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index ac6ee10..b6da0e7 100644
|
||||
index dcedd99..e55273a 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -6225,6 +6225,73 @@ static void test_sioRoutingInterfaceQuery(void)
|
||||
@@ -6607,6 +6607,73 @@ static void test_sioRoutingInterfaceQuery(void)
|
||||
closesocket(sock);
|
||||
}
|
||||
|
||||
@@ -85,14 +85,14 @@ index ac6ee10..b6da0e7 100644
|
||||
static void test_synchronous_WSAIoctl(void)
|
||||
{
|
||||
HANDLE previous_port, io_port;
|
||||
@@ -7101,6 +7168,7 @@ START_TEST( sock )
|
||||
@@ -7694,6 +7761,7 @@ START_TEST( sock )
|
||||
test_ConnectEx();
|
||||
|
||||
test_sioRoutingInterfaceQuery();
|
||||
+ test_sioAddressListChange();
|
||||
|
||||
test_WSAAsyncGetServByPort();
|
||||
test_WSAAsyncGetServByName();
|
||||
test_WSALookupService();
|
||||
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -1,3 +1,3 @@
|
||||
Revision: 1
|
||||
Revision: 2
|
||||
Author: Erich E. Hoover
|
||||
Title: Implement SIO_ADDRESS_LIST_CHANGE.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user