diff --git a/DEVELOPER.md b/DEVELOPER.md index 0a3dbba6..0a63e7c4 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -32,15 +32,15 @@ before proceeding. As the first step please grab the latest Wine source: ```bash -wget http://prdownloads.sourceforge.net/wine/wine-1.7.24.tar.bz2 -wget https://github.com/compholio/wine-compholio-daily/archive/v1.7.24.tar.gz +wget http://prdownloads.sourceforge.net/wine/wine-1.7.25.tar.bz2 +wget https://github.com/compholio/wine-compholio-daily/archive/v1.7.25.tar.gz ``` Extract the archives: ```bash tar xvjf wine-1*.tar.bz2 cd wine-1* -tar xvzf ../v1.7.24.tar.gz --strip-components 1 +tar xvzf ../v1.7.25.tar.gz --strip-components 1 ``` And apply the patches: diff --git a/README.md b/README.md index 8066b579..04d2dc0b 100644 --- a/README.md +++ b/README.md @@ -13,57 +13,52 @@ which are not present in regular wine, and always report such issues to us Included bugfixes and improvements ---------------------------------- -**Bugfixes and features included in the next upcoming release [12]:** +**Bugfixes and features included in the next upcoming release [1]:** -* Adobe Reader requires NtProtectVirtualMemory and NtCreateSection to be on separate pages ([Wine Bug #33162](http://bugs.winehq.org/show_bug.cgi?id=33162 "Acrobat Reader 11 crashes on start (native API application virtualization, NtProtectVirtualMemory removes execute page protection on its own code)")) -* Fix ITERATE_MoveFiles when no source- and destname is specified ([Wine Bug #10085](http://bugs.winehq.org/show_bug.cgi?id=10085 "Adobe Bridge CS2 complains that it can't start due to licensing restrictions (affects photoshop)")) -* Fix issue with invisible dragimages in ImageList ([Wine Bug #36761](http://bugs.winehq.org/show_bug.cgi?id=36761 "Imagelist invisible dragimage")) -* Games For Windows Live 1.x expects a valid linker version in the PE header ([Wine Bug #28768](http://bugs.winehq.org/show_bug.cgi?id=28768 "Multiple GFWL (Games For Windows Live) 1.x games crash on startup (Kane & Lynch: Dead Men)")) -* Gothic 2 demo expects an error when opening a terminating process ([Wine Bug #37087](http://bugs.winehq.org/show_bug.cgi?id=37087 "Gothic 2 english demo fails with 'Conflict: a hook process was found. Please deactivate all Antivirus and Anti-Trojan programs and debuggers.'")) -* Multiple applications need BCryptGetFipsAlgorithmMode ([Wine Bug #32194](http://bugs.winehq.org/show_bug.cgi?id=32194 "Multiple games and applications need bcrypt.dll.BCryptGetFipsAlgorithmMode (Chess Position Trainer, Terraria, .NET System.Security.Cryptography)")) -* Other Pipelight-specific enhancements -* Prevent window managers from grouping all wine programs together ([Wine Bug #32699](http://bugs.winehq.org/show_bug.cgi?id=32699 "Add StartupWMClass to .desktop files.")) * Support for DOS hidden/system file attributes ([Wine Bug #9158](http://bugs.winehq.org/show_bug.cgi?id=9158 "Multiple Microsoft development tools online/web installers fail to skip \"$shtdwn$.req\" with FILE_ATTRIBUTE_HIDDEN (Visual Studio Express Editions, .NET Framework 3.0)")) -* Support for DwmInvalidateIconicBitmaps ([Wine Bug #32977](http://bugs.winehq.org/show_bug.cgi?id=32977 "Solidworks 2012 needs unimplemented function dwmapi.dll.DwmInvalidateIconicBitmaps (Win7 mode)")) -* Support for Dynamic DST (daylight saving time) information in registry -* Support for GetFinalPathNameByHandle ([Wine Bug #36073](http://bugs.winehq.org/show_bug.cgi?id=36073 "OneDrive crashes on unimplemented function KERNEL32.dll.GetFinalPathNameByHandleW")) -* nVidia driver for high-end laptop cards does not list all supported resolutions -**Bugs fixed in Wine-Compholio 1.7.24 [45]:** +**Bugs fixed in Wine-Compholio 1.7.25 [53]:** * ATL IOCS data should not be stored in GWLP_USERDATA ([Wine Bug #21767](http://bugs.winehq.org/show_bug.cgi?id=21767 "JLC's Internet TV crashes on startup")) * Add Dynamic DST exceptions for Israel Standard Time ([Wine Bug #36374](http://bugs.winehq.org/show_bug.cgi?id=36374 "Israel timezone handled incorrectly")) * Add default ACLs for user shell folders -* ~~Add support for Dynamic DST (daylight saving time) information in registry~~ * Allow special characters in pipe names ([Wine Bug #28995](http://bugs.winehq.org/show_bug.cgi?id=28995 "Unable to use named pipes with \">\" character in the name")) * Audio stuttering and performance drops in multiple applications ([Wine Bug #30639](http://bugs.winehq.org/show_bug.cgi?id=30639 "Audio stuttering and performance drops in Star Wolves 3")) +* Ensure NtProtectVirtualMemory and NtCreateSection are on separate pages ([Wine Bug #33162](http://bugs.winehq.org/show_bug.cgi?id=33162 "Acrobat Reader 11 crashes on start (native API application virtualization, NtProtectVirtualMemory removes execute page protection on its own code)")) +* Fix ITERATE_MoveFiles when no source- and destname is specified ([Wine Bug #10085](http://bugs.winehq.org/show_bug.cgi?id=10085 "Adobe Bridge CS2 complains that it can't start due to licensing restrictions (affects photoshop)")) * Fix comparison of punctuation characters in lstrcmp ([Wine Bug #10767](http://bugs.winehq.org/show_bug.cgi?id=10767 "lstrcmp and others do not compare punctuation characters correctly")) * Fix for ConnectNamedPort return value in overlapped mode ([Wine Bug #16550](http://bugs.winehq.org/show_bug.cgi?id=16550 "ConnectNamedPort should never return OK in overlapped mode (affects chromium ui_tests.exe)")) * Fix for programs leaking wndproc slots ([Wine Bug #32451](http://bugs.winehq.org/show_bug.cgi?id=32451 "Multiple GOG.com installer bundles show a broken/unresponsive dialog window during installation (installer process running out of wndproc slots)")) +* Fix issue with invisible dragimages in ImageList ([Wine Bug #36761](http://bugs.winehq.org/show_bug.cgi?id=36761 "Imagelist invisible dragimage")) +* Games For Windows Live 1.x expects a valid linker version in the PE header ([Wine Bug #28768](http://bugs.winehq.org/show_bug.cgi?id=28768 "Multiple GFWL (Games For Windows Live) 1.x games crash on startup (Kane & Lynch: Dead Men)")) * GetSecurityInfo returns NULL DACL for process object ([Wine Bug #15980](http://bugs.winehq.org/show_bug.cgi?id=15980 "Rhapsody 2 crashes on startup (GetSecurityInfo returns NULL DACL for process object)")) * Implement a Microsoft Yahei replacement font ([Wine Bug #13829](http://bugs.winehq.org/show_bug.cgi?id=13829 "Wine does not have CJK fonts")) * Implement an Arial replacement font ([Wine Bug #32323](http://bugs.winehq.org/show_bug.cgi?id=32323 "Netflix (Silverlight 4.x) and several .NET Framework 3.x/4.0 WPF apps require either Arial or Verdana to be installed")) * Lockfree algorithm for filedescriptor cache (improves file access speed) * Make it possible to change media center / tablet pc status ([Wine Bug #18732](http://bugs.winehq.org/show_bug.cgi?id=18732 "Microsoft Experience Pack for Tablet PC 1 refuses to install")) * Need for Speed 3 installer requires devices in HKEY_DYN_DATA ([Wine Bug #7115](http://bugs.winehq.org/show_bug.cgi?id=7115 "Need for Speed III installer fails in Win9X mode, reporting \"Could not get 'HardWareKey' value\" (active PnP device keys in 'HKEY_DYN_DATA\\\\Config Manager\\\\Enum' missing)")) -* ~~Old games cannot locate software-only renderer~~ ([Wine Bug #32581](http://bugs.winehq.org/show_bug.cgi?id=32581 "Invalid dwFlags of reference rasterizer's HAL D3DDEVICEDESC")) -* ~~Other Pipelight specific enhancements~~ +* Other Pipelight-specific enhancements +* Prevent window managers from grouping all wine programs together ([Wine Bug #32699](http://bugs.winehq.org/show_bug.cgi?id=32699 "Add StartupWMClass to .desktop files.")) * Reduced SetTimer minimum value from 10 ms to 5 ms (improves Silverlight framerates) +* Return an error when trying to open a terminated process ([Wine Bug #37087](http://bugs.winehq.org/show_bug.cgi?id=37087 "Gothic 2 english demo fails with 'Conflict: a hook process was found. Please deactivate all Antivirus and Anti-Trojan programs and debuggers.'")) * Return correct IMediaSeeking stream positions in quartz ([Wine Bug #23174](http://bugs.winehq.org/show_bug.cgi?id=23174 "Fallout 3: Diologue and Video/sound issues")) * SO_CONNECT_TIME returns the appropriate time * Set ldr.EntryPoint for main executable ([Wine Bug #33034](http://bugs.winehq.org/show_bug.cgi?id=33034 "Many GFWL (Games For Windows Live) 1.x/2.x/3.x games crash or exit silently on startup (DiRT 2/3, GTA IV Steam)")) * Support for AllocateAndGetTcpExTableFromStack ([Wine Bug #34372](http://bugs.winehq.org/show_bug.cgi?id=34372 "Add missing function AllocateAndGetTcpExTableFromStack() to iphlpapi.dll")) +* Support for BCryptGetFipsAlgorithmMode ([Wine Bug #32194](http://bugs.winehq.org/show_bug.cgi?id=32194 "Multiple games and applications need bcrypt.dll.BCryptGetFipsAlgorithmMode (Chess Position Trainer, Terraria, .NET System.Security.Cryptography)")) +* Support for Dynamic DST (daylight saving time) information in registry +* Support for GetFinalPathNameByHandle ([Wine Bug #36073](http://bugs.winehq.org/show_bug.cgi?id=36073 "OneDrive crashes on unimplemented function KERNEL32.dll.GetFinalPathNameByHandleW")) * Support for GetSystemTimes ([Wine Bug #19813](http://bugs.winehq.org/show_bug.cgi?id=19813 "Voddler needs GetSystemTimes to run")) * Support for GetVolumePathName * Support for ITextDocument_fnRange function ([Wine Bug #12458](http://bugs.winehq.org/show_bug.cgi?id=12458 "Multiple apps fail due to RichEdit ITextDocument_fnRange stub (MySQL Workbench, BlitzMaxDemo137)")) * Support for ITextRange, ITextFont and ITextPara ([Wine Bug #18303](http://bugs.winehq.org/show_bug.cgi?id=18303 "Adobe Acrobat Pro 7: Crashes when selecting the \"edit\" menu while having a file open.")) * Support for Junction Points ([Wine Bug #12401](http://bugs.winehq.org/show_bug.cgi?id=12401 "Support junction points, i.e. DeviceIoCtl(FSCTL_SET_REPARSE_POINT/FSCTL_GET_REPARSE_POINT)")) +* Support for KF_FLAG_DEFAULT_PATH in SHGetKnownFolderPath ([Wine Bug #30385](http://bugs.winehq.org/show_bug.cgi?id=30385 "Windows Live Essentials 2011 web installer fails to download packages in background (shell32.SHGetKnownFolderPath missing support for KF_FLAG_DEFAULT_PATH)")) * Support for LoadIconMetric ([Wine Bug #35375](http://bugs.winehq.org/show_bug.cgi?id=35375 "Multiple applications need Vista+ API COMCTL32.dll.380 a.k.a. 'LoadIconMetric' (Solidworks 2013 systray monitor, Microsoft One/SkyDrive)")) * Support for NtSetInformationFile class FileDispositionInformation ([Wine Bug #30397](http://bugs.winehq.org/show_bug.cgi?id=30397 "Multiple applications need support for NtSetInformationFile class FileDispositionInformation (Cygwin installer, Stylizer 5.x Visual CSS editor, Spoon Studio 2011 (ex Xenocode) application sandboxing scheme)")) * Support for PulseAudio backend for audio ([Wine Bug #10495](http://bugs.winehq.org/show_bug.cgi?id=10495 "Wine should support PulseAudio")) * Support for SHCreateSessionKey ([Wine Bug #35630](http://bugs.winehq.org/show_bug.cgi?id=35630 "SHCreateSessionKey is unimplemented")) -* Support for SetNamedPipeHandleState ([Wine Bug #17273](http://bugs.winehq.org/show_bug.cgi?id=17273 "Many apps and games need SetNamedPipeHandleState implementation (support for named pipe message mode)(FireFox+Flash, Win8/NET 4.x SDK/vcrun2012, WiX installers)")) * Support for TOOLTIPS_GetTipText edge cases ([Wine Bug #30648](http://bugs.winehq.org/show_bug.cgi?id=30648 "SEGA Genesis / Mega Drive Classic Collection (Steam) crashes on startup")) * Support for TransmitFile ([Wine Bug #5048](http://bugs.winehq.org/show_bug.cgi?id=5048 "Multiple applications and games need support for ws2_32 SIO_GET_EXTENSION_FUNCTION_POINTER TransmitFile (WSAID_TRANSMITFILE)")) * Support for WTSEnumerateProcessesW ([Wine Bug #29903](http://bugs.winehq.org/show_bug.cgi?id=29903 "Some Microsoft debuggers fail to enumerate processes due to wtsapi32.WTSEnumerateProcessesW() being a stub (Microsoft Visual Studio 2005, DbgCLR from .NET 2.0 SDK)")) @@ -77,6 +72,7 @@ Included bugfixes and improvements * Use manual relay for RunDLL_CallEntry16 in shell32 ([Wine Bug #23033](http://bugs.winehq.org/show_bug.cgi?id=23033 "Tages Protection v5.x: games report \"DLL not found shell.dll16.dll\" (Runaway 2: The Dream Of The Turtle, ...)")) * Workaround for shlwapi URLs with relative paths * XEMBED support for embedding Wine windows inside Linux applications +* nVidia driver for high-end laptop cards does not list all supported resolutions How to install Wine-Compholio diff --git a/debian/changelog b/debian/changelog index 7ab07bdd..7d228f53 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,27 @@ -wine-compholio (1.7.25) UNRELEASED; urgency=low +wine-compholio (1.7.25) unstable; urgency=low * Improve generation of README.md on patch update. + * Updated patches for riched20 IText* Interface. + * Fixed some issues in the patches for TransmitFile. + * Fixed some issues in the patches for CreateProcess ACLs. + * Fixed issue with gitapply.sh script on Gentoo systems. * Added patch with stub for DwmInvalidateIconicBitmaps. * Added Courier Prime (OFLv1.1) as a Courier New replacement. * Added patch to implement DOS hidden/system file attributes. * Added patch to better detect broken nVidia RandR 1.2 support. + * Added patch to set linker version in PE header. + * Added patch to move NtProtectVirtualMemory and NtCreateSection to separate pages. + * Added patch to fix issues with drag image in ImageLists. + * Added patch with stub for BCryptGetFipsAlgorithmMode. + * Added patch to fix issues with OpenProcess on terminated processes. + * Added patch to fix issues with msi/ITERATE_MoveFiles. + * Added patch to avoid grouping all Wine windows together. + * Added patch to implement KF_FLAG_DEFAULT_PATH for SHGetKnownFolderPath. + * Added patch to implement GetFinalPathNameByHandle. + * Removed patch to update gl_drawable for embedded windows (deprecated). * Removed patch to return empty D3D hardware flags for RGB device enumeration (accepted upstream). - -- Erich E. Hoover Mon, 11 Aug 2014 16:21:22 -0600 + * Removed patch with stub for DwmInvalidateIconicBitmaps (accepted upstream). + * Removed patch for SetNamedPipeHandleState implementation (accepted upstream). + -- Erich E. Hoover Sun, 24 Aug 2014 11:09:58 -0600 wine-compholio (1.7.24) unstable; urgency=low * Various further improvements to the patch system. diff --git a/patches/Makefile b/patches/Makefile index dc8317d1..024b6b11 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -15,7 +15,6 @@ PATCHLIST := \ comctl32-ImageList.ok \ comctl32-LoadIconMetric.ok \ dsound-Fast_Mixer.ok \ - dwmapi-Invalidate_Thumbnail.ok \ fonts-Missing_Fonts.ok \ iphlpapi-TCP_Table.ok \ kernel32-GetFinalPathNameByHandle.ok \ @@ -41,9 +40,10 @@ PATCHLIST := \ server-CreateProcess_ACLs.ok \ server-Inherited_ACLs.ok \ server-Misc_ACL.ok \ - server-Process.ok \ + server-OpenProcess.ok \ server-Stored_ACLs.ok \ shell32-Default_Folder_ACLs.ok \ + shell32-Default_Path.ok \ shell32-Icons.ok \ shell32-RunDLL_CallEntry16.ok \ shell32-SHCreateSessionKey.ok \ @@ -148,7 +148,7 @@ atl-IOCS_Property.ok: # | * Add semi-stub for BCryptGetFipsAlgorithmMode. [by Michael Müller] # | # | This patchset fixes the following Wine bugs: -# | * [#32194] Multiple applications need BCryptGetFipsAlgorithmMode +# | * [#32194] Support for BCryptGetFipsAlgorithmMode # | # | Modified files: # | * dlls/bcrypt/bcrypt.spec, dlls/bcrypt/bcrypt_main.c, dlls/bcrypt/tests/bcrypt.c @@ -216,24 +216,6 @@ dsound-Fast_Mixer.ok: echo '+ { "dsound-Fast_Mixer", "Alexander E. Patrakov", "Add a linear resampler for use with a large number of dsound mixing buffers." },'; \ ) > dsound-Fast_Mixer.ok -# Patchset dwmapi-Invalidate_Thumbnail -# | -# | Included patches: -# | * Add stub for DwmInvalidateIconicBitmaps. [by Erich E. Hoover] -# | -# | This patchset fixes the following Wine bugs: -# | * [#32977] Support for DwmInvalidateIconicBitmaps -# | -# | Modified files: -# | * dlls/dwmapi/dwmapi.spec, dlls/dwmapi/dwmapi_main.c, include/dwmapi.h -# | -.INTERMEDIATE: dwmapi-Invalidate_Thumbnail.ok -dwmapi-Invalidate_Thumbnail.ok: - $(call APPLY_FILE,dwmapi-Invalidate_Thumbnail/0001-dwmapi-Add-stub-for-DwmInvalidateIconicBitmaps.patch) - @( \ - echo '+ { "dwmapi-Invalidate_Thumbnail", "Erich E. Hoover", "Add stub for DwmInvalidateIconicBitmaps." },'; \ - ) > dwmapi-Invalidate_Thumbnail.ok - # Patchset fonts-Missing_Fonts # | # | Included patches: @@ -332,24 +314,18 @@ kernel32-GetVolumePathName.ok: # | # | Included patches: # | * Fix for ConnectNamedPort return value in overlapped mode. [by Dan Kegel] -# | * Add proper implementation for SetNamedPipeHandleState. [rev 7, by Sebastian Lackner / Adam Martinson] # | # | This patchset fixes the following Wine bugs: # | * [#16550] Fix for ConnectNamedPort return value in overlapped mode -# | * [#17273] Support for SetNamedPipeHandleState # | # | Modified files: -# | * dlls/kernel32/sync.c, dlls/kernel32/tests/pipe.c, dlls/ntdll/tests/pipe.c +# | * dlls/kernel32/sync.c # | .INTERMEDIATE: kernel32-Named_Pipe.ok kernel32-Named_Pipe.ok: $(call APPLY_FILE,kernel32-Named_Pipe/0001-kernel32-ConnectNamedPort-should-return-FALSE-and-se.patch) - $(call APPLY_FILE,kernel32-Named_Pipe/0002-ntdll-tests-Add-tests-for-FILE_PIPE_INFORMATION.patch) - $(call APPLY_FILE,kernel32-Named_Pipe/0003-kernel32-tests-Always-allow-only-one-specific-test-r.patch) - $(call APPLY_FILE,kernel32-Named_Pipe/0004-kernel32-Implement-Get-Set-NamedPipeHandleState.patch) @( \ echo '+ { "kernel32-Named_Pipe", "Dan Kegel", "Fix for ConnectNamedPort return value in overlapped mode." },'; \ - echo '+ { "kernel32-Named_Pipe", "Sebastian Lackner / Adam Martinson", "Add proper implementation for SetNamedPipeHandleState. [rev 7]" },'; \ ) > kernel32-Named_Pipe.ok # Patchset kernel32-SystemFileCacheSize @@ -511,7 +487,7 @@ ntdll-FileDispositionInformation.ok: # | * Move NtProtectVirtualMemory and NtCreateSection to separate pages in ntdll on x86. [by Michael Müller] # | # | This patchset fixes the following Wine bugs: -# | * [#33162] Adobe Reader requires NtProtectVirtualMemory and NtCreateSection to be on separate pages +# | * [#33162] Ensure NtProtectVirtualMemory and NtCreateSection are on separate pages # | # | Modified files: # | * dlls/ntdll/virtual.c @@ -609,16 +585,17 @@ quartz-MediaSeeking_Positions.ok: # | # | Included patches: # | * Implement Stubs for ITextRange interface. [rev 3, by Jactry Zeng] -# | * Implement IText{Range,Selection}::{GetChar,GetStart,GetEnd,GetDuplicate,Collapse,SetStart,SetEnd}. [by Jactry Zeng] # | * Implement Stubs for ITextFont interface. [rev 2, by Jactry Zeng] # | * Implement Stubs for ITextPara interface. [rev 2, by Jactry Zeng] +# | * Implement ITextRange/Selection::{GetChar,GetStart,GetEnd,GetDuplicate,Collapse,SetStart,SetEnd}. [by Jactry Zeng] +# | * Implement ITextRange/Selection::{GetText,SetRange,IsEqual,GetStoryLength}. [by Jactry Zeng] # | # | This patchset fixes the following Wine bugs: # | * [#12458] Support for ITextDocument_fnRange function # | * [#18303] Support for ITextRange, ITextFont and ITextPara # | # | Modified files: -# | * dlls/riched20/richole.c, dlls/riched20/tests/richole.c +# | * dlls/riched20/richole.c, dlls/riched20/run.c, dlls/riched20/tests/richole.c # | .INTERMEDIATE: riched20-IText_Interface.ok riched20-IText_Interface.ok: @@ -630,11 +607,18 @@ riched20-IText_Interface.ok: $(call APPLY_FILE,riched20-IText_Interface/0006-riched20-Implement-IText-Selection-Range-Set-Start-E.patch) $(call APPLY_FILE,riched20-IText_Interface/0007-riched20-Stub-for-ITextFont-interface-and-implement-.patch) $(call APPLY_FILE,riched20-IText_Interface/0008-riched20-Stub-for-ITextPara-interface-and-implement-.patch) + $(call APPLY_FILE,riched20-IText_Interface/0009-riched20-Fix-ME_RunOfsFromCharOfs-when-nCharOfs-strl.patch) + $(call APPLY_FILE,riched20-IText_Interface/0010-riched20-Implement-ITextRange-GetText.patch) + $(call APPLY_FILE,riched20-IText_Interface/0011-riched20-Implement-ITextRange-SetRange.patch) + $(call APPLY_FILE,riched20-IText_Interface/0012-riched20-Implement-ITextRange-IsEqual.patch) + $(call APPLY_FILE,riched20-IText_Interface/0013-riched20-Implement-ITextRange-GetStoryLength.patch) + $(call APPLY_FILE,riched20-IText_Interface/0014-riched20-Implement-ITextSelection-GetStoryLength.patch) @( \ echo '+ { "riched20-IText_Interface", "Jactry Zeng", "Implement Stubs for ITextRange interface. [rev 3]" },'; \ - echo '+ { "riched20-IText_Interface", "Jactry Zeng", "Implement IText{Range,Selection}::{GetChar,GetStart,GetEnd,GetDuplicate,Collapse,SetStart,SetEnd}." },'; \ echo '+ { "riched20-IText_Interface", "Jactry Zeng", "Implement Stubs for ITextFont interface. [rev 2]" },'; \ echo '+ { "riched20-IText_Interface", "Jactry Zeng", "Implement Stubs for ITextPara interface. [rev 2]" },'; \ + echo '+ { "riched20-IText_Interface", "Jactry Zeng", "Implement ITextRange/Selection::{GetChar,GetStart,GetEnd,GetDuplicate,Collapse,SetStart,SetEnd}." },'; \ + echo '+ { "riched20-IText_Interface", "Jactry Zeng", "Implement ITextRange/Selection::{GetText,SetRange,IsEqual,GetStoryLength}." },'; \ ) > riched20-IText_Interface.ok # Patchset server-ACL_Compat @@ -677,7 +661,7 @@ server-Address_Change_Notification.ok: # Patchset server-CreateProcess_ACLs # | # | Included patches: -# | * Implement passing ACLs to CreateProcess. [by Joris van der Wel] +# | * Implement passing ACLs to CreateProcess. [rev 2, by Joris van der Wel / Sebastian Lackner] # | # | This patchset fixes the following Wine bugs: # | * [#22006] Support for process ACLs @@ -689,11 +673,11 @@ server-Address_Change_Notification.ok: .INTERMEDIATE: server-CreateProcess_ACLs.ok server-CreateProcess_ACLs.ok: $(call APPLY_FILE,server-CreateProcess_ACLs/0001-server-A-new-function-set_sd_defaults_from_token-tha.patch) - $(call APPLY_FILE,server-CreateProcess_ACLs/0002-server-Support-sending-process-and-thread-security-d.patch) - $(call APPLY_FILE,server-CreateProcess_ACLs/0003-server-implement-passing-a-process-security-descript.patch) - $(call APPLY_FILE,server-CreateProcess_ACLs/0004-server-implement-passing-a-thread-security-descripto.patch) + $(call APPLY_FILE,server-CreateProcess_ACLs/0002-server-Support-sending-thread-and-process-security-d.patch) + $(call APPLY_FILE,server-CreateProcess_ACLs/0003-kernel32-Implement-passing-a-process-security-descri.patch) + $(call APPLY_FILE,server-CreateProcess_ACLs/0004-advapi32-tests-Add-additional-tests-for-passing-a-th.patch) @( \ - echo '+ { "server-CreateProcess_ACLs", "Joris van der Wel", "Implement passing ACLs to CreateProcess." },'; \ + echo '+ { "server-CreateProcess_ACLs", "Joris van der Wel / Sebastian Lackner", "Implement passing ACLs to CreateProcess. [rev 2]" },'; \ ) > server-CreateProcess_ACLs.ok # Patchset server-Inherited_ACLs @@ -734,23 +718,23 @@ server-Misc_ACL.ok: echo '+ { "server-Misc_ACL", "Erich E. Hoover", "Add default security descriptor ownership and DACLs for processes." },'; \ ) > server-Misc_ACL.ok -# Patchset server-Process +# Patchset server-OpenProcess # | # | Included patches: -# | * Return error when opening a terminating process. [by Michael Müller] +# | * Return error when opening a terminating process. [rev 3, by Michael Müller] # | # | This patchset fixes the following Wine bugs: -# | * [#37087] Gothic 2 demo expects an error when opening a terminating process +# | * [#37087] Return an error when trying to open a terminated process # | # | Modified files: -# | * server/process.c +# | * server/process.c, server/process.h # | -.INTERMEDIATE: server-Process.ok -server-Process.ok: - $(call APPLY_FILE,server-Process/0001-server-Return-error-when-opening-a-terminating-proce.patch) +.INTERMEDIATE: server-OpenProcess.ok +server-OpenProcess.ok: + $(call APPLY_FILE,server-OpenProcess/0001-server-Return-error-when-opening-a-terminating-proce.patch) @( \ - echo '+ { "server-Process", "Michael Müller", "Return error when opening a terminating process." },'; \ - ) > server-Process.ok + echo '+ { "server-OpenProcess", "Michael Müller", "Return error when opening a terminating process. [rev 3]" },'; \ + ) > server-OpenProcess.ok # Patchset server-Stored_ACLs # | @@ -790,6 +774,24 @@ shell32-Default_Folder_ACLs.ok: echo '+ { "shell32-Default_Folder_ACLs", "Erich E. Hoover", "Generate default ACLs for user shell folders. [rev 6]" },'; \ ) > shell32-Default_Folder_ACLs.ok +# Patchset shell32-Default_Path +# | +# | Included patches: +# | * Implement KF_FLAG_DEFAULT_PATH flag for SHGetKnownFolderPath. [by Sebastian Lackner] +# | +# | This patchset fixes the following Wine bugs: +# | * [#30385] Support for KF_FLAG_DEFAULT_PATH in SHGetKnownFolderPath +# | +# | Modified files: +# | * dlls/shell32/shellpath.c, dlls/shell32/tests/shellpath.c +# | +.INTERMEDIATE: shell32-Default_Path.ok +shell32-Default_Path.ok: + $(call APPLY_FILE,shell32-Default_Path/0001-shell32-Implement-KF_FLAG_DEFAULT_PATH-flag-for-SHGe.patch) + @( \ + echo '+ { "shell32-Default_Path", "Sebastian Lackner", "Implement KF_FLAG_DEFAULT_PATH flag for SHGetKnownFolderPath." },'; \ + ) > shell32-Default_Path.ok + # Patchset shell32-Icons # | # | Included patches: diff --git a/patches/bcrypt-BCryptGetFipsAlgorithmMode/definition b/patches/bcrypt-BCryptGetFipsAlgorithmMode/definition index eed58efe..05f9031a 100644 --- a/patches/bcrypt-BCryptGetFipsAlgorithmMode/definition +++ b/patches/bcrypt-BCryptGetFipsAlgorithmMode/definition @@ -1,4 +1,4 @@ Author: Michael Müller Subject: Add semi-stub for BCryptGetFipsAlgorithmMode. Revision: 1 -Fixes: [32194] Multiple applications need BCryptGetFipsAlgorithmMode +Fixes: [32194] Support for BCryptGetFipsAlgorithmMode diff --git a/patches/dwmapi-Invalidate_Thumbnail/0001-dwmapi-Add-stub-for-DwmInvalidateIconicBitmaps.patch b/patches/dwmapi-Invalidate_Thumbnail/0001-dwmapi-Add-stub-for-DwmInvalidateIconicBitmaps.patch deleted file mode 100644 index e923919a..00000000 --- a/patches/dwmapi-Invalidate_Thumbnail/0001-dwmapi-Add-stub-for-DwmInvalidateIconicBitmaps.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 30201042f9da59a0943902d45f65659226fa3583 Mon Sep 17 00:00:00 2001 -From: "Erich E. Hoover" -Date: Sat, 9 Aug 2014 16:30:53 -0600 -Subject: dwmapi: Add stub for DwmInvalidateIconicBitmaps. - ---- - dlls/dwmapi/dwmapi.spec | 1 + - dlls/dwmapi/dwmapi_main.c | 12 ++++++++++++ - include/dwmapi.h | 1 + - 3 files changed, 14 insertions(+) - -diff --git a/dlls/dwmapi/dwmapi.spec b/dlls/dwmapi/dwmapi.spec -index 5f74970..764f04c 100644 ---- a/dlls/dwmapi/dwmapi.spec -+++ b/dlls/dwmapi/dwmapi.spec -@@ -33,6 +33,7 @@ - @ stdcall DwmGetGraphicsStreamTransformHint(long ptr) - @ stdcall DwmGetTransportAttributes(ptr ptr ptr) - @ stdcall DwmGetWindowAttribute(ptr long ptr long) -+@ stdcall DwmInvalidateIconicBitmaps(ptr) - @ stdcall DwmIsCompositionEnabled(ptr) - @ stub DwmModifyPreviousDxFrameDuration - @ stub DwmQueryThumbnailSourceSize -diff --git a/dlls/dwmapi/dwmapi_main.c b/dlls/dwmapi/dwmapi_main.c -index 8cc46f0..6ee45af 100644 ---- a/dlls/dwmapi/dwmapi_main.c -+++ b/dlls/dwmapi/dwmapi_main.c -@@ -108,6 +108,18 @@ HRESULT WINAPI DwmFlush(void) - } - - /********************************************************************** -+ * DwmInvalidateIconicBitmaps (DWMAPI.@) -+ */ -+HRESULT WINAPI DwmInvalidateIconicBitmaps(HWND hwnd) -+{ -+ static BOOL once; -+ -+ if (!once++) FIXME("(%p) stub\n", hwnd); -+ -+ return E_NOTIMPL; -+} -+ -+/********************************************************************** - * DwmSetWindowAttribute (DWMAPI.@) - */ - HRESULT WINAPI DwmSetWindowAttribute(HWND hwnd, DWORD attributenum, LPCVOID attribute, DWORD size) -diff --git a/include/dwmapi.h b/include/dwmapi.h -index f85999a..db13b5f 100644 ---- a/include/dwmapi.h -+++ b/include/dwmapi.h -@@ -116,6 +116,7 @@ DWMAPI DwmEnableMMCSS(BOOL); - DWMAPI DwmExtendFrameIntoClientArea(HWND,const MARGINS*); - DWMAPI DwmGetColorizationColor(DWORD*,BOOL); - DWMAPI DwmGetCompositionTimingInfo(HWND,DWM_TIMING_INFO*); -+DWMAPI DwmInvalidateIconicBitmaps(HWND); - DWMAPI DwmIsCompositionEnabled(BOOL*); - DWMAPI DwmRegisterThumbnail(HWND, HWND, PHTHUMBNAIL); - DWMAPI DwmSetWindowAttribute(HWND, DWORD, LPCVOID, DWORD); --- -1.7.9.5 - diff --git a/patches/dwmapi-Invalidate_Thumbnail/definition b/patches/dwmapi-Invalidate_Thumbnail/definition deleted file mode 100644 index 16f38e19..00000000 --- a/patches/dwmapi-Invalidate_Thumbnail/definition +++ /dev/null @@ -1,4 +0,0 @@ -Author: Erich E. Hoover -Subject: Add stub for DwmInvalidateIconicBitmaps. -Revision: 1 -Fixes: [32977] Support for DwmInvalidateIconicBitmaps diff --git a/patches/kernel32-GetSystemTimes/0001-kernel32-Add-tests-for-GetSystemTimes.patch b/patches/kernel32-GetSystemTimes/0001-kernel32-Add-tests-for-GetSystemTimes.patch index 66034265..d64894ff 100644 --- a/patches/kernel32-GetSystemTimes/0001-kernel32-Add-tests-for-GetSystemTimes.patch +++ b/patches/kernel32-GetSystemTimes/0001-kernel32-Add-tests-for-GetSystemTimes.patch @@ -1,4 +1,4 @@ -From d42b5e55c0b0eeae00b0c12cac539d918a5bacf9 Mon Sep 17 00:00:00 2001 +From 289599c8372b08c97561d6703ac45c0b9ad395d2 Mon Sep 17 00:00:00 2001 From: Louis Lenders Date: Sun, 27 Jul 2014 11:42:28 -0600 Subject: kernel32: Add tests for GetSystemTimes. @@ -8,7 +8,7 @@ Subject: kernel32: Add tests for GetSystemTimes. 1 file changed, 77 insertions(+) diff --git a/dlls/kernel32/tests/time.c b/dlls/kernel32/tests/time.c -index 55d4be9..dde9f5d 100644 +index 55d4be9..6f5c03d 100644 --- a/dlls/kernel32/tests/time.c +++ b/dlls/kernel32/tests/time.c @@ -22,9 +22,11 @@ @@ -55,17 +55,17 @@ index 55d4be9..dde9f5d 100644 + ul1.LowPart = idletime.dwLowDateTime; + ul1.HighPart = idletime.dwHighDateTime; + -+ trace( "IdleTime: %llu seconds\n",ul1.QuadPart/10000000); ++ trace( "IdleTime: %f seconds\n", (double)ul1.QuadPart/10000000.0 ); + + ul2.LowPart = kerneltime.dwLowDateTime; + ul2.HighPart = kerneltime.dwHighDateTime; + -+ trace( "KernelTime: %llu seconds\n", ul2.QuadPart/10000000 ); ++ trace( "KernelTime: %f seconds\n", (double)ul2.QuadPart/10000000.0 ); + + ul3.LowPart = usertime.dwLowDateTime; + ul3.HighPart = usertime.dwHighDateTime; + -+ trace( "UserTime: %llu seconds\n", ul3.QuadPart/10000000 ); ++ trace( "UserTime: %f seconds\n", (double)ul3.QuadPart/10000000.0 ); + + + ok( !NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength), diff --git a/patches/kernel32-GetSystemTimes/0002-kernel32-Implement-GetSystemTimes.patch b/patches/kernel32-GetSystemTimes/0002-kernel32-Implement-GetSystemTimes.patch index 9a87f9ac..d50c3625 100644 --- a/patches/kernel32-GetSystemTimes/0002-kernel32-Implement-GetSystemTimes.patch +++ b/patches/kernel32-GetSystemTimes/0002-kernel32-Implement-GetSystemTimes.patch @@ -1,4 +1,4 @@ -From c3acb24297b1b4e41746ba13f7e997bbe7e0c64a Mon Sep 17 00:00:00 2001 +From c7d23fced92e26c724cdeb389f827c436294b05d Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sun, 27 Jul 2014 12:38:29 -0600 Subject: kernel32: Implement GetSystemTimes. @@ -9,7 +9,7 @@ Subject: kernel32: Implement GetSystemTimes. 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/dlls/kernel32/tests/time.c b/dlls/kernel32/tests/time.c -index dde9f5d..fe459e4 100644 +index 6f5c03d..d3d3939 100644 --- a/dlls/kernel32/tests/time.c +++ b/dlls/kernel32/tests/time.c @@ -751,13 +751,13 @@ static void test_GetSystemTimes(void) diff --git a/patches/kernel32-GetVolumePathName/0001-kernel32-Implement-GetVolumePathName.patch b/patches/kernel32-GetVolumePathName/0001-kernel32-Implement-GetVolumePathName.patch index b7a2a2f2..3fc82278 100644 --- a/patches/kernel32-GetVolumePathName/0001-kernel32-Implement-GetVolumePathName.patch +++ b/patches/kernel32-GetVolumePathName/0001-kernel32-Implement-GetVolumePathName.patch @@ -1,4 +1,4 @@ -From bcf395630fde511be0606ad8292385f37d127969 Mon Sep 17 00:00:00 2001 +From c8a873013240a0511789c5e9d38b8d1fab18658b Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sat, 25 Jan 2014 09:47:12 -0700 Subject: kernel32: Implement GetVolumePathName. @@ -29,10 +29,10 @@ index 61da509..4b3bdf5 100644 /* test an invalid path */ diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c -index 1509d73..a4b158a 100644 +index d396764..75bc20f 100644 --- a/dlls/kernel32/volume.c +++ b/dlls/kernel32/volume.c -@@ -1784,7 +1784,7 @@ BOOL WINAPI GetVolumePathNameA(LPCSTR filename, LPSTR volumepathname, DWORD bufl +@@ -1786,7 +1786,7 @@ BOOL WINAPI GetVolumePathNameA(LPCSTR filename, LPSTR volumepathname, DWORD bufl BOOL ret; WCHAR *filenameW = NULL, *volumeW = NULL; @@ -41,7 +41,7 @@ index 1509d73..a4b158a 100644 if (filename && !(filenameW = FILE_name_AtoW( filename, FALSE ))) return FALSE; -@@ -1800,37 +1800,137 @@ BOOL WINAPI GetVolumePathNameA(LPCSTR filename, LPSTR volumepathname, DWORD bufl +@@ -1802,37 +1802,137 @@ BOOL WINAPI GetVolumePathNameA(LPCSTR filename, LPSTR volumepathname, DWORD bufl /*********************************************************************** * GetVolumePathNameW (KERNEL32.@) diff --git a/patches/kernel32-GetVolumePathName/0002-kernel32-Convert-GetVolumePathName-tests-into-a-list.patch b/patches/kernel32-GetVolumePathName/0002-kernel32-Convert-GetVolumePathName-tests-into-a-list.patch index 17f9ee44..7fa65dcf 100644 --- a/patches/kernel32-GetVolumePathName/0002-kernel32-Convert-GetVolumePathName-tests-into-a-list.patch +++ b/patches/kernel32-GetVolumePathName/0002-kernel32-Convert-GetVolumePathName-tests-into-a-list.patch @@ -1,4 +1,4 @@ -From 9d3403bbcab0fbfb465a224fae93ebbc9e442e35 Mon Sep 17 00:00:00 2001 +From 7739a32bd18ed7912e610941f6cfb273748b82cd Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sat, 25 Jan 2014 09:53:39 -0700 Subject: kernel32: Convert GetVolumePathName tests into a list. @@ -8,7 +8,7 @@ Subject: kernel32: Convert GetVolumePathName tests into a list. 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c -index 4b3bdf5..7f68dd0 100644 +index 4b3bdf5..f15269c 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -591,79 +591,90 @@ static void test_disk_extents(void) @@ -106,7 +106,7 @@ index 4b3bdf5..7f68dd0 100644 + ret = pGetVolumePathNameA( test_paths[i].file_name, output, test_paths[i].path_len ); + error = GetLastError(); + ok(ret == expected_ret, "GetVolumePathName test %d %s unexpectedly.\n", -+ i, test_paths[i].error == NO_ERROR ? "failed" : "succeeded"); ++ i, test_paths[i].error == NO_ERROR ? "failed" : "succeeded"); - SetLastError( 0xdeadbeef ); - ret = pGetVolumePathNameA(pathC1, volume, 0); @@ -146,7 +146,7 @@ index 4b3bdf5..7f68dd0 100644 - ok(!ret, "expected failure\n"); - ok(error == ERROR_INVALID_NAME || broken(ERROR_FILENAME_EXCED_RANGE) /* <=2000 */, - "expected ERROR_INVALID_NAME got %u\n", error); -+ if(ret) ++ if (ret) + { + /* If we succeeded then make sure the path is correct */ + success = (strcmp( volume_path, test_paths[i].path_name ) == 0) @@ -157,7 +157,7 @@ index 4b3bdf5..7f68dd0 100644 + else + { + /* On success Windows always returns ERROR_MORE_DATA, so only worry about failure */ -+ success = (error == test_paths[i].error); ++ success = (error == test_paths[i].error || broken(error == test_paths[i].broken_error)); + ok(success, "GetVolumePathName test %d unexpectedly returned error 0x%x (expected 0x%x).\n", + i, error, test_paths[i].error); + } diff --git a/patches/kernel32-GetVolumePathName/0003-kernel32-Add-a-bunch-more-GetVolumePathName-tests.patch b/patches/kernel32-GetVolumePathName/0003-kernel32-Add-a-bunch-more-GetVolumePathName-tests.patch index 601172a3..23cbec53 100644 --- a/patches/kernel32-GetVolumePathName/0003-kernel32-Add-a-bunch-more-GetVolumePathName-tests.patch +++ b/patches/kernel32-GetVolumePathName/0003-kernel32-Add-a-bunch-more-GetVolumePathName-tests.patch @@ -1,4 +1,4 @@ -From 0ca1995e881b0951348ddfb4ab702f7cc3746549 Mon Sep 17 00:00:00 2001 +From a6eb5189737a6aeb31dd305649f407ca5ddc9faf Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sat, 25 Jan 2014 09:54:39 -0700 Subject: kernel32: Add a bunch more GetVolumePathName tests. @@ -8,7 +8,7 @@ Subject: kernel32: Add a bunch more GetVolumePathName tests. 1 file changed, 28 insertions(+) diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c -index 7f68dd0..9159cad 100644 +index f15269c..e17cc16 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -635,6 +635,34 @@ static void test_GetVolumePathNameA(void) diff --git a/patches/kernel32-Named_Pipe/0002-ntdll-tests-Add-tests-for-FILE_PIPE_INFORMATION.patch b/patches/kernel32-Named_Pipe/0002-ntdll-tests-Add-tests-for-FILE_PIPE_INFORMATION.patch deleted file mode 100644 index 511b0a36..00000000 --- a/patches/kernel32-Named_Pipe/0002-ntdll-tests-Add-tests-for-FILE_PIPE_INFORMATION.patch +++ /dev/null @@ -1,244 +0,0 @@ -From f78c4bb06e2c463ea2e7a7cee374714814a5fdb1 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Tue, 12 Aug 2014 21:31:00 +0200 -Subject: ntdll/tests: Add tests for FILE_PIPE_INFORMATION. - -Based on patch by Adam Martinson. - -I've added more tests, and have marked failing tests as broken(...). On Windows 8 -we still get some failures, but as there is a lot more going wrong there, we probably shouldn't -worry about that. ;) ---- - dlls/ntdll/tests/pipe.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 188 insertions(+) - -diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c -index c275e3d..75faf76 100644 ---- a/dlls/ntdll/tests/pipe.c -+++ b/dlls/ntdll/tests/pipe.c -@@ -34,6 +34,11 @@ - #ifndef __WINE_WINTERNL_H - - typedef struct { -+ ULONG ReadMode; -+ ULONG CompletionMode; -+} FILE_PIPE_INFORMATION; -+ -+typedef struct { - ULONG NamedPipeType; - ULONG NamedPipeConfiguration; - ULONG MaximumInstances; -@@ -68,6 +73,7 @@ static NTSTATUS (WINAPI *pNtCreateNamedPipeFile) (PHANDLE handle, ULONG access, - ULONG inbound_quota, ULONG outbound_quota, - PLARGE_INTEGER timeout); - static NTSTATUS (WINAPI *pNtQueryInformationFile) (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass); -+static NTSTATUS (WINAPI *pNtSetInformationFile) (HANDLE handle, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class); - static NTSTATUS (WINAPI *pNtCancelIoFile) (HANDLE hFile, PIO_STATUS_BLOCK io_status); - static void (WINAPI *pRtlInitUnicodeString) (PUNICODE_STRING target, PCWSTR source); - -@@ -87,6 +93,7 @@ static BOOL init_func_ptrs(void) - loadfunc(NtFsControlFile) - loadfunc(NtCreateNamedPipeFile) - loadfunc(NtQueryInformationFile) -+ loadfunc(NtSetInformationFile) - loadfunc(NtCancelIoFile) - loadfunc(RtlInitUnicodeString) - -@@ -479,6 +486,184 @@ static void test_cancelio(void) - CloseHandle(hPipe); - } - -+#define check_pipe_handle_state(handle, r, c) \ -+ do \ -+ { \ -+ memset(&fpi, 0x55, sizeof(fpi)); \ -+ if (handle == INVALID_HANDLE_VALUE) break; \ -+ res = pNtQueryInformationFile(handle, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); \ -+ ok(!res, "NtQueryInformationFile returned %x\n", res); \ -+ ok(fpi.ReadMode == r, "ReadMode == %x\n", fpi.ReadMode); \ -+ ok(fpi.CompletionMode == c, "CompletionMode == %x\n", fpi.CompletionMode); \ -+ } \ -+ while (0) -+ -+static void test_filepipeinfo(void) -+{ -+ IO_STATUS_BLOCK iosb; -+ OBJECT_ATTRIBUTES attr; -+ UNICODE_STRING name; -+ LARGE_INTEGER timeout; -+ HANDLE hServer, hClient; -+ FILE_PIPE_INFORMATION fpi; -+ NTSTATUS res; -+ -+ pRtlInitUnicodeString(&name, testpipe_nt); -+ -+ attr.Length = sizeof(attr); -+ attr.RootDirectory = 0; -+ attr.ObjectName = &name; -+ attr.Attributes = 0x40; /* case insensitive */ -+ attr.SecurityDescriptor = NULL; -+ attr.SecurityQualityOfService = NULL; -+ -+ timeout.QuadPart = -100000000000ll; -+ -+ /* test with INVALID_HANDLE_VALUE */ -+ res = pNtQueryInformationFile(INVALID_HANDLE_VALUE, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_OBJECT_TYPE_MISMATCH, "NtQueryInformationFile returned %x\n", res); -+ -+ fpi.ReadMode = 0; -+ fpi.CompletionMode = 0; -+ res = pNtSetInformationFile(INVALID_HANDLE_VALUE, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_OBJECT_TYPE_MISMATCH, "NtSetInformationFile returned %x\n", res); -+ -+ /* server end with read-only attributes */ -+ res = pNtCreateNamedPipeFile(&hServer, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, -+ FILE_SHARE_READ | FILE_SHARE_WRITE, 2 /* FILE_CREATE */, -+ 0, 0, 0, 1, 0xFFFFFFFF, 500, 500, &timeout); -+ ok(!res, "NtCreateNamedPipeFile returned %x\n", res); -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ -+ hClient = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); -+ ok(hClient != INVALID_HANDLE_VALUE, "can't open pipe, GetLastError: %x\n", GetLastError()); -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ check_pipe_handle_state(hClient, 0, 0); -+ -+ fpi.ReadMode = 0; -+ fpi.CompletionMode = 0; -+ res = pNtSetInformationFile(hServer, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_ACCESS_DENIED, "NtSetInformationFile returned %x\n", res); -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ check_pipe_handle_state(hClient, 0, 0); -+ -+ fpi.ReadMode = 1; /* invalid on a byte stream pipe */ -+ fpi.CompletionMode = 1; -+ res = pNtSetInformationFile(hServer, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_ACCESS_DENIED, "NtSetInformationFile returned %x\n", res); -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ check_pipe_handle_state(hClient, 0, 0); -+ -+ if (hClient != INVALID_HANDLE_VALUE) -+ { -+ fpi.ReadMode = 1; /* invalid on a byte stream pipe */ -+ fpi.CompletionMode = 1; -+ res = pNtSetInformationFile(hClient, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_INVALID_PARAMETER, "NtSetInformationFile returned %x\n", res); -+ } -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ check_pipe_handle_state(hClient, 0, 0); -+ -+ if (hClient != INVALID_HANDLE_VALUE) -+ { -+ fpi.ReadMode = 0; -+ fpi.CompletionMode = 1; -+ res = pNtSetInformationFile(hClient, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(!res, "NtSetInformationFile returned %x\n", res); -+ } -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ check_pipe_handle_state(hClient, 0, 1); -+ -+ if (hClient != INVALID_HANDLE_VALUE) -+ { -+ fpi.ReadMode = 0; -+ fpi.CompletionMode = 2; /* not in range 0-1 */ -+ res = pNtSetInformationFile(hClient, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_INVALID_PARAMETER || broken(!res) /* < Vista */, "NtSetInformationFile returned %x\n", res); -+ -+ fpi.ReadMode = 2; /* not in range 0-1 */ -+ fpi.CompletionMode = 0; -+ res = pNtSetInformationFile(hClient, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_INVALID_PARAMETER || broken(!res) /* < Vista */, "NtSetInformationFile returned %x\n", res); -+ } -+ -+ CloseHandle(hClient); -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ -+ fpi.ReadMode = 0; -+ fpi.CompletionMode = 0; -+ res = pNtSetInformationFile(hServer, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_ACCESS_DENIED, "NtSetInformationFile returned %x\n", res); -+ -+ CloseHandle(hServer); -+ -+ /* message mode server with read/write attributes */ -+ res = pNtCreateNamedPipeFile(&hServer, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, -+ FILE_SHARE_READ | FILE_SHARE_WRITE, 2 /* FILE_CREATE */, -+ 0, 1, 1, 0, 0xFFFFFFFF, 500, 500, &timeout); -+ ok(!res, "NtCreateNamedPipeFile returned %x\n", res); -+ -+ check_pipe_handle_state(hServer, 1, 0); -+ -+ hClient = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); -+ ok(hClient != INVALID_HANDLE_VALUE, "can't open pipe, GetLastError: %x\n", GetLastError()); -+ -+ check_pipe_handle_state(hServer, 1, 0); -+ check_pipe_handle_state(hClient, 0, 0); -+ -+ if (hClient != INVALID_HANDLE_VALUE) -+ { -+ fpi.ReadMode = 1; -+ fpi.CompletionMode = 1; -+ res = pNtSetInformationFile(hClient, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(!res, "NtSetInformationFile returned %x\n", res); -+ } -+ -+ check_pipe_handle_state(hServer, 1, 0); -+ check_pipe_handle_state(hClient, 1, 1); -+ -+ fpi.ReadMode = 0; -+ fpi.CompletionMode = 1; -+ res = pNtSetInformationFile(hServer, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(!res, "NtSetInformationFile returned %x\n", res); -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ check_pipe_handle_state(hClient, 1, 1); -+ -+ if (hClient != INVALID_HANDLE_VALUE) -+ { -+ fpi.ReadMode = 0; -+ fpi.CompletionMode = 2; /* not in range 0-1 */ -+ res = pNtSetInformationFile(hClient, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_INVALID_PARAMETER || broken(!res) /* < Vista */, "NtSetInformationFile returned %x\n", res); -+ -+ fpi.ReadMode = 2; /* not in range 0-1 */ -+ fpi.CompletionMode = 0; -+ res = pNtSetInformationFile(hClient, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(res == STATUS_INVALID_PARAMETER || broken(!res) /* < Vista */, "NtSetInformationFile returned %x\n", res); -+ } -+ -+ CloseHandle(hClient); -+ -+ check_pipe_handle_state(hServer, 0, 1); -+ -+ fpi.ReadMode = 1; -+ fpi.CompletionMode = 0; -+ res = pNtSetInformationFile(hServer, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); -+ ok(!res, "NtSetInformationFile returned %x\n", res); -+ -+ check_pipe_handle_state(hServer, 1, 0); -+ -+ CloseHandle(hServer); -+} -+ - START_TEST(pipe) - { - if (!init_func_ptrs()) -@@ -493,6 +678,9 @@ START_TEST(pipe) - trace("starting overlapped tests\n"); - test_overlapped(); - -+ trace("starting FILE_PIPE_INFORMATION tests\n"); -+ test_filepipeinfo(); -+ - if (!pOpenThread || !pQueueUserAPC) - return; - --- -1.7.9.5 - diff --git a/patches/kernel32-Named_Pipe/0003-kernel32-tests-Always-allow-only-one-specific-test-r.patch b/patches/kernel32-Named_Pipe/0003-kernel32-tests-Always-allow-only-one-specific-test-r.patch deleted file mode 100644 index 8e90bffe..00000000 --- a/patches/kernel32-Named_Pipe/0003-kernel32-tests-Always-allow-only-one-specific-test-r.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 2ae3b0fe9a03067879de3c7409e212510e134900 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 30 Jul 2014 18:00:19 +0200 -Subject: kernel32/tests: Always allow only one specific test result, add - todo_wine where necessary. - -The current pipe tests are not really a good base for fixing the implemenation - -some of the todo_wine's depend on the return value itself. This hides if one of -the following patches breaks things. Besides that some of the tests are currently -broken on kernel >= 3.12 (bug #35781), mark those as todo_wine. - -Changes in v2: - * Ensure that the APC is properly removed - as it turned out this broke like 20 patches - later one of the other new tests... ^^ ---- - dlls/kernel32/tests/pipe.c | 57 +++++++++++++++++--------------------------- - 1 file changed, 22 insertions(+), 35 deletions(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index f7c7531..5790be8 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -153,20 +153,13 @@ static void test_CreateNamedPipe(int pipemode) - ok(written == sizeof(obuf2), "write file len 3b\n"); - ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek3\n"); - if (pipemode == PIPE_TYPE_BYTE) { -- if (readden != sizeof(obuf)) /* Linux only returns the first message */ -- ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); -- else -- todo_wine ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); -+ todo_wine ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); - } - else - { -- if (readden != sizeof(obuf) + sizeof(obuf2)) /* MacOS returns both messages */ -- ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden); -- else -- todo_wine ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden); -+ ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden); - } -- if (avail != sizeof(obuf)) /* older Linux kernels only return the first write here */ -- ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); -+ ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); - pbuf = ibuf; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 3a check\n"); - if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) { -@@ -188,21 +181,13 @@ static void test_CreateNamedPipe(int pipemode) - ok(written == sizeof(obuf2), "write file len 4b\n"); - ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek4\n"); - if (pipemode == PIPE_TYPE_BYTE) { -- if (readden != sizeof(obuf)) /* Linux only returns the first message */ -- /* should return all 23 bytes */ -- ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); -- else -- todo_wine ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); -+ todo_wine ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); - } - else - { -- if (readden != sizeof(obuf) + sizeof(obuf2)) /* MacOS returns both messages */ -- ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden); -- else -- todo_wine ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden); -+ ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden); - } -- if (avail != sizeof(obuf)) /* older Linux kernels only return the first write here */ -- ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes available\n", avail); -+ ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes available\n", avail); - pbuf = ibuf; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 4a check\n"); - if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) { -@@ -243,14 +228,8 @@ static void test_CreateNamedPipe(int pipemode) - ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile5b\n"); - ok(written == sizeof(obuf2), "write file len 3b\n"); - ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek5\n"); -- if (readden != sizeof(obuf) + sizeof(obuf2)) /* MacOS returns both writes */ -- ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden); -- else -- todo_wine ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden); -- if (avail != sizeof(obuf)) /* older Linux kernels only return the first write here */ -- ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %d bytes available\n", avail); -- else -- todo_wine ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %d bytes available\n", avail); -+ ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden); -+ ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %d bytes available\n", avail); - pbuf = ibuf; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); - ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -@@ -279,12 +258,8 @@ static void test_CreateNamedPipe(int pipemode) - ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile6b\n"); - ok(written == sizeof(obuf2), "write file len 6b\n"); - ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6\n"); -- if (readden != sizeof(obuf) + sizeof(obuf2)) /* MacOS returns both writes */ -- ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden); -- else -- todo_wine ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden); -- if (avail != sizeof(obuf)) /* older Linux kernels only return the first write here */ -- ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %d bytes available\n", avail); -+ ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden); -+ ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %d bytes available\n", avail); - pbuf = ibuf; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); - ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -@@ -1856,7 +1831,19 @@ static void test_readfileex_pending(void) - ok(completion_called == 0, "completion routine called during ReadFile\n"); - - wait = WaitForSingleObjectEx(event, 0, TRUE); -+ todo_wine - ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); -+ if (wait == WAIT_TIMEOUT) -+ { -+ /* work around kernel regression, and read some more */ -+ ret = ReadFile(client, read_buf, sizeof(read_buf), &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile failed\n"); -+ -+ ok(completion_called == 0, "completion routine called during ReadFile\n"); -+ -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); -+ } - - ok(completion_called == 1, "completion routine not called\n"); - ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); --- -1.7.9.5 - diff --git a/patches/kernel32-Named_Pipe/0004-kernel32-Implement-Get-Set-NamedPipeHandleState.patch b/patches/kernel32-Named_Pipe/0004-kernel32-Implement-Get-Set-NamedPipeHandleState.patch deleted file mode 100644 index 5f711103..00000000 --- a/patches/kernel32-Named_Pipe/0004-kernel32-Implement-Get-Set-NamedPipeHandleState.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 5b33f8fd992f8944442e8428e433461157b9e6c9 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 11 Aug 2014 17:26:18 +0200 -Subject: kernel32: Implement {Get,Set}NamedPipeHandleState. - -Based on patch by Adam Martinson. ---- - dlls/kernel32/sync.c | 88 +++++++++++++++++++++++++++++++++++++++----- - dlls/kernel32/tests/pipe.c | 16 +------- - 2 files changed, 81 insertions(+), 23 deletions(-) - -diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c -index ff0e234..96a36b9 100644 ---- a/dlls/kernel32/sync.c -+++ b/dlls/kernel32/sync.c -@@ -1713,12 +1713,16 @@ BOOL WINAPI GetNamedPipeHandleStateA( - LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout, - LPSTR lpUsername, DWORD nUsernameMaxSize) - { -- FIXME("%p %p %p %p %p %p %d\n", -- hNamedPipe, lpState, lpCurInstances, -- lpMaxCollectionCount, lpCollectDataTimeout, -- lpUsername, nUsernameMaxSize); -+ WARN("%p %p %p %p %p %p %d: semi-stub\n", -+ hNamedPipe, lpState, lpCurInstances, -+ lpMaxCollectionCount, lpCollectDataTimeout, -+ lpUsername, nUsernameMaxSize); - -- return FALSE; -+ if (lpUsername && nUsernameMaxSize) -+ *lpUsername = 0; -+ -+ return GetNamedPipeHandleStateW(hNamedPipe, lpState, lpCurInstances, -+ lpMaxCollectionCount, lpCollectDataTimeout, NULL, 0); - } - - /*********************************************************************** -@@ -1729,12 +1733,53 @@ BOOL WINAPI GetNamedPipeHandleStateW( - LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout, - LPWSTR lpUsername, DWORD nUsernameMaxSize) - { -- FIXME("%p %p %p %p %p %p %d\n", -+ IO_STATUS_BLOCK iosb; -+ NTSTATUS status; -+ -+ FIXME("%p %p %p %p %p %p %d: semi-stub\n", - hNamedPipe, lpState, lpCurInstances, - lpMaxCollectionCount, lpCollectDataTimeout, - lpUsername, nUsernameMaxSize); - -- return FALSE; -+ if (lpMaxCollectionCount) -+ *lpMaxCollectionCount = 0; -+ -+ if (lpCollectDataTimeout) -+ *lpCollectDataTimeout = 0; -+ -+ if (lpUsername && nUsernameMaxSize) -+ *lpUsername = 0; -+ -+ if (lpState) -+ { -+ FILE_PIPE_INFORMATION fpi; -+ status = NtQueryInformationFile(hNamedPipe, &iosb, &fpi, sizeof(fpi), -+ FilePipeInformation); -+ if (status) -+ { -+ SetLastError( RtlNtStatusToDosError(status) ); -+ return FALSE; -+ } -+ -+ *lpState = (fpi.ReadMode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE) | -+ (fpi.CompletionMode ? PIPE_NOWAIT : PIPE_WAIT); -+ } -+ -+ if (lpCurInstances) -+ { -+ FILE_PIPE_LOCAL_INFORMATION fpli; -+ status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli), -+ FilePipeLocalInformation); -+ if (status) -+ { -+ SetLastError( RtlNtStatusToDosError(status) ); -+ return FALSE; -+ } -+ -+ *lpCurInstances = fpli.CurrentInstances; -+ } -+ -+ return TRUE; - } - - /*********************************************************************** -@@ -1746,9 +1791,34 @@ BOOL WINAPI SetNamedPipeHandleState( - { - /* should be a fixme, but this function is called a lot by the RPC - * runtime, and it slows down InstallShield a fair bit. */ -- WARN("stub: %p %p/%d %p %p\n", -+ WARN("semi-stub: %p %p/%d %p %p\n", - hNamedPipe, lpMode, lpMode ? *lpMode : 0, lpMaxCollectionCount, lpCollectDataTimeout); -- return FALSE; -+ -+ if (lpMode) -+ { -+ FILE_PIPE_INFORMATION fpi; -+ IO_STATUS_BLOCK iosb; -+ NTSTATUS status; -+ -+ if (*lpMode & ~(PIPE_READMODE_MESSAGE | PIPE_NOWAIT)) -+ status = STATUS_INVALID_PARAMETER; -+ else -+ { -+ fpi.CompletionMode = (*lpMode & PIPE_NOWAIT) ? -+ FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION; -+ fpi.ReadMode = (*lpMode & PIPE_READMODE_MESSAGE) ? -+ FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE; -+ status = NtSetInformationFile(hNamedPipe, &iosb, &fpi, sizeof(fpi), FilePipeInformation); -+ } -+ -+ if (status) -+ { -+ SetLastError( RtlNtStatusToDosError(status) ); -+ return FALSE; -+ } -+ } -+ -+ return TRUE; - } - - /*********************************************************************** -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 5790be8..46004a3 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -218,10 +218,8 @@ static void test_CreateNamedPipe(int pipemode) - ok(!SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); - } - else { -- todo_wine { -- ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); -- } -- -+ ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); -+ - memset(ibuf, 0, sizeof(ibuf)); - ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile5a\n"); - ok(written == sizeof(obuf), "write file len 3a\n"); -@@ -1637,11 +1635,9 @@ static void test_NamedPipeHandleState(void) - /* lpSecurityAttrib */ NULL); - ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); - ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); -- todo_wine - ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); - ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, - 0); -- todo_wine - ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); - if (ret) - { -@@ -1662,7 +1658,6 @@ static void test_NamedPipeHandleState(void) - state = PIPE_READMODE_MESSAGE; - SetLastError(0xdeadbeef); - ret = SetNamedPipeHandleState(server, &state, NULL, NULL); -- todo_wine - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - -@@ -1672,13 +1667,11 @@ static void test_NamedPipeHandleState(void) - - state = PIPE_READMODE_BYTE; - ret = SetNamedPipeHandleState(client, &state, NULL, NULL); -- todo_wine - ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); - /* A byte-mode pipe client can't be changed to message mode, either. */ - state = PIPE_READMODE_MESSAGE; - SetLastError(0xdeadbeef); - ret = SetNamedPipeHandleState(server, &state, NULL, NULL); -- todo_wine - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - -@@ -1694,11 +1687,9 @@ static void test_NamedPipeHandleState(void) - /* lpSecurityAttrib */ NULL); - ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); - ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); -- todo_wine - ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); - ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, - 0); -- todo_wine - ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); - if (ret) - { -@@ -1710,7 +1701,6 @@ static void test_NamedPipeHandleState(void) - */ - state = PIPE_READMODE_BYTE; - ret = SetNamedPipeHandleState(server, &state, NULL, NULL); -- todo_wine - ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); - - client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, -@@ -1719,13 +1709,11 @@ static void test_NamedPipeHandleState(void) - - state = PIPE_READMODE_MESSAGE; - ret = SetNamedPipeHandleState(client, &state, NULL, NULL); -- todo_wine - ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); - /* A message-mode pipe client can also be changed to byte mode. - */ - state = PIPE_READMODE_BYTE; - ret = SetNamedPipeHandleState(client, &state, NULL, NULL); -- todo_wine - ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); - - CloseHandle(client); --- -1.7.9.5 - diff --git a/patches/kernel32-Named_Pipe/definition b/patches/kernel32-Named_Pipe/definition index 59497cf5..e17a441b 100644 --- a/patches/kernel32-Named_Pipe/definition +++ b/patches/kernel32-Named_Pipe/definition @@ -1,10 +1,4 @@ Author: Dan Kegel Subject: Fix for ConnectNamedPort return value in overlapped mode. Revision: 1 - -Author: Sebastian Lackner / Adam Martinson -Subject: Add proper implementation for SetNamedPipeHandleState. -Revision: 7 - Fixes: [16550] Fix for ConnectNamedPort return value in overlapped mode -Fixes: [17273] Support for SetNamedPipeHandleState diff --git a/patches/ntdll-Fix_Alignment/definition b/patches/ntdll-Fix_Alignment/definition index 6f59b806..3ceadf7d 100644 --- a/patches/ntdll-Fix_Alignment/definition +++ b/patches/ntdll-Fix_Alignment/definition @@ -1,4 +1,4 @@ Author: Michael Müller Subject: Move NtProtectVirtualMemory and NtCreateSection to separate pages in ntdll on x86. Revision: 1 -Fixes: [33162] Adobe Reader requires NtProtectVirtualMemory and NtCreateSection to be on separate pages +Fixes: [33162] Ensure NtProtectVirtualMemory and NtCreateSection are on separate pages diff --git a/patches/riched20-IText_Interface/0001-riched20-Stub-for-ITextRange-interface-and-implement.patch b/patches/riched20-IText_Interface/0001-riched20-Stub-for-ITextRange-interface-and-implement.patch index 2fe64948..a873c8f0 100644 --- a/patches/riched20-IText_Interface/0001-riched20-Stub-for-ITextRange-interface-and-implement.patch +++ b/patches/riched20-IText_Interface/0001-riched20-Stub-for-ITextRange-interface-and-implement.patch @@ -1,4 +1,4 @@ -From bbe2850e3277120e570c47fd3dde1e3e90dc84e3 Mon Sep 17 00:00:00 2001 +From e2f7556764c4ce3647b67ed687023919b891e9b0 Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Mon, 11 Aug 2014 13:29:06 +0800 Subject: riched20: Stub for ITextRange interface and implement diff --git a/patches/riched20-IText_Interface/0002-riched20-Implement-ITextSelection-GetChar-and-ITextR.patch b/patches/riched20-IText_Interface/0002-riched20-Implement-ITextSelection-GetChar-and-ITextR.patch index d6cf35b5..1c08dc1e 100644 --- a/patches/riched20-IText_Interface/0002-riched20-Implement-ITextSelection-GetChar-and-ITextR.patch +++ b/patches/riched20-IText_Interface/0002-riched20-Implement-ITextSelection-GetChar-and-ITextR.patch @@ -1,4 +1,4 @@ -From f2671157f09140350a3dccda9dbc65890d4c0567 Mon Sep 17 00:00:00 2001 +From 347be1f6538c25517c48c9ff10bd888d13d241b8 Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Sun, 10 Aug 2014 21:55:44 +0800 Subject: riched20: Implement ITextSelection::GetChar and ITextRange::GetChar. diff --git a/patches/riched20-IText_Interface/0003-riched20-Implement-IText-Selection-Range-Get-Start-E.patch b/patches/riched20-IText_Interface/0003-riched20-Implement-IText-Selection-Range-Get-Start-E.patch index cbf77bdd..68e18983 100644 --- a/patches/riched20-IText_Interface/0003-riched20-Implement-IText-Selection-Range-Get-Start-E.patch +++ b/patches/riched20-IText_Interface/0003-riched20-Implement-IText-Selection-Range-Get-Start-E.patch @@ -1,4 +1,4 @@ -From 9ec3f81caf3544b782cda012e7737d1784c1978b Mon Sep 17 00:00:00 2001 +From 86451a53a9707a545430c25ae124cabc198fd48e Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Mon, 11 Aug 2014 10:58:26 +0800 Subject: riched20: Implement IText{Selection, Range}::Get{Start, End}. diff --git a/patches/riched20-IText_Interface/0004-riched20-Implement-ITextRange-GetDuplicate.patch b/patches/riched20-IText_Interface/0004-riched20-Implement-ITextRange-GetDuplicate.patch index 3f8298c1..1ab896ef 100644 --- a/patches/riched20-IText_Interface/0004-riched20-Implement-ITextRange-GetDuplicate.patch +++ b/patches/riched20-IText_Interface/0004-riched20-Implement-ITextRange-GetDuplicate.patch @@ -1,4 +1,4 @@ -From 8f98440f78071eaa1487ddb86749a9850f834811 Mon Sep 17 00:00:00 2001 +From 7f4a575af2fa25ca40654127d6b499583c1e5dd9 Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Sun, 10 Aug 2014 20:43:41 +0800 Subject: riched20: Implement ITextRange::GetDuplicate. diff --git a/patches/riched20-IText_Interface/0005-riched20-Implement-ITextRange-Collapse-and-ITextSele.patch b/patches/riched20-IText_Interface/0005-riched20-Implement-ITextRange-Collapse-and-ITextSele.patch index 33db324c..6b3ee4d2 100644 --- a/patches/riched20-IText_Interface/0005-riched20-Implement-ITextRange-Collapse-and-ITextSele.patch +++ b/patches/riched20-IText_Interface/0005-riched20-Implement-ITextRange-Collapse-and-ITextSele.patch @@ -1,4 +1,4 @@ -From 3aed8c6d2529035b486cd9cb78c090b882e87db8 Mon Sep 17 00:00:00 2001 +From 93048ac9d04e0002cfaefaa97e0ce276303cddb6 Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Sun, 10 Aug 2014 06:02:02 +0800 Subject: riched20: Implement ITextRange::Collapse and diff --git a/patches/riched20-IText_Interface/0006-riched20-Implement-IText-Selection-Range-Set-Start-E.patch b/patches/riched20-IText_Interface/0006-riched20-Implement-IText-Selection-Range-Set-Start-E.patch index 8d171c90..342e9cca 100644 --- a/patches/riched20-IText_Interface/0006-riched20-Implement-IText-Selection-Range-Set-Start-E.patch +++ b/patches/riched20-IText_Interface/0006-riched20-Implement-IText-Selection-Range-Set-Start-E.patch @@ -1,4 +1,4 @@ -From 323889ff346b8e10fa13fede8241263fb9f34c0d Mon Sep 17 00:00:00 2001 +From 27bf1cd55b38e8f4a36dd18d5dedd7d29c1be409 Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Fri, 8 Aug 2014 21:32:57 +0800 Subject: riched20: Implement IText{Selection, Range}::Set{Start, End}. diff --git a/patches/riched20-IText_Interface/0007-riched20-Stub-for-ITextFont-interface-and-implement-.patch b/patches/riched20-IText_Interface/0007-riched20-Stub-for-ITextFont-interface-and-implement-.patch index 74894d57..efb38b5b 100644 --- a/patches/riched20-IText_Interface/0007-riched20-Stub-for-ITextFont-interface-and-implement-.patch +++ b/patches/riched20-IText_Interface/0007-riched20-Stub-for-ITextFont-interface-and-implement-.patch @@ -1,4 +1,4 @@ -From ee362b1b02e5ca39a70c13628c7c4ca11bf09ba6 Mon Sep 17 00:00:00 2001 +From fbef39fb5b1f1cad842289bb8cb16d8df51d0d2c Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Mon, 11 Aug 2014 13:51:55 +0800 Subject: riched20: Stub for ITextFont interface and implement diff --git a/patches/riched20-IText_Interface/0008-riched20-Stub-for-ITextPara-interface-and-implement-.patch b/patches/riched20-IText_Interface/0008-riched20-Stub-for-ITextPara-interface-and-implement-.patch index f04f70f2..22b3b79d 100644 --- a/patches/riched20-IText_Interface/0008-riched20-Stub-for-ITextPara-interface-and-implement-.patch +++ b/patches/riched20-IText_Interface/0008-riched20-Stub-for-ITextPara-interface-and-implement-.patch @@ -1,4 +1,4 @@ -From af810f9f3a3c1ffbdc0099a2eb3088e30be3a8a3 Mon Sep 17 00:00:00 2001 +From fee736f4564aadedd78a1fa8f09a6bf7caa8706c Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Sun, 10 Aug 2014 22:17:57 +0800 Subject: riched20: Stub for ITextPara interface and implement diff --git a/patches/riched20-IText_Interface/0009-riched20-Fix-ME_RunOfsFromCharOfs-when-nCharOfs-strl.patch b/patches/riched20-IText_Interface/0009-riched20-Fix-ME_RunOfsFromCharOfs-when-nCharOfs-strl.patch new file mode 100644 index 00000000..e5aea801 --- /dev/null +++ b/patches/riched20-IText_Interface/0009-riched20-Fix-ME_RunOfsFromCharOfs-when-nCharOfs-strl.patch @@ -0,0 +1,41 @@ +From 4c89684f20fd9963709307fc6419d6cbe0eacf0d Mon Sep 17 00:00:00 2001 +From: Jactry Zeng +Date: Wed, 13 Aug 2014 14:57:52 +0800 +Subject: riched20: Fix ME_RunOfsFromCharOfs() when nCharOfs > strlen(). + +--- + dlls/riched20/run.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c +index 38d0270..ad08b82 100644 +--- a/dlls/riched20/run.c ++++ b/dlls/riched20/run.c +@@ -181,9 +181,10 @@ void ME_RunOfsFromCharOfs(ME_TextEditor *editor, + int *pOfs) + { + ME_DisplayItem *item, *next_item; ++ int endOfs = nCharOfs, len = ME_GetTextLength(editor); + + nCharOfs = max(nCharOfs, 0); +- nCharOfs = min(nCharOfs, ME_GetTextLength(editor)); ++ nCharOfs = min(nCharOfs, len); + + /* Find the paragraph at the offset. */ + next_item = editor->pBuffer->pFirst->member.para.next_para; +@@ -206,7 +207,11 @@ void ME_RunOfsFromCharOfs(ME_TextEditor *editor, + nCharOfs -= item->member.run.nCharOfs; + + if (ppRun) *ppRun = item; +- if (pOfs) *pOfs = nCharOfs; ++ if (pOfs) { ++ if (((*ppRun)->member.run.nFlags & MERF_ENDPARA) && endOfs > len) ++ *pOfs = (*ppRun)->member.run.len; ++ else *pOfs = nCharOfs; ++ } + } + + /****************************************************************************** +-- +1.7.9.5 + diff --git a/patches/riched20-IText_Interface/0010-riched20-Implement-ITextRange-GetText.patch b/patches/riched20-IText_Interface/0010-riched20-Implement-ITextRange-GetText.patch new file mode 100644 index 00000000..9ef217df --- /dev/null +++ b/patches/riched20-IText_Interface/0010-riched20-Implement-ITextRange-GetText.patch @@ -0,0 +1,148 @@ +From c76f8caf18ce72f26901f4a05b0ff13b5ea38e51 Mon Sep 17 00:00:00 2001 +From: Jactry Zeng +Date: Wed, 13 Aug 2014 15:40:11 +0800 +Subject: riched20: Implement ITextRange::GetText. + +--- + dlls/riched20/richole.c | 50 ++++++++++++++++++++++++----------------- + dlls/riched20/tests/richole.c | 38 +++++++++++++++++++++++++++++++ + 2 files changed, 67 insertions(+), 21 deletions(-) + +diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c +index 241c681..8b93aad 100644 +--- a/dlls/riched20/richole.c ++++ b/dlls/riched20/richole.c +@@ -1949,14 +1949,40 @@ static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, R + return E_NOTIMPL; + } + ++static HRESULT range_GetText(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, BSTR *pbstr) ++{ ++ int nChars, endOfs; ++ BOOL bEOP; ++ ++ endOfs = ME_GetCursorOfs(end); ++ nChars = endOfs - ME_GetCursorOfs(start); ++ if (!nChars) ++ { ++ *pbstr = NULL; ++ return S_OK; ++ } ++ ++ *pbstr = SysAllocStringLen(NULL, nChars); ++ if (!*pbstr) ++ return E_OUTOFMEMORY; ++ ++ bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(editor)); ++ ME_GetTextW(editor, *pbstr, nChars, start, nChars, FALSE, bEOP); ++ TRACE("%s\n", wine_dbgstr_w(*pbstr)); ++ ++ return S_OK; ++} ++ + static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *pbstr) + { + ITextRangeImpl *This = impl_from_ITextRange(me); ++ ME_Cursor start, end; + if (!This->reOle) + return CO_E_RELEASED; + +- FIXME("not implemented %p\n", This); +- return E_NOTIMPL; ++ ME_CursorFromCharOfs(This->reOle->editor, This->start, &start); ++ ME_CursorFromCharOfs(This->reOle->editor, This->end, &end); ++ return range_GetText(This->reOle->editor, &start, &end, pbstr); + } + + static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR bstr) +@@ -3039,8 +3065,6 @@ static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) + { + ITextSelectionImpl *This = impl_from_ITextSelection(me); + ME_Cursor *start = NULL, *end = NULL; +- int nChars, endOfs; +- BOOL bEOP; + + if (!This->reOle) + return CO_E_RELEASED; +@@ -3049,23 +3073,7 @@ static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) + return E_INVALIDARG; + + ME_GetSelection(This->reOle->editor, &start, &end); +- endOfs = ME_GetCursorOfs(end); +- nChars = endOfs - ME_GetCursorOfs(start); +- if (!nChars) +- { +- *pbstr = NULL; +- return S_OK; +- } +- +- *pbstr = SysAllocStringLen(NULL, nChars); +- if (!*pbstr) +- return E_OUTOFMEMORY; +- +- bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor)); +- ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP); +- TRACE("%s\n", wine_dbgstr_w(*pbstr)); +- +- return S_OK; ++ return range_GetText(This->reOle->editor, start, end, pbstr); + } + + static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR bstr) +diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c +index f7f27d1..ae514ec 100644 +--- a/dlls/riched20/tests/richole.c ++++ b/dlls/riched20/tests/richole.c +@@ -1017,6 +1017,43 @@ static void test_ITextRange_GetPara(void) + ITextPara_Release(txtPara); + } + ++static void test_ITextRange_GetText(void) ++{ ++ HWND w; ++ IRichEditOle *reOle = NULL; ++ ITextDocument *txtDoc = NULL; ++ ITextRange *txtRge = NULL; ++ HRESULT hres; ++ BSTR bstr = NULL; ++ static const CHAR test_text1[] = "TestSomeText"; ++ static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0}; ++ static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0}; ++ static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0}; ++ static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm', ++ 'e', 'T', 'e', 'x', 't', '\r', 0}; ++ static const WCHAR bufW5[] = {'\r', 0}; ++ ++ ++#define TEST_TXTRGE_GETTEXT(first, lim, expected_string) \ ++ create_interfaces(&w, &reOle, &txtDoc, NULL); \ ++ SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); \ ++ ITextDocument_Range(txtDoc, first, lim, &txtRge); \ ++ hres = ITextRange_GetText(txtRge, &bstr); \ ++ ok(hres == S_OK, "ITextRange_GetText\n"); \ ++ ok(!lstrcmpW(bstr, expected_string), "got wrong text: %s\n", wine_dbgstr_w(bstr)); \ ++ SysFreeString(bstr); \ ++ ITextRange_Release(txtRge); \ ++ release_interfaces(&w, &reOle, &txtDoc, NULL); ++ ++ TEST_TXTRGE_GETTEXT(0, 4, bufW1) ++ TEST_TXTRGE_GETTEXT(4, 0, bufW1) ++ TEST_TXTRGE_GETTEXT(8, 12, bufW3) ++ TEST_TXTRGE_GETTEXT(8, 13, bufW2) ++ TEST_TXTRGE_GETTEXT(12, 13, bufW5) ++ TEST_TXTRGE_GETTEXT(0, 13, bufW4) ++ TEST_TXTRGE_GETTEXT(1, 1, NULL) ++} ++ + START_TEST(richole) + { + /* Must explicitly LoadLibrary(). The test has no references to functions in +@@ -1041,4 +1078,5 @@ START_TEST(richole) + test_ITextRange_SetEnd(); + test_ITextRange_GetFont(); + test_ITextRange_GetPara(); ++ test_ITextRange_GetText(); + } +-- +1.7.9.5 + diff --git a/patches/riched20-IText_Interface/0011-riched20-Implement-ITextRange-SetRange.patch b/patches/riched20-IText_Interface/0011-riched20-Implement-ITextRange-SetRange.patch new file mode 100644 index 00000000..ecd3a1a6 --- /dev/null +++ b/patches/riched20-IText_Interface/0011-riched20-Implement-ITextRange-SetRange.patch @@ -0,0 +1,134 @@ +From 8403ff90bb26c427c34beb7094d1dbf61e56102f Mon Sep 17 00:00:00 2001 +From: Jactry Zeng +Date: Wed, 13 Aug 2014 17:17:14 +0800 +Subject: riched20: Implement ITextRange::SetRange. + +--- + dlls/riched20/richole.c | 41 +++++++++++++++++++++++++---------------- + dlls/riched20/tests/richole.c | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 60 insertions(+), 16 deletions(-) + +diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c +index 8b93aad..98f1b1e 100644 +--- a/dlls/riched20/richole.c ++++ b/dlls/riched20/richole.c +@@ -2311,14 +2311,36 @@ static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG Unit, LONG Inde + return E_NOTIMPL; + } + ++static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2) ++{ ++ int len = ME_GetTextLength(editor) + 1; ++ *cp1 = max(*cp1, 0); ++ *cp2 = max(*cp2, 0); ++ *cp1 = min(*cp1, len); ++ *cp2 = min(*cp2, len); ++ if (*cp1 > *cp2) ++ { ++ int tmp = *cp1; ++ *cp1 = *cp2; ++ *cp2 = tmp; ++ } ++ if (*cp1 == len) ++ *cp1 = *cp2 = len - 1; ++} ++ + static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG cpActive, LONG cpOther) + { + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + +- FIXME("not implemented %p\n", This); +- return E_NOTIMPL; ++ cp2range(This->reOle->editor, &cpActive, &cpOther); ++ if (cpActive == This->start && cpOther == This->end) ++ return S_FALSE; ++ ++ This->start = cpActive; ++ This->end = cpOther; ++ return S_OK; + } + + static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *pRange, LONG *pb) +@@ -2911,25 +2933,12 @@ ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2, + { + IRichEditOleImpl *This = impl_from_ITextDocument(me); + ITextRangeImpl *txtRge = NULL; +- const int len = ME_GetTextLength(This->editor) + 1; + + TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2); + if (!ppRange) + return E_INVALIDARG; + +- cp1 = max(cp1, 0); +- cp2 = max(cp2, 0); +- cp1 = min(cp1, len); +- cp2 = min(cp2, len); +- if (cp1 > cp2) +- { +- LONG tmp; +- tmp = cp1; +- cp1 = cp2; +- cp2 = tmp; +- } +- if (cp1 == len) +- cp1 = cp2 = len - 1; ++ cp2range(This->editor, &cp1, &cp2); + txtRge = heap_alloc(sizeof(ITextRangeImpl)); + if (!txtRge) + return E_OUTOFMEMORY; +diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c +index ae514ec..6c7c15d 100644 +--- a/dlls/riched20/tests/richole.c ++++ b/dlls/riched20/tests/richole.c +@@ -1054,6 +1054,40 @@ static void test_ITextRange_GetText(void) + TEST_TXTRGE_GETTEXT(1, 1, NULL) + } + ++static void test_ITextRange_SetRange(void) ++{ ++ HWND w; ++ IRichEditOle *reOle = NULL; ++ ITextDocument *txtDoc = NULL; ++ ITextRange *txtRge = NULL; ++ HRESULT hres; ++ int start, end; ++ static const CHAR test_text1[] = "TestSomeText"; ++ ++ create_interfaces(&w, &reOle, &txtDoc, NULL); ++ SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); ++ ITextDocument_Range(txtDoc, 0, 0, &txtRge); ++ ++#define TEST_TXTRGE_SETRANGE(first, lim, expected_start, expected_end, expected_return) \ ++ hres = ITextRange_SetRange(txtRge, first, lim); \ ++ ok(hres == expected_return, "ITextRange_SetRange\n"); \ ++ ITextRange_GetStart(txtRge, &start); \ ++ ITextRange_GetEnd(txtRge, &end); \ ++ ok(start == expected_start, "got wrong start value: %d\n", start); \ ++ ok(end == expected_end, "got wrong end value: %d\n", end); ++ ++ TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_OK) ++ TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_FALSE) ++ TEST_TXTRGE_SETRANGE(4, 2, 2, 4, S_FALSE) ++ TEST_TXTRGE_SETRANGE(14, 14, 12, 12, S_OK) ++ TEST_TXTRGE_SETRANGE(15, 15, 12, 12, S_FALSE) ++ TEST_TXTRGE_SETRANGE(14, 1, 1, 13, S_OK) ++ TEST_TXTRGE_SETRANGE(-1, 4, 0, 4, S_OK) ++ ++ ITextRange_Release(txtRge); ++ release_interfaces(&w, &reOle, &txtDoc, NULL); ++} ++ + START_TEST(richole) + { + /* Must explicitly LoadLibrary(). The test has no references to functions in +@@ -1079,4 +1113,5 @@ START_TEST(richole) + test_ITextRange_GetFont(); + test_ITextRange_GetPara(); + test_ITextRange_GetText(); ++ test_ITextRange_SetRange(); + } +-- +1.7.9.5 + diff --git a/patches/riched20-IText_Interface/0012-riched20-Implement-ITextRange-IsEqual.patch b/patches/riched20-IText_Interface/0012-riched20-Implement-ITextRange-IsEqual.patch new file mode 100644 index 00000000..81eccd4b --- /dev/null +++ b/patches/riched20-IText_Interface/0012-riched20-Implement-ITextRange-IsEqual.patch @@ -0,0 +1,112 @@ +From e17c9f4954b364347ef6b5eb258ec66f50362db6 Mon Sep 17 00:00:00 2001 +From: Jactry Zeng +Date: Fri, 15 Aug 2014 14:27:21 +0800 +Subject: riched20: Implement ITextRange::IsEqual. + +--- + dlls/riched20/richole.c | 19 +++++++++++++++-- + dlls/riched20/tests/richole.c | 47 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 64 insertions(+), 2 deletions(-) + +diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c +index 98f1b1e..47ad0f9 100644 +--- a/dlls/riched20/richole.c ++++ b/dlls/riched20/richole.c +@@ -2363,14 +2363,29 @@ static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, L + return E_NOTIMPL; + } + ++static HRESULT range_IsEqual(LONG start, LONG end, ITextRange *pRange, LONG *pb) ++{ ++ ITextRangeImpl *pRangeImpl = impl_from_ITextRange(pRange); ++ if (start == pRangeImpl->start && end == pRangeImpl->end) ++ { ++ if (pb) ++ *pb = tomTrue; ++ return S_OK; ++ } ++ if (pb) ++ *pb = tomFalse; ++ return S_FALSE; ++} ++ + static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *pRange, LONG *pb) + { + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + +- FIXME("not implemented %p\n", This); +- return E_NOTIMPL; ++ if (!pRange) ++ return S_FALSE; ++ return range_IsEqual(This->start, This->end, pRange, pb); + } + + static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me) +diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c +index 6c7c15d..6642ca3 100644 +--- a/dlls/riched20/tests/richole.c ++++ b/dlls/riched20/tests/richole.c +@@ -1088,6 +1088,52 @@ static void test_ITextRange_SetRange(void) + release_interfaces(&w, &reOle, &txtDoc, NULL); + } + ++static void test_ITextRange_IsEqual(void) ++{ ++ HWND w; ++ IRichEditOle *reOle = NULL; ++ ITextDocument *txtDoc = NULL; ++ ITextRange *txtRge1 = NULL, *txtRge2 = NULL; ++ HRESULT hres; ++ static const CHAR test_text1[] = "TestSomeText"; ++ LONG res; ++ ++ create_interfaces(&w, &reOle, &txtDoc, NULL); ++ SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); ++ ITextDocument_Range(txtDoc, 2, 4, &txtRge1); ++ ITextDocument_Range(txtDoc, 2, 4, &txtRge2); ++ ++#define TEST_TXTRGE_ISEQUAL(expected_hres, expected_res) \ ++ hres = ITextRange_IsEqual(txtRge1, txtRge2, &res); \ ++ ok(hres == expected_hres, "ITextRange_IsEqual\n"); \ ++ ok(res == expected_res, "got wrong return value: %d\n", res); ++ ++ TEST_TXTRGE_ISEQUAL(S_OK, tomTrue) ++ ITextRange_SetRange(txtRge2, 1, 2); ++ TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse) ++ ++ ITextRange_SetRange(txtRge1, 1, 1); ++ ITextRange_SetRange(txtRge2, 2, 2); ++ TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse) ++ ++ ITextRange_SetRange(txtRge2, 1, 1); ++ TEST_TXTRGE_ISEQUAL(S_OK, tomTrue) ++ ++ hres = ITextRange_IsEqual(txtRge1, txtRge1, &res); ++ ok(hres == S_OK, "ITextRange_IsEqual\n"); ++ ok(res == tomTrue, "got wrong return value: %d\n", res); ++ ++ hres = ITextRange_IsEqual(txtRge1, txtRge2, NULL); ++ ok(hres == S_OK, "ITextRange_IsEqual\n"); ++ ++ hres = ITextRange_IsEqual(txtRge1, NULL, NULL); ++ ok(hres == S_FALSE, "ITextRange_IsEqual\n"); ++ ++ ITextRange_Release(txtRge1); ++ ITextRange_Release(txtRge2); ++ release_interfaces(&w, &reOle, &txtDoc, NULL); ++} ++ + START_TEST(richole) + { + /* Must explicitly LoadLibrary(). The test has no references to functions in +@@ -1114,4 +1160,5 @@ START_TEST(richole) + test_ITextRange_GetPara(); + test_ITextRange_GetText(); + test_ITextRange_SetRange(); ++ test_ITextRange_IsEqual(); + } +-- +1.7.9.5 + diff --git a/patches/riched20-IText_Interface/0013-riched20-Implement-ITextRange-GetStoryLength.patch b/patches/riched20-IText_Interface/0013-riched20-Implement-ITextRange-GetStoryLength.patch new file mode 100644 index 00000000..e1a7ecf6 --- /dev/null +++ b/patches/riched20-IText_Interface/0013-riched20-Implement-ITextRange-GetStoryLength.patch @@ -0,0 +1,78 @@ +From 7c46ccadf6492585c2a2cd3fc9f06ab960fe30f4 Mon Sep 17 00:00:00 2001 +From: Jactry Zeng +Date: Mon, 18 Aug 2014 14:38:50 +0800 +Subject: riched20: Implement ITextRange::GetStoryLength. + +--- + dlls/riched20/richole.c | 6 ++++-- + dlls/riched20/tests/richole.c | 32 ++++++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c +index 47ad0f9..1af7804 100644 +--- a/dlls/riched20/richole.c ++++ b/dlls/riched20/richole.c +@@ -2244,8 +2244,10 @@ static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *pcch) + if (!This->reOle) + return CO_E_RELEASED; + +- FIXME("not implemented %p\n", This); +- return E_NOTIMPL; ++ if (!pcch) ++ return E_INVALIDARG; ++ *pcch = ME_GetTextLength(This->reOle->editor) + 1; ++ return S_OK; + } + + static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *pValue) +diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c +index 6642ca3..c4f58fd 100644 +--- a/dlls/riched20/tests/richole.c ++++ b/dlls/riched20/tests/richole.c +@@ -1134,6 +1134,37 @@ static void test_ITextRange_IsEqual(void) + release_interfaces(&w, &reOle, &txtDoc, NULL); + } + ++static void test_ITextRange_GetStoryLength(void) ++{ ++ HWND w; ++ IRichEditOle *reOle = NULL; ++ ITextDocument *txtDoc = NULL; ++ ITextRange *txtRge = NULL; ++ HRESULT hres; ++ LONG count; ++ static const CHAR test_text1[] = "TestSomeText"; ++ int len = strlen(test_text1) + 1; ++ ++ create_interfaces(&w, &reOle, &txtDoc, NULL); ++ SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); ++ ITextDocument_Range(txtDoc, 0, 0, &txtRge); ++ ++ hres = ITextRange_GetStoryLength(txtRge, &count); ++ ok(hres == S_OK, "ITextRange_GetStoryLength\n"); ++ ok(count == len, "got wrong length: %d\n", count); ++ ++ ITextRange_SetRange(txtRge, 1, 2); ++ hres = ITextRange_GetStoryLength(txtRge, &count); ++ ok(hres == S_OK, "ITextRange_GetStoryLength\n"); ++ ok(count == len, "got wrong length: %d\n", count); ++ ++ hres = ITextRange_GetStoryLength(txtRge, NULL); ++ ok(hres == E_INVALIDARG, "ITextRange_GetStoryLength\n"); ++ ++ ITextRange_Release(txtRge); ++ release_interfaces(&w, &reOle, &txtDoc, NULL); ++} ++ + START_TEST(richole) + { + /* Must explicitly LoadLibrary(). The test has no references to functions in +@@ -1161,4 +1192,5 @@ START_TEST(richole) + test_ITextRange_GetText(); + test_ITextRange_SetRange(); + test_ITextRange_IsEqual(); ++ test_ITextRange_GetStoryLength(); + } +-- +1.7.9.5 + diff --git a/patches/riched20-IText_Interface/0014-riched20-Implement-ITextSelection-GetStoryLength.patch b/patches/riched20-IText_Interface/0014-riched20-Implement-ITextSelection-GetStoryLength.patch new file mode 100644 index 00000000..f2f08785 --- /dev/null +++ b/patches/riched20-IText_Interface/0014-riched20-Implement-ITextSelection-GetStoryLength.patch @@ -0,0 +1,78 @@ +From f9427d23ca1d7fac8f561fa8ed2563ea187451f4 Mon Sep 17 00:00:00 2001 +From: Jactry Zeng +Date: Mon, 18 Aug 2014 14:47:14 +0800 +Subject: riched20: Implement ITextSelection::GetStoryLength. + +--- + dlls/riched20/richole.c | 6 ++++-- + dlls/riched20/tests/richole.c | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c +index 1af7804..ed70b8d 100644 +--- a/dlls/riched20/richole.c ++++ b/dlls/riched20/richole.c +@@ -3284,8 +3284,10 @@ static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG * + if (!This->reOle) + return CO_E_RELEASED; + +- FIXME("not implemented\n"); +- return E_NOTIMPL; ++ if (!pcch) ++ return E_INVALIDARG; ++ *pcch = ME_GetTextLength(This->reOle->editor) + 1; ++ return S_OK; + } + + static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *pValue) +diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c +index c4f58fd..a14f88b 100644 +--- a/dlls/riched20/tests/richole.c ++++ b/dlls/riched20/tests/richole.c +@@ -1165,6 +1165,35 @@ static void test_ITextRange_GetStoryLength(void) + release_interfaces(&w, &reOle, &txtDoc, NULL); + } + ++static void test_ITextSelection_GetStoryLength(void) ++{ ++ HWND w; ++ IRichEditOle *reOle = NULL; ++ ITextDocument *txtDoc = NULL; ++ ITextSelection *txtSel = NULL; ++ HRESULT hres; ++ LONG count; ++ static const CHAR test_text1[] = "TestSomeText"; ++ int len = strlen(test_text1) + 1; ++ ++ create_interfaces(&w, &reOle, &txtDoc, &txtSel); ++ SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); ++ ++ hres = ITextSelection_GetStoryLength(txtSel, &count); ++ ok(hres == S_OK, "ITextSelection_GetStoryLength\n"); ++ ok(count == len, "got wrong length: %d\n", count); ++ ++ SendMessageA(w, EM_SETSEL, 1, 2); ++ hres = ITextSelection_GetStoryLength(txtSel, &count); ++ ok(hres == S_OK, "ITextSelection_GetStoryLength\n"); ++ ok(count == len, "got wrong length: %d\n", count); ++ ++ hres = ITextSelection_GetStoryLength(txtSel, NULL); ++ ok(hres == E_INVALIDARG, "ITextSelection_GetStoryLength\n"); ++ ++ release_interfaces(&w, &reOle, &txtDoc, &txtSel); ++} ++ + START_TEST(richole) + { + /* Must explicitly LoadLibrary(). The test has no references to functions in +@@ -1180,6 +1209,7 @@ START_TEST(richole) + test_ITextSelection_SetEnd(); + test_ITextSelection_Collapse(); + test_ITextSelection_GetFont(); ++ test_ITextSelection_GetStoryLength(); + test_ITextDocument_Range(); + test_ITextRange_GetChar(); + test_ITextRange_GetDuplicate(); +-- +1.7.9.5 + diff --git a/patches/riched20-IText_Interface/definition b/patches/riched20-IText_Interface/definition index 9a3ade3a..356e7dab 100644 --- a/patches/riched20-IText_Interface/definition +++ b/patches/riched20-IText_Interface/definition @@ -2,10 +2,6 @@ Author: Jactry Zeng Subject: Implement Stubs for ITextRange interface. Revision: 3 -Author: Jactry Zeng -Subject: Implement IText{Range,Selection}::{GetChar,GetStart,GetEnd,GetDuplicate,Collapse,SetStart,SetEnd}. -Revision: 1 - Author: Jactry Zeng Subject: Implement Stubs for ITextFont interface. Revision: 2 @@ -14,5 +10,13 @@ Author: Jactry Zeng Subject: Implement Stubs for ITextPara interface. Revision: 2 +Author: Jactry Zeng +Subject: Implement ITextRange/Selection::{GetChar,GetStart,GetEnd,GetDuplicate,Collapse,SetStart,SetEnd}. +Revision: 1 + +Author: Jactry Zeng +Subject: Implement ITextRange/Selection::{GetText,SetRange,IsEqual,GetStoryLength}. +Revision: 1 + Fixes: [12458] Support for ITextDocument_fnRange function Fixes: [18303] Support for ITextRange, ITextFont and ITextPara diff --git a/patches/server-CreateProcess_ACLs/0001-server-A-new-function-set_sd_defaults_from_token-tha.patch b/patches/server-CreateProcess_ACLs/0001-server-A-new-function-set_sd_defaults_from_token-tha.patch index 682c7376..b5ef7224 100644 --- a/patches/server-CreateProcess_ACLs/0001-server-A-new-function-set_sd_defaults_from_token-tha.patch +++ b/patches/server-CreateProcess_ACLs/0001-server-A-new-function-set_sd_defaults_from_token-tha.patch @@ -1,14 +1,10 @@ -From 30c44423ffde37855f0fd468096aa5fc6aa14912 Mon Sep 17 00:00:00 2001 +From 99fa68f60166b3064371eb8ef68fcb3d733a28dc Mon Sep 17 00:00:00 2001 From: Joris van der Wel Date: Sun, 3 Aug 2014 12:52:06 +0200 Subject: server: A new function "set_sd_defaults_from_token" that sets the security descriptor along with a token that will be used to gather defaults, instead of always using the primary token. (try 4) -server: A new function "set_sd_defaults_from_token" that sets the - security descriptor along with a token that will be used to gather defaults, - instead of always using the primary token. - Some objects take their defaults not from a primary token but from a different one (such as from the impersonation token or the process token). @@ -23,7 +19,7 @@ defaults _only_ upon creation. 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/server/object.c b/server/object.c -index 133c6b5..ec196c1 100644 +index 11ef0ce..6389409 100644 --- a/server/object.c +++ b/server/object.c @@ -423,8 +423,8 @@ struct security_descriptor *default_get_sd( struct object *obj ) @@ -88,14 +84,14 @@ index 133c6b5..ec196c1 100644 unsigned int attr ) { diff --git a/server/object.h b/server/object.h -index bb3ff21..7201ff9 100644 +index bb3ff21..dd93b76e 100644 --- a/server/object.h +++ b/server/object.h @@ -139,6 +139,8 @@ extern struct fd *no_get_fd( struct object *obj ); extern unsigned int no_map_access( struct object *obj, unsigned int access ); extern struct security_descriptor *default_get_sd( struct object *obj ); extern int default_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info ); -+extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd, ++extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd, + unsigned int set_info, struct token *token ); extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes ); extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing, diff --git a/patches/server-CreateProcess_ACLs/0002-server-Support-sending-process-and-thread-security-d.patch b/patches/server-CreateProcess_ACLs/0002-server-Support-sending-process-and-thread-security-d.patch deleted file mode 100644 index 471d5441..00000000 --- a/patches/server-CreateProcess_ACLs/0002-server-Support-sending-process-and-thread-security-d.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 7c1b44caf023c4120b48a2792a442ca5ac1e3166 Mon Sep 17 00:00:00 2001 -From: Joris van der Wel -Date: Sun, 3 Aug 2014 12:52:14 +0200 -Subject: server: Support sending process and thread security descriptors for - the "new_process" request in the protocol - -server: Support sending process and thread security descriptors for - the "new_process" request in the protocol. ---- - dlls/kernel32/process.c | 2 ++ - server/process.c | 44 ++++++++++++++++++++++++++++++-------------- - server/protocol.def | 4 ++++ - 3 files changed, 36 insertions(+), 14 deletions(-) - -diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c -index 2566ac4..efd0e84 100644 ---- a/dlls/kernel32/process.c -+++ b/dlls/kernel32/process.c -@@ -2034,6 +2034,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - req->thread_access = THREAD_ALL_ACCESS; - req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0; - req->cpu = cpu; -+ req->process_sd_size= 0; -+ req->thread_sd_size = 0; - req->info_size = startup_info_size; - - wine_server_add_data( req, startup_info, startup_info_size ); -diff --git a/server/process.c b/server/process.c -index 7b9a3b2..110a38f 100644 ---- a/server/process.c -+++ b/server/process.c -@@ -880,6 +880,24 @@ DECL_HANDLER(new_process) - struct process *process; - struct process *parent = current->process; - int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); -+ const startup_info_t *req_info; -+ data_size_t req_info_size; -+ const WCHAR *req_env; -+ data_size_t req_env_size; -+ -+ if (req->process_sd_size > get_req_data_size() || -+ req->thread_sd_size > get_req_data_size() - req->process_sd_size || -+ req->info_size > get_req_data_size() - req->process_sd_size - req->thread_sd_size) -+ { -+ close( socket_fd ); -+ return; -+ } -+ -+ req_info = (const startup_info_t *) -+ ((char*)get_req_data() + req->process_sd_size + req->thread_sd_size); -+ req_env = (const WCHAR *) -+ ((char*)get_req_data() + req->process_sd_size + req->thread_sd_size + req->info_size); -+ req_env_size = get_req_data_size() - (req->process_sd_size + req->thread_sd_size + req->info_size); - - if (socket_fd == -1) - { -@@ -920,27 +938,25 @@ DECL_HANDLER(new_process) - !(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA ))) - goto done; - -- info->data_size = get_req_data_size(); -- info->info_size = min( req->info_size, info->data_size ); -- - if (req->info_size < sizeof(*info->data)) - { - /* make sure we have a full startup_info_t structure */ -- data_size_t env_size = info->data_size - info->info_size; -- data_size_t info_size = min( req->info_size, FIELD_OFFSET( startup_info_t, curdir_len )); -- -- if (!(info->data = mem_alloc( sizeof(*info->data) + env_size ))) goto done; -- memcpy( info->data, get_req_data(), info_size ); -- memset( (char *)info->data + info_size, 0, sizeof(*info->data) - info_size ); -- memcpy( info->data + 1, (const char *)get_req_data() + req->info_size, env_size ); -- info->info_size = sizeof(startup_info_t); -- info->data_size = info->info_size + env_size; -+ info->info_size = sizeof(*info->data); -+ info->data_size = sizeof(*info->data) + req_env_size; -+ -+ req_info_size = min( req->info_size, FIELD_OFFSET( startup_info_t, curdir_len )); -+ if (!(info->data = mem_alloc( info->data_size ))) goto done; -+ memset( info->data, 0, info->data_size ); -+ memcpy( info->data, req_info, req_info_size ); -+ memcpy( info->data + 1, req_env, req_env_size ); - } - else - { - data_size_t pos = sizeof(*info->data); -- -- if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done; -+ info->info_size = req->info_size; -+ info->data_size = req->info_size + req_env_size; -+ -+ if (!(info->data = memdup( req_info, info->data_size ))) goto done; - #define FIXUP_LEN(len) do { (len) = min( (len), info->info_size - pos ); pos += (len); } while(0) - FIXUP_LEN( info->data->curdir_len ); - FIXUP_LEN( info->data->dllpath_len ); -diff --git a/server/protocol.def b/server/protocol.def -index a8c1fb9..d2cfd71 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -670,7 +670,11 @@ struct rawinput_device - unsigned int thread_access; /* access rights for thread object */ - unsigned int thread_attr; /* attributes for thread object */ - cpu_type_t cpu; /* CPU that the new process will use */ -+ data_size_t process_sd_size;/* size of the process security descriptor */ -+ data_size_t thread_sd_size; /* size of the thread security descriptor */ - data_size_t info_size; /* size of startup info */ -+ VARARG(process_sd,security_descriptor,process_sd_size); /* security descriptor to set on the process */ -+ VARARG(thread_sd,security_descriptor,thread_sd_size); /* security descriptor to set on the thread */ - VARARG(info,startup_info,info_size); /* startup information */ - VARARG(env,unicode_str); /* environment for new process */ - @REPLY --- -1.7.9.5 - diff --git a/patches/server-CreateProcess_ACLs/0002-server-Support-sending-thread-and-process-security-d.patch b/patches/server-CreateProcess_ACLs/0002-server-Support-sending-thread-and-process-security-d.patch new file mode 100644 index 00000000..51048201 --- /dev/null +++ b/patches/server-CreateProcess_ACLs/0002-server-Support-sending-thread-and-process-security-d.patch @@ -0,0 +1,128 @@ +From 9a9b0d8a21af0e88e1a0af4f32bcf10fabad3e5a Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 23 Aug 2014 05:58:30 +0200 +Subject: server: Support sending thread and process security descriptors in + new_process wineserver call. + +Based on a patch by Joris van der Wel. The original patch was removed since it contained several mistakes in validating untrusted length arguments. +--- + dlls/kernel32/process.c | 2 ++ + server/process.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- + server/protocol.def | 6 +++++- + 3 files changed, 55 insertions(+), 2 deletions(-) + +diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c +index 301c64a..5de8b59 100644 +--- a/dlls/kernel32/process.c ++++ b/dlls/kernel32/process.c +@@ -2035,6 +2035,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW + req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0; + req->cpu = cpu; + req->info_size = startup_info_size; ++ req->env_size = (env_end - env) * sizeof(WCHAR); ++ req->process_sd_size = 0; + + wine_server_add_data( req, startup_info, startup_info_size ); + wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) ); +diff --git a/server/process.c b/server/process.c +index 7b9a3b2..426bcca 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -880,6 +880,7 @@ DECL_HANDLER(new_process) + struct process *process; + struct process *parent = current->process; + int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); ++ const struct security_descriptor *process_sd = NULL, *thread_sd = NULL; + + if (socket_fd == -1) + { +@@ -920,7 +921,7 @@ DECL_HANDLER(new_process) + !(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA ))) + goto done; + +- info->data_size = get_req_data_size(); ++ info->data_size = min( get_req_data_size(), req->info_size + req->env_size ); + info->info_size = min( req->info_size, info->data_size ); + + if (req->info_size < sizeof(*info->data)) +@@ -953,6 +954,31 @@ DECL_HANDLER(new_process) + #undef FIXUP_LEN + } + ++ /* validate security descriptors (if any) */ ++ if (get_req_data_size() > req->info_size + req->env_size) ++ { ++ data_size_t sd_size, pos = req->info_size + req->env_size; ++ if ((sd_size = min( get_req_data_size() - pos, req->process_sd_size ))) ++ { ++ process_sd = (const struct security_descriptor *)((const char *)get_req_data() + pos); ++ if (!sd_is_valid( process_sd, sd_size )) ++ { ++ set_error( STATUS_INVALID_SECURITY_DESCR ); ++ goto done; ++ } ++ pos += sd_size; ++ } ++ if ((sd_size = get_req_data_size() - pos)) ++ { ++ thread_sd = (const struct security_descriptor *)((const char *)get_req_data() + pos); ++ if (!sd_is_valid( thread_sd, sd_size )) ++ { ++ set_error( STATUS_INVALID_SECURITY_DESCR ); ++ goto done; ++ } ++ } ++ } ++ + if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done; + process = thread->process; + process->debug_children = (req->create_flags & DEBUG_PROCESS) +@@ -1004,6 +1030,27 @@ DECL_HANDLER(new_process) + reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr ); + reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr ); + ++ if (process_sd) ++ { ++ default_set_sd( &process->obj, ++ process_sd, ++ OWNER_SECURITY_INFORMATION | ++ GROUP_SECURITY_INFORMATION | ++ DACL_SECURITY_INFORMATION | ++ SACL_SECURITY_INFORMATION ); ++ } ++ ++ if (thread_sd) ++ { ++ set_sd_defaults_from_token( &thread->obj, ++ thread_sd, ++ OWNER_SECURITY_INFORMATION | ++ GROUP_SECURITY_INFORMATION | ++ DACL_SECURITY_INFORMATION | ++ SACL_SECURITY_INFORMATION, ++ process->token ); ++ } ++ + done: + release_object( info ); + } +diff --git a/server/protocol.def b/server/protocol.def +index c9270ea..3f75375 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -671,8 +671,12 @@ struct rawinput_device + unsigned int thread_attr; /* attributes for thread object */ + cpu_type_t cpu; /* CPU that the new process will use */ + data_size_t info_size; /* size of startup info */ ++ data_size_t env_size; /* size of the environment */ ++ data_size_t process_sd_size;/* size of the process security descriptor */ + VARARG(info,startup_info,info_size); /* startup information */ +- VARARG(env,unicode_str); /* environment for new process */ ++ VARARG(env,unicode_str,env_size); /* environment for new process */ ++ VARARG(process_sd,security_descriptor,process_sd_size); /* security descriptor to set on the process */ ++ VARARG(thread_sd,security_descriptor); /* security descriptor to set on the thread */ + @REPLY + obj_handle_t info; /* new process info handle */ + process_id_t pid; /* process id */ +-- +1.7.9.5 + diff --git a/patches/server-CreateProcess_ACLs/0003-server-implement-passing-a-process-security-descript.patch b/patches/server-CreateProcess_ACLs/0003-kernel32-Implement-passing-a-process-security-descri.patch similarity index 54% rename from patches/server-CreateProcess_ACLs/0003-server-implement-passing-a-process-security-descript.patch rename to patches/server-CreateProcess_ACLs/0003-kernel32-Implement-passing-a-process-security-descri.patch index b5e8491a..13843792 100644 --- a/patches/server-CreateProcess_ACLs/0003-server-implement-passing-a-process-security-descript.patch +++ b/patches/server-CreateProcess_ACLs/0003-kernel32-Implement-passing-a-process-security-descri.patch @@ -1,23 +1,14 @@ -From 43eb6734382c298997573522244de3daf3a52a78 Mon Sep 17 00:00:00 2001 -From: Joris van der Wel -Date: Sun, 3 Aug 2014 12:52:32 +0200 -Subject: server: implement passing a process security descriptor to - CreateProcess +From bcf14e35900209c3177b76ae9b1e368aa12d58e6 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 23 Aug 2014 06:27:28 +0200 +Subject: kernel32: Implement passing a process security descriptor from + CreateProcess to the wineserver. -server: implement passing a process security descriptor to CreateProcess. - -For now the function "NTDLL_create_struct_sd" has been duplicated in -kernel32. This is needed because kernel32 makes the server call. -Kernel32 currently makes the server call because NtCreateProcess(Ex) -has not been implemented in ntdll. When NtCreateProcessEx (and -NtCreateThreadEx) gets implemented, -the server call will be made from within ntdll instead, and this extra -function in kernel32 will no longer be needed. +Based on a patch by Joris van der Wel. --- dlls/advapi32/tests/security.c | 3 -- - dlls/kernel32/process.c | 85 +++++++++++++++++++++++++++++++++++++++- - server/process.c | 24 ++++++++++++ - 3 files changed, 108 insertions(+), 4 deletions(-) + dlls/kernel32/process.c | 102 +++++++++++++++++++++++++++++++++++++++- + 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index b44496a..b1b35aa 100644 @@ -43,7 +34,7 @@ index b44496a..b1b35aa 100644 /* Documented privilege elevation */ diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c -index efd0e84..44e7711 100644 +index 5de8b59..7d28140 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1916,6 +1916,70 @@ static pid_t exec_loader( LPCWSTR cmd_line, unsigned int flags, int socketfd, @@ -117,125 +108,81 @@ index efd0e84..44e7711 100644 /*********************************************************************** * create_process * -@@ -1939,17 +2003,31 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW +@@ -1939,6 +2003,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW int socketfd[2], stdin_fd = -1, stdout_fd = -1; pid_t pid; int err, cpu; -+ struct security_descriptor *psd = NULL; -+ data_size_t psd_len = 0; ++ struct security_descriptor *process_sd = NULL, *thread_sd = NULL; ++ data_size_t process_sd_size = 0, thread_sd_size = 0; if ((cpu = get_process_cpu( filename, binary_info )) == -1) { - SetLastError( ERROR_BAD_EXE_FORMAT ); +@@ -1993,12 +2059,41 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW return FALSE; } -+ -+ if (psa && (psa->nLength >= sizeof(*psa)) && psa->lpSecurityDescriptor) + ++ if (psa && (psa->nLength >= sizeof(*psa))) + { -+ status = create_struct_sd( psa->lpSecurityDescriptor, &psd, &psd_len ); ++ status = create_struct_sd( psa->lpSecurityDescriptor, &process_sd, &process_sd_size ); + if (status != STATUS_SUCCESS) + { -+ WARN("Invalid process security descriptor with status %x\n", status); ++ close( socketfd[0] ); ++ close( socketfd[1] ); ++ WARN("Invalid process security descriptor: Status %x\n", status); + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } -+ } - - /* create the socket for the new process */ - - if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1) - { -+ RtlFreeHeap(GetProcessHeap(), 0, psd); - SetLastError( ERROR_TOO_MANY_OPEN_FILES ); - return FALSE; - } -@@ -1989,6 +2067,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - winedebug, binary_info, TRUE ); - } - close( socketfd[0] ); -+ RtlFreeHeap(GetProcessHeap(), 0, psd); - SetLastError( RtlNtStatusToDosError( status )); - return FALSE; - } -@@ -2001,6 +2080,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - RtlReleasePebLock(); - close( socketfd[0] ); - close( socketfd[1] ); -+ RtlFreeHeap(GetProcessHeap(), 0, psd); - return FALSE; - } - if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment; -@@ -2034,10 +2114,11 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - req->thread_access = THREAD_ALL_ACCESS; - req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0; - req->cpu = cpu; -- req->process_sd_size= 0; -+ req->process_sd_size= psd_len; - req->thread_sd_size = 0; - req->info_size = startup_info_size; - -+ wine_server_add_data( req, psd, psd_len ); - wine_server_add_data( req, startup_info, startup_info_size ); - wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) ); - if (!(status = wine_server_call( req ))) -@@ -2051,6 +2132,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - } - SERVER_END_REQ; - -+ RtlFreeHeap(GetProcessHeap(), 0, psd); ++ } + - RtlReleasePebLock(); - if (status) - { -diff --git a/server/process.c b/server/process.c -index 110a38f..571f05a 100644 ---- a/server/process.c -+++ b/server/process.c -@@ -880,6 +880,7 @@ DECL_HANDLER(new_process) - struct process *process; - struct process *parent = current->process; - int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); -+ const struct security_descriptor *req_psd = NULL; - const startup_info_t *req_info; - data_size_t req_info_size; - const WCHAR *req_env; -@@ -892,6 +893,16 @@ DECL_HANDLER(new_process) - close( socket_fd ); - return; - } -+ -+ if (req->process_sd_size) ++ if (tsa && (tsa->nLength >= sizeof(*tsa))) + { -+ req_psd = get_req_data(); -+ if (!sd_is_valid( req_psd, req->process_sd_size )) ++ status = create_struct_sd( tsa->lpSecurityDescriptor, &thread_sd, &thread_sd_size ); ++ if (status != STATUS_SUCCESS) + { -+ set_error( STATUS_INVALID_SECURITY_DESCR ); -+ return; ++ RtlFreeHeap(GetProcessHeap(), 0, process_sd); ++ close( socketfd[0] ); ++ close( socketfd[1] ); ++ WARN("Invalid thread security descriptor: Status %x\n", status); ++ SetLastError( RtlNtStatusToDosError(status) ); ++ return FALSE; + } -+ } - - req_info = (const startup_info_t *) - ((char*)get_req_data() + req->process_sd_size + req->thread_sd_size); -@@ -1020,6 +1031,19 @@ DECL_HANDLER(new_process) - reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr ); - reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr ); - -+ /* note: alloc_handle might fail with access denied -+ * if the security descriptor is set before that call */ -+ -+ if (req_psd) -+ { -+ default_set_sd( &process->obj, -+ req_psd, -+ OWNER_SECURITY_INFORMATION| -+ GROUP_SECURITY_INFORMATION| -+ DACL_SECURITY_INFORMATION| -+ SACL_SECURITY_INFORMATION ); + } + - done: - release_object( info ); - } + RtlAcquirePebLock(); + + if (!(startup_info = create_startup_info( filename, cmd_line, cur_dir, env, flags, startup, + &startup_info_size ))) + { + RtlReleasePebLock(); ++ RtlFreeHeap(GetProcessHeap(), 0, process_sd); ++ RtlFreeHeap(GetProcessHeap(), 0, thread_sd); + close( socketfd[0] ); + close( socketfd[1] ); + return FALSE; +@@ -2036,10 +2131,12 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW + req->cpu = cpu; + req->info_size = startup_info_size; + req->env_size = (env_end - env) * sizeof(WCHAR); +- req->process_sd_size = 0; ++ req->process_sd_size = process_sd_size; + + wine_server_add_data( req, startup_info, startup_info_size ); + wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) ); ++ wine_server_add_data( req, process_sd, process_sd_size ); ++ wine_server_add_data( req, thread_sd, thread_sd_size ); + if (!(status = wine_server_call( req ))) + { + info->dwProcessId = (DWORD)reply->pid; +@@ -2052,6 +2149,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW + SERVER_END_REQ; + + RtlReleasePebLock(); ++ RtlFreeHeap(GetProcessHeap(), 0, process_sd); ++ RtlFreeHeap(GetProcessHeap(), 0, thread_sd); ++ + if (status) + { + switch (status) -- 1.7.9.5 diff --git a/patches/server-CreateProcess_ACLs/0004-advapi32-tests-Add-additional-tests-for-passing-a-th.patch b/patches/server-CreateProcess_ACLs/0004-advapi32-tests-Add-additional-tests-for-passing-a-th.patch new file mode 100644 index 00000000..0f164280 --- /dev/null +++ b/patches/server-CreateProcess_ACLs/0004-advapi32-tests-Add-additional-tests-for-passing-a-th.patch @@ -0,0 +1,96 @@ +From 3c5ee362799eef25543ef8a9787d97fcf8cef304 Mon Sep 17 00:00:00 2001 +From: Joris van der Wel +Date: Sun, 3 Aug 2014 12:52:44 +0200 +Subject: advapi32/tests: Add additional tests for passing a thread sd to + CreateProcess. + +--- + dlls/advapi32/tests/security.c | 44 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 40 insertions(+), 4 deletions(-) + +diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c +index b1b35aa..eb9b8cb 100644 +--- a/dlls/advapi32/tests/security.c ++++ b/dlls/advapi32/tests/security.c +@@ -2532,12 +2532,12 @@ static void test_process_security(void) + PTOKEN_OWNER owner; + PTOKEN_PRIMARY_GROUP group; + PSID AdminSid = NULL, UsersSid = NULL; +- PACL Acl = NULL; +- SECURITY_DESCRIPTOR *SecurityDescriptor = NULL; ++ PACL Acl = NULL, ThreadAcl = NULL; ++ SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL; + char buffer[MAX_PATH]; + PROCESS_INFORMATION info; + STARTUPINFOA startup; +- SECURITY_ATTRIBUTES psa; ++ SECURITY_ATTRIBUTES psa, tsa; + HANDLE token, event; + DWORD size; + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; +@@ -2658,11 +2658,36 @@ static void test_process_security(void) + psa.lpSecurityDescriptor = SecurityDescriptor; + psa.bInheritHandle = TRUE; + ++ ThreadSecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); ++ res = InitializeSecurityDescriptor(ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); ++ ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); ++ ++ ThreadAcl = HeapAlloc(GetProcessHeap(), 0, 256); ++ res = InitializeAcl(ThreadAcl, 256, ACL_REVISION); ++ ok(res, "InitializeAcl failed with error %d\n", GetLastError()); ++ res = AddAccessDeniedAce(ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid); ++ ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError()); ++ res = AddAccessAllowedAce(ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid); ++ ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); ++ ++ res = SetSecurityDescriptorOwner(ThreadSecurityDescriptor, AdminSid, FALSE); ++ ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); ++ res = SetSecurityDescriptorGroup(ThreadSecurityDescriptor, UsersSid, FALSE); ++ ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); ++ res = SetSecurityDescriptorDacl(ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE); ++ ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); ++ ++ tsa.nLength = sizeof(tsa); ++ tsa.lpSecurityDescriptor = ThreadSecurityDescriptor; ++ tsa.bInheritHandle = TRUE; ++ + /* Doesn't matter what ACL say we should get full access for ourselves */ +- res = CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info ); ++ res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info ); + ok(res, "CreateProcess with err:%d\n", GetLastError()); + TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); ++ TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4, ++ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); + winetest_wait_child_process( info.hProcess ); + + FreeSid(EveryoneSid); +@@ -2673,6 +2698,8 @@ static void test_process_security(void) + HeapFree(GetProcessHeap(), 0, owner); + HeapFree(GetProcessHeap(), 0, Acl); + HeapFree(GetProcessHeap(), 0, SecurityDescriptor); ++ HeapFree(GetProcessHeap(), 0, ThreadAcl); ++ HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor); + } + + static void test_process_security_child(void) +@@ -2728,6 +2755,15 @@ static void test_process_security_child(void) + TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ ); + CloseHandle( handle1 ); + CloseHandle( handle ); ++ ++ ++ handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() ); ++ ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError()); ++ TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE ); ++ CloseHandle( handle ); ++ ++ handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() ); ++ ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n"); + } + + static void test_impersonation_level(void) +-- +1.7.9.5 + diff --git a/patches/server-CreateProcess_ACLs/0004-server-implement-passing-a-thread-security-descripto.patch b/patches/server-CreateProcess_ACLs/0004-server-implement-passing-a-thread-security-descripto.patch deleted file mode 100644 index 1f812df4..00000000 --- a/patches/server-CreateProcess_ACLs/0004-server-implement-passing-a-thread-security-descripto.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 649ce4e95f5ea671857d5c62eb220c95a6af35d7 Mon Sep 17 00:00:00 2001 -From: Joris van der Wel -Date: Sun, 3 Aug 2014 12:52:44 +0200 -Subject: server: implement passing a thread security descriptor to - CreateProcess - -server: implement passing a thread security descriptor to CreateProcess ---- - dlls/advapi32/tests/security.c | 44 ++++++++++++++++++++++++++++++++++++---- - dlls/kernel32/process.c | 24 +++++++++++++++++++--- - server/process.c | 25 +++++++++++++++++++++-- - 3 files changed, 84 insertions(+), 9 deletions(-) - -diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index b1b35aa..244844f 100644 ---- a/dlls/advapi32/tests/security.c -+++ b/dlls/advapi32/tests/security.c -@@ -2532,12 +2532,12 @@ static void test_process_security(void) - PTOKEN_OWNER owner; - PTOKEN_PRIMARY_GROUP group; - PSID AdminSid = NULL, UsersSid = NULL; -- PACL Acl = NULL; -- SECURITY_DESCRIPTOR *SecurityDescriptor = NULL; -+ PACL Acl = NULL, ThreadAcl = NULL; -+ SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL; - char buffer[MAX_PATH]; - PROCESS_INFORMATION info; - STARTUPINFOA startup; -- SECURITY_ATTRIBUTES psa; -+ SECURITY_ATTRIBUTES psa, tsa; - HANDLE token, event; - DWORD size; - SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; -@@ -2658,11 +2658,36 @@ static void test_process_security(void) - psa.lpSecurityDescriptor = SecurityDescriptor; - psa.bInheritHandle = TRUE; - -+ ThreadSecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); -+ res = InitializeSecurityDescriptor(ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); -+ ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); -+ -+ ThreadAcl = HeapAlloc(GetProcessHeap(), 0, 256); -+ res = InitializeAcl(ThreadAcl, 256, ACL_REVISION); -+ ok(res, "InitializeAcl failed with error %d\n", GetLastError()); -+ res = AddAccessDeniedAce(ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid); -+ ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError()); -+ res = AddAccessAllowedAce(ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid); -+ ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); -+ -+ res = SetSecurityDescriptorOwner(ThreadSecurityDescriptor, AdminSid, FALSE); -+ ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); -+ res = SetSecurityDescriptorGroup(ThreadSecurityDescriptor, UsersSid, FALSE); -+ ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); -+ res = SetSecurityDescriptorDacl(ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE); -+ ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); -+ -+ tsa.nLength = sizeof(tsa); -+ tsa.lpSecurityDescriptor = ThreadSecurityDescriptor; -+ tsa.bInheritHandle = TRUE; -+ - /* Doesn't matter what ACL say we should get full access for ourselves */ -- res = CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info ); -+ res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info ); - ok(res, "CreateProcess with err:%d\n", GetLastError()); - TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4, - STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); -+ TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4, -+ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); - winetest_wait_child_process( info.hProcess ); - - FreeSid(EveryoneSid); -@@ -2673,6 +2698,8 @@ static void test_process_security(void) - HeapFree(GetProcessHeap(), 0, owner); - HeapFree(GetProcessHeap(), 0, Acl); - HeapFree(GetProcessHeap(), 0, SecurityDescriptor); -+ HeapFree(GetProcessHeap(), 0, ThreadAcl); -+ HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor); - } - - static void test_process_security_child(void) -@@ -2728,6 +2755,15 @@ static void test_process_security_child(void) - TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ ); - CloseHandle( handle1 ); - CloseHandle( handle ); -+ -+ -+ handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() ); -+ ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError()); -+ TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE ); -+ CloseHandle( handle ); -+ -+ handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() ); -+ ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n"); - } - - static void test_impersonation_level(void) -diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c -index 44e7711..dd21100 100644 ---- a/dlls/kernel32/process.c -+++ b/dlls/kernel32/process.c -@@ -2003,8 +2003,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - int socketfd[2], stdin_fd = -1, stdout_fd = -1; - pid_t pid; - int err, cpu; -- struct security_descriptor *psd = NULL; -- data_size_t psd_len = 0; -+ struct security_descriptor *psd = NULL, *tsd = NULL; -+ data_size_t psd_len = 0, tsd_len = 0; - - if ((cpu = get_process_cpu( filename, binary_info )) == -1) - { -@@ -2022,12 +2022,26 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - return FALSE; - } - } -+ if (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->lpSecurityDescriptor) -+ { -+ status = create_struct_sd( tsa->lpSecurityDescriptor, &tsd, &tsd_len ); -+ -+ if (status != STATUS_SUCCESS) -+ { -+ RtlFreeHeap(GetProcessHeap(), 0, psd); -+ RtlFreeHeap(GetProcessHeap(), 0, tsd); -+ WARN("Invalid thread security descriptor with status %x\n", status); -+ SetLastError( RtlNtStatusToDosError(status) ); -+ return FALSE; -+ } -+ } - - /* create the socket for the new process */ - - if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1) - { - RtlFreeHeap(GetProcessHeap(), 0, psd); -+ RtlFreeHeap(GetProcessHeap(), 0, tsd); - SetLastError( ERROR_TOO_MANY_OPEN_FILES ); - return FALSE; - } -@@ -2068,6 +2082,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - } - close( socketfd[0] ); - RtlFreeHeap(GetProcessHeap(), 0, psd); -+ RtlFreeHeap(GetProcessHeap(), 0, tsd); - SetLastError( RtlNtStatusToDosError( status )); - return FALSE; - } -@@ -2081,6 +2096,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - close( socketfd[0] ); - close( socketfd[1] ); - RtlFreeHeap(GetProcessHeap(), 0, psd); -+ RtlFreeHeap(GetProcessHeap(), 0, tsd); - return FALSE; - } - if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment; -@@ -2115,10 +2131,11 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0; - req->cpu = cpu; - req->process_sd_size= psd_len; -- req->thread_sd_size = 0; -+ req->thread_sd_size = tsd_len; - req->info_size = startup_info_size; - - wine_server_add_data( req, psd, psd_len ); -+ wine_server_add_data( req, tsd, tsd_len ); - wine_server_add_data( req, startup_info, startup_info_size ); - wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) ); - if (!(status = wine_server_call( req ))) -@@ -2133,6 +2150,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW - SERVER_END_REQ; - - RtlFreeHeap(GetProcessHeap(), 0, psd); -+ RtlFreeHeap(GetProcessHeap(), 0, tsd); - - RtlReleasePebLock(); - if (status) -diff --git a/server/process.c b/server/process.c -index 571f05a..52c04f7 100644 ---- a/server/process.c -+++ b/server/process.c -@@ -880,7 +880,7 @@ DECL_HANDLER(new_process) - struct process *process; - struct process *parent = current->process; - int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); -- const struct security_descriptor *req_psd = NULL; -+ const struct security_descriptor *req_psd = NULL, *req_tsd = NULL; - const startup_info_t *req_info; - data_size_t req_info_size; - const WCHAR *req_env; -@@ -903,7 +903,17 @@ DECL_HANDLER(new_process) - return; - } - } -+ if (req->thread_sd_size) -+ { -+ req_tsd = (const struct security_descriptor *) -+ ((char*)get_req_data() + req->process_sd_size); - -+ if (!sd_is_valid( req_tsd, req->thread_sd_size )) -+ { -+ set_error( STATUS_INVALID_SECURITY_DESCR ); -+ return; -+ } -+ } - req_info = (const startup_info_t *) - ((char*)get_req_data() + req->process_sd_size + req->thread_sd_size); - req_env = (const WCHAR *) -@@ -1043,7 +1053,18 @@ DECL_HANDLER(new_process) - DACL_SECURITY_INFORMATION| - SACL_SECURITY_INFORMATION ); - } -- -+ if (req_tsd) -+ { -+ /* In CreateProcess the thread defaults come from the process token, -+ * (this is not the case during CreateThread however) */ -+ set_sd_defaults_from_token( &thread->obj, -+ req_tsd, -+ OWNER_SECURITY_INFORMATION| -+ GROUP_SECURITY_INFORMATION| -+ DACL_SECURITY_INFORMATION| -+ SACL_SECURITY_INFORMATION, -+ process->token ); -+ } - done: - release_object( info ); - } --- -1.7.9.5 - diff --git a/patches/server-CreateProcess_ACLs/definition b/patches/server-CreateProcess_ACLs/definition index 72e68063..45245156 100644 --- a/patches/server-CreateProcess_ACLs/definition +++ b/patches/server-CreateProcess_ACLs/definition @@ -1,4 +1,4 @@ -Author: Joris van der Wel +Author: Joris van der Wel / Sebastian Lackner Subject: Implement passing ACLs to CreateProcess. -Revision: 1 +Revision: 2 Fixes: [22006] Support for process ACLs diff --git a/patches/server-OpenProcess/0001-server-Return-error-when-opening-a-terminating-proce.patch b/patches/server-OpenProcess/0001-server-Return-error-when-opening-a-terminating-proce.patch new file mode 100644 index 00000000..b097fba5 --- /dev/null +++ b/patches/server-OpenProcess/0001-server-Return-error-when-opening-a-terminating-proce.patch @@ -0,0 +1,57 @@ +From c45e6864494332d04e7e93be02a0ee8222bd9383 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 14 Aug 2014 03:05:52 +0200 +Subject: server: Return error when opening a terminating process. + +--- + server/process.c | 7 ++++++- + server/process.h | 1 + + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/server/process.c b/server/process.c +index 426bcca..0574a32 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -268,6 +268,7 @@ void shutdown_master_socket(void) + /* final cleanup once we are sure a process is really dead */ + static void process_died( struct process *process ) + { ++ process->is_terminated = 1; + if (debug_level) fprintf( stderr, "%04x: *process killed*\n", process->id ); + if (!process->is_system) + { +@@ -324,6 +325,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit + process->is_system = 0; + process->debug_children = 0; + process->is_terminating = 0; ++ process->is_terminated = 0; + process->console = NULL; + process->startup_state = STARTUP_IN_PROGRESS; + process->startup_info = NULL; +@@ -1129,7 +1131,10 @@ DECL_HANDLER(open_process) + reply->handle = 0; + if (process) + { +- reply->handle = alloc_handle( current->process, process, req->access, req->attributes ); ++ if (!process->is_terminated) ++ reply->handle = alloc_handle( current->process, process, req->access, req->attributes ); ++ else ++ set_error( STATUS_INVALID_PARAMETER ); + release_object( process ); + } + } +diff --git a/server/process.h b/server/process.h +index a50b537..da6d3da 100644 +--- a/server/process.h ++++ b/server/process.h +@@ -75,6 +75,7 @@ struct process + unsigned int is_system:1; /* is it a system process? */ + unsigned int debug_children:1;/* also debug all child processes */ + unsigned int is_terminating:1;/* is process terminating? */ ++ unsigned int is_terminated:1; /* is process terminated? */ + struct list locks; /* list of file locks owned by the process */ + struct list classes; /* window classes owned by the process */ + struct console_input*console; /* console input */ +-- +1.7.9.5 + diff --git a/patches/server-OpenProcess/definition b/patches/server-OpenProcess/definition new file mode 100644 index 00000000..e182ffb2 --- /dev/null +++ b/patches/server-OpenProcess/definition @@ -0,0 +1,4 @@ +Author: Michael Müller +Subject: Return error when opening a terminating process. +Revision: 3 +Fixes: [37087] Return an error when trying to open a terminated process diff --git a/patches/server-Process/0001-server-Return-error-when-opening-a-terminating-proce.patch b/patches/server-Process/0001-server-Return-error-when-opening-a-terminating-proce.patch deleted file mode 100644 index a573cdfe..00000000 --- a/patches/server-Process/0001-server-Return-error-when-opening-a-terminating-proce.patch +++ /dev/null @@ -1,28 +0,0 @@ -From dd42b1c92e5e72953da216a12e2d244178633089 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Thu, 14 Aug 2014 03:05:52 +0200 -Subject: server: Return error when opening a terminating process. - ---- - server/process.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/server/process.c b/server/process.c -index 7b9a3b2..7935373 100644 ---- a/server/process.c -+++ b/server/process.c -@@ -1082,7 +1082,10 @@ DECL_HANDLER(open_process) - reply->handle = 0; - if (process) - { -- reply->handle = alloc_handle( current->process, process, req->access, req->attributes ); -+ if (!process->is_terminating) -+ reply->handle = alloc_handle( current->process, process, req->access, req->attributes ); -+ else -+ set_error( STATUS_INVALID_PARAMETER ); - release_object( process ); - } - } --- -1.9.1 - diff --git a/patches/server-Process/definition b/patches/server-Process/definition deleted file mode 100644 index deb23d35..00000000 --- a/patches/server-Process/definition +++ /dev/null @@ -1,4 +0,0 @@ -Author: Michael Müller -Subject: Return error when opening a terminating process. -Revision: 1 -Fixes: [37087] Gothic 2 demo expects an error when opening a terminating process diff --git a/patches/shell32-Default_Path/0001-shell32-Implement-KF_FLAG_DEFAULT_PATH-flag-for-SHGe.patch b/patches/shell32-Default_Path/0001-shell32-Implement-KF_FLAG_DEFAULT_PATH-flag-for-SHGe.patch new file mode 100644 index 00000000..b8c177bd --- /dev/null +++ b/patches/shell32-Default_Path/0001-shell32-Implement-KF_FLAG_DEFAULT_PATH-flag-for-SHGe.patch @@ -0,0 +1,52 @@ +From 12199f1bcc3fabab52034df4362a5b3c4e93337d Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 23 Aug 2014 01:34:38 +0200 +Subject: shell32: Implement KF_FLAG_DEFAULT_PATH flag for + SHGetKnownFolderPath. + +--- + dlls/shell32/shellpath.c | 6 ++++-- + dlls/shell32/tests/shellpath.c | 5 +++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c +index e361483..600e002 100644 +--- a/dlls/shell32/shellpath.c ++++ b/dlls/shell32/shellpath.c +@@ -3104,13 +3104,15 @@ HRESULT WINAPI SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE t + if (flags & KF_FLAG_INIT) + index |= CSIDL_FLAG_PER_USER_INIT; + +- if (flags & ~(KF_FLAG_CREATE|KF_FLAG_DONT_VERIFY|KF_FLAG_NO_ALIAS|KF_FLAG_INIT)) ++ if (flags & ~(KF_FLAG_CREATE|KF_FLAG_DONT_VERIFY|KF_FLAG_NO_ALIAS| ++ KF_FLAG_INIT|KF_FLAG_DEFAULT_PATH)) + { + FIXME("flags 0x%08x not supported\n", flags); + return E_INVALIDARG; + } + +- hr = SHGetFolderPathW( NULL, index, token, 0, folder ); ++ hr = SHGetFolderPathW( NULL, index, token, (flags & KF_FLAG_DEFAULT_PATH) ? ++ SHGFP_TYPE_DEFAULT : SHGFP_TYPE_CURRENT, folder ); + if (SUCCEEDED(hr)) + { + *path = CoTaskMemAlloc( (strlenW( folder ) + 1) * sizeof(WCHAR) ); +diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c +index efdfbbd..f518a7a 100644 +--- a/dlls/shell32/tests/shellpath.c ++++ b/dlls/shell32/tests/shellpath.c +@@ -861,6 +861,11 @@ if (0) { /* crashes */ + ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); + ok(path != NULL, "expected path != NULL\n"); + ++ path = NULL; ++ hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL, &path); ++ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ++ ok(path != NULL, "expected path != NULL\n"); ++ + hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH); + ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); + ok(!lstrcmpiW(path, buffer), "expected equal paths\n"); +-- +1.7.9.5 + diff --git a/patches/shell32-Default_Path/definition b/patches/shell32-Default_Path/definition new file mode 100644 index 00000000..6bfbf9bf --- /dev/null +++ b/patches/shell32-Default_Path/definition @@ -0,0 +1,4 @@ +Author: Sebastian Lackner +Subject: Implement KF_FLAG_DEFAULT_PATH flag for SHGetKnownFolderPath. +Revision: 1 +Fixes: [30385] Support for KF_FLAG_DEFAULT_PATH in SHGetKnownFolderPath diff --git a/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch b/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch index ca6a6c33..4dd45e85 100644 --- a/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch +++ b/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch @@ -1,4 +1,4 @@ -From 9a7e400269a26545f47dfbd4f40ac2e74713c496 Mon Sep 17 00:00:00 2001 +From 56a72cb0a034dd7b3cc6ac68ad2d296c7f2ac47b Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 17:52:50 -0700 Subject: ws2_32: Add stub for TransmitFile. @@ -8,10 +8,10 @@ Subject: ws2_32: Add stub for TransmitFile. 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index a855285..c7f17c7 100644 +index d5e9fd1..07d2a47 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2473,6 +2473,18 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW +@@ -2485,6 +2485,18 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW } /*********************************************************************** @@ -30,7 +30,7 @@ index a855285..c7f17c7 100644 * GetAcceptExSockaddrs */ static void WINAPI WS2_GetAcceptExSockaddrs(PVOID buffer, DWORD data_size, DWORD local_size, DWORD remote_size, -@@ -3974,7 +3986,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID +@@ -4031,7 +4043,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID } else if ( IsEqualGUID(&transmitfile_guid, in_buff) ) { diff --git a/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch b/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch index 0cb70fdb..635e21ac 100644 --- a/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch +++ b/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch @@ -1,18 +1,18 @@ -From 4ee238e8c4b76aba464025ba0d0d9c2f297c7300 Mon Sep 17 00:00:00 2001 +From 75ceb8ccd7dcf5908f7a1fcf9ef4d20b71f4148a Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 17 Jan 2014 12:35:57 -0700 Subject: ws2_32: Check for invalid parameters in TransmitFile. --- - dlls/ws2_32/socket.c | 20 +++++++++ + dlls/ws2_32/socket.c | 21 ++++++++++ dlls/ws2_32/tests/sock.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 123 insertions(+) + 2 files changed, 124 insertions(+) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index c7f17c7..ae23dd6 100644 +index 07d2a47..597b248 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2478,8 +2478,28 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW +@@ -2490,8 +2490,29 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, DWORD flags ) { @@ -22,12 +22,13 @@ index c7f17c7..ae23dd6 100644 + FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); -+ if (s == INVALID_SOCKET) ++ ++ fd = get_sock_fd( s, 0, NULL ); ++ if (fd == -1) + { -+ WSASetLastError( WSAENOTSOCK ); ++ SetLastError( WSAENOTSOCK ); + return FALSE; + } -+ fd = get_sock_fd( s, 0, NULL ); + if (getpeername( fd, &uaddr.addr, &uaddrlen ) != 0) + { + release_sock_fd( s, fd ); @@ -42,10 +43,10 @@ index c7f17c7..ae23dd6 100644 return FALSE; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 0abf732..9b01dd5 100644 +index 8a9cbba..dc393e6 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -6334,6 +6334,108 @@ end: +@@ -6491,6 +6491,108 @@ end: closesocket(connector2); } @@ -154,7 +155,7 @@ index 0abf732..9b01dd5 100644 static void test_getpeername(void) { SOCKET sock; -@@ -7564,6 +7666,7 @@ START_TEST( sock ) +@@ -7726,6 +7828,7 @@ START_TEST( sock ) test_events(1); test_ipv6only(); diff --git a/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch b/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch index 3e859929..4c9baea1 100644 --- a/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch +++ b/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch @@ -1,23 +1,23 @@ -From e1278ab064bba641f34caa8132c8ddc8e83b9778 Mon Sep 17 00:00:00 2001 +From 87a9e724ea4529250b5e194265fd81019b76eea9 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 18:24:27 -0700 Subject: ws2_32: Implement a basic synchronous TransmitFile. --- - dlls/ws2_32/socket.c | 66 ++++++++++++++++++++++++++++++++++++++++-- + dlls/ws2_32/socket.c | 66 +++++++++++++++++++++++++++++++++++++++++- dlls/ws2_32/tests/sock.c | 71 +++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 134 insertions(+), 3 deletions(-) + 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index ae23dd6..1faf443 100644 +index 597b248..322c5ed 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2473,6 +2473,64 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW +@@ -2485,6 +2485,65 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW } /*********************************************************************** + * WS2_transmitfile_base (INTERNAL) -+ * ++ * + * Shared implementation for both synchronous and asynchronous TransmitFile. + */ +static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, @@ -56,7 +56,8 @@ index ae23dd6..1faf443 100644 + break; + else if(!ok) + goto cleanup; -+ if (WS_send( s, buffer, n, 0 ) == SOCKET_ERROR) ++ n = WS_send( s, buffer, n, 0 ); ++ if (n == SOCKET_ERROR) + goto cleanup; + bytes_sent += n; + } while(total_bytes == 0 || bytes_sent < total_bytes); @@ -77,17 +78,16 @@ index ae23dd6..1faf443 100644 * TransmitFile */ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, -@@ -2482,8 +2540,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR +@@ -2494,7 +2553,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR unsigned int uaddrlen = sizeof(uaddr); int fd; - FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, -- flags ); -+ TRACE("(%lx, %p, %d, %d, %p, %p, %d)\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); - if (s == INVALID_SOCKET) - { - WSASetLastError( WSAENOTSOCK ); -@@ -2500,6 +2557,11 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR ++ TRACE("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, + flags ); + + fd = get_sock_fd( s, 0, NULL ); +@@ -2513,6 +2572,11 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR if (flags) FIXME("Flags are not currently supported (0x%x).\n", flags); @@ -100,10 +100,10 @@ index ae23dd6..1faf443 100644 return FALSE; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 30c8bc1..79052ab 100644 +index dc393e6..2312f50 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -6334,15 +6334,45 @@ end: +@@ -6491,15 +6491,45 @@ end: closesocket(connector2); } @@ -149,7 +149,7 @@ index 30c8bc1..79052ab 100644 int iret, len; BOOL bret; -@@ -6420,7 +6450,46 @@ static void test_TransmitFile(void) +@@ -6577,7 +6607,46 @@ static void test_TransmitFile(void) /* Test TransmitFile with no possible buffer */ bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0); diff --git a/patches/ws2_32-TransmitFile/0004-ws2_32-Add-asynchronous-support-for-TransmitFile.patch b/patches/ws2_32-TransmitFile/0004-ws2_32-Add-asynchronous-support-for-TransmitFile.patch index bf95fd29..416906ed 100644 --- a/patches/ws2_32-TransmitFile/0004-ws2_32-Add-asynchronous-support-for-TransmitFile.patch +++ b/patches/ws2_32-TransmitFile/0004-ws2_32-Add-asynchronous-support-for-TransmitFile.patch @@ -1,4 +1,4 @@ -From ecf3a78c92ff49e1322d5e7467c54081606e9e8d Mon Sep 17 00:00:00 2001 +From 0535832365c4fba553cfddd1546ce55d63b45510 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 18:24:53 -0700 Subject: ws2_32: Add asynchronous support for TransmitFile. @@ -9,10 +9,10 @@ Subject: ws2_32: Add asynchronous support for TransmitFile. 2 files changed, 124 insertions(+), 9 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index 1faf443..2323e3d 100644 +index 322c5ed..42c7832 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -363,6 +363,18 @@ typedef struct ws2_accept_async +@@ -364,6 +364,18 @@ typedef struct ws2_accept_async struct ws2_async *read; } ws2_accept_async; @@ -31,7 +31,7 @@ index 1faf443..2323e3d 100644 /****************************************************************/ /* ----------------------------------- internal data */ -@@ -2499,6 +2511,16 @@ static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD +@@ -2511,6 +2523,16 @@ static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD buffer = HeapAlloc( GetProcessHeap(), 0, bytes_per_send ); if (!buffer) goto cleanup; @@ -48,15 +48,15 @@ index 1faf443..2323e3d 100644 /* read and send the data from the file */ do { -@@ -2531,6 +2553,32 @@ cleanup: +@@ -2544,6 +2566,32 @@ cleanup: } /*********************************************************************** + * WS2_async_transmitfile (INTERNAL) -+ * ++ * + * Asynchronous callback for overlapped TransmitFile operations. + */ -+static NTSTATUS WS2_async_transmitfile( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved ) ++static NTSTATUS WS2_async_transmitfile( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved, void **apc) +{ + struct ws2_transmitfile_async *wsa = arg; + BOOL ret; @@ -81,7 +81,7 @@ index 1faf443..2323e3d 100644 * TransmitFile */ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, -@@ -2538,7 +2586,9 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR +@@ -2551,7 +2599,9 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR { union generic_unix_sockaddr uaddr; unsigned int uaddrlen = sizeof(uaddr); @@ -90,9 +90,9 @@ index 1faf443..2323e3d 100644 + struct ws2_transmitfile_async *wsa; + int status, fd; - TRACE("(%lx, %p, %d, %d, %p, %p, %d)\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); - if (s == INVALID_SOCKET) -@@ -2560,9 +2610,37 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR + TRACE("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, + flags ); +@@ -2575,9 +2625,37 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR if (!overlapped) return WS2_transmitfile_base( s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); @@ -134,10 +134,10 @@ index 1faf443..2323e3d 100644 } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 79052ab..652f75f 100644 +index 2312f50..dbb762a 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -6334,15 +6334,15 @@ end: +@@ -6491,15 +6491,15 @@ end: closesocket(connector2); } @@ -156,7 +156,7 @@ index 79052ab..652f75f 100644 while (1) { DWORD n1 = 0, n2 = 0; -@@ -6372,10 +6372,13 @@ static void test_TransmitFile(void) +@@ -6529,10 +6529,13 @@ static void test_TransmitFile(void) TRANSMIT_FILE_BUFFERS buffers; SOCKET client, server, dest; DWORD num_bytes, err; @@ -170,7 +170,7 @@ index 79052ab..652f75f 100644 /* Setup sockets for testing TransmitFile */ client = socket(AF_INET, SOCK_STREAM, 0); server = socket(AF_INET, SOCK_STREAM, 0); -@@ -6473,7 +6476,7 @@ static void test_TransmitFile(void) +@@ -6630,7 +6633,7 @@ static void test_TransmitFile(void) /* Test TransmitFile with only file data */ bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0); ok(bret, "TransmitFile failed unexpectedly.\n"); @@ -179,7 +179,7 @@ index 79052ab..652f75f 100644 /* Test TransmitFile with both file and buffer data */ buffers.Head = &header_msg[0]; -@@ -6486,11 +6489,44 @@ static void test_TransmitFile(void) +@@ -6643,11 +6646,44 @@ static void test_TransmitFile(void) iret = recv(dest, buf, sizeof(header_msg)+1, 0); ok(memcmp(buf, &header_msg[0], sizeof(header_msg)+1) == 0, "TransmitFile header buffer did not match!\n"); @@ -225,7 +225,7 @@ index 79052ab..652f75f 100644 /* Test TransmitFile with a UDP datagram socket */ closesocket(client); client = socket(AF_INET, SOCK_DGRAM, 0); -@@ -6501,6 +6537,7 @@ static void test_TransmitFile(void) +@@ -6658,6 +6694,7 @@ static void test_TransmitFile(void) cleanup: CloseHandle(file); diff --git a/patches/ws2_32-TransmitFile/0005-ws2_32-Add-support-for-TF_DISCONNECT-and-TF_REUSE_SO.patch b/patches/ws2_32-TransmitFile/0005-ws2_32-Add-support-for-TF_DISCONNECT-and-TF_REUSE_SO.patch index 4c61dfa6..fc1eb5d9 100644 --- a/patches/ws2_32-TransmitFile/0005-ws2_32-Add-support-for-TF_DISCONNECT-and-TF_REUSE_SO.patch +++ b/patches/ws2_32-TransmitFile/0005-ws2_32-Add-support-for-TF_DISCONNECT-and-TF_REUSE_SO.patch @@ -1,4 +1,4 @@ -From 986759caf5c16c81f4a479e57b6ff2a96dbb3a2a Mon Sep 17 00:00:00 2001 +From 8acfd293ecd49b7cad340dc90e6ea6b0ed07289a Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 19:08:30 -0700 Subject: ws2_32: Add support for TF_DISCONNECT and TF_REUSE_SOCKET to @@ -13,10 +13,10 @@ Subject: ws2_32: Add support for TF_DISCONNECT and TF_REUSE_SOCKET to 5 files changed, 89 insertions(+), 12 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index 2323e3d..500d288 100644 +index 42c7832..ddb50a5 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2545,6 +2545,18 @@ static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD +@@ -2558,6 +2558,18 @@ static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD if (buffers && WS_send( s, buffers->Tail, buffers->TailLength, 0 ) == SOCKET_ERROR) goto cleanup; @@ -35,7 +35,7 @@ index 2323e3d..500d288 100644 ret = TRUE; cleanup: -@@ -2586,6 +2598,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR +@@ -2599,6 +2611,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR { union generic_unix_sockaddr uaddr; unsigned int uaddrlen = sizeof(uaddr); @@ -43,7 +43,7 @@ index 2323e3d..500d288 100644 IO_STATUS_BLOCK *iosb = (IO_STATUS_BLOCK *)overlapped; struct ws2_transmitfile_async *wsa; int status, fd; -@@ -2604,8 +2617,8 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR +@@ -2619,8 +2632,8 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR return FALSE; } release_sock_fd( s, fd ); @@ -55,10 +55,10 @@ index 2323e3d..500d288 100644 if (!overlapped) return WS2_transmitfile_base( s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 652f75f..8f96f84 100644 +index dbb762a..5bf23a0 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -6527,8 +6527,17 @@ static void test_TransmitFile(void) +@@ -6684,8 +6684,17 @@ static void test_TransmitFile(void) ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n"); compare_file(file, dest, 10); @@ -90,10 +90,10 @@ index 06e6309..4426557 100644 #define FD_WINE_NONBLOCKING 0x20000000 #define FD_WINE_CONNECTED 0x40000000 diff --git a/server/protocol.def b/server/protocol.def -index fec5e75..a1ac327 100644 +index c9270ea..328f8a8 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -1220,6 +1220,12 @@ enum server_fd_type +@@ -1208,6 +1208,12 @@ enum server_fd_type @END @@ -107,10 +107,10 @@ index fec5e75..a1ac327 100644 @REQ(set_socket_event) obj_handle_t handle; /* handle to the socket */ diff --git a/server/sock.c b/server/sock.c -index 5ffb1fe..242327d 100644 +index 4adad0f..15afe81 100644 --- a/server/sock.c +++ b/server/sock.c -@@ -77,6 +77,7 @@ +@@ -80,6 +80,7 @@ #define FD_CLOSE 0x00000020 /* internal per-socket flags */ @@ -118,7 +118,7 @@ index 5ffb1fe..242327d 100644 #define FD_WINE_LISTENING 0x10000000 #define FD_WINE_NONBLOCKING 0x20000000 #define FD_WINE_CONNECTED 0x40000000 -@@ -121,6 +122,8 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, +@@ -124,6 +125,8 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, 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 ); @@ -127,7 +127,7 @@ index 5ffb1fe..242327d 100644 static int sock_get_ntstatus( int err ); static int sock_get_error( int err ); static void sock_set_error(void); -@@ -141,7 +144,7 @@ static const struct object_ops sock_ops = +@@ -144,7 +147,7 @@ static const struct object_ops sock_ops = default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ @@ -136,7 +136,7 @@ index 5ffb1fe..242327d 100644 sock_destroy /* destroy */ }; -@@ -580,6 +583,47 @@ static struct fd *sock_get_fd( struct object *obj ) +@@ -583,6 +586,47 @@ static struct fd *sock_get_fd( struct object *obj ) return (struct fd *)grab_object( sock->fd ); } @@ -184,7 +184,7 @@ index 5ffb1fe..242327d 100644 static void sock_destroy( struct object *obj ) { struct sock *sock = (struct sock *)obj; -@@ -627,15 +671,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne +@@ -630,15 +674,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne struct sock *sock; int sockfd; @@ -201,7 +201,7 @@ index 5ffb1fe..242327d 100644 if (!(sock = alloc_object( &sock_ops ))) { close( sockfd ); -@@ -960,6 +997,17 @@ DECL_HANDLER(accept_into_socket) +@@ -963,6 +1000,17 @@ DECL_HANDLER(accept_into_socket) release_object( sock ); }