From 036d1ce2e951d0166714c915e93ad98bc34d3793 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Mon, 30 Apr 2007 15:10:09 +0200 Subject: [PATCH] push 46d7c5ab81dbd26521afad86048775d05a228dc3 --- .gitignore | 4 + ANNOUNCE | 809 +++++++++++----------- ChangeLog | 1230 +++++++++++++++++++++++++++++++++ Makefile.in | 2 + VERSION | 2 +- configure | 21 +- configure.ac | 1 + dlls/Makefile.in | 1 + dlls/advapi32/crypt_lmhash.c | 2 - dlls/advapi32/eventlog.c | 1 - dlls/advapi32/security.c | 4 +- dlls/advapi32/tests/registry.c | 2 +- dlls/atl/atl.spec | 6 +- dlls/atl/atl_main.c | 41 ++ dlls/comdlg32/filedlg.c | 1 - dlls/comdlg32/filedlg31.c | 1 - dlls/comdlg32/fontdlg16.c | 1 - dlls/comdlg32/printdlg16.c | 1 - dlls/compstui/compstui_main.c | 3 - dlls/crypt32/decode.c | 2 - dlls/crypt32/encode.c | 2 - dlls/crypt32/main.c | 3 - dlls/crypt32/protectdata.c | 1 - dlls/crypt32/serialize.c | 1 - dlls/crypt32/store.c | 1 - dlls/d3d9/device.c | 2 +- dlls/d3drm/math.c | 54 +- dlls/d3drm/tests/vector.c | 79 +-- dlls/dbghelp/minidump.c | 2 +- dlls/ddraw/ddraw.c | 159 +++-- dlls/ddraw/ddraw_private.h | 14 +- dlls/ddraw/device.c | 3 + dlls/ddraw/main.c | 2 +- dlls/ddraw/surface.c | 243 ++++--- dlls/ddraw/tests/dsurface.c | 159 +++++ dlls/dnsapi/query.c | 2 +- dlls/dplayx/dplay.c | 12 +- dlls/dplayx/dplayx_global.c | 20 +- dlls/dplayx/dplayx_global.h | 4 +- dlls/dplayx/name_server.c | 2 +- dlls/dplayx/name_server.h | 2 +- dlls/dsound/dsound_main.c | 10 +- dlls/dsound/mixer.c | 9 +- dlls/dsound/propset.c | 9 +- dlls/dsound/sound3d.c | 14 +- dlls/dswave/dswave_main.c | 2 +- dlls/dswave/dswave_private.h | 2 +- dlls/gdi32/brush.c | 2 +- dlls/gdi32/enhmetafile.c | 2 +- dlls/gdi32/font.c | 8 +- dlls/iphlpapi/iphlpapi_main.c | 2 +- dlls/kernel32/kernel32.spec | 2 + dlls/kernel32/path.c | 37 + dlls/kernel32/process.c | 2 +- dlls/kernel32/tests/path.c | 57 ++ dlls/localspl/localmon.c | 9 +- dlls/mshtml/navigate.c | 3 +- dlls/msi/table.c | 11 +- dlls/msi/tests/Makefile.in | 3 +- dlls/msi/tests/automation.c | 924 +++++++++++++++++++++++++ dlls/msi/tests/db.c | 2 +- dlls/ntdll/om.c | 4 +- dlls/ntdll/time.c | 2 +- dlls/odbccp32/tests/misc.c | 2 +- dlls/oleaut32/tmarshal.c | 2 - dlls/quartz/Makefile.in | 1 + dlls/quartz/main.c | 1 + dlls/quartz/mpegsplit.c | 543 +++++++++++++++ dlls/quartz/quartz_private.h | 1 + dlls/quartz/regsvr.c | 33 + dlls/rpcrt4/rpc_message.c | 2 +- dlls/schannel/Makefile.in | 4 +- dlls/schannel/lsamode.c | 158 +++++ dlls/schannel/schannel.spec | 4 +- dlls/schannel/{ => tests}/Makefile.in | 12 +- dlls/schannel/tests/main.c | 180 +++++ dlls/schannel/usermode.c | 85 +++ dlls/user32/menu.c | 6 +- dlls/winealsa.drv/mixer.c | 8 +- dlls/winealsa.drv/waveinit.c | 12 +- dlls/winecoreaudio.drv/coremidi.c | 2 +- dlls/winecoreaudio.drv/coremidi.h | 2 +- dlls/winecoreaudio.drv/midi.c | 288 +++++++- dlls/wined3d/device.c | 2 +- dlls/wineoss.drv/mixer.c | 6 + dlls/winex11.drv/mouse.c | 154 +++-- dlls/winex11.drv/xdnd.c | 1 - dlls/winspool.drv/info.c | 8 +- include/winbase.h | 3 + include/wingdi.h | 4 +- programs/cmd/builtins.c | 2 +- programs/winebrowser/main.c | 30 +- programs/winetest/Makefile.in | 3 + programs/winetest/winetest.rc | 1 + 94 files changed, 4744 insertions(+), 834 deletions(-) rewrite ANNOUNCE (94%) create mode 100644 dlls/msi/tests/automation.c create mode 100644 dlls/quartz/mpegsplit.c create mode 100644 dlls/schannel/lsamode.c copy dlls/schannel/{ => tests}/Makefile.in (54%) create mode 100644 dlls/schannel/tests/main.c create mode 100644 dlls/schannel/usermode.c diff --git a/.gitignore b/.gitignore index ecdb9d272b0..7bbff768275 100644 --- a/.gitignore +++ b/.gitignore @@ -455,6 +455,9 @@ dlls/rsaenh/tests/rsaenh_crosstest.exe dlls/rsaenh/tests/testlist.c dlls/rsaenh/version.res dlls/sane.ds/rsrc.res +dlls/schannel/tests/*.ok +dlls/schannel/tests/schannel_crosstest.exe +dlls/schannel/tests/testlist.c dlls/secur32/libsecur32.def dlls/secur32/tests/*.ok dlls/secur32/tests/secur32_crosstest.exe @@ -860,6 +863,7 @@ programs/winetest/riched20_test.exe programs/winetest/rpcrt4_test.exe programs/winetest/rsabase_test.exe programs/winetest/rsaenh_test.exe +programs/winetest/schannel_test.exe programs/winetest/secur32_test.exe programs/winetest/serialui_test.exe programs/winetest/setupapi_test.exe diff --git a/ANNOUNCE b/ANNOUNCE dissimilarity index 94% index 27ca2b4cfc4..7b99a487715 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,401 +1,408 @@ -This is release 0.9.35 of Wine, a free implementation of Windows on Unix. - -What's new in this release: - - Broken aRts sound driver now removed for good. - - Many fixes to the Quartz DLL sound support. - - File I/O performance improvements. - - The usual assortment of Direct3D fixes. - - Lots of bug fixes. - -Because of lags created by using mirrors, this message may reach you -before the release is available at the public sites. The sources will -be available from the following locations: - - http://ibiblio.org/pub/linux/system/emulators/wine/wine-0.9.35.tar.bz2 - http://prdownloads.sourceforge.net/wine/wine-0.9.35.tar.bz2 - -Binary packages for various distributions will be available from: - - http://www.winehq.org/site/download - -You will find documentation on - - http://www.winehq.org/site/documentation - -You can also get the current source directly from the git or CVS -repositories. Check respectively http://www.winehq.org/site/git or -http://www.winehq.org/site/cvs for details. - -If you fix something, please submit a patch; instructions on how to do -this can be found at http://www.winehq.org/site/sending_patches - -Wine is available thanks to the work of many people. See the file -AUTHORS in the distribution for the complete list. - ----------------------------------------------------------------- - -Changes since 0.9.34: - -Alessandro Pignotti (1): - dplayx: Implement proper interface locking for DP_EnumSession. - -Alexandre Julliard (39): - make_makefiles: Add the .INIT/.BEGIN rules for the main makefile. - server: Add a generic wait queue to the file descriptor object. - server: Avoid redundant polling in fd_queue_async_timeout. - server: Take advantage of the fd generic wait queue to remove a lot of serial code. - server: Use the fd generic wait queue for directory change I/O operations. - server: Make async I/O queues into real objects. - server: Check file access in register_async before calling the object method. - kernel32: Added some last error tests for mailslots. - server: Add a separate function to set the timeout of an async I/O operation. - server: Make timeout status for async I/O specifiable. Fix mailslots timeout handling. - server: Hold a pointer to the queue from the async operations. - make_requests: More aggressive grepping for status values. - server: Add support for associating a file descriptor to a message queue. - winex11.drv: Store the display file descriptor directly in the server message queue. - server: Fix the handling of the signaled status for file descriptors. - server: Use the standard file descriptor signal mechanism for directory changes. - ntdll: Avoid setting status in IO_STATUS_BLOCK until the I/O operation is done. - ntdll: Avoid relying on the IO_STATUS_BLOCK for storing the current transfer count. - ws2_32: Don't access the IO_STATUS_BLOCK until the I/O operation is finished. - ntdll: Make test for heap boundaries more strict in HEAP_FindSubHeap. - kernel32: Add a bit of slack to the mailslot timeout test. - ntdll: Reimplement NtReadFile. - ntdll: Reimplement NtWriteFile. - ntdll: Rely on the server to queue the final APC for asynchronous read/write. - ntdll: Use send(2) instead of write(2) for zero-byte writes to sockets. - ntdll: Add some test cases for asynchronous I/O. - setupapi: Avoid using sizeof in traces. - server: Add support for restarting an async I/O when the client side couldn't finish it right away. - ntdll: Simplify the async read/write code now that most of the work is done in the server. - ntdll: Determine the async read avail_mode flag from the client side. - server: Explicitly shutdown closed pipes to prevent access from file descriptors cached in the client. - kernel32: Add SYNCHRONIZE access to mailslot handles. - server: Store the opening options in the file descriptor instead of in the individual objects. - server: Rename the get_file_info function to get_fd_type and get rid of the flags. - ntdll: Store the file access and options in the fd cache, and get rid of the dynamic flags. - shell32: Have _ILCreateFromFindDataW also create a FileStructW type of pidl. - server: Create a separate fd object for each mailslot writer. Make them first-class file handles. - server: Don't bother with default entry points for objects that don't even return an fd. - winex11.drv: Hack to disable XInitThreads when an XIM is used. - -Andrew Talbot (35): - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - comctl32: Constify some variables. - advapi32: Constify some variables. - atl: Constify some variables. - advpack: Constify some variables. - comcat: Constify some variables. - avifil32: Constify some variables. - comdlg32: Constify some variables. - comdlg32: Constify some variables. - comdlg32: Constify some variables. - comdlg32: Constify some variables. - comdlg32: Constify some variables. - comdlg32: Constify some variables. - comdlg32: Remove inappropriate const qualifier. - include: Remove superfluous semicolons. - d3d8: Void functions should not return a value. - d3d9: Void functions should not return a value. - kernel32: Remove superfluous semicolons. - mapi32: Void functions should not return a value. - crypt32: Constify some variables. - mshtml: Void functions should not return a value. - msvcrt: Remove superfluous semicolons. - ntdll: Void functions should not return a value. - ntdll: Remove superfluous semicolons. - ole32: Void functions should not return a value. - oleaut32: Remove superfluous semicolons. - -András Kovács (2): - ntdll: Add Vista version option. - winecfg: Add Windows Vista version option. - -Aric Stewart (8): - comctl32: Unset active page while setting a new active page for a propsheet. - comctl32: Propsheet exception fix. - ole32: Storage optimization. - msi: Register fonts with full target paths as applications can and will install fonts to places other than the windows/fonts directory. - shell32: Avoid unneeded A->W conversions in _ILSimpleGetTextW. - shell32: Update the debug functions to handle Unicode value pidl. - shell32: Use _ILSimpleGetTextW instead of using _ILGetTextPointer - msi: Do not crash in MsiGetUserInfo if org, user or serial are not present, instead return USERINFOSTATE_ABSENT. - -Byeong-Sik Jeon (2): - regedit: Support REG_MULTI_SZ creation and editing. - regedit: Update Korean resource. - -Chris Robinson (23): - quartz: Don't fill the dsound buffer with small amounts. - quartz: Remove errant parser output pins on input connection failure. - quartz: Set the sample time based on the number of bytes read before sending it downstream. - quartz: Use a safe APC to kill the PullPin thread when the PullPin is being released. - quartz: Use a second-long DSound buffer for playback. - quartz: Hold a reference on the PullPin's filter while the processing thread is alive. - quartz: Connect input when the pins connect, not when querying. - quartz: Add a QueryConnect method for transform filters. - quartz: Break loop on error in ACMWrapper. - quartz: Implement Get/SetSyncSource for the FilterGraph's IMediaFilter interface. - quartz: Don't call ReleaseSemaphore on NULL semaphore handles. - quartz: Tell filters to stop sending data when the chain is broken. - quartz: Avoid releasing NULL objects. - quartz: Send a notification when the filter graph clock changes. - quartz: Use more precise positioning information for the DSound filter's reference clock. - quartz: Add partial implementation of IReferenceClock for DSoundRenderer. - quartz: Add a cleanup callback for parser filters to call on release. - quartz: Make sure cached media samples are released for parser filters. - quartz: Fix ALIGN macros. - quartz: Fix error with operator precedence. - quartz: Pass the media sample to the individual transform filter callbacks. - winedbg: Align module addresses to 8 characters. - quartz: Implement IAMFilterData interface for IFilterMapper. - -Dan Hipschman (1): - rpcrt4: Add tests for RpcServerListen and friends. - -Dan Kegel (2): - imagehlp: BindImageEx stub should report success. - winex11.drv: GetAsyncKeyState must check mouse buttons, too. - -Detlef Riekenberg (4): - localui: Add localui.dll with stubs. - localui/tests: Add initial test. - localspl/tests: Remove duplicate tests. - localui: Add version resource. - -Dmitry Timoshkov (8): - kernel32: Add GetCPInfo test. - gdi32: Make GetKerningPairsA not fail for fonts with SYMBOL charset. - winspool: Add a test for DeviceCapabilities, fix some bugs found. - shlwapi: Fix a forward to user32.PrivateExtractIconExW. - user32: Windows uses ptMaxTrackSize to set an initial window size not ptMaxSize. - winebuild: Check if a given forward does exist in one of the imported dlls, fix a couple of problems detected. - gdi32: Fix a couple of problems with negative lfWidth test. - ntdll: Fix a compiler warning. - -Eric Pouech (3): - winedbg: When reloading real PE modules from a minidump, also look in the search path (as we do for ELF modules). - winedbg, winedump: Extended some info printed from system info directory in minidump about the CPU. - taskmgr: Let the debug channels work again. - -Fabian Bieler (7): - wined3d: Fix GLSL cmp instruction for INF and NAN arguments. - wined3d: Fix GLSL cnd instruction for INF and NAN arguments. - wined3d: Add support for float texture formats back in. - wined3d: Fix UpdateSurface for sourceRect != sourceWidth. - wined3d: Fix GLSL cnd instruction. - wined3d: Add GL_EXT_framebuffer_blit to extension handler. - wined3d: Mark vertex shader 3.0 as foggy shaders if they write out the fog coord. - -Felix Nawothnig (13): - gdi32: Properly handle negative font widths. - wined3d: Make CreateCubeTexture fail when not supported. - wined3d: Downgrade some ERRs to FIXMEs. - wined3d: Only issue state_patchsegments FIXME once. - comctl32: Fix item rect calculation. - comctl32: Use appropriate font for header drag image. - taskmgr: Use default font for proc listview. - comctl32: Allow destruction of toolbar in BN_CLICKED handler. - comctl32: Allow enabling TVS_CHECKBOXES on the fly. - d3d8: Add missing relay trace. - wined3d: Allow np2 textures to be loaded for SFLAG_INDRAWABLE. - wined3d: Preload target in ActivateContext() for ORM_BACKBUFFER/ORM_PBUFFER. - wined3d: Issue an error when the render target is read back without SFLAG_INDRAWABLE being set. - -Francois Gouget (8): - ole32/tests: Spelling fix. - ole32/tests: Spelling fix. - Assorted spelling and English fixes. - shell32/tests: Fix some expected FindExecutable() error codes. - shell32/tests: End the lines with CR+LF otherwise the profile APIs are unable to read them back on Win >= 2000. - shell32/tests: On Windows 98 FindExecutable() does not '\0' terminate the returned command which caused many tests to fail. - shell32/tests: On NT4 FindExecutable() returns an extra backspace character in some tests. - oleaut32/tests: Fix compilation on systems that don't support nameless structs or unions. - -H. Verbeet (16): - wined3d: Handle FBO attachments slightly more efficiently. - wined3d: Fixup FBO depth attachments when the depth attachment is larger than the render target. - wined3d: Add a function to dump WINED3DTEXTUREFILTERTYPE values. - wined3d: Make bind_fbo a bit more generic. - wined3d: Separate attaching a surface to an FBO from set_render_target_fbo. - wined3d: Use the framebuffer blit extension to implement StretchRect. - wined3d: Add some StretchRectFilterCaps. - wined3d: Don't report render target formats we don't support as supported. - wined3d: Display the stream offset in GetStreamSource/SetStreamSource traces. - wined3d: Set the stream offset to 0 in DrawPrimitiveUP/DrawIndexedPrimitiveUP. - wined3d: Add some traces to stretch_rect_fbo. - wined3d: Remove some redundant IWineD3DSurface_PreLoad calls from stretch_rect_fbo. - wined3d: Disable the scissor test in stretch_rect_fbo. - wined3d: Disable the scissor test for depth blits. - wined3d: Dirtify the sampler used by IWineD3DSurface_PreLoad in IWineD3DSurfaceImpl_BltOverride. - wined3d: Fix some swizzles on scalars. - -Hans Leidekker (8): - wintrust: Improve a number of stubs. - setupapi: Implement SetupGetFileCompressionInfoEx{A, W}. - setupapi: Add tests for SetupGetFileCompressionInfoEx. - setupapi: Implement SetupDecompressOrCopyFile{A, W}. - setupapi: Add tests for SetupDecompressOrCopyFile. - setupapi: Remove debug traces from allocation routines. - setupapi: Implement SetupGetFileCompressionInfo on top of SetupGetFileCompressionInfoEx. - kernel32: Allow any amount of whitespace between the words ANSI and SCSI in /proc/scsi/scsi. - -Huw Davies (3): - wineps.drv: Add a heuristic to cope with resolution strings of the form "nnnmmmdpi" (ie without the 'x' separator). - winspool.drv: Implement level 1 support for EnumPrinters. - imagehlp: Add support for the indices array passed to ImageEnumerateCertificates. - -Ivan Gyurdiev (2): - d3d9: Break out two helper functions from test_fvf_to_decl. - d3d9: Add a test for the converted vertex decl. - -Jacek Caban (5): - mshtml: Change TRACE to FIXME in stubs. - mshtml: Added IHTMLBodyElement::get_background implementation. - mshtml: Correctly handle utf-16 encoded pages. - mshtml: Added IPersistFile::Save implementation. - mshtml: Added IDM_COMPOSESETTINGS and IDM_HTMLEDITMODE stub implementation. - -James Hawkins (1): - msi: Reset the is_extracted flag when every cabinet is loaded. - -Jason Edmeades (20): - xcopy: Add support for /EXCLUDELIST:file1+file2 etc. - xcopy: Add support for /D and /D:m-d-y. - xcopy: Rearrange code to closely match windows ordering. - xcopy: Move all messages into an English resource file. - xcopy: Update comments with unsupported operations and current status. - xcopy: Add help. - xcopy: Make displayed names mirror windows. - xcopy: /E implies recursive (fixes ActiveState Perl installer). - xcopy: Hack/workaround for filenames starting with a '.'. - oleaut32: Convert to VT_DECIMAL fails with overflow (with test). - cmd.exe: Only search for supplied command as-is if it includes an extension. - cmd.exe: Attempt to launch pgm even if fails to locate it. - cmd.exe: Fix dir filename /s and resolve many output differences. - cmd.exe: Make dir support multiple parameters. - cmd.exe: Make dir a* b* or dir a* b* /s mirror windows. - cmd.exe: Partially fix 'dir *.' (ie files with no extension). - cmd.exe: Add support for move with simple wildcards. - cmd.exe: Add move support for wildcards and directories. - cmd.exe: Add prompting and COPYCMD plus /Y support to move. - cmd.exe: Fix regression when launching a fully qualified program. - -Kai Blin (1): - ntdll: Don't use settimeofday() to attempt to set the timezone. - -Laurent Vromman (3): - gdi32: Add two basic tests to check what WidenPath does. - gdi32: Correction of WidenPath behaviour when pen width is 1. - gdi32: Correct WidenPath behaviour when working on an open path. - -Lei Zhang (5): - advapi32: Spelling fixes. - comctl32: Fix first day of the week in monthcal. - comctl32: More monthcal hit tests. - user32: WM_ACTIVATEAPP on minimize message test. - comctl32: monthcal: GetMonthRange Tests. - -Louis Lenders (1): - user32: Add RealChildWindowFromPoint. - -Maarten Lankhorst (2): - winearts.drv: Kill off winearts. - winecfg: Close audio driver when not needed any more. - -Marcus Meissner (2): - ntdll: Remove superflous NULL checks. - configure: Include before including . - -Michael Ploujnikov (1): - wined3d: Remove DDBLT_WAIT fixme. - -Michael Stefaniuc (3): - msvcrt: Move the code to demangle a name with its template argument list out of get_class() and into a separate function. - msvcrt: Demangle a C++ mangled string that is only a name with it's template argument list. - ws2_32/tests: Remove redundant NULL check before HeapFree(). - -Paul Vriens (11): - advapi32/tests: Reopen the main handle if needed. - advapi32/tests: Some cleanup. - ole32/stg_bigblockfile: Check page before use (Coverity). - odbccp32: Don't print *pcbPathOut as it can be NULL (Coverity). - ntdll/tests: Use GetModuleHandle and skip. - user32/tests: Don't run unicode tests if not supported. - advapi32/tests: Make sure NT4 and W2K tests don't fail. - setupapi/tests: Run tests on win98 again. - advapi32/tests: Use skip when OpenSCManagerA is not implemented. - advapi32/tests: Fix RegQueryValueExA test for win9x and ME. - advpack/tests: Don't hardcode the windows directory. - -Peter Beutner (2): - dinput: Add missing definition to public header. - ntdll: Remove one exception test. - -Rob Shearman (21): - urlmon: Fix a reference count leak that would keep the module alive when it shouldn't. - advpack: Call OleInitialize before registering OCXs, like native does. - advpack: Stop processing if there was an error registering an OCX. - ntdll: Pass the correct value to NtClose in the tests. - msi: Don't wait on closed handles in ACTION_FinishCustomActions. - atl: AddRef the object being returned in AtlInternalQueryInterface, not "this". - ole32: Convert the OpenDll list to a standard Wine list. - ole32: Move the in-process module loading to COMPOBJ_DllList_Add. - ole32: Move the handling of loading a dll and getting an in-process object from it to an apartment-specific function. - ole32: Add a test that shows CoFreeUnusedLibraries only frees unused libraries from the current apartment. - ole32: Cache the address for the library's DllGetClassObject and DllCanUnloadNow in the OpenDll list entry. - ole32: Keep a list of the loaded dlls for each apartment. - ole32: In 16-bit OLE, LPOLESTR uses multibyte, not Unicode characters so make LoadTypeLib16 take an LPSTR instead of LPOLESTR. - ole32: Add tests for drag and drop functions. - ole32: Check for COM not being initialised and an invalid window handle being input to RegisterDragDrop. - ole32: Check the input hwnd is valid in RevokeDragDrop. - ole32: Don't release the registered drop targets in OleUninitialize. - ole32: Move declaration for FileMonikerImpl_DecomposePath from compobj_private.h to moniker.h. - ole32: Fix a hack which depended on the IID of the interface being marshaled - shell32: Return Unicode strings from all of the IShellFolder::GetDisplayNameOf functions in not running in Win9x mode. - msi: Provide UI action data for uncompressed files, not just compressed ones. - -Rolf Kalbermatter (4): - notepad: Implement handling of page setup dialog parameters. - notepad: Fix a possible rounding error when storing the font point size to the registry. - notepad: Fix text label. - notepad: Improve printing considerably. - -Stefan Dösinger (10): - wined3d: Add GL_APPLE_client_storage to our extension list. - wined3d: Use GL_APPLE_client_storage if available. - wined3d: Add D3DDEVCAPS3_* to the wined3d caps header. - wined3d: Add Filtering to IWineD3DSurface::Blt and handle it. - wined3d: Set WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD caps3 cap. - wined3d: Index buffer data is unsigned. - wined3d: Dirtify the shader and declaration states if the bound interface is destroyed. - d3d9: AddRef the device in IDirect3DVertexDeclaration9::AddRef. - d3d9: Fix the circular converted vertex declaration reference. - d3d9: Fix vertex decl test. - -Stefan Leichter (1): - advapi32: Add some tests for RegDeleteTreeA. - -Steven Edwards (1): - winecfg: Add a button for audio test. - -Vit Hrachovy (1): - winecfg: Fix outdated Czech localization. - -Vitaliy Margolen (2): - dinput: Set the event regardless of the queue state. - ntdll: Take size of the arena from the current pointer before advancing. - --- -Alexandre Julliard -julliard@winehq.org +This is release 0.9.36 of Wine, a free implementation of Windows on Unix. + +What's new in this release: + - Midi support in the CoreAudio driver. + - Mixer support in the Alsa driver. + - A lot of MSI fixes. + - Implementation for most D3DRM functions. + - The usual assortment of Direct3D fixes. + - Lots of bug fixes. + +Because of lags created by using mirrors, this message may reach you +before the release is available at the public sites. The sources will +be available from the following locations: + + http://ibiblio.org/pub/linux/system/emulators/wine/wine-0.9.36.tar.bz2 + http://prdownloads.sourceforge.net/wine/wine-0.9.36.tar.bz2 + +Binary packages for various distributions will be available from: + + http://www.winehq.org/site/download + +You will find documentation on + + http://www.winehq.org/site/documentation + +You can also get the current source directly from the git or CVS +repositories. Check respectively http://www.winehq.org/site/git or +http://www.winehq.org/site/cvs for details. + +If you fix something, please submit a patch; instructions on how to do +this can be found at http://www.winehq.org/site/sending_patches + +Wine is available thanks to the work of many people. See the file +AUTHORS in the distribution for the complete list. + +---------------------------------------------------------------- + +Changes since 0.9.35: + +Alasdair Sinclair (1): + advapi32: Fix one byte array overflow during DES unhash. + +Alban Browaeys (2): + msi: Move msi_free(msiFilePath) to enable ERR message to use it before it is freed. + wininet: Fix szCacheContent in URLCacheContainer_OpenIndex. + +Alexandre Julliard (19): + kernel32: Use the correct access rights when opening named pipes. + server: Add infrastructure for ioctl server request. + server: Implement the FSCTL_PIPE_DISCONNECT ioctl on the server side. + server: Move the server part of device unmounting to the ioctl processing. + server: Change the timeout handling to use NT-style 64-bit timeouts everywhere. + server: Add a specific data type for ioctl codes so they can be printed as symbols. + server: Move the FSCTL_PIPE_WAIT ioctl implementation to the server. + server: Allow specifying the status code to return on file descriptors that don't have a Unix fd. + server: Moved the FSCTL_PIPE_LISTEN implementation to the server. + server: Use the standard file descriptor wait queue for named pipe server async waits. + server: Don't give out read/write access to the named pipe device. + dbghelp: Don't print garbage chars in ERR message. + version: Avoid size_t type in traces. + server: Return a more correct fd type for anonymous files. + configure: Use AC_SEARCH_LIBS for the Solaris libs to avoid unused function checks. + winedbg: Properly handle EOF on input. + cabinet: Make sure we don't try to close an invalid file handle. + make_makefiles: Avoid duplicate .gitignore entries. + winecoreaudio: Avoid sizeof in trace. + +Alexey Markachev (1): + ntdll: Fix mistake in Novosibirsk time zone. + +Andrew Riedi (1): + winex11.drv: Add legacy 32-bit cursor support. + +Andrew Talbot (27): + crypt32: Constify some variables. + crypt32: Constify some variables. + user32: Make function definitions and declarations agree. + slwapi: Make function definitions and declarations agree. + slwapi: Make function definitions and declarations agree. + dbghelp: Constify some variables. + uxtheme: Fix conflicting declarations. + dbghelp: Constify some variables. + dbghelp: Constify some variables. + ddraw: Constify some variables. + activeds: Exclude unused headers. + acledit: Exclude unused headers. + advpack: Exclude unused headers. + avicap32: Exclude unused header. + avifil32: Exclude unused headers. + amstream: Exclude unused headers. + dinput: Constify some variables. + dmcompos: Constify a variable. + dmusic: Constify a variable. + dmscript: Constify a variable. + dmloader: Constify some variables. + dmime: Constify some variables. + dmstyle: Constify some variables. + dmband: Constify some variables. + dnsapi: Constify some variables. + dplayx: Fix a typo. + dplayx: Constify some variables. + +Aric Stewart (4): + taskmgr: Add Japanese resource. + shell32: SHGFI_EXETYPE flag should have the files returning 0 if they are DLL images. + gdi32: Make the comparison for system link font replacement not case sensitive. + usp10: Do not crash in ScriptPlace if pABC is null. + +Ben Taylor (2): + configure: Fix to properly recognize functions on Solaris. + wineoss: Fix to compile on Solaris 10. + +Bernd Buschinski (1): + wined3d: Fix drawStridedSlow typo. + +Chia-I Wu (1): + kernel32: Fix non-terminated separator string. + +Chris Robinson (2): + quartz: Create DirectSound device and buffer at filter creation and connection respectively. + quartz: Partially implement the MPEG 1 Stream Splitter filter. + +Clinton Stimpson (1): + riched20: Set modify state when removing text. + +Damjan Jovanovic (1): + mapi32: MAPIAdminProfiles stub. + +Dan Hipschman (4): + widl: Add --prefix-* options (take 3). + rpcrt4: Add tests for RPC and widl generated code. + widl: Declare fixed-size array args as pointers to arrays. + rpcrt4: Add a testcase for RPCs with fixed-size arrays. + +David Adam (15): + include: Add d3drmdef.h header. + d3drm: Implement D3DRMVectorAdd. + d3drm: Implement D3DVectorSubtract. + d3drm: Implement D3DRMVectorCrossProduct. + d3drm: Implement D3DRMVectorDotProduct. + d3drm: Implement D3DRMVectorModulus. + d3drm: Implement D3DRMVectorscale. + d3drm: Implement D3DRMVectorNormalize. + d3drm: Implement D3DRMVectorRandom. + d3drm: Implement D3DRMVectorReflect. + d3drm: Implement D3DRMQuaternionMultiply. + d3drm: Implement D3DRMVectorRotate. + d3drm: Implement D3DRMMatrixFromQuaternion. + d3drm: Implement D3DRMQuaternionFromRotation. + d3drm: Implement D3DRMQuaternionSlerp. + +Detlef Riekenberg (9): + include/winspool: Declare missing function. + spoolss: Build the import library. + localspl: Implement XcvData_AddPort. + localui: Implement DeletePortUI. + localspl: DeletePort is now in localui.dll. + localui: Implement ConfigurePortUI. + localspl: ConfigurePort is now in localui.dll. + localui: Avoid crash on NULL pointer. + localui: Implement ConfigurePortUI for COMx. + +Dmitry Timoshkov (7): + version: Add a VerQueryValue test, make it mostly pass under Wine. + advapi32: Thunk GetFileSecurityW to NtQuerySecurityObject. + comctl32: Fix an off by one error in ImageList_Remove. + comctl32: Use packing only for public ILHEAD structure, 2 bytes packing is enough. + comctl32: Add an image list storage test, make it pass under Wine. + comctl32: Add more image list tests, fix one problem found. + user32: Windows doesn't redraw a window if it is being just moved. + +EA Durbin (1): + sxs: Add new dll stub. + +Emmanuel Maillard (17): + winecoreaudio: Initial MIDI support on Mac OS X. + winecoreaudio: Implement MIDI_NotifyClient, MIDIOut_Open and MIDIOut_Close. + winecoreaudio: Implement MIDIOut_GetDevCaps and MIDIOut_GetNumDevs. + winecoreaudio: Implement MIDIOut_Prepare and MIDIOut_Unprepare. + winecoreaudio: Implement MIDIOut_Data. + winecoreaudio: Implement MIDIOut_LongData. + winecoreaudio: Implement MIDIOut_GetVolume and MIDIOut_SetVolume. + winecoreaudio: Implement MIDIOut_Reset. + winecoreaudio: Initial MIDI In support on Mac OS X. + winecoreaudio: Initial MIDI In Mach message handling. + winecoreaudio: Add MIDI In messages in MIDI_NotifyClient. + winecoreaudio: Implement MIDIIn_Open and MIDIIn_Close. + winecoreaudio: Implement MIDIIn_GetNumDevs and MIDIIn_GetDevCaps. + winecoreaudio: Implement MIDIIn_Start and MIDIIn_Stop. + winecoreaudio: Implement MIDIIn_Reset. + winecoreaudio: Implement MIDIIn_AddBuffer. + winecoreaudio: Implement MIDIIn_Prepare and MIDIIn_Unprepare. + +Eric Pouech (1): + acledit: Stubbed out acledit DLL, needed by SysInternals process explorer. + +Fabian Bieler (2): + d3d9/tests: Fix fog with shader test. + wined3d: Remove usesFog flag from IWineD3DVertexShaderImpl. + +Francois Gouget (2): + advapi32: Fix and extend the RegQueryValueEx() tests. + advapi32/tests: Use memcmp() instead of strcmp() so that we can check 'intrazeroed' strings. + +Gerald Pfeifer (1): + server: Silence compiler warning in fd_queue_async(). + +H. Verbeet (16): + wined3d: Add a function for dumping FBO status codes. + wined3d: Dump the FBO's attachments when its status is GL_FRAMEBUFFER_UNSUPPORTED_EXT. + wined3d: Use GL_UNSIGNED_BYTE as data type for WINED3DFMT_A8. + wined3d: Ignore SetTextureStageState on unsupported texture stages. + wined3d: Set the FBO drawbuffer using glDrawBuffer when ARB_DRAW_BUFFERS is not supported. + wined3d: Add a function to determine if a surface is the front or the backbuffer for a swapchain, and return the corresponding GLenum. + wined3d: Use surface_get_gl_buffer where appropriate. + wined3d: Properly handle the difference between GL_BACK and GL_FRONT for onscreen surfaces. + wined3d: Don't try to clear the depth stencil if there is none. + wined3d: Implement ColorFill using FBOs, if they're being used. + wined3d: Remove GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT from debug_fbostatus(). + wined3d: Output pretty GL errors in checkGLcall and vcheckGLcall. + wined3d: Actually use the calculated mipmap surface sizes in IWineD3DDeviceImpl_CreateVolumeTexture. + wined3d: Improve IWineD3DVolumeImpl_LoadTexture TRACE output. + wined3d: The second parameter to glTexImage3DEXT isn't a GLenum. + wined3d: Fix the return value for IWineD3DDeviceImpl_ColorFill. + +Hans Leidekker (9): + iphlpapi: Only call res_init() once per process. + msvcrt: Correct the spec file entry for _makepath. + shell32: Add a stub implementation for OpenAs_RunDLL. + urlmon: Add an implementation for CreateURLMonikerEx based on existing code for CreateURLMoniker. + msi: Install translators in the InstallODBC custom action. + msi: Install data sources in the InstallODBC custom action. + shell32: Add a stub implementation for SHMapIDListToImageListIndexAsync. + msi: Add a stub implementation for MsiEnumProductsEx{A, W}. + expand.exe: Add support for cabinet files. + +Huw Davies (5): + user32: Keep track of whether the app has asked for the text buffer handle. + user32: Add a function to return the length of the text buffer. + user32: Cache the text buffer length to avoid excessive calls to strlenW. + oleaut32: Don't try to free the typeinfo if get_funcdesc fails. + oleaut32: Rewrite get_funcdesc to avoid using the funcdesc's oVft member so that it works correctly for non-dual dispinterfaces. + +Hwang YunSong(황윤성) (2): + cmd: Updated Korean resource. + cmd: Updated Korean resource. + +Jacek Caban (1): + hhctrl.ocx: Don't insert content item that could not be merged. + +James Hawkins (9): + msi: Add tests for the concurrent installation custom action. + msi: Generalize the msi_custom_action_info struct so other custom actions can use it. + msi: Run the InstallExecute sequence if the InstallUISequnce table is empty. + msi: Add handling for the concurrent install custom action. + msi: Return MSICONDITION_NONE in MsiDatabaseIsTablePersistent if the table doesn't exist. + msi: Add the _Property table back, with tests. + msi: Add an internal MSI_ViewModify. + msi: Abstract MSI_RecordSetStream. + msi: Implement special handling for the _Streams table. + +Jan Zerebecki (2): + user32: Fix to succeed reliably in test where it works by accident. + wined3d: Remove resourceStoreCriticalSection. + +Jason Edmeades (2): + cmd.exe: Implement a basic 'more'. + cmd.exe: Support for DEL filename /s. + +Jesse Allen (1): + wined3d: Remove fake nvidia card in GetAdapterIdentifier. + +José Manuel Ferrer Ortiz (1): + winspool.drv: Add Spanish resources. + +Kai Blin (1): + secur32: Move NTLM debug output to a seperate "ntlm" channel. + +Ken Thomases (3): + shell32/tests: Added to-do test showing a bug with file paths with spaces. + shell32: Don't break file path at spaces in ShellExecuteEx if quoted. + shell32/tests: Test that quoting file path prevents masking at space. + +Kevin Koltzau (1): + user32: Draw menu item bitmaps in the correct location when the scroll arrows are active. + +Kirill K. Smirnov (3): + xcopy: Add Russian resource. + kernel32: Add partial stub for NeedCurrentDirectoryForExePath. + kernel32/tests: Add tests for NeedCurrentDirectoryForExePath. + +Lei Zhang (2): + wineshelllink: Fall back to $HOME if $HOME/Desktop does not exist. + comdlg32: Initialize CommDlgExtendedError() return value for file dialogs. + +Maarten Lankhorst (14): + winmm: Implement CALLBACK_WINDOW. + winmm: Pass the right message to hwnd from mixer callback. + winecfg: Update Dutch resources. + dsound: Make sure we're holding the lock on Drop And Stop. + dsound: Don't deadlock in capture because of callback. + winealsa: Drop unplayed frames instead of waiting for them. + winealsa: Clear WAVECAPS_DIRECTSOUND for capture. + winealsa: Remove disabled code. + winealsa: Introduce mixer code. + winealsa: Implement opening/closing and caps of device. + winealsa: Implement mixer controls, and add GetLineInfo. + winealsa: Implement GetLineControls in mixer. + winealsa: Implement Get/SetControlDetails in mixer. + winealsa: Unset WAVECAPS_DIRECTSOUND properly for capture. + +Marcus Meissner (1): + msi: Do not mark the tables const. + +Michael Kaufmann (1): + gdi32: Add a stub for CancelDC. + +Michael Stefaniuc (2): + janitorial: Pass HEAP_ZERO_MEMORY as flag to HeapAlloc() instead of zeroing out the allocated memory in a later call. + winealsa: Do not check for non-NULL before HeapFree'ing a variable as the check is redundant. + +Michał Wiernowolski (1): + winealsa: Improved handling of SysEx MIDI messages. + +Mikołaj Zalewski (6): + winecfg: Add Polish translation. + regedit: Update Polish translation. + comctl32: toolbar: Merge TOOLBAR_GetButtonInfoA and TB_GetButtonInfoW. + comctl32: toolbar: Don't execute TB_GETBUTTONINFO if cbSize is invalid. + comctl32: toolbar: In CreateToolbarEx the default bitmap size is also 16x16. + shlwapi: Fix the handling of overflows in PathCombine[AW]. + +Paul Vriens (8): + crypt32/tests: Use A-version for registry functions. + ws2_32/tests: Add required parameter to CreateThread (for Win9x and WinME). + kernel32/tests: CreateRemoteThread is not implemented on win98. + kernel32/tests: GetComputerNameW is not implemented on win98. + kernel32/tests: GetLongPathNameW is not implemented on win98. + setupapi/tests: SetupDiCreateDeviceInfoListExW is not implemented on win98. + setupapi/tests: SetupCopyOEMInfA is not available on NT4. + kernel32/tests: Resource functions are not implemented on win98. + +Rob Shearman (20): + msi: Add support for non-persistent strings. + msi: Move string loading and saving to string.c. + msi: Cleanup unneeded string table functions. + msi: Remove the hash table for a column when one of its values is modified since it will now be invalid. + msi: Store the column info in the MSITABLE structure. + msi: Move table creation to table.c. + msi: Create the table directly in create_table instead of requiring it to be loaded after saving. + msi: The HOLD keyword implies a temporary table, whereas database importing should lead to permanent tables, so remove the HOLD keyword. + msi: Add support for adding temporary/non-persistent data to tables. + msi: Don't add info to the _Columns table for non-persistent tables. + msi: Add a persistent flag to tables. + msi: All columns being temporary means the table is non-persistent. + msi: Add a non-persistent string instead of a persistent one if the table or row is non-persistent. + msi: Set rec to NULL after calling msiobj_release on it in msi_create_table so that we don't call msiobj_release on it again. + msi: Create the _Property table as a temporary table so that the properties aren't saved to the .msi file. + msi: Fix an off-by-one error when calculating the path and filename for the action data in the SelfRegModules action. + kernel32: Add the directory the executable was loaded from to the module search path if the module file name doesn't contain a path. + winebuild: Refer to strings used in generated stubs by symbol rather than by offset to avoid problems when the compiler aligns the strings by 2 or more bytes. + atl: Use the first entry in the object map in AtlInternalQueryInterface when IUnknown is requested. + atl: AtlModuleGetClassObject should store an intermediate pointer in obj->pCF and then query this for the requested interface. + +Rolf Kalbermatter (6): + advapi32: Implement QueryServiceStatusEx. + advapi32: Make QueryServiceStatus use QueryServiceStatusEx. + advapi32: Make SERVICE_STATUS_PROCESS match the declaration in MSDN and PSDK. + advapi32: Add EnumServicesStatusExA/W stub implementation. + advapi32: Make struct service_data_t have the new SERVICE_STATUS_PROCESS struct. + advapi32: Make service_start_process return the pid to the caller. + +Stefan Dösinger (15): + d3d: Enumerate palettized formats for ddraw. + d3d: Remove dependency on ddraw.h header. + d3d9: Do not allow Direct3D9::GetAdapterModeCount to be called with D3DFMT_UNKNOWN. + d3d9: Rework the converted vertex declaration management. + wined3d: Do not upload to the vbo if there's nothing to do. + wined3d: The cursor texture doesn't have GL_APPLE_client_storage backing. + wined3d: Do not allocate surfaces unless needed. + wined3d: Add a method to create a declaration from a fvf. + wined3d: Implement CreateVertexDeclarationFromFVF. + ddraw: Get rid of FVFs. + d3d: Fix ProcessVertices. + ddraw: Add a test for EnumSurfaces. + ddraw: Use EnumAttachedSurfaces to search for a render target. + ddraw: Search for texture sublevels with GetAttachedSurface. + ddraw: Use EnumAttachedSurfaces for SetColorKey. + +Stefan Leichter (1): + advapi32: More tests for RegDeleteTreeA. + +Tom Spear (1): + winecfg: Change WINE_ERR to WINE_TRACE since there is no real error. + +Yuval Fledel (8): + include: Fix a typo in wincrypt.h. + userenv: Make GetProfileType report a normal (non-roaming) profile. + include: Introduce ntsecpkg.h. + rsaenh: Convert handle type from unsigned int to HCRYPTKEY. + include: Introduce SECPKG_INTERFACE_VERSION and extend PSECPKG_FUNCTION_TABLE accordingly. + schannel: Implement SpLsaModeInitialize and GetInfo. + schannel: Implement SpUserModeInitialize. + schannel: Tests for SpLsaModeInitialize, SpUserModeInitialize and GetInfo. + +-- +Alexandre Julliard +julliard@winehq.org diff --git a/ChangeLog b/ChangeLog index 650141a1364..1ff85e076c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,1233 @@ +2007-04-24 Maarten Lankhorst + + * dlls/winealsa.drv/waveinit.c: + winealsa: Unset WAVECAPS_DIRECTSOUND properly for capture. + +2007-04-24 Chris Robinson + + * dlls/quartz/Makefile.in, dlls/quartz/main.c, dlls/quartz/mpegsplit.c, + dlls/quartz/quartz_private.h, dlls/quartz/regsvr.c: + quartz: Partially implement the MPEG 1 Stream Splitter filter. + +2007-04-25 Kirill K. Smirnov + + * dlls/kernel32/tests/path.c: + kernel32/tests: Add tests for NeedCurrentDirectoryForExePath. + + * dlls/kernel32/kernel32.spec, dlls/kernel32/path.c, include/winbase.h: + kernel32: Add partial stub for NeedCurrentDirectoryForExePath. + +2007-04-27 Alexandre Julliard + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Avoid sizeof in trace. + +2007-04-26 Kevin Koltzau + + * dlls/user32/menu.c: + user32: Draw menu item bitmaps in the correct location when the scroll arrows + are active. + +2007-04-26 Alexey Markachev + + * dlls/ntdll/time.c: + ntdll: Fix mistake in Novosibirsk time zone. + +2007-04-22 Stefan Dösinger + + * dlls/ddraw/surface.c: + ddraw: Use EnumAttachedSurfaces for SetColorKey. + + * dlls/ddraw/ddraw.c: + ddraw: Search for texture sublevels with GetAttachedSurface. + + * dlls/ddraw/ddraw.c: + ddraw: Use EnumAttachedSurfaces to search for a render target. + + * dlls/ddraw/tests/dsurface.c: + ddraw: Add a test for EnumSurfaces. + +2007-04-25 Andrew Riedi + + * dlls/winex11.drv/mouse.c: + winex11.drv: Add legacy 32-bit cursor support. + +2007-04-25 Yuval Fledel + + * .gitignore, Makefile.in, configure, configure.ac, dlls/Makefile.in, + dlls/schannel/tests/Makefile.in, dlls/schannel/tests/main.c, + programs/winetest/Makefile.in, programs/winetest/winetest.rc: + schannel: Tests for SpLsaModeInitialize, SpUserModeInitialize and GetInfo. + + * dlls/schannel/Makefile.in, dlls/schannel/schannel.spec, + dlls/schannel/usermode.c: + schannel: Implement SpUserModeInitialize. + + * dlls/schannel/Makefile.in, dlls/schannel/lsamode.c, + dlls/schannel/schannel.spec: + schannel: Implement SpLsaModeInitialize and GetInfo. + +2007-04-26 Emmanuel Maillard + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIIn_Prepare and MIDIIn_Unprepare. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIIn_AddBuffer. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIIn_Reset. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIIn_Start and MIDIIn_Stop. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIIn_GetNumDevs and MIDIIn_GetDevCaps. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIIn_Open and MIDIIn_Close. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Add MIDI In messages in MIDI_NotifyClient. + +2007-04-27 H. Verbeet + + * dlls/wined3d/device.c: + wined3d: Fix the return value for IWineD3DDeviceImpl_ColorFill. + +2007-04-26 Andrew Talbot + + * dlls/dplayx/dplay.c, dlls/dplayx/dplayx_global.c, + dlls/dplayx/dplayx_global.h, dlls/dplayx/name_server.c, + dlls/dplayx/name_server.h: + dplayx: Constify some variables. + +2007-04-26 Marcus Meissner + + * dlls/msi/table.c: + msi: Do not mark the tables const. + +2007-04-26 Ben Taylor + + * dlls/wineoss.drv/mixer.c: + wineoss: Fix to compile on Solaris 10. + +2007-04-26 Dmitry Timoshkov + + * dlls/user32/tests/msg.c, dlls/user32/winpos.c: + user32: Windows doesn't redraw a window if it is being just moved. + +2007-04-26 Huw Davies + + * dlls/oleaut32/tmarshal.c: + oleaut32: Rewrite get_funcdesc to avoid using the funcdesc's oVft member so + that it works correctly for non-dual dispinterfaces. + +2007-04-25 Huw Davies + + * dlls/oleaut32/tmarshal.c: + oleaut32: Don't try to free the typeinfo if get_funcdesc fails. + +2007-04-26 Alexandre Julliard + + * .gitignore, tools/make_makefiles: + make_makefiles: Avoid duplicate .gitignore entries. + +2007-04-25 Dan Hipschman + + * dlls/rpcrt4/tests/server.c, dlls/rpcrt4/tests/server.idl: + rpcrt4: Add a testcase for RPCs with fixed-size arrays. + + * tools/widl/proxy.c, tools/widl/server.c, tools/widl/typegen.c: + widl: Declare fixed-size array args as pointers to arrays. + + * .gitignore, dlls/rpcrt4/tests/Makefile.in, dlls/rpcrt4/tests/server.c, + dlls/rpcrt4/tests/server.idl: + rpcrt4: Add tests for RPC and widl generated code. + + * tools/widl/client.c, tools/widl/header.c, tools/widl/header.h, + tools/widl/server.c, tools/widl/widl.c, tools/widl/widl.h: + widl: Add --prefix-* options (take 3). + +2007-04-26 Emmanuel Maillard + + * dlls/winecoreaudio.drv/coremidi.c, dlls/winecoreaudio.drv/coremidi.h, + dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Initial MIDI In Mach message handling. + + * dlls/winecoreaudio.drv/coremidi.c, dlls/winecoreaudio.drv/coremidi.h, + dlls/winecoreaudio.drv/midi.c, + dlls/winecoreaudio.drv/winecoreaudio.drv.spec: + winecoreaudio: Initial MIDI In support on Mac OS X. + +2007-04-25 Jesse Allen + + * dlls/wined3d/directx.c: + wined3d: Remove fake nvidia card in GetAdapterIdentifier. + +2007-04-22 Stefan Dösinger + + * dlls/d3d9/device.c, dlls/ddraw/vertexbuffer.c, dlls/wined3d/device.c, + include/wine/wined3d_interface.h: + d3d: Fix ProcessVertices. + IDirect3DDevice9::ProcessVertices takes a vertex declaration, not a + vertex buffer. The source for ProcessVertices is taken from the + stateblock, not the vertex declaration. + + * dlls/ddraw/ddraw.c, dlls/ddraw/ddraw_private.h, dlls/ddraw/device.c, + dlls/ddraw/direct3d.c, dlls/ddraw/main.c, dlls/ddraw/vertexbuffer.c: + ddraw: Get rid of FVFs. + Remove all IWineD3DDevice::SetFVF calls and instead create converted + vertex declarations and use them. The idea is to remove the FVF paths + from wined3d to simplify the code, and optimize the vertex declaration + codepath. + +2007-04-25 Stefan Dösinger + + * dlls/wined3d/device.c, include/wine/wined3d_types.h: + wined3d: Implement CreateVertexDeclarationFromFVF. + +2007-04-22 Stefan Dösinger + + * dlls/wined3d/device.c, include/wine/wined3d_interface.h: + wined3d: Add a method to create a declaration from a fvf. + + * dlls/wined3d/surface.c, dlls/wined3d/wined3d_private.h: + wined3d: Do not allocate surfaces unless needed. + +2007-04-26 Alexandre Julliard + + * dlls/cabinet/fdi.c: + cabinet: Make sure we don't try to close an invalid file handle. + + * programs/winedbg/dbg.y, programs/winedbg/debug.l, + programs/winedbg/symbol.c: + winedbg: Properly handle EOF on input. + +2007-04-26 Paul Vriens + + * dlls/kernel32/tests/resource.c: + kernel32/tests: Resource functions are not implemented on win98. + + * dlls/setupapi/tests/misc.c: + setupapi/tests: SetupCopyOEMInfA is not available on NT4. + +2007-04-25 Clinton Stimpson + + * dlls/riched20/caret.c, dlls/riched20/tests/editor.c: + riched20: Set modify state when removing text. + +2007-04-25 Andrew Talbot + + * dlls/dplayx/dplayx_global.c: + dplayx: Fix a typo. + + * dlls/dnsapi/query.c: + dnsapi: Constify some variables. + +2007-04-25 Hans Leidekker + + * programs/expand/Makefile.in, programs/expand/expand.c: + expand.exe: Add support for cabinet files. + + * dlls/msi/msi.spec, dlls/msi/registry.c: + msi: Add a stub implementation for MsiEnumProductsEx{A, W}. + + * dlls/shell32/iconcache.c, dlls/shell32/shell32.spec: + shell32: Add a stub implementation for SHMapIDListToImageListIndexAsync. + +2007-04-25 Jacek Caban + + * dlls/hhctrl.ocx/content.c: + hhctrl.ocx: Don't insert content item that could not be merged. + +2007-04-25 Paul Vriens + + * dlls/setupapi/tests/devinst.c: + setupapi/tests: SetupDiCreateDeviceInfoListExW is not implemented on win98. + + * dlls/kernel32/tests/path.c: + kernel32/tests: GetLongPathNameW is not implemented on win98. + + * dlls/kernel32/tests/environ.c: + kernel32/tests: GetComputerNameW is not implemented on win98. + + * dlls/kernel32/tests/thread.c: + kernel32/tests: CreateRemoteThread is not implemented on win98. + +2007-04-25 Emmanuel Maillard + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIOut_Reset. + + * dlls/winecoreaudio.drv/coremidi.h, dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIOut_GetVolume and MIDIOut_SetVolume. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIOut_LongData. + + * dlls/winecoreaudio.drv/coremidi.h, dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIOut_Data. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIOut_Prepare and MIDIOut_Unprepare. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDIOut_GetDevCaps and MIDIOut_GetNumDevs. + + * dlls/winecoreaudio.drv/midi.c: + winecoreaudio: Implement MIDI_NotifyClient, MIDIOut_Open and MIDIOut_Close. + + * configure, configure.ac, dlls/winecoreaudio.drv/Makefile.in, + dlls/winecoreaudio.drv/audiounit.c, + dlls/winecoreaudio.drv/coreaudio.c, + dlls/winecoreaudio.drv/coreaudio.h, + dlls/winecoreaudio.drv/coremidi.c, dlls/winecoreaudio.drv/coremidi.h, + dlls/winecoreaudio.drv/midi.c, + dlls/winecoreaudio.drv/winecoreaudio.drv.spec: + winecoreaudio: Initial MIDI support on Mac OS X. + +2007-04-25 James Hawkins + + * dlls/msi/Makefile.in, dlls/msi/msipriv.h, dlls/msi/query.h, + dlls/msi/streams.c, dlls/msi/string.c, dlls/msi/table.c, + dlls/msi/tests/db.c: + msi: Implement special handling for the _Streams table. + +2007-04-25 Rob Shearman + + * dlls/atl/atl_main.c: + atl: AtlModuleGetClassObject should store an intermediate pointer in obj->pCF + and then query this for the requested interface. + Return CLASS_E_CLASSNOTAVAILABLE instead of E_FAIL. + + * dlls/atl/atl_main.c: + atl: Use the first entry in the object map in AtlInternalQueryInterface when + IUnknown is requested. + + * tools/winebuild/import.c: + winebuild: Refer to strings used in generated stubs by symbol rather than by + offset to avoid problems when the compiler aligns the strings by 2 or more bytes. + +2007-04-25 Paul Vriens + + * dlls/ws2_32/tests/sock.c: + ws2_32/tests: Add required parameter to CreateThread (for Win9x and WinME). + +2007-04-25 Michael Stefaniuc + + * dlls/winealsa.drv/mixer.c: + winealsa: Do not check for non-NULL before HeapFree'ing a variable as the + check is redundant. + + * dlls/dbghelp/module.c, dlls/gdi32/tests/font.c, dlls/imm32/imm.c, + dlls/msvfw32/msvideo_main.c, dlls/ntdll/tests/port.c, + dlls/ole32/storage32.c, dlls/winex11.drv/xfont.c, dlls/wininet/ftp.c, + dlls/wininet/internet.c, dlls/winspool.drv/info.c, + programs/oleview/tree.c, programs/oleview/typelib.c: + janitorial: Pass HEAP_ZERO_MEMORY as flag to HeapAlloc() instead of zeroing + out the allocated memory in a later call. + +2007-04-25 Yuval Fledel + + * include/ntsecpkg.h: + include: Introduce SECPKG_INTERFACE_VERSION and extend PSECPKG_FUNCTION_TABLE + accordingly. + +2007-04-24 Andrew Talbot + + * dlls/dmband/dmutils.c: + dmband: Constify some variables. + + * dlls/dmstyle/dmutils.c: + dmstyle: Constify some variables. + + * dlls/dmime/dmutils.c: + dmime: Constify some variables. + + * dlls/dmloader/debug.c, dlls/dmloader/debug.h: + dmloader: Constify some variables. + + * dlls/dmscript/dmscript_main.c, dlls/dmscript/dmscript_private.h: + dmscript: Constify a variable. + + * dlls/dmusic/dmusic_main.c, dlls/dmusic/dmusic_private.h: + dmusic: Constify a variable. + + * dlls/dmcompos/dmcompos_main.c, dlls/dmcompos/dmcompos_private.h: + dmcompos: Constify a variable. + +2007-04-24 Michał Wiernowolski + + * dlls/winealsa.drv/midi.c: + winealsa: Improved handling of SysEx MIDI messages. + +2007-04-24 Aric Stewart + + * dlls/usp10/usp10.c: + usp10: Do not crash in ScriptPlace if pABC is null. + +2007-04-24 Tom Spear + + * programs/winecfg/driveui.c: + winecfg: Change WINE_ERR to WINE_TRACE since there is no real error. + +2007-04-24 Rob Shearman + + * dlls/kernel32/module.c: + kernel32: Add the directory the executable was loaded from to the module search + path if the module file name doesn't contain a path. + + * dlls/msi/action.c: + msi: Fix an off-by-one error when calculating the path and filename for the + action data in the SelfRegModules action. + The backslash is in p[0], not p[1]. + + * dlls/msi/package.c: + msi: Create the _Property table as a temporary table so that the properties + aren't saved to the .msi file. + + * dlls/msi/table.c: + msi: Set rec to NULL after calling msiobj_release on it in msi_create_table + so that we don't call msiobj_release on it again. + +2007-04-24 Maarten Lankhorst + + * dlls/winealsa.drv/mixer.c: + winealsa: Implement Get/SetControlDetails in mixer. + + * dlls/winealsa.drv/mixer.c: + winealsa: Implement GetLineControls in mixer. + + * dlls/winealsa.drv/mixer.c: + winealsa: Implement mixer controls, and add GetLineInfo. + + * dlls/winealsa.drv/mixer.c: + winealsa: Implement opening/closing and caps of device. + + * dlls/winealsa.drv/Makefile.in, dlls/winealsa.drv/mixer.c, + dlls/winealsa.drv/winealsa.drv.spec: + winealsa: Introduce mixer code. + +2007-04-23 Rob Shearman + + * dlls/msi/table.c: + msi: Add a non-persistent string instead of a persistent one if the table or + row is non-persistent. + + * dlls/msi/create.c, dlls/msi/query.h, dlls/msi/sql.y, + dlls/msi/tests/db.c: + msi: All columns being temporary means the table is non-persistent. + The HOLD keyword just means that the non-persistent data in the table + should be kept around, not that the table is temporary. + +2007-04-24 Rob Shearman + + * dlls/msi/table.c, dlls/msi/tests/db.c: + msi: Add a persistent flag to tables. + Implement MSI_DatabaseIsTablePersistent. + +2007-04-23 Rob Shearman + + * dlls/msi/table.c, dlls/msi/tests/db.c: + msi: Don't add info to the _Columns table for non-persistent tables. + + * dlls/msi/insert.c, dlls/msi/msipriv.h, dlls/msi/select.c, + dlls/msi/table.c: + msi: Add support for adding temporary/non-persistent data to tables. + + * dlls/msi/database.c: + msi: The HOLD keyword implies a temporary table, whereas database importing + should lead to permanent tables, so remove the HOLD keyword. + + * dlls/msi/table.c: + msi: Create the table directly in create_table instead of requiring it to be + loaded after saving. + + * dlls/msi/create.c, dlls/msi/query.h, dlls/msi/table.c: + msi: Move table creation to table.c. + + * dlls/msi/table.c: + msi: Store the column info in the MSITABLE structure. + Load the data on view creation for simplicity instead of view execution. + + * dlls/msi/table.c: + msi: Remove the hash table for a column when one of its values is modified + since it will now be invalid. + + * dlls/msi/msipriv.h, dlls/msi/string.c: + msi: Cleanup unneeded string table functions. + Make string table functions that aren't used outside of string.c static. + + * dlls/msi/database.c, dlls/msi/msipriv.h, dlls/msi/string.c, + dlls/msi/table.c: + msi: Move string loading and saving to string.c. + + * dlls/msi/msipriv.h, dlls/msi/string.c, dlls/msi/table.c: + msi: Add support for non-persistent strings. + Store the loaded refcount in the string table. + +2007-04-24 Dmitry Timoshkov + + * dlls/comctl32/imagelist.c, dlls/comctl32/tests/imagelist.c: + comctl32: Add more image list tests, fix one problem found. + +2007-04-24 Paul Vriens + + * dlls/crypt32/tests/oid.c: + crypt32/tests: Use A-version for registry functions. + +2007-04-24 Andrew Talbot + + * dlls/dinput/device.c, dlls/dinput/device_private.h, + dlls/dinput/effect_linuxinput.c, dlls/dinput/joystick_linux.c: + dinput: Constify some variables. + +2007-04-24 Rolf Kalbermatter + + * dlls/advapi32/service.c: + advapi32: Make service_start_process return the pid to the caller. + + * dlls/advapi32/service.c: + advapi32: Make struct service_data_t have the new SERVICE_STATUS_PROCESS struct. + +2007-04-23 Jason Edmeades + + * programs/cmd/README, programs/cmd/builtins.c, programs/cmd/directory.c, + programs/cmd/wcmd.h, programs/cmd/wcmdmain.c: + cmd.exe: Support for DEL filename /s. + +2007-04-24 Detlef Riekenberg + + * dlls/localui/localui.c, dlls/localui/localui.h: + localui: Implement ConfigurePortUI for COMx. + + * dlls/localui/localui.c: + localui: Avoid crash on NULL pointer. + +2007-04-23 Lei Zhang + + * dlls/comdlg32/filedlg.c, dlls/comdlg32/tests/Makefile.in, + dlls/comdlg32/tests/filedlg.c: + comdlg32: Initialize CommDlgExtendedError() return value for file dialogs. + +2007-04-23 H. Verbeet + + * dlls/wined3d/volume.c, dlls/wined3d/volumetexture.c, + include/wine/wined3d_interface.h: + wined3d: The second parameter to glTexImage3DEXT isn't a GLenum. + + * dlls/wined3d/volume.c: + wined3d: Improve IWineD3DVolumeImpl_LoadTexture TRACE output. + + * dlls/wined3d/device.c: + wined3d: Actually use the calculated mipmap surface sizes in + IWineD3DDeviceImpl_CreateVolumeTexture. + + * dlls/wined3d/utils.c, dlls/wined3d/wined3d_private.h: + wined3d: Output pretty GL errors in checkGLcall and vcheckGLcall. + +2007-04-05 Mikołaj Zalewski + + * dlls/shlwapi/path.c, dlls/shlwapi/tests/path.c: + shlwapi: Fix the handling of overflows in PathCombine[AW]. + + * dlls/comctl32/commctrl.c, dlls/comctl32/tests/toolbar.c: + comctl32: toolbar: In CreateToolbarEx the default bitmap size is also 16x16. + + * dlls/comctl32/tests/toolbar.c, dlls/comctl32/toolbar.c: + comctl32: toolbar: Don't execute TB_GETBUTTONINFO if cbSize is invalid. + + * dlls/comctl32/toolbar.c: + comctl32: toolbar: Merge TOOLBAR_GetButtonInfoA and TB_GetButtonInfoW. + +2007-04-04 Mikołaj Zalewski + + * programs/regedit/Pl.rc: + regedit: Update Polish translation. + +2007-04-23 Mikołaj Zalewski + + * programs/winecfg/Pl.rc, programs/winecfg/winecfg.rc: + winecfg: Add Polish translation. + +2007-04-21 Maarten Lankhorst + + * dlls/winealsa.drv/wavein.c, dlls/winealsa.drv/waveout.c: + winealsa: Remove disabled code. + SND_PCM_ASYNC was needed to get asynchronous callbacks, but they are + not used any more, so remove the code. + + * dlls/winealsa.drv/waveinit.c: + winealsa: Clear WAVECAPS_DIRECTSOUND for capture. + +2007-04-19 David Adam + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMQuaternionSlerp. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMQuaternionFromRotation. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMMatrixFromQuaternion. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMVectorRotate. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c: + d3drm: Implement D3DRMQuaternionMultiply. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMVectorReflect. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c: + d3drm: Implement D3DRMVectorRandom. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMVectorNormalize. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMVectorscale. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMVectorModulus. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMVectorDotProduct. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DRMVectorCrossProduct. + + * dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, dlls/d3drm/tests/vector.c: + d3drm: Implement D3DVectorSubtract. + + * .gitignore, Makefile.in, configure, configure.ac, dlls/Makefile.in, + dlls/d3drm/Makefile.in, dlls/d3drm/d3drm.spec, dlls/d3drm/math.c, + dlls/d3drm/tests/Makefile.in, dlls/d3drm/tests/vector.c, + programs/winetest/Makefile.in, programs/winetest/winetest.rc: + d3drm: Implement D3DRMVectorAdd. + + * include/Makefile.in, include/d3drmdef.h: + include: Add d3drmdef.h header. + +2007-04-21 Andrew Talbot + + * dlls/amstream/amstream.c, dlls/amstream/main.c, + dlls/amstream/mediastream.c, dlls/amstream/regsvr.c: + amstream: Exclude unused headers. + + * dlls/avifil32/acmstream.c, dlls/avifil32/api.c, + dlls/avifil32/editstream.c, dlls/avifil32/factory.c, + dlls/avifil32/getframe.c, dlls/avifil32/icmstream.c, + dlls/avifil32/regsvr.c, dlls/avifil32/tmpfile.c: + avifil32: Exclude unused headers. + + * dlls/avicap32/avicap32_main.c: + avicap32: Exclude unused header. + + * dlls/advpack/advpack.c, dlls/advpack/install.c, dlls/advpack/reg.c: + advpack: Exclude unused headers. + + * dlls/acledit/main.c: + acledit: Exclude unused headers. + + * dlls/activeds/activeds_main.c: + activeds: Exclude unused headers. + +2007-04-22 Stefan Leichter + + * dlls/advapi32/tests/registry.c: + advapi32: More tests for RegDeleteTreeA. + +2007-04-23 Alexandre Julliard + + * configure, configure.ac, include/config.h.in: + configure: Use AC_SEARCH_LIBS for the Solaris libs to avoid unused function + checks. + +2007-04-23 Ben Taylor + + * configure, configure.ac: + configure: Fix to properly recognize functions on Solaris. + +2007-04-20 Maarten Lankhorst + + * dlls/winealsa.drv/dsoutput.c: + winealsa: Drop unplayed frames instead of waiting for them. + +2007-04-21 James Hawkins + + * dlls/msi/msipriv.h, dlls/msi/record.c: + msi: Abstract MSI_RecordSetStream. + + * dlls/msi/msipriv.h, dlls/msi/msiquery.c: + msi: Add an internal MSI_ViewModify. + +2007-04-21 Yuval Fledel + + * dlls/rsaenh/handle.c, dlls/rsaenh/handle.h, dlls/rsaenh/rsaenh.c: + rsaenh: Convert handle type from unsigned int to HCRYPTKEY. + + * include/Makefile.in, include/ntsecpkg.h: + include: Introduce ntsecpkg.h. + +2007-04-19 EA Durbin + + * Makefile.in, configure, configure.ac, dlls/Makefile.in, + dlls/sxs/Makefile.in, dlls/sxs/sxs.c, dlls/sxs/sxs.spec: + sxs: Add new dll stub. + +2007-04-23 Alexandre Julliard + + * dlls/ntdll/file.c, include/wine/server_protocol.h, server/file.c, + server/protocol.def: + server: Return a more correct fd type for anonymous files. + + * dlls/version/tests/info.c: + version: Avoid size_t type in traces. + + * dlls/dbghelp/msc.c: + dbghelp: Don't print garbage chars in ERR message. + +2007-04-21 Andrew Talbot + + * dlls/ddraw/ddraw_private.h, dlls/ddraw/executebuffer.c, + dlls/ddraw/light.c, dlls/ddraw/main.c, dlls/ddraw/material.c, + dlls/ddraw/utils.c, dlls/ddraw/viewport.c: + ddraw: Constify some variables. + +2007-04-22 Alasdair Sinclair + + * dlls/advapi32/crypt_des.c: + advapi32: Fix one byte array overflow during DES unhash. + +2007-04-22 Rolf Kalbermatter + + * dlls/advapi32/advapi32.spec, dlls/advapi32/service.c: + advapi32: Add EnumServicesStatusExA/W stub implementation. + + * dlls/advapi32/service.c, include/winsvc.h: + advapi32: Make SERVICE_STATUS_PROCESS match the declaration in MSDN and PSDK. + +2007-04-22 Hans Leidekker + + * dlls/msi/action.c, include/msidefs.h, include/odbcinst.h: + msi: Install data sources in the InstallODBC custom action. + + * dlls/msi/action.c: + msi: Install translators in the InstallODBC custom action. + + * dlls/urlmon/umon.c, dlls/urlmon/urlmon.spec, include/urlmon.idl: + urlmon: Add an implementation for CreateURLMonikerEx based on existing code + for CreateURLMoniker. + +2007-04-21 Maarten Lankhorst + + * dlls/dsound/capture.c: + dsound: Don't deadlock in capture because of callback. + +2007-04-20 Maarten Lankhorst + + * dlls/dsound/primary.c: + dsound: Make sure we're holding the lock on Drop And Stop. + +2007-04-21 James Hawkins + + * dlls/msi/msipriv.h, dlls/msi/package.c, dlls/msi/tests/format.c, + dlls/msi/tests/package.c: + msi: Add the _Property table back, with tests. + + * dlls/msi/msipriv.h, dlls/msi/table.c, dlls/msi/tests/db.c: + msi: Return MSICONDITION_NONE in MsiDatabaseIsTablePersistent if the table + doesn't exist. + +2007-04-23 Hwang YunSong(황윤성) + + * programs/cmd/Ko.rc: + cmd: Updated Korean resource. + +2007-04-23 Dmitry Timoshkov + + * dlls/comctl32/imagelist.c, dlls/comctl32/tests/imagelist.c: + comctl32: Add an image list storage test, make it pass under Wine. + +2007-04-21 Dmitry Timoshkov + + * dlls/comctl32/imagelist.h: + comctl32: Use packing only for public ILHEAD structure, 2 bytes packing + is enough. + +2007-04-23 Dmitry Timoshkov + + * dlls/comctl32/imagelist.c: + comctl32: Fix an off by one error in ImageList_Remove. + +2007-04-21 Dmitry Timoshkov + + * dlls/advapi32/security.c: + advapi32: Thunk GetFileSecurityW to NtQuerySecurityObject. + +2007-04-20 Lei Zhang + + * tools/wineshelllink: + wineshelllink: Fall back to $HOME if $HOME/Desktop does not exist. + +2007-04-20 Yuval Fledel + + * dlls/userenv/userenv_main.c: + userenv: Make GetProfileType report a normal (non-roaming) profile. + + * include/wincrypt.h: + include: Fix a typo in wincrypt.h. + +2007-04-20 Fabian Bieler + + * dlls/wined3d/state.c, dlls/wined3d/vertexshader.c, + dlls/wined3d/wined3d_private.h: + wined3d: Remove usesFog flag from IWineD3DVertexShaderImpl. + + * dlls/d3d9/tests/visual.c: + d3d9/tests: Fix fog with shader test. + +2007-04-20 Maarten Lankhorst + + * programs/winecfg/Nl.rc: + winecfg: Update Dutch resources. + + * dlls/winmm/winmm.c: + winmm: Pass the right message to hwnd from mixer callback. + +2007-04-20 Gerald Pfeifer + + * server/fd.c: + server: Silence compiler warning in fd_queue_async(). + +2007-04-20 Kirill K. Smirnov + + * programs/xcopy/Ru.rc, programs/xcopy/rsrc.rc: + xcopy: Add Russian resource. + +2007-04-20 Rolf Kalbermatter + + * dlls/advapi32/service.c: + advapi32: Make QueryServiceStatus use QueryServiceStatusEx. + + * dlls/advapi32/service.c, include/winsvc.h: + advapi32: Implement QueryServiceStatusEx. + Based on a patch by Anastasius Focht. + +2007-04-19 Stefan Dösinger + + * dlls/wined3d/device.c: + wined3d: The cursor texture doesn't have GL_APPLE_client_storage backing. + +2007-04-19 Huw Davies + + * dlls/user32/edit.c: + user32: Cache the text buffer length to avoid excessive calls to strlenW. + + * dlls/user32/edit.c: + user32: Add a function to return the length of the text buffer. + + * dlls/user32/edit.c: + user32: Keep track of whether the app has asked for the text buffer handle. + +2007-04-19 Aric Stewart + + * dlls/gdi32/freetype.c: + gdi32: Make the comparison for system link font replacement not case sensitive. + +2007-04-19 Stefan Dösinger + + * dlls/wined3d/indexbuffer.c: + wined3d: Do not upload to the vbo if there's nothing to do. + +2007-04-19 Andrew Talbot + + * dlls/dbghelp/dbghelp_private.h, dlls/dbghelp/storage.c, + dlls/dbghelp/symbol.c, dlls/dbghelp/type.c: + dbghelp: Constify some variables. + +2007-04-19 Detlef Riekenberg + + * dlls/localspl/localmon.c, dlls/localspl/localspl_private.h, + dlls/localspl/spl_De.rc, dlls/localspl/spl_En.rc, + dlls/localspl/spl_Fr.rc, dlls/localspl/spl_Ko.rc, + dlls/localspl/spl_No.rc, dlls/localspl/spl_Pl.rc: + localspl: ConfigurePort is now in localui.dll. + + * dlls/localui/Makefile.in, dlls/localui/localui.c, + dlls/localui/localui.h, dlls/localui/localui.rc, + dlls/localui/ui_En.rc: + localui: Implement ConfigurePortUI. + + * dlls/localspl/localmon.c: + localspl: DeletePort is now in localui.dll. + +2007-04-18 Andrew Talbot + + * dlls/dbghelp/msc.c: + dbghelp: Constify some variables. + +2007-04-18 H. Verbeet + + * dlls/wined3d/utils.c: + wined3d: Remove GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT from + debug_fbostatus(). + +2007-04-18 Hans Leidekker + + * dlls/shell32/shell32.spec, dlls/shell32/shlexec.c: + shell32: Add a stub implementation for OpenAs_RunDLL. + + * dlls/msvcrt/msvcrt.spec: + msvcrt: Correct the spec file entry for _makepath. + + * dlls/dnsapi/query.c, dlls/iphlpapi/iphlpapi_main.c: + iphlpapi: Only call res_init() once per process. + +2007-04-18 Aric Stewart + + * dlls/shell32/shell32_main.c: + shell32: SHGFI_EXETYPE flag should have the files returning 0 if they are + DLL images. + +2007-04-18 Alexandre Julliard + + * server/named_pipe.c: + server: Don't give out read/write access to the named pipe device. + + * server/fd.c, server/named_pipe.c: + server: Use the standard file descriptor wait queue for named pipe server + async waits. + + * dlls/ntdll/file.c, include/wine/server_protocol.h, server/named_pipe.c, + server/protocol.def, server/request.h, server/trace.c: + server: Moved the FSCTL_PIPE_LISTEN implementation to the server. + + * server/fd.c, server/file.h: + server: Allow specifying the status code to return on file descriptors that + don't have a Unix fd. + +2007-04-17 Ken Thomases + + * dlls/shell32/tests/shlexec.c: + shell32/tests: Test that quoting file path prevents masking at space. + + * dlls/shell32/shlexec.c: + shell32: Don't break file path at spaces in ShellExecuteEx if quoted. + + * dlls/shell32/tests/shlexec.c: + shell32/tests: Added to-do test showing a bug with file paths with spaces. + If ShellExecuteEx is asked to execute a file which has a space in its path, + and if there exists a "masking" file whose name matches the path truncated + at a space, then ShellExecuteEx launches the masking file instead. + +2007-04-17 Stefan Dösinger + + * dlls/d3d9/d3d9_private.h, dlls/d3d9/device.c, dlls/d3d9/directx.c, + dlls/d3d9/tests/vertexdeclaration.c, dlls/d3d9/vertexdeclaration.c: + d3d9: Rework the converted vertex declaration management. + Instead of creating a converted declaration each time SetFVF is + called, exactly one declaration is created for each FVF(on demand) and + stored for the lifetime of the device. This avoids memory leaks and + makes keeping track of converted declarations easier. Wether a + declaration is converted from a fvf or not is now a static information + inside the declaration. Those declarations are not destroyed in + VertexDeclaration::Release, they stay for the lifetime of the + device. This keeps us free from tracking the declaration through + stateblocks + +2007-04-14 Bernd Buschinski + + * dlls/wined3d/drawprim.c: + wined3d: Fix drawStridedSlow typo. + +2007-04-17 Francois Gouget + + * dlls/advapi32/tests/registry.c: + advapi32/tests: Use memcmp() instead of strcmp() so that we can check + 'intrazeroed' strings. + +2007-04-17 José Manuel Ferrer Ortiz + + * dlls/winspool.drv/Es.rc, dlls/winspool.drv/winspool.rc: + winspool.drv: Add Spanish resources. + +2007-04-18 Andrew Talbot + + * dlls/uxtheme/msstyles.h: + uxtheme: Fix conflicting declarations. + +2007-04-17 Andrew Talbot + + * dlls/dbghelp/dwarf.c, dlls/dbghelp/minidump.c, dlls/dbghelp/module.c: + dbghelp: Constify some variables. + +2007-04-17 Detlef Riekenberg + + * dlls/localui/Makefile.in, dlls/localui/localui.c: + localui: Implement DeletePortUI. + + * dlls/localspl/Makefile.in, dlls/localspl/localmon.c: + localspl: Implement XcvData_AddPort. + + * .gitignore, dlls/Makefile.in, dlls/spoolss/Makefile.in: + spoolss: Build the import library. + +2007-04-17 Aric Stewart + + * programs/taskmgr/Ja.rc, programs/taskmgr/taskmgr.rc: + taskmgr: Add Japanese resource. + +2007-04-17 Alexandre Julliard + + * dlls/kernel32/tests/pipe.c, dlls/ntdll/file.c, + include/wine/server_protocol.h, server/named_pipe.c, + server/protocol.def, server/request.h, server/trace.c: + server: Move the FSCTL_PIPE_WAIT ioctl implementation to the server. + + * include/wine/server_protocol.h, server/fd.c, server/file.h, + server/named_pipe.c, server/protocol.def, server/trace.c, + tools/make_requests: + server: Add a specific data type for ioctl codes so they can be printed + as symbols. + + * dlls/kernel32/sync.c, dlls/ntdll/file.c, dlls/ntdll/nt.c, + dlls/ntdll/ntdll_misc.h, dlls/ntdll/process.c, dlls/ntdll/server.c, + dlls/ntdll/sync.c, dlls/ntdll/thread.c, dlls/ntdll/time.c, + dlls/user32/message.c, include/wine/server_protocol.h, + server/async.c, server/fd.c, server/file.h, server/mailslot.c, + server/main.c, server/named_pipe.c, server/object.h, + server/process.c, server/process.h, server/protocol.def, + server/queue.c, server/registry.c, server/request.c, server/serial.c, + server/thread.c, server/thread.h, server/timer.c, server/trace.c, + server/winstation.c, tools/make_requests: + server: Change the timeout handling to use NT-style 64-bit timeouts everywhere. + +2007-04-16 Dmitry Timoshkov + + * dlls/version/info.c, dlls/version/tests/info.c, + dlls/version/tests/version.rc: + version: Add a VerQueryValue test, make it mostly pass under Wine. + +2007-04-17 Stefan Dösinger + + * dlls/d3d9/directx.c: + d3d9: Do not allow Direct3D9::GetAdapterModeCount to be called with + D3DFMT_UNKNOWN. + +2007-04-16 Michael Kaufmann + + * dlls/gdi32/dc.c, dlls/gdi32/gdi32.spec: + gdi32: Add a stub for CancelDC. + +2007-04-16 H. Verbeet + + * dlls/wined3d/device.c: + wined3d: Implement ColorFill using FBOs, if they're being used. + + * dlls/wined3d/swapchain.c: + wined3d: Don't try to clear the depth stencil if there is none. + + * dlls/wined3d/device.c: + wined3d: Properly handle the difference between GL_BACK and GL_FRONT for + onscreen surfaces. + + * dlls/wined3d/surface.c: + wined3d: Use surface_get_gl_buffer where appropriate. + + * dlls/wined3d/surface.c, dlls/wined3d/wined3d_private.h: + wined3d: Add a function to determine if a surface is the front or the backbuffer + for a swapchain, and return the corresponding GLenum. + + * dlls/wined3d/device.c: + wined3d: Set the FBO drawbuffer using glDrawBuffer when ARB_DRAW_BUFFERS is + not supported. + + * dlls/wined3d/device.c: + wined3d: Ignore SetTextureStageState on unsupported texture stages. + + * dlls/wined3d/utils.c: + wined3d: Use GL_UNSIGNED_BYTE as data type for WINED3DFMT_A8. + + * dlls/wined3d/device.c: + wined3d: Dump the FBO's attachments when its status is + GL_FRAMEBUFFER_UNSUPPORTED_EXT. + + * dlls/wined3d/device.c, dlls/wined3d/utils.c, + dlls/wined3d/wined3d_private.h: + wined3d: Add a function for dumping FBO status codes. + +2007-04-16 Alexandre Julliard + + * dlls/ntdll/directory.c, dlls/ntdll/file.c, + include/wine/server_protocol.h, server/fd.c, server/protocol.def, + server/request.h, server/trace.c: + server: Move the server part of device unmounting to the ioctl processing. + + * dlls/kernel32/tests/pipe.c, dlls/ntdll/file.c, + include/wine/server_protocol.h, server/named_pipe.c, + server/protocol.def, server/request.h, server/trace.c: + server: Implement the FSCTL_PIPE_DISCONNECT ioctl on the server side. + + * dlls/ntdll/file.c, include/wine/server_protocol.h, server/change.c, + server/fd.c, server/file.c, server/file.h, server/mailslot.c, + server/named_pipe.c, server/process.c, server/protocol.def, + server/queue.c, server/request.c, server/request.h, server/serial.c, + server/signal.c, server/sock.c, server/thread.c, server/trace.c: + server: Add infrastructure for ioctl server request. + + * dlls/kernel32/sync.c: + kernel32: Use the correct access rights when opening named pipes. + +2007-04-16 Jan Zerebecki + + * dlls/wined3d/device.c, dlls/wined3d/wined3d_main.c: + wined3d: Remove resourceStoreCriticalSection. + + * dlls/user32/cursoricon.c: + user32: Fix to succeed reliably in test where it works by accident. + +2007-04-16 Eric Pouech + + * Makefile.in, configure, configure.ac, dlls/Makefile.in, + dlls/acledit/Makefile.in, dlls/acledit/acledit.spec, + dlls/acledit/main.c: + acledit: Stubbed out acledit DLL, needed by SysInternals process explorer. + +2007-04-16 Damjan Jovanovic + + * dlls/mapi32/mapi32.spec, dlls/mapi32/mapi32_main.c: + mapi32: MAPIAdminProfiles stub. + +2007-04-15 Alban Browaeys + + * dlls/wininet/urlcache.c: + wininet: Fix szCacheContent in URLCacheContainer_OpenIndex. + + * dlls/msi/action.c: + msi: Move msi_free(msiFilePath) to enable ERR message to use it before it + is freed. + +2007-04-14 Stefan Dösinger + + * dlls/d3d8/d3d8_private.h, dlls/d3d8/device.c, dlls/d3d9/d3d9_private.h, + dlls/d3d9/device.c, dlls/ddraw/ddraw.c, dlls/ddraw/surface.c, + dlls/wined3d/device.c, dlls/wined3d/directx.c, + dlls/wined3d/palette.c, dlls/wined3d/query.c, dlls/wined3d/state.c, + dlls/wined3d/surface.c, dlls/wined3d/surface_gdi.c, + dlls/wined3d/swapchain.c, dlls/wined3d/wined3d_private.h, + include/wine/wined3d_interface.h, include/wine/wined3d_types.h: + d3d: Remove dependency on ddraw.h header. + +2007-04-16 Detlef Riekenberg + + * include/winspool.h: + include/winspool: Declare missing function. + +2007-04-14 Andrew Talbot + + * dlls/shlwapi/ordinal.c: + slwapi: Make function definitions and declarations agree. + + * dlls/shlwapi/reg.c, dlls/shlwapi/thread.c: + slwapi: Make function definitions and declarations agree. + + * dlls/user32/network.c, include/wine/winnet16.h, + include/wine/winuser16.h: + user32: Make function definitions and declarations agree. + + * dlls/crypt32/sip.c, dlls/crypt32/store.c, dlls/crypt32/str.c: + crypt32: Constify some variables. + + * dlls/crypt32/protectdata.c: + crypt32: Constify some variables. + +2007-04-13 Jason Edmeades + + * programs/cmd/Cs.rc, programs/cmd/De.rc, programs/cmd/En.rc, + programs/cmd/Es.rc, programs/cmd/Fr.rc, programs/cmd/Ja.rc, + programs/cmd/Ko.rc, programs/cmd/Nl.rc, programs/cmd/No.rc, + programs/cmd/Pl.rc, programs/cmd/Pt.rc, programs/cmd/Ru.rc, + programs/cmd/Si.rc, programs/cmd/Tr.rc, programs/cmd/builtins.c, + programs/cmd/directory.c, programs/cmd/wcmd.h, + programs/cmd/wcmdmain.c: + cmd.exe: Implement a basic 'more'. + This implements a basic more, eg 'dir | more' or 'more file.c' + but it does not support the flags or keys which can control it. + Basically its not worth implementing those, as in some modes + we cannot read a single key, we have to wait for anyway. + +2007-04-13 Maarten Lankhorst + + * dlls/winmm/tests/mixer.c, dlls/winmm/winmm.c: + winmm: Implement CALLBACK_WINDOW. + +2007-04-13 Stefan Dösinger + + * dlls/d3d9/directx.c, dlls/ddraw/ddraw.c, dlls/wined3d/directx.c: + d3d: Enumerate palettized formats for ddraw. + +2007-04-14 Hwang YunSong(황윤성) + + * programs/cmd/Ko.rc: + cmd: Updated Korean resource. + +2007-04-15 James Hawkins + + * dlls/msi/custom.c, dlls/msi/tests/install.c: + msi: Add handling for the concurrent install custom action. + + * dlls/msi/action.c: + msi: Run the InstallExecute sequence if the InstallUISequnce table is empty. + + * dlls/msi/custom.c: + msi: Generalize the msi_custom_action_info struct so other custom actions can + use it. + + * dlls/msi/tests/install.c: + msi: Add tests for the concurrent installation custom action. + +2007-04-14 Kai Blin + + * dlls/secur32/base64_codec.c, dlls/secur32/dispatcher.c, + dlls/secur32/ntlm.c, dlls/secur32/util.c: + secur32: Move NTLM debug output to a seperate "ntlm" channel. + +2007-04-13 Francois Gouget + + * dlls/advapi32/tests/registry.c: + advapi32: Fix and extend the RegQueryValueEx() tests. + - Added tests for empty and zero-byte strings. Wine passes these tests, sort of. + - Check that the returned string is correct. + - All known Windows versions implement RegQueryValueExA(), so complain if it + is not implemented. + - Only allow the Win9x quirks for the Ansi version. + - Query the name2A/W value for the string2A/W tests! + - The test_hkey_main_Value_A/W() functions were doing a sizeof() on the string + parameter to compute the string's full size! + - We must reset GLE before each test, otherwise Win9x skips all but the + first test. + +2007-04-13 Chris Robinson + + * dlls/quartz/dsoundrender.c: + quartz: Create DirectSound device and buffer at filter creation and connection + respectively. + +2007-04-13 Chia-I Wu + + * dlls/kernel32/locale.c: + kernel32: Fix non-terminated separator string. + +2007-04-13 Alexandre Julliard + + * ANNOUNCE, ChangeLog, VERSION, configure: + Release 0.9.35. + +---------------------------------------------------------------- 2007-04-13 Huw Davies * dlls/imagehlp/integrity.c: diff --git a/Makefile.in b/Makefile.in index bd311621e6b..1f8f0c9ebf2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -344,6 +344,7 @@ ALL_MAKEFILES = \ dlls/rsaenh/tests/Makefile \ dlls/sane.ds/Makefile \ dlls/schannel/Makefile \ + dlls/schannel/tests/Makefile \ dlls/secur32/Makefile \ dlls/secur32/tests/Makefile \ dlls/security/Makefile \ @@ -688,6 +689,7 @@ dlls/rsaenh/Makefile: dlls/rsaenh/Makefile.in dlls/Makedll.rules dlls/rsaenh/tests/Makefile: dlls/rsaenh/tests/Makefile.in dlls/Maketest.rules dlls/sane.ds/Makefile: dlls/sane.ds/Makefile.in dlls/Makedll.rules dlls/schannel/Makefile: dlls/schannel/Makefile.in dlls/Makedll.rules +dlls/schannel/tests/Makefile: dlls/schannel/tests/Makefile.in dlls/Maketest.rules dlls/secur32/Makefile: dlls/secur32/Makefile.in dlls/Makedll.rules dlls/secur32/tests/Makefile: dlls/secur32/tests/Makefile.in dlls/Maketest.rules dlls/security/Makefile: dlls/security/Makefile.in dlls/Makedll.rules diff --git a/VERSION b/VERSION index f475890a6ef..7ec981d2e77 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Wine version 0.9.35 +Wine version 0.9.36 diff --git a/configure b/configure index 8f82985401d..546541e9bc1 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for Wine 0.9.35. +# Generated by GNU Autoconf 2.61 for Wine 0.9.36. # # Report bugs to . # @@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='Wine' PACKAGE_TARNAME='wine' -PACKAGE_VERSION='0.9.35' -PACKAGE_STRING='Wine 0.9.35' +PACKAGE_VERSION='0.9.36' +PACKAGE_STRING='Wine 0.9.36' PACKAGE_BUGREPORT='wine-devel@winehq.org' ac_unique_file="server/atom.c" @@ -1290,7 +1290,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Wine 0.9.35 to adapt to many kinds of systems. +\`configure' configures Wine 0.9.36 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1359,7 +1359,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Wine 0.9.35:";; + short | recursive ) echo "Configuration of Wine 0.9.36:";; esac cat <<\_ACEOF @@ -1455,7 +1455,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Wine configure 0.9.35 +Wine configure 0.9.36 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1469,7 +1469,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Wine $as_me 0.9.35, which was +It was created by Wine $as_me 0.9.36, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -20714,6 +20714,8 @@ ac_config_files="$ac_config_files dlls/sane.ds/Makefile" ac_config_files="$ac_config_files dlls/schannel/Makefile" +ac_config_files="$ac_config_files dlls/schannel/tests/Makefile" + ac_config_files="$ac_config_files dlls/secur32/Makefile" ac_config_files="$ac_config_files dlls/secur32/tests/Makefile" @@ -21389,7 +21391,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Wine $as_me 0.9.35, which was +This file was extended by Wine $as_me 0.9.36, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21442,7 +21444,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -Wine config.status 0.9.35 +Wine config.status 0.9.36 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -21752,6 +21754,7 @@ do "dlls/rsaenh/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/rsaenh/tests/Makefile" ;; "dlls/sane.ds/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/sane.ds/Makefile" ;; "dlls/schannel/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/schannel/Makefile" ;; + "dlls/schannel/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/schannel/tests/Makefile" ;; "dlls/secur32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/secur32/Makefile" ;; "dlls/secur32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/secur32/tests/Makefile" ;; "dlls/security/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/security/Makefile" ;; diff --git a/configure.ac b/configure.ac index 620753f55d6..1b52cb67aef 100644 --- a/configure.ac +++ b/configure.ac @@ -1682,6 +1682,7 @@ AC_CONFIG_FILES([dlls/rsaenh/Makefile]) AC_CONFIG_FILES([dlls/rsaenh/tests/Makefile]) AC_CONFIG_FILES([dlls/sane.ds/Makefile]) AC_CONFIG_FILES([dlls/schannel/Makefile]) +AC_CONFIG_FILES([dlls/schannel/tests/Makefile]) AC_CONFIG_FILES([dlls/secur32/Makefile]) AC_CONFIG_FILES([dlls/secur32/tests/Makefile]) AC_CONFIG_FILES([dlls/security/Makefile]) diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 4a857d9638c..caa5b404d59 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -269,6 +269,7 @@ TESTSUBDIRS = \ rpcrt4/tests \ rsabase/tests \ rsaenh/tests \ + schannel/tests \ secur32/tests \ serialui/tests \ setupapi/tests \ diff --git a/dlls/advapi32/crypt_lmhash.c b/dlls/advapi32/crypt_lmhash.c index 2e379d43b12..2f5784266af 100644 --- a/dlls/advapi32/crypt_lmhash.c +++ b/dlls/advapi32/crypt_lmhash.c @@ -25,8 +25,6 @@ #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" -#include "winbase.h" -#include "winreg.h" #include "winternl.h" #include "crypt.h" diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c index 7b9ee499fff..03bb4f371df 100644 --- a/dlls/advapi32/eventlog.c +++ b/dlls/advapi32/eventlog.c @@ -25,7 +25,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "winreg.h" #include "winternl.h" #include "wmistr.h" #include "evntrace.h" diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 80dd89f992b..729727fa0cf 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -27,7 +27,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "rpcnterr.h" #include "winreg.h" #include "winternl.h" #include "winioctl.h" @@ -2865,7 +2864,8 @@ DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries, PACL OldAcl, PACL* NewAcl ) { FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl); - return ERROR_CALL_NOT_IMPLEMENTED; + *NewAcl = NULL; + return ERROR_SUCCESS; } /****************************************************************************** diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 9d7363367ae..0cc58f1b1e9 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -196,7 +196,7 @@ static DWORD delete_key( HKEY hkey ) static void setup_main_key(void) { - if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )) delete_key( hkey_main ); + if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )) delete_key( hkey_main ); assert (!RegCreateKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )); } diff --git a/dlls/atl/atl.spec b/dlls/atl/atl.spec index 6204c5d8cf8..27fb1710314 100644 --- a/dlls/atl/atl.spec +++ b/dlls/atl/atl.spec @@ -23,7 +23,7 @@ 28 stdcall AtlPixelToHiMetric(ptr ptr) 29 stub AtlDevModeW2A 30 stdcall AtlComPtrAssign(ptr ptr) -31 stub AtlComQIPtrAssign +31 stdcall AtlComQIPtrAssign(ptr ptr ptr) 32 stdcall AtlInternalQueryInterface(ptr ptr ptr ptr) 34 stub AtlGetVersion 35 stub AtlAxDialogBoxW @@ -41,8 +41,8 @@ 47 stdcall AtlAxGetControl(long ptr) 48 stdcall AtlAxGetHost(long ptr) 49 stub AtlRegisterClassCategoriesHelper -50 stub AtlIPersistStreamInit_Load -51 stub AtlIPersistStreamInit_Save +50 stdcall AtlIPersistStreamInit_Load(ptr ptr ptr ptr) +51 stdcall AtlIPersistStreamInit_Save(ptr long ptr ptr ptr) 52 stub AtlIPersistPropertyBag_Load 53 stub AtlIPersistPropertyBag_Save 54 stub AtlGetObjectSourceInterface diff --git a/dlls/atl/atl_main.c b/dlls/atl/atl_main.c index 3b5703e9d66..938df36b51a 100644 --- a/dlls/atl/atl_main.c +++ b/dlls/atl/atl_main.c @@ -208,6 +208,18 @@ IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p) return p; } +IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid) +{ + IUnknown *new_p = NULL; + + TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid)); + + if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p); + if (*pp) IUnknown_Release(*pp); + *pp = new_p; + return new_p; +} + HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject) { @@ -522,3 +534,32 @@ void* WINAPI AtlModuleExtractCreateWndData(_ATL_MODULEW *pM) } return NULL; } + +/* FIXME: should be in a header file */ +typedef struct ATL_PROPMAP_ENTRY +{ + LPCOLESTR szDesc; + DISPID dispid; + const CLSID* pclsidPropPage; + const IID* piidDispatch; + DWORD dwOffsetData; + DWORD dwSizeData; + VARTYPE vt; +} ATL_PROPMAP_ENTRY; + +HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap, + void *pThis, IUnknown *pUnk) +{ + FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk); + + return S_OK; +} + +HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty, + ATL_PROPMAP_ENTRY *pMap, void *pThis, + IUnknown *pUnk) +{ + FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk); + + return S_OK; +} diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c index 0b940ea01d6..68b6b601d77 100644 --- a/dlls/comdlg32/filedlg.c +++ b/dlls/comdlg32/filedlg.c @@ -73,7 +73,6 @@ #include "filedlg31.h" #include "cderr.h" #include "shellapi.h" -#include "shlguid.h" #include "shlobj.h" #include "filedlgbrowser.h" #include "shlwapi.h" diff --git a/dlls/comdlg32/filedlg31.c b/dlls/comdlg32/filedlg31.c index b49cc7e6986..6c0f08de935 100644 --- a/dlls/comdlg32/filedlg31.c +++ b/dlls/comdlg32/filedlg31.c @@ -30,7 +30,6 @@ #include "winuser.h" #include "wine/unicode.h" #include "wine/debug.h" -#include "cderr.h" #include "winreg.h" #include "winternl.h" #include "commdlg.h" diff --git a/dlls/comdlg32/fontdlg16.c b/dlls/comdlg32/fontdlg16.c index 7ed63dc0e0b..3580af5d740 100644 --- a/dlls/comdlg32/fontdlg16.c +++ b/dlls/comdlg32/fontdlg16.c @@ -32,7 +32,6 @@ #include "wine/winbase16.h" #include "wine/winuser16.h" #include "commdlg.h" -#include "dlgs.h" #include "wine/debug.h" #include "cderr.h" diff --git a/dlls/comdlg32/printdlg16.c b/dlls/comdlg32/printdlg16.c index 4f883daad53..6aa8c6cc64f 100644 --- a/dlls/comdlg32/printdlg16.c +++ b/dlls/comdlg32/printdlg16.c @@ -40,7 +40,6 @@ #include "wine/debug.h" #include "cderr.h" #include "winspool.h" -#include "winerror.h" WINE_DEFAULT_DEBUG_CHANNEL(commdlg); diff --git a/dlls/compstui/compstui_main.c b/dlls/compstui/compstui_main.c index 12999714108..41b24416176 100644 --- a/dlls/compstui/compstui_main.c +++ b/dlls/compstui/compstui_main.c @@ -26,9 +26,6 @@ #include "windef.h" #include "winbase.h" #include "winuser.h" -#include "winreg.h" -#include "winver.h" -#include "winnls.h" #include "ddk/compstui.h" #include "wine/unicode.h" diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index cb83a80a0bb..2ab9de385d0 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -40,10 +40,8 @@ #include "windef.h" #include "winbase.h" -#include "excpt.h" #include "wincrypt.h" #include "winnls.h" -#include "winreg.h" #include "snmp.h" #include "wine/debug.h" #include "wine/exception.h" diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index d897617d9b9..9522b967dc3 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -40,9 +40,7 @@ #include "windef.h" #include "winbase.h" -#include "excpt.h" #include "wincrypt.h" -#include "winreg.h" #include "snmp.h" #include "wine/debug.h" #include "wine/exception.h" diff --git a/dlls/crypt32/main.c b/dlls/crypt32/main.c index f5d68d55f88..a0c4f4c5754 100644 --- a/dlls/crypt32/main.c +++ b/dlls/crypt32/main.c @@ -25,10 +25,7 @@ #include "winbase.h" #include "wincrypt.h" #include "winreg.h" -#include "winnls.h" -#include "mssip.h" #include "winuser.h" -#include "advpub.h" #include "crypt32_private.h" #include "wine/debug.h" diff --git a/dlls/crypt32/protectdata.c b/dlls/crypt32/protectdata.c index 1957e7cb4bb..a1a3369dcb5 100644 --- a/dlls/crypt32/protectdata.c +++ b/dlls/crypt32/protectdata.c @@ -42,7 +42,6 @@ #include "windef.h" #include "winbase.h" #include "wincrypt.h" -#include "winreg.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); diff --git a/dlls/crypt32/serialize.c b/dlls/crypt32/serialize.c index 49749e38a16..e45dcd09fb6 100644 --- a/dlls/crypt32/serialize.c +++ b/dlls/crypt32/serialize.c @@ -20,7 +20,6 @@ #include "winbase.h" #include "wincrypt.h" #include "wine/debug.h" -#include "excpt.h" #include "wine/exception.h" #include "crypt32_private.h" diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 3b9bcb815ce..77a75b12f63 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -36,7 +36,6 @@ #include "wincrypt.h" #include "wine/debug.h" #include "wine/list.h" -#include "excpt.h" #include "wine/exception.h" #include "crypt32_private.h" diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 682cb902016..af4f3adc928 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -827,7 +827,7 @@ IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD convertedDecls[low] = pDecl; This->numConvertedDecls++; - /* Will prevent the decl from beeing destroyed */ + /* Will prevent the decl from being destroyed */ ((IDirect3DVertexDeclaration9Impl *) pDecl)->convFVF = fvf; IDirect3DVertexDeclaration9_Release(pDecl); /* Does not destroy now */ diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c index 0355b220cc5..1e57cf8a5f3 100644 --- a/dlls/d3drm/math.c +++ b/dlls/d3drm/math.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define NONAMELESSUNION + #include #include #include @@ -38,9 +40,9 @@ LPD3DRMQUATERNION WINAPI D3DRMQuaternionMultiply(LPD3DRMQUATERNION q, LPD3DRMQUA D3DVECTOR cross_product; D3DRMVectorCrossProduct(&cross_product, &a->v, &b->v); q->s = a->s * b->s - D3DRMVectorDotProduct(&a->v, &b->v); - q->v.x = a->s * b->v.x + b->s * a->v.x + cross_product.x; - q->v.y = a->s * b->v.y + b->s * a->v.y + cross_product.y; - q->v.z = a->s * b->v.z + b->s * a->v.z + cross_product.z; + q->v.u1.x = a->s * b->v.u1.x + b->s * a->v.u1.x + cross_product.u1.x; + q->v.u2.y = a->s * b->v.u2.y + b->s * a->v.u2.y + cross_product.u2.y; + q->v.u3.z = a->s * b->v.u3.z + b->s * a->v.u3.z + cross_product.u3.z; return q; } @@ -49,9 +51,9 @@ void WINAPI D3DRMMatrixFromQuaternion(D3DRMMATRIX4D m, LPD3DRMQUATERNION q) { D3DVALUE w,x,y,z; w = q->s; - x = q->v.x; - y = q->v.y; - z = q->v.z; + x = q->v.u1.x; + y = q->v.u2.y; + z = q->v.u3.z; m[0][0] = 1.0-2.0*(y*y+z*z); m[1][1] = 1.0-2.0*(x*x+z*z); m[2][2] = 1.0-2.0*(x*x+y*y); @@ -93,27 +95,27 @@ LPD3DRMQUATERNION WINAPI D3DRMQuaternionSlerp(LPD3DRMQUATERNION q, LPD3DRMQUATER /* Add Two Vectors */ LPD3DVECTOR WINAPI D3DRMVectorAdd(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2) { - d->x=s1->x + s2->x; - d->y=s1->y + s2->y; - d->z=s1->z + s2->z; + d->u1.x=s1->u1.x + s2->u1.x; + d->u2.y=s1->u2.y + s2->u2.y; + d->u3.z=s1->u3.z + s2->u3.z; return d; } /* Subtract Two Vectors */ LPD3DVECTOR WINAPI D3DRMVectorSubtract(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2) { - d->x=s1->x - s2->x; - d->y=s1->y - s2->y; - d->z=s1->z - s2->z; + d->u1.x=s1->u1.x - s2->u1.x; + d->u2.y=s1->u2.y - s2->u2.y; + d->u3.z=s1->u3.z - s2->u3.z; return d; } /* Cross Product of Two Vectors */ LPD3DVECTOR WINAPI D3DRMVectorCrossProduct(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2) { - d->x=s1->y * s2->z - s1->z * s2->y; - d->y=s1->z * s2->x - s1->x * s2->z; - d->z=s1->x * s2->y - s1->y * s2->x; + d->u1.x=s1->u2.y * s2->u3.z - s1->u3.z * s2->u2.y; + d->u2.y=s1->u3.z * s2->u1.x - s1->u1.x * s2->u3.z; + d->u3.z=s1->u1.x * s2->u2.y - s1->u2.y * s2->u1.x; return d; } @@ -121,7 +123,7 @@ LPD3DVECTOR WINAPI D3DRMVectorCrossProduct(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DV D3DVALUE WINAPI D3DRMVectorDotProduct(LPD3DVECTOR s1, LPD3DVECTOR s2) { D3DVALUE dot_product; - dot_product=s1->x * s2->x + s1->y * s2->y + s1->z * s2->z; + dot_product=s1->u1.x * s2->u1.x + s1->u2.y * s2->u2.y + s1->u3.z * s2->u3.z; return dot_product; } @@ -129,7 +131,7 @@ D3DVALUE WINAPI D3DRMVectorDotProduct(LPD3DVECTOR s1, LPD3DVECTOR s2) D3DVALUE WINAPI D3DRMVectorModulus(LPD3DVECTOR v) { D3DVALUE result; - result=sqrt(v->x * v->x + v->y * v->y + v->z * v->z); + result=sqrt(v->u1.x * v->u1.x + v->u2.y * v->u2.y + v->u3.z * v->u3.z); return result; } @@ -143,9 +145,9 @@ LPD3DVECTOR WINAPI D3DRMVectorNormalize(LPD3DVECTOR u) } else { - u->x=1.0; - u->y=0.0; - u->z=0.0; + u->u1.x=1.0; + u->u2.y=0.0; + u->u3.z=0.0; } return u; } @@ -153,9 +155,9 @@ LPD3DVECTOR WINAPI D3DRMVectorNormalize(LPD3DVECTOR u) /* Returns a random unit vector */ LPD3DVECTOR WINAPI D3DRMVectorRandom(LPD3DVECTOR d) { - d->x = rand(); - d->y = rand(); - d->z = rand(); + d->u1.x = rand(); + d->u2.y = rand(); + d->u3.z = rand(); D3DRMVectorNormalize(d); return d; } @@ -190,8 +192,8 @@ LPD3DVECTOR WINAPI D3DRMVectorRotate(LPD3DVECTOR r, LPD3DVECTOR v, LPD3DVECTOR a /* Scale a vector */ LPD3DVECTOR WINAPI D3DRMVectorScale(LPD3DVECTOR d, LPD3DVECTOR s, D3DVALUE factor) { - d->x=factor * s->x; - d->y=factor * s->y; - d->z=factor * s->z; + d->u1.x=factor * s->u1.x; + d->u2.y=factor * s->u2.y; + d->u3.z=factor * s->u3.z; return d; } diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c index 1c25c5038da..e4c65ce05a1 100644 --- a/dlls/d3drm/tests/vector.c +++ b/dlls/d3drm/tests/vector.c @@ -18,10 +18,11 @@ */ #include -#include "wine/test.h" #include "d3drmdef.h" #include +#include "wine/test.h" + #define PI (4*atan(1.0)) #define admit_error 0.000001 @@ -51,87 +52,87 @@ } #define expect_quat(expectedquat,gotquat) \ - ok( (fabs(expectedquat.v.x-gotquat.v.x)module[i].timestamp; mdModule.ModuleNameRva = dc->rva; ms->Length -= sizeof(WCHAR); - append(dc, ms, sizeof(ULONG) + ms->Length); + append(dc, ms, sizeof(ULONG) + ms->Length + sizeof(WCHAR)); memset(&mdModule.VersionInfo, 0, sizeof(mdModule.VersionInfo)); /* FIXME */ mdModule.CvRecord.DataSize = 0; /* FIXME */ mdModule.CvRecord.Rva = 0; /* FIXME */ diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 3f8cea8b322..25b02d8dca7 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -1598,12 +1598,20 @@ D3D7CB_CreateSurface(IUnknown *device, { ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device); IDirectDrawSurfaceImpl *surf = This->tex_root; - int i; + int i = 0; TRACE("(%p) call back. surf=%p\n", device, surf); /* Find the wanted mipmap. There are enough mipmaps in the chain */ - for(i = 0; i < level; i++) - surf = surf->next_complex; + while(i < level) + { + IDirectDrawSurface7 *attached; + IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(surf, IDirectDrawSurface7), + &This->tex_root->surface_desc.ddsCaps, + &attached); + surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, attached); + IDirectDrawSurface7_Release(attached); + i++; + } /* Return the surface */ *Surface = surf->WineD3DSurface; @@ -1789,9 +1797,6 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, (*ppSurf)->next_attached = NULL; (*ppSurf)->first_attached = *ppSurf; - (*ppSurf)->next_complex = NULL; - (*ppSurf)->first_complex = *ppSurf; - /* Needed to re-create the surface on an implementation change */ (*ppSurf)->ImplType = ImplType; @@ -1942,6 +1947,51 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, return DD_OK; } +static HRESULT +CreateAdditionalSurfaces(IDirectDrawImpl *This, + IDirectDrawSurfaceImpl *root, + UINT count, + DDSURFACEDESC2 *DDSD) +{ + UINT i, level = 0; + HRESULT hr; + IDirectDrawSurfaceImpl *last = root; + for(i = 0; i < count; i++) + { + IDirectDrawSurfaceImpl *object2 = NULL; + + /* increase the mipmap level, but only if a mipmap is created + * In this case, also halve the size + */ + if(DDSD->ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + level++; + if(DDSD->dwWidth > 1) DDSD->dwWidth /= 2; + if(DDSD->dwHeight > 1) DDSD->dwHeight /= 2; + } + + hr = IDirectDrawImpl_CreateNewSurface(This, + DDSD, + &object2, + level); + if(hr != DD_OK) + { + return hr; + } + + /* Add the new surface to the complex attachment array */ + last->complex_array[0] = object2; + last = object2; + + /* Remove the (possible) back buffer cap from the new surface description, + * because only one surface in the flipping chain is a back buffer, one + * is a front buffer, the others are just primary surfaces. + */ + DDSD->ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; + } + return DD_OK; +} + /***************************************************************************** * IDirectDraw7::CreateSurface * @@ -2028,9 +2078,8 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); IDirectDrawSurfaceImpl *object = NULL; HRESULT hr; - LONG extra_surfaces = 0, i; + LONG extra_surfaces = 0; DDSURFACEDESC2 desc2; - UINT level = 0; WINED3DDISPLAYMODE Mode; TRACE("(%p)->(%p,%p,%p)\n", This, DDSD, Surf, UnkOuter); @@ -2251,6 +2300,7 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, ERR("IDirectDrawImpl_CreateNewSurface failed with %08x\n", hr); return hr; } + object->is_complex_root = TRUE; *Surf = ICOM_INTERFACE(object, IDirectDrawSurface7); @@ -2271,44 +2321,12 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, desc2.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; } - for(i = 0; i < extra_surfaces; i++) + hr = CreateAdditionalSurfaces(This, object, extra_surfaces, &desc2); + if(hr != DD_OK) { - IDirectDrawSurfaceImpl *object2 = NULL; - IDirectDrawSurfaceImpl *iterator; - - /* increase the mipmap level, but only if a mipmap is created - * In this case, also halve the size - */ - if(DDSD->ddsCaps.dwCaps & DDSCAPS_MIPMAP) - { - level++; - if(desc2.dwWidth > 1) desc2.dwWidth /= 2; - if(desc2.dwHeight > 1) desc2.dwHeight /= 2; - } - - hr = IDirectDrawImpl_CreateNewSurface(This, - &desc2, - &object2, - level); - if(hr != DD_OK) - { - /* This destroys and possibly created surfaces too */ - IDirectDrawSurface_Release( ICOM_INTERFACE(object, IDirectDrawSurface7) ); - return hr; - } - - /* Add the new surface to the complex attachment list */ - object2->first_complex = object; - object2->next_complex = NULL; - iterator = object; - while(iterator->next_complex) iterator = iterator->next_complex; - iterator->next_complex = object2; - - /* Remove the (possible) back buffer cap from the new surface description, - * because only one surface in the flipping chain is a back buffer, one - * is a front buffer, the others are just primary surfaces. - */ - desc2.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; + /* This destroys and possibly created surfaces too */ + IDirectDrawSurface_Release( ICOM_INTERFACE(object, IDirectDrawSurface7) ); + return hr; } /* Addref the ddraw interface to keep an reference for each surface */ @@ -2333,7 +2351,8 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, LIST_FOR_EACH(entry, &This->surface_list) { surface = LIST_ENTRY(entry, IDirectDrawSurfaceImpl, surface_list_entry); - if(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + if((surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) == + (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) { /* found */ target = surface; @@ -2343,7 +2362,7 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, } TRACE("(%p) Attaching a D3DDevice, rendertarget = %p\n", This, target); - hr = IDirectDrawImpl_AttachD3DDevice(This, target->first_complex); + hr = IDirectDrawImpl_AttachD3DDevice(This, target); if(hr != D3D_OK) { ERR("IDirectDrawImpl_AttachD3DDevice failed, hr = %x\n", hr); @@ -2574,6 +2593,28 @@ IDirectDrawImpl_EnumSurfaces(IDirectDraw7 *iface, return DD_OK; } +static HRESULT WINAPI +findRenderTarget(IDirectDrawSurface7 *surface, + DDSURFACEDESC2 *desc, + void *ctx) +{ + IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, surface); + IDirectDrawSurfaceImpl **target = (IDirectDrawSurfaceImpl **) ctx; + + if(!surf->isRenderTarget) { + *target = surf; + IDirectDrawSurface7_Release(surface); + return DDENUMRET_CANCEL; + } + + /* Recurse into the surface tree */ + IDirectDrawSurface7_EnumAttachedSurfaces(surface, ctx, findRenderTarget); + + IDirectDrawSurface7_Release(surface); + if(*target) return DDENUMRET_CANCEL; + else return DDENUMRET_OK; /* Continue with the next neighbor surface */ +} + /***************************************************************************** * D3D7CB_CreateRenderTarget * @@ -2606,25 +2647,29 @@ D3D7CB_CreateRenderTarget(IUnknown *device, IUnknown *pSuperior, HANDLE* pSharedHandle) { ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device); - IDirectDrawSurfaceImpl *d3dSurface = (IDirectDrawSurfaceImpl *) This->d3d_target->first_complex; + IDirectDrawSurfaceImpl *d3dSurface = This->d3d_target, *target = NULL; TRACE("(%p) call back\n", device); - /* Loop through the complex chain and try to find unused primary surfaces */ - while(d3dSurface->isRenderTarget) + if(d3dSurface->isRenderTarget) { - d3dSurface = d3dSurface->next_complex; - if(!d3dSurface) break; + IDirectDrawSurface7_EnumAttachedSurfaces(ICOM_INTERFACE(d3dSurface, IDirectDrawSurface7), + &target, findRenderTarget); } - if(!d3dSurface) + else + { + target = d3dSurface; + } + + if(!target) { - d3dSurface = This->d3d_target; + target = This->d3d_target; ERR(" (%p) : No DirectDrawSurface found to create the back buffer. Using the front buffer as back buffer. Uncertain consequences\n", This); } /* TODO: Return failure if the dimensions do not match, but this shouldn't happen */ - *ppSurface = d3dSurface->WineD3DSurface; - d3dSurface->isRenderTarget = TRUE; + *ppSurface = target->WineD3DSurface; + target->isRenderTarget = TRUE; TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *ppSurface, d3dSurface); return D3D_OK; } @@ -3031,7 +3076,7 @@ const IDirectDraw7Vtbl IDirectDraw7_Vtbl = * * This function is in ddraw.c and the DDraw object space because D3D7 * vertex buffers are created using the IDirect3D interface to the ddraw - * object, so they can be valid accross D3D devices(theoretically. The ddraw + * object, so they can be valid across D3D devices(theoretically. The ddraw * object also owns the wined3d device * * Parameters: diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 14db3c39aac..85e15bc8e3e 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -232,8 +232,18 @@ struct IDirectDrawSurfaceImpl /* This implementation handles attaching surfaces to other surfaces */ IDirectDrawSurfaceImpl *next_attached; IDirectDrawSurfaceImpl *first_attached; - IDirectDrawSurfaceImpl *next_complex; - IDirectDrawSurfaceImpl *first_complex; + + /* Complex surfaces are organized in a tree, although the tree is degenerated to a list in most cases. + * In mipmap and primary surfaces each level has only one attachment, which is the next surface level. + * Only the cube texture root has 6 surfaces attached, which then have a normal mipmap chain attached + * to them. So hardcode the array to 6, a dynamic array or a list would be an overkill. + */ +#define MAX_COMPLEX_ATTACHED 6 + IDirectDrawSurfaceImpl *complex_array[MAX_COMPLEX_ATTACHED]; + /* You can't traverse the tree upwards. Only a flag for Surface::Release because its needed there, + * but no pointer to prevent temptations to traverse it in the wrong direction. + */ + BOOL is_complex_root; /* Surface description, for GetAttachedSurface */ DDSURFACEDESC2 surface_desc; diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 14866f3614a..e7e975d49ae 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -379,11 +379,13 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) HeapFree(GetProcessHeap(), 0, This->Handles); + TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target); /* Release the render target and the WineD3D render target * (See IDirect3D7::CreateDevice for more comments on this) */ IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7)); IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7)); + TRACE("Target release done\n"); This->ddraw->d3ddevice = NULL; @@ -391,6 +393,7 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) HeapFree(GetProcessHeap(), 0, This); } + TRACE("Done\n"); return ref; } diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index cfe069ca65f..239460cfd4d 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -785,7 +785,7 @@ DestroyCallback(IDirectDrawSurface7 *surf, * part of a complex compound. They will get released when destroying * the root */ - if( (Impl->first_complex != Impl) || (Impl->first_attached != Impl) ) + if( (!Impl->is_complex_root) || (Impl->first_attached != Impl) ) return DDENUMRET_OK; /* Skip our depth stencil surface, it will be released with the render target */ if( Impl == ddraw->DepthStencilBuffer) diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index e374f983e8f..fa9ce3dec87 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -266,6 +266,8 @@ static void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This) * capabilities of the WineD3DDevice are uninitialized, which causes the * swapchain to be released. * + * When a complex sublevel falls to ref zero, then this is ignored. + * * Returns: * The new refcount * @@ -284,11 +286,12 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) IDirectDrawSurfaceImpl *surf; IDirectDrawImpl *ddraw; IUnknown *ifaceToRelease = This->ifaceToRelease; + int i; /* Complex attached surfaces are destroyed implicitely when the root is released */ - if(This->first_complex != This) + if(!This->is_complex_root) { - WARN("(%p) Attempt to destroy a surface that is attached to a complex root %p\n", This, This->first_complex); + WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This); return ref; } ddraw = This->ddraw; @@ -345,17 +348,33 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) * The same applies for textures without an * IWineD3DTexture object attached */ - surf = This; - while(surf) - { - IParent *Parent; + IParent *Parent; - IWineD3DSurface_GetParent(surf->WineD3DSurface, - (IUnknown **) &Parent); - IParent_Release(Parent); /* For the getParent */ - IParent_Release(Parent); /* To release it */ - surf = surf->next_complex; + for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) + { + if(This->complex_array[i]) + { + /* Only the topmost level can have more than 1 surfaces in the complex + * attachment array(Cube texture roots), for all others there is only + * one + */ + surf = This->complex_array[i]; + while(surf) + { + IWineD3DSurface_GetParent(surf->WineD3DSurface, + (IUnknown **) &Parent); + IParent_Release(Parent); /* For the getParent */ + IParent_Release(Parent); /* To release it */ + surf = surf->complex_array[0]; + } + } } + + /* Now the top-level surface */ + IWineD3DSurface_GetParent(This->WineD3DSurface, + (IUnknown **) &Parent); + IParent_Release(Parent); /* For the getParent */ + IParent_Release(Parent); /* To release it */ } /* The refcount test shows that the palette is detached when the surface is destroyed */ @@ -363,15 +382,26 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) NULL); /* Loop through all complex attached surfaces, - * and destroy them + * and destroy them. + * + * Yet again, only the root can have more than one complexly attached surface, all the others + * have a total of one; */ - while( (surf = This->next_complex) ) + for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) { - This->next_complex = surf->next_complex; /* Unchain it from the complex listing */ - IDirectDrawSurfaceImpl_Destroy(surf); /* Destroy it */ + if(!This->complex_array[i]) break; + + surf = This->complex_array[i]; + This->complex_array[i] = NULL; + while(surf) + { + IDirectDrawSurfaceImpl *destroy = surf; + surf = surf->complex_array[0]; /* Iterate through the "tree" */ + IDirectDrawSurfaceImpl_Destroy(destroy); /* Destroy it */ + } } - /* Destroy the surface. + /* Destroy the root surface. */ IDirectDrawSurfaceImpl_Destroy(This); @@ -388,13 +418,14 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) * Returns an attached surface with the requested caps. Surface attachment * and complex surfaces are not clearly described by the MSDN or sdk, * so this method is tricky and likely to contain problems. - * This implementation searches the complex chain first, then the - * attachment chain, and then it checks if the caps match to itself. + * This implementation searches the complex list first, then the + * attachment chain. * * The chains are searched from This down to the last surface in the chain, * not from the first element in the chain. The first surface found is * returned. The MSDN says that this method fails if more than one surface - * matches the caps, but apparently this is incorrect. + * matches the caps, but it is not sure if that is right. The attachment + * structure may not even allow two matching surfaces. * * The found surface is AddRef-ed before it is returned. * @@ -416,6 +447,7 @@ IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface, ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); IDirectDrawSurfaceImpl *surf; DDSCAPS2 our_caps; + int i; TRACE("(%p)->(%p,%p)\n", This, Caps, Surface); @@ -431,11 +463,11 @@ IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface, TRACE("(%p): Looking for caps: %x,%x,%x,%x\n", This, our_caps.dwCaps, our_caps.dwCaps2, our_caps.dwCaps3, our_caps.dwCaps4); /* FIXME: Better debugging */ - /* First, look at the complex chain */ - surf = This; - - while( (surf = surf->next_complex) ) + for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) { + surf = This->complex_array[i]; + if(!surf) break; + if (TRACE_ON(ddraw)) { TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf, @@ -451,8 +483,7 @@ IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface, /* MSDN: "This method fails if more than one surface is attached * that matches the capabilities requested." * - * The mipmap demo of the DirectX7 sdk shows what to do here: - * apparently apps expect the first found surface to be returned. + * Not sure how to test this. */ TRACE("(%p): Returning surface %p\n", This, surf); @@ -480,13 +511,6 @@ IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface, if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) { - /* MSDN: "This method fails if more than one surface is attached - * that matches the capabilities requested." - * - * The mipmap demo of the DirectX7 sdk shows what to do here: - * apparently apps expect the first found surface to be returned. - */ - TRACE("(%p): Returning surface %p\n", This, surf); *Surface = ICOM_INTERFACE(surf, IDirectDrawSurface7); IDirectDrawSurface7_AddRef(*Surface); @@ -494,22 +518,6 @@ IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface, } } - /* Is this valid? */ -#if 0 - if (((This->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && - ((This->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2) && - This == This->first_complex) - { - - TRACE("(%p): Returning surface %p\n", This, This); - *Surface = ICOM_INTERFACE(This, IDirectDrawSurface7); - IDirectDrawSurface7_AddRef(*Surface); - return DD_OK; - } -#endif - - /* What to do here? Continue with the surface root?? */ - TRACE("(%p) Didn't find a valid surface\n", This); return DDERR_NOTFOUND; } @@ -737,9 +745,12 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface, /***************************************************************************** * IDirectDrawSurface7::AddAttachedSurface * - * Attaches a surface to another surface. Surface attachments are - * incorrectly described in the SDK and the MSDN, and this method - * is prone to bugs. The surface that is attached is AddRef-ed. + * Attaches a surface to another surface. How the surface attachments work + * is not totally understood yet, and this method is prone to problems. + * he surface that is attached is AddRef-ed. + * + * Tests with complex surfaces suggest that the surface attachments form a + * tree, but no method to test this has been found yet. * * The attachment list consists of a first surface (first_attached) and * for each surface a pointer to the next attached surface (next_attached). @@ -747,22 +758,20 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface, * first_attached points to the surface itself. A surface that has * no successors in the chain has next_attached set to NULL. * - * Newly attached surfaces are attached right after the root surface. The - * complex chains are handled separately in a similar chain, with - * first_complex and next_complex. If a surface is attached to a complex - * surface compound, it's attached to the surface that the app requested, - * not the complex root. See GetAttachedSurface for a description - * how surfaces are found. + * Newly attached surfaces are attached right after the root surface. + * If a surface is attached to a complex surface compound, it's attached to + * the surface that the app requested, not the complex root. See + * GetAttachedSurface for a description how surfaces are found. * * This is how the current implementation works, and it was coded by looking * at the needs of the applications. * - * So far only Z-Buffer attachments are tested, but there's no code yet - * to activate them. Mipmaps could be tricky to activate in WineD3D. - * Back buffers should work in 2D mode, but they are not tested. - * Rendering to the primary surface and switching between that and - * double buffering is not yet implemented in WineD3D, so for 3D it might - * have unexpected results. + * So far only Z-Buffer attachments are tested, and they are activated in + * WineD3D. Mipmaps could be tricky to activate in WineD3D. + * Back buffers should work in 2D mode, but they are not tested(Not sure if + * they can be attached at all). Rendering to the primary surface and + * switching between that and double buffering is not yet implemented in + * WineD3D, so for 3D it might have unexpected results. * * Params: * Attach: Surface to attach to iface @@ -785,8 +794,16 @@ IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurface7 *iface, if(Surf == This) return DDERR_CANNOTATTACHSURFACE; /* unchecked */ - /* TODO MSDN: "You can attach only z-buffer surfaces with this method." - * But apparently backbuffers and mipmaps can be attached too. */ + /* MSDN: Only Z buffer surfaces can be attached. An old comment said that apparently + * mipmaps and back buffers can be attached too, although our tests say no. + */ + if(!(Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) + { + /* Write a fixme until we know for sure what is going on */ + FIXME("Application tries to attach a non Z buffer surface. caps %08x\n", + Surf->surface_desc.ddsCaps.dwCaps); + return DDERR_CANNOTATTACHSURFACE; + } /* Set MIPMAPSUBLEVEL if this seems to be one */ if (This->surface_desc.ddsCaps.dwCaps & @@ -1222,6 +1239,7 @@ IDirectDrawSurfaceImpl_EnumAttachedSurfaces(IDirectDrawSurface7 *iface, ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); IDirectDrawSurfaceImpl *surf; DDSURFACEDESC2 desc; + int i; /* Attached surfaces aren't handled in WineD3D */ TRACE("(%p)->(%p,%p)\n",This,context,cb); @@ -1229,8 +1247,11 @@ IDirectDrawSurfaceImpl_EnumAttachedSurfaces(IDirectDrawSurface7 *iface, if(!cb) return DDERR_INVALIDPARAMS; - for (surf = This->next_complex; surf != NULL; surf = surf->next_complex) + for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) { + surf = This->complex_array[i]; + if(!surf) break; + IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf, IDirectDrawSurface7)); desc = surf->surface_desc; /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */ @@ -2073,6 +2094,45 @@ IDirectDrawSurfaceImpl_GetPalette(IDirectDrawSurface7 *iface, } /***************************************************************************** + * SetColorKeyEnum + * + * EnumAttachedSurface callback for SetColorKey. Used to set color keys + * recursively in the surface tree + * + *****************************************************************************/ +struct SCKContext +{ + HRESULT ret; + WINEDDCOLORKEY *CKey; + DWORD Flags; +}; + +static HRESULT WINAPI +SetColorKeyEnum(IDirectDrawSurface7 *surface, + DDSURFACEDESC2 *desc, + void *context) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, surface); + struct SCKContext *ctx = context; + HRESULT hr; + + hr = IWineD3DSurface_SetColorKey(This->WineD3DSurface, + ctx->Flags, + ctx->CKey); + if(hr != DD_OK) + { + WARN("IWineD3DSurface_SetColorKey failed, hr = %08x\n", hr); + ctx->ret = hr; + } + + IDirectDrawSurface7_EnumAttachedSurfaces(surface, + context, + SetColorKeyEnum); + IDirectDrawSurface7_Release(surface); + return DDENUMRET_OK; +} + +/***************************************************************************** * IDirectDrawSurface7::SetColorKey * * Sets the color keying options for the surface. Observations showed that @@ -2094,8 +2154,7 @@ IDirectDrawSurfaceImpl_SetColorKey(IDirectDrawSurface7 *iface, DDCOLORKEY *CKey) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); - IDirectDrawSurfaceImpl *surf; - HRESULT hr; + struct SCKContext ctx = { DD_OK, (WINEDDCOLORKEY *) CKey, Flags }; TRACE("(%p)->(%x,%p)\n", This, Flags, CKey); if (CKey) @@ -2150,23 +2209,17 @@ IDirectDrawSurfaceImpl_SetColorKey(IDirectDrawSurface7 *iface, return DDERR_INVALIDPARAMS; } } - for(surf = This->first_complex; surf; surf = surf->next_complex) + ctx.ret = IWineD3DSurface_SetColorKey(This->WineD3DSurface, + Flags, + ctx.CKey); + IDirectDrawSurface7_EnumAttachedSurfaces(iface, + (void *) &ctx, + SetColorKeyEnum); + switch(ctx.ret) { - hr = IWineD3DSurface_SetColorKey(surf->WineD3DSurface, - Flags, - (WINEDDCOLORKEY *) CKey); - if(FAILED(hr)) - { - WARN("IWineD3DSurface::SetColorKey for surface %p failed with hr=%08x\n", - surf->WineD3DSurface, hr); - switch(hr) - { - case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; - default: return hr; - } - } + case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; + default: return ctx.ret; } - return DD_OK; } /***************************************************************************** @@ -2206,13 +2259,31 @@ IDirectDrawSurfaceImpl_SetPalette(IDirectDrawSurface7 *iface, /* Release the old palette */ if(oldPal) IDirectDrawPalette_Release(oldPal); - /* If this is a front buffer, also update the back buffers */ + /* If this is a front buffer, also update the back buffers + * TODO: How do things work for palettized cube textures? + */ if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) { - for(surf = This->next_complex; surf != NULL; surf = surf->next_complex) + /* For primary surfaces the tree is just a list, so the simpler scheme fits too */ + DDSCAPS2 caps2 = { DDSCAPS_PRIMARYSURFACE, 0, 0, 0 }; + + surf = This; + while(1) { - IDirectDrawSurface7_SetPalette(ICOM_INTERFACE(surf, IDirectDrawSurface7), + IDirectDrawSurface7 *attach; + HRESULT hr; + hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(surf, IDirectDrawSurface7), + &caps2, &attach); + if(hr != DD_OK) + { + break; + } + + TRACE("Setting palette on %p\n", attach); + IDirectDrawSurface7_SetPalette(attach, Pal); + surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, attach); + IDirectDrawSurface7_Release(attach); } } diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c index 2d5a625600b..6db2d98c5f1 100644 --- a/dlls/ddraw/tests/dsurface.c +++ b/dlls/ddraw/tests/dsurface.c @@ -885,6 +885,163 @@ static void GetDDInterface_7(void) IDirectDrawSurface7_Release(dsurface7); } +#define MAXEXPECTED 8 /* Can match up to 8 expected surfaces */ +struct enumstruct +{ + IDirectDrawSurface *expected[MAXEXPECTED]; + UINT count; +}; + +static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx) +{ + int i; + BOOL found = FALSE; + + for(i = 0; i < MAXEXPECTED; i++) + { + if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE; + } + + ok(found, "Unexpected surface %p enumerated\n", surf); + ((struct enumstruct *)ctx)->count++; + IDirectDrawSurface_Release(surf); + return DDENUMRET_OK; +} + +static void EnumTest(void) +{ + HRESULT rc; + DDSURFACEDESC ddsd; + IDirectDrawSurface *surface; + struct enumstruct ctx; + + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + U2(ddsd).dwMipMapCount = 3; + ddsd.dwWidth = 32; + ddsd.dwHeight = 32; + rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL); + ok(rc==DD_OK,"CreateSurface returned: %x\n",rc); + + memset(&ctx, 0, sizeof(ctx)); + ctx.expected[0] = surface; + rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]); + ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc); + rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]); + ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc); + rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]); + ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc); + ctx.count = 0; + + rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, (void *) &ctx, enumCB); + ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc); + ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count); + + IDirectDrawSurface_Release(ctx.expected[2]); + IDirectDrawSurface_Release(ctx.expected[1]); + IDirectDrawSurface_Release(surface); +} + +HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context) +{ + UINT *num = context; + (*num)++; + IDirectDrawSurface_Release(surface); + return DDENUMRET_OK; +} + +static void AttachmentTest(void) +{ + HRESULT hr; + IDirectDraw7 *dd7; + IDirectDrawSurface7 *surface1, *surface2, *surface3; + DDSURFACEDESC2 ddsd; + UINT num; + DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}; + HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL ); + + hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7); + ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr); + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */ + ddsd.dwWidth = 128; + ddsd.dwHeight = 128; + hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL); + ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); + + /* ROOT */ + num = 0; + IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter); + ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num); + /* DONE ROOT */ + + /* LEVEL 1 */ + hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2); + ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); + num = 0; + IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter); + ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num); + /* DONE LEVEL 1 */ + + /* LEVEL 2 */ + hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3); + ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr); + IDirectDrawSurface7_Release(surface2); + num = 0; + IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter); + ok(num == 0, "Secound mip level has %d surfaces attached, expected 1\n", num); + /* Done level 2 */ + /* Mip level 3 is still needed */ + + /* Try to attach a 16x16 miplevel - Should not work as far I can see */ + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + ddsd.dwWidth = 16; + ddsd.dwHeight = 16; + hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL); + ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); + + hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2); + ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr); + hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1); + ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr); + hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2); + ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr); + hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3); + ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr); + + IDirectDrawSurface7_Release(surface3); + IDirectDrawSurface7_Release(surface2); + IDirectDrawSurface7_Release(surface1); + + hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr); + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; + U2(ddsd).dwBackBufferCount = 2; + hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL); + ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); + + num = 0; + IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter); + ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num); + IDirectDrawSurface7_Release(surface1); + + hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr); + IDirectDraw7_Release(dd7); +} + START_TEST(dsurface) { if (!CreateDirectDraw()) @@ -896,5 +1053,7 @@ START_TEST(dsurface) GetDDInterface_2(); GetDDInterface_4(); GetDDInterface_7(); + EnumTest(); + AttachmentTest(); ReleaseDirectDraw(); } diff --git a/dlls/dnsapi/query.c b/dlls/dnsapi/query.c index 1366b0b9cd6..95229291eec 100644 --- a/dlls/dnsapi/query.c +++ b/dlls/dnsapi/query.c @@ -67,7 +67,7 @@ static CRITICAL_SECTION resolver_cs = { &resolver_cs_debug, -1, 0, 0, 0, 0 }; static int resolver_initialised; -/* call res_init() just once because of a bug in Mac OSX 10.4 */ +/* call res_init() just once because of a bug in Mac OS X 10.4 */ static void initialise_resolver( void ) { if (!resolver_initialised) diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 650adfd9bff..17ebd00a281 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -54,12 +54,12 @@ static lpPlayerList DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid ); static lpPlayerData DP_CreatePlayer( IDirectPlay2Impl* iface, LPDPID lpid, LPDPNAME lpName, DWORD dwFlags, HANDLE hEvent, BOOL bAnsi ); -static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi ); +static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, const DPNAME *lpSrc, BOOL bAnsi ); static void DP_SetPlayerData( lpPlayerData lpPData, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize ); -static lpGroupData DP_CreateGroup( IDirectPlay2AImpl* iface, LPDPID lpid, - LPDPNAME lpName, DWORD dwFlags, +static lpGroupData DP_CreateGroup( IDirectPlay2AImpl* iface, const DPID *lpid, + const DPNAME *lpName, DWORD dwFlags, DPID idParent, BOOL bAnsi ); static void DP_SetGroupData( lpGroupData lpGData, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize ); @@ -919,8 +919,8 @@ static HRESULT WINAPI DirectPlay2WImpl_Close } static -lpGroupData DP_CreateGroup( IDirectPlay2AImpl* This, LPDPID lpid, - LPDPNAME lpName, DWORD dwFlags, +lpGroupData DP_CreateGroup( IDirectPlay2AImpl* This, const DPID *lpid, + const DPNAME *lpName, DWORD dwFlags, DPID idParent, BOOL bAnsi ) { lpGroupData lpGData; @@ -1290,7 +1290,7 @@ static lpPlayerList DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid ) } /* Basic area for Dst must already be allocated */ -static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi ) +static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, const DPNAME *lpSrc, BOOL bAnsi ) { if( lpSrc == NULL ) { diff --git a/dlls/dplayx/dplayx_global.c b/dlls/dplayx/dplayx_global.c index 13bf1e21812..9ad9b3e366a 100644 --- a/dlls/dplayx/dplayx_global.c +++ b/dlls/dplayx/dplayx_global.c @@ -199,10 +199,10 @@ static DPSESSIONDESC2* sessionData = NULL; /* static DPSESSIONDESC2* sessionData[ numSupportedSessions ]; */ /* Function prototypes */ -static DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpDplData ); -static DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpDplData ); -static void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src ); -static void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src ); +static DWORD DPLAYX_SizeOfLobbyDataA( const DPLCONNECTION *lpDplData ); +static DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpDplData ); +static void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, const DPLCONNECTION *src ); +static void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *src ); static BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, LPDPLAYX_LOBBYDATA* dplData ); static void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData ); static BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, @@ -658,7 +658,7 @@ HRESULT DPLAYX_GetConnectionSettingsA } /* Assumption: Enough contiguous space was allocated at dest */ -void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src ) +void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, const DPLCONNECTION *src ) { BYTE* lpStartOfFreeSpace; @@ -780,7 +780,7 @@ HRESULT DPLAYX_GetConnectionSettingsW } /* Assumption: Enough contiguous space was allocated at dest */ -void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src ) +void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *src ) { BYTE* lpStartOfFreeSpace; @@ -855,7 +855,7 @@ void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src ) HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags, DWORD dwAppID, - LPDPLCONNECTION lpConn ) + const DPLCONNECTION *lpConn ) { LPDPLAYX_LOBBYDATA lpDplData; @@ -917,7 +917,7 @@ HRESULT DPLAYX_SetConnectionSettingsA HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags, DWORD dwAppID, - LPDPLCONNECTION lpConn ) + const DPLCONNECTION *lpConn ) { LPDPLAYX_LOBBYDATA lpDplData; @@ -961,7 +961,7 @@ HRESULT DPLAYX_SetConnectionSettingsW return DP_OK; } -DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpConn ) +DWORD DPLAYX_SizeOfLobbyDataA( const DPLCONNECTION *lpConn ) { DWORD dwTotalSize = sizeof( DPLCONNECTION ); @@ -1008,7 +1008,7 @@ DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpConn ) return dwTotalSize; } -DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpConn ) +DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpConn ) { DWORD dwTotalSize = sizeof( DPLCONNECTION ); diff --git a/dlls/dplayx/dplayx_global.h b/dlls/dplayx/dplayx_global.h index d7f7e73ce93..a4d109a9c9b 100644 --- a/dlls/dplayx/dplayx_global.h +++ b/dlls/dplayx/dplayx_global.h @@ -38,10 +38,10 @@ HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID, HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags, DWORD dwAppID, - LPDPLCONNECTION lpConn ); + const DPLCONNECTION *lpConn ); HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags, DWORD dwAppID, - LPDPLCONNECTION lpConn ); + const DPLCONNECTION *lpConn ); BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID ); BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID ); diff --git a/dlls/dplayx/name_server.c b/dlls/dplayx/name_server.c index f46af67c956..e875c19063a 100644 --- a/dlls/dplayx/name_server.c +++ b/dlls/dplayx/name_server.c @@ -211,7 +211,7 @@ void NS_SetLocalAddr( LPVOID lpNSInfo, LPCVOID lpHdr, DWORD dwHdrSize ) */ HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid, DWORD dwFlags, - LPSPINITDATA lpSpData ) + const SPINITDATA *lpSpData ) { DPSP_ENUMSESSIONSDATA data; diff --git a/dlls/dplayx/name_server.h b/dlls/dplayx/name_server.h index ec2c298191a..2df4a3bf7ea 100644 --- a/dlls/dplayx/name_server.h +++ b/dlls/dplayx/name_server.h @@ -46,7 +46,7 @@ void NS_ReplyToEnumSessionsRequest( LPCVOID lpcMsg, HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid, DWORD dwFlags, - LPSPINITDATA lpSpData ); + const SPINITDATA *lpSpData ); BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo ); diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c index 94d2122b596..1736fe3423b 100644 --- a/dlls/dsound/dsound_main.c +++ b/dlls/dsound/dsound_main.c @@ -439,9 +439,17 @@ static HRESULT WINAPI DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj) { IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - FIXME("(%p, %s, %p) stub!\n", This, debugstr_guid(riid), ppobj); + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); if (ppobj == NULL) return E_POINTER; + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IClassFactory)) + { + *ppobj = iface; + IUnknown_AddRef(iface); + return S_OK; + } + *ppobj = NULL; return E_NOINTERFACE; } diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index b961cf6180e..adbee9e98eb 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -175,7 +175,7 @@ static inline BYTE cvtS16toU8(INT16 s) * Copy a single frame from the given input buffer to the given output buffer. * Translate 8 <-> 16 bits and mono <-> stereo */ -static inline void cp_fields(const IDirectSoundBufferImpl *dsb, BYTE *ibuf, BYTE *obuf ) +static inline void cp_fields(const IDirectSoundBufferImpl *dsb, const BYTE *ibuf, BYTE *obuf ) { DirectSoundDevice * device = dsb->device; INT fl,fr; @@ -192,8 +192,8 @@ static inline void cp_fields(const IDirectSoundBufferImpl *dsb, BYTE *ibuf, BYTE fl = cvtU8toS16(*ibuf); fr = (dsb->pwfx->nChannels==2 ? cvtU8toS16(*(ibuf + 1)) : fl); } else { - fl = *((INT16 *)ibuf); - fr = (dsb->pwfx->nChannels==2 ? *(((INT16 *)ibuf) + 1) : fl); + fl = *((const INT16 *)ibuf); + fr = (dsb->pwfx->nChannels==2 ? *(((const INT16 *)ibuf) + 1) : fl); } if (device->pwfx->nChannels == 2) { @@ -910,7 +910,8 @@ post_mix: * * Returns: the length beyond the writepos that was mixed to. */ -static DWORD DSOUND_MixToPrimary(DirectSoundDevice *device, DWORD playpos, DWORD writepos, DWORD mixlen, BOOL recover) +static DWORD DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD playpos, DWORD writepos, + DWORD mixlen, BOOL recover) { INT i, len, maxlen = 0; IDirectSoundBufferImpl *dsb; diff --git a/dlls/dsound/propset.c b/dlls/dsound/propset.c index 66a4af617c4..b83ae377c2e 100644 --- a/dlls/dsound/propset.c +++ b/dlls/dsound/propset.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS #include #include "windef.h" @@ -241,8 +242,14 @@ static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface( IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IKsPropertySet)) { + *ppobj = iface; + IUnknown_AddRef(iface); + return S_OK; + } *ppobj = NULL; - return DSERR_INVALIDPARAM; + return E_NOINTERFACE; } static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface) diff --git a/dlls/dsound/sound3d.c b/dlls/dsound/sound3d.c index 234c40ba370..6145cffa9a6 100644 --- a/dlls/dsound/sound3d.c +++ b/dlls/dsound/sound3d.c @@ -66,7 +66,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound3d); */ /* scalar product (i believe it's called dot product in english) */ -static inline D3DVALUE ScalarProduct (LPD3DVECTOR a, LPD3DVECTOR b) +static inline D3DVALUE ScalarProduct (const D3DVECTOR *a, const D3DVECTOR *b) { D3DVALUE c; c = (a->x*b->x) + (a->y*b->y) + (a->z*b->z); @@ -76,7 +76,7 @@ static inline D3DVALUE ScalarProduct (LPD3DVECTOR a, LPD3DVECTOR b) } /* vector product (i believe it's called cross product in english */ -static inline D3DVECTOR VectorProduct (LPD3DVECTOR a, LPD3DVECTOR b) +static inline D3DVECTOR VectorProduct (const D3DVECTOR *a, const D3DVECTOR *b) { D3DVECTOR c; c.x = (a->y*b->z) - (a->z*b->y); @@ -88,7 +88,7 @@ static inline D3DVECTOR VectorProduct (LPD3DVECTOR a, LPD3DVECTOR b) } /* magnitude (length) of vector */ -static inline D3DVALUE VectorMagnitude (LPD3DVECTOR a) +static inline D3DVALUE VectorMagnitude (const D3DVECTOR *a) { D3DVALUE l; l = sqrt (ScalarProduct (a, a)); @@ -106,7 +106,7 @@ static inline D3DVALUE RadToDeg (D3DVALUE angle) } /* angle between vectors - deg version */ -static inline D3DVALUE AngleBetweenVectorsDeg (LPD3DVECTOR a, LPD3DVECTOR b) +static inline D3DVALUE AngleBetweenVectorsDeg (const D3DVECTOR *a, const D3DVECTOR *b) { D3DVALUE la, lb, product, angle, cos; /* definition of scalar product: a*b = |a|*|b|*cos...therefore: */ @@ -123,7 +123,7 @@ static inline D3DVALUE AngleBetweenVectorsDeg (LPD3DVECTOR a, LPD3DVECTOR b) } /* angle between vectors - rad version */ -static inline D3DVALUE AngleBetweenVectorsRad (LPD3DVECTOR a, LPD3DVECTOR b) +static inline D3DVALUE AngleBetweenVectorsRad (const D3DVECTOR *a, const D3DVECTOR *b) { D3DVALUE la, lb, product, angle, cos; /* definition of scalar product: a*b = |a|*|b|*cos...therefore: */ @@ -138,7 +138,7 @@ static inline D3DVALUE AngleBetweenVectorsRad (LPD3DVECTOR a, LPD3DVECTOR b) } /* calculates vector between two points */ -static inline D3DVECTOR VectorBetweenTwoPoints (LPD3DVECTOR a, LPD3DVECTOR b) +static inline D3DVECTOR VectorBetweenTwoPoints (const D3DVECTOR *a, const D3DVECTOR *b) { D3DVECTOR c; c.x = b->x - a->x; @@ -150,7 +150,7 @@ static inline D3DVECTOR VectorBetweenTwoPoints (LPD3DVECTOR a, LPD3DVECTOR b) } /* calculates the length of vector's projection on another vector */ -static inline D3DVALUE ProjectVector (LPD3DVECTOR a, LPD3DVECTOR p) +static inline D3DVALUE ProjectVector (const D3DVECTOR *a, const D3DVECTOR *p) { D3DVALUE prod, result; prod = ScalarProduct(a, p); diff --git a/dlls/dswave/dswave_main.c b/dlls/dswave/dswave_main.c index d919de81bba..939c492096b 100644 --- a/dlls/dswave/dswave_main.c +++ b/dlls/dswave/dswave_main.c @@ -144,7 +144,7 @@ const char *debugstr_fourcc (DWORD fourcc) { } /* DMUS_VERSION struct to string conversion for debug messages */ -const char *debugstr_dmversion (LPDMUS_VERSION version) { +const char *debugstr_dmversion (const DMUS_VERSION *version) { if (!version) return "'null'"; return wine_dbg_sprintf ("\'%i,%i,%i,%i\'", (int)((version->dwVersionMS & 0xFFFF0000) >> 8), (int)(version->dwVersionMS & 0x0000FFFF), diff --git a/dlls/dswave/dswave_private.h b/dlls/dswave/dswave_private.h index 19ad4baf433..0c2d675e8bd 100644 --- a/dlls/dswave/dswave_private.h +++ b/dlls/dswave/dswave_private.h @@ -111,7 +111,7 @@ extern int even_or_odd (DWORD number); /* FOURCC to string conversion for debug messages */ extern const char *debugstr_fourcc (DWORD fourcc); /* DMUS_VERSION struct to string conversion for debug messages */ -extern const char *debugstr_dmversion (LPDMUS_VERSION version); +extern const char *debugstr_dmversion (const DMUS_VERSION *version); /* returns name of given GUID */ extern const char *debugstr_dmguid (const GUID *id); /* returns name of given error code */ diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index 8e636aeeaaa..f8f48472027 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -57,7 +57,7 @@ static const struct gdi_obj_funcs brush_funcs = BRUSH_DeleteObject /* pDeleteObject */ }; -static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse) +static HGLOBAL16 dib_copy(const BITMAPINFO *info, UINT coloruse) { BITMAPINFO *newInfo; HGLOBAL16 hmem; diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c index 5c1294fc23a..c822b28b904 100644 --- a/dlls/gdi32/enhmetafile.c +++ b/dlls/gdi32/enhmetafile.c @@ -516,7 +516,7 @@ typedef struct enum_emh_data #define IS_WIN9X() (GetVersion()&0x80000000) -static void EMF_Update_MF_Xform(HDC hdc, enum_emh_data *info) +static void EMF_Update_MF_Xform(HDC hdc, const enum_emh_data *info) { XFORM mapping_mode_trans, final_trans; FLOAT scaleX, scaleY; diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 263454d0572..d9e6e350ba9 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -2332,9 +2332,7 @@ BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count) * * See PolyTextOutW. */ -BOOL WINAPI PolyTextOutA ( HDC hdc, /* [in] Handle to device context */ - PPOLYTEXTA pptxt, /* [in] Array of strings */ - INT cStrings ) /* [in] Number of strings in array */ +BOOL WINAPI PolyTextOutA( HDC hdc, const POLYTEXTA *pptxt, INT cStrings ) { for (; cStrings>0; cStrings--, pptxt++) if (!ExtTextOutA( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx )) @@ -2353,9 +2351,7 @@ BOOL WINAPI PolyTextOutA ( HDC hdc, /* [in] Handle to device conte * TRUE: Success. * FALSE: Failure. */ -BOOL WINAPI PolyTextOutW ( HDC hdc, /* [in] Handle to device context */ - PPOLYTEXTW pptxt, /* [in] Array of strings */ - INT cStrings ) /* [in] Number of strings in array */ +BOOL WINAPI PolyTextOutW( HDC hdc, const POLYTEXTW *pptxt, INT cStrings ) { for (; cStrings>0; cStrings--, pptxt++) if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx )) diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index c80e1e0ed9c..6b7fa621aed 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -52,7 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); static int resolver_initialised; -/* call res_init() just once because of a bug in Mac OSX 10.4 */ +/* call res_init() just once because of a bug in Mac OS X 10.4 */ static void initialise_resolver(void) { if (!resolver_initialised) diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index a675386e0c1..4d3d083908d 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -799,6 +799,8 @@ @ stdcall MoveFileWithProgressW(wstr wstr ptr ptr long) @ stdcall MulDiv(long long long) @ stdcall MultiByteToWideChar(long long str long ptr long) +@ stdcall NeedCurrentDirectoryForExePathA(str) +@ stdcall NeedCurrentDirectoryForExePathW(wstr) # @ stub NlsConvertIntegerToString # @ stub NlsGetCacheUpdateCount # @ stub NlsResetProcessLocale diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c index b195435f521..eb752f0c326 100644 --- a/dlls/kernel32/path.c +++ b/dlls/kernel32/path.c @@ -1511,6 +1511,43 @@ UINT WINAPI GetSystemWow64DirectoryA( LPSTR lpBuffer, UINT uSize ) /*********************************************************************** + * NeedCurrentDirectoryForExePathW (KERNEL32.@) + */ +BOOL WINAPI NeedCurrentDirectoryForExePathW( LPCWSTR name ) +{ + static const WCHAR env_name[] = {'N','o','D','e','f','a','u','l','t', + 'C','u','r','r','e','n','t', + 'D','i','r','e','c','t','o','r','y', + 'I','n','E','x','e','P','a','t','h',0}; + WCHAR env_val; + + /* MSDN mentions some 'registry location'. We do not use registry. */ + FIXME("(%s): partial stub\n", debugstr_w(name)); + + if (strchrW(name, '\\')) + return TRUE; + + /* Check the existence of the variable, not value */ + if (!GetEnvironmentVariableW( env_name, &env_val, 1 )) + return TRUE; + + return FALSE; +} + + +/*********************************************************************** + * NeedCurrentDirectoryForExePathA (KERNEL32.@) + */ +BOOL WINAPI NeedCurrentDirectoryForExePathA( LPCSTR name ) +{ + WCHAR *nameW; + + if (!(nameW = FILE_name_AtoW( name, FALSE ))) return TRUE; + return NeedCurrentDirectoryForExePathW( nameW ); +} + + +/*********************************************************************** * wine_get_unix_file_name (KERNEL32.@) Not a Windows API * * Return the full Unix file name for a given path. diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 8b8bd3c4cdc..8e5999fb267 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -346,7 +346,7 @@ static void set_registry_variables( HANDLE hkey, ULONG type ) env_value.Buffer = (WCHAR *)(buffer + info->DataOffset); env_value.Length = env_value.MaximumLength = info->DataLength; if (env_value.Length && !env_value.Buffer[env_value.Length/sizeof(WCHAR)-1]) - env_value.Length--; /* don't count terminating null if any */ + env_value.Length -= sizeof(WCHAR); /* don't count terminating null if any */ if (info->Type == REG_EXPAND_SZ) { WCHAR buf_expanded[1024]; diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c index 33fcf6f884b..47ec23ff88c 100644 --- a/dlls/kernel32/tests/path.c +++ b/dlls/kernel32/tests/path.c @@ -53,6 +53,10 @@ static const CHAR is_char_ok[] ="11111110111111111011"; static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD); static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD); +/* Present in Win2003+ */ +static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR); +static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR); + /* a structure to deal with wine todos somewhat cleanly */ typedef struct { DWORD shortlen; @@ -1074,6 +1078,44 @@ static void test_GetWindowsDirectory(void) res, GetLastError(), buffer, total); } +static void test_NeedCurrentDirectoryForExePathA(void) +{ + /* Crashes in Windows */ + if (0) + ok(pNeedCurrentDirectoryForExePathA(NULL), "returned FALSE for NULL\n"); + + SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL); + ok(pNeedCurrentDirectoryForExePathA("."), "returned FALSE for \".\"\n"); + ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n"); + ok(pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned FALSE for \"cmd.exe\"\n"); + + SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya"); + ok(!pNeedCurrentDirectoryForExePathA("."), "returned TRUE for \".\"\n"); + ok(pNeedCurrentDirectoryForExePathA("c:\\"), "returned FALSE for \"c:\\\"\n"); + ok(!pNeedCurrentDirectoryForExePathA("cmd.exe"), "returned TRUE for \"cmd.exe\"\n"); +} + +static void test_NeedCurrentDirectoryForExePathW(void) +{ + const WCHAR thispath[] = {'.', 0}; + const WCHAR fullpath[] = {'c', ':', '\\', 0}; + const WCHAR cmdname[] = {'c', 'm', 'd', '.', 'e', 'x', 'e', 0}; + + /* Crashes in Windows */ + if (0) + ok(pNeedCurrentDirectoryForExePathW(NULL), "returned FALSE for NULL\n"); + + SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", NULL); + ok(pNeedCurrentDirectoryForExePathW(thispath), "returned FALSE for \".\"\n"); + ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n"); + ok(pNeedCurrentDirectoryForExePathW(cmdname), "returned FALSE for \"cmd.exe\"\n"); + + SetEnvironmentVariableA("NoDefaultCurrentDirectoryInExePath", "nya"); + ok(!pNeedCurrentDirectoryForExePathW(thispath), "returned TRUE for \".\"\n"); + ok(pNeedCurrentDirectoryForExePathW(fullpath), "returned FALSE for \"c:\\\"\n"); + ok(!pNeedCurrentDirectoryForExePathW(cmdname), "returned TRUE for \"cmd.exe\"\n"); +} + START_TEST(path) { CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive; @@ -1081,6 +1123,13 @@ START_TEST(path) "GetLongPathNameA" ); pGetLongPathNameW = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll") , "GetLongPathNameW" ); + pNeedCurrentDirectoryForExePathA = + (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"), + "NeedCurrentDirectoryForExePathA" ); + pNeedCurrentDirectoryForExePathW = + (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"), + "NeedCurrentDirectoryForExePathW" ); + test_InitPathA(curdir, &curDrive, &otherDrive); test_CurrentDirectoryA(origdir,curdir); test_PathNameA(curdir, curDrive, otherDrive); @@ -1089,4 +1138,12 @@ START_TEST(path) test_GetLongPathNameW(); test_GetSystemDirectory(); test_GetWindowsDirectory(); + if (pNeedCurrentDirectoryForExePathA) + { + test_NeedCurrentDirectoryForExePathA(); + } + if (pNeedCurrentDirectoryForExePathW) + { + test_NeedCurrentDirectoryForExePathW(); + } } diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c index 0dc128cc927..fda2c91ed20 100644 --- a/dlls/localspl/localmon.c +++ b/dlls/localspl/localmon.c @@ -401,7 +401,7 @@ BOOL WINAPI localmon_XcvClosePort(HANDLE hXcv) * * RETURNS * Success: ERROR_SUCCESS - * Failure: win32 error code (same value is returned by GetLastError) + * Failure: win32 error code * * NOTES * @@ -431,13 +431,13 @@ DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInput if (res == ERROR_SUCCESS) { if (does_port_exist((LPWSTR) pInputData)) { RegCloseKey(hroot); + TRACE("=> %u\n", ERROR_ALREADY_EXISTS); return ERROR_ALREADY_EXISTS; } res = RegSetValueExW(hroot, (LPWSTR) pInputData, 0, REG_SZ, (const BYTE *) emptyW, sizeof(emptyW)); RegCloseKey(hroot); - SetLastError(ERROR_SUCCESS); - return res; } + TRACE("=> %u\n", res); return res; } @@ -509,7 +509,8 @@ DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInput /* names, that we have recognized, are valid */ if (res) return ERROR_SUCCESS; - /* ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND ore something else */ + /* ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND or something else */ + TRACE("=> %u\n", GetLastError()); return GetLastError(); } diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index a30df13eff5..c2a6947e9a9 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -425,7 +425,8 @@ static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *if nsres = nsIStreamListener_OnDataAvailable(This->nslistener, (nsIRequest*)NSCHANNEL(This->nschannel), This->nscontext, - NSINSTREAM(This->nsstream), This->readed, This->nsstream->buf_size); + NSINSTREAM(This->nsstream), This->readed-This->nsstream->buf_size, + This->nsstream->buf_size); if(NS_FAILED(nsres)) ERR("OnDataAvailable failed: %08x\n", nsres); diff --git a/dlls/msi/table.c b/dlls/msi/table.c index 0d96793a5f6..64ddcabaa22 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -91,13 +91,16 @@ static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 }; static const WCHAR szNumber[] = { 'N','u','m','b','e','r',0 }; static const WCHAR szType[] = { 'T','y','p','e',0 }; -static const MSICOLUMNINFO _Columns_cols[4] = { +/* These tables are written into (the .hash_table part). + * Do not mark them const. + */ +static MSICOLUMNINFO _Columns_cols[4] = { { szColumns, 1, szTable, MSITYPE_VALID | MSITYPE_STRING | 64, 0 }, { szColumns, 2, szNumber, MSITYPE_VALID | 2, 2 }, { szColumns, 3, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 4 }, { szColumns, 4, szType, MSITYPE_VALID | 2, 6 }, }; -static const MSICOLUMNINFO _Tables_cols[1] = { +static MSICOLUMNINFO _Tables_cols[1] = { { szTables, 1, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 0 }, }; @@ -780,12 +783,12 @@ static UINT get_table( MSIDATABASE *db, LPCWSTR name, MSITABLE **table_ret ) /* these two tables are special - we know the column types already */ if( !lstrcmpW( name, szColumns ) ) { - table->colinfo = (MSICOLUMNINFO *)_Columns_cols; + table->colinfo = _Columns_cols; table->col_count = sizeof(_Columns_cols)/sizeof(_Columns_cols[0]); } else if( !lstrcmpW( name, szTables ) ) { - table->colinfo = (MSICOLUMNINFO *)_Tables_cols; + table->colinfo = _Tables_cols; table->col_count = sizeof(_Tables_cols)/sizeof(_Tables_cols[0]); } else diff --git a/dlls/msi/tests/Makefile.in b/dlls/msi/tests/Makefile.in index 885c174fe00..d960eb22ee1 100644 --- a/dlls/msi/tests/Makefile.in +++ b/dlls/msi/tests/Makefile.in @@ -3,10 +3,11 @@ TOPOBJDIR = ../../.. SRCDIR = @srcdir@ VPATH = @srcdir@ TESTDLL = msi.dll -IMPORTS = cabinet msi shell32 ole32 advapi32 kernel32 +IMPORTS = cabinet msi shell32 ole32 oleaut32 advapi32 kernel32 EXTRALIBS = -luuid CTESTS = \ + automation.c \ db.c \ format.c \ iface.c \ diff --git a/dlls/msi/tests/automation.c b/dlls/msi/tests/automation.c new file mode 100644 index 00000000000..0977104b521 --- /dev/null +++ b/dlls/msi/tests/automation.c @@ -0,0 +1,924 @@ +/* + * Copyright (C) 2007 Misha Koshelev + * + * A test program for MSI OLE automation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include + +#include +#include +#include +#include +#include + +#include "wine/test.h" + +static const char *msifile = "winetest.msi"; +static const WCHAR szMsifile[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0}; +CHAR CURR_DIR[MAX_PATH]; +EXCEPINFO excepinfo; + +/* + * OLE automation data + **/ +static const WCHAR szProgId[] = { 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r','.','I','n','s','t','a','l','l','e','r',0 }; + +/* Installer */ +static const WCHAR szOpenPackage[] = { 'O','p','e','n','P','a','c','k','a','g','e',0 }; + +/* Session */ +static const WCHAR szProperty[] = { 'P','r','o','p','e','r','t','y',0 }; +static const WCHAR szLanguage[] = { 'L','a','n','g','u','a','g','e',0 }; +static const WCHAR szMode[] = { 'M','o','d','e',0 }; +static const WCHAR szDatabase[] = { 'D','a','t','a','b','a','s','e',0 }; +static const WCHAR szDoAction[] = { 'D','o','A','c','t','i','o','n',0 }; +static const WCHAR szSetInstallLevel[] = { 'S','e','t','I','n','s','t','a','l','l','L','e','v','e','l',0 }; +static const WCHAR szFeatureCurrentState[] = { 'F','e','a','t','u','r','e','C','u','r','r','e','n','t','S','t','a','t','e',0 }; +static const WCHAR szFeatureRequestState[] = { 'F','e','a','t','u','r','e','R','e','q','u','e','s','t','S','t','a','t','e',0 }; + +/* Database */ +static const WCHAR szOpenView[] = { 'O','p','e','n','V','i','e','w',0 }; + +/* View */ +static const WCHAR szExecute[] = { 'E','x','e','c','u','t','e',0 }; +static const WCHAR szFetch[] = { 'F','e','t','c','h',0 }; +static const WCHAR szClose[] = { 'C','l','o','s','e',0 }; + +/* Record */ +static const WCHAR szStringData[] = { 'S','t','r','i','n','g','D','a','t','a',0 }; + +static IDispatch *pInstaller; + +/* msi database data */ + +static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n" + "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n" + "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\t\tone.txt\n" + "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n" + "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n" + "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n" + "component\t\tMSITESTDIR\t0\t1\tfile\n" + "service_comp\t\tMSITESTDIR\t0\t1\tservice_file"; + +static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" + "s72\tS72\tl255\n" + "Directory\tDirectory\n" + "CABOUTDIR\tMSITESTDIR\tcabout\n" + "CHANGEDDIR\tMSITESTDIR\tchanged:second\n" + "FIRSTDIR\tMSITESTDIR\tfirst\n" + "MSITESTDIR\tProgramFilesFolder\tmsitest\n" + "NEWDIR\tCABOUTDIR\tnew\n" + "ProgramFilesFolder\tTARGETDIR\t.\n" + "TARGETDIR\t\tSourceDir"; + +static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n" + "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n" + "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n" + "Three\tOne\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n" + "Two\tOne\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n" + "feature\t\t\t\t2\t1\tTARGETDIR\t0\n" + "service_feature\t\t\t\t2\t1\tTARGETDIR\t0"; + +static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "Five\tFive\n" + "Four\tFour\n" + "One\tOne\n" + "Three\tThree\n" + "Two\tTwo\n" + "feature\tcomponent\n" + "service_feature\tservice_comp\n"; + +static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n" + "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n" + "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n" + "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n" + "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n" + "file\tcomponent\tfilename\t100\t\t\t8192\t1\n" + "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1"; + +static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "AllocateRegistrySpace\tNOT Installed\t1550\n" + "CostFinalize\t\t1000\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "InstallFiles\t\t4000\n" + "InstallServices\t\t5000\n" + "InstallFinalize\t\t6600\n" + "InstallInitialize\t\t1500\n" + "InstallValidate\t\t1400\n" + "LaunchConditions\t\t100\n" + "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000"; + +static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" + "i2\ti4\tL64\tS255\tS32\tS72\n" + "Media\tDiskId\n" + "1\t3\t\t\tDISK1\t\n" + "2\t5\t\tmsitest.cab\tDISK2\t\n"; + +static const CHAR property_dat[] = "Property\tValue\n" + "s72\tl0\n" + "Property\tProperty\n" + "DefaultUIFont\tDlgFont8\n" + "HASUIRUN\t0\n" + "INSTALLLEVEL\t3\n" + "InstallMode\tTypical\n" + "Manufacturer\tWine\n" + "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n" + "ProductCode\t{F1C3AF50-8B56-4A69-A00C-00773FE42F30}\n" + "ProductID\tnone\n" + "ProductLanguage\t1033\n" + "ProductName\tMSITEST\n" + "ProductVersion\t1.1.1\n" + "PROMPTROLLBACKCOST\tP\n" + "Setup\tSetup\n" + "UpgradeCode\t{CE067E8D-2E1A-4367-B734-4EB2BDAD6565}"; + +static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" + "s72\ti2\tl255\tL255\tL0\ts72\n" + "Registry\tRegistry\n" + "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n" + "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n" + "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n" + "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent"; + +static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t" + "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n" + "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n" + "ServiceInstall\tServiceInstall\n" + "TestService\tTestService\tTestService\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t"; + +static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n" + "s72\tl255\ti2\tL255\tI2\ts72\n" + "ServiceControl\tServiceControl\n" + "ServiceControl\tTestService\t8\t\t0\tservice_comp"; + +typedef struct _msi_table +{ + const CHAR *filename; + const CHAR *data; + int size; +} msi_table; + +#define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)} + +static const msi_table tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property), + ADD_TABLE(registry), + ADD_TABLE(service_install), + ADD_TABLE(service_control) +}; + +/* + * Database Helpers + */ + +static void write_file(const CHAR *filename, const char *data, int data_size) +{ + DWORD size; + + HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + WriteFile(hf, data, data_size, &size, NULL); + CloseHandle(hf); +} + +static void write_msi_summary_info(MSIHANDLE db) +{ + MSIHANDLE summary; + UINT r; + + r = MsiGetSummaryInformationA(db, NULL, 4, &summary); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL, + "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* write the summary changes back to the stream */ + r = MsiSummaryInfoPersist(summary); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + MsiCloseHandle(summary); +} + +static void create_database(const CHAR *name, const msi_table *tables, int num_tables) +{ + MSIHANDLE db; + UINT r; + int j; + + r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* import the tables into the database */ + for (j = 0; j < num_tables; j++) + { + const msi_table *table = &tables[j]; + + write_file(table->filename, table->data, (table->size - 1) * sizeof(char)); + + r = MsiDatabaseImportA(db, CURR_DIR, table->filename); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + DeleteFileA(table->filename); + } + + write_msi_summary_info(db); + + r = MsiDatabaseCommit(db); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + MsiCloseHandle(db); +} + +/* + * Automation helpers and tests + */ + +/* ok-like statement which takes two unicode strings as arguments */ +static CHAR string1[MAX_PATH], string2[MAX_PATH]; +static UINT len; + +#define ok_w2(format, szString1, szString2) \ +\ + if (lstrcmpW(szString1, szString2) != 0) \ + { \ + len = WideCharToMultiByte(CP_ACP, 0, szString1, -1, string1, MAX_PATH, NULL, NULL); \ + ok(len, "WideCharToMultiByteChar returned error %d\n", GetLastError()); \ +\ + len = WideCharToMultiByte(CP_ACP, 0, szString2, -1, string2, MAX_PATH, NULL, NULL); \ + ok(len, "WideCharToMultiByteChar returned error %d\n", GetLastError()); \ +\ + ok(0, format, string1, string2); \ + } + +/* exception checker */ +static WCHAR szSource[] = {'M','s','i',' ','A','P','I',' ','E','r','r','o','r',0}; + +#define ok_exception(hr, szDescription) \ + if (hr == DISP_E_EXCEPTION) \ + { \ + /* Compare wtype, source, and destination */ \ + ok(excepinfo.wCode == 1000, "Exception info was %d, expected 1000\n", excepinfo.wCode); \ +\ + ok(excepinfo.bstrSource != NULL, "Exception source was NULL\n"); \ + if (excepinfo.bstrSource) \ + ok_w2("Exception source was \"%s\" but expected to be \"%s\"\n", excepinfo.bstrSource, szSource); \ +\ + ok(excepinfo.bstrDescription != NULL, "Exception description was NULL\n"); \ + if (excepinfo.bstrDescription) \ + ok_w2("Exception description was \"%s\" but expected to be \"%s\"\n", excepinfo.bstrDescription, szDescription); \ + } + +/* Test basic IDispatch functions */ +static void test_dispatch(void) +{ + static WCHAR szOpenPackageException[] = {'O','p','e','n','P','a','c','k','a','g','e',',','P','a','c','k','a','g','e','P','a','t','h',',','O','p','t','i','o','n','s',0}; + HRESULT hr; + DISPID dispid; + OLECHAR *name; + VARIANT varresult; + VARIANTARG vararg[2]; + DISPPARAMS dispparams = {NULL, NULL, 0, 0}; + + /* Test getting ID of a function name that does not exist */ + name = (WCHAR *)szMsifile; + hr = IDispatch_GetIDsOfNames(pInstaller, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); + ok(hr == DISP_E_UNKNOWNNAME, "IDispatch::GetIDsOfNames returned 0x%08x\n", hr); + + /* Test invoking this function */ + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, NULL, NULL); + ok(hr == DISP_E_MEMBERNOTFOUND, "IDispatch::Invoke returned 0x%08x\n", hr); + + /* Test getting ID of a function name that does exist */ + name = (WCHAR *)szOpenPackage; + hr = IDispatch_GetIDsOfNames(pInstaller, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); + ok(SUCCEEDED(hr), "IDispatch::GetIDsOfNames returned 0x%08x\n", hr); + + /* Test invoking this function (without parameters passed) */ + if (0) /* All of these crash MSI on Windows XP */ + { + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, NULL, NULL); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, &excepinfo, NULL); + VariantInit(&varresult); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, &varresult, &excepinfo, NULL); + } + + /* Try with NULL params */ + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + + /* Try one empty parameter */ + dispparams.rgvarg = vararg; + dispparams.cArgs = 1; + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + + /* Try one parameter, function requires two */ + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szMsifile); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + VariantClear(&vararg[0]); + + ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); + ok_exception(hr, szOpenPackageException); +} + +/* invocation helper function */ +static HRESULT invoke(IDispatch *pDispatch, LPCWSTR szName, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, VARTYPE vtResult) +{ + OLECHAR *name = (WCHAR *)szName; + DISPID dispid; + HRESULT hr; + int i; + + hr = IDispatch_GetIDsOfNames(pDispatch, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); + ok(SUCCEEDED(hr), "IDispatch::GetIDsOfNames returned 0x%08x\n", hr); + if (!SUCCEEDED(hr)) return hr; + + VariantInit(pVarResult); + memset(&excepinfo, 0, sizeof(excepinfo)); + hr = IDispatch_Invoke(pDispatch, dispid, &IID_NULL, LOCALE_NEUTRAL, wFlags, pDispParams, pVarResult, &excepinfo, NULL); + + if (SUCCEEDED(hr)) + { + ok(V_VT(pVarResult) == vtResult, "Variant result type is %d, expected %d\n", V_VT(pVarResult), vtResult); + if (vtResult != VT_EMPTY) + { + hr = VariantChangeTypeEx(pVarResult, pVarResult, LOCALE_NEUTRAL, 0, vtResult); + ok(SUCCEEDED(hr), "VariantChangeTypeEx returned 0x%08x\n", hr); + } + } + + for (i=0; icArgs; i++) + VariantClear(&pDispParams->rgvarg[i]); + + return hr; +} + +/* Object_Property helper functions */ + +static HRESULT Installer_OpenPackage(LPCWSTR szPackagePath, int options, IDispatch **pSession) +{ + VARIANT varresult; + VARIANTARG vararg[2]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szPackagePath); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I4; + V_I4(&vararg[0]) = options; + + hr = invoke(pInstaller, szOpenPackage, DISPATCH_METHOD, &dispparams, &varresult, VT_DISPATCH); + *pSession = V_DISPATCH(&varresult); + return hr; +} + +static HRESULT Session_PropertyGet(IDispatch *pSession, LPCWSTR szName, LPCWSTR szReturn) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szName); + + hr = invoke(pSession, szProperty, DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR); + lstrcpyW((WCHAR *)szReturn, V_BSTR(&varresult)); + VariantClear(&varresult); + return hr; +} + +static HRESULT Session_PropertyPut(IDispatch *pSession, LPCWSTR szName, LPCWSTR szValue) +{ + VARIANT varresult; + VARIANTARG vararg[2]; + DISPID dispid = DISPID_PROPERTYPUT; + DISPPARAMS dispparams = {vararg, &dispid, sizeof(vararg)/sizeof(VARIANTARG), 1}; + + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szName); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szValue); + + return invoke(pSession, szProperty, DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY); +} + +static HRESULT Session_LanguageGet(IDispatch *pSession, UINT *pLangId) +{ + VARIANT varresult; + DISPPARAMS dispparams = {NULL, NULL, 0, 0}; + HRESULT hr; + + hr = invoke(pSession, szLanguage, DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4); + *pLangId = V_I4(&varresult); + VariantClear(&varresult); + return hr; +} + +static HRESULT Session_ModeGet(IDispatch *pSession, int iFlag, BOOL *pMode) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I4; + V_I4(&vararg[0]) = iFlag; + + hr = invoke(pSession, szMode, DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BOOL); + *pMode = V_BOOL(&varresult); + VariantClear(&varresult); + return hr; +} + +static HRESULT Session_ModePut(IDispatch *pSession, int iFlag, BOOL bMode) +{ + VARIANT varresult; + VARIANTARG vararg[2]; + DISPID dispid = DISPID_PROPERTYPUT; + DISPPARAMS dispparams = {vararg, &dispid, sizeof(vararg)/sizeof(VARIANTARG), 1}; + + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_I4; + V_I4(&vararg[1]) = iFlag; + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BOOL; + V_BOOL(&vararg[0]) = bMode; + + return invoke(pSession, szMode, DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY); +} + +static HRESULT Session_Database(IDispatch *pSession, IDispatch **pDatabase) +{ + VARIANT varresult; + DISPPARAMS dispparams = {NULL, NULL, 0, 0}; + HRESULT hr; + + hr = invoke(pSession, szDatabase, DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_DISPATCH); + *pDatabase = V_DISPATCH(&varresult); + return hr; +} + +static HRESULT Session_DoAction(IDispatch *pSession, LPCWSTR szAction, int *iReturn) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szAction); + + hr = invoke(pSession, szDoAction, DISPATCH_METHOD, &dispparams, &varresult, VT_I4); + *iReturn = V_I4(&varresult); + VariantClear(&varresult); + return hr; +} + +static HRESULT Session_SetInstallLevel(IDispatch *pSession, long iInstallLevel) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I4; + V_I4(&vararg[0]) = iInstallLevel; + + return invoke(pSession, szSetInstallLevel, DISPATCH_METHOD, &dispparams, &varresult, VT_EMPTY); +} + +static HRESULT Session_FeatureCurrentState(IDispatch *pSession, LPCWSTR szName, int *pState) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szName); + + hr = invoke(pSession, szFeatureCurrentState, DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4); + *pState = V_I4(&varresult); + VariantClear(&varresult); + return hr; +} + +static HRESULT Session_FeatureRequestStateGet(IDispatch *pSession, LPCWSTR szName, int *pState) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szName); + + hr = invoke(pSession, szFeatureRequestState, DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4); + *pState = V_I4(&varresult); + VariantClear(&varresult); + return hr; +} + +static HRESULT Session_FeatureRequestStatePut(IDispatch *pSession, LPCWSTR szName, int iState) +{ + VARIANT varresult; + VARIANTARG vararg[2]; + DISPID dispid = DISPID_PROPERTYPUT; + DISPPARAMS dispparams = {vararg, &dispid, sizeof(vararg)/sizeof(VARIANTARG), 1}; + + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szName); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I4; + V_I4(&vararg[0]) = iState; + + return invoke(pSession, szFeatureRequestState, DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY); +} + +static HRESULT Database_OpenView(IDispatch *pDatabase, LPCWSTR szSql, IDispatch **pView) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szSql); + + hr = invoke(pDatabase, szOpenView, DISPATCH_METHOD, &dispparams, &varresult, VT_DISPATCH); + *pView = V_DISPATCH(&varresult); + return hr; +} + +static HRESULT View_Execute(IDispatch *pView, IDispatch *pRecord) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_DISPATCH; + V_DISPATCH(&vararg[0]) = pRecord; + + return invoke(pView, szExecute, DISPATCH_METHOD, &dispparams, &varresult, VT_EMPTY); +} + +static HRESULT View_Fetch(IDispatch *pView, IDispatch **ppRecord) +{ + VARIANT varresult; + DISPPARAMS dispparams = {NULL, NULL, 0, 0}; + HRESULT hr = invoke(pView, szFetch, DISPATCH_METHOD, &dispparams, &varresult, VT_DISPATCH); + *ppRecord = V_DISPATCH(&varresult); + return hr; +} + +static HRESULT View_Close(IDispatch *pView) +{ + VARIANT varresult; + DISPPARAMS dispparams = {NULL, NULL, 0, 0}; + return invoke(pView, szClose, DISPATCH_METHOD, &dispparams, &varresult, VT_EMPTY); +} + +static HRESULT Record_StringDataGet(IDispatch *pRecord, int iField, LPCWSTR szString) +{ + VARIANT varresult; + VARIANTARG vararg[1]; + DISPPARAMS dispparams = {vararg, NULL, sizeof(vararg)/sizeof(VARIANTARG), 0}; + HRESULT hr; + + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I4; + V_I4(&vararg[0]) = iField; + + hr = invoke(pRecord, szStringData, DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR); + lstrcpyW((WCHAR *)szString, V_BSTR(&varresult)); + VariantClear(&varresult); + return hr; +} + +static HRESULT Record_StringDataPut(IDispatch *pRecord, int iField, LPCWSTR szString) +{ + VARIANT varresult; + VARIANTARG vararg[2]; + DISPID dispid = DISPID_PROPERTYPUT; + DISPPARAMS dispparams = {vararg, &dispid, sizeof(vararg)/sizeof(VARIANTARG), 1}; + + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_I4; + V_I4(&vararg[1]) = iField; + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szString); + + return invoke(pRecord, szStringData, DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_BSTR); +} + +/* Test the various objects */ + +static void test_Database(IDispatch *pDatabase) +{ + static WCHAR szSql[] = { 'S','E','L','E','C','T',' ','`','F','e','a','t','u','r','e','`',' ','F','R','O','M',' ','`','F','e','a','t','u','r','e','`',' ','W','H','E','R','E',' ','`','F','e','a','t','u','r','e','_','P','a','r','e','n','t','`','=','\'','O','n','e','\'',0 }; + static WCHAR szThree[] = { 'T','h','r','e','e',0 }; + static WCHAR szTwo[] = { 'T','w','o',0 }; + static WCHAR szStringDataField[] = { 'S','t','r','i','n','g','D','a','t','a',',','F','i','e','l','d',0 }; + IDispatch *pView = NULL; + HRESULT hr; + + hr = Database_OpenView(pDatabase, szSql, &pView); + ok(SUCCEEDED(hr), "Database_OpenView failed, hresult 0x%08x\n", hr); + if (SUCCEEDED(hr)) + { + IDispatch *pRecord = NULL; + WCHAR szString[MAX_PATH]; + + /* View::Execute */ + hr = View_Execute(pView, NULL); + ok(SUCCEEDED(hr), "View_Execute failed, hresult 0x%08x\n", hr); + + /* View::Fetch */ + hr = View_Fetch(pView, &pRecord); + ok(SUCCEEDED(hr), "View_Fetch failed, hresult 0x%08x\n", hr); + ok(pRecord != NULL, "View_Fetch should not have returned NULL record\n"); + if (pRecord) + { + /* Record::StringDataGet */ + memset(szString, 0, sizeof(szString)); + hr = Record_StringDataGet(pRecord, 1, szString); + ok(SUCCEEDED(hr), "Record_StringDataGet failed, hresult 0x%08x\n", hr); + ok_w2("Record_StringDataGet result was %s but expected %s\n", szString, szThree); + + /* Record::StringDataPut with incorrect index */ + hr = Record_StringDataPut(pRecord, -1, szString); + ok(hr == DISP_E_EXCEPTION, "Record_StringDataPut failed, hresult 0x%08x\n", hr); + ok_exception(hr, szStringDataField); + + IDispatch_Release(pRecord); + } + + /* View::Fetch */ + hr = View_Fetch(pView, &pRecord); + ok(SUCCEEDED(hr), "View_Fetch failed, hresult 0x%08x\n", hr); + ok(pRecord != NULL, "View_Fetch should not have returned NULL record\n"); + if (pRecord) + { + /* Record::StringDataGet */ + memset(szString, 0, sizeof(szString)); + hr = Record_StringDataGet(pRecord, 1, szString); + ok(SUCCEEDED(hr), "Record_StringDataGet failed, hresult 0x%08x\n", hr); + ok_w2("Record_StringDataGet result was %s but expected %s\n", szString, szTwo); + + IDispatch_Release(pRecord); + } + + /* View::Fetch */ + hr = View_Fetch(pView, &pRecord); + ok(SUCCEEDED(hr), "View_Fetch failed, hresult 0x%08x\n", hr); + ok(pRecord == NULL, "View_Fetch should have returned NULL record\n"); + if (pRecord) + IDispatch_Release(pRecord); + + /* View::Close */ + hr = View_Close(pView); + ok(SUCCEEDED(hr), "View_Close failed, hresult 0x%08x\n", hr); + + IDispatch_Release(pView); + } +} + +static void test_Session(IDispatch *pSession) +{ + static WCHAR szProductName[] = { 'P','r','o','d','u','c','t','N','a','m','e',0 }; + static WCHAR szMSITEST[] = { 'M','S','I','T','E','S','T',0 }; + static WCHAR szOne[] = { 'O','n','e',0 }; + static WCHAR szCostInitialize[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 }; + static WCHAR szEmpty[] = { 0 }; + static WCHAR szEquals[] = { '=',0 }; + static WCHAR szPropertyName[] = { 'P','r','o','p','e','r','t','y',',','N','a','m','e',0 }; + WCHAR stringw[MAX_PATH]; + CHAR string[MAX_PATH]; + UINT len; + BOOL bool; + int myint; + IDispatch *pDatabase = NULL; + HRESULT hr; + + /* Session::Property, get */ + memset(stringw, 0, sizeof(stringw)); + hr = Session_PropertyGet(pSession, szProductName, stringw); + ok(SUCCEEDED(hr), "Session_PropertyGet failed, hresult 0x%08x\n", hr); + if (lstrcmpW(stringw, szMSITEST) != 0) + { + len = WideCharToMultiByte(CP_ACP, 0, stringw, -1, string, MAX_PATH, NULL, NULL); + ok(len, "WideCharToMultiByteChar returned error %d\n", GetLastError()); + ok(0, "Property \"ProductName\" expected to be \"MSITEST\" but was \"%s\"\n", string); + } + + /* Session::Property, put */ + hr = Session_PropertyPut(pSession, szProductName, szProductName); + ok(SUCCEEDED(hr), "Session_PropertyPut failed, hresult 0x%08x\n", hr); + memset(stringw, 0, sizeof(stringw)); + hr = Session_PropertyGet(pSession, szProductName, stringw); + ok(SUCCEEDED(hr), "Session_PropertyGet failed, hresult 0x%08x\n", hr); + if (lstrcmpW(stringw, szProductName) != 0) + { + len = WideCharToMultiByte(CP_ACP, 0, stringw, -1, string, MAX_PATH, NULL, NULL); + ok(len, "WideCharToMultiByteChar returned error %d\n", GetLastError()); + ok(0, "Property \"ProductName\" expected to be \"ProductName\" but was \"%s\"\n", string); + } + + /* Try putting a property using empty property identifier */ + hr = Session_PropertyPut(pSession, szEmpty, szProductName); + ok(hr == DISP_E_EXCEPTION, "Session_PropertyPut failed, hresult 0x%08x\n", hr); + ok_exception(hr, szPropertyName); + + /* Try putting a property using illegal property identifier */ + hr = Session_PropertyPut(pSession, szEquals, szProductName); + ok(SUCCEEDED(hr), "Session_PropertyPut failed, hresult 0x%08x\n", hr); + + /* Session::Language, get */ + hr = Session_LanguageGet(pSession, &len); + ok(SUCCEEDED(hr), "Session_LanguageGet failed, hresult 0x%08x\n", hr); + /* Not sure how to check the language is correct */ + + /* Session::Mode, get */ + hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTATEND, &bool); + ok(SUCCEEDED(hr), "Session_ModeGet failed, hresult 0x%08x\n", hr); + ok(!bool, "Reboot at end session mode is %d\n", bool); + + /* Session::Mode, put */ + hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTATEND, TRUE); + ok(SUCCEEDED(hr), "Session_ModePut failed, hresult 0x%08x\n", hr); + hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTATEND, &bool); + ok(SUCCEEDED(hr), "Session_ModeGet failed, hresult 0x%08x\n", hr); + ok(bool, "Reboot at end session mode is %d, expected 1\n", bool); + hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTATEND, FALSE); /* set it again so we don't reboot */ + ok(SUCCEEDED(hr), "Session_ModePut failed, hresult 0x%08x\n", hr); + + /* Session::Database, get */ + hr = Session_Database(pSession, &pDatabase); + ok(SUCCEEDED(hr), "Session_Database failed, hresult 0x%08x\n", hr); + if (SUCCEEDED(hr)) + { + test_Database(pDatabase); + IDispatch_Release(pDatabase); + } + + /* Session::DoAction(CostInitialize) must occur before the next statements */ + hr = Session_DoAction(pSession, szCostInitialize, &myint); + ok(SUCCEEDED(hr), "Session_DoAction failed, hresult 0x%08x\n", hr); + ok(myint == IDOK, "DoAction(CostInitialize) returned %d, %d expected\n", myint, IDOK); + + /* Session::SetInstallLevel */ + hr = Session_SetInstallLevel(pSession, INSTALLLEVEL_MINIMUM); + ok(SUCCEEDED(hr), "Session_SetInstallLevel failed, hresult 0x%08x\n", hr); + + /* Session::FeatureCurrentState, get */ + hr = Session_FeatureCurrentState(pSession, szOne, &myint); + ok(SUCCEEDED(hr), "Session_FeatureCurrentState failed, hresult 0x%08x\n", hr); + ok(myint == INSTALLSTATE_UNKNOWN, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN); + + /* Session::FeatureRequestState, put */ + hr = Session_FeatureRequestStatePut(pSession, szOne, INSTALLSTATE_ADVERTISED); + ok(SUCCEEDED(hr), "Session_FeatureRequestStatePut failed, hresult 0x%08x\n", hr); + hr = Session_FeatureRequestStateGet(pSession, szOne, &myint); + ok(SUCCEEDED(hr), "Session_FeatureRequestStateGet failed, hresult 0x%08x\n", hr); + ok(myint == INSTALLSTATE_ADVERTISED, "Feature request state was %d but expected %d\n", myint, INSTALLSTATE_ADVERTISED); +} + +static void test_Installer(void) +{ + static WCHAR szBackslash[] = { '\\',0 }; + WCHAR szPath[MAX_PATH]; + HRESULT hr; + UINT len; + IDispatch *pSession = NULL; + + if (!pInstaller) return; + + create_database(msifile, tables, sizeof(tables) / sizeof(msi_table)); + + len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, CURR_DIR, -1, szPath, MAX_PATH); + ok(len, "MultiByteToWideChar returned error %d\n", GetLastError()); + if (!len) return; + + lstrcatW(szPath, szBackslash); + lstrcatW(szPath, szMsifile); + + /* Installer::OpenPackage */ + hr = Installer_OpenPackage(szPath, 0, &pSession); + ok(SUCCEEDED(hr), "Installer_OpenPackage failed, hresult 0x%08x\n", hr); + if (SUCCEEDED(hr)) + { + test_Session(pSession); + IDispatch_Release(pSession); + } + + DeleteFileA(msifile); +} + +START_TEST(automation) +{ + DWORD len; + char temp_path[MAX_PATH], prev_path[MAX_PATH]; + HRESULT hr; + CLSID clsid; + IUnknown *pUnk; + + GetCurrentDirectoryA(MAX_PATH, prev_path); + GetTempPath(MAX_PATH, temp_path); + SetCurrentDirectoryA(temp_path); + + lstrcpyA(CURR_DIR, temp_path); + len = lstrlenA(CURR_DIR); + + if(len && (CURR_DIR[len - 1] == '\\')) + CURR_DIR[len - 1] = 0; + + hr = OleInitialize(NULL); + ok (SUCCEEDED(hr), "OleInitialize returned 0x%08x\n", hr); + hr = CLSIDFromProgID(szProgId, &clsid); + ok (SUCCEEDED(hr), "CLSIDFromProgID returned 0x%08x\n", hr); + hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); + todo_wine ok(SUCCEEDED(hr), "CoCreateInstance returned 0x%08x\n", hr); + + if (pUnk) + { + hr = IUnknown_QueryInterface(pUnk, &IID_IDispatch, (void **)&pInstaller); + ok (SUCCEEDED(hr), "IUnknown::QueryInterface returned 0x%08x\n", hr); + + todo_wine test_dispatch(); + todo_wine test_Installer(); + + hr = IUnknown_Release(pUnk); + ok (SUCCEEDED(hr), "IUnknown::Release returned 0x%08x\n", hr); + } + + OleUninitialize(); + + SetCurrentDirectoryA(prev_path); +} diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 1d24f5d54f8..9f985407db5 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -1265,7 +1265,7 @@ static void test_streamtable(void) memset(buf, 0, MAX_PATH); r = MsiRecordReadStream( rec, 2, buf, &size ); ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r); - ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s", buf); + ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf); MsiCloseHandle( rec ); diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c index 35ce1bee6fe..0e94e35ecef 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -247,7 +247,7 @@ NtQuerySecurityObject( pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pace->Header.AceFlags = CONTAINER_INHERIT_ACE; pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1); - pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | 0x3f; + pace->Mask = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; pace->SidStart = BufferIndex; /* SID S-1-5-12 (System) */ @@ -267,7 +267,7 @@ NtQuerySecurityObject( pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pace->Header.AceFlags = CONTAINER_INHERIT_ACE; pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(2); - pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | 0x3f; + pace->Mask = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; pace->SidStart = BufferIndex; /* S-1-5-12 (Administrators) */ diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c index ea316d186e4..30c71db2c7a 100644 --- a/dlls/ntdll/time.c +++ b/dlls/ntdll/time.c @@ -403,7 +403,7 @@ static const struct tagTZ_INFO TZ_INFO[] = {'P','h','i','l','i','p','p','i','n','e',' ','T','i','m','e','\0'}, -480, 0}, {"NOVST", {'N','o','v','o','s','i','b','i','r','s','k',' ','S','u','m','m','e','r', - ' ','T','i','m','e','\0'}, -480, 1}, + ' ','T','i','m','e','\0'}, -420, 1}, {"UZT", {'U','z','b','e','k','i','s','t','h','a','n',' ','T','i','m','e','\0'}, -300, 0} }; diff --git a/dlls/odbccp32/tests/misc.c b/dlls/odbccp32/tests/misc.c index fdfecc027e8..cffbd9c2132 100644 --- a/dlls/odbccp32/tests/misc.c +++ b/dlls/odbccp32/tests/misc.c @@ -120,7 +120,7 @@ static void test_SQLInstallDriverManager(void) sql_ret = SQLInstallerErrorW(1, &error_code, NULL, 0, NULL); ok(bool_ret, "SQLInstallDriverManager unexpectedly failed\n"); ok(sql_ret == SQL_NO_DATA, "Expected SQL_NO_DATA, got %d\n", sql_ret); - /* path_out should in practice be less then 0xcafe */ + /* path_out should in practice be less than 0xcafe */ ok(path_out != 0xcafe, "Expected path_out to show the correct amount of bytes\n"); } diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c index 7d0637ef7e2..3783acaf88d 100644 --- a/dlls/oleaut32/tmarshal.c +++ b/dlls/oleaut32/tmarshal.c @@ -286,14 +286,12 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) { ERR("No %s key found.\n",interfacekey); return E_FAIL; } - type = (1< +#include + +#include "quartz_private.h" +#include "control_private.h" +#include "pin.h" + +#include "uuids.h" +#include "mmreg.h" +#include "vfwmsgs.h" +#include "mmsystem.h" + +#include "winternl.h" + +#include "wine/unicode.h" +#include "wine/debug.h" + +#include "parser.h" + +WINE_DEFAULT_DEBUG_CHANNEL(quartz); + +#define SEQUENCE_HEADER_CODE 0xB3 +#define PACK_START_CODE 0xBA + +#define SYSTEM_START_CODE 0xBB +#define AUDIO_ELEMENTARY_STREAM 0xC0 +#define VIDEO_ELEMENTARY_STREAM 0xE0 + +#define MPEG_SYSTEM_HEADER 3 +#define MPEG_VIDEO_HEADER 2 +#define MPEG_AUDIO_HEADER 1 +#define MPEG_NO_HEADER 0 + + +typedef struct MPEGSplitterImpl +{ + ParserImpl Parser; + IMediaSample *pCurrentSample; + LONGLONG EndOfFile; +} MPEGSplitterImpl; + +static int MPEGSplitter_head_check(const BYTE *header) +{ + /* If this is a possible start code, check for a system or video header */ + if (header[0] == 0 && header[1] == 0 && header[2] == 1) + { + /* Check if we got a system or elementary stream start code */ + if (header[3] == PACK_START_CODE || + header[3] == VIDEO_ELEMENTARY_STREAM || + header[3] == AUDIO_ELEMENTARY_STREAM) + return MPEG_SYSTEM_HEADER; + + /* Check for a MPEG video sequence start code */ + if (header[3] == SEQUENCE_HEADER_CODE) + return MPEG_VIDEO_HEADER; + } + + /* This should give a good guess if we have an MPEG audio header */ + if(header[0] == 0xff && ((header[1]>>5)&0x7) == 0x7 && + ((header[1]>>1)&0x3) != 0 && ((header[2]>>4)&0xf) != 0xf && + ((header[2]>>2)&0x3) != 0x3) + return MPEG_AUDIO_HEADER; + + /* Nothing yet.. */ + return MPEG_NO_HEADER; +} + + +static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample) +{ + MPEGSplitterImpl *This = (MPEGSplitterImpl*)iface; + LPBYTE pbSrcStream = NULL; + DWORD cbSrcStream = 0; + DWORD used_bytes = 0; + REFERENCE_TIME tStart, tStop; + HRESULT hr; + BYTE *pbDstStream; + DWORD cbDstStream; + long remaining_bytes = 0; + Parser_OutputPin * pOutputPin; + DWORD bytes_written = 0; + + pOutputPin = (Parser_OutputPin*)This->Parser.ppPins[1]; + + hr = IMediaSample_GetTime(pSample, &tStart, &tStop); + if (SUCCEEDED(hr)) + { + cbSrcStream = IMediaSample_GetActualDataLength(pSample); + hr = IMediaSample_GetPointer(pSample, &pbSrcStream); + } + + /* trace removed for performance reasons */ + /* TRACE("(%p), %llu -> %llu\n", pSample, tStart, tStop); */ + + if (This->pCurrentSample) + bytes_written = IMediaSample_GetActualDataLength(This->pCurrentSample); + + while (hr == S_OK && used_bytes < cbSrcStream) + { + remaining_bytes = (long)(This->EndOfFile - BYTES_FROM_MEDIATIME(tStart) - used_bytes); + if (remaining_bytes <= 0) + break; + + if (!This->pCurrentSample) + { + /* cache media sample until it is ready to be despatched + * (i.e. we reach the end of the chunk) */ + hr = OutputPin_GetDeliveryBuffer(&pOutputPin->pin, &This->pCurrentSample, NULL, NULL, 0); + if (FAILED(hr)) + { + TRACE("Skipping sending sample due to error (%x)\n", hr); + This->pCurrentSample = NULL; + break; + } + + IMediaSample_SetTime(This->pCurrentSample, NULL, NULL); + hr = IMediaSample_SetActualDataLength(This->pCurrentSample, 0); + assert(hr == S_OK); + bytes_written = 0; + } + + hr = IMediaSample_GetPointer(This->pCurrentSample, &pbDstStream); + if (SUCCEEDED(hr)) + { + cbDstStream = IMediaSample_GetSize(This->pCurrentSample); + remaining_bytes = min(remaining_bytes, (long)(cbDstStream - bytes_written)); + + assert(remaining_bytes >= 0); + + /* trace removed for performance reasons */ + /* TRACE("remaining_bytes: %d, cbSrcStream: 0x%x\n", remaining_bytes, cbSrcStream); */ + } + + if (remaining_bytes <= (long)(cbSrcStream-used_bytes)) + { + if (SUCCEEDED(hr)) + { + memcpy(pbDstStream + bytes_written, pbSrcStream + used_bytes, remaining_bytes); + bytes_written += remaining_bytes; + + hr = IMediaSample_SetActualDataLength(This->pCurrentSample, bytes_written); + assert(hr == S_OK); + + used_bytes += remaining_bytes; + } + + if (SUCCEEDED(hr)) + { + REFERENCE_TIME tMPEGStart, tMPEGStop; + + pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / pOutputPin->dwSampleSize; + + tMPEGStart = (tStart + MEDIATIME_FROM_BYTES(used_bytes-bytes_written)) / + (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize); + tMPEGStop = (tStart + MEDIATIME_FROM_BYTES(used_bytes)) / + (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize); + + /* If the start of the sample has a valid MPEG header, it's a + * sync point */ + if (MPEGSplitter_head_check(pbDstStream) == MPEG_AUDIO_HEADER) + IMediaSample_SetSyncPoint(This->pCurrentSample, TRUE); + else + IMediaSample_SetSyncPoint(This->pCurrentSample, FALSE); + IMediaSample_SetTime(This->pCurrentSample, &tMPEGStart, &tMPEGStop); + + hr = OutputPin_SendSample(&pOutputPin->pin, This->pCurrentSample); + if (FAILED(hr)) + WARN("Error sending sample (%x)\n", hr); + } + + if (This->pCurrentSample) + IMediaSample_Release(This->pCurrentSample); + This->pCurrentSample = NULL; + } + else + { + if (SUCCEEDED(hr)) + { + memcpy(pbDstStream + bytes_written, pbSrcStream + used_bytes, cbSrcStream - used_bytes); + bytes_written += cbSrcStream - used_bytes; + IMediaSample_SetActualDataLength(This->pCurrentSample, bytes_written); + + used_bytes += cbSrcStream - used_bytes; + } + } + } + + if (BYTES_FROM_MEDIATIME(tStop) >= This->EndOfFile) + { + int i; + + TRACE("End of file reached (%d out of %d bytes used)\n", used_bytes, cbSrcStream); + + if (This->pCurrentSample) + { + /* Make sure the last bit of data, if any, is sent */ + if (IMediaSample_GetActualDataLength(This->pCurrentSample) > 0) + { + REFERENCE_TIME tMPEGStart, tMPEGStop; + + pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / pOutputPin->dwSampleSize; + + tMPEGStart = (tStart + MEDIATIME_FROM_BYTES(used_bytes-bytes_written)) / + (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize); + tMPEGStop = (tStart + MEDIATIME_FROM_BYTES(used_bytes)) / + (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize); + + if (MPEGSplitter_head_check(pbDstStream) == MPEG_AUDIO_HEADER) + IMediaSample_SetSyncPoint(This->pCurrentSample, TRUE); + else + IMediaSample_SetSyncPoint(This->pCurrentSample, FALSE); + IMediaSample_SetTime(This->pCurrentSample, &tMPEGStart, &tMPEGStop); + + hr = OutputPin_SendSample(&pOutputPin->pin, This->pCurrentSample); + if (FAILED(hr)) + WARN("Error sending sample (%x)\n", hr); + } + IMediaSample_Release(This->pCurrentSample); + } + This->pCurrentSample = NULL; + + for (i = 0; i < This->Parser.cStreams; i++) + { + IPin* ppin; + HRESULT hr; + + TRACE("Send End Of Stream to output pin %d\n", i); + + hr = IPin_ConnectedTo(This->Parser.ppPins[i+1], &ppin); + if (SUCCEEDED(hr)) + { + hr = IPin_EndOfStream(ppin); + IPin_Release(ppin); + } + if (FAILED(hr)) + WARN("Error sending EndOfStream to pin %d (%x)\n", i, hr); + } + + /* Force the pullpin thread to stop */ + hr = S_FALSE; + } + + return hr; +} + + +static HRESULT MPEGSplitter_query_accept(LPVOID iface, const AM_MEDIA_TYPE *pmt) +{ + if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Stream)) + return S_FALSE; + + if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1Audio)) + return S_OK; + + if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1Video)) + FIXME("MPEG-1 video streams not yet supported.\n"); + else if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1System)) + FIXME("MPEG-1 system streams not yet supported.\n"); + else if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1VideoCD)) + FIXME("MPEG-1 VideoCD streams not yet supported.\n"); + + return S_FALSE; +} + + +static const WCHAR wszAudioStream[] = {'A','u','d','i','o',0}; +static const WCHAR wszVideoStream[] = {'V','i','d','e','o',0}; + +static HRESULT MPEGSplitter_init_audio(MPEGSplitterImpl *This, const BYTE *header, PIN_INFO *ppiOutput, AM_MEDIA_TYPE *pamt) +{ + static const DWORD freqs[10] = { 44100, 48000, 32000, 22050, 24000, + 16000, 11025, 12000, 8000, 0 }; + static const DWORD tabsel_123[2][3][16] = { + { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, + {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, + {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, + + { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } + }; + + WAVEFORMATEX *format; + int bitrate_index; + int freq_index; + int mode_ext; + int emphasis; + int padding; + int lsf = 1; + int mpeg1; + int layer; + int mode; + + ZeroMemory(pamt, sizeof(*pamt)); + ppiOutput->dir = PINDIR_OUTPUT; + ppiOutput->pFilter = (IBaseFilter*)This; + wsprintfW(ppiOutput->achName, wszAudioStream); + + memcpy(&pamt->formattype, &FORMAT_WaveFormatEx, sizeof(GUID)); + memcpy(&pamt->majortype, &MEDIATYPE_Audio, sizeof(GUID)); + memcpy(&pamt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload, sizeof(GUID)); + + pamt->lSampleSize = 0; + pamt->bFixedSizeSamples = TRUE; + pamt->bTemporalCompression = 0; + + mpeg1 = (header[1]>>4)&0x1; + if (mpeg1) + lsf = ((header[1]>>3)&0x1)^1; + + layer = 4-((header[1]>>1)&0x3); + bitrate_index = ((header[2]>>4)&0xf); + freq_index = ((header[2]>>2)&0x3) + (mpeg1?(lsf*3):6); + padding = ((header[2]>>1)&0x1); + mode = ((header[3]>>6)&0x3); + mode_ext = ((header[3]>>4)&0x3); + emphasis = ((header[3]>>0)&0x3); + + + pamt->cbFormat = ((layer==3)? sizeof(MPEGLAYER3WAVEFORMAT) : + sizeof(MPEG1WAVEFORMAT)); + pamt->pbFormat = CoTaskMemAlloc(pamt->cbFormat); + if (!pamt->pbFormat) + return E_OUTOFMEMORY; + ZeroMemory(pamt->pbFormat, pamt->cbFormat); + format = (WAVEFORMATEX*)pamt->pbFormat; + + format->wFormatTag = ((layer == 3) ? WAVE_FORMAT_MPEGLAYER3 : + WAVE_FORMAT_MPEG); + format->nChannels = ((mode == 3) ? 1 : 2); + format->nSamplesPerSec = freqs[freq_index]; + format->nAvgBytesPerSec = tabsel_123[lsf][layer-1][bitrate_index] * 1000 / 8; + if (format->nAvgBytesPerSec == 0) + { + WARN("Variable-bitrate audio is not supported.\n"); + return E_FAIL; + } + + if (layer == 3) + format->nBlockAlign = format->nAvgBytesPerSec * 8 * 144 / + (format->nSamplesPerSec<nBlockAlign = format->nAvgBytesPerSec * 8 * 144 / + format->nSamplesPerSec + (padding - 4); + else + format->nBlockAlign = ((format->nAvgBytesPerSec * 8 * 12 / + format->nSamplesPerSec + padding) << 2) - 4; + + format->wBitsPerSample = 0; + + if (layer == 3) + { + MPEGLAYER3WAVEFORMAT *mp3format = (MPEGLAYER3WAVEFORMAT*)format; + + format->cbSize = MPEGLAYER3_WFX_EXTRA_BYTES; + + mp3format->wID = MPEGLAYER3_ID_MPEG; + mp3format->fdwFlags = (padding ? + MPEGLAYER3_FLAG_PADDING_OFF : + MPEGLAYER3_FLAG_PADDING_ON); + mp3format->nBlockSize = format->nBlockAlign; + mp3format->nFramesPerBlock = 1; + + /* Beware the evil magic numbers. This struct is apparently horribly + * under-documented, and the only references I could find had it being + * set to this with no real explanation. It works fine though, so I'm + * not complaining (yet). + */ + mp3format->nCodecDelay = 1393; + } + else + { + MPEG1WAVEFORMAT *mpgformat = (MPEG1WAVEFORMAT*)format; + + format->cbSize = 22; + + mpgformat->fwHeadLayer = ((layer == 1) ? ACM_MPEG_LAYER1 : + ((layer == 2) ? ACM_MPEG_LAYER2 : + ACM_MPEG_LAYER3)); + mpgformat->dwHeadBitrate = format->nAvgBytesPerSec * 8; + mpgformat->fwHeadMode = ((mode == 3) ? ACM_MPEG_SINGLECHANNEL : + ((mode == 2) ? ACM_MPEG_DUALCHANNEL : + ((mode == 1) ? ACM_MPEG_JOINTSTEREO : + ACM_MPEG_STEREO))); + mpgformat->fwHeadModeExt = ((mode == 1) ? 0x0F : (1<wHeadEmphasis = emphasis + 1; + mpgformat->fwHeadFlags = ACM_MPEG_ID_MPEG1; + } + pamt->subtype.Data1 = format->wFormatTag; + + TRACE("MPEG audio stream detected:\n" + "\tLayer %d (%#x)\n" + "\tFrequency: %d\n" + "\tChannels: %d (%d)\n" + "\tBytesPerSec: %d\n", + layer, format->wFormatTag, format->nSamplesPerSec, + format->nChannels, mode, format->nAvgBytesPerSec); + + dump_AM_MEDIA_TYPE(pamt); + + return S_OK; +} + + +static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin) +{ + PullPin *pPin = (PullPin *)iface; + MPEGSplitterImpl *This = (MPEGSplitterImpl*)pPin->pin.pinInfo.pFilter; + ALLOCATOR_PROPERTIES props; + HRESULT hr; + LONGLONG pos = 0; /* in bytes */ + BYTE header[4]; + int streamtype = 0; + LONGLONG total, avail; + AM_MEDIA_TYPE amt; + PIN_INFO piOutput; + + IAsyncReader_Length(pPin->pReader, &total, &avail); + This->EndOfFile = total; + + hr = IAsyncReader_SyncRead(pPin->pReader, pos, 4, (LPVOID)&header[0]); + if (SUCCEEDED(hr)) + pos += 4; + + while(SUCCEEDED(hr) && !(streamtype=MPEGSplitter_head_check(header))) + { + /* No valid header yet; shift by a byte and check again */ + memcpy(header, header+1, 3); + hr = IAsyncReader_SyncRead(pPin->pReader, pos++, 1, (LPVOID)&header[3]); + } + if (FAILED(hr)) + return hr; + + switch(streamtype) + { + case MPEG_AUDIO_HEADER: + hr = MPEGSplitter_init_audio(This, header, &piOutput, &amt); + if (SUCCEEDED(hr)) + { + WAVEFORMATEX *format = (WAVEFORMATEX*)amt.pbFormat; + + props.cbAlign = 1; + props.cbPrefix = 0; + /* Make the output buffer a multiple of the frame size */ + props.cbBuffer = 0x4000 / format->nBlockAlign * + format->nBlockAlign; + props.cBuffers = 1; + + hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt, + (float)format->nAvgBytesPerSec / + (float)format->nBlockAlign, + format->nBlockAlign, + total); + } + + if (FAILED(hr)) + { + if (amt.pbFormat) + CoTaskMemFree(amt.pbFormat); + ERR("Could not create pin for MPEG audio stream (%x)\n", hr); + } + break; + case MPEG_VIDEO_HEADER: + FIXME("MPEG video processing not yet supported!\n"); + hr = E_FAIL; + break; + case MPEG_SYSTEM_HEADER: + FIXME("MPEG system streams not yet supported!\n"); + hr = E_FAIL; + break; + + default: + break; + } + + return hr; +} + +static HRESULT MPEGSplitter_cleanup(LPVOID iface) +{ + MPEGSplitterImpl *This = (MPEGSplitterImpl*)iface; + + TRACE("(%p)->()\n", This); + + if (This->pCurrentSample) + IMediaSample_Release(This->pCurrentSample); + This->pCurrentSample = NULL; + + return S_OK; +} + +HRESULT MPEGSplitter_create(IUnknown * pUnkOuter, LPVOID * ppv) +{ + MPEGSplitterImpl *This; + HRESULT hr = E_FAIL; + + TRACE("(%p, %p)\n", pUnkOuter, ppv); + + *ppv = NULL; + + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + This = CoTaskMemAlloc(sizeof(MPEGSplitterImpl)); + if (!This) + return E_OUTOFMEMORY; + + ZeroMemory(This, sizeof(MPEGSplitterImpl)); + hr = Parser_Create(&(This->Parser), &CLSID_MPEG1Splitter, MPEGSplitter_process_sample, MPEGSplitter_query_accept, MPEGSplitter_pre_connect, MPEGSplitter_cleanup); + if (FAILED(hr)) + { + CoTaskMemFree(This); + return hr; + } + + /* Note: This memory is managed by the parser filter once created */ + *ppv = (LPVOID)This; + + return hr; +} diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 5b5094d5bb9..a483f2a9aad 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -48,6 +48,7 @@ HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj); HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv); HRESULT StdMemAllocator_create(IUnknown * pUnkOuter, LPVOID * ppv); HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv); +HRESULT MPEGSplitter_create(IUnknown * pUnkOuter, LPVOID * ppv); HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv); HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv); HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv); diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c index 7206e240d4a..ced43bcac3e 100644 --- a/dlls/quartz/regsvr.c +++ b/dlls/quartz/regsvr.c @@ -901,6 +901,12 @@ static struct regsvr_coclass const coclass_list[] = { "quartz.dll", "Both" }, + { &CLSID_MPEG1Splitter, + "MPEG-I Stream Splitter", + NULL, + "quartz.dll", + "Both" + }, { &CLSID_AVIDec, "AVI Decompressor", NULL, @@ -1094,6 +1100,33 @@ static struct regsvr_filter const filter_list[] = { { 0xFFFFFFFF }, } }, + { &CLSID_MPEG1Splitter, + &CLSID_LegacyAmFilterCategory, + {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0}, + 0x600000, + { { 0, + { { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio }, + { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video }, + { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System }, + { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD }, + { NULL } + }, + }, + { REG_PINFLAG_B_OUTPUT, + { { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet }, + { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload }, + { NULL } + }, + }, + { REG_PINFLAG_B_OUTPUT, + { { &MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet }, + { &MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload }, + { NULL } + }, + }, + { 0xFFFFFFFF }, + } + }, { &CLSID_VideoRenderer, &CLSID_LegacyAmFilterCategory, {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0}, diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c index 10866020dd4..a30c9254af0 100644 --- a/dlls/rpcrt4/rpc_message.c +++ b/dlls/rpcrt4/rpc_message.c @@ -691,7 +691,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, if (((*Header)->common.frag_len < hdr_length) || ((*Header)->common.frag_len - hdr_length < header_auth_len)) { WARN("frag_len %d too small for hdr_length %d and auth_len %d\n", - common_hdr.frag_len, hdr_length, common_hdr.auth_len); + (*Header)->common.frag_len, hdr_length, header_auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; } diff --git a/dlls/schannel/Makefile.in b/dlls/schannel/Makefile.in index bc67151d872..3cf48ef4433 100644 --- a/dlls/schannel/Makefile.in +++ b/dlls/schannel/Makefile.in @@ -6,7 +6,9 @@ MODULE = schannel.dll IMPORTS = secur32 kernel32 C_SRCS = \ - schannel_main.c + lsamode.c \ + schannel_main.c \ + usermode.c @MAKE_DLL_RULES@ diff --git a/dlls/schannel/lsamode.c b/dlls/schannel/lsamode.c new file mode 100644 index 00000000000..b017eb9beac --- /dev/null +++ b/dlls/schannel/lsamode.c @@ -0,0 +1,158 @@ +/* + * LSA-mode functions of the SChannel security provider + * + * Copyright 2007 Yuval Fledel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "sspi.h" +#include "ntsecapi.h" +#include "ntsecpkg.h" +#include "schannel.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(schannel); + +/*********************************************************************** + * SpGetInfoUnified + */ +static NTSTATUS WINAPI SpGetInfoUnified(PSecPkgInfoW PackageInfo) +{ + TRACE("(%p)\n", PackageInfo); + + PackageInfo->fCapabilities = SECPKG_FLAG_MUTUAL_AUTH | + SECPKG_FLAG_INTEGRITY | SECPKG_FLAG_PRIVACY | + SECPKG_FLAG_CONNECTION | SECPKG_FLAG_MULTI_REQUIRED | + SECPKG_FLAG_EXTENDED_ERROR | SECPKG_FLAG_IMPERSONATION | + SECPKG_FLAG_ACCEPT_WIN32_NAME | SECPKG_FLAG_STREAM; + PackageInfo->wVersion = 1; + PackageInfo->wRPCID = UNISP_RPC_ID; + PackageInfo->cbMaxToken = 0x4000; + PackageInfo->Name = (LPWSTR)UNISP_NAME_W; + PackageInfo->Comment = (LPWSTR)UNISP_NAME_W; + + return STATUS_SUCCESS; +} + +static SEC_WCHAR schannelCommentW[] = { 'S','c','h','a','n','n','e','l', + ' ','S','e','c','u','r','i','t','y',' ','P','a','c','k','a','g','e',0 }; + +/*********************************************************************** + * SpGetInfoSChannel + */ +static NTSTATUS WINAPI SpGetInfoSChannel(PSecPkgInfoW PackageInfo) +{ + TRACE("(%p)\n", PackageInfo); + + PackageInfo->fCapabilities = SECPKG_FLAG_MUTUAL_AUTH | + SECPKG_FLAG_INTEGRITY | SECPKG_FLAG_PRIVACY | + SECPKG_FLAG_CONNECTION | SECPKG_FLAG_MULTI_REQUIRED | + SECPKG_FLAG_EXTENDED_ERROR | SECPKG_FLAG_IMPERSONATION | + SECPKG_FLAG_ACCEPT_WIN32_NAME | SECPKG_FLAG_STREAM; + PackageInfo->wVersion = 1; + PackageInfo->wRPCID = UNISP_RPC_ID; + PackageInfo->cbMaxToken = 0x4000; + PackageInfo->Name = (LPWSTR)SCHANNEL_NAME_W; + PackageInfo->Comment = schannelCommentW; + + return STATUS_SUCCESS; +} + +static SECPKG_FUNCTION_TABLE secPkgFunctionTable[2] = +{ { + NULL, /* InitializePackage */ + NULL, /* LsaLogonUser */ + NULL, /* CallPackage */ + NULL, /* LogonTerminated */ + NULL, /* CallPackageUntrusted */ + NULL, /* CallPackagePassthrough */ + NULL, /* LogonUserEx */ + NULL, /* LogonUserEx2 */ + NULL, /* Initialize */ + NULL, /* Shutdown */ + SpGetInfoUnified, + NULL, /* AcceptCredentials */ + NULL, /* SpAcquireCredentialsHandle */ + NULL, /* SpQueryCredentialsAttributes */ + NULL, /* FreeCredentialsHandle */ + NULL, /* SaveCredentials */ + NULL, /* GetCredentials */ + NULL, /* DeleteCredentials */ + NULL, /* InitLsaModeContext */ + NULL, /* AcceptLsaModeContext */ + NULL, /* DeleteContext */ + NULL, /* ApplyControlToken */ + NULL, /* GetUserInfo */ + NULL, /* GetExtendedInformation */ + NULL, /* SpQueryContextAttributes */ + NULL, /* SpAddCredentials */ + NULL, /* SetExtendedInformation */ + NULL, /* SpSetContextAttributes */ + NULL, /* SetCredentialsAttributes */ + }, { + NULL, /* InitializePackage */ + NULL, /* LsaLogonUser */ + NULL, /* CallPackage */ + NULL, /* LogonTerminated */ + NULL, /* CallPackageUntrusted */ + NULL, /* CallPackagePassthrough */ + NULL, /* LogonUserEx */ + NULL, /* LogonUserEx2 */ + NULL, /* Initialize */ + NULL, /* Shutdown */ + SpGetInfoSChannel, + NULL, /* AcceptCredentials */ + NULL, /* SpAcquireCredentialsHandle */ + NULL, /* SpQueryCredentialsAttributes */ + NULL, /* FreeCredentialsHandle */ + NULL, /* SaveCredentials */ + NULL, /* GetCredentials */ + NULL, /* DeleteCredentials */ + NULL, /* InitLsaModeContext */ + NULL, /* AcceptLsaModeContext */ + NULL, /* DeleteContext */ + NULL, /* ApplyControlToken */ + NULL, /* GetUserInfo */ + NULL, /* GetExtendedInformation */ + NULL, /* SpQueryContextAttributes */ + NULL, /* SpAddCredentials */ + NULL, /* SetExtendedInformation */ + NULL, /* SpSetContextAttributes */ + NULL, /* SetCredentialsAttributes */ + } +}; + +/*********************************************************************** + * SpLsaModeInitialize (SCHANNEL.@) + */ +NTSTATUS WINAPI SpLsaModeInitialize(ULONG LsaVersion, PULONG PackageVersion, + PSECPKG_FUNCTION_TABLE *ppTables, PULONG pcTables) +{ + TRACE("(%u, %p, %p, %p)\n", LsaVersion, PackageVersion, ppTables, pcTables); + + *PackageVersion = SECPKG_INTERFACE_VERSION_3; + *pcTables = 2; + *ppTables = secPkgFunctionTable; + + return STATUS_SUCCESS; +} diff --git a/dlls/schannel/schannel.spec b/dlls/schannel/schannel.spec index 7dd12fa3d03..c330c83ff93 100644 --- a/dlls/schannel/schannel.spec +++ b/dlls/schannel/schannel.spec @@ -23,8 +23,8 @@ @ stdcall QuerySecurityPackageInfoW(wstr ptr) secur32.QuerySecurityPackageInfoW @ stdcall RevertSecurityContext(ptr) secur32.RevertSecurityContext @ stdcall SealMessage(ptr long ptr long) secur32.SealMessage -@ stub SpLsaModeInitialize -@ stub SpUserModeInitialize +@ stdcall SpLsaModeInitialize(long ptr ptr ptr) +@ stdcall SpUserModeInitialize(long ptr ptr ptr) @ stub SslCrackCertificate @ stub SslEmptyCacheA @ stub SslEmptyCacheW diff --git a/dlls/schannel/Makefile.in b/dlls/schannel/tests/Makefile.in similarity index 54% copy from dlls/schannel/Makefile.in copy to dlls/schannel/tests/Makefile.in index bc67151d872..02621079aad 100644 --- a/dlls/schannel/Makefile.in +++ b/dlls/schannel/tests/Makefile.in @@ -1,13 +1,13 @@ TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../.. +TOPOBJDIR = ../../.. SRCDIR = @srcdir@ VPATH = @srcdir@ -MODULE = schannel.dll -IMPORTS = secur32 kernel32 +TESTDLL = schannel.dll +IMPORTS = crypt32 advapi32 kernel32 -C_SRCS = \ - schannel_main.c +CTESTS = \ + main.c -@MAKE_DLL_RULES@ +@MAKE_TEST_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/schannel/tests/main.c b/dlls/schannel/tests/main.c new file mode 100644 index 00000000000..737495e267e --- /dev/null +++ b/dlls/schannel/tests/main.c @@ -0,0 +1,180 @@ +/* + * Schannel tests + * + * Copyright 2006 Yuval Fledel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include +#include +#define SECURITY_WIN32 +#include +#include +#include +#include + +#include "wine/test.h" + +static NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG, + PSECPKG_FUNCTION_TABLE*, PULONG); +static NTSTATUS (NTAPI *pSpUserModeInitialize)(ULONG, PULONG, + PSECPKG_USER_FUNCTION_TABLE*, PULONG); + +static void testInitialize(void) +{ + PSECPKG_USER_FUNCTION_TABLE pUserTables, pUserTables2; + PSECPKG_FUNCTION_TABLE pTables, pTables2; + ULONG cTables = 0, cUserTables = 0, Version = 0; + NTSTATUS status; + + /* Passing NULL into one of the parameters of SpLsaModeInitialize or + SpUserModeInitialize causes a crash. */ + + /* SpLsaModeInitialize does not care about the LSA version. */ + status = pSpLsaModeInitialize(0, &Version, &pTables2, &cTables); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + ok(cTables == 2, "cTables: %d\n", cTables); + ok(pTables2 != NULL,"pTables: %p\n", pTables2); + + /* We can call it as many times we want. */ + status = pSpLsaModeInitialize(0x10000, &Version, &pTables, &cTables); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + ok(cTables == 2, "cTables: %d\n", cTables); + ok(pTables != NULL, "pTables: %p\n", pTables); + /* It will always return the same pointer. */ + ok(pTables == pTables2, "pTables: %p, pTables2: %p\n", pTables, pTables2); + + status = pSpLsaModeInitialize(0x23456, &Version, &pTables, &cTables); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + ok(cTables == 2, "cTables: %d\n", cTables); + ok(pTables != NULL, "pTables: %p\n", pTables); + ok(pTables == pTables2, "pTables: %p, pTables2: %p\n", pTables, pTables2); + + /* Bad versions to SpUserModeInitialize. Parameters unchanged */ + Version = 0xdead; + cUserTables = 0xdead; + pUserTables = NULL; + status = pSpUserModeInitialize(0, &Version, &pUserTables, &cUserTables); + ok(status == STATUS_INVALID_PARAMETER, "status: 0x%x\n", status); + ok(Version == 0xdead, "Version: 0x%x\n", Version); + ok(cUserTables == 0xdead, "cTables: %d\n", cUserTables); + ok(pUserTables == NULL, "pUserTables: %p\n", pUserTables); + + status = pSpUserModeInitialize(0x20000, &Version, &pUserTables, + &cUserTables); + ok(status == STATUS_INVALID_PARAMETER, "status: 0x%x\n", status); + ok(Version == 0xdead, "Version: 0x%x\n", Version); + ok(cUserTables == 0xdead, "cTables: %d\n", cUserTables); + ok(pUserTables == NULL, "pUserTables: %p\n", pUserTables); + + /* Good version to SpUserModeInitialize */ + status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &Version, + &pUserTables, &cUserTables); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + ok(Version == SECPKG_INTERFACE_VERSION, "Version: 0x%x\n", Version); + ok(cUserTables == 2, "cUserTables: %d\n", cUserTables); + ok(pUserTables != NULL, "pUserTables: %p\n", pUserTables); + + /* Initializing user again */ + status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &Version, + &pUserTables2, &cTables); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + ok(pUserTables == pUserTables2, "pUserTables: %p, pUserTables2: %p\n", + pUserTables, pUserTables2); +} + +/* A helper function to find the dispatch table of the next package. + Needed because SECPKG_FUNCTION_TABLE's size depend on the version */ +static PSECPKG_FUNCTION_TABLE getNextSecPkgTable(PSECPKG_FUNCTION_TABLE pTable, + ULONG Version) +{ + size_t size; + + if (Version == SECPKG_INTERFACE_VERSION) + size = SECPKG_FUNCTION_TABLE_SIZE_1; + else if (Version == SECPKG_INTERFACE_VERSION_2) + size = SECPKG_FUNCTION_TABLE_SIZE_2; + else if (Version == SECPKG_INTERFACE_VERSION_3) + size = SECPKG_FUNCTION_TABLE_SIZE_3; + else { + ok(FALSE, "Unknown package version 0x%x\n", Version); + return NULL; + } + + return (PSECPKG_FUNCTION_TABLE)((PBYTE)pTable + size); +} + +static void testGetInfo(void) +{ + PSECPKG_FUNCTION_TABLE pTables; + SecPkgInfoW PackageInfo; + ULONG cTables, Version; + NTSTATUS status; + + /* Get the dispatch table */ + status = pSpLsaModeInitialize(0, &Version, &pTables, &cTables); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + + /* Passing NULL into ->GetInfo causes a crash. */ + + /* First package: Unified */ + status = pTables->GetInfo(&PackageInfo); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + ok(PackageInfo.fCapabilities == 0x107b3, "fCapabilities: 0x%lx\n", + PackageInfo.fCapabilities); + ok(PackageInfo.wVersion == 1, "wVersion: %d\n", PackageInfo.wVersion); + ok(PackageInfo.wRPCID == 14, "wRPCID: %d\n", PackageInfo.wRPCID); + ok(PackageInfo.cbMaxToken == 0x4000, "cbMaxToken: 0x%lx\n", + PackageInfo.cbMaxToken); + + /* Second package: SChannel */ + pTables = getNextSecPkgTable(pTables, Version); + if (!pTables) + return; + status = pTables->GetInfo(&PackageInfo); + ok(status == STATUS_SUCCESS, "status: 0x%x\n", status); + ok(PackageInfo.fCapabilities == 0x107b3, "fCapabilities: 0x%lx\n", + PackageInfo.fCapabilities); + ok(PackageInfo.wVersion == 1, "wVersion: %d\n", PackageInfo.wVersion); + ok(PackageInfo.wRPCID == 14, "wRPCID: %d\n", PackageInfo.wRPCID); + ok(PackageInfo.cbMaxToken == 0x4000, "cbMaxToken: 0x%lx\n", + PackageInfo.cbMaxToken); +} + +START_TEST(main) +{ + HMODULE hMod = LoadLibraryA("schannel.dll"); + if (!hMod) { + skip("schannel.dll not found.\n"); + return; + } + + pSpLsaModeInitialize = GetProcAddress(hMod, "SpLsaModeInitialize"); + pSpUserModeInitialize = GetProcAddress(hMod, "SpUserModeInitialize"); + + if (pSpLsaModeInitialize && pSpUserModeInitialize) + { + testInitialize(); + testGetInfo(); + } + else skip( "schannel functions not found\n" ); + + FreeLibrary(hMod); +} diff --git a/dlls/schannel/usermode.c b/dlls/schannel/usermode.c new file mode 100644 index 00000000000..0713f822f91 --- /dev/null +++ b/dlls/schannel/usermode.c @@ -0,0 +1,85 @@ +/* + * User-mode functions of the SChannel security provider + * + * Copyright 2007 Yuval Fledel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "sspi.h" +#include "ntsecapi.h" +#include "ntsecpkg.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(schannel); + +static SECPKG_USER_FUNCTION_TABLE secPkgUserTables[2] = +{ { + NULL, /* InstanceInit */ + NULL, /* InitUserModeContext */ + NULL, /* MakeSignature */ + NULL, /* VerifySignature */ + NULL, /* SealMessage */ + NULL, /* UnsealMessage */ + NULL, /* GetContextToken */ + NULL, /* SpQueryContextAttributes */ + NULL, /* CompleteAuthToken */ + NULL, /* DeleteUserModeContext */ + NULL, /* FormatCredentials */ + NULL, /* MarshallSupplementalCreds */ + NULL, /* ExportContext */ + NULL, /* ImportContext */ + }, { + NULL, /* InstanceInit */ + NULL, /* InitUserModeContext */ + NULL, /* MakeSignature */ + NULL, /* VerifySignature */ + NULL, /* SealMessage */ + NULL, /* UnsealMessage */ + NULL, /* GetContextToken */ + NULL, /* SpQueryContextAttributes */ + NULL, /* CompleteAuthToken */ + NULL, /* DeleteUserModeContext */ + NULL, /* FormatCredentials */ + NULL, /* MarshallSupplementalCreds */ + NULL, /* ExportContext */ + NULL, /* ImportContext */ + } +}; + +/*********************************************************************** + * SpUserModeInitialize (SCHANNEL.@) + */ +NTSTATUS WINAPI SpUserModeInitialize(ULONG LsaVersion, PULONG PackageVersion, + PSECPKG_USER_FUNCTION_TABLE *ppTables, PULONG pcTables) +{ + TRACE("(%u, %p, %p, %p)\n", LsaVersion, PackageVersion, ppTables, pcTables); + + if (LsaVersion != SECPKG_INTERFACE_VERSION) + return STATUS_INVALID_PARAMETER; + + *PackageVersion = SECPKG_INTERFACE_VERSION; + *pcTables = 2; + *ppTables = secPkgUserTables; + + return STATUS_SUCCESS; +} diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 63cb4442e1c..4aca343dc7a 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -1515,7 +1515,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, if( menuBar && !(lpitem->hbmpItem == HBMMENU_CALLBACK)) bmprc.top = 0; else - bmprc.top = (lpitem->rect.bottom - lpitem->rect.top - + bmprc.top = (rect.bottom - rect.top - lpitem->bmpsize.cy) / 2; bmprc.bottom = bmprc.top + lpitem->bmpsize.cy; } @@ -1570,7 +1570,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, !( checked && (menu->dwStyle & MNS_CHECKORBMP))) { POINT origorg; /* some applications make this assumption on the DC's origin */ - SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg); + SetViewportOrgEx( hdc, rect.left, rect.top, &origorg); MENU_DrawBitmapItem(hdc, lpitem, &bmprc, hmenu, hwndOwner, odaction, FALSE); SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL); @@ -1588,7 +1588,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, { /* Draw the bitmap */ POINT origorg; - SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg); + SetViewportOrgEx( hdc, rect.left, rect.top, &origorg); MENU_DrawBitmapItem( hdc, lpitem, &bmprc, hmenu, hwndOwner, odaction, menuBar); SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL); diff --git a/dlls/winealsa.drv/mixer.c b/dlls/winealsa.drv/mixer.c index 84701f612b1..ad879168ed1 100644 --- a/dlls/winealsa.drv/mixer.c +++ b/dlls/winealsa.drv/mixer.c @@ -67,7 +67,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mixer); * Mute is optional * * For capture controls, it is needed that there is a capture switch and a volume switch, - * It doesn't matter wether it is a playback volume switch or a capture volume switch. + * It doesn't matter whether it is a playback volume switch or a capture volume switch. * The code will first try to get/adjust capture volume, if that fails it tries playback volume * It is not pretty, but under my 3 test cards it seems that there is no other choice: * Most capture controls don't have a capture volume setting @@ -305,7 +305,7 @@ static void fillcontrols(mixer *mmixer) } /* get amount of channels for elem */ -/* Officially we should keep capture/playback seperated, +/* Officially we should keep capture/playback separated, * but that's not going to work in the alsa api */ static int chans(mixer *mmixer, snd_mixer_elem_t * elem, DWORD capt) { @@ -371,7 +371,7 @@ static void ALSA_MixerInit(void) err = snd_mixer_open(&mixdev[mixnum].mix,0); if (err < 0) { - WARN("Error occured opening mixer: %s\n", snd_strerror(err)); + WARN("Error occurred opening mixer: %s\n", snd_strerror(err)); continue; } @@ -504,7 +504,7 @@ static void ALSA_MixerInit(void) continue; eclose: - WARN("Error occured initialising mixer: %s\n", snd_strerror(err)); + WARN("Error occurred initialising mixer: %s\n", snd_strerror(err)); HeapFree(GetProcessHeap(), 0, mixdev[mixnum].lines); HeapFree(GetProcessHeap(), 0, mixdev[mixnum].controls); snd_mixer_close(mixdev[mixnum].mix); diff --git a/dlls/winealsa.drv/waveinit.c b/dlls/winealsa.drv/waveinit.c index 6614c00e163..11f8fdd2301 100644 --- a/dlls/winealsa.drv/waveinit.c +++ b/dlls/winealsa.drv/waveinit.c @@ -504,12 +504,6 @@ static int ALSA_AddCaptureDevice(snd_ctl_t *ctl, snd_pcm_t *pcm, const char *pcm wwi.incaps.wPid = MM_CREATIVE_SBP16_WAVEOUT; wwi.incaps.vDriverVersion = 0x0100; - if (wwi.ds_caps.dwFlags & WAVECAPS_DIRECTSOUND) - { - FIXME("Add support for DSCapture\n"); - wwi.ds_caps.dwFlags &= ~WAVECAPS_DIRECTSOUND; - } - rc = ALSA_ComputeCaps(ctl, pcm, &wwi.incaps.wChannels, &wwi.ds_caps.dwFlags, &wwi.incaps.dwFormats, &wwi.dwSupport); if (rc) @@ -519,6 +513,12 @@ static int ALSA_AddCaptureDevice(snd_ctl_t *ctl, snd_pcm_t *pcm, const char *pcm return(rc); } + if (wwi.dwSupport & WAVECAPS_DIRECTSOUND) + { + FIXME("Add support for DSCapture\n"); + wwi.dwSupport &= ~WAVECAPS_DIRECTSOUND; + } + rc = ALSA_AddDeviceToArray(&wwi, &WInDev, &ALSA_WidNumDevs, &ALSA_WidNumMallocedDevs, isdefault); if (rc) ALSA_FreeDevice(&wwi); diff --git a/dlls/winecoreaudio.drv/coremidi.c b/dlls/winecoreaudio.drv/coremidi.c index a127aff8030..6c47c878063 100644 --- a/dlls/winecoreaudio.drv/coremidi.c +++ b/dlls/winecoreaudio.drv/coremidi.c @@ -1,5 +1,5 @@ /* - * Wine Midi driver for MacOSX + * Wine Midi driver for Mac OS X * * Copyright 2006 Emmanuel Maillard * diff --git a/dlls/winecoreaudio.drv/coremidi.h b/dlls/winecoreaudio.drv/coremidi.h index 7cc7f0875b3..405f9990fcd 100644 --- a/dlls/winecoreaudio.drv/coremidi.h +++ b/dlls/winecoreaudio.drv/coremidi.h @@ -1,5 +1,5 @@ /* - * Wine Midi driver for MacOSX + * Wine Midi driver for Mac OS X * * Copyright 2006 Emmanuel Maillard * diff --git a/dlls/winecoreaudio.drv/midi.c b/dlls/winecoreaudio.drv/midi.c index ff43a3504b4..f10f5f0b6a7 100644 --- a/dlls/winecoreaudio.drv/midi.c +++ b/dlls/winecoreaudio.drv/midi.c @@ -1,5 +1,5 @@ /* - * Sample MIDI Wine Driver for MacOSX (based on OSS midi driver) + * Sample MIDI Wine Driver for Mac OS X (based on OSS midi driver) * * Copyright 1994 Martin Ayotte * Copyright 1998 Luiz Otavio L. Zorzella (init procedures) @@ -242,6 +242,11 @@ static DWORD MIDI_NotifyClient(UINT wDevID, WORD wMsg, DWORD dwParam1, DWORD dwP case MIM_ERROR: case MIM_LONGERROR: case MIM_MOREDATA: + dwCallBack = sources[wDevID].midiDesc.dwCallback; + uFlags = sources[wDevID].wFlags; + hDev = sources[wDevID].midiDesc.hMidi; + dwInstance = sources[wDevID].midiDesc.dwInstance; + break; default: WARN("Unsupported MSW-MIDI message %u\n", wMsg); return MMSYSERR_ERROR; @@ -589,6 +594,226 @@ static DWORD MIDIOut_Reset(WORD wDevID) return MMSYSERR_NOERROR; } +static DWORD MIDIIn_Open(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) +{ + TRACE("wDevID=%d lpDesc=%p dwFlags=%08x\n", wDevID, lpDesc, dwFlags); + + if (lpDesc == NULL) { + WARN("Invalid Parameter\n"); + return MMSYSERR_INVALPARAM; + } + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + if (sources[wDevID].midiDesc.hMidi != 0) { + WARN("device already open !\n"); + return MMSYSERR_ALLOCATED; + } + if ((dwFlags & MIDI_IO_STATUS) != 0) { + WARN("No support for MIDI_IO_STATUS in dwFlags yet, ignoring it\n"); + dwFlags &= ~MIDI_IO_STATUS; + } + if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) { + FIXME("Bad dwFlags\n"); + return MMSYSERR_INVALFLAG; + } + + sources[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); + sources[wDevID].lpQueueHdr = NULL; + sources[wDevID].midiDesc = *lpDesc; + sources[wDevID].startTime = 0; + sources[wDevID].state = 0; + + return MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L); +} + +static DWORD MIDIIn_Close(WORD wDevID) +{ + DWORD ret = MMSYSERR_NOERROR; + + TRACE("wDevID=%d\n", wDevID); + + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + + if (sources[wDevID].midiDesc.hMidi == 0) { + WARN("device not opened !\n"); + return MMSYSERR_ERROR; + } + if (sources[wDevID].lpQueueHdr != 0) { + return MIDIERR_STILLPLAYING; + } + + ret = MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L); + sources[wDevID].midiDesc.hMidi = 0; + return ret; +} + +static DWORD MIDIIn_AddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) +{ + TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); + + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + if (lpMidiHdr == NULL) { + WARN("Invalid Parameter\n"); + return MMSYSERR_INVALPARAM; + } + if (sizeof(MIDIHDR) > dwSize) { + WARN("Invalid Parameter\n"); + return MMSYSERR_INVALPARAM; + } + if (lpMidiHdr->dwBufferLength == 0) { + WARN("Invalid Parameter\n"); + return MMSYSERR_INVALPARAM; + } + if (lpMidiHdr->dwFlags & MHDR_INQUEUE) { + WARN("Still playing\n"); + return MIDIERR_STILLPLAYING; + } + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) { + WARN("Unprepared\n"); + return MIDIERR_UNPREPARED; + } + + EnterCriticalSection(&midiInLock); + if (sources[wDevID].lpQueueHdr == 0) { + sources[wDevID].lpQueueHdr = lpMidiHdr; + } else { + LPMIDIHDR ptr; + for (ptr = sources[wDevID].lpQueueHdr; + ptr->lpNext != 0; + ptr = (LPMIDIHDR)ptr->lpNext); + ptr->lpNext = (struct midihdr_tag*)lpMidiHdr; + } + LeaveCriticalSection(&midiInLock); + + return MMSYSERR_NOERROR; +} + +static DWORD MIDIIn_Prepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) +{ + TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); + + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + /* MS doc says that dwFlags must be set to zero, but (kinda funny) MS mciseq drivers + * asks to prepare MIDIHDR which dwFlags != 0. + * So at least check for the inqueue flag + */ + if (dwSize < sizeof(MIDIHDR) || lpMidiHdr == 0 || + lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0 || + lpMidiHdr->dwBufferLength >= 0x10000ul) { + WARN("Invalid parameter %p %p %08x %d\n", lpMidiHdr, lpMidiHdr->lpData, + lpMidiHdr->dwFlags, dwSize); + return MMSYSERR_INVALPARAM; + } + + lpMidiHdr->lpNext = 0; + lpMidiHdr->dwFlags |= MHDR_PREPARED; + lpMidiHdr->dwFlags &= ~MHDR_DONE; + return MMSYSERR_NOERROR; +} + +static DWORD MIDIIn_Unprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) +{ + TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + if (dwSize < sizeof(MIDIHDR) || lpMidiHdr == 0) { + WARN("Invalid Parameter\n"); + return MMSYSERR_INVALPARAM; + } + if (lpMidiHdr->dwFlags & MHDR_INQUEUE) { + WARN("Still playing\n"); + return MIDIERR_STILLPLAYING; + } + + lpMidiHdr->dwFlags &= ~MHDR_PREPARED; + return MMSYSERR_NOERROR; +} + +static DWORD MIDIIn_GetDevCaps(WORD wDevID, LPMIDIINCAPSW lpCaps, DWORD dwSize) +{ + TRACE("wDevID=%d lpCaps=%p dwSize=%d\n", wDevID, lpCaps, dwSize); + + if (lpCaps == NULL) { + WARN("Invalid Parameter\n"); + return MMSYSERR_INVALPARAM; + } + + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + memcpy(lpCaps, &sources[wDevID].caps, min(dwSize, sizeof(*lpCaps))); + return MMSYSERR_NOERROR; +} + +static DWORD MIDIIn_GetNumDevs(void) +{ + TRACE("\n"); + return MIDIIn_NumDevs; +} + +static DWORD MIDIIn_Start(WORD wDevID) +{ + TRACE("%d\n", wDevID); + + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + sources[wDevID].state = 1; + sources[wDevID].startTime = GetTickCount(); + return MMSYSERR_NOERROR; +} + +static DWORD MIDIIn_Stop(WORD wDevID) +{ + TRACE("%d\n", wDevID); + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + sources[wDevID].state = 0; + return MMSYSERR_NOERROR; +} + +static DWORD MIDIIn_Reset(WORD wDevID) +{ + DWORD dwTime = GetTickCount(); + + TRACE("%d\n", wDevID); + if (wDevID >= MIDIIn_NumDevs) { + WARN("bad device ID : %d\n", wDevID); + return MMSYSERR_BADDEVICEID; + } + + EnterCriticalSection(&midiInLock); + while (sources[wDevID].lpQueueHdr) { + sources[wDevID].lpQueueHdr->dwFlags &= ~MHDR_INQUEUE; + sources[wDevID].lpQueueHdr->dwFlags |= MHDR_DONE; + /* FIXME: when called from 16 bit, lpQueueHdr needs to be a segmented ptr */ + if (MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD)sources[wDevID].lpQueueHdr, dwTime) != MMSYSERR_NOERROR) { + WARN("Couldn't notify client\n"); + } + sources[wDevID].lpQueueHdr = (LPMIDIHDR)sources[wDevID].lpQueueHdr->lpNext; + } + LeaveCriticalSection(&midiInLock); + + return MMSYSERR_NOERROR; +} + /* * MIDI In Mach message handling */ @@ -617,8 +842,10 @@ static CFDataRef MIDIIn_MessageHandler(CFMessagePortRef local, SInt32 msgid, CFD { MIDIMessage *msg = NULL; int i = 0; - FIXME("\n"); + MIDISource *src = NULL; + DWORD sendData = 0; + TRACE("\n"); switch (msgid) { case 0: @@ -628,11 +855,58 @@ static CFDataRef MIDIIn_MessageHandler(CFMessagePortRef local, SInt32 msgid, CFD TRACE("%02X ", msg->data[i]); } TRACE("\n"); + src = &sources[msg->devID]; + if (src->state < 1) + { + TRACE("input not started, thrown away\n"); + goto done; + } + /* FIXME skipping SysEx */ + if (msg->data[0] == 0xF0) + { + FIXME("Starting System Exclusive\n"); + src->state |= 2; + for (i = 0; i < msg->length; ++i) + { + if (msg->data[i] == 0xF7) + { + FIXME("Ending System Exclusive\n"); + src->state &= ~2; + } + } + goto done; + } + if (src->state & 2) + { + for (i = 0; i < msg->length; ++i) + { + if (msg->data[i] == 0xF7) + { + FIXME("Ending System Exclusive\n"); + src->state &= ~2; + } + } + goto done; + } + EnterCriticalSection(&midiInLock); + if (msg->length == 3) + { + sendData = (msg->data[2] << 16) | + (msg->data[1] << 8) | + (msg->data[0] << 0); + } + if (msg->length == 2) + { + sendData = (msg->data[1] << 8) | (msg->data[0] << 0); + } + MIDI_NotifyClient(msg->devID, MIM_DATA, sendData, GetTickCount() - src->startTime); + LeaveCriticalSection(&midiInLock); break; default: CFRunLoopStop(CFRunLoopGetCurrent()); break; } +done: return NULL; } @@ -712,15 +986,25 @@ DWORD WINAPI CoreAudio_midMessage(UINT wDevID, UINT wMsg, DWORD dwUser, DWORD dw case DRVM_DISABLE: return 0; case MIDM_OPEN: + return MIDIIn_Open(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2); case MIDM_CLOSE: + return MIDIIn_Close(wDevID); case MIDM_ADDBUFFER: + return MIDIIn_AddBuffer(wDevID, (LPMIDIHDR)dwParam1, dwParam2); case MIDM_PREPARE: + return MIDIIn_Prepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2); case MIDM_UNPREPARE: + return MIDIIn_Unprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2); case MIDM_GETDEVCAPS: + return MIDIIn_GetDevCaps(wDevID, (LPMIDIINCAPSW) dwParam1, dwParam2); case MIDM_GETNUMDEVS: + return MIDIIn_GetNumDevs(); case MIDM_START: + return MIDIIn_Start(wDevID); case MIDM_STOP: + return MIDIIn_Stop(wDevID); case MIDM_RESET: + return MIDIIn_Reset(wDevID); default: TRACE("Unsupported message\n"); } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 4faf84e7cfb..104fd538ddb 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5220,7 +5220,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { color_fill_fbo(iface, pSurface, pRect, color); - return WINED3DERR_INVALIDCALL; + return WINED3D_OK; } else { /* Just forward this to the DirectDraw blitting engine */ memset(&BltFx, 0, sizeof(BltFx)); diff --git a/dlls/wineoss.drv/mixer.c b/dlls/wineoss.drv/mixer.c index a28305b3262..22f580f4ffa 100644 --- a/dlls/wineoss.drv/mixer.c +++ b/dlls/wineoss.drv/mixer.c @@ -159,11 +159,17 @@ static const char * getIoctlCommand(int command) IOCTL_TO_STR(SOUND_MIXER_DIGITAL1); IOCTL_TO_STR(SOUND_MIXER_DIGITAL2); IOCTL_TO_STR(SOUND_MIXER_DIGITAL3); +#ifdef SOUND_MIXER_PHONEIN IOCTL_TO_STR(SOUND_MIXER_PHONEIN); +#endif +#ifdef SOUND_MIXER_PHONEOUT IOCTL_TO_STR(SOUND_MIXER_PHONEOUT); +#endif IOCTL_TO_STR(SOUND_MIXER_VIDEO); IOCTL_TO_STR(SOUND_MIXER_RADIO); +#ifdef SOUND_MIXER_MONITOR IOCTL_TO_STR(SOUND_MIXER_MONITOR); +#endif } #undef IOCTL_TO_STR sprintf(str, "UNKNOWN(%08x)", command); diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index fb0446858ad..a01d15212f1 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -571,9 +571,11 @@ static Cursor create_xcursor_cursor( Display *display, const cursor_t *cursor_ob */ static Cursor create_cursor( Display *display, const cursor_t *ptr ) { - Pixmap pixmapBits, pixmapMask, pixmapMaskInv, pixmapAll; + Pixmap pixmapBits, pixmapMask, pixmapMaskInv = 0, pixmapAll; XColor fg, bg; Cursor cursor = None; + POINT hotspot; + char *bitMask32 = NULL; #ifdef HAVE_X11_XCURSOR_XCURSOR_H if (pXcursorImageLoadCursor) return create_xcursor_cursor( display, ptr ); @@ -601,6 +603,7 @@ static Cursor create_cursor( Display *display, const cursor_t *ptr ) TRACE("Bitmap %dx%d planes=%d bpp=%d bytesperline=%d\n", frame->width, frame->height, frame->planes, frame->bpp, frame->xor_width_bytes); + /* Create a pixmap and transfer all the bits to it */ /* NOTE: Following hack works, but only because XFree depth @@ -647,6 +650,10 @@ static Cursor create_cursor( Display *display, const cursor_t *ptr ) switch (frame->bpp) { + case 32: + bitMask32 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + frame->width * frame->height / 8 ); + /* Fallthrough */ case 24: rbits = 8; gbits = 8; @@ -695,6 +702,20 @@ static Cursor create_cursor( Display *display, const cursor_t *ptr ) red = green = blue = 0; switch (frame->bpp) { + case 32: + theChar = theImage[byteIndex++]; + blue = theChar; + theChar = theImage[byteIndex++]; + green = theChar; + theChar = theImage[byteIndex++]; + red = theChar; + theChar = theImage[byteIndex++]; + /* If the alpha channel is >5% transparent, + * assume that we can add it to the bitMask32. + */ + if (theChar > 0x0D) + *(bitMask32 + (y*xmax+x)/8) |= 1 << (x & 7); + break; case 24: theChar = theImage[byteIndex++]; blue = theChar; @@ -779,73 +800,82 @@ static Cursor create_cursor( Display *display, const cursor_t *ptr ) /* Now create the 2 pixmaps for bits and mask */ pixmapBits = XCreatePixmap( display, root_window, frame->width, frame->height, 1 ); - pixmapMask = XCreatePixmap( display, root_window, frame->width, frame->height, 1 ); - pixmapMaskInv = XCreatePixmap( display, root_window, frame->width, frame->height, 1 ); - - /* Make sure everything went OK so far */ - - if (pixmapBits && pixmapMask && pixmapMaskInv) + if (frame->bpp != 32) { - POINT hotspot; - - /* We have to do some magic here, as cursors are not fully - * compatible between Windows and X11. Under X11, there - * are only 3 possible color cursor: black, white and - * masked. So we map the 4th Windows color (invert the - * bits on the screen) to black and an additional white bit on - * an other place (+1,+1). This require some boolean arithmetic: - * - * Windows | X11 - * And Xor Result | Bits Mask Result - * 0 0 black | 0 1 background - * 0 1 white | 1 1 foreground - * 1 0 no change | X 0 no change - * 1 1 inverted | 0 1 background - * - * which gives: - * Bits = not 'And' and 'Xor' or 'And2' and 'Xor2' - * Mask = not 'And' or 'Xor' or 'And2' and 'Xor2' - * - * FIXME: apparently some servers do support 'inverted' color. - * I don't know if it's correct per the X spec, but maybe - * we ought to take advantage of it. -- AJ - */ - XSetFunction( display, gc, GXcopy ); - XCopyArea( display, pixmapAll, pixmapBits, gc, - 0, 0, frame->width, frame->height, 0, 0 ); - XCopyArea( display, pixmapAll, pixmapMask, gc, - 0, 0, frame->width, frame->height, 0, 0 ); - XCopyArea( display, pixmapAll, pixmapMaskInv, gc, - 0, 0, frame->width, frame->height, 0, 0 ); - XSetFunction( display, gc, GXand ); - XCopyArea( display, pixmapAll, pixmapMaskInv, gc, - 0, frame->height, frame->width, frame->height, 0, 0 ); - XSetFunction( display, gc, GXandReverse ); - XCopyArea( display, pixmapAll, pixmapBits, gc, - 0, frame->height, frame->width, frame->height, 0, 0 ); - XSetFunction( display, gc, GXorReverse ); - XCopyArea( display, pixmapAll, pixmapMask, gc, - 0, frame->height, frame->width, frame->height, 0, 0 ); - /* Additional white */ - XSetFunction( display, gc, GXor ); - XCopyArea( display, pixmapMaskInv, pixmapMask, gc, - 0, 0, frame->width, frame->height, 1, 1 ); - XCopyArea( display, pixmapMaskInv, pixmapBits, gc, - 0, 0, frame->width, frame->height, 1, 1 ); - XSetFunction( display, gc, GXcopy ); + pixmapMaskInv = XCreatePixmap( display, root_window, frame->width, frame->height, 1 ); + pixmapMask = XCreatePixmap( display, root_window, frame->width, frame->height, 1 ); - /* Make sure hotspot is valid */ - hotspot.x = frame->xhot; - hotspot.y = frame->yhot; - if (hotspot.x < 0 || hotspot.x >= frame->width || - hotspot.y < 0 || hotspot.y >= frame->height) + /* Make sure everything went OK so far */ + if (pixmapBits && pixmapMask && pixmapMaskInv) { - hotspot.x = frame->width / 2; - hotspot.y = frame->height / 2; + /* We have to do some magic here, as cursors are not fully + * compatible between Windows and X11. Under X11, there are + * only 3 possible color cursor: black, white and masked. So + * we map the 4th Windows color (invert the bits on the screen) + * to black and an additional white bit on an other place + * (+1,+1). This require some boolean arithmetic: + * + * Windows | X11 + * And Xor Result | Bits Mask Result + * 0 0 black | 0 1 background + * 0 1 white | 1 1 foreground + * 1 0 no change | X 0 no change + * 1 1 inverted | 0 1 background + * + * which gives: + * Bits = not 'And' and 'Xor' or 'And2' and 'Xor2' + * Mask = not 'And' or 'Xor' or 'And2' and 'Xor2' + * + * FIXME: apparently some servers do support 'inverted' color. + * I don't know if it's correct per the X spec, but maybe we + * ought to take advantage of it. -- AJ + */ + XSetFunction( display, gc, GXcopy ); + XCopyArea( display, pixmapAll, pixmapBits, gc, + 0, 0, frame->width, frame->height, 0, 0 ); + XCopyArea( display, pixmapAll, pixmapMask, gc, + 0, 0, frame->width, frame->height, 0, 0 ); + XCopyArea( display, pixmapAll, pixmapMaskInv, gc, + 0, 0, frame->width, frame->height, 0, 0 ); + XSetFunction( display, gc, GXand ); + XCopyArea( display, pixmapAll, pixmapMaskInv, gc, + 0, frame->height, frame->width, frame->height, 0, 0 ); + XSetFunction( display, gc, GXandReverse ); + XCopyArea( display, pixmapAll, pixmapBits, gc, + 0, frame->height, frame->width, frame->height, 0, 0 ); + XSetFunction( display, gc, GXorReverse ); + XCopyArea( display, pixmapAll, pixmapMask, gc, + 0, frame->height, frame->width, frame->height, 0, 0 ); + /* Additional white */ + XSetFunction( display, gc, GXor ); + XCopyArea( display, pixmapMaskInv, pixmapMask, gc, + 0, 0, frame->width, frame->height, 1, 1 ); + XCopyArea( display, pixmapMaskInv, pixmapBits, gc, + 0, 0, frame->width, frame->height, 1, 1 ); + XSetFunction( display, gc, GXcopy ); } + } + else + { + pixmapMask = XCreateBitmapFromData( display, root_window, + bitMask32, frame->width, + frame->height ); + HeapFree( GetProcessHeap(), 0, bitMask32 ); + } + + /* Make sure hotspot is valid */ + hotspot.x = frame->xhot; + hotspot.y = frame->yhot; + if (hotspot.x < 0 || hotspot.x >= frame->width || + hotspot.y < 0 || hotspot.y >= frame->height) + { + hotspot.x = frame->width / 2; + hotspot.y = frame->height / 2; + } + + if (pixmapBits && pixmapMask) cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask, &fg, &bg, hotspot.x, hotspot.y ); - } /* Now free everything */ diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index cfb28abf483..af04d759012 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -32,7 +32,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wownt32.h" #include "x11drv.h" #include "shlobj.h" /* DROPFILES */ diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index a6d65eaf2c1..e19c82c7247 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -1419,7 +1419,7 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul TRACE(",XcvMonitor: %s\n", debugstr_w(&printername[len])); printer->pm = monitor_load(&printername[len], NULL); if (printer->pm == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(ERROR_UNKNOWN_PORT); handle = 0; goto end; } @@ -1432,7 +1432,7 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul TRACE(",XcvPort: %s\n", debugstr_w(&printername[len])); printer->pm = monitor_load_by_port(&printername[len]); if (printer->pm == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(ERROR_UNKNOWN_PORT); handle = 0; goto end; } @@ -1441,7 +1441,9 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul if (printer->pm) { if ((printer->pm->monitor) && (printer->pm->monitor->pfnXcvOpenPort)) { - printer->pm->monitor->pfnXcvOpenPort(&printername[len], pDefault->DesiredAccess, &printer->hXcv); + printer->pm->monitor->pfnXcvOpenPort(&printername[len], + pDefault ? pDefault->DesiredAccess : 0, + &printer->hXcv); } if (printer->hXcv == NULL) { SetLastError(ERROR_INVALID_PARAMETER); diff --git a/include/winbase.h b/include/winbase.h index 59e7718cee8..da9c547bacd 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1839,6 +1839,9 @@ BOOL WINAPI MoveFileWithProgressA(LPCSTR,LPCSTR,LPPROGRESS_ROUTINE,LPVOID BOOL WINAPI MoveFileWithProgressW(LPCWSTR,LPCWSTR,LPPROGRESS_ROUTINE,LPVOID,DWORD); #define MoveFileWithProgress WINELIB_NAME_AW(MoveFileWithProgress) INT WINAPI MulDiv(INT,INT,INT); +BOOL WINAPI NeedCurrentDirectoryForExePathA(LPCSTR); +BOOL WINAPI NeedCurrentDirectoryForExePathW(LPCWSTR); +#define NeedCurrentDirectoryForExePath WINELIB_NAME_AW(NeedCurrentDirectoryForExePath) BOOL WINAPI NotifyChangeEventLog(HANDLE,HANDLE); BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR,LPVOID,BOOL); BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR,LPVOID,BOOL); diff --git a/include/wingdi.h b/include/wingdi.h index ca72f33149a..77ad737da0f 100644 --- a/include/wingdi.h +++ b/include/wingdi.h @@ -3660,8 +3660,8 @@ BOOL WINAPI UpdateICMRegKeyA(DWORD,LPSTR,LPSTR,UINT); BOOL WINAPI UpdateICMRegKeyW(DWORD,LPWSTR,LPWSTR,UINT); #define UpdateICMRegKey WINELIB_NAME_AW(UpdateICMRegKey) BOOL WINAPI WidenPath(HDC); -BOOL WINAPI PolyTextOutA(HDC,PPOLYTEXTA,INT); -BOOL WINAPI PolyTextOutW(HDC,PPOLYTEXTW,INT); +BOOL WINAPI PolyTextOutA(HDC,const POLYTEXTA*,INT); +BOOL WINAPI PolyTextOutW(HDC,const POLYTEXTW*,INT); #define PolyTextOut WINELIB_NAME_AW(PolyTextOut) /* These defines are used by wglSwapLayerBuffers */ diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 4d0fd5e9e4e..53aa74219a0 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -414,7 +414,7 @@ BOOL WCMD_delete (char *command, BOOL expectDir) { FindClose (hff); } - /* Now recurse into all subdirectories handling the paramater in the same way */ + /* Now recurse into all subdirectories handling the parameter in the same way */ if (strstr (quals, "/S") != NULL) { char thisDir[MAX_PATH]; diff --git a/programs/winebrowser/main.c b/programs/winebrowser/main.c index 7bea32c9420..fa4f0c9e37d 100644 --- a/programs/winebrowser/main.c +++ b/programs/winebrowser/main.c @@ -83,22 +83,13 @@ static int open_http_url( const char *url ) length = sizeof(browsers); /* @@ Wine registry key: HKCU\Software\Wine\WineBrowser */ - if (RegCreateKeyEx( HKEY_CURRENT_USER, "Software\\Wine\\WineBrowser", 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL)) + if (!(r = RegOpenKey( HKEY_CURRENT_USER, "Software\\Wine\\WineBrowser", &key ))) { - fprintf( stderr, "winebrowser: cannot create config key\n" ); - return 1; + r = RegQueryValueExA( key, "Browsers", 0, &type, (LPBYTE)browsers, &length ); + RegCloseKey( key ); } - - r = RegQueryValueExA( key, "Browsers", 0, &type, (LPBYTE)browsers, &length ); if (r != ERROR_SUCCESS) - { - /* set value to the default */ - RegSetValueExA( key, "Browsers", 0, REG_SZ, (const BYTE *)defaultbrowsers, - lstrlen( defaultbrowsers ) + 1 ); strcpy( browsers, defaultbrowsers ); - } - RegCloseKey( key ); return launch_app( browsers, url ); } @@ -115,22 +106,13 @@ static int open_mailto_url( const char *url ) length = sizeof(mailers); /* @@ Wine registry key: HKCU\Software\Wine\WineBrowser */ - if (RegCreateKeyEx( HKEY_CURRENT_USER, "Software\\Wine\\WineBrowser", 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL )) + if (!(r = RegOpenKey( HKEY_CURRENT_USER, "Software\\Wine\\WineBrowser", &key ))) { - fprintf( stderr, "winebrowser: cannot create config key\n" ); - return 1; + r = RegQueryValueExA( key, "Mailers", 0, &type, (LPBYTE)mailers, &length ); + RegCloseKey( key ); } - - r = RegQueryValueExA( key, "Mailers", 0, &type, (LPBYTE)mailers, &length ); if (r != ERROR_SUCCESS) - { - /* set value to the default */ - RegSetValueExA( key, "Mailers", 0, REG_SZ, (const BYTE *)defaultmailers, - lstrlen( defaultmailers ) + 1 ); strcpy( mailers, defaultmailers ); - } - RegCloseKey( key ); return launch_app( mailers, url ); } diff --git a/programs/winetest/Makefile.in b/programs/winetest/Makefile.in index a15819cc08d..c5afe482064 100644 --- a/programs/winetest/Makefile.in +++ b/programs/winetest/Makefile.in @@ -68,6 +68,7 @@ TESTBINS = \ rpcrt4_test.exe \ rsabase_test.exe \ rsaenh_test.exe \ + schannel_test.exe \ secur32_test.exe \ serialui_test.exe \ setupapi_test.exe \ @@ -176,6 +177,8 @@ rsabase_test.exe: $(DLLDIR)/rsabase/tests/rsabase_test.exe$(DLLEXT) cp $(DLLDIR)/rsabase/tests/rsabase_test.exe$(DLLEXT) $@ && $(STRIP) $@ rsaenh_test.exe: $(DLLDIR)/rsaenh/tests/rsaenh_test.exe$(DLLEXT) cp $(DLLDIR)/rsaenh/tests/rsaenh_test.exe$(DLLEXT) $@ && $(STRIP) $@ +schannel_test.exe: $(DLLDIR)/schannel/tests/schannel_test.exe$(DLLEXT) + cp $(DLLDIR)/schannel/tests/schannel_test.exe$(DLLEXT) $@ && $(STRIP) $@ secur32_test.exe: $(DLLDIR)/secur32/tests/secur32_test.exe$(DLLEXT) cp $(DLLDIR)/secur32/tests/secur32_test.exe$(DLLEXT) $@ && $(STRIP) $@ serialui_test.exe: $(DLLDIR)/serialui/tests/serialui_test.exe$(DLLEXT) diff --git a/programs/winetest/winetest.rc b/programs/winetest/winetest.rc index 3e7d00239c8..103a03740e0 100644 --- a/programs/winetest/winetest.rc +++ b/programs/winetest/winetest.rc @@ -191,6 +191,7 @@ riched20_test.exe TESTRES "riched20_test.exe" rpcrt4_test.exe TESTRES "rpcrt4_test.exe" rsabase_test.exe TESTRES "rsabase_test.exe" rsaenh_test.exe TESTRES "rsaenh_test.exe" +schannel_test.exe TESTRES "schannel_test.exe" secur32_test.exe TESTRES "secur32_test.exe" serialui_test.exe TESTRES "serialui_test.exe" setupapi_test.exe TESTRES "setupapi_test.exe" -- 2.11.4.GIT