diff -urN wine-20050419/ANNOUNCE wine-20050524/ANNOUNCE --- wine-20050419/ANNOUNCE 2005-04-19 14:54:44.000000000 +0200 +++ wine-20050524/ANNOUNCE 2005-05-24 16:16:16.000000000 +0200 @@ -1,14 +1,14 @@ -This is release 20050419 of Wine, a free implementation of Windows on +This is release 20050524 of Wine, a free implementation of Windows on Unix. This is still a developers only release. There are many bugs and unimplemented features. Most applications still do not work correctly. -WHAT'S NEW with Wine-20050419: (see ChangeLog for details) - - Mailslot support. - - Support for side mouse buttons (X buttons). - - More Richedit improvements. - - Loading of Windows registry files disabled for now. - - Many code cleanups. +WHAT'S NEW with Wine-20050524: (see ChangeLog for details) + - Many MSI improvements. + - More features in the file manager. + - Better compatibility for Winelib import libraries. + - SGML documentation moved out of the source tree. + - Header files cleanups. - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -17,8 +17,8 @@ the release is available at the ftp sites. The sources will be available from the following locations: - http://www.ibiblio.org/pub/Linux/ALPHA/wine/development/Wine-20050419.tar.gz - http://prdownloads.sourceforge.net/wine/Wine-20050419.tar.gz + http://www.ibiblio.org/pub/Linux/ALPHA/wine/development/Wine-20050524.tar.gz + http://prdownloads.sourceforge.net/wine/Wine-20050524.tar.gz It should also be available from any other site that mirrors ibiblio.org. These locations also hold pre-built documentation packages in various diff -urN wine-20050419/ChangeLog wine-20050524/ChangeLog --- wine-20050419/ChangeLog 2005-04-19 14:54:44.000000000 +0200 +++ wine-20050524/ChangeLog 2005-05-24 16:16:16.000000000 +0200 @@ -1,4 +1,2619 @@ ---------------------------------------------------------------- +2005-05-24 Alexandre Julliard + + * dlls/qcap/Makefile.in, dlls/qcap/qcap_main.h, dlls/qcap/yuv.c: + Maarten Lankhorst + Added YUV routines needed for v4l driver, and in the future possibly + other capture drivers too. + + * dlls/kernel/file.c: Rein Klazes + Work around a problem where WriteFile is asked to write memory + protected by DIBSection code. + + * dlls/comctl32/datetime.c, dlls/itss/chm_lib.c, dlls/kernel/instr.c, + dlls/wineps/truetype.c, dlls/wintab32/context.c, + programs/winedbg/break.c, tools/winedump/pe.c: + Hans Leidekker + Fix uninitialized warnings. + + * dlls/ntdll/sec.c, include/wine/server_protocol.h, + server/protocol.def, server/request.h, server/token.c, + server/trace.c: + Robert Shearman + Implement NtAccessCheck. + + * dlls/urlmon/sec_mgr.c, include/urlmon.idl: + Mike McCormack + Add the missing interface method PromptAction to + IInternetZoneManager. + + * configure, configure.ac, dlls/msvcrt/time.c, include/config.h.in: + Phil Krylov + Added detection of platforms which don't have external timezone and + daylight variables, and emulation of these variables. + + * dlls/comctl32/listview.c: Kouji Sasaki + Added handling of WM_ENABLE message. + + * programs/winedbg/Makefile.in, programs/winedbg/be_alpha.c, + programs/winedbg/be_cpu.h, programs/winedbg/be_i386.c, + programs/winedbg/be_ppc.c, programs/winedbg/break.c, + programs/winedbg/debugger.h, programs/winedbg/gdbproxy.c, + programs/winedbg/memory.c, programs/winedbg/tgt_active.c, + programs/winedbg/types.c, programs/winedbg/winedbg.c: + Eric Pouech + - started infrastructure for proper multi-target support (active + process, minidump...) + - all read/write memory ops are now done thru a centralized process_io + facility + - minor fixes & cleanups in CPU backends + + * dlls/shell32/folders.c, dlls/shell32/regsvr.c, + dlls/shell32/shell32_main.h, dlls/shell32/shellole.c, + dlls/shell32/shfldr_unixfs.c: + Michael Jung + Add a new CLSID for UnixDosFolder, which is identical to UnixFolder, + but does unix <-> dos path conversion for GetDisplayNameOf and + ParseDisplayName. + + * tools/winedump/dump.c, tools/winedump/minidump.c, tools/winedump/pe.c: + Dmitry Timoshkov + Print data offset additionally to prefix while dumping data. + + * dlls/x11drv/window.c: Dmitry Timoshkov + SetParent needs to clear 'managed' flag for former top level window. + + * dlls/mshtml/oleobj.c: Jacek Caban + Added OLEIVERB_UIACTIVATE handling. + + * include/urlmon.idl: Mike McCormack + Define GetSoftwareUpdateInfo and ISoftDistExt. + + * dlls/wininet/internet.c, dlls/wininet/tests/http.c: + Uwe Bonnes + Handle more Escape situations. + + * tools/winebuild/build.h, tools/winebuild/import.c, + tools/winebuild/spec32.c: + Free delayed import modules on PROCESS_DETACH. + + * dlls/kernel/Makefile.in, dlls/kernel/toolhelp.c, + dlls/kernel/toolhelp16.c: + Steven Edwards + Split Win16 and Win32 toolhelp functions. + Compile out win87em and 16bit toolhelp functions if 16 bit support is + disabled. + + * programs/winedbg/gdbproxy.c: David Welch + Added the ability to break into the program when using the gdb proxy. + + * dlls/riched20/paint.c: Hannu Valtonen + Use correct background color for the whole richedit control. + + * dlls/user/button.c: Vitaly Lipatov + Add BUTTON_NOTIFY_PARENT macro (as in edit.c). + Notify parent about WM_KILL/SETFOCUS events. + + * configure, configure.ac, dlls/crypt32/Makefile.in, + dlls/crypt32/tests/.cvsignore, dlls/crypt32/tests/Makefile.in, + dlls/crypt32/tests/protectdata.c: + Kees Cook + Create basic test suite for CryptProtectData/CryptUnprotectData. + + * dlls/user/nonclient.c, dlls/user/tests/win.c: + Richard Cohen + Fix off-by-one in menu height calculation (& therefore + AdjustWindowRect) + test. + + * dlls/comctl32/listview.c: James Hawkins + Audit the List-View control. + + * programs/winedbg/gdbproxy.c: David Welch + Fix decoding of thread IDs in the gdbproxy. + + * dlls/uxtheme/draw.c: Kevin Koltzau + Use uniformsizing theme property. + + * include/exdisp.idl: Mike McCormack + Define CLSID_ShellWindows. + + * dlls/msi/sql.y: Mike McCormack + Simplify parsing of the FROM keyword. + +2005-05-23 Alexandre Julliard + + * include/wine/server_protocol.h, server/protocol.def, server/trace.c: + Robert Shearman + - Add new server type "struct security_descriptor". + - Add tracing for this new type. + + * dlls/shell32/shfldr_desktop.c, dlls/shell32/shfldr_fs.c, + dlls/shell32/shfldr_mycomp.c, dlls/shell32/shfldr_unixfs.c: + Michael Jung + More robustly query the SHGDN_FORPARSING flag in the shell32's folders + GetDisplayNameOf methods. + + * dlls/ole32/oleobj.c: Mike McCormack + Remove forward declarations. + + * dlls/msi/action.c: Aric Stewart + Double terminate SZ_MULTI properly. + ClassInfo and ExtensionInfo are also written for ADVERTISED + components. + + * dlls/msi/msi.c: Aric Stewart + Fix a leaking handle. + Make MsiCollectUserInfo more internally consistent. + Thanks to Mike McCormack. + + * include/winnt.h: Ivan Leo Puoti + Update LDT_ENTRY definition. + + * dlls/msi/sql.y: Mike McCormack + Improve parser error checking. + + * dlls/shlwapi/tests/path.c, dlls/shlwapi/url.c: + Uwe Bonnes + Test cases for URL_UNESCAPE and small fix. + + * programs/winedbg/Makefile.in, programs/winedbg/dbg.y, + programs/winedbg/debug.l, programs/winedbg/debugger.h, + programs/winedbg/tgt_minidump.c, programs/winedbg/winedbg.c: + Eric Pouech + - now storing exception info (if any) in thread structure + - added minidump function in winedbg (write only) + + * dlls/kernel/kernel16_private.h, dlls/kernel/ne_module.c: + Support unloading 16-bit builtin modules, and properly manage the + refcount of the 32-bit owner module. + + * dlls/kernel/kernel32.spec, dlls/kernel/toolhelp.c: + Kevin Koltzau + Implement Module32FirstW/NextW. + + * dlls/msi/create.c, dlls/msi/insert.c, dlls/msi/msipriv.h, + dlls/msi/msiquery.c, dlls/msi/query.h, dlls/msi/sql.y, + dlls/msi/update.c, dlls/msi/where.c: + Mike McCormack + Track memory allocations in the SQL parser. + + * dlls/advapi32/advapi32.spec, dlls/advapi32/crypt.c: + Uwe Bonnes + Implemented SystemFunction036. + + * dlls/kernel/kernel16_private.h, dlls/kernel/ne_module.c, + include/wine/winbase16.h, tools/winebuild/spec16.c: + Moved the generated code segment for 16-bit builtins inside the module + structure. + Get rid of the BUILTIN16_DESCRIPTOR structure and directly register + the MZ header instead. + + * dlls/msi/sql.y: Mike McCormack + Simplify parsing of select query. + + * dlls/dplayx/dplay.c: Lionel Ulmer + Rewrite DirectPlayEnumerateA and add W version at the same time. + + * dlls/oleaut32/tests/vartest.c: Michael Stefaniuc + Tests for VarMul(). + + * dlls/oleaut32/variant.c: Michael Stefaniuc + Reimplement VarMul(). It can multiply now all variants that the native + (WinXP) function supports too. + + * dlls/dbghelp/stack.c, include/dbghelp.h: + Eric Pouech + - fixed ReadProcessMemoryProc prototype + - made StackWalk work when dbghelp is run against a non running + process + + * dlls/ddraw/dsurface/main.c: Antoine Chavasse + Added traces in GetPrivateData and SetPrivateData. + Made SetPrivateData actually store the data from the buffer as well as + its size. + + * dlls/ntdll/loader.c: + Moved the loaddll trace into the load_builtin_dll function so that it + gets printed even when we don't get the expected so file. + + * tools/winedump/lnk.c, tools/winedump/minidump.c, + tools/winedump/msmangle.c, tools/winedump/pe.c, + tools/winedump/winedump.h, tools/wmc/lang.h, tools/wmc/write.c: + Robert Shearman + Fix -Wwrite-strings warnings. + + * dlls/msvcrt/msvcrt.spec, dlls/msvcrt/string.c: + Uwe Bonnes + Implement minimal _stricoll. + + * dlls/ole32/filemoniker.c, dlls/ole32/itemmoniker.c: + Robert Shearman + - Add error messages on failure in file moniker load function. + - Fix incorrect pointer check in both monikers. + - Fix max size calculation of item moniker to match native. + + * dlls/ole32/marshal.c: Robert Shearman + - Add a useful trace message. + - Fix more places where custom header size was calculated exclusive of + the data size member. + - Optimize custom marshaling by getting size before calling the custom + marshaler so we can write the header before and not use a second + stream. + + * dlls/msi/order.c, dlls/msi/query.h, dlls/msi/sql.y: + Mike McCormack + Create the ORDER BY view in a single call. + + * programs/winefile/winefile.c, programs/winefile/winefile.h: + Martin Fuchs + Bug fixes for _NO_EXTENSIONS mode. + + * dlls/oleaut32/tests/vartest.c, dlls/oleaut32/variant.c: + Richard Cohen + - Remove unused macro. + - Check for VT_I8 before testing it. + - VarMod returns DISP_E_OVERFLOW not E_INVALIDARG. + + * programs/winedbg/debugger.h, programs/winedbg/memory.c, + programs/winedbg/symbol.c: + Eric Pouech + Removed the macros for verbose memory read/write operations. + + * dlls/avifil32/avifile.spec, dlls/kernel/comm.drv.spec, + dlls/kernel/windebug.spec, dlls/ole32/ole2thk.spec, + dlls/setupapi/setupx.spec, dlls/shell32/shell.spec, + dlls/user/keyboard.drv.spec, dlls/win32s/win32s16.spec: + Comment out stub WEP entry points so that we can call WEP for builtin + dlls too. + + * dlls/commdlg/Makefile.in, dlls/commdlg/commdlg.spec, + dlls/commdlg/generic.c, dlls/msacm/msacm.spec, + dlls/msacm/msacm_main.c, dlls/msvideo/msvideo.spec, + dlls/msvideo/msvideo16.c, dlls/ole32/ole16.c, + dlls/setupapi/virtcopy.c, dlls/shell32/shell.c, + dlls/winmm/mmsystem.c, dlls/winmm/mmsystem.spec: + Removed unnecessary code in the 16-bit DllEntryPoint function of some + dlls, and also fixed its ordinal in a few places. + + * dlls/ole32/moniker.c, dlls/ole32/tests/marshal.c: + Robert Shearman + - Marshal objects & monikers into the ROT. + - Test for this behaviour. + + * dlls/riched20/editor.c: Hannu Valtonen + - Implement EM_LINESCROLL message handling + - Fix a problem with scrolling over the end of the text in + WM_WHEELMOUSE. + + * include/wincrypt.h: Kees Cook + Add defines for dwFlags in pPromptStruct and calls to + CryptProtectData. + + * include/ntddscsi.h: Ivan Leo Puoti + Added some structs to ntddscsi.h. + + * dlls/msi/msipriv.h, dlls/msi/msiquery.c, dlls/msi/query.h, + dlls/msi/sql.y: + Mike McCormack + - remove the unused utf8 field of an expression + - make the parse result a single assignment at top level of parsing + - abort parsing on a memory allocation failure + + * dlls/urlmon/tests/url.c, dlls/urlmon/umon.c: + Jacek Caban + Separated IBinding and IMoniker interfaces. + + * server/registry.c, server/window.c: + Rob Shearman + Fix several memory leaks. + + * programs/winefile/Cs.rc, programs/winefile/De.rc, + programs/winefile/En.rc, programs/winefile/Es.rc, + programs/winefile/Fr.rc, programs/winefile/Hu.rc, + programs/winefile/It.rc, programs/winefile/Nl.rc, + programs/winefile/Pl.rc, programs/winefile/Pt.rc, + programs/winefile/Ru.rc, programs/winefile/Si.rc, + programs/winefile/Sv.rc, programs/winefile/Zh.rc, + programs/winefile/resource.h, programs/winefile/winefile.c: + Martin Fuchs + Implement ID_VIEW_SPLIT command. + + * dlls/x11drv/settings.c: Daniel Schepler + Implement CDS_TEST flag in ChangeDisplaySettings. + + * dlls/ole32/compositemoniker.c: Kevin Koltzau + Implement Hash function on composite moniker. + + * programs/winedbg/dbg.y, programs/winedbg/debug.l, + programs/winedbg/debugger.h, programs/winedbg/expr.c, + programs/winedbg/stack.c, programs/winedbg/types.c, + programs/winedbg/winedbg.c: + Eric Pouech + - no longer store internally the " for strings + - misc clean-ups + - activate symbol demangling by default + + * tools/fnt2fon.c: Dmitry Timoshkov + Small fix for the font directory resource written by fnt2fon. + + * dlls/ntdll/virtual.c: Mike McCormack + Use LIST_FOR_EACH_ENTRY in virtual memory code. + + * dlls/oleaut32/variant.c: Michael Stefaniuc + Fix VariantChangeType: calls to VarDecFromCy and VarDecFromDisp had + source and destination swapped. + + * dlls/crypt32/protectdata.c: Kees Cook + Correct crypt context init in CryptProtectData/CryptUnprotectData. + + * dlls/dbghelp/dwarf.c: Raphael Junqueira + - fixme when unexpected children found + - no more dwarf2_check_sibling errors (ie perfect parsing count) :) + - dwarf2_parse_inlined_subroutine, dwarf2_parse_variable + + * dlls/msi/version.rc: Stefan Leichter + Update version resource of msi.dll to current version shipped from + windows update. + +2005-05-20 Alexandre Julliard + + * dlls/crypt32/Makefile.in, dlls/crypt32/crypt32.spec, + dlls/crypt32/encode.c, dlls/crypt32/main.c: + Juan Lang + - more fully implement CryptRegisterOIDFunction + - implement CryptUnregisterOIDFunction + - add stubs for CryptEncodeObject(Ex)/CryptDecodeObject(Ex) + + * dlls/ntdll/directory.c: Gerald Pfeifer + Avoid compiler warning in parse_mount_entries(). + + * dlls/crypt32/crypt32.spec, dlls/crypt32/protectdata.c: + Kees Cook + Implement CryptUnprotectData counterpart to CryptProtectData. + + * dlls/kernel/ne_module.c, dlls/kernel/resource16.c, + tools/winebuild/build.h, tools/winebuild/res16.c, + tools/winebuild/spec16.c: + Generate 16-bit resources in the proper format inside the module data, + and get rid of the special case for builtins in NE_DefResourceHandler. + + * dlls/msi/table.c: Juan Lang + Turn handled errors from ERRs to WARNs or TRACEs. + + * dlls/ntdll/file.c: Juan Lang + Implement NtQueryVolumeInformationFile for type + FileFsDeviceInformation on FreeBSD. + + * dlls/comctl32/listview.c: James Hawkins + Select the item under the point (x,y) in MouseHover. + + * dlls/crypt32/main.c, dlls/crypt32/protectdata.c: + Kees Cook + Implement CryptProtectData with best-guess encryption. + + * dlls/oleaut32/tests/safearray.c: + Richard Cohen + Check if VT_R8 and VT_INT_PTR are supported before testing them. + + * dlls/gdi/gdiobj.c: David Hemmo + GDI_ReleaseObj was not called with the right parameter. + + * dlls/msi/msi.spec: Aric Stewart + We have a stub for MsiGetUserInfoA we should use it. + + * dlls/msi/msi.c: Aric Stewart + Fix a leaking handle in MsiConfigureProductExW. + Implement MsiGetProductCodeW. + Implement MsiGetUserInfoW. + Implement MsiCollectUserInfoA/W. + + * dlls/msi/action.c: Aric Stewart + Write the RegOwner and RegCompany keys as blank if they do not exist + when doing the RegisterUser action. + + * dlls/shell32/iconcache.c: Michael Jung + Consider only the GIL_FORSHORTCUT flag in SIC_CompareEntries. + + * dlls/gdi/tests/gdiobj.c: Richard Cohen + Fix gdiobj test on NT4, remove asserts. + + * dlls/opengl32/make_opengl: Francois Gouget + Add 'use strict' and fix make_opengl accordingly. + Add function prototypes. + Write "$a $b" rather than the more complex $a . " " . $b. + Document which OpenGL spec files need to be downloaded. + Update the documentation of the list of supported OpenGL versions. + Tweak the usage so it always reports the right command name. + + * include/wincrypt.h: Juan Lang + Add a bunch of missing declarations and definitions. + + * dlls/crypt32/protectdata.c: Kees Cook + Implement serialization and helper functions for CryptProtectData. + + * include/commctrl.h: James Hawkins + Update LVGROUP struct to match MSDN. + + * tools/fnt2fon.c: Dmitry Timoshkov + Make .fon files generated by fnt2fon slightly more compatible with + fontforge, freetype and Windows font viewer. + + * tools/sfnt2fnt.c: Dmitry Timoshkov + - Always initialize width table. + - FT_Get_Next_Char for some reason returns too high number (1040) if + the wine_courier font has been generated by fontforge, use 32 as the + 1st char instead. + + * tools/winedump/ne.c: Dmitry Timoshkov + Print also flags and length of NE resources. + + * dlls/dbghelp/dwarf.c: Raphael Junqueira + - better traces + - handle inclusion "levels" + - better parsing of subprogram, typedef, pointer, ... entries + - arrays, enums, const_type, reference_type parsing + - checks parsing cursors errors (when sibling value available) + - more utilities functions (dwarf2_parse_attr_as_data) + + * dlls/ntdll/nt.c, include/winternl.h: + Ivan Leo Puoti + Rename SystemDriverInformation to SystemModuleInformation. + + * dlls/msi/action.c: Aric Stewart + Fix quoting on queries. + Respect '+' and '*' in WriteRegistryValues to only create the key if + it does not already exist. Prevents overwriting values with NULL. + + * dlls/msi/package.c: Aric Stewart + Quoting fixes. + + * dlls/msi/custom.c: Aric Stewart + Correct query quoting based on Mike's patch. + Also more error messages about return codes from custom actions and + ignore an error that we should be ignoring. + +2005-05-19 Alexandre Julliard + + * dlls/Makefile.in, dlls/winedos/.cvsignore, dlls/winedos/Makefile.in: + Revert previous patch, we still need the winedos import lib for now. + + * configure, configure.ac: + Disable Win16 support by default on non-x86 platforms. + + * dlls/Makefile.in, dlls/winedos/.cvsignore, dlls/winedos/Makefile.in: + We no longer need a winedos import library. + + * programs/winevdm/Makefile.in, programs/winevdm/winevdm.c: + Fail more gracefully if 16-bit support is missing. + + * programs/winefile/winefile.c: Martin Fuchs + The call to ScreenToClient() changes the content of the 'pt' variable, + so it can't be used for the following ShellFolderContextMenu() call. + + * dlls/ole32/filemoniker.c, dlls/ole32/itemmoniker.c, + dlls/ole32/moniker.c, dlls/ole32/moniker.h, dlls/ole32/oleproxy.c: + Robert Shearman + - Add a generic moniker marshaler that works by saving & loading + monikers to & from the stream. + - Use the generic moniker marshal in the file & item monikers and add + a class factory for each. + + * dlls/comctl32/listview.c: Dimi Paun + Do not compute the hit test if we don't really need it. + + * dlls/msvcrt/except.c: Juan Lang + Implement _XcptFilter using signal handlers, and add a couple traces. + + * dlls/winedos/dosexe.h, dlls/winedos/dosmem.c, dlls/winedos/dosvm.c: + Refuse to load if 16-bit support is missing. + + * tools/winebuild/spec16.c: + Use RaiseException instead of RtlRaiseException in 16-bit spec files + since they already depend on kernel32. + + * dlls/kernel/kernel32.spec, dlls/kernel/ne_module.c, + tools/winebuild/spec16.c: + Renamed __wine_(un)register_dll_16 to __wine_dll_(un)register_16 for + consistency with the 32-bit version, and also make the register + function use the same prototype as the 32-bit one. + + * dlls/kernel/kernel16_private.h, dlls/kernel/ne_module.c, + dlls/kernel/ne_segment.c, dlls/kernel/resource16.c: + Use a memory mapping instead of file I/O to load 16-bit modules. + + * dlls/ole32/marshal.c: Robert Shearman + - Change remaining blocks of code with 2-space indentation to 4-space + indentation. + - Make vtables const. + - Remove an unnecessary memcpy and let the compiler do the work. + + * dlls/ole32/marshal.c: Robert Shearman + Write custom header up to and including size, not excluding. + + * dlls/msi/package.c, dlls/msi/sql.y, dlls/msi/tests/db.c, + dlls/msi/tokenize.c: + Mike McCormack + Only tables can be backquoted, strings must be single quoted. + + * dlls/msi/action.c: Juan Lang + Don't fail in RegisterFonts if the Fonts table is missing. + + * programs/winecfg/En.rc, programs/winecfg/driveui.c, + programs/winecfg/resource.h: + James Hawkins + Load Show/Hide Advanced strings from resources. + + * dlls/dbghelp/dwarf.c: Raphael Junqueira + - basic parsing of subprogram, typedef, pointer, class, struct, enum + entries + - indirect strings support + - utilities functions (parse_byte, parse_u2, ...) + + * include/wine/rpcfc.h: Eric Kohl + Define RPC_FC_IGNORE. + + * include/shlobj.h: Kevin Koltzau + Added missing AW define. + + * include/richole.idl: Kevin Koltzau + Add missing typedefs. + + * dlls/kernel/local16.c, include/local.h: Dimi Paun + Rename back local_compact to LOCAL_Compact for consistency. + Get rid of no longer used local.h. + + * dlls/user/user_private.h, windows/syscolor.c, windows/user.c: + Dimi Paun + Remove LOCAL_*() calls from USER, use Local*16() instead. + + * tools/wineprefixcreate.in: + Stefan Leichter + Create link for msiexec.exe in system directory. + + * dlls/ntdll/directory.c: Juan Lang + Implement get_default_drive_device for FreeBSD. + +2005-05-18 Alexandre Julliard + + * dlls/ntdll/heap.c, include/thread.h: + Removed last dependencies on 16-bit headers from ntdll. + + * dlls/ole32/filemoniker.c, dlls/ole32/itemmoniker.c: + Robert Shearman + Implement IROTData::GetComparisonData for file & item monikers. + + * dlls/kernel/kernel16_private.h, dlls/ntdll/loader.c, + include/module.h: + Moved entry point definitions from module.h to kernel16_private.h. + + * dlls/devenum/Makefile.in, dlls/devenum/createdevenum.c: + Maarten Lankhorst + Add vfwindex when enumerating devices, and make sure every device has + a unique registry key, so multiple devices with same name are allowed. + + * dlls/kernel/ne_module.c, tools/winebuild/build.h, + tools/winebuild/res16.c, tools/winebuild/spec16.c: + Generate the 16-bit module header in the standard on-disk format, so + that winebuild doesn't need to know about kernel internal structures. + + * dlls/devenum/mediacatenum.c: + Maarten Lankhorst + Pass property bag to IPersistPropertyBag, if supported. + + * configure, configure.ac, dlls/kernel/cpu.c, dlls/kernel/time.c, + include/config.h.in: + Emmanuel Maillard + Added Darwin 8.0 specific headers. + + * dlls/kernel/ne_module.c: + Split the module building functionality of NE_LoadExeHeader into + separate functions. + + * dlls/msi/cond.y: Aric Stewart + A few small fixes. + + * dlls/msi/action.c: Aric Stewart + We cannot internally load the files in FileCost because that action + may be skipped or not called. So do it in CostInitialize. + Quote the file path in SelfRegModules. + Do not write squished null guids to the feature registration. + + * dlls/qcap/capturegraph.c: Maarten Lankhorst + Fixed SetFilterGraph failure. + Added debug info. + Added ObjectRefCount info for DllCanUnloadNow. + + * dlls/kernel/kernel32.spec, dlls/user/cursoricon.c, + dlls/user/user16.c, include/module.h: + Removed implementation of LoadDIBIconHandler16 and + LoadDIBCursorHandler16 since they are no longer used, and stop + exporting NE_DefResourceHandler. + + * dlls/qcap/Makefile.in, dlls/qcap/pin.c, dlls/qcap/pin.h: + Maarten Lankhorst + Add pin functions from quartz. + + * dlls/crypt32/Makefile.in, dlls/crypt32/protectdata.c: + Kees Cook + Define structures for CryptProtectData/CryptUnprotectData calls. + + * dlls/kernel/tests/pipe.c, dlls/oleaut32/tests/olefont.c, + dlls/oleaut32/tests/safearray.c, dlls/oleaut32/tests/vartest.c, + dlls/shlwapi/tests/clsid.c, dlls/shlwapi/tests/ordinal.c, + dlls/shlwapi/tests/path.c, dlls/shlwapi/tests/shreg.c, + dlls/shlwapi/tests/string.c, programs/expand/expand.c, + programs/rpcss/rpcss_main.c, programs/uninstaller/main.c, + programs/winecfg/drive.c, programs/winemine/main.c, + programs/winhelp/hlp2sgml.c: + Pierre d'Herbemont + Remove stdlib.h inclusion if winsock.h is included. + + * dlls/qcap/enumpins.c, dlls/qcap/qcap_main.c: + Maarten Lankhorst + DllCanUnloadNow fix. + Fixed ObjRefCount for EnumPins. + + * dlls/comctl32/listview.c: James Hawkins + - Store the click point in LISTVIEW_INFO. + - Move mouse tracking to MouseMove. + - Use DragDetect instead of TrackMouse. + - Remove the unused TrackMouse function. + + * dlls/dbghelp/msc.c: Fixed a couple of warnings. + + * dlls/quartz/filtergraph.c: + Maarten Lankhorst + Added reconnect function for filtergraph. + + * dlls/quartz/memallocator.c: + Maarten Lankhorst + Fixed freeing of mediatype. + + * include/wine/list.h: Dimi Paun + Document the more convenient iteration method. + + * include/wincrypt.h: Kees Cook + Define CryptProtectData/CryptUnprotectData crypt32.dll calls. + + * dlls/msi/action.c, dlls/msi/action.h: + Aric Stewart + Correctly use short filenames from uncompressed file sources. Also + default feature and component install states to ABSENT instead of + UNKNOWN. + + * dlls/kernel/kernel16_private.h, dlls/kernel/ne_module.c, + dlls/kernel/snoop16.c: + Changed SNOOP16_RegisterDLL to take a module handle instead of + pointer. Moved snoop function prototypes to kernel16_private.h. + + * dlls/ntdll/loader.c: + Moved import tracing to a separate channel so that +module traces + don't contain too much noise. + + * dlls/gdi/gdiobj.c: Dimi Paun + Remove the LOCAL_*() functions from GDI. + + * programs/winecfg/driveui.c: James Hawkins + Add handling for drive options. + + * dlls/kernel/toolhelp.c: Dimi Paun + Remove the LOCAL_*() function calls from KERNEL. + + * dlls/comctl32/listview.c: + Felix Nawothnig + Resize listview column to autofit on a doubleclick on the + header-divider. + + * dlls/dbghelp/dwarf.c: Raphael Junqueira + - add some Dwarf2 enums + - abbrev entries parser (with attributes) + - debug info parser skeleton (see big tag swith in dwarf2_parse). + + * dlls/ntdll/exception.c: Dimi Paun + Use the more idiomatic form of iterating through the list. + + * dlls/ntdll/virtual.c: Dimi Paun + Make the argument comments out-of-line. + + * dlls/msi/action.c: Aric Stewart + Some error messages and strcmp changes suggested by Dmitry. + + * dlls/ole32/storage32.c: Pierre d'Herbemont + Big Endian specific code fixes in order to conform with + NONAMELESSSTRUCT. + + * dlls/shell32/shlfolder.c: Kouji Sasaki + Added the processing for determination of SFGAO_HASSUBFOLDER flag in + SHELL32_GetItemAttribute function. + + * include/commctrl.h: Kouji Sasaki + Exchanged the values for LVA_ALIGNLEFT style and LVA_DEFAULT style. + + * programs/winhelp/hlpfile.c: Kouji Sasaki + Corrected RLE decompression processing. + + * dlls/dbghelp/msc.c, dlls/dbghelp/path.c: + Raphael Junqueira + Fix open_pdb_file (used for locate/open pdbs): + - pdb_match heuristic now only stop when "first file" exists + - SymFindFileInPath now fill output buffer with a valid value on + success. + +2005-05-17 Alexandre Julliard + + * dlls/devenum/devenum.spec, dlls/devenum/devenum_main.c, + dlls/dmcompos/dmcompos.spec, dlls/dmcompos/dmcompos_main.c, + dlls/dmcompos/regsvr.c, dlls/dmime/dmime.spec, + dlls/dmime/dmime_main.c, dlls/dmime/regsvr.c, + dlls/dmstyle/dmstyle.spec, dlls/dmstyle/dmstyle_main.c, + dlls/dmstyle/regsvr.c, dlls/dsound/dsound.spec, + dlls/dsound/dsound_main.c, dlls/dsound/regsvr.c, + dlls/hhctrl.ocx/hhctrl.ocx.spec, dlls/hhctrl.ocx/regsvr.c, + dlls/olepro32/olepro32.spec, dlls/olepro32/olepro32stubs.c, + dlls/quartz/main.c, dlls/quartz/quartz.spec, dlls/quartz/regsvr.c, + dlls/rsaenh/rsaenh.c, dlls/rsaenh/rsaenh.spec, dlls/shdocvw/regsvr.c, + dlls/shdocvw/shdocvw.spec, dlls/shdocvw/shdocvw_main.c: + Robert Shearman + Rename MODULENAME_Dll* functions to Dll* for better consistency and + type checking. + + * dlls/kernel/kernel16_private.h, dlls/kernel/local16.c, + dlls/kernel/ne_module.c, dlls/kernel/ne_segment.c, + dlls/kernel/relay16.c, dlls/kernel/resource16.c, + dlls/kernel/snoop16.c, dlls/kernel/task.c: + Renamed some fields in NE_MODULE to use the same name as in the + exported IMAGE_OS2_HEADER structure. + + * dlls/gdi/gdiobj.c: Dimi Paun + Use standard TRACE macro. + + * programs/msiexec/msiexec.c: Robert Shearman + Rename DllRegisterServer and DllUnregisterServer to avoid confusion + with the COM functions of different signatures. + + * include/objbase.h: Robert Shearman + Add Wine-only type checking for DllRegisterServer and + DllUnregisterServer. + + * dlls/dbghelp/Makefile.in, dlls/dbghelp/dbghelp_private.h, + dlls/dbghelp/dwarf.c, dlls/dbghelp/elf_module.c: + Raphael Junqueira + Beginning of dbghelp dwarf2 support: + - add elf_module entry for dwarf2_parse + - stubbed dwarf2_parse in new dwarf.c file + + * dlls/user/edit.c: Dimi Paun + Use standard Local*16() functions instead of LOCAL_*() ones. + + * dlls/qcap/Makefile.in, dlls/qcap/enumpins.c: + Maarten Lankhorst + Added EnumPins from quartz for internal use. + + * dlls/kernel/kernel16_private.h, dlls/kernel/ne_module.c, + include/module.h, tools/winebuild/spec16.c: + Use the exported IMAGE_OS2_HEADER to generate the module header in the + spec file, and moved the NE_MODULE structure definition to + kernel16_private.h. + + * programs/winecfg/En.rc, programs/winecfg/resource.h: + James Hawkins + Add ShowDirSymLink and ShowDotFiles to the drive ui. + + * dlls/comctl32/tab.c: James Hawkins + Fixed centering of tab text. + + * dlls/qcap/dllsetup.c: Maarten Lankhorst + Fixed initialisation crash on loading qcap dll. + + * dlls/ole32/ole2.c: Juan Lang + Obvious fixes to PropVariantClear and PropVariantCopy for vector + types. + + * dlls/qcap/enummedia.c: Maarten Lankhorst + Fixed qcap's inherited enummedia bugs. + +2005-05-16 Alexandre Julliard + + * dlls/ole32/stg_prop.c: Juan Lang + Add a comment, and a no-op cleanup. + + * dlls/msi/action.c, include/msidefs.h: + Aric Stewart + Correct a problem with parse_data if binary data was not in full bytes. + More properly handle uncompressed file sources, fix the creating and + parsing of Source Directories. + + * programs/winefile/Cs.rc, programs/winefile/De.rc, + programs/winefile/En.rc, programs/winefile/Es.rc, + programs/winefile/Fr.rc, programs/winefile/Hu.rc, + programs/winefile/It.rc, programs/winefile/Makefile.in, + programs/winefile/Nl.rc, programs/winefile/Pl.rc, + programs/winefile/Pt.rc, programs/winefile/Ru.rc, + programs/winefile/Si.rc, programs/winefile/Sv.rc, + programs/winefile/Zh.rc, programs/winefile/resource.h, + programs/winefile/winefile.c: + Martin Fuchs + Implement connecting and disconnecting of network drives. + + * dlls/kernel/atom16.c, dlls/kernel/debugger.c, dlls/kernel/global16.c, + dlls/kernel/instr.c, dlls/kernel/kernel16_private.h, + dlls/kernel/kernel_main.c, dlls/kernel/kernel_private.h, + dlls/kernel/local16.c, dlls/kernel/ne_module.c, + dlls/kernel/ne_segment.c, dlls/kernel/relay16.c, + dlls/kernel/resource16.c, dlls/kernel/snoop16.c, + dlls/kernel/system.c, dlls/kernel/task.c, dlls/kernel/thunk.c, + dlls/kernel/wowthunk.c, include/module.h: + Moved a bunch of definitions out of module.h into a new + kernel16_private.h header. + + * configure, configure.ac, dlls/Makefile.in, dlls/odbccp32/.cvsignore, + dlls/odbccp32/Makefile.in, dlls/odbccp32/odbccp32.c, + dlls/odbccp32/odbccp32.spec: + Mike McCormack + Initial mostly stub implementation of ODBC control panel. + + * server/token.c: Robert Shearman + Add user attribute to token objects. + + * dlls/ole32/stg_prop.c: Juan Lang + Differentiate between version 0 and version 1 property storages. + + * dlls/dbghelp/stack.c, dlls/kernel/comm.c, dlls/kernel/instr.c, + dlls/kernel/kernel_main.c, dlls/kernel/locale.c, + dlls/kernel/syslevel.c, dlls/kernel/task.c, dlls/kernel/thread.c, + dlls/kernel/thunk.c, dlls/kernel/wowthunk.c, dlls/ntdll/file.c, + dlls/ntdll/ntdll_misc.h, dlls/ntdll/path.c, dlls/ntdll/signal_i386.c, + dlls/ntdll/sync.c, dlls/user/winproc.c, include/winternl.h: + Removed the special casing of kernel32 and ntdll for the TEB + definition in winternl.h. + + * dlls/kernel/atom16.c, dlls/kernel/debugger.c, dlls/kernel/error16.c, + dlls/kernel/global16.c, dlls/kernel/kernel_main.c, + dlls/kernel/kernel_private.h, dlls/kernel/local16.c, + dlls/kernel/ne_module.c, dlls/kernel/ne_segment.c, + dlls/kernel/relay16.c, dlls/kernel/snoop16.c, dlls/kernel/system.c, + dlls/kernel/task.c, dlls/kernel/thunk.c, dlls/kernel/toolhelp.c, + dlls/kernel/wowthunk.c, include/local.h, include/stackframe.h: + Moved the remaining stack frame definitions to kernel_private.h and + removed stackframe.h. + + * dlls/dbghelp/stack.c, dlls/user/winproc.c, dlls/user/wnd16.c, + programs/winedbg/stack.c, tools/winebuild/relay.c, + tools/winebuild/spec16.c: + Avoid referencing stackframe.h from outside kernel32. + + * dlls/ole32/compobj.c, dlls/ole32/compobj_private.h, + dlls/ole32/ole2.c, dlls/ole32/ole2_16.c, dlls/ole32/ole32_main.c, + dlls/ole32/ole32_main.h: + Marcus Meissner + Move the Dll init function to compobj.c to avoid having global + variables. Remove need of ole32_main.h. + + * programs/winefile/Cs.rc, programs/winefile/De.rc, + programs/winefile/En.rc, programs/winefile/Es.rc, + programs/winefile/Fr.rc, programs/winefile/Hu.rc, + programs/winefile/It.rc, programs/winefile/Nl.rc, + programs/winefile/Pl.rc, programs/winefile/Pt.rc, + programs/winefile/Ru.rc, programs/winefile/Si.rc, + programs/winefile/Zh.rc, programs/winefile/resource.h, + programs/winefile/winefile.c: + Martin Fuchs + Implement menu entry "format disk" (derived from Robert Dickenson's + code). + + * dlls/advapi32/registry.c, dlls/ntdll/reg.c: + Robert Shearman + Implement RegNotifyChangeKeyValue on top of NtNotifyChangeKey. + + * dlls/kernel/local16.c: Dimi Paun + Use the standard Local*16() instead of LOCAL_*() functions. + + * dlls/dinput/device.c: Robert Reif + Effect objects are not supported yet so don't crash when trying to + enumerate them. + + * dlls/kernel/ne_module.c, dlls/kernel/ne_segment.c, + dlls/kernel/relay16.c, dlls/kernel/snoop16.c, dlls/winedos/relay.c, + include/builtin16.h, include/stackframe.h, include/wine/winbase16.h, + tools/winebuild/spec16.c: + Moved data structures for 16-bit relay calls to winbase16.h and + removed builtin16.h. + + * dlls/rsaenh/rsaenh.c: Kees Cook + Avoid segfault in hash update with corrupted decrypt data. + + * dlls/riched20/run.c: Michael Stefaniuc + Change an assert to a WARN. + + * dlls/gdi/path.c: Felix Nawothnig + Keep width for cosmetic pens, don't use LPtoDP() for widths and + convert the dashes for PS_USERSTYLE pens into device units. + + * dlls/advapi32/eventlog.c, dlls/riched20/editor.c, + dlls/richedit/richedit.c, dlls/rpcrt4/ndr_stubless.c: + Vincent Béron + Provide minimal API documentation in advapi/eventlog.c to silence some + winapi_check output. + Move around functions in riched20, richedit and rpcrt4 to achieve the + same goal. + + * dlls/rsaenh/rsaenh.c: Kees Cook + Avoid segfault when detecting decryption buffer size. + + * dlls/msvcrt/file.c, dlls/msvcrt/tests/file.c: + Uwe Bonnes + Correct return value of fsetpos. + + * dlls/setupapi/queue.c: Ivan Leo Puoti + Minor fix in SetupQueueCopySectionW. + + * dlls/kernel/local16.c: Dimi Paun + Avoid using some LOCAL_*() functions. + + * programs/winefile/Sv.rc, programs/winefile/rsrc.rc: + Martin Fuchs + Swedish translation of winefile resources by David Nordenberg, + proofread by Andreas Bjerkeholt. + + * programs/winefile/De.rc, programs/winefile/En.rc, + programs/winefile/Es.rc, programs/winefile/Fr.rc, + programs/winefile/Hu.rc, programs/winefile/It.rc, + programs/winefile/Nl.rc, programs/winefile/Pt.rc, + programs/winefile/Ru.rc, programs/winefile/Si.rc, + programs/winefile/Zh.rc, programs/winefile/resource.h, + programs/winefile/winefile.c: + Martin Fuchs + Implement switching of file sort order. + + * include/shlobj.h: Martin Fuchs + Define flags for SHFormatDrive(). + + * dlls/dbghelp/stabs.c: Hans Leidekker + Silence some unknown stab type messages. + + * dlls/ole32/ole16.c: Marcus Meissner + Make _xmalloc16() static. + + * dlls/ole32/ftmarshal.c: Marcus Meissner + Staticify FTMarshalImpl definition. + + * dlls/ole32/hglobalstream.c: Marcus Meissner + Make HGLOBALStream_* functions static. + + * include/.cvsignore, include/Makefile.in, include/msxml.idl, + include/msxmldid.h: + Mike McCormack + Added some xml headers. + + * tools/winapi/win16.api, tools/winapi/win32.api: + Vincent Béron + Update win16.api and win32.api to keep up with current Wine + development. + + * dlls/ntdll/ntdll.spec, dlls/unicows/unicows.spec: + Vincent Béron + Correct arg count for 3 functions in ntdll.spec and unicows.spec. + + * dlls/user/sysparams.c, include/winuser.h: + Michael Stefaniuc + Add some SystemParametersInfo SPI_* defines. + + * dlls/dinput/dinput_main.c, dlls/dinput/dinput_private.h, + dlls/dinput/joystick_linux.c, dlls/dinput/joystick_linuxinput.c, + dlls/dinput/keyboard.c, dlls/dinput/mouse.c, + dlls/dinput/tests/joystick.c: + Robert Reif + Pass around real version and do correct thing based on it. + Change cooperative level to pass on windows. + + * dlls/ole32/stg_prop.c: Juan Lang + Store property names in the code page of the property set. + +2005-05-14 Alexandre Julliard + + * programs/winefile/resource.h, programs/winefile/resource.rc, + programs/winefile/winefile.c: + Martin Fuchs + - spelling fixes (prefered -> preferred) + - add ", {0, 0}, 0, 0" in comment lines + - update copyright statement + + * dlls/ole32/moniker.c, dlls/ole32/tests/moniker.c: + Jeff Latimer + Implement the IEnumMoniker interface for the ROT and provide tests to + exercise the interface. + + * dlls/gdi/path.c: Felix Nawothnig + Convert pen width to DP in StrokePath(). + + * dlls/winmm/wineoss/audio.c, dlls/winmm/wineoss/midi.c: + Mike McCormack + Set thread priorities to time critical. + + * dlls/user/tests/win.c, dlls/user/win.c: + Paul Vriens + Check for a NULL pointer in GetWindowTextA/W. + + * dlls/ntdll/directory.c: Robert Lunnon + Implement get_default_drive_device for Solaris. + + * dlls/gdi/gdiobj.c, dlls/kernel/kernel32.spec, dlls/kernel/local16.c, + include/local.h, windows/user.c: + Dimi Paun + Make LOCAL_*() just wrappers around Local*16() functions. + + * dlls/dbghelp/stack.c, dlls/kernel/kernel_main.c, + dlls/kernel/ne_module.c, dlls/kernel/ne_segment.c, + dlls/kernel/system.c, dlls/kernel/task.c, dlls/kernel/thunk.c, + dlls/kernel/wowthunk.c, dlls/ntdll/signal_i386.c, + dlls/user/winproc.c, include/stackframe.h, include/thread.h, + tools/winebuild/build.h: + Store the 16-bit stack pointer in the WOW32Reserved TEB field. + + * dlls/ntdll/atom.c, server/atom.c: + Fixed a number of atom test failures. + + * dlls/winsock/socket.c, include/thread.h: + Store the winsock per-thread data in NtCurrentTeb()->WinSockData + instead of using TlsAlloc. + + * server/queue.c: + Fixed another case where a mouse message could get assigned to a + different thread input. + + * programs/winefile/De.rc, programs/winefile/En.rc, + programs/winefile/resource.h, programs/winefile/winefile.c: + Martin Fuchs + Display free and total disk space in status bar. + + * dlls/gdi/path.c: Felix Nawothnig + Draw each figure as a single primitive in StrokePath(). + + * dlls/msvcrt/data.c, dlls/msvcrt/msvcrt.h, dlls/msvcrt/msvcrt.spec, + dlls/msvcrt/time.c: + Juan Lang + - move _timezone to time.c, and correct its type + - implement _tzset, and initialize _daylight, _timezone, and _tzname + from libc values + + * dlls/shell32/shlexec.c: Juan Lang + - only log unsupported flags in ShellExecute + - environment variables are expanded, so SEE_MASK_DOENVSUBST is + supported + + * dlls/ole32/stg_prop.c, dlls/ole32/storage32.c, + dlls/ole32/storage32.h: + Juan Lang + - maintain proper byte order + - maintain PROPSETFLAG_ANSI flag based on codepage + - update comments + + * dlls/cabinet/cabinet.h, dlls/cabinet/fci.c: + Gerold Jens Wucherpfennig + Initial FCI work (FCICreate and FCIDestroy). + + * dlls/qcap/Makefile.in, dlls/qcap/enummedia.c, dlls/qcap/qcap_main.h: + Rolf Kalbermatter + Add IEnumMediaType object for use by other class objects. This is + taken from quartz with only minor adaptions. + + * dlls/comctl32/header.c: Felix Nawothnig + Rewrote item layouting - new code fixes bitmap/image position for + non-left-aligned text, prevents jumping when resizing non-left-aligned + text, implements clipping for images and correctly aligns bitmaps when + an image is already there. + +2005-05-13 Alexandre Julliard + + * dlls/commdlg/fontdlg.c: + Don't convert the template name to Unicode, it's not used by the + dialog anyway. Clear the window property on WM_DESTROY. + + * dlls/shell32/.cvsignore, dlls/shell32/Makefile.in, + dlls/shell32/folders.c, dlls/shell32/iconcache.c, + dlls/shell32/shell32_main.c, dlls/shell32/shell32_main.h, + dlls/shell32/shres.rc, dlls/shell32/shresdef.h, tools/wine.inf: + Ge van Geldorp + Overlay icons for .lnk files with a small arrow in the lower left + corner. + + * programs/winefile/winefile.c: Martin Fuchs + Display source path in "move file" dialog. + + * dlls/ole32/git.c: Mike McCormack + Remove function prototypes. + + * dlls/riched20/editor.c: Krzysztof Foltman + Added stubs for a couple of missing 2.0 and 3.0 messages. + + * programs/winefile/Cs.rc, programs/winefile/De.rc, + programs/winefile/En.rc, programs/winefile/Es.rc, + programs/winefile/Fr.rc, programs/winefile/Hu.rc, + programs/winefile/It.rc, programs/winefile/Nl.rc, + programs/winefile/Pl.rc, programs/winefile/Pt.rc, + programs/winefile/Ru.rc, programs/winefile/Si.rc, + programs/winefile/Zh.rc, programs/winefile/resource.h: + Martin Fuchs + Replace numeric resource identifiers by their defined constants. + + * dlls/secur32/Makefile.in, dlls/secur32/schannel.c, + dlls/secur32/secur32.c, dlls/secur32/secur32_priv.h: + Juan Lang + Begin stubs of built-in schannel provider. + + * dlls/msvcrt/except.c, dlls/msvcrt/main.c, dlls/msvcrt/msvcrt.h, + include/Makefile.in, include/msvcrt/float.h, include/msvcrt/signal.h: + Juan Lang + Implement signals. + + * dlls/ole32/tests/Makefile.in: Hans Leidekker + Don't import from ntdll. + + * dlls/user/painting.c: + Process the pending expose events on RDW_UPDATENOW before doing the + redraw_window server call so that the parent windows get properly + validated if necessary. + + * server/queue.c: + Only set the new window of a hardware message if the window belongs to + the same thread input, otherwise just drop the message. + + * dlls/shell32/shelllink.c: Mike McCormack + Remove some unused include files. + + * dlls/opengl32/opengl_ext.h: Added yet another missing OpenGL define. + + * dlls/ole32/storage32.c, dlls/ole32/storage32.h, + dlls/ole32/tests/storage32.c: + Mike McCormack + Make sure a stream can't be created in read only storage. + + * dlls/user/win.c: Dmitry Timoshkov + Avoid a crash in free_window_handle() on an invalid window handle. + + * dlls/Makefile.in, dlls/make_dlls: + Build import libraries also when only doing an install-lib. + + * dlls/dinput/dinput_main.c, dlls/dinput/dinput_private.h, + dlls/dinput/joystick_linux.c, dlls/dinput/tests/joystick.c: + Robert Reif + Fix SetProperty error returned. + Add EnumDevice joystick version check. + Test multiple versions. + + * dlls/ntdll/exception.c: Mike Hearn + Make unimplemented function message a bit prettier. + + * dlls/msi/action.c, dlls/msi/msipriv.h: + Aric Stewart + - ExecuteAction runs the whole Execute table and not just from + InstallValidate onward. To do this make sure we do not do the + costing initialization work again if it is already done (by checking + the CostingComplete Property). + - A lot of work to refine feature states, setting the state affects + the state of all child features and also respect features that want + to default to something other than LOCAL. + + * dlls/ntdll/nt.c: Paul Vriens + Added (stubbed) SystemDriverInformation and + SystemInterruptInformation. + + * programs/notepad/main.c: Kevin Koltzau + Enable/disable menu items based on edit control state. + + * dlls/rpcrt4/rpc_server.c: Robert Shearman + - Fix RpcServerListen so that it doesn't return + RPC_S_ALREADY_LISTENING when the only interfaces it is listening on + are auto listens. + - Only synchronize with server thread when necessary and move this + into RpcMgmtWaitServerListen. + + * dlls/shell32/shfldr_unixfs.c: + Michael Jung + Replace '\\' by '/' in strings passed to ParseDisplayName to be able + to handle DOS-style relative paths. + +2005-05-12 Alexandre Julliard + + * dlls/ole32/compobj_private.h, dlls/ole32/filemoniker.c: + Mike McCormack + Remove unnecessary declarations and make functions static. + + * dlls/comctl32/tab.c: Aric Stewart + Handle WM_NCCALCSIZE in the tab control. + + * dlls/shell32/shell32_main.c: Mike McCormack + Split SHGetFileInfoW into two functions. + + * dlls/x11drv/clipboard.c: Dmitry Timoshkov + Do not pass an invalid target buffer info to WideCharToMultiByte. + + * dlls/commdlg/filedlgbrowser.c: Mike Hearn + Fix return code abuse. + + * dlls/shell32/shfldr_unixfs.c: Michael Lin + - Implement IPersistFolder2. + - Retrieve the correct attributes in ParseDisplayName(). + + * dlls/opengl32/wgl.c, dlls/opengl32/wgl_ext.c: + Raphael Junqueira + - better robustness of pbuffer code (checks, SetLastError as specs, etc...). + - better heuristic for WGL_render_texture and first try of + WGL_render_texture "emulation" using Pbuffers (deactivated by + default) + - more traces + + * include/Makefile.in, include/schannel.h, include/schnlsp.h: + Juan Lang + Added schannel header files. + + * dlls/msvcrt/file.c: + Flush output buffers from _close() rather than MSVCRT_fclose(). + + * dlls/ntdll/time.c: Gabriel Gambetta + Added UYT to TZ_INFO. + +2005-05-11 Alexandre Julliard + + * dlls/user/property.c, include/wine/server_protocol.h, + server/protocol.def, server/trace.c, server/window.c: + Allow passing a string to the window property server requests instead + of an atom to avoid redundant server round-trips. + + * server/atom.c, server/object.h: + Changed atom handling to use counted strings instead of + null-terminated ones, avoiding the need for a temporary buffer. + + * documentation/README.pt_br: Dimi Paun + Fix spelling errors discovered by Marcelo Duarte. + + * include/winternl.h: Paul Vriens + Sorted some of the structs and made them consistent. + + * programs/winefile/winefile.c: Martin Fuchs + Improved version of Piotr Caban's bugfix patch "Fixed display bug". + + * include/evntrace.h: Added a few missing structure names. + + * dlls/oleaut32/tmarshal.c: Robert Shearman + Use I_RpcGetBuffer instead of HeapReAlloc for getting the Buffer + memory. + + * dlls/ole32/moniker.c: Mike McCormack + Make functions static and remove unnecessary declarations. + + * dlls/riched20/run.c, dlls/riched20/style.c: + Ivan Leo Puoti + Fix crash in ME_GetRunSizeCommon(). Turn a FIXME into a TRACE. + + * dlls/ntdll/tests/.cvsignore, dlls/ntdll/tests/Makefile.in, + dlls/ntdll/tests/atom.c: + Eric Pouech + Some tests for NTDLL atom support (by György 'Nog' Jeney). + + * dlls/ntdll/Makefile.in, dlls/ntdll/atom.c, dlls/ntdll/ntdll.spec, + include/winternl.h: + Eric Pouech + Implemented NTDLL atom support. + + * dlls/user/hook.c, dlls/user/message.c, dlls/user/user_private.h, + include/wine/server_protocol.h, server/hook.c, server/protocol.def, + server/queue.c, server/trace.c, server/user.h: + Store a bitmap of active hooks on the client side to try to avoid + server calls for hooks that are not set. + + * dlls/advapi32/advapi32.spec, dlls/advapi32/eventlog.c, + include/evntrace.h: + Aric Stewart + Add a stub implementation of RegisterTraceGuids. + + * dlls/msi/msiquery.c, dlls/msi/table.c: + Mike McCormack + Avoid some non-standard str functions. + + * dlls/kernel/kernel32.spec, dlls/kernel/locale.c: + Mike McCormack + Stub implementation for GetGeoInfo. + + * dlls/ole32/compobj.c, dlls/ole32/ole32.spec: + Mike McCormack + Add a stub implementation of CoIsHandlerConnected. + + * dlls/msvideo/msvideo_main.c: Mike McCormack + Correct the function name in a comment. + + * configure, configure.ac, dlls/dinput/Makefile.in, + dlls/dinput/tests/.cvsignore, dlls/dinput/tests/Makefile.in, + dlls/dinput/tests/dinput_test.h, dlls/dinput/tests/joystick.c, + dlls/dinput/tests/keyboard.c, dlls/dinput/tests/mouse.c, + programs/winetest/Makefile.in: + Robert Reif + Added dinput tests. + + * dlls/gdi/enhmfdrv/bitblt.c: Mike McCormack + Check that GetObject is successful. + + * dlls/ntdll/ntdll.spec: Mike McCormack + ZwQueryTimer should forward to NtQueryTimer. + + * dlls/kernel/kernel32.spec: Mike McCormack + Add Module32FirstW and Module32NextW exports. + + * dlls/comctl32/updown.c: Dimi Paun + Make it more explicit how we deal with WS_DISABLED. + + * dlls/msi/msi.c: Stefan Leichter + Added minimal implementation of MsiCreateAndVerifyInstallerDirectory. + + * include/winbase.h, programs/taskmgr/perfdata.h: + Dimitrie O. Paun + Move {ABOVE,BELOW}_NORMAL_PRIORITY_CLASS to winbase.h. + + * dlls/msvcrt/tests/printf.c: + Add test for correctly interpreting %% printf format string conversion + specifier. + +2005-05-10 Alexandre Julliard + + * documentation/README.de, documentation/README.es, + documentation/README.fr, documentation/README.it, + documentation/README.pt, documentation/README.pt_br: + Dimitrie O. Paun + Update README translations to match the latest changes to the English + README. + + * programs/Makefile.in, programs/make_progs: + Michael Stefaniuc + Install msiexec in the bin directory. + + * dlls/kernel/kernel_main.c, dlls/kernel/selector.c, + dlls/kernel/wowthunk.c, dlls/winedos/dosaspi.c, dlls/winedos/int09.c, + dlls/winedos/int10.c, dlls/winedos/int16.c, dlls/winedos/int19.c, + dlls/winedos/int1a.c, dlls/winedos/int29.c, dlls/winedos/int2f.c, + dlls/winedos/int33.c, dlls/winedos/int67.c, dlls/winedos/ppdev.c, + dlls/winedos/vga.c, include/miscemu.h: + Eric Pouech + Get rid of include/miscemu.h. + + * dlls/msi/database.c: Mike McCormack + - make sure to free the string table when closing the database + - don't free szPersist in MsiOpenDatabase if it's not a string + + * dlls/ole32/storage32.c: Mike McCormack + Fix a memory leak in the ole storage implementation. + + * dlls/kernel/dosmem.c, dlls/kernel/global16.c, dlls/kernel/instr.c, + dlls/kernel/kernel32.spec, dlls/kernel/kernel_private.h, + dlls/winedos/Makefile.in, dlls/winedos/dosexe.h, + dlls/winedos/dosmem.c, dlls/winedos/dosvm.c, dlls/winedos/int21.c, + dlls/winedos/int31.c, dlls/winedos/module.c, + dlls/winedos/winedos.spec, include/miscemu.h: + Eric Pouech + Moved DOS memory handling to winedos. + + * dlls/kernel/atom.c, include/wine/server_protocol.h, server/atom.c, + server/process.c, server/process.h, server/protocol.def, + server/request.h, server/trace.c: + Eric Pouech + - changed ATOM support in wineserver to match NTDLL needs + - adapted accordingly kernel32 atom support + + * libs/wine/loader.c: Robert Lunnon + Add RTLD_FIRST flag to dlopen calls. + + * README, configure, configure.ac, documentation/.cvsignore, + documentation/Makefile.in, documentation/address-space.sgml, + documentation/architecture.sgml, documentation/bugs.sgml, + documentation/configuring.sgml, documentation/ddraw.sgml, + documentation/debugger.sgml, documentation/debugging.sgml, + documentation/documentation.sgml, documentation/faq.sgml, + documentation/fonts.sgml, documentation/getting.sgml, + documentation/glossary.sgml, documentation/introduction.sgml, + documentation/multimedia.sgml, documentation/ole.sgml, + documentation/opengl.sgml, documentation/patches.sgml, + documentation/printing.sgml, documentation/registry.sgml, + documentation/running.sgml, documentation/testing.sgml, + documentation/wine-devel.sgml, documentation/wine-faq.sgml, + documentation/wine-user.sgml, documentation/winedev-coding.sgml, + documentation/winedev-graphical.sgml, + documentation/winedev-kernel.sgml, + documentation/winedev-otherdebug.sgml, + documentation/winedev-windowing.sgml, + documentation/winelib-bindlls.sgml, documentation/winelib-intro.sgml, + documentation/winelib-mfc.sgml, documentation/winelib-porting.sgml, + documentation/winelib-toolkit.sgml, documentation/winelib-user.sgml: + Dimi Paun + Moved the SGML documentation over to SourceForge. + + * dlls/Makedll.rules.in, dlls/Makefile.in, dlls/Maketest.rules.in, + dlls/make_dlls, programs/Makeprog.rules.in, + programs/avitools/Makefile.in: + Build and load import libraries directly from the dll directory where + possible, and only create symlinks for directories that don't have the + correct name. + + * dlls/user/menu.c, dlls/user/tests/menu.c: + Rein Klazes + Multi column popup menus have 4 pixel space between the columns. With + conformance test. + + * dlls/dinput/device.c, dlls/dinput/dinput_main.c, + dlls/dinput/joystick_linux.c: + Robert Reif + Fix joystick crash when a button guid is specified in the data + format. + Add some parameter checking. + + * dlls/ntdll/tests/info.c: Paul Vriens + Added SystemHandleInformation tests. + Removed HeapAlloc in test_basic. + Renamed test_basic to test_query_basic. + + * dlls/ntdll/nt.c: Paul Vriens + Added (stubbed) SystemHandleInformation. + Sorted the list. + + * include/winternl.h: Paul Vriens + Changed SystemHandleList into SystemHandleInformation + Unknown18 is now SystemPageFileInformation + Some consistency (added numbers to the definitions). + + * dlls/opengl32/wgl.c: Raphael Junqueira + Fix allocated buffer size to avoid buffer overflow. + + * programs/winecfg/driveui.c: James Hawkins + - Remove useless LVN_ITEMACTIVATE notification handling. + - Update controls in response to a NM_CLICK notification. + + * programs/winecfg/driveui.c: James Hawkins + Remove old listbox code from driveui. + + * programs/winecfg/En.rc: James Hawkins + Set listview style LVS_SINGLESEL so only one drive can be selected. + + * include/mapidefs.h: Juan Lang + Fix FILETIME to match winbase.h on big-endian machines. + + * dlls/shell32/cpanelfolder.c, dlls/shell32/shfldr_desktop.c, + dlls/shell32/shfldr_fs.c, dlls/shell32/shfldr_mycomp.c: + Juan Lang + Fixes to IShellFolder::GetAttributesOf implementations, spotted by + silverblade_: + - a count of zero is allowed to GetAttributesOf if apidl is NULL + - SFGAO_VALIDATE must be cleared upon return + + * dlls/msvcrt/wcs.c: + Interpret %% correctly in printf format string. + + * dlls/shell32/pidl.c: Mike Hearn + Fix SHELL_GetPathFromIDList[AW] to return the desktop path given an + empty PIDL. + + * dlls/msi/appsearch.c, include/msidefs.h: + Juan Lang + Partially implement AppSearch for RegLocator-type searches. + + * dlls/x11drv/opengl.c: Raphael Junqueira + Fix X11DRV_ChoosePixelFormat to choose 24 bpp as 32 bpp for depth + buffers (needed as many X11 drivers only support 24bpp). + + * dlls/ntdll/time.c: Juan Lang + Added Irish Summer Time. + +2005-05-09 Alexandre Julliard + + * dlls/msi/action.c, dlls/msi/dialog.c: + Aric Stewart + Fix a few leaking object handles. + + * dlls/commdlg/filedlg.c: Michael Jung + Detect drive letters, which have to have a backslash appended, in a + more robust way. + + * dlls/shell32/shfldr_unixfs.c: + Michael Jung + Support folder relative paths in UnixFolders' ParseDisplayName + method. + + * dlls/wined3d/directx.c: Daniel Lund + Added D3DDEVCAPS_HWRASTERIZATION to the DevCaps for scene + rasterization. Allows GuildWars to start. + + * dlls/kernel/comm.c, include/winbase.h: + Andreas Mohr + Fix for CommConfigDialog*() hwnd argument. + + * include/winternl.h: Paul Vriens + Remove HANDLEINFO struct. + Add SYSTEM_HANDLE_INFORMATION and SYSTEM_HANDLE_ENTRY structs. + + * dlls/opengl32/wgl_ext.c: Aric Cyr + Fix WGL_ACCELERATION_ARB queries from applications. + + * dlls/winsock/socket.c: Eric Pouech + Some fixes on async shutdown. + + * dlls/opengl32/opengl_ext.h: Francois Gouget + Define GLX_SAMPLE_BUFFERS_ARB and GLX_SAMPLES_ARB if they were not + defined by the OpenGL headers. + + * dlls/Makedll.rules.in, dlls/Makefile.in, dlls/advapi32/Makefile.in, + dlls/advpack/Makefile.in, dlls/amstream/Makefile.in, + dlls/atl/Makefile.in, dlls/avicap32/Makefile.in, + dlls/avifil32/Makefile.in, dlls/cabinet/Makefile.in, + dlls/capi2032/Makefile.in, dlls/cards/Makefile.in, + dlls/cfgmgr32/Makefile.in, dlls/comcat/Makefile.in, + dlls/comctl32/Makefile.in, dlls/make_dlls, dlls/commdlg/Makefile.in, + dlls/crtdll/Makefile.in, dlls/crypt32/Makefile.in, + dlls/cryptdll/Makefile.in, dlls/ctl3d/Makefile.in, + dlls/d3d8/Makefile.in, dlls/d3d9/Makefile.in, dlls/d3dim/Makefile.in, + dlls/d3drm/Makefile.in, dlls/d3dx8/Makefile.in, + dlls/d3dxof/Makefile.in, dlls/dbghelp/Makefile.in, + dlls/dciman32/Makefile.in, dlls/ddraw/Makefile.in, + dlls/devenum/Makefile.in, dlls/dinput/Makefile.in, + dlls/dinput8/Makefile.in, dlls/dmband/Makefile.in, + dlls/dmcompos/Makefile.in, dlls/dmime/Makefile.in, + dlls/dmloader/Makefile.in, dlls/dmscript/Makefile.in, + dlls/dmstyle/Makefile.in, dlls/dmsynth/Makefile.in, + dlls/dmusic/Makefile.in, dlls/dmusic32/Makefile.in, + dlls/dplay/Makefile.in, dlls/dplayx/Makefile.in, + dlls/dpnet/Makefile.in, dlls/dpnhpast/Makefile.in, + dlls/dsound/Makefile.in, dlls/dswave/Makefile.in, + dlls/dxdiagn/Makefile.in, dlls/gdi/Makefile.in, + dlls/glu32/Makefile.in, dlls/glut32/Makefile.in, + dlls/iccvid/Makefile.in, dlls/icmp/Makefile.in, + dlls/imagehlp/Makefile.in, dlls/imm32/Makefile.in, + dlls/iphlpapi/Makefile.in, dlls/itss/Makefile.in, + dlls/kernel/Makefile.in, dlls/lzexpand/Makefile.in, + dlls/mapi32/Makefile.in, dlls/mlang/Makefile.in, + dlls/mpr/Makefile.in, dlls/msacm/Makefile.in, dlls/mscms/Makefile.in, + dlls/msdmo/Makefile.in, dlls/mshtml/Makefile.in, + dlls/msi/Makefile.in, dlls/msimg32/Makefile.in, + dlls/msnet32/Makefile.in, dlls/msrle32/Makefile.in, + dlls/msvcrt/Makefile.in, dlls/msvcrt20/Makefile.in, + dlls/msvcrt40/Makefile.in, dlls/msvcrtd/Makefile.in, + dlls/msvidc32/Makefile.in, dlls/msvideo/Makefile.in, + dlls/mswsock/Makefile.in, dlls/netapi32/Makefile.in, + dlls/newdev/Makefile.in, dlls/ntdll/Makefile.in, + dlls/odbc32/Makefile.in, dlls/ole32/Makefile.in, + dlls/oleacc/Makefile.in, dlls/oleaut32/Makefile.in, + dlls/olecli/Makefile.in, dlls/oledlg/Makefile.in, + dlls/olepro32/Makefile.in, dlls/olesvr/Makefile.in, + dlls/opengl32/Makefile.in, dlls/powrprof/Makefile.in, + dlls/psapi/Makefile.in, dlls/qcap/Makefile.in, + dlls/quartz/Makefile.in, dlls/rasapi32/Makefile.in, + dlls/riched20/Makefile.in, dlls/richedit/Makefile.in, + dlls/rpcrt4/Makefile.in, dlls/rsabase/Makefile.in, + dlls/rsaenh/Makefile.in, dlls/secur32/Makefile.in, + dlls/sensapi/Makefile.in, dlls/serialui/Makefile.in, + dlls/setupapi/Makefile.in, dlls/shdocvw/Makefile.in, + dlls/shell32/Makefile.in, dlls/shfolder/Makefile.in, + dlls/shlwapi/Makefile.in, dlls/snmpapi/Makefile.in, + dlls/sti/Makefile.in, dlls/tapi32/Makefile.in, + dlls/twain/Makefile.in, dlls/unicows/Makefile.in, + dlls/url/Makefile.in, dlls/urlmon/Makefile.in, dlls/user/Makefile.in, + dlls/uxtheme/Makefile.in, dlls/vdmdbg/Makefile.in, + dlls/version/Makefile.in, dlls/win32s/Makefile.in, + dlls/winaspi/Makefile.in, dlls/wined3d/Makefile.in, + dlls/winedos/Makefile.in, dlls/wininet/Makefile.in, + dlls/winmm/Makefile.in, dlls/winnls/Makefile.in, + dlls/winsock/Makefile.in, dlls/winspool/Makefile.in, + dlls/wintab32/Makefile.in, dlls/wintrust/Makefile.in, + dlls/wow32/Makefile.in, dlls/wsock32/Makefile.in, + dlls/wtsapi32/Makefile.in: + Added rules for building import libraries in the individual dll + makefiles, and added support for building a .def.a static import + library too. + + * tools/winegcc/winegcc.c: + For each imported dll, check if there is a static library with the + same base name as the import library, and if yes add it to the library + list. + + * include/winternl.h: Paul Vriens + Remove the not used PROCESS_INFO struct. + + * programs/winecfg/En.rc, programs/winecfg/driveui.c: + James Hawkins + Use a listview instead of a listbox for drives list. + + * tools/wineshelllink: Laurent Blume + Replace the test of the which command for type command to get similar + behaviour on all OSes. + + * dlls/ole32/stg_prop.c: Juan Lang + Correct/improve error checking in IPropertyStorage. + + * server/token.c, tools/wrc/wrctypes.h: + Michael Stefaniuc + Change the type of 1 bit wide bitfields to unsigned. + + * dlls/shell32/shfldr_unixfs.c: + Michael Jung + Always pass fully qualified paths to stat system call. + + * server/named_pipe.c: Eric Pouech + Fixed a wrong ops when creating named pipe client. + + * dlls/shell32/shres.rc: Huw Davies + It makes no sense to have a left pointing arrow as the desktop icon. + Replace it with something more appropiate. + + * dlls/dinput/mouse.c: Lionel Ulmer + - Windows reports 0x80 on pressed buttons not 0xFF + - trace the events reported to the application + + * dlls/comctl32/ipaddress.c: + Felix Nawothnig + Implemented WM_ENABLE. + + * dlls/dsound/buffer.c, dlls/dsound/dsound_private.h, + dlls/dsound/mixer.c: + Robert Reif + Remove dead code and redundant variables from DSOUND_CalcPlayPosition + and callers. + + * programs/notepad/De.rc, programs/regedit/De.rc, + programs/uninstaller/De.rc: + Henning Gerhardt + Update German resource files. + +2005-05-07 Alexandre Julliard + + * tools/winebuild/import.c, tools/winebuild/parser.c, + tools/winebuild/spec32.c, tools/winebuild/winebuild.man.in: + Removed no longer used support for 32-bit register entry points. + + * dlls/Makedll.rules.in, tools/c2man.pl: + William Poetra Yoga H + Support building man pages outside of the source directory. + + * dlls/kernel/heap.c, dlls/kernel/kernel32.spec, + dlls/kernel/krnl386.exe.spec, dlls/kernel/ne_module.c, + dlls/kernel/selector.c, dlls/kernel/thunk.c, dlls/kernel/vxd.c: + Converted all the kernel32 register functions to the + DEFINE_REGS_ENTRYPOINT mechanism. + + * dlls/qcap/Makefile.in, dlls/qcap/capturegraph.c, + dlls/qcap/qcap_main.c: + Rolf Kalbermatter + Implement ICaptureGraphBuilder and IcaptureGraphBuilder2 based on + Maarten Lankhorst's patch. + + * dlls/msvcrt/cppexcept.c, dlls/msvcrt/except.c, + dlls/ntdll/exception.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/rtl.c, + dlls/ntdll/signal_i386.c, dlls/ntdll/signal_powerpc.c, + dlls/ntdll/signal_sparc.c, include/wine/port.h: + Prefix the internal name of all register functions with __regs_ for + better consistency and to make automated checking possible. + + * programs/winecfg/En.rc, programs/winecfg/appdefaults.c, + programs/winecfg/properties.c, programs/winecfg/resource.h: + Get rid of the DOS version combobox, normal users should never need to + change it. + + * dlls/qcap/Makefile.in, dlls/qcap/dllsetup.c, dlls/qcap/dllsetup.h, + dlls/qcap/qcap.spec, dlls/qcap/qcap_main.c, dlls/qcap/qcap_main.h: + Rolf Kalbermatter + Implement DLL registering and unregistering functions, class factory + and server locking based on how it is done with DirectX samples. + + * dlls/x11drv/graphics.c: Rein Klazes + Don't set the pen width to 1 in X11DRV_PolyLine. + + * tools/winebuild/import.c: + Use RaiseException instead of RtlRaiseException for delayed entry + points load failure to avoid creating a dependency on ntdll. + + * dlls/user/win.c, server/user.c: + Treat 0xffff the same as 0 for the handle generation field to avoid + sign extension problems. + + * configure, configure.ac, include/config.h.in, libs/port/futimes.c: + Robert Lunnon + Implement futimes for Solaris using futimesat. + + * dlls/ntdll/time.c: Francois Gouget + Add the 'Western European Summer Time' (WEST) timezone (reported by + José Melo). + + * programs/winemenubuilder/winemenubuilder.c: + Francois Gouget + winemenubuilder.c is the only Wine source file checking for + HAVE_STRING_H. Remove that check for consistency. + + * programs/winecfg/De.rc, programs/winecfg/En.rc, + programs/winecfg/driveui.c, programs/winecfg/resource.h: + Michael Jung + The unixfs extension doesn't have a distinguished '/' node anymore. + Moved UI string into the resources. + + * dlls/shell32/shfldr_unixfs.c: Robert Lunnon + Make references to NAME_MAX refer to PATH_MAX instead. + + * Make.rules.in, dlls/Makedll.rules.in, dlls/Makefile.in, + dlls/Maketest.rules.in, dlls/advapi32/.cvsignore, + dlls/advpack/.cvsignore, dlls/amstream/.cvsignore, + dlls/atl/.cvsignore, dlls/avicap32/.cvsignore, + dlls/avifil32/.cvsignore, dlls/cabinet/.cvsignore, + dlls/capi2032/.cvsignore, dlls/cards/.cvsignore, + dlls/cfgmgr32/.cvsignore, dlls/comcat/.cvsignore, dlls/make_dlls, + dlls/comctl32/.cvsignore, dlls/commdlg/.cvsignore, + dlls/crtdll/.cvsignore, dlls/crypt32/.cvsignore, + dlls/cryptdll/.cvsignore, dlls/ctl3d/.cvsignore, + dlls/d3d8/.cvsignore, dlls/d3d9/.cvsignore, dlls/d3dim/.cvsignore, + dlls/d3drm/.cvsignore, dlls/d3dx8/.cvsignore, dlls/d3dxof/.cvsignore, + dlls/dbghelp/.cvsignore, dlls/dciman32/.cvsignore, + dlls/ddraw/.cvsignore, dlls/devenum/.cvsignore, + dlls/dinput/.cvsignore, dlls/dinput8/.cvsignore, + dlls/dmband/.cvsignore, dlls/dmcompos/.cvsignore, + dlls/dmime/.cvsignore, dlls/dmloader/.cvsignore, + dlls/dmscript/.cvsignore, dlls/dmstyle/.cvsignore, + dlls/dmsynth/.cvsignore, dlls/dmusic/.cvsignore, + dlls/dmusic32/.cvsignore, dlls/dplay/.cvsignore, + dlls/dplayx/.cvsignore, dlls/dpnet/.cvsignore, + dlls/dpnhpast/.cvsignore, dlls/dsound/.cvsignore, + dlls/dswave/.cvsignore, dlls/dxdiagn/.cvsignore, dlls/gdi/.cvsignore, + dlls/glu32/.cvsignore, dlls/glut32/.cvsignore, + dlls/iccvid/.cvsignore, dlls/icmp/.cvsignore, + dlls/imagehlp/.cvsignore, dlls/imm32/.cvsignore, + dlls/iphlpapi/.cvsignore, dlls/itss/.cvsignore, + dlls/kernel/.cvsignore, dlls/lzexpand/.cvsignore, + dlls/mapi32/.cvsignore, dlls/mlang/.cvsignore, dlls/mpr/.cvsignore, + dlls/msacm/.cvsignore, dlls/mscms/.cvsignore, dlls/msdmo/.cvsignore, + dlls/mshtml/.cvsignore, dlls/msi/.cvsignore, dlls/msimg32/.cvsignore, + dlls/msnet32/.cvsignore, dlls/msrle32/.cvsignore, + dlls/msvcrt/.cvsignore, dlls/msvcrt20/.cvsignore, + dlls/msvcrt40/.cvsignore, dlls/msvcrtd/.cvsignore, + dlls/msvidc32/.cvsignore, dlls/msvideo/.cvsignore, + dlls/mswsock/.cvsignore, dlls/netapi32/.cvsignore, + dlls/newdev/.cvsignore, dlls/ntdll/.cvsignore, + dlls/odbc32/.cvsignore, dlls/ole32/.cvsignore, + dlls/oleacc/.cvsignore, dlls/oleaut32/.cvsignore, + dlls/olecli/.cvsignore, dlls/oledlg/.cvsignore, + dlls/olepro32/.cvsignore, dlls/olesvr/.cvsignore, + dlls/opengl32/.cvsignore, dlls/powrprof/.cvsignore, + dlls/psapi/.cvsignore, dlls/qcap/.cvsignore, dlls/quartz/.cvsignore, + dlls/rasapi32/.cvsignore, dlls/riched20/.cvsignore, + dlls/richedit/.cvsignore, dlls/rpcrt4/.cvsignore, + dlls/rsabase/.cvsignore, dlls/rsaenh/.cvsignore, + dlls/secur32/.cvsignore, dlls/sensapi/.cvsignore, + dlls/serialui/.cvsignore, dlls/setupapi/.cvsignore, + dlls/shdocvw/.cvsignore, dlls/shell32/.cvsignore, + dlls/shfolder/.cvsignore, dlls/shlwapi/.cvsignore, + dlls/snmpapi/.cvsignore, dlls/sti/.cvsignore, dlls/tapi32/.cvsignore, + dlls/twain/.cvsignore, dlls/unicows/.cvsignore, dlls/url/.cvsignore, + dlls/urlmon/.cvsignore, dlls/user/.cvsignore, + dlls/uxtheme/.cvsignore, dlls/vdmdbg/.cvsignore, + dlls/version/.cvsignore, dlls/win32s/.cvsignore, + dlls/winaspi/.cvsignore, dlls/wined3d/.cvsignore, + dlls/winedos/.cvsignore, dlls/wininet/.cvsignore, + dlls/winmm/.cvsignore, dlls/winnls/.cvsignore, + dlls/winsock/.cvsignore, dlls/winspool/.cvsignore, + dlls/wintab32/.cvsignore, dlls/wintrust/.cvsignore, + dlls/wow32/.cvsignore, dlls/wsock32/.cvsignore, + dlls/wtsapi32/.cvsignore: + Added rules to build import libraries in the individual dll makefiles. + Generate import libraries with the right name right away instead of + using an intermediate .spec.def file. + + * dlls/x11drv/keyboard.c: Robert Lunnon + Avoid passing NULL buffer elements and status pointers to + XmbLookupString. + + * dlls/winsock/socket.c: Robert Lunnon + Added a conditionally compiled definition of INADDR_NONE for platforms + that don't define it. + + * dlls/ddraw/ddraw/user.c: Lionel Ulmer + '0' means 'default refresh rate' and not a real refresh rate of '0'. + + * dlls/winmm/wineaudioio/audio.c: Robert Lunnon + Fix segmentation fault caused by incorrect referencing of client audio + format specifications array. + + * dlls/shell32/regsvr.c, dlls/shell32/shfldr_unixfs.c: + Michael Jung + Make the root of the shell extension map to the root of the unix + filesystem. + + * dlls/ntdll/file.c: Robert Lunnon + Implement NtQueryVolumeInformation for Solaris. + + * server/mailslot.c: Robert Lunnon + Include on platforms that support it. + + * programs/notepad/dialog.c: Kevin Koltzau + Handle notepad log feature. + + * programs/notepad/En.rc, programs/notepad/rsrc.rc: + Kevin Koltzau + Add a few missing accelerators. + + * dlls/msi/record.c: Aric Stewart + Add a missing msiobj_release that was resulting in a leaked object + with each MsiCreateRecord call. + + * dlls/msi/tests/db.c: Aric Stewart + Correct a missing MsiCloseHandle(). + + * dlls/quartz/enummedia.c: Maarten Lankhorst + Fixed two small memory leaks. + + * dlls/ole32/tests/stg_prop.c: + Stefan Leichter + Make ole32 tests loadable on NT4. + +2005-05-06 Alexandre Julliard + + * dlls/Makefile.in, dlls/wineps/.cvsignore, dlls/wineps/Makefile.in, + dlls/wineps/wineps.drv.spec, dlls/wineps/wineps.spec, + dlls/winspool/info.c: + Renamed wineps.dll to wineps.drv for consistency. + + * dlls/wineps/driver.c, dlls/wineps/init.c, dlls/wineps/psdrv.h: + Store the module instance we get in DllMain to avoid extra LoadLibrary + calls. + + * dlls/Makefile.in, dlls/d3d8/d3d8_main.c, dlls/d3d9/d3d9_main.c, + dlls/ddraw/main.c, dlls/gdi/driver.c, dlls/imm32/imm.c, + dlls/make_dlls, dlls/opengl32/wgl.c, dlls/ttydrv/.cvsignore, + dlls/ttydrv/Makefile.in, dlls/ttydrv/ttydrv.spec, + dlls/ttydrv/winetty.drv.spec, dlls/user/user_main.c, + dlls/wined3d/wined3d_main.c, dlls/wintab32/wintab32.c, + dlls/x11drv/.cvsignore, dlls/x11drv/Makefile.in, + dlls/x11drv/winex11.drv.spec, dlls/x11drv/x11drv.spec, + documentation/samples/config: + Renamed ttydrv and x11drv to winetty.drv and winex11.drv respectively + to follow the namespace conventions and make it clear that they are + drivers and not dlls. + Moved the graphics driver configuration to HKLM\Software\Wine\Drivers. + + * tools/winedump/output.c: + Removed a bunch of obsolete makefile hacking sed code. + + * dlls/dsound/dsound.c, dlls/dsound/tests/dsound.c, + dlls/dsound/tests/dsound8.c: + Robert Reif + Move initialization to IDirectSound_Initialize. + Fix error paths to handle a failed IDirectSound_Initialize. + Add tests for IDirectSound_Initialize. + + * dlls/shell32/brsfolder.c: Michael Jung + Return a cloned PIDL by SHBrowseForFolder to avoid heap corruption. + + * dlls/shell32/folders.c: Michael Jung + Display a drive icon for the unix root directory. + + * dlls/winmm/time.c: Robert Reif + Change FIXME to WARN. + + * dlls/crtdll/crtdll_main.c, dlls/dbghelp/elf_module.c, + dlls/dbghelp/stabs.c, dlls/gdi/freetype.c, dlls/kernel/comm.c, + dlls/kernel/kernel_main.c, dlls/kernel/oldconfig.c, + dlls/kernel/vxd.c, dlls/msacm/winemp3/common.c, dlls/ntdll/cdrom.c, + dlls/ntdll/directory.c, dlls/ntdll/path.c, dlls/ntdll/server.c, + dlls/shell32/shfldr_unixfs.c, dlls/winaspi/winaspi16.c, + dlls/winaspi/winaspi32.c, dlls/winedos/int21.c, + dlls/winedos/module.c, dlls/winedos/ppdev.c, dlls/winedos/vxd.c, + dlls/winsock/socket.c, loader/preloader.c, tools/winapi/nativeapi.pm, + tools/winapi/winapi_check: + Francois Gouget + Fix nativeapi.pm so it knows about AC_HEADER_STAT(). + Make the error message about unexpected '#ifdef HAVE_XXX' clearer. + Protect sys/stat.h #includes with the corresponding '#ifdef HAVE_XXX' + check. + + * dlls/Makedll.rules.in, programs/Makeprog.rules.in, + tools/winebuild/build.h, tools/winebuild/import.c, + tools/winebuild/main.c, tools/winebuild/utils.c, + tools/winebuild/winebuild.man.in: + Added support in winebuild for specifying import libraries directly on + the command line without the -l option. + Changed the -d option to only mark the library as delayed, the actual + loading is now done separately. + + * dlls/comctl32/comctl32undoc.c, dlls/comctl32/hotkey.c, + dlls/comctl32/imagelist.c, dlls/comctl32/listview.c, + dlls/comctl32/toolbar.c, dlls/dsound/buffer.c, dlls/dsound/primary.c, + dlls/gdi/bitblt.c, dlls/gdi/palette.c, dlls/kernel/profile.c, + dlls/kernel/tests/file.c, dlls/kernel/volume.c, + dlls/kernel/wowthunk.c, dlls/ntdll/rtlstr.c, dlls/odbc32/proxyodbc.c, + dlls/opengl32/wgl_ext.c, dlls/shell32/shell32_En.rc, + dlls/shell32/shlfileop.c, dlls/shell32/tests/shlfileop.c, + dlls/shlwapi/reg.c, dlls/winspool/info.c, dlls/x11drv/palette.c, + documentation/configuring.sgml, documentation/debugging.sgml, + documentation/opengl.sgml, documentation/winedev-coding.sgml, + documentation/winedev-otherdebug.sgml, + documentation/winelib-mfc.sgml, programs/notepad/En.rc, + programs/wineconsole/wineconsole.c, tools/winegcc/utils.c: + Francois Gouget + Assorted spelling fixes. + + * dlls/setupapi/misc.c, dlls/setupapi/setupapi.spec, + include/setupapi.h, include/winnt.h: + Eric Kohl + Implement CaptureAndConvertAnsiArg, CaptureStringArg, + OpenAndMapForRead, RetreiveFileSecurity, StampFileSecurity, + TakeOwnershipOfFile, and UnmapAndCloseFile. + + * dlls/quartz/filtergraph.c, dlls/quartz/pin.c: + Maarten Lankhorst + Fixed a dozen of reference (and some memory) leaks. + Implemented filtergraph_pause/stop. + + * dlls/quartz/enummedia.c, dlls/quartz/quartz_private.h: + Maarten Lankhorst + Fixed {Copy/Delete/Free}MediaType functions to show proper behaviour. + Fixed EnumMediaTypes to copy pbFormat too. + Added FreeMediaType. + + * tools/winapi/winapi_check: Francois Gouget + HAVE_V4L2 is not an autoconf define so tell winapi_check not to + complain complain about it. + + * dlls/rpcrt4/rpcss_np_client.c: Hartmut Birr + Clean up if named pipe is not available. + + * dlls/msi/registry.c, dlls/x11drv/opengl.c: + Francois Gouget + Tweak the documentation to make winapi_check happy. + + * dlls/urlmon/urlmon_main.c, include/urlmon.idl, + tools/winapi/win32.api: + Francois Gouget + Update win32.api to match the current sources. + Declare CoGetClassObjectFromURL() in urlmon.h. + + * dlls/ole32/ole32.spec, dlls/ole32/storage32.c: + Matthew Mastracci + Replace stub entry for StgOpenStorageEx with call to StgOpenStorage. + +2005-05-05 Alexandre Julliard + + * server/registry.c: Robert Shearman + - Fix access rights for RegOpenKeyEx and RegCreateKeyEx calls. + - Add privilege checks for RegLoadKey, RegUnloadKey & RegSaveKey + calls. + + * dlls/user/painting.c: + Don't retrieve a window DC in GetUpdateRect if there is nothing to + erase, to avoid setting a null update region in an owned DC. + Avoid potential double delete of the update region on return from + send_erase. + + * dlls/msvcrt/file.c: + Return ENOENT rather than EBADF from MSVCRT_fopen() when file doesn't + exist. + + * dlls/advapi32/registry.c: Robert Shearman + Fix RegDeleteKey{A,W} to open the specified key with the DELETE access + right. + + * tools/winegcc/winegcc.c: + output_name already contains .exe extension, don't add it again for -F + option. + + * dlls/ole32/storage32.c, include/objbase.h: + Matthew Mastracci + Replace StgCreateStorageEx stub with call to StgCreateDocfile and add + required STGFMT_* enumerations. + + * dlls/gdi/bitblt.c: Rein Klazes + In MaskBlt delete correct bitmap. + + * dlls/user/winproc.c, include/wine/winuser16.h: + Rein Klazes + Add 16<->32 bit message mappings for WM_COPYDATA messages. + + * dlls/winedos/module.c: Rein Klazes + - In MZ_DoLoadImage if an environment segment is specified in the + parameter block, use that and do not inherit from the calling + process. + - Call FreeEnvironmentStrings when the strings are no longer used. + + * dlls/shell32/shfldr_fs.c: Michael Jung + Fixed GetDisplayNameOf method to not depend on incorrect behaviour + regarding the SHGDN_INFOLDER flag. + + * dlls/shell32/shfldr_mycomp.c: + Michael Jung + Fixed MyComputer's GetDisplayNameOf method. + + * dlls/dinput/mouse.c: Lionel Ulmer + - do not flush the buffer when the application only wants to peek the + number of elements in the queue + - trace the GetDeviceState values before they are reset + + * dlls/urlmon/urlmon.spec, dlls/urlmon/urlmon_main.c: + Christian Costa + Added stub implementation for CoGetClassObjectFromURL. + + * dlls/urlmon/umon.c: Troy Rollo + Correct bug truncating downloaded files to 4096 bytes. + + * dlls/quartz/filtergraph.c, dlls/quartz/main.c, + dlls/quartz/quartz_private.h, dlls/quartz/regsvr.c: + Christian Costa + Forward CLSID_FilterGraphNoThread to CLSID_FilterGraph. + + * dlls/dbghelp/elf_module.c: Emmanuel Maillard + Fix compile on non-ELF host. + + * dlls/dinput/device.c: Lionel Ulmer + - more pretty print for the types flag + - more Windows-aligned check for object instances + + * dlls/winsock/socket.c: Marcus Meissner + Initialize iosb. + + * dlls/ntdll/version.c: Ivan Leo Puoti + Set win2k3 service pack number to 1. + + * dlls/ntdll/signal_powerpc.c: Emmanuel Maillard + - Fix NTDLL_wait_for_multiple_objects call in usr1_handler. + - Fix an error due to "invalid lvalue in assignment" with gcc 4 on + Darwin 8.0. + +2005-05-04 Alexandre Julliard + + * tools/winapi/config.pm, tools/winapi/make_parser.pm, + tools/winapi/modules.pm, tools/winapi/nativeapi.pm, + tools/winapi/setup.pm, tools/winapi/winapi_extract, + tools/winapi/winapi_fixup, tools/winapi/winapi_test: + Get rid of the winapi_check_dir config parameter. + + * dlls/comctl32/comboex.c: + Felix Nawothnig + Set iItem to index before notifying callback items. + + * dlls/msi/package.c: Marcus Meissner + Set PhysicalMemory property from system data. + + * dlls/urlmon/Makefile.in, dlls/urlmon/umon.c, dlls/urlmon/umstream.c, + dlls/urlmon/urlmon_main.h: + Troy Rollo + Implement URLMonikerImpl_BindToStorage. + + * dlls/wininet/urlcache.c: Troy Rollo + Create URL Cache if it does not already exist. + + * Make.rules.in, tools/Makefile.in, tools/winapi/modules.pm, + tools/winapi/nativeapi.dat, tools/winapi/nativeapi.pm, + tools/winapi/preprocessor.pm, tools/winapi/setup.pm, + tools/winapi/winapi_c_parser.pm, tools/winapi/winapi_check, + tools/winapi/winapi_documentation.pm, + tools/winapi/winapi_function.pm, tools/winapi/winapi_global.pm, + tools/winapi/winapi_local.pm, tools/winapi/winapi_parser.pm: + Hans Leidekker + Move all files from winapi_check/ to winapi/, and remove references to + winapi_check directory. Merge winapi_check programs. + + * dlls/msi/msi_Fr.rc, dlls/oleaut32/oleaut32_Fr.rc, + dlls/oledlg/oledlg_Fr.rc, dlls/shdocvw/Fr.rc, programs/taskmgr/Fr.rc, + programs/winecfg/Fr.rc: + Vincent Béron + Use SUBLANG_NEUTRAL for French resources. + + * programs/winecfg/Cs.rc, programs/winecfg/De.rc, + programs/winecfg/En.rc, programs/winecfg/Es.rc, + programs/winecfg/Fr.rc, programs/winecfg/It.rc, + programs/winecfg/Nl.rc, programs/winecfg/Pt.rc, + programs/winecfg/Ru.rc, programs/winecfg/Si.rc: + James Hawkins + Enlarge the license text control length. + + * dlls/shell32/brsfolder.c: Mike McCormack + Remove static variables in SHBrowseForFolder implementation. + + * programs/winecfg/drive.c: James Hawkins + Remove the corresponding registry entry when deleting a drive. + + * programs/winecfg/appdefaults.c: James Hawkins + Don't add the same program in AppDefaults more than once. + + * dlls/setupapi/setupapi.spec, dlls/setupapi/stubs.c: + Hans Leidekker + Stub implementation for SetupCopyOEMInfW. + + * dlls/kernel/version.rc: Hans Leidekker + Bump version number to XP SP2. + + * programs/winefile/winefile.c: Martin Fuchs + Implement owner drawn context menus. + + * dlls/dsound/propset.c: Robert Reif + Set driver type properly. + + * include/axextend.idl: Maarten Lankhorst + Added IAMVideoProcAmp. + + * dlls/dinput/mouse.c: James Dean Anderson + Report an error if trying to get data from an unacquired mouse. + + * dlls/ntdll/time.c: Ivan Wong + Added Hong Kong Standard Time (HKT). + + * dlls/user/edit.c: Ulrich Czekalla + Let the default winproc handle WM_MOUSEACTIVATE. + +2005-04-28 Alexandre Julliard + + * dlls/opengl32/Makefile.in, dlls/opengl32/make_opengl, + dlls/opengl32/opengl_ext.h, dlls/opengl32/opengl_norm.c, + dlls/opengl32/wgl.c, dlls/opengl32/wgl.h, dlls/opengl32/wgl_ext.c, + dlls/opengl32/wgl_ext.h: + Raphael Junqueira + - implement wglGetCurrentReadDCARB, wglMakeContextCurrentARB on + openGL32 (wgl_ext) + - add code to disable some openGL extensions support using wine + registry key HKLM\Software\Wine\OpenGL\DisabledExtensions (list + separated by spaces) + - valid/robust implementation of wglChoosePixelFormatARB and + wglGetPixelFormatAttribivARB (wgl_ext) + + * dlls/x11drv/opengl.c, dlls/x11drv/xrandr.c: + Raphael Junqueira + - valid implementation of X11DRV_ChoosePixelFormat using GLX1.3 API + (ie. using real card caps and not ugly way using visuals array) to + be compatible with opengl32 pixel formats (wgl*PixelFormat* APIs) as + they need to be the same + - add more traces to xrandr + + * dlls/msi/action.c, dlls/msi/msi.c, dlls/msi/registry.c: + Aric Stewart + Correct user component publication. + Implement MsiEnumComponentQualifiers. + + * dlls/winsock/socket.c: Marcus Meissner + Fixed stack overwrite by using sizeof(WS_sockaddr_ipx). + + * dlls/shell32/brsfolder.c: Mike McCormack + Split up the window procedure. + + * dlls/user/input.c, dlls/user/message.c, + include/wine/server_protocol.h, server/protocol.def, server/queue.c, + server/request.h, server/trace.c: + Mike McCormack + Implemented GetLastInputInfo. + + * dlls/wined3d/directx.c: Raphael Junqueira + - implement memory access APIs to VertexBuffers + - more valid implementation for IWineD3DImpl_Check* APIs (not more + S_OK for all cases) + + * include/wine/unicode.h: Jeff Latimer + Define strncpyW to ensure that users know why it is not present. + + * dlls/msi/msi.c: Aric Stewart + Implement MsiQueryFeatureStateW. + +2005-04-27 Alexandre Julliard + + * dlls/user/misc.c, dlls/user/user_main.c, windows/user.c: + Moved the USER syslevel to dlls/user/user_main.c. + Moved a bunch of stubs to dlls/user/misc.c. + + * dlls/kernel/dosmem.c, dlls/kernel/kernel32.spec, + dlls/kernel/kernel_main.c, dlls/winedos/int31.c, + dlls/winedos/module.c, include/miscemu.h: + Eric Pouech + - delayed initialisation of BIOS and SYSTEM information until someone + actually needs it + - now using some manifest constants to make code clearer + + * dlls/devenum/Makefile.in, dlls/devenum/createdevenum.c, + dlls/devenum/devenum_private.h: + Maarten Lankhorst + Added the video input device category. + + * dlls/user/combo.c, dlls/user/cursoricon.c, dlls/user/defwnd.c, + dlls/user/edit.c, dlls/user/hook.c, dlls/user/hook16.c, + dlls/user/input.c, dlls/user/listbox.c, dlls/user/mdi.c, + dlls/user/message.c, dlls/user/message.h, dlls/user/msg16.c, + dlls/user/scroll.c, dlls/user/spy.c, dlls/user/user_main.c, + dlls/user/user_private.h, dlls/user/win.c, dlls/user/winpos.c, + dlls/user/winproc.c, windows/user.c: + Moved remaining messaging definitions to user_private.h and removed + message.h. + + * dlls/msi/action.c, dlls/msi/custom.c, dlls/msi/dialog.c, + dlls/msi/msipriv.h: + Mike McCormack + Make sure that dialogs are only created and destroyed in a single + thread. + + * configure, configure.ac, dlls/avicap32/Makefile.in, + dlls/avicap32/avicap32_main.c, include/config.h.in: + Maarten Lankhorst + Implemented capGetDriverDescription. + + * dlls/winmm/mciavi/mciavi.c, dlls/winmm/mciseq/mcimidi.c, + dlls/winmm/mciwave/mciwave.c, dlls/winmm/mmsystem.c, + dlls/winmm/playsound.c, dlls/winmm/winealsa/audio.c, + dlls/winmm/winealsa/midi.c, dlls/winmm/winmm.c, + dlls/winmm/winearts/audio.c, dlls/winmm/wineaudioio/audio.c, + dlls/winmm/winenas/audio.c: + Mike McCormack + Make multimedia threads high priority. + + * dlls/advpack/advpack.c, dlls/advpack/tests/advpack.c: + Sami Aario + Added initial version of Delnode plus some tests. + + * dlls/kernel/task.c, dlls/ntdll/thread.c, dlls/user/Makefile.in, + dlls/user/cursoricon.c, dlls/user/hook.c, dlls/user/hook16.c, + dlls/user/input.c, dlls/user/message.c, dlls/user/message.h, + dlls/user/user16.c, dlls/user/user_main.c, dlls/user/user_private.h, + dlls/user/wnd16.c, include/thread.h, windows/queue.c: + Removed the MESSAGEQUEUE structure, and store the corresponding + information directly in the TEB, in the Win32ClientInfo field. + + * include/winternl.h: Added proper names for the remaining TEB fields. + + * dlls/winmm/mci.c, dlls/winmm/mmio.c, dlls/winmm/mmsystem.c, + dlls/winmm/playsound.c, dlls/winmm/time.c, dlls/winmm/winemm.h, + dlls/winmm/winmm.c: + Mike McCormack + Make WINMM_IData statically allocated. + + * dlls/d3d8/drawprim.c: Raphael Junqueira + Fix crash on drawStridedSlow. + + * dlls/shell32/shfldr_unixfs.c: Gerald Pfeifer + Include to get a definition of NAME_MAX. + + * dlls/msi/msi.c: Aric Stewart + Correct a leaking hkey handle. + +2005-04-26 Alexandre Julliard + + * programs/taskmgr/graphctl.c, programs/winemine/main.c, + programs/winhelp/hlp2sgml.c, programs/winhelp/hlpfile.c: + Removed a few more strncpy calls. + + * server/queue.c, server/user.h, server/window.c: + Make sure a thread has a queue as soon as it creates a window. + + * dlls/msi/msi.c: Aric Stewart + Expand some handling of special properties in MsiGetProductInfo. + + * dlls/msi/database.c, dlls/msi/msi.spec: + Mike McCormack + Declare MsiExportDatabase* in the spec file, and fix a typo. + + * dlls/winmm/mciavi/info.c: Christian Costa + Fixed flags handling in MCIAVI_mciInfo. + + * dlls/user/input.c, dlls/user/message.c, windows/queue.c: + Moved some messaging and input functions to message.c and input.c + respectively. + + * dlls/user/tests/win.c, dlls/x11drv/window.c: + Ulrich Czekalla + SetParent should not remove menu from non-child windows. + + * dlls/user/combo.c: Huw Davies + The ansi version of CB_ADDSTRING shouldn't overwrite the string if + converting case. + + * dlls/devenum/mediacatenum.c: + Maarten Lankhorst + Fixed a reference leak. + +2005-04-25 Alexandre Julliard + + * include/winbase.h: + Define strncpy to an error to make sure it doesn't creep back in. + + * dlls/user/Makefile.in, dlls/user/painting.c, windows/scroll.c: + Moved the ScrollWindow and ScrollDC functions to dlls/user/painting.c, + and removed windows/scroll.c. + + * dlls/gdi/dc.c: Maxime Bellengé + Prevent CreateDCA from crashing if a bad lpInitData parameter is + provided. + + * dlls/ntdll/file.c: Ivan Leo Puoti + Add parameter checking to NtReadFile/NtWriteFile. + + * dlls/msvcrt/mbcs.c, dlls/ntdll/file.c, include/wine/library.h, + libs/wine/debug.c, libs/wine/loader.c, tools/sfnt2fnt.c, + tools/winedump/dump.c: + Remove a few more instances of strncpy. + + * dlls/user/Makefile.in, dlls/user/class.c, dlls/user/clipboard.c, + dlls/user/cursoricon.c, dlls/user/defdlg.c, dlls/user/defwnd.c, + dlls/user/dialog.c, dlls/user/input.c, dlls/user/mdi.c, + dlls/user/msgbox.c, dlls/user/nonclient.c, dlls/user/spy.c, + dlls/user/win.c, dlls/user/winhelp.c, dlls/user/winpos.c, + dlls/user/winproc.c, windows/class.c, windows/clipboard.c, + windows/cursoricon.c, windows/defdlg.c, windows/defwnd.c, + windows/dialog.c, windows/input.c, windows/mdi.c, windows/msgbox.c, + windows/nonclient.c, windows/spy.c, windows/win.c, windows/winhelp.c, + windows/winpos.c, windows/winproc.c: + Moved most files from the windows directory to dlls/user. + + * dlls/shell32/shell32_De.rc, dlls/shell32/shell32_En.rc, + dlls/shell32/shfldr_unixfs.c, dlls/shell32/shresdef.h: + Michael Jung + Support for regular files (as opposed to directories). + + * dlls/quartz/dsoundrender.c: Christian Costa + Improved errors handling a bit in dsound renderer. + + * include/msvcrt/conio.h, include/msvcrt/io.h, + include/msvcrt/process.h: + Marcus Meissner + gcc4 alias fixes. + + * dlls/ddraw/ddraw/hal.c, dlls/dinput/device.c, + dlls/msacm/tests/msacm.c: + Marcus Meissner + Fixed 3 memset()s which used the wrong size (too large). + +2005-04-24 Alexandre Julliard + + * dlls/kernel/tests/.cvsignore, dlls/kernel/tests/Makefile.in, + dlls/kernel/tests/sync.c: + Mike McCormack + Tests for SignalObjectAndWait. + + * dlls/kernel/sync.c: Mike McCormack + Implemented SignalObjectAndWait. + + * dlls/ntdll/ntdll_misc.h, dlls/ntdll/signal_i386.c, dlls/ntdll/sync.c, + include/wine/server_protocol.h, include/winternl.h, server/atom.c, + server/change.c, server/console.c, server/debugger.c, server/event.c, + server/fd.c, server/file.c, server/handle.c, server/handle.h, + server/hook.c, server/mailslot.c, server/mapping.c, server/mutex.c, + server/named_pipe.c, server/object.c, server/object.h, + server/process.c, server/protocol.def, server/queue.c, + server/registry.c, server/request.c, server/semaphore.c, + server/serial.c, server/signal.c, server/snapshot.c, server/sock.c, + server/thread.c, server/timer.c, server/token.c, server/trace.c: + Mike McCormack + Implemented NtSignalAndWaitForSingleObject. + + * dlls/winmm/tests/timer.c: Robert Reif + Remove priority boost stuff. + + * dlls/ddraw/ddraw/user.c: Dylan Taft + Set display frequency too in SetDisplayMode. + + * tools/wineinstall: Paul Vriens + --update is no longer needed with wineprefixcreate. + + * dlls/ole32/storage32.c, dlls/ole32/storage32.h: + Juan Lang + Define and use endian conversion macros for big-endian machines. + +2005-04-23 Alexandre Julliard + + * dlls/msvcrt/msvcrt.spec, dlls/msvcrt/time.c: + Juan Lang + Export _tzname, expected by Mozilla. + + * dlls/advapi32/tests/crypt.c: + Stefan Leichter + Excluded tests crashing on NT4 from compiling. + + * dlls/ole32/stg_prop.c, dlls/ole32/tests/stg_prop.c: + Juan Lang + - convert strings between property storage's code page and system code + page + - add tests for setting code page + - fix tests and behavior to match WinXP + + * dlls/winmm/tests/timer.c, dlls/winmm/time.c: + Robert Reif + Set thread priority for timer thread. + Add timer thread priority test. + +2005-04-22 Alexandre Julliard + + * dlls/shell32/shfldr_unixfs.c: + Michael Jung + Use the shell32 typical binary format for ITEMIDLISTs. + + * dlls/comctl32/tests/dpa.c: + Stefan Leichter + Import DPA_Search by ordinal like other DPA functions. + + * tools/winapi/win32.api: Francois Gouget + Add a powrprof section. + Update win32.api to match the current source. + + * dlls/advapi32/security.c: Robert Shearman + Implement PrivilegeCheck. + + * dlls/ntdll/nt.c, dlls/ntdll/ntdll.spec, + include/wine/server_protocol.h, include/winnt.h, include/winternl.h, + server/object.h, server/process.c, server/protocol.def, + server/request.h, server/security.h, server/thread.c, + server/thread.h, server/token.c, server/trace.c: + Robert Shearman + - Clean up well-known privileges. + - Implement checking tokens for privileges in the server. + - Implement NtPrivilegeCheck. + + * dlls/shell32/brsfolder.c: Michael Jung + Fixed incorrect IShellFolder::EnumOjects API usage. + + * dlls/x11drv/dib.c: Huw Davies + If XShmAttach fails then reset shmid to -1 so that we don't try to use + it later. + + * dlls/shell32/shelllink.c: Mike McCormack + MSI advertised shortcuts don't require a product ID. + + * dlls/ole32/tests/stg_prop.c: + Stefan Leichter + Make ole32 tests loadable on NT4. + + * dlls/winmm/winealsa/audio.c: + Alex Villacís Lasso + Perform one more commit in ALSA non-emulation if there are still + frames to be transmitted. + + * dlls/oleaut32/olepicture.c: + Alex Villacís Lasso + - Fix leftover negative sign in height parameter for transparent + bitmap. + - Properly announce whether bitmap is transparent in get_Attributes. + - GIF transparency is now palette-index based, instead of RGB based. + - Keep original bitmap and XOR mask separate, so that get_Handle + returns original bitmap. + + * dlls/msi/msi.c: Francois Gouget + Tweak the API documentation to silence winapi_check warnings. + + * dlls/atl/atl_main.c, dlls/atl/atlbase.h, tools/winapi/win32.api: + Francois Gouget + Add a definition for _ATL_REGMAP_ENTRY in atlbase.h. + Fix the prototype of AtlModuleUpdateRegistryFromResourceD() so it uses + the right pointer types. + +2005-04-21 Alexandre Julliard + + * dlls/x11drv/clipboard.c, dlls/x11drv/x11drv.h, + dlls/x11drv/x11drv_main.c, documentation/samples/config: + Moved the UsePrimary config parameter to the x11drv section, renamed + as UsePrimarySelection. + + * dlls/msi/msi.c: Aric Stewart + Fix for the return codes for the Qualified component calls. They are + not INSTALLSTATEs but rather success values. + + * dlls/advapi32/security.c, dlls/ntdll/time.c, dlls/ntdll/wcstring.c, + dlls/wininet/ftp.c, dlls/wininet/utility.c, include/wine/unicode.h: + Get rid of the remaining calls to strncpyW, and remove that function + from wine/unicode.h. + + * dlls/shell32/shell.c: Peter Berg Larsen + Rewritten DoEnvironmentSubst16. + + * dlls/ntdll/nt.c, include/winternl.h: + Paul Vriens + Remove THREAD_INFO struct. + Rename THREADINFO into SYSTEM_THREAD_INFORMATION. + +2005-04-20 Alexandre Julliard + + * DEVELOPERS-HINTS, configure, configure.ac, dlls/Makefile.in, + dlls/powrprof/.cvsignore, dlls/powrprof/Makefile.in, + dlls/powrprof/powrprof.c, dlls/powrprof/powrprof.spec: + Benjamin Cutler + Added partial implementation of powrprof.dll. + + * dlls/user/message.c: + Handle posted internal messages directly in PeekMessageW to avoid + having to return them to the application. + Call NtYieldExecution for nicer behavior when PM_NOYIELD is not + specified. + + * dlls/x11drv/dib.c, dlls/x11drv/x11drv.h: Avoid a compiler warning. + + * dlls/dciman32/dciman_main.c, include/Makefile.in, include/dciddi.h, + include/dciman.h, tools/winapi/win32.api: + Francois Gouget + Fix the DCICreatePrimary() prototype. It's supposed to return an int + so have it return DCI_FAIL_UNSUPPORTED. + Add the needed error codes and the DCISURFACEINFO definition to + dciddi.h. + Add dciman.h and put the function prototypes there. + dciddi.h and dciman.h should be installed with the other Windows + headers. + + * dlls/ntdll/ntdll.spec, dlls/ntdll/ntdll_misc.h, dlls/ntdll/virtual.c: + Remove all traces of the VIRTUAL_SetFaultHandler support. + + * dlls/x11drv/dib.c, dlls/x11drv/x11drv.h: + Dimitrie O. Paun + Use vectored exceptions to get rid of VIRTUAL_SetFaultHandler(). + + * dlls/ole32/ole2.c: Francois Gouget + Specify the proper call convention in the PropSysFreeString() + implementation. + + * DEVELOPERS-HINTS, configure, configure.ac, dlls/kernel/Makefile.in, + dlls/kernel/oldconfig.c, dlls/kernel/process.c, dlls/kernel/volume.c: + Move all the old config conversion code to a new oldconfig.c file, and + get rid of misc/registry.c and the misc directory. + + * dlls/advapi32/crypt.c, dlls/advapi32/security.c, dlls/gdi/palette.c, + dlls/mshtml/main.c, dlls/msi/action.c, dlls/msi/msi.c, + dlls/ole32/ole2.c, dlls/rpcrt4/rpcrt4_main.c, dlls/user/misc.c, + dlls/wininet/ftp.c, dlls/x11drv/xrender.c: + Francois Gouget + Tweak the API documentation to silence winapi_check warnings. + + * tools/wineprefixcreate.in: + Properly support out-of-tree builds (based on patch by Paul Millar). + + * dlls/riched20/editor.c: Phil Krylov + Fixed an error in my previous commit which caused an infinite loop in + IE6 installer. + + * tools/winapi/winapi_fixup_documentation.pm: + Francois Gouget + Try to clarify the 'no translation defined' error. + Remove an unused variable. + + * dlls/msi/tests/suminfo.c: Mike McCormack + Test MsiSummaryInfoGetProperty reading an empty property. + + * dlls/msi/suminfo.c: Mike McCormack + Fix loading of the summary information. + + * dlls/ntdll/server.c, tools/wineprefixcreate.in, tools/winewrapper: + Replace the wineprefixcreate --update option by a --wait option, and + make the non-wait behavior the default. + + * dlls/user/message.c, include/wine/server_protocol.h, + server/protocol.def, server/queue.c, server/trace.c: + Allow nested hardware message processing by storing a unique id in + every message and using it to manage the current queue position. + Better filtering of hardware messages to avoid returning messages that + have no chance to match the filter. + + * server/registry.c: + Load system.reg and userdef.reg at server init time. + + * dlls/gdi/gdiobj.c, dlls/x11drv/brush.c: + Richard Cohen + Dither solid colours on monochrome bitmaps. + + * include/Makefile.in, include/evntrace.h, include/wmistr.h: + Mike McCormack + Added evntrace.h and wmistr.h. + + * include/guiddef.h: Mike McCormack + Define LPCGUID. + + * tools/winapi/win32.api: Francois Gouget + Update win32.api to match the current source. + + * dlls/comctl32/monthcal.c: Duane Clark + Misc rectangle fixes. + The date should be initialized from local time. + + * dlls/kernel/sync.c: Gerald Pfeifer + Fix compilation problem caused by ULONG_MAX. + + * dlls/msi/action.c, dlls/msi/msi.c, dlls/msi/msi.spec, + dlls/msi/msipriv.h, dlls/msi/registry.c: + Aric Stewart + Implement Publish Components in order for MsiGetQualifiedComponent + apis to work. Also implement MsiGetQualifiedComponent, or at least some + of the functionality as it is supposed to install stuff if it is + absent, which it does not do yet. + +2005-04-19 Alexandre Julliard + + * ANNOUNCE, ChangeLog, VERSION, configure: Release 20050419. + +---------------------------------------------------------------- 2005-04-19 Alexandre Julliard * dlls/wtsapi32/wtsapi32.c, dlls/wtsapi32/wtsapi32.spec, diff -urN wine-20050419/DEVELOPERS-HINTS wine-20050524/DEVELOPERS-HINTS --- wine-20050419/DEVELOPERS-HINTS 2005-04-11 14:52:20.000000000 +0200 +++ wine-20050524/DEVELOPERS-HINTS 2005-04-20 21:15:31.000000000 +0200 @@ -109,6 +109,7 @@ olepro32/ - 32 bit OLE 2.0 automation olesvr/ - 16 bit OLE server opengl32/ - OpenGL implementation (graphics) + powrprof/ - Power Management and Profiling psapi/ - Process Status interface qcap/ - DirectShow runtime quartz/ - DirectShow runtime @@ -247,7 +248,6 @@ Note: these directories will ultimately get moved into their respective dlls. - misc/ - KERNEL registry windows/ - USER window management diff -urN wine-20050419/Make.rules.in wine-20050524/Make.rules.in --- wine-20050419/Make.rules.in 2005-03-16 21:02:17.000000000 +0100 +++ wine-20050524/Make.rules.in 2005-05-07 14:39:58.000000000 +0200 @@ -58,7 +58,7 @@ ALLLINTFLAGS = $(INCLUDES) $(DEFS) $(LINTFLAGS) IDLFLAGS = $(INCLUDES) $(DEFS) $(EXTRAIDLFLAGS) MKINSTALLDIRS= $(TOPSRCDIR)/tools/mkinstalldirs -m 755 -WINAPI_CHECK = $(TOPSRCDIR)/tools/winapi_check/winapi_check +WINAPI_CHECK = $(TOPSRCDIR)/tools/winapi/winapi_check WINEWRAPPER = $(TOPSRCDIR)/tools/winewrapper C2MAN = $(TOPSRCDIR)/tools/c2man.pl RUNTEST = $(TOPSRCDIR)/tools/runtest @@ -105,7 +105,7 @@ api_manext = 3w conf_manext = 5 CLEAN_FILES = *.o *.a *.so *.ln *.$(LIBEXT) \\\#*\\\# *~ *% .\\\#* *.bak *.orig *.rej \ - *.flc *.spec.c *.spec.def *.dbg.c *.tab.c *.tab.h @LEX_OUTPUT_ROOT@.c core + *.flc *.spec.c *.dbg.c *.tab.c *.tab.h @LEX_OUTPUT_ROOT@.c core OBJS = $(C_SRCS:.c=.o) $(EXTRA_OBJS) @@ -114,7 +114,7 @@ # Implicit rules -.SUFFIXES: .mc .rc .mc.rc .res .res.o .spec .spec.c .spec.def .idl .tlb .h .ok .sfd .ttf +.SUFFIXES: .mc .rc .mc.rc .res .res.o .spec .spec.c .idl .tlb .h .ok .sfd .ttf .c.o: $(CC) -c $(ALLCFLAGS) -o $@ $< @@ -134,9 +134,6 @@ .spec.spec.c: $(WINEBUILD) $(DEFS) --dll -o $@ --main-module $(MODULE) --export $< -.spec.spec.def: - $(WINEBUILD) -w $(DEFS) --def -o $@ --export $< - .idl.h: $(WIDL) $(IDLFLAGS) -h -H $@ $< diff -urN wine-20050419/README wine-20050524/README --- wine-20050419/README 2005-01-03 15:27:23.000000000 +0100 +++ wine-20050524/README 2005-05-10 15:26:15.000000000 +0200 @@ -19,10 +19,8 @@ ./tools/wineinstall Run programs as "wine [options] program". For more information and -problem resolution, read the rest of this file, the Wine man page, -the files in the documentation directory of the Wine source -(see "DOCUMENTATION"), and especially the wealth of information -found at http://www.winehq.org. +problem resolution, read the rest of this file, the Wine man page, and +especially the wealth of information found at http://www.winehq.org. 3. REQUIREMENTS @@ -90,9 +88,6 @@ If you want CUPS printing support, please install both cups and cups-devel packages. -For requirements in case you intend to build the documentation yourself, -see "DOCUMENTATION" section. - 4. COMPILATION In case you chose to not use wineinstall, run the following commands @@ -129,17 +124,8 @@ first. Try either "dpkg -r wine" or "rpm -e wine" or "make uninstall" before installing. -If you want to read the documentation supplied with the Wine source, -see the "DOCUMENTATION" section. - -Wine requires a configuration file named named "config" in your -~/.wine directory. The format of this file is explained in the config file -man page (documentation/wine.conf.man). -The file documentation/samples/config contains an example configuration file -which has to be adapted and copied to the location mentioned above. - -See the Support area at http://www.winehq.org/ for further -configuration hints. +See the Support area at http://www.winehq.org/ for configuration +hints. In case of library loading errors (e.g. "Error while loading shared libraries: libntdll.so"), make sure @@ -180,19 +166,7 @@ can at least partially be fixed by using http://home.nexgo.de/andi.mohr/download/decorrupt_explorer -7. DOCUMENTATION - -Some documentation (various Wine Guides etc.) can be found in the -documentation/ directory (apart from also being available on WineHQ). - -If you want to process the SGML files in there, then you can run "make doc" -in the documentation/ directory. -Doing so requires the sgml tools package (for db2html, db2ps, db2pdf) named: -Debian: docbook-utils -Mandrake: sgml-tools-A.B.C-DDmdk -SuSE: docbktls-A.BB.C-DD - -8. GETTING MORE INFORMATION +7. GETTING MORE INFORMATION WWW: A great deal of information about Wine is available from WineHQ at http://www.winehq.org/ : various Wine Guides, application database, diff -urN wine-20050419/VERSION wine-20050524/VERSION --- wine-20050419/VERSION 2005-04-19 14:54:44.000000000 +0200 +++ wine-20050524/VERSION 2005-05-24 16:16:16.000000000 +0200 @@ -1 +1 @@ -Wine version 20050419 +Wine version 20050524 diff -urN wine-20050419/configure wine-20050524/configure --- wine-20050419/configure 2005-04-19 14:54:44.000000000 +0200 +++ wine-20050524/configure 2005-05-24 16:16:16.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for Wine 20050419. +# Generated by GNU Autoconf 2.59 for Wine 20050524. # # Report bugs to . # @@ -269,8 +269,8 @@ # Identity of this package. PACKAGE_NAME='Wine' PACKAGE_TARNAME='wine' -PACKAGE_VERSION='20050419' -PACKAGE_STRING='Wine 20050419' +PACKAGE_VERSION='20050524' +PACKAGE_STRING='Wine 20050524' PACKAGE_BUGREPORT='wine-devel@winehq.org' ac_unique_file="server/atom.c" @@ -311,7 +311,7 @@ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS WIN16_FILES WIN16_INSTALL DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS DB2HTML DB2PDF DB2PS DB2TXT FONTFORGE LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS ft_devel ft_devel2 FREETYPELIBS FREETYPEINCL FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS LDLIBWINEFLAGS COREFOUNDATIONLIB IOKITLIB CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD ALLOCA LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os WIN16_FILES WIN16_INSTALL SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS FONTFORGE LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS ft_devel ft_devel2 FREETYPELIBS FREETYPEINCL FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS LDLIBWINEFLAGS COREFOUNDATIONLIB IOKITLIB CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD ALLOCA LIBOBJS LTLIBOBJS' ac_subst_files='MAKE_RULES MAKE_DLL_RULES MAKE_TEST_RULES MAKE_LIB_RULES MAKE_PROG_RULES' # Initialize some variables set by options. @@ -788,7 +788,7 @@ # 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 20050419 to adapt to many kinds of systems. +\`configure' configures Wine 20050524 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -853,7 +853,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Wine 20050419:";; + short | recursive ) echo "Configuration of Wine 20050524:";; esac cat <<\_ACEOF @@ -984,7 +984,7 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -Wine configure 20050419 +Wine configure 20050524 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -998,7 +998,7 @@ 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 20050419, which was +It was created by Wine $as_me 20050524, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1404,16 +1404,6 @@ fi; -WIN16_FILES="\$(WIN16_FILES)" - -WIN16_INSTALL="\$(WIN16_INSTALL)" - -if test "x$enable_win16" = "xno" -then - WIN16_FILES="" - WIN16_INSTALL="" -fi - DLLDEFS="" if test "x$enable_debug" = "xno" @@ -1425,7 +1415,6 @@ DLLDEFS="$DLLDEFS -DWINE_NO_TRACE_MSGS" fi - # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 @@ -1492,6 +1481,26 @@ ;; esac +case $host_cpu in + *i[3456789]86*) + if test "x$enable_win16" != "xno" + then + enable_win16="yes" + fi + ;; +esac + +WIN16_FILES="\$(WIN16_FILES)" + +WIN16_INSTALL="\$(WIN16_INSTALL)" + +if test "x$enable_win16" != "xyes" +then + WIN16_FILES="" + WIN16_INSTALL="" +fi + + echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` @@ -5590,170 +5599,6 @@ -for ac_prog in docbook2html db2html -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_DB2HTML+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$DB2HTML"; then - ac_cv_prog_DB2HTML="$DB2HTML" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DB2HTML="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -DB2HTML=$ac_cv_prog_DB2HTML -if test -n "$DB2HTML"; then - echo "$as_me:$LINENO: result: $DB2HTML" >&5 -echo "${ECHO_T}$DB2HTML" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$DB2HTML" && break -done -test -n "$DB2HTML" || DB2HTML="false" - -for ac_prog in docbook2pdf db2pdf -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_DB2PDF+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$DB2PDF"; then - ac_cv_prog_DB2PDF="$DB2PDF" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DB2PDF="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -DB2PDF=$ac_cv_prog_DB2PDF -if test -n "$DB2PDF"; then - echo "$as_me:$LINENO: result: $DB2PDF" >&5 -echo "${ECHO_T}$DB2PDF" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$DB2PDF" && break -done -test -n "$DB2PDF" || DB2PDF="false" - -for ac_prog in docbook2ps db2ps -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_DB2PS+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$DB2PS"; then - ac_cv_prog_DB2PS="$DB2PS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DB2PS="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -DB2PS=$ac_cv_prog_DB2PS -if test -n "$DB2PS"; then - echo "$as_me:$LINENO: result: $DB2PS" >&5 -echo "${ECHO_T}$DB2PS" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$DB2PS" && break -done -test -n "$DB2PS" || DB2PS="false" - -for ac_prog in docbook2txt db2txt -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_DB2TXT+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$DB2TXT"; then - ac_cv_prog_DB2TXT="$DB2TXT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DB2TXT="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -DB2TXT=$ac_cv_prog_DB2TXT -if test -n "$DB2TXT"; then - echo "$as_me:$LINENO: result: $DB2TXT" >&5 -echo "${ECHO_T}$DB2TXT" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$DB2TXT" && break -done -test -n "$DB2TXT" || DB2TXT="false" - for ac_prog in fontforge do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -7262,9 +7107,13 @@ + + + for ac_header in \ arpa/inet.h \ arpa/nameser.h \ + asm/types.h \ cups/cups.h \ direct.h \ elf.h \ @@ -7289,7 +7138,9 @@ linux/param.h \ linux/serial.h \ linux/ucdrom.h \ + mach/machine.h \ machine/cpu.h \ + machine/limits.h \ mntent.h \ netdb.h \ netinet/in.h \ @@ -16382,6 +16233,7 @@ + for ac_func in \ _lwp_create \ _lwp_self \ @@ -16403,6 +16255,7 @@ fstatvfs \ ftruncate \ futimes \ + futimesat \ getnetbyname \ getopt_long \ getpagesize \ @@ -16809,6 +16662,73 @@ + +for ac_header in linux/videodev.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + echo "$as_me:$LINENO: checking for GNU style IPX support" >&5 echo $ECHO_N "checking for GNU style IPX support... $ECHO_C" >&6 if test "${ac_cv_c_ipx_gnu+set}" = set; then @@ -19840,6 +19760,129 @@ fi +echo "$as_me:$LINENO: checking for timezone variable" >&5 +echo $ECHO_N "checking for timezone variable... $ECHO_C" >&6 +if test "${ac_cv_have_timezone+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +timezone; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_timezone="yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_have_timezone="no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_have_timezone" >&5 +echo "${ECHO_T}$ac_cv_have_timezone" >&6 +if test "$ac_cv_have_timezone" = "yes" +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TIMEZONE 1 +_ACEOF + +fi +echo "$as_me:$LINENO: checking for daylight variable" >&5 +echo $ECHO_N "checking for daylight variable... $ECHO_C" >&6 +if test "${ac_cv_have_daylight+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +daylight; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_daylight="yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_have_daylight="no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_have_daylight" >&5 +echo "${ECHO_T}$ac_cv_have_daylight" >&6 +if test "$ac_cv_have_daylight" = "yes" +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DAYLIGHT 1 +_ACEOF + +fi + case $host_cpu in *i[3456789]86*) echo "$as_me:$LINENO: checking whether we need to define __i386__" >&5 @@ -20032,8 +20075,6 @@ ac_config_commands="$ac_config_commands include/wine" - ac_config_commands="$ac_config_commands misc" - ac_config_commands="$ac_config_commands programs/regedit/tests" ac_config_commands="$ac_config_commands windows" @@ -20054,7 +20095,7 @@ MAKE_PROG_RULES=programs/Makeprog.rules - ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules dlls/Maketest.rules libs/Makelib.rules programs/Makeprog.rules Makefile dlls/Makefile dlls/advapi32/Makefile dlls/advapi32/tests/Makefile dlls/advpack/Makefile dlls/advpack/tests/Makefile dlls/amstream/Makefile dlls/atl/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/cabinet/Makefile dlls/capi2032/Makefile dlls/cards/Makefile dlls/cfgmgr32/Makefile dlls/comcat/Makefile dlls/comctl32/Makefile dlls/comctl32/tests/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/cryptdll/Makefile dlls/ctl3d/Makefile dlls/d3d8/Makefile dlls/d3d9/Makefile dlls/d3dim/Makefile dlls/d3drm/Makefile dlls/d3dx8/Makefile dlls/d3dxof/Makefile dlls/dbghelp/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/ddraw/tests/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dinput8/Makefile dlls/dmband/Makefile dlls/dmcompos/Makefile dlls/dmime/Makefile dlls/dmloader/Makefile dlls/dmscript/Makefile dlls/dmstyle/Makefile dlls/dmsynth/Makefile dlls/dmusic/Makefile dlls/dmusic32/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dpnet/Makefile dlls/dpnhpast/Makefile dlls/dsound/Makefile dlls/dsound/tests/Makefile dlls/dswave/Makefile dlls/dxdiagn/Makefile dlls/dxerr8/Makefile dlls/dxerr9/Makefile dlls/dxguid/Makefile dlls/gdi/Makefile dlls/gdi/tests/Makefile dlls/glu32/Makefile dlls/glut32/Makefile dlls/hhctrl.ocx/Makefile dlls/iccvid/Makefile dlls/icmp/Makefile dlls/ifsmgr.vxd/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/iphlpapi/Makefile dlls/iphlpapi/tests/Makefile dlls/itss/Makefile dlls/kernel/Makefile dlls/kernel/tests/Makefile dlls/lzexpand/Makefile dlls/lzexpand/tests/Makefile dlls/mapi32/Makefile dlls/mapi32/tests/Makefile dlls/mlang/Makefile dlls/mlang/tests/Makefile dlls/mmdevldr.vxd/Makefile dlls/monodebg.vxd/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/imaadp32/Makefile dlls/msacm/msadp32/Makefile dlls/msacm/msg711/Makefile dlls/msacm/winemp3/Makefile dlls/msacm/tests/Makefile dlls/mscms/Makefile dlls/mscms/tests/Makefile dlls/msdmo/Makefile dlls/mshtml/Makefile dlls/msi/Makefile dlls/msi/tests/Makefile dlls/msimg32/Makefile dlls/msisys/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt/tests/Makefile dlls/msvcrt20/Makefile dlls/msvcrt40/Makefile dlls/msvcrtd/Makefile dlls/msvcrtd/tests/Makefile dlls/msvidc32/Makefile dlls/msvideo/Makefile dlls/mswsock/Makefile dlls/netapi32/Makefile dlls/netapi32/tests/Makefile dlls/newdev/Makefile dlls/ntdll/Makefile dlls/ntdll/tests/Makefile dlls/odbc32/Makefile dlls/ole32/Makefile dlls/ole32/tests/Makefile dlls/oleacc/Makefile dlls/oleaut32/Makefile dlls/oleaut32/tests/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/psapi/Makefile dlls/psapi/tests/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/quartz/tests/Makefile dlls/rasapi32/Makefile dlls/riched20/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/rpcrt4/tests/Makefile dlls/rsabase/Makefile dlls/rsabase/tests/Makefile dlls/rsaenh/Makefile dlls/rsaenh/tests/Makefile dlls/secur32/Makefile dlls/sensapi/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shell32/tests/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/shlwapi/tests/Makefile dlls/snmpapi/Makefile dlls/stdole32.tlb/Makefile dlls/sti/Makefile dlls/strmiids/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/unicows/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/urlmon/tests/Makefile dlls/user/Makefile dlls/user/tests/Makefile dlls/uuid/Makefile dlls/uxtheme/Makefile dlls/vdhcp.vxd/Makefile dlls/vdmdbg/Makefile dlls/version/Makefile dlls/version/tests/Makefile dlls/vmm.vxd/Makefile dlls/vnbt.vxd/Makefile dlls/vnetbios.vxd/Makefile dlls/vtdapi.vxd/Makefile dlls/vwin32.vxd/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/wined3d/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/wininet/tests/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/tests/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winealsa/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineaudioio/Makefile dlls/winmm/winejack/Makefile dlls/winmm/winenas/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winsock/tests/Makefile dlls/winspool/Makefile dlls/winspool/tests/Makefile dlls/wintab32/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/wtsapi32/Makefile dlls/x11drv/Makefile documentation/Makefile fonts/Makefile include/Makefile libs/Makefile libs/port/Makefile libs/unicode/Makefile libs/wine/Makefile libs/wpp/Makefile loader/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/expand/Makefile programs/msiexec/Makefile programs/notepad/Makefile programs/progman/Makefile programs/regedit/Makefile programs/regsvr32/Makefile programs/rpcss/Makefile programs/rundll32/Makefile programs/start/Makefile programs/taskmgr/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineboot/Makefile programs/winebrowser/Makefile programs/winecfg/Makefile programs/wineconsole/Makefile programs/winedbg/Makefile programs/winefile/Makefile programs/winemenubuilder/Makefile programs/winemine/Makefile programs/winepath/Makefile programs/winetest/Makefile programs/winevdm/Makefile programs/winhelp/Makefile programs/winver/Makefile server/Makefile tools/Makefile tools/widl/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/winegcc/Makefile tools/wmc/Makefile tools/wrc/Makefile" + ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules dlls/Maketest.rules libs/Makelib.rules programs/Makeprog.rules Makefile dlls/Makefile dlls/advapi32/Makefile dlls/advapi32/tests/Makefile dlls/advpack/Makefile dlls/advpack/tests/Makefile dlls/amstream/Makefile dlls/atl/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/cabinet/Makefile dlls/capi2032/Makefile dlls/cards/Makefile dlls/cfgmgr32/Makefile dlls/comcat/Makefile dlls/comctl32/Makefile dlls/comctl32/tests/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/crypt32/tests/Makefile dlls/cryptdll/Makefile dlls/ctl3d/Makefile dlls/d3d8/Makefile dlls/d3d9/Makefile dlls/d3dim/Makefile dlls/d3drm/Makefile dlls/d3dx8/Makefile dlls/d3dxof/Makefile dlls/dbghelp/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/ddraw/tests/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dinput/tests/Makefile dlls/dinput8/Makefile dlls/dmband/Makefile dlls/dmcompos/Makefile dlls/dmime/Makefile dlls/dmloader/Makefile dlls/dmscript/Makefile dlls/dmstyle/Makefile dlls/dmsynth/Makefile dlls/dmusic/Makefile dlls/dmusic32/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dpnet/Makefile dlls/dpnhpast/Makefile dlls/dsound/Makefile dlls/dsound/tests/Makefile dlls/dswave/Makefile dlls/dxdiagn/Makefile dlls/dxerr8/Makefile dlls/dxerr9/Makefile dlls/dxguid/Makefile dlls/gdi/Makefile dlls/gdi/tests/Makefile dlls/glu32/Makefile dlls/glut32/Makefile dlls/hhctrl.ocx/Makefile dlls/iccvid/Makefile dlls/icmp/Makefile dlls/ifsmgr.vxd/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/iphlpapi/Makefile dlls/iphlpapi/tests/Makefile dlls/itss/Makefile dlls/kernel/Makefile dlls/kernel/tests/Makefile dlls/lzexpand/Makefile dlls/lzexpand/tests/Makefile dlls/mapi32/Makefile dlls/mapi32/tests/Makefile dlls/mlang/Makefile dlls/mlang/tests/Makefile dlls/mmdevldr.vxd/Makefile dlls/monodebg.vxd/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/imaadp32/Makefile dlls/msacm/msadp32/Makefile dlls/msacm/msg711/Makefile dlls/msacm/winemp3/Makefile dlls/msacm/tests/Makefile dlls/mscms/Makefile dlls/mscms/tests/Makefile dlls/msdmo/Makefile dlls/mshtml/Makefile dlls/msi/Makefile dlls/msi/tests/Makefile dlls/msimg32/Makefile dlls/msisys/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt/tests/Makefile dlls/msvcrt20/Makefile dlls/msvcrt40/Makefile dlls/msvcrtd/Makefile dlls/msvcrtd/tests/Makefile dlls/msvidc32/Makefile dlls/msvideo/Makefile dlls/mswsock/Makefile dlls/netapi32/Makefile dlls/netapi32/tests/Makefile dlls/newdev/Makefile dlls/ntdll/Makefile dlls/ntdll/tests/Makefile dlls/odbc32/Makefile dlls/odbccp32/Makefile dlls/ole32/Makefile dlls/ole32/tests/Makefile dlls/oleacc/Makefile dlls/oleaut32/Makefile dlls/oleaut32/tests/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/powrprof/Makefile dlls/psapi/Makefile dlls/psapi/tests/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/quartz/tests/Makefile dlls/rasapi32/Makefile dlls/riched20/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/rpcrt4/tests/Makefile dlls/rsabase/Makefile dlls/rsabase/tests/Makefile dlls/rsaenh/Makefile dlls/rsaenh/tests/Makefile dlls/secur32/Makefile dlls/sensapi/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shell32/tests/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/shlwapi/tests/Makefile dlls/snmpapi/Makefile dlls/stdole32.tlb/Makefile dlls/sti/Makefile dlls/strmiids/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/unicows/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/urlmon/tests/Makefile dlls/user/Makefile dlls/user/tests/Makefile dlls/uuid/Makefile dlls/uxtheme/Makefile dlls/vdhcp.vxd/Makefile dlls/vdmdbg/Makefile dlls/version/Makefile dlls/version/tests/Makefile dlls/vmm.vxd/Makefile dlls/vnbt.vxd/Makefile dlls/vnetbios.vxd/Makefile dlls/vtdapi.vxd/Makefile dlls/vwin32.vxd/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/wined3d/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/wininet/tests/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/tests/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winealsa/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineaudioio/Makefile dlls/winmm/winejack/Makefile dlls/winmm/winenas/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winsock/tests/Makefile dlls/winspool/Makefile dlls/winspool/tests/Makefile dlls/wintab32/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/wtsapi32/Makefile dlls/x11drv/Makefile documentation/Makefile fonts/Makefile include/Makefile libs/Makefile libs/port/Makefile libs/unicode/Makefile libs/wine/Makefile libs/wpp/Makefile loader/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/expand/Makefile programs/msiexec/Makefile programs/notepad/Makefile programs/progman/Makefile programs/regedit/Makefile programs/regsvr32/Makefile programs/rpcss/Makefile programs/rundll32/Makefile programs/start/Makefile programs/taskmgr/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineboot/Makefile programs/winebrowser/Makefile programs/winecfg/Makefile programs/wineconsole/Makefile programs/winedbg/Makefile programs/winefile/Makefile programs/winemenubuilder/Makefile programs/winemine/Makefile programs/winepath/Makefile programs/winetest/Makefile programs/winevdm/Makefile programs/winhelp/Makefile programs/winver/Makefile server/Makefile tools/Makefile tools/widl/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/winegcc/Makefile tools/wmc/Makefile tools/wrc/Makefile" cat >confcache <<\_ACEOF @@ -20419,7 +20460,7 @@ } >&5 cat >&5 <<_CSEOF -This file was extended by Wine $as_me 20050419, which was +This file was extended by Wine $as_me 20050524, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20482,7 +20523,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -Wine config.status 20050419 +Wine config.status 20050524 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -20610,6 +20651,7 @@ "dlls/commdlg/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/commdlg/Makefile" ;; "dlls/crtdll/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/crtdll/Makefile" ;; "dlls/crypt32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/crypt32/Makefile" ;; + "dlls/crypt32/tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/crypt32/tests/Makefile" ;; "dlls/cryptdll/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/cryptdll/Makefile" ;; "dlls/ctl3d/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/ctl3d/Makefile" ;; "dlls/d3d8/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/d3d8/Makefile" ;; @@ -20624,6 +20666,7 @@ "dlls/ddraw/tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/ddraw/tests/Makefile" ;; "dlls/devenum/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/devenum/Makefile" ;; "dlls/dinput/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/dinput/Makefile" ;; + "dlls/dinput/tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/dinput/tests/Makefile" ;; "dlls/dinput8/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/dinput8/Makefile" ;; "dlls/dmband/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/dmband/Makefile" ;; "dlls/dmcompos/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/dmcompos/Makefile" ;; @@ -20700,6 +20743,7 @@ "dlls/ntdll/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/ntdll/Makefile" ;; "dlls/ntdll/tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/ntdll/tests/Makefile" ;; "dlls/odbc32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/odbc32/Makefile" ;; + "dlls/odbccp32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/odbccp32/Makefile" ;; "dlls/ole32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/ole32/Makefile" ;; "dlls/ole32/tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/ole32/tests/Makefile" ;; "dlls/oleacc/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/oleacc/Makefile" ;; @@ -20710,6 +20754,7 @@ "dlls/olepro32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/olepro32/Makefile" ;; "dlls/olesvr/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/olesvr/Makefile" ;; "dlls/opengl32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/opengl32/Makefile" ;; + "dlls/powrprof/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/powrprof/Makefile" ;; "dlls/psapi/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/psapi/Makefile" ;; "dlls/psapi/tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/psapi/tests/Makefile" ;; "dlls/qcap/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/qcap/Makefile" ;; @@ -20854,7 +20899,6 @@ "dlls/user/resources" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/user/resources" ;; "dlls/wineps/data" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/wineps/data" ;; "include/wine" ) CONFIG_COMMANDS="$CONFIG_COMMANDS include/wine" ;; - "misc" ) CONFIG_COMMANDS="$CONFIG_COMMANDS misc" ;; "programs/regedit/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS programs/regedit/tests" ;; "windows" ) CONFIG_COMMANDS="$CONFIG_COMMANDS windows" ;; "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; @@ -20943,8 +20987,6 @@ s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t -s,@WIN16_FILES@,$WIN16_FILES,;t t -s,@WIN16_INSTALL@,$WIN16_INSTALL,;t t s,@DLLDEFS@,$DLLDEFS,;t t s,@build@,$build,;t t s,@build_cpu@,$build_cpu,;t t @@ -20954,6 +20996,8 @@ s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t +s,@WIN16_FILES@,$WIN16_FILES,;t t +s,@WIN16_INSTALL@,$WIN16_INSTALL,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t @@ -20999,10 +21043,6 @@ s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@LINT@,$LINT,;t t s,@LINTFLAGS@,$LINTFLAGS,;t t -s,@DB2HTML@,$DB2HTML,;t t -s,@DB2PDF@,$DB2PDF,;t t -s,@DB2PS@,$DB2PS,;t t -s,@DB2TXT@,$DB2TXT,;t t s,@FONTFORGE@,$FONTFORGE,;t t s,@LIBPTHREAD@,$LIBPTHREAD,;t t s,@XLIB@,$XLIB,;t t @@ -21668,8 +21708,6 @@ echo "$as_me: creating dlls/wineps/data" >&6;} && mkdir "dlls/wineps/data") ;; include/wine ) test -d "include/wine" || ({ echo "$as_me:$LINENO: creating include/wine" >&5 echo "$as_me: creating include/wine" >&6;} && mkdir "include/wine") ;; - misc ) test -d "misc" || ({ echo "$as_me:$LINENO: creating misc" >&5 -echo "$as_me: creating misc" >&6;} && mkdir "misc") ;; programs/regedit/tests ) test -d "programs/regedit/tests" || ({ echo "$as_me:$LINENO: creating programs/regedit/tests" >&5 echo "$as_me: creating programs/regedit/tests" >&6;} && mkdir "programs/regedit/tests") ;; windows ) test -d "windows" || ({ echo "$as_me:$LINENO: creating windows" >&5 diff -urN wine-20050419/configure.ac wine-20050524/configure.ac --- wine-20050419/configure.ac 2005-03-28 11:58:45.000000000 +0200 +++ wine-20050524/configure.ac 2005-05-24 13:52:46.000000000 +0200 @@ -21,14 +21,6 @@ AC_ARG_WITH(curses, AC_HELP_STRING([--without-curses],[do not use curses])) AC_ARG_WITH(wine-tools,AC_HELP_STRING([--with-wine-tools=],[use Wine tools from directory ])) -AC_SUBST(WIN16_FILES,"\$(WIN16_FILES)") -AC_SUBST(WIN16_INSTALL,"\$(WIN16_INSTALL)") -if test "x$enable_win16" = "xno" -then - WIN16_FILES="" - WIN16_INSTALL="" -fi - AC_SUBST(DLLDEFS,"") if test "x$enable_debug" = "xno" then @@ -39,8 +31,6 @@ DLLDEFS="$DLLDEFS -DWINE_NO_TRACE_MSGS" fi -dnl **** Check for some programs **** - AC_CANONICAL_HOST case $host in x86_64*linux*) @@ -54,6 +44,26 @@ ;; esac +dnl enable_win16 defaults to yes on x86, to no on other CPUs +case $host_cpu in + *i[[3456789]]86*) + if test "x$enable_win16" != "xno" + then + enable_win16="yes" + fi + ;; +esac + +AC_SUBST(WIN16_FILES,"\$(WIN16_FILES)") +AC_SUBST(WIN16_INSTALL,"\$(WIN16_INSTALL)") +if test "x$enable_win16" != "xyes" +then + WIN16_FILES="" + WIN16_INSTALL="" +fi + +dnl **** Check for some programs **** + AC_PROG_MAKE_SET AC_PROG_CC AC_PROG_CXX @@ -123,10 +133,6 @@ AC_SUBST(LINTFLAGS) dnl Check for various programs -AC_CHECK_PROGS(DB2HTML, docbook2html db2html, false) -AC_CHECK_PROGS(DB2PDF, docbook2pdf db2pdf, false) -AC_CHECK_PROGS(DB2PS, docbook2ps db2ps, false) -AC_CHECK_PROGS(DB2TXT, docbook2txt db2txt, false) AC_CHECK_PROGS(FONTFORGE, fontforge, false) dnl **** Check for some libraries **** @@ -167,6 +173,7 @@ AC_CHECK_HEADERS(\ arpa/inet.h \ arpa/nameser.h \ + asm/types.h \ cups/cups.h \ direct.h \ elf.h \ @@ -191,7 +198,9 @@ linux/param.h \ linux/serial.h \ linux/ucdrom.h \ + mach/machine.h \ machine/cpu.h \ + machine/limits.h \ mntent.h \ netdb.h \ netinet/in.h \ @@ -1142,6 +1151,7 @@ fstatvfs \ ftruncate \ futimes \ + futimesat \ getnetbyname \ getopt_long \ getpagesize \ @@ -1211,6 +1221,16 @@ AC_CHECK_HEADERS(ucontext.h,,,[#include ]) +dnl **** Check for v4l(2) headers **** + +AC_CHECK_HEADERS(linux/videodev.h,,, +[#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_ASM_TYPES_H +#include +#endif]) + dnl **** Check for IPX headers (currently Linux only) **** AC_CACHE_CHECK([for GNU style IPX support], ac_cv_c_ipx_gnu, @@ -1454,6 +1474,22 @@ dnl Check for stat.st_blocks AC_CHECK_MEMBERS([struct stat.st_blocks]) +dnl Check for the external timezone variables timezone and daylight +AC_CACHE_CHECK([for timezone variable], ac_cv_have_timezone, + AC_TRY_LINK([#include ],[timezone;], + ac_cv_have_timezone="yes", ac_cv_have_timezone="no")) +if test "$ac_cv_have_timezone" = "yes" +then + AC_DEFINE(HAVE_TIMEZONE, 1, [Define if you have the timezone variable]) +fi +AC_CACHE_CHECK([for daylight variable], ac_cv_have_daylight, + AC_TRY_LINK([#include ],[daylight;], + ac_cv_have_daylight="yes", ac_cv_have_daylight="no")) +if test "$ac_cv_have_daylight" = "yes" +then + AC_DEFINE(HAVE_DAYLIGHT, 1, [Define if you have the daylight variable]) +fi + dnl *** check for the need to define platform-specific symbols case $host_cpu in @@ -1484,7 +1520,6 @@ WINE_CONFIG_EXTRA_DIR(dlls/user/resources) WINE_CONFIG_EXTRA_DIR(dlls/wineps/data) WINE_CONFIG_EXTRA_DIR(include/wine) -WINE_CONFIG_EXTRA_DIR(misc) WINE_CONFIG_EXTRA_DIR(programs/regedit/tests) WINE_CONFIG_EXTRA_DIR(windows) @@ -1529,6 +1564,7 @@ dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile +dlls/crypt32/tests/Makefile dlls/cryptdll/Makefile dlls/ctl3d/Makefile dlls/d3d8/Makefile @@ -1543,6 +1579,7 @@ dlls/ddraw/tests/Makefile dlls/devenum/Makefile dlls/dinput/Makefile +dlls/dinput/tests/Makefile dlls/dinput8/Makefile dlls/dmband/Makefile dlls/dmcompos/Makefile @@ -1619,6 +1656,7 @@ dlls/ntdll/Makefile dlls/ntdll/tests/Makefile dlls/odbc32/Makefile +dlls/odbccp32/Makefile dlls/ole32/Makefile dlls/ole32/tests/Makefile dlls/oleacc/Makefile @@ -1629,6 +1667,7 @@ dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile +dlls/powrprof/Makefile dlls/psapi/Makefile dlls/psapi/tests/Makefile dlls/qcap/Makefile diff -urN wine-20050419/dlls/Makedll.rules.in wine-20050524/dlls/Makedll.rules.in --- wine-20050419/dlls/Makedll.rules.in 2005-03-08 17:55:26.000000000 +0100 +++ wine-20050524/dlls/Makedll.rules.in 2005-05-10 15:21:04.000000000 +0200 @@ -12,13 +12,18 @@ DLLDEFS = @DLLDEFS@ DLLFLAGS = @DLLFLAGS@ DLLEXT = @DLLEXT@ +IMPLIBEXT = @IMPLIBEXT@ DEFS = -D__WINESRC__ $(DLLDEFS) $(EXTRADEFS) -MAINSPEC = $(MODULE:%.dll=%).spec -SPEC_DEF = $(MAINSPEC).def +BASEMODULE = $(MODULE:%.dll=%) +MAINSPEC = $(BASEMODULE).spec +SPEC_DEF = lib$(BASEMODULE).def WIN16_FILES = $(SPEC_SRCS16:.spec=.spec.o) $(C_SRCS16:.c=.o) $(EXTRA_OBJS16) -ALL_OBJS = @WIN16_FILES@ $(OBJS) $(MODULE).dbg.o +ALL_OBJS = @WIN16_FILES@ $(OBJS) $(MODULE).dbg.o $(RC_SRCS:.rc=.res) ALL_LIBS = $(LIBWINE) $(EXTRALIBS) $(LIBPORT) $(LDFLAGS) $(LIBS) -IMPORTLIBS = $(DELAYIMPORTS:%=$(DLLDIR)/lib%.$(IMPLIBEXT)) $(IMPORTS:%=$(DLLDIR)/lib%.$(IMPLIBEXT)) +ALL_IMPORTS = $(DELAYIMPORTS) $(IMPORTS) +IMPLIB_OBJS = $(IMPLIB_SRCS:.c=.o) +STATICIMPLIB= $(IMPORTLIB:.def=.def.a) +DLL_LDPATH = -L$(DLLDIR) $(ALL_IMPORTS:%=-L$(DLLDIR)/%) all: $(MODULE)$(DLLEXT) $(SUBDIRS) @@ -26,15 +31,34 @@ # Rules for .so files -$(MODULE).so: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) Makefile.in - $(WINEGCC) -B$(TOOLSDIR)/tools/winebuild -shared $(SRCDIR)/$(MAINSPEC) $(ALL_OBJS) $(RC_SRCS:.rc=.res) $(SUBSYSTEM:%=-Wb,--subsystem,%) -o $@ -L$(DLLDIR) $(DELAYIMPORTS:%=-Wb,-d%) $(IMPORTS:%=-l%) $(ALL_LIBS) +$(MODULE).so: $(MAINSPEC) $(ALL_OBJS) Makefile.in + $(WINEGCC) -B$(TOOLSDIR)/tools/winebuild -shared $(SRCDIR)/$(MAINSPEC) $(ALL_OBJS) $(SUBSYSTEM:%=-Wb,--subsystem,%) -o $@ $(DLL_LDPATH) $(ALL_IMPORTS:%=-l%) $(DELAYIMPORTS:%=-Wb,-d%) $(ALL_LIBS) # Rules for .dll files -$(MODULE): $(RCOBJS) $(OBJS) $(MODULE).dbg.o $(SPEC_DEF) $(IMPORTLIBS) Makefile.in - $(DLLWRAP) -k --def $(SPEC_DEF) -o $@ $(RCOBJS) $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(DELAYIMPORTS:%=-l%) $(IMPORTS:%=-l%) $(ALL_LIBS) +$(MODULE): $(RCOBJS) $(OBJS) $(MODULE).dbg.o $(SPEC_DEF) Makefile.in + $(DLLWRAP) -k --def $(SPEC_DEF) -o $@ $(RCOBJS) $(OBJS) $(MODULE).dbg.o $(DLL_LDPATH) $(ALL_IMPORTS:%=-l%) $(ALL_LIBS) -$(SPEC_DEF): $(WINEBUILD) +# Rules for import libraries + +.PHONY: implib static_implib $(IMPLIB_OBJS:%=__static_implib__%) + +all implib: $(IMPORTLIB) $(IMPLIB_OBJS:%=__static_implib__%) + +$(IMPLIB_OBJS:%=__static_implib__%): $(STATICIMPLIB) + +lib$(BASEMODULE).def: $(MAINSPEC) + $(WINEBUILD) -w --def -o $@ --export $(SRCDIR)/$(MAINSPEC) + +lib$(BASEMODULE).def.a: $(IMPLIB_OBJS) + $(RM) $@ + $(AR) $@ $(IMPLIB_OBJS) + $(RANLIB) $@ + +lib$(BASEMODULE).a: $(SPEC_DEF) $(IMPLIB_OBJS) + $(DLLTOOL) -k -l $@ -d $(SPEC_DEF) + $(AR) $@ $(IMPLIB_OBJS) + $(RANLIB) $@ # Rules for checking that no imports are missing @@ -55,19 +79,19 @@ # Rule to explicitly generate the .spec.c for debugging -$(MAINSPEC).c: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) $(WINEBUILD) - $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --export $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%) +$(MAINSPEC).c: $(MAINSPEC) $(ALL_OBJS) + $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --export $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(ALL_OBJS) $(DLL_LDPATH) $(ALL_IMPORTS:%=-l%) $(DELAYIMPORTS:%=-d%) # Rules for auto documentation man: $(C_SRCS) - $(C2MAN) -o $(TOPOBJDIR)/documentation/man$(api_manext) -R$(TOPOBJDIR) -S$(api_manext) $(INCLUDES) $(MAINSPEC:%=-w %) $(SPEC_SRCS16:%=-w %) $(C_SRCS) $(C_SRCS16) + $(C2MAN) -o $(TOPOBJDIR)/documentation/man$(api_manext) -R$(TOPOBJDIR) -C$(SRCDIR) -S$(api_manext) $(INCLUDES) $(MAINSPEC:%=-w %) $(SPEC_SRCS16:%=-w %) $(C_SRCS) $(C_SRCS16) doc-html: $(C_SRCS) - $(C2MAN) -o $(TOPOBJDIR)/documentation/html -R$(TOPSRCDIR) $(INCLUDES) -Th $(MAINSPEC:%=-w %) $(SPEC_SRCS16:%=-w %) $(C_SRCS) $(C_SRCS16) + $(C2MAN) -o $(TOPOBJDIR)/documentation/html -R$(TOPOBJDIR) -C$(SRCDIR) $(INCLUDES) -Th $(MAINSPEC:%=-w %) $(SPEC_SRCS16:%=-w %) $(C_SRCS) $(C_SRCS16) doc-sgml: $(C_SRCS) - $(C2MAN) -o $(TOPOBJDIR)/documentation/api-guide -R$(TOPSRCDIR) $(INCLUDES) -Ts $(MAINSPEC:%=-w %) $(SPEC_SRCS16:%=-w %) $(C_SRCS) $(C_SRCS16) + $(C2MAN) -o $(TOPOBJDIR)/documentation/api-guide -R$(TOPOBJDIR) -C$(SRCDIR) $(INCLUDES) -Ts $(MAINSPEC:%=-w %) $(SPEC_SRCS16:%=-w %) $(C_SRCS) $(C_SRCS16) .PHONY: man doc-html doc-sgml @@ -79,25 +103,40 @@ WIN16_INSTALL = $(ALL_SPECS16:%=_install_/%) -.PHONY: install_lib $(ALL_SPECS16:%=_install_/%) $(ALL_SPECS16:%=_uninstall_/%) +.PHONY: install_lib install_static_implib_def install_static_implib_a +.PHONY: $(ALL_SPECS16:%=_install_/%) $(IMPORTLIB:%=_install_/%) $(IMPLIB_OBJS:%=_install_static_implib_/%) $(ALL_SPECS16:%=_install_/%): install_lib cd $(dlldir) && $(RM) `basename $@`$(DLLEXT) && $(LN_S) $(MODULE)$(DLLEXT) `basename $@`$(DLLEXT) -$(ALL_SPECS16:%=_uninstall_/%): dummy - $(RM) $(dlldir)/`basename $@`$(DLLEXT) - install_lib: $(MODULE)$(DLLEXT) $(MKINSTALLDIRS) $(dlldir) $(INSTALL_PROGRAM) $(MODULE)$(DLLEXT) $(dlldir)/$(MODULE)$(DLLEXT) -install:: install_lib @WIN16_INSTALL@ +$(IMPORTLIB:%=_install_/%): $(IMPORTLIB) + $(MKINSTALLDIRS) $(dlldir) + $(INSTALL_DATA) $(IMPORTLIB) $(dlldir)/$(IMPORTLIB) -uninstall:: $(ALL_SPECS16:%=_uninstall_/%) - $(RM) $(dlldir)/$(MODULE)$(DLLEXT) +install_static_implib_def: $(STATICIMPLIB) + $(MKINSTALLDIRS) $(dlldir) + $(INSTALL_DATA) $(STATICIMPLIB) $(dlldir)/$(STATICIMPLIB) + +install_static_implib_a: + +$(IMPLIB_OBJS:%=_install_static_implib_/%): install_static_implib_$(IMPLIBEXT) + +install install-lib:: install_lib @WIN16_INSTALL@ + +install install-dev:: $(IMPORTLIB:%=_install_/%) $(IMPLIB_OBJS:%=_install_static_implib_/%) + +uninstall:: + [ ! -d $(dlldir) ] || (cd $(dlldir) && $(RM) $(MODULE)$(DLLEXT) $(IMPORTLIB) $(STATICIMPLIB) $(ALL_SPECS16:%=%$(DLLEXT))) # Misc. rules -$(SPEC_SRCS16:.spec=.spec.c): $(WINEBUILD) +clean:: + $(RM) $(SPEC_DEF) + +$(SPEC_DEF) $(SPEC_SRCS16:.spec=.spec.c): $(WINEBUILD) # End of global dll rules diff -urN wine-20050419/dlls/Makefile.in wine-20050524/dlls/Makefile.in --- wine-20050419/dlls/Makefile.in 2005-03-05 12:19:14.000000000 +0100 +++ wine-20050524/dlls/Makefile.in 2005-05-19 23:18:53.000000000 +0200 @@ -97,6 +97,7 @@ newdev \ ntdll \ odbc32 \ + odbccp32 \ ole32 \ oleacc \ oleaut32 \ @@ -104,6 +105,7 @@ oledlg \ olepro32 \ olesvr \ + powrprof \ psapi \ qcap \ quartz \ @@ -341,6 +343,7 @@ newdev.dll.so \ ntdll.dll.so \ odbc32.dll.so \ + odbccp32.dll.so \ ole32.dll.so \ oleacc.dll.so \ oleaut32.dll.so \ @@ -348,6 +351,7 @@ oledlg.dll.so \ olepro32.dll.so \ olesvr32.dll.so \ + powrprof.dll.so \ psapi.dll.so \ qcap.dll.so \ quartz.dll.so \ @@ -369,7 +373,6 @@ stdole32.tlb.so \ sti.dll.so \ tapi32.dll.so \ - ttydrv.dll.so \ twain_32.dll.so \ unicows.dll.so \ url.dll.so \ @@ -393,7 +396,8 @@ winemp3.acm.so \ winenas.drv.so \ wineoss.drv.so \ - wineps.dll.so \ + wineps.drv.so \ + winetty.drv.so \ wininet.dll.so \ winmm.dll.so \ winnls32.dll.so \ @@ -416,6 +420,9 @@ symlinks: $(BUILDSUBDIRS) +x11drv.dll.so: winex11.drv.so + $(RM) $@ && $(LN_S) winex11.drv.so $@ + # Map symlink name to the corresponding library @@ -730,6 +737,9 @@ odbc32.dll.so: odbc32/odbc32.dll.so $(RM) $@ && $(LN_S) odbc32/odbc32.dll.so $@ +odbccp32.dll.so: odbccp32/odbccp32.dll.so + $(RM) $@ && $(LN_S) odbccp32/odbccp32.dll.so $@ + ole32.dll.so: ole32/ole32.dll.so $(RM) $@ && $(LN_S) ole32/ole32.dll.so $@ @@ -768,6 +778,9 @@ opengl32.dll.so: opengl32/opengl32.dll.so $(RM) $@ && $(LN_S) opengl32/opengl32.dll.so $@ +powrprof.dll.so: powrprof/powrprof.dll.so + $(RM) $@ && $(LN_S) powrprof/powrprof.dll.so $@ + psapi.dll.so: psapi/psapi.dll.so $(RM) $@ && $(LN_S) psapi/psapi.dll.so $@ @@ -840,9 +853,6 @@ tapi32.dll.so: tapi32/tapi32.dll.so $(RM) $@ && $(LN_S) tapi32/tapi32.dll.so $@ -ttydrv.dll.so: ttydrv/ttydrv.dll.so - $(RM) $@ && $(LN_S) ttydrv/ttydrv.dll.so $@ - twain_32.dll.so: twain/twain_32.dll.so $(RM) $@ && $(LN_S) twain/twain_32.dll.so $@ @@ -931,11 +941,17 @@ wineoss.drv.so: winmm/wineoss/wineoss.drv.so $(RM) $@ && $(LN_S) winmm/wineoss/wineoss.drv.so $@ -wineps.dll.so: wineps/wineps.dll.so - $(RM) $@ && $(LN_S) wineps/wineps.dll.so $@ +wineps.drv.so: wineps/wineps.drv.so + $(RM) $@ && $(LN_S) wineps/wineps.drv.so $@ + +wineps16.drv.so : wineps.drv.so + $(RM) $@ && $(LN_S) wineps.drv.so $@ -wineps16.drv.so : wineps.dll.so - $(RM) $@ && $(LN_S) wineps.dll.so $@ +winetty.drv.so: ttydrv/winetty.drv.so + $(RM) $@ && $(LN_S) ttydrv/winetty.drv.so $@ + +winex11.drv.so: x11drv/winex11.drv.so + $(RM) $@ && $(LN_S) x11drv/winex11.drv.so $@ wininet.dll.so: wininet/wininet.dll.so $(RM) $@ && $(LN_S) wininet/wininet.dll.so $@ @@ -985,9 +1001,6 @@ wtsapi32.dll.so: wtsapi32/wtsapi32.dll.so $(RM) $@ && $(LN_S) wtsapi32/wtsapi32.dll.so $@ -x11drv.dll.so: x11drv/x11drv.dll.so - $(RM) $@ && $(LN_S) x11drv/x11drv.dll.so $@ - libdxerr8.a: dxerr8/libdxerr8.a $(RM) $@ && $(LN_S) dxerr8/libdxerr8.a $@ @@ -1006,935 +1019,614 @@ # Import libraries -IMPORT_LIBS = \ - libadvapi32.$(IMPLIBEXT) \ - libadvpack.$(IMPLIBEXT) \ - libamstream.$(IMPLIBEXT) \ - libatl.$(IMPLIBEXT) \ - libavicap32.$(IMPLIBEXT) \ - libavifil32.$(IMPLIBEXT) \ - libcabinet.$(IMPLIBEXT) \ - libcapi2032.$(IMPLIBEXT) \ - libcards.$(IMPLIBEXT) \ - libcfgmgr32.$(IMPLIBEXT) \ - libcomcat.$(IMPLIBEXT) \ - libcomctl32.$(IMPLIBEXT) \ +STATIC_IMPLIBEXT = $(IMPLIBEXT:def=def.a) + +IMPORT_SYMLINKS = \ libcomdlg32.$(IMPLIBEXT) \ - libcrtdll.$(IMPLIBEXT) \ - libcrypt32.$(IMPLIBEXT) \ - libcryptdll.$(IMPLIBEXT) \ libctl3d32.$(IMPLIBEXT) \ - libd3d8.$(IMPLIBEXT) \ - libd3d9.$(IMPLIBEXT) \ - libd3dim.$(IMPLIBEXT) \ - libd3drm.$(IMPLIBEXT) \ - libd3dx8.$(IMPLIBEXT) \ - libd3dxof.$(IMPLIBEXT) \ - libdbghelp.$(IMPLIBEXT) \ - libdciman32.$(IMPLIBEXT) \ - libddraw.$(IMPLIBEXT) \ - libdevenum.$(IMPLIBEXT) \ - libdinput.$(IMPLIBEXT) \ - libdinput8.$(IMPLIBEXT) \ - libdmband.$(IMPLIBEXT) \ - libdmcompos.$(IMPLIBEXT) \ - libdmime.$(IMPLIBEXT) \ - libdmloader.$(IMPLIBEXT) \ - libdmscript.$(IMPLIBEXT) \ - libdmstyle.$(IMPLIBEXT) \ - libdmsynth.$(IMPLIBEXT) \ - libdmusic.$(IMPLIBEXT) \ - libdmusic32.$(IMPLIBEXT) \ - libdplay.$(IMPLIBEXT) \ - libdplayx.$(IMPLIBEXT) \ - libdpnet.$(IMPLIBEXT) \ - libdpnhpast.$(IMPLIBEXT) \ - libdsound.$(IMPLIBEXT) \ - libdswave.$(IMPLIBEXT) \ - libdxdiagn.$(IMPLIBEXT) \ libgdi32.$(IMPLIBEXT) \ - libglu32.$(IMPLIBEXT) \ - libglut32.$(IMPLIBEXT) \ - libiccvid.$(IMPLIBEXT) \ - libicmp.$(IMPLIBEXT) \ - libimagehlp.$(IMPLIBEXT) \ - libimm32.$(IMPLIBEXT) \ - libiphlpapi.$(IMPLIBEXT) \ - libitss.$(IMPLIBEXT) \ libkernel32.$(IMPLIBEXT) \ liblz32.$(IMPLIBEXT) \ - libmapi32.$(IMPLIBEXT) \ - libmlang.$(IMPLIBEXT) \ - libmpr.$(IMPLIBEXT) \ libmsacm32.$(IMPLIBEXT) \ - libmscms.$(IMPLIBEXT) \ - libmsdmo.$(IMPLIBEXT) \ - libmshtml.$(IMPLIBEXT) \ - libmsi.$(IMPLIBEXT) \ - libmsimg32.$(IMPLIBEXT) \ - libmsnet32.$(IMPLIBEXT) \ - libmsrle32.$(IMPLIBEXT) \ - libmsvcrt.$(IMPLIBEXT) \ - libmsvcrt20.$(IMPLIBEXT) \ - libmsvcrt40.$(IMPLIBEXT) \ - libmsvcrtd.$(IMPLIBEXT) \ libmsvfw32.$(IMPLIBEXT) \ - libmsvidc32.$(IMPLIBEXT) \ - libmswsock.$(IMPLIBEXT) \ - libnetapi32.$(IMPLIBEXT) \ - libnewdev.$(IMPLIBEXT) \ libntdll.$(IMPLIBEXT) \ - libodbc32.$(IMPLIBEXT) \ - libole32.$(IMPLIBEXT) \ - liboleacc.$(IMPLIBEXT) \ - liboleaut32.$(IMPLIBEXT) \ libolecli32.$(IMPLIBEXT) \ - liboledlg.$(IMPLIBEXT) \ - libolepro32.$(IMPLIBEXT) \ libolesvr32.$(IMPLIBEXT) \ - libopengl32.$(IMPLIBEXT) \ - libpsapi.$(IMPLIBEXT) \ - libqcap.$(IMPLIBEXT) \ - libquartz.$(IMPLIBEXT) \ - librasapi32.$(IMPLIBEXT) \ - libriched20.$(IMPLIBEXT) \ libriched32.$(IMPLIBEXT) \ - librpcrt4.$(IMPLIBEXT) \ - librsabase.$(IMPLIBEXT) \ - librsaenh.$(IMPLIBEXT) \ - libsecur32.$(IMPLIBEXT) \ - libsensapi.$(IMPLIBEXT) \ - libserialui.$(IMPLIBEXT) \ - libsetupapi.$(IMPLIBEXT) \ - libshdocvw.$(IMPLIBEXT) \ - libshell32.$(IMPLIBEXT) \ - libshfolder.$(IMPLIBEXT) \ - libshlwapi.$(IMPLIBEXT) \ - libsnmpapi.$(IMPLIBEXT) \ - libsti.$(IMPLIBEXT) \ - libtapi32.$(IMPLIBEXT) \ - libttydrv.$(IMPLIBEXT) \ libtwain_32.$(IMPLIBEXT) \ - libunicows.$(IMPLIBEXT) \ - liburl.$(IMPLIBEXT) \ - liburlmon.$(IMPLIBEXT) \ libuser32.$(IMPLIBEXT) \ - libuxtheme.$(IMPLIBEXT) \ - libvdmdbg.$(IMPLIBEXT) \ - libversion.$(IMPLIBEXT) \ libw32skrnl.$(IMPLIBEXT) \ - libwined3d.$(IMPLIBEXT) \ - libwinedos.$(IMPLIBEXT) \ - libwineps.$(IMPLIBEXT) \ - libwininet.$(IMPLIBEXT) \ - libwinmm.$(IMPLIBEXT) \ libwinnls32.$(IMPLIBEXT) \ - libwinspool.$(IMPLIBEXT) \ - libwintab32.$(IMPLIBEXT) \ - libwintrust.$(IMPLIBEXT) \ libwnaspi32.$(IMPLIBEXT) \ - libwow32.$(IMPLIBEXT) \ libws2_32.$(IMPLIBEXT) \ - libwsock32.$(IMPLIBEXT) \ - libwtsapi32.$(IMPLIBEXT) \ - libx11drv.$(IMPLIBEXT) \ libdxerr8.a \ libdxerr9.a \ libdxguid.a \ libstrmiids.a \ libuuid.a +IMPORT_LIBS = \ + $(IMPORT_SYMLINKS) \ + advapi32/libadvapi32.$(IMPLIBEXT) \ + advpack/libadvpack.$(IMPLIBEXT) \ + amstream/libamstream.$(IMPLIBEXT) \ + atl/libatl.$(IMPLIBEXT) \ + avicap32/libavicap32.$(IMPLIBEXT) \ + avifil32/libavifil32.$(IMPLIBEXT) \ + cabinet/libcabinet.$(IMPLIBEXT) \ + capi2032/libcapi2032.$(IMPLIBEXT) \ + cards/libcards.$(IMPLIBEXT) \ + cfgmgr32/libcfgmgr32.$(IMPLIBEXT) \ + comcat/libcomcat.$(IMPLIBEXT) \ + comctl32/libcomctl32.$(IMPLIBEXT) \ + commdlg/libcomdlg32.$(IMPLIBEXT) \ + crtdll/libcrtdll.$(IMPLIBEXT) \ + crypt32/libcrypt32.$(IMPLIBEXT) \ + cryptdll/libcryptdll.$(IMPLIBEXT) \ + ctl3d/libctl3d32.$(IMPLIBEXT) \ + d3d8/libd3d8.$(IMPLIBEXT) \ + d3d9/libd3d9.$(IMPLIBEXT) \ + d3dim/libd3dim.$(IMPLIBEXT) \ + d3drm/libd3drm.$(IMPLIBEXT) \ + d3dx8/libd3dx8.$(IMPLIBEXT) \ + d3dxof/libd3dxof.$(IMPLIBEXT) \ + dbghelp/libdbghelp.$(IMPLIBEXT) \ + dciman32/libdciman32.$(IMPLIBEXT) \ + ddraw/libddraw.$(IMPLIBEXT) \ + devenum/libdevenum.$(IMPLIBEXT) \ + dinput/libdinput.$(IMPLIBEXT) \ + dinput/libdinput.$(STATIC_IMPLIBEXT) \ + dinput8/libdinput8.$(IMPLIBEXT) \ + dmband/libdmband.$(IMPLIBEXT) \ + dmcompos/libdmcompos.$(IMPLIBEXT) \ + dmime/libdmime.$(IMPLIBEXT) \ + dmloader/libdmloader.$(IMPLIBEXT) \ + dmscript/libdmscript.$(IMPLIBEXT) \ + dmstyle/libdmstyle.$(IMPLIBEXT) \ + dmsynth/libdmsynth.$(IMPLIBEXT) \ + dmusic/libdmusic.$(IMPLIBEXT) \ + dmusic32/libdmusic32.$(IMPLIBEXT) \ + dplay/libdplay.$(IMPLIBEXT) \ + dplayx/libdplayx.$(IMPLIBEXT) \ + dpnet/libdpnet.$(IMPLIBEXT) \ + dpnhpast/libdpnhpast.$(IMPLIBEXT) \ + dsound/libdsound.$(IMPLIBEXT) \ + dswave/libdswave.$(IMPLIBEXT) \ + dxdiagn/libdxdiagn.$(IMPLIBEXT) \ + gdi/libgdi32.$(IMPLIBEXT) \ + glu32/libglu32.$(IMPLIBEXT) \ + glut32/libglut32.$(IMPLIBEXT) \ + iccvid/libiccvid.$(IMPLIBEXT) \ + icmp/libicmp.$(IMPLIBEXT) \ + imagehlp/libimagehlp.$(IMPLIBEXT) \ + imm32/libimm32.$(IMPLIBEXT) \ + iphlpapi/libiphlpapi.$(IMPLIBEXT) \ + itss/libitss.$(IMPLIBEXT) \ + kernel/libkernel32.$(IMPLIBEXT) \ + lzexpand/liblz32.$(IMPLIBEXT) \ + mapi32/libmapi32.$(IMPLIBEXT) \ + mlang/libmlang.$(IMPLIBEXT) \ + mpr/libmpr.$(IMPLIBEXT) \ + msacm/libmsacm32.$(IMPLIBEXT) \ + mscms/libmscms.$(IMPLIBEXT) \ + msdmo/libmsdmo.$(IMPLIBEXT) \ + mshtml/libmshtml.$(IMPLIBEXT) \ + msi/libmsi.$(IMPLIBEXT) \ + msimg32/libmsimg32.$(IMPLIBEXT) \ + msnet32/libmsnet32.$(IMPLIBEXT) \ + msrle32/libmsrle32.$(IMPLIBEXT) \ + msvcrt/libmsvcrt.$(IMPLIBEXT) \ + msvcrt20/libmsvcrt20.$(IMPLIBEXT) \ + msvcrt40/libmsvcrt40.$(IMPLIBEXT) \ + msvcrtd/libmsvcrtd.$(IMPLIBEXT) \ + msvideo/libmsvfw32.$(IMPLIBEXT) \ + msvidc32/libmsvidc32.$(IMPLIBEXT) \ + mswsock/libmswsock.$(IMPLIBEXT) \ + netapi32/libnetapi32.$(IMPLIBEXT) \ + newdev/libnewdev.$(IMPLIBEXT) \ + ntdll/libntdll.$(IMPLIBEXT) \ + odbc32/libodbc32.$(IMPLIBEXT) \ + odbccp32/libodbccp32.$(IMPLIBEXT) \ + ole32/libole32.$(IMPLIBEXT) \ + oleacc/liboleacc.$(IMPLIBEXT) \ + oleaut32/liboleaut32.$(IMPLIBEXT) \ + olecli/libolecli32.$(IMPLIBEXT) \ + oledlg/liboledlg.$(IMPLIBEXT) \ + olepro32/libolepro32.$(IMPLIBEXT) \ + olesvr/libolesvr32.$(IMPLIBEXT) \ + opengl32/libopengl32.$(IMPLIBEXT) \ + powrprof/libpowrprof.$(IMPLIBEXT) \ + psapi/libpsapi.$(IMPLIBEXT) \ + qcap/libqcap.$(IMPLIBEXT) \ + quartz/libquartz.$(IMPLIBEXT) \ + rasapi32/librasapi32.$(IMPLIBEXT) \ + riched20/libriched20.$(IMPLIBEXT) \ + richedit/libriched32.$(IMPLIBEXT) \ + rpcrt4/librpcrt4.$(IMPLIBEXT) \ + rsabase/librsabase.$(IMPLIBEXT) \ + rsaenh/librsaenh.$(IMPLIBEXT) \ + secur32/libsecur32.$(IMPLIBEXT) \ + sensapi/libsensapi.$(IMPLIBEXT) \ + serialui/libserialui.$(IMPLIBEXT) \ + setupapi/libsetupapi.$(IMPLIBEXT) \ + shdocvw/libshdocvw.$(IMPLIBEXT) \ + shell32/libshell32.$(IMPLIBEXT) \ + shfolder/libshfolder.$(IMPLIBEXT) \ + shlwapi/libshlwapi.$(IMPLIBEXT) \ + snmpapi/libsnmpapi.$(IMPLIBEXT) \ + sti/libsti.$(IMPLIBEXT) \ + tapi32/libtapi32.$(IMPLIBEXT) \ + twain/libtwain_32.$(IMPLIBEXT) \ + unicows/libunicows.$(IMPLIBEXT) \ + url/liburl.$(IMPLIBEXT) \ + urlmon/liburlmon.$(IMPLIBEXT) \ + user/libuser32.$(IMPLIBEXT) \ + uxtheme/libuxtheme.$(IMPLIBEXT) \ + vdmdbg/libvdmdbg.$(IMPLIBEXT) \ + version/libversion.$(IMPLIBEXT) \ + win32s/libw32skrnl.$(IMPLIBEXT) \ + wined3d/libwined3d.$(IMPLIBEXT) \ + winedos/libwinedos.$(IMPLIBEXT) \ + wininet/libwininet.$(IMPLIBEXT) \ + winmm/libwinmm.$(IMPLIBEXT) \ + winnls/libwinnls32.$(IMPLIBEXT) \ + winspool/libwinspool.$(IMPLIBEXT) \ + wintab32/libwintab32.$(IMPLIBEXT) \ + wintrust/libwintrust.$(IMPLIBEXT) \ + winaspi/libwnaspi32.$(IMPLIBEXT) \ + wow32/libwow32.$(IMPLIBEXT) \ + winsock/libws2_32.$(IMPLIBEXT) \ + wsock32/libwsock32.$(IMPLIBEXT) \ + wtsapi32/libwtsapi32.$(IMPLIBEXT) + implib: $(IMPORT_LIBS) -libadvapi32.def: advapi32/advapi32.spec.def - $(RM) $@ && $(LN_S) advapi32/advapi32.spec.def $@ -libadvapi32.a: advapi32/advapi32.spec.def - $(DLLTOOL) -k -l $@ -d advapi32/advapi32.spec.def - -libadvpack.def: advpack/advpack.spec.def - $(RM) $@ && $(LN_S) advpack/advpack.spec.def $@ -libadvpack.a: advpack/advpack.spec.def - $(DLLTOOL) -k -l $@ -d advpack/advpack.spec.def - -libamstream.def: amstream/amstream.spec.def - $(RM) $@ && $(LN_S) amstream/amstream.spec.def $@ -libamstream.a: amstream/amstream.spec.def - $(DLLTOOL) -k -l $@ -d amstream/amstream.spec.def - -libatl.def: atl/atl.spec.def - $(RM) $@ && $(LN_S) atl/atl.spec.def $@ -libatl.a: atl/atl.spec.def - $(DLLTOOL) -k -l $@ -d atl/atl.spec.def - -libavicap32.def: avicap32/avicap32.spec.def - $(RM) $@ && $(LN_S) avicap32/avicap32.spec.def $@ -libavicap32.a: avicap32/avicap32.spec.def - $(DLLTOOL) -k -l $@ -d avicap32/avicap32.spec.def - -libavifil32.def: avifil32/avifil32.spec.def - $(RM) $@ && $(LN_S) avifil32/avifil32.spec.def $@ -libavifil32.a: avifil32/avifil32.spec.def - $(DLLTOOL) -k -l $@ -d avifil32/avifil32.spec.def - -libcabinet.def: cabinet/cabinet.spec.def - $(RM) $@ && $(LN_S) cabinet/cabinet.spec.def $@ -libcabinet.a: cabinet/cabinet.spec.def - $(DLLTOOL) -k -l $@ -d cabinet/cabinet.spec.def - -libcapi2032.def: capi2032/capi2032.spec.def - $(RM) $@ && $(LN_S) capi2032/capi2032.spec.def $@ -libcapi2032.a: capi2032/capi2032.spec.def - $(DLLTOOL) -k -l $@ -d capi2032/capi2032.spec.def - -libcards.def: cards/cards.spec.def - $(RM) $@ && $(LN_S) cards/cards.spec.def $@ -libcards.a: cards/cards.spec.def - $(DLLTOOL) -k -l $@ -d cards/cards.spec.def - -libcfgmgr32.def: cfgmgr32/cfgmgr32.spec.def - $(RM) $@ && $(LN_S) cfgmgr32/cfgmgr32.spec.def $@ -libcfgmgr32.a: cfgmgr32/cfgmgr32.spec.def - $(DLLTOOL) -k -l $@ -d cfgmgr32/cfgmgr32.spec.def - -libcomcat.def: comcat/comcat.spec.def - $(RM) $@ && $(LN_S) comcat/comcat.spec.def $@ -libcomcat.a: comcat/comcat.spec.def - $(DLLTOOL) -k -l $@ -d comcat/comcat.spec.def - -libcomctl32.def: comctl32/comctl32.spec.def - $(RM) $@ && $(LN_S) comctl32/comctl32.spec.def $@ -libcomctl32.a: comctl32/comctl32.spec.def - $(DLLTOOL) -k -l $@ -d comctl32/comctl32.spec.def - -libcomdlg32.def: commdlg/comdlg32.spec.def - $(RM) $@ && $(LN_S) commdlg/comdlg32.spec.def $@ -libcomdlg32.a: commdlg/comdlg32.spec.def - $(DLLTOOL) -k -l $@ -d commdlg/comdlg32.spec.def - -libcrtdll.def: crtdll/crtdll.spec.def - $(RM) $@ && $(LN_S) crtdll/crtdll.spec.def $@ -libcrtdll.a: crtdll/crtdll.spec.def - $(DLLTOOL) -k -l $@ -d crtdll/crtdll.spec.def - -libcrypt32.def: crypt32/crypt32.spec.def - $(RM) $@ && $(LN_S) crypt32/crypt32.spec.def $@ -libcrypt32.a: crypt32/crypt32.spec.def - $(DLLTOOL) -k -l $@ -d crypt32/crypt32.spec.def - -libcryptdll.def: cryptdll/cryptdll.spec.def - $(RM) $@ && $(LN_S) cryptdll/cryptdll.spec.def $@ -libcryptdll.a: cryptdll/cryptdll.spec.def - $(DLLTOOL) -k -l $@ -d cryptdll/cryptdll.spec.def - -libctl3d32.def: ctl3d/ctl3d32.spec.def - $(RM) $@ && $(LN_S) ctl3d/ctl3d32.spec.def $@ -libctl3d32.a: ctl3d/ctl3d32.spec.def - $(DLLTOOL) -k -l $@ -d ctl3d/ctl3d32.spec.def - -libd3d8.def: d3d8/d3d8.spec.def - $(RM) $@ && $(LN_S) d3d8/d3d8.spec.def $@ -libd3d8.a: d3d8/d3d8.spec.def - $(DLLTOOL) -k -l $@ -d d3d8/d3d8.spec.def - -libd3d9.def: d3d9/d3d9.spec.def - $(RM) $@ && $(LN_S) d3d9/d3d9.spec.def $@ -libd3d9.a: d3d9/d3d9.spec.def - $(DLLTOOL) -k -l $@ -d d3d9/d3d9.spec.def - -libd3dim.def: d3dim/d3dim.spec.def - $(RM) $@ && $(LN_S) d3dim/d3dim.spec.def $@ -libd3dim.a: d3dim/d3dim.spec.def - $(DLLTOOL) -k -l $@ -d d3dim/d3dim.spec.def - -libd3drm.def: d3drm/d3drm.spec.def - $(RM) $@ && $(LN_S) d3drm/d3drm.spec.def $@ -libd3drm.a: d3drm/d3drm.spec.def - $(DLLTOOL) -k -l $@ -d d3drm/d3drm.spec.def - -libd3dx8.def: d3dx8/d3dx8.spec.def - $(RM) $@ && $(LN_S) d3dx8/d3dx8.spec.def $@ -libd3dx8.a: d3dx8/d3dx8.spec.def - $(DLLTOOL) -k -l $@ -d d3dx8/d3dx8.spec.def - -libd3dxof.def: d3dxof/d3dxof.spec.def - $(RM) $@ && $(LN_S) d3dxof/d3dxof.spec.def $@ -libd3dxof.a: d3dxof/d3dxof.spec.def - $(DLLTOOL) -k -l $@ -d d3dxof/d3dxof.spec.def - -libdbghelp.def: dbghelp/dbghelp.spec.def - $(RM) $@ && $(LN_S) dbghelp/dbghelp.spec.def $@ -libdbghelp.a: dbghelp/dbghelp.spec.def - $(DLLTOOL) -k -l $@ -d dbghelp/dbghelp.spec.def - -libdciman32.def: dciman32/dciman32.spec.def - $(RM) $@ && $(LN_S) dciman32/dciman32.spec.def $@ -libdciman32.a: dciman32/dciman32.spec.def - $(DLLTOOL) -k -l $@ -d dciman32/dciman32.spec.def - -libddraw.def: ddraw/ddraw.spec.def - $(RM) $@ && $(LN_S) ddraw/ddraw.spec.def $@ -libddraw.a: ddraw/ddraw.spec.def - $(DLLTOOL) -k -l $@ -d ddraw/ddraw.spec.def - -libdevenum.def: devenum/devenum.spec.def - $(RM) $@ && $(LN_S) devenum/devenum.spec.def $@ -libdevenum.a: devenum/devenum.spec.def - $(DLLTOOL) -k -l $@ -d devenum/devenum.spec.def - -libdinput.def: dinput/dinput.spec.def - $(RM) $@ && $(LN_S) dinput/dinput.spec.def $@ -libdinput.a: dinput/dinput.spec.def - $(DLLTOOL) -k -l $@ -d dinput/dinput.spec.def - -libdinput8.def: dinput8/dinput8.spec.def - $(RM) $@ && $(LN_S) dinput8/dinput8.spec.def $@ -libdinput8.a: dinput8/dinput8.spec.def - $(DLLTOOL) -k -l $@ -d dinput8/dinput8.spec.def - -libdmband.def: dmband/dmband.spec.def - $(RM) $@ && $(LN_S) dmband/dmband.spec.def $@ -libdmband.a: dmband/dmband.spec.def - $(DLLTOOL) -k -l $@ -d dmband/dmband.spec.def - -libdmcompos.def: dmcompos/dmcompos.spec.def - $(RM) $@ && $(LN_S) dmcompos/dmcompos.spec.def $@ -libdmcompos.a: dmcompos/dmcompos.spec.def - $(DLLTOOL) -k -l $@ -d dmcompos/dmcompos.spec.def - -libdmime.def: dmime/dmime.spec.def - $(RM) $@ && $(LN_S) dmime/dmime.spec.def $@ -libdmime.a: dmime/dmime.spec.def - $(DLLTOOL) -k -l $@ -d dmime/dmime.spec.def - -libdmloader.def: dmloader/dmloader.spec.def - $(RM) $@ && $(LN_S) dmloader/dmloader.spec.def $@ -libdmloader.a: dmloader/dmloader.spec.def - $(DLLTOOL) -k -l $@ -d dmloader/dmloader.spec.def - -libdmscript.def: dmscript/dmscript.spec.def - $(RM) $@ && $(LN_S) dmscript/dmscript.spec.def $@ -libdmscript.a: dmscript/dmscript.spec.def - $(DLLTOOL) -k -l $@ -d dmscript/dmscript.spec.def - -libdmstyle.def: dmstyle/dmstyle.spec.def - $(RM) $@ && $(LN_S) dmstyle/dmstyle.spec.def $@ -libdmstyle.a: dmstyle/dmstyle.spec.def - $(DLLTOOL) -k -l $@ -d dmstyle/dmstyle.spec.def - -libdmsynth.def: dmsynth/dmsynth.spec.def - $(RM) $@ && $(LN_S) dmsynth/dmsynth.spec.def $@ -libdmsynth.a: dmsynth/dmsynth.spec.def - $(DLLTOOL) -k -l $@ -d dmsynth/dmsynth.spec.def - -libdmusic.def: dmusic/dmusic.spec.def - $(RM) $@ && $(LN_S) dmusic/dmusic.spec.def $@ -libdmusic.a: dmusic/dmusic.spec.def - $(DLLTOOL) -k -l $@ -d dmusic/dmusic.spec.def - -libdmusic32.def: dmusic32/dmusic32.spec.def - $(RM) $@ && $(LN_S) dmusic32/dmusic32.spec.def $@ -libdmusic32.a: dmusic32/dmusic32.spec.def - $(DLLTOOL) -k -l $@ -d dmusic32/dmusic32.spec.def - -libdplay.def: dplay/dplay.spec.def - $(RM) $@ && $(LN_S) dplay/dplay.spec.def $@ -libdplay.a: dplay/dplay.spec.def - $(DLLTOOL) -k -l $@ -d dplay/dplay.spec.def - -libdplayx.def: dplayx/dplayx.spec.def - $(RM) $@ && $(LN_S) dplayx/dplayx.spec.def $@ -libdplayx.a: dplayx/dplayx.spec.def - $(DLLTOOL) -k -l $@ -d dplayx/dplayx.spec.def - -libdpnet.def: dpnet/dpnet.spec.def - $(RM) $@ && $(LN_S) dpnet/dpnet.spec.def $@ -libdpnet.a: dpnet/dpnet.spec.def - $(DLLTOOL) -k -l $@ -d dpnet/dpnet.spec.def - -libdpnhpast.def: dpnhpast/dpnhpast.spec.def - $(RM) $@ && $(LN_S) dpnhpast/dpnhpast.spec.def $@ -libdpnhpast.a: dpnhpast/dpnhpast.spec.def - $(DLLTOOL) -k -l $@ -d dpnhpast/dpnhpast.spec.def - -libdsound.def: dsound/dsound.spec.def - $(RM) $@ && $(LN_S) dsound/dsound.spec.def $@ -libdsound.a: dsound/dsound.spec.def - $(DLLTOOL) -k -l $@ -d dsound/dsound.spec.def - -libdswave.def: dswave/dswave.spec.def - $(RM) $@ && $(LN_S) dswave/dswave.spec.def $@ -libdswave.a: dswave/dswave.spec.def - $(DLLTOOL) -k -l $@ -d dswave/dswave.spec.def - -libdxdiagn.def: dxdiagn/dxdiagn.spec.def - $(RM) $@ && $(LN_S) dxdiagn/dxdiagn.spec.def $@ -libdxdiagn.a: dxdiagn/dxdiagn.spec.def - $(DLLTOOL) -k -l $@ -d dxdiagn/dxdiagn.spec.def - -libgdi32.def: gdi/gdi32.spec.def - $(RM) $@ && $(LN_S) gdi/gdi32.spec.def $@ -libgdi32.a: gdi/gdi32.spec.def - $(DLLTOOL) -k -l $@ -d gdi/gdi32.spec.def - -libglu32.def: glu32/glu32.spec.def - $(RM) $@ && $(LN_S) glu32/glu32.spec.def $@ -libglu32.a: glu32/glu32.spec.def - $(DLLTOOL) -k -l $@ -d glu32/glu32.spec.def - -libglut32.def: glut32/glut32.spec.def - $(RM) $@ && $(LN_S) glut32/glut32.spec.def $@ -libglut32.a: glut32/glut32.spec.def - $(DLLTOOL) -k -l $@ -d glut32/glut32.spec.def - -libiccvid.def: iccvid/iccvid.spec.def - $(RM) $@ && $(LN_S) iccvid/iccvid.spec.def $@ -libiccvid.a: iccvid/iccvid.spec.def - $(DLLTOOL) -k -l $@ -d iccvid/iccvid.spec.def - -libicmp.def: icmp/icmp.spec.def - $(RM) $@ && $(LN_S) icmp/icmp.spec.def $@ -libicmp.a: icmp/icmp.spec.def - $(DLLTOOL) -k -l $@ -d icmp/icmp.spec.def - -libimagehlp.def: imagehlp/imagehlp.spec.def - $(RM) $@ && $(LN_S) imagehlp/imagehlp.spec.def $@ -libimagehlp.a: imagehlp/imagehlp.spec.def - $(DLLTOOL) -k -l $@ -d imagehlp/imagehlp.spec.def - -libimm32.def: imm32/imm32.spec.def - $(RM) $@ && $(LN_S) imm32/imm32.spec.def $@ -libimm32.a: imm32/imm32.spec.def - $(DLLTOOL) -k -l $@ -d imm32/imm32.spec.def - -libiphlpapi.def: iphlpapi/iphlpapi.spec.def - $(RM) $@ && $(LN_S) iphlpapi/iphlpapi.spec.def $@ -libiphlpapi.a: iphlpapi/iphlpapi.spec.def - $(DLLTOOL) -k -l $@ -d iphlpapi/iphlpapi.spec.def - -libitss.def: itss/itss.spec.def - $(RM) $@ && $(LN_S) itss/itss.spec.def $@ -libitss.a: itss/itss.spec.def - $(DLLTOOL) -k -l $@ -d itss/itss.spec.def - -libkernel32.def: kernel/kernel32.spec.def - $(RM) $@ && $(LN_S) kernel/kernel32.spec.def $@ -libkernel32.a: kernel/kernel32.spec.def - $(DLLTOOL) -k -l $@ -d kernel/kernel32.spec.def - -liblz32.def: lzexpand/lz32.spec.def - $(RM) $@ && $(LN_S) lzexpand/lz32.spec.def $@ -liblz32.a: lzexpand/lz32.spec.def - $(DLLTOOL) -k -l $@ -d lzexpand/lz32.spec.def - -libmapi32.def: mapi32/mapi32.spec.def - $(RM) $@ && $(LN_S) mapi32/mapi32.spec.def $@ -libmapi32.a: mapi32/mapi32.spec.def - $(DLLTOOL) -k -l $@ -d mapi32/mapi32.spec.def - -libmlang.def: mlang/mlang.spec.def - $(RM) $@ && $(LN_S) mlang/mlang.spec.def $@ -libmlang.a: mlang/mlang.spec.def - $(DLLTOOL) -k -l $@ -d mlang/mlang.spec.def - -libmpr.def: mpr/mpr.spec.def - $(RM) $@ && $(LN_S) mpr/mpr.spec.def $@ -libmpr.a: mpr/mpr.spec.def - $(DLLTOOL) -k -l $@ -d mpr/mpr.spec.def - -libmsacm32.def: msacm/msacm32.spec.def - $(RM) $@ && $(LN_S) msacm/msacm32.spec.def $@ -libmsacm32.a: msacm/msacm32.spec.def - $(DLLTOOL) -k -l $@ -d msacm/msacm32.spec.def - -libmscms.def: mscms/mscms.spec.def - $(RM) $@ && $(LN_S) mscms/mscms.spec.def $@ -libmscms.a: mscms/mscms.spec.def - $(DLLTOOL) -k -l $@ -d mscms/mscms.spec.def - -libmsdmo.def: msdmo/msdmo.spec.def - $(RM) $@ && $(LN_S) msdmo/msdmo.spec.def $@ -libmsdmo.a: msdmo/msdmo.spec.def - $(DLLTOOL) -k -l $@ -d msdmo/msdmo.spec.def - -libmshtml.def: mshtml/mshtml.spec.def - $(RM) $@ && $(LN_S) mshtml/mshtml.spec.def $@ -libmshtml.a: mshtml/mshtml.spec.def - $(DLLTOOL) -k -l $@ -d mshtml/mshtml.spec.def - -libmsi.def: msi/msi.spec.def - $(RM) $@ && $(LN_S) msi/msi.spec.def $@ -libmsi.a: msi/msi.spec.def - $(DLLTOOL) -k -l $@ -d msi/msi.spec.def - -libmsimg32.def: msimg32/msimg32.spec.def - $(RM) $@ && $(LN_S) msimg32/msimg32.spec.def $@ -libmsimg32.a: msimg32/msimg32.spec.def - $(DLLTOOL) -k -l $@ -d msimg32/msimg32.spec.def - -libmsnet32.def: msnet32/msnet32.spec.def - $(RM) $@ && $(LN_S) msnet32/msnet32.spec.def $@ -libmsnet32.a: msnet32/msnet32.spec.def - $(DLLTOOL) -k -l $@ -d msnet32/msnet32.spec.def - -libmsrle32.def: msrle32/msrle32.spec.def - $(RM) $@ && $(LN_S) msrle32/msrle32.spec.def $@ -libmsrle32.a: msrle32/msrle32.spec.def - $(DLLTOOL) -k -l $@ -d msrle32/msrle32.spec.def - -libmsvcrt.def: msvcrt/msvcrt.spec.def - $(RM) $@ && $(LN_S) msvcrt/msvcrt.spec.def $@ -libmsvcrt.a: msvcrt/msvcrt.spec.def - $(DLLTOOL) -k -l $@ -d msvcrt/msvcrt.spec.def - -libmsvcrt20.def: msvcrt20/msvcrt20.spec.def - $(RM) $@ && $(LN_S) msvcrt20/msvcrt20.spec.def $@ -libmsvcrt20.a: msvcrt20/msvcrt20.spec.def - $(DLLTOOL) -k -l $@ -d msvcrt20/msvcrt20.spec.def - -libmsvcrt40.def: msvcrt40/msvcrt40.spec.def - $(RM) $@ && $(LN_S) msvcrt40/msvcrt40.spec.def $@ -libmsvcrt40.a: msvcrt40/msvcrt40.spec.def - $(DLLTOOL) -k -l $@ -d msvcrt40/msvcrt40.spec.def - -libmsvcrtd.def: msvcrtd/msvcrtd.spec.def - $(RM) $@ && $(LN_S) msvcrtd/msvcrtd.spec.def $@ -libmsvcrtd.a: msvcrtd/msvcrtd.spec.def - $(DLLTOOL) -k -l $@ -d msvcrtd/msvcrtd.spec.def - -libmsvfw32.def: msvideo/msvfw32.spec.def - $(RM) $@ && $(LN_S) msvideo/msvfw32.spec.def $@ -libmsvfw32.a: msvideo/msvfw32.spec.def - $(DLLTOOL) -k -l $@ -d msvideo/msvfw32.spec.def - -libmsvidc32.def: msvidc32/msvidc32.spec.def - $(RM) $@ && $(LN_S) msvidc32/msvidc32.spec.def $@ -libmsvidc32.a: msvidc32/msvidc32.spec.def - $(DLLTOOL) -k -l $@ -d msvidc32/msvidc32.spec.def - -libmswsock.def: mswsock/mswsock.spec.def - $(RM) $@ && $(LN_S) mswsock/mswsock.spec.def $@ -libmswsock.a: mswsock/mswsock.spec.def - $(DLLTOOL) -k -l $@ -d mswsock/mswsock.spec.def - -libnetapi32.def: netapi32/netapi32.spec.def - $(RM) $@ && $(LN_S) netapi32/netapi32.spec.def $@ -libnetapi32.a: netapi32/netapi32.spec.def - $(DLLTOOL) -k -l $@ -d netapi32/netapi32.spec.def - -libnewdev.def: newdev/newdev.spec.def - $(RM) $@ && $(LN_S) newdev/newdev.spec.def $@ -libnewdev.a: newdev/newdev.spec.def - $(DLLTOOL) -k -l $@ -d newdev/newdev.spec.def - -libntdll.def: ntdll/ntdll.spec.def - $(RM) $@ && $(LN_S) ntdll/ntdll.spec.def $@ -libntdll.a: ntdll/ntdll.spec.def - $(DLLTOOL) -k -l $@ -d ntdll/ntdll.spec.def - -libodbc32.def: odbc32/odbc32.spec.def - $(RM) $@ && $(LN_S) odbc32/odbc32.spec.def $@ -libodbc32.a: odbc32/odbc32.spec.def - $(DLLTOOL) -k -l $@ -d odbc32/odbc32.spec.def - -libole32.def: ole32/ole32.spec.def - $(RM) $@ && $(LN_S) ole32/ole32.spec.def $@ -libole32.a: ole32/ole32.spec.def - $(DLLTOOL) -k -l $@ -d ole32/ole32.spec.def - -liboleacc.def: oleacc/oleacc.spec.def - $(RM) $@ && $(LN_S) oleacc/oleacc.spec.def $@ -liboleacc.a: oleacc/oleacc.spec.def - $(DLLTOOL) -k -l $@ -d oleacc/oleacc.spec.def - -liboleaut32.def: oleaut32/oleaut32.spec.def - $(RM) $@ && $(LN_S) oleaut32/oleaut32.spec.def $@ -liboleaut32.a: oleaut32/oleaut32.spec.def - $(DLLTOOL) -k -l $@ -d oleaut32/oleaut32.spec.def - -libolecli32.def: olecli/olecli32.spec.def - $(RM) $@ && $(LN_S) olecli/olecli32.spec.def $@ -libolecli32.a: olecli/olecli32.spec.def - $(DLLTOOL) -k -l $@ -d olecli/olecli32.spec.def - -liboledlg.def: oledlg/oledlg.spec.def - $(RM) $@ && $(LN_S) oledlg/oledlg.spec.def $@ -liboledlg.a: oledlg/oledlg.spec.def - $(DLLTOOL) -k -l $@ -d oledlg/oledlg.spec.def - -libolepro32.def: olepro32/olepro32.spec.def - $(RM) $@ && $(LN_S) olepro32/olepro32.spec.def $@ -libolepro32.a: olepro32/olepro32.spec.def - $(DLLTOOL) -k -l $@ -d olepro32/olepro32.spec.def - -libolesvr32.def: olesvr/olesvr32.spec.def - $(RM) $@ && $(LN_S) olesvr/olesvr32.spec.def $@ -libolesvr32.a: olesvr/olesvr32.spec.def - $(DLLTOOL) -k -l $@ -d olesvr/olesvr32.spec.def - -libopengl32.def: opengl32/opengl32.spec.def - $(RM) $@ && $(LN_S) opengl32/opengl32.spec.def $@ -libopengl32.a: opengl32/opengl32.spec.def - $(DLLTOOL) -k -l $@ -d opengl32/opengl32.spec.def - -libpsapi.def: psapi/psapi.spec.def - $(RM) $@ && $(LN_S) psapi/psapi.spec.def $@ -libpsapi.a: psapi/psapi.spec.def - $(DLLTOOL) -k -l $@ -d psapi/psapi.spec.def - -libqcap.def: qcap/qcap.spec.def - $(RM) $@ && $(LN_S) qcap/qcap.spec.def $@ -libqcap.a: qcap/qcap.spec.def - $(DLLTOOL) -k -l $@ -d qcap/qcap.spec.def - -libquartz.def: quartz/quartz.spec.def - $(RM) $@ && $(LN_S) quartz/quartz.spec.def $@ -libquartz.a: quartz/quartz.spec.def - $(DLLTOOL) -k -l $@ -d quartz/quartz.spec.def - -librasapi32.def: rasapi32/rasapi32.spec.def - $(RM) $@ && $(LN_S) rasapi32/rasapi32.spec.def $@ -librasapi32.a: rasapi32/rasapi32.spec.def - $(DLLTOOL) -k -l $@ -d rasapi32/rasapi32.spec.def - -libriched20.def: riched20/riched20.spec.def - $(RM) $@ && $(LN_S) riched20/riched20.spec.def $@ -libriched20.a: riched20/riched20.spec.def - $(DLLTOOL) -k -l $@ -d riched20/riched20.spec.def - -libriched32.def: richedit/riched32.spec.def - $(RM) $@ && $(LN_S) richedit/riched32.spec.def $@ -libriched32.a: richedit/riched32.spec.def - $(DLLTOOL) -k -l $@ -d richedit/riched32.spec.def - -librpcrt4.def: rpcrt4/rpcrt4.spec.def - $(RM) $@ && $(LN_S) rpcrt4/rpcrt4.spec.def $@ -librpcrt4.a: rpcrt4/rpcrt4.spec.def - $(DLLTOOL) -k -l $@ -d rpcrt4/rpcrt4.spec.def - -librsabase.def: rsabase/rsabase.spec.def - $(RM) $@ && $(LN_S) rsabase/rsabase.spec.def $@ -librsabase.a: rsabase/rsabase.spec.def - $(DLLTOOL) -k -l $@ -d rsabase/rsabase.spec.def - -librsaenh.def: rsaenh/rsaenh.spec.def - $(RM) $@ && $(LN_S) rsaenh/rsaenh.spec.def $@ -librsaenh.a: rsaenh/rsaenh.spec.def - $(DLLTOOL) -k -l $@ -d rsaenh/rsaenh.spec.def - -libsecur32.def: secur32/secur32.spec.def - $(RM) $@ && $(LN_S) secur32/secur32.spec.def $@ -libsecur32.a: secur32/secur32.spec.def - $(DLLTOOL) -k -l $@ -d secur32/secur32.spec.def - -libsensapi.def: sensapi/sensapi.spec.def - $(RM) $@ && $(LN_S) sensapi/sensapi.spec.def $@ -libsensapi.a: sensapi/sensapi.spec.def - $(DLLTOOL) -k -l $@ -d sensapi/sensapi.spec.def - -libserialui.def: serialui/serialui.spec.def - $(RM) $@ && $(LN_S) serialui/serialui.spec.def $@ -libserialui.a: serialui/serialui.spec.def - $(DLLTOOL) -k -l $@ -d serialui/serialui.spec.def - -libsetupapi.def: setupapi/setupapi.spec.def - $(RM) $@ && $(LN_S) setupapi/setupapi.spec.def $@ -libsetupapi.a: setupapi/setupapi.spec.def - $(DLLTOOL) -k -l $@ -d setupapi/setupapi.spec.def - -libshdocvw.def: shdocvw/shdocvw.spec.def - $(RM) $@ && $(LN_S) shdocvw/shdocvw.spec.def $@ -libshdocvw.a: shdocvw/shdocvw.spec.def - $(DLLTOOL) -k -l $@ -d shdocvw/shdocvw.spec.def - -libshell32.def: shell32/shell32.spec.def - $(RM) $@ && $(LN_S) shell32/shell32.spec.def $@ -libshell32.a: shell32/shell32.spec.def - $(DLLTOOL) -k -l $@ -d shell32/shell32.spec.def - -libshfolder.def: shfolder/shfolder.spec.def - $(RM) $@ && $(LN_S) shfolder/shfolder.spec.def $@ -libshfolder.a: shfolder/shfolder.spec.def - $(DLLTOOL) -k -l $@ -d shfolder/shfolder.spec.def - -libshlwapi.def: shlwapi/shlwapi.spec.def - $(RM) $@ && $(LN_S) shlwapi/shlwapi.spec.def $@ -libshlwapi.a: shlwapi/shlwapi.spec.def - $(DLLTOOL) -k -l $@ -d shlwapi/shlwapi.spec.def - -libsnmpapi.def: snmpapi/snmpapi.spec.def - $(RM) $@ && $(LN_S) snmpapi/snmpapi.spec.def $@ -libsnmpapi.a: snmpapi/snmpapi.spec.def - $(DLLTOOL) -k -l $@ -d snmpapi/snmpapi.spec.def - -libsti.def: sti/sti.spec.def - $(RM) $@ && $(LN_S) sti/sti.spec.def $@ -libsti.a: sti/sti.spec.def - $(DLLTOOL) -k -l $@ -d sti/sti.spec.def - -libtapi32.def: tapi32/tapi32.spec.def - $(RM) $@ && $(LN_S) tapi32/tapi32.spec.def $@ -libtapi32.a: tapi32/tapi32.spec.def - $(DLLTOOL) -k -l $@ -d tapi32/tapi32.spec.def - -libttydrv.def: ttydrv/ttydrv.spec.def - $(RM) $@ && $(LN_S) ttydrv/ttydrv.spec.def $@ -libttydrv.a: ttydrv/ttydrv.spec.def - $(DLLTOOL) -k -l $@ -d ttydrv/ttydrv.spec.def - -libtwain_32.def: twain/twain_32.spec.def - $(RM) $@ && $(LN_S) twain/twain_32.spec.def $@ -libtwain_32.a: twain/twain_32.spec.def - $(DLLTOOL) -k -l $@ -d twain/twain_32.spec.def - -libunicows.def: unicows/unicows.spec.def - $(RM) $@ && $(LN_S) unicows/unicows.spec.def $@ -libunicows.a: unicows/unicows.spec.def - $(DLLTOOL) -k -l $@ -d unicows/unicows.spec.def - -liburl.def: url/url.spec.def - $(RM) $@ && $(LN_S) url/url.spec.def $@ -liburl.a: url/url.spec.def - $(DLLTOOL) -k -l $@ -d url/url.spec.def - -liburlmon.def: urlmon/urlmon.spec.def - $(RM) $@ && $(LN_S) urlmon/urlmon.spec.def $@ -liburlmon.a: urlmon/urlmon.spec.def - $(DLLTOOL) -k -l $@ -d urlmon/urlmon.spec.def - -libuser32.def: user/user32.spec.def - $(RM) $@ && $(LN_S) user/user32.spec.def $@ -libuser32.a: user/user32.spec.def - $(DLLTOOL) -k -l $@ -d user/user32.spec.def - -libuxtheme.def: uxtheme/uxtheme.spec.def - $(RM) $@ && $(LN_S) uxtheme/uxtheme.spec.def $@ -libuxtheme.a: uxtheme/uxtheme.spec.def - $(DLLTOOL) -k -l $@ -d uxtheme/uxtheme.spec.def - -libvdmdbg.def: vdmdbg/vdmdbg.spec.def - $(RM) $@ && $(LN_S) vdmdbg/vdmdbg.spec.def $@ -libvdmdbg.a: vdmdbg/vdmdbg.spec.def - $(DLLTOOL) -k -l $@ -d vdmdbg/vdmdbg.spec.def - -libversion.def: version/version.spec.def - $(RM) $@ && $(LN_S) version/version.spec.def $@ -libversion.a: version/version.spec.def - $(DLLTOOL) -k -l $@ -d version/version.spec.def - -libw32skrnl.def: win32s/w32skrnl.spec.def - $(RM) $@ && $(LN_S) win32s/w32skrnl.spec.def $@ -libw32skrnl.a: win32s/w32skrnl.spec.def - $(DLLTOOL) -k -l $@ -d win32s/w32skrnl.spec.def - -libwined3d.def: wined3d/wined3d.spec.def - $(RM) $@ && $(LN_S) wined3d/wined3d.spec.def $@ -libwined3d.a: wined3d/wined3d.spec.def - $(DLLTOOL) -k -l $@ -d wined3d/wined3d.spec.def - -libwinedos.def: winedos/winedos.spec.def - $(RM) $@ && $(LN_S) winedos/winedos.spec.def $@ -libwinedos.a: winedos/winedos.spec.def - $(DLLTOOL) -k -l $@ -d winedos/winedos.spec.def - -libwineps.def: wineps/wineps.spec.def - $(RM) $@ && $(LN_S) wineps/wineps.spec.def $@ -libwineps.a: wineps/wineps.spec.def - $(DLLTOOL) -k -l $@ -d wineps/wineps.spec.def - -libwininet.def: wininet/wininet.spec.def - $(RM) $@ && $(LN_S) wininet/wininet.spec.def $@ -libwininet.a: wininet/wininet.spec.def - $(DLLTOOL) -k -l $@ -d wininet/wininet.spec.def - -libwinmm.def: winmm/winmm.spec.def - $(RM) $@ && $(LN_S) winmm/winmm.spec.def $@ -libwinmm.a: winmm/winmm.spec.def - $(DLLTOOL) -k -l $@ -d winmm/winmm.spec.def - -libwinnls32.def: winnls/winnls32.spec.def - $(RM) $@ && $(LN_S) winnls/winnls32.spec.def $@ -libwinnls32.a: winnls/winnls32.spec.def - $(DLLTOOL) -k -l $@ -d winnls/winnls32.spec.def - -libwinspool.def: winspool/winspool.drv.spec.def - $(RM) $@ && $(LN_S) winspool/winspool.drv.spec.def $@ -libwinspool.a: winspool/winspool.drv.spec.def - $(DLLTOOL) -k -l $@ -d winspool/winspool.drv.spec.def - -libwintab32.def: wintab32/wintab32.spec.def - $(RM) $@ && $(LN_S) wintab32/wintab32.spec.def $@ -libwintab32.a: wintab32/wintab32.spec.def - $(DLLTOOL) -k -l $@ -d wintab32/wintab32.spec.def - -libwintrust.def: wintrust/wintrust.spec.def - $(RM) $@ && $(LN_S) wintrust/wintrust.spec.def $@ -libwintrust.a: wintrust/wintrust.spec.def - $(DLLTOOL) -k -l $@ -d wintrust/wintrust.spec.def - -libwnaspi32.def: winaspi/wnaspi32.spec.def - $(RM) $@ && $(LN_S) winaspi/wnaspi32.spec.def $@ -libwnaspi32.a: winaspi/wnaspi32.spec.def - $(DLLTOOL) -k -l $@ -d winaspi/wnaspi32.spec.def - -libwow32.def: wow32/wow32.spec.def - $(RM) $@ && $(LN_S) wow32/wow32.spec.def $@ -libwow32.a: wow32/wow32.spec.def - $(DLLTOOL) -k -l $@ -d wow32/wow32.spec.def - -libws2_32.def: winsock/ws2_32.spec.def - $(RM) $@ && $(LN_S) winsock/ws2_32.spec.def $@ -libws2_32.a: winsock/ws2_32.spec.def - $(DLLTOOL) -k -l $@ -d winsock/ws2_32.spec.def - -libwsock32.def: wsock32/wsock32.spec.def - $(RM) $@ && $(LN_S) wsock32/wsock32.spec.def $@ -libwsock32.a: wsock32/wsock32.spec.def - $(DLLTOOL) -k -l $@ -d wsock32/wsock32.spec.def - -libwtsapi32.def: wtsapi32/wtsapi32.spec.def - $(RM) $@ && $(LN_S) wtsapi32/wtsapi32.spec.def $@ -libwtsapi32.a: wtsapi32/wtsapi32.spec.def - $(DLLTOOL) -k -l $@ -d wtsapi32/wtsapi32.spec.def - -libx11drv.def: x11drv/x11drv.spec.def - $(RM) $@ && $(LN_S) x11drv/x11drv.spec.def $@ -libx11drv.a: x11drv/x11drv.spec.def - $(DLLTOOL) -k -l $@ -d x11drv/x11drv.spec.def - -advapi32/advapi32.spec.def: $(WINEBUILD) -advpack/advpack.spec.def: $(WINEBUILD) -amstream/amstream.spec.def: $(WINEBUILD) -atl/atl.spec.def: $(WINEBUILD) -avicap32/avicap32.spec.def: $(WINEBUILD) -avifil32/avifil32.spec.def: $(WINEBUILD) -cabinet/cabinet.spec.def: $(WINEBUILD) -capi2032/capi2032.spec.def: $(WINEBUILD) -cards/cards.spec.def: $(WINEBUILD) -cfgmgr32/cfgmgr32.spec.def: $(WINEBUILD) -comcat/comcat.spec.def: $(WINEBUILD) -comctl32/comctl32.spec.def: $(WINEBUILD) -commdlg/comdlg32.spec.def: $(WINEBUILD) -crtdll/crtdll.spec.def: $(WINEBUILD) -crypt32/crypt32.spec.def: $(WINEBUILD) -cryptdll/cryptdll.spec.def: $(WINEBUILD) -ctl3d/ctl3d32.spec.def: $(WINEBUILD) -d3d8/d3d8.spec.def: $(WINEBUILD) -d3d9/d3d9.spec.def: $(WINEBUILD) -d3dim/d3dim.spec.def: $(WINEBUILD) -d3drm/d3drm.spec.def: $(WINEBUILD) -d3dx8/d3dx8.spec.def: $(WINEBUILD) -d3dxof/d3dxof.spec.def: $(WINEBUILD) -dbghelp/dbghelp.spec.def: $(WINEBUILD) -dciman32/dciman32.spec.def: $(WINEBUILD) -ddraw/ddraw.spec.def: $(WINEBUILD) -devenum/devenum.spec.def: $(WINEBUILD) -dinput/dinput.spec.def: $(WINEBUILD) -dinput8/dinput8.spec.def: $(WINEBUILD) -dmband/dmband.spec.def: $(WINEBUILD) -dmcompos/dmcompos.spec.def: $(WINEBUILD) -dmime/dmime.spec.def: $(WINEBUILD) -dmloader/dmloader.spec.def: $(WINEBUILD) -dmscript/dmscript.spec.def: $(WINEBUILD) -dmstyle/dmstyle.spec.def: $(WINEBUILD) -dmsynth/dmsynth.spec.def: $(WINEBUILD) -dmusic/dmusic.spec.def: $(WINEBUILD) -dmusic32/dmusic32.spec.def: $(WINEBUILD) -dplay/dplay.spec.def: $(WINEBUILD) -dplayx/dplayx.spec.def: $(WINEBUILD) -dpnet/dpnet.spec.def: $(WINEBUILD) -dpnhpast/dpnhpast.spec.def: $(WINEBUILD) -dsound/dsound.spec.def: $(WINEBUILD) -dswave/dswave.spec.def: $(WINEBUILD) -dxdiagn/dxdiagn.spec.def: $(WINEBUILD) -gdi/gdi32.spec.def: $(WINEBUILD) -glu32/glu32.spec.def: $(WINEBUILD) -glut32/glut32.spec.def: $(WINEBUILD) -iccvid/iccvid.spec.def: $(WINEBUILD) -icmp/icmp.spec.def: $(WINEBUILD) -imagehlp/imagehlp.spec.def: $(WINEBUILD) -imm32/imm32.spec.def: $(WINEBUILD) -iphlpapi/iphlpapi.spec.def: $(WINEBUILD) -itss/itss.spec.def: $(WINEBUILD) -kernel/kernel32.spec.def: $(WINEBUILD) -lzexpand/lz32.spec.def: $(WINEBUILD) -mapi32/mapi32.spec.def: $(WINEBUILD) -mlang/mlang.spec.def: $(WINEBUILD) -mpr/mpr.spec.def: $(WINEBUILD) -msacm/msacm32.spec.def: $(WINEBUILD) -mscms/mscms.spec.def: $(WINEBUILD) -msdmo/msdmo.spec.def: $(WINEBUILD) -mshtml/mshtml.spec.def: $(WINEBUILD) -msi/msi.spec.def: $(WINEBUILD) -msimg32/msimg32.spec.def: $(WINEBUILD) -msnet32/msnet32.spec.def: $(WINEBUILD) -msrle32/msrle32.spec.def: $(WINEBUILD) -msvcrt/msvcrt.spec.def: $(WINEBUILD) -msvcrt20/msvcrt20.spec.def: $(WINEBUILD) -msvcrt40/msvcrt40.spec.def: $(WINEBUILD) -msvcrtd/msvcrtd.spec.def: $(WINEBUILD) -msvideo/msvfw32.spec.def: $(WINEBUILD) -msvidc32/msvidc32.spec.def: $(WINEBUILD) -mswsock/mswsock.spec.def: $(WINEBUILD) -netapi32/netapi32.spec.def: $(WINEBUILD) -newdev/newdev.spec.def: $(WINEBUILD) -ntdll/ntdll.spec.def: $(WINEBUILD) -odbc32/odbc32.spec.def: $(WINEBUILD) -ole32/ole32.spec.def: $(WINEBUILD) -oleacc/oleacc.spec.def: $(WINEBUILD) -oleaut32/oleaut32.spec.def: $(WINEBUILD) -olecli/olecli32.spec.def: $(WINEBUILD) -oledlg/oledlg.spec.def: $(WINEBUILD) -olepro32/olepro32.spec.def: $(WINEBUILD) -olesvr/olesvr32.spec.def: $(WINEBUILD) -opengl32/opengl32.spec.def: $(WINEBUILD) -psapi/psapi.spec.def: $(WINEBUILD) -qcap/qcap.spec.def: $(WINEBUILD) -quartz/quartz.spec.def: $(WINEBUILD) -rasapi32/rasapi32.spec.def: $(WINEBUILD) -riched20/riched20.spec.def: $(WINEBUILD) -richedit/riched32.spec.def: $(WINEBUILD) -rpcrt4/rpcrt4.spec.def: $(WINEBUILD) -rsabase/rsabase.spec.def: $(WINEBUILD) -rsaenh/rsaenh.spec.def: $(WINEBUILD) -secur32/secur32.spec.def: $(WINEBUILD) -sensapi/sensapi.spec.def: $(WINEBUILD) -serialui/serialui.spec.def: $(WINEBUILD) -setupapi/setupapi.spec.def: $(WINEBUILD) -shdocvw/shdocvw.spec.def: $(WINEBUILD) -shell32/shell32.spec.def: $(WINEBUILD) -shfolder/shfolder.spec.def: $(WINEBUILD) -shlwapi/shlwapi.spec.def: $(WINEBUILD) -snmpapi/snmpapi.spec.def: $(WINEBUILD) -sti/sti.spec.def: $(WINEBUILD) -tapi32/tapi32.spec.def: $(WINEBUILD) -ttydrv/ttydrv.spec.def: $(WINEBUILD) -twain/twain_32.spec.def: $(WINEBUILD) -unicows/unicows.spec.def: $(WINEBUILD) -url/url.spec.def: $(WINEBUILD) -urlmon/urlmon.spec.def: $(WINEBUILD) -user/user32.spec.def: $(WINEBUILD) -uxtheme/uxtheme.spec.def: $(WINEBUILD) -vdmdbg/vdmdbg.spec.def: $(WINEBUILD) -version/version.spec.def: $(WINEBUILD) -win32s/w32skrnl.spec.def: $(WINEBUILD) -wined3d/wined3d.spec.def: $(WINEBUILD) -winedos/winedos.spec.def: $(WINEBUILD) -wineps/wineps.spec.def: $(WINEBUILD) -wininet/wininet.spec.def: $(WINEBUILD) -winmm/winmm.spec.def: $(WINEBUILD) -winnls/winnls32.spec.def: $(WINEBUILD) -winspool/winspool.drv.spec.def: $(WINEBUILD) -wintab32/wintab32.spec.def: $(WINEBUILD) -wintrust/wintrust.spec.def: $(WINEBUILD) -winaspi/wnaspi32.spec.def: $(WINEBUILD) -wow32/wow32.spec.def: $(WINEBUILD) -winsock/ws2_32.spec.def: $(WINEBUILD) -wsock32/wsock32.spec.def: $(WINEBUILD) -wtsapi32/wtsapi32.spec.def: $(WINEBUILD) -x11drv/x11drv.spec.def: $(WINEBUILD) +advapi32/libadvapi32.$(IMPLIBEXT): advapi32/advapi32.spec $(WINEBUILD) + @cd advapi32 && $(MAKE) libadvapi32.$(IMPLIBEXT) + +advpack/libadvpack.$(IMPLIBEXT): advpack/advpack.spec $(WINEBUILD) + @cd advpack && $(MAKE) libadvpack.$(IMPLIBEXT) + +amstream/libamstream.$(IMPLIBEXT): amstream/amstream.spec $(WINEBUILD) + @cd amstream && $(MAKE) libamstream.$(IMPLIBEXT) + +atl/libatl.$(IMPLIBEXT): atl/atl.spec $(WINEBUILD) + @cd atl && $(MAKE) libatl.$(IMPLIBEXT) + +avicap32/libavicap32.$(IMPLIBEXT): avicap32/avicap32.spec $(WINEBUILD) + @cd avicap32 && $(MAKE) libavicap32.$(IMPLIBEXT) + +avifil32/libavifil32.$(IMPLIBEXT): avifil32/avifil32.spec $(WINEBUILD) + @cd avifil32 && $(MAKE) libavifil32.$(IMPLIBEXT) + +cabinet/libcabinet.$(IMPLIBEXT): cabinet/cabinet.spec $(WINEBUILD) + @cd cabinet && $(MAKE) libcabinet.$(IMPLIBEXT) + +capi2032/libcapi2032.$(IMPLIBEXT): capi2032/capi2032.spec $(WINEBUILD) + @cd capi2032 && $(MAKE) libcapi2032.$(IMPLIBEXT) + +cards/libcards.$(IMPLIBEXT): cards/cards.spec $(WINEBUILD) + @cd cards && $(MAKE) libcards.$(IMPLIBEXT) + +cfgmgr32/libcfgmgr32.$(IMPLIBEXT): cfgmgr32/cfgmgr32.spec $(WINEBUILD) + @cd cfgmgr32 && $(MAKE) libcfgmgr32.$(IMPLIBEXT) + +comcat/libcomcat.$(IMPLIBEXT): comcat/comcat.spec $(WINEBUILD) + @cd comcat && $(MAKE) libcomcat.$(IMPLIBEXT) + +comctl32/libcomctl32.$(IMPLIBEXT): comctl32/comctl32.spec $(WINEBUILD) + @cd comctl32 && $(MAKE) libcomctl32.$(IMPLIBEXT) + +commdlg/libcomdlg32.$(IMPLIBEXT): commdlg/comdlg32.spec $(WINEBUILD) + @cd commdlg && $(MAKE) libcomdlg32.$(IMPLIBEXT) + +crtdll/libcrtdll.$(IMPLIBEXT): crtdll/crtdll.spec $(WINEBUILD) + @cd crtdll && $(MAKE) libcrtdll.$(IMPLIBEXT) + +crypt32/libcrypt32.$(IMPLIBEXT): crypt32/crypt32.spec $(WINEBUILD) + @cd crypt32 && $(MAKE) libcrypt32.$(IMPLIBEXT) + +cryptdll/libcryptdll.$(IMPLIBEXT): cryptdll/cryptdll.spec $(WINEBUILD) + @cd cryptdll && $(MAKE) libcryptdll.$(IMPLIBEXT) + +ctl3d/libctl3d32.$(IMPLIBEXT): ctl3d/ctl3d32.spec $(WINEBUILD) + @cd ctl3d && $(MAKE) libctl3d32.$(IMPLIBEXT) + +d3d8/libd3d8.$(IMPLIBEXT): d3d8/d3d8.spec $(WINEBUILD) + @cd d3d8 && $(MAKE) libd3d8.$(IMPLIBEXT) + +d3d9/libd3d9.$(IMPLIBEXT): d3d9/d3d9.spec $(WINEBUILD) + @cd d3d9 && $(MAKE) libd3d9.$(IMPLIBEXT) + +d3dim/libd3dim.$(IMPLIBEXT): d3dim/d3dim.spec $(WINEBUILD) + @cd d3dim && $(MAKE) libd3dim.$(IMPLIBEXT) + +d3drm/libd3drm.$(IMPLIBEXT): d3drm/d3drm.spec $(WINEBUILD) + @cd d3drm && $(MAKE) libd3drm.$(IMPLIBEXT) + +d3dx8/libd3dx8.$(IMPLIBEXT): d3dx8/d3dx8.spec $(WINEBUILD) + @cd d3dx8 && $(MAKE) libd3dx8.$(IMPLIBEXT) + +d3dxof/libd3dxof.$(IMPLIBEXT): d3dxof/d3dxof.spec $(WINEBUILD) + @cd d3dxof && $(MAKE) libd3dxof.$(IMPLIBEXT) + +dbghelp/libdbghelp.$(IMPLIBEXT): dbghelp/dbghelp.spec $(WINEBUILD) + @cd dbghelp && $(MAKE) libdbghelp.$(IMPLIBEXT) + +dciman32/libdciman32.$(IMPLIBEXT): dciman32/dciman32.spec $(WINEBUILD) + @cd dciman32 && $(MAKE) libdciman32.$(IMPLIBEXT) + +ddraw/libddraw.$(IMPLIBEXT): ddraw/ddraw.spec $(WINEBUILD) + @cd ddraw && $(MAKE) libddraw.$(IMPLIBEXT) + +devenum/libdevenum.$(IMPLIBEXT): devenum/devenum.spec $(WINEBUILD) + @cd devenum && $(MAKE) libdevenum.$(IMPLIBEXT) + +dinput/libdinput.$(IMPLIBEXT): dinput/dinput.spec $(WINEBUILD) + @cd dinput && $(MAKE) libdinput.$(IMPLIBEXT) + +dinput/libdinput.$(STATIC_IMPLIBEXT): dummy + @cd dinput && $(MAKE) libdinput.$(STATIC_IMPLIBEXT) + +dinput8/libdinput8.$(IMPLIBEXT): dinput8/dinput8.spec $(WINEBUILD) + @cd dinput8 && $(MAKE) libdinput8.$(IMPLIBEXT) + +dmband/libdmband.$(IMPLIBEXT): dmband/dmband.spec $(WINEBUILD) + @cd dmband && $(MAKE) libdmband.$(IMPLIBEXT) + +dmcompos/libdmcompos.$(IMPLIBEXT): dmcompos/dmcompos.spec $(WINEBUILD) + @cd dmcompos && $(MAKE) libdmcompos.$(IMPLIBEXT) + +dmime/libdmime.$(IMPLIBEXT): dmime/dmime.spec $(WINEBUILD) + @cd dmime && $(MAKE) libdmime.$(IMPLIBEXT) + +dmloader/libdmloader.$(IMPLIBEXT): dmloader/dmloader.spec $(WINEBUILD) + @cd dmloader && $(MAKE) libdmloader.$(IMPLIBEXT) + +dmscript/libdmscript.$(IMPLIBEXT): dmscript/dmscript.spec $(WINEBUILD) + @cd dmscript && $(MAKE) libdmscript.$(IMPLIBEXT) + +dmstyle/libdmstyle.$(IMPLIBEXT): dmstyle/dmstyle.spec $(WINEBUILD) + @cd dmstyle && $(MAKE) libdmstyle.$(IMPLIBEXT) + +dmsynth/libdmsynth.$(IMPLIBEXT): dmsynth/dmsynth.spec $(WINEBUILD) + @cd dmsynth && $(MAKE) libdmsynth.$(IMPLIBEXT) + +dmusic/libdmusic.$(IMPLIBEXT): dmusic/dmusic.spec $(WINEBUILD) + @cd dmusic && $(MAKE) libdmusic.$(IMPLIBEXT) + +dmusic32/libdmusic32.$(IMPLIBEXT): dmusic32/dmusic32.spec $(WINEBUILD) + @cd dmusic32 && $(MAKE) libdmusic32.$(IMPLIBEXT) + +dplay/libdplay.$(IMPLIBEXT): dplay/dplay.spec $(WINEBUILD) + @cd dplay && $(MAKE) libdplay.$(IMPLIBEXT) + +dplayx/libdplayx.$(IMPLIBEXT): dplayx/dplayx.spec $(WINEBUILD) + @cd dplayx && $(MAKE) libdplayx.$(IMPLIBEXT) + +dpnet/libdpnet.$(IMPLIBEXT): dpnet/dpnet.spec $(WINEBUILD) + @cd dpnet && $(MAKE) libdpnet.$(IMPLIBEXT) + +dpnhpast/libdpnhpast.$(IMPLIBEXT): dpnhpast/dpnhpast.spec $(WINEBUILD) + @cd dpnhpast && $(MAKE) libdpnhpast.$(IMPLIBEXT) + +dsound/libdsound.$(IMPLIBEXT): dsound/dsound.spec $(WINEBUILD) + @cd dsound && $(MAKE) libdsound.$(IMPLIBEXT) + +dswave/libdswave.$(IMPLIBEXT): dswave/dswave.spec $(WINEBUILD) + @cd dswave && $(MAKE) libdswave.$(IMPLIBEXT) + +dxdiagn/libdxdiagn.$(IMPLIBEXT): dxdiagn/dxdiagn.spec $(WINEBUILD) + @cd dxdiagn && $(MAKE) libdxdiagn.$(IMPLIBEXT) + +gdi/libgdi32.$(IMPLIBEXT): gdi/gdi32.spec $(WINEBUILD) + @cd gdi && $(MAKE) libgdi32.$(IMPLIBEXT) + +glu32/libglu32.$(IMPLIBEXT): glu32/glu32.spec $(WINEBUILD) + @cd glu32 && $(MAKE) libglu32.$(IMPLIBEXT) + +glut32/libglut32.$(IMPLIBEXT): glut32/glut32.spec $(WINEBUILD) + @cd glut32 && $(MAKE) libglut32.$(IMPLIBEXT) + +iccvid/libiccvid.$(IMPLIBEXT): iccvid/iccvid.spec $(WINEBUILD) + @cd iccvid && $(MAKE) libiccvid.$(IMPLIBEXT) + +icmp/libicmp.$(IMPLIBEXT): icmp/icmp.spec $(WINEBUILD) + @cd icmp && $(MAKE) libicmp.$(IMPLIBEXT) + +imagehlp/libimagehlp.$(IMPLIBEXT): imagehlp/imagehlp.spec $(WINEBUILD) + @cd imagehlp && $(MAKE) libimagehlp.$(IMPLIBEXT) + +imm32/libimm32.$(IMPLIBEXT): imm32/imm32.spec $(WINEBUILD) + @cd imm32 && $(MAKE) libimm32.$(IMPLIBEXT) + +iphlpapi/libiphlpapi.$(IMPLIBEXT): iphlpapi/iphlpapi.spec $(WINEBUILD) + @cd iphlpapi && $(MAKE) libiphlpapi.$(IMPLIBEXT) + +itss/libitss.$(IMPLIBEXT): itss/itss.spec $(WINEBUILD) + @cd itss && $(MAKE) libitss.$(IMPLIBEXT) + +kernel/libkernel32.$(IMPLIBEXT): kernel/kernel32.spec $(WINEBUILD) + @cd kernel && $(MAKE) libkernel32.$(IMPLIBEXT) + +lzexpand/liblz32.$(IMPLIBEXT): lzexpand/lz32.spec $(WINEBUILD) + @cd lzexpand && $(MAKE) liblz32.$(IMPLIBEXT) + +mapi32/libmapi32.$(IMPLIBEXT): mapi32/mapi32.spec $(WINEBUILD) + @cd mapi32 && $(MAKE) libmapi32.$(IMPLIBEXT) + +mlang/libmlang.$(IMPLIBEXT): mlang/mlang.spec $(WINEBUILD) + @cd mlang && $(MAKE) libmlang.$(IMPLIBEXT) + +mpr/libmpr.$(IMPLIBEXT): mpr/mpr.spec $(WINEBUILD) + @cd mpr && $(MAKE) libmpr.$(IMPLIBEXT) + +msacm/libmsacm32.$(IMPLIBEXT): msacm/msacm32.spec $(WINEBUILD) + @cd msacm && $(MAKE) libmsacm32.$(IMPLIBEXT) + +mscms/libmscms.$(IMPLIBEXT): mscms/mscms.spec $(WINEBUILD) + @cd mscms && $(MAKE) libmscms.$(IMPLIBEXT) + +msdmo/libmsdmo.$(IMPLIBEXT): msdmo/msdmo.spec $(WINEBUILD) + @cd msdmo && $(MAKE) libmsdmo.$(IMPLIBEXT) + +mshtml/libmshtml.$(IMPLIBEXT): mshtml/mshtml.spec $(WINEBUILD) + @cd mshtml && $(MAKE) libmshtml.$(IMPLIBEXT) + +msi/libmsi.$(IMPLIBEXT): msi/msi.spec $(WINEBUILD) + @cd msi && $(MAKE) libmsi.$(IMPLIBEXT) + +msimg32/libmsimg32.$(IMPLIBEXT): msimg32/msimg32.spec $(WINEBUILD) + @cd msimg32 && $(MAKE) libmsimg32.$(IMPLIBEXT) + +msnet32/libmsnet32.$(IMPLIBEXT): msnet32/msnet32.spec $(WINEBUILD) + @cd msnet32 && $(MAKE) libmsnet32.$(IMPLIBEXT) + +msrle32/libmsrle32.$(IMPLIBEXT): msrle32/msrle32.spec $(WINEBUILD) + @cd msrle32 && $(MAKE) libmsrle32.$(IMPLIBEXT) + +msvcrt/libmsvcrt.$(IMPLIBEXT): msvcrt/msvcrt.spec $(WINEBUILD) + @cd msvcrt && $(MAKE) libmsvcrt.$(IMPLIBEXT) + +msvcrt20/libmsvcrt20.$(IMPLIBEXT): msvcrt20/msvcrt20.spec $(WINEBUILD) + @cd msvcrt20 && $(MAKE) libmsvcrt20.$(IMPLIBEXT) + +msvcrt40/libmsvcrt40.$(IMPLIBEXT): msvcrt40/msvcrt40.spec $(WINEBUILD) + @cd msvcrt40 && $(MAKE) libmsvcrt40.$(IMPLIBEXT) + +msvcrtd/libmsvcrtd.$(IMPLIBEXT): msvcrtd/msvcrtd.spec $(WINEBUILD) + @cd msvcrtd && $(MAKE) libmsvcrtd.$(IMPLIBEXT) + +msvideo/libmsvfw32.$(IMPLIBEXT): msvideo/msvfw32.spec $(WINEBUILD) + @cd msvideo && $(MAKE) libmsvfw32.$(IMPLIBEXT) + +msvidc32/libmsvidc32.$(IMPLIBEXT): msvidc32/msvidc32.spec $(WINEBUILD) + @cd msvidc32 && $(MAKE) libmsvidc32.$(IMPLIBEXT) + +mswsock/libmswsock.$(IMPLIBEXT): mswsock/mswsock.spec $(WINEBUILD) + @cd mswsock && $(MAKE) libmswsock.$(IMPLIBEXT) + +netapi32/libnetapi32.$(IMPLIBEXT): netapi32/netapi32.spec $(WINEBUILD) + @cd netapi32 && $(MAKE) libnetapi32.$(IMPLIBEXT) + +newdev/libnewdev.$(IMPLIBEXT): newdev/newdev.spec $(WINEBUILD) + @cd newdev && $(MAKE) libnewdev.$(IMPLIBEXT) + +ntdll/libntdll.$(IMPLIBEXT): ntdll/ntdll.spec $(WINEBUILD) + @cd ntdll && $(MAKE) libntdll.$(IMPLIBEXT) + +odbc32/libodbc32.$(IMPLIBEXT): odbc32/odbc32.spec $(WINEBUILD) + @cd odbc32 && $(MAKE) libodbc32.$(IMPLIBEXT) + +odbccp32/libodbccp32.$(IMPLIBEXT): odbccp32/odbccp32.spec $(WINEBUILD) + @cd odbccp32 && $(MAKE) libodbccp32.$(IMPLIBEXT) + +ole32/libole32.$(IMPLIBEXT): ole32/ole32.spec $(WINEBUILD) + @cd ole32 && $(MAKE) libole32.$(IMPLIBEXT) + +oleacc/liboleacc.$(IMPLIBEXT): oleacc/oleacc.spec $(WINEBUILD) + @cd oleacc && $(MAKE) liboleacc.$(IMPLIBEXT) + +oleaut32/liboleaut32.$(IMPLIBEXT): oleaut32/oleaut32.spec $(WINEBUILD) + @cd oleaut32 && $(MAKE) liboleaut32.$(IMPLIBEXT) + +olecli/libolecli32.$(IMPLIBEXT): olecli/olecli32.spec $(WINEBUILD) + @cd olecli && $(MAKE) libolecli32.$(IMPLIBEXT) + +oledlg/liboledlg.$(IMPLIBEXT): oledlg/oledlg.spec $(WINEBUILD) + @cd oledlg && $(MAKE) liboledlg.$(IMPLIBEXT) + +olepro32/libolepro32.$(IMPLIBEXT): olepro32/olepro32.spec $(WINEBUILD) + @cd olepro32 && $(MAKE) libolepro32.$(IMPLIBEXT) + +olesvr/libolesvr32.$(IMPLIBEXT): olesvr/olesvr32.spec $(WINEBUILD) + @cd olesvr && $(MAKE) libolesvr32.$(IMPLIBEXT) + +opengl32/libopengl32.$(IMPLIBEXT): opengl32/opengl32.spec $(WINEBUILD) + @cd opengl32 && $(MAKE) libopengl32.$(IMPLIBEXT) + +powrprof/libpowrprof.$(IMPLIBEXT): powrprof/powrprof.spec $(WINEBUILD) + @cd powrprof && $(MAKE) libpowrprof.$(IMPLIBEXT) + +psapi/libpsapi.$(IMPLIBEXT): psapi/psapi.spec $(WINEBUILD) + @cd psapi && $(MAKE) libpsapi.$(IMPLIBEXT) + +qcap/libqcap.$(IMPLIBEXT): qcap/qcap.spec $(WINEBUILD) + @cd qcap && $(MAKE) libqcap.$(IMPLIBEXT) + +quartz/libquartz.$(IMPLIBEXT): quartz/quartz.spec $(WINEBUILD) + @cd quartz && $(MAKE) libquartz.$(IMPLIBEXT) + +rasapi32/librasapi32.$(IMPLIBEXT): rasapi32/rasapi32.spec $(WINEBUILD) + @cd rasapi32 && $(MAKE) librasapi32.$(IMPLIBEXT) + +riched20/libriched20.$(IMPLIBEXT): riched20/riched20.spec $(WINEBUILD) + @cd riched20 && $(MAKE) libriched20.$(IMPLIBEXT) + +richedit/libriched32.$(IMPLIBEXT): richedit/riched32.spec $(WINEBUILD) + @cd richedit && $(MAKE) libriched32.$(IMPLIBEXT) + +rpcrt4/librpcrt4.$(IMPLIBEXT): rpcrt4/rpcrt4.spec $(WINEBUILD) + @cd rpcrt4 && $(MAKE) librpcrt4.$(IMPLIBEXT) + +rsabase/librsabase.$(IMPLIBEXT): rsabase/rsabase.spec $(WINEBUILD) + @cd rsabase && $(MAKE) librsabase.$(IMPLIBEXT) + +rsaenh/librsaenh.$(IMPLIBEXT): rsaenh/rsaenh.spec $(WINEBUILD) + @cd rsaenh && $(MAKE) librsaenh.$(IMPLIBEXT) + +secur32/libsecur32.$(IMPLIBEXT): secur32/secur32.spec $(WINEBUILD) + @cd secur32 && $(MAKE) libsecur32.$(IMPLIBEXT) + +sensapi/libsensapi.$(IMPLIBEXT): sensapi/sensapi.spec $(WINEBUILD) + @cd sensapi && $(MAKE) libsensapi.$(IMPLIBEXT) + +serialui/libserialui.$(IMPLIBEXT): serialui/serialui.spec $(WINEBUILD) + @cd serialui && $(MAKE) libserialui.$(IMPLIBEXT) + +setupapi/libsetupapi.$(IMPLIBEXT): setupapi/setupapi.spec $(WINEBUILD) + @cd setupapi && $(MAKE) libsetupapi.$(IMPLIBEXT) + +shdocvw/libshdocvw.$(IMPLIBEXT): shdocvw/shdocvw.spec $(WINEBUILD) + @cd shdocvw && $(MAKE) libshdocvw.$(IMPLIBEXT) + +shell32/libshell32.$(IMPLIBEXT): shell32/shell32.spec $(WINEBUILD) + @cd shell32 && $(MAKE) libshell32.$(IMPLIBEXT) + +shfolder/libshfolder.$(IMPLIBEXT): shfolder/shfolder.spec $(WINEBUILD) + @cd shfolder && $(MAKE) libshfolder.$(IMPLIBEXT) + +shlwapi/libshlwapi.$(IMPLIBEXT): shlwapi/shlwapi.spec $(WINEBUILD) + @cd shlwapi && $(MAKE) libshlwapi.$(IMPLIBEXT) + +snmpapi/libsnmpapi.$(IMPLIBEXT): snmpapi/snmpapi.spec $(WINEBUILD) + @cd snmpapi && $(MAKE) libsnmpapi.$(IMPLIBEXT) + +sti/libsti.$(IMPLIBEXT): sti/sti.spec $(WINEBUILD) + @cd sti && $(MAKE) libsti.$(IMPLIBEXT) + +tapi32/libtapi32.$(IMPLIBEXT): tapi32/tapi32.spec $(WINEBUILD) + @cd tapi32 && $(MAKE) libtapi32.$(IMPLIBEXT) + +twain/libtwain_32.$(IMPLIBEXT): twain/twain_32.spec $(WINEBUILD) + @cd twain && $(MAKE) libtwain_32.$(IMPLIBEXT) + +unicows/libunicows.$(IMPLIBEXT): unicows/unicows.spec $(WINEBUILD) + @cd unicows && $(MAKE) libunicows.$(IMPLIBEXT) + +url/liburl.$(IMPLIBEXT): url/url.spec $(WINEBUILD) + @cd url && $(MAKE) liburl.$(IMPLIBEXT) + +urlmon/liburlmon.$(IMPLIBEXT): urlmon/urlmon.spec $(WINEBUILD) + @cd urlmon && $(MAKE) liburlmon.$(IMPLIBEXT) + +user/libuser32.$(IMPLIBEXT): user/user32.spec $(WINEBUILD) + @cd user && $(MAKE) libuser32.$(IMPLIBEXT) + +uxtheme/libuxtheme.$(IMPLIBEXT): uxtheme/uxtheme.spec $(WINEBUILD) + @cd uxtheme && $(MAKE) libuxtheme.$(IMPLIBEXT) + +vdmdbg/libvdmdbg.$(IMPLIBEXT): vdmdbg/vdmdbg.spec $(WINEBUILD) + @cd vdmdbg && $(MAKE) libvdmdbg.$(IMPLIBEXT) + +version/libversion.$(IMPLIBEXT): version/version.spec $(WINEBUILD) + @cd version && $(MAKE) libversion.$(IMPLIBEXT) + +win32s/libw32skrnl.$(IMPLIBEXT): win32s/w32skrnl.spec $(WINEBUILD) + @cd win32s && $(MAKE) libw32skrnl.$(IMPLIBEXT) + +wined3d/libwined3d.$(IMPLIBEXT): wined3d/wined3d.spec $(WINEBUILD) + @cd wined3d && $(MAKE) libwined3d.$(IMPLIBEXT) + +winedos/libwinedos.$(IMPLIBEXT): winedos/winedos.spec $(WINEBUILD) + @cd winedos && $(MAKE) libwinedos.$(IMPLIBEXT) + +wininet/libwininet.$(IMPLIBEXT): wininet/wininet.spec $(WINEBUILD) + @cd wininet && $(MAKE) libwininet.$(IMPLIBEXT) + +winmm/libwinmm.$(IMPLIBEXT): winmm/winmm.spec $(WINEBUILD) + @cd winmm && $(MAKE) libwinmm.$(IMPLIBEXT) + +winnls/libwinnls32.$(IMPLIBEXT): winnls/winnls32.spec $(WINEBUILD) + @cd winnls && $(MAKE) libwinnls32.$(IMPLIBEXT) + +winspool/libwinspool.$(IMPLIBEXT): winspool/winspool.drv.spec $(WINEBUILD) + @cd winspool && $(MAKE) libwinspool.$(IMPLIBEXT) + +wintab32/libwintab32.$(IMPLIBEXT): wintab32/wintab32.spec $(WINEBUILD) + @cd wintab32 && $(MAKE) libwintab32.$(IMPLIBEXT) + +wintrust/libwintrust.$(IMPLIBEXT): wintrust/wintrust.spec $(WINEBUILD) + @cd wintrust && $(MAKE) libwintrust.$(IMPLIBEXT) + +winaspi/libwnaspi32.$(IMPLIBEXT): winaspi/wnaspi32.spec $(WINEBUILD) + @cd winaspi && $(MAKE) libwnaspi32.$(IMPLIBEXT) + +wow32/libwow32.$(IMPLIBEXT): wow32/wow32.spec $(WINEBUILD) + @cd wow32 && $(MAKE) libwow32.$(IMPLIBEXT) + +winsock/libws2_32.$(IMPLIBEXT): winsock/ws2_32.spec $(WINEBUILD) + @cd winsock && $(MAKE) libws2_32.$(IMPLIBEXT) + +wsock32/libwsock32.$(IMPLIBEXT): wsock32/wsock32.spec $(WINEBUILD) + @cd wsock32 && $(MAKE) libwsock32.$(IMPLIBEXT) + +wtsapi32/libwtsapi32.$(IMPLIBEXT): wtsapi32/wtsapi32.spec $(WINEBUILD) + @cd wtsapi32 && $(MAKE) libwtsapi32.$(IMPLIBEXT) + +libcomdlg32.$(IMPLIBEXT): commdlg/libcomdlg32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) commdlg/libcomdlg32.$(IMPLIBEXT) $@ + +libctl3d32.$(IMPLIBEXT): ctl3d/libctl3d32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) ctl3d/libctl3d32.$(IMPLIBEXT) $@ + +libgdi32.$(IMPLIBEXT): gdi/libgdi32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) gdi/libgdi32.$(IMPLIBEXT) $@ + +libkernel32.$(IMPLIBEXT): kernel/libkernel32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) kernel/libkernel32.$(IMPLIBEXT) $@ + +liblz32.$(IMPLIBEXT): lzexpand/liblz32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) lzexpand/liblz32.$(IMPLIBEXT) $@ + +libmsacm32.$(IMPLIBEXT): msacm/libmsacm32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) msacm/libmsacm32.$(IMPLIBEXT) $@ + +libmsvfw32.$(IMPLIBEXT): msvideo/libmsvfw32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) msvideo/libmsvfw32.$(IMPLIBEXT) $@ + +libntdll.$(IMPLIBEXT): ntdll/libntdll.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) ntdll/libntdll.$(IMPLIBEXT) $@ + +libolecli32.$(IMPLIBEXT): olecli/libolecli32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) olecli/libolecli32.$(IMPLIBEXT) $@ + +libolesvr32.$(IMPLIBEXT): olesvr/libolesvr32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) olesvr/libolesvr32.$(IMPLIBEXT) $@ + +libriched32.$(IMPLIBEXT): richedit/libriched32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) richedit/libriched32.$(IMPLIBEXT) $@ + +libtwain_32.$(IMPLIBEXT): twain/libtwain_32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) twain/libtwain_32.$(IMPLIBEXT) $@ + +libuser32.$(IMPLIBEXT): user/libuser32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) user/libuser32.$(IMPLIBEXT) $@ + +libw32skrnl.$(IMPLIBEXT): win32s/libw32skrnl.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) win32s/libw32skrnl.$(IMPLIBEXT) $@ + +libwinnls32.$(IMPLIBEXT): winnls/libwinnls32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) winnls/libwinnls32.$(IMPLIBEXT) $@ + +libwnaspi32.$(IMPLIBEXT): winaspi/libwnaspi32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) winaspi/libwnaspi32.$(IMPLIBEXT) $@ + +libws2_32.$(IMPLIBEXT): winsock/libws2_32.$(IMPLIBEXT) + $(RM) $@ && $(LN_S) winsock/libws2_32.$(IMPLIBEXT) $@ $(BUILDSUBDIRS): $(IMPORT_LIBS) -$(INSTALLSUBDIRS:%=%/__install__): $(IMPORT_LIBS) +$(INSTALLSUBDIRS:%=%/__install__) $(INSTALLSUBDIRS:%=%/__install-lib__): $(IMPORT_LIBS) # Map library name to the corresponding directory @@ -2032,6 +1724,7 @@ newdev/newdev.dll.so: newdev ntdll/ntdll.dll.so: ntdll odbc32/odbc32.dll.so: odbc32 +odbccp32/odbccp32.dll.so: odbccp32 ole32/ole32.dll.so: ole32 oleacc/oleacc.dll.so: oleacc oleaut32/oleaut32.dll.so: oleaut32 @@ -2040,6 +1733,7 @@ olepro32/olepro32.dll.so: olepro32 olesvr/olesvr32.dll.so: olesvr opengl32/opengl32.dll.so: opengl32 +powrprof/powrprof.dll.so: powrprof psapi/psapi.dll.so: psapi qcap/qcap.dll.so: qcap quartz/quartz.dll.so: quartz @@ -2061,7 +1755,6 @@ stdole32.tlb/stdole32.tlb.so: stdole32.tlb sti/sti.dll.so: sti tapi32/tapi32.dll.so: tapi32 -ttydrv/ttydrv.dll.so: ttydrv twain/twain_32.dll.so: twain unicows/unicows.dll.so: unicows url/url.dll.so: url @@ -2086,7 +1779,9 @@ msacm/winemp3/winemp3.acm.so: msacm/winemp3 winmm/winenas/winenas.drv.so: winmm/winenas winmm/wineoss/wineoss.drv.so: winmm/wineoss -wineps/wineps.dll.so: wineps +wineps/wineps.drv.so: wineps +ttydrv/winetty.drv.so: ttydrv +x11drv/winex11.drv.so: x11drv wininet/wininet.dll.so: wininet winmm/winmm.dll.so: winmm winnls/winnls32.dll.so: winnls @@ -2098,7 +1793,6 @@ winsock/ws2_32.dll.so: winsock wsock32/wsock32.dll.so: wsock32 wtsapi32/wtsapi32.dll.so: wtsapi32 -x11drv/x11drv.dll.so: x11drv dxerr8/libdxerr8.a: dxerr8 dxerr9/libdxerr9.a: dxerr9 dxguid/libdxguid.a: dxguid @@ -2126,18 +1820,15 @@ # Misc rules -install install-dev:: $(IMPORT_LIBS) - $(MKINSTALLDIRS) $(dlldir) - for f in $(IMPORT_LIBS); do $(INSTALL_DATA) $$f $(dlldir)/$$f; done +install-lib:: $(INSTALLSUBDIRS:%=%/__install-lib__) -install install-lib:: $(INSTALLSUBDIRS:%=%/__install__) +install-dev:: $(INSTALLSUBDIRS:%=%/__install-dev__) uninstall:: - -cd $(dlldir) && $(RM) $(IMPORT_LIBS) -rmdir $(dlldir) clean:: - $(RM) $(IMPORT_LIBS) $(SYMLINKS) + $(RM) $(IMPORT_SYMLINKS) check test:: $(BUILDSUBDIRS:%=%/__test__) diff -urN wine-20050419/dlls/Maketest.rules.in wine-20050524/dlls/Maketest.rules.in --- wine-20050419/dlls/Maketest.rules.in 2005-03-16 21:02:17.000000000 +0100 +++ wine-20050524/dlls/Maketest.rules.in 2005-05-10 15:21:04.000000000 +0200 @@ -23,7 +23,7 @@ EXTRA_SRCS = $(TESTLIST) EXTRA_OBJS = $(TESTLIST:.c=.o) ALL_LIBS = $(IMPORTS:%=-l%) $(EXTRALIBS) $(LDFLAGS) $(LIBS) -IMPORTLIBS = $(IMPORTS:%=$(DLLDIR)/lib%.$(IMPLIBEXT)) +DLL_LDPATH = -L$(DLLDIR) $(IMPORTS:%=-L$(DLLDIR)/%) CROSSTEST = $(TESTDLL:%.dll=%)_crosstest.exe CROSSOBJS = $(C_SRCS:.c=.cross.o) $(RC_SRCS:.rc=.res.cross.o) $(TESTLIST:.c=.cross.o) @@ -36,8 +36,8 @@ # Rules for .so main module -$(MODULE).so: $(OBJS) $(RC_SRCS:.rc=.res) $(IMPORTLIBS) Makefile.in - $(WINEGCC) -B$(TOOLSDIR)/tools/winebuild -mconsole $(OBJS) $(RC_SRCS:.rc=.res) -o $@ $(LIBPORT) -L$(DLLDIR) -L$(LIBDIR) $(ALL_LIBS) +$(MODULE).so: $(OBJS) $(RC_SRCS:.rc=.res) Makefile.in + $(WINEGCC) -B$(TOOLSDIR)/tools/winebuild -mconsole $(OBJS) $(RC_SRCS:.rc=.res) -o $@ $(LIBPORT) $(DLL_LDPATH) -L$(LIBDIR) $(ALL_LIBS) # Rules for .exe main module diff -urN wine-20050419/dlls/advapi32/.cvsignore wine-20050524/dlls/advapi32/.cvsignore --- wine-20050419/dlls/advapi32/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/advapi32/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,3 +1,3 @@ Makefile advapi32.dll.dbg.c -advapi32.spec.def +libadvapi32.def diff -urN wine-20050419/dlls/advapi32/Makefile.in wine-20050524/dlls/advapi32/Makefile.in --- wine-20050419/dlls/advapi32/Makefile.in 2004-10-06 20:53:29.000000000 +0200 +++ wine-20050524/dlls/advapi32/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = advapi32.dll +IMPORTLIB = libadvapi32.$(IMPLIBEXT) IMPORTS = kernel32 ntdll EXTRALIBS = $(LIBUNICODE) diff -urN wine-20050419/dlls/advapi32/advapi32.spec wine-20050524/dlls/advapi32/advapi32.spec --- wine-20050419/dlls/advapi32/advapi32.spec 2005-03-07 12:00:24.000000000 +0100 +++ wine-20050524/dlls/advapi32/advapi32.spec 2005-05-23 14:08:00.000000000 +0200 @@ -271,6 +271,8 @@ @ stdcall RegisterEventSourceW(ptr ptr) @ stdcall RegisterServiceCtrlHandlerA (ptr ptr) @ stdcall RegisterServiceCtrlHandlerW (ptr ptr) +@ stdcall RegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) +@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) @ stdcall ReportEventA (long long long long ptr long long str ptr) @ stdcall ReportEventW (long long long long ptr long long wstr ptr) @ stdcall RevertToSelf() @@ -341,7 +343,7 @@ @ stub SystemFunction033 @ stub SystemFunction034 @ stub SystemFunction035 -@ stub SystemFunction036 +@ stdcall SystemFunction036(ptr long) # RtlGenRandom @ stdcall SystemFunction040(ptr long long) # RtlEncryptMemory @ stdcall SystemFunction041(ptr long long) # RtlDecryptMemory @ stub TraceEvent diff -urN wine-20050419/dlls/advapi32/crypt.c wine-20050524/dlls/advapi32/crypt.c --- wine-20050419/dlls/advapi32/crypt.c 2005-04-11 14:55:36.000000000 +0200 +++ wine-20050524/dlls/advapi32/crypt.c 2005-05-23 14:08:00.000000000 +0200 @@ -27,6 +27,10 @@ #include #include #include +#include +#include +#include +#include #include "crypt.h" #include "winnls.h" @@ -1891,6 +1895,39 @@ return result; } +/****************************************************************************** + * SystemFunction036 (ADVAPI32.@) + * + * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h + * + * PARAMS + * pbBufer [O] Pointer to memory to receive random bytes. + * dwLen [I] Number of random bytes to fetch. + */ + +BOOL WINAPI SystemFunction036(PVOID pbBuffer, ULONG dwLen) +{ + int dev_random; + + /* FIXME: /dev/urandom does not provide random numbers of a sufficient + * quality for cryptographic applications. /dev/random is much better, + * but it blocks if the kernel has not yet collected enough entropy for + * the request, which will suspend the calling thread for an indefinite + * amount of time. */ + dev_random = open("/dev/urandom", O_RDONLY); + if (dev_random != -1) + { + if (read(dev_random, pbBuffer, dwLen) == (ssize_t)dwLen) + { + close(dev_random); + return TRUE; + } + close(dev_random); + } + SetLastError(NTE_FAIL); + return FALSE; +} + /* These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory, in crypt32.dll. @@ -1899,6 +1936,8 @@ /****************************************************************************** * SystemFunction040 (ADVAPI32.@) * + * MSDN documents this function as RtlEncryptMemory. + * * PARAMS * memory [I/O] Pointer to memory to encrypt. * length [I] Length of region to encrypt in bytes. @@ -1912,7 +1951,7 @@ * If flags are specified when encrypting, the same flag value must be given * when decrypting the memory. */ -NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags) /* RtlEncryptMemory */ +NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags) { FIXME("(%p, %lx, %lx): stub [RtlEncryptMemory]\n", memory, length, flags); return STATUS_SUCCESS; @@ -1921,6 +1960,8 @@ /****************************************************************************** * SystemFunction041 (ADVAPI32.@) * + * MSDN documents this function as RtlDecryptMemory. + * * PARAMS * memory [I/O] Pointer to memory to decrypt. * length [I] Length of region to decrypt in bytes. @@ -1934,7 +1975,7 @@ * If flags are specified when encrypting, the same flag value must be given * when decrypting the memory. */ -NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags) /* RtlDecryptMemory */ +NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags) { FIXME("(%p, %lx, %lx): stub [RtlDecryptMemory]\n", memory, length, flags); return STATUS_SUCCESS; diff -urN wine-20050419/dlls/advapi32/eventlog.c wine-20050524/dlls/advapi32/eventlog.c --- wine-20050419/dlls/advapi32/eventlog.c 2005-03-23 14:09:27.000000000 +0100 +++ wine-20050524/dlls/advapi32/eventlog.c 2005-05-16 10:51:19.000000000 +0200 @@ -27,6 +27,8 @@ #include "winerror.h" #include "winreg.h" #include "winternl.h" +#include "wmistr.h" +#include "evntrace.h" #include "wine/debug.h" @@ -436,3 +438,33 @@ } return TRUE; } + +/****************************************************************************** + * RegisterTraceGuidsW [ADVAPI32.@] + * + */ +ULONG WINAPI RegisterTraceGuidsW( WMIDPREQUEST RequestAddress, + PVOID RequestContext, LPCGUID ControlGuid, ULONG GuidCount, + PTRACE_GUID_REGISTRATION TraceGuidReg, LPCWSTR MofImagePath, + LPCWSTR MofResourceName, PTRACEHANDLE RegistrationHandle ) +{ + FIXME("%p %p %p %lu %p %s %s %p\n", RequestAddress, RequestContext, + ControlGuid, GuidCount, TraceGuidReg, debugstr_w(MofImagePath), + debugstr_w(MofResourceName), RegistrationHandle); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +/****************************************************************************** + * RegisterTraceGuidsA [ADVAPI32.@] + * + */ +ULONG WINAPI RegisterTraceGuidsA( WMIDPREQUEST RequestAddress, + PVOID RequestContext, LPCGUID ControlGuid, ULONG GuidCount, + PTRACE_GUID_REGISTRATION TraceGuidReg, LPCSTR MofImagePath, + LPCSTR MofResourceName, PTRACEHANDLE RegistrationHandle ) +{ + FIXME("%p %p %p %lu %p %s %s %p\n", RequestAddress, RequestContext, + ControlGuid, GuidCount, TraceGuidReg, debugstr_a(MofImagePath), + debugstr_a(MofResourceName), RegistrationHandle); + return ERROR_CALL_NOT_IMPLEMENTED; +} diff -urN wine-20050419/dlls/advapi32/registry.c wine-20050524/dlls/advapi32/registry.c --- wine-20050419/dlls/advapi32/registry.c 2005-04-16 12:49:10.000000000 +0200 +++ wine-20050524/dlls/advapi32/registry.c 2005-05-16 16:08:11.000000000 +0200 @@ -35,10 +35,10 @@ #include "winreg.h" #include "winerror.h" #include "ntstatus.h" +#include "winternl.h" + #include "wine/unicode.h" -#include "wine/server.h" #include "wine/debug.h" -#include "winternl.h" WINE_DEFAULT_DEBUG_CHANNEL(reg); @@ -875,11 +875,7 @@ if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; - if (!*name) - { - ret = RtlNtStatusToDosError( NtDeleteKey( hkey ) ); - } - else if (!(ret = RegOpenKeyExW( hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp ))) + if (!(ret = RegOpenKeyExW( hkey, name, 0, DELETE, &tmp ))) { ret = RtlNtStatusToDosError( NtDeleteKey( tmp ) ); RegCloseKey( tmp ); @@ -898,6 +894,11 @@ * hkey [I] Handle to parent key containing the key to delete * name [I] Name of the key user hkey to delete * + * NOTES + * + * MSDN is wrong when it says that hkey must be opened with the DELETE access + * right. In reality, it opens a new handle with DELETE access. + * * RETURNS * Success: ERROR_SUCCESS * Failure: Error code @@ -911,11 +912,7 @@ if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; - if (!*name) - { - ret = RtlNtStatusToDosError( NtDeleteKey( hkey ) ); - } - else if (!(ret = RegOpenKeyExA( hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp ))) + if (!(ret = RegOpenKeyExA( hkey, name, 0, DELETE, &tmp ))) { if (!is_version_nt()) /* win95 does recursive key deletes */ { @@ -2035,32 +2032,23 @@ DWORD fdwNotifyFilter, HANDLE hEvent, BOOL fAsync ) { - LONG ret; + NTSTATUS status; + IO_STATUS_BLOCK iosb; - TRACE("(%p,%i,%ld,%p,%i)\n",hkey,fWatchSubTree,fdwNotifyFilter, - hEvent,fAsync); + hkey = get_special_root_hkey( hkey ); + if (!hkey) return ERROR_INVALID_HANDLE; - if( !fAsync ) - hEvent = CreateEventW(NULL, 0, 0, NULL); + TRACE("(%p,%i,%ld,%p,%i)\n", hkey, fWatchSubTree, fdwNotifyFilter, + hEvent, fAsync); - SERVER_START_REQ( set_registry_notification ) - { - req->hkey = hkey; - req->event = hEvent; - req->subtree = fWatchSubTree; - req->filter = fdwNotifyFilter; - ret = RtlNtStatusToDosError( wine_server_call(req) ); - } - SERVER_END_REQ; - - if( !fAsync ) - { - if( ret == ERROR_SUCCESS ) - WaitForSingleObject( hEvent, INFINITE ); - CloseHandle( hEvent ); - } + status = NtNotifyChangeKey( hkey, hEvent, NULL, NULL, &iosb, + fdwNotifyFilter, fWatchSubTree, NULL, 0, + fAsync ); - return ret; + if (status && status != STATUS_TIMEOUT) + return RtlNtStatusToDosError( status ); + + return ERROR_SUCCESS; } /****************************************************************************** diff -urN wine-20050419/dlls/advapi32/security.c wine-20050524/dlls/advapi32/security.c --- wine-20050419/dlls/advapi32/security.c 2005-04-13 13:02:59.000000000 +0200 +++ wine-20050524/dlls/advapi32/security.c 2005-04-22 23:17:42.000000000 +0200 @@ -1673,6 +1673,9 @@ return TRUE; } +/****************************************************************************** + * LsaSetInformationPolicy [ADVAPI32.@] + */ NTSTATUS WINAPI LsaSetInformationPolicy( LSA_HANDLE PolicyHandle, @@ -1937,6 +1940,9 @@ return ret; } +/****************************************************************************** + * LookupAccountNameW [ADVAPI32.@] + */ BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid, LPDWORD cbSid, LPWSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse ) @@ -1952,10 +1958,15 @@ */ BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult) { - FIXME("stub %p %p %p\n", ClientToken, RequiredPrivileges, pfResult); - if (pfResult) - *pfResult=TRUE; - return TRUE; + BOOL ret; + BOOLEAN Result; + + TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult); + + ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result)); + if (ret) + *pfResult = Result; + return ret; } /****************************************************************************** @@ -2663,6 +2674,7 @@ WCHAR tok[MAX_PATH]; LPCWSTR lptoken; LPBYTE lpNext = NULL; + DWORD len; *cBytes = 0; @@ -2690,7 +2702,9 @@ if (*lptoken) lptoken--; - strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor); + len = lptoken - StringSecurityDescriptor; + memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) ); + tok[len] = 0; switch (toktype) { diff -urN wine-20050419/dlls/advapi32/tests/crypt.c wine-20050524/dlls/advapi32/tests/crypt.c --- wine-20050419/dlls/advapi32/tests/crypt.c 2005-04-15 18:12:14.000000000 +0200 +++ wine-20050524/dlls/advapi32/tests/crypt.c 2005-04-23 21:05:03.000000000 +0200 @@ -258,8 +258,10 @@ result = pCryptGenRandom(hProv, 1, &temp); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); +#ifdef CRASHES_ON_NT40 result = pCryptContextAddRef(hProv, NULL, 0); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); +#endif result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); @@ -275,11 +277,13 @@ result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); +#ifdef CRASHES_ON_NT40 result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2); ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); +#endif dwLen = 1; result = pCryptExportKey(hKey, (HCRYPTPROV)NULL, 0, 0, &temp, &dwLen); diff -urN wine-20050419/dlls/advpack/.cvsignore wine-20050524/dlls/advpack/.cvsignore --- wine-20050419/dlls/advpack/.cvsignore 2004-09-27 22:39:40.000000000 +0200 +++ wine-20050524/dlls/advpack/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,3 +1,3 @@ Makefile advpack.dll.dbg.c -advpack.spec.def +libadvpack.def diff -urN wine-20050419/dlls/advpack/Makefile.in wine-20050524/dlls/advpack/Makefile.in --- wine-20050419/dlls/advpack/Makefile.in 2005-01-20 21:03:13.000000000 +0100 +++ wine-20050524/dlls/advpack/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = advpack.dll +IMPORTLIB = libadvpack.$(IMPLIBEXT) IMPORTS = setupapi version user32 kernel32 ntdll EXTRALIBS = $(LIBUNICODE) diff -urN wine-20050419/dlls/advpack/advpack.c wine-20050524/dlls/advpack/advpack.c --- wine-20050419/dlls/advpack/advpack.c 2005-04-18 11:51:53.000000000 +0200 +++ wine-20050524/dlls/advpack/advpack.c 2005-04-27 11:37:25.000000000 +0200 @@ -2,6 +2,7 @@ * Advpack main * * Copyright 2004 Huw D M Davies + * Copyright 2005 Sami Aario * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -260,8 +261,71 @@ FreeLibrary(hm); } +static HRESULT DELNODE_recurse_dirtree(LPSTR fname, DWORD flags) +{ + DWORD fattrs = GetFileAttributesA(fname); + HRESULT ret = E_FAIL; + + if (fattrs & FILE_ATTRIBUTE_DIRECTORY) + { + HANDLE hFindFile; + WIN32_FIND_DATAA w32fd; + BOOL done = TRUE; + int fname_len = lstrlenA(fname); + + /* Generate a path with wildcard suitable for iterating */ + if (CharPrevA(fname, fname + fname_len) != "\\") + { + lstrcpyA(fname + fname_len, "\\"); + ++fname_len; + } + lstrcpyA(fname + fname_len, "*"); + + if ((hFindFile = FindFirstFileA(fname, &w32fd)) != INVALID_HANDLE_VALUE) + { + /* Iterate through the files in the directory */ + for (done = FALSE; !done; done = !FindNextFileA(hFindFile, &w32fd)) + { + TRACE("%s\n", w32fd.cFileName); + if (lstrcmpA(".", w32fd.cFileName) != 0 && + lstrcmpA("..", w32fd.cFileName) != 0) + { + lstrcpyA(fname + fname_len, w32fd.cFileName); + if (DELNODE_recurse_dirtree(fname, flags) != S_OK) + { + break; /* Failure */ + } + } + } + FindClose(hFindFile); + } + + /* We're done with this directory, so restore the old path without wildcard */ + *(fname + fname_len) = '\0'; + + if (done) + { + TRACE("%s: directory\n", fname); + if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && RemoveDirectoryA(fname)) + { + ret = S_OK; + } + } + } + else + { + TRACE("%s: file\n", fname); + if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && DeleteFileA(fname)) + { + ret = S_OK; + } + } + + return ret; +} + /*********************************************************************** - * DelNode (ADVPACK.@) + * DelNode (ADVPACK.@) * * Deletes a file or directory * @@ -274,12 +338,26 @@ * Failure: E_FAIL * * BUGS - * Unimplemented + * - Ignores flags + * - Native version apparently does a lot of checking to make sure + * we're not trying to delete a system directory etc. */ HRESULT WINAPI DelNode( LPCSTR pszFileOrDirName, DWORD dwFlags ) { - FIXME("(%s, 0x%08lx): stub\n", debugstr_a(pszFileOrDirName), dwFlags); - return E_FAIL; + CHAR fname[MAX_PATH]; + HRESULT ret = E_FAIL; + + FIXME("(%s, 0x%08lx): flags ignored\n", debugstr_a(pszFileOrDirName), dwFlags); + if (pszFileOrDirName && *pszFileOrDirName) + { + lstrcpyA(fname, pszFileOrDirName); + + /* TODO: Should check for system directory deletion etc. here */ + + ret = DELNODE_recurse_dirtree(fname, dwFlags); + } + + return ret; } /*********************************************************************** diff -urN wine-20050419/dlls/advpack/tests/advpack.c wine-20050524/dlls/advpack/tests/advpack.c --- wine-20050419/dlls/advpack/tests/advpack.c 2005-02-14 12:02:46.000000000 +0100 +++ wine-20050524/dlls/advpack/tests/advpack.c 2005-04-27 11:37:25.000000000 +0200 @@ -2,6 +2,7 @@ * Unit tests for advpack.dll * * Copyright (C) 2005 Robert Reif + * Copyright (C) 2005 Sami Aario * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,12 +21,11 @@ #include #include - +#include #include "wine/test.h" - static HRESULT (WINAPI *pGetVersionFromFile)(LPSTR,LPDWORD,LPDWORD,BOOL); - +static HRESULT (WINAPI *pDelNode)(LPCSTR,DWORD); static void version_test() { @@ -49,6 +49,68 @@ HIWORD(minor), LOWORD(minor)); } +static void delnode_test() +{ + HRESULT hr; + HANDLE hn; + CHAR currDir[MAX_PATH]; + int currDirLen; + + /* Native DelNode apparently does not support relative paths, so we use + absolute paths for testing */ + currDirLen = GetCurrentDirectoryA(sizeof(currDir) / sizeof(CHAR), currDir); + assert(currDirLen > 0 && currDirLen < sizeof(currDir) / sizeof(CHAR)); + + /* Simple tests; these should fail. */ + hr = pDelNode(NULL, 0); + ok (hr == E_FAIL, "DelNode called with NULL pathname should return E_FAIL\n"); + hr = pDelNode("", 0); + ok (hr == E_FAIL, "DelNode called with empty pathname should return E_FAIL\n"); + + /* Test deletion of a file. */ + hn = CreateFile("DelNodeTestFile1", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + assert(hn != INVALID_HANDLE_VALUE); + CloseHandle(hn); + hr = pDelNode(lstrcat(currDir, "\\DelNodeTestFile1"), 0); + ok (hr == S_OK, "DelNode failed deleting a single file\n"); + currDir[currDirLen] = '\0'; + + /* Test deletion of an empty directory. */ + CreateDirectoryA("DelNodeTestDir", NULL); + hr = pDelNode(lstrcat(currDir, "\\DelNodeTestDir"), 0); + ok (hr == S_OK, "DelNode failed deleting an empty directory\n"); + currDir[currDirLen] = '\0'; + + /* Test deletion of a directory containing one file. */ + CreateDirectoryA("DelNodeTestDir", NULL); + hn = CreateFile("DelNodeTestDir\\DelNodeTestFile1", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + assert(hn != INVALID_HANDLE_VALUE); + CloseHandle(hn); + hr = pDelNode(lstrcat(currDir, "\\DelNodeTestDir"), 0); + ok (hr == S_OK, "DelNode failed deleting a directory containing one file\n"); + currDir[currDirLen] = '\0'; + + /* Test deletion of a directory containing multiple files. */ + CreateDirectoryA("DelNodeTestDir", NULL); + hn = CreateFile("DelNodeTestDir\\DelNodeTestFile1", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + assert(hn != INVALID_HANDLE_VALUE); + CloseHandle(hn); + hn = CreateFile("DelNodeTestDir\\DelNodeTestFile2", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + assert(hn != INVALID_HANDLE_VALUE); + CloseHandle(hn); + hn = CreateFile("DelNodeTestDir\\DelNodeTestFile3", GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + assert(hn != INVALID_HANDLE_VALUE); + CloseHandle(hn); + hr = pDelNode(lstrcat(currDir, "\\DelNodeTestDir"), 0); + ok (hr == S_OK, "DelNode failed deleting a directory containing multiple files\n"); + currDir[currDirLen] = '\0'; +} + START_TEST(advpack) { HMODULE hdll; @@ -56,9 +118,14 @@ hdll = LoadLibraryA("advpack.dll"); if (!hdll) return; + pGetVersionFromFile = (void*)GetProcAddress(hdll, "GetVersionFromFile"); - if (!pGetVersionFromFile) + pDelNode = (void*)GetProcAddress(hdll, "DelNode"); + if (!pGetVersionFromFile || !pDelNode) return; version_test(); + delnode_test(); + + FreeLibrary(hdll); } diff -urN wine-20050419/dlls/amstream/.cvsignore wine-20050524/dlls/amstream/.cvsignore --- wine-20050419/dlls/amstream/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/amstream/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,4 +1,4 @@ Makefile amstream.dll.dbg.c -amstream.spec.def +libamstream.def version.res diff -urN wine-20050419/dlls/amstream/Makefile.in wine-20050524/dlls/amstream/Makefile.in --- wine-20050419/dlls/amstream/Makefile.in 2004-08-19 21:31:20.000000000 +0200 +++ wine-20050524/dlls/amstream/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = amstream.dll +IMPORTLIB = libamstream.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -lstrmiids -luuid diff -urN wine-20050419/dlls/atl/.cvsignore wine-20050524/dlls/atl/.cvsignore --- wine-20050419/dlls/atl/.cvsignore 2005-03-16 20:53:41.000000000 +0100 +++ wine-20050524/dlls/atl/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,5 +1,5 @@ Makefile atl.dll.dbg.c -atl.spec.def atliface.h +libatl.def rsrc.res diff -urN wine-20050419/dlls/atl/Makefile.in wine-20050524/dlls/atl/Makefile.in --- wine-20050419/dlls/atl/Makefile.in 2005-03-17 14:57:44.000000000 +0100 +++ wine-20050524/dlls/atl/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = atl.dll +IMPORTLIB = libatl.$(IMPLIBEXT) IMPORTS = ole32 shlwapi user32 advapi32 kernel32 EXTRALIBS = $(LIBUNICODE) -luuid diff -urN wine-20050419/dlls/atl/atl_main.c wine-20050524/dlls/atl/atl_main.c --- wine-20050419/dlls/atl/atl_main.c 2005-03-16 20:53:41.000000000 +0100 +++ wine-20050524/dlls/atl/atl_main.c 2005-04-22 21:04:18.000000000 +0200 @@ -32,6 +32,7 @@ #include "objidl.h" #include "ole2.h" #include "atlbase.h" +#include "atliface.h" WINE_DEFAULT_DEBUG_CHANNEL(atl); @@ -169,7 +170,7 @@ * */ HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW* pM, LPCOLESTR lpszRes, - BOOL bRegister, /* struct _ATL_REGMAP_ENTRY* */ void* pMapEntries, /* IRegistrar* */ void* pReg) + BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg) { HINSTANCE hInst = pM->m_hInst; /* everything inside this function below this point diff -urN wine-20050419/dlls/atl/atlbase.h wine-20050524/dlls/atl/atlbase.h --- wine-20050419/dlls/atl/atlbase.h 2004-09-28 05:14:11.000000000 +0200 +++ wine-20050524/dlls/atl/atlbase.h 2005-04-22 21:04:18.000000000 +0200 @@ -128,6 +128,12 @@ _ATL_CREATORARGFUNC* pFunc; } _ATL_INTMAP_ENTRY; +struct _ATL_REGMAP_ENTRY +{ + LPCOLESTR szKey; + LPCOLESTR szData; +}; + HRESULT WINAPI AtlModuleInit(_ATL_MODULEA* pM, _ATL_OBJMAP_ENTRYA* p, HINSTANCE h); HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEA* pM, DWORD dwClsContext, DWORD dwFlags); HRESULT WINAPI AtlModuleUnregisterServerEx(_ATL_MODULEA* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID); diff -urN wine-20050419/dlls/avicap32/.cvsignore wine-20050524/dlls/avicap32/.cvsignore --- wine-20050419/dlls/avicap32/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/avicap32/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,3 +1,3 @@ Makefile avicap32.dll.dbg.c -avicap32.spec.def +libavicap32.def diff -urN wine-20050419/dlls/avicap32/Makefile.in wine-20050524/dlls/avicap32/Makefile.in --- wine-20050419/dlls/avicap32/Makefile.in 2003-10-11 03:09:21.000000000 +0200 +++ wine-20050524/dlls/avicap32/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,7 +3,8 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = avicap32.dll -IMPORTS = ntdll +IMPORTLIB = libavicap32.$(IMPLIBEXT) +IMPORTS = kernel32 ntdll C_SRCS = avicap32_main.c diff -urN wine-20050419/dlls/avicap32/avicap32_main.c wine-20050524/dlls/avicap32/avicap32_main.c --- wine-20050419/dlls/avicap32/avicap32_main.c 2003-09-09 21:39:32.000000000 +0200 +++ wine-20050524/dlls/avicap32/avicap32_main.c 2005-04-27 11:46:25.000000000 +0200 @@ -1,5 +1,6 @@ /* * Copyright 2002 Dmitry Timoshkov for CodeWeavers + * Copyright 2005 Maarten Lankhorst * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,7 +18,31 @@ */ #define COM_NO_WINDOWS_H +#include "config.h" #include +#include +#include +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_ERRNO_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_ASM_TYPES_H +# include +#endif +#ifdef HAVE_LINUX_VIDEODEV_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif #include "windef.h" #include "winbase.h" @@ -25,9 +50,12 @@ #include "winuser.h" #include "vfw.h" #include "winreg.h" +#include "winnls.h" #include "winternl.h" #include "wine/debug.h" +#define CAP_DESC_MAX 32 + WINE_DEFAULT_DEBUG_CHANNEL(avicap); @@ -63,24 +91,117 @@ return retW; } +#ifdef HAVE_LINUX_VIDEODEV_H + +static int xioctl(int fd, int request, void * arg) +{ + int r; + + do r = ioctl (fd, request, arg); + while (-1 == r && EINTR == errno); + + return r; +} + +static BOOL query_video_device(int devnum, char *name, int namesize, char *version, int versionsize) +{ + int fd; + char device[16]; + struct stat st; + struct video_capability capa; +#ifdef HAVE_V4L2 + struct v4l2_capability caps; +#endif + + snprintf(device, sizeof(device), "/dev/video%i", devnum); + + if (stat (device, &st) == -1) { + /* This is probably because the device does not exist */ + WARN("%s: %s\n", device, strerror(errno)); + return FALSE; + } + + if (!S_ISCHR (st.st_mode)) { + ERR("%s: Not a device\n", device); + return FALSE; + } + + fd = open(device, O_RDWR | O_NONBLOCK); + if (fd == -1) { + ERR("%s: Failed to open: %s\n", device, strerror(errno)); + return FALSE; + } + +#ifdef HAVE_V4L2 + memset(&caps, 0, sizeof(caps)); + if (xioctl(fd, VIDIOC_QUERYCAP, &caps) != -1) { + lstrcpynA(name, caps.card, namesize); + snprintf(version, versionsize, "%s v%u.%u.%u", caps.driver, (caps.version >> 16) & 0xFF, + (caps.version >> 8) & 0xFF, caps.version & 0xFF); + close(fd); + return TRUE; + } + + if (errno != EINVAL && errno != 515) + WARN("%s: ioctl failed: %s -- Falling back to V4L\n", device, strerror(errno)); + else WARN("%s: Not a V4L2 compatible device, trying V4l 1\n", device); +#endif /* HAVE_V4L2 */ + + memset(&capa, 0, sizeof(capa)); + if (xioctl(fd, VIDIOCGCAP, &capa) == -1) { +/* errno 515 is used by some webcam drivers for unknown IOICTL command */ + if (errno != EINVAL && errno != 515) + ERR("%s: Querying failed: %s\n", device, strerror(errno)); + else ERR("%s: Querying failed: Not a V4L compatible device", device); + close(fd); + return FALSE; + } + + lstrcpynA(name, capa.name, namesize); + lstrcpynA(version, device, versionsize); + close(fd); + return TRUE; +} + +#else /* HAVE_LINUX_VIDEODEV_H */ + +static BOOL query_video_device(int devnum, char *name, int namesize, char *version, int versionsize) +{ + ERR("Video 4 Linux support not enabled\n"); + return FALSE; +} + +#endif /* HAVE_LINUX_VIDEODEV_H */ + /*********************************************************************** * capGetDriverDescriptionA (AVICAP32.@) */ BOOL VFWAPI capGetDriverDescriptionA(WORD wDriverIndex, LPSTR lpszName, - INT cbName, LPSTR lpszVer, INT cbVer) + INT cbName, LPSTR lpszVer, INT cbVer) { - FIXME("(%d, %p, %d, %p, %d) stub!\n", wDriverIndex, lpszName, cbName, - lpszVer, cbVer); - return FALSE; + HRESULT retval; + WCHAR devname[CAP_DESC_MAX], devver[CAP_DESC_MAX]; + TRACE("--> capGetDriverDescriptionW\n"); + retval = capGetDriverDescriptionW(wDriverIndex, devname, CAP_DESC_MAX, devver, CAP_DESC_MAX); + if (retval) { + WideCharToMultiByte(CP_ACP, 0, devname, -1, lpszName, cbName, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, devver, -1, lpszVer, cbVer, NULL, NULL); + } + return retval; } /*********************************************************************** * capGetDriverDescriptionW (AVICAP32.@) */ BOOL VFWAPI capGetDriverDescriptionW(WORD wDriverIndex, LPWSTR lpszName, - INT cbName, LPWSTR lpszVer, INT cbVer) + INT cbName, LPWSTR lpszVer, INT cbVer) { - FIXME("(%d, %p, %d, %p, %d) stub!\n", wDriverIndex, lpszName, cbName, - lpszVer, cbVer); - return FALSE; + char devname[CAP_DESC_MAX], devver[CAP_DESC_MAX]; + + if (!query_video_device(wDriverIndex, devname, CAP_DESC_MAX, devver, CAP_DESC_MAX)) return FALSE; + + MultiByteToWideChar(CP_UNIXCP, 0, devname, -1, lpszName, cbName); + MultiByteToWideChar(CP_UNIXCP, 0, devver, -1, lpszVer, cbVer); + TRACE("Version: %s - Name: %s\n", debugstr_w(lpszVer), debugstr_w(lpszName)); + return TRUE; } diff -urN wine-20050419/dlls/avifil32/.cvsignore wine-20050524/dlls/avifil32/.cvsignore --- wine-20050419/dlls/avifil32/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/avifil32/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,5 +1,5 @@ Makefile avifil32.dll.dbg.c -avifil32.spec.def avifile.spec.c +libavifil32.def rsrc.res diff -urN wine-20050419/dlls/avifil32/Makefile.in wine-20050524/dlls/avifil32/Makefile.in --- wine-20050419/dlls/avifil32/Makefile.in 2005-01-03 21:43:13.000000000 +0100 +++ wine-20050524/dlls/avifil32/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = avifil32.dll +IMPORTLIB = libavifil32.$(IMPLIBEXT) IMPORTS = msacm32 msvfw32 shell32 winmm ole32 user32 advapi32 kernel32 ntdll EXTRALIBS = -luuid diff -urN wine-20050419/dlls/avifil32/avifile.spec wine-20050524/dlls/avifil32/avifile.spec --- wine-20050419/dlls/avifil32/avifile.spec 2003-06-23 20:10:06.000000000 +0200 +++ wine-20050524/dlls/avifil32/avifile.spec 2005-05-23 12:12:26.000000000 +0200 @@ -3,7 +3,7 @@ # but the app doesn't really need to know, it should never need to # dereference the interface pointer itself (if we're lucky)... -1 stub WEP +#1 stub WEP 2 stub DLLGETCLASSOBJECT 3 stub DLLCANUNLOADNOW 4 stub ___EXPORTEDSTUB diff -urN wine-20050419/dlls/cabinet/.cvsignore wine-20050524/dlls/cabinet/.cvsignore --- wine-20050419/dlls/cabinet/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/cabinet/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,4 +1,4 @@ Makefile cabinet.dll.dbg.c cabinet.res -cabinet.spec.def +libcabinet.def diff -urN wine-20050419/dlls/cabinet/Makefile.in wine-20050524/dlls/cabinet/Makefile.in --- wine-20050419/dlls/cabinet/Makefile.in 2003-12-31 19:56:07.000000000 +0100 +++ wine-20050524/dlls/cabinet/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cabinet.dll +IMPORTLIB = libcabinet.$(IMPLIBEXT) IMPORTS = kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/cabinet/cabinet.h wine-20050524/dlls/cabinet/cabinet.h --- wine-20050419/dlls/cabinet/cabinet.h 2004-01-08 01:42:36.000000000 +0100 +++ wine-20050524/dlls/cabinet/cabinet.h 2005-05-14 13:06:10.000000000 +0200 @@ -2,6 +2,7 @@ * cabinet.h * * Copyright 2002 Greg Turner + * Copyright 2005 Gerold Jens Wucherpfennig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -292,6 +293,19 @@ typedef struct { unsigned int FCI_Intmagic; + PERF perf; + PFNFCIFILEPLACED pfnfiledest; + PFNFCIALLOC pfnalloc; + PFNFCIFREE pfnfree; + PFNFCIOPEN pfnopen; + PFNFCIREAD pfnread; + PFNFCIWRITE pfnwrite; + PFNFCICLOSE pfnclose; + PFNFCISEEK pfnseek; + PFNFCIDELETE pfndelete; + PFNFCIGETTEMPFILE pfnfcigtf; + PCCAB pccab; + void *pv; } FCI_Int, *PFCI_Int; typedef struct { @@ -307,7 +321,7 @@ } FDI_Int, *PFDI_Int; /* cast an HFCI into a PFCI_Int */ -#define PFCI_INT(hfci) ((PFDI_Int)(hfci)) +#define PFCI_INT(hfci) ((PFCI_Int)(hfci)) /* cast an HFDI into a PFDI_Int */ #define PFDI_INT(hfdi) ((PFDI_Int)(hfdi)) diff -urN wine-20050419/dlls/cabinet/fci.c wine-20050524/dlls/cabinet/fci.c --- wine-20050419/dlls/cabinet/fci.c 2003-09-06 01:08:44.000000000 +0200 +++ wine-20050524/dlls/cabinet/fci.c 2005-05-14 13:06:10.000000000 +0200 @@ -2,6 +2,7 @@ * File Compression Interface * * Copyright 2002 Patrik Stridvall + * Copyright 2005 Gerold Jens Wucherpfennig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,6 +27,7 @@ #include "winbase.h" #include "winerror.h" #include "fci.h" +#include "cabinet.h" #include "wine/debug.h" @@ -33,12 +35,55 @@ /*********************************************************************** * FCICreate (CABINET.10) + * + * Provided with several callbacks, + * returns a handle which can be used to perform operations + * on cabinet files. + * + * PARAMS + * perf [IO] A pointer to an ERF structure. When FCICreate + * returns an error condition, error information may + * be found here as well as from GetLastError. + * pfnfiledest [I] A pointer to a function which is called when a file + * is placed. Only useful for subsequent cabinet files. + * pfnalloc [I] A pointer to a function which allocates ram. Uses + * the same interface as malloc. + * pfnfree [I] A pointer to a function which frees ram. Uses the + * same interface as free. + * pfnopen [I] A pointer to a function which opens a file. Uses + * the same interface as _open. + * pfnread [I] A pointer to a function which reads from a file into + * a caller-provided buffer. Uses the same interface + * as _read + * pfnwrite [I] A pointer to a function which writes to a file from + * a caller-provided buffer. Uses the same interface + * as _write. + * pfnclose [I] A pointer to a function which closes a file handle. + * Uses the same interface as _close. + * pfnseek [I] A pointer to a function which seeks in a file. + * Uses the same interface as _lseek. + * pfndelete [I] A pointer to a function which deletes a file. + * pfnfcigtf [I] A pointer to a function which gets the name of a + * temporary file; ignored in wine + * pccab [I] A pointer to an initialized CCAB structure + * pv [I] A pointer to an application-defined notification + * function which will be passed to other FCI functions + * as a parameter. + * + * RETURNS + * On success, returns an FCI handle of type HFCI. + * On failure, the NULL file handle is returned. Error + * info can be retrieved from perf. + * + * INCLUDES + * fci.h + * */ HFCI __cdecl FCICreate( PERF perf, - PFNFCIFILEPLACED pfnfcifp, - PFNFCIALLOC pfna, - PFNFCIFREE pfnf, + PFNFCIFILEPLACED pfnfiledest, + PFNFCIALLOC pfnalloc, + PFNFCIFREE pfnfree, PFNFCIOPEN pfnopen, PFNFCIREAD pfnread, PFNFCIWRITE pfnwrite, @@ -49,17 +94,57 @@ PCCAB pccab, void *pv) { - FIXME("(%p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p): stub\n", - perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose, - pfnseek, pfndelete, pfnfcigtf, pccab, pv); + HFCI rv; + if ((!pfnalloc) || (!pfnfree)) { perf->erfOper = FCIERR_NONE; - perf->erfType = 0; + perf->erfType = ERROR_BAD_ARGUMENTS; perf->fError = TRUE; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + SetLastError(ERROR_BAD_ARGUMENTS); + return NULL; + } + if (!(rv = (HFCI) (*pfnalloc)(sizeof(FCI_Int)))) { + perf->erfOper = FCIERR_ALLOC_FAIL; + perf->erfType = ERROR_NOT_ENOUGH_MEMORY; + perf->fError = TRUE; + + SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; + } + + PFCI_INT(rv)->FCI_Intmagic = FCI_INT_MAGIC; + PFCI_INT(rv)->perf = perf; + PFCI_INT(rv)->pfnfiledest = pfnfiledest; + PFCI_INT(rv)->pfnalloc = pfnalloc; + PFCI_INT(rv)->pfnfree = pfnfree; + PFCI_INT(rv)->pfnopen = pfnopen; + PFCI_INT(rv)->pfnread = pfnread; + PFCI_INT(rv)->pfnwrite = pfnwrite; + PFCI_INT(rv)->pfnclose = pfnclose; + PFCI_INT(rv)->pfnseek = pfnseek; + PFCI_INT(rv)->pfndelete = pfndelete; + PFCI_INT(rv)->pfnfcigtf = pfnfcigtf; + PFCI_INT(rv)->pccab = pccab; + PFCI_INT(rv)->pv = pv; + + /* Still mark as incomplete, because of other missing FCI* APIs */ + + PFCI_INT(rv)->FCI_Intmagic = 0; + PFDI_FREE(rv, rv); + FIXME("(%p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p): stub\n", + perf, pfnfiledest, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose, + pfnseek, pfndelete, pfnfcigtf, pccab, pv); + + perf->erfOper = FCIERR_NONE; + perf->erfType = 0; + perf->fError = TRUE; + + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return NULL; + } /*********************************************************************** @@ -116,12 +201,30 @@ /*********************************************************************** * FCIDestroy (CABINET.14) + * + * Frees a handle created by FCICreate. + * Only reason for failure would be an invalid handle. + * + * PARAMS + * hfci [I] The HFCI to free + * + * RETURNS + * TRUE for success + * FALSE for failure */ BOOL __cdecl FCIDestroy(HFCI hfci) { - FIXME("(%p): stub\n", hfci); - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - + if (REALLY_IS_FCI(hfci)) { + PFCI_INT(hfci)->FCI_Intmagic = 0; + PFDI_FREE(hfci, hfci); + /*return TRUE; */ + } else { + SetLastError(ERROR_INVALID_HANDLE); return FALSE; + } + + /* Still mark as incomplete, because of other missing FCI* APIs */ + FIXME("(%p): stub\n", hfci); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } diff -urN wine-20050419/dlls/capi2032/.cvsignore wine-20050524/dlls/capi2032/.cvsignore --- wine-20050419/dlls/capi2032/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/capi2032/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,3 +1,3 @@ Makefile capi2032.dll.dbg.c -capi2032.spec.def +libcapi2032.def diff -urN wine-20050419/dlls/capi2032/Makefile.in wine-20050524/dlls/capi2032/Makefile.in --- wine-20050419/dlls/capi2032/Makefile.in 2005-01-07 16:33:02.000000000 +0100 +++ wine-20050524/dlls/capi2032/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = capi2032.dll +IMPORTLIB = libcapi2032.$(IMPLIBEXT) IMPORTS = kernel32 C_SRCS = cap20wxx.c diff -urN wine-20050419/dlls/cards/.cvsignore wine-20050524/dlls/cards/.cvsignore --- wine-20050419/dlls/cards/.cvsignore 2004-03-31 22:10:27.000000000 +0200 +++ wine-20050524/dlls/cards/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -13,7 +13,6 @@ c9.bmp cards.dll.dbg.c cards.res -cards.spec.def cj.bmp ck.bmp cq.bmp @@ -44,6 +43,7 @@ hj.bmp hk.bmp hq.bmp +libcards.def s1.bmp s10.bmp s2.bmp diff -urN wine-20050419/dlls/cards/Makefile.in wine-20050524/dlls/cards/Makefile.in --- wine-20050419/dlls/cards/Makefile.in 2004-03-31 22:10:27.000000000 +0200 +++ wine-20050524/dlls/cards/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cards.dll +IMPORTLIB = libcards.$(IMPLIBEXT) IMPORTS = user32 gdi32 kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/cfgmgr32/.cvsignore wine-20050524/dlls/cfgmgr32/.cvsignore --- wine-20050419/dlls/cfgmgr32/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/cfgmgr32/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,3 +1,3 @@ Makefile cfgmgr32.dll.dbg.c -cfgmgr32.spec.def +libcfgmgr32.def diff -urN wine-20050419/dlls/cfgmgr32/Makefile.in wine-20050524/dlls/cfgmgr32/Makefile.in --- wine-20050419/dlls/cfgmgr32/Makefile.in 2003-10-31 04:38:07.000000000 +0100 +++ wine-20050524/dlls/cfgmgr32/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cfgmgr32.dll +IMPORTLIB = libcfgmgr32.$(IMPLIBEXT) IMPORTS = kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/comcat/.cvsignore wine-20050524/dlls/comcat/.cvsignore --- wine-20050419/dlls/comcat/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/comcat/.cvsignore 2005-05-07 14:39:58.000000000 +0200 @@ -1,4 +1,4 @@ Makefile comcat.dll.dbg.c -comcat.spec.def +libcomcat.def version.res diff -urN wine-20050419/dlls/comcat/Makefile.in wine-20050524/dlls/comcat/Makefile.in --- wine-20050419/dlls/comcat/Makefile.in 2004-01-27 01:11:18.000000000 +0100 +++ wine-20050524/dlls/comcat/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = comcat.dll +IMPORTLIB = libcomcat.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = $(LIBUNICODE) -luuid diff -urN wine-20050419/dlls/comctl32/.cvsignore wine-20050524/dlls/comctl32/.cvsignore --- wine-20050419/dlls/comctl32/.cvsignore 2004-09-07 22:43:30.000000000 +0200 +++ wine-20050524/dlls/comctl32/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,7 +1,6 @@ Makefile comctl32.dll comctl32.dll.dbg.c -comctl32.spec.def idb_hist_large.bmp idb_hist_small.bmp idb_std_large.bmp @@ -17,4 +16,5 @@ idi_tt_info_sm.ico idi_tt_warn_sm.ico idt_check.bmp +libcomctl32.def rsrc.res diff -urN wine-20050419/dlls/comctl32/Makefile.in wine-20050524/dlls/comctl32/Makefile.in --- wine-20050419/dlls/comctl32/Makefile.in 2004-09-07 22:43:30.000000000 +0200 +++ wine-20050524/dlls/comctl32/Makefile.in 2005-05-09 16:42:36.000000000 +0200 @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = comctl32.dll +IMPORTLIB = libcomctl32.$(IMPLIBEXT) IMPORTS = user32 gdi32 advapi32 kernel32 DELAYIMPORTS = winmm EXTRALIBS = $(LIBUNICODE) diff -urN wine-20050419/dlls/comctl32/comboex.c wine-20050524/dlls/comctl32/comboex.c --- wine-20050419/dlls/comctl32/comboex.c 2005-03-23 14:15:21.000000000 +0100 +++ wine-20050524/dlls/comctl32/comboex.c 2005-05-04 12:37:17.000000000 +0200 @@ -283,6 +283,26 @@ } +static INT COMBOEX_GetIndex(COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item) +{ + CBE_ITEMDATA *moving; + INT index; + + moving = infoPtr->items; + index = infoPtr->nb_items - 1; + + while (moving && (moving != item)) { + moving = moving->next; + index--; + } + if (!moving || (index < 0)) { + ERR("COMBOBOXEX item structures broken. Please report!\n"); + return -1; + } + return index; +} + + static LPCWSTR COMBOEX_GetText(COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item) { NMCOMBOBOXEXW nmce; @@ -295,6 +315,7 @@ ZeroMemory(&nmce, sizeof(nmce)); nmce.ceItem.mask = CBEIF_TEXT; nmce.ceItem.lParam = item->lParam; + nmce.ceItem.iItem = COMBOEX_GetIndex(infoPtr, item); COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce); if (is_textW(nmce.ceItem.pszText)) { @@ -1389,6 +1410,7 @@ ZeroMemory(&nmce, sizeof(nmce)); nmce.ceItem.mask = CBEIF_INDENT; nmce.ceItem.lParam = item->lParam; + nmce.ceItem.iItem = dis->itemID; COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce); if (nmce.ceItem.mask & CBEIF_DI_SETITEM) item->iIndent = nmce.ceItem.iIndent; @@ -1453,6 +1475,7 @@ ZeroMemory(&nmce, sizeof(nmce)); nmce.ceItem.mask = (drawstate == ILD_NORMAL) ? CBEIF_IMAGE : CBEIF_SELECTEDIMAGE; nmce.ceItem.lParam = item->lParam; + nmce.ceItem.iItem = dis->itemID; COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce); if (drawstate == ILD_NORMAL) { if (nmce.ceItem.mask & CBEIF_DI_SETITEM) item->iImage = nmce.ceItem.iImage; @@ -1468,6 +1491,7 @@ ZeroMemory(&nmce, sizeof(nmce)); nmce.ceItem.mask = CBEIF_OVERLAY; nmce.ceItem.lParam = item->lParam; + nmce.ceItem.iItem = dis->itemID; COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce); if (nmce.ceItem.mask & CBEIF_DI_SETITEM) item->iOverlay = nmce.ceItem.iOverlay; diff -urN wine-20050419/dlls/comctl32/comctl32undoc.c wine-20050524/dlls/comctl32/comctl32undoc.c --- wine-20050419/dlls/comctl32/comctl32undoc.c 2005-03-24 16:07:23.000000000 +0100 +++ wine-20050524/dlls/comctl32/comctl32undoc.c 2005-05-06 17:44:32.000000000 +0200 @@ -588,7 +588,7 @@ if ((err = RegOpenKeyExW( mp->extview.hKey, mp->extview.lpszSubKey, 0, KEY_WRITE, &newkey))) { /* not present - what to do ??? */ - ERR("Can not open key, error=%d, attempting to create\n", + ERR("Could not open key, error=%d, attempting to create\n", err); if ((err = RegCreateKeyExW( mp->extview.hKey, mp->extview.lpszSubKey, 0, @@ -980,7 +980,7 @@ &newkey, &dwdisp))) { /* error - what to do ??? */ - ERR("(%lu %lu %lx %lx \"%s\" %p): Can not open key, error=%d\n", + ERR("(%lu %lu %lx %lx \"%s\" %p): Could not open key, error=%d\n", mp->extview.cbSize, mp->extview.nMaxItems, mp->extview.dwFlags, (DWORD)mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey), mp->extview.lpfnCompare, err); diff -urN wine-20050419/dlls/comctl32/datetime.c wine-20050524/dlls/comctl32/datetime.c --- wine-20050419/dlls/comctl32/datetime.c 2005-04-18 11:52:18.000000000 +0200 +++ wine-20050524/dlls/comctl32/datetime.c 2005-05-24 14:34:30.000000000 +0200 @@ -607,7 +607,7 @@ RECT *checkbox = &infoPtr->checkbox; SIZE size; COLORREF oldTextColor; - SHORT fieldWidth; + SHORT fieldWidth = 0; /* draw control edge */ TRACE("\n"); diff -urN wine-20050419/dlls/comctl32/header.c wine-20050524/dlls/comctl32/header.c --- wine-20050419/dlls/comctl32/header.c 2005-03-23 14:15:21.000000000 +0100 +++ wine-20050524/dlls/comctl32/header.c 2005-05-14 13:03:17.000000000 +0200 @@ -163,7 +163,7 @@ HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); HEADER_ITEM *phdi = &infoPtr->items[iItem]; RECT r; - INT oldBkMode; + INT oldBkMode, cxEdge = GetSystemMetrics(SM_CXEDGE); TRACE("DrawItem(iItem %d bHotTrack %d unicode flag %d)\n", iItem, bHotTrack, infoPtr->bUnicode); @@ -188,6 +188,9 @@ else DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST); + r.left -= cxEdge; + r.right += cxEdge; + if (phdi->fmt & HDF_OWNERDRAW) { DRAWITEMSTRUCT dis; dis.CtlType = ODT_HEADER; @@ -206,149 +209,117 @@ SetBkMode(hdc, oldBkMode); } else { - UINT uTextJustify = DT_LEFT; - - if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER) - uTextJustify = DT_CENTER; - else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT) - uTextJustify = DT_RIGHT; - - if ((phdi->fmt & HDF_BITMAP) && !(phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) { - BITMAP bmp; - HDC hdcBitmap; - INT yD, yS, cx, cy, rx, ry; - - GetObjectW (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp); - - ry = r.bottom - r.top; - rx = r.right - r.left; - - if (ry >= bmp.bmHeight) { - cy = bmp.bmHeight; - yD = r.top + (ry - bmp.bmHeight) / 2; - yS = 0; - } - else { - cy = ry; - yD = r.top; - yS = (bmp.bmHeight - ry) / 2; - - } + UINT rw, rh, /* width and height of r */ + *x = NULL, *w = NULL; /* x and width of the pic (bmp or img) which is part of cnt */ + /* cnt,txt,img,bmp */ + UINT cx, tx, ix, bx, + cw, tw, iw, bw; + BITMAP bmp; + + cw = tw = iw = bw = 0; + rw = r.right - r.left; + rh = r.bottom - r.top; - if (rx >= bmp.bmWidth + infoPtr->iMargin) { - cx = bmp.bmWidth; - } - else { - cx = rx - infoPtr->iMargin; - } - - hdcBitmap = CreateCompatibleDC (hdc); - SelectObject (hdcBitmap, phdi->hbm); - BitBlt (hdc, r.left + infoPtr->iMargin, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY); - DeleteDC (hdcBitmap); + if (phdi->fmt & HDF_STRING) { + RECT textRect; - r.left += (bmp.bmWidth + infoPtr->iMargin); + DrawTextW (hdc, phdi->pszText, -1, + &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT); + cw = textRect.right - textRect.left + 2 * infoPtr->iMargin; } + if ((phdi->fmt & HDF_IMAGE) && (infoPtr->himl)) { + iw = infoPtr->himl->cx + 2 * infoPtr->iMargin; + x = &ix; + w = &iw; + } - if ((phdi->fmt & HDF_BITMAP) && (phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) { - BITMAP bmp; - HDC hdcBitmap; - INT xD, yD, yS, cx, cy, rx, ry, tx; - RECT textRect; - + if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) { GetObjectW (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp); - - textRect = r; - if (phdi->fmt & HDF_STRING) { - DrawTextW (hdc, phdi->pszText, -1, - &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT); - tx = textRect.right - textRect.left; + bw = bmp.bmWidth + 2 * infoPtr->iMargin; + if (!iw) { + x = &bx; + w = &bw; } - else - tx = 0; - ry = r.bottom - r.top; - rx = r.right - r.left; - - if (ry >= bmp.bmHeight) { - cy = bmp.bmHeight; - yD = r.top + (ry - bmp.bmHeight) / 2; - yS = 0; - } - else { - cy = ry; - yD = r.top; - yS = (bmp.bmHeight - ry) / 2; + } - } + if (bw || iw) + cw += *w; - if (r.left + tx + bmp.bmWidth + 2*infoPtr->iMargin <= r.right) { - cx = bmp.bmWidth; - xD = r.left + tx + infoPtr->iMargin; - } - else { - if (rx >= bmp.bmWidth + infoPtr->iMargin ) { - cx = bmp.bmWidth; - xD = r.right - bmp.bmWidth - infoPtr->iMargin; - r.right = xD - infoPtr->iMargin; - } - else { - cx = rx - infoPtr->iMargin; - xD = r.left; - r.right = r.left; - } + /* align cx using the unclipped cw */ + if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_LEFT) + cx = r.left; + else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER) + cx = r.left + rw / 2 - cw / 2; + else /* HDF_RIGHT */ + cx = r.right - cw; + + /* clip cx & cw */ + if (cx < r.left) + cx = r.left; + if (cx + cw > r.right) + cw = r.right - cx; + + tx = cx + infoPtr->iMargin; + /* since cw might have changed we have to recalculate tw */ + tw = cw - infoPtr->iMargin * 2; + + if (iw || bw) { + tw -= *w; + if (phdi->fmt & HDF_BITMAP_ON_RIGHT) { + /* put pic behind text */ + *x = cx + tw + infoPtr->iMargin * 3; + } else { + *x = cx + infoPtr->iMargin; + /* move text behind pic */ + tx += *w; } - - hdcBitmap = CreateCompatibleDC (hdc); - SelectObject (hdcBitmap, phdi->hbm); - BitBlt (hdc, xD, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY); - DeleteDC (hdcBitmap); } - if ((phdi->fmt & HDF_IMAGE) && !(phdi->fmt & HDF_BITMAP_ON_RIGHT) && (infoPtr->himl)) { - r.left += infoPtr->iMargin; - ImageList_DrawEx(infoPtr->himl, phdi->iImage, hdc, r.left, r.top + (r.bottom-r.top- infoPtr->himl->cy)/2, - infoPtr->himl->cx, r.bottom-r.top, CLR_DEFAULT, CLR_DEFAULT, 0); - r.left += infoPtr->himl->cx; + if (iw && bw) { + /* since we're done with the layout we can + now calculate the position of bmp which + has no influence on alignment and layout + because of img */ + if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT) + bx = cx - bw + infoPtr->iMargin; + else + bx = cx + cw + infoPtr->iMargin; } - if ((phdi->fmt & HDF_IMAGE) && (phdi->fmt & HDF_BITMAP_ON_RIGHT) && (infoPtr->himl)) { - RECT textRect; - INT tx; - - textRect = r; - if (phdi->fmt & HDF_STRING) { - DrawTextW (hdc, phdi->pszText, -1, - &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT); - tx = textRect.right - textRect.left; - } - else - tx = 0; + if (iw || bw) { + HDC hClipDC = GetDC(hwnd); + HRGN hClipRgn = CreateRectRgn(r.left, r.top, r.right, r.bottom); + SelectClipRgn(hClipDC, hClipRgn); + + if (bw) { + HDC hdcBitmap = CreateCompatibleDC (hClipDC); + SelectObject (hdcBitmap, phdi->hbm); + BitBlt (hClipDC, bx, r.top + ((INT)rh - bmp.bmHeight) / 2, + bmp.bmWidth, bmp.bmHeight, hdcBitmap, 0, 0, SRCCOPY); + DeleteDC (hdcBitmap); + } - if (tx < (r.right-r.left - infoPtr->himl->cx - GetSystemMetrics(SM_CXEDGE))) - ImageList_DrawEx(infoPtr->himl, phdi->iImage, hdc, r.left + tx + 2*infoPtr->iMargin, - r.top + (r.bottom-r.top-infoPtr->himl->cy)/2, infoPtr->himl->cx, r.bottom-r.top, - CLR_DEFAULT, CLR_DEFAULT, 0); - else { - INT x = max(r.right - infoPtr->iMargin - infoPtr->himl->cx, r.left); - INT cx = min(infoPtr->himl->cx, r.right-r.left - GetSystemMetrics(SM_CXEDGE)); - ImageList_DrawEx(infoPtr->himl, phdi->iImage, hdc, x , - r.top + (r.bottom-r.top-infoPtr->himl->cy)/2, cx, r.bottom-r.top, - CLR_DEFAULT, CLR_DEFAULT, 0); - r.right -= infoPtr->himl->cx - infoPtr->iMargin; + if (iw) { + ImageList_DrawEx (infoPtr->himl, phdi->iImage, hClipDC, + ix, r.top + ((INT)rh - infoPtr->himl->cy) / 2, + infoPtr->himl->cx, infoPtr->himl->cy, CLR_DEFAULT, CLR_DEFAULT, 0); } - } - if (((phdi->fmt & HDF_STRING) + DeleteObject(hClipRgn); + DeleteDC(hClipDC); + } + + if (((phdi->fmt & HDF_STRING) || (!(phdi->fmt & (HDF_OWNERDRAW|HDF_STRING|HDF_BITMAP| HDF_BITMAP_ON_RIGHT|HDF_IMAGE)))) /* no explicit format specified? */ && (phdi->pszText)) { - oldBkMode = SetBkMode(hdc, TRANSPARENT); - r.left += infoPtr->iMargin; - r.right -= infoPtr->iMargin; + oldBkMode = SetBkMode(hdc, TRANSPARENT); SetTextColor (hdc, (bHotTrack) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT); + r.left = tx; + r.right = tx + tw; DrawTextW (hdc, phdi->pszText, -1, - &r, uTextJustify|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE); + &r, DT_LEFT|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE); if (oldBkMode != TRANSPARENT) SetBkMode(hdc, oldBkMode); } diff -urN wine-20050419/dlls/comctl32/hotkey.c wine-20050524/dlls/comctl32/hotkey.c --- wine-20050419/dlls/comctl32/hotkey.c 2004-10-27 23:16:27.000000000 +0200 +++ wine-20050524/dlls/comctl32/hotkey.c 2005-05-06 17:44:32.000000000 +0200 @@ -54,7 +54,7 @@ BYTE CurrMod; INT CaretPos; DWORD ScanCode; - WCHAR strNone[15]; /* hope its long enough ... */ + WCHAR strNone[15]; /* hope it's long enough ... */ } HOTKEY_INFO; static const WCHAR HOTKEY_plussep[] = { ' ', '+', ' ' }; diff -urN wine-20050419/dlls/comctl32/imagelist.c wine-20050524/dlls/comctl32/imagelist.c --- wine-20050419/dlls/comctl32/imagelist.c 2005-03-25 21:49:00.000000000 +0100 +++ wine-20050524/dlls/comctl32/imagelist.c 2005-05-06 17:44:32.000000000 +0200 @@ -98,7 +98,7 @@ * nothing * * NOTES - * This function can NOT be used to reduce the number of images. + * This function CANNOT be used to reduce the number of images. */ static void IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT cy) diff -urN wine-20050419/dlls/comctl32/ipaddress.c wine-20050524/dlls/comctl32/ipaddress.c --- wine-20050419/dlls/comctl32/ipaddress.c 2004-10-27 23:15:53.000000000 +0200 +++ wine-20050524/dlls/comctl32/ipaddress.c 2005-05-09 11:24:05.000000000 +0200 @@ -62,6 +62,7 @@ { HWND Self; HWND Notify; + BOOL Enabled; IPPART_INFO Part[4]; } IPADDRESS_INFO; @@ -127,12 +128,26 @@ static const WCHAR dotW[] = { '.', 0 }; RECT rect, rcPart; POINT pt; + COLORREF bgCol, fgCol; int i; TRACE("\n"); GetClientRect (infoPtr->Self, &rect); + + if (infoPtr->Enabled) { + bgCol = COLOR_WINDOW; + fgCol = COLOR_WINDOWTEXT; + } else { + bgCol = COLOR_3DFACE; + fgCol = COLOR_GRAYTEXT; + } + + FillRect (hdc, &rect, (HBRUSH) (bgCol+1)); DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + + SetBkColor (hdc, GetSysColor(bgCol)); + SetTextColor(hdc, GetSysColor(fgCol)); for (i = 0; i < 3; i++) { GetWindowRect (infoPtr->Part[i].EditHwnd, &rcPart); @@ -174,6 +189,7 @@ edit.bottom = rcClient.bottom - 2; infoPtr->Self = hwnd; + infoPtr->Enabled = FALSE; infoPtr->Notify = lpCreate->hwndParent; for (i = 0; i < 4; i++) { @@ -215,6 +231,20 @@ } +static LRESULT IPADDRESS_Enable (IPADDRESS_INFO *infoPtr, BOOL enabled) +{ + int i; + + infoPtr->Enabled = enabled; + + for (i = 0; i < 4; i++) + EnableWindow(infoPtr->Part[i].EditHwnd, enabled); + + InvalidateRgn(infoPtr->Self, NULL, FALSE); + return 0; +} + + static LRESULT IPADDRESS_Paint (IPADDRESS_INFO *infoPtr, HDC hdc) { PAINTSTRUCT ps; @@ -517,6 +547,10 @@ case WM_DESTROY: return IPADDRESS_Destroy (infoPtr); + case WM_ENABLE: + return IPADDRESS_Enable (infoPtr, (BOOL)wParam); + break; + case WM_PAINT: return IPADDRESS_Paint (infoPtr, (HDC)wParam); diff -urN wine-20050419/dlls/comctl32/listview.c wine-20050524/dlls/comctl32/listview.c --- wine-20050419/dlls/comctl32/listview.c 2005-04-14 15:58:25.000000000 +0200 +++ wine-20050524/dlls/comctl32/listview.c 2005-05-24 13:46:53.000000000 +0200 @@ -24,7 +24,7 @@ * NOTES * * This code was audited for completeness against the documented features - * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Dimitrie O. Paun. + * of Comctl32.dll version 6.0 on May. 20, 2005, by James Hawkins. * * Unless otherwise noted, we believe this code to be complete, as per * the specification mentioned above. @@ -32,6 +32,17 @@ * * TODO: * + * Default Message Processing + * -- EN_KILLFOCUS should be handled in WM_COMMAND + * -- WM_CREATE: create the icon and small icon image lists at this point only if + * the LVS_SHAREIMAGELISTS style is not specified. + * -- WM_ERASEBKGND: forward this message to the parent window if the bkgnd + * color is CLR_NONE. + * -- WM_WINDOWPOSCHANGED: arrange the list items if the current view is icon + * or small icon and the LVS_AUTOARRANGE style is specified. + * -- WM_TIMER + * -- WM_WININICHANGE + * * Features * -- Hot item handling, mouse hovering * -- Workareas support @@ -74,6 +85,8 @@ * -- LVS_NOLABELWRAP * -- LVS_NOSCROLL (see Q137520) * -- LVS_SORTASCENDING, LVS_SORTDESCENDING + * -- LVS_ALIGNTOP + * -- LVS_TYPESTYLEMASK * * Extended Styles * -- LVS_EX_BORDERSELECT @@ -99,6 +112,7 @@ * -- LVN_ODFINDITEM * -- LVN_SETDISPINFO * -- NM_HOVER + * -- LVN_BEGINRDRAG * * Messages: * -- LVM_CANCELEDITLABEL @@ -130,6 +144,20 @@ * -- LVM_SORTGROUPS * -- LVM_SORTITEMSEX * + * Macros: + * -- ListView_GetCheckSate, ListView_SetCheckState + * -- ListView_GetHoverTime, ListView_SetHoverTime + * -- ListView_GetISearchString + * -- ListView_GetNumberOfWorkAreas + * -- ListView_GetOrigin + * -- ListView_GetTextBkColor + * -- ListView_GetUnicodeFormat, ListView_SetUnicodeFormat + * -- ListView_GetWorkAreas, ListView_SetWorkAreas + * -- ListView_SortItemsEx + * + * Functions: + * -- LVGroupComparE + * * Known differences in message stream from native control (not known if * these differences cause problems): * LVM_INSERTITEM issues LVM_SETITEMSTATE and LVM_SETITEM in certain cases. @@ -224,6 +252,7 @@ HIMAGELIST himlState; BOOL bLButtonDown; BOOL bRButtonDown; + POINT ptClickPos; /* point where the user clicked */ BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */ INT nItemHeight; INT nItemWidth; @@ -393,6 +422,7 @@ static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *, INT, BOOL); static HWND CreateEditLabelT(LISTVIEW_INFO *, LPCWSTR, DWORD, INT, INT, INT, INT, BOOL); static HIMAGELIST LISTVIEW_SetImageList(LISTVIEW_INFO *, INT, HIMAGELIST); +static INT LISTVIEW_HitTest(LISTVIEW_INFO *, LPLVHITTESTINFO, BOOL, BOOL); /******** Text handling functions *************************************/ @@ -3141,6 +3171,22 @@ return bResult; } +static BOOL LISTVIEW_GetItemAtPt(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, POINT pt) +{ + LVHITTESTINFO lvHitTestInfo; + + ZeroMemory(&lvHitTestInfo, sizeof(lvHitTestInfo)); + lvHitTestInfo.pt.x = pt.x; + lvHitTestInfo.pt.y = pt.y; + + LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE); + + lpLVItem->mask = LVIF_PARAM; + lpLVItem->iItem = lvHitTestInfo.iItem; + lpLVItem->iSubItem = 0; + + return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE); +} /*** * DESCRIPTION: @@ -3162,9 +3208,17 @@ */ static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKyes, INT x, INT y) { - if(infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT) - /* FIXME: select the item!!! */ - /*LISTVIEW_GetItemAtPt(infoPtr, pt)*/; + if (infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT) + { + LVITEMW item; + POINT pt; + + pt.x = x; + pt.y = y; + + if (LISTVIEW_GetItemAtPt(infoPtr, &item, pt)) + LISTVIEW_SetSelection(infoPtr, item.iItem); + } return 0; } @@ -3183,7 +3237,24 @@ */ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, INT y) { - TRACKMOUSEEVENT trackinfo; + TRACKMOUSEEVENT trackinfo; + + if (infoPtr->bLButtonDown && DragDetect(infoPtr->hwndSelf, infoPtr->ptClickPos)) + { + LVHITTESTINFO lvHitTestInfo; + NMLISTVIEW nmlv; + + lvHitTestInfo.pt = infoPtr->ptClickPos; + LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE); + + ZeroMemory(&nmlv, sizeof(nmlv)); + nmlv.iItem = lvHitTestInfo.iItem; + nmlv.ptAction = infoPtr->ptClickPos; + + notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv); + + return 0; + } /* see if we are supposed to be tracking mouse hovering */ if(infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT) { @@ -7488,6 +7559,25 @@ /*** * DESCRIPTION: + * Enables the listview control. + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] bEnable : specifies whether to enable or disable the window + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static BOOL LISTVIEW_Enable(LISTVIEW_INFO *infoPtr, BOOL bEnable) +{ + if (infoPtr->dwStyle & LVS_OWNERDRAWFIXED) + InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); + return TRUE; +} + +/*** + * DESCRIPTION: * Erases the background of the listview control. * * PARAMETER(S): @@ -7901,68 +7991,6 @@ return 0; } - -/*** - * DESCRIPTION: - * Track mouse/dragging - * - * PARAMETER(S): - * [I] infoPtr : valid pointer to the listview structure - * [I] pt : mouse coordinate - * - * RETURN: - * Zero - */ -static LRESULT LISTVIEW_TrackMouse(LISTVIEW_INFO *infoPtr, POINT pt) -{ - INT cxDrag = GetSystemMetrics(SM_CXDRAG); - INT cyDrag = GetSystemMetrics(SM_CYDRAG); - RECT r; - MSG msg; - - TRACE("\n"); - - r.top = pt.y - cyDrag; - r.left = pt.x - cxDrag; - r.bottom = pt.y + cyDrag; - r.right = pt.x + cxDrag; - - SetCapture(infoPtr->hwndSelf); - - while (1) - { - if (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) - { - if (msg.message == WM_MOUSEMOVE) - { - pt.x = (short)LOWORD(msg.lParam); - pt.y = (short)HIWORD(msg.lParam); - if (PtInRect(&r, pt)) - continue; - else - { - ReleaseCapture(); - return 1; - } - } - else if (msg.message >= WM_LBUTTONDOWN && - msg.message <= WM_RBUTTONDBLCLK) - { - break; - } - - DispatchMessageW(&msg); - } - - if (GetCapture() != infoPtr->hwndSelf) - return 0; - } - - ReleaseCapture(); - return 0; -} - - /*** * DESCRIPTION: * Processes double click messages (left mouse button). @@ -8023,8 +8051,9 @@ if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf); - /* set left button down flag */ + /* set left button down flag and record the click position */ infoPtr->bLButtonDown = TRUE; + infoPtr->ptClickPos = pt; lvHitTestInfo.pt.x = x; lvHitTestInfo.pt.y = y; @@ -8047,19 +8076,6 @@ } return 0; } - if (LISTVIEW_TrackMouse(infoPtr, lvHitTestInfo.pt)) - { - NMLISTVIEW nmlv; - - ZeroMemory(&nmlv, sizeof(nmlv)); - nmlv.iItem = nItem; - nmlv.ptAction.x = lvHitTestInfo.pt.x; - nmlv.ptAction.y = lvHitTestInfo.pt.y; - - notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv); - - return 0; - } if (infoPtr->dwStyle & LVS_SINGLESEL) { @@ -8288,6 +8304,11 @@ notify_listview(infoPtr, LVN_COLUMNCLICK, &nmlv); } break; + + case HDN_DIVIDERDBLCLICKW: + case HDN_DIVIDERDBLCLICKA: + LISTVIEW_SetColumnWidth(infoPtr, lpnmh->iItem, LVSCW_AUTOSIZE); + break; } return 0; @@ -8617,7 +8638,7 @@ { TRACE("infoPtr->bRedraw=%d, bRedraw=%d\n", infoPtr->bRedraw, bRedraw); - /* we can not use straight equality here because _any_ non-zero value is TRUE */ + /* we cannot use straight equality here because _any_ non-zero value is TRUE */ if ((infoPtr->bRedraw && bRedraw) || (!infoPtr->bRedraw && !bRedraw)) return 0; infoPtr->bRedraw = bRedraw; @@ -9190,6 +9211,9 @@ case WM_CREATE: return LISTVIEW_Create(hwnd, (LPCREATESTRUCTW)lParam); + case WM_ENABLE: + return LISTVIEW_Enable(infoPtr, (BOOL)wParam); + case WM_ERASEBKGND: return LISTVIEW_EraseBkgnd(infoPtr, (HDC)wParam); diff -urN wine-20050419/dlls/comctl32/monthcal.c wine-20050524/dlls/comctl32/monthcal.c --- wine-20050419/dlls/comctl32/monthcal.c 2005-04-14 13:31:17.000000000 +0200 +++ wine-20050524/dlls/comctl32/monthcal.c 2005-04-20 14:51:37.000000000 +0200 @@ -473,29 +473,23 @@ SetTextColor(hdc, infoPtr->titletxt); currentFont = SelectObject(hdc, infoPtr->hBoldFont); - /* titlemonth->left and right are set in MONTHCAL_UpdateSize */ - titlemonth->left = title->left; - titlemonth->right = title->right; - GetLocaleInfoW( LOCALE_USER_DEFAULT,LOCALE_SMONTHNAME1+infoPtr->currentMonth -1, buf1,countof(buf1)); wsprintfW(buf, fmt1W, buf1, infoPtr->currentYear); - if(IntersectRect(&rcTemp, &(ps->rcPaint), titlemonth)) + if(IntersectRect(&rcTemp, &(ps->rcPaint), title)) { - DrawTextW(hdc, buf, strlenW(buf), titlemonth, + DrawTextW(hdc, buf, strlenW(buf), title, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } - SelectObject(hdc, infoPtr->hFont); - /* titlemonth left/right contained rect for whole titletxt('June 1999') * MCM_HitTestInfo wants month & year rects, so prepare these now. *(no, we can't draw them separately; the whole text is centered) */ GetTextExtentPoint32W(hdc, buf, strlenW(buf), &size); - titlemonth->left = title->right / 2 - size.cx / 2; - titleyear->right = title->right / 2 + size.cx / 2; + titlemonth->left = title->right / 2 + title->left / 2 - size.cx / 2; + titleyear->right = title->right / 2 + title->left / 2 + size.cx / 2; GetTextExtentPoint32W(hdc, buf1, strlenW(buf1), &size); titlemonth->right = titlemonth->left + size.cx; titleyear->left = titlemonth->right; @@ -524,6 +518,7 @@ infoPtr->wdays.left = infoPtr->days.left = infoPtr->weeknums.right; /* draw day abbreviations */ + SelectObject(hdc, infoPtr->hFont); SetBkColor(hdc, infoPtr->monthbk); SetTextColor(hdc, infoPtr->trailingtxt); @@ -673,9 +668,9 @@ wsprintfW(buf, fmt2W, buf1, buf2); SelectObject(hdc, infoPtr->hBoldFont); + DrawTextW(hdc, buf, -1, &rtoday, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE); if(IntersectRect(&rcTemp, &(ps->rcPaint), &rtoday)) { - DrawTextW(hdc, buf, -1, &rtoday, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE); DrawTextW(hdc, buf, -1, &rtoday, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } SelectObject(hdc, infoPtr->hFont); @@ -1424,18 +1419,19 @@ 0, WS_VISIBLE | WS_CHILD |UDS_SETBUDDYINT, infoPtr->titleyear.left+3,infoPtr->titlebtnnext.top, - infoPtr->titleyear.right-infoPtr->titleyear.left, + infoPtr->titleyear.right-infoPtr->titleyear.left+4, infoPtr->textHeight, infoPtr->hwndSelf, NULL, NULL, NULL); + SendMessageW( infoPtr->hWndYearEdit, WM_SETFONT, (WPARAM) infoPtr->hBoldFont, (LPARAM)TRUE); infoPtr->hWndYearUpDown=CreateWindowExW(0, UPDOWN_CLASSW, 0, WS_VISIBLE | WS_CHILD |UDS_SETBUDDYINT|UDS_NOTHOUSANDS|UDS_ARROWKEYS, - infoPtr->titleyear.right+6,infoPtr->titlebtnnext.top, - 20, + infoPtr->titleyear.right+7,infoPtr->titlebtnnext.top, + 18, infoPtr->textHeight, infoPtr->hwndSelf, NULL, @@ -1733,7 +1729,7 @@ xdiv = (dwStyle & MCS_WEEKNUMBERS) ? 8 : 7; - infoPtr->width_increment = size.cx * 2; + infoPtr->width_increment = size.cx * 2 + 4; infoPtr->height_increment = infoPtr->textHeight; left_offset = (rcClient.right - rcClient.left) - (infoPtr->width_increment * xdiv); @@ -1852,7 +1848,7 @@ /* initialize info structure */ /* FIXME: calculate systemtime ->> localtime(substract timezoneinfo) */ - GetSystemTime(&infoPtr->todaysDate); + GetLocalTime(&infoPtr->todaysDate); MONTHCAL_SetFirstDayOfWeek(infoPtr, (LPARAM)-1); infoPtr->currentMonth = infoPtr->todaysDate.wMonth; infoPtr->currentYear = infoPtr->todaysDate.wYear; diff -urN wine-20050419/dlls/comctl32/tab.c wine-20050524/dlls/comctl32/tab.c --- wine-20050419/dlls/comctl32/tab.c 2005-04-13 16:40:12.000000000 +0200 +++ wine-20050524/dlls/comctl32/tab.c 2005-05-17 12:19:37.000000000 +0200 @@ -1727,12 +1727,12 @@ else drawRect->bottom-=center_offset_h; - center_offset_v = ((drawRect->right - drawRect->left) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2; + center_offset_v = ((drawRect->right - drawRect->left) - (rcText.bottom - rcText.top) + infoPtr->uVItemPadding) / 2; } else { drawRect->left += center_offset_h; - center_offset_v = ((drawRect->bottom - drawRect->top) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2; + center_offset_v = ((drawRect->bottom - drawRect->top) - (rcText.bottom - rcText.top) + infoPtr->uVItemPadding) / 2; } if (center_offset_v < 0) @@ -2961,9 +2961,16 @@ return 0; } +static LRESULT TAB_NCCalcSize(HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + if (!wParam) + return 0; + return WVR_ALIGNTOP; +} + static inline LRESULT TAB_SetItemExtra (TAB_INFO *infoPtr, INT cbInfo) -{ +{ if (!infoPtr || cbInfo <= 0) return FALSE; @@ -3143,6 +3150,9 @@ case WM_NCHITTEST: return TAB_NCHitTest(infoPtr, lParam); + case WM_NCCALCSIZE: + return TAB_NCCalcSize(hwnd, wParam, lParam); + default: if (uMsg >= WM_USER && uMsg < WM_APP) WARN("unknown msg %04x wp=%08x lp=%08lx\n", diff -urN wine-20050419/dlls/comctl32/tests/dpa.c wine-20050524/dlls/comctl32/tests/dpa.c --- wine-20050419/dlls/comctl32/tests/dpa.c 2004-12-15 11:55:36.000000000 +0100 +++ wine-20050524/dlls/comctl32/tests/dpa.c 2005-04-22 23:18:12.000000000 +0200 @@ -30,6 +30,7 @@ static HDPA (WINAPI *pDPA_Create)(int); static BOOL (WINAPI *pDPA_Grow)(const HDPA hdpa, INT nGrow); static BOOL (WINAPI *pDPA_Destroy)(const HDPA hdpa); +static INT (WINAPI *pDPA_Search)(HDPA, LPVOID, INT, PFNDPACOMPARE, LPARAM, UINT); static BOOL (WINAPI *pDPA_SetPtr)(const HDPA hdpa, INT i, LPVOID p); static INT CALLBACK dpa_strcmp(LPVOID pvstr1, LPVOID pvstr2, LPARAM flags) @@ -51,11 +52,11 @@ dpa_ret = pDPA_Create(0); ok((dpa_ret !=0), "DPA_Create failed\n"); - int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED); + int_ret = pDPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED); ok((int_ret == -1), "DPA_Search found invalid item\n"); - int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTBEFORE); + int_ret = pDPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTBEFORE); ok((int_ret == 0), "DPA_Search proposed bad item\n"); - int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTAFTER); + int_ret = pDPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTAFTER); ok((int_ret == 0), "DPA_Search proposed bad item\n"); int_ret = pDPA_Grow(dpa_ret,0); ok(int_ret != 0, "DPA_Grow failed\n"); @@ -73,6 +74,7 @@ pDPA_Create=(void*)GetProcAddress(hdll,(LPCSTR)328); pDPA_Destroy=(void*)GetProcAddress(hdll,(LPCSTR)329); pDPA_Grow=(void*)GetProcAddress(hdll,(LPCSTR)330); + pDPA_Search=(void*)GetProcAddress(hdll,(LPCSTR)339); pDPA_SetPtr=(void*)GetProcAddress(hdll,(LPCSTR)335); DPA_test(); diff -urN wine-20050419/dlls/comctl32/toolbar.c wine-20050524/dlls/comctl32/toolbar.c --- wine-20050419/dlls/comctl32/toolbar.c 2005-04-15 16:09:05.000000000 +0200 +++ wine-20050524/dlls/comctl32/toolbar.c 2005-05-06 17:44:32.000000000 +0200 @@ -6233,7 +6233,7 @@ * forgets to specify TBSTYLE_TRANSPARENT but does specify either * CCS_TOP or CCS_BOTTOM (_NOMOVEY and _TOP), then the control * does *not* set TBSTYLE_TRANSPARENT even though it should!!!! - * Some how, the only cases of this seem to be MFC programs. + * Somehow, the only cases of this seem to be MFC programs. * * Note also that the addition of _TRANSPARENT occurs *only* here. It * does not occur in the WM_STYLECHANGING routine. diff -urN wine-20050419/dlls/comctl32/updown.c wine-20050524/dlls/comctl32/updown.c --- wine-20050419/dlls/comctl32/updown.c 2005-04-14 15:58:45.000000000 +0200 +++ wine-20050524/dlls/comctl32/updown.c 2005-05-11 14:01:27.000000000 +0200 @@ -775,9 +775,12 @@ break; case WM_ENABLE: - infoPtr->dwStyle &= ~WS_DISABLED; - infoPtr->dwStyle |= (wParam ? 0 : WS_DISABLED); - if (infoPtr->dwStyle & WS_DISABLED) UPDOWN_CancelMode (infoPtr); + if (wParam) { + infoPtr->dwStyle &= ~WS_DISABLED; + } else { + infoPtr->dwStyle |= WS_DISABLED; + UPDOWN_CancelMode (infoPtr); + } InvalidateRect (infoPtr->Self, NULL, FALSE); break; diff -urN wine-20050419/dlls/commdlg/.cvsignore wine-20050524/dlls/commdlg/.cvsignore --- wine-20050419/dlls/commdlg/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/commdlg/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -2,13 +2,13 @@ Makefile cdrom.ico comdlg32.dll.dbg.c -comdlg32.spec.def commdlg.spec.c floppy.ico folder.ico folder2.ico fontpics.bmp hdisk.ico +libcomdlg32.def network.ico pd32_collate.ico pd32_landscape.ico diff -urN wine-20050419/dlls/commdlg/Makefile.in wine-20050524/dlls/commdlg/Makefile.in --- wine-20050419/dlls/commdlg/Makefile.in 2004-08-12 01:59:07.000000000 +0200 +++ wine-20050524/dlls/commdlg/Makefile.in 2005-05-23 12:00:27.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = comdlg32.dll +IMPORTLIB = libcomdlg32.$(IMPLIBEXT) IMPORTS = shell32 shlwapi comctl32 winspool user32 gdi32 kernel32 ntdll EXTRALIBS = -luuid @@ -22,7 +23,6 @@ filedlg16.c \ finddlg.c \ fontdlg16.c \ - generic.c \ printdlg16.c SPEC_SRCS16 = commdlg.spec diff -urN wine-20050419/dlls/commdlg/commdlg.spec wine-20050524/dlls/commdlg/commdlg.spec --- wine-20050419/dlls/commdlg/commdlg.spec 2003-09-26 06:32:20.000000000 +0200 +++ wine-20050524/dlls/commdlg/commdlg.spec 2005-05-23 12:00:27.000000000 +0200 @@ -24,4 +24,3 @@ #29 pascal DWLBSUBCLASS exported, shared data #30 pascal DWUPARROWHACK exported, shared data #31 pascal DWOKSUBCLASS exported, shared data -32 pascal DllEntryPoint(long word word word long word) COMMDLG_DllEntryPoint diff -urN wine-20050419/dlls/commdlg/filedlg.c wine-20050524/dlls/commdlg/filedlg.c --- wine-20050419/dlls/commdlg/filedlg.c 2005-04-18 12:30:56.000000000 +0200 +++ wine-20050524/dlls/commdlg/filedlg.c 2005-05-09 21:33:24.000000000 +0200 @@ -1835,7 +1835,13 @@ TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_w(lpszTemp), lpsf); - if(lstrlenW(lpwstrTemp)==2) PathAddBackslashW(lpwstrTemp); + /* append a backslash to drive letters */ + if(lstrlenW(lpwstrTemp)==2 && lpwstrTemp[1] == ':' && + ((lpwstrTemp[0] >= 'a' && lpwstrTemp[0] <= 'z') || + (lpwstrTemp[0] >= 'A' && lpwstrTemp[0] <= 'Z'))) + { + PathAddBackslashW(lpwstrTemp); + } dwAttributes = SFGAO_FOLDER; if(SUCCEEDED(IShellFolder_ParseDisplayName(lpsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes))) diff -urN wine-20050419/dlls/commdlg/filedlgbrowser.c wine-20050524/dlls/commdlg/filedlgbrowser.c --- wine-20050419/dlls/commdlg/filedlgbrowser.c 2005-04-19 11:47:42.000000000 +0200 +++ wine-20050524/dlls/commdlg/filedlgbrowser.c 2005-05-12 11:56:17.000000000 +0200 @@ -776,7 +776,8 @@ else { /* Tell the dialog that the user selected a file */ - hRes = PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L); + PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L); + hRes = S_OK; } /* Free memory used by pidl */ diff -urN wine-20050419/dlls/commdlg/fontdlg.c wine-20050524/dlls/commdlg/fontdlg.c --- wine-20050419/dlls/commdlg/fontdlg.c 2005-02-25 15:00:38.000000000 +0100 +++ wine-20050524/dlls/commdlg/fontdlg.c 2005-05-13 19:50:26.000000000 +0200 @@ -1024,18 +1024,15 @@ LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcfw) { LPCHOOSEFONTA lpcfa; - LPCSTR lpTemplateName; LPSTR lpszStyle; LPLOGFONTA lpLogFonta; int len; lpcfa = GetPropW(hwnd, strWineFontData_a); lpLogFonta = lpcfa->lpLogFont; - lpTemplateName = lpcfa->lpTemplateName; lpszStyle = lpcfa->lpszStyle; memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA)); lpcfa->lpLogFont = lpLogFonta; - lpcfa->lpTemplateName = lpTemplateName; lpcfa->lpszStyle = lpszStyle; memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA)); WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, @@ -1047,9 +1044,9 @@ HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle); } - HeapFree(GetProcessHeap(), 0, (LPBYTE)lpcfw->lpTemplateName); HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont); HeapFree(GetProcessHeap(), 0, lpcfw); + SetPropW(hwnd, strWineFontData, 0); return TRUE; } @@ -1141,13 +1138,6 @@ MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len); } - if((lpcfa->Flags & CF_ENABLETEMPLATE) && lpcfa->lpTemplateName) { - len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpTemplateName, -1, NULL, 0); - lpcfw->lpTemplateName = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, lpcfa->lpTemplateName, - -1, (LPWSTR)lpcfw->lpTemplateName, len); - } - if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcfw)) { TRACE("CFn_WMInitDialog returned FALSE\n"); diff -urN wine-20050419/dlls/commdlg/generic.c wine-20050524/dlls/commdlg/generic.c --- wine-20050419/dlls/commdlg/generic.c 2003-12-12 07:09:13.000000000 +0100 +++ wine-20050524/dlls/commdlg/generic.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,63 +0,0 @@ -/* - * COMMDLG/COMDLG32 functions - * - * Copyright 1994 Martin Ayotte - * Copyright 1996 Albrecht Kleine - * Copyright 1998,1999 Bertho Stultiens - * Copyright 1999 Klaas van Gend - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "commdlg.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#include "cdlg.h" -#include "cdlg16.h" - -/*********************************************************************** - * DllEntryPoint [COMMDLG.32] - * - * Initialization code for the COMMDLG DLL - * - * RETURNS: - */ -BOOL WINAPI COMMDLG_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2) -{ - TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2); - return TRUE; -} - - -/*********************************************************************** - * CommDlgExtendedError16 [COMMDLG.26] - * - * Get the last error value if a commdlg function fails. - * RETURNS - * Current error value which might not be valid - * if a previous call succeeded. - */ -DWORD WINAPI CommDlgExtendedError16(void) -{ - return CommDlgExtendedError(); -} diff -urN wine-20050419/dlls/crtdll/.cvsignore wine-20050524/dlls/crtdll/.cvsignore --- wine-20050419/dlls/crtdll/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/crtdll/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,3 +1,3 @@ Makefile crtdll.dll.dbg.c -crtdll.spec.def +libcrtdll.def diff -urN wine-20050419/dlls/crtdll/Makefile.in wine-20050524/dlls/crtdll/Makefile.in --- wine-20050419/dlls/crtdll/Makefile.in 2003-10-11 03:09:20.000000000 +0200 +++ wine-20050524/dlls/crtdll/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = crtdll.dll +IMPORTLIB = libcrtdll.$(IMPLIBEXT) IMPORTS = msvcrt kernel32 EXTRALIBS = $(LIBUNICODE) EXTRAINCL = -I$(TOPSRCDIR)/include/msvcrt diff -urN wine-20050419/dlls/crtdll/crtdll_main.c wine-20050524/dlls/crtdll/crtdll_main.c --- wine-20050419/dlls/crtdll/crtdll_main.c 2003-08-22 07:05:57.000000000 +0200 +++ wine-20050524/dlls/crtdll/crtdll_main.c 2005-05-06 18:22:55.000000000 +0200 @@ -21,7 +21,9 @@ #include "config.h" #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #include "windef.h" #include "winbase.h" diff -urN wine-20050419/dlls/crypt32/.cvsignore wine-20050524/dlls/crypt32/.cvsignore --- wine-20050419/dlls/crypt32/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/crypt32/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,3 +1,3 @@ Makefile crypt32.dll.dbg.c -crypt32.spec.def +libcrypt32.def diff -urN wine-20050419/dlls/crypt32/Makefile.in wine-20050524/dlls/crypt32/Makefile.in --- wine-20050419/dlls/crypt32/Makefile.in 2004-03-01 22:19:37.000000000 +0100 +++ wine-20050524/dlls/crypt32/Makefile.in 2005-05-24 11:58:26.000000000 +0200 @@ -4,12 +4,17 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = crypt32.dll +IMPORTLIB = libcrypt32.$(IMPLIBEXT) IMPORTS = advapi32 kernel32 C_SRCS = \ cert.c \ + encode.c \ + protectdata.c \ main.c +SUBDIRS = tests + @MAKE_DLL_RULES@ ### Dependencies: diff -urN wine-20050419/dlls/crypt32/crypt32.spec wine-20050524/dlls/crypt32/crypt32.spec --- wine-20050419/dlls/crypt32/crypt32.spec 2004-11-10 02:31:50.000000000 +0100 +++ wine-20050524/dlls/crypt32/crypt32.spec 2005-05-20 21:37:26.000000000 +0200 @@ -85,10 +85,12 @@ @ stub CryptCloseAsyncHandle @ stub CryptCreateAsyncHandle @ stub CryptDecodeMessage -@ stub CryptDecodeObject +@ stdcall CryptDecodeObject(long str ptr long long ptr ptr) +@ stdcall CryptDecodeObjectEx(long str ptr long long ptr ptr ptr) @ stub CryptDecryptAndVerifyMessageSignature @ stub CryptDecryptMessage -@ stub CryptEncodeObject +@ stdcall CryptEncodeObject(long str ptr ptr ptr) +@ stdcall CryptEncodeObjectEx(long str ptr long ptr ptr) @ stub CryptEncryptMessage @ stub CryptEnumOIDFunction @ stub CryptEnumOIDInfo @@ -149,9 +151,9 @@ @ stub CryptSignHashU @ stub CryptSignMessage @ stub CryptSignMessageWithKey -@ stub CryptUnprotectData +@ stdcall CryptUnprotectData(ptr ptr ptr ptr ptr long ptr) @ stub CryptUnregisterDefaultOIDFunction -@ stub CryptUnregisterOIDFunction +@ stdcall CryptUnregisterOIDFunction(long str str) @ stub CryptUnregisterOIDInfo @ stub CryptVerifyCertificateSignature @ stub CryptVerifyDetachedMessageHash diff -urN wine-20050419/dlls/crypt32/encode.c wine-20050524/dlls/crypt32/encode.c --- wine-20050419/dlls/crypt32/encode.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/crypt32/encode.c 2005-05-20 21:37:26.000000000 +0200 @@ -0,0 +1,181 @@ +/* + * Copyright 2002 Mike McCormack for CodeWeavers + * Copyright 2005 Juan Lang + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#include "winreg.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID) +{ + static const char szEncodingTypeFmt[] = + "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s"; + UINT len; + char numericOID[7]; /* enough for "#65535" */ + const char *oid; + LPSTR szKey; + + /* MSDN says the encoding type is a mask, but it isn't treated that way. + * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and + * "EncodingType 2" would be expected if it were a mask. Instead native + * stores values in "EncodingType 3". + */ + if (!HIWORD(pszOID)) + { + snprintf(numericOID, sizeof(numericOID), "#%d", (int)pszOID); + oid = numericOID; + } + else + oid = pszOID; + + /* This is enough: the lengths of the two string parameters are explicitly + * counted, and we need up to five additional characters for the encoding + * type. These are covered by the "%d", "%s", and "%s" characters in the + * format specifier that are removed by sprintf. + */ + len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid); + szKey = HeapAlloc(GetProcessHeap(), 0, len); + if (szKey) + sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid); + return szKey; +} + +BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName) +{ + LONG r; + static const WCHAR szDllName[] = { 'D','l','l',0 }; + HKEY hKey; + LPSTR szKey; + + TRACE("%lx %s %s %s %s\n", dwEncodingType, pszFuncName, pszOID, + debugstr_w(pwszDll), pszOverrideFuncName); + + /* MSDN states dwEncodingType is a mask, but it isn't really treated as + * such. Values 65536 or greater are ignored. + */ + if (dwEncodingType >= PKCS_7_ASN_ENCODING) + return TRUE; + + /* I'm not matching MS bug for bug here, because I doubt any app depends on + * it: + * - native does nothing if pwszDll is NULL + * - native "succeeds" if pszFuncName is NULL, but the nonsensical entry + * it creates would never be used + * - native returns an HRESULT rather than a Win32 error if pszOID is NULL. + * Instead I disallow all of these with ERROR_INVALID_PARAMETER. + */ + if (!pszFuncName || !pszOID || !pwszDll) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); + TRACE("Key name is %s\n", debugstr_a(szKey)); + + if (!szKey) + return FALSE; + + r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); + HeapFree(GetProcessHeap(), 0, szKey); + if(r != ERROR_SUCCESS) + return FALSE; + + /* write the values */ + if (pszOverrideFuncName) + RegSetValueExA(hKey, "FuncName", 0, REG_SZ, pszOverrideFuncName, + lstrlenA(pszOverrideFuncName) + 1); + RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*) pwszDll, + (lstrlenW(pwszDll) + 1) * sizeof (WCHAR)); + + RegCloseKey(hKey); + return TRUE; +} + +BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID) +{ + LPSTR szKey; + LONG rc; + + TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID); + + if (dwEncodingType >= PKCS_7_ASN_ENCODING) + return TRUE; + + if (!pszFuncName || !pszOID) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); + rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey); + if (!rc) + SetLastError(rc); + return rc ? FALSE : TRUE; +} + +BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, + const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + FIXME("(0x%08lx, %s, %p, %p, %p): stub\n", + dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : + "(integer value)", pvStructInfo, pbEncoded, pcbEncoded); + return FALSE; +} + +BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, + const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, + BYTE *pbEncoded, DWORD *pcbEncoded) +{ + FIXME("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p): stub\n", + dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : + "(integer value)", pvStructInfo, dwFlags, pEncodePara, pbEncoded, + pcbEncoded); + return FALSE; +} + +BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, + const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, + DWORD *pcbStructInfo) +{ + FIXME("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p): stub\n", + dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : + "(integer value)", pbEncoded, cbEncoded, dwFlags, pvStructInfo, + pcbStructInfo); + return FALSE; +} + +BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, + const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + FIXME("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p): stub\n", + dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : + "(integer value)", pbEncoded, cbEncoded, dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo); + return FALSE; +} diff -urN wine-20050419/dlls/crypt32/main.c wine-20050524/dlls/crypt32/main.c --- wine-20050419/dlls/crypt32/main.c 2004-11-30 22:39:00.000000000 +0100 +++ wine-20050524/dlls/crypt32/main.c 2005-05-20 21:37:26.000000000 +0200 @@ -56,14 +56,6 @@ return FALSE; } -BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn, LPCWSTR szDataDescr, DATA_BLOB* pOptionalEntropy, - PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, - DWORD dwFlags, DATA_BLOB* pDataOut) -{ - FIXME("stub!\n"); - return FALSE; -} - BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv) { FIXME("stub!\n"); @@ -209,50 +201,3 @@ debugstr_w(pwszDll)); return FALSE; } - -BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName) -{ - LONG r; - static const char szOID[] = "Software\\Microsoft\\Cryptography\\OID"; - static const char szType1[] = "EncodingType 1"; - static const WCHAR szDllName[] = { 'D','l','l',0 }; - HKEY hKey; - LPSTR szKey; - UINT len; - - TRACE("%lx %s %s %s %s\n", dwEncodingType, pszFuncName, pszOID, - debugstr_w(pwszDll), pszOverrideFuncName); - - if( dwEncodingType & PKCS_7_ASN_ENCODING ) - FIXME("PKCS_7_ASN_ENCODING not implemented\n"); - - if( dwEncodingType & X509_ASN_ENCODING ) - { - /* construct the name of the key */ - len = sizeof szOID + sizeof szType1 + 2 + - lstrlenA( pszFuncName ) + lstrlenA( pszOID ); - szKey = HeapAlloc( GetProcessHeap(), 0, len ); - if( !szKey ) - return FALSE; - sprintf( szKey, "%s\\%s\\%s\\%s", - szOID, szType1, pszFuncName, pszOID ); - - TRACE("Key name is %s\n", debugstr_a( szKey ) ); - - r = RegCreateKeyA( HKEY_LOCAL_MACHINE, szKey, &hKey ); - HeapFree( GetProcessHeap(), 0, szKey ); - if( r != ERROR_SUCCESS ) - return FALSE; - - /* write the values */ - RegSetValueExA( hKey, "FuncName", 0, REG_SZ, pszOverrideFuncName, - lstrlenA( pszOverrideFuncName ) + 1 ); - RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) pwszDll, - (lstrlenW( pwszDll ) + 1) * sizeof (WCHAR) ); - - RegCloseKey( hKey ); - } - - return TRUE; -} diff -urN wine-20050419/dlls/crypt32/protectdata.c wine-20050524/dlls/crypt32/protectdata.c --- wine-20050419/dlls/crypt32/protectdata.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/crypt32/protectdata.c 2005-05-23 11:50:26.000000000 +0200 @@ -0,0 +1,1136 @@ +/* + * Copyright 2005 Kees Cook + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* + * The Win32 CryptProtectData and CryptUnprotectData functions are meant + * to provide a mechanism for encrypting data on a machine where other users + * of the system can't be trusted. It is used in many examples as a way + * to store username and password information to the registry, but store + * it not in the clear. + * + * The encryption is symmetric, but the method is unknown. However, since + * it is keyed to the machine and the user, it is unlikely that the values + * would be portable. Since programs must first call CryptProtectData to + * get a cipher text, the underlying system doesn't have to exactly + * match the real Windows version. However, attempts have been made to + * at least try to look like the Windows version, including guesses at the + * purpose of various portions of the "opaque data blob" that is used. + * + */ + +#include +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#include "winreg.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +#define CRYPT32_PROTECTDATA_PROV PROV_RSA_FULL +#define CRYPT32_PROTECTDATA_HASH_CALG CALG_MD5 +#define CRYPT32_PROTECTDATA_KEY_CALG CALG_RC2 +#define CRYPT32_PROTECTDATA_SALT_LEN 16 + +#define CRYPT32_PROTECTDATA_SECRET "I'm hunting wabbits" + +/* + * The data format returned by the real Windows CryptProtectData seems + * to be something like this: + + DWORD count0; - how many "info0_*[16]" blocks follow (was always 1) + BYTE info0_0[16]; - unknown information + ... + DWORD count1; - how many "info1_*[16]" blocks follow (was always 1) + BYTE info1_0[16]; - unknown information + ... + DWORD null0; - NULL "end of records"? + DWORD str_len; - length of WCHAR string including term + WCHAR str[str_len]; - The "dataDescription" value + DWORD unknown0; - unknown value (seems large, but only WORD large) + DWORD unknown1; - unknown value (seems small, less than a BYTE) + DWORD data_len; - length of data (was 16 in samples) + BYTE data[data_len]; - unknown data (fingerprint?) + DWORD null1; - NULL ? + DWORD unknown2; - unknown value (seems large, but only WORD large) + DWORD unknown3; - unknown value (seems small, less than a BYTE) + DWORD salt_len; - length of salt(?) data + BYTE salt[salt_len]; - salt(?) for symmetric encryption + DWORD cipher_len; - length of cipher(?) data - was close to plain len + BYTE cipher[cipher_len]; - cipher text? + DWORD crc_len; - length of fingerprint(?) data - was 20 byte==160b SHA1 + BYTE crc[crc_len]; - fingerprint of record? + + * The data structures used in Wine are modelled after this guess. + */ + +struct protect_data_t +{ + DWORD count0; + DATA_BLOB info0; /* using this to hold crypt_magic_str */ + DWORD count1; + DATA_BLOB info1; + DWORD null0; + WCHAR * szDataDescr; /* serialized differently than the DATA_BLOBs */ + DWORD unknown0; /* perhaps the HASH alg const should go here? */ + DWORD unknown1; + DATA_BLOB data0; + DWORD null1; + DWORD unknown2; /* perhaps the KEY alg const should go here? */ + DWORD unknown3; + DATA_BLOB salt; + DATA_BLOB cipher; + DATA_BLOB fingerprint; +}; + +/* this is used to check if an incoming structure was built by Wine */ +static const char * crypt_magic_str = "Wine Crypt32 ok"; + +/* debugging tool to print strings of hex chars */ +static const char * +hex_str(unsigned char *p, int n) +{ + const char * ptr; + char report[80]; + int r=-1; + report[0]='\0'; + ptr = wine_dbg_sprintf("%s",""); + while (--n >= 0) + { + if (r++ % 20 == 19) + { + ptr = wine_dbg_sprintf("%s%s",ptr,report); + report[0]='\0'; + } + sprintf(report+strlen(report),"%s%02x", r ? "," : "", *p++); + } + return wine_dbg_sprintf("%s%s",ptr,report); +} + +#define TRACE_DATA_BLOB(blob) do { \ + TRACE("%s cbData: %u\n", #blob ,(unsigned int)((blob)->cbData)); \ + TRACE("%s pbData @ 0x%x:%s\n", #blob ,(unsigned int)((blob)->pbData), \ + hex_str((blob)->pbData, (blob)->cbData)); \ +} while (0) + +static +void serialize_dword(DWORD value,BYTE ** ptr) +{ + /*TRACE("called\n");*/ + + memcpy(*ptr,&value,sizeof(DWORD)); + *ptr+=sizeof(DWORD); +} + +static +void serialize_string(BYTE * str,BYTE ** ptr,DWORD len, DWORD width, + BOOL prepend_len) +{ + /*TRACE("called %ux%u\n",(unsigned int)len,(unsigned int)width);*/ + + if (prepend_len) + { + serialize_dword(len,ptr); + } + memcpy(*ptr,str,len*width); + *ptr+=len*width; +} + +static +BOOL unserialize_dword(BYTE * ptr, DWORD *index, DWORD size, DWORD * value) +{ + /*TRACE("called\n");*/ + + if (!ptr || !index || !value) return FALSE; + + if (*index+sizeof(DWORD)>size) + { + return FALSE; + } + + memcpy(value,&(ptr[*index]),sizeof(DWORD)); + *index+=sizeof(DWORD); + + return TRUE; +} + +static +BOOL unserialize_string(BYTE * ptr, DWORD *index, DWORD size, + DWORD len, DWORD width, BOOL inline_len, + BYTE ** data, DWORD * stored) +{ + /*TRACE("called\n");*/ + + if (!ptr || !data) return FALSE; + + if (inline_len) { + if (!unserialize_dword(ptr,index,size,&len)) + return FALSE; + } + + if (*index+len*width>size) + { + return FALSE; + } + + if (!(*data = HeapAlloc( GetProcessHeap(), 0, len*width))) + { + return FALSE; + } + + memcpy(*data,&(ptr[*index]),len*width); + if (stored) + { + *stored = len; + } + *index+=len*width; + + return TRUE; +} + +static +BOOL serialize(struct protect_data_t * pInfo, DATA_BLOB * pSerial) +{ + BYTE * ptr; + DWORD dwStrLen; + DWORD dwStruct; + + TRACE("called\n"); + + if (!pInfo || !pInfo->szDataDescr || !pSerial || + !pInfo->info0.pbData || !pInfo->info1.pbData || + !pInfo->data0.pbData || !pInfo->salt.pbData || + !pInfo->cipher.pbData || !pInfo->fingerprint.pbData) + { + return FALSE; + } + + if (pInfo->info0.cbData!=16) + { + ERR("protect_data_t info0 not 16 bytes long\n"); + } + + if (pInfo->info1.cbData!=16) + { + ERR("protect_data_t info1 not 16 bytes long\n"); + } + + dwStrLen=lstrlenW(pInfo->szDataDescr); + + pSerial->cbData=0; + pSerial->cbData+=sizeof(DWORD)*8; /* 8 raw DWORDs */ + pSerial->cbData+=sizeof(DWORD)*4; /* 4 BLOBs with size */ + pSerial->cbData+=pInfo->info0.cbData; + pSerial->cbData+=pInfo->info1.cbData; + pSerial->cbData+=(dwStrLen+1)*sizeof(WCHAR) + 4; /* str, null, size */ + pSerial->cbData+=pInfo->data0.cbData; + pSerial->cbData+=pInfo->salt.cbData; + pSerial->cbData+=pInfo->cipher.cbData; + pSerial->cbData+=pInfo->fingerprint.cbData; + + /* save the actual structure size */ + dwStruct = pSerial->cbData; + /* There may be a 256 byte minimum, but I can't prove it. */ + /*if (pSerial->cbData<256) pSerial->cbData=256;*/ + + pSerial->pbData=LocalAlloc(LPTR,pSerial->cbData); + if (!pSerial->pbData) return FALSE; + + ptr=pSerial->pbData; + + /* count0 */ + serialize_dword(pInfo->count0,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* info0 */ + serialize_string(pInfo->info0.pbData,&ptr, + pInfo->info0.cbData,sizeof(BYTE),FALSE); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* count1 */ + serialize_dword(pInfo->count1,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* info1 */ + serialize_string(pInfo->info1.pbData,&ptr, + pInfo->info1.cbData,sizeof(BYTE),FALSE); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* null0 */ + serialize_dword(pInfo->null0,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* szDataDescr */ + serialize_string((BYTE*)pInfo->szDataDescr,&ptr, + (dwStrLen+1)*sizeof(WCHAR),sizeof(BYTE),TRUE); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* unknown0 */ + serialize_dword(pInfo->unknown0,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + /* unknown1 */ + serialize_dword(pInfo->unknown1,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* data0 */ + serialize_string(pInfo->data0.pbData,&ptr, + pInfo->data0.cbData,sizeof(BYTE),TRUE); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* null1 */ + serialize_dword(pInfo->null1,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* unknown2 */ + serialize_dword(pInfo->unknown2,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + /* unknown3 */ + serialize_dword(pInfo->unknown3,&ptr); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* salt */ + serialize_string(pInfo->salt.pbData,&ptr, + pInfo->salt.cbData,sizeof(BYTE),TRUE); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* cipher */ + serialize_string(pInfo->cipher.pbData,&ptr, + pInfo->cipher.cbData,sizeof(BYTE),TRUE); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + /* fingerprint */ + serialize_string(pInfo->fingerprint.pbData,&ptr, + pInfo->fingerprint.cbData,sizeof(BYTE),TRUE); + /*TRACE("used %u\n",ptr-pSerial->pbData);*/ + + if (ptr - pSerial->pbData != dwStruct) + { + ERR("struct size changed!? %u != expected %u\n", + ptr - pSerial->pbData, (unsigned int)dwStruct); + LocalFree(pSerial->pbData); + pSerial->pbData=NULL; + pSerial->cbData=0; + return FALSE; + } + + return TRUE; +} + +static +BOOL unserialize(DATA_BLOB * pSerial, struct protect_data_t * pInfo) +{ + BYTE * ptr; + DWORD index; + DWORD size; + BOOL status=TRUE; + + TRACE("called\n"); + + if (!pInfo || !pSerial || !pSerial->pbData) + return FALSE; + + index=0; + ptr=pSerial->pbData; + size=pSerial->cbData; + + /* count0 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->count0)) + { + ERR("reading count0 failed!\n"); + return FALSE; + } + + /* info0 */ + if (!unserialize_string(ptr,&index,size,16,sizeof(BYTE),FALSE, + &pInfo->info0.pbData, &pInfo->info0.cbData)) + { + ERR("reading info0 failed!\n"); + return FALSE; + } + + /* count1 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->count1)) + { + ERR("reading count1 failed!\n"); + return FALSE; + } + + /* info1 */ + if (!unserialize_string(ptr,&index,size,16,sizeof(BYTE),FALSE, + &pInfo->info1.pbData, &pInfo->info1.cbData)) + { + ERR("reading info1 failed!\n"); + return FALSE; + } + + /* null0 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->null0)) + { + ERR("reading null0 failed!\n"); + return FALSE; + } + + /* szDataDescr */ + if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE, + (BYTE**)&pInfo->szDataDescr, NULL)) + { + ERR("reading szDataDescr failed!\n"); + return FALSE; + } + + /* unknown0 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->unknown0)) + { + ERR("reading unknown0 failed!\n"); + return FALSE; + } + + /* unknown1 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->unknown1)) + { + ERR("reading unknown1 failed!\n"); + return FALSE; + } + + /* data0 */ + if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE, + &pInfo->data0.pbData, &pInfo->data0.cbData)) + { + ERR("reading data0 failed!\n"); + return FALSE; + } + + /* null1 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->null1)) + { + ERR("reading null1 failed!\n"); + return FALSE; + } + + /* unknown2 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->unknown2)) + { + ERR("reading unknown2 failed!\n"); + return FALSE; + } + + /* unknown3 */ + if (!unserialize_dword(ptr,&index,size,&pInfo->unknown3)) + { + ERR("reading unknown3 failed!\n"); + return FALSE; + } + + /* salt */ + if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE, + &pInfo->salt.pbData, &pInfo->salt.cbData)) + { + ERR("reading salt failed!\n"); + return FALSE; + } + + /* cipher */ + if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE, + &pInfo->cipher.pbData, &pInfo->cipher.cbData)) + { + ERR("reading cipher failed!\n"); + return FALSE; + } + + /* fingerprint */ + if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE, + &pInfo->fingerprint.pbData, &pInfo->fingerprint.cbData)) + { + ERR("reading fingerprint failed!\n"); + return FALSE; + } + + /* allow structure size to be too big (since some applications + * will pad this up to 256 bytes, it seems) */ + if (index>size) + { + /* this is an impossible-to-reach test, but if the padding + * issue is ever understood, this may become more useful */ + ERR("loaded corrupt structure! (used %u expected %u)\n", + (unsigned int)index, (unsigned int)size); + status=FALSE; + } + + return status; +} + +/* perform sanity checks */ +static +BOOL valid_protect_data(struct protect_data_t * pInfo) +{ + BOOL status=TRUE; + + TRACE("called\n"); + + if (pInfo->count0 != 0x0001) + { + ERR("count0 != 0x0001 !\n"); + status=FALSE; + } + if (pInfo->count1 != 0x0001) + { + ERR("count0 != 0x0001 !\n"); + status=FALSE; + } + if (pInfo->null0 != 0x0000) + { + ERR("null0 != 0x0000 !\n"); + status=FALSE; + } + if (pInfo->null1 != 0x0000) + { + ERR("null1 != 0x0000 !\n"); + status=FALSE; + } + /* since we have no idea what info0 is used for, and it seems + * rather constant, we can test for a Wine-specific magic string + * there to be reasonably sure we're using data created by the Wine + * implementation of CryptProtectData. + */ + if (pInfo->info0.cbData!=strlen(crypt_magic_str)+1 || + strcmp(pInfo->info0.pbData,crypt_magic_str) != 0) + { + ERR("info0 magic value not matched !\n"); + status=FALSE; + } + + if (!status) + { + ERR("unrecognized CryptProtectData block\n"); + } + + return status; +} + +static +void free_protect_data(struct protect_data_t * pInfo) +{ + TRACE("called\n"); + + if (!pInfo) return; + + if (pInfo->info0.pbData) + HeapFree( GetProcessHeap(), 0, pInfo->info0.pbData); + if (pInfo->info1.pbData) + HeapFree( GetProcessHeap(), 0, pInfo->info1.pbData); + if (pInfo->szDataDescr) + HeapFree( GetProcessHeap(), 0, pInfo->szDataDescr); + if (pInfo->data0.pbData) + HeapFree( GetProcessHeap(), 0, pInfo->data0.pbData); + if (pInfo->salt.pbData) + HeapFree( GetProcessHeap(), 0, pInfo->salt.pbData); + if (pInfo->cipher.pbData) + HeapFree( GetProcessHeap(), 0, pInfo->cipher.pbData); + if (pInfo->fingerprint.pbData) + HeapFree( GetProcessHeap(), 0, pInfo->fingerprint.pbData); +} + +/* copies a string into a data blob */ +static +BYTE * convert_str_to_blob(char* str, DATA_BLOB* blob) +{ + if (!str || !blob) return NULL; + + blob->cbData=strlen(str)+1; + if (!(blob->pbData=HeapAlloc(GetProcessHeap(),0,blob->cbData))) + { + blob->cbData=0; + } + else { + strcpy(blob->pbData, str); + } + + return blob->pbData; +} + +/* + * Populates everything except "cipher" and "fingerprint". + */ +static +BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr, + HCRYPTPROV hProv) +{ + DWORD dwStrLen; + + TRACE("called\n"); + + if (!pInfo) return FALSE; + + dwStrLen=lstrlenW(szDataDescr); + + memset(pInfo,0,sizeof(*pInfo)); + + pInfo->count0=0x0001; + + convert_str_to_blob((char*)crypt_magic_str,&pInfo->info0); + + pInfo->count1=0x0001; + + convert_str_to_blob((char*)crypt_magic_str,&pInfo->info1); + + pInfo->null0=0x0000; + + if ((pInfo->szDataDescr=HeapAlloc( GetProcessHeap(), 0, (dwStrLen+1)*sizeof(WCHAR)))) + { + memcpy(pInfo->szDataDescr,szDataDescr,(dwStrLen+1)*sizeof(WCHAR)); + } + + pInfo->unknown0=0x0000; + pInfo->unknown1=0x0000; + + convert_str_to_blob((char*)crypt_magic_str,&pInfo->data0); + + pInfo->null1=0x0000; + pInfo->unknown2=0x0000; + pInfo->unknown3=0x0000; + + /* allocate memory to hold a salt */ + pInfo->salt.cbData=CRYPT32_PROTECTDATA_SALT_LEN; + if ((pInfo->salt.pbData=HeapAlloc( GetProcessHeap(),0,pInfo->salt.cbData))) + { + /* generate random salt */ + if (!CryptGenRandom(hProv, pInfo->salt.cbData, pInfo->salt.pbData)) + { + ERR("CryptGenRandom\n"); + free_protect_data(pInfo); + return FALSE; + } + } + + /* debug: show our salt */ + TRACE_DATA_BLOB(&pInfo->salt); + + pInfo->cipher.cbData=0; + pInfo->cipher.pbData=NULL; + + pInfo->fingerprint.cbData=0; + pInfo->fingerprint.pbData=NULL; + + /* check all the allocations at once */ + if (!pInfo->info0.pbData || + !pInfo->info1.pbData || + !pInfo->szDataDescr || + !pInfo->data0.pbData || + !pInfo->salt.pbData + ) + { + ERR("could not allocate protect_data structures\n"); + free_protect_data(pInfo); + return FALSE; + } + + return TRUE; +} + +static +BOOL convert_hash_to_blob(HCRYPTHASH hHash, DATA_BLOB * blob) +{ + DWORD dwSize; + + TRACE("called\n"); + + if (!blob) return FALSE; + + dwSize=sizeof(DWORD); + if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&blob->cbData, + &dwSize, 0)) + { + ERR("failed to get hash size\n"); + return FALSE; + } + + if (!(blob->pbData=HeapAlloc( GetProcessHeap(), 0, blob->cbData))) + { + ERR("failed to allocate blob memory\n"); + return FALSE; + } + + dwSize=blob->cbData; + if (!CryptGetHashParam(hHash, HP_HASHVAL, blob->pbData, &dwSize, 0)) + { + ERR("failed to get hash value\n"); + HeapFree( GetProcessHeap(), 0, blob->pbData); + blob->pbData=NULL; + blob->cbData=0; + return FALSE; + } + + return TRUE; +} + +/* test that a given hash matches an exported-to-blob hash value */ +static +BOOL hash_matches_blob(HCRYPTHASH hHash, DATA_BLOB * two) +{ + BOOL rc = FALSE; + DATA_BLOB one; + + if (!two || !two->pbData) return FALSE; + + if (!convert_hash_to_blob(hHash,&one)) { + return FALSE; + } + + if ( one.cbData == two->cbData && + memcmp( one.pbData, two->pbData, one.cbData ) == 0 ) + { + rc = TRUE; + } + + HeapFree( GetProcessHeap(), 0, one.pbData ); + return rc; +} + +/* create an encryption key from a given salt and optional entropy */ +static +BOOL load_encryption_key(HCRYPTPROV hProv, DATA_BLOB * salt, + DATA_BLOB * pOptionalEntropy, HCRYPTKEY * phKey) +{ + BOOL rc = TRUE; + HCRYPTHASH hSaltHash; + char * szUsername = NULL; + DWORD dwUsernameLen; + DWORD dwError; + + /* create hash for salt */ + if (!salt || !phKey || + !CryptCreateHash(hProv,CRYPT32_PROTECTDATA_HASH_CALG,0,0,&hSaltHash)) + { + ERR("CryptCreateHash\n"); + return FALSE; + } + + /* This should be the "logon credentials" instead of username */ + dwError=GetLastError(); + dwUsernameLen = 0; + if (!GetUserNameA(NULL,&dwUsernameLen) && + GetLastError()==ERROR_MORE_DATA && dwUsernameLen && + (szUsername = HeapAlloc( GetProcessHeap(), 0, dwUsernameLen))) + { + szUsername[0]='\0'; + GetUserNameA( szUsername, &dwUsernameLen ); + } + SetLastError(dwError); + + /* salt the hash with: + * - the user id + * - an "internal secret" + * - randomness (from the salt) + * - user-supplied entropy + */ + if ((szUsername && !CryptHashData(hSaltHash,szUsername,dwUsernameLen,0)) || + !CryptHashData(hSaltHash,CRYPT32_PROTECTDATA_SECRET, + strlen(CRYPT32_PROTECTDATA_SECRET),0) || + !CryptHashData(hSaltHash,salt->pbData,salt->cbData,0) || + (pOptionalEntropy && !CryptHashData(hSaltHash, + pOptionalEntropy->pbData, + pOptionalEntropy->cbData,0))) + { + ERR("CryptHashData\n"); + rc = FALSE; + } + + /* produce a symmetric key */ + if (rc && !CryptDeriveKey(hProv,CRYPT32_PROTECTDATA_KEY_CALG, + hSaltHash,CRYPT_EXPORTABLE,phKey)) + { + ERR("CryptDeriveKey\n"); + rc = FALSE; + } + + /* clean up */ + CryptDestroyHash(hSaltHash); + if (szUsername) HeapFree( GetProcessHeap(), 0, szUsername ); + + return rc; +} + +/* debugging tool to print the structures of a ProtectData call */ +static void +report(DATA_BLOB* pDataIn, DATA_BLOB* pOptionalEntropy, + CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags) +{ + TRACE("pPromptStruct: 0x%x\n",(unsigned int)pPromptStruct); + if (pPromptStruct) + { + TRACE(" cbSize: 0x%x\n",(unsigned int)pPromptStruct->cbSize); + TRACE(" dwPromptFlags: 0x%x\n",(unsigned int)pPromptStruct->dwPromptFlags); + TRACE(" hwndApp: 0x%x\n",(unsigned int)pPromptStruct->hwndApp); + TRACE(" szPrompt: 0x%x %s\n", + (unsigned int)pPromptStruct->szPrompt, + pPromptStruct->szPrompt ? debugstr_w(pPromptStruct->szPrompt) + : ""); + } + TRACE("dwFlags: 0x%04x\n",(unsigned int)dwFlags); + TRACE_DATA_BLOB(pDataIn); + if (pOptionalEntropy) + { + TRACE_DATA_BLOB(pOptionalEntropy); + TRACE(" %s\n",debugstr_an(pOptionalEntropy->pbData,pOptionalEntropy->cbData)); + } + +} + + +/*************************************************************************** + * CryptProtectData [CRYPT32.@] + * + * Generate Cipher data from given Plain and Entropy data. + * + * PARAMS + * pDataIn [I] Plain data to be enciphered + * szDataDescr [I] Optional Unicode string describing the Plain data + * pOptionalEntropy [I] Optional entropy data to adjust cipher, can be NULL + * pvReserved [I] Reserved, must be NULL + * pPromptStruct [I] Structure describing if/how to prompt during ciphering + * dwFlags [I] Flags describing options to the ciphering + * pDataOut [O] Resulting Cipher data, for calls to CryptUnprotectData + * + * RETURNS + * TRUE If a Cipher was generated. + * FALSE If something failed and no Cipher is available. + * + * FIXME + * The true Windows encryption and keying mechanisms are unknown. + * + * dwFlags and pPromptStruct are currently ignored. + * + * NOTES + * Memory allocated in pDataOut must be freed with LocalFree. + * + */ +BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn, + LPCWSTR szDataDescr, + DATA_BLOB* pOptionalEntropy, + PVOID pvReserved, + CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, + DWORD dwFlags, + DATA_BLOB* pDataOut) +{ + BOOL rc = FALSE; + + HCRYPTPROV hProv; + struct protect_data_t protect_data; + HCRYPTHASH hHash; + HCRYPTKEY hKey; + DWORD dwLength; + + TRACE("called\n"); + + SetLastError(ERROR_SUCCESS); + + if (!pDataIn || !pDataOut) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto finished; + } + + /* debug: show our arguments */ + report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags); + TRACE("\tszDataDescr: 0x%x %s\n",(unsigned int)szDataDescr, + szDataDescr ? debugstr_w(szDataDescr) : ""); + + /* Windows appears to create an empty szDataDescr instead of maintaining + * a NULL */ + if (!szDataDescr) + szDataDescr=(WCHAR[]){'\0'}; + + /* get crypt context */ + if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,0) && + !CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_NEWKEYSET)) + { + ERR("CryptAcquireContextW failed\n"); + goto finished; + } + + /* populate our structure */ + if (!fill_protect_data(&protect_data,szDataDescr,hProv)) + { + ERR("fill_protect_data\n"); + goto free_context; + } + + /* load key */ + if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey)) + { + goto free_protect_data; + } + + /* create a hash for the encryption validation */ + if (!CryptCreateHash(hProv,CRYPT32_PROTECTDATA_HASH_CALG,0,0,&hHash)) + { + ERR("CryptCreateHash\n"); + goto free_key; + } + + /* calculate storage required */ + dwLength=pDataIn->cbData; + if (CryptEncrypt(hKey, 0, TRUE, 0, pDataIn->pbData, &dwLength, 0) || + GetLastError()!=ERROR_MORE_DATA) + { + ERR("CryptEncrypt\n"); + goto free_hash; + } + TRACE("required encrypted storage: %u\n",(unsigned int)dwLength); + + /* copy plain text into cipher area for CryptEncrypt call */ + protect_data.cipher.cbData=dwLength; + if (!(protect_data.cipher.pbData=HeapAlloc( GetProcessHeap(), 0, + protect_data.cipher.cbData))) + { + ERR("HeapAlloc\n"); + goto free_hash; + } + memcpy(protect_data.cipher.pbData,pDataIn->pbData,pDataIn->cbData); + + /* encrypt! */ + dwLength=pDataIn->cbData; + if (!CryptEncrypt(hKey, hHash, TRUE, 0, protect_data.cipher.pbData, + &dwLength, protect_data.cipher.cbData)) + { + ERR("CryptEncrypt %u\n",(unsigned int)GetLastError()); + goto free_hash; + } + protect_data.cipher.cbData=dwLength; + + /* debug: show the cipher */ + TRACE_DATA_BLOB(&protect_data.cipher); + + /* attach our fingerprint */ + if (!convert_hash_to_blob(hHash, &protect_data.fingerprint)) + { + ERR("convert_hash_to_blob\n"); + goto free_hash; + } + + /* serialize into an opaque blob */ + if (!serialize(&protect_data, pDataOut)) + { + ERR("serialize\n"); + goto free_hash; + } + + /* success! */ + rc=TRUE; + +free_hash: + CryptDestroyHash(hHash); +free_key: + CryptDestroyKey(hKey); +free_protect_data: + free_protect_data(&protect_data); +free_context: + CryptReleaseContext(hProv,0); +finished: + /* If some error occured, and no error code was set, force one. */ + if (!rc && GetLastError()==ERROR_SUCCESS) + { + SetLastError(ERROR_INVALID_DATA); + } + + if (rc) + { + SetLastError(ERROR_SUCCESS); + + TRACE_DATA_BLOB(pDataOut); + } + + TRACE("returning %s\n", rc ? "ok" : "FAIL"); + + return rc; +} + + +/*************************************************************************** + * CryptUnprotectData [CRYPT32.@] + * + * Generate Plain data and Description from given Cipher and Entropy data. + * + * PARAMS + * pDataIn [I] Cipher data to be decoded + * ppszDataDescr [O] Optional Unicode string describing the Plain data + * pOptionalEntropy [I] Optional entropy data to adjust cipher, can be NULL + * pvReserved [I] Reserved, must be NULL + * pPromptStruct [I] Structure describing if/how to prompt during decoding + * dwFlags [I] Flags describing options to the decoding + * pDataOut [O] Resulting Plain data, from calls to CryptProtectData + * + * RETURNS + * TRUE If a Plain was generated. + * FALSE If something failed and no Plain is available. + * + * FIXME + * The true Windows encryption and keying mechanisms are unknown. + * + * dwFlags and pPromptStruct are currently ignored. + * + * NOTES + * Memory allocated in pDataOut and non-NULL ppszDataDescr must be freed + * with LocalFree. + * + */ +BOOL WINAPI CryptUnprotectData(DATA_BLOB* pDataIn, + LPWSTR * ppszDataDescr, + DATA_BLOB* pOptionalEntropy, + PVOID pvReserved, + CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, + DWORD dwFlags, + DATA_BLOB* pDataOut) +{ + BOOL rc = FALSE; + + HCRYPTPROV hProv; + struct protect_data_t protect_data; + HCRYPTHASH hHash; + HCRYPTKEY hKey; + DWORD dwLength; + + const char * announce_bad_opaque_data = "CryptUnprotectData received a DATA_BLOB that seems to have NOT been generated by Wine. Please enable tracing ('export WINEDEBUG=crypt') to see details."; + + TRACE("called\n"); + + SetLastError(ERROR_SUCCESS); + + if (!pDataIn || !pDataOut) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto finished; + } + + /* debug: show our arguments */ + report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags); + TRACE("\tppszDataDescr: 0x%x\n",(unsigned int)ppszDataDescr); + + /* take apart the opaque blob */ + if (!unserialize(pDataIn, &protect_data)) + { + SetLastError(ERROR_INVALID_DATA); + FIXME("%s\n",announce_bad_opaque_data); + goto finished; + } + + /* perform basic validation on the resulting structure */ + if (!valid_protect_data(&protect_data)) + { + SetLastError(ERROR_INVALID_DATA); + FIXME("%s\n",announce_bad_opaque_data); + goto free_protect_data; + } + + /* get a crypt context */ + if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,0) && + !CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_NEWKEYSET)) + { + ERR("CryptAcquireContextW failed\n"); + goto free_protect_data; + } + + /* load key */ + if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey)) + { + goto free_context; + } + + /* create a hash for the decryption validation */ + if (!CryptCreateHash(hProv,CRYPT32_PROTECTDATA_HASH_CALG,0,0,&hHash)) + { + ERR("CryptCreateHash\n"); + goto free_key; + } + + /* prepare for plaintext */ + pDataOut->cbData=protect_data.cipher.cbData; + if (!(pDataOut->pbData=LocalAlloc( LPTR, pDataOut->cbData))) + { + ERR("HeapAlloc\n"); + goto free_hash; + } + memcpy(pDataOut->pbData,protect_data.cipher.pbData,protect_data.cipher.cbData); + + /* decrypt! */ + if (!CryptDecrypt(hKey, hHash, TRUE, 0, pDataOut->pbData, + &pDataOut->cbData) || + /* check the hash fingerprint */ + pDataOut->cbData > protect_data.cipher.cbData || + !hash_matches_blob(hHash, &protect_data.fingerprint)) + { + SetLastError(ERROR_INVALID_DATA); + + LocalFree( pDataOut->pbData ); + pDataOut->pbData = NULL; + pDataOut->cbData = 0; + + goto free_hash; + } + + /* Copy out the description */ + dwLength = (lstrlenW(protect_data.szDataDescr)+1) * sizeof(WCHAR); + if (ppszDataDescr) + { + if (!(*ppszDataDescr = LocalAlloc(LPTR,dwLength))) + { + ERR("LocalAlloc (ppszDataDescr)\n"); + goto free_hash; + } + else { + memcpy(*ppszDataDescr,protect_data.szDataDescr,dwLength); + } + } + + /* success! */ + rc = TRUE; + +free_hash: + CryptDestroyHash(hHash); +free_key: + CryptDestroyKey(hKey); +free_context: + CryptReleaseContext(hProv,0); +free_protect_data: + free_protect_data(&protect_data); +finished: + /* If some error occured, and no error code was set, force one. */ + if (!rc && GetLastError()==ERROR_SUCCESS) + { + SetLastError(ERROR_INVALID_DATA); + } + + if (rc) { + SetLastError(ERROR_SUCCESS); + + if (ppszDataDescr) + { + TRACE("szDataDescr: %s\n",debugstr_w(*ppszDataDescr)); + } + TRACE_DATA_BLOB(pDataOut); + } + + TRACE("returning %s\n", rc ? "ok" : "FAIL"); + + return rc; +} diff -urN wine-20050419/dlls/crypt32/tests/.cvsignore wine-20050524/dlls/crypt32/tests/.cvsignore --- wine-20050419/dlls/crypt32/tests/.cvsignore 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/crypt32/tests/.cvsignore 2005-05-24 11:58:26.000000000 +0200 @@ -0,0 +1,3 @@ +Makefile +protectdata.ok +testlist.c diff -urN wine-20050419/dlls/crypt32/tests/Makefile.in wine-20050524/dlls/crypt32/tests/Makefile.in --- wine-20050419/dlls/crypt32/tests/Makefile.in 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/crypt32/tests/Makefile.in 2005-05-24 11:58:26.000000000 +0200 @@ -0,0 +1,13 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +TESTDLL = crypt32.dll +IMPORTS = crypt32 + +CTESTS = \ + protectdata.c + +@MAKE_TEST_RULES@ + +### Dependencies: diff -urN wine-20050419/dlls/crypt32/tests/protectdata.c wine-20050524/dlls/crypt32/tests/protectdata.c --- wine-20050419/dlls/crypt32/tests/protectdata.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/crypt32/tests/protectdata.c 2005-05-24 11:58:26.000000000 +0200 @@ -0,0 +1,215 @@ +/* + * Unit test suite for crypt32.dll's CryptProtectData/CryptUnprotectData + * + * Copyright 2005 Kees Cook + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include "wine/test.h" + +static const char * secret = "I am a super secret string that no one can see!"; +static const char * secret2 = "I am a super secret string indescribable string"; +static const char * key = "Wibble wibble wibble"; +static const WCHAR desc[] = {'U','l','t','r','a',' ','s','e','c','r','e','t',' ','t','e','s','t',' ','m','e','s','s','a','g','e',0}; +static BOOL protected = FALSE; /* if true, the unprotect tests can run */ +static DATA_BLOB cipher; +static DATA_BLOB cipher_entropy; +static DATA_BLOB cipher_no_desc; + +static void test_cryptprotectdata(void) +{ + LONG r; + DATA_BLOB plain; + DATA_BLOB entropy; + + plain.pbData=(void*)secret; + plain.cbData=strlen(secret)+1; + + entropy.pbData=(void*)key; + entropy.cbData=strlen(key)+1; + + SetLastError(0xDEADBEEF); + protected = CryptProtectData(NULL,desc,NULL,NULL,NULL,0,&cipher); + ok(!protected, "Encrypting without plain data source.\n"); + r = GetLastError(); + ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); + + SetLastError(0xDEADBEEF); + protected = CryptProtectData(&plain,desc,NULL,NULL,NULL,0,NULL); + ok(!protected, "Encrypting without cipher destination.\n"); + r = GetLastError(); + ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); + + cipher.pbData=NULL; + cipher.cbData=0; + + /* without entropy */ + SetLastError(0xDEADBEEF); + protected = CryptProtectData(&plain,desc,NULL,NULL,NULL,0,&cipher); + ok(protected, "Encrypting without entropy.\n"); + r = GetLastError(); + ok(r == ERROR_SUCCESS, "Wrong (%lu) GetLastError seen\n",r); + + cipher_entropy.pbData=NULL; + cipher_entropy.cbData=0; + + /* with entropy */ + SetLastError(0xDEADBEEF); + protected = CryptProtectData(&plain,desc,&entropy,NULL,NULL,0,&cipher_entropy); + ok(protected, "Encrypting with entropy.\n"); + r = GetLastError(); + ok(r == ERROR_SUCCESS, "Wrong (%lu) GetLastError seen\n",r); + + cipher_no_desc.pbData=NULL; + cipher_no_desc.cbData=0; + + /* with entropy but no description */ + plain.pbData=(void*)secret2; + plain.cbData=strlen(secret2)+1; + SetLastError(0xDEADBEEF); + protected = CryptProtectData(&plain,NULL,&entropy,NULL,NULL,0,&cipher_no_desc); + ok(protected, "Encrypting with entropy and no description.\n"); + r = GetLastError(); + ok(r == ERROR_SUCCESS, "Wrong (%lu) GetLastError seen\n",r); +} + +static void test_cryptunprotectdata(void) +{ + LONG r; + DATA_BLOB plain; + DATA_BLOB entropy; + BOOL okay; + WCHAR * data_desc; + + entropy.pbData=(void*)key; + entropy.cbData=strlen(key)+1; + + ok(protected, "CryptProtectData failed to run, so I can't test its output\n"); + if (!protected) return; + + plain.pbData=NULL; + plain.cbData=0; + + SetLastError(0xDEADBEEF); + okay = CryptUnprotectData(&cipher,NULL,NULL,NULL,NULL,0,NULL); + ok(!okay,"Decrypting without destination\n"); + r = GetLastError(); + ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); + + SetLastError(0xDEADBEEF); + okay = CryptUnprotectData(NULL,NULL,NULL,NULL,NULL,0,&plain); + ok(!okay,"Decrypting without source\n"); + r = GetLastError(); + ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); + + plain.pbData=NULL; + plain.cbData=0; + + SetLastError(0xDEADBEEF); + okay = CryptUnprotectData(&cipher_entropy,NULL,NULL,NULL,NULL,0,&plain); + ok(!okay,"Decrypting without needed entropy\n"); + r = GetLastError(); + ok(r == ERROR_INVALID_DATA, "Wrong (%lu) GetLastError seen\n", r); + + plain.pbData=NULL; + plain.cbData=0; + data_desc=NULL; + + /* without entropy */ + SetLastError(0xDEADBEEF); + okay = CryptUnprotectData(&cipher,&data_desc,NULL,NULL,NULL,0,&plain); + ok(okay,"Decrypting without entropy\n"); + r = GetLastError(); + ok(r == ERROR_SUCCESS, "Wrong (%lu) GetLastError seen\n",r); + + ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); + ok(plain.cbData==strlen(secret)+1,"Plain DATA_BLOB wrong length\n"); + ok(!strcmp(plain.pbData,secret),"Plain does not match secret\n"); + ok(data_desc!=NULL,"Description not allocated\n"); + ok(!lstrcmpW(data_desc,desc),"Description does not match\n"); + + LocalFree(plain.pbData); + LocalFree(data_desc); + + plain.pbData=NULL; + plain.cbData=0; + data_desc=NULL; + + /* with wrong entropy */ + SetLastError(0xDEADBEEF); + okay = CryptUnprotectData(&cipher_entropy,&data_desc,&cipher_entropy,NULL,NULL,0,&plain); + ok(!okay,"Decrypting with wrong entropy\n"); + r = GetLastError(); + ok(r == ERROR_INVALID_DATA, "Wrong (%lu) GetLastError seen\n",r); + + /* with entropy */ + SetLastError(0xDEADBEEF); + okay = CryptUnprotectData(&cipher_entropy,&data_desc,&entropy,NULL,NULL,0,&plain); + ok(okay,"Decrypting with entropy\n"); + r = GetLastError(); + ok(r == ERROR_SUCCESS, "Wrong (%lu) GetLastError seen\n",r); + + ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); + ok(plain.cbData==strlen(secret)+1,"Plain DATA_BLOB wrong length\n"); + ok(!strcmp(plain.pbData,secret),"Plain does not match secret\n"); + ok(data_desc!=NULL,"Description not allocated\n"); + ok(!lstrcmpW(data_desc,desc),"Description does not match\n"); + + LocalFree(plain.pbData); + LocalFree(data_desc); + + plain.pbData=NULL; + plain.cbData=0; + data_desc=NULL; + + /* with entropy but no description */ + SetLastError(0xDEADBEEF); + okay = CryptUnprotectData(&cipher_no_desc,&data_desc,&entropy,NULL,NULL,0,&plain); + ok(okay,"Decrypting with entropy and no description\n"); + r = GetLastError(); + ok(r == ERROR_SUCCESS, "Wrong (%lu) GetLastError seen\n",r); + + ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); + ok(plain.cbData==strlen(secret2)+1,"Plain DATA_BLOB wrong length\n"); + ok(!strcmp(plain.pbData,secret2),"Plain does not match secret\n"); + ok(data_desc!=NULL,"Description not allocated\n"); + ok(data_desc[0]=='\0',"Description not empty\n"); + + LocalFree(plain.pbData); + + plain.pbData=NULL; + plain.cbData=0; +} + +START_TEST(protectdata) +{ + protected=FALSE; + + test_cryptprotectdata(); + test_cryptunprotectdata(); + + /* deinit globals here */ + if (cipher.pbData) LocalFree(cipher.pbData); + if (cipher_entropy.pbData) LocalFree(cipher_entropy.pbData); + if (cipher_no_desc.pbData) LocalFree(cipher_no_desc.pbData); +} diff -urN wine-20050419/dlls/cryptdll/.cvsignore wine-20050524/dlls/cryptdll/.cvsignore --- wine-20050419/dlls/cryptdll/.cvsignore 2005-01-24 20:07:16.000000000 +0100 +++ wine-20050524/dlls/cryptdll/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,3 +1,3 @@ Makefile cryptdll.dll.dbg.c -cryptdll.spec.def +libcryptdll.def diff -urN wine-20050419/dlls/cryptdll/Makefile.in wine-20050524/dlls/cryptdll/Makefile.in --- wine-20050419/dlls/cryptdll/Makefile.in 2005-02-22 20:34:15.000000000 +0100 +++ wine-20050524/dlls/cryptdll/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cryptdll.dll +IMPORTLIB = libcryptdll.$(IMPLIBEXT) IMPORTS = advapi32 kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/ctl3d/.cvsignore wine-20050524/dlls/ctl3d/.cvsignore --- wine-20050419/dlls/ctl3d/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/ctl3d/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,5 +1,5 @@ Makefile ctl3d.spec.c ctl3d32.dll.dbg.c -ctl3d32.spec.def ctl3dv2.spec.c +libctl3d32.def diff -urN wine-20050419/dlls/ctl3d/Makefile.in wine-20050524/dlls/ctl3d/Makefile.in --- wine-20050419/dlls/ctl3d/Makefile.in 2004-08-12 01:59:07.000000000 +0200 +++ wine-20050524/dlls/ctl3d/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = ctl3d32.dll +IMPORTLIB = libctl3d32.$(IMPLIBEXT) IMPORTS = user32 kernel32 C_SRCS = ctl3d32.c diff -urN wine-20050419/dlls/d3d8/.cvsignore wine-20050524/dlls/d3d8/.cvsignore --- wine-20050419/dlls/d3d8/.cvsignore 2004-03-24 04:36:50.000000000 +0100 +++ wine-20050524/dlls/d3d8/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile d3d8.dll.dbg.c -d3d8.spec.def +libd3d8.def version.res diff -urN wine-20050419/dlls/d3d8/Makefile.in wine-20050524/dlls/d3d8/Makefile.in --- wine-20050419/dlls/d3d8/Makefile.in 2004-09-28 04:12:12.000000000 +0200 +++ wine-20050524/dlls/d3d8/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3d8.dll +IMPORTLIB = libd3d8.$(IMPLIBEXT) IMPORTS = wined3d user32 gdi32 advapi32 kernel32 EXTRAINCL = @X_CFLAGS@ EXTRALIBS = -ldxguid -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ diff -urN wine-20050419/dlls/d3d8/d3d8_main.c wine-20050524/dlls/d3d8/d3d8_main.c --- wine-20050419/dlls/d3d8/d3d8_main.c 2004-11-23 14:52:46.000000000 +0100 +++ wine-20050524/dlls/d3d8/d3d8_main.c 2005-05-06 21:38:50.000000000 +0200 @@ -76,7 +76,7 @@ DisableThreadLibraryCalls(hInstDLL); - mod = GetModuleHandleA( "x11drv.dll" ); + mod = GetModuleHandleA( "winex11.drv" ); if (mod) { wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" ); diff -urN wine-20050419/dlls/d3d8/drawprim.c wine-20050524/dlls/d3d8/drawprim.c --- wine-20050419/dlls/d3d8/drawprim.c 2004-12-09 15:08:00.000000000 +0100 +++ wine-20050524/dlls/d3d8/drawprim.c 2005-04-27 10:12:23.000000000 +0200 @@ -1050,8 +1050,6 @@ if (This->StateBlock->textures[textureNo] != NULL) { int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX]; - float *ptrToCoords = (float *)(sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride)); - float s = 0.0, t = 0.0, r = 0.0, q = 0.0; if (coordIdx > 7) { VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo)); @@ -1061,7 +1059,9 @@ continue; } else { + float* ptrToCoords = (float*) (sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride)); int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == D3DVSDT_FLOAT1 etc */ + float s = 0.0, t = 0.0, r = 0.0, q = 0.0; /* The coords to supply depend completely on the fvf / vertex shader */ switch (coordsToUse) { diff -urN wine-20050419/dlls/d3d9/.cvsignore wine-20050524/dlls/d3d9/.cvsignore --- wine-20050419/dlls/d3d9/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/d3d9/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile d3d9.dll.dbg.c -d3d9.spec.def +libd3d9.def version.res diff -urN wine-20050419/dlls/d3d9/Makefile.in wine-20050524/dlls/d3d9/Makefile.in --- wine-20050419/dlls/d3d9/Makefile.in 2004-09-23 06:34:28.000000000 +0200 +++ wine-20050524/dlls/d3d9/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3d9.dll +IMPORTLIB = libd3d9.$(IMPLIBEXT) IMPORTS = wined3d user32 gdi32 kernel32 EXTRAINCL = @X_CFLAGS@ EXTRALIBS = -ldxguid -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ diff -urN wine-20050419/dlls/d3d9/d3d9_main.c wine-20050524/dlls/d3d9/d3d9_main.c --- wine-20050419/dlls/d3d9/d3d9_main.c 2005-03-02 14:44:59.000000000 +0100 +++ wine-20050524/dlls/d3d9/d3d9_main.c 2005-05-06 21:38:50.000000000 +0200 @@ -59,7 +59,7 @@ DisableThreadLibraryCalls(hInstDLL); - mod = GetModuleHandleA( "x11drv.dll" ); + mod = GetModuleHandleA( "winex11.drv" ); if (mod) { wine_tsx11_lock_ptr = (void*) GetProcAddress(mod, "wine_tsx11_lock"); diff -urN wine-20050419/dlls/d3dim/.cvsignore wine-20050524/dlls/d3dim/.cvsignore --- wine-20050419/dlls/d3dim/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/d3dim/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile d3dim.dll.dbg.c -d3dim.spec.def +libd3dim.def version.res diff -urN wine-20050419/dlls/d3dim/Makefile.in wine-20050524/dlls/d3dim/Makefile.in --- wine-20050419/dlls/d3dim/Makefile.in 2003-10-11 03:09:20.000000000 +0200 +++ wine-20050524/dlls/d3dim/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3dim.dll +IMPORTLIB = libd3dim.$(IMPLIBEXT) C_SRCS = d3dim_main.c @@ -11,4 +12,3 @@ @MAKE_DLL_RULES@ ### Dependencies: - diff -urN wine-20050419/dlls/d3drm/.cvsignore wine-20050524/dlls/d3drm/.cvsignore --- wine-20050419/dlls/d3drm/.cvsignore 2004-05-18 02:54:12.000000000 +0200 +++ wine-20050524/dlls/d3drm/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile d3drm.dll.dbg.c -d3drm.spec.def +libd3drm.def version.res diff -urN wine-20050419/dlls/d3drm/Makefile.in wine-20050524/dlls/d3drm/Makefile.in --- wine-20050419/dlls/d3drm/Makefile.in 2004-05-18 02:54:12.000000000 +0200 +++ wine-20050524/dlls/d3drm/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3drm.dll +IMPORTLIB = libd3drm.$(IMPLIBEXT) C_SRCS = d3drm_main.c diff -urN wine-20050419/dlls/d3dx8/.cvsignore wine-20050524/dlls/d3dx8/.cvsignore --- wine-20050419/dlls/d3dx8/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/d3dx8/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,3 +1,3 @@ Makefile d3dx8.dll.dbg.c -d3dx8.spec.def +libd3dx8.def diff -urN wine-20050419/dlls/d3dx8/Makefile.in wine-20050524/dlls/d3dx8/Makefile.in --- wine-20050419/dlls/d3dx8/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/d3dx8/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3dx8.dll +IMPORTLIB = libd3dx8.$(IMPLIBEXT) IMPORTS = d3d8 user32 gdi32 kernel32 EXTRAINCL = @X_CFLAGS@ EXTRALIBS = -ldxguid -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ diff -urN wine-20050419/dlls/d3dxof/.cvsignore wine-20050524/dlls/d3dxof/.cvsignore --- wine-20050419/dlls/d3dxof/.cvsignore 2004-06-03 02:03:23.000000000 +0200 +++ wine-20050524/dlls/d3dxof/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile d3dxof.dll.dbg.c -d3dxof.spec.def +libd3dxof.def version.res diff -urN wine-20050419/dlls/d3dxof/Makefile.in wine-20050524/dlls/d3dxof/Makefile.in --- wine-20050419/dlls/d3dxof/Makefile.in 2004-06-03 02:03:23.000000000 +0200 +++ wine-20050524/dlls/d3dxof/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = d3dxof.dll +IMPORTLIB = libd3dxof.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dbghelp/.cvsignore wine-20050524/dlls/dbghelp/.cvsignore --- wine-20050419/dlls/dbghelp/.cvsignore 2004-04-06 00:21:27.000000000 +0200 +++ wine-20050524/dlls/dbghelp/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,3 +1,3 @@ Makefile dbghelp.dll.dbg.c -dbghelp.spec.def +libdbghelp.def diff -urN wine-20050419/dlls/dbghelp/Makefile.in wine-20050524/dlls/dbghelp/Makefile.in --- wine-20050419/dlls/dbghelp/Makefile.in 2004-11-21 16:51:47.000000000 +0100 +++ wine-20050524/dlls/dbghelp/Makefile.in 2005-05-17 16:32:55.000000000 +0200 @@ -3,11 +3,13 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dbghelp.dll +IMPORTLIB = libdbghelp.$(IMPLIBEXT) IMPORTS = psapi kernel32 ntdll C_SRCS = \ coff.c \ dbghelp.c \ + dwarf.c \ elf_module.c \ image.c \ memory.c \ diff -urN wine-20050419/dlls/dbghelp/dbghelp_private.h wine-20050524/dlls/dbghelp/dbghelp_private.h --- wine-20050419/dlls/dbghelp/dbghelp_private.h 2005-03-29 15:14:08.000000000 +0200 +++ wine-20050524/dlls/dbghelp/dbghelp_private.h 2005-05-17 16:32:55.000000000 +0200 @@ -356,6 +356,12 @@ const void* stabs, int stablen, const char* strs, int strtablen); +/* dwarf.c */ +extern BOOL dwarf2_parse(struct module* module, unsigned long load_offset, + const unsigned char* debug, unsigned int debug_size, + const unsigned char* abbrev, unsigned int abbrev_size, + const unsigned char* str, unsigned int str_sz); + /* symbol.c */ extern const char* symt_get_name(const struct symt* sym); extern int symt_cmp_addr(const void* p1, const void* p2); diff -urN wine-20050419/dlls/dbghelp/dwarf.c wine-20050524/dlls/dbghelp/dwarf.c --- wine-20050419/dlls/dbghelp/dwarf.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/dbghelp/dwarf.c 2005-05-23 11:50:15.000000000 +0200 @@ -0,0 +1,2180 @@ +/* + * File dwarf.c - read dwarf2 information from the ELF modules + * + * Copyright (C) 2005, Raphael Junqueira + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" + +#include "dbghelp_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf); + +#if 0 +static void dump(const void* ptr, unsigned len) +{ + int i, j; + BYTE msg[128]; + static const char hexof[] = "0123456789abcdef"; + const BYTE* x = (const BYTE*)ptr; + + for (i = 0; i < len; i += 16) + { + sprintf(msg, "%08x: ", i); + memset(msg + 10, ' ', 3 * 16 + 1 + 16); + for (j = 0; j < min(16, len - i); j++) + { + msg[10 + 3 * j + 0] = hexof[x[i + j] >> 4]; + msg[10 + 3 * j + 1] = hexof[x[i + j] & 15]; + msg[10 + 3 * j + 2] = ' '; + msg[10 + 3 * 16 + 1 + j] = (x[i + j] >= 0x20 && x[i + j] < 0x7f) ? + x[i + j] : '.'; + } + msg[10 + 3 * 16] = ' '; + msg[10 + 3 * 16 + 1 + 16] = '\0'; + TRACE("%s\n", msg); + } +} +#endif + +/** + * + * Main Specs: + * http://www.eagercon.com/dwarf/dwarf3std.htm + * http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf + * + * dwarf2.h: http://www.hakpetzna.com/b/binutils/dwarf2_8h-source.html + * + * example of projects who do dwarf2 parsing: + * http://www.x86-64.org/cgi-bin/cvsweb.cgi/binutils.dead/binutils/readelf.c?rev=1.1.1.2 + * http://elis.ugent.be/diota/log/ltrace_elf.c + */ + +typedef struct { + unsigned char length[4]; + unsigned char version[2]; + unsigned char abbrev_offset[4]; + unsigned char word_size[1]; +} dwarf2_comp_unit_stream_t; + +typedef struct { + unsigned long length; + unsigned short version; + unsigned long abbrev_offset; + unsigned char word_size; +} dwarf2_comp_unit_t; + +typedef struct { + unsigned int length; + unsigned short version; + unsigned int prologue_length; + unsigned char min_insn_length; + unsigned char default_is_stmt; + int line_base; + unsigned char line_range; + unsigned char opcode_base; +} dwarf2_line_info_t; + +typedef enum dwarf_tag_e { + DW_TAG_padding = 0x00, + DW_TAG_array_type = 0x01, + DW_TAG_class_type = 0x02, + DW_TAG_entry_point = 0x03, + DW_TAG_enumeration_type = 0x04, + DW_TAG_formal_parameter = 0x05, + DW_TAG_imported_declaration = 0x08, + DW_TAG_label = 0x0a, + DW_TAG_lexical_block = 0x0b, + DW_TAG_member = 0x0d, + DW_TAG_pointer_type = 0x0f, + DW_TAG_reference_type = 0x10, + DW_TAG_compile_unit = 0x11, + DW_TAG_string_type = 0x12, + DW_TAG_structure_type = 0x13, + DW_TAG_subroutine_type = 0x15, + DW_TAG_typedef = 0x16, + DW_TAG_union_type = 0x17, + DW_TAG_unspecified_parameters = 0x18, + DW_TAG_variant = 0x19, + DW_TAG_common_block = 0x1a, + DW_TAG_common_inclusion = 0x1b, + DW_TAG_inheritance = 0x1c, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_module = 0x1e, + DW_TAG_ptr_to_member_type = 0x1f, + DW_TAG_set_type = 0x20, + DW_TAG_subrange_type = 0x21, + DW_TAG_with_stmt = 0x22, + DW_TAG_access_declaration = 0x23, + DW_TAG_base_type = 0x24, + DW_TAG_catch_block = 0x25, + DW_TAG_const_type = 0x26, + DW_TAG_constant = 0x27, + DW_TAG_enumerator = 0x28, + DW_TAG_file_type = 0x29, + DW_TAG_friend = 0x2a, + DW_TAG_namelist = 0x2b, + DW_TAG_namelist_item = 0x2c, + DW_TAG_packed_type = 0x2d, + DW_TAG_subprogram = 0x2e, + DW_TAG_template_type_param = 0x2f, + DW_TAG_template_value_param = 0x30, + DW_TAG_thrown_type = 0x31, + DW_TAG_try_block = 0x32, + DW_TAG_variant_part = 0x33, + DW_TAG_variable = 0x34, + DW_TAG_volatile_type = 0x35, + /** extensions */ + DW_TAG_MIPS_loop = 0x4081, + DW_TAG_format_label = 0x4101, + DW_TAG_function_template = 0x4102, + DW_TAG_class_template = 0x4103 +} dwarf_tag_t; + +typedef enum dwarf_attribute_e { + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + DW_AT_ordering = 0x09, + DW_AT_subscr_data = 0x0a, + DW_AT_byte_size = 0x0b, + DW_AT_bit_offset = 0x0c, + DW_AT_bit_size = 0x0d, + DW_AT_element_list = 0x0f, + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + DW_AT_member = 0x14, + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + DW_AT_producer = 0x25, + DW_AT_prototyped = 0x27, + DW_AT_return_addr = 0x2a, + DW_AT_start_scope = 0x2c, + DW_AT_stride_size = 0x2e, + DW_AT_upper_bound = 0x2f, + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_macro_info = 0x43, + DW_AT_namelist_items = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + + DW_AT_ranges = 0x55, + /* extensions */ + DW_AT_MIPS_fde = 0x2001, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, + DW_AT_MIPS_linkage_name = 0x2007, + DW_AT_MIPS_stride = 0x2008, + DW_AT_MIPS_abstract_name = 0x2009, + DW_AT_MIPS_clone_origin = 0x200a, + DW_AT_MIPS_has_inlines = 0x200b, + DW_AT_sf_names = 0x2101, + DW_AT_src_info = 0x2102, + DW_AT_mac_info = 0x2103, + DW_AT_src_coords = 0x2104, + DW_AT_body_begin = 0x2105, + DW_AT_body_end = 0x2106 +} dwarf_attribute_t; + +typedef enum dwarf_form_e { + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16 +} dwarf_form_t; + +/** type encoding */ +typedef enum dwarf_type_e { + DW_ATE_void = 0x0, + DW_ATE_address = 0x1, + DW_ATE_boolean = 0x2, + DW_ATE_complex_float = 0x3, + DW_ATE_float = 0x4, + DW_ATE_signed = 0x5, + DW_ATE_signed_char = 0x6, + DW_ATE_unsigned = 0x7, + DW_ATE_unsigned_char = 0x8 +} dwarf_type_t; + +typedef enum dwarf_operation_e { + DW_OP_addr = 0x03, + DW_OP_deref = 0x06, + DW_OP_const1u = 0x08, + DW_OP_const1s = 0x09, + DW_OP_const2u = 0x0a, + DW_OP_const2s = 0x0b, + DW_OP_const4u = 0x0c, + DW_OP_const4s = 0x0d, + DW_OP_const8u = 0x0e, + DW_OP_const8s = 0x0f, + DW_OP_constu = 0x10, + DW_OP_consts = 0x11, + DW_OP_dup = 0x12, + DW_OP_drop = 0x13, + DW_OP_over = 0x14, + DW_OP_pick = 0x15, + DW_OP_swap = 0x16, + DW_OP_rot = 0x17, + DW_OP_xderef = 0x18, + DW_OP_abs = 0x19, + DW_OP_and = 0x1a, + DW_OP_div = 0x1b, + DW_OP_minus = 0x1c, + DW_OP_mod = 0x1d, + DW_OP_mul = 0x1e, + DW_OP_neg = 0x1f, + DW_OP_not = 0x20, + DW_OP_or = 0x21, + DW_OP_plus = 0x22, + DW_OP_plus_uconst = 0x23, + DW_OP_shl = 0x24, + DW_OP_shr = 0x25, + DW_OP_shra = 0x26, + DW_OP_xor = 0x27, + DW_OP_bra = 0x28, + DW_OP_eq = 0x29, + DW_OP_ge = 0x2a, + DW_OP_gt = 0x2b, + DW_OP_le = 0x2c, + DW_OP_lt = 0x2d, + DW_OP_ne = 0x2e, + DW_OP_skip = 0x2f, + DW_OP_lit0 = 0x30, + DW_OP_lit1 = 0x31, + DW_OP_lit2 = 0x32, + DW_OP_lit3 = 0x33, + DW_OP_lit4 = 0x34, + DW_OP_lit5 = 0x35, + DW_OP_lit6 = 0x36, + DW_OP_lit7 = 0x37, + DW_OP_lit8 = 0x38, + DW_OP_lit9 = 0x39, + DW_OP_lit10 = 0x3a, + DW_OP_lit11 = 0x3b, + DW_OP_lit12 = 0x3c, + DW_OP_lit13 = 0x3d, + DW_OP_lit14 = 0x3e, + DW_OP_lit15 = 0x3f, + DW_OP_lit16 = 0x40, + DW_OP_lit17 = 0x41, + DW_OP_lit18 = 0x42, + DW_OP_lit19 = 0x43, + DW_OP_lit20 = 0x44, + DW_OP_lit21 = 0x45, + DW_OP_lit22 = 0x46, + DW_OP_lit23 = 0x47, + DW_OP_lit24 = 0x48, + DW_OP_lit25 = 0x49, + DW_OP_lit26 = 0x4a, + DW_OP_lit27 = 0x4b, + DW_OP_lit28 = 0x4c, + DW_OP_lit29 = 0x4d, + DW_OP_lit30 = 0x4e, + DW_OP_lit31 = 0x4f, + DW_OP_reg0 = 0x50, + DW_OP_reg1 = 0x51, + DW_OP_reg2 = 0x52, + DW_OP_reg3 = 0x53, + DW_OP_reg4 = 0x54, + DW_OP_reg5 = 0x55, + DW_OP_reg6 = 0x56, + DW_OP_reg7 = 0x57, + DW_OP_reg8 = 0x58, + DW_OP_reg9 = 0x59, + DW_OP_reg10 = 0x5a, + DW_OP_reg11 = 0x5b, + DW_OP_reg12 = 0x5c, + DW_OP_reg13 = 0x5d, + DW_OP_reg14 = 0x5e, + DW_OP_reg15 = 0x5f, + DW_OP_reg16 = 0x60, + DW_OP_reg17 = 0x61, + DW_OP_reg18 = 0x62, + DW_OP_reg19 = 0x63, + DW_OP_reg20 = 0x64, + DW_OP_reg21 = 0x65, + DW_OP_reg22 = 0x66, + DW_OP_reg23 = 0x67, + DW_OP_reg24 = 0x68, + DW_OP_reg25 = 0x69, + DW_OP_reg26 = 0x6a, + DW_OP_reg27 = 0x6b, + DW_OP_reg28 = 0x6c, + DW_OP_reg29 = 0x6d, + DW_OP_reg30 = 0x6e, + DW_OP_reg31 = 0x6f, + DW_OP_breg0 = 0x70, + DW_OP_breg1 = 0x71, + DW_OP_breg2 = 0x72, + DW_OP_breg3 = 0x73, + DW_OP_breg4 = 0x74, + DW_OP_breg5 = 0x75, + DW_OP_breg6 = 0x76, + DW_OP_breg7 = 0x77, + DW_OP_breg8 = 0x78, + DW_OP_breg9 = 0x79, + DW_OP_breg10 = 0x7a, + DW_OP_breg11 = 0x7b, + DW_OP_breg12 = 0x7c, + DW_OP_breg13 = 0x7d, + DW_OP_breg14 = 0x7e, + DW_OP_breg15 = 0x7f, + DW_OP_breg16 = 0x80, + DW_OP_breg17 = 0x81, + DW_OP_breg18 = 0x82, + DW_OP_breg19 = 0x83, + DW_OP_breg20 = 0x84, + DW_OP_breg21 = 0x85, + DW_OP_breg22 = 0x86, + DW_OP_breg23 = 0x87, + DW_OP_breg24 = 0x88, + DW_OP_breg25 = 0x89, + DW_OP_breg26 = 0x8a, + DW_OP_breg27 = 0x8b, + DW_OP_breg28 = 0x8c, + DW_OP_breg29 = 0x8d, + DW_OP_breg30 = 0x8e, + DW_OP_breg31 = 0x8f, + DW_OP_regx = 0x90, + DW_OP_fbreg = 0x91, + DW_OP_bregx = 0x92, + DW_OP_piece = 0x93, + DW_OP_deref_size = 0x94, + DW_OP_xderef_size = 0x95, + DW_OP_nop = 0x96 +} dwarf_operation_t; + +/** + * Parsers + */ + +typedef struct dwarf2_abbrev_entry_attr_s { + unsigned long attribute; + unsigned long form; + struct dwarf2_abbrev_entry_attr_s* next; +} dwarf2_abbrev_entry_attr_t; + +typedef struct dwarf2_abbrev_entry_s { + unsigned long entry_code; + unsigned long tag; + unsigned char have_child; + dwarf2_abbrev_entry_attr_t* attrs; + struct dwarf2_abbrev_entry_s* next; +} dwarf2_abbrev_entry_t; + +typedef struct dwarf2_abbrev_table_s { + dwarf2_abbrev_entry_t* first; + unsigned n_entries; +} dwarf2_abbrev_table_t; + +typedef struct dwarf2_parse_context_s { + dwarf2_abbrev_table_t* abbrev_table; + const unsigned char* data_stream; + const unsigned char* data; + const unsigned char* start_data; + const unsigned char* end_data; + const unsigned char* str_section; + unsigned long offset; + unsigned char word_size; + unsigned char level; +} dwarf2_parse_context_t; + +static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx) +{ + unsigned char uvalue = *(unsigned char*) ctx->data; + ctx->data += 1; + return uvalue; +} + +static unsigned short dwarf2_parse_u2(dwarf2_parse_context_t* ctx) +{ + unsigned short uvalue = *(unsigned short*) ctx->data; + ctx->data += 2; + return uvalue; +} + +static unsigned long dwarf2_parse_u4(dwarf2_parse_context_t* ctx) +{ + unsigned long uvalue = *(unsigned int*) ctx->data; + ctx->data += 4; + return uvalue; +} + +static unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx) +{ + unsigned long ret = 0; + unsigned char byte; + unsigned shift = 0; + + assert( NULL != ctx ); + + while (1) { + byte = dwarf2_parse_byte(ctx); + ret |= (byte & 0x7f) << shift; + shift += 7; + if (0 == (byte & 0x80)) { break ; } + } + + return ret; +} + +static long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx) +{ + long ret = 0; + unsigned char byte; + unsigned shift = 0; + const unsigned size = sizeof(int) * 8; + + assert( NULL != ctx ); + + while (1) { + byte = dwarf2_parse_byte(ctx); + ret |= (byte & 0x7f) << shift; + shift += 7; + if (0 == (byte & 0x80)) { break ; } + } + /* as spec: sign bit of byte is 2nd high order bit (80x40) + * -> 0x80 is used as flag. + */ + if ((shift < size) && (byte & 0x40)) { + ret |= - (1 << shift); + } + return ret; +} + +const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx) +{ + /*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */ + return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->data_stream, ctx->level); +} +const char* dwarf2_debug_attr(dwarf2_abbrev_entry_attr_t* attr) +{ + return wine_dbg_sprintf("attr(attr:0x%lx,form:0x%lx)", attr->attribute, attr->form); +} + +static void dwarf2_check_sibling(dwarf2_parse_context_t* ctx, unsigned long next_sibling) +{ + if (0 < next_sibling && ctx->data != ctx->data_stream + next_sibling) { + if ((ctx->data + 1) != ctx->data_stream + next_sibling) { + /** padding check */ + WARN("cursor error for %s should be sibling<0x%lx>\n", dwarf2_debug_ctx(ctx), next_sibling); + } + ctx->data = ctx->data_stream + next_sibling; + } +} + + +dwarf2_abbrev_entry_attr_t* dwarf2_abbrev_entry_add_attr(dwarf2_abbrev_entry_t* abbrev_entry, unsigned long attribute, unsigned long form) +{ + dwarf2_abbrev_entry_attr_t* ret = NULL; + dwarf2_abbrev_entry_attr_t* it = NULL; + + assert( NULL != abbrev_entry ); + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_attr_t)); + assert( NULL != ret ); + + ret->attribute = attribute; + ret->form = form; + + ret->next = NULL; + if (NULL == abbrev_entry->attrs) { + abbrev_entry->attrs = ret; + } else { + for (it = abbrev_entry->attrs; NULL != it->next; it = it->next) ; + it->next = ret; + } + return ret; +} + +dwarf2_abbrev_entry_t* dwarf2_abbrev_table_add_entry(dwarf2_abbrev_table_t* abbrev_table, unsigned long entry_code, unsigned long tag, unsigned char have_child) +{ + dwarf2_abbrev_entry_t* ret = NULL; + + assert( NULL != abbrev_table ); + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_t)); + assert( NULL != ret ); + + TRACE("(table:%p,n_entries:%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n", abbrev_table, abbrev_table->n_entries, entry_code, tag, have_child, ret); + + ret->entry_code = entry_code; + ret->tag = tag; + ret->have_child = have_child; + ret->attrs = NULL; + + ret->next = abbrev_table->first; + abbrev_table->first = ret; + abbrev_table->n_entries++; + return ret; +} + +dwarf2_abbrev_entry_t* dwarf2_abbrev_table_find_entry(dwarf2_abbrev_table_t* abbrev_table, unsigned long entry_code) +{ + dwarf2_abbrev_entry_t* ret = NULL; + + assert( NULL != abbrev_table ); + for (ret = abbrev_table->first; ret; ret = ret->next) { + if (ret->entry_code == entry_code) { break ; } + } + return ret; +} + +void dwarf2_abbrev_table_free(dwarf2_abbrev_table_t* abbrev_table) +{ + dwarf2_abbrev_entry_t* entry = NULL; + dwarf2_abbrev_entry_t* next_entry = NULL; + assert( NULL != abbrev_table ); + for (entry = abbrev_table->first; NULL != entry; entry = next_entry) { + dwarf2_abbrev_entry_attr_t* attr = NULL; + dwarf2_abbrev_entry_attr_t* next_attr = NULL; + for (attr = entry->attrs; NULL != attr; attr = next_attr) { + next_attr = attr->next; + HeapFree(GetProcessHeap(), 0, attr); + } + next_entry = entry->next; + HeapFree(GetProcessHeap(), 0, entry); + } + abbrev_table->first = NULL; + abbrev_table->n_entries = 0; +} + +dwarf2_abbrev_table_t* dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx) +{ + dwarf2_abbrev_table_t* abbrev_table = NULL; + + TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data); + + assert( NULL != abbrev_ctx ); + abbrev_table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_table_t)); + assert( NULL != abbrev_table ); + + while (abbrev_ctx->data < abbrev_ctx->end_data) { + unsigned long entry_code; + unsigned long tag; + unsigned char have_child; + dwarf2_abbrev_entry_t* abbrev_entry; + + TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx)); + entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx); + TRACE("found entry_code %lu\n", entry_code); + if (0 == entry_code) { + TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx)); + break ; + } + tag = dwarf2_leb128_as_unsigned(abbrev_ctx); + have_child = dwarf2_parse_byte(abbrev_ctx); + + abbrev_entry = dwarf2_abbrev_table_add_entry(abbrev_table, entry_code, tag, have_child); + assert( NULL != abbrev_entry ); + while (1) { + unsigned long attribute; + unsigned long form; + attribute = dwarf2_leb128_as_unsigned(abbrev_ctx); + form = dwarf2_leb128_as_unsigned(abbrev_ctx); + if (0 == attribute) break; + dwarf2_abbrev_entry_add_attr(abbrev_entry, attribute, form); + } + } + + TRACE("found %u entries\n", abbrev_table->n_entries); + return abbrev_table; +} + +static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr, + dwarf2_parse_context_t* ctx) +{ + const char* ret = NULL; + switch (attr->form) { + case DW_FORM_string: + ret = (const char*) ctx->data; + ctx->data += strlen(ret) + 1; + break; + case DW_FORM_strp: + { + unsigned long offset = dwarf2_parse_u4(ctx); + ret = (const char*) ctx->str_section + offset; + /*FIXME("Unsupported indirect string format offset 0x%lx (in .debug_str)\n", offset);*/ + } + break; + default: + ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute); + } + return ret; +} + +static unsigned long dwarf2_parse_attr_as_addr(dwarf2_abbrev_entry_attr_t* attr, + dwarf2_parse_context_t* ctx) +{ + unsigned long offset = 0; + switch (ctx->word_size) { + case 4: + offset = *(unsigned int*) ctx->data; + break; + case 8: + default: + FIXME("Unsupported Word Size %u\n", ctx->word_size); + } + ctx->data += ctx->word_size; + return offset; +} + +static unsigned long dwarf2_parse_attr_as_ref(dwarf2_abbrev_entry_attr_t* attr, + dwarf2_parse_context_t* ctx) +{ + unsigned long uvalue = 0; + switch (attr->form) { + case DW_FORM_ref1: + uvalue = ctx->offset + dwarf2_parse_byte(ctx); + TRACE("ref1<0x%lx>\n", uvalue); + break; + + case DW_FORM_ref2: + uvalue = ctx->offset + dwarf2_parse_u2(ctx); + TRACE("ref2<0x%lx>\n", uvalue); + break; + + case DW_FORM_ref4: + uvalue = ctx->offset + dwarf2_parse_u4(ctx); + TRACE("ref4<0x%lx>\n", uvalue); + break; + + case DW_FORM_ref8: + /* FIXME: 64bits support */ + /* + uvalue = ctx->offset + dwarf2_parse_u8(ctx); + TRACE("ref8<0x%lx>\n", uvalue); + */ + ctx->data += 8; + break; + } + return uvalue; +} + + +static unsigned long dwarf2_parse_attr_as_data(dwarf2_abbrev_entry_attr_t* attr, + dwarf2_parse_context_t* ctx) +{ + unsigned long uvalue = 0; + switch (attr->form) { + case DW_FORM_data1: + uvalue = dwarf2_parse_byte(ctx); + TRACE("data1<%lu>\n", uvalue); + break; + + case DW_FORM_data2: + uvalue = dwarf2_parse_u2(ctx); + TRACE("data2<%lu>\n", uvalue); + break; + + case DW_FORM_data4: + uvalue = dwarf2_parse_u4(ctx); + TRACE("data4<%lu>\n", uvalue); + break; + + case DW_FORM_data8: + FIXME("Unsupported 64bits support\n"); + ctx->data += 8; + break; + } + return uvalue; +} + +static void dwarf2_parse_attr(dwarf2_abbrev_entry_attr_t* attr, + dwarf2_parse_context_t* ctx) +{ + const unsigned long attribute = attr->attribute; + const unsigned long form = attr->form; + unsigned long uvalue = 0; + long svalue = 0; + const char* str = NULL; + + TRACE("(attr:0x%lx,form:0x%lx)\n", attribute, form); + + switch (form) { + case DW_FORM_ref_addr: + case DW_FORM_addr: + uvalue = dwarf2_parse_attr_as_addr(attr, ctx); + break; + + case DW_FORM_flag: + uvalue = dwarf2_parse_byte(ctx); + TRACE("flag<0x%lx>\n", uvalue); + break; + + case DW_FORM_data1: + uvalue = dwarf2_parse_byte(ctx); + TRACE("data1<%lu>\n", uvalue); + break; + + case DW_FORM_data2: + uvalue = dwarf2_parse_u2(ctx); + TRACE("data2<%lu>\n", uvalue); + break; + + case DW_FORM_data4: + uvalue = dwarf2_parse_u4(ctx); + TRACE("data4<%lu>\n", uvalue); + break; + + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + uvalue = dwarf2_parse_attr_as_ref(attr, ctx); + /*TRACE("ref<0x%lx>\n", ctx->offset + uvalue);*/ + break; + + case DW_FORM_data8: + FIXME("Unsupported 64bits support\n"); + ctx->data += 8; + break; + + case DW_FORM_sdata: + svalue = dwarf2_leb128_as_signed(ctx); + break; + + case DW_FORM_ref_udata: + case DW_FORM_udata: + uvalue = dwarf2_leb128_as_unsigned(ctx); + break; + + case DW_FORM_string: + case DW_FORM_strp: + str = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("string<%s>\n", str); + break; + + case DW_FORM_block: + uvalue = dwarf2_leb128_as_unsigned(ctx); + ctx->data += uvalue; + break; + + case DW_FORM_block1: + uvalue = dwarf2_parse_byte(ctx); + ctx->data += uvalue; + break; + + case DW_FORM_block2: + uvalue = dwarf2_parse_u2(ctx); + ctx->data += uvalue; + break; + + case DW_FORM_block4: + uvalue = dwarf2_parse_u4(ctx); + ctx->data += uvalue; + break; + + default: + break; + } +} + +struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref) +{ + TRACE("want ref<0x%lx>\n", ref); + return NULL; +} + +struct symt* dwarf2_add_symt_ref(struct module* module, unsigned long ref, struct symt* symt) +{ + if (NULL != symt) return NULL; + return NULL; +} + +static struct symt_basic* dwarf2_parse_base_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_basic* symt = NULL; + const char* name = NULL; + unsigned size = 0; + unsigned encoding = 0; + enum BasicType bt; + dwarf2_abbrev_entry_attr_t* attr = NULL; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_byte_size: + size = dwarf2_parse_byte(ctx); + break; + case DW_AT_encoding: + encoding = dwarf2_parse_byte(ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + switch (encoding) { + case DW_ATE_void: bt = btVoid; break; + case DW_ATE_address: bt = btULong; break; + case DW_ATE_boolean: bt = btBool; break; + case DW_ATE_complex_float: bt = btComplex; break; + case DW_ATE_float: bt = btFloat; break; + case DW_ATE_signed: bt = btInt; break; + case DW_ATE_unsigned: bt = btUInt; break; + case DW_ATE_signed_char: bt = btChar; break; + case DW_ATE_unsigned_char: bt = btChar; break; + default: + bt = btNoType; + } + /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/ + symt = symt_new_basic(module, bt, name, size); + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + return symt; +} + +static struct symt_typedef* dwarf2_parse_typedef(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_typedef* symt = NULL; + struct symt* ref_type = NULL; + const char* name = NULL; + dwarf2_abbrev_entry_attr_t* attr = NULL; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + ref_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + if (NULL != name) { + symt = symt_new_typedef(module, ref_type, name); + } + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + return symt; +} + +static struct symt_pointer* dwarf2_parse_pointer_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_pointer* symt = NULL; + struct symt* ref_type = NULL; + unsigned size = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_byte_size: + size = dwarf2_parse_byte(ctx); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + ref_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + symt = symt_new_pointer(module, ref_type); + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + return symt; +} + +static void dwarf2_parse_array_subrange_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_array* parent) +{ + unsigned min = 0; + unsigned max = 0; + struct symt* idx_type = NULL; + dwarf2_abbrev_entry_attr_t* attr = NULL; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + idx_type = dwarf2_find_symt_by_ref(module, ref); + /** check if idx_type is a basic_type integer */ + } + break; + case DW_AT_lower_bound: + TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + min = dwarf2_parse_attr_as_data(attr, ctx); + break; + case DW_AT_upper_bound: + TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + max = dwarf2_parse_attr_as_data(attr, ctx); + break; + case DW_AT_count: + TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min); + max = min + dwarf2_parse_attr_as_data(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + parent->start = min; + parent->end = max; + + TRACE("found min:%u max:%u\n", min, max); + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } +} + + +static struct symt_array* dwarf2_parse_array_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_array* symt = NULL; + struct symt* ref_type = NULL; + unsigned min = 0; + unsigned max = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + ref_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + + symt = symt_new_array(module, min, max, ref_type); + + if (entry->have_child) { /** any interest to not have child ? */ + ++ctx->level; + while (ctx->data < ctx->end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx->data - ctx->data_stream; + + entry_code = dwarf2_leb128_as_unsigned(ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + break ; + } + + entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code); + assert( NULL != entry ); + + switch (entry->tag) { + case DW_TAG_subrange_type: + dwarf2_parse_array_subrange_type(module, entry, ctx, symt); + break; + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, ctx); + } + } + break; + } + } + --ctx->level; + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return symt; +} + +static struct symt_typedef* dwarf2_parse_const_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_typedef* symt = NULL; + struct symt* ref_type = NULL; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + ref_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + FIXME("need to generate a name\n"); + symt = symt_new_typedef(module, ref_type, ""); + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return symt; +} + +static struct symt_typedef* dwarf2_parse_reference_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_typedef* symt = NULL; + struct symt* ref_type = NULL; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + ref_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + FIXME("need to generate a name\n"); + symt = symt_new_typedef(module, ref_type, ""); + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return symt; +} + +static void dwarf2_parse_udt_member(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* parent) +{ + struct symt* elt_type = NULL; + const char* name = NULL; + unsigned long offset = 0; + unsigned size = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + assert( NULL != parent ); + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + elt_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + case DW_AT_data_member_location: + { + unsigned long uvalue = 0; + TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/ + switch (attr->form) { + case DW_FORM_block: + uvalue = dwarf2_leb128_as_unsigned(ctx); + break; + case DW_FORM_block1: + uvalue = dwarf2_parse_byte(ctx); + break; + case DW_FORM_block2: + uvalue = dwarf2_parse_u2(ctx); + break; + case DW_FORM_block4: + uvalue = dwarf2_parse_u4(ctx); + break; + default: + TRACE("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + if (uvalue) { + unsigned char op = dwarf2_parse_byte(ctx); + --uvalue; + switch (op) { + case DW_OP_plus_uconst: + offset = dwarf2_leb128_as_unsigned(ctx); + break; + default: + TRACE("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op); + ctx->data += uvalue; + } + TRACE("found offset:%lu\n", offset); + } + } + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + symt_add_udt_element(module, parent, name, elt_type, offset, size); + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); +} + +static void dwarf2_parse_udt_members(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* symt) +{ + if (entry->have_child) { /** any interest to not have child ? */ + ++ctx->level; + while (ctx->data < ctx->end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx->data - ctx->data_stream; + + entry_code = dwarf2_leb128_as_unsigned(ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + break ; + } + + entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code); + assert( NULL != entry ); + + switch (entry->tag) { + case DW_TAG_member: + dwarf2_parse_udt_member(module, entry, ctx, symt); + break; + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, ctx); + } + } + break; + } + } + --ctx->level; + } +} + +static struct symt_udt* dwarf2_parse_class_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_udt* symt = NULL; + const char* name = NULL; + unsigned size = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_byte_size: + size = dwarf2_parse_byte(ctx); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + symt = symt_new_udt(module, name, size, UdtClass); + dwarf2_parse_udt_members(module, entry, ctx, symt); + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return symt; +} + +static struct symt_udt* dwarf2_parse_struct_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_udt* symt = NULL; + const char* name = NULL; + unsigned size = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_byte_size: + size = dwarf2_parse_byte(ctx); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + symt = symt_new_udt(module, name, size, UdtStruct); + dwarf2_parse_udt_members(module, entry, ctx, symt); + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return symt; +} + +static struct symt_udt* dwarf2_parse_union_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_udt* symt = NULL; + const char* name = NULL; + unsigned size = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_byte_size: + size = dwarf2_parse_byte(ctx); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + symt = symt_new_udt(module, name, size, UdtUnion); + dwarf2_parse_udt_members(module, entry, ctx, symt); + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return symt; +} + +static void dwarf2_parse_enumerator(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_enum* parent) +{ + const char* name = NULL; + long value = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_const_value: + switch (attr->form) { + case DW_FORM_sdata: + value = dwarf2_leb128_as_signed(ctx); + TRACE("found value %ld\n", value); + break; + case DW_FORM_udata: + value = dwarf2_leb128_as_unsigned(ctx); + TRACE("found value %ld\n", value); + break; + default: + TRACE("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + symt_add_enum_element(module, parent, name, value); + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } +} + +static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_enum* symt = NULL; + const char* name = NULL; + unsigned long size = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_byte_size: + size = dwarf2_parse_attr_as_data(attr, ctx); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + symt = symt_new_enum(module, name); + + if (entry->have_child) { /** any interest to not have child ? */ + ++ctx->level; + while (ctx->data < ctx->end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx->data - ctx->data_stream; + + entry_code = dwarf2_leb128_as_unsigned(ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + break ; + } + + entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code); + assert( NULL != entry ); + + switch (entry->tag) { + case DW_TAG_enumerator: + dwarf2_parse_enumerator(module, entry, ctx, symt); + break; + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, ctx); + } + } + break; + } + } + --ctx->level; + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return symt; +} + +static void dwarf2_parse_variable(struct module* module, + dwarf2_abbrev_entry_t* entry, + dwarf2_parse_context_t* ctx) +{ + struct symt* var_type = NULL; + dwarf2_abbrev_entry_attr_t* attr = NULL; + const char* name = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + var_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); +} + +static void dwarf2_parse_subprogram_parameter(struct module* module, + dwarf2_abbrev_entry_t* entry, + dwarf2_parse_context_t* ctx, + struct symt_function_signature* sig_type, + struct symt_function* func_type) +{ + struct symt* param_type = NULL; + const char* name = NULL; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + param_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + case DW_AT_location: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + if (NULL != sig_type) { + symt_add_function_signature_parameter(module, sig_type, param_type); + } + + if (entry->have_child) { + FIXME("Unsupported children\n"); + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); +} + +static void dwarf2_parse_inlined_subroutine(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + const char* name = NULL; + unsigned long addr = 0; + unsigned long low_pc = 0; + unsigned long high_pc = 0; + unsigned size = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_low_pc: + low_pc = dwarf2_parse_attr_as_addr(attr, ctx); + addr = module->module.BaseOfImage + low_pc; + break; + case DW_AT_high_pc: + high_pc = dwarf2_parse_attr_as_addr(attr, ctx); + size = high_pc - low_pc; + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + + if (entry->have_child) { /** any interest to not have child ? */ + ++ctx->level; + while (ctx->data < ctx->end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx->data - ctx->data_stream; + + entry_code = dwarf2_leb128_as_unsigned(ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + break ; + } + + entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code); + assert( NULL != entry ); + + switch (entry->tag) { + case DW_TAG_formal_parameter: + dwarf2_parse_subprogram_parameter(module, entry, ctx, NULL, NULL); + break; + case DW_TAG_variable: + dwarf2_parse_variable(module, entry, ctx); + break; + case DW_TAG_label: + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, ctx); + } + } + break; + } + } + --ctx->level; + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); +} + + +static void dwarf2_parse_subprogram_block(struct module* module, + dwarf2_abbrev_entry_t* entry, + dwarf2_parse_context_t* ctx, + struct symt_function_signature* sig_type, + struct symt_function* func_type) +{ + dwarf2_abbrev_entry_attr_t* attr = NULL; + const char* name = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + dwarf2_parse_attr(attr, ctx); + break; + case DW_AT_ranges: /** what to do ? */ + dwarf2_parse_attr(attr, ctx); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + + if (entry->have_child) { /** any interest to not have child ? */ + ++ctx->level; + while (ctx->data < ctx->end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx->data - ctx->data_stream; + + entry_code = dwarf2_leb128_as_unsigned(ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + break ; + } + + entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code); + assert( NULL != entry ); + + switch (entry->tag) { + case DW_TAG_inlined_subroutine: + dwarf2_parse_inlined_subroutine(module, entry, ctx); + break; + case DW_TAG_variable: + dwarf2_parse_variable(module, entry, ctx); + break; + case DW_TAG_label: + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, ctx); + } + } + break; + } + } + --ctx->level; + } + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); +} + +static void dwarf2_parse_subprogram_content(struct module* module, + dwarf2_abbrev_entry_t* entry, + dwarf2_parse_context_t* ctx, + struct symt_function_signature* sig_type, + struct symt_function* func_type) +{ + if (entry->have_child) { /** any interest to not have child ? */ + ++ctx->level; + while (ctx->data < ctx->end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx->data - ctx->data_stream; + + entry_code = dwarf2_leb128_as_unsigned(ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + break ; + } + + entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code); + assert( NULL != entry ); + + switch (entry->tag) { + case DW_TAG_formal_parameter: + dwarf2_parse_subprogram_parameter(module, entry, ctx, sig_type, func_type); + break; + case DW_TAG_lexical_block: + dwarf2_parse_subprogram_block(module, entry, ctx, sig_type, func_type); + break; + case DW_TAG_variable: + dwarf2_parse_variable(module, entry, ctx); + break; + case DW_TAG_label: + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, ctx); + } + } + break; + } + } + --ctx->level; + } +} + +static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland) +{ + struct symt_function* func_type = NULL; + const char* name = NULL; + struct symt* ret_type = NULL; + struct symt_function_signature* sig_type = NULL; + unsigned long addr = 0; + unsigned long low_pc = 0; + unsigned long high_pc = 0; + unsigned size = 0; + unsigned char is_decl = 0; + unsigned char inl_flags = 0; + unsigned char decl_file = 0; + unsigned char decl_line = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + unsigned long next_sibling = 0; + + TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_low_pc: + low_pc = dwarf2_parse_attr_as_addr(attr, ctx); + addr = module->module.BaseOfImage + low_pc; + break; + case DW_AT_high_pc: + high_pc = dwarf2_parse_attr_as_addr(attr, ctx); + size = high_pc - low_pc; + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + case DW_AT_type: + { + unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx); + ret_type = dwarf2_find_symt_by_ref(module, ref); + } + break; + case DW_AT_declaration: + is_decl = dwarf2_parse_byte(ctx); + break; + case DW_AT_inline: + inl_flags = dwarf2_parse_byte(ctx); + break; + /* not work yet, need parsing .debug_line and using Compil Unit stmt_list + case DW_AT_decl_file: + decl_file = dwarf2_parse_byte(ctx); + break; + case DW_AT_decl_line: + decl_line = dwarf2_parse_byte(ctx); + break; + */ + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + sig_type = symt_new_function_signature(module, ret_type); + if (!is_decl) { + func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt); + if (low_pc && high_pc) { + symt_add_function_point(module, func_type, SymTagFuncDebugStart, low_pc, NULL); + symt_add_function_point(module, func_type, SymTagFuncDebugEnd, high_pc, NULL); + } + if (decl_file && decl_line) { + symt_add_func_line(module, func_type, decl_file, decl_line, low_pc); + } + } + dwarf2_parse_subprogram_content(module, entry, ctx, sig_type, func_type); + symt_normalize_function(module, func_type); + + /** set correct data cursor */ + dwarf2_check_sibling(ctx, next_sibling); + + return func_type; +} + +static void dwarf2_parse_compiland_content(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland) +{ + if (entry->have_child) { /** any interest to not have child ? */ + ++ctx->level; + while (ctx->data < ctx->end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx->data - ctx->data_stream; + + entry_code = dwarf2_leb128_as_unsigned(ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + break ; + } + + entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code); + assert( NULL != entry ); + + switch (entry->tag) { + case DW_TAG_typedef: + { + struct symt_typedef* symt = dwarf2_parse_typedef(module, entry, ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_base_type: + { + struct symt_basic* symt = dwarf2_parse_base_type(module, entry, ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_pointer_type: + { + struct symt_pointer* symt = dwarf2_parse_pointer_type(module, entry, ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_class_type: + { + struct symt_udt* symt = dwarf2_parse_class_type(module, entry, ctx); + if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_structure_type: + { + struct symt_udt* symt = dwarf2_parse_struct_type(module, entry, ctx); + if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_union_type: + { + struct symt_udt* symt = dwarf2_parse_union_type(module, entry, ctx); + if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_array_type: + { + struct symt_array* symt = dwarf2_parse_array_type(module, entry, ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_const_type: + { + struct symt_typedef* symt = dwarf2_parse_const_type(module, entry, ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_reference_type: + { + struct symt_typedef* symt = dwarf2_parse_reference_type(module, entry, ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_enumeration_type: + { + struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + case DW_TAG_subprogram: + { + struct symt_function* symt = dwarf2_parse_subprogram(module, entry, ctx, compiland); + if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + } + break; + + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, ctx); + } + } + break; + } + } + --ctx->level; + } +} + +static struct symt_compiland* dwarf2_parse_compiland(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx) +{ + struct symt_compiland* compiland = NULL; + const char* name = NULL; + unsigned long next_sibling = 0; + dwarf2_abbrev_entry_attr_t* attr = NULL; + + TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code); + + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + switch (attr->attribute) { + case DW_AT_sibling: + next_sibling = dwarf2_parse_attr_as_ref(attr, ctx); + break; + case DW_AT_name: + name = dwarf2_parse_attr_as_string(attr, ctx); + TRACE("found name %s\n", name); + break; + default: + TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); + dwarf2_parse_attr(attr, ctx); + } + } + compiland = symt_new_compiland(module, name); + dwarf2_parse_compiland_content(module, entry, ctx, compiland); + + dwarf2_check_sibling(ctx, next_sibling); + + return compiland; +} + +BOOL dwarf2_parse(struct module* module, unsigned long load_offset, + const unsigned char* debug, unsigned int debug_size, + const unsigned char* abbrev, unsigned int abbrev_size, + const unsigned char* str, unsigned int str_sz) +{ + const unsigned char* comp_unit_cursor = debug; + const unsigned char* end_debug = debug + debug_size; + BOOL bRet = TRUE; + + while (comp_unit_cursor < end_debug) { + dwarf2_abbrev_table_t* abbrev_table; + dwarf2_comp_unit_stream_t* comp_unit_stream; + dwarf2_comp_unit_t comp_unit; + dwarf2_parse_context_t ctx; + dwarf2_parse_context_t abbrev_ctx; + struct symt_compiland* compiland = NULL; + + comp_unit_stream = (dwarf2_comp_unit_stream_t*) comp_unit_cursor; + + comp_unit.length = *(unsigned long*) comp_unit_stream->length; + comp_unit.version = *(unsigned short*) comp_unit_stream->version; + comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset; + comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size; + + TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug); + TRACE("- length: %lu\n", comp_unit.length); + TRACE("- version: %u\n", comp_unit.version); + TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset); + TRACE("- word_size: %u\n", comp_unit.word_size); + + ctx.data_stream = debug; + ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t); + ctx.offset = comp_unit_cursor - debug; + ctx.word_size = comp_unit.word_size; + ctx.str_section = str; + ctx.level = 0; + + comp_unit_cursor += comp_unit.length + sizeof(unsigned); + ctx.end_data = comp_unit_cursor; + + if (2 != comp_unit.version) { + WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version); + continue ; + } + + abbrev_ctx.abbrev_table = NULL; + abbrev_ctx.data_stream = abbrev; + abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset; + abbrev_ctx.end_data = abbrev + abbrev_size; + abbrev_ctx.offset = comp_unit.abbrev_offset; + abbrev_ctx.str_section = str; + abbrev_table = dwarf2_parse_abbrev_set(&abbrev_ctx); + + ctx.abbrev_table = abbrev_table; + + while (ctx.data < ctx.end_data) { + dwarf2_abbrev_entry_t* entry = NULL; + unsigned long entry_code; + unsigned long entry_ref = 0; + + entry_ref = ctx.data - ctx.data_stream; + + entry_code = dwarf2_leb128_as_unsigned(&ctx); + TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref); + if (0 == entry_code) { + continue ; + } + entry = dwarf2_abbrev_table_find_entry(abbrev_table, entry_code); + if (NULL == entry) { + WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref); + dwarf2_abbrev_table_free(abbrev_table); + return FALSE; + } + + switch (entry->tag) { + case DW_TAG_compile_unit: + { + struct symt_compiland* symt = dwarf2_parse_compiland(module, entry, &ctx); + dwarf2_add_symt_ref(module, entry_ref, &symt->symt); + compiland = symt; + } + break; + default: + { + dwarf2_abbrev_entry_attr_t* attr; + TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code); + for (attr = entry->attrs; NULL != attr; attr = attr->next) { + dwarf2_parse_attr(attr, &ctx); + } + } + break; + } + } + dwarf2_abbrev_table_free(abbrev_table); + } + return bRet; +} + +BOOL dwarf2_parse_lines(struct module* module, unsigned long load_offset, + const unsigned char* debug_line, unsigned int debug_line_size) +{ + return FALSE; +} diff -urN wine-20050419/dlls/dbghelp/elf_module.c wine-20050524/dlls/dbghelp/elf_module.c --- wine-20050419/dlls/dbghelp/elf_module.c 2005-03-29 15:14:08.000000000 +0200 +++ wine-20050524/dlls/dbghelp/elf_module.c 2005-05-17 16:32:55.000000000 +0200 @@ -24,7 +24,9 @@ #include #include #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #include #ifdef HAVE_SYS_MMAN_H #include @@ -774,7 +776,9 @@ BOOL ret = FALSE; const char* shstrtab; int i; - int symtab_sect, dynsym_sect, stab_sect, stabstr_sect, debug_sect, debuglink_sect; + int symtab_sect, dynsym_sect, stab_sect, stabstr_sect; + int debug_sect, debug_str_sect, debug_abbrev_sect, debug_line_sect; + int debuglink_sect; struct thunk_area thunks[] = { {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */ @@ -804,8 +808,9 @@ shstrtab = elf_map_section(fmap, fmap->elfhdr.e_shstrndx); if (shstrtab == NO_MAP) return FALSE; - symtab_sect = dynsym_sect = stab_sect = stabstr_sect = - debug_sect = debuglink_sect = -1; + symtab_sect = dynsym_sect = stab_sect = stabstr_sect = -1; + debug_sect = debug_str_sect = debug_abbrev_sect = debug_line_sect = -1; + debuglink_sect = -1; for (i = 0; i < fmap->elfhdr.e_shnum; i++) { @@ -815,6 +820,12 @@ stabstr_sect = i; if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_info") == 0) debug_sect = i; + if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_str") == 0) + debug_str_sect = i; + if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_abbrev") == 0) + debug_abbrev_sect = i; + if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_line") == 0) + debug_line_sect = i; if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".gnu_debuglink") == 0) debuglink_sect = i; if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".symtab") == 0) && @@ -872,8 +883,31 @@ else if (debug_sect != -1) { /* Dwarf 2 debug information */ - FIXME("Unsupported Dwarf2 information for %s\n", - module->module.ModuleName); + const char* dw2_debug; + const char* dw2_debug_abbrev; + const char* dw2_debug_str; + + FIXME("Alpha-support for Dwarf2 information for %s\n", module->module.ModuleName); + + dw2_debug = elf_map_section(fmap, debug_sect); + dw2_debug_abbrev = elf_map_section(fmap, debug_abbrev_sect); + dw2_debug_str = elf_map_section(fmap, debug_str_sect); + if (dw2_debug != NO_MAP && NO_MAP != dw2_debug_abbrev && dw2_debug_str != NO_MAP) + { + /* OK, now just parse dwarf2 debug infos. */ + ret = dwarf2_parse(module, module->elf_info->elf_addr, + dw2_debug, fmap->sect[debug_sect].shdr.sh_size, + dw2_debug_abbrev, fmap->sect[debug_abbrev_sect].shdr.sh_size, + dw2_debug_str, fmap->sect[debug_str_sect].shdr.sh_size); + } + elf_unmap_section(fmap, debug_sect); + elf_unmap_section(fmap, debug_abbrev_sect); + elf_unmap_section(fmap, debug_str_sect); + if (!ret) + { + WARN("Couldn't correctly read stabs\n"); + return FALSE; + } } else if (debuglink_sect != -1) { @@ -1409,7 +1443,7 @@ return NULL; } -BOOL elf_load_debug_info(struct module* module) +BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap) { return FALSE; } diff -urN wine-20050419/dlls/dbghelp/msc.c wine-20050524/dlls/dbghelp/msc.c --- wine-20050419/dlls/dbghelp/msc.c 2005-03-29 13:30:57.000000000 +0200 +++ wine-20050524/dlls/dbghelp/msc.c 2005-05-18 15:27:24.000000000 +0200 @@ -1763,8 +1763,14 @@ static BOOL CALLBACK pdb_match(char* file, void* user) { - /* accept first file */ - return FALSE; + /* accept first file that exists */ + HANDLE h = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + TRACE("match with %s returns %p\n", file, h); + if (INVALID_HANDLE_VALUE != h) { + CloseHandle(h); + return FALSE; + } + return TRUE; } static HANDLE open_pdb_file(const struct process* pcs, const char* filename) @@ -1781,6 +1787,7 @@ { h = CreateFileA(dbg_file_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + TRACE("with %s returns %p\n", dbg_file_path, h); } return (h == INVALID_HANDLE_VALUE) ? NULL : h; } diff -urN wine-20050419/dlls/dbghelp/path.c wine-20050524/dlls/dbghelp/path.c --- wine-20050419/dlls/dbghelp/path.c 2005-03-29 15:14:08.000000000 +0200 +++ wine-20050524/dlls/dbghelp/path.c 2005-05-18 11:42:17.000000000 +0200 @@ -342,7 +342,10 @@ strcpy(tmp, searchPath); searchPath = NULL; } - if (do_search(filename, tmp, FALSE, sffip_cb, &s)) return TRUE; + if (do_search(filename, tmp, FALSE, sffip_cb, &s)) { + strcpy(buffer, tmp); + return TRUE; + } } return FALSE; } diff -urN wine-20050419/dlls/dbghelp/stabs.c wine-20050524/dlls/dbghelp/stabs.c --- wine-20050419/dlls/dbghelp/stabs.c 2005-03-01 11:39:49.000000000 +0100 +++ wine-20050524/dlls/dbghelp/stabs.c 2005-05-16 10:47:55.000000000 +0200 @@ -33,7 +33,9 @@ #include #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #ifdef HAVE_SYS_MMAN_H #include #endif @@ -71,9 +73,11 @@ #define N_LCSYM 0x28 #define N_MAIN 0x2a #define N_ROSYM 0x2c +#define N_BNSYM 0x2e #define N_OPT 0x3c #define N_RSYM 0x40 #define N_SLINE 0x44 +#define N_ENSYM 0x4e #define N_SO 0x64 #define N_LSYM 0x80 #define N_BINCL 0x82 @@ -1508,6 +1512,10 @@ case N_MAIN: /* Always ignore these. GCC doesn't even generate them. */ break; + case N_BNSYM: + case N_ENSYM: + /* Always ignore these, they seem to be used only on Darwin. */ + break; default: ERR("Unknown stab type 0x%02x\n", stab_ptr->n_type); break; diff -urN wine-20050419/dlls/dbghelp/stack.c wine-20050524/dlls/dbghelp/stack.c --- wine-20050419/dlls/dbghelp/stack.c 2004-09-23 06:27:46.000000000 +0200 +++ wine-20050524/dlls/dbghelp/stack.c 2005-05-23 13:43:44.000000000 +0200 @@ -30,10 +30,9 @@ #include "dbghelp_private.h" #include "winreg.h" #include "ntstatus.h" -#include "thread.h" /* FIXME: must be included before winternl.h */ #include "winternl.h" +#include "wine/winbase16.h" #include "wine/debug.h" -#include "stackframe.h" WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); @@ -57,6 +56,12 @@ } } +static BOOL CALLBACK read_mem(HANDLE hProcess, DWORD addr, void* buffer, + DWORD size, LPDWORD nread) +{ + return ReadProcessMemory(hProcess, (void*)addr, buffer, size, nread); +} + /* indexes in Reserved array */ #define __CurrentMode 0 #define __CurrentSwitch 1 @@ -98,7 +103,8 @@ /* sanity check */ if (curr_mode >= stm_done) return FALSE; - if (!f_read_mem) f_read_mem = ReadProcessMemory; + /* sigh... MS isn't even consistent in the func prototypes */ + if (!f_read_mem) f_read_mem = read_mem; if (!f_xlat_adr) f_xlat_adr = addr_to_linear; TRACE("Enter: PC=%s Frame=%s Return=%s Stack=%s Mode=%s cSwitch=%08lx nSwitch=%08lx\n", @@ -124,53 +130,58 @@ curr_mode = (frame->AddrPC.Mode == AddrModeFlat) ? stm_32bit : stm_16bit; - /* cur_switch holds address of curr_stack's field in TEB in debuggee + /* cur_switch holds address of WOW32Reserved field in TEB in debuggee * address space */ if (NtQueryInformationThread(hThread, ThreadBasicInformation, &info, - sizeof(info), NULL) != STATUS_SUCCESS) - goto done_err; - curr_switch = (unsigned long)info.TebBaseAddress + FIELD_OFFSET(TEB, cur_stack); - if (!f_read_mem(hProcess, (void*)curr_switch, &next_switch, - sizeof(next_switch), NULL)) + sizeof(info), NULL) == STATUS_SUCCESS) { - WARN("Can't read TEB:cur_stack\n"); - goto done_err; - } - if (curr_mode == stm_16bit) - { - if (!f_read_mem(hProcess, (void*)next_switch, &frame32, - sizeof(frame32), NULL)) + curr_switch = (unsigned long)info.TebBaseAddress + FIELD_OFFSET(TEB, WOW32Reserved); + if (!f_read_mem(hProcess, curr_switch, &next_switch, + sizeof(next_switch), NULL)) { - WARN("Bad stack frame 0x%08lx\n", next_switch); + WARN("Can't read TEB:WOW32Reserved\n"); goto done_err; } - curr_switch = (DWORD)frame32.frame16; - tmp.Mode = AddrMode1616; - tmp.Segment = SELECTOROF(curr_switch); - tmp.Offset = OFFSETOF(curr_switch); - if (!f_read_mem(hProcess, (void*)f_xlat_adr(hProcess, hThread, &tmp), - &ch, sizeof(ch), NULL)) - curr_switch = 0xFFFFFFFF; - frame->AddrReturn.Mode = frame->AddrStack.Mode = AddrMode1616; - } - else - { - tmp.Mode = AddrMode1616; - tmp.Segment = SELECTOROF(next_switch); - tmp.Offset = OFFSETOF(next_switch); - p = f_xlat_adr(hProcess, hThread, &tmp); - if (!f_read_mem(hProcess, (void*)p, &frame16, sizeof(frame16), NULL)) + if (curr_mode == stm_16bit) { - WARN("Bad stack frame 0x%08lx\n", p); - goto done_err; + if (!f_read_mem(hProcess, next_switch, &frame32, + sizeof(frame32), NULL)) + { + WARN("Bad stack frame 0x%08lx\n", next_switch); + goto done_err; + } + curr_switch = (DWORD)frame32.frame16; + tmp.Mode = AddrMode1616; + tmp.Segment = SELECTOROF(curr_switch); + tmp.Offset = OFFSETOF(curr_switch); + if (!f_read_mem(hProcess, f_xlat_adr(hProcess, hThread, &tmp), + &ch, sizeof(ch), NULL)) + curr_switch = 0xFFFFFFFF; } - curr_switch = (DWORD)frame16.frame32; + else + { + tmp.Mode = AddrMode1616; + tmp.Segment = SELECTOROF(next_switch); + tmp.Offset = OFFSETOF(next_switch); + p = f_xlat_adr(hProcess, hThread, &tmp); + if (!f_read_mem(hProcess, p, &frame16, sizeof(frame16), NULL)) + { + WARN("Bad stack frame 0x%08lx\n", p); + goto done_err; + } + curr_switch = (DWORD)frame16.frame32; - if (!f_read_mem(hProcess, (void*)curr_switch, &ch, sizeof(ch), NULL)) - curr_switch = 0xFFFFFFFF; - frame->AddrReturn.Mode = frame->AddrStack.Mode = AddrModeFlat; + if (!f_read_mem(hProcess, curr_switch, &ch, sizeof(ch), NULL)) + curr_switch = 0xFFFFFFFF; + } } + else + /* FIXME: this will allow to work when we're not attached to a live target, + * but the 16 <=> 32 switch facility won't be available. + */ + curr_switch = 0; + frame->AddrReturn.Mode = frame->AddrStack.Mode = (curr_mode == stm_16bit) ? AddrMode1616 : AddrModeFlat; /* don't set up AddrStack on first call. Either the caller has set it up, or * we will get it in the next frame */ @@ -186,7 +197,7 @@ else { assert(curr_mode == stm_16bit); - do_switch = OFFSETOF(curr_switch) && + do_switch = curr_switch && frame->AddrFrame.Segment == SELECTOROF(curr_switch) && frame->AddrFrame.Offset >= OFFSETOF(curr_switch); } @@ -195,7 +206,7 @@ { if (curr_mode == stm_16bit) { - if (!f_read_mem(hProcess, (void*)next_switch, &frame32, + if (!f_read_mem(hProcess, next_switch, &frame32, sizeof(frame32), NULL)) { WARN("Bad stack frame 0x%08lx\n", next_switch); @@ -220,15 +231,15 @@ tmp.Offset = OFFSETOF(next_switch); p = f_xlat_adr(hProcess, hThread, &tmp); - if (!f_read_mem(hProcess, (void*)p, &frame16, sizeof(frame16), NULL)) + if (!f_read_mem(hProcess, p, &frame16, sizeof(frame16), NULL)) { WARN("Bad stack frame 0x%08lx\n", p); goto done_err; } curr_switch = (DWORD)frame16.frame32; curr_mode = stm_32bit; - if (!f_read_mem(hProcess, (void*)curr_switch, &ch, sizeof(ch), NULL)) - curr_switch = 0xFFFFFFFF; + if (!f_read_mem(hProcess, curr_switch, &ch, sizeof(ch), NULL)) + curr_switch = 0; } else { @@ -237,7 +248,7 @@ tmp.Offset = OFFSETOF(next_switch); p = f_xlat_adr(hProcess, hThread, &tmp); - if (!f_read_mem(hProcess, (void*)p, &frame16, sizeof(frame16), NULL)) + if (!f_read_mem(hProcess, p, &frame16, sizeof(frame16), NULL)) { WARN("Bad stack frame 0x%08lx\n", p); goto done_err; @@ -273,8 +284,7 @@ frame->AddrReturn.Segment = frame16.cs; next_switch = curr_switch; - if (!f_read_mem(hProcess, (void*)next_switch, &frame32, sizeof(frame32), - NULL)) + if (!f_read_mem(hProcess, next_switch, &frame32, sizeof(frame32), NULL)) { WARN("Bad stack frame 0x%08lx\n", next_switch); goto done_err; @@ -284,9 +294,9 @@ tmp.Segment = SELECTOROF(curr_switch); tmp.Offset = OFFSETOF(curr_switch); - if (!f_read_mem(hProcess, (void*)f_xlat_adr(hProcess, hThread, &tmp), + if (!f_read_mem(hProcess, f_xlat_adr(hProcess, hThread, &tmp), &ch, sizeof(ch), NULL)) - curr_switch = 0xFFFFFFFF; + curr_switch = 0; curr_mode = stm_16bit; } } @@ -298,7 +308,7 @@ frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(WORD); /* "pop up" previous BP value */ if (!f_read_mem(hProcess, - (void*)f_xlat_adr(hProcess, hThread, &frame->AddrFrame), + f_xlat_adr(hProcess, hThread, &frame->AddrFrame), &val, sizeof(WORD), NULL)) goto done_err; frame->AddrFrame.Offset = val; @@ -307,7 +317,7 @@ { frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(DWORD); /* "pop up" previous EBP value */ - if (!f_read_mem(hProcess, (void*)frame->AddrFrame.Offset, + if (!f_read_mem(hProcess, frame->AddrFrame.Offset, &frame->AddrFrame.Offset, sizeof(DWORD), NULL)) goto done_err; } @@ -319,11 +329,11 @@ int i; p = f_xlat_adr(hProcess, hThread, &frame->AddrFrame); - if (!f_read_mem(hProcess, (void*)(p + sizeof(WORD)), &val, sizeof(WORD), NULL)) + if (!f_read_mem(hProcess, p + sizeof(WORD), &val, sizeof(WORD), NULL)) goto done_err; frame->AddrReturn.Offset = val; /* get potential cs if a far call was used */ - if (!f_read_mem(hProcess, (void*)(p + 2 * sizeof(WORD)), + if (!f_read_mem(hProcess, p + 2 * sizeof(WORD), &val, sizeof(WORD), NULL)) goto done_err; if (frame->AddrFrame.Offset & 1) @@ -354,7 +364,7 @@ */ for (i = 0; i < sizeof(frame->Params) / sizeof(frame->Params[0]); i++) { - f_read_mem(hProcess, (void*)(p + (2 + i) * sizeof(WORD)), + f_read_mem(hProcess, p + (2 + i) * sizeof(WORD), &val, sizeof(val), NULL); frame->Params[i] = val; } @@ -362,11 +372,14 @@ else { if (!f_read_mem(hProcess, - (void*)(frame->AddrFrame.Offset + sizeof(DWORD)), + frame->AddrFrame.Offset + sizeof(DWORD), &frame->AddrReturn.Offset, sizeof(DWORD), NULL)) + { + WARN("Cannot read new frame offset %08lx\n", frame->AddrFrame.Offset + sizeof(DWORD)); goto done_err; + } f_read_mem(hProcess, - (void*)(frame->AddrFrame.Offset + 2 * sizeof(DWORD)), + frame->AddrFrame.Offset + 2 * sizeof(DWORD), frame->Params, sizeof(frame->Params), NULL); } diff -urN wine-20050419/dlls/dciman32/.cvsignore wine-20050524/dlls/dciman32/.cvsignore --- wine-20050419/dlls/dciman32/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dciman32/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,3 +1,3 @@ Makefile dciman32.dll.dbg.c -dciman32.spec.def +libdciman32.def diff -urN wine-20050419/dlls/dciman32/Makefile.in wine-20050524/dlls/dciman32/Makefile.in --- wine-20050419/dlls/dciman32/Makefile.in 2003-10-11 03:09:20.000000000 +0200 +++ wine-20050524/dlls/dciman32/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dciman32.dll +IMPORTLIB = libdciman32.$(IMPLIBEXT) IMPORTS = kernel32 C_SRCS = dciman_main.c diff -urN wine-20050419/dlls/dciman32/dciman_main.c wine-20050524/dlls/dciman32/dciman_main.c --- wine-20050419/dlls/dciman32/dciman_main.c 2005-04-15 18:11:56.000000000 +0200 +++ wine-20050524/dlls/dciman32/dciman_main.c 2005-04-20 20:42:04.000000000 +0200 @@ -25,6 +25,7 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" +#include "dciman.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(dciman); @@ -47,7 +48,7 @@ HDC WINAPI DCIOpenProvider(void) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return NULL; } /*********************************************************************** @@ -62,10 +63,10 @@ /************************************************************************** * DCICreatePrimary (DCIMAN32.@) */ -void WINAPI -DCICreatePrimary(HDC hdc, LPVOID pDciSurfaceInfo) +int WINAPI +DCICreatePrimary(HDC hdc, LPDCISURFACEINFO *pDciSurfaceInfo) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); FIXME("%p %p\n", hdc, pDciSurfaceInfo); - return; + return DCI_FAIL_UNSUPPORTED; } diff -urN wine-20050419/dlls/ddraw/.cvsignore wine-20050524/dlls/ddraw/.cvsignore --- wine-20050419/dlls/ddraw/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/ddraw/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile ddraw.dll.dbg.c -ddraw.spec.def +libddraw.def version.res diff -urN wine-20050419/dlls/ddraw/Makefile.in wine-20050524/dlls/ddraw/Makefile.in --- wine-20050419/dlls/ddraw/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/ddraw/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = ddraw.dll +IMPORTLIB = libddraw.$(IMPLIBEXT) IMPORTS = ole32 user32 gdi32 advapi32 kernel32 EXTRAINCL = @X_CFLAGS@ EXTRALIBS = -ldxguid -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ diff -urN wine-20050419/dlls/ddraw/ddraw/hal.c wine-20050524/dlls/ddraw/ddraw/hal.c --- wine-20050419/dlls/ddraw/ddraw/hal.c 2004-12-06 17:21:27.000000000 +0100 +++ wine-20050524/dlls/ddraw/ddraw/hal.c 2005-04-25 12:48:38.000000000 +0200 @@ -114,7 +114,7 @@ if (lpDDHalInfo->lpD3DHALCallbacks) memcpy(&d3d_hal_cbs1, (LPVOID)lpDDHalInfo->lpD3DHALCallbacks, sizeof(D3DHAL_CALLBACKS)); else - memset(&d3d_hal_cbs1, 0, sizeof(D3DDEVICEDESC_V1)); + memset(&d3d_hal_cbs1, 0, sizeof(D3DHAL_CALLBACKS)); dd_gbl.lpD3DHALCallbacks = (ULONG_PTR)&d3d_hal_cbs1; if (lpDDHalInfo->dwFlags & DDHALINFO_GETDRIVERINFOSET) { diff -urN wine-20050419/dlls/ddraw/ddraw/user.c wine-20050524/dlls/ddraw/ddraw/user.c --- wine-20050419/dlls/ddraw/ddraw/user.c 2005-03-07 12:01:10.000000000 +0100 +++ wine-20050524/dlls/ddraw/ddraw/user.c 2005-05-07 14:17:45.000000000 +0200 @@ -506,6 +506,12 @@ devmode.dmBitsPerPel = dwBPP; devmode.dmPelsWidth = dwWidth; devmode.dmPelsHeight = dwHeight; + /* '0' means default frequency */ + if (dwRefreshRate != 0) + { + devmode.dmFields |= DM_DISPLAYFREQUENCY; + devmode.dmDisplayFrequency = dwRefreshRate; + } if (ChangeDisplaySettingsExW(NULL, &devmode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) return DDERR_INVALIDMODE; diff -urN wine-20050419/dlls/ddraw/dsurface/main.c wine-20050524/dlls/ddraw/dsurface/main.c --- wine-20050419/dlls/ddraw/dsurface/main.c 2005-03-07 13:23:34.000000000 +0100 +++ wine-20050524/dlls/ddraw/dsurface/main.c 2005-05-23 13:42:40.000000000 +0200 @@ -1000,6 +1000,8 @@ IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; PrivateData* data; + TRACE("(%p)->(%p), size = %ld\n", This, pBuffer, *pcbBufferSize); + data = find_private_data(This, tag); if (data == NULL) return DDERR_NOTFOUND; @@ -1370,6 +1372,8 @@ PrivateData* data; IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; + TRACE("(%p)->(%p), size=%ld\n", This, pData, cbSize); + data = find_private_data(This, tag); if (data == NULL) { @@ -1394,6 +1398,9 @@ HeapFree(GetProcessHeap(), 0, data); return DDERR_OUTOFMEMORY; } + + data->size = cbSize; + memcpy(data->ptr.data, pData, data->size); } /* link it in */ @@ -1412,6 +1419,7 @@ * guarantee SetPrivateData working when using LPUNKNOWN or data * that is no larger than the old data. */ + FIXME("Replacing existing private data not implemented yet.\n"); return E_FAIL; } } diff -urN wine-20050419/dlls/ddraw/main.c wine-20050524/dlls/ddraw/main.c --- wine-20050419/dlls/ddraw/main.c 2005-01-09 18:35:44.000000000 +0100 +++ wine-20050524/dlls/ddraw/main.c 2005-05-06 21:38:50.000000000 +0200 @@ -654,7 +654,7 @@ DisableThreadLibraryCalls(hInstDLL); - mod = GetModuleHandleA( "x11drv.dll" ); + mod = GetModuleHandleA( "winex11.drv" ); if (mod) { wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" ); diff -urN wine-20050419/dlls/devenum/.cvsignore wine-20050524/dlls/devenum/.cvsignore --- wine-20050419/dlls/devenum/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/devenum/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile devenum.dll.dbg.c devenum.res -devenum.spec.def +libdevenum.def diff -urN wine-20050419/dlls/devenum/Makefile.in wine-20050524/dlls/devenum/Makefile.in --- wine-20050419/dlls/devenum/Makefile.in 2004-08-19 21:31:20.000000000 +0200 +++ wine-20050524/dlls/devenum/Makefile.in 2005-05-18 20:25:12.000000000 +0200 @@ -3,8 +3,9 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = devenum.dll -IMPORTS = ole32 oleaut32 winmm user32 advapi32 kernel32 -EXTRALIBS = -lstrmiids -luuid +IMPORTLIB = libdevenum.$(IMPLIBEXT) +IMPORTS = ole32 oleaut32 avicap32 winmm user32 advapi32 kernel32 +EXTRALIBS = -lstrmiids -luuid $(LIBUNICODE) C_SRCS = \ createdevenum.c \ diff -urN wine-20050419/dlls/devenum/createdevenum.c wine-20050524/dlls/devenum/createdevenum.c --- wine-20050419/dlls/devenum/createdevenum.c 2005-01-25 11:56:39.000000000 +0100 +++ wine-20050524/dlls/devenum/createdevenum.c 2005-05-18 20:25:12.000000000 +0200 @@ -27,8 +27,10 @@ #define NONAMELESSUNION #include "devenum_private.h" +#include "vfw.h" #include "wine/debug.h" +#include "wine/unicode.h" #include "mmddk.h" WINE_DEFAULT_DEBUG_CHANNEL(devenum); @@ -117,6 +119,7 @@ if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) || IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) || + IsEqualGUID(clsidDeviceClass, &CLSID_VideoInputDeviceCategory) || IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory)) { hbasekey = HKEY_CURRENT_USER; @@ -142,6 +145,7 @@ { if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) || IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) || + IsEqualGUID(clsidDeviceClass, &CLSID_VideoInputDeviceCategory) || IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory)) { HRESULT hr = DEVENUM_CreateSpecialCategories(); @@ -413,6 +417,57 @@ CoTaskMemFree(pTypes); } } + res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory); + if (SUCCEEDED(res)) + for (i = 0; i < 10; i++) + { + WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10]; + + if (capGetDriverDescriptionW ((WORD) i, + szDeviceName, sizeof(szDeviceName)/sizeof(WCHAR), + szDeviceVersion, sizeof(szDeviceVersion)/sizeof(WCHAR))) + { + IMoniker * pMoniker = NULL; + IPropertyBag * pPropBag = NULL; + WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 }; + snprintfW(szDevicePath, sizeof(szDevicePath)/sizeof(WCHAR), dprintf, i); + /* The above code prevents 1 device with a different ID overwriting another */ + + rfp2.nMediaTypes = 1; + pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); + if (!pTypes) { + IFilterMapper2_Release(pMapper); + return E_OUTOFMEMORY; + } + + pTypes[0].clsMajorType = &MEDIATYPE_Video; + pTypes[0].clsMinorType = &MEDIASUBTYPE_None; + + rfp2.lpMediaType = pTypes; + + res = IFilterMapper2_RegisterFilter(pMapper, + &CLSID_VfwCapture, + szDeviceName, + &pMoniker, + &CLSID_VideoInputDeviceCategory, + szDevicePath, + &rf2); + + if (pMoniker) { + OLECHAR wszVfwIndex[] = { 'V','F','W','I','n','d','e','x',0 }; + VARIANT var; + V_VT(&var) = VT_I4; + V_UNION(&var, ulVal) = (ULONG)i; + res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag); + if (SUCCEEDED(res)) + res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var); + IMoniker_Release(pMoniker); + } + + if (i == iDefaultDevice) FIXME("Default device\n"); + CoTaskMemFree(pTypes); + } + } } if (pMapper) diff -urN wine-20050419/dlls/devenum/devenum.spec wine-20050524/dlls/devenum/devenum.spec --- wine-20050419/dlls/devenum/devenum.spec 2003-07-30 05:48:56.000000000 +0200 +++ wine-20050524/dlls/devenum/devenum.spec 2005-05-17 16:41:38.000000000 +0200 @@ -1,4 +1,4 @@ -@ stdcall -private DllCanUnloadNow() DEVENUM_DllCanUnloadNow -@ stdcall -private DllGetClassObject(ptr ptr ptr) DEVENUM_DllGetClassObject -@ stdcall -private DllRegisterServer() DEVENUM_DllRegisterServer -@ stdcall -private DllUnregisterServer() DEVENUM_DllUnregisterServer +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff -urN wine-20050419/dlls/devenum/devenum_main.c wine-20050524/dlls/devenum/devenum_main.c --- wine-20050419/dlls/devenum/devenum_main.c 2004-12-07 15:37:11.000000000 +0100 +++ wine-20050524/dlls/devenum/devenum_main.c 2005-05-17 16:41:38.000000000 +0200 @@ -66,7 +66,7 @@ /*********************************************************************** * DllGetClassObject (DEVENUM.@) */ -HRESULT WINAPI DEVENUM_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) { TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); @@ -85,7 +85,7 @@ /*********************************************************************** * DllCanUnloadNow (DEVENUM.@) */ -HRESULT WINAPI DEVENUM_DllCanUnloadNow(void) +HRESULT WINAPI DllCanUnloadNow(void) { return dll_refs != 0 ? S_FALSE : S_OK; } @@ -93,7 +93,7 @@ /*********************************************************************** * DllRegisterServer (DEVENUM.@) */ -HRESULT WINAPI DEVENUM_DllRegisterServer(void) +HRESULT WINAPI DllRegisterServer(void) { HRESULT res; HKEY hkeyClsid = NULL; @@ -289,7 +289,7 @@ /*********************************************************************** * DllUnregisterServer (DEVENUM.@) */ -HRESULT WINAPI DEVENUM_DllUnregisterServer(void) +HRESULT WINAPI DllUnregisterServer(void) { FIXME("stub!\n"); return E_FAIL; diff -urN wine-20050419/dlls/devenum/devenum_private.h wine-20050524/dlls/devenum/devenum_private.h --- wine-20050419/dlls/devenum/devenum_private.h 2004-12-13 22:19:02.000000000 +0100 +++ wine-20050524/dlls/devenum/devenum_private.h 2005-04-27 13:07:55.000000000 +0200 @@ -26,6 +26,7 @@ #include "windef.h" #include "winbase.h" +#include "wingdi.h" #include "winuser.h" #include "winreg.h" #include "winerror.h" diff -urN wine-20050419/dlls/devenum/mediacatenum.c wine-20050524/dlls/devenum/mediacatenum.c --- wine-20050419/dlls/devenum/mediacatenum.c 2005-01-10 13:25:29.000000000 +0100 +++ wine-20050524/dlls/devenum/mediacatenum.c 2005-05-18 20:20:39.000000000 +0200 @@ -25,6 +25,7 @@ #include "devenum_private.h" #include "vfwmsgs.h" #include "oleauto.h" +#include "ocidl.h" #include "wine/debug.h" @@ -431,7 +432,19 @@ if (pObj!=NULL) { /* get the requested interface from the loaded class */ - res= IUnknown_QueryInterface(pObj,riidResult,ppvResult); + res = S_OK; + if (pProp) { + HRESULT res2; + LPVOID ppv = NULL; + res2 = IUnknown_QueryInterface(pObj, &IID_IPersistPropertyBag, &ppv); + if (SUCCEEDED(res2)) { + res = IPersistPropertyBag_Load((IPersistPropertyBag *) ppv, pProp, NULL); + IPersistPropertyBag_Release((IPersistPropertyBag *) ppv); + } + } + if (SUCCEEDED(res)) + res= IUnknown_QueryInterface(pObj,riidResult,ppvResult); + IUnknown_Release(pObj); } if (pProp) diff -urN wine-20050419/dlls/dinput/.cvsignore wine-20050524/dlls/dinput/.cvsignore --- wine-20050419/dlls/dinput/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dinput/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dinput.dll.dbg.c -dinput.spec.def +libdinput.def version.res diff -urN wine-20050419/dlls/dinput/Makefile.in wine-20050524/dlls/dinput/Makefile.in --- wine-20050419/dlls/dinput/Makefile.in 2004-08-31 20:51:23.000000000 +0200 +++ wine-20050524/dlls/dinput/Makefile.in 2005-05-11 14:05:17.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dinput.dll +IMPORTLIB = libdinput.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid @@ -16,8 +17,12 @@ mouse.c \ regsvr.c +IMPLIB_SRCS = data_formats.c + RC_SRCS = version.rc +SUBDIRS = tests + @MAKE_DLL_RULES@ ### Dependencies: diff -urN wine-20050419/dlls/dinput/device.c wine-20050524/dlls/dinput/device.c --- wine-20050419/dlls/dinput/device.c 2005-03-24 22:01:39.000000000 +0100 +++ wine-20050524/dlls/dinput/device.c 2005-05-16 16:07:36.000000000 +0200 @@ -80,7 +80,10 @@ FE(DIDFT_NODATA), FE(DIDFT_FFACTUATOR), FE(DIDFT_FFEFFECTTRIGGER), - FE(DIDFT_OUTPUT) + FE(DIDFT_OUTPUT), + FE(DIDFT_VENDORDEFINED), + FE(DIDFT_ALIAS), + FE(DIDFT_OPTIONAL) #undef FE }; type = (dwFlags & 0xFF0000FF); @@ -310,13 +313,18 @@ * the GUID of the Wine object. */ ((asked_format->rgodf[j].pguid == NULL) || + (wine_format->rgodf[i].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid))) && (/* Then check if it accepts any instance id, and if not, if it matches Wine's * instance id. */ - ((asked_format->rgodf[j].dwType & 0x00FFFF00) == DIDFT_ANYINSTANCE) || - (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType))) { + (DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType) == 0xFFFF) || + (DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType) == 0x00FF) || /* This is mentionned in no DX docs, but it works fine - tested on WinXP */ + (DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType) == DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType))) + && + ( /* Then if the asked type matches the one Wine provides */ + wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) { done[j] = 1; @@ -329,19 +337,19 @@ TRACE(" * dwType: %08lx\n", asked_format->rgodf[j].dwType); TRACE(" "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n"); - TRACE(" - Wine (%d) :\n", j); + TRACE(" - Wine (%d) :\n", i); TRACE(" * GUID: %s ('%s')\n", - debugstr_guid(wine_format->rgodf[j].pguid), - _dump_dinput_GUID(wine_format->rgodf[j].pguid)); - TRACE(" * Offset: %3ld\n", wine_format->rgodf[j].dwOfs); - TRACE(" * dwType: %08lx\n", wine_format->rgodf[j].dwType); - TRACE(" "); _dump_EnumObjects_flags(wine_format->rgodf[j].dwType); TRACE("\n"); + debugstr_guid(wine_format->rgodf[i].pguid), + _dump_dinput_GUID(wine_format->rgodf[i].pguid)); + TRACE(" * Offset: %3ld\n", wine_format->rgodf[i].dwOfs); + TRACE(" * dwType: %08lx\n", wine_format->rgodf[i].dwType); + TRACE(" "); _dump_EnumObjects_flags(wine_format->rgodf[i].dwType); TRACE("\n"); if (wine_format->rgodf[i].dwType & DIDFT_BUTTON) dt[index].size = sizeof(BYTE); else dt[index].size = sizeof(DWORD); - dt[index].offset_in = wine_format ->rgodf[i].dwOfs; + dt[index].offset_in = wine_format->rgodf[i].dwOfs; if (asked_format->rgodf[j].dwOfs < next) { WARN("bad format: dwOfs=%ld, changing to %ld\n", asked_format->rgodf[j].dwOfs, next); dt[index].offset_out = next; @@ -409,7 +417,7 @@ data = (device_enumobjects_AtoWcb_data*) lpvRef; - memset(&ddtmp, 0, sizeof(DIDEVICEINSTANCEW)); + memset(&ddtmp, 0, sizeof(ddtmp)); ddtmp.dwSize = sizeof(DIDEVICEINSTANCEW); ddtmp.guidType = lpddi->guidType; @@ -749,8 +757,6 @@ { FIXME("(this=%p,%p,%p,0x%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags); - if (lpCallback) - lpCallback(NULL, lpvRef); return DI_OK; } diff -urN wine-20050419/dlls/dinput/dinput_main.c wine-20050524/dlls/dinput/dinput_main.c --- wine-20050419/dlls/dinput/dinput_main.c 2005-03-24 22:01:39.000000000 +0100 +++ wine-20050524/dlls/dinput/dinput_main.c 2005-05-16 10:44:14.000000000 +0200 @@ -94,7 +94,7 @@ This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl)); This->lpVtbl = &ddi7avt; This->ref = 1; - This->version = 1; + This->dwVersion = dwVersion; *ppDI = This; return DI_OK; @@ -106,7 +106,7 @@ This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl)); This->lpVtbl = &ddi7wvt; This->ref = 1; - This->version = 1; + This->dwVersion = dwVersion; *ppDI = This; return DI_OK; @@ -116,7 +116,7 @@ This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl)); This->lpVtbl = &ddi8avt; This->ref = 1; - This->version = 8; + This->dwVersion = dwVersion; *ppDI = This; return DI_OK; @@ -126,7 +126,7 @@ This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl)); This->lpVtbl = &ddi8wvt; This->ref = 1; - This->version = 8; + This->dwVersion = dwVersion; *ppDI = This; return DI_OK; @@ -145,12 +145,7 @@ This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl)); This->lpVtbl = &ddi7avt; This->ref = 1; - if (dwVersion >= 0x0800) { - This->version = 8; - } else { - /* We do not differientiate between version 1, 2 and 7 */ - This->version = 1; - } + This->dwVersion = dwVersion; *ppDI = (IDirectInputA*)This; return 0; @@ -166,12 +161,7 @@ This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl)); This->lpVtbl = &ddi7wvt; This->ref = 1; - if (dwVersion >= 0x0800) { - This->version = 8; - } else { - /* We do not differientiate between version 1, 2 and 7 */ - This->version = 1; - } + This->dwVersion = dwVersion; *ppDI = (IDirectInputW*)This; return 0; } @@ -227,13 +217,13 @@ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType), lpCallback, pvRef, dwFlags); TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n"); - + for (i = 0; i < NB_DINPUT_DEVICES; i++) { if (!dinput_devices[i]->enum_deviceA) continue; for (j = 0, r = -1; r != 0; j++) { devInstance.dwSize = sizeof(devInstance); TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name); - if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version, j))) { + if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->dwVersion, j))) { if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) return 0; } @@ -257,13 +247,13 @@ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType), lpCallback, pvRef, dwFlags); TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n"); - + for (i = 0; i < NB_DINPUT_DEVICES; i++) { if (!dinput_devices[i]->enum_deviceW) continue; for (j = 0, r = -1; r != 0; j++) { devInstance.dwSize = sizeof(devInstance); TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name); - if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version, j))) { + if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->dwVersion, j))) { if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) return 0; } @@ -331,6 +321,16 @@ TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk); + if (pdev == NULL) { + WARN("invalid pointer: pdev == NULL\n"); + return E_POINTER; + } + + if (rguid == NULL) { + WARN("invalid pointer: rguid == NULL\n"); + return E_POINTER; + } + /* Loop on all the devices to see if anyone matches the given GUID */ for (i = 0; i < NB_DINPUT_DEVICES; i++) { HRESULT ret; diff -urN wine-20050419/dlls/dinput/dinput_private.h wine-20050524/dlls/dinput/dinput_private.h --- wine-20050419/dlls/dinput/dinput_private.h 2005-03-15 20:36:15.000000000 +0100 +++ wine-20050524/dlls/dinput/dinput_private.h 2005-05-16 10:44:14.000000000 +0200 @@ -35,14 +35,14 @@ /* Used to have an unique sequence number for all the events */ DWORD evsequence; - int version; + DWORD dwVersion; }; /* Function called by all devices that Wine supports */ struct dinput_device { const char *name; - BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id); - BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id); + BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id); + BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id); HRESULT (*create_deviceA)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev); HRESULT (*create_deviceW)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev); }; diff -urN wine-20050419/dlls/dinput/joystick_linux.c wine-20050524/dlls/dinput/joystick_linux.c --- wine-20050419/dlls/dinput/joystick_linux.c 2005-03-15 20:36:15.000000000 +0100 +++ wine-20050524/dlls/dinput/joystick_linux.c 2005-05-16 10:44:14.000000000 +0200 @@ -148,7 +148,7 @@ } } -static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) +static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id) { int fd = -1; char dev[32]; @@ -159,8 +159,8 @@ } if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 8))) { + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) { /* check whether we have a joystick */ sprintf(dev, "%s%d", JOYDEV, id); if ((fd = open(dev,O_RDONLY)) < 0) { @@ -173,7 +173,7 @@ lpddi->guidInstance.Data3 = id; lpddi->guidProduct = DInput_Wine_Joystick_GUID; /* we only support traditional joysticks for now */ - if (version >= 8) + if (version >= 0x0800) lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); else lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); @@ -196,7 +196,7 @@ return FALSE; } -static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) +static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id) { int fd = -1; char name[MAX_PATH]; @@ -209,8 +209,8 @@ } if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 8))) { + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) { /* check whether we have a joystick */ sprintf(dev, "%s%d", JOYDEV, id); if ((fd = open(dev,O_RDONLY)) < 0) { @@ -223,7 +223,7 @@ lpddi->guidInstance.Data3 = id; lpddi->guidProduct = DInput_Wine_Joystick_GUID; /* we only support traditional joysticks for now */ - if (version >= 8) + if (version >= 0x0800) lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); else lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); @@ -557,7 +557,7 @@ newDevice->devcaps.dwSize = sizeof(newDevice->devcaps); newDevice->devcaps.dwFlags = DIDC_ATTACHED; - if (newDevice->dinput->version >= 8) + if (newDevice->dinput->dwVersion >= 0x0800) newDevice->devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); else newDevice->devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); @@ -713,6 +713,16 @@ TRACE("(%p,%p)\n",This,df); + if (df == NULL) { + WARN("invalid pointer\n"); + return E_POINTER; + } + + if (df->dwSize != sizeof(*df)) { + WARN("invalid argument\n"); + return DIERR_INVALIDPARAM; + } + if (This->acquired) { WARN("acquired\n"); return DIERR_ACQUIRED; @@ -1113,6 +1123,11 @@ TRACE("(%p,%s,%p)\n",This,debugstr_guid(rguid),ph); + if (ph == NULL) { + WARN("invalid parameter: ph == NULL\n"); + return DIERR_INVALIDPARAM; + } + if (TRACE_ON(dinput)) _dump_DIPROPHEADER(ph); @@ -1213,11 +1228,17 @@ TRACE("%p->(%p)\n",iface,lpDIDevCaps); if (lpDIDevCaps == NULL) { - WARN("invalid parameter: lpDIDevCaps = NULL\n"); - return DIERR_INVALIDPARAM; + WARN("invalid pointer\n"); + return E_POINTER; } size = lpDIDevCaps->dwSize; + + if (!(size == sizeof(DIDEVCAPS) || size == sizeof(DIDEVCAPS_DX3))) { + WARN("invalid parameter\n"); + return DIERR_INVALIDPARAM; + } + CopyMemory(lpDIDevCaps, &This->devcaps, size); lpDIDevCaps->dwSize = size; @@ -1555,6 +1576,11 @@ TRACE("(%p,%p)\n", iface, pdidi); + if (pdidi == NULL) { + WARN("invalid pointer\n"); + return E_POINTER; + } + if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3A)) && (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA))) { WARN("invalid parameter: pdidi->dwSize = %ld != %d or %d\n", diff -urN wine-20050419/dlls/dinput/joystick_linuxinput.c wine-20050524/dlls/dinput/joystick_linuxinput.c --- wine-20050419/dlls/dinput/joystick_linuxinput.c 2005-03-18 11:25:15.000000000 +0100 +++ wine-20050524/dlls/dinput/joystick_linuxinput.c 2005-05-16 10:44:14.000000000 +0200 @@ -164,7 +164,7 @@ return havejoy; } -static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) +static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id) { int havejoy = 0; @@ -172,8 +172,8 @@ return FALSE; if (!((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 8)))) + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800)))) return FALSE; if (dwFlags & DIEDFL_FORCEFEEDBACK) @@ -191,7 +191,7 @@ lpddi->guidProduct = DInput_Wine_Joystick_GUID; lpddi->guidFFDriver = GUID_NULL; - if (version >= 8) + if (version >= 0x0800) lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); else lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); @@ -202,7 +202,7 @@ return TRUE; } -static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) +static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id) { int havejoy = 0; @@ -210,8 +210,8 @@ return FALSE; if (!((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 8)))) + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800)))) return FALSE; if (dwFlags & DIEDFL_FORCEFEEDBACK) @@ -229,7 +229,7 @@ lpddi->guidProduct = DInput_Wine_Joystick_GUID; lpddi->guidFFDriver = GUID_NULL; - if (version >= 8) + if (version >= 0x0800) lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); else lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); @@ -755,7 +755,7 @@ wasacquired = 0; } lpDIDevCaps->dwFlags = DIDC_ATTACHED; - if (This->dinput->version >= 8) + if (This->dinput->dwVersion >= 0x0800) lpDIDevCaps->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); else lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); diff -urN wine-20050419/dlls/dinput/keyboard.c wine-20050524/dlls/dinput/keyboard.c --- wine-20050419/dlls/dinput/keyboard.c 2005-03-24 16:08:28.000000000 +0100 +++ wine-20050524/dlls/dinput/keyboard.c 2005-05-16 10:44:14.000000000 +0200 @@ -154,7 +154,7 @@ {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41} }; -static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, int version) { +static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) { DWORD dwSize; DIDEVICEINSTANCEA ddi; @@ -168,7 +168,7 @@ ddi.dwSize = dwSize; ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */ ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ - if (version >= 8) + if (version >= 0x0800) ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8); else ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); @@ -178,7 +178,7 @@ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, int version) { +static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) { DWORD dwSize; DIDEVICEINSTANCEW ddi; @@ -192,7 +192,7 @@ ddi.dwSize = dwSize; ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */ ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ - if (version >= 8) + if (version >= 0x0800) ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8); else ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); @@ -202,14 +202,14 @@ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) +static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id) { if (id != 0) return FALSE; if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 8))) { + ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) { TRACE("Enumerating the Keyboard device\n"); fill_keyboard_dideviceinstanceA(lpddi, version); @@ -220,14 +220,14 @@ return FALSE; } -static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) +static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id) { if (id != 0) return FALSE; if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 8))) { + ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) { TRACE("Enumerating the Keyboard device\n"); fill_keyboard_dideviceinstanceW(lpddi, version); @@ -622,7 +622,7 @@ devcaps.dwSize = lpDIDevCaps->dwSize; devcaps.dwFlags = DIDC_ATTACHED; - if (This->dinput->version >= 8) + if (This->dinput->dwVersion >= 0x0800) devcaps.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8); else devcaps.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); @@ -727,7 +727,7 @@ return DI_OK; } - fill_keyboard_dideviceinstanceA(pdidi, This->dinput->version); + fill_keyboard_dideviceinstanceA(pdidi, This->dinput->dwVersion); return DI_OK; } @@ -742,7 +742,7 @@ return DI_OK; } - fill_keyboard_dideviceinstanceW(pdidi, This->dinput->version); + fill_keyboard_dideviceinstanceW(pdidi, This->dinput->dwVersion); return DI_OK; } diff -urN wine-20050419/dlls/dinput/mouse.c wine-20050524/dlls/dinput/mouse.c --- wine-20050419/dlls/dinput/mouse.c 2005-03-24 22:01:39.000000000 +0100 +++ wine-20050524/dlls/dinput/mouse.c 2005-05-16 10:44:14.000000000 +0200 @@ -155,7 +155,7 @@ {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} }; -static void fill_mouse_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, int version) { +static void fill_mouse_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) { DWORD dwSize; DIDEVICEINSTANCEA ddi; @@ -169,7 +169,7 @@ ddi.dwSize = dwSize; ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */ ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */ - if (version >= 8) + if (version >= 0x0800) ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8); else ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8); @@ -179,7 +179,7 @@ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static void fill_mouse_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, int version) { +static void fill_mouse_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) { DWORD dwSize; DIDEVICEINSTANCEW ddi; @@ -193,7 +193,7 @@ ddi.dwSize = dwSize; ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */ ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */ - if (version >= 8) + if (version >= 0x0800) ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8); else ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8); @@ -203,14 +203,14 @@ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) +static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id) { if (id != 0) return FALSE; if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 8))) { + ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) { TRACE("Enumerating the mouse device\n"); fill_mouse_dideviceinstanceA(lpddi, version); @@ -221,14 +221,14 @@ return FALSE; } -static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) +static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id) { if (id != 0) return FALSE; if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) || - (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 8))) { + ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) || + (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) { TRACE("Enumerating the mouse device\n"); fill_mouse_dideviceinstanceW(lpddi, version); @@ -604,9 +604,9 @@ This->org_coords = point; } This->m_state.lZ = 0; - This->m_state.rgbButtons[0] = ((GetKeyState(VK_LBUTTON) & 0x80) ? 0xFF : 0x00); - This->m_state.rgbButtons[1] = ((GetKeyState(VK_RBUTTON) & 0x80) ? 0xFF : 0x00); - This->m_state.rgbButtons[2] = ((GetKeyState(VK_MBUTTON) & 0x80) ? 0xFF : 0x00); + This->m_state.rgbButtons[0] = GetKeyState(VK_LBUTTON) & 0x80; + This->m_state.rgbButtons[1] = GetKeyState(VK_RBUTTON) & 0x80; + This->m_state.rgbButtons[2] = GetKeyState(VK_MBUTTON) & 0x80; /* Install our mouse hook */ if (This->dwCoopLevel & DISCL_EXCLUSIVE) @@ -685,9 +685,14 @@ LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr ) { SysMouseImpl *This = (SysMouseImpl *)iface; - + + if(This->acquired == 0) return DIERR_NOTACQUIRED; + EnterCriticalSection(&(This->crit)); TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr); + TRACE("(X: %ld - Y: %ld - Z: %ld L: %02x M: %02x R: %02x)\n", + This->m_state.lX, This->m_state.lY, This->m_state.lZ, + This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); /* Copy the current mouse state */ fill_DataFormat(ptr, &(This->m_state), This->wine_df); @@ -714,15 +719,11 @@ LeaveCriticalSection(&(This->crit)); - TRACE("(X: %ld - Y: %ld - Z: %ld L: %02x M: %02x R: %02x)\n", - This->m_state.lX, This->m_state.lY, This->m_state.lZ, - This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); - return DI_OK; } /****************************************************************************** - * GetDeviceState : gets buffered input data. + * GetDeviceData : gets buffered input data. */ static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface, DWORD dodsize, @@ -732,9 +733,11 @@ ) { SysMouseImpl *This = (SysMouseImpl *)iface; DWORD len; - int nqtail; + int nqtail = 0; - TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags); + TRACE("(%p)->(dods=%ld,dod=%p,entries=%p (%ld)%s,fl=0x%08lx%s)\n",This,dodsize,dod, + entries, *entries,*entries == INFINITE ? " (INFINITE)" : "", + flags, (flags & DIGDD_PEEK) ? " (DIGDD_PEEK)": "" ); if (This->acquired == 0) { WARN(" application tries to get data from an unacquired device !\n"); @@ -742,18 +745,23 @@ } EnterCriticalSection(&(This->crit)); - + len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0) + (This->queue_head - This->queue_tail); - if (len > *entries) len = *entries; + if ((*entries != INFINITE) && (len > *entries)) len = *entries; if (dod == NULL) { - if (len) - TRACE("Application discarding %ld event(s).\n", len); - *entries = len; - nqtail = This->queue_tail + len; - while (nqtail >= This->queue_len) nqtail -= This->queue_len; + + if (!(flags & DIGDD_PEEK)) { + if (len) + TRACE("Application discarding %ld event(s).\n", len); + + nqtail = This->queue_tail + len; + while (nqtail >= This->queue_len) nqtail -= This->queue_len; + } else { + TRACE("Telling application that %ld event(s) are in the queue.\n", len); + } } else { if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) { ERR("Wrong structure size !\n"); @@ -762,12 +770,19 @@ } if (len) - TRACE("Application retrieving %ld event(s).\n", len); + TRACE("Application retrieving %ld event(s):\n", len); *entries = 0; nqtail = This->queue_tail; while (len) { /* Copy the buffered data into the application queue */ + TRACE(" - queuing Offs:%2ld Data:%5ld TS:%8ld Seq:%8ld at address %p from queue tail %4d\n", + (This->data_queue)->dwOfs, + (This->data_queue)->dwData, + (This->data_queue)->dwTimeStamp, + (This->data_queue)->dwSequence, + (char *)dod + *entries * dodsize, + nqtail); memcpy((char *)dod + *entries * dodsize, This->data_queue + nqtail, dodsize); /* Advance position */ nqtail++; @@ -930,7 +945,7 @@ devcaps.dwSize = lpDIDevCaps->dwSize; devcaps.dwFlags = DIDC_ATTACHED; - if (This->dinput->version >= 8) + if (This->dinput->dwVersion >= 0x0800) devcaps.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8); else devcaps.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8); @@ -1056,7 +1071,7 @@ return DI_OK; } - fill_mouse_dideviceinstanceA(pdidi, This->dinput->version); + fill_mouse_dideviceinstanceA(pdidi, This->dinput->dwVersion); return DI_OK; } @@ -1071,7 +1086,7 @@ return DI_OK; } - fill_mouse_dideviceinstanceW(pdidi, This->dinput->version); + fill_mouse_dideviceinstanceW(pdidi, This->dinput->dwVersion); return DI_OK; } diff -urN wine-20050419/dlls/dinput/tests/.cvsignore wine-20050524/dlls/dinput/tests/.cvsignore --- wine-20050419/dlls/dinput/tests/.cvsignore 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/dinput/tests/.cvsignore 2005-05-11 14:05:17.000000000 +0200 @@ -0,0 +1,5 @@ +Makefile +joystick.ok +keyboard.ok +mouse.ok +testlist.c diff -urN wine-20050419/dlls/dinput/tests/Makefile.in wine-20050524/dlls/dinput/tests/Makefile.in --- wine-20050419/dlls/dinput/tests/Makefile.in 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/dinput/tests/Makefile.in 2005-05-11 14:05:17.000000000 +0200 @@ -0,0 +1,16 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +TESTDLL = dinput.dll +IMPORTS = dinput ole32 version user32 kernel32 +EXTRALIBS = -ldxguid -luuid -ldxerr8 + +CTESTS = \ + joystick.c \ + keyboard.c \ + mouse.c + +@MAKE_TEST_RULES@ + +### Dependencies: diff -urN wine-20050419/dlls/dinput/tests/dinput_test.h wine-20050524/dlls/dinput/tests/dinput_test.h --- wine-20050419/dlls/dinput/tests/dinput_test.h 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/dinput/tests/dinput_test.h 2005-05-11 14:05:17.000000000 +0200 @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2005 Robert Reif + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +extern HWND get_hwnd(); +extern const char * get_file_version(const char * file_name); diff -urN wine-20050419/dlls/dinput/tests/joystick.c wine-20050524/dlls/dinput/tests/joystick.c --- wine-20050419/dlls/dinput/tests/joystick.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/dinput/tests/joystick.c 2005-05-16 10:44:14.000000000 +0200 @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2004-2005 Robert Reif + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define STRICT +#define DIRECTINPUT_VERSION 0x0700 + +#define NONAMELESSSTRUCT +#define NONAMELESSUNION +#include + +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "wingdi.h" +#include "dinput.h" +#include "dxerr8.h" +#include "dinput_test.h" + +#define numObjects(x) (sizeof(x) / sizeof(x[0])) + +typedef struct tagUserData { + LPDIRECTINPUT pDI; + DWORD version; +} UserData; + +static const DIOBJECTDATAFORMAT dfDIJoystickTest[] = { + { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_Button,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, +}; + +static const DIDATAFORMAT c_dfDIJoystickTest = { + sizeof(DIDATAFORMAT), + sizeof(DIOBJECTDATAFORMAT), + DIDF_ABSAXIS, + sizeof(DIJOYSTATE2), + numObjects(dfDIJoystickTest), + (LPDIOBJECTDATAFORMAT)dfDIJoystickTest +}; + +HWND get_hwnd() +{ + HWND hwnd=GetForegroundWindow(); + if (!hwnd) + hwnd=GetDesktopWindow(); + return hwnd; +} + +typedef struct tagJoystickInfo +{ + LPDIRECTINPUTDEVICE pJoystick; + DWORD axis; + DWORD pov; + DWORD button; +} JoystickInfo; + +static BOOL CALLBACK EnumAxes( + const DIDEVICEOBJECTINSTANCE* pdidoi, + VOID* pContext) +{ + HRESULT hr; + JoystickInfo * info = (JoystickInfo *)pContext; + + if (IsEqualIID(&pdidoi->guidType, &GUID_XAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_YAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_ZAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_RxAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_RyAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_RzAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_Slider)) { + DIPROPRANGE diprg; + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprg.diph.dwHow = DIPH_BYID; + diprg.diph.dwObj = pdidoi->dwType; + diprg.lMin = -1000; + diprg.lMax = +1000; + + hr = IDirectInputDevice_SetProperty(info->pJoystick, DIPROP_RANGE, NULL); + ok(hr==E_INVALIDARG,"IDirectInputDevice_SetProperty() should have returned " + "E_INVALIDARG, returned: %s\n", DXGetErrorString8(hr)); + + hr = IDirectInputDevice_SetProperty(info->pJoystick, DIPROP_RANGE, &diprg.diph); + ok(hr==DI_OK,"IDirectInputDevice_SetProperty() failed: %s\n", DXGetErrorString8(hr)); + + info->axis++; + } else if (IsEqualIID(&pdidoi->guidType, &GUID_POV)) + info->pov++; + else if (IsEqualIID(&pdidoi->guidType, &GUID_Button)) + info->button++; + + return DIENUM_CONTINUE; +} + +static BOOL CALLBACK EnumJoysticks( + LPCDIDEVICEINSTANCE lpddi, + LPVOID pvRef) +{ + HRESULT hr; + UserData * data = (UserData *)pvRef; + LPDIRECTINPUTDEVICE pJoystick; + DIDATAFORMAT format; + DIDEVCAPS caps; + DIJOYSTATE2 js; + JoystickInfo info; + int i, count; + ULONG ref; + DIDEVICEINSTANCE inst; + DIDEVICEINSTANCE_DX3 inst3; + HWND hWnd = get_hwnd(); + + ok(data->version > 0x0300, "Joysticks not supported in version 0x%04lx\n", data->version); + + hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, NULL, NULL); + ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned " + "E_POINTER, returned: %s\n", DXGetErrorString8(hr)); + + hr = IDirectInput_CreateDevice(data->pDI, NULL, &pJoystick, NULL); + ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned " + "E_POINTER, returned: %s\n", DXGetErrorString8(hr)); + + hr = IDirectInput_CreateDevice(data->pDI, NULL, NULL, NULL); + ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned " + "E_POINTER, returned: %s\n", DXGetErrorString8(hr)); + + hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, + &pJoystick, NULL); + ok(hr==DI_OK,"IDirectInput_CreateDevice() failed: %s\n", + DXGetErrorString8(hr)); + if (hr!=DI_OK) + goto DONE; + + trace("---- %s ----\n", lpddi->tszProductName); + + hr = IDirectInputDevice_SetDataFormat(pJoystick, NULL); + ok(hr==E_POINTER,"IDirectInputDevice_SetDataFormat() should have returned " + "E_POINTER, returned: %s\n", DXGetErrorString8(hr)); + + ZeroMemory(&format, sizeof(format)); + hr = IDirectInputDevice_SetDataFormat(pJoystick, &format); + ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_SetDataFormat() should have " + "returned DIERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(hr)); + + /* try the default formats */ + hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystick); + ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %s\n", + DXGetErrorString8(hr)); + + hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystick2); + ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %s\n", + DXGetErrorString8(hr)); + + /* try an alternate format */ + hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystickTest); + ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %s\n", + DXGetErrorString8(hr)); + + hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystick2); + ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %s\n", + DXGetErrorString8(hr)); + if (hr != DI_OK) + goto RELEASE; + + hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, hWnd, + DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); + ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %s\n", + DXGetErrorString8(hr)); + + /* get capabilities */ + hr = IDirectInputDevice_GetCapabilities(pJoystick, NULL); + ok(hr==E_POINTER,"IDirectInputDevice_GetCapabilities() " + "should have returned E_POINTER, returned: %s\n", + DXGetErrorString8(hr)); + + ZeroMemory(&caps, sizeof(caps)); + hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps); + ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_GetCapabilities() " + "should have returned DIERR_INVALIDPARAM, returned: %s\n", + DXGetErrorString8(hr)); + + caps.dwSize = sizeof(caps); + hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps); + ok(hr==DI_OK,"IDirectInputDevice_GetCapabilities() failed: %s\n", + DXGetErrorString8(hr)); + + ZeroMemory(&info, sizeof(info)); + info.pJoystick = pJoystick; + + /* enumerate objects */ + hr = IDirectInputDevice_EnumObjects(pJoystick, EnumAxes, (VOID*)&info, DIDFT_ALL); + ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %s\n", + DXGetErrorString8(hr)); + + ok(caps.dwAxes == info.axis, "Number of enumerated axes doesn't match capabilities\n"); + ok(caps.dwButtons == info.button, "Number of enumerated buttons doesn't match capabilities\n"); + ok(caps.dwPOVs == info.pov, "Number of enumerated POVs doesn't match capabilities\n"); + + hr = IDirectInputDevice_GetDeviceInfo(pJoystick, 0); + ok(hr==E_POINTER, "IDirectInputDevice_GetDeviceInfo() " + "should have returned E_POINTER, returned: %s\n", + DXGetErrorString8(hr)); + + ZeroMemory(&inst, sizeof(inst)); + ZeroMemory(&inst3, sizeof(inst3)); + + hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst); + ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceInfo() " + "should have returned DIERR_INVALIDPARAM, returned: %s\n", + DXGetErrorString8(hr)); + + inst.dwSize = sizeof(inst); + hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst); + ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %s\n", + DXGetErrorString8(hr)); + + inst3.dwSize = sizeof(inst3); + hr = IDirectInputDevice_GetDeviceInfo(pJoystick, (LPDIDEVICEINSTANCE)&inst3); + ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %s\n", + DXGetErrorString8(hr)); + + hr = IDirectInputDevice_Acquire(pJoystick); + ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %s\n", + DXGetErrorString8(hr)); + if (hr != DI_OK) + goto RELEASE; + + if (winetest_interactive) { + trace("You have 30 seconds to test all axes, sliders, POVs and buttons\n"); + count = 300; + } else + count = 1; + + trace("\n"); + for (i = 0; i < count; i++) { + hr = IDirectInputDevice_GetDeviceState(pJoystick, sizeof(DIJOYSTATE2), &js); + ok(hr==DI_OK,"IDirectInputDevice_GetDeviceState() failed: %s\n", + DXGetErrorString8(hr)); + if (hr != DI_OK) + break; + trace("X%5ld Y%5ld Z%5ld Rx%5ld Ry%5ld Rz%5ld " + "S0%5ld S1%5ld POV0%5ld POV1%5ld POV2%5ld POV3%5ld " + "B %d %d %d %d %d %d %d %d %d %d %d %d\r", + js.lX, js.lY, js.lZ, js.lRx, js.lRy, js.lRz, + js.rglSlider[0], js.rglSlider[1], + js.rgdwPOV[0], js.rgdwPOV[1], js.rgdwPOV[2], js.rgdwPOV[3], + js.rgbButtons[0]>>7, js.rgbButtons[1]>>7, js.rgbButtons[2]>>7, + js.rgbButtons[3]>>7, js.rgbButtons[4]>>7, js.rgbButtons[5]>>7, + js.rgbButtons[6]>>7, js.rgbButtons[7]>>7, js.rgbButtons[8]>>7, + js.rgbButtons[9]>>7, js.rgbButtons[10]>>7, js.rgbButtons[11]>>7); + Sleep(100); + } + trace("\n"); + + hr = IDirectInputDevice_Unacquire(pJoystick); + ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %s\n", + DXGetErrorString8(hr)); + +RELEASE: + ref = IDirectInputDevice_Release(pJoystick); + ok(ref==0,"IDirectInputDevice_Release() reference count = %ld\n", ref); + +DONE: + return DIENUM_CONTINUE; +} + +static void joystick_tests(DWORD version) +{ + HRESULT hr; + LPDIRECTINPUT pDI; + ULONG ref; + HINSTANCE hInstance = GetModuleHandle(NULL); + + trace("-- Testing Direct Input Version 0x%04lx --\n", version); + hr = DirectInputCreate(hInstance, version, &pDI, NULL); + ok(hr==DI_OK||hr==DIERR_OLDDIRECTINPUTVERSION, + "DirectInputCreate() failed: %s\n", DXGetErrorString8(hr)); + if (hr==DI_OK && pDI!=0) { + UserData data; + data.pDI = pDI; + data.version = version; + hr = IDirectInput_EnumDevices(pDI, DIDEVTYPE_JOYSTICK, EnumJoysticks, + &data, DIEDFL_ALLDEVICES); + ok(hr==DI_OK,"IDirectInput_EnumDevices() failed: %s\n", + DXGetErrorString8(hr)); + ref = IDirectInput_Release(pDI); + ok(ref==0,"IDirectInput_Release() reference count = %ld\n", ref); + } else if (hr==DIERR_OLDDIRECTINPUTVERSION) + trace(" Version Not Supported\n"); +} + +START_TEST(joystick) +{ + CoInitialize(NULL); + + trace("DLL Version: %s\n", get_file_version("dinput.dll")); + + joystick_tests(0x0700); + joystick_tests(0x0500); + joystick_tests(0x0300); + + CoUninitialize(); +} diff -urN wine-20050419/dlls/dinput/tests/keyboard.c wine-20050524/dlls/dinput/tests/keyboard.c --- wine-20050419/dlls/dinput/tests/keyboard.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/dinput/tests/keyboard.c 2005-05-11 14:05:17.000000000 +0200 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2005 Robert Reif + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define STRICT +#define DIRECTINPUT_VERSION 0x0700 + +#define NONAMELESSSTRUCT +#define NONAMELESSUNION +#include + +#include +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "wingdi.h" +#include "dinput.h" +#include "dxerr8.h" +#include "dinput_test.h" + +const char * get_file_version(const char * file_name) +{ + static char version[32]; + DWORD size; + DWORD handle; + + size = GetFileVersionInfoSizeA(file_name, &handle); + if (size) { + char * data = HeapAlloc(GetProcessHeap(), 0, size); + if (data) { + if (GetFileVersionInfoA(file_name, handle, size, data)) { + VS_FIXEDFILEINFO *pFixedVersionInfo; + UINT len; + if (VerQueryValueA(data, "\\", (LPVOID *)&pFixedVersionInfo, &len)) { + sprintf(version, "%ld.%ld.%ld.%ld", + pFixedVersionInfo->dwFileVersionMS >> 16, + pFixedVersionInfo->dwFileVersionMS & 0xffff, + pFixedVersionInfo->dwFileVersionLS >> 16, + pFixedVersionInfo->dwFileVersionLS & 0xffff); + } else + sprintf(version, "not available"); + } else + sprintf(version, "failed"); + + HeapFree(GetProcessHeap(), 0, data); + } else + sprintf(version, "failed"); + } else + sprintf(version, "not available"); + + return version; +} + +static void keyboard_tests() +{ +} + +START_TEST(keyboard) +{ + CoInitialize(NULL); + + trace("DLL Version: %s\n", get_file_version("dinput.dll")); + + keyboard_tests(); + + CoUninitialize(); +} diff -urN wine-20050419/dlls/dinput/tests/mouse.c wine-20050524/dlls/dinput/tests/mouse.c --- wine-20050419/dlls/dinput/tests/mouse.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/dinput/tests/mouse.c 2005-05-11 14:05:17.000000000 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005 Robert Reif + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define STRICT +#define DIRECTINPUT_VERSION 0x0700 + +#define NONAMELESSSTRUCT +#define NONAMELESSUNION +#include + +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "wingdi.h" +#include "dinput.h" +#include "dxerr8.h" +#include "dinput_test.h" + +static void mouse_tests() +{ +} + +START_TEST(mouse) +{ + CoInitialize(NULL); + + trace("DLL Version: %s\n", get_file_version("dinput.dll")); + + mouse_tests(); + + CoUninitialize(); +} diff -urN wine-20050419/dlls/dinput8/.cvsignore wine-20050524/dlls/dinput8/.cvsignore --- wine-20050419/dlls/dinput8/.cvsignore 2004-05-13 01:17:33.000000000 +0200 +++ wine-20050524/dlls/dinput8/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dinput8.dll.dbg.c -dinput8.spec.def +libdinput8.def version.res diff -urN wine-20050419/dlls/dinput8/Makefile.in wine-20050524/dlls/dinput8/Makefile.in --- wine-20050419/dlls/dinput8/Makefile.in 2004-05-13 01:17:33.000000000 +0200 +++ wine-20050524/dlls/dinput8/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dinput8.dll +IMPORTLIB = libdinput8.$(IMPLIBEXT) IMPORTS = dinput EXTRALIBS = -luuid diff -urN wine-20050419/dlls/dmband/.cvsignore wine-20050524/dlls/dmband/.cvsignore --- wine-20050419/dlls/dmband/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmband/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmband.dll.dbg.c -dmband.spec.def +libdmband.def version.res diff -urN wine-20050419/dlls/dmband/Makefile.in wine-20050524/dlls/dmband/Makefile.in --- wine-20050419/dlls/dmband/Makefile.in 2004-05-14 06:57:02.000000000 +0200 +++ wine-20050524/dlls/dmband/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmband.dll +IMPORTLIB = libdmband.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmcompos/.cvsignore wine-20050524/dlls/dmcompos/.cvsignore --- wine-20050419/dlls/dmcompos/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmcompos/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmcompos.dll.dbg.c -dmcompos.spec.def +libdmcompos.def version.res diff -urN wine-20050419/dlls/dmcompos/Makefile.in wine-20050524/dlls/dmcompos/Makefile.in --- wine-20050419/dlls/dmcompos/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/dmcompos/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmcompos.dll +IMPORTLIB = libdmcompos.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmcompos/dmcompos.spec wine-20050524/dlls/dmcompos/dmcompos.spec --- wine-20050419/dlls/dmcompos/dmcompos.spec 2003-07-30 05:48:56.000000000 +0200 +++ wine-20050524/dlls/dmcompos/dmcompos.spec 2005-05-17 16:41:38.000000000 +0200 @@ -1,4 +1,4 @@ -@ stdcall -private DllCanUnloadNow() DMCOMPOS_DllCanUnloadNow -@ stdcall -private DllGetClassObject(long long ptr) DMCOMPOS_DllGetClassObject -@ stdcall -private DllRegisterServer() DMCOMPOS_DllRegisterServer -@ stdcall -private DllUnregisterServer() DMCOMPOS_DllUnregisterServer +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(long long ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff -urN wine-20050419/dlls/dmcompos/dmcompos_main.c wine-20050524/dlls/dmcompos/dmcompos_main.c --- wine-20050419/dlls/dmcompos/dmcompos_main.c 2004-12-09 14:46:47.000000000 +0100 +++ wine-20050524/dlls/dmcompos/dmcompos_main.c 2005-05-17 16:41:38.000000000 +0200 @@ -302,7 +302,7 @@ * * */ -HRESULT WINAPI DMCOMPOS_DllCanUnloadNow(void) { +HRESULT WINAPI DllCanUnloadNow(void) { return DMCOMPOS_refCount != 0 ? S_FALSE : S_OK; } @@ -312,7 +312,7 @@ * * */ -HRESULT WINAPI DMCOMPOS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { TRACE("(%s, %s, %p)\n", debugstr_dmguid(rclsid), debugstr_dmguid(riid), ppv); if (IsEqualCLSID (rclsid, &CLSID_DirectMusicChordMap) && IsEqualIID (riid, &IID_IClassFactory)) { *ppv = (LPVOID) &ChordMap_CF; diff -urN wine-20050419/dlls/dmcompos/regsvr.c wine-20050524/dlls/dmcompos/regsvr.c --- wine-20050419/dlls/dmcompos/regsvr.c 2004-01-20 01:21:42.000000000 +0100 +++ wine-20050524/dlls/dmcompos/regsvr.c 2005-05-17 16:41:38.000000000 +0200 @@ -531,7 +531,8 @@ /*********************************************************************** * DllRegisterServer (DMCOMPOS.3) */ -HRESULT WINAPI DMCOMPOS_DllRegisterServer(void) { +HRESULT WINAPI DllRegisterServer(void) +{ HRESULT hr; TRACE("\n"); @@ -545,7 +546,8 @@ /*********************************************************************** * DllUnregisterServer (DMCOMPOS.4) */ -HRESULT WINAPI DMCOMPOS_DllUnregisterServer(void) { +HRESULT WINAPI DllUnregisterServer(void) +{ HRESULT hr; TRACE("\n"); diff -urN wine-20050419/dlls/dmime/.cvsignore wine-20050524/dlls/dmime/.cvsignore --- wine-20050419/dlls/dmime/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmime/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmime.dll.dbg.c -dmime.spec.def +libdmime.def version.res diff -urN wine-20050419/dlls/dmime/Makefile.in wine-20050524/dlls/dmime/Makefile.in --- wine-20050419/dlls/dmime/Makefile.in 2004-05-14 06:57:02.000000000 +0200 +++ wine-20050524/dlls/dmime/Makefile.in 2005-05-09 16:42:35.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmime.dll +IMPORTLIB = libdmime.$(IMPLIBEXT) IMPORTS = dsound winmm ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmime/dmime.spec wine-20050524/dlls/dmime/dmime.spec --- wine-20050419/dlls/dmime/dmime.spec 2003-07-30 05:48:55.000000000 +0200 +++ wine-20050524/dlls/dmime/dmime.spec 2005-05-17 16:41:37.000000000 +0200 @@ -1,4 +1,4 @@ -@ stdcall -private DllCanUnloadNow() DMIME_DllCanUnloadNow -@ stdcall -private DllGetClassObject(long long ptr) DMIME_DllGetClassObject -@ stdcall -private DllRegisterServer() DMIME_DllRegisterServer -@ stdcall -private DllUnregisterServer() DMIME_DllUnregisterServer +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(long long ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff -urN wine-20050419/dlls/dmime/dmime_main.c wine-20050524/dlls/dmime/dmime_main.c --- wine-20050419/dlls/dmime/dmime_main.c 2005-02-02 10:31:07.000000000 +0100 +++ wine-20050524/dlls/dmime/dmime_main.c 2005-05-17 16:41:37.000000000 +0200 @@ -752,7 +752,8 @@ * * */ -HRESULT WINAPI DMIME_DllCanUnloadNow(void) { +HRESULT WINAPI DllCanUnloadNow(void) +{ return DMIME_refCount != 0 ? S_FALSE : S_OK; } @@ -762,7 +763,7 @@ * * */ -HRESULT WINAPI DMIME_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { TRACE("(%s, %s, %p)\n", debugstr_dmguid(rclsid), debugstr_dmguid(riid), ppv); if (IsEqualCLSID (rclsid, &CLSID_DirectMusicPerformance) && IsEqualIID (riid, &IID_IClassFactory)) { diff -urN wine-20050419/dlls/dmime/regsvr.c wine-20050524/dlls/dmime/regsvr.c --- wine-20050419/dlls/dmime/regsvr.c 2004-02-27 07:08:33.000000000 +0100 +++ wine-20050524/dlls/dmime/regsvr.c 2005-05-17 16:41:37.000000000 +0200 @@ -611,7 +611,7 @@ /*********************************************************************** * DllRegisterServer (DMIME.3) */ -HRESULT WINAPI DMIME_DllRegisterServer(void) { +HRESULT WINAPI DllRegisterServer(void) { HRESULT hr; TRACE("\n"); @@ -625,7 +625,7 @@ /*********************************************************************** * DllUnregisterServer (DMIME.4) */ -HRESULT WINAPI DMIME_DllUnregisterServer(void) { +HRESULT WINAPI DllUnregisterServer(void) { HRESULT hr; TRACE("\n"); diff -urN wine-20050419/dlls/dmloader/.cvsignore wine-20050524/dlls/dmloader/.cvsignore --- wine-20050419/dlls/dmloader/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmloader/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmloader.dll.dbg.c -dmloader.spec.def +libdmloader.def version.res diff -urN wine-20050419/dlls/dmloader/Makefile.in wine-20050524/dlls/dmloader/Makefile.in --- wine-20050419/dlls/dmloader/Makefile.in 2004-05-13 02:00:22.000000000 +0200 +++ wine-20050524/dlls/dmloader/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmloader.dll +IMPORTLIB = libdmloader.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmscript/.cvsignore wine-20050524/dlls/dmscript/.cvsignore --- wine-20050419/dlls/dmscript/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmscript/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmscript.dll.dbg.c -dmscript.spec.def +libdmscript.def version.res diff -urN wine-20050419/dlls/dmscript/Makefile.in wine-20050524/dlls/dmscript/Makefile.in --- wine-20050419/dlls/dmscript/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/dmscript/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmscript.dll +IMPORTLIB = libdmscript.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmstyle/.cvsignore wine-20050524/dlls/dmstyle/.cvsignore --- wine-20050419/dlls/dmstyle/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmstyle/.cvsignore 2005-05-07 14:39:57.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmstyle.dll.dbg.c -dmstyle.spec.def +libdmstyle.def version.res diff -urN wine-20050419/dlls/dmstyle/Makefile.in wine-20050524/dlls/dmstyle/Makefile.in --- wine-20050419/dlls/dmstyle/Makefile.in 2004-05-14 06:57:02.000000000 +0200 +++ wine-20050524/dlls/dmstyle/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmstyle.dll +IMPORTLIB = libdmstyle.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmstyle/dmstyle.spec wine-20050524/dlls/dmstyle/dmstyle.spec --- wine-20050419/dlls/dmstyle/dmstyle.spec 2003-07-30 05:48:55.000000000 +0200 +++ wine-20050524/dlls/dmstyle/dmstyle.spec 2005-05-17 16:41:37.000000000 +0200 @@ -1,4 +1,4 @@ -@ stdcall -private DllCanUnloadNow() DMSTYLE_DllCanUnloadNow -@ stdcall -private DllGetClassObject(long long ptr) DMSTYLE_DllGetClassObject -@ stdcall -private DllRegisterServer() DMSTYLE_DllRegisterServer -@ stdcall -private DllUnregisterServer() DMSTYLE_DllUnregisterServer +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(long long ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff -urN wine-20050419/dlls/dmstyle/dmstyle_main.c wine-20050524/dlls/dmstyle/dmstyle_main.c --- wine-20050419/dlls/dmstyle/dmstyle_main.c 2005-01-24 20:33:23.000000000 +0100 +++ wine-20050524/dlls/dmstyle/dmstyle_main.c 2005-05-17 16:41:37.000000000 +0200 @@ -452,7 +452,7 @@ * * */ -HRESULT WINAPI DMSTYLE_DllCanUnloadNow(void) { +HRESULT WINAPI DllCanUnloadNow(void) { return DMSTYLE_refCount != 0 ? S_FALSE : S_OK; } @@ -462,7 +462,7 @@ * * */ -HRESULT WINAPI DMSTYLE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { TRACE("(%s, %s, %p)\n", debugstr_dmguid(rclsid), debugstr_dmguid(riid), ppv); if (IsEqualCLSID (rclsid, &CLSID_DirectMusicSection) && IsEqualIID (riid, &IID_IClassFactory)) { diff -urN wine-20050419/dlls/dmstyle/regsvr.c wine-20050524/dlls/dmstyle/regsvr.c --- wine-20050419/dlls/dmstyle/regsvr.c 2004-02-27 07:08:33.000000000 +0100 +++ wine-20050524/dlls/dmstyle/regsvr.c 2005-05-17 16:41:37.000000000 +0200 @@ -563,7 +563,7 @@ /*********************************************************************** * DllRegisterServer (DMSTYLE.3) */ -HRESULT WINAPI DMSTYLE_DllRegisterServer() { +HRESULT WINAPI DllRegisterServer() { HRESULT hr; TRACE("\n"); @@ -577,7 +577,7 @@ /*********************************************************************** * DllUnregisterServer (DMSTYLE.4) */ -HRESULT WINAPI DMSTYLE_DllUnregisterServer() { +HRESULT WINAPI DllUnregisterServer() { HRESULT hr; TRACE("\n"); diff -urN wine-20050419/dlls/dmsynth/.cvsignore wine-20050524/dlls/dmsynth/.cvsignore --- wine-20050419/dlls/dmsynth/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmsynth/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmsynth.dll.dbg.c -dmsynth.spec.def +libdmsynth.def version.res diff -urN wine-20050419/dlls/dmsynth/Makefile.in wine-20050524/dlls/dmsynth/Makefile.in --- wine-20050419/dlls/dmsynth/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/dmsynth/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmsynth.dll +IMPORTLIB = libdmsynth.$(IMPLIBEXT) IMPORTS = winmm ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmusic/.cvsignore wine-20050524/dlls/dmusic/.cvsignore --- wine-20050419/dlls/dmusic/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmusic/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmusic.dll.dbg.c -dmusic.spec.def +libdmusic.def version.res diff -urN wine-20050419/dlls/dmusic/Makefile.in wine-20050524/dlls/dmusic/Makefile.in --- wine-20050419/dlls/dmusic/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/dmusic/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmusic.dll +IMPORTLIB = libdmusic.$(IMPLIBEXT) IMPORTS = winmm ole32 msacm32 dsound rpcrt4 user32 advapi32 kernel32 ntdll EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dmusic32/.cvsignore wine-20050524/dlls/dmusic32/.cvsignore --- wine-20050419/dlls/dmusic32/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dmusic32/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dmusic32.dll.dbg.c -dmusic32.spec.def +libdmusic32.def version.res diff -urN wine-20050419/dlls/dmusic32/Makefile.in wine-20050524/dlls/dmusic32/Makefile.in --- wine-20050419/dlls/dmusic32/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/dmusic32/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dmusic32.dll +IMPORTLIB = libdmusic32.$(IMPLIBEXT) IMPORTS = winmm user32 advapi32 kernel32 EXTRALIBS = -luuid diff -urN wine-20050419/dlls/dplay/.cvsignore wine-20050524/dlls/dplay/.cvsignore --- wine-20050419/dlls/dplay/.cvsignore 2004-05-21 22:54:48.000000000 +0200 +++ wine-20050524/dlls/dplay/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dplay.dll.dbg.c -dplay.spec.def +libdplay.def version.res diff -urN wine-20050419/dlls/dplay/Makefile.in wine-20050524/dlls/dplay/Makefile.in --- wine-20050419/dlls/dplay/Makefile.in 2004-05-21 22:54:48.000000000 +0200 +++ wine-20050524/dlls/dplay/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dplay.dll +IMPORTLIB = libdplay.$(IMPLIBEXT) IMPORTS = dplayx C_SRCS = dplay_main.c diff -urN wine-20050419/dlls/dplayx/.cvsignore wine-20050524/dlls/dplayx/.cvsignore --- wine-20050419/dlls/dplayx/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dplayx/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dplayx.dll.dbg.c -dplayx.spec.def +libdplayx.def version.res diff -urN wine-20050419/dlls/dplayx/Makefile.in wine-20050524/dlls/dplayx/Makefile.in --- wine-20050419/dlls/dplayx/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/dplayx/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dplayx.dll +IMPORTLIB = libdplayx.$(IMPLIBEXT) IMPORTS = winmm ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dplayx/dplay.c wine-20050524/dlls/dplayx/dplay.c --- wine-20050419/dlls/dplayx/dplay.c 2005-04-19 11:48:09.000000000 +0200 +++ wine-20050524/dlls/dplayx/dplay.c 2005-05-23 13:49:36.000000000 +0200 @@ -5155,8 +5155,7 @@ } /*************************************************************************** - * DirectPlayEnumerate [DPLAYX.9] - * DirectPlayEnumerateA [DPLAYX.2] + * DirectPlayEnumerateAW * * The pointer to the structure lpContext will be filled with the * appropriate data for each service offered by the OS. These services are @@ -5176,125 +5175,169 @@ * supply service providers to use specialized hardware, protocols, communications * media, and network resources. * - * TODO: Allocate string buffer space from the heap (length from reg) - * Pass real device driver numbers... - * Get the GUID properly... */ -HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback, - LPVOID lpContext ) +static HRESULT DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA, + LPDPENUMDPCALLBACKW lpEnumCallbackW, + LPVOID lpContext) { - - HKEY hkResult; - LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers"; - DWORD dwIndex; - DWORD sizeOfSubKeyName=50; - char subKeyName[51]; - FILETIME filetime; - - TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext ); - - if( !lpEnumCallback || !*lpEnumCallback ) - { - return DPERR_INVALIDPARAMS; - } - - /* Need to loop over the service providers in the registry */ - if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey, - 0, KEY_READ, &hkResult ) != ERROR_SUCCESS ) - { - /* Hmmm. Does this mean that there are no service providers? */ - ERR(": no service providers?\n"); - return DPERR_NOSERVICEPROVIDER; - } - - /* Traverse all the service providers we have available */ - for( dwIndex=0; - RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName, - NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS; - ++dwIndex, sizeOfSubKeyName=50 ) - { - LPCSTR majVerDataSubKey = "dwReserved1"; - LPCSTR minVerDataSubKey = "dwReserved2"; - LPCSTR guidDataSubKey = "Guid"; - HKEY hkServiceProvider; - GUID serviceProviderGUID; - DWORD returnTypeGUID, returnTypeReserved, sizeOfReturnBuffer = 50; - char returnBuffer[51]; - WCHAR buff[51]; - DWORD majVersionNum , minVersionNum = 0; - - TRACE(" this time through: %s\n", subKeyName ); - - /* Get a handle for this particular service provider */ - if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ, - &hkServiceProvider ) != ERROR_SUCCESS ) - { - ERR(": what the heck is going on?\n" ); - continue; - } - - /* Get the GUID, Device major number and device minor number - * from the registry. - */ - if( RegQueryValueExA( hkServiceProvider, guidDataSubKey, - NULL, &returnTypeGUID, returnBuffer, - &sizeOfReturnBuffer ) != ERROR_SUCCESS ) - { - ERR(": missing GUID registry data members\n" ); - continue; - } - - /* FIXME: Check return types to ensure we're interpreting data right */ - MultiByteToWideChar( CP_ACP, 0, returnBuffer, -1, buff, sizeof(buff)/sizeof(WCHAR) ); - CLSIDFromString( buff, &serviceProviderGUID ); - - /* FIXME: Need to know which of dwReserved1 and dwReserved2 are maj and min */ - - sizeOfReturnBuffer = 50; - if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey, - NULL, &returnTypeReserved, returnBuffer, - &sizeOfReturnBuffer ) != ERROR_SUCCESS ) + HKEY hkResult; + static const WCHAR searchSubKey[] = { + 'S', 'O', 'F', 'T', 'W', 'A', 'R', 'E', '\\', + 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '\\', + 'D', 'i', 'r', 'e', 'c', 't', 'P', 'l', 'a', 'y', '\\', + 'S', 'e', 'r', 'v', 'i', 'c', 'e', ' ', 'P', 'r', 'o', 'v', 'i', 'd', 'e', 'r', 's', 0 }; + static const WCHAR guidKey[] = { 'G', 'u', 'i', 'd', 0 }; + static const WCHAR descW[] = { 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 'W', 0 }; + + DWORD dwIndex; + FILETIME filetime; + + char *descriptionA = NULL; + DWORD max_sizeOfDescriptionA = 0; + WCHAR *descriptionW = NULL; + DWORD max_sizeOfDescriptionW = 0; + + if (!lpEnumCallbackA && !lpEnumCallbackW) { - ERR(": missing dwReserved1 registry data members\n") ; - continue; + return DPERR_INVALIDPARAMS; } - memcpy( &majVersionNum, returnBuffer, sizeof(majVersionNum) ); - - sizeOfReturnBuffer = 50; - if( RegQueryValueExA( hkServiceProvider, minVerDataSubKey, - NULL, &returnTypeReserved, returnBuffer, - &sizeOfReturnBuffer ) != ERROR_SUCCESS ) + + /* Need to loop over the service providers in the registry */ + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, searchSubKey, + 0, KEY_READ, &hkResult) != ERROR_SUCCESS) { - ERR(": missing dwReserved2 registry data members\n") ; - continue; + /* Hmmm. Does this mean that there are no service providers? */ + ERR(": no service provider key in the registry - check your Wine installation !!!\n"); + return DPERR_GENERIC; } - memcpy( &minVersionNum, returnBuffer, sizeof(minVersionNum) ); - - - /* The enumeration will return FALSE if we are not to continue */ - if( !lpEnumCallback( &serviceProviderGUID , subKeyName, - majVersionNum, minVersionNum, lpContext ) ) + + /* Traverse all the service providers we have available */ + dwIndex = 0; + while (1) { - WARN("lpEnumCallback returning FALSE\n" ); - break; - } + WCHAR subKeyName[255]; /* 255 is the maximum key size according to MSDN */ + DWORD sizeOfSubKeyName = sizeof(subKeyName) / sizeof(WCHAR); + HKEY hkServiceProvider; + GUID serviceProviderGUID; + WCHAR guidKeyContent[(2 * 16) + 1 + 6 /* This corresponds to '{....-..-..-..-......}' */ ]; + DWORD sizeOfGuidKeyContent = sizeof(guidKeyContent); + LONG ret_value; + + ret_value = RegEnumKeyExW(hkResult, dwIndex, subKeyName, &sizeOfSubKeyName, + NULL, NULL, NULL, &filetime); + if (ret_value == ERROR_NO_MORE_ITEMS) + break; + else if (ret_value != ERROR_SUCCESS) + { + ERR(": could not enumerate on service provider key.\n"); + return DPERR_EXCEPTION; + } + TRACE(" this time through sub-key %s.\n", debugstr_w(subKeyName)); + + /* Open the key for this service provider */ + if (RegOpenKeyExW(hkResult, subKeyName, 0, KEY_READ, &hkServiceProvider) != ERROR_SUCCESS) + { + ERR(": could not open registry key for service provider %s.\n", debugstr_w(subKeyName)); + continue; + } + + /* Get the GUID from the registry */ + if (RegQueryValueExW(hkServiceProvider, guidKey, + NULL, NULL, (LPBYTE) guidKeyContent, &sizeOfGuidKeyContent) != ERROR_SUCCESS) + { + ERR(": missing GUID registry data member for service provider %s.\n", debugstr_w(subKeyName)); + continue; + } + if (sizeOfGuidKeyContent != sizeof(guidKeyContent)) + { + ERR(": invalid format for the GUID registry data member for service provider %s (%s).\n", debugstr_w(subKeyName), debugstr_w(guidKeyContent)); + continue; + } + CLSIDFromString(guidKeyContent, &serviceProviderGUID ); + + /* The enumeration will return FALSE if we are not to continue. + * + * Note: on my windows box, major / minor version is 6 / 0 for all service providers + * and have no relations to any of the two dwReserved1 and dwReserved2 keys. + * I think that it simply means that they are in-line with DirectX 6.0 + */ + if (lpEnumCallbackA) + { + DWORD sizeOfDescription = 0; + + /* Note that this the the A case of this function, so use the A variant to get the description string */ + if (RegQueryValueExA(hkServiceProvider, "DescriptionA", + NULL, NULL, NULL, &sizeOfDescription) != ERROR_SUCCESS) + { + ERR(": missing 'DescriptionA' registry data member for service provider %s.\n", debugstr_w(subKeyName)); + continue; + } + if (sizeOfDescription > max_sizeOfDescriptionA) + { + HeapFree(GetProcessHeap(), 0, descriptionA); + max_sizeOfDescriptionA = sizeOfDescription; + descriptionA = HeapAlloc(GetProcessHeap(), 0, max_sizeOfDescriptionA); + } + descriptionA = HeapAlloc(GetProcessHeap(), 0, sizeOfDescription); + RegQueryValueExA(hkServiceProvider, "DescriptionA", + NULL, NULL, (LPBYTE) descriptionA, &sizeOfDescription); + + if (!lpEnumCallbackA(&serviceProviderGUID, descriptionA, 6, 0, lpContext)) + goto end; + } + else + { + DWORD sizeOfDescription = 0; + + if (RegQueryValueExW(hkServiceProvider, descW, + NULL, NULL, NULL, &sizeOfDescription) != ERROR_SUCCESS) + { + ERR(": missing 'DescriptionW' registry data member for service provider %s.\n", debugstr_w(subKeyName)); + continue; + } + if (sizeOfDescription > max_sizeOfDescriptionW) + { + HeapFree(GetProcessHeap(), 0, descriptionW); + max_sizeOfDescriptionW = sizeOfDescription; + descriptionW = HeapAlloc(GetProcessHeap(), 0, max_sizeOfDescriptionW); + } + descriptionW = HeapAlloc(GetProcessHeap(), 0, sizeOfDescription); + RegQueryValueExW(hkServiceProvider, descW, + NULL, NULL, (LPBYTE) descriptionW, &sizeOfDescription); + + if (!lpEnumCallbackW(&serviceProviderGUID, descriptionW, 6, 0, lpContext)) + goto end; + } + + dwIndex++; } - return DP_OK; + end: + HeapFree(GetProcessHeap(), 0, descriptionA); + HeapFree(GetProcessHeap(), 0, descriptionW); + + return DP_OK; +} +/*************************************************************************** + * DirectPlayEnumerate [DPLAYX.9] + * DirectPlayEnumerateA [DPLAYX.2] + */ +HRESULT WINAPI DirectPlayEnumerateA(LPDPENUMDPCALLBACKA lpEnumCallback, LPVOID lpContext ) +{ + TRACE("(%p,%p)\n", lpEnumCallback, lpContext); + + return DirectPlayEnumerateAW(lpEnumCallback, NULL, lpContext); } /*************************************************************************** * DirectPlayEnumerateW [DPLAYX.3] - * */ -HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext ) +HRESULT WINAPI DirectPlayEnumerateW(LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext ) { - - FIXME(":stub\n"); - - return DPERR_OUTOFMEMORY; - + TRACE("(%p,%p)\n", lpEnumCallback, lpContext); + + return DirectPlayEnumerateAW(NULL, lpEnumCallback, lpContext); } typedef struct tagCreateEnum diff -urN wine-20050419/dlls/dpnet/.cvsignore wine-20050524/dlls/dpnet/.cvsignore --- wine-20050419/dlls/dpnet/.cvsignore 2004-04-07 22:39:00.000000000 +0200 +++ wine-20050524/dlls/dpnet/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dpnet.dll.dbg.c -dpnet.spec.def +libdpnet.def version.res diff -urN wine-20050419/dlls/dpnet/Makefile.in wine-20050524/dlls/dpnet/Makefile.in --- wine-20050419/dlls/dpnet/Makefile.in 2004-04-07 22:39:00.000000000 +0200 +++ wine-20050524/dlls/dpnet/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dpnet.dll +IMPORTLIB = libdpnet.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dpnhpast/.cvsignore wine-20050524/dlls/dpnhpast/.cvsignore --- wine-20050419/dlls/dpnhpast/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dpnhpast/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dpnhpast.dll.dbg.c -dpnhpast.spec.def +libdpnhpast.def version.res diff -urN wine-20050419/dlls/dpnhpast/Makefile.in wine-20050524/dlls/dpnhpast/Makefile.in --- wine-20050419/dlls/dpnhpast/Makefile.in 2003-10-11 03:09:19.000000000 +0200 +++ wine-20050524/dlls/dpnhpast/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dpnhpast.dll +IMPORTLIB = libdpnhpast.$(IMPLIBEXT) IMPORTS = kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/dsound/.cvsignore wine-20050524/dlls/dsound/.cvsignore --- wine-20050419/dlls/dsound/.cvsignore 2004-03-24 04:36:49.000000000 +0100 +++ wine-20050524/dlls/dsound/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dsound.dll.dbg.c -dsound.spec.def +libdsound.def version.res diff -urN wine-20050419/dlls/dsound/Makefile.in wine-20050524/dlls/dsound/Makefile.in --- wine-20050419/dlls/dsound/Makefile.in 2004-07-04 02:13:45.000000000 +0200 +++ wine-20050524/dlls/dsound/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dsound.dll +IMPORTLIB = libdsound.$(IMPLIBEXT) IMPORTS = winmm ole32 user32 advapi32 kernel32 ntdll EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dsound/buffer.c wine-20050524/dlls/dsound/buffer.c --- wine-20050419/dlls/dsound/buffer.c 2005-02-16 17:09:03.000000000 +0100 +++ wine-20050524/dlls/dsound/buffer.c 2005-05-09 11:23:54.000000000 +0200 @@ -394,27 +394,15 @@ return ref; } -DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, - DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix) +DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD pwrite) { - DWORD bplay; - - TRACE("primary playpos=%ld, mixpos=%ld\n", pplay, pmix); - TRACE("this mixpos=%ld, time=%ld\n", bmix, GetTickCount()); + DWORD bplay = This->buf_mixpos; + DWORD pmix = This->primary_mixpos; + TRACE("(%p, pplay=%lu, pwrite=%lu)\n", This, pplay, pwrite); /* the actual primary play position (pplay) is always behind last mixed (pmix), * unless the computer is too slow or something */ /* we need to know how far away we are from there */ -#if 0 /* we'll never fill the primary entirely */ - if (pmix == pplay) { - if ((state == STATE_PLAYING) || (state == STATE_STOPPING)) { - /* wow, the software mixer is really doing well, - * seems the entire primary buffer is filled! */ - pmix += This->dsound->buflen; - } - /* else: the primary buffer is not playing, so probably empty */ - } -#endif if (pmix < pplay) pmix += This->dsound->buflen; /* wraparound */ pmix -= pplay; /* detect buffer underrun */ @@ -433,10 +421,9 @@ pmix *= This->pwfx->nBlockAlign; TRACE("this back-offset=%ld\n", pmix); /* subtract from our last mixed position */ - bplay = bmix; while (bplay < pmix) bplay += This->buflen; /* wraparound */ bplay -= pmix; - if (This->leadin && ((bplay < This->startpos) || (bplay > bmix))) { + if (This->leadin && ((bplay < This->startpos) || (bplay > This->buf_mixpos))) { /* seems we haven't started playing yet */ TRACE("this still in lead-in phase\n"); bplay = This->startpos; @@ -462,28 +449,17 @@ /* we haven't been merged into the primary buffer (yet) */ *playpos = This->buf_mixpos; } else if (playpos) { - DWORD pplay, pwrite, lplay, splay, pstate; + DWORD pplay, pwrite; /* let's get this exact; first, recursively call GetPosition on the primary */ EnterCriticalSection(&(This->dsound->mixlock)); if (DSOUND_PrimaryGetPosition(This->dsound, &pplay, &pwrite) != DS_OK) WARN("DSOUND_PrimaryGetPosition failed\n"); /* detect HEL mode underrun */ - pstate = This->dsound->state; - if (!(This->dsound->hwbuf || This->dsound->pwqueue)) { + if (!(This->dsound->hwbuf || This->dsound->pwqueue)) TRACE("detected an underrun\n"); - /* pplay = ? */ - if (pstate == STATE_PLAYING) - pstate = STATE_STARTING; - else if (pstate == STATE_STOPPING) - pstate = STATE_STOPPED; - } - /* get data for ourselves while we still have the lock */ - pstate &= This->state; - lplay = This->primary_mixpos; - splay = This->buf_mixpos; if ((This->dsbd.dwFlags & DSBCAPS_GETCURRENTPOSITION2) || This->dsound->hwbuf) { /* calculate play position using this */ - *playpos = DSOUND_CalcPlayPosition(This, pstate, pplay, pwrite, lplay, splay); + *playpos = DSOUND_CalcPlayPosition(This, pplay, pwrite); } else { /* (unless the app isn't using GETCURRENTPOSITION2) */ /* don't know exactly how this should be handled... @@ -493,7 +469,7 @@ DWORD wp; wp = (This->dsound->pwplay + ds_hel_margin) * This->dsound->fraglen; wp %= This->dsound->buflen; - *playpos = DSOUND_CalcPlayPosition(This, pstate, wp, pwrite, lplay, splay); + *playpos = DSOUND_CalcPlayPosition(This, wp, pwrite); } LeaveCriticalSection(&(This->dsound->mixlock)); } @@ -554,7 +530,7 @@ if (wfwritten) *wfwritten = size; } else { - WARN("invalid parameter: wfsize to small\n"); + WARN("invalid parameter: wfsize too small\n"); if (wfwritten) *wfwritten = 0; return DSERR_INVALIDPARAM; diff -urN wine-20050419/dlls/dsound/dsound.c wine-20050524/dlls/dsound/dsound.c --- wine-20050419/dlls/dsound/dsound.c 2005-03-15 16:40:36.000000000 +0100 +++ wine-20050524/dlls/dsound/dsound.c 2005-05-06 21:33:32.000000000 +0200 @@ -684,11 +684,107 @@ LPCGUID lpcGuid) { IDirectSoundImpl *This = (IDirectSoundImpl *)iface; + HRESULT hr = DS_OK; TRACE("(%p,%s)\n",This,debugstr_guid(lpcGuid)); - This->initialized = TRUE; + if (This->initialized == TRUE) { + WARN("already initialized\n"); + return DSERR_ALREADYINITIALIZED; + } - return DS_OK; + /* If the driver requests being opened through MMSYSTEM + * (which is recommended by the DDK), it is supposed to happen + * before the DirectSound interface is opened */ + if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) + { + DWORD flags = CALLBACK_FUNCTION; + + /* disable direct sound if requested */ + if (ds_hw_accel != DS_HW_ACCEL_EMULATION) + flags |= WAVE_DIRECTSOUND; + + hr = mmErr(waveOutOpen(&(This->hwo), + This->drvdesc.dnDevNode, This->pwfx, + (DWORD)DSOUND_callback, (DWORD)This, + flags)); + if (hr != DS_OK) { + WARN("waveOutOpen failed\n"); + return hr; + } + } + + if (This->driver) { + hr = IDsDriver_Open(This->driver); + if (hr != DS_OK) { + WARN("IDsDriver_Open failed\n"); + return hr; + } + + /* the driver is now open, so it's now allowed to call GetCaps */ + hr = IDsDriver_GetCaps(This->driver,&(This->drvcaps)); + if (hr != DS_OK) { + WARN("IDsDriver_GetCaps failed\n"); + return hr; + } + } else { + WAVEOUTCAPSA woc; + hr = mmErr(waveOutGetDevCapsA(This->drvdesc.dnDevNode, &woc, sizeof(woc))); + if (hr != DS_OK) { + WARN("waveOutGetDevCaps failed\n"); + return hr; + } + ZeroMemory(&This->drvcaps, sizeof(This->drvcaps)); + if ((woc.dwFormats & WAVE_FORMAT_1M08) || + (woc.dwFormats & WAVE_FORMAT_2M08) || + (woc.dwFormats & WAVE_FORMAT_4M08) || + (woc.dwFormats & WAVE_FORMAT_48M08) || + (woc.dwFormats & WAVE_FORMAT_96M08)) { + This->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT; + This->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO; + } + if ((woc.dwFormats & WAVE_FORMAT_1M16) || + (woc.dwFormats & WAVE_FORMAT_2M16) || + (woc.dwFormats & WAVE_FORMAT_4M16) || + (woc.dwFormats & WAVE_FORMAT_48M16) || + (woc.dwFormats & WAVE_FORMAT_96M16)) { + This->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT; + This->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO; + } + if ((woc.dwFormats & WAVE_FORMAT_1S08) || + (woc.dwFormats & WAVE_FORMAT_2S08) || + (woc.dwFormats & WAVE_FORMAT_4S08) || + (woc.dwFormats & WAVE_FORMAT_48S08) || + (woc.dwFormats & WAVE_FORMAT_96S08)) { + This->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT; + This->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO; + } + if ((woc.dwFormats & WAVE_FORMAT_1S16) || + (woc.dwFormats & WAVE_FORMAT_2S16) || + (woc.dwFormats & WAVE_FORMAT_4S16) || + (woc.dwFormats & WAVE_FORMAT_48S16) || + (woc.dwFormats & WAVE_FORMAT_96S16)) { + This->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT; + This->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO; + } + if (ds_emuldriver) + This->drvcaps.dwFlags |= DSCAPS_EMULDRIVER; + This->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN; + This->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX; + This->drvcaps.dwPrimaryBuffers = 1; + } + + hr = DSOUND_PrimaryCreate((IDirectSoundImpl*)This); + if (hr == DS_OK) { + This->initialized = TRUE; + DSOUND_renderer = (IDirectSoundImpl*)This; + timeBeginPeriod(DS_TIME_RES); + DSOUND_renderer->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer, + (DWORD)DSOUND_renderer, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); + } else { + WARN("DSOUND_PrimaryCreate failed\n"); + } + + return hr; } static HRESULT WINAPI IDirectSoundImpl_VerifyCertification( @@ -841,11 +937,11 @@ return DSERR_OUTOFMEMORY; } - pDS->pwfx->wFormatTag = WAVE_FORMAT_PCM; /* We rely on the sound driver to return the actual sound format of * the device if it does not support 22050x8x2 and is given the * WAVE_DIRECTSOUND flag. */ + pDS->pwfx->wFormatTag = WAVE_FORMAT_PCM; pDS->pwfx->nSamplesPerSec = 22050; pDS->pwfx->wBitsPerSample = 8; pDS->pwfx->nChannels = 2; @@ -853,95 +949,6 @@ pDS->pwfx->nAvgBytesPerSec = pDS->pwfx->nSamplesPerSec * pDS->pwfx->nBlockAlign; pDS->pwfx->cbSize = 0; - /* If the driver requests being opened through MMSYSTEM - * (which is recommended by the DDK), it is supposed to happen - * before the DirectSound interface is opened */ - if (pDS->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) - { - DWORD flags = CALLBACK_FUNCTION; - - /* disable direct sound if requested */ - if (ds_hw_accel != DS_HW_ACCEL_EMULATION) - flags |= WAVE_DIRECTSOUND; - - err = mmErr(waveOutOpen(&(pDS->hwo), - pDS->drvdesc.dnDevNode, pDS->pwfx, - (DWORD)DSOUND_callback, (DWORD)pDS, - flags)); - if (err != DS_OK) { - WARN("waveOutOpen failed\n"); - HeapFree(GetProcessHeap(),0,pDS); - *ppDS = NULL; - return err; - } - } - - if (drv) { - err = IDsDriver_Open(drv); - if (err != DS_OK) { - WARN("IDsDriver_Open failed\n"); - HeapFree(GetProcessHeap(),0,pDS); - *ppDS = NULL; - return err; - } - - /* the driver is now open, so it's now allowed to call GetCaps */ - err = IDsDriver_GetCaps(drv,&(pDS->drvcaps)); - if (err != DS_OK) { - WARN("IDsDriver_GetCaps failed\n"); - HeapFree(GetProcessHeap(),0,pDS); - *ppDS = NULL; - return err; - } - } else { - WAVEOUTCAPSA woc; - err = mmErr(waveOutGetDevCapsA(pDS->drvdesc.dnDevNode, &woc, sizeof(woc))); - if (err != DS_OK) { - WARN("waveOutGetDevCaps failed\n"); - HeapFree(GetProcessHeap(),0,pDS); - *ppDS = NULL; - return err; - } - ZeroMemory(&pDS->drvcaps, sizeof(pDS->drvcaps)); - if ((woc.dwFormats & WAVE_FORMAT_1M08) || - (woc.dwFormats & WAVE_FORMAT_2M08) || - (woc.dwFormats & WAVE_FORMAT_4M08) || - (woc.dwFormats & WAVE_FORMAT_48M08) || - (woc.dwFormats & WAVE_FORMAT_96M08)) { - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT; - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO; - } - if ((woc.dwFormats & WAVE_FORMAT_1M16) || - (woc.dwFormats & WAVE_FORMAT_2M16) || - (woc.dwFormats & WAVE_FORMAT_4M16) || - (woc.dwFormats & WAVE_FORMAT_48M16) || - (woc.dwFormats & WAVE_FORMAT_96M16)) { - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT; - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO; - } - if ((woc.dwFormats & WAVE_FORMAT_1S08) || - (woc.dwFormats & WAVE_FORMAT_2S08) || - (woc.dwFormats & WAVE_FORMAT_4S08) || - (woc.dwFormats & WAVE_FORMAT_48S08) || - (woc.dwFormats & WAVE_FORMAT_96S08)) { - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT; - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO; - } - if ((woc.dwFormats & WAVE_FORMAT_1S16) || - (woc.dwFormats & WAVE_FORMAT_2S16) || - (woc.dwFormats & WAVE_FORMAT_4S16) || - (woc.dwFormats & WAVE_FORMAT_48S16) || - (woc.dwFormats & WAVE_FORMAT_96S16)) { - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT; - pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO; - } - if (ds_emuldriver) - pDS->drvcaps.dwFlags |= DSCAPS_EMULDRIVER; - pDS->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN; - pDS->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX; - pDS->drvcaps.dwPrimaryBuffers = 1; - } - InitializeCriticalSection(&(pDS->mixlock)); pDS->mixlock.DebugInfo->Spare[1] = (DWORD)"DSOUND_mixlock"; @@ -1610,16 +1617,6 @@ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter); - if (pUnkOuter != NULL) { - WARN("invalid parameter: pUnkOuter != NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (ppDS == NULL) { - WARN("invalid parameter: ppDS == NULL\n"); - return DSERR_INVALIDPARAM; - } - /* Get dsound configuration */ setup_dsound_options(); @@ -1649,22 +1646,11 @@ LPDIRECTSOUND8 pDS; hr = IDirectSoundImpl_Create(&devGuid, &pDS); if (hr == DS_OK) { - hr = DSOUND_PrimaryCreate((IDirectSoundImpl*)pDS); - if (hr == DS_OK) { - hr = IDirectSound_IDirectSound_Create(pDS, ppDS); - if (*ppDS) { - IDirectSound_IDirectSound_AddRef(*ppDS); - - DSOUND_renderer = (IDirectSoundImpl*)pDS; - timeBeginPeriod(DS_TIME_RES); - DSOUND_renderer->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer, - (DWORD)DSOUND_renderer, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); - } else { - WARN("IDirectSound_IDirectSound_Create failed\n"); - IDirectSound8_Release(pDS); - } - } else { - WARN("DSOUND_PrimaryCreate failed\n"); + hr = IDirectSound_IDirectSound_Create(pDS, ppDS); + if (*ppDS) + IDirectSound_IDirectSound_AddRef(*ppDS); + else { + WARN("IDirectSound_IDirectSound_Create failed\n"); IDirectSound8_Release(pDS); } } else @@ -1695,12 +1681,33 @@ IUnknown *pUnkOuter) { HRESULT hr; + LPDIRECTSOUND pDS; TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter); - hr = DSOUND_Create(lpcGUID, ppDS, pUnkOuter); - if (hr == DS_OK) - IDirectSound_Initialize(*ppDS, lpcGUID); + if (ppDS == NULL) { + WARN("invalid parameter: ppDS == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (pUnkOuter != NULL) { + WARN("invalid parameter: pUnkOuter != NULL\n"); + *ppDS = 0; + return DSERR_INVALIDPARAM; + } + + hr = DSOUND_Create(lpcGUID, &pDS, pUnkOuter); + if (hr == DS_OK) { + IDirectSound_IDirectSound * pp = (IDirectSound_IDirectSound *)pDS; + IDirectSoundImpl * p = (IDirectSoundImpl *)(pp->pds); + if (!(p->initialized)) { + hr = IDirectSound_Initialize(pDS, lpcGUID); + if (hr != DS_OK) + IDirectSound_Release(pDS); + } + } + + *ppDS = pDS; return hr; } @@ -1715,16 +1722,6 @@ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter); - if (pUnkOuter != NULL) { - WARN("invalid parameter: pUnkOuter != NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (ppDS == NULL) { - WARN("invalid parameter: ppDS == NULL\n"); - return DSERR_INVALIDPARAM; - } - /* Get dsound configuration */ setup_dsound_options(); @@ -1754,22 +1751,11 @@ LPDIRECTSOUND8 pDS; hr = IDirectSoundImpl_Create(&devGuid, &pDS); if (hr == DS_OK) { - hr = DSOUND_PrimaryCreate((IDirectSoundImpl*)pDS); - if (hr == DS_OK) { - hr = IDirectSound8_IDirectSound8_Create(pDS, ppDS); - if (*ppDS) { - IDirectSound8_IDirectSound8_AddRef(*ppDS); - - DSOUND_renderer = (IDirectSoundImpl*)pDS; - timeBeginPeriod(DS_TIME_RES); - DSOUND_renderer->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer, - (DWORD)DSOUND_renderer, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); - } else { - WARN("IDirectSound8_IDirectSound8_Create failed\n"); - IDirectSound8_Release(pDS); - } - } else { - WARN("DSOUND_PrimaryCreate failed\n"); + hr = IDirectSound8_IDirectSound8_Create(pDS, ppDS); + if (*ppDS) + IDirectSound8_IDirectSound8_AddRef(*ppDS); + else { + WARN("IDirectSound8_IDirectSound8_Create failed\n"); IDirectSound8_Release(pDS); } } else @@ -1800,12 +1786,33 @@ IUnknown *pUnkOuter) { HRESULT hr; + LPDIRECTSOUND8 pDS; TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter); - hr = DSOUND_Create8(lpcGUID, ppDS, pUnkOuter); - if (hr == DS_OK) - IDirectSound8_Initialize(*ppDS, lpcGUID); + if (ppDS == NULL) { + WARN("invalid parameter: ppDS == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (pUnkOuter != NULL) { + WARN("invalid parameter: pUnkOuter != NULL\n"); + *ppDS = 0; + return DSERR_INVALIDPARAM; + } + + hr = DSOUND_Create8(lpcGUID, &pDS, pUnkOuter); + if (hr == DS_OK) { + IDirectSound8_IDirectSound8 * pp = (IDirectSound8_IDirectSound8 *)pDS; + IDirectSoundImpl * p = (IDirectSoundImpl *)(pp->pds); + if (!(p->initialized)) { + hr = IDirectSound8_Initialize(pDS, lpcGUID); + if (hr != DS_OK) + IDirectSound8_Release(pDS); + } + } + + *ppDS = pDS; return hr; } diff -urN wine-20050419/dlls/dsound/dsound.spec wine-20050524/dlls/dsound/dsound.spec --- wine-20050419/dlls/dsound/dsound.spec 2004-07-04 02:13:45.000000000 +0200 +++ wine-20050524/dlls/dsound/dsound.spec 2005-05-17 16:41:37.000000000 +0200 @@ -1,8 +1,6 @@ 1 stdcall DirectSoundCreate(ptr ptr ptr) 2 stdcall DirectSoundEnumerateA(ptr ptr) 3 stdcall DirectSoundEnumerateW(ptr ptr) -4 stdcall -private DllCanUnloadNow() DSOUND_DllCanUnloadNow -5 stdcall -private DllGetClassObject(ptr ptr ptr) DSOUND_DllGetClassObject 6 stdcall DirectSoundCaptureCreate(ptr ptr ptr) DirectSoundCaptureCreate8 7 stdcall DirectSoundCaptureEnumerateA(ptr ptr) 8 stdcall DirectSoundCaptureEnumerateW(ptr ptr) @@ -10,5 +8,7 @@ 10 stdcall DirectSoundFullDuplexCreate(ptr ptr ptr ptr long long ptr ptr ptr ptr) 11 stdcall DirectSoundCreate8(ptr ptr ptr) 12 stdcall DirectSoundCaptureCreate8(ptr ptr ptr) -@ stdcall -private DllRegisterServer() DSOUND_DllRegisterServer -@ stdcall -private DllUnregisterServer() DSOUND_DllUnregisterServer +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff -urN wine-20050419/dlls/dsound/dsound_main.c wine-20050524/dlls/dsound/dsound_main.c --- wine-20050419/dlls/dsound/dsound_main.c 2005-03-28 16:17:52.000000000 +0200 +++ wine-20050524/dlls/dsound/dsound_main.c 2005-05-17 16:41:37.000000000 +0200 @@ -570,7 +570,7 @@ * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, * E_UNEXPECTED */ -DWORD WINAPI DSOUND_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv) +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); @@ -640,7 +640,7 @@ * Success: S_OK * Failure: S_FALSE */ -DWORD WINAPI DSOUND_DllCanUnloadNow(void) +HRESULT WINAPI DllCanUnloadNow(void) { FIXME("(void): stub\n"); return S_FALSE; diff -urN wine-20050419/dlls/dsound/dsound_private.h wine-20050524/dlls/dsound/dsound_private.h --- wine-20050419/dlls/dsound/dsound_private.h 2005-03-15 16:40:36.000000000 +0100 +++ wine-20050524/dlls/dsound/dsound_private.h 2005-05-09 11:23:54.000000000 +0200 @@ -469,8 +469,7 @@ /* buffer.c */ -DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, - DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix); +DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD pwrite); /* mixer.c */ diff -urN wine-20050419/dlls/dsound/mixer.c wine-20050524/dlls/dsound/mixer.c --- wine-20050419/dlls/dsound/mixer.c 2005-03-19 18:09:33.000000000 +0100 +++ wine-20050524/dlls/dsound/mixer.c 2005-05-09 11:23:54.000000000 +0200 @@ -657,13 +657,8 @@ { TRACE("(%p)\n",dsb); EnterCriticalSection(&dsb->lock); - if (dsb->state == STATE_PLAYING) { -#if 0 /* this may not be quite reliable yet */ - dsb->need_remix = TRUE; -#else + if (dsb->state == STATE_PLAYING) dsb->dsound->need_remix = TRUE; -#endif - } LeaveCriticalSection(&dsb->lock); } @@ -671,8 +666,7 @@ { DWORD len, slen; /* determine this buffer's write position */ - DWORD buf_writepos = DSOUND_CalcPlayPosition(dsb, dsb->state & dsb->dsound->state, writepos, - writepos, dsb->primary_mixpos, dsb->buf_mixpos); + DWORD buf_writepos = DSOUND_CalcPlayPosition(dsb, writepos, writepos); /* determine how much already-mixed data exists */ DWORD buf_done = ((dsb->buf_mixpos < buf_writepos) ? dsb->buflen : 0) + @@ -805,6 +799,7 @@ dsb->last_playpos = 0; dsb->buf_mixpos = 0; dsb->leadin = FALSE; + dsb->need_remix = FALSE; DSOUND_CheckEvent(dsb, buf_left); } diff -urN wine-20050419/dlls/dsound/primary.c wine-20050524/dlls/dsound/primary.c --- wine-20050419/dlls/dsound/primary.c 2005-04-11 15:00:00.000000000 +0200 +++ wine-20050524/dlls/dsound/primary.c 2005-05-06 17:44:32.000000000 +0200 @@ -649,7 +649,7 @@ if (wfwritten) *wfwritten = size; } else { - WARN("invalid parameter: wfsize to small\n"); + WARN("invalid parameter: wfsize too small\n"); if (wfwritten) *wfwritten = 0; return DSERR_INVALIDPARAM; diff -urN wine-20050419/dlls/dsound/propset.c wine-20050524/dlls/dsound/propset.c --- wine-20050419/dlls/dsound/propset.c 2005-04-13 16:39:49.000000000 +0200 +++ wine-20050524/dlls/dsound/propset.c 2005-05-04 11:46:41.000000000 +0200 @@ -1063,6 +1063,7 @@ for (wod = 0; wod < devs; ++wod) { err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0)); if (err == DS_OK) { + PIDSCDRIVER drv; ZeroMemory(&data, sizeof(data)); data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; data.WaveDeviceId = wod; @@ -1073,6 +1074,13 @@ MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW) ); MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW) ); + data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; + err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0)); + if (err == DS_OK && drv) + data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; + else + WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); + TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); (ppd->Callback)(&data, ppd->Context); } @@ -1082,16 +1090,24 @@ for (wid = 0; wid < devs; ++wid) { err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0)); if (err == DS_OK) { + PIDSCDRIVER drv; ZeroMemory(&data, sizeof(data)); - data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - data.WaveDeviceId = wod; - data.DeviceId = DSOUND_renderer_guids[wod]; + data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; + data.WaveDeviceId = wid; + data.DeviceId = DSOUND_capture_guids[wid]; lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA)); lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA)); MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW) ); MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW) ); + data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; + err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0)); + if (err == DS_OK && drv) + data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; + else + WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); + TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); (ppd->Callback)(&data, ppd->Context); } @@ -1143,6 +1159,7 @@ if (err == DS_OK) { CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR)); if (szInterface) { + PIDSCDRIVER drv; ZeroMemory(&data, sizeof(data)); data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; data.WaveDeviceId = wod; @@ -1152,6 +1169,13 @@ WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL ); data.Interface = szInterface; + data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; + err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0)); + if (err == DS_OK && drv) + data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; + else + WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); + TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); (ppd->Callback)(&data, ppd->Context); } @@ -1176,6 +1200,7 @@ if (err == DS_OK) { CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR)); if (szInterface) { + PIDSCDRIVER drv; ZeroMemory(&data, sizeof(data)); data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; data.WaveDeviceId = wid; @@ -1185,6 +1210,13 @@ WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL ); data.Interface = szInterface; + data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; + err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0)); + if (err == DS_OK && drv) + data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; + else + WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); + TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); (ppd->Callback)(&data, ppd->Context); } @@ -1243,6 +1275,7 @@ if (wInterface) { err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size)); if (err == DS_OK) { + PIDSCDRIVER drv; ZeroMemory(&data, sizeof(data)); data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; data.WaveDeviceId = wod; @@ -1255,6 +1288,13 @@ data.Module = wModule; data.Interface = wInterface; + data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; + err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0)); + if (err == DS_OK && drv) + data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; + else + WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); + TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); (ppd->Callback)(&data, ppd->Context); } @@ -1279,8 +1319,9 @@ if (err == DS_OK) { WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size); if (wInterface) { - err = mmErr(waveInMessage((HWAVEIN)wod, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size)); + err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size)); if (err == DS_OK) { + PIDSCDRIVER drv; ZeroMemory(&data, sizeof(data)); data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; data.WaveDeviceId = wid; @@ -1292,6 +1333,13 @@ data.Description = wDescription; data.Module = wModule; data.Interface = wInterface; + data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; + err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0)); + if (err == DS_OK && drv) + data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; + else + WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); + TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); (ppd->Callback)(&data, ppd->Context); } diff -urN wine-20050419/dlls/dsound/regsvr.c wine-20050524/dlls/dsound/regsvr.c --- wine-20050419/dlls/dsound/regsvr.c 2005-01-24 14:31:27.000000000 +0100 +++ wine-20050524/dlls/dsound/regsvr.c 2005-05-17 16:41:37.000000000 +0200 @@ -555,7 +555,7 @@ /*********************************************************************** * DllRegisterServer (DSOUND.@) */ -HRESULT WINAPI DSOUND_DllRegisterServer(void) +HRESULT WINAPI DllRegisterServer(void) { HRESULT hr; @@ -570,7 +570,7 @@ /*********************************************************************** * DllUnregisterServer (DSOUND.@) */ -HRESULT WINAPI DSOUND_DllUnregisterServer(void) +HRESULT WINAPI DllUnregisterServer(void) { HRESULT hr; diff -urN wine-20050419/dlls/dsound/tests/dsound.c wine-20050524/dlls/dsound/tests/dsound.c --- wine-20050419/dlls/dsound/tests/dsound.c 2005-03-30 12:21:44.000000000 +0200 +++ wine-20050524/dlls/dsound/tests/dsound.c 2005-05-06 21:33:32.000000000 +0200 @@ -93,16 +93,21 @@ "IDirectSound_Initialize() failed: %s\n",DXGetErrorString8(rc)); if (rc==DSERR_NODRIVER) { trace(" No Driver\n"); - return; + goto EXIT; } else if (rc==E_FAIL) { trace(" No Device\n"); - return; + goto EXIT; } else if (rc==DSERR_ALLOCATED) { trace(" Already In Use\n"); - return; + goto EXIT; } } + rc=IDirectSound_Initialize(dso,lpGuid); + ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound_Initialize() " + "should have returned DSERR_ALREADYINITIALIZED: %s\n", + DXGetErrorString8(rc)); + /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSound_GetCaps(dso,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps(NULL) " @@ -158,6 +163,7 @@ speaker_config,new_speaker_config); } +EXIT: ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); } @@ -238,6 +244,8 @@ rc=DirectSoundCreate(&DSDEVID_DefaultVoiceCapture,&dso,NULL); ok(rc==DSERR_NODRIVER,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) " "should have failed: %s\n",DXGetErrorString8(rc)); + if (rc==DS_OK && dso) + IDirectSound_Release(dso); } static HRESULT test_dsound(LPGUID lpGuid) diff -urN wine-20050419/dlls/dsound/tests/dsound8.c wine-20050524/dlls/dsound/tests/dsound8.c --- wine-20050419/dlls/dsound/tests/dsound8.c 2005-04-11 14:52:00.000000000 +0200 +++ wine-20050524/dlls/dsound/tests/dsound8.c 2005-05-06 21:33:32.000000000 +0200 @@ -108,16 +108,21 @@ "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc)); if (rc==DSERR_NODRIVER) { trace(" No Driver\n"); - return; + goto EXIT; } else if (rc==E_FAIL) { trace(" No Device\n"); - return; + goto EXIT; } else if (rc==DSERR_ALLOCATED) { trace(" Already In Use\n"); - return; + goto EXIT; } } + rc=IDirectSound8_Initialize(dso,lpGuid); + ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound8_Initialize() " + "should have returned DSERR_ALREADYINITIALIZED: %s\n", + DXGetErrorString8(rc)); + /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSound8_GetCaps(dso,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() " @@ -177,6 +182,7 @@ ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n", DXGetErrorString8(rc)); +EXIT: ref=IDirectSound8_Release(dso); ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); } diff -urN wine-20050419/dlls/dswave/.cvsignore wine-20050524/dlls/dswave/.cvsignore --- wine-20050419/dlls/dswave/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/dswave/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dswave.dll.dbg.c -dswave.spec.def +libdswave.def version.res diff -urN wine-20050419/dlls/dswave/Makefile.in wine-20050524/dlls/dswave/Makefile.in --- wine-20050419/dlls/dswave/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/dswave/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dswave.dll +IMPORTLIB = libdswave.$(IMPLIBEXT) IMPORTS = msacm32 ole32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/dxdiagn/.cvsignore wine-20050524/dlls/dxdiagn/.cvsignore --- wine-20050419/dlls/dxdiagn/.cvsignore 2004-04-16 02:26:14.000000000 +0200 +++ wine-20050524/dlls/dxdiagn/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile dxdiagn.dll.dbg.c -dxdiagn.spec.def +libdxdiagn.def version.res diff -urN wine-20050419/dlls/dxdiagn/Makefile.in wine-20050524/dlls/dxdiagn/Makefile.in --- wine-20050419/dlls/dxdiagn/Makefile.in 2005-01-27 11:42:00.000000000 +0100 +++ wine-20050524/dlls/dxdiagn/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dxdiagn.dll +IMPORTLIB = libdxdiagn.$(IMPLIBEXT) IMPORTS = ole32 oleaut32 user32 advapi32 kernel32 EXTRALIBS = -ldxguid -luuid diff -urN wine-20050419/dlls/gdi/.cvsignore wine-20050524/dlls/gdi/.cvsignore --- wine-20050419/dlls/gdi/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/gdi/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -2,7 +2,7 @@ dispdib.spec.c gdi.exe.spec.c gdi32.dll.dbg.c -gdi32.spec.def +libgdi32.def version.res version16.res wing.spec.c diff -urN wine-20050419/dlls/gdi/Makefile.in wine-20050524/dlls/gdi/Makefile.in --- wine-20050419/dlls/gdi/Makefile.in 2005-03-08 17:55:26.000000000 +0100 +++ wine-20050524/dlls/gdi/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = gdi32.dll +IMPORTLIB = libgdi32.$(IMPLIBEXT) IMPORTS = advapi32 kernel32 ntdll EXTRAINCL = @FREETYPEINCL@ EXTRALIBS = $(LIBUNICODE) @ICULIBS@ diff -urN wine-20050419/dlls/gdi/bitblt.c wine-20050524/dlls/gdi/bitblt.c --- wine-20050419/dlls/gdi/bitblt.c 2004-08-11 20:51:10.000000000 +0200 +++ wine-20050524/dlls/gdi/bitblt.c 2005-05-06 17:44:32.000000000 +0200 @@ -295,7 +295,7 @@ /* delete all temp objects */ DeleteObject(hBitmap1); - DeleteObject(hBitmap1); + DeleteObject(hBitmap2); DeleteObject(hbrMask); DeleteDC(hDC1); @@ -323,7 +323,7 @@ int oldStretchMode; if(widthDest < 0 || heightDest < 0 || widthSrc < 0 || heightSrc < 0) { - TRACE("Can not mirror\n"); + TRACE("Cannot mirror\n"); return FALSE; } diff -urN wine-20050419/dlls/gdi/dc.c wine-20050524/dlls/gdi/dc.c --- wine-20050419/dlls/gdi/dc.c 2005-04-14 15:57:55.000000000 +0200 +++ wine-20050524/dlls/gdi/dc.c 2005-04-25 18:02:27.000000000 +0200 @@ -38,6 +38,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dc); +static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 }; + static BOOL DC_DeleteObject( HGDIOBJ handle, void *obj ); static const struct gdi_obj_funcs dc_funcs = @@ -670,8 +672,13 @@ if (output) RtlCreateUnicodeStringFromAsciiz(&outputW, output); else outputW.Buffer = NULL; - if (initData) initDataW = GdiConvertToDevmodeW(initData); - else initDataW = NULL; + initDataW = NULL; + if (initData) + { + /* don't convert initData for DISPLAY driver, it's not used */ + if (!driverW.Buffer || strcmpiW( driverW.Buffer, displayW )) + initDataW = GdiConvertToDevmodeW(initData); + } ret = CreateDCW( driverW.Buffer, deviceW.Buffer, outputW.Buffer, initDataW ); @@ -725,7 +732,6 @@ } else { - static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 }; funcs = DRIVER_load_driver( displayW ); physDev = NULL; } diff -urN wine-20050419/dlls/gdi/driver.c wine-20050524/dlls/gdi/driver.c --- wine-20050419/dlls/gdi/driver.c 2004-12-23 19:41:06.000000000 +0100 +++ wine-20050524/dlls/gdi/driver.c 2005-05-06 21:38:50.000000000 +0200 @@ -24,6 +24,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" #include "winreg.h" @@ -210,7 +211,7 @@ */ static struct graphics_driver *load_display_driver(void) { - char buffer[MAX_PATH], *name, *next; + char buffer[MAX_PATH], libname[32], *name, *next; HMODULE module = 0; HKEY hkey; @@ -220,11 +221,11 @@ return display_driver; } - strcpy( buffer, "x11drv,ttydrv" ); /* default value */ - if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Wine", &hkey )) + strcpy( buffer, "x11,tty" ); /* default value */ + if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Drivers", &hkey )) { DWORD type, count = sizeof(buffer); - RegQueryValueExA( hkey, "GraphicsDriver", 0, &type, buffer, &count ); + RegQueryValueExA( hkey, "Graphics", 0, &type, buffer, &count ); RegCloseKey( hkey ); } @@ -234,13 +235,14 @@ next = strchr( name, ',' ); if (next) *next++ = 0; - if ((module = LoadLibraryA( name )) != 0) break; + snprintf( libname, sizeof(libname), "wine%s.drv", name ); + if ((module = LoadLibraryA( libname )) != 0) break; name = next; } if (!module) { MESSAGE( "wine: Could not load graphics driver '%s'.\n", buffer ); - if (!strcasecmp( buffer, "x11drv" )) + if (!strcasecmp( buffer, "x11" )) MESSAGE( "Make sure that your X server is running and that $DISPLAY is set correctly.\n" ); ExitProcess(1); } diff -urN wine-20050419/dlls/gdi/enhmfdrv/bitblt.c wine-20050524/dlls/gdi/enhmfdrv/bitblt.c --- wine-20050419/dlls/gdi/enhmfdrv/bitblt.c 2004-03-11 01:37:46.000000000 +0100 +++ wine-20050524/dlls/gdi/enhmfdrv/bitblt.c 2005-05-11 14:02:16.000000000 +0200 @@ -94,7 +94,8 @@ else return FALSE; - GetObjectW(hBitmap, sizeof(BITMAP), &BM); + if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM)) + return FALSE; nBPP = BM.bmPlanes * BM.bmBitsPixel; if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ diff -urN wine-20050419/dlls/gdi/freetype.c wine-20050524/dlls/gdi/freetype.c --- wine-20050419/dlls/gdi/freetype.c 2005-04-18 12:30:56.000000000 +0200 +++ wine-20050524/dlls/gdi/freetype.c 2005-05-06 18:22:55.000000000 +0200 @@ -25,7 +25,9 @@ #include #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #include #include #include diff -urN wine-20050419/dlls/gdi/gdiobj.c wine-20050524/dlls/gdi/gdiobj.c --- wine-20050419/dlls/gdi/gdiobj.c 2005-03-25 21:58:29.000000000 +0100 +++ wine-20050524/dlls/gdi/gdiobj.c 2005-05-20 20:59:46.000000000 +0200 @@ -30,8 +30,8 @@ #include "wingdi.h" #include "winreg.h" #include "winerror.h" +#include "winternl.h" -#include "local.h" #include "gdi.h" #include "gdi_private.h" #include "wine/debug.h" @@ -50,13 +50,9 @@ static const LOGBRUSH BlackBrush = { BS_SOLID, RGB(0,0,0), 0 }; static const LOGBRUSH NullBrush = { BS_NULL, 0, 0 }; -/* FIXME: these should perhaps be BS_HATCHED, at least for 1 bitperpixel */ static const LOGBRUSH LtGrayBrush = { BS_SOLID, RGB(192,192,192), 0 }; static const LOGBRUSH GrayBrush = { BS_SOLID, RGB(128,128,128), 0 }; - -/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */ -/* See HatchBrushes in x11drv for the HS_DIAGCROSS+1 hack */ -static const LOGBRUSH DkGrayBrush = { BS_HATCHED, RGB(0,0,0), (HS_DIAGCROSS+1) }; +static const LOGBRUSH DkGrayBrush = { BS_SOLID, RGB(64,64,64), 0 }; static const LOGPEN WhitePen = { PS_SOLID, { 0, 0 }, RGB(255,255,255) }; static const LOGPEN BlackPen = { PS_SOLID, { 0, 0 }, RGB(0,0,0) }; @@ -557,10 +553,6 @@ } -#define TRACE_SEC(handle,text) \ - TRACE("(%p): " text " %ld\n", (handle), GDI_level.crst.RecursionCount) - - /*********************************************************************** * inc_ref_count * @@ -717,7 +709,7 @@ */ void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle, const struct gdi_obj_funcs *funcs ) { - GDIOBJHDR *obj; + GDIOBJHDR *obj = NULL; HLOCAL16 hlocal; _EnterSysLevel( &GDI_level ); @@ -727,10 +719,18 @@ case BRUSH_MAGIC: if (GDI_HeapSel) { - if (!(hlocal = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error; - assert( hlocal & 2 ); - obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hlocal ); - *handle = (HGDIOBJ)(ULONG_PTR)hlocal; + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; + + stack16->ds = GDI_HeapSel; + if ((hlocal = LocalAlloc16( LMEM_MOVEABLE, size ))) + { + assert( hlocal & 2 ); + obj = MapSL(LocalLock16( hlocal )); + *handle = (HGDIOBJ)(ULONG_PTR)hlocal; + } + stack16->ds = oldDS; + if (!hlocal) goto error; break; } /* fall through */ @@ -744,7 +744,7 @@ obj->funcs = funcs; obj->hdcs = NULL; - TRACE_SEC( *handle, "enter" ); + TRACE("(%p): enter %ld\n", *handle, GDI_level.crst.RecursionCount); return obj; error: @@ -763,34 +763,39 @@ void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object ) { HGDIOBJ new_handle; + void *new_ptr = NULL; if ((UINT_PTR)handle & 2) /* GDI heap handle */ { + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; HLOCAL16 h = LOWORD(handle); - LOCAL_Unlock( GDI_HeapSel, h ); - if ((new_handle = (HGDIOBJ)(ULONG_PTR)LOCAL_ReAlloc( GDI_HeapSel, h, size, LMEM_MOVEABLE ))) + + stack16->ds = GDI_HeapSel; + LocalUnlock16( h ); + if ((new_handle = (HGDIOBJ)(ULONG_PTR)LocalReAlloc16( h, size, LMEM_MOVEABLE ))) { assert( new_handle == handle ); /* moveable handle cannot change */ - return LOCAL_Lock( GDI_HeapSel, h ); + new_ptr = MapSL(LocalLock16( h )); } + stack16->ds = oldDS; } else { int i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE; if (i >= 0 && i < MAX_LARGE_HANDLES && large_handles[i]) { - void *new_ptr = HeapReAlloc( GetProcessHeap(), 0, large_handles[i], size ); - if (new_ptr) - { - large_handles[i] = new_ptr; - return new_ptr; - } + new_ptr = HeapReAlloc( GetProcessHeap(), 0, large_handles[i], size ); + if (new_ptr) large_handles[i] = new_ptr; } else ERR( "Invalid handle %p\n", handle ); } - TRACE_SEC( handle, "leave" ); - _LeaveSysLevel( &GDI_level ); - return NULL; + if (!new_ptr) + { + TRACE("(%p): leave %ld\n", handle, GDI_level.crst.RecursionCount); + _LeaveSysLevel( &GDI_level ); + } + return new_ptr; } @@ -805,9 +810,14 @@ object->funcs = NULL; if ((UINT_PTR)handle & 2) /* GDI heap handle */ { + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; HLOCAL16 h = LOWORD(handle); - LOCAL_Unlock( GDI_HeapSel, h ); - LOCAL_Free( GDI_HeapSel, h ); + + stack16->ds = GDI_HeapSel; + LocalUnlock16( h ); + LocalFree16( h ); + stack16->ds = oldDS; } else /* large heap handle */ { @@ -819,7 +829,7 @@ } else ERR( "Invalid handle %p\n", handle ); } - TRACE_SEC( handle, "leave" ); + TRACE("(%p): leave %ld\n", handle, GDI_level.crst.RecursionCount); _LeaveSysLevel( &GDI_level ); return TRUE; } @@ -840,18 +850,23 @@ if ((UINT_PTR)handle & 2) /* GDI heap handle */ { + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; HLOCAL16 h = LOWORD(handle); - ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, h ); + + stack16->ds = GDI_HeapSel; + ptr = MapSL(LocalLock16( h )); if (ptr) { if (((magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) || (GDIMAGIC(ptr->wMagic) < FIRST_MAGIC) || (GDIMAGIC(ptr->wMagic) > LAST_MAGIC)) { - LOCAL_Unlock( GDI_HeapSel, h ); + LocalUnlock16( h ); ptr = NULL; } } + stack16->ds = oldDS; } else /* large heap handle */ { @@ -868,7 +883,7 @@ _LeaveSysLevel( &GDI_level ); WARN( "Invalid handle %p\n", handle ); } - else TRACE_SEC( handle, "enter" ); + else TRACE("(%p): enter %ld\n", handle, GDI_level.crst.RecursionCount); return ptr; } @@ -880,8 +895,16 @@ */ void GDI_ReleaseObj( HGDIOBJ handle ) { - if ((UINT_PTR)handle & 2) LOCAL_Unlock( GDI_HeapSel, LOWORD(handle) ); - TRACE_SEC( handle, "leave" ); + if ((UINT_PTR)handle & 2) + { + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; + + stack16->ds = GDI_HeapSel; + LocalUnlock16( LOWORD(handle) ); + stack16->ds = oldDS; + } + TRACE("(%p): leave %ld\n", handle, GDI_level.crst.RecursionCount); _LeaveSysLevel( &GDI_level ); } @@ -1249,7 +1272,7 @@ SetLastError( ERROR_INVALID_HANDLE ); else { - GDI_ReleaseObj( (GDIOBJHDR *)dc ); + GDI_ReleaseObj( hdc ); header = GDI_GetObjPtr( hObj, MAGIC_DONTCARE ); if (header) @@ -1456,20 +1479,31 @@ DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3 ) { + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; + DWORD ret = ~0UL; + + stack16->ds = GDI_HeapSel; switch (wReqType) { case 0x0001: /* LocalAlloc */ - return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 ); + ret = LocalAlloc16( wParam1, wParam3 ); + break; case 0x0002: /* LocalFree */ - return LOCAL_Free( GDI_HeapSel, wParam1 ); + ret = LocalFree16( wParam1 ); + break; case 0x0003: /* LocalCompact */ - return LOCAL_Compact( GDI_HeapSel, wParam3, 0 ); + ret = LocalCompact16( wParam3 ); + break; case 0x0103: /* LocalHeap */ - return GDI_HeapSel; + ret = GDI_HeapSel; + break; default: WARN("(wReqType=%04x): Unknown\n", wReqType); - return ~0UL; + break; } + stack16->ds = oldDS; + return ret; } /*********************************************************************** @@ -1485,11 +1519,12 @@ * GdiInit2 (GDI.403) * * See "Undocumented Windows" + * + * PARAMS + * h1 [I] GDI object + * h2 [I] global data */ -HANDLE16 WINAPI GdiInit216( - HANDLE16 h1, /* [in] GDI object */ - HANDLE16 h2 /* [in] global data */ -) +HANDLE16 WINAPI GdiInit216( HANDLE16 h1, HANDLE16 h2 ) { FIXME("(%04x, %04x), stub.\n", h1, h2); if (h2 == 0xffff) @@ -1509,8 +1544,15 @@ */ WORD WINAPI GdiFreeResources16( DWORD reserve ) { - return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 / - (int)LOCAL_HeapSize( GDI_HeapSel ) ); + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; + WORD ret; + + stack16->ds = GDI_HeapSel; + ret = (WORD)( (int)LocalCountFree16() * 100 / (int)LocalHeapSize16() ); + stack16->ds = oldDS; + + return ret; } diff -urN wine-20050419/dlls/gdi/palette.c wine-20050524/dlls/gdi/palette.c --- wine-20050419/dlls/gdi/palette.c 2005-03-30 19:08:34.000000000 +0200 +++ wine-20050524/dlls/gdi/palette.c 2005-05-06 17:44:32.000000000 +0200 @@ -124,7 +124,7 @@ if (palObj) { if (!(palObj->mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(int) * NB_RESERVED_COLORS ))) - ERR("Can not create palette mapping -- out of memory!\n"); + ERR("Cannot create palette mapping -- out of memory!\n"); GDI_ReleaseObj( hpalette ); } return hpalette; @@ -401,7 +401,7 @@ int *newMap = HeapReAlloc(GetProcessHeap(), 0, mapping, cEntries * sizeof(int) ); if(newMap == NULL) { - ERR("Can not resize mapping -- out of memory!\n"); + ERR("Cannot resize mapping -- out of memory!\n"); GDI_ReleaseObj( hPal ); return FALSE; } @@ -956,6 +956,9 @@ return TRUE; } +/********************************************************************** + * GetICMProfileW [GDI32.@] + **/ BOOL WINAPI GetICMProfileW(HDC hDC, LPDWORD lpcbName, LPWSTR lpszFilename) { DWORD callerLen; diff -urN wine-20050419/dlls/gdi/path.c wine-20050524/dlls/gdi/path.c --- wine-20050419/dlls/gdi/path.c 2005-03-24 22:01:38.000000000 +0100 +++ wine-20050524/dlls/gdi/path.c 2005-05-16 11:13:28.000000000 +0200 @@ -121,7 +121,18 @@ dc->xformWorld2Vport.eDy; } - +/* Performs a world-to-viewport transformation on the specified width. + */ +static inline void INTERNAL_WSTODS(DC *dc, LONG *width) +{ + POINT pt[2]; + pt[0].x = pt[0].y = 0; + pt[1].x = *width; + pt[1].y = 0; + LPtoDP(dc->hSelf, pt, 2); + *width = pt[1].x - pt[0].x; +} + /*********************************************************************** * BeginPath (GDI32.@) */ @@ -1430,12 +1441,14 @@ static BOOL PATH_StrokePath(DC *dc, GdiPath *pPath) { - INT i; - POINT ptLastMove = {0,0}; + INT i, nLinePts, nAlloc; + POINT *pLinePts; POINT ptViewportOrg, ptWindowOrg; SIZE szViewportExt, szWindowExt; DWORD mapMode, graphicsMode; XFORM xform; + HGDIOBJ hOldPen; + HPEN hNewPen; BOOL ret = TRUE; if(dc->funcs->pStrokePath) @@ -1444,6 +1457,32 @@ if(pPath->state != PATH_Closed) return FALSE; + /* Convert pen properties from logical to device units for MWT_IDENTITY */ + hOldPen = GetCurrentObject(dc->hSelf, OBJ_PEN); + if(GetObjectType(hOldPen) == OBJ_EXTPEN) { + EXTLOGPEN elp; + LOGBRUSH lb; + GetObjectW(hOldPen, sizeof(EXTLOGPEN), &elp); + if(elp.elpPenStyle & PS_GEOMETRIC) { + INTERNAL_WSTODS(dc, &elp.elpWidth); + if(elp.elpPenStyle & PS_USERSTYLE) + for(i = 0; i < elp.elpNumEntries; i++) + INTERNAL_WSTODS(dc, &elp.elpStyleEntry[i]); + } + lb.lbStyle = elp.elpBrushStyle; + lb.lbColor = elp.elpColor; + lb.lbHatch = elp.elpHatch; + hNewPen = ExtCreatePen(elp.elpPenStyle, elp.elpWidth, &lb, + elp.elpNumEntries, elp.elpStyleEntry); + } else /* OBJ_PEN */ { + LOGPEN lp; + GetObjectW(hOldPen, sizeof(LOGPEN), &lp); + if(lp.lopnWidth.x > 0) + INTERNAL_WSTODS(dc, &lp.lopnWidth.x); + hNewPen = CreatePenIndirect(&lp); + } + SelectObject(dc->hSelf, hNewPen); + /* Save the mapping mode info */ mapMode=GetMapMode(dc->hSelf); GetViewportExtEx(dc->hSelf, &szViewportExt); @@ -1461,19 +1500,36 @@ ModifyWorldTransform(dc->hSelf, &xform, MWT_IDENTITY); SetGraphicsMode(dc->hSelf, graphicsMode); + /* Allocate enough memory for the worst case without beziers (one PT_MOVETO + * and the rest PT_LINETO with PT_CLOSEFIGURE at the end) plus some buffer + * space in case we get one to keep the number of reallocations small. */ + nAlloc = pPath->numEntriesUsed + 1 + 300; + pLinePts = HeapAlloc(GetProcessHeap(), 0, nAlloc * sizeof(POINT)); + nLinePts = 0; + for(i = 0; i < pPath->numEntriesUsed; i++) { + if((i == 0 || (pPath->pFlags[i-1] & PT_CLOSEFIGURE)) && + (pPath->pFlags[i] != PT_MOVETO)) { + ERR("Expected PT_MOVETO %s, got path flag %d\n", + i == 0 ? "as first point" : "after PT_CLOSEFIGURE", + (INT)pPath->pFlags[i]); + ret = FALSE; + goto end; + } switch(pPath->pFlags[i]) { case PT_MOVETO: TRACE("Got PT_MOVETO (%ld, %ld)\n", pPath->pPoints[i].x, pPath->pPoints[i].y); - MoveToEx(dc->hSelf, pPath->pPoints[i].x, pPath->pPoints[i].y, NULL); - ptLastMove = pPath->pPoints[i]; + if(nLinePts >= 2) + Polyline(dc->hSelf, pLinePts, nLinePts); + nLinePts = 0; + pLinePts[nLinePts++] = pPath->pPoints[i]; break; case PT_LINETO: case (PT_LINETO | PT_CLOSEFIGURE): TRACE("Got PT_LINETO (%ld, %ld)\n", pPath->pPoints[i].x, pPath->pPoints[i].y); - LineTo(dc->hSelf, pPath->pPoints[i].x, pPath->pPoints[i].y); + pLinePts[nLinePts++] = pPath->pPoints[i]; break; case PT_BEZIERTO: TRACE("Got PT_BEZIERTO\n"); @@ -1482,9 +1538,25 @@ ERR("Path didn't contain 3 successive PT_BEZIERTOs\n"); ret = FALSE; goto end; + } else { + INT nBzrPts, nMinAlloc; + POINT *pBzrPts = GDI_Bezier(&pPath->pPoints[i-1], 4, &nBzrPts); + /* Make sure we have allocated enough memory for the lines of + * this bezier and the rest of the path, assuming we won't get + * another one (since we won't reallocate again then). */ + nMinAlloc = nLinePts + (pPath->numEntriesUsed - i) + nBzrPts; + if(nAlloc < nMinAlloc) + { + nAlloc = nMinAlloc * 2; + pLinePts = HeapReAlloc(GetProcessHeap(), 0, pLinePts, + nAlloc * sizeof(POINT)); + } + memcpy(&pLinePts[nLinePts], &pBzrPts[1], + (nBzrPts - 1) * sizeof(POINT)); + nLinePts += nBzrPts - 1; + HeapFree(GetProcessHeap(), 0, pBzrPts); + i += 2; } - PolyBezierTo(dc->hSelf, &pPath->pPoints[i], 3); - i += 2; break; default: ERR("Got path flag %d\n", (INT)pPath->pFlags[i]); @@ -1492,10 +1564,13 @@ goto end; } if(pPath->pFlags[i] & PT_CLOSEFIGURE) - LineTo(dc->hSelf, ptLastMove.x, ptLastMove.y); + pLinePts[nLinePts++] = pLinePts[0]; } + if(nLinePts >= 2) + Polyline(dc->hSelf, pLinePts, nLinePts); end: + HeapFree(GetProcessHeap(), 0, pLinePts); /* Restore the old mapping mode */ SetMapMode(dc->hSelf, mapMode); @@ -1522,6 +1597,11 @@ DPtoLP(dc->hSelf, &pt, 1); MoveToEx(dc->hSelf, pt.x, pt.y, NULL); } + + /* Restore old pen */ + DeleteObject(hNewPen); + SelectObject(dc->hSelf, hOldPen); + return ret; } diff -urN wine-20050419/dlls/gdi/tests/gdiobj.c wine-20050524/dlls/gdi/tests/gdiobj.c --- wine-20050419/dlls/gdi/tests/gdiobj.c 2005-01-03 21:19:32.000000000 +0100 +++ wine-20050524/dlls/gdi/tests/gdiobj.c 2005-05-20 20:58:19.000000000 +0200 @@ -20,7 +20,6 @@ */ #include -#include #include "windef.h" #include "winbase.h" @@ -29,11 +28,40 @@ #include "wine/test.h" + +static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont) +{ + LOGFONTA getobj_lf; + int ret, minlen = 0; + + if (!hfont) + return; + + ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf); + /* NT4 tries to be clever and only returns the minimum length */ + while (lf->lfFaceName[minlen] && minlen < LF_FACESIZE-1) + minlen++; + minlen += FIELD_OFFSET(LOGFONTA, lfFaceName) + 1; + ok(ret == sizeof(LOGFONTA) || ret == minlen, + "%s: GetObject returned %d expected %d or %d\n", test, ret, sizeof(LOGFONTA), minlen); + ok(!memcmp(&lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "%s: fonts don't match\n", test); + ok(!lstrcmpA(lf->lfFaceName, getobj_lf.lfFaceName), + "%s: font names don't match: %s != %s\n", test, lf->lfFaceName, getobj_lf.lfFaceName); +} + +static HFONT create_font(const char* test, const LOGFONTA* lf) +{ + HFONT hfont = CreateFontIndirectA(lf); + ok(hfont != 0, "%s: CreateFontIndirect failed\n", test); + if (hfont) + check_font(test, lf, hfont); + return hfont; +} + static void test_logfont(void) { - LOGFONTA lf, lfout; + LOGFONTA lf; HFONT hfont; - int ret; memset(&lf, 0, sizeof lf); @@ -43,35 +71,17 @@ lf.lfHeight = 16; lf.lfWidth = 16; lf.lfQuality = DEFAULT_QUALITY; - lstrcpyA(lf.lfFaceName, "Arial"); - - hfont = CreateFontIndirectA(&lf); - ok(hfont != 0, "CreateFontIndirect failed\n"); - - ret = GetObjectA(hfont, sizeof(lfout), &lfout); - ok(ret == sizeof(lfout), - "GetObject returned %d expected %d\n", ret, sizeof(lfout)); - - ok(!memcmp(&lfout, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "fonts don't match\n"); - ok(!lstrcmpA(lfout.lfFaceName, lf.lfFaceName), - "font names don't match: %s != %s\n", lfout.lfFaceName, lf.lfFaceName); + lstrcpyA(lf.lfFaceName, "Arial"); + hfont = create_font("Arial", &lf); DeleteObject(hfont); memset(&lf, 'A', sizeof(lf)); hfont = CreateFontIndirectA(&lf); ok(hfont != 0, "CreateFontIndirectA with strange LOGFONT failed\n"); - - ok(GetObjectA(hfont, sizeof(lfout), NULL) == sizeof(lfout), - "GetObjectA with NULL failed\n"); - - ok(GetObjectA(hfont, sizeof(lfout), &lfout) == sizeof(lfout), - "GetObjectA failed\n"); - ok(!memcmp(&lfout, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "fonts don't match\n"); + lf.lfFaceName[LF_FACESIZE - 1] = 0; - ok(!lstrcmpA(lfout.lfFaceName, lf.lfFaceName), - "font names don't match: %s != %s\n", lfout.lfFaceName, lf.lfFaceName); - + check_font("AAA...", &lf, hfont); DeleteObject(hfont); } @@ -97,6 +107,9 @@ SIZE size; INT width; + if (!hfont) + return; + old_hfont = SelectObject(hdc, hfont); GetTextMetricsA(hdc, &tm); @@ -123,7 +136,7 @@ { static const char test_str[11] = "Test String"; HDC hdc; - LOGFONTA bitmap_lf, lf; + LOGFONTA bitmap_lf; HFONT hfont, old_hfont; TEXTMETRICA tm_orig; SIZE size_orig; @@ -143,8 +156,7 @@ trace("found bitmap font %s, height %ld\n", bitmap_lf.lfFaceName, bitmap_lf.lfHeight); height_orig = bitmap_lf.lfHeight; - hfont = CreateFontIndirectA(&bitmap_lf); - assert(hfont); + hfont = create_font("bitmap", &bitmap_lf); old_hfont = SelectObject(hdc, hfont); ok(GetTextMetricsA(hdc, &tm_orig), "GetTextMetricsA failed\n"); @@ -156,16 +168,7 @@ /* test fractional scaling */ for (i = 1; i < height_orig; i++) { - bitmap_lf.lfHeight = i; - hfont = CreateFontIndirectA(&bitmap_lf); - assert(hfont); - - ret = GetObject(hfont, sizeof(lf), &lf); - ok(ret == sizeof(lf), "GetObject failed: %d\n", ret); - ok(!memcmp(&bitmap_lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "fonts don't match\n"); - ok(!lstrcmpA(bitmap_lf.lfFaceName, lf.lfFaceName), - "font names don't match: %s != %s\n", bitmap_lf.lfFaceName, lf.lfFaceName); - + hfont = create_font("fractional", &bitmap_lf); test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, 1); DeleteObject(hfont); } @@ -173,14 +176,7 @@ /* test integer scaling 3x2 */ bitmap_lf.lfHeight = height_orig * 2; bitmap_lf.lfWidth *= 3; - hfont = CreateFontIndirectA(&bitmap_lf); - assert(hfont); - - ret = GetObject(hfont, sizeof(lf), &lf); - ok(ret == sizeof(lf), "GetObject failed: %d\n", ret); - ok(!memcmp(&bitmap_lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "fonts don't match\n"); - ok(!lstrcmpA(bitmap_lf.lfFaceName, lf.lfFaceName), - "font names don't match: %s != %s\n", bitmap_lf.lfFaceName, lf.lfFaceName); + hfont = create_font("3x2", &bitmap_lf); todo_wine { test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2); @@ -190,14 +186,8 @@ /* test integer scaling 3x3 */ bitmap_lf.lfHeight = height_orig * 3; bitmap_lf.lfWidth = 0; - hfont = CreateFontIndirectA(&bitmap_lf); - assert(hfont); + hfont = create_font("3x3", &bitmap_lf); - ret = GetObject(hfont, sizeof(lf), &lf); - ok(ret == sizeof(lf), "GetObject failed: %d\n", ret); - ok(!memcmp(&bitmap_lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "fonts don't match\n"); - ok(!lstrcmpA(bitmap_lf.lfFaceName, lf.lfFaceName), - "font names don't match: %s != %s\n", bitmap_lf.lfFaceName, lf.lfFaceName); todo_wine { test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3); diff -urN wine-20050419/dlls/glu32/.cvsignore wine-20050524/dlls/glu32/.cvsignore --- wine-20050419/dlls/glu32/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/glu32/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,3 +1,3 @@ Makefile glu32.dll.dbg.c -glu32.spec.def +libglu32.def diff -urN wine-20050419/dlls/glu32/Makefile.in wine-20050524/dlls/glu32/Makefile.in --- wine-20050419/dlls/glu32/Makefile.in 2003-11-11 01:30:10.000000000 +0100 +++ wine-20050524/dlls/glu32/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = glu32.dll +IMPORTLIB = libglu32.$(IMPLIBEXT) IMPORTS = kernel32 ntdll EXTRAINCL = @X_CFLAGS@ EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ diff -urN wine-20050419/dlls/glut32/.cvsignore wine-20050524/dlls/glut32/.cvsignore --- wine-20050419/dlls/glut32/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/glut32/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,3 +1,3 @@ Makefile glut32.dll.dbg.c -glut32.spec.def +libglut32.def diff -urN wine-20050419/dlls/glut32/Makefile.in wine-20050524/dlls/glut32/Makefile.in --- wine-20050419/dlls/glut32/Makefile.in 2003-12-02 05:11:09.000000000 +0100 +++ wine-20050524/dlls/glut32/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = glut32.dll +IMPORTLIB = libglut32.$(IMPLIBEXT) IMPORTS = kernel32 EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ @GLUT_LIBS@ diff -urN wine-20050419/dlls/hhctrl.ocx/hhctrl.ocx.spec wine-20050524/dlls/hhctrl.ocx/hhctrl.ocx.spec --- wine-20050419/dlls/hhctrl.ocx/hhctrl.ocx.spec 2004-10-08 22:49:09.000000000 +0200 +++ wine-20050524/dlls/hhctrl.ocx/hhctrl.ocx.spec 2005-05-17 16:41:37.000000000 +0200 @@ -1,5 +1,5 @@ 13 stdcall doWinMain(long ptr) 14 stdcall HtmlHelpA(ptr ptr long long) 15 stdcall HtmlHelpW(ptr ptr long long) -@ stdcall -private DllRegisterServer() HHCTRL_DllRegisterServer -@ stdcall -private DllUnregisterServer() HHCTRL_DllUnregisterServer +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff -urN wine-20050419/dlls/hhctrl.ocx/regsvr.c wine-20050524/dlls/hhctrl.ocx/regsvr.c --- wine-20050419/dlls/hhctrl.ocx/regsvr.c 2004-08-23 20:50:54.000000000 +0200 +++ wine-20050524/dlls/hhctrl.ocx/regsvr.c 2005-05-17 16:41:37.000000000 +0200 @@ -542,7 +542,7 @@ /*********************************************************************** * DllRegisterServer (HHCTRL.@) */ -HRESULT WINAPI HHCTRL_DllRegisterServer(void) +HRESULT WINAPI DllRegisterServer(void) { HRESULT hr; @@ -557,7 +557,7 @@ /*********************************************************************** * DllUnregisterServer (HHCTRL.@) */ -HRESULT WINAPI HHCTRL_DllUnregisterServer(void) +HRESULT WINAPI DllUnregisterServer(void) { HRESULT hr; diff -urN wine-20050419/dlls/iccvid/.cvsignore wine-20050524/dlls/iccvid/.cvsignore --- wine-20050419/dlls/iccvid/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/iccvid/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,3 +1,3 @@ Makefile iccvid.dll.dbg.c -iccvid.spec.def +libiccvid.def diff -urN wine-20050419/dlls/iccvid/Makefile.in wine-20050524/dlls/iccvid/Makefile.in --- wine-20050419/dlls/iccvid/Makefile.in 2004-01-15 05:56:18.000000000 +0100 +++ wine-20050524/dlls/iccvid/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = iccvid.dll +IMPORTLIB = libiccvid.$(IMPLIBEXT) IMPORTS = kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/icmp/.cvsignore wine-20050524/dlls/icmp/.cvsignore --- wine-20050419/dlls/icmp/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/icmp/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,3 +1,3 @@ Makefile icmp.dll.dbg.c -icmp.spec.def +libicmp.def diff -urN wine-20050419/dlls/icmp/Makefile.in wine-20050524/dlls/icmp/Makefile.in --- wine-20050419/dlls/icmp/Makefile.in 2003-10-11 03:09:19.000000000 +0200 +++ wine-20050524/dlls/icmp/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = icmp.dll +IMPORTLIB = libicmp.$(IMPLIBEXT) IMPORTS = kernel32 C_SRCS = icmp_main.c diff -urN wine-20050419/dlls/imagehlp/.cvsignore wine-20050524/dlls/imagehlp/.cvsignore --- wine-20050419/dlls/imagehlp/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/imagehlp/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,3 +1,3 @@ Makefile imagehlp.dll.dbg.c -imagehlp.spec.def +libimagehlp.def diff -urN wine-20050419/dlls/imagehlp/Makefile.in wine-20050524/dlls/imagehlp/Makefile.in --- wine-20050419/dlls/imagehlp/Makefile.in 2004-04-06 00:50:45.000000000 +0200 +++ wine-20050524/dlls/imagehlp/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = imagehlp.dll +IMPORTLIB = libimagehlp.$(IMPLIBEXT) IMPORTS = dbghelp kernel32 ntdll C_SRCS = \ diff -urN wine-20050419/dlls/imm32/.cvsignore wine-20050524/dlls/imm32/.cvsignore --- wine-20050419/dlls/imm32/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/imm32/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile imm.spec.c imm32.dll.dbg.c -imm32.spec.def +libimm32.def diff -urN wine-20050419/dlls/imm32/Makefile.in wine-20050524/dlls/imm32/Makefile.in --- wine-20050419/dlls/imm32/Makefile.in 2004-08-12 01:59:07.000000000 +0200 +++ wine-20050524/dlls/imm32/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = imm32.dll +IMPORTLIB = libimm32.$(IMPLIBEXT) IMPORTS = user32 gdi32 kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/imm32/imm.c wine-20050524/dlls/imm32/imm.c --- wine-20050419/dlls/imm32/imm.c 2005-03-24 22:01:38.000000000 +0100 +++ wine-20050524/dlls/imm32/imm.c 2005-05-06 21:38:50.000000000 +0200 @@ -140,7 +140,7 @@ DisableThreadLibraryCalls(hInstDLL); hImeInst = hInstDLL; IMM_RegisterMessages(); - x11drv = GetModuleHandleA("x11drv.dll"); + x11drv = GetModuleHandleA("winex11.drv"); if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset"); break; case DLL_PROCESS_DETACH: diff -urN wine-20050419/dlls/iphlpapi/.cvsignore wine-20050524/dlls/iphlpapi/.cvsignore --- wine-20050419/dlls/iphlpapi/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/iphlpapi/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,3 +1,3 @@ Makefile iphlpapi.dll.dbg.c -iphlpapi.spec.def +libiphlpapi.def diff -urN wine-20050419/dlls/iphlpapi/Makefile.in wine-20050524/dlls/iphlpapi/Makefile.in --- wine-20050419/dlls/iphlpapi/Makefile.in 2004-01-07 02:08:55.000000000 +0100 +++ wine-20050524/dlls/iphlpapi/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = iphlpapi.dll +IMPORTLIB = libiphlpapi.$(IMPLIBEXT) IMPORTS = advapi32 kernel32 C_SRCS = \ diff -urN wine-20050419/dlls/itss/.cvsignore wine-20050524/dlls/itss/.cvsignore --- wine-20050419/dlls/itss/.cvsignore 2004-09-21 03:05:14.000000000 +0200 +++ wine-20050524/dlls/itss/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile itss.dll.dbg.c itss.h -itss.spec.def +libitss.def diff -urN wine-20050419/dlls/itss/Makefile.in wine-20050524/dlls/itss/Makefile.in --- wine-20050419/dlls/itss/Makefile.in 2004-09-21 02:35:03.000000000 +0200 +++ wine-20050524/dlls/itss/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = itss.dll +IMPORTLIB = libitss.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 ntdll EXTRALIBS = $(LIBUNICODE) -luuid EXTRADEFS = -DCOM_NO_WINDOWS_H diff -urN wine-20050419/dlls/itss/chm_lib.c wine-20050524/dlls/itss/chm_lib.c --- wine-20050419/dlls/itss/chm_lib.c 2005-04-18 12:30:56.000000000 +0200 +++ wine-20050524/dlls/itss/chm_lib.c 2005-05-24 14:34:30.000000000 +0200 @@ -1289,7 +1289,7 @@ UInt64 nBlock, nOffset; UInt64 nLen; UInt64 gotLen; - UChar *ubuffer; + UChar *ubuffer = NULL; if (len <= 0) return (Int64)0; diff -urN wine-20050419/dlls/kernel/.cvsignore wine-20050524/dlls/kernel/.cvsignore --- wine-20050419/dlls/kernel/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/kernel/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -2,8 +2,8 @@ comm.drv.spec.c kernel.res kernel32.dll.dbg.c -kernel32.spec.def krnl386.exe.spec.c +libkernel32.def relay16asm.s stress.spec.c system.drv.spec.c diff -urN wine-20050419/dlls/kernel/Makefile.in wine-20050524/dlls/kernel/Makefile.in --- wine-20050419/dlls/kernel/Makefile.in 2005-03-08 17:55:26.000000000 +0100 +++ wine-20050524/dlls/kernel/Makefile.in 2005-05-24 12:12:06.000000000 +0200 @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = kernel32.dll +IMPORTLIB = libkernel32.$(IMPLIBEXT) IMPORTS = ntdll EXTRALIBS = $(LIBUNICODE) @COREFOUNDATIONLIB@ @@ -17,7 +18,6 @@ windebug.spec C_SRCS = \ - $(TOPOBJDIR)/misc/registry.c \ actctx.c \ atom.c \ change.c \ @@ -44,6 +44,7 @@ module.c \ ne_module.c \ ne_segment.c \ + oldconfig.c \ path.c \ powermgnt.c \ process.c \ @@ -70,14 +71,15 @@ virtual.c \ volume.c \ vxd.c \ - win87em.c \ windebug.c \ wowthunk.c C_SRCS16 = \ atom16.c \ error16.c \ - registry16.c + registry16.c \ + toolhelp16.c \ + win87em.c ASM_SRCS = relay16asm.s @@ -91,10 +93,7 @@ EXTRA_OBJS = $(ASM_SRCS:.s=.o) SUBDIRS = tests -EXTRASUBDIRS = \ - $(TOPOBJDIR)/misc \ - messages \ - nls +EXTRASUBDIRS = messages nls @MAKE_DLL_RULES@ diff -urN wine-20050419/dlls/kernel/atom.c wine-20050524/dlls/kernel/atom.c --- wine-20050419/dlls/kernel/atom.c 2005-02-03 17:58:21.000000000 +0100 +++ wine-20050524/dlls/kernel/atom.c 2005-05-10 17:15:50.000000000 +0200 @@ -48,6 +48,31 @@ #define MAX_ATOM_LEN 255 +static struct atom_table* get_local_table(DWORD entries) +{ + static struct atom_table* local_table; + + if (!local_table) + { + NTSTATUS status; + struct atom_table* table; + + SERVER_START_REQ( init_atom_table ) + { + req->entries = entries; + status = wine_server_call( req ); + table = reply->table; + } + SERVER_END_REQ; + + if (status) + SetLastError( RtlNtStatusToDosError( status ) ); + else if (InterlockedCompareExchangePointer((void*)&local_table, table, NULL) != NULL) + NtClose((HANDLE)table); + } + return local_table; +} + /*********************************************************************** * ATOM_IsIntAtomA */ @@ -116,18 +141,11 @@ */ BOOL WINAPI InitAtomTable( DWORD entries ) { - BOOL ret; - SERVER_START_REQ( init_atom_table ) - { - req->entries = entries; - ret = !wine_server_call_err( req ); - } - SERVER_END_REQ; - return ret; + return get_local_table( entries ) ? TRUE : FALSE; } -static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local ) +static ATOM ATOM_AddAtomA( LPCSTR str, struct atom_table* table ) { ATOM atom = 0; if (!ATOM_IsIntAtomA( str, &atom )) @@ -143,12 +161,12 @@ SERVER_START_REQ( add_atom ) { wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); - req->local = local; + req->table = table; if (!wine_server_call_err(req)) atom = reply->atom; } SERVER_END_REQ; } - TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_a(str), atom ); + TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_a(str), atom ); return atom; } @@ -165,7 +183,7 @@ */ ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ ) { - return ATOM_AddAtomA( str, FALSE ); + return ATOM_AddAtomA( str, NULL ); } @@ -181,11 +199,11 @@ */ ATOM WINAPI AddAtomA( LPCSTR str /* [in] String to add */ ) { - return ATOM_AddAtomA( str, TRUE ); + return ATOM_AddAtomA( str, get_local_table(0) ); } -static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local ) +static ATOM ATOM_AddAtomW( LPCWSTR str, struct atom_table* table ) { ATOM atom = 0; if (!ATOM_IsIntAtomW( str, &atom )) @@ -198,13 +216,13 @@ } SERVER_START_REQ( add_atom ) { - req->local = local; + req->table = table; wine_server_add_data( req, str, len * sizeof(WCHAR) ); if (!wine_server_call_err(req)) atom = reply->atom; } SERVER_END_REQ; } - TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_w(str), atom ); + TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_w(str), atom ); return atom; } @@ -216,7 +234,7 @@ */ ATOM WINAPI GlobalAddAtomW( LPCWSTR str ) { - return ATOM_AddAtomW( str, FALSE ); + return ATOM_AddAtomW( str, NULL ); } @@ -227,19 +245,19 @@ */ ATOM WINAPI AddAtomW( LPCWSTR str ) { - return ATOM_AddAtomW( str, TRUE ); + return ATOM_AddAtomW( str, get_local_table(0) ); } -static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local) +static ATOM ATOM_DeleteAtom( ATOM atom, struct atom_table* table ) { - TRACE( "(%s) %x\n", local ? "local" : "global", atom ); + TRACE( "(%s) %x\n", table ? "local" : "global", atom ); if (atom >= MAXINTATOM) { SERVER_START_REQ( delete_atom ) { req->atom = atom; - req->local = local; + req->table = table; wine_server_call_err( req ); } SERVER_END_REQ; @@ -260,7 +278,7 @@ */ ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ ) { - return ATOM_DeleteAtom( atom, FALSE); + return ATOM_DeleteAtom( atom, NULL); } @@ -276,11 +294,11 @@ */ ATOM WINAPI DeleteAtom( ATOM atom /* [in] Atom to delete */ ) { - return ATOM_DeleteAtom( atom, TRUE ); + return ATOM_DeleteAtom( atom, get_local_table(0) ); } -static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local ) +static ATOM ATOM_FindAtomA( LPCSTR str, struct atom_table* table ) { ATOM atom = 0; if (!ATOM_IsIntAtomA( str, &atom )) @@ -295,13 +313,13 @@ } SERVER_START_REQ( find_atom ) { - req->local = local; + req->table = table; wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); if (!wine_server_call_err(req)) atom = reply->atom; } SERVER_END_REQ; } - TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_a(str), atom ); + TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_a(str), atom ); return atom; } @@ -317,7 +335,7 @@ */ ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for */ ) { - return ATOM_FindAtomA( str, FALSE ); + return ATOM_FindAtomA( str, NULL ); } /*********************************************************************** @@ -331,11 +349,11 @@ */ ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ ) { - return ATOM_FindAtomA( str, TRUE ); + return ATOM_FindAtomA( str, get_local_table(0) ); } -static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local ) +static ATOM ATOM_FindAtomW( LPCWSTR str, struct atom_table* table ) { ATOM atom = 0; if (!ATOM_IsIntAtomW( str, &atom )) @@ -349,12 +367,12 @@ SERVER_START_REQ( find_atom ) { wine_server_add_data( req, str, len * sizeof(WCHAR) ); - req->local = local; + req->table = table; if (!wine_server_call_err( req )) atom = reply->atom; } SERVER_END_REQ; } - TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_w(str), atom ); + TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_w(str), atom ); return atom; } @@ -366,7 +384,7 @@ */ ATOM WINAPI GlobalFindAtomW( LPCWSTR str ) { - return ATOM_FindAtomW( str, FALSE ); + return ATOM_FindAtomW( str, NULL ); } @@ -377,11 +395,11 @@ */ ATOM WINAPI FindAtomW( LPCWSTR str ) { - return ATOM_FindAtomW( str, TRUE ); + return ATOM_FindAtomW( str, get_local_table(0) ); } -static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local ) +static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, struct atom_table* table ) { INT len; @@ -406,10 +424,10 @@ WCHAR full_name[MAX_ATOM_LEN]; len = 0; - SERVER_START_REQ( get_atom_name ) + SERVER_START_REQ( get_atom_information ) { req->atom = atom; - req->local = local; + req->table = table; wine_server_set_reply( req, full_name, sizeof(full_name) ); if (!wine_server_call_err( req )) { @@ -429,7 +447,7 @@ buffer[count-1] = 0; return 0; } - TRACE( "(%s) %x -> %s\n", local ? "local" : "global", atom, debugstr_a(buffer) ); + TRACE( "(%s) %x -> %s\n", table ? "local" : "global", atom, debugstr_a(buffer) ); return len; } @@ -448,7 +466,7 @@ LPSTR buffer, /* [out] Pointer to buffer for atom string */ INT count ) /* [in] Size of buffer */ { - return ATOM_GetAtomNameA( atom, buffer, count, FALSE ); + return ATOM_GetAtomNameA( atom, buffer, count, NULL ); } @@ -466,11 +484,11 @@ LPSTR buffer, /* [out] Pointer to string for atom string */ INT count) /* [in] Size of buffer */ { - return ATOM_GetAtomNameA( atom, buffer, count, TRUE ); + return ATOM_GetAtomNameA( atom, buffer, count, get_local_table(0) ); } -static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local ) +static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, struct atom_table* table ) { INT len; @@ -496,10 +514,10 @@ WCHAR full_name[MAX_ATOM_LEN]; len = 0; - SERVER_START_REQ( get_atom_name ) + SERVER_START_REQ( get_atom_information ) { req->atom = atom; - req->local = local; + req->table = table; wine_server_set_reply( req, full_name, sizeof(full_name) ); if (!wine_server_call_err( req )) { @@ -512,7 +530,7 @@ SERVER_END_REQ; if (!len) return 0; } - TRACE( "(%s) %x -> %s\n", local ? "local" : "global", atom, debugstr_w(buffer) ); + TRACE( "(%s) %x -> %s\n", table ? "local" : "global", atom, debugstr_w(buffer) ); return len; } @@ -524,7 +542,7 @@ */ UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count ) { - return ATOM_GetAtomNameW( atom, buffer, count, FALSE); + return ATOM_GetAtomNameW( atom, buffer, count, NULL); } @@ -535,5 +553,5 @@ */ UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count ) { - return ATOM_GetAtomNameW( atom, buffer, count, TRUE ); + return ATOM_GetAtomNameW( atom, buffer, count, get_local_table(0) ); } diff -urN wine-20050419/dlls/kernel/atom16.c wine-20050524/dlls/kernel/atom16.c --- wine-20050419/dlls/kernel/atom16.c 2005-03-28 16:58:52.000000000 +0200 +++ wine-20050524/dlls/kernel/atom16.c 2005-05-16 21:44:54.000000000 +0200 @@ -42,7 +42,7 @@ #include "wine/unicode.h" #include "wine/winbase16.h" #include "kernel_private.h" -#include "stackframe.h" +#include "kernel16_private.h" #include "wine/debug.h" diff -urN wine-20050419/dlls/kernel/comm.c wine-20050524/dlls/kernel/comm.c --- wine-20050419/dlls/kernel/comm.c 2005-03-30 19:08:34.000000000 +0200 +++ wine-20050524/dlls/kernel/comm.c 2005-05-16 19:52:11.000000000 +0200 @@ -65,7 +65,9 @@ #endif #include #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #ifdef HAVE_SYS_FILIO_H # include #endif @@ -92,9 +94,9 @@ #include "winbase.h" #include "winerror.h" +#include "thread.h" #include "wine/server.h" #include "wine/unicode.h" -#include "thread.h" #include "wine/debug.h" @@ -2122,7 +2124,7 @@ */ BOOL WINAPI CommConfigDialogA( LPCSTR lpszDevice, /* [in] name of communications device */ - HANDLE hWnd, /* [in] parent window for the dialog */ + HWND hWnd, /* [in] parent window for the dialog */ LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */ { FARPROC lpfnCommDialog; @@ -2152,7 +2154,7 @@ */ BOOL WINAPI CommConfigDialogW( LPCWSTR lpszDevice, /* [in] name of communications device */ - HANDLE hWnd, /* [in] parent window for the dialog */ + HWND hWnd, /* [in] parent window for the dialog */ LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */ { FARPROC lpfnCommDialog; diff -urN wine-20050419/dlls/kernel/comm.drv.spec wine-20050524/dlls/kernel/comm.drv.spec --- wine-20050419/dlls/kernel/comm.drv.spec 2003-09-27 04:32:54.000000000 +0200 +++ wine-20050524/dlls/kernel/comm.drv.spec 2005-05-23 12:12:26.000000000 +0200 @@ -13,7 +13,7 @@ 13 stub CSETBRK 14 stub CCLRBRK 15 stub GETDCB - 16 stub WEP +#16 stub WEP 17 stub SUSPENDOPENCOMMPORTS # win3.1 18 stub REACTIVATEOPENCOMMPORTS # win3.1 19 stub COMMWRITESTRING diff -urN wine-20050419/dlls/kernel/cpu.c wine-20050524/dlls/kernel/cpu.c --- wine-20050419/dlls/kernel/cpu.c 2005-02-23 21:29:17.000000000 +0100 +++ wine-20050524/dlls/kernel/cpu.c 2005-05-18 20:20:23.000000000 +0200 @@ -31,6 +31,9 @@ #ifdef HAVE_MACHINE_CPU_H # include #endif +#ifdef HAVE_MACH_MACHINE_H +# include +#endif #include #include diff -urN wine-20050419/dlls/kernel/debugger.c wine-20050524/dlls/kernel/debugger.c --- wine-20050419/dlls/kernel/debugger.c 2004-08-26 20:22:17.000000000 +0200 +++ wine-20050524/dlls/kernel/debugger.c 2005-05-16 21:44:54.000000000 +0200 @@ -25,7 +25,8 @@ #include "wine/winbase16.h" #include "wine/server.h" #include "ntstatus.h" -#include "stackframe.h" +#include "kernel_private.h" +#include "kernel16_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(debugstr); diff -urN wine-20050419/dlls/kernel/dosmem.c wine-20050524/dlls/kernel/dosmem.c --- wine-20050419/dlls/kernel/dosmem.c 2004-10-11 21:53:54.000000000 +0200 +++ wine-20050524/dlls/kernel/dosmem.c 2005-05-10 17:22:10.000000000 +0200 @@ -33,11 +33,13 @@ #include "windef.h" #include "winbase.h" +#include "winreg.h" +#include "excpt.h" +#include "winternl.h" #include "wine/winbase16.h" #include "kernel_private.h" #include "toolhelp.h" -#include "miscemu.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(dosmem); @@ -47,292 +49,141 @@ WORD DOSMEM_BiosDataSeg; /* BIOS data segment at 0x40:0 */ WORD DOSMEM_BiosSysSeg; /* BIOS ROM segment at 0xf000:0 */ -/* use 2 low bits of 'size' for the housekeeping */ - -#define DM_BLOCK_DEBUG 0xABE00000 -#define DM_BLOCK_TERMINAL 0x00000001 -#define DM_BLOCK_FREE 0x00000002 -#define DM_BLOCK_MASK 0x001FFFFC - -/* -#define __DOSMEM_DEBUG__ +/* DOS memory highest address (including HMA) */ +#define DOSMEM_SIZE 0x110000 +#define DOSMEM_64KB 0x10000 + +/* when looking at DOS and real mode memory, we activate in three different + * modes, depending the situation. + * 1/ By default (protected mode), the first MB of memory (actually 0x110000, + * when you also look at the HMA part) is always reserved, whatever you do. + * We allocated some PM selectors to this memory, even if this area is not + * committed at startup + * 2/ if a program tries to use the memory through the selectors, we actually + * commit this memory, made of: BIOS segment, but also some system + * information, usually low in memory that we map for the circumstance also + * in the BIOS segment, so that we keep the low memory protected (for NULL + * pointer deref catching for example). In this case, we're still in PM + * mode, accessing part of the "physical" real mode memory. In fact, we don't + * map all the first meg, we keep 64k uncommitted to still catch NULL + * pointers dereference + * 3/ if the process enters the real mode, then we (also) commit the full first + * MB of memory (and also initialize the DOS structures in it). */ -typedef struct { - unsigned size; -} dosmem_entry; - -typedef struct { - unsigned blocks; - unsigned free; -} dosmem_info; - -#define NEXT_BLOCK(block) \ - (dosmem_entry*)(((char*)(block)) + \ - sizeof(dosmem_entry) + ((block)->size & DM_BLOCK_MASK)) - -#define VM_STUB(x) (0x90CF00CD|(x<<8)) /* INT x; IRET; NOP */ -#define VM_STUB_SEGMENT 0xf000 /* BIOS segment */ - -/* DOS memory base */ +/* DOS memory base (linear in process address space) */ static char *DOSMEM_dosmem; -/* DOS system base (for interrupt vector table and BIOS data area) - * ...should in theory (i.e. Windows) be equal to DOSMEM_dosmem (NULL), - * but is normally set to 0xf0000 in Wine to allow trapping of NULL pointers, - * and only relocated to NULL when absolutely necessary */ -static char *DOSMEM_sysmem; +/* number of bytes protected from _dosmem. 0 when DOS memory is initialized, + * 64k otherwise to trap NULL pointers deref */ +static DWORD DOSMEM_protect; -/* Start of DOS conventional memory */ -static char *DOSMEM_membase; +static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except); -static void DOSMEM_InitMemory(void); +struct winedos_exports winedos; -/*********************************************************************** - * DOSMEM_MemoryTop - * - * Gets the DOS memory top. - */ -static char *DOSMEM_MemoryTop(void) +void load_winedos(void) { - return DOSMEM_dosmem+0x9FFFC; /* 640K */ -} + static HANDLE hRunOnce /* = 0 */; + static HMODULE hWineDos /* = 0 */; -/*********************************************************************** - * DOSMEM_InfoBlock - * - * Gets the DOS memory info block. - */ -static dosmem_info *DOSMEM_InfoBlock(void) -{ - if (!DOSMEM_membase) + /* FIXME: this isn't 100% thread safe, as we won't catch access to 1MB while + * loading winedos (and may return uninitialized valued) + */ + if (hWineDos) return; + if (hRunOnce == 0) { - DWORD reserve; - - /* - * Reserve either: - * - lowest 64k for NULL pointer catching (Win16) - * - lowest 1k for interrupt handlers and - * another 0.5k for BIOS, DOS and intra-application - * areas (DOS) - */ - if (DOSMEM_dosmem != DOSMEM_sysmem) - reserve = 0x10000; /* 64k */ - else - reserve = 0x600; /* 1.5k */ - - /* - * Round to paragraph boundary in order to make - * sure the alignment is correct. - */ - reserve = ((reserve + 15) >> 4) << 4; - - /* - * Set DOS memory base and initialize conventional memory. - */ - DOSMEM_membase = DOSMEM_dosmem + reserve; - DOSMEM_InitMemory(); + HANDLE hEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); + if (InterlockedCompareExchangePointer( (PVOID)&hRunOnce, hEvent, 0 ) == 0) + { + HMODULE hModule; + + /* ok, we're the winning thread */ + VirtualProtect( DOSMEM_dosmem + DOSMEM_protect, + DOSMEM_SIZE - DOSMEM_protect, + PAGE_EXECUTE_READWRITE, NULL ); + if (!(hModule = LoadLibraryA( "winedos.dll" ))) + { + ERR("Could not load winedos.dll, DOS subsystem unavailable\n"); + hWineDos = (HMODULE)1; /* not to try to load it again */ + return; + } +#define GET_ADDR(func) winedos.func = (void *)GetProcAddress( hModule, #func ); + GET_ADDR(AllocDosBlock); + GET_ADDR(FreeDosBlock); + GET_ADDR(ResizeDosBlock); + GET_ADDR(inport); + GET_ADDR(outport); + GET_ADDR(EmulateInterruptPM); + GET_ADDR(CallBuiltinHandler); + GET_ADDR(BiosTick); +#undef GET_ADDR + RtlRemoveVectoredExceptionHandler( dosmem_handler ); + hWineDos = hModule; + SetEvent( hRunOnce ); + return; + } + /* someone beat us here... */ + CloseHandle( hEvent ); + } + + /* and wait for the winner to have finished */ + WaitForSingleObject( hRunOnce, INFINITE ); +} + +/****************************************************************** + * dosmem_handler + * + * Handler to catch access to our 1MB address space reserved for real memory + */ +static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except) +{ + if (except->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + { + DWORD addr = except->ExceptionRecord->ExceptionInformation[1]; + if (addr >= (ULONG_PTR)DOSMEM_dosmem + DOSMEM_protect && + addr < (ULONG_PTR)DOSMEM_dosmem + DOSMEM_SIZE) + { + load_winedos(); + return EXCEPTION_CONTINUE_EXECUTION; + } } - - return (dosmem_info*)DOSMEM_membase; -} - -/*********************************************************************** - * DOSMEM_RootBlock - * - * Gets the DOS memory root block. - */ -static dosmem_entry *DOSMEM_RootBlock(void) -{ - /* first block has to be paragraph-aligned */ - return (dosmem_entry*)(((char*)DOSMEM_InfoBlock()) + - ((((sizeof(dosmem_info) + 0xf) & ~0xf) - sizeof(dosmem_entry)))); -} - -/*********************************************************************** - * DOSMEM_FillIsrTable - * - * Fill the interrupt table with fake BIOS calls to BIOSSEG (0xf000). - * - * NOTES: - * Linux normally only traps INTs performed from or destined to BIOSSEG - * for us to handle, if the int_revectored table is empty. Filling the - * interrupt table with calls to INT stubs in BIOSSEG allows DOS programs - * to hook interrupts, as well as use their familiar retf tricks to call - * them, AND let Wine handle any unhooked interrupts transparently. - */ -static void DOSMEM_FillIsrTable(void) -{ - SEGPTR *isr = (SEGPTR*)DOSMEM_sysmem; - int x; - - for (x=0; x<256; x++) isr[x]=MAKESEGPTR(VM_STUB_SEGMENT,x*4); -} - -static void DOSMEM_MakeIsrStubs(void) -{ - DWORD *stub = (DWORD*)(DOSMEM_dosmem + (VM_STUB_SEGMENT << 4)); - int x; - - for (x=0; x<256; x++) stub[x]=VM_STUB(x); -} - -static BIOSDATA * DOSMEM_BiosData(void) -{ - return (BIOSDATA *)(DOSMEM_sysmem + 0x400); -} - -/********************************************************************** - * DOSMEM_GetTicksSinceMidnight - * - * Return number of clock ticks since midnight. - */ -static DWORD DOSMEM_GetTicksSinceMidnight(void) -{ - SYSTEMTIME time; - - /* This should give us the (approximately) correct - * 18.206 clock ticks per second since midnight. - */ - - GetLocalTime( &time ); - - return (((time.wHour * 3600 + time.wMinute * 60 + - time.wSecond) * 18206) / 1000) + - (time.wMilliseconds * 1000 / 54927); -} - -/*********************************************************************** - * DOSMEM_FillBiosSegments - * - * Fill the BIOS data segment with dummy values. - */ -static void DOSMEM_FillBiosSegments(void) -{ - char *pBiosSys = DOSMEM_dosmem + 0xf0000; - BYTE *pBiosROMTable = pBiosSys+0xe6f5; - BIOSDATA *pBiosData = DOSMEM_BiosData(); - - /* Clear all unused values */ - memset( pBiosData, 0, sizeof(*pBiosData) ); - - /* FIXME: should check the number of configured drives and ports */ - pBiosData->Com1Addr = 0x3f8; - pBiosData->Com2Addr = 0x2f8; - pBiosData->Lpt1Addr = 0x378; - pBiosData->Lpt2Addr = 0x278; - pBiosData->InstalledHardware = 0x5463; - pBiosData->MemSize = 640; - pBiosData->NextKbdCharPtr = 0x1e; - pBiosData->FirstKbdCharPtr = 0x1e; - pBiosData->VideoMode = 3; - pBiosData->VideoColumns = 80; - pBiosData->VideoPageSize = 80 * 25 * 2; - pBiosData->VideoPageStartAddr = 0xb800; - pBiosData->VideoCtrlAddr = 0x3d4; - pBiosData->Ticks = DOSMEM_GetTicksSinceMidnight(); - pBiosData->NbHardDisks = 2; - pBiosData->KbdBufferStart = 0x1e; - pBiosData->KbdBufferEnd = 0x3e; - pBiosData->RowsOnScreenMinus1 = 24; - pBiosData->BytesPerChar = 0x10; - pBiosData->ModeOptions = 0x64; - pBiosData->FeatureBitsSwitches = 0xf9; - pBiosData->VGASettings = 0x51; - pBiosData->DisplayCombination = 0x08; - pBiosData->DiskDataRate = 0; - - /* fill ROM configuration table (values from Award) */ - *(pBiosROMTable+0x0) = 0x08; /* number of bytes following LO */ - *(pBiosROMTable+0x1) = 0x00; /* number of bytes following HI */ - *(pBiosROMTable+0x2) = 0xfc; /* model */ - *(pBiosROMTable+0x3) = 0x01; /* submodel */ - *(pBiosROMTable+0x4) = 0x00; /* BIOS revision */ - *(pBiosROMTable+0x5) = 0x74; /* feature byte 1 */ - *(pBiosROMTable+0x6) = 0x00; /* feature byte 2 */ - *(pBiosROMTable+0x7) = 0x00; /* feature byte 3 */ - *(pBiosROMTable+0x8) = 0x00; /* feature byte 4 */ - *(pBiosROMTable+0x9) = 0x00; /* feature byte 5 */ - - /* BIOS date string */ - strcpy(pBiosSys+0xfff5, "13/01/99"); - - /* BIOS ID */ - *(pBiosSys+0xfffe) = 0xfc; - - /* Reboot vector (f000:fff0 or ffff:0000) */ - *(DWORD*)(pBiosSys + 0xfff0) = VM_STUB(0x19); -} - -/*********************************************************************** - * DOSMEM_InitMemory - * - * Initialises the DOS memory structures. - */ -static void DOSMEM_InitMemory(void) -{ - dosmem_info* info_block = DOSMEM_InfoBlock(); - dosmem_entry* root_block = DOSMEM_RootBlock(); - dosmem_entry* dm; - - root_block->size = DOSMEM_MemoryTop() - (((char*)root_block) + sizeof(dosmem_entry)); - - info_block->blocks = 0; - info_block->free = root_block->size; - - dm = NEXT_BLOCK(root_block); - dm->size = DM_BLOCK_TERMINAL; - root_block->size |= DM_BLOCK_FREE -#ifdef __DOSMEM_DEBUG__ - | DM_BLOCK_DEBUG -#endif - ; - - TRACE( "DOS conventional memory initialized, %d bytes free.\n", - DOSMEM_Available() ); + return EXCEPTION_CONTINUE_SEARCH; } - /********************************************************************** * setup_dos_mem * * Setup the first megabyte for DOS memory access */ -static void setup_dos_mem( int dos_init ) +static char* setup_dos_mem(void) { int sys_offset = 0; int page_size = getpagesize(); void *addr = NULL; - if (wine_mmap_is_in_reserved_area( NULL, 0x110000 ) != 1) + if (wine_mmap_is_in_reserved_area( NULL, DOSMEM_SIZE ) != 1) { - addr = wine_anon_mmap( (void *)page_size, 0x110000-page_size, + addr = wine_anon_mmap( (void *)page_size, DOSMEM_SIZE-page_size, PROT_READ | PROT_WRITE | PROT_EXEC, 0 ); if (addr == (void *)page_size) addr = NULL; /* we got what we wanted */ - else munmap( addr, 0x110000 - page_size ); + else munmap( addr, DOSMEM_SIZE - page_size ); } if (!addr) { - /* now map from address 0 */ - wine_anon_mmap( NULL, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED ); - - /* inform the memory manager that there is a mapping here */ - VirtualAlloc( addr, 0x110000, MEM_RESERVE | MEM_SYSTEM, PAGE_EXECUTE_READWRITE ); + /* now reserve from address 0 */ + wine_anon_mmap( NULL, DOSMEM_SIZE, 0, MAP_FIXED ); - /* protect the first 64K to catch NULL pointers */ - if (!dos_init) - { - VirtualProtect( addr, 0x10000, PAGE_NOACCESS, NULL ); - /* move the BIOS and ISR area from 0x00000 to 0xf0000 */ - sys_offset += 0xf0000; - } + /* inform the memory manager that there is a mapping here, but don't commit yet */ + VirtualAlloc( NULL, DOSMEM_SIZE, MEM_RESERVE | MEM_SYSTEM, PAGE_NOACCESS ); + sys_offset = 0xf0000; + DOSMEM_protect = DOSMEM_64KB; } else { ERR("Cannot use first megabyte for DOS address space, please report\n" ); - if (dos_init) ExitProcess(1); /* allocate the DOS area somewhere else */ - addr = VirtualAlloc( NULL, 0x110000, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); + addr = VirtualAlloc( NULL, DOSMEM_SIZE, MEM_RESERVE, PAGE_NOACCESS ); if (!addr) { ERR( "Cannot allocate DOS memory\n" ); @@ -340,7 +191,8 @@ } } DOSMEM_dosmem = addr; - DOSMEM_sysmem = (char*)addr + sys_offset; + RtlAddVectoredExceptionHandler(FALSE, dosmem_handler); + return (char*)addr + sys_offset; } @@ -350,280 +202,20 @@ * Create the dos memory segments, and store them into the KERNEL * exported values. */ -BOOL DOSMEM_Init(BOOL dos_init) +BOOL DOSMEM_Init(void) { - static int already_done, already_mapped; + char* sysmem = setup_dos_mem(); - if (!already_done) - { - setup_dos_mem( dos_init ); + DOSMEM_0000H = GLOBAL_CreateBlock( GMEM_FIXED, sysmem, + DOSMEM_64KB, 0, WINE_LDT_FLAGS_DATA ); + DOSMEM_BiosDataSeg = GLOBAL_CreateBlock( GMEM_FIXED, sysmem + 0x400, + 0x100, 0, WINE_LDT_FLAGS_DATA ); + DOSMEM_BiosSysSeg = GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem + 0xf0000, + DOSMEM_64KB, 0, WINE_LDT_FLAGS_DATA ); - DOSMEM_0000H = GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_sysmem, - 0x10000, 0, WINE_LDT_FLAGS_DATA ); - DOSMEM_BiosDataSeg = GLOBAL_CreateBlock(GMEM_FIXED,DOSMEM_sysmem + 0x400, - 0x100, 0, WINE_LDT_FLAGS_DATA ); - DOSMEM_BiosSysSeg = GLOBAL_CreateBlock(GMEM_FIXED,DOSMEM_dosmem+0xf0000, - 0x10000, 0, WINE_LDT_FLAGS_DATA ); - DOSMEM_FillBiosSegments(); - DOSMEM_FillIsrTable(); - already_done = 1; - } - else if (dos_init && !already_mapped) - { - if (DOSMEM_dosmem) - { - ERR( "Needs access to the first megabyte for DOS mode\n" ); - ExitProcess(1); - } - MESSAGE( "Warning: unprotecting the first 64KB of memory to allow real-mode calls.\n" - " NULL pointer accesses will no longer be caught.\n" ); - VirtualProtect( NULL, 0x10000, PAGE_EXECUTE_READWRITE, NULL ); - /* copy the BIOS and ISR area down */ - memcpy( DOSMEM_dosmem, DOSMEM_sysmem, 0x400 + 0x100 ); - DOSMEM_sysmem = DOSMEM_dosmem; - SetSelectorBase( DOSMEM_0000H, 0 ); - SetSelectorBase( DOSMEM_BiosDataSeg, 0x400 ); - /* we may now need the actual interrupt stubs, and since we've just moved the - * interrupt vector table away, we can fill the area with stubs instead... */ - DOSMEM_MakeIsrStubs(); - already_mapped = 1; - } return TRUE; } - -/*********************************************************************** - * DOSMEM_Tick - * - * Increment the BIOS tick counter. Called by timer signal handler. - */ -void DOSMEM_Tick( WORD timer ) -{ - BIOSDATA *pBiosData = DOSMEM_BiosData(); - if (pBiosData) pBiosData->Ticks++; -} - -/*********************************************************************** - * DOSMEM_GetBlock - * - * Carve a chunk of the DOS memory block (without selector). - */ -LPVOID DOSMEM_GetBlock(UINT size, UINT16* pseg) -{ - UINT blocksize; - char *block = NULL; - dosmem_info *info_block = DOSMEM_InfoBlock(); - dosmem_entry *dm; -#ifdef __DOSMEM_DEBUG_ - dosmem_entry *prev = NULL; -#endif - - if( size > info_block->free ) return NULL; - dm = DOSMEM_RootBlock(); - - while (dm && dm->size != DM_BLOCK_TERMINAL) - { -#ifdef __DOSMEM_DEBUG__ - if( (dm->size & DM_BLOCK_DEBUG) != DM_BLOCK_DEBUG ) - { - WARN("MCB overrun! [prev = 0x%08x]\n", 4 + (UINT)prev); - return NULL; - } - prev = dm; -#endif - if( dm->size & DM_BLOCK_FREE ) - { - dosmem_entry *next = NEXT_BLOCK(dm); - - while( next->size & DM_BLOCK_FREE ) /* collapse free blocks */ - { - dm->size += sizeof(dosmem_entry) + (next->size & DM_BLOCK_MASK); - next->size = (DM_BLOCK_FREE | DM_BLOCK_TERMINAL); - next = NEXT_BLOCK(dm); - } - - blocksize = dm->size & DM_BLOCK_MASK; - if( blocksize >= size ) - { - block = ((char*)dm) + sizeof(dosmem_entry); - if( blocksize - size > 0x20 ) - { - /* split dm so that the next one stays - * paragraph-aligned (and dm loses free bit) */ - - dm->size = (((size + 0xf + sizeof(dosmem_entry)) & ~0xf) - - sizeof(dosmem_entry)); - next = (dosmem_entry*)(((char*)dm) + - sizeof(dosmem_entry) + dm->size); - next->size = (blocksize - (dm->size + - sizeof(dosmem_entry))) | DM_BLOCK_FREE -#ifdef __DOSMEM_DEBUG__ - | DM_BLOCK_DEBUG -#endif - ; - } else dm->size &= DM_BLOCK_MASK; - - info_block->blocks++; - info_block->free -= dm->size; - if( pseg ) *pseg = (block - DOSMEM_dosmem) >> 4; -#ifdef __DOSMEM_DEBUG__ - dm->size |= DM_BLOCK_DEBUG; -#endif - break; - } - dm = next; - } - else dm = NEXT_BLOCK(dm); - } - return (LPVOID)block; -} - -/*********************************************************************** - * DOSMEM_FreeBlock - */ -BOOL DOSMEM_FreeBlock(void* ptr) -{ - dosmem_info *info_block = DOSMEM_InfoBlock(); - - if( ptr >= (void*)(((char*)DOSMEM_RootBlock()) + sizeof(dosmem_entry)) && - ptr < (void*)DOSMEM_MemoryTop() && !((((char*)ptr) - - DOSMEM_dosmem) & 0xf) ) - { - dosmem_entry *dm = (dosmem_entry*)(((char*)ptr) - sizeof(dosmem_entry)); - - if( !(dm->size & (DM_BLOCK_FREE | DM_BLOCK_TERMINAL)) -#ifdef __DOSMEM_DEBUG__ - && ((dm->size & DM_BLOCK_DEBUG) == DM_BLOCK_DEBUG ) -#endif - ) - { - info_block->blocks--; - info_block->free += dm->size; - - dm->size |= DM_BLOCK_FREE; - return TRUE; - } - } - return FALSE; -} - -/*********************************************************************** - * DOSMEM_ResizeBlock - * - * Resize DOS memory block in place. Returns block size or -1 on error. - * - * If exact is TRUE, returned value is either old or requested block - * size. If exact is FALSE, block is expanded even if there is not - * enough space for full requested block size. - */ -UINT DOSMEM_ResizeBlock(void *ptr, UINT size, BOOL exact) -{ - char *block = NULL; - dosmem_info *info_block = DOSMEM_InfoBlock(); - dosmem_entry *dm; - dosmem_entry *next; - UINT blocksize; - UINT orgsize; - - if( (ptr < (void*)(sizeof(dosmem_entry) + (char*)DOSMEM_RootBlock())) || - (ptr >= (void*)DOSMEM_MemoryTop()) || - (((((char*)ptr) - DOSMEM_dosmem) & 0xf) != 0) ) - return (UINT)-1; - - dm = (dosmem_entry*)(((char*)ptr) - sizeof(dosmem_entry)); - if( dm->size & (DM_BLOCK_FREE | DM_BLOCK_TERMINAL) ) - return (UINT)-1; - - next = NEXT_BLOCK(dm); - orgsize = dm->size & DM_BLOCK_MASK; - - /* collapse free blocks */ - while( next->size & DM_BLOCK_FREE ) - { - dm->size += sizeof(dosmem_entry) + (next->size & DM_BLOCK_MASK); - next->size = (DM_BLOCK_FREE | DM_BLOCK_TERMINAL); - next = NEXT_BLOCK(dm); - } - - blocksize = dm->size & DM_BLOCK_MASK; - - /* - * If collapse didn't help we either expand block to maximum - * available size (exact == FALSE) or give collapsed blocks - * back to free storage (exact == TRUE). - */ - if (blocksize < size) - size = exact ? orgsize : blocksize; - - block = ((char*)dm) + sizeof(dosmem_entry); - if( blocksize - size > 0x20 ) - { - /* - * split dm so that the next one stays - * paragraph-aligned (and next gains free bit) - */ - - dm->size = (((size + 0xf + sizeof(dosmem_entry)) & ~0xf) - - sizeof(dosmem_entry)); - next = (dosmem_entry*)(((char*)dm) + - sizeof(dosmem_entry) + dm->size); - next->size = (blocksize - (dm->size + - sizeof(dosmem_entry))) | DM_BLOCK_FREE; - } - else - { - dm->size &= DM_BLOCK_MASK; - } - - /* - * Adjust available memory if block size changes. - */ - info_block->free += orgsize - dm->size; - - return size; -} - -/*********************************************************************** - * DOSMEM_Available - */ -UINT DOSMEM_Available(void) -{ - UINT blocksize, available = 0; - dosmem_entry *dm; - - dm = DOSMEM_RootBlock(); - - while (dm && dm->size != DM_BLOCK_TERMINAL) - { -#ifdef __DOSMEM_DEBUG__ - if( (dm->size & DM_BLOCK_DEBUG) != DM_BLOCK_DEBUG ) - { - WARN("MCB overrun! [prev = 0x%08x]\n", 4 + (UINT)prev); - return NULL; - } - prev = dm; -#endif - if( dm->size & DM_BLOCK_FREE ) - { - dosmem_entry *next = NEXT_BLOCK(dm); - - while( next->size & DM_BLOCK_FREE ) /* collapse free blocks */ - { - dm->size += sizeof(dosmem_entry) + (next->size & DM_BLOCK_MASK); - next->size = (DM_BLOCK_FREE | DM_BLOCK_TERMINAL); - next = NEXT_BLOCK(dm); - } - - blocksize = dm->size & DM_BLOCK_MASK; - if ( blocksize > available ) available = blocksize; - dm = next; - } - else dm = NEXT_BLOCK(dm); - } - return available; -} - - /*********************************************************************** * DOSMEM_MapLinearToDos * @@ -632,7 +224,7 @@ UINT DOSMEM_MapLinearToDos(LPVOID ptr) { if (((char*)ptr >= DOSMEM_dosmem) && - ((char*)ptr < DOSMEM_dosmem + 0x100000)) + ((char*)ptr < DOSMEM_dosmem + DOSMEM_SIZE)) return (UINT)ptr - (UINT)DOSMEM_dosmem; return (UINT)ptr; } @@ -645,7 +237,7 @@ */ LPVOID DOSMEM_MapDosToLinear(UINT ptr) { - if (ptr < 0x100000) return (LPVOID)(ptr + (UINT)DOSMEM_dosmem); + if (ptr < DOSMEM_SIZE) return (LPVOID)(ptr + (UINT)DOSMEM_dosmem); return (LPVOID)ptr; } @@ -659,7 +251,7 @@ { LPVOID lin; - lin=DOSMEM_dosmem+(x&0xffff)+(((x&0xffff0000)>>16)*16); + lin = DOSMEM_dosmem + HIWORD(x) * 16 + LOWORD(x); TRACE_(selector)("(0x%08lx) returns %p.\n", x, lin ); return lin; } @@ -674,7 +266,7 @@ HMODULE16 hModule = GetModuleHandle16("KERNEL"); WORD sel; - sel=GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+realsel*16, 0x10000, + sel=GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+realsel*16, DOSMEM_64KB, hModule, WINE_LDT_FLAGS_DATA ); TRACE_(selector)("(0x%04x) returns 0x%04x.\n", realsel,sel); return sel; diff -urN wine-20050419/dlls/kernel/error16.c wine-20050524/dlls/kernel/error16.c --- wine-20050419/dlls/kernel/error16.c 2003-09-06 01:08:37.000000000 +0200 +++ wine-20050524/dlls/kernel/error16.c 2005-05-16 16:45:18.000000000 +0200 @@ -25,7 +25,7 @@ #include "windef.h" #include "winbase.h" -#include "stackframe.h" +#include "wine/winbase16.h" #include "wine/debug.h" diff -urN wine-20050419/dlls/kernel/file.c wine-20050524/dlls/kernel/file.c --- wine-20050419/dlls/kernel/file.c 2005-03-30 21:02:15.000000000 +0200 +++ wine-20050524/dlls/kernel/file.c 2005-05-24 14:50:24.000000000 +0200 @@ -451,6 +451,16 @@ status = NtWriteFile(hFile, hEvent, NULL, NULL, piosb, buffer, bytesToWrite, poffset, NULL); + /* FIXME: NtWriteFile does not always cause page faults, generate them now */ + if (status == STATUS_INVALID_USER_BUFFER && !IsBadReadPtr( buffer, bytesToWrite )) + { + status = NtWriteFile(hFile, hEvent, NULL, NULL, piosb, + buffer, bytesToWrite, poffset, NULL); + if (status != STATUS_INVALID_USER_BUFFER) + FIXME("Could not access memory (%p,%ld) at first, now OK. Protected by DIBSection code?\n", + buffer, bytesToWrite); + } + if (status != STATUS_PENDING && bytesWritten) *bytesWritten = piosb->Information; diff -urN wine-20050419/dlls/kernel/global16.c wine-20050524/dlls/kernel/global16.c --- wine-20050419/dlls/kernel/global16.c 2004-12-23 19:48:47.000000000 +0100 +++ wine-20050524/dlls/kernel/global16.c 2005-05-16 21:44:54.000000000 +0200 @@ -40,9 +40,8 @@ #include "wine/winbase16.h" #include "ntstatus.h" #include "toolhelp.h" -#include "miscemu.h" -#include "stackframe.h" #include "kernel_private.h" +#include "kernel16_private.h" #include "wine/debug.h" #include "winerror.h" @@ -77,6 +76,23 @@ #define VALID_HANDLE(handle) (((handle)>>__AHSHIFT)> __AHSHIFT)) +static inline void* DOSMEM_AllocBlock(UINT size, UINT16* pseg) +{ + if (!winedos.AllocDosBlock) load_winedos(); + return winedos.AllocDosBlock ? winedos.AllocDosBlock(size, pseg) : NULL; +} + +static inline BOOL DOSMEM_FreeBlock(void* ptr) +{ + if (!winedos.FreeDosBlock) load_winedos(); + return winedos.FreeDosBlock ? winedos.FreeDosBlock( ptr ) : FALSE; +} + +static inline UINT DOSMEM_ResizeBlock(void *ptr, UINT size, BOOL exact) +{ + if (!winedos.ResizeDosBlock) load_winedos(); + return winedos.ResizeDosBlock ? winedos.ResizeDosBlock(ptr, size, TRUE) : 0; +} /*********************************************************************** * GLOBAL_GetArena @@ -336,7 +352,7 @@ newptr = 0; else { - newptr = DOSMEM_GetBlock( size, 0 ); + newptr = DOSMEM_AllocBlock( size, 0 ); if (newptr) { memcpy( newptr, ptr, oldsize ); @@ -757,7 +773,7 @@ DWORD size /* [in] Number of bytes to be allocated */ ) { UINT16 uParagraph; - LPVOID lpBlock = DOSMEM_GetBlock( size, &uParagraph ); + LPVOID lpBlock = DOSMEM_AllocBlock( size, &uParagraph ); if( lpBlock ) { diff -urN wine-20050419/dlls/kernel/heap.c wine-20050524/dlls/kernel/heap.c --- wine-20050419/dlls/kernel/heap.c 2005-03-24 22:01:38.000000000 +0100 +++ wine-20050524/dlls/kernel/heap.c 2005-05-07 20:25:51.000000000 +0200 @@ -980,7 +980,7 @@ * * The SEGPTR is used by the caller! */ -void AllocMappedBuffer( CONTEXT86 *context ) +void WINAPI __regs_AllocMappedBuffer( CONTEXT86 *context ) { HGLOBAL handle = GlobalAlloc(0, context->Edi + 8); DWORD *buffer = (DWORD *)GlobalLock(handle); @@ -1004,7 +1004,9 @@ context->Edi = (DWORD)(buffer + 2); } } - +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( AllocMappedBuffer, 0, 0 ); +#endif /********************************************************************** * FreeMappedBuffer (KERNEL32.39) @@ -1013,7 +1015,7 @@ * * Input: EDI register: pointer to buffer */ -void FreeMappedBuffer( CONTEXT86 *context ) +void WINAPI __regs_FreeMappedBuffer( CONTEXT86 *context ) { if (context->Edi) { @@ -1025,6 +1027,9 @@ GlobalFree((HGLOBAL)buffer[0]); } } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( FreeMappedBuffer, 0, 0 ); +#endif /*********************************************************************** * GlobalMemoryStatusEx (KERNEL32.@) diff -urN wine-20050419/dlls/kernel/instr.c wine-20050524/dlls/kernel/instr.c --- wine-20050419/dlls/kernel/instr.c 2005-03-23 14:15:19.000000000 +0100 +++ wine-20050524/dlls/kernel/instr.c 2005-05-24 14:34:30.000000000 +0200 @@ -29,11 +29,10 @@ #include "wingdi.h" #include "wine/winuser16.h" #include "excpt.h" -#include "module.h" -#include "miscemu.h" +#include "thread.h" #include "wine/debug.h" #include "kernel_private.h" -#include "thread.h" +#include "kernel16_private.h" #include "wine/exception.h" WINE_DEFAULT_DEBUG_CHANNEL(int); @@ -67,34 +66,6 @@ return wine_ldt_get_ptr( context->SegSs, context->Esp ); } - -static void (WINAPI *DOS_EmulateInterruptPM)( CONTEXT86 *context, BYTE intnum ); -static void (WINAPI *DOS_CallBuiltinHandler)( CONTEXT86 *context, BYTE intnum ); -static DWORD (WINAPI *DOS_inport)( int port, int size ); -static void (WINAPI *DOS_outport)( int port, int size, DWORD val ); - - -static void init_winedos(void) -{ - static HMODULE module; - - if (module) return; - module = LoadLibraryA( "winedos.dll" ); - if (!module) - { - ERR("could not load winedos.dll, DOS subsystem unavailable\n"); - module = (HMODULE)1; /* don't try again */ - return; - } -#define GET_ADDR(func) DOS_##func = (void *)GetProcAddress(module, #func); - GET_ADDR(inport); - GET_ADDR(outport); - GET_ADDR(EmulateInterruptPM); - GET_ADDR(CallBuiltinHandler); -#undef GET_ADDR -} - - /*********************************************************************** * INSTR_ReplaceSelector * @@ -112,7 +83,11 @@ { static WORD sys_timer = 0; if (!sys_timer) - sys_timer = CreateSystemTimer( 55, DOSMEM_Tick ); + { + if (!winedos.BiosTick) load_winedos(); + if (winedos.BiosTick) + sys_timer = CreateSystemTimer( 55, winedos.BiosTick ); + } *sel = DOSMEM_BiosDataSeg; return TRUE; } @@ -128,7 +103,7 @@ static BYTE *INSTR_GetOperandAddr( CONTEXT86 *context, BYTE *instr, int long_addr, int segprefix, int *len ) { - int mod, rm, base, index = 0, ss = 0, seg = 0, off; + int mod, rm, base = 0, index = 0, ss = 0, seg = 0, off; LDT_ENTRY entry; #define GET_VAL(val,type) \ @@ -367,8 +342,8 @@ { DWORD res = ~0U; - if (!DOS_inport) init_winedos(); - if (DOS_inport) res = DOS_inport( port, size ); + if (!winedos.inport) load_winedos(); + if (winedos.inport) res = winedos.inport( port, size ); if (TRACE_ON(io)) { @@ -399,8 +374,8 @@ */ static void INSTR_outport( WORD port, int size, DWORD val, CONTEXT86 *context ) { - if (!DOS_outport) init_winedos(); - if (DOS_outport) DOS_outport( port, size, val ); + if (!winedos.outport) load_winedos(); + if (winedos.outport) winedos.outport( port, size, val ); if (TRACE_ON(io)) { @@ -733,11 +708,11 @@ case 0xcd: /* int */ if (wine_ldt_is_system(context->SegCs)) break; /* don't emulate it in 32-bit code */ - if (!DOS_EmulateInterruptPM) init_winedos(); - if (DOS_EmulateInterruptPM) + if (!winedos.EmulateInterruptPM) load_winedos(); + if (winedos.EmulateInterruptPM) { context->Eip += prefixlen + 2; - DOS_EmulateInterruptPM( context, instr[1] ); + winedos.EmulateInterruptPM( context, instr[1] ); return ExceptionContinueExecution; } break; /* Unable to emulate it */ @@ -839,8 +814,8 @@ */ void INSTR_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum ) { - if (!DOS_CallBuiltinHandler) init_winedos(); - if (DOS_CallBuiltinHandler) DOS_CallBuiltinHandler( context, intnum ); + if (!winedos.CallBuiltinHandler) load_winedos(); + if (winedos.CallBuiltinHandler) winedos.CallBuiltinHandler( context, intnum ); } diff -urN wine-20050419/dlls/kernel/kernel16_private.h wine-20050524/dlls/kernel/kernel16_private.h --- wine-20050419/dlls/kernel/kernel16_private.h 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/kernel/kernel16_private.h 2005-05-23 14:15:26.000000000 +0200 @@ -0,0 +1,247 @@ +/* + * Kernel 16-bit private definitions + * + * Copyright 1995 Alexandre Julliard + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __WINE_KERNEL16_PRIVATE_H +#define __WINE_KERNEL16_PRIVATE_H + +#include "wine/winbase16.h" +#include "winreg.h" +#include "winternl.h" + +#include "pshpack1.h" + +/* In-memory module structure. See 'Windows Internals' p. 219 */ +typedef struct _NE_MODULE +{ + WORD ne_magic; /* 00 'NE' signature */ + WORD count; /* 02 Usage count (ne_ver/ne_rev on disk) */ + WORD ne_enttab; /* 04 Near ptr to entry table */ + HMODULE16 next; /* 06 Selector to next module (ne_cbenttab on disk) */ + WORD dgroup_entry; /* 08 Near ptr to segment entry for DGROUP (ne_crc on disk) */ + WORD fileinfo; /* 0a Near ptr to file info (OFSTRUCT) (ne_crc on disk) */ + WORD ne_flags; /* 0c Module flags */ + WORD ne_autodata; /* 0e Logical segment for DGROUP */ + WORD ne_heap; /* 10 Initial heap size */ + WORD ne_stack; /* 12 Initial stack size */ + DWORD ne_csip; /* 14 Initial cs:ip */ + DWORD ne_sssp; /* 18 Initial ss:sp */ + WORD ne_cseg; /* 1c Number of segments in segment table */ + WORD ne_cmod; /* 1e Number of module references */ + WORD ne_cbnrestab; /* 20 Size of non-resident names table */ + WORD ne_segtab; /* 22 Near ptr to segment table */ + WORD ne_rsrctab; /* 24 Near ptr to resource table */ + WORD ne_restab; /* 26 Near ptr to resident names table */ + WORD ne_modtab; /* 28 Near ptr to module reference table */ + WORD ne_imptab; /* 2a Near ptr to imported names table */ + DWORD ne_nrestab; /* 2c File offset of non-resident names table */ + WORD ne_cmovent; /* 30 Number of moveable entries in entry table*/ + WORD ne_align; /* 32 Alignment shift count */ + WORD ne_cres; /* 34 # of resource segments */ + BYTE ne_exetyp; /* 36 Operating system flags */ + BYTE ne_flagsothers; /* 37 Misc. flags */ + HANDLE16 dlls_to_init; /* 38 List of DLLs to initialize (ne_pretthunks on disk) */ + HANDLE16 nrname_handle; /* 3a Handle to non-resident name table (ne_psegrefbytes on disk) */ + WORD ne_swaparea; /* 3c Min. swap area size */ + WORD ne_expver; /* 3e Expected Windows version */ + /* From here, these are extra fields not present in normal Windows */ + HMODULE module32; /* PE module handle for Win32 modules */ + HMODULE owner32; /* PE module containing this one for 16-bit builtins */ + HMODULE16 self; /* Handle for this module */ + WORD self_loading_sel; /* Selector used for self-loading apps. */ + LPVOID rsrc32_map; /* HRSRC 16->32 map (for 32-bit modules) */ + LPCVOID mapping; /* mapping of the binary file */ + SIZE_T mapping_size; /* size of the file mapping */ +} NE_MODULE; + +typedef struct +{ + BYTE type; + BYTE flags; + BYTE segnum; + WORD offs; +} ET_ENTRY; + +typedef struct +{ + WORD first; /* ordinal */ + WORD last; /* ordinal */ + WORD next; /* bundle */ +} ET_BUNDLE; + + + /* In-memory segment table */ +typedef struct +{ + WORD filepos; /* Position in file, in sectors */ + WORD size; /* Segment size on disk */ + WORD flags; /* Segment flags */ + WORD minsize; /* Min. size of segment in memory */ + HANDLE16 hSeg; /* Selector or handle (selector - 1) of segment in memory */ +} SEGTABLEENTRY; + +/* this structure is always located at offset 0 of the DGROUP segment */ +typedef struct +{ + WORD null; /* Always 0 */ + DWORD old_ss_sp; /* Stack pointer; used by SwitchTaskTo() */ + WORD heap; /* Pointer to the local heap information (if any) */ + WORD atomtable; /* Pointer to the local atom table (if any) */ + WORD stacktop; /* Top of the stack */ + WORD stackmin; /* Lowest stack address used so far */ + WORD stackbottom; /* Bottom of the stack */ +} INSTANCEDATA; + +/* relay entry points */ + +#ifdef __i386__ + +typedef struct +{ + WORD pushw_bp; /* pushw %bp */ + BYTE pushl; /* pushl $target */ + void (*target)(); + WORD call; /* call CALLFROM16 */ + short callfrom16; +} ENTRYPOINT16; + +typedef struct +{ + BYTE pushl; /* pushl $relay */ + void *relay; + BYTE lcall; /* lcall __FLATCS__:glue */ + void *glue; + WORD flatcs; + WORD lret; /* lret $nArgs */ + WORD nArgs; + DWORD arg_types[2]; /* type of each argument */ +} CALLFROM16; + +#else /* __i386__ */ + +typedef struct +{ + void (*target)(); + WORD call; /* call CALLFROM16 */ + short callfrom16; +} ENTRYPOINT16; + +typedef struct +{ + WORD lret; /* lret $nArgs */ + WORD nArgs; + DWORD arg_types[2]; /* type of each argument */ +} CALLFROM16; + +#endif /* __i386__ */ + +/* THHOOK Kernel Data Structure */ +typedef struct _THHOOK +{ + HANDLE16 hGlobalHeap; /* 00 (handle BURGERMASTER) */ + WORD pGlobalHeap; /* 02 (selector BURGERMASTER) */ + HMODULE16 hExeHead; /* 04 hFirstModule */ + HMODULE16 hExeSweep; /* 06 (unused) */ + HANDLE16 TopPDB; /* 08 (handle of KERNEL PDB) */ + HANDLE16 HeadPDB; /* 0A (first PDB in list) */ + HANDLE16 TopSizePDB; /* 0C (unused) */ + HTASK16 HeadTDB; /* 0E hFirstTask */ + HTASK16 CurTDB; /* 10 hCurrentTask */ + HTASK16 LoadTDB; /* 12 (unused) */ + HTASK16 LockTDB; /* 14 hLockedTask */ +} THHOOK; + +extern THHOOK *pThhook; + +#include "poppack.h" + +#define NE_SEG_TABLE(pModule) \ + ((SEGTABLEENTRY *)((char *)(pModule) + (pModule)->ne_segtab)) + +#define NE_MODULE_NAME(pModule) \ + (((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName) + +#define NE_GET_DATA(pModule,offset,size) \ + ((const void *)(((offset)+(size) <= pModule->mapping_size) ? \ + (const char *)pModule->mapping + (offset) : NULL)) + +#define NE_READ_DATA(pModule,buffer,offset,size) \ + (((offset)+(size) <= pModule->mapping_size) ? \ + (memcpy( buffer, (const char *)pModule->mapping + (offset), (size) ), TRUE) : FALSE) + +#define CURRENT_STACK16 ((STACK16FRAME*)MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved)) +#define CURRENT_DS (CURRENT_STACK16->ds) + +/* push bytes on the 16-bit stack of a thread; return a segptr to the first pushed byte */ +static inline SEGPTR stack16_push( int size ) +{ + STACK16FRAME *frame = CURRENT_STACK16; + memmove( (char*)frame - size, frame, sizeof(*frame) ); + NtCurrentTeb()->WOW32Reserved = (char *)NtCurrentTeb()->WOW32Reserved - size; + return (SEGPTR)((char *)NtCurrentTeb()->WOW32Reserved + sizeof(*frame)); +} + +/* pop bytes from the 16-bit stack of a thread */ +static inline void stack16_pop( int size ) +{ + STACK16FRAME *frame = CURRENT_STACK16; + memmove( (char*)frame + size, frame, sizeof(*frame) ); + NtCurrentTeb()->WOW32Reserved = (char *)NtCurrentTeb()->WOW32Reserved + size; +} + +/* ne_module.c */ +extern NE_MODULE *NE_GetPtr( HMODULE16 hModule ); +extern WORD NE_GetOrdinal( HMODULE16 hModule, const char *name ); +extern FARPROC16 WINAPI NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal ); +extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop ); +extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset ); +extern DWORD NE_StartTask(void); + +/* ne_segment.c */ +extern BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ); +extern BOOL NE_LoadAllSegments( NE_MODULE *pModule ); +extern BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum ); +extern BOOL NE_CreateAllSegments( NE_MODULE *pModule ); +extern HINSTANCE16 NE_GetInstance( NE_MODULE *pModule ); +extern void NE_InitializeDLLs( HMODULE16 hModule ); +extern void NE_DllProcessAttach( HMODULE16 hModule ); +extern void NE_CallUserSignalProc( HMODULE16 hModule, UINT16 code ); + +/* selector.c */ +extern WORD SELECTOR_AllocBlock( const void *base, DWORD size, unsigned char flags ); +extern WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size ); +extern void SELECTOR_FreeBlock( WORD sel ); +#define IS_SELECTOR_32BIT(sel) \ + (wine_ldt_is_system(sel) || (wine_ldt_copy.flags[LOWORD(sel) >> 3] & WINE_LDT_FLAGS_32BIT)) + +/* snoop16.c */ +extern void SNOOP16_RegisterDLL(HMODULE16,LPCSTR); +extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16); +extern int SNOOP16_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname); + +/* task.c */ +extern void TASK_CreateMainTask(void); +extern HTASK16 TASK_SpawnTask( NE_MODULE *pModule, WORD cmdShow, + LPCSTR cmdline, BYTE len, HANDLE *hThread ); +extern void TASK_ExitTask(void); +extern HTASK16 TASK_GetTaskFromThread( DWORD thread ); +extern TDB *TASK_GetCurrent(void); +extern void TASK_InstallTHHook( THHOOK *pNewThook ); + +#endif /* __WINE_KERNEL16_PRIVATE_H */ diff -urN wine-20050419/dlls/kernel/kernel32.spec wine-20050524/dlls/kernel/kernel32.spec --- wine-20050419/dlls/kernel/kernel32.spec 2005-03-29 13:34:03.000000000 +0200 +++ wine-20050524/dlls/kernel/kernel32.spec 2005-05-23 14:14:09.000000000 +0200 @@ -8,15 +8,15 @@ # - code generated by the MS Thunk Compiler # - symbols exported by the Oct 94 beta version of kernel32.dll - 1 stdcall -register -i386 VxDCall0(long) VxDCall - 2 stdcall -register -i386 VxDCall1(long) VxDCall - 3 stdcall -register -i386 VxDCall2(long) VxDCall - 4 stdcall -register -i386 VxDCall3(long) VxDCall - 5 stdcall -register -i386 VxDCall4(long) VxDCall - 6 stdcall -register -i386 VxDCall5(long) VxDCall - 7 stdcall -register -i386 VxDCall6(long) VxDCall - 8 stdcall -register -i386 VxDCall7(long) VxDCall - 9 stdcall -register -i386 VxDCall8(long) VxDCall + 1 stdcall -i386 VxDCall0(long) VxDCall + 2 stdcall -i386 VxDCall1(long) VxDCall + 3 stdcall -i386 VxDCall2(long) VxDCall + 4 stdcall -i386 VxDCall3(long) VxDCall + 5 stdcall -i386 VxDCall4(long) VxDCall + 6 stdcall -i386 VxDCall5(long) VxDCall + 7 stdcall -i386 VxDCall6(long) VxDCall + 8 stdcall -i386 VxDCall7(long) VxDCall + 9 stdcall -i386 VxDCall8(long) VxDCall 10 stdcall k32CharToOemA(str ptr) 11 stdcall k32CharToOemBuffA(str ptr long) 12 stdcall k32OemToCharA(ptr ptr) @@ -24,7 +24,7 @@ 14 stdcall k32LoadStringA(long long ptr long) 15 varargs k32wsprintfA(str str) 16 stdcall k32wvsprintfA(ptr str ptr) - 17 stdcall -register -i386 CommonUnimpStub() + 17 stdcall -i386 CommonUnimpStub() 18 stdcall GetProcessDword(long long) 19 stub ThunkTheTemplateHandle 20 stdcall DosFileHandleToWin32Handle(long) @@ -45,20 +45,20 @@ 35 stdcall LoadLibrary16(str) 36 stdcall FreeLibrary16(long) 37 stdcall GetProcAddress16(long str) WIN32_GetProcAddress16 - 38 stdcall -register -i386 AllocMappedBuffer() - 39 stdcall -register -i386 FreeMappedBuffer() - 40 stdcall -register -i386 OT_32ThkLSF() + 38 stdcall -i386 AllocMappedBuffer() + 39 stdcall -i386 FreeMappedBuffer() + 40 stdcall -i386 OT_32ThkLSF() 41 stdcall ThunkInitLSF(long str long str str) - 42 stdcall -register -i386 LogApiThkLSF(str) + 42 stdcall -i386 LogApiThkLSF(str) 43 stdcall ThunkInitLS(long str long str str) - 44 stdcall -register -i386 LogApiThkSL(str) - 45 stdcall -register -i386 Common32ThkLS() + 44 stdcall -i386 LogApiThkSL(str) + 45 stdcall -i386 Common32ThkLS() 46 stdcall ThunkInitSL(long str long str str) - 47 stdcall -register -i386 LogCBThkSL(str) + 47 stdcall -i386 LogCBThkSL(str) 48 stdcall ReleaseThunkLock(ptr) 49 stdcall RestoreThunkLock(long) - 51 stdcall -register -i386 W32S_BackTo32() + 51 stdcall -i386 W32S_BackTo32() 52 stdcall GetThunkBuff() 53 stdcall GetThunkStuff(str str) 54 stdcall K32WOWCallback16(long long) @@ -96,8 +96,8 @@ 86 stdcall @(ptr) _KERNEL32_86 87 stdcall SSOnBigStack() 88 varargs SSCall(long long ptr) - 89 stdcall -register -i386 FT_PrologPrime() - 90 stdcall -register -i386 QT_ThunkPrime() + 89 stdcall -i386 FT_PrologPrime() + 90 stdcall -i386 QT_ThunkPrime() 91 stdcall PK16FNF(ptr) 92 stdcall GetPK16SysVar() 93 stdcall GetpWin16Lock(ptr) @@ -278,23 +278,23 @@ @ stdcall ExitThread(long) @ stdcall ExpandEnvironmentStringsA(str ptr long) @ stdcall ExpandEnvironmentStringsW(wstr ptr long) -@ stdcall -register -i386 FT_Exit0() -@ stdcall -register -i386 FT_Exit12() -@ stdcall -register -i386 FT_Exit16() -@ stdcall -register -i386 FT_Exit20() -@ stdcall -register -i386 FT_Exit24() -@ stdcall -register -i386 FT_Exit28() -@ stdcall -register -i386 FT_Exit32() -@ stdcall -register -i386 FT_Exit36() -@ stdcall -register -i386 FT_Exit40() -@ stdcall -register -i386 FT_Exit44() -@ stdcall -register -i386 FT_Exit48() -@ stdcall -register -i386 FT_Exit4() -@ stdcall -register -i386 FT_Exit52() -@ stdcall -register -i386 FT_Exit56() -@ stdcall -register -i386 FT_Exit8() -@ stdcall -register -i386 FT_Prolog() -@ stdcall -register -i386 FT_Thunk() +@ stdcall -i386 FT_Exit0() +@ stdcall -i386 FT_Exit12() +@ stdcall -i386 FT_Exit16() +@ stdcall -i386 FT_Exit20() +@ stdcall -i386 FT_Exit24() +@ stdcall -i386 FT_Exit28() +@ stdcall -i386 FT_Exit32() +@ stdcall -i386 FT_Exit36() +@ stdcall -i386 FT_Exit40() +@ stdcall -i386 FT_Exit44() +@ stdcall -i386 FT_Exit48() +@ stdcall -i386 FT_Exit4() +@ stdcall -i386 FT_Exit52() +@ stdcall -i386 FT_Exit56() +@ stdcall -i386 FT_Exit8() +@ stdcall -i386 FT_Prolog() +@ stdcall -i386 FT_Thunk() @ stdcall FatalAppExitA(long str) @ stdcall FatalAppExitW(long wstr) @ stdcall FatalExit(long) @@ -417,8 +417,8 @@ @ stdcall GetFileType(long) @ stdcall GetFullPathNameA(str long ptr ptr) @ stdcall GetFullPathNameW(wstr long ptr ptr) -@ stub GetGeoInfoA -@ stub GetGeoInfoW +@ stdcall GetGeoInfoA(long long ptr long long) +@ stdcall GetGeoInfoW(long long ptr long long) @ stdcall GetHandleContext(long) @ stdcall GetHandleInformation(long ptr) @ stub GetLSCallbackTarget @@ -590,8 +590,8 @@ @ stdcall IsValidCodePage(long) @ stdcall IsValidLanguageGroup(long long) @ stdcall IsValidLocale(long long) -@ stdcall -register -i386 K32Thk1632Epilog() -@ stdcall -register -i386 K32Thk1632Prolog() +@ stdcall -i386 K32Thk1632Epilog() +@ stdcall -i386 K32Thk1632Prolog() @ stdcall LCMapStringA(long long str long ptr long) @ stdcall LCMapStringW(long long wstr long ptr long) @ stdcall LeaveCriticalSection(ptr) ntdll.RtlLeaveCriticalSection @@ -616,10 +616,10 @@ @ stdcall LockFileEx(long long long long long ptr) @ stdcall LockResource(long) @ stdcall MakeCriticalSectionGlobal(ptr) -@ stdcall -register -i386 MapHInstLS() -@ stdcall -register -i386 MapHInstLS_PN() -@ stdcall -register -i386 MapHInstSL() -@ stdcall -register -i386 MapHInstSL_PN() +@ stdcall -i386 MapHInstLS() +@ stdcall -i386 MapHInstLS_PN() +@ stdcall -i386 MapHInstSL() +@ stdcall -i386 MapHInstSL_PN() @ stdcall MapHModuleLS(long) @ stdcall MapHModuleSL(long) @ stdcall MapLS(ptr) @@ -628,7 +628,9 @@ @ stdcall MapViewOfFile(long long long long long) @ stdcall MapViewOfFileEx(long long long long long ptr) @ stdcall Module32First(long ptr) +@ stdcall Module32FirstW(long ptr) @ stdcall Module32Next(long ptr) +@ stdcall Module32NextW(long ptr) @ stdcall MoveFileA(str str) @ stdcall MoveFileExA(str str long) @ stdcall MoveFileExW(wstr wstr long) @@ -666,7 +668,7 @@ @ stdcall Process32NextW (ptr ptr) @ stdcall PulseEvent(long) @ stdcall PurgeComm(long long) -@ stdcall -register -i386 QT_Thunk() +@ stdcall -i386 QT_Thunk() @ stdcall QueryDosDeviceA(str ptr long) @ stdcall QueryDosDeviceW(wstr ptr long) @ stub QueryInformationJobObject @@ -713,26 +715,26 @@ @ stdcall RtlMoveMemory(ptr ptr long) ntdll.RtlMoveMemory @ stdcall RtlUnwind(ptr ptr ptr long) ntdll.RtlUnwind @ stdcall RtlZeroMemory(ptr long) ntdll.RtlZeroMemory -@ stdcall -register -i386 SMapLS() -@ stdcall -register -i386 SMapLS_IP_EBP_12() -@ stdcall -register -i386 SMapLS_IP_EBP_16() -@ stdcall -register -i386 SMapLS_IP_EBP_20() -@ stdcall -register -i386 SMapLS_IP_EBP_24() -@ stdcall -register -i386 SMapLS_IP_EBP_28() -@ stdcall -register -i386 SMapLS_IP_EBP_32() -@ stdcall -register -i386 SMapLS_IP_EBP_36() -@ stdcall -register -i386 SMapLS_IP_EBP_40() -@ stdcall -register -i386 SMapLS_IP_EBP_8() -@ stdcall -register -i386 SUnMapLS() -@ stdcall -register -i386 SUnMapLS_IP_EBP_12() -@ stdcall -register -i386 SUnMapLS_IP_EBP_16() -@ stdcall -register -i386 SUnMapLS_IP_EBP_20() -@ stdcall -register -i386 SUnMapLS_IP_EBP_24() -@ stdcall -register -i386 SUnMapLS_IP_EBP_28() -@ stdcall -register -i386 SUnMapLS_IP_EBP_32() -@ stdcall -register -i386 SUnMapLS_IP_EBP_36() -@ stdcall -register -i386 SUnMapLS_IP_EBP_40() -@ stdcall -register -i386 SUnMapLS_IP_EBP_8() +@ stdcall -i386 SMapLS() +@ stdcall -i386 SMapLS_IP_EBP_8() +@ stdcall -i386 SMapLS_IP_EBP_12() +@ stdcall -i386 SMapLS_IP_EBP_16() +@ stdcall -i386 SMapLS_IP_EBP_20() +@ stdcall -i386 SMapLS_IP_EBP_24() +@ stdcall -i386 SMapLS_IP_EBP_28() +@ stdcall -i386 SMapLS_IP_EBP_32() +@ stdcall -i386 SMapLS_IP_EBP_36() +@ stdcall -i386 SMapLS_IP_EBP_40() +@ stdcall -i386 SUnMapLS() +@ stdcall -i386 SUnMapLS_IP_EBP_8() +@ stdcall -i386 SUnMapLS_IP_EBP_12() +@ stdcall -i386 SUnMapLS_IP_EBP_16() +@ stdcall -i386 SUnMapLS_IP_EBP_20() +@ stdcall -i386 SUnMapLS_IP_EBP_24() +@ stdcall -i386 SUnMapLS_IP_EBP_28() +@ stdcall -i386 SUnMapLS_IP_EBP_32() +@ stdcall -i386 SUnMapLS_IP_EBP_36() +@ stdcall -i386 SUnMapLS_IP_EBP_40() @ stdcall ScrollConsoleScreenBufferA(long ptr ptr ptr ptr) @ stdcall ScrollConsoleScreenBufferW(long ptr ptr ptr ptr) @ stdcall SearchPathA(str str str long ptr ptr) @@ -838,7 +840,7 @@ @ stdcall UTRegister(long str str str ptr ptr ptr) @ stdcall UTUnRegister(long) @ stdcall UnMapLS(long) -@ stdcall -register -i386 UnMapSLFixArray(long long) +@ stdcall -i386 UnMapSLFixArray(long long) @ stdcall UnhandledExceptionFilter(ptr) @ stdcall UninitializeCriticalSection(ptr) @ stdcall UnlockFile(long long long long long) @@ -1136,6 +1138,14 @@ @ stdcall LocalInit16(long long long) @ stdcall LocalLock16(long) @ stdcall LocalUnlock16(long) +@ stdcall LocalReAlloc16(long long long) +@ stdcall LocalFree16(long) +@ stdcall LocalSize16(long) +@ stdcall LocalHandle16(long) +@ stdcall LocalFlags16(long) +@ stdcall LocalCompact16(long) +@ stdcall LocalCountFree16() +@ stdcall LocalHeapSize16() @ stdcall LockResource16(long) @ stdcall SelectorAccessRights16(long long long) @ stdcall SetSelectorBase(long long) @@ -1151,8 +1161,8 @@ # or 'wine_' (for user-visible functions) to avoid namespace conflicts. # 16-bit relays -@ cdecl __wine_register_dll_16(ptr) -@ cdecl __wine_unregister_dll_16(ptr) +@ cdecl __wine_dll_register_16(ptr str) +@ cdecl __wine_dll_unregister_16(ptr) @ varargs __wine_call_from_16_word() @ varargs __wine_call_from_16_long() @ varargs __wine_call_from_16_regs() @@ -1167,18 +1177,3 @@ # Wine dll separation hacks, these will go away, don't use them # @ cdecl DOSMEM_AllocSelector(long) -@ cdecl DOSMEM_Available() -@ cdecl DOSMEM_FreeBlock(ptr) -@ cdecl DOSMEM_GetBlock(long ptr) -@ cdecl DOSMEM_Init(long) -@ cdecl DOSMEM_ResizeBlock(ptr long long) -@ cdecl LOCAL_Alloc(long long long) -@ cdecl LOCAL_Compact(long long long) -@ cdecl LOCAL_CountFree(long) -@ cdecl LOCAL_Free(long long) -@ cdecl LOCAL_HeapSize(long) -@ cdecl LOCAL_Lock(long long) -@ cdecl LOCAL_ReAlloc(long long long long) -@ cdecl LOCAL_Size(long long) -@ cdecl LOCAL_Unlock(long long) -@ stdcall NE_DefResourceHandler(long long long) diff -urN wine-20050419/dlls/kernel/kernel_main.c wine-20050524/dlls/kernel/kernel_main.c --- wine-20050419/dlls/kernel/kernel_main.c 2004-10-11 22:11:01.000000000 +0200 +++ wine-20050524/dlls/kernel/kernel_main.c 2005-05-16 21:44:54.000000000 +0200 @@ -25,24 +25,24 @@ #include #include #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #include #include "windef.h" #include "winbase.h" #include "wincon.h" +#include "thread.h" #include "winreg.h" #include "winternl.h" #include "wine/winbase16.h" #include "wine/library.h" -#include "miscemu.h" -#include "module.h" -#include "thread.h" -#include "stackframe.h" #include "wincon.h" #include "toolhelp.h" #include "kernel_private.h" +#include "kernel16_private.h" #include "console_private.h" extern void LOCALE_InitRegistry(void); @@ -85,8 +85,8 @@ /* allocate the 16-bit stack (FIXME: should be done lazily) */ HGLOBAL16 hstack = K32WOWGlobalAlloc16( GMEM_FIXED, 0x10000 ); NtCurrentTeb()->stack_sel = GlobalHandleToSel16( hstack ); - NtCurrentTeb()->cur_stack = MAKESEGPTR( NtCurrentTeb()->stack_sel, - 0x10000 - sizeof(STACK16FRAME) ); + NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR( NtCurrentTeb()->stack_sel, + 0x10000 - sizeof(STACK16FRAME) ); } @@ -97,7 +97,7 @@ { /* free the 16-bit stack */ K32WOWGlobalFree16( NtCurrentTeb()->stack_sel ); - NtCurrentTeb()->cur_stack = 0; + NtCurrentTeb()->WOW32Reserved = 0; if (NtCurrentTeb()->Tib.SubSystemTib) TASK_ExitTask(); } @@ -121,7 +121,7 @@ if (!WOWTHUNK_Init()) return FALSE; /* Initialize DOS memory */ - if (!DOSMEM_Init(0)) return FALSE; + if (!DOSMEM_Init()) return FALSE; /* Setup computer name */ COMPUTERNAME_Init(); diff -urN wine-20050419/dlls/kernel/kernel_private.h wine-20050524/dlls/kernel/kernel_private.h --- wine-20050419/dlls/kernel/kernel_private.h 2004-05-14 23:43:18.000000000 +0200 +++ wine-20050524/dlls/kernel/kernel_private.h 2005-05-16 21:44:54.000000000 +0200 @@ -65,30 +65,51 @@ extern DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context ); extern void INSTR_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum ); +/* return values for MODULE_GetBinaryType */ +enum binary_type +{ + BINARY_UNKNOWN, + BINARY_PE_EXE, + BINARY_PE_DLL, + BINARY_WIN16, + BINARY_OS216, + BINARY_DOS, + BINARY_UNIX_EXE, + BINARY_UNIX_LIB +}; + +/* module.c */ extern WCHAR *MODULE_get_dll_load_path( LPCWSTR module ); +extern enum binary_type MODULE_GetBinaryType( HANDLE hfile, void **res_start, void **res_end ); extern BOOL NLS_IsUnicodeOnlyLcid(LCID); -extern WORD SELECTOR_AllocBlock( const void *base, DWORD size, unsigned char flags ); -extern WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size ); -extern void SELECTOR_FreeBlock( WORD sel ); -#define IS_SELECTOR_32BIT(sel) \ - (wine_ldt_is_system(sel) || (wine_ldt_copy.flags[LOWORD(sel) >> 3] & WINE_LDT_FLAGS_32BIT)) - extern HANDLE VXD_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa ); -/* this structure is always located at offset 0 of the DGROUP segment */ -#include "pshpack1.h" -typedef struct +extern WORD DOSMEM_0000H; +extern WORD DOSMEM_BiosDataSeg; +extern WORD DOSMEM_BiosSysSeg; + +/* dosmem.c */ +extern BOOL DOSMEM_Init(void); +extern WORD DOSMEM_AllocSelector(WORD); +extern LPVOID DOSMEM_MapRealToLinear(DWORD); /* real-mode to linear */ +extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */ +extern UINT DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */ +extern void load_winedos(void); + +extern struct winedos_exports { - WORD null; /* Always 0 */ - DWORD old_ss_sp; /* Stack pointer; used by SwitchTaskTo() */ - WORD heap; /* Pointer to the local heap information (if any) */ - WORD atomtable; /* Pointer to the local atom table (if any) */ - WORD stacktop; /* Top of the stack */ - WORD stackmin; /* Lowest stack address used so far */ - WORD stackbottom; /* Bottom of the stack */ -} INSTANCEDATA; -#include "poppack.h" + /* for global16.c */ + void* (*AllocDosBlock)(UINT size, UINT16* pseg); + BOOL (*FreeDosBlock)(void* ptr); + UINT (*ResizeDosBlock)(void *ptr, UINT size, BOOL exact); + /* for instr.c */ + void (WINAPI *EmulateInterruptPM)( CONTEXT86 *context, BYTE intnum ); + void (WINAPI *CallBuiltinHandler)( CONTEXT86 *context, BYTE intnum ); + DWORD (WINAPI *inport)( int port, int size ); + void (WINAPI *outport)( int port, int size, DWORD val ); + void (* BiosTick)(WORD timer); +} winedos; #endif diff -urN wine-20050419/dlls/kernel/krnl386.exe.spec wine-20050524/dlls/kernel/krnl386.exe.spec --- wine-20050419/dlls/kernel/krnl386.exe.spec 2004-08-24 20:46:05.000000000 +0200 +++ wine-20050524/dlls/kernel/krnl386.exe.spec 2005-05-07 20:25:51.000000000 +0200 @@ -374,8 +374,8 @@ 469 stub WOAGimmeTitle 470 stub WOADestroyConsole 471 pascal GetCurrentProcessId() GetCurrentProcessId -472 pascal -register MapHInstLS() MapHInstLS -473 pascal -register MapHInstSL() MapHInstSL +472 pascal -register MapHInstLS() __regs_MapHInstLS +473 pascal -register MapHInstSL() __regs_MapHInstSL 474 pascal CloseW32Handle(long) CloseHandle 475 pascal -ret16 GetTEBSelectorFS() GetTEBSelectorFS16 476 pascal ConvertToGlobalHandle(long) ConvertToGlobalHandle diff -urN wine-20050419/dlls/kernel/local16.c wine-20050524/dlls/kernel/local16.c --- wine-20050419/dlls/kernel/local16.c 2005-03-24 22:01:38.000000000 +0100 +++ wine-20050524/dlls/kernel/local16.c 2005-05-19 13:13:36.000000000 +0200 @@ -35,11 +35,9 @@ #include #include "wine/winbase16.h" #include "wownt32.h" -#include "local.h" -#include "module.h" -#include "stackframe.h" #include "toolhelp.h" #include "kernel_private.h" +#include "kernel16_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(local); @@ -728,7 +726,7 @@ /*********************************************************************** * LOCAL_Compact */ -WORD LOCAL_Compact( HANDLE16 ds, UINT16 minfree, UINT16 flags ) +static UINT16 LOCAL_Compact( HANDLE16 ds, UINT16 minfree, UINT16 flags ) { char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); LOCALHEAPINFO *pInfo; @@ -1117,12 +1115,11 @@ /*********************************************************************** - * LOCAL_Free - * - * Implementation of LocalFree(). + * LocalFree (KERNEL.7) */ -HLOCAL16 LOCAL_Free( HANDLE16 ds, HLOCAL16 handle ) +HLOCAL16 WINAPI LocalFree16( HLOCAL16 handle ) { + HANDLE16 ds = CURRENT_DS; char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); TRACE("%04x ds=%04x\n", handle, ds ); @@ -1150,15 +1147,13 @@ /*********************************************************************** - * LOCAL_Alloc - * - * Implementation of LocalAlloc(). - * + * LocalAlloc (KERNEL.5) */ -HLOCAL16 LOCAL_Alloc( HANDLE16 ds, WORD flags, WORD size ) +HLOCAL16 WINAPI LocalAlloc16( UINT16 flags, WORD size ) { + HANDLE16 ds = CURRENT_DS; + HLOCAL16 handle = 0; char *ptr; - HLOCAL16 handle; TRACE("%04x %d ds=%04x\n", flags, size, ds ); @@ -1171,7 +1166,7 @@ if(size) { if (!(hmem = LOCAL_GetBlock( ds, size + MOVEABLE_PREFIX, flags ))) - return 0; + goto exit; } else /* We just need to allocate a discarded handle */ hmem = 0; @@ -1180,7 +1175,7 @@ WARN("Couldn't get handle.\n"); if(hmem) LOCAL_FreeArena( ds, ARENA_HEADER(hmem) ); - return 0; + goto exit; } ptr = MapSL( MAKESEGPTR( ds, 0 ) ); plhe = (LOCALHANDLEENTRY *)(ptr + handle); @@ -1199,21 +1194,21 @@ } else /* FIXED */ { - if(!size) - return 0; - handle = LOCAL_GetBlock( ds, size, flags ); + if(size) handle = LOCAL_GetBlock( ds, size, flags ); } + +exit: + CURRENT_STACK16->ecx = handle; /* must be returned in cx too */ return handle; } /*********************************************************************** - * LOCAL_ReAlloc - * - * Implementation of LocalReAlloc(). + * LocalReAlloc (KERNEL.6) */ -HLOCAL16 LOCAL_ReAlloc( HANDLE16 ds, HLOCAL16 handle, WORD size, WORD flags ) +HLOCAL16 WINAPI LocalReAlloc16( HLOCAL16 handle, WORD size, UINT16 flags ) { + HANDLE16 ds = CURRENT_DS; char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); LOCALHEAPINFO *pInfo; LOCALARENA *pArena, *pNext; @@ -1283,7 +1278,7 @@ if (HANDLE_FIXED(handle)) { TRACE("Freeing fixed block.\n"); - return LOCAL_Free( ds, handle ); + return LocalFree16( handle ); } else /* Moveable block */ { @@ -1306,7 +1301,7 @@ if (pEntry->lock == 0) { /* Frees block */ - return LOCAL_Free( ds, handle ); + return LocalFree16( handle ); } } return 0; @@ -1433,20 +1428,11 @@ /*********************************************************************** - * LOCAL_Lock - */ -void *LOCAL_Lock( HANDLE16 ds, HLOCAL16 handle ) -{ - char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); - return handle ? ptr + LOCAL_InternalLock( ptr, handle ) : NULL; -} - - -/*********************************************************************** - * LOCAL_Unlock + * LocalUnlock (KERNEL.9) */ -BOOL16 LOCAL_Unlock( HANDLE16 ds, HLOCAL16 handle ) +BOOL16 WINAPI LocalUnlock16( HLOCAL16 handle ) { + HANDLE16 ds = CURRENT_DS; char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); TRACE("%04x\n", handle ); @@ -1463,12 +1449,11 @@ /*********************************************************************** - * LOCAL_Size - * - * Implementation of LocalSize(). + * LocalSize (KERNEL.10) */ -WORD LOCAL_Size( HANDLE16 ds, HLOCAL16 handle ) +UINT16 WINAPI LocalSize16( HLOCAL16 handle ) { + HANDLE16 ds = CURRENT_DS; char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); LOCALARENA *pArena; @@ -1489,12 +1474,11 @@ /*********************************************************************** - * LOCAL_Flags - * - * Implementation of LocalFlags(). + * LocalFlags (KERNEL.12) */ -WORD LOCAL_Flags( HANDLE16 ds, HLOCAL16 handle ) +UINT16 WINAPI LocalFlags16( HLOCAL16 handle ) { + HANDLE16 ds = CURRENT_DS; char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); if (HANDLE_MOVEABLE(handle)) @@ -1514,25 +1498,22 @@ /*********************************************************************** - * LOCAL_HeapSize - * - * Implementation of LocalHeapSize(). + * LocalHeapSize (KERNEL.162) */ -WORD LOCAL_HeapSize( HANDLE16 ds ) +WORD WINAPI LocalHeapSize16(void) { + HANDLE16 ds = CURRENT_DS; LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds ); - if (!pInfo) return 0; - return pInfo->last - pInfo->first; + return pInfo ? pInfo->last - pInfo->first : 0; } /*********************************************************************** - * LOCAL_CountFree - * - * Implementation of LocalCountFree(). + * LocalCountFree (KERNEL.161) */ -WORD LOCAL_CountFree( HANDLE16 ds ) +WORD WINAPI LocalCountFree16(void) { + HANDLE16 ds = CURRENT_DS; WORD arena, total; LOCALARENA *pArena; LOCALHEAPINFO *pInfo; @@ -1561,12 +1542,11 @@ /*********************************************************************** - * LOCAL_Handle - * - * Implementation of LocalHandle(). + * LocalHandle (KERNEL.11) */ -HLOCAL16 LOCAL_Handle( HANDLE16 ds, WORD addr ) +HLOCAL16 WINAPI LocalHandle16( WORD addr ) { + HANDLE16 ds = CURRENT_DS; char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); LOCALHEAPINFO *pInfo; WORD table; @@ -1594,33 +1574,6 @@ } -/*********************************************************************** - * LocalAlloc (KERNEL.5) - */ -HLOCAL16 WINAPI LocalAlloc16( UINT16 flags, WORD size ) -{ - HLOCAL16 ret = LOCAL_Alloc( CURRENT_DS, flags, size ); - CURRENT_STACK16->ecx = ret; /* must be returned in cx too */ - return ret; -} - - -/*********************************************************************** - * LocalReAlloc (KERNEL.6) - */ -HLOCAL16 WINAPI LocalReAlloc16( HLOCAL16 handle, WORD size, UINT16 flags ) -{ - return LOCAL_ReAlloc( CURRENT_DS, handle, size, flags ); -} - - -/*********************************************************************** - * LocalFree (KERNEL.7) - */ -HLOCAL16 WINAPI LocalFree16( HLOCAL16 handle ) -{ - return LOCAL_Free( CURRENT_DS, handle ); -} /*********************************************************************** @@ -1637,42 +1590,6 @@ /*********************************************************************** - * LocalUnlock (KERNEL.9) - */ -BOOL16 WINAPI LocalUnlock16( HLOCAL16 handle ) -{ - return LOCAL_Unlock( CURRENT_DS, handle ); -} - - -/*********************************************************************** - * LocalSize (KERNEL.10) - */ -UINT16 WINAPI LocalSize16( HLOCAL16 handle ) -{ - return LOCAL_Size( CURRENT_DS, handle ); -} - - -/*********************************************************************** - * LocalHandle (KERNEL.11) - */ -HLOCAL16 WINAPI LocalHandle16( WORD addr ) -{ - return LOCAL_Handle( CURRENT_DS, addr ); -} - - -/*********************************************************************** - * LocalFlags (KERNEL.12) - */ -UINT16 WINAPI LocalFlags16( HLOCAL16 handle ) -{ - return LOCAL_Flags( CURRENT_DS, handle ); -} - - -/*********************************************************************** * LocalCompact (KERNEL.13) */ UINT16 WINAPI LocalCompact16( UINT16 minfree ) @@ -1736,31 +1653,14 @@ DWORD WINAPI GetHeapSpaces16( HMODULE16 module ) { NE_MODULE *pModule; - WORD ds; + WORD oldDS = CURRENT_DS; + DWORD spaces; if (!(pModule = NE_GetPtr( module ))) return 0; - ds = - GlobalHandleToSel16((NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->hSeg); - return MAKELONG( LOCAL_CountFree( ds ), LOCAL_HeapSize( ds ) ); -} - - -/*********************************************************************** - * LocalCountFree (KERNEL.161) - */ -WORD WINAPI LocalCountFree16(void) -{ - return LOCAL_CountFree( CURRENT_DS ); -} - - -/*********************************************************************** - * LocalHeapSize (KERNEL.162) - */ -WORD WINAPI LocalHeapSize16(void) -{ - TRACE("(void)\n" ); - return LOCAL_HeapSize( CURRENT_DS ); + CURRENT_DS = GlobalHandleToSel16((NE_SEG_TABLE( pModule ) + pModule->ne_autodata - 1)->hSeg); + spaces = MAKELONG( LocalCountFree16(), LocalHeapSize16() ); + CURRENT_DS = oldDS; + return spaces; } diff -urN wine-20050419/dlls/kernel/locale.c wine-20050524/dlls/kernel/locale.c --- wine-20050419/dlls/kernel/locale.c 2005-04-18 17:42:49.000000000 +0200 +++ wine-20050524/dlls/kernel/locale.c 2005-05-16 19:52:10.000000000 +0200 @@ -35,13 +35,13 @@ #include "windef.h" #include "winbase.h" #include "winuser.h" /* for RT_STRINGW */ +#include "thread.h" #include "winreg.h" #include "winternl.h" #include "wine/unicode.h" #include "winnls.h" #include "winerror.h" #include "winver.h" -#include "thread.h" #include "kernel_private.h" #include "wine/debug.h" @@ -3230,3 +3230,17 @@ pUILangEnumProc( value, lParam ); return(TRUE); } + +INT WINAPI GetGeoInfoW(GEOID GeoId, GEOTYPE GeoType, LPWSTR lpGeoData, + int cchData, LANGID language) +{ + FIXME("%ld %ld %p %d %d\n", GeoId, GeoType, lpGeoData, cchData, language); + return 0; +} + +INT WINAPI GetGeoInfoA(GEOID GeoId, GEOTYPE GeoType, LPSTR lpGeoData, + int cchData, LANGID language) +{ + FIXME("%ld %ld %p %d %d\n", GeoId, GeoType, lpGeoData, cchData, language); + return 0; +} diff -urN wine-20050419/dlls/kernel/ne_module.c wine-20050524/dlls/kernel/ne_module.c --- wine-20050419/dlls/kernel/ne_module.c 2005-03-30 12:31:33.000000000 +0200 +++ wine-20050524/dlls/kernel/ne_module.c 2005-05-23 14:15:26.000000000 +0200 @@ -35,11 +35,10 @@ #include "windef.h" #include "wine/winbase16.h" #include "wownt32.h" -#include "module.h" #include "toolhelp.h" -#include "builtin16.h" -#include "stackframe.h" #include "excpt.h" +#include "kernel_private.h" +#include "kernel16_private.h" #include "wine/exception.h" #include "wine/debug.h" @@ -69,24 +68,17 @@ #define hFirstModule (pThhook->hExeHead) -typedef struct +struct builtin_dll { - void *module_start; /* 32-bit address of the module data */ - int module_size; /* Size of the module data */ - void *code_start; /* 32-bit address of DLL code */ - void *data_start; /* 32-bit address of DLL data */ - const char *owner; /* 32-bit dll that contains this dll */ - const void *rsrc; /* resources data */ -} BUILTIN16_DESCRIPTOR; + const IMAGE_DOS_HEADER *header; /* module headers */ + const char *file_name; /* module file name */ +}; /* Table of all built-in DLLs */ #define MAX_DLLS 50 -static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS]; - -extern void SNOOP16_RegisterDLL(NE_MODULE*,LPCSTR); -extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16); +static struct builtin_dll builtin_dlls[MAX_DLLS]; static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only ); static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep ); @@ -106,15 +98,24 @@ /* patch all the flat cs references of the code segment if necessary */ -inline static void patch_code_segment( void *code_segment ) +inline static void patch_code_segment( NE_MODULE *pModule ) { #ifdef __i386__ - CALLFROM16 *call = code_segment; - if (call->flatcs == wine_get_cs()) return; /* nothing to patch */ - while (call->pushl == 0x68) + int i; + SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ); + + for (i = 0; i < pModule->ne_cseg; i++, pSeg++) { - call->flatcs = wine_get_cs(); - call++; + if (!(pSeg->flags & NE_SEGFLAGS_DATA)) /* found the code segment */ + { + CALLFROM16 *call = GlobalLock16( pSeg->hSeg ); + if (call->flatcs == wine_get_cs()) return; /* nothing to patch */ + while (call->pushl == 0x68) + { + call->flatcs = wine_get_cs(); + call++; + } + } } #endif } @@ -153,24 +154,30 @@ * * Find a descriptor in the list */ -static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname ) +static const IMAGE_DOS_HEADER *find_dll_descr( const char *dllname, const char **file_name ) { int i; + const IMAGE_DOS_HEADER *mz_header; + const IMAGE_OS2_HEADER *ne_header; + BYTE *name_table; + for (i = 0; i < MAX_DLLS; i++) { - const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i]; - if (descr) + mz_header = builtin_dlls[i].header; + if (mz_header) { - NE_MODULE *pModule = (NE_MODULE *)descr->module_start; - OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo); - BYTE *name_table = (BYTE *)pModule + pModule->name_table; + ne_header = (const IMAGE_OS2_HEADER *)((const char *)mz_header + mz_header->e_lfanew); + name_table = (BYTE *)ne_header + ne_header->ne_restab; /* check the dll file name */ - if (!NE_strcasecmp( pOfs->szPathName, dllname )) return descr; + if (!NE_strcasecmp( builtin_dlls[i].file_name, dllname ) || /* check the dll module name (without extension) */ - if (!NE_strncasecmp( dllname, name_table+1, *name_table ) && - !strcmp( dllname + *name_table, ".dll" )) - return descr; + (!NE_strncasecmp( dllname, name_table+1, *name_table ) && + !strcmp( dllname + *name_table, ".dll" ))) + { + *file_name = builtin_dlls[i].file_name; + return builtin_dlls[i].header; + } } } return NULL; @@ -178,18 +185,19 @@ /*********************************************************************** - * __wine_register_dll_16 (KERNEL32.@) + * __wine_dll_register_16 (KERNEL32.@) * * Register a built-in DLL descriptor. */ -void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr ) +void __wine_dll_register_16( const IMAGE_DOS_HEADER *header, const char *file_name ) { int i; for (i = 0; i < MAX_DLLS; i++) { - if (builtin_dlls[i]) continue; - builtin_dlls[i] = descr; + if (builtin_dlls[i].header) continue; + builtin_dlls[i].header = header; + builtin_dlls[i].file_name = file_name; break; } assert( i < MAX_DLLS ); @@ -197,18 +205,18 @@ /*********************************************************************** - * __wine_unregister_dll_16 (KERNEL32.@) + * __wine_dll_unregister_16 (KERNEL32.@) * * Unregister a built-in DLL descriptor. */ -void __wine_unregister_dll_16( const BUILTIN16_DESCRIPTOR *descr ) +void __wine_dll_unregister_16( const IMAGE_DOS_HEADER *header ) { int i; for (i = 0; i < MAX_DLLS; i++) { - if (builtin_dlls[i] != descr) continue; - builtin_dlls[i] = NULL; + if (builtin_dlls[i].header != header) continue; + builtin_dlls[i].header = NULL; break; } } @@ -256,15 +264,15 @@ DPRINTF( "---\n" ); DPRINTF( "Module %04x:\n", hModule ); DPRINTF( "count=%d flags=%04x heap=%d stack=%d\n", - pModule->count, pModule->flags, - pModule->heap_size, pModule->stack_size ); + pModule->count, pModule->ne_flags, + pModule->ne_heap, pModule->ne_stack ); DPRINTF( "cs:ip=%04x:%04x ss:sp=%04x:%04x ds=%04x nb seg=%d modrefs=%d\n", - pModule->cs, pModule->ip, pModule->ss, pModule->sp, pModule->dgroup, - pModule->seg_count, pModule->modref_count ); + SELECTOROF(pModule->ne_csip), OFFSETOF(pModule->ne_csip), + SELECTOROF(pModule->ne_sssp), OFFSETOF(pModule->ne_sssp), + pModule->ne_autodata, pModule->ne_cseg, pModule->ne_cmod ); DPRINTF( "os_flags=%d swap_area=%d version=%04x\n", - pModule->os_flags, pModule->min_swap_area, - pModule->expected_version ); - if (pModule->flags & NE_FFLAGS_WIN32) + pModule->ne_exetyp, pModule->ne_swaparea, pModule->ne_expver ); + if (pModule->ne_flags & NE_FFLAGS_WIN32) DPRINTF( "PE module=%p\n", pModule->module32 ); /* Dump the file info */ @@ -275,7 +283,7 @@ DPRINTF( "---\n" ); DPRINTF( "Segment table:\n" ); pSeg = NE_SEG_TABLE( pModule ); - for (i = 0; i < pModule->seg_count; i++, pSeg++) + for (i = 0; i < pModule->ne_cseg; i++, pSeg++) DPRINTF( "%02x: pos=%d size=%d flags=%04x minsize=%d hSeg=%04x\n", i + 1, pSeg->filepos, pSeg->size, pSeg->flags, pSeg->minsize, pSeg->hSeg ); @@ -283,9 +291,9 @@ /* Dump the resource table */ DPRINTF( "---\n" ); DPRINTF( "Resource table:\n" ); - if (pModule->res_table) + if (pModule->ne_rsrctab) { - pword = (WORD *)((BYTE *)pModule + pModule->res_table); + pword = (WORD *)((BYTE *)pModule + pModule->ne_rsrctab); DPRINTF( "Alignment: %d\n", *pword++ ); while (*pword) { @@ -303,7 +311,7 @@ /* Dump the resident name table */ DPRINTF( "---\n" ); DPRINTF( "Resident-name table:\n" ); - pstr = (char *)pModule + pModule->name_table; + pstr = (char *)pModule + pModule->ne_restab; while (*pstr) { DPRINTF( "%*.*s: %d\n", *pstr, *pstr, pstr + 1, @@ -314,10 +322,10 @@ /* Dump the module reference table */ DPRINTF( "---\n" ); DPRINTF( "Module ref table:\n" ); - if (pModule->modref_table) + if (pModule->ne_modtab) { - pword = (WORD *)((BYTE *)pModule + pModule->modref_table); - for (i = 0; i < pModule->modref_count; i++, pword++) + pword = (WORD *)((BYTE *)pModule + pModule->ne_modtab); + for (i = 0; i < pModule->ne_cmod; i++, pword++) { char name[10]; GetModuleName16( *pword, name, sizeof(name) ); @@ -329,7 +337,7 @@ /* Dump the entry table */ DPRINTF( "---\n" ); DPRINTF( "Entry table:\n" ); - bundle = (ET_BUNDLE *)((BYTE *)pModule+pModule->entry_table); + bundle = (ET_BUNDLE *)((BYTE *)pModule+pModule->ne_enttab); do { entry = (ET_ENTRY *)((BYTE *)bundle+6); DPRINTF( "Bundle %d-%d: %02x\n", bundle->first, bundle->last, entry->type); @@ -378,9 +386,9 @@ MESSAGE( "Bad module %04x in list\n", hModule ); return; } - MESSAGE( " %04x %04x %.*s\n", hModule, pModule->flags, - *((char *)pModule + pModule->name_table), - (char *)pModule + pModule->name_table + 1 ); + MESSAGE( " %04x %04x %.*s\n", hModule, pModule->ne_flags, + *((char *)pModule + pModule->ne_restab), + (char *)pModule + pModule->ne_restab + 1 ); hModule = pModule->next; } } @@ -391,16 +399,20 @@ * * Fill in 'resloader' fields in the resource table. */ -static void NE_InitResourceHandler( NE_MODULE *pModule ) +static void NE_InitResourceHandler( HMODULE16 hModule ) { static FARPROC16 proc; - NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); + NE_TYPEINFO *pTypeInfo; + NE_MODULE *pModule; + + if (!(pModule = NE_GetPtr( hModule )) || !pModule->ne_rsrctab) return; - TRACE("InitResourceHandler[%04x]\n", pModule->self ); + TRACE("InitResourceHandler[%04x]\n", hModule ); if (!proc) proc = GetProcAddress16( GetModuleHandle16("KERNEL"), "DefResourceHandler" ); + pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->ne_rsrctab + 2); while(pTypeInfo->type_id) { memcpy_unaligned( &pTypeInfo->resloader, &proc, sizeof(FARPROC16) ); @@ -421,7 +433,7 @@ NE_MODULE *pModule; if (!(pModule = NE_GetPtr( hModule ))) return 0; - if (pModule->flags & NE_FFLAGS_WIN32) return 0; + if (pModule->ne_flags & NE_FFLAGS_WIN32) return 0; TRACE("(%04x,'%s')\n", hModule, name ); @@ -437,7 +449,7 @@ /* First search the resident names */ - cpnt = (char *)pModule + pModule->name_table; + cpnt = (char *)pModule + pModule->ne_restab; /* Skip the first entry (module name) */ cpnt += *cpnt + 1 + sizeof(WORD); @@ -495,9 +507,9 @@ ET_BUNDLE *bundle; if (!(pModule = NE_GetPtr( hModule ))) return 0; - assert( !(pModule->flags & NE_FFLAGS_WIN32) ); + assert( !(pModule->ne_flags & NE_FFLAGS_WIN32) ); - bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table); + bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->ne_enttab); while ((ordinal < bundle->first + 1) || (ordinal > bundle->last)) { if (!(bundle->next)) @@ -549,9 +561,9 @@ int i; if (!(pModule = NE_GetPtr( hModule ))) return FALSE; - assert( !(pModule->flags & NE_FFLAGS_WIN32) ); + assert( !(pModule->ne_flags & NE_FFLAGS_WIN32) ); - bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table); + bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->ne_enttab); while ((ordinal < bundle->first + 1) || (ordinal > bundle->last)) { bundle = (ET_BUNDLE *)((BYTE *)pModule + bundle->next); @@ -568,107 +580,127 @@ /*********************************************************************** - * NE_OpenFile + * build_bundle_data + * + * Build the entry table bundle data from the on-disk format. Helper for build_module. */ -HANDLE NE_OpenFile( NE_MODULE *pModule ) +static void *build_bundle_data( NE_MODULE *pModule, void *dest, const BYTE *table ) { - HANDLE handle; - char *name = NE_MODULE_NAME( pModule ); + ET_BUNDLE *oldbundle, *bundle = dest; + ET_ENTRY *entry; + BYTE nr_entries, type; - TRACE("(%p)\n", pModule ); + memset(bundle, 0, sizeof(ET_BUNDLE)); /* in case no entry table exists */ + entry = (ET_ENTRY *)((BYTE *)bundle+6); - if (pModule->fd) + while ((nr_entries = *table++)) { - if (!DuplicateHandle( GetCurrentProcess(), pModule->fd, - GetCurrentProcess(), &handle, 0, FALSE, - DUPLICATE_SAME_ACCESS )) handle = INVALID_HANDLE_VALUE; - } - else - { - handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, 0, 0 ); + if ((type = *table++)) + { + bundle->last += nr_entries; + if (type == 0xff) + { + while (nr_entries--) + { + entry->type = type; + entry->flags = *table++; + table += sizeof(WORD); + entry->segnum = *table++; + entry->offs = *(WORD *)table; + table += sizeof(WORD); + entry++; + } + } + else + { + while (nr_entries--) + { + entry->type = type; + entry->flags = *table++; + entry->segnum = type; + entry->offs = *(WORD *)table; + table += sizeof(WORD); + entry++; + } + } + } + else + { + if (bundle->first == bundle->last) + { + bundle->first += nr_entries; + bundle->last += nr_entries; + } + else + { + oldbundle = bundle; + oldbundle->next = (char *)entry - (char *)pModule; + bundle = (ET_BUNDLE *)entry; + bundle->first = bundle->last = oldbundle->last + nr_entries; + bundle->next = 0; + entry = (ET_ENTRY*)(((BYTE*)entry)+sizeof(ET_BUNDLE)); + } + } } - if (handle == INVALID_HANDLE_VALUE) - ERR( "Can't open file '%s' for module %04x\n", name, pModule->self ); - - TRACE("opened '%s' -> %p\n", name, handle); - return handle; + return entry; } -/* wrapper for SetFilePointer and ReadFile */ -static BOOL read_data( HANDLE handle, LONG offset, void *buffer, DWORD size ) -{ - DWORD result; - - if (SetFilePointer( handle, offset, NULL, SEEK_SET ) == INVALID_SET_FILE_POINTER) return FALSE; - if (!ReadFile( handle, buffer, size, &result, NULL )) return FALSE; - return (result == size); -} - /*********************************************************************** - * NE_LoadExeHeader + * build_module + * + * Build the in-memory module from the on-disk data. */ -static HMODULE16 NE_LoadExeHeader( HANDLE handle, LPCSTR path ) +static HMODULE16 build_module( const void *mapping, SIZE_T mapping_size, LPCSTR path ) { - IMAGE_DOS_HEADER mz_header; - IMAGE_OS2_HEADER ne_header; - int size; + const IMAGE_DOS_HEADER *mz_header = mapping; + const IMAGE_OS2_HEADER *ne_header; + const struct ne_segment_table_entry_s *pSeg; + const void *ptr; + int i; + size_t size; HMODULE16 hModule; NE_MODULE *pModule; - BYTE *pData, *pTempEntryTable; - char *buffer, *fastload = NULL; - unsigned int fastload_offset = 0, fastload_length = 0; - ET_ENTRY *entry; - ET_BUNDLE *bundle, *oldbundle; + BYTE *buffer, *pData, *end; OFSTRUCT *ofs; - /* Read a block from either the file or the fast-load area. */ -#define READ(offset,size,buffer) \ - ((fastload && ((offset) >= fastload_offset) && \ - ((offset)+(size) <= fastload_offset+fastload_length)) ? \ - (memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \ - read_data( handle, (offset), (buffer), (size))) - - if (!read_data( handle, 0, &mz_header, sizeof(mz_header)) || - (mz_header.e_magic != IMAGE_DOS_SIGNATURE)) - return ERROR_BAD_FORMAT; - - if (!read_data( handle, mz_header.e_lfanew, &ne_header, sizeof(ne_header) )) - return ERROR_BAD_FORMAT; - - if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21; /* win32 exe */ - if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) { - MESSAGE("Sorry, this is an OS/2 linear executable (LX) file!\n"); - return (HMODULE16)12; + if (mapping_size < sizeof(*mz_header)) return ERROR_BAD_FORMAT; + if (mz_header->e_magic != IMAGE_DOS_SIGNATURE) return ERROR_BAD_FORMAT; + ne_header = (const IMAGE_OS2_HEADER *)((const char *)mapping + mz_header->e_lfanew); + if (mz_header->e_lfanew + sizeof(*ne_header) > mapping_size) return ERROR_BAD_FORMAT; + if (ne_header->ne_magic == IMAGE_NT_SIGNATURE) return 21; /* win32 exe */ + if (ne_header->ne_magic == IMAGE_OS2_SIGNATURE_LX) + { + MESSAGE("Sorry, %s is an OS/2 linear executable (LX) file!\n", path); + return 12; } - if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return ERROR_BAD_FORMAT; + if (ne_header->ne_magic != IMAGE_OS2_SIGNATURE) return ERROR_BAD_FORMAT; /* We now have a valid NE header */ /* check to be able to fall back to loading OS/2 programs as DOS * FIXME: should this check be reversed in order to be less strict? * (only fail for OS/2 ne_exetyp 0x01 here?) */ - if ((ne_header.ne_exetyp != 0x02 /* Windows */) - && (ne_header.ne_exetyp != 0x04) /* Windows 386 */) + if ((ne_header->ne_exetyp != 0x02 /* Windows */) + && (ne_header->ne_exetyp != 0x04) /* Windows 386 */) return ERROR_BAD_FORMAT; size = sizeof(NE_MODULE) + /* segment table */ - ne_header.ne_cseg * sizeof(SEGTABLEENTRY) + + ne_header->ne_cseg * sizeof(SEGTABLEENTRY) + /* resource table */ - ne_header.ne_restab - ne_header.ne_rsrctab + + ne_header->ne_restab - ne_header->ne_rsrctab + /* resident names table */ - ne_header.ne_modtab - ne_header.ne_restab + + ne_header->ne_modtab - ne_header->ne_restab + /* module ref table */ - ne_header.ne_cmod * sizeof(WORD) + + ne_header->ne_cmod * sizeof(WORD) + /* imported names table */ - ne_header.ne_enttab - ne_header.ne_imptab + + ne_header->ne_enttab - ne_header->ne_imptab + /* entry table length */ - ne_header.ne_cbenttab + + ne_header->ne_cbenttab + /* entry table extra conversion space */ sizeof(ET_BUNDLE) + - 2 * (ne_header.ne_cbenttab - ne_header.ne_cmovent*6) + + 2 * (ne_header->ne_cbenttab - ne_header->ne_cmovent*6) + /* loaded file info */ sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path) + 1; @@ -677,273 +709,133 @@ FarSetOwner16( hModule, hModule ); pModule = (NE_MODULE *)GlobalLock16( hModule ); - memcpy( pModule, &ne_header, sizeof(ne_header) ); + memcpy( pModule, ne_header, sizeof(*ne_header) ); pModule->count = 0; - /* check *programs* for default minimal stack size */ - if ( (!(pModule->flags & NE_FFLAGS_LIBMODULE)) - && (pModule->stack_size < 0x1400) ) - pModule->stack_size = 0x1400; - pModule->module32 = 0; - pModule->self = hModule; - pModule->self_loading_sel = 0; + /* check programs for default minimal stack size */ + if (!(pModule->ne_flags & NE_FFLAGS_LIBMODULE) && (pModule->ne_stack < 0x1400)) + pModule->ne_stack = 0x1400; + + pModule->self = hModule; + pModule->mapping = mapping; + pModule->mapping_size = mapping_size; + pData = (BYTE *)(pModule + 1); /* Clear internal Wine flags in case they are set in the EXE file */ - pModule->flags &= ~(NE_FFLAGS_BUILTIN | NE_FFLAGS_WIN32); - - /* Read the fast-load area */ - - if (ne_header.ne_flagsothers & NE_AFLAGS_FASTLOAD) - { - fastload_offset=ne_header.ne_pretthunks << ne_header.ne_align; - fastload_length=ne_header.ne_psegrefbytes << ne_header.ne_align; - TRACE("Using fast-load area offset=%x len=%d\n", - fastload_offset, fastload_length ); - if ((fastload = HeapAlloc( GetProcessHeap(), 0, fastload_length )) != NULL) - { - if (!read_data( handle, fastload_offset, fastload, fastload_length)) - { - HeapFree( GetProcessHeap(), 0, fastload ); - WARN("Error reading fast-load area!\n"); - fastload = NULL; - } - } - } + pModule->ne_flags &= ~(NE_FFLAGS_BUILTIN | NE_FFLAGS_WIN32); /* Get the segment table */ - pModule->seg_table = pData - (BYTE *)pModule; - buffer = HeapAlloc( GetProcessHeap(), 0, ne_header.ne_cseg * - sizeof(struct ne_segment_table_entry_s)); - if (buffer) - { - int i; - struct ne_segment_table_entry_s *pSeg; - - if (!READ( mz_header.e_lfanew + ne_header.ne_segtab, - ne_header.ne_cseg * sizeof(struct ne_segment_table_entry_s), - buffer )) - { - HeapFree( GetProcessHeap(), 0, buffer ); - HeapFree( GetProcessHeap(), 0, fastload ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; - } - pSeg = (struct ne_segment_table_entry_s *)buffer; - for (i = ne_header.ne_cseg; i > 0; i--, pSeg++) - { - memcpy( pData, pSeg, sizeof(*pSeg) ); - pData += sizeof(SEGTABLEENTRY); - } - HeapFree( GetProcessHeap(), 0, buffer ); - } - else + pModule->ne_segtab = pData - (BYTE *)pModule; + if (!(pSeg = NE_GET_DATA( pModule, mz_header->e_lfanew + ne_header->ne_segtab, + ne_header->ne_cseg * sizeof(struct ne_segment_table_entry_s) ))) + goto failed; + for (i = ne_header->ne_cseg; i > 0; i--, pSeg++) { - HeapFree( GetProcessHeap(), 0, fastload ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; + memcpy( pData, pSeg, sizeof(*pSeg) ); + pData += sizeof(SEGTABLEENTRY); } /* Get the resource table */ - if (ne_header.ne_rsrctab < ne_header.ne_restab) + if (ne_header->ne_rsrctab < ne_header->ne_restab) { - pModule->res_table = pData - (BYTE *)pModule; - if (!READ(mz_header.e_lfanew + ne_header.ne_rsrctab, - ne_header.ne_restab - ne_header.ne_rsrctab, - pData )) - return ERROR_BAD_FORMAT; - pData += ne_header.ne_restab - ne_header.ne_rsrctab; - NE_InitResourceHandler( pModule ); + pModule->ne_rsrctab = pData - (BYTE *)pModule; + if (!NE_READ_DATA( pModule, pData, mz_header->e_lfanew + ne_header->ne_rsrctab, + ne_header->ne_restab - ne_header->ne_rsrctab )) goto failed; + pData += ne_header->ne_restab - ne_header->ne_rsrctab; } - else pModule->res_table = 0; /* No resource table */ + else pModule->ne_rsrctab = 0; /* No resource table */ /* Get the resident names table */ - pModule->name_table = pData - (BYTE *)pModule; - if (!READ( mz_header.e_lfanew + ne_header.ne_restab, - ne_header.ne_modtab - ne_header.ne_restab, - pData )) - { - HeapFree( GetProcessHeap(), 0, fastload ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; - } - pData += ne_header.ne_modtab - ne_header.ne_restab; + pModule->ne_restab = pData - (BYTE *)pModule; + if (!NE_READ_DATA( pModule, pData, mz_header->e_lfanew + ne_header->ne_restab, + ne_header->ne_modtab - ne_header->ne_restab )) goto failed; + pData += ne_header->ne_modtab - ne_header->ne_restab; /* Get the module references table */ - if (ne_header.ne_cmod > 0) + if (ne_header->ne_cmod > 0) { - pModule->modref_table = pData - (BYTE *)pModule; - if (!READ( mz_header.e_lfanew + ne_header.ne_modtab, - ne_header.ne_cmod * sizeof(WORD), - pData )) - { - HeapFree( GetProcessHeap(), 0, fastload ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; - } - pData += ne_header.ne_cmod * sizeof(WORD); + pModule->ne_modtab = pData - (BYTE *)pModule; + if (!NE_READ_DATA( pModule, pData, mz_header->e_lfanew + ne_header->ne_modtab, + ne_header->ne_cmod * sizeof(WORD) )) goto failed; + pData += ne_header->ne_cmod * sizeof(WORD); } - else pModule->modref_table = 0; /* No module references */ + else pModule->ne_modtab = 0; /* No module references */ /* Get the imported names table */ - pModule->import_table = pData - (BYTE *)pModule; - if (!READ( mz_header.e_lfanew + ne_header.ne_imptab, - ne_header.ne_enttab - ne_header.ne_imptab, - pData )) - { - HeapFree( GetProcessHeap(), 0, fastload ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; - } - pData += ne_header.ne_enttab - ne_header.ne_imptab; + pModule->ne_imptab = pData - (BYTE *)pModule; + if (!NE_READ_DATA( pModule, pData, mz_header->e_lfanew + ne_header->ne_imptab, + ne_header->ne_enttab - ne_header->ne_imptab )) goto failed; + pData += ne_header->ne_enttab - ne_header->ne_imptab; /* Load entry table, convert it to the optimized version used by Windows */ - if ((pTempEntryTable = HeapAlloc( GetProcessHeap(), 0, ne_header.ne_cbenttab)) != NULL) - { - BYTE nr_entries, type, *s; - - TRACE("Converting entry table.\n"); - pModule->entry_table = pData - (BYTE *)pModule; - if (!READ( mz_header.e_lfanew + ne_header.ne_enttab, - ne_header.ne_cbenttab, pTempEntryTable )) - { - HeapFree( GetProcessHeap(), 0, pTempEntryTable ); - HeapFree( GetProcessHeap(), 0, fastload ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; - } - - s = pTempEntryTable; - TRACE("entry table: offs %04x, len %04x, entries %d\n", ne_header.ne_enttab, ne_header.ne_cbenttab, *s); + pModule->ne_enttab = pData - (BYTE *)pModule; + if (!(ptr = NE_GET_DATA( pModule, mz_header->e_lfanew + ne_header->ne_enttab, + ne_header->ne_cbenttab ))) goto failed; + end = build_bundle_data( pModule, pData, ptr ); - bundle = (ET_BUNDLE *)pData; - TRACE("first bundle: %p\n", bundle); - memset(bundle, 0, sizeof(ET_BUNDLE)); /* in case no entry table exists */ - entry = (ET_ENTRY *)((BYTE *)bundle+6); + pData += ne_header->ne_cbenttab + sizeof(ET_BUNDLE) + + 2 * (ne_header->ne_cbenttab - ne_header->ne_cmovent*6); - while ((nr_entries = *s++)) - { - if ((type = *s++)) - { - bundle->last += nr_entries; - if (type == 0xff) - while (nr_entries--) - { - entry->type = type; - entry->flags = *s++; - s += 2; - entry->segnum = *s++; - entry->offs = *(WORD *)s; s += 2; - /*TRACE(module, "entry: %p, type: %d, flags: %d, segnum: %d, offs: %04x\n", entry, entry->type, entry->flags, entry->segnum, entry->offs);*/ - entry++; - } - else - while (nr_entries--) - { - entry->type = type; - entry->flags = *s++; - entry->segnum = type; - entry->offs = *(WORD *)s; s += 2; - /*TRACE(module, "entry: %p, type: %d, flags: %d, segnum: %d, offs: %04x\n", entry, entry->type, entry->flags, entry->segnum, entry->offs);*/ - entry++; - } - } - else - { - if (bundle->first == bundle->last) - { - bundle->first += nr_entries; - bundle->last += nr_entries; - } - else - { - oldbundle = bundle; - oldbundle->next = ((int)entry - (int)pModule); - bundle = (ET_BUNDLE *)entry; - TRACE("new bundle: %p\n", bundle); - bundle->first = bundle->last = - oldbundle->last + nr_entries; - bundle->next = 0; - entry = (ET_ENTRY*)(((BYTE*)entry)+sizeof(ET_BUNDLE)); - } - } - } - HeapFree( GetProcessHeap(), 0, pTempEntryTable ); - } - else + if (end > pData) { - HeapFree( GetProcessHeap(), 0, fastload ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; + FIXME( "not enough space for entry table for %s\n", debugstr_a(path) ); + goto failed; } - pData += ne_header.ne_cbenttab + sizeof(ET_BUNDLE) + - 2 * (ne_header.ne_cbenttab - ne_header.ne_cmovent*6); - - if ((DWORD)entry > (DWORD)pData) - ERR("converted entry table bigger than reserved space !!!\nentry: %p, pData: %p. Please report !\n", entry, pData); - /* Store the filename information */ pModule->fileinfo = pData - (BYTE *)pModule; - size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path) + 1; ofs = (OFSTRUCT *)pData; - ofs->cBytes = size - 1; + ofs->cBytes = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path); ofs->fFixedDisk = 1; strcpy( ofs->szPathName, path ); - pData += size; - - /* Free the fast-load area */ - -#undef READ - HeapFree( GetProcessHeap(), 0, fastload ); + pData += ofs->cBytes + 1; + assert( (BYTE *)pModule + size <= pData ); /* Get the non-resident names table */ - if (ne_header.ne_cbnrestab) + if (ne_header->ne_cbnrestab) { - pModule->nrname_handle = GlobalAlloc16( 0, ne_header.ne_cbnrestab ); - if (!pModule->nrname_handle) - { - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; - } + pModule->nrname_handle = GlobalAlloc16( 0, ne_header->ne_cbnrestab ); + if (!pModule->nrname_handle) goto failed; FarSetOwner16( pModule->nrname_handle, hModule ); buffer = GlobalLock16( pModule->nrname_handle ); - if (!read_data( handle, ne_header.ne_nrestab, buffer, ne_header.ne_cbnrestab )) + if (!NE_READ_DATA( pModule, buffer, ne_header->ne_nrestab, ne_header->ne_cbnrestab )) { GlobalFree16( pModule->nrname_handle ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; + goto failed; } } else pModule->nrname_handle = 0; /* Allocate a segment for the implicitly-loaded DLLs */ - if (pModule->modref_count) + if (pModule->ne_cmod) { pModule->dlls_to_init = GlobalAlloc16( GMEM_ZEROINIT, - (pModule->modref_count+1)*sizeof(HMODULE16) ); + (pModule->ne_cmod+1)*sizeof(HMODULE16) ); if (!pModule->dlls_to_init) { if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle ); - GlobalFree16( hModule ); - return ERROR_BAD_FORMAT; + goto failed; } FarSetOwner16( pModule->dlls_to_init, hModule ); } else pModule->dlls_to_init = 0; NE_RegisterModule( pModule ); - SNOOP16_RegisterDLL(pModule,path); return hModule; + +failed: + GlobalFree16( hModule ); + return ERROR_BAD_FORMAT; } @@ -955,13 +847,13 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule ) { int i; - WORD *pModRef = (WORD *)((char *)pModule + pModule->modref_table); + WORD *pModRef = (WORD *)((char *)pModule + pModule->ne_modtab); WORD *pDLLs = (WORD *)GlobalLock16( pModule->dlls_to_init ); - for (i = 0; i < pModule->modref_count; i++, pModRef++) + for (i = 0; i < pModule->ne_cmod; i++, pModRef++) { char buffer[260], *p; - BYTE *pstr = (BYTE *)pModule + pModule->import_table + *pModRef; + BYTE *pstr = (BYTE *)pModule + pModule->ne_imptab + *pModRef; memcpy( buffer, pstr + 1, *pstr ); *(buffer + *pstr) = 0; /* terminate it */ @@ -981,8 +873,8 @@ /* FIXME: cleanup what was done */ MESSAGE( "Could not load '%s' required by '%.*s', error=%d\n", - buffer, *((BYTE*)pModule + pModule->name_table), - (char *)pModule + pModule->name_table + 1, hDLL ); + buffer, *((BYTE*)pModule + pModule->ne_restab), + (char *)pModule + pModule->ne_restab + 1, hDLL ); return FALSE; } *pModRef = GetExePtr( hDLL ); @@ -1003,9 +895,8 @@ * * Load first instance of NE module from file. * - * pModule must point to a module structure prepared by NE_LoadExeHeader. + * pModule must point to a module structure prepared by build_module. * This routine must never be called twice on a module. - * */ static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule ) { @@ -1053,31 +944,37 @@ HINSTANCE16 hInstance; HFILE16 hFile; OFSTRUCT ofs; - UINT drive_type; + HANDLE mapping; + void *ptr; + MEMORY_BASIC_INFORMATION info; /* Open file */ if ((hFile = OpenFile16( name, &ofs, OF_READ|OF_SHARE_DENY_WRITE )) == HFILE_ERROR16) return ERROR_FILE_NOT_FOUND; - hModule = NE_LoadExeHeader( DosFileHandleToWin32Handle(hFile), ofs.szPathName ); + mapping = CreateFileMappingW( DosFileHandleToWin32Handle(hFile), NULL, PAGE_WRITECOPY, 0, 0, NULL ); + _lclose16( hFile ); + if (!mapping) return ERROR_BAD_FORMAT; + + ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 0 ); + CloseHandle( mapping ); + if (!ptr) return ERROR_BAD_FORMAT; + + VirtualQuery( ptr, &info, sizeof(info) ); + hModule = build_module( ptr, info.RegionSize, ofs.szPathName ); + if (hModule < 32) { - _lclose16( hFile ); + UnmapViewOfFile( ptr ); return hModule; } - pModule = NE_GetPtr( hModule ); - drive_type = GetDriveTypeA( ofs.szPathName ); - if (drive_type != DRIVE_REMOVABLE && drive_type != DRIVE_CDROM) - { - /* keep the file handle open if not on a removable media */ - DuplicateHandle( GetCurrentProcess(), DosFileHandleToWin32Handle(hFile), - GetCurrentProcess(), &pModule->fd, 0, FALSE, - DUPLICATE_SAME_ACCESS ); - } - _lclose16( hFile ); + SNOOP16_RegisterDLL( hModule, ofs.szPathName ); + NE_InitResourceHandler( hModule ); + + pModule = NE_GetPtr( hModule ); - if ( !lib_only && !( pModule->flags & NE_FFLAGS_LIBMODULE ) ) + if ( !lib_only && !( pModule->ne_flags & NE_FFLAGS_LIBMODULE ) ) return hModule; hInstance = NE_DoLoadModule( pModule ); @@ -1096,51 +993,44 @@ * * Load a built-in Win16 module. Helper function for NE_LoadBuiltinModule. */ -static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr ) +static HMODULE16 NE_DoLoadBuiltinModule( const IMAGE_DOS_HEADER *mz_header, const char *file_name, + HMODULE owner32 ) { NE_MODULE *pModule; - int minsize; - SEGTABLEENTRY *pSegTable; HMODULE16 hModule; + HINSTANCE16 hInstance; + OSVERSIONINFOW versionInfo; + const IMAGE_OS2_HEADER *ne_header; + SIZE_T mapping_size = ~0UL; /* assume builtins don't contain invalid offsets... */ + + ne_header = (const IMAGE_OS2_HEADER *)((const BYTE *)mz_header + mz_header->e_lfanew); + hModule = build_module( mz_header, mapping_size, file_name ); + if (hModule < 32) return hModule; + pModule = GlobalLock16( hModule ); + pModule->ne_flags |= NE_FFLAGS_BUILTIN; + pModule->owner32 = owner32; + + /* fake the expected version the module should have according to the current Windows version */ + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (GetVersionExW( &versionInfo )) + pModule->ne_expver = MAKEWORD( versionInfo.dwMinorVersion, versionInfo.dwMajorVersion ); - hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start, - descr->module_size, 0, WINE_LDT_FLAGS_DATA ); - if (!hModule) return ERROR_NOT_ENOUGH_MEMORY; - FarSetOwner16( hModule, hModule ); + hInstance = NE_DoLoadModule( pModule ); + if (hInstance < 32) NE_FreeModule( hModule, 0 ); - pModule = (NE_MODULE *)GlobalLock16( hModule ); - pModule->self = hModule; - /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */ - pModule->hRsrcMap = (void *)descr->rsrc; - - /* Allocate the code segment */ - - pSegTable = NE_SEG_TABLE( pModule ); - pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start, - pSegTable->minsize, hModule, - WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT ); - if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY; - patch_code_segment( descr->code_start ); - pSegTable++; - - /* Allocate the data segment */ - - minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000; - minsize += pModule->heap_size; - if (minsize > 0x10000) minsize = 0x10000; - pSegTable->hSeg = GlobalAlloc16( GMEM_FIXED, minsize ); - if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY; - FarSetOwner16( pSegTable->hSeg, hModule ); - if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ), - descr->data_start, pSegTable->minsize); - if (pModule->heap_size) - LocalInit16( GlobalHandleToSel16(pSegTable->hSeg), pSegTable->minsize, minsize ); + NE_InitResourceHandler( hModule ); - if (descr->rsrc) NE_InitResourceHandler(pModule); + if (pModule->ne_heap) + { + SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ) + pModule->ne_autodata - 1; + unsigned int size = pSeg->minsize + pModule->ne_heap; + if (size > 0xfffe) size = 0xfffe; + LocalInit16( GlobalHandleToSel16(pSeg->hSeg), pSeg->minsize, size ); + } - NE_RegisterModule( pModule ); + patch_code_segment( pModule ); - return hModule; + return hInstance; } @@ -1155,8 +1045,10 @@ { HINSTANCE16 hinst = 2; HMODULE16 hModule; + HMODULE mod32 = 0; NE_MODULE *pModule; - const BUILTIN16_DESCRIPTOR *descr = NULL; + const IMAGE_DOS_HEADER *descr = NULL; + const char *file_name = NULL; char dllname[20], owner[20], *p; const char *basename; int owner_exists; @@ -1177,10 +1069,10 @@ if (wine_dll_get_owner( dllname, owner, sizeof(owner), &owner_exists ) != -1) { - HMODULE mod32 = LoadLibraryA( owner ); + mod32 = LoadLibraryA( owner ); if (mod32) { - if (!(descr = find_dll_descr( dllname ))) + if (!(descr = find_dll_descr( dllname, &file_name ))) { FreeLibrary( mod32 ); owner_exists = 0; @@ -1192,6 +1084,7 @@ TRACE( "module %s already loaded by owner\n", libname ); pModule = NE_GetPtr( hModule ); if (pModule) pModule->count++; + FreeLibrary( mod32 ); return hModule; } } @@ -1207,8 +1100,8 @@ if (descr) { TRACE("Trying built-in '%s'\n", libname); - hinst = NE_DoLoadBuiltinModule( descr ); - if (hinst > 32) TRACE_(loaddll)("Loaded module %s : builtin\n", debugstr_a(libname)); + hinst = NE_DoLoadBuiltinModule( descr, file_name, mod32 ); + if (hinst > 32) TRACE_(loaddll)("Loaded module %s : builtin\n", debugstr_a(file_name)); } else { @@ -1242,7 +1135,7 @@ * Call initialization routines for all loaded DLLs. Note that * when we load implicitly linked DLLs this will be done by InitTask(). */ - if(pModule->flags & NE_FFLAGS_LIBMODULE) + if(pModule->ne_flags & NE_FFLAGS_LIBMODULE) { NE_InitializeDLLs(hModule); NE_DllProcessAttach(hModule); @@ -1330,7 +1223,7 @@ /* If library module, we just retrieve the instance handle */ - if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only ) + if ( ( pModule->ne_flags & NE_FFLAGS_LIBMODULE ) || lib_only ) return NE_GetInstance( pModule ); /* @@ -1368,19 +1261,19 @@ hPrevInstance = NE_GetInstance( pModule ); - if ( pModule->dgroup ) - if ( NE_CreateSegment( pModule, pModule->dgroup ) ) - NE_LoadSegment( pModule, pModule->dgroup ); + if ( pModule->ne_autodata ) + if ( NE_CreateSegment( pModule, pModule->ne_autodata ) ) + NE_LoadSegment( pModule, pModule->ne_autodata ); hInstance = NE_GetInstance( pModule ); - TRACE("created second instance %04x[%d] of instance %04x.\n", hInstance, pModule->dgroup, hPrevInstance); + TRACE("created second instance %04x[%d] of instance %04x.\n", hInstance, pModule->ne_autodata, hPrevInstance); } else { /* Load first instance of NE module */ - pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */ + pModule->ne_flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */ hInstance = NE_DoLoadModule( pModule ); hPrevInstance = 0; @@ -1397,11 +1290,11 @@ /* Use DGROUP for 16-bit stack */ - if (!(sp = pModule->sp)) - sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size; + if (!(sp = OFFSETOF(pModule->ne_sssp))) + sp = pSegTable[SELECTOROF(pModule->ne_sssp)-1].minsize + pModule->ne_stack; sp &= ~1; sp -= sizeof(STACK16FRAME); - NtCurrentTeb()->cur_stack = MAKESEGPTR( GlobalHandleToSel16(hInstance), sp ); + NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR( GlobalHandleToSel16(hInstance), sp ); /* Registers at initialization must be: * ax zero @@ -1416,14 +1309,14 @@ * sp top of the stack */ memset( &context, 0, sizeof(context) ); - context.SegCs = GlobalHandleToSel16(pSegTable[pModule->cs - 1].hSeg); + context.SegCs = GlobalHandleToSel16(pSegTable[SELECTOROF(pModule->ne_csip) - 1].hSeg); context.SegDs = GlobalHandleToSel16(pTask->hInstance); context.SegEs = pTask->hPDB; context.SegFs = wine_get_fs(); context.SegGs = wine_get_gs(); - context.Eip = pModule->ip; - context.Ebx = pModule->stack_size; - context.Ecx = pModule->heap_size; + context.Eip = OFFSETOF(pModule->ne_csip); + context.Ebx = pModule->ne_stack; + context.Ecx = pModule->ne_heap; context.Edi = pTask->hInstance; context.Esi = pTask->hPrevInstance; @@ -1431,8 +1324,8 @@ TRACE("Starting main program: cs:ip=%04lx:%04lx ds=%04lx ss:sp=%04x:%04x\n", context.SegCs, context.Eip, context.SegDs, - SELECTOROF(NtCurrentTeb()->cur_stack), - OFFSETOF(NtCurrentTeb()->cur_stack) ); + SELECTOROF(NtCurrentTeb()->WOW32Reserved), + OFFSETOF(NtCurrentTeb()->WOW32Reserved) ); WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context ); ExitThread( LOWORD(context.Eax) ); @@ -1502,25 +1395,25 @@ if (((INT16)(--pModule->count)) > 0 ) return TRUE; else pModule->count = 0; - if (pModule->flags & NE_FFLAGS_BUILTIN) - return FALSE; /* Can't free built-in module */ - - if (call_wep && !(pModule->flags & NE_FFLAGS_WIN32)) + if (call_wep && !(pModule->ne_flags & NE_FFLAGS_WIN32)) { /* Free the objects owned by the DLL module */ NE_CallUserSignalProc( hModule, USIG16_DLL_UNLOAD ); - if (pModule->flags & NE_FFLAGS_LIBMODULE) + if (pModule->ne_flags & NE_FFLAGS_LIBMODULE) MODULE_CallWEP( hModule ); else call_wep = FALSE; /* We are freeing a task -> no more WEPs */ } + TRACE_(loaddll)("Unloaded module %s : %s\n", debugstr_a(NE_MODULE_NAME(pModule)), + (pModule->ne_flags & NE_FFLAGS_BUILTIN) ? "builtin" : "native"); /* Clear magic number just in case */ - pModule->magic = pModule->self = 0; - if (pModule->fd) CloseHandle( pModule->fd ); + pModule->ne_magic = pModule->self = 0; + if (pModule->owner32) FreeLibrary( pModule->owner32 ); + else if (pModule->mapping) UnmapViewOfFile( (void *)pModule->mapping ); /* Remove it from the linked list */ @@ -1533,8 +1426,8 @@ /* Free the referenced modules */ - pModRef = (HMODULE16*)((char *)pModule + pModule->modref_table); - for (i = 0; i < pModule->modref_count; i++, pModRef++) + pModRef = (HMODULE16*)((char *)pModule + pModule->ne_modtab); + for (i = 0; i < pModule->ne_cmod; i++, pModRef++) { NE_FreeModule( *pModRef, call_wep ); } @@ -1593,9 +1486,9 @@ { pModule = NE_GetPtr( hModule ); if (!pModule) break; - if (pModule->flags & NE_FFLAGS_WIN32) continue; + if (pModule->ne_flags & NE_FFLAGS_WIN32) continue; - name_table = (BYTE *)pModule + pModule->name_table; + name_table = (BYTE *)pModule + pModule->ne_restab; if ((*name_table == len) && !strncmp(name, name_table+1, len)) return hModule; } @@ -1609,9 +1502,9 @@ { pModule = NE_GetPtr( hModule ); if (!pModule) break; - if (pModule->flags & NE_FFLAGS_WIN32) continue; + if (pModule->ne_flags & NE_FFLAGS_WIN32) continue; - name_table = (BYTE *)pModule + pModule->name_table; + name_table = (BYTE *)pModule + pModule->ne_restab; /* FIXME: the strncasecmp is WRONG. It should not be case insensitive, * but case sensitive! (Unfortunately Winword 6 and subdlls have * lowercased module names, but try to load uppercase DLLs, so this @@ -1645,7 +1538,7 @@ pModule = NE_GetPtr( hModule ); if (!pModule) break; if (!pModule->fileinfo) continue; - if (pModule->flags & NE_FFLAGS_WIN32) continue; + if (pModule->ne_flags & NE_FFLAGS_WIN32) continue; ofs = (OFSTRUCT*)((BYTE *)pModule + pModule->fileinfo); loadedfn = ((char*)ofs->szPathName) + strlen(ofs->szPathName); @@ -1673,7 +1566,7 @@ BYTE *p; if (!(pModule = NE_GetPtr( hinst ))) return FALSE; - p = (BYTE *)pModule + pModule->name_table; + p = (BYTE *)pModule + pModule->ne_restab; if (count > *p) count = *p + 1; if (count > 0) { @@ -1703,7 +1596,7 @@ if (!(pModule = NE_GetPtr( hModule ))) return 0; lstrcpynA( lpFileName, NE_MODULE_NAME(pModule), nSize ); - if (pModule->expected_version >= 0x400) + if (pModule->ne_expver >= 0x400) GetLongPathNameA(NE_MODULE_NAME(pModule), lpFileName, nSize); TRACE("%04x -> '%s'\n", hModule, lpFileName ); return strlen(lpFileName); @@ -1727,23 +1620,7 @@ { NE_MODULE *pModule = NE_GetPtr( hModule ); if ( !pModule ) return 0; - - /* - * For built-in modules, fake the expected version the module should - * have according to the Windows version emulated by Wine - */ - if ( !pModule->expected_version ) - { - OSVERSIONINFOA versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - - if ( GetVersionExA( &versionInfo ) ) - pModule->expected_version = - (versionInfo.dwMajorVersion & 0xff) << 8 - | (versionInfo.dwMinorVersion & 0xff); - } - - return pModule->expected_version; + return pModule->ne_expver; } @@ -1957,7 +1834,7 @@ pModule = NE_GetPtr( hModule ); if (!pModule) break; if (!pModule->fileinfo) continue; - if (pModule->flags & NE_FFLAGS_WIN32) continue; + if (pModule->ne_flags & NE_FFLAGS_WIN32) continue; ofs = (OFSTRUCT*)((BYTE *)pModule + pModule->fileinfo); loadedfn = ((char*)ofs->szPathName) + strlen(ofs->szPathName); @@ -1983,9 +1860,9 @@ { pModule = NE_GetPtr( hModule ); if (!pModule) break; - if (pModule->flags & NE_FFLAGS_WIN32) continue; + if (pModule->ne_flags & NE_FFLAGS_WIN32) continue; - name_table = (BYTE *)pModule + pModule->name_table; + name_table = (BYTE *)pModule + pModule->ne_restab; if ((*name_table == len) && !NE_strncasecmp(s, name_table+1, len)) return hModule; } @@ -2028,7 +1905,7 @@ if (!lpme->wNext) return FALSE; if (!(pModule = NE_GetPtr( lpme->wNext ))) return FALSE; - name = (char *)pModule + pModule->name_table; + name = (char *)pModule + pModule->ne_restab; memcpy( lpme->szModule, name + 1, min(*name, MAX_MODULE_NAME) ); lpme->szModule[min(*name, MAX_MODULE_NAME)] = '\0'; lpme->hModule = lpme->wNext; @@ -2125,28 +2002,28 @@ pModule = (NE_MODULE *)GlobalLock16( hModule ); /* Set all used entries */ - pModule->magic = IMAGE_OS2_SIGNATURE; + pModule->ne_magic = IMAGE_OS2_SIGNATURE; pModule->count = 1; pModule->next = 0; - pModule->flags = NE_FFLAGS_WIN32; - pModule->dgroup = 0; - pModule->ss = 1; - pModule->cs = 2; - pModule->heap_size = 0; - pModule->stack_size = 0; - pModule->seg_count = 2; - pModule->modref_count = 0; - pModule->nrname_size = 0; + pModule->ne_flags = NE_FFLAGS_WIN32; + pModule->ne_autodata = 0; + pModule->ne_sssp = MAKESEGPTR( 0, 1 ); + pModule->ne_csip = MAKESEGPTR( 0, 2 ); + pModule->ne_heap = 0; + pModule->ne_stack = 0; + pModule->ne_cseg = 2; + pModule->ne_cmod = 0; + pModule->ne_cbnrestab = 0; pModule->fileinfo = sizeof(NE_MODULE); - pModule->os_flags = NE_OSFLAGS_WINDOWS; + pModule->ne_exetyp = NE_OSFLAGS_WINDOWS; pModule->self = hModule; pModule->module32 = module32; /* Set version and flags */ - pModule->expected_version = ((nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | - (nt->OptionalHeader.MinorSubsystemVersion & 0xff); + pModule->ne_expver = ((nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | + (nt->OptionalHeader.MinorSubsystemVersion & 0xff); if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) - pModule->flags |= NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA; + pModule->ne_flags |= NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA; /* Set loaded file information */ ofs = (OFSTRUCT *)(pModule + 1); @@ -2155,7 +2032,7 @@ strcpy( ofs->szPathName, filename ); pSegment = (SEGTABLEENTRY*)((char*)(pModule + 1) + ((of_size + 3) & ~3)); - pModule->seg_table = (int)pSegment - (int)pModule; + pModule->ne_segtab = (char *)pSegment - (char *)pModule; /* Data segment */ pSegment->size = 0; pSegment->flags = NE_SEGFLAGS_DATA; @@ -2167,17 +2044,17 @@ /* Module name */ pStr = (char *)pSegment; - pModule->name_table = (int)pStr - (int)pModule; + pModule->ne_restab = pStr - (char *)pModule; assert(len<256); *pStr = len; lstrcpynA( pStr+1, basename, len+1 ); pStr += len+2; /* All tables zero terminated */ - pModule->res_table = pModule->import_table = pModule->entry_table = (int)pStr - (int)pModule; + pModule->ne_rsrctab = pModule->ne_imptab = pModule->ne_enttab = (char *)pStr - (char *)pModule; NE_RegisterModule( pModule ); - LoadLibraryA( filename ); /* increment the ref count of the 32-bit module */ + pModule->owner32 = LoadLibraryA( filename ); /* increment the ref count of the 32-bit module */ return hModule; } @@ -2254,7 +2131,7 @@ hmod = pTask->hModule; } pModule = (NE_MODULE*)GlobalLock16(hmod); - if ((pModule->magic!=IMAGE_OS2_SIGNATURE) || !(pModule->flags & NE_FFLAGS_WIN32)) + if ((pModule->ne_magic != IMAGE_OS2_SIGNATURE) || !(pModule->ne_flags & NE_FFLAGS_WIN32)) return 0; return pModule->module32; } @@ -2263,32 +2140,44 @@ * MapHInstLS (KERNEL32.@) * MapHInstLS (KERNEL.472) */ -void MapHInstLS( CONTEXT86 *context ) +void WINAPI __regs_MapHInstLS( CONTEXT86 *context ) { context->Eax = MapHModuleLS( (HMODULE)context->Eax ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( MapHInstLS, 0, 0 ); +#endif /*************************************************************************** * MapHInstSL (KERNEL32.@) * MapHInstSL (KERNEL.473) */ -void MapHInstSL( CONTEXT86 *context ) +void WINAPI __regs_MapHInstSL( CONTEXT86 *context ) { context->Eax = (DWORD)MapHModuleSL( context->Eax ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( MapHInstSL, 0, 0 ); +#endif /*************************************************************************** * MapHInstLS_PN (KERNEL32.@) */ -void MapHInstLS_PN( CONTEXT86 *context ) +void WINAPI __regs_MapHInstLS_PN( CONTEXT86 *context ) { if (context->Eax) context->Eax = MapHModuleLS( (HMODULE)context->Eax ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( MapHInstLS_PN, 0, 0 ); +#endif /*************************************************************************** * MapHInstSL_PN (KERNEL32.@) */ -void MapHInstSL_PN( CONTEXT86 *context ) +void WINAPI __regs_MapHInstSL_PN( CONTEXT86 *context ) { if (context->Eax) context->Eax = (DWORD)MapHModuleSL( context->Eax ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( MapHInstSL_PN, 0, 0 ); +#endif diff -urN wine-20050419/dlls/kernel/ne_segment.c wine-20050524/dlls/kernel/ne_segment.c --- wine-20050419/dlls/kernel/ne_segment.c 2005-03-24 22:01:38.000000000 +0100 +++ wine-20050524/dlls/kernel/ne_segment.c 2005-05-19 14:05:28.000000000 +0200 @@ -37,9 +37,7 @@ #include "wownt32.h" #include "wine/library.h" #include "kernel_private.h" -#include "module.h" -#include "stackframe.h" -#include "builtin16.h" +#include "kernel16_private.h" #include "toolhelp.h" #include "wine/debug.h" @@ -118,162 +116,58 @@ /*********************************************************************** - * NE_LoadSegment + * NE_OpenFile */ -BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) +static HFILE16 NE_OpenFile( NE_MODULE *pModule ) { - SEGTABLEENTRY *pSegTable, *pSeg; - HMODULE16 *pModuleTable; - WORD count, i, offset, next_offset; - HMODULE16 module; - FARPROC16 address = 0; - HANDLE hf; - DWORD res; - struct relocation_entry_s *rep, *reloc_entries; - BYTE *func_name; - int size; - char* mem; - - char buffer[256]; - int ordinal, additive; - unsigned short *sp; - - pSegTable = NE_SEG_TABLE( pModule ); - pSeg = pSegTable + segnum - 1; + char *name = NE_MODULE_NAME( pModule ); + HANDLE handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, 0, 0 ); - if (pSeg->flags & NE_SEGFLAGS_LOADED) + if (handle == INVALID_HANDLE_VALUE) { - /* self-loader ? -> already loaded it */ - if (pModule->flags & NE_FFLAGS_SELFLOAD) - return TRUE; - - /* leave, except for DGROUP, as this may be the second instance */ - if (segnum != pModule->dgroup) - return TRUE; + ERR( "Can't open file '%s' for module %04x\n", name, pModule->self ); + return HFILE_ERROR; } + return Win32HandleToDosFileHandle( handle ); +} - if (!pSeg->filepos) return TRUE; /* No file image, just return */ - - pModuleTable = (HMODULE16 *)((char *)pModule + pModule->modref_table); - - hf = NE_OpenFile( pModule ); - TRACE_(module)("Loading segment %d, hSeg=%04x, flags=%04x\n", - segnum, pSeg->hSeg, pSeg->flags ); - SetFilePointer( hf, pSeg->filepos << pModule->alignment, NULL, SEEK_SET ); - if (pSeg->size) size = pSeg->size; - else size = pSeg->minsize ? pSeg->minsize : 0x10000; - mem = GlobalLock16(pSeg->hSeg); - if (pModule->flags & NE_FFLAGS_SELFLOAD && segnum > 1) - { - /* Implement self-loading segments */ - SELFLOADHEADER *selfloadheader; - DWORD oldstack; - HANDLE hFile32; - HFILE16 hFile16; - WORD args[3]; - DWORD ret; - - selfloadheader = MapSL( MAKESEGPTR(SEL(pSegTable->hSeg),0) ); - oldstack = NtCurrentTeb()->cur_stack; - NtCurrentTeb()->cur_stack = MAKESEGPTR(pModule->self_loading_sel, - 0xff00 - sizeof(STACK16FRAME)); - - TRACE_(dll)("CallLoadAppSegProc(hmodule=0x%04x,hf=%p,segnum=%d\n", - pModule->self,hf,segnum ); - DuplicateHandle( GetCurrentProcess(), hf, GetCurrentProcess(), &hFile32, - 0, FALSE, DUPLICATE_SAME_ACCESS ); - hFile16 = Win32HandleToDosFileHandle( hFile32 ); - args[2] = pModule->self; - args[1] = hFile16; - args[0] = segnum; - WOWCallback16Ex( (DWORD)selfloadheader->LoadAppSeg, WCB16_PASCAL, sizeof(args), args, &ret ); - pSeg->hSeg = LOWORD(ret); - TRACE_(dll)("Ret CallLoadAppSegProc: hSeg = 0x%04x\n", pSeg->hSeg); - _lclose16( hFile16 ); - NtCurrentTeb()->cur_stack = oldstack; - } - else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED)) - ReadFile(hf, mem, size, &res, NULL); - else { - /* - The following bit of code for "iterated segments" was written without - any documentation on the format of these segments. It seems to work, - but may be missing something. If you have any doc please either send - it to me or fix the code yourself. gfm@werple.mira.net.au - */ - char* buff = HeapAlloc(GetProcessHeap(), 0, size); - char* curr = buff; - - if(buff == NULL) { - WARN_(dll)("Memory exhausted!\n"); - goto fail; - } - - ReadFile(hf, buff, size, &res, NULL); - while(curr < buff + size) { - unsigned int rept = ((short*)curr)[0]; - unsigned int len = ((short*)curr)[1]; - - curr += 2*sizeof(short); - for(; rept > 0; rept--) { - char* bytes = curr; - unsigned int byte; - for(byte = 0; byte < len; byte++) - *mem++ = *bytes++; - } - curr += len; - } - HeapFree(GetProcessHeap(), 0, buff); - } - - pSeg->flags |= NE_SEGFLAGS_LOADED; - - /* Perform exported function prolog fixups */ - NE_FixupSegmentPrologs( pModule, segnum ); - - if (!(pSeg->flags & NE_SEGFLAGS_RELOC_DATA)) - goto succeed; /* No relocation data, we are done */ - - ReadFile(hf, &count, sizeof(count), &res, NULL); - if (!count) goto succeed; - TRACE("Fixups for %.*s, segment %d, hSeg %04x\n", - *((BYTE *)pModule + pModule->name_table), - (char *)pModule + pModule->name_table + 1, - segnum, pSeg->hSeg ); - - reloc_entries = HeapAlloc(GetProcessHeap(), 0, count * sizeof(struct relocation_entry_s)); - if(reloc_entries == NULL) { - WARN("Not enough memory for relocation entries!\n"); - goto fail; - } - if (!ReadFile( hf, reloc_entries, count * sizeof(struct relocation_entry_s), &res, NULL) || - (res != count * sizeof(struct relocation_entry_s))) - { - WARN("Unable to read relocation information\n" ); - goto fail; - } +/*********************************************************************** + * apply_relocations + * + * Apply relocations to a segment. Helper for NE_LoadSegment. + */ +static inline BOOL apply_relocations( NE_MODULE *pModule, const struct relocation_entry_s *rep, + int count, int segnum ) +{ + BYTE *func_name; + char buffer[256]; + int i, ordinal; + WORD offset, *sp; + HMODULE16 module; + FARPROC16 address = 0; + HMODULE16 *pModuleTable = (HMODULE16 *)((char *)pModule + pModule->ne_modtab); + SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); + SEGTABLEENTRY *pSeg = pSegTable + segnum - 1; /* * Go through the relocation table one entry at a time. */ - rep = reloc_entries; for (i = 0; i < count; i++, rep++) { - /* - * Get the target address corresponding to this entry. - */ - - /* If additive, there is no target chain list. Instead, add source - and target */ - additive = rep->relocation_type & NE_RELFLAG_ADDITIVE; - rep->relocation_type &= 0x3; - - switch (rep->relocation_type) - { - case NE_RELTYPE_ORDINAL: + /* + * Get the target address corresponding to this entry. + */ + + /* If additive, there is no target chain list. Instead, add source + and target */ + int additive = rep->relocation_type & NE_RELFLAG_ADDITIVE; + switch (rep->relocation_type & 3) + { + case NE_RELTYPE_ORDINAL: module = pModuleTable[rep->target1-1]; - ordinal = rep->target2; + ordinal = rep->target2; address = NE_GetEntryPoint( module, ordinal ); if (!address) { @@ -281,14 +175,14 @@ if (!pTarget) WARN_(module)("Module not found: %04x, reference %d of module %*.*s\n", module, rep->target1, - *((BYTE *)pModule + pModule->name_table), - *((BYTE *)pModule + pModule->name_table), - (char *)pModule + pModule->name_table + 1 ); + *((BYTE *)pModule + pModule->ne_restab), + *((BYTE *)pModule + pModule->ne_restab), + (char *)pModule + pModule->ne_restab + 1 ); else { ERR("No implementation for %.*s.%d, setting to 0xdeadbeef\n", - *((BYTE *)pTarget + pTarget->name_table), - (char *)pTarget + pTarget->name_table + 1, + *((BYTE *)pTarget + pTarget->ne_restab), + (char *)pTarget + pTarget->ne_restab + 1, ordinal ); address = (FARPROC16)0xdeadbeef; } @@ -297,16 +191,16 @@ { NE_MODULE *pTarget = NE_GetPtr( module ); TRACE("%d: %.*s.%d=%04x:%04x %s\n", i + 1, - *((BYTE *)pTarget + pTarget->name_table), - (char *)pTarget + pTarget->name_table + 1, + *((BYTE *)pTarget + pTarget->ne_restab), + (char *)pTarget + pTarget->ne_restab + 1, ordinal, HIWORD(address), LOWORD(address), NE_GetRelocAddrName( rep->address_type, additive ) ); } - break; + break; - case NE_RELTYPE_NAME: + case NE_RELTYPE_NAME: module = pModuleTable[rep->target1-1]; - func_name = (char *)pModule + pModule->import_table + rep->target2; + func_name = (char *)pModule + pModule->ne_imptab + rep->target2; memcpy( buffer, func_name+1, *func_name ); buffer[*func_name] = '\0'; func_name = buffer; @@ -317,57 +211,57 @@ { NE_MODULE *pTarget = NE_GetPtr( module ); ERR("No implementation for %.*s.%s, setting to 0xdeadbeef\n", - *((BYTE *)pTarget + pTarget->name_table), - (char *)pTarget + pTarget->name_table + 1, func_name ); + *((BYTE *)pTarget + pTarget->ne_restab), + (char *)pTarget + pTarget->ne_restab + 1, func_name ); } if (!address) address = (FARPROC16) 0xdeadbeef; if (TRACE_ON(fixup)) { - NE_MODULE *pTarget = NE_GetPtr( module ); + NE_MODULE *pTarget = NE_GetPtr( module ); TRACE("%d: %.*s.%s=%04x:%04x %s\n", i + 1, - *((BYTE *)pTarget + pTarget->name_table), - (char *)pTarget + pTarget->name_table + 1, + *((BYTE *)pTarget + pTarget->ne_restab), + (char *)pTarget + pTarget->ne_restab + 1, func_name, HIWORD(address), LOWORD(address), NE_GetRelocAddrName( rep->address_type, additive ) ); } - break; + break; - case NE_RELTYPE_INTERNAL: - if ((rep->target1 & 0xff) == 0xff) - { - address = NE_GetEntryPoint( pModule->self, rep->target2 ); - } - else - { + case NE_RELTYPE_INTERNAL: + if ((rep->target1 & 0xff) == 0xff) + { + address = NE_GetEntryPoint( pModule->self, rep->target2 ); + } + else + { address = (FARPROC16)MAKESEGPTR( SEL(pSegTable[rep->target1-1].hSeg), rep->target2 ); - } - - TRACE("%d: %04x:%04x %s\n", - i + 1, HIWORD(address), LOWORD(address), - NE_GetRelocAddrName( rep->address_type, additive ) ); - break; + } - case NE_RELTYPE_OSFIXUP: - /* Relocation type 7: - * - * These appear to be used as fixups for the Windows - * floating point emulator. Let's just ignore them and - * try to use the hardware floating point. Linux should - * successfully emulate the coprocessor if it doesn't - * exist. - */ - TRACE("%d: TYPE %d, OFFSET %04x, TARGET %04x %04x %s\n", - i + 1, rep->relocation_type, rep->offset, - rep->target1, rep->target2, - NE_GetRelocAddrName( rep->address_type, additive ) ); - continue; - } + TRACE("%d: %04x:%04x %s\n", + i + 1, HIWORD(address), LOWORD(address), + NE_GetRelocAddrName( rep->address_type, additive ) ); + break; + + case NE_RELTYPE_OSFIXUP: + /* Relocation type 7: + * + * These appear to be used as fixups for the Windows + * floating point emulator. Let's just ignore them and + * try to use the hardware floating point. Linux should + * successfully emulate the coprocessor if it doesn't + * exist. + */ + TRACE("%d: TYPE %d, OFFSET %04x, TARGET %04x %04x %s\n", + i + 1, rep->relocation_type, rep->offset, + rep->target1, rep->target2, + NE_GetRelocAddrName( rep->address_type, additive ) ); + continue; + } - offset = rep->offset; + offset = rep->offset; /* Apparently, high bit of address_type is sometimes set; */ /* we ignore it for now */ - if (rep->address_type > NE_RADDR_OFFSET32) + if (rep->address_type > NE_RADDR_OFFSET32) { char module[10]; GetModuleName16( pModule->self, module, sizeof(module) ); @@ -385,17 +279,17 @@ *(BYTE *)sp += LOBYTE((int)address); break; case NE_RADDR_OFFSET16: - *sp += LOWORD(address); + *sp += LOWORD(address); break; case NE_RADDR_POINTER32: - *sp += LOWORD(address); - *(sp+1) = HIWORD(address); + *sp += LOWORD(address); + *(sp+1) = HIWORD(address); break; case NE_RADDR_SELECTOR: - /* Borland creates additive records with offset zero. Strange, but OK */ + /* Borland creates additive records with offset zero. Strange, but OK */ if (*sp) ERR("Additive selector to %04x.Please report\n",*sp); - else + else *sp = HIWORD(address); break; default: @@ -406,6 +300,8 @@ { do { + WORD next_offset; + sp = MapSL( MAKESEGPTR( SEL(pSeg->hSeg), offset ) ); next_offset = *sp; TRACE(" %04x:%04x\n", offset, *sp ); @@ -432,11 +328,6 @@ } while (offset != 0xffff); } } - - HeapFree(GetProcessHeap(), 0, reloc_entries); - -succeed: - CloseHandle(hf); return TRUE; unknown: @@ -444,15 +335,126 @@ "TYPE %d, OFFSET %04x, TARGET %04x %04x\n", i + 1, rep->address_type, rep->relocation_type, rep->offset, rep->target1, rep->target2); - HeapFree(GetProcessHeap(), 0, reloc_entries); - -fail: - CloseHandle(hf); return FALSE; } /*********************************************************************** + * NE_LoadSegment + */ +BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) +{ + WORD count; + DWORD pos; + const struct relocation_entry_s *rep; + int size; + SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); + SEGTABLEENTRY *pSeg = pSegTable + segnum - 1; + + if (pSeg->flags & NE_SEGFLAGS_LOADED) + { + /* self-loader ? -> already loaded it */ + if (pModule->ne_flags & NE_FFLAGS_SELFLOAD) + return TRUE; + + /* leave, except for DGROUP, as this may be the second instance */ + if (segnum != pModule->ne_autodata) + return TRUE; + } + + if (!pSeg->filepos) return TRUE; /* No file image, just return */ + + TRACE_(module)("Loading segment %d, hSeg=%04x, flags=%04x\n", + segnum, pSeg->hSeg, pSeg->flags ); + pos = pSeg->filepos << pModule->ne_align; + if (pSeg->size) size = pSeg->size; + else size = pSeg->minsize ? pSeg->minsize : 0x10000; + + if (pModule->ne_flags & NE_FFLAGS_SELFLOAD && segnum > 1) + { + /* Implement self-loading segments */ + SELFLOADHEADER *selfloadheader; + void *oldstack; + HFILE16 hFile16; + WORD args[3]; + DWORD ret; + + selfloadheader = MapSL( MAKESEGPTR(SEL(pSegTable->hSeg),0) ); + oldstack = NtCurrentTeb()->WOW32Reserved; + NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR(pModule->self_loading_sel, + 0xff00 - sizeof(STACK16FRAME)); + + hFile16 = NE_OpenFile( pModule ); + TRACE_(dll)("CallLoadAppSegProc(hmodule=0x%04x,hf=%x,segnum=%d\n", + pModule->self,hFile16,segnum ); + args[2] = pModule->self; + args[1] = hFile16; + args[0] = segnum; + WOWCallback16Ex( (DWORD)selfloadheader->LoadAppSeg, WCB16_PASCAL, sizeof(args), args, &ret ); + pSeg->hSeg = LOWORD(ret); + TRACE_(dll)("Ret CallLoadAppSegProc: hSeg = 0x%04x\n", pSeg->hSeg); + _lclose16( hFile16 ); + NtCurrentTeb()->WOW32Reserved = oldstack; + } + else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED)) + { + void *mem = GlobalLock16(pSeg->hSeg); + if (!NE_READ_DATA( pModule, mem, pos, size )) + return FALSE; + pos += size; + } + else + { + /* + The following bit of code for "iterated segments" was written without + any documentation on the format of these segments. It seems to work, + but may be missing something. + */ + const char *buff = NE_GET_DATA( pModule, pos, size ); + const char* curr = buff; + char *mem = GlobalLock16(pSeg->hSeg); + + pos += size; + if (buff == NULL) return FALSE; + + while(curr < buff + size) { + unsigned int rept = ((short*)curr)[0]; + unsigned int len = ((short*)curr)[1]; + + curr += 2*sizeof(short); + while (rept--) + { + memcpy( mem, curr, len ); + mem += len; + } + curr += len; + } + } + + pSeg->flags |= NE_SEGFLAGS_LOADED; + + /* Perform exported function prolog fixups */ + NE_FixupSegmentPrologs( pModule, segnum ); + + if (!(pSeg->flags & NE_SEGFLAGS_RELOC_DATA)) + return TRUE; /* No relocation data, we are done */ + + if (!NE_READ_DATA( pModule, &count, pos, sizeof(count) ) || !count) return TRUE; + pos += sizeof(count); + + TRACE("Fixups for %.*s, segment %d, hSeg %04x\n", + *((BYTE *)pModule + pModule->ne_restab), + (char *)pModule + pModule->ne_restab + 1, + segnum, pSeg->hSeg ); + + if (!(rep = NE_GET_DATA( pModule, pos, count * sizeof(struct relocation_entry_s) ))) + return FALSE; + + return apply_relocations( pModule, rep, count, segnum ); +} + + +/*********************************************************************** * NE_LoadAllSegments */ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) @@ -460,20 +462,19 @@ int i; SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule); - if (pModule->flags & NE_FFLAGS_SELFLOAD) + if (pModule->ne_flags & NE_FFLAGS_SELFLOAD) { - HANDLE hf; HFILE16 hFile16; HGLOBAL16 sel; /* Handle self-loading modules */ SELFLOADHEADER *selfloadheader; HMODULE16 mod = GetModuleHandle16("KERNEL"); - DWORD oldstack; + void *oldstack; WORD args[2]; TRACE_(module)("%.*s is a self-loading module!\n", - *((BYTE*)pModule + pModule->name_table), - (char *)pModule + pModule->name_table + 1); + *((BYTE*)pModule + pModule->ne_restab), + (char *)pModule + pModule->ne_restab + 1); if (!NE_LoadSegment( pModule, 1 )) return FALSE; selfloadheader = MapSL( MAKESEGPTR(SEL(pSegTable->hSeg), 0) ); selfloadheader->EntryAddrProc = GetProcAddress16(mod,"EntryAddrProc"); @@ -482,12 +483,11 @@ sel = GlobalAlloc16( GMEM_ZEROINIT, 0xFF00 ); pModule->self_loading_sel = SEL(sel); FarSetOwner16( sel, pModule->self ); - oldstack = NtCurrentTeb()->cur_stack; - NtCurrentTeb()->cur_stack = MAKESEGPTR(pModule->self_loading_sel, - 0xff00 - sizeof(STACK16FRAME) ); + oldstack = NtCurrentTeb()->WOW32Reserved; + NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR(pModule->self_loading_sel, + 0xff00 - sizeof(STACK16FRAME) ); - hf = NE_OpenFile(pModule); - hFile16 = Win32HandleToDosFileHandle( hf ); + hFile16 = NE_OpenFile(pModule); TRACE_(dll)("CallBootAppProc(hModule=0x%04x,hf=0x%04x)\n", pModule->self,hFile16); args[1] = pModule->self; @@ -495,14 +495,14 @@ WOWCallback16Ex( (DWORD)selfloadheader->BootApp, WCB16_PASCAL, sizeof(args), args, NULL ); TRACE_(dll)("Return from CallBootAppProc\n"); _lclose16(hFile16); - NtCurrentTeb()->cur_stack = oldstack; + NtCurrentTeb()->WOW32Reserved = oldstack; - for (i = 2; i <= pModule->seg_count; i++) + for (i = 2; i <= pModule->ne_cseg; i++) if (!NE_LoadSegment( pModule, i )) return FALSE; } else { - for (i = 1; i <= pModule->seg_count; i++) + for (i = 1; i <= pModule->ne_cseg; i++) if (!NE_LoadSegment( pModule, i )) return FALSE; } return TRUE; @@ -530,13 +530,13 @@ return; } - if (!pModule->dgroup) return; + if (!pModule->ne_autodata) return; - if (!(dgroup = SEL(pSegTable[pModule->dgroup-1].hSeg))) return; + if (!(dgroup = SEL(pSegTable[pModule->ne_autodata-1].hSeg))) return; pSeg = MapSL( MAKESEGPTR(sel, 0) ); - bundle = (ET_BUNDLE *)((BYTE *)pModule+pModule->entry_table); + bundle = (ET_BUNDLE *)((BYTE *)pModule+pModule->ne_enttab); do { TRACE("num_entries: %d, bundle: %p, next: %04x, pSeg: %p\n", bundle->last - bundle->first, bundle, bundle->next, pSeg); @@ -567,7 +567,7 @@ *(WORD *)(pFunc+1) = dgroup; } else - if ((pModule->flags & NE_FFLAGS_MULTIPLEDATA) + if ((pModule->ne_flags & NE_FFLAGS_MULTIPLEDATA) && (entry->flags & 1)) /* exported ? */ { TRACE("patch %04x:%04x -> nop, nop\n", sel, entry->offs); @@ -598,7 +598,7 @@ TRACE_(module)("(%04x);\n", hSeg); /* find the segment number of the module that belongs to hSeg */ - for (segnum = 1; segnum <= pModule->seg_count; segnum++) + for (segnum = 1; segnum <= pModule->ne_cseg; segnum++) { if (SEL(pSegTable[segnum-1].hSeg) == sel) { @@ -619,9 +619,9 @@ { SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); - if (!(pModule->flags & NE_FFLAGS_SINGLEDATA)) + if (!(pModule->ne_flags & NE_FFLAGS_SINGLEDATA)) { - if (pModule->flags & NE_FFLAGS_MULTIPLEDATA || pModule->dgroup) + if (pModule->ne_flags & NE_FFLAGS_MULTIPLEDATA || pModule->ne_autodata) { /* Not SINGLEDATA */ ERR_(dll)("Library is not marked SINGLEDATA\n"); @@ -635,9 +635,9 @@ } else /* DATA SINGLE DLL */ { - if (pModule->dgroup) { - *ds = SEL(pSegTable[pModule->dgroup-1].hSeg); - *heap = pModule->heap_size; + if (pModule->ne_autodata) { + *ds = SEL(pSegTable[pModule->ne_autodata-1].hSeg); + *heap = pModule->ne_heap; } else /* hmm, DLL has no dgroup, but why has it NE_FFLAGS_SINGLEDATA set ? @@ -665,13 +665,13 @@ pSegTable = NE_SEG_TABLE( pModule ); - if (!(pModule->flags & NE_FFLAGS_LIBMODULE) || - (pModule->flags & NE_FFLAGS_WIN32)) return TRUE; /*not a library*/ + if (!(pModule->ne_flags & NE_FFLAGS_LIBMODULE) || + (pModule->ne_flags & NE_FFLAGS_WIN32)) return TRUE; /*not a library*/ /* Call USER signal handler for Win3.1 compatibility. */ NE_CallUserSignalProc( pModule->self, USIG16_DLL_LOAD ); - if (!pModule->cs) return TRUE; /* no initialization code */ + if (!SELECTOROF(pModule->ne_csip)) return TRUE; /* no initialization code */ /* Registers at initialization must be: @@ -691,14 +691,14 @@ context.SegEs = ds; /* who knows ... */ context.SegFs = wine_get_fs(); context.SegGs = wine_get_gs(); - context.SegCs = SEL(pSegTable[pModule->cs-1].hSeg); - context.Eip = pModule->ip; - context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack) + (WORD)&((STACK16FRAME*)0)->bp; + context.SegCs = SEL(pSegTable[SELECTOROF(pModule->ne_csip)-1].hSeg); + context.Eip = OFFSETOF(pModule->ne_csip); + context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp; - pModule->cs = 0; /* Don't initialize it twice */ + pModule->ne_csip = 0; /* Don't initialize it twice */ TRACE_(dll)("Calling LibMain for %.*s, cs:ip=%04lx:%04lx ds=%04lx di=%04x cx=%04x\n", - *((BYTE*)pModule + pModule->name_table), - (char *)pModule + pModule->name_table + 1, + *((BYTE*)pModule + pModule->ne_restab), + (char *)pModule + pModule->ne_restab + 1, context.SegCs, context.Eip, context.SegDs, LOWORD(context.Edi), LOWORD(context.Ecx) ); WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context ); @@ -717,7 +717,7 @@ HMODULE16 *pDLL; if (!(pModule = NE_GetPtr( hModule ))) return; - assert( !(pModule->flags & NE_FFLAGS_WIN32) ); + assert( !(pModule->ne_flags & NE_FFLAGS_WIN32) ); if (pModule->dlls_to_init) { @@ -770,8 +770,8 @@ WORD hInst, ds, heap; FARPROC16 entryPoint; - if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) return; - if (!(pModule->flags & NE_FFLAGS_BUILTIN) && pModule->expected_version < 0x0400) return; + if (!(pModule->ne_flags & NE_FFLAGS_LIBMODULE)) return; + if (!(pModule->ne_flags & NE_FFLAGS_BUILTIN) && pModule->ne_expver < 0x0400) return; if (!(entryPoint = GetProcAddress16( pModule->self, "DllEntryPoint" ))) return; NE_GetDLLInitParams( pModule, &hInst, &ds, &heap ); @@ -780,7 +780,7 @@ NE_MODULE_NAME( pModule ), SELECTOROF(entryPoint), OFFSETOF(entryPoint) ); - if ( pModule->flags & NE_FFLAGS_BUILTIN ) + if ( pModule->ne_flags & NE_FFLAGS_BUILTIN ) { WinNEEntryProc entryProc = (WinNEEntryProc)((ENTRYPOINT16 *)MapSL( (SEGPTR)entryPoint ))->target; @@ -797,9 +797,8 @@ context.SegFs = wine_get_fs(); context.SegGs = wine_get_gs(); context.SegCs = HIWORD(entryPoint); - context.Eip = LOWORD(entryPoint); - context.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) - + (WORD)&((STACK16FRAME*)0)->bp; + context.Eip = LOWORD(entryPoint); + context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp; args[7] = HIWORD(dwReason); args[6] = LOWORD(dwReason); @@ -884,7 +883,7 @@ int i; if (!(pModule = NE_GetPtr( hModule ))) return; - assert( !(pModule->flags & NE_FFLAGS_WIN32) ); + assert( !(pModule->ne_flags & NE_FFLAGS_WIN32) ); /* Never add a module twice */ for ( i = 0; i < list->count; i++ ) @@ -892,23 +891,23 @@ return; /* Check for recursive call */ - if ( pModule->misc_flags & 0x80 ) return; + if ( pModule->ne_flagsothers & 0x80 ) return; TRACE_(dll)("(%s) - START\n", NE_MODULE_NAME(pModule) ); /* Tag current module to prevent recursive loop */ - pModule->misc_flags |= 0x80; + pModule->ne_flagsothers |= 0x80; /* Recursively attach all DLLs this one depends on */ - pModRef = (HMODULE16 *)((char *)pModule + pModule->modref_table); - for ( i = 0; i < pModule->modref_count; i++ ) + pModRef = (HMODULE16 *)((char *)pModule + pModule->ne_modtab); + for ( i = 0; i < pModule->ne_cmod; i++ ) if ( pModRef[i] ) fill_init_list( list, pModRef[i] ); /* Add current module */ add_to_init_list( list, pModule ); /* Remove recursion flag */ - pModule->misc_flags &= ~0x80; + pModule->ne_flagsothers &= ~0x80; TRACE_(dll)("(%s) - END\n", NE_MODULE_NAME(pModule) ); } @@ -989,12 +988,12 @@ */ HINSTANCE16 NE_GetInstance( NE_MODULE *pModule ) { - if ( !pModule->dgroup ) + if ( !pModule->ne_autodata ) return pModule->self; else { SEGTABLEENTRY *pSeg; - pSeg = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1; + pSeg = NE_SEG_TABLE( pModule ) + pModule->ne_autodata - 1; return pSeg->hSeg; } } @@ -1008,20 +1007,20 @@ int minsize; unsigned char selflags; - assert( !(pModule->flags & NE_FFLAGS_WIN32) ); + assert( !(pModule->ne_flags & NE_FFLAGS_WIN32) ); - if ( segnum < 1 || segnum > pModule->seg_count ) + if ( segnum < 1 || segnum > pModule->ne_cseg ) return FALSE; - if ( (pModule->flags & NE_FFLAGS_SELFLOAD) && segnum != 1 ) + if ( (pModule->ne_flags & NE_FFLAGS_SELFLOAD) && segnum != 1 ) return TRUE; /* selfloader allocates segment itself */ - if ( (pSeg->flags & NE_SEGFLAGS_ALLOCATED) && segnum != pModule->dgroup ) + if ( (pSeg->flags & NE_SEGFLAGS_ALLOCATED) && segnum != pModule->ne_autodata ) return TRUE; /* all but DGROUP only allocated once */ minsize = pSeg->minsize ? pSeg->minsize : 0x10000; - if ( segnum == pModule->ss ) minsize += pModule->stack_size; - if ( segnum == pModule->dgroup ) minsize += pModule->heap_size; + if ( segnum == SELECTOROF(pModule->ne_sssp) ) minsize += pModule->ne_stack; + if ( segnum == pModule->ne_autodata ) minsize += pModule->ne_heap; selflags = (pSeg->flags & NE_SEGFLAGS_DATA) ? WINE_LDT_FLAGS_DATA : WINE_LDT_FLAGS_CODE; if (pSeg->flags & NE_SEGFLAGS_32BIT) selflags |= WINE_LDT_FLAGS_32BIT; @@ -1038,12 +1037,12 @@ BOOL NE_CreateAllSegments( NE_MODULE *pModule ) { int i; - for ( i = 1; i <= pModule->seg_count; i++ ) + for ( i = 1; i <= pModule->ne_cseg; i++ ) if ( !NE_CreateSegment( pModule, i ) ) return FALSE; - pModule->dgroup_entry = pModule->dgroup ? pModule->seg_table + - (pModule->dgroup - 1) * sizeof(SEGTABLEENTRY) : 0; + pModule->dgroup_entry = pModule->ne_autodata ? pModule->ne_segtab + + (pModule->ne_autodata - 1) * sizeof(SEGTABLEENTRY) : 0; return TRUE; } @@ -1056,5 +1055,5 @@ /* Check whether the selector belongs to a DLL */ NE_MODULE *pModule = NE_GetPtr( selector ); if (!pModule) return FALSE; - return (pModule->flags & NE_FFLAGS_LIBMODULE) != 0; + return (pModule->ne_flags & NE_FFLAGS_LIBMODULE) != 0; } diff -urN wine-20050419/dlls/kernel/oldconfig.c wine-20050524/dlls/kernel/oldconfig.c --- wine-20050419/dlls/kernel/oldconfig.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/kernel/oldconfig.c 2005-05-06 18:22:55.000000000 +0200 @@ -0,0 +1,693 @@ +/* + * Support for converting from old configuration format + * + * Copyright 2005 Alexandre Julliard + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * NOTES + * This file should be removed after a suitable transition period. + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#ifdef HAVE_SYS_STAT_H +# include +#endif +#include +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_LINUX_HDREG_H +# include +#endif + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "winternl.h" +#include "ntstatus.h" +#include "winioctl.h" +#include "ntddscsi.h" +#include "wine/library.h" +#include "wine/server.h" +#include "wine/unicode.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(reg); + + +/* create symlinks for the DOS drives; helper for create_dos_devices */ +static int create_drives( int devices_only ) +{ + static const WCHAR PathW[] = {'P','a','t','h',0}; + static const WCHAR DeviceW[] = {'D','e','v','i','c','e',0}; + WCHAR driveW[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\','W','i','n','e','\\', + 'C','o','n','f','i','g','\\','D','r','i','v','e',' ','A',0}; + const char *config_dir = wine_get_config_dir(); + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + char tmp[1024*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; + char dest[1024]; + char *buffer; + WCHAR *p, name[3]; + HKEY hkey; + DWORD dummy; + int i, count = 0; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + /* create symlinks for the drive roots */ + + if (!devices_only) for (i = 0; i < 26; i++) + { + RtlInitUnicodeString( &nameW, driveW ); + nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; + if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; + + RtlInitUnicodeString( &nameW, PathW ); + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) + { + WCHAR path[1024]; + WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + ExpandEnvironmentStringsW( data, path, sizeof(path)/sizeof(WCHAR) ); + + p = path + strlenW(path) - 1; + while ((p > path) && (*p == '/')) *p-- = '\0'; + + name[0] = 'a' + i; + name[1] = ':'; + name[2] = 0; + + if (path[0] != '/') + { + /* relative paths are relative to config dir */ + memmove( path + 3, path, (strlenW(path) + 1) * sizeof(WCHAR) ); + path[0] = '.'; + path[1] = '.'; + path[2] = '/'; + } + if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, name, path )) + { + WideCharToMultiByte(CP_UNIXCP, 0, path, -1, dest, sizeof(dest), NULL, NULL); + MESSAGE( "Created symlink %s/dosdevices/%c: -> %s\n", + wine_get_config_dir(), 'a' + i, dest ); + count++; + } + } + NtClose( hkey ); + } + + /* create symlinks for the drive devices */ + + buffer = HeapAlloc( GetProcessHeap(), 0, + strlen(config_dir) + sizeof("/dosdevices/a::") ); + strcpy( buffer, config_dir ); + strcat( buffer, "/dosdevices/a::" ); + + for (i = 0; i < 26; i++) + { + RtlInitUnicodeString( &nameW, driveW ); + nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; + if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; + + RtlInitUnicodeString( &nameW, DeviceW ); + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) + { + WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + WideCharToMultiByte(CP_UNIXCP, 0, data, -1, dest, sizeof(dest), NULL, NULL); + + buffer[strlen(buffer) - 3] = 'a' + i; + if (!symlink( dest, buffer )) + { + MESSAGE( "Created symlink %s/dosdevices/%c:: -> %s\n", + wine_get_config_dir(), 'a' + i, dest ); + count++; + } + } + NtClose( hkey ); + } + HeapFree( GetProcessHeap(), 0, buffer ); + + return count; +} + + +/* create the device files for the new device naming scheme */ +static void create_dos_devices(void) +{ + const char *config_dir = wine_get_config_dir(); + char *buffer; + int i, count = 0; + + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, + strlen(config_dir) + sizeof("/dosdevices/a::") ))) + return; + + strcpy( buffer, config_dir ); + strcat( buffer, "/dosdevices" ); + + if (!mkdir( buffer, 0777 )) /* we created it, so now create the devices */ + { + HKEY hkey; + DWORD dummy; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + WCHAR *p, *devnameW; + char tmp[128]; + WCHAR com[5] = {'C','O','M','1',0}; + WCHAR lpt[5] = {'L','P','T','1',0}; + + static const WCHAR serialportsW[] = {'M','a','c','h','i','n','e','\\', + 'S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\','W','i','n','e','\\', + 'C','o','n','f','i','g','\\', + 'S','e','r','i','a','l','P','o','r','t','s',0}; + static const WCHAR parallelportsW[] = {'M','a','c','h','i','n','e','\\', + 'S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\','W','i','n','e','\\', + 'C','o','n','f','i','g','\\', + 'P','a','r','a','l','l','e','l','P','o','r','t','s',0}; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, serialportsW ); + + if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) + { + RtlInitUnicodeString( &nameW, com ); + for (i = 1; i <= 9; i++) + { + com[3] = '0' + i; + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, + tmp, sizeof(tmp), &dummy )) + { + devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + if ((p = strchrW( devnameW, ',' ))) *p = 0; + if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, com, devnameW )) + { + char devname[32]; + WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, + devname, sizeof(devname), NULL, NULL); + MESSAGE( "Created symlink %s/dosdevices/com%d -> %s\n", config_dir, i, devname ); + count++; + } + } + } + NtClose( hkey ); + } + + RtlInitUnicodeString( &nameW, parallelportsW ); + if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) + { + RtlInitUnicodeString( &nameW, lpt ); + for (i = 1; i <= 9; i++) + { + lpt[3] = '0' + i; + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, + tmp, sizeof(tmp), &dummy )) + { + devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + if ((p = strchrW( devnameW, ',' ))) *p = 0; + if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, lpt, devnameW )) + { + char devname[32]; + WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, + devname, sizeof(devname), NULL, NULL); + MESSAGE( "Created symlink %s/dosdevices/lpt%d -> %s\n", config_dir, i, devname ); + count++; + } + } + } + NtClose( hkey ); + } + count += create_drives( FALSE ); + } + else + { + struct stat st; + int i; + + /* it is possible that the serial/parallel devices have been created but */ + /* not the drives; check for at least one drive symlink to catch that case */ + strcat( buffer, "/a:" ); + for (i = 0; i < 26; i++) + { + buffer[strlen(buffer)-2] = 'a' + i; + if (!lstat( buffer, &st )) break; + } + if (i == 26) count += create_drives( FALSE ); + else + { + strcat( buffer, ":" ); + for (i = 0; i < 26; i++) + { + buffer[strlen(buffer)-3] = 'a' + i; + if (!lstat( buffer, &st )) break; + } + if (i == 26) count += create_drives( TRUE ); + } + } + + if (count) + MESSAGE( "\nYou can now remove the [SerialPorts], [ParallelPorts], and [Drive] sections\n" + "in your configuration file, they are replaced by the above symlinks.\n\n" ); + + HeapFree( GetProcessHeap(), 0, buffer ); +} + + +/* convert the drive type entries from the old format to the new one */ +static void convert_drive_types(void) +{ + static const WCHAR TypeW[] = {'T','y','p','e',0}; + static const WCHAR drive_types_keyW[] = {'M','a','c','h','i','n','e','\\', + 'S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\', + 'D','r','i','v','e','s',0 }; + WCHAR driveW[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\','W','i','n','e','\\', + 'C','o','n','f','i','g','\\','D','r','i','v','e',' ','A',0}; + char tmp[32*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + DWORD dummy; + ULONG disp; + HKEY hkey_old, hkey_new; + int i; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, drive_types_keyW ); + + if (NtCreateKey( &hkey_new, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &disp )) return; + if (disp != REG_CREATED_NEW_KEY) + { + NtClose( hkey_new ); + return; + } + + for (i = 0; i < 26; i++) + { + RtlInitUnicodeString( &nameW, driveW ); + nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; + if (NtOpenKey( &hkey_old, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; + RtlInitUnicodeString( &nameW, TypeW ); + if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) + { + WCHAR valueW[] = {'A',':',0}; + WCHAR *type = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + + valueW[0] = 'A' + i; + RtlInitUnicodeString( &nameW, valueW ); + NtSetValueKey( hkey_new, &nameW, 0, REG_SZ, type, (strlenW(type) + 1) * sizeof(WCHAR) ); + MESSAGE( "Converted drive type to new entry HKLM\\Software\\Wine\\Drives \"%c:\" = %s\n", + 'A' + i, debugstr_w(type) ); + } + NtClose( hkey_old ); + } + NtClose( hkey_new ); +} + + +/* convert the environment variable entries from the old format to the new one */ +static void convert_environment( HKEY hkey_current_user ) +{ + static const WCHAR wineW[] = {'M','a','c','h','i','n','e','\\', + 'S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\','W','i','n','e','\\', + 'C','o','n','f','i','g','\\','W','i','n','e',0}; + static const WCHAR windowsW[] = {'w','i','n','d','o','w','s',0}; + static const WCHAR systemW[] = {'s','y','s','t','e','m',0}; + static const WCHAR windirW[] = {'w','i','n','d','i','r',0}; + static const WCHAR systemrootW[] = {'S','y','s','t','e','m','r','o','o','t',0}; + static const WCHAR winsysdirW[] = {'w','i','n','s','y','s','d','i','r',0}; + static const WCHAR envW[] = {'E','n','v','i','r','o','n','m','e','n','t',0}; + static const WCHAR tempW[] = {'T','E','M','P',0}; + static const WCHAR tmpW[] = {'T','M','P',0}; + static const WCHAR pathW[] = {'P','A','T','H',0}; + static const WCHAR profileW[] = {'p','r','o','f','i','l','e',0}; + static const WCHAR userprofileW[] = {'U','S','E','R','P','R','O','F','I','L','E',0}; + + char buffer[1024*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + DWORD dummy; + ULONG disp; + HKEY hkey_old, hkey_env; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, wineW ); + + if (NtOpenKey( &hkey_old, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return; + + attr.RootDirectory = hkey_current_user; + RtlInitUnicodeString( &nameW, envW ); + if (NtCreateKey( &hkey_env, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &disp )) + { + NtClose( hkey_old ); + return; + } + + /* Test for existence of TEMP */ + RtlInitUnicodeString( &nameW, tempW ); + if (NtQueryValueKey(hkey_env, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + /* convert TEMP */ + RtlInitUnicodeString( &nameW, tempW ); + if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength ); + RtlInitUnicodeString( &nameW, tmpW ); + NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength ); + MESSAGE( "Converted temp dir to new entry HKCU\\Environment \"TEMP\" = %s\n", + debugstr_w( (WCHAR*)info->Data ) ); + } + } + + /* Test for existence of PATH */ + RtlInitUnicodeString( &nameW, pathW ); + if (NtQueryValueKey(hkey_env, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + /* convert PATH */ + RtlInitUnicodeString( &nameW, pathW ); + if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength ); + MESSAGE( "Converted path dir to new entry HKCU\\Environment \"PATH\" = %s\n", + debugstr_w( (WCHAR*)info->Data ) ); + } + } + + /* Test for existence of USERPROFILE */ + RtlInitUnicodeString( &nameW, userprofileW ); + if (NtQueryValueKey(hkey_env, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + /* convert USERPROFILE */ + RtlInitUnicodeString( &nameW, profileW ); + if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + RtlInitUnicodeString( &nameW, userprofileW ); + NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength ); + MESSAGE( "Converted profile dir to new entry HKCU\\Environment \"USERPROFILE\" = %s\n", + debugstr_w( (WCHAR*)info->Data ) ); + } + } + + /* Test for existence of windir */ + RtlInitUnicodeString( &nameW, windirW ); + if (NtQueryValueKey(hkey_env, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + /* convert windir */ + RtlInitUnicodeString( &nameW, windowsW ); + if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + RtlInitUnicodeString( &nameW, windirW ); + NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength ); + RtlInitUnicodeString( &nameW, systemrootW ); + NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength ); + MESSAGE( "Converted windows dir to new entry HKCU\\Environment \"windir\" = %s\n", + debugstr_w( (WCHAR*)info->Data ) ); + } + } + + /* Test for existence of winsysdir */ + RtlInitUnicodeString( &nameW, winsysdirW ); + if (NtQueryValueKey(hkey_env, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + /* convert winsysdir */ + RtlInitUnicodeString( &nameW, systemW ); + if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) + { + RtlInitUnicodeString( &nameW, winsysdirW ); + NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength ); + MESSAGE( "Converted system dir to new entry HKCU\\Environment \"winsysdir\" = %s\n", + debugstr_w( (WCHAR*)info->Data ) ); + } + } + NtClose( hkey_old ); + NtClose( hkey_env ); +} + + +/* registry initialisation, allocates some default keys. */ +static ULONG allocate_default_keys(void) +{ + static const WCHAR StatDataW[] = {'D','y','n','D','a','t','a','\\', + 'P','e','r','f','S','t','a','t','s','\\', + 'S','t','a','t','D','a','t','a',0}; + static const WCHAR ConfigManagerW[] = {'D','y','n','D','a','t','a','\\', + 'C','o','n','f','i','g',' ','M','a','n','a','g','e','r','\\', + 'E','n','u','m',0}; + HKEY hkey; + ULONG dispos; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + RtlInitUnicodeString( &nameW, StatDataW ); + if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &dispos )) NtClose( hkey ); + if (dispos == REG_OPENED_EXISTING_KEY) + return dispos; /* someone else already loaded the registry */ + + RtlInitUnicodeString( &nameW, ConfigManagerW ); + if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) NtClose( hkey ); + + return dispos; +} + + +/****************************************************************** + * init_cdrom_registry + * + * Initializes registry to contain scsi info about the cdrom in NT. + * All devices (even not real scsi ones) have this info in NT. + * TODO: for now it only works for non scsi devices + * NOTE: programs usually read these registry entries after sending the + * IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom + */ +static void init_cdrom_registry( HANDLE handle ) +{ + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + WCHAR dataW[50]; + DWORD lenW; + char buffer[40]; + DWORD value; + const char *data; + HKEY scsiKey; + HKEY portKey; + HKEY busKey; + HKEY targetKey; + DWORD disp; + IO_STATUS_BLOCK io; + SCSI_ADDRESS scsi_addr; + + if (NtDeviceIoControlFile( handle, 0, NULL, NULL, &io, IOCTL_SCSI_GET_ADDRESS, + NULL, 0, &scsi_addr, sizeof(scsi_addr) )) + return; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + /* Ensure there is Scsi key */ + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) || + NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr.PortNumber); + attr.RootDirectory = scsiKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || + NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" ); + data = "atapi"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + value = 10; + RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" ); + NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); + RtlFreeUnicodeString( &nameW ); + value = 0; +#ifdef HDIO_GET_DMA + { + int fd, dma; + if (!wine_server_handle_to_fd( handle, 0, &fd, NULL )) + { + if (ioctl(fd,HDIO_GET_DMA, &dma) != -1) value = dma; + wine_server_release_fd( handle, fd ); + } + } +#endif + RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" ); + NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); + RtlFreeUnicodeString( &nameW ); + + snprintf(buffer,40,"Scsi Bus %d", scsi_addr.PathId); + attr.RootDirectory = portKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || + NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + attr.RootDirectory = busKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) || + NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + NtClose( targetKey ); + + snprintf(buffer,40,"Target Id %d", scsi_addr.TargetId); + attr.RootDirectory = busKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || + NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" ); + data = "CdRomPeripheral"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + /* FIXME - maybe read the real identifier?? */ + RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" ); + data = "Wine CDROM"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + /* FIXME - we always use Cdrom0 - do not know about the nt behaviour */ + RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" ); + data = "Cdrom0"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + + NtClose( targetKey ); + NtClose( busKey ); + NtClose( portKey ); + NtClose( scsiKey ); +} + + +/* create the hardware registry branch */ +static void create_hardware_branch(void) +{ + int i; + HANDLE handle; + char drive[] = "\\\\.\\A:"; + + /* create entries for cdroms (skipping A: and B:) */ + for (i = 2; i < 26; i++) + { + drive[4] = 'A' + i; + handle = CreateFileA( drive, 0, 0, NULL, OPEN_EXISTING, 0, 0 ); + if (handle == INVALID_HANDLE_VALUE) continue; + init_cdrom_registry( handle ); + CloseHandle( handle ); + } +} + + +/*********************************************************************** + * convert_old_config + */ +void convert_old_config(void) +{ + HKEY hkey_current_user; + + if (allocate_default_keys() == REG_OPENED_EXISTING_KEY) + return; /* someone else already loaded the registry */ + + RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey_current_user ); + + /* load the user registry (FIXME: should be done at server init time) */ + SERVER_START_REQ( load_user_registries ) + { + req->hkey = hkey_current_user; + wine_server_call( req ); + } + SERVER_END_REQ; + + /* convert old configuration */ + create_dos_devices(); + convert_drive_types(); + convert_environment( hkey_current_user ); + + /* create some hardware keys (FIXME: should not be done here) */ + create_hardware_branch(); + + NtClose( hkey_current_user ); +} diff -urN wine-20050419/dlls/kernel/process.c wine-20050524/dlls/kernel/process.c --- wine-20050419/dlls/kernel/process.c 2005-03-19 18:14:12.000000000 +0100 +++ wine-20050524/dlls/kernel/process.c 2005-04-20 17:43:36.000000000 +0200 @@ -86,7 +86,7 @@ static const WCHAR winevdmW[] = {'w','i','n','e','v','d','m','.','e','x','e',0}; extern void SHELL_LoadRegistry(void); -extern void VOLUME_CreateDevices(void); +extern void convert_old_config(void); extern void VERSION_Init( const WCHAR *appname ); extern void LOCALE_Init(void); @@ -995,11 +995,8 @@ /* Copy the parent environment */ if (!build_initial_environment( __wine_main_environ )) return FALSE; - /* Create device symlinks */ - VOLUME_CreateDevices(); - - /* registry initialisation */ - SHELL_LoadRegistry(); + /* convert old configuration to new format */ + convert_old_config(); /* global boot finished, the rest is process-local */ SERVER_START_REQ( boot_done ) diff -urN wine-20050419/dlls/kernel/profile.c wine-20050524/dlls/kernel/profile.c --- wine-20050419/dlls/kernel/profile.c 2005-03-28 16:58:52.000000000 +0200 +++ wine-20050524/dlls/kernel/profile.c 2005-05-06 17:44:32.000000000 +0200 @@ -1580,12 +1580,12 @@ * Win95: * - if the buffer is 0 or 1 character long then it is as if it was of * infinite length. - * - otherwise, if the buffer is to small only the section names that fit + * - otherwise, if the buffer is too small only the section names that fit * are returned. - * - note that this means if the buffer was to small to return even just + * - note that this means if the buffer was too small to return even just * the first section name then a single '\0' will be returned. * - the return value is the number of characters written in the buffer, - * except if the buffer was too smal in which case len-2 is returned + * except if the buffer was too small in which case len-2 is returned * * Win2000: * - if the buffer is 0, 1 or 2 characters long then it is filled with diff -urN wine-20050419/dlls/kernel/relay16.c wine-20050524/dlls/kernel/relay16.c --- wine-20050419/dlls/kernel/relay16.c 2003-11-17 21:31:30.000000000 +0100 +++ wine-20050524/dlls/kernel/relay16.c 2005-05-17 16:36:09.000000000 +0200 @@ -29,10 +29,8 @@ #include "windef.h" #include "winbase.h" #include "wine/winbase16.h" -#include "module.h" -#include "stackframe.h" -#include "builtin16.h" #include "kernel_private.h" +#include "kernel16_private.h" #include "wine/unicode.h" #include "wine/library.h" #include "wine/debug.h" @@ -241,7 +239,7 @@ max_offset = 0; *pOrd = 0; - bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table); + bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->ne_enttab); do { entry = (ET_ENTRY *)((BYTE *)bundle+6); @@ -262,7 +260,7 @@ /* Search for the name in the resident names table */ /* (built-in modules have no non-resident table) */ - p = (BYTE *)pModule + pModule->name_table; + p = (BYTE *)pModule + pModule->ne_restab; memcpy( module, p + 1, *p ); module[*p] = 0; diff -urN wine-20050419/dlls/kernel/resource16.c wine-20050524/dlls/kernel/resource16.c --- wine-20050419/dlls/kernel/resource16.c 2005-03-24 22:01:38.000000000 +0100 +++ wine-20050524/dlls/kernel/resource16.c 2005-05-20 21:19:01.000000000 +0200 @@ -36,7 +36,7 @@ #include "wine/winbase16.h" #include "wine/winuser16.h" #include "wine/unicode.h" -#include "module.h" +#include "kernel16_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(resource); @@ -72,7 +72,7 @@ */ static HRSRC16 MapHRsrc32To16( NE_MODULE *pModule, HRSRC hRsrc32, WORD type ) { - HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + HRSRC_MAP *map = pModule->rsrc32_map; HRSRC_ELEM *newElem; int i; @@ -84,7 +84,7 @@ ERR("Cannot allocate HRSRC map\n" ); return 0; } - pModule->hRsrcMap = map; + pModule->rsrc32_map = map; } /* Check whether HRSRC32 already in map */ @@ -125,7 +125,7 @@ */ static HRSRC MapHRsrc16To32( NE_MODULE *pModule, HRSRC16 hRsrc16 ) { - HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + HRSRC_MAP *map = pModule->rsrc32_map; if ( !map || !hRsrc16 || hRsrc16 > map->nUsed ) return 0; return map->elem[hRsrc16-1].hRsrc; @@ -136,7 +136,7 @@ */ static WORD MapHRsrc16ToType( NE_MODULE *pModule, HRSRC16 hRsrc16 ) { - HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + HRSRC_MAP *map = pModule->rsrc32_map; if ( !map || !hRsrc16 || hRsrc16 > map->nUsed ) return 0; return map->elem[hRsrc16-1].type; @@ -184,7 +184,7 @@ */ static DWORD NE_FindNameTableId( NE_MODULE *pModule, LPCSTR typeId, LPCSTR resId ) { - NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); + NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->ne_rsrctab + 2); NE_NAMEINFO *pNameInfo; HGLOBAL16 handle; WORD *p; @@ -330,53 +330,32 @@ HGLOBAL16 WINAPI NE_DefResourceHandler( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc ) { - HANDLE fd; + HGLOBAL16 handle; + WORD sizeShift; + NE_NAMEINFO* pNameInfo; NE_MODULE* pModule = NE_GetPtr( hModule ); - if (pModule && (pModule->flags & NE_FFLAGS_BUILTIN)) - { - HGLOBAL16 handle; - WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); - NE_NAMEINFO* pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); - if ( hMemObj ) - handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 ); - else - handle = AllocResource16( hModule, hRsrc, 0 ); + if (!pModule) return 0; - if ( handle ) - { - /* NOTE: hRsrcMap points to start of built-in resource data */ - memcpy( GlobalLock16( handle ), - (char *)pModule->hRsrcMap + (pNameInfo->offset << sizeShift), - pNameInfo->length << sizeShift ); - } - return handle; - } - if (pModule && (fd = NE_OpenFile( pModule )) != INVALID_HANDLE_VALUE) - { - HGLOBAL16 handle; - WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); - NE_NAMEINFO* pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); + sizeShift = *(WORD *)((char *)pModule + pModule->ne_rsrctab); + pNameInfo = (NE_NAMEINFO *)((char *)pModule + hRsrc); - TRACE("loading, pos=%d, len=%d\n", - (int)pNameInfo->offset << sizeShift, - (int)pNameInfo->length << sizeShift ); - if( hMemObj ) - handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 ); - else - handle = AllocResource16( hModule, hRsrc, 0 ); + if ( hMemObj ) + handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 ); + else + handle = AllocResource16( hModule, hRsrc, 0 ); - if( handle ) + if (handle) + { + if (!NE_READ_DATA( pModule, GlobalLock16( handle ), + (int)pNameInfo->offset << sizeShift, + (int)pNameInfo->length << sizeShift )) { - DWORD res; - SetFilePointer( fd, (int)pNameInfo->offset << sizeShift, NULL, SEEK_SET ); - ReadFile( fd, GlobalLock16( handle ), (int)pNameInfo->length << sizeShift, - &res, NULL ); + GlobalFree16( handle ); + handle = 0; } - CloseHandle(fd); - return handle; } - return (HGLOBAL16)0; + return handle; } @@ -390,9 +369,9 @@ FARPROC16 prevHandler = NULL; NE_MODULE *pModule = NE_GetPtr( hModule ); - if (!pModule || !pModule->res_table) return NULL; + if (!pModule || !pModule->ne_rsrctab) return NULL; - pResTab = (LPBYTE)pModule + pModule->res_table; + pResTab = (LPBYTE)pModule + pModule->ne_rsrctab; pTypeInfo = (NE_TYPEINFO *)(pResTab + 2); TRACE("module=%04x type=%s\n", hModule, debugstr_a(typeId) ); @@ -892,11 +871,11 @@ HGLOBAL16 ret; NE_MODULE *pModule = NE_GetPtr( hModule ); - if (!pModule || !pModule->res_table || !hRsrc) return 0; + if (!pModule || !pModule->ne_rsrctab || !hRsrc) return 0; TRACE("module=%04x res=%04x size=%ld\n", hModule, hRsrc, size ); - sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + sizeShift = *(WORD *)((char *)pModule + pModule->ne_rsrctab); pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); if (size < (DWORD)pNameInfo->length << sizeShift) size = (DWORD)pNameInfo->length << sizeShift; @@ -934,13 +913,13 @@ HFILE16 fd; NE_MODULE *pModule = NE_GetPtr( hModule ); - if (!pModule || !pModule->res_table || !hRsrc) return -1; + if (!pModule || !pModule->ne_rsrctab || !hRsrc) return -1; TRACE("module=%04x res=%04x\n", pModule->self, hRsrc ); if ((fd = _lopen16( NE_MODULE_NAME(pModule), OF_READ )) != HFILE_ERROR16) { - WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + WORD sizeShift = *(WORD *)((char *)pModule + pModule->ne_rsrctab); NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); _llseek16( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET ); } @@ -969,7 +948,7 @@ TRACE("module=%04x name=%s type=%s\n", pModule->self, debugstr_a(name), debugstr_a(type) ); - if (!pModule->res_table) return 0; + if (!pModule->ne_rsrctab) return 0; type = get_res_name( type ); name = get_res_name( name ); @@ -983,7 +962,7 @@ name = (LPCSTR)(ULONG_PTR)HIWORD(id); } } - pResTab = (LPBYTE)pModule + pModule->res_table; + pResTab = (LPBYTE)pModule + pModule->ne_rsrctab; pTypeInfo = (NE_TYPEINFO *)( pResTab + 2 ); for (;;) @@ -1025,7 +1004,7 @@ /* first, verify hRsrc (just an offset from pModule to the needed pNameInfo) */ - d = pModule->res_table + 2; + d = pModule->ne_rsrctab + 2; pTypeInfo = (NE_TYPEINFO *)((char *)pModule + d); while( hRsrc > d ) { @@ -1111,9 +1090,9 @@ if (!hRsrc) return 0; if (!(pModule = get_module( hModule ))) return 0; - if (pModule->res_table) + if (pModule->ne_rsrctab) { - WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + WORD sizeShift = *(WORD *)((char *)pModule + pModule->ne_rsrctab); NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); return (DWORD)pNameInfo->length << sizeShift; } @@ -1141,9 +1120,9 @@ /* Try NE resource first */ - if (pModule && pModule->res_table) + if (pModule && pModule->ne_rsrctab) { - NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); + NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->ne_rsrctab + 2); while (pTypeInfo->type_id) { WORD count; diff -urN wine-20050419/dlls/kernel/selector.c wine-20050524/dlls/kernel/selector.c --- wine-20050419/dlls/kernel/selector.c 2004-10-22 21:55:14.000000000 +0200 +++ wine-20050524/dlls/kernel/selector.c 2005-05-10 18:01:38.000000000 +0200 @@ -25,7 +25,6 @@ #include "winerror.h" #include "wine/winbase16.h" -#include "miscemu.h" #include "wine/server.h" #include "wine/debug.h" #include "kernel_private.h" @@ -564,11 +563,13 @@ /*********************************************************************** * UnMapSLFixArray (KERNEL32.@) */ - -void UnMapSLFixArray( SEGPTR sptr[], INT length, CONTEXT86 *context ) +void WINAPI __regs_UnMapSLFixArray( SEGPTR sptr[], INT length, CONTEXT86 *context ) { /* Must not change EAX, hence defined as 'register' function */ } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( UnMapSLFixArray, 8, 8 ); +#endif /*********************************************************************** * GetThreadSelectorEntry (KERNEL32.@) @@ -637,77 +638,12 @@ } -/********************************************************************** - * SMapLS* (KERNEL32) - * These functions map linear pointers at [EBP+xxx] to segmented pointers - * and return them. - * Win95 uses some kind of alias structs, which it stores in [EBP+x] to - * unravel them at SUnMapLS. We just store the segmented pointer there. - */ -static void x_SMapLS_IP_EBP_x(CONTEXT86 *context,int argoff) -{ - DWORD val,ptr; - - val =*(DWORD*)(context->Ebp + argoff); - if (val<0x10000) { - ptr=val; - *(DWORD*)(context->Ebp + argoff) = 0; - } else { - ptr = MapLS((LPVOID)val); - *(DWORD*)(context->Ebp + argoff) = ptr; - } - context->Eax = ptr; -} - -/*********************************************************************** - * SMapLS_IP_EBP_8 (KERNEL32.@) - */ -void SMapLS_IP_EBP_8 (CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context, 8);} - -/*********************************************************************** - * SMapLS_IP_EBP_12 (KERNEL32.@) - */ -void SMapLS_IP_EBP_12(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,12);} - -/*********************************************************************** - * SMapLS_IP_EBP_16 (KERNEL32.@) - */ -void SMapLS_IP_EBP_16(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,16);} - -/*********************************************************************** - * SMapLS_IP_EBP_20 (KERNEL32.@) - */ -void SMapLS_IP_EBP_20(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,20);} - -/*********************************************************************** - * SMapLS_IP_EBP_24 (KERNEL32.@) - */ -void SMapLS_IP_EBP_24(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,24);} - -/*********************************************************************** - * SMapLS_IP_EBP_28 (KERNEL32.@) - */ -void SMapLS_IP_EBP_28(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,28);} - -/*********************************************************************** - * SMapLS_IP_EBP_32 (KERNEL32.@) - */ -void SMapLS_IP_EBP_32(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,32);} - -/*********************************************************************** - * SMapLS_IP_EBP_36 (KERNEL32.@) - */ -void SMapLS_IP_EBP_36(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,36);} - -/*********************************************************************** - * SMapLS_IP_EBP_40 (KERNEL32.@) - */ -void SMapLS_IP_EBP_40(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,40);} +#ifdef DEFINE_REGS_ENTRYPOINT /*********************************************************************** * SMapLS (KERNEL32.@) */ -void SMapLS( CONTEXT86 *context ) +void WINAPI __regs_SMapLS( CONTEXT86 *context ) { if (HIWORD(context->Eax)) { @@ -717,67 +653,87 @@ context->Edx = 0; } } +DEFINE_REGS_ENTRYPOINT( SMapLS, 0, 0 ); /*********************************************************************** * SUnMapLS (KERNEL32.@) */ - -void SUnMapLS( CONTEXT86 *context ) +void WINAPI __regs_SUnMapLS( CONTEXT86 *context ) { if (HIWORD(context->Eax)) UnMapLS( (SEGPTR)context->Eax ); } +DEFINE_REGS_ENTRYPOINT( SUnMapLS, 0, 0 ); -inline static void x_SUnMapLS_IP_EBP_x(CONTEXT86 *context,int argoff) -{ - SEGPTR *ptr = (SEGPTR *)(context->Ebp + argoff); - if (*ptr) - { - UnMapLS( *ptr ); - *ptr = 0; - } -} /*********************************************************************** - * SUnMapLS_IP_EBP_8 (KERNEL32.@) + * SMapLS_IP_EBP_8 (KERNEL32.@) + * SMapLS_IP_EBP_12 (KERNEL32.@) + * SMapLS_IP_EBP_16 (KERNEL32.@) + * SMapLS_IP_EBP_20 (KERNEL32.@) + * SMapLS_IP_EBP_24 (KERNEL32.@) + * SMapLS_IP_EBP_28 (KERNEL32.@) + * SMapLS_IP_EBP_32 (KERNEL32.@) + * SMapLS_IP_EBP_36 (KERNEL32.@) + * SMapLS_IP_EBP_40 (KERNEL32.@) + * + * These functions map linear pointers at [EBP+xxx] to segmented pointers + * and return them. + * Win95 uses some kind of alias structs, which it stores in [EBP+x] to + * unravel them at SUnMapLS. We just store the segmented pointer there. */ -void SUnMapLS_IP_EBP_8 (CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context, 8); } +#define DEFINE_SMapLS(n) \ +void WINAPI __regs_SMapLS_IP_EBP_ ## n (CONTEXT86 *context) \ +{ \ + SEGPTR *ptr = (SEGPTR *)(context->Ebp + n); \ + if (!HIWORD(*ptr)) \ + { \ + context->Eax = *ptr; \ + *ptr = 0; \ + } \ + else *ptr = context->Eax = MapLS((LPVOID)*ptr); \ +} \ +DEFINE_REGS_ENTRYPOINT( SMapLS_IP_EBP_ ## n, 0, 0 ) + +DEFINE_SMapLS(8); +DEFINE_SMapLS(12); +DEFINE_SMapLS(16); +DEFINE_SMapLS(20); +DEFINE_SMapLS(24); +DEFINE_SMapLS(28); +DEFINE_SMapLS(32); +DEFINE_SMapLS(36); +DEFINE_SMapLS(40); -/*********************************************************************** - * SUnMapLS_IP_EBP_12 (KERNEL32.@) - */ -void SUnMapLS_IP_EBP_12(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,12); } /*********************************************************************** + * SUnMapLS_IP_EBP_8 (KERNEL32.@) + * SUnMapLS_IP_EBP_12 (KERNEL32.@) * SUnMapLS_IP_EBP_16 (KERNEL32.@) - */ -void SUnMapLS_IP_EBP_16(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,16); } - -/*********************************************************************** * SUnMapLS_IP_EBP_20 (KERNEL32.@) - */ -void SUnMapLS_IP_EBP_20(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,20); } - -/*********************************************************************** * SUnMapLS_IP_EBP_24 (KERNEL32.@) - */ -void SUnMapLS_IP_EBP_24(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,24); } - -/*********************************************************************** * SUnMapLS_IP_EBP_28 (KERNEL32.@) - */ -void SUnMapLS_IP_EBP_28(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,28); } - -/*********************************************************************** * SUnMapLS_IP_EBP_32 (KERNEL32.@) - */ -void SUnMapLS_IP_EBP_32(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,32); } - -/*********************************************************************** * SUnMapLS_IP_EBP_36 (KERNEL32.@) - */ -void SUnMapLS_IP_EBP_36(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,36); } - -/*********************************************************************** * SUnMapLS_IP_EBP_40 (KERNEL32.@) */ -void SUnMapLS_IP_EBP_40(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,40); } + +#define DEFINE_SUnMapLS(n) \ +void WINAPI __regs_SUnMapLS_IP_EBP_ ## n (CONTEXT86 *context) \ +{ \ + SEGPTR *ptr = (SEGPTR *)(context->Ebp + n); \ + UnMapLS( *ptr ); \ + *ptr = 0; \ +} \ +DEFINE_REGS_ENTRYPOINT( SUnMapLS_IP_EBP_ ## n, 0, 0 ) + +DEFINE_SUnMapLS(8); +DEFINE_SUnMapLS(12); +DEFINE_SUnMapLS(16); +DEFINE_SUnMapLS(20); +DEFINE_SUnMapLS(24); +DEFINE_SUnMapLS(28); +DEFINE_SUnMapLS(32); +DEFINE_SUnMapLS(36); +DEFINE_SUnMapLS(40); + +#endif /* DEFINE_REGS_ENTRYPOINT */ diff -urN wine-20050419/dlls/kernel/snoop16.c wine-20050524/dlls/kernel/snoop16.c --- wine-20050419/dlls/kernel/snoop16.c 2004-05-27 22:00:37.000000000 +0200 +++ wine-20050524/dlls/kernel/snoop16.c 2005-05-18 11:58:43.000000000 +0200 @@ -31,9 +31,7 @@ #include "wine/winbase16.h" #include "wine/library.h" #include "kernel_private.h" -#include "module.h" -#include "stackframe.h" -#include "builtin16.h" +#include "kernel16_private.h" #include "toolhelp.h" #include "wine/debug.h" @@ -43,8 +41,6 @@ #include "pshpack1.h" -extern int SNOOP16_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname); - void WINAPI SNOOP16_Entry(FARPROC proc, LPBYTE args, CONTEXT86 *context); void WINAPI SNOOP16_Return(FARPROC proc, LPBYTE args, CONTEXT86 *context); @@ -104,13 +100,13 @@ static HANDLE16 xsnr = 0; void -SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) { +SNOOP16_RegisterDLL(HMODULE16 hModule,LPCSTR name) { SNOOP16_DLL **dll = &(firstdll); char *s; if (!TRACE_ON(snoop)) return; - TRACE("hmod=%x, name=%s\n", pModule->self, name); + TRACE("hmod=%x, name=%s\n", hModule, name); if (!snr) { xsnr=GLOBAL_Alloc(GMEM_ZEROINIT,2*sizeof(*snr),0,WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT); @@ -136,7 +132,7 @@ snr[1].lret = 0xcb66; } while (*dll) { - if ((*dll)->hmod == pModule->self) + if ((*dll)->hmod == hModule) { /* another dll, loaded at the same address */ GlobalUnlock16((*dll)->funhandle); @@ -152,7 +148,7 @@ *dll = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SNOOP16_DLL)+strlen(name)); (*dll)->next = NULL; - (*dll)->hmod = pModule->self; + (*dll)->hmod = hModule; if ((s=strrchr(name,'\\'))) name = s+1; strcpy( (*dll)->name, name ); @@ -195,7 +191,7 @@ fun->origfun = origfun; if (fun->name) return (FARPROC16)(SEGPTR)MAKELONG(((char*)fun-(char*)dll->funs),dll->funhandle); - cpnt = (unsigned char *)pModule + pModule->name_table; + cpnt = (unsigned char *)pModule + pModule->ne_restab; while (*cpnt) { cpnt += *cpnt + 1 + sizeof(WORD); if (*(WORD*)(cpnt+*cpnt+1) == ordinal) { @@ -348,7 +344,7 @@ ret->origreturn = NULL; /* mark as empty */ } #else /* !__i386__ */ -void SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) { +void SNOOP16_RegisterDLL(HMODULE16 hModule,LPCSTR name) { if (!TRACE_ON(snoop)) return; FIXME("snooping works only on i386 for now.\n"); } diff -urN wine-20050419/dlls/kernel/sync.c wine-20050524/dlls/kernel/sync.c --- wine-20050419/dlls/kernel/sync.c 2005-04-18 16:57:04.000000000 +0200 +++ wine-20050524/dlls/kernel/sync.c 2005-04-24 19:36:34.000000000 +0200 @@ -284,12 +284,31 @@ * Allows to atomically signal any of the synchro objects (semaphore, * mutex, event) and wait on another. */ -DWORD WINAPI SignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable ) +DWORD WINAPI SignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, + DWORD dwMilliseconds, BOOL bAlertable ) { - FIXME("(%p %p %ld %d): stub\n", hObjectToSignal, hObjectToWaitOn, dwMilliseconds, bAlertable); - return WAIT_OBJECT_0; -} + NTSTATUS status; + LARGE_INTEGER timeout, *ptimeout = NULL; + + TRACE("%p %p %ld %d\n", hObjectToSignal, + hObjectToWaitOn, dwMilliseconds, bAlertable); + + if (dwMilliseconds != INFINITE) + { + timeout.QuadPart = dwMilliseconds * (ULONGLONG)10000; + timeout.QuadPart = -timeout.QuadPart; + ptimeout = &timeout; + } + status = NtSignalAndWaitForSingleObject( hObjectToSignal, hObjectToWaitOn, + bAlertable, ptimeout ); + if (HIWORD(status)) + { + SetLastError( RtlNtStatusToDosError(status) ); + status = WAIT_FAILED; + } + return status; +} /*********************************************************************** * InitializeCriticalSection (KERNEL32.@) @@ -1098,7 +1117,7 @@ pipe_type = (dwPipeMode & PIPE_TYPE_MESSAGE) ? TRUE : FALSE; read_mode = (dwPipeMode & PIPE_READMODE_MESSAGE) ? TRUE : FALSE; non_block = (dwPipeMode & PIPE_NOWAIT) ? TRUE : FALSE; - if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES) nMaxInstances = ULONG_MAX; + if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES) nMaxInstances = ~0UL; timeout.QuadPart = (ULONGLONG)nDefaultTimeOut * -10000; diff -urN wine-20050419/dlls/kernel/syslevel.c wine-20050524/dlls/kernel/syslevel.c --- wine-20050419/dlls/kernel/syslevel.c 2004-02-26 06:30:54.000000000 +0100 +++ wine-20050524/dlls/kernel/syslevel.c 2005-05-16 19:52:10.000000000 +0200 @@ -27,10 +27,10 @@ #include #include "windef.h" #include "winbase.h" +#include "thread.h" #include "winreg.h" #include "winternl.h" #include "wine/winbase16.h" -#include "thread.h" #include "kernel_private.h" #include "wine/library.h" #include "wine/debug.h" diff -urN wine-20050419/dlls/kernel/system.c wine-20050524/dlls/kernel/system.c --- wine-20050419/dlls/kernel/system.c 2004-01-23 02:51:34.000000000 +0100 +++ wine-20050524/dlls/kernel/system.c 2005-05-16 21:44:54.000000000 +0200 @@ -28,7 +28,8 @@ #include "wine/winbase16.h" #include "wine/winuser16.h" #include "wownt32.h" -#include "stackframe.h" +#include "kernel_private.h" +#include "kernel16_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(system); @@ -175,8 +176,7 @@ context.SegGs = wine_get_gs(); context.SegCs = SELECTOROF( proc ); context.Eip = OFFSETOF( proc ); - context.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) - + (WORD)&((STACK16FRAME*)0)->bp; + context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp; context.Eax = timer; WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context ); diff -urN wine-20050419/dlls/kernel/task.c wine-20050524/dlls/kernel/task.c --- wine-20050419/dlls/kernel/task.c 2005-04-18 17:36:21.000000000 +0200 +++ wine-20050524/dlls/kernel/task.c 2005-05-17 16:36:09.000000000 +0200 @@ -37,13 +37,12 @@ #include "winuser.h" #include "wine/winbase16.h" -#include "module.h" +#include "thread.h" #include "winternl.h" #include "wine/server.h" -#include "stackframe.h" -#include "thread.h" #include "toolhelp.h" #include "kernel_private.h" +#include "kernel16_private.h" #include "wine/debug.h" @@ -274,7 +273,7 @@ pTask->hSelf = hTask; - pTask->version = pModule ? pModule->expected_version : 0x0400; + pTask->version = pModule ? pModule->ne_expver : 0x0400; pTask->hModule = hModule; pTask->hParent = GetCurrentTask(); pTask->magic = TDB_MAGIC; @@ -611,7 +610,7 @@ /* Initialize the INSTANCEDATA structure */ pinstance = MapSL( MAKESEGPTR(CURRENT_DS, 0) ); - pinstance->stackmin = OFFSETOF( NtCurrentTeb()->cur_stack ) + sizeof( STACK16FRAME ); + pinstance->stackmin = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + sizeof( STACK16FRAME ); pinstance->stackbottom = pinstance->stackmin; /* yup, that's right. Confused me too. */ pinstance->stacktop = ( pinstance->stackmin > LOWORD(context->Ebx) ? pinstance->stackmin - LOWORD(context->Ebx) : 0 ) + 150; @@ -857,7 +856,7 @@ hInstance = GlobalHandle16(hInstanceSelector); /* no thunking for DLLs */ - if (NE_GetPtr(FarGetOwner16(hInstance))->flags & NE_FFLAGS_LIBMODULE) + if (NE_GetPtr(FarGetOwner16(hInstance))->ne_flags & NE_FFLAGS_LIBMODULE) return func; thunkaddr = TASK_AllocThunk(); @@ -917,10 +916,10 @@ /* Try pair of module handle / segment number */ pModule = (NE_MODULE *) GlobalLock16( HIWORD( proc ) ); - if ( pModule && pModule->magic == IMAGE_OS2_SIGNATURE ) + if ( pModule && pModule->ne_magic == IMAGE_OS2_SIGNATURE ) { segNr = LOWORD( proc ); - if ( segNr && segNr <= pModule->seg_count ) + if ( segNr && segNr <= pModule->ne_cseg ) pSeg = NE_SEG_TABLE( pModule ) + segNr-1; } @@ -939,11 +938,11 @@ pSeg = pModule? NE_SEG_TABLE( pModule ) : NULL; if ( pModule ) - for ( segNr = 1; segNr <= pModule->seg_count; segNr++, pSeg++ ) + for ( segNr = 1; segNr <= pModule->ne_cseg; segNr++, pSeg++ ) if ( GlobalHandleToSel16(pSeg->hSeg) == selector ) break; - if ( pModule && segNr > pModule->seg_count ) + if ( pModule && segNr > pModule->ne_cseg ) pSeg = NULL; } @@ -993,10 +992,10 @@ segInfo->flags = pSeg->flags; segInfo->cbAlloc = pSeg->minsize; segInfo->h = pSeg->hSeg; - segInfo->alignShift = pModule->alignment; + segInfo->alignShift = pModule->ne_align; - if ( segNr == pModule->dgroup ) - segInfo->cbAlloc += pModule->heap_size + pModule->stack_size; + if ( segNr == pModule->ne_autodata ) + segInfo->cbAlloc += pModule->ne_heap + pModule->ne_stack; /* Return module handle in %es */ @@ -1021,16 +1020,8 @@ */ HQUEUE16 WINAPI SetTaskQueue16( HTASK16 hTask, HQUEUE16 hQueue ) { - HQUEUE16 hPrev; - TDB *pTask; - - if (!hTask) hTask = GetCurrentTask(); - if (!(pTask = TASK_GetPtr( hTask ))) return 0; - - hPrev = pTask->hQueue; - pTask->hQueue = hQueue; - - return hPrev; + FIXME( "stub, should not get called\n" ); + return 0xbeef; } @@ -1039,11 +1030,8 @@ */ HQUEUE16 WINAPI GetTaskQueue16( HTASK16 hTask ) { - TDB *pTask; - - if (!hTask) hTask = GetCurrentTask(); - if (!(pTask = TASK_GetPtr( hTask ))) return 0; - return pTask->hQueue; + FIXME( "stub, should not get called\n" ); + return 0xbeef; } /*********************************************************************** @@ -1051,17 +1039,8 @@ */ HQUEUE16 WINAPI SetThreadQueue16( DWORD thread, HQUEUE16 hQueue ) { - HQUEUE16 oldQueue = NtCurrentTeb()->queue; - - if (thread && thread != GetCurrentThreadId()) - { - FIXME( "not supported on other thread %04lx\n", thread ); - return 0; - } - NtCurrentTeb()->queue = hQueue; - if ( GetTaskQueue16( NtCurrentTeb()->htask16 ) == oldQueue ) - SetTaskQueue16( NtCurrentTeb()->htask16, hQueue ); - return oldQueue; + FIXME( "stub, should not get called\n" ); + return 0xbeef; } /*********************************************************************** @@ -1069,12 +1048,8 @@ */ HQUEUE16 WINAPI GetThreadQueue16( DWORD thread ) { - if (thread && thread != GetCurrentThreadId()) - { - FIXME( "not supported on other thread %04lx\n", thread ); - return 0; - } - return NtCurrentTeb()->queue; + FIXME( "stub, should not get called\n" ); + return 0xbeef; } /*********************************************************************** @@ -1082,10 +1057,7 @@ */ VOID WINAPI SetFastQueue16( DWORD thread, HQUEUE16 hQueue ) { - if (!thread || thread == GetCurrentThreadId()) - NtCurrentTeb()->queue = hQueue; - else - FIXME( "not supported on other thread %04lx\n", thread ); + FIXME( "stub, should not get called\n" ); } /*********************************************************************** @@ -1093,10 +1065,8 @@ */ HQUEUE16 WINAPI GetFastQueue16( void ) { - HQUEUE16 ret = NtCurrentTeb()->queue; - - if (!ret) FIXME("(): should initialize thread-local queue, expect failure!\n" ); - return ret; + FIXME( "stub, should not get called\n" ); + return 0xbeef; } /*********************************************************************** @@ -1110,14 +1080,14 @@ if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return; TRACE("old=%04x:%04x new=%04x:%04x\n", - SELECTOROF( NtCurrentTeb()->cur_stack ), - OFFSETOF( NtCurrentTeb()->cur_stack ), seg, ptr ); + SELECTOROF( NtCurrentTeb()->WOW32Reserved ), + OFFSETOF( NtCurrentTeb()->WOW32Reserved ), seg, ptr ); /* Save the old stack */ oldFrame = CURRENT_STACK16; /* pop frame + args and push bp */ - pData->old_ss_sp = NtCurrentTeb()->cur_stack + sizeof(STACK16FRAME) + pData->old_ss_sp = (SEGPTR)NtCurrentTeb()->WOW32Reserved + sizeof(STACK16FRAME) + 2 * sizeof(WORD); *(WORD *)MapSL(pData->old_ss_sp) = oldFrame->bp; pData->stacktop = top; @@ -1131,7 +1101,7 @@ */ copySize = oldFrame->bp - OFFSETOF(pData->old_ss_sp); copySize += 3 * sizeof(WORD) + sizeof(STACK16FRAME); - NtCurrentTeb()->cur_stack = MAKESEGPTR( seg, ptr - copySize ); + NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR( seg, ptr - copySize ); newFrame = CURRENT_STACK16; /* Copy the stack frame and the local variables to the new stack */ @@ -1150,7 +1120,7 @@ STACK16FRAME *oldFrame, *newFrame; INSTANCEDATA *pData; - if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(NtCurrentTeb()->cur_stack)))) + if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(NtCurrentTeb()->WOW32Reserved)))) return; if (!pData->old_ss_sp) { @@ -1169,7 +1139,7 @@ /* Switch back to the old stack */ - NtCurrentTeb()->cur_stack = pData->old_ss_sp - sizeof(STACK16FRAME); + NtCurrentTeb()->WOW32Reserved = (void *)(pData->old_ss_sp - sizeof(STACK16FRAME)); context->SegSs = SELECTOROF(pData->old_ss_sp); context->Esp = OFFSETOF(pData->old_ss_sp) - sizeof(DWORD); /*ret addr*/ pData->old_ss_sp = 0; @@ -1407,7 +1377,7 @@ /* Check for module handle */ if (!(ptr = GlobalLock16( handle ))) return 0; - if (((NE_MODULE *)ptr)->magic == IMAGE_OS2_SIGNATURE) return handle; + if (((NE_MODULE *)ptr)->ne_magic == IMAGE_OS2_SIGNATURE) return handle; /* Search for this handle inside all tasks */ @@ -1426,7 +1396,7 @@ owner = FarGetOwner16( handle ); if (!(ptr = GlobalLock16( owner ))) return 0; - if (((NE_MODULE *)ptr)->magic == IMAGE_OS2_SIGNATURE) return owner; + if (((NE_MODULE *)ptr)->ne_magic == IMAGE_OS2_SIGNATURE) return owner; /* Search for the owner inside all tasks */ @@ -1502,8 +1472,8 @@ lpte->hTaskParent = pTask->hParent; lpte->hInst = pTask->hInstance; lpte->hModule = pTask->hModule; - lpte->wSS = SELECTOROF( pTask->teb->cur_stack ); - lpte->wSP = OFFSETOF( pTask->teb->cur_stack ); + lpte->wSS = SELECTOROF( pTask->teb->WOW32Reserved ); + lpte->wSP = OFFSETOF( pTask->teb->WOW32Reserved ); lpte->wStackTop = pInstData->stacktop; lpte->wStackMinimum = pInstData->stackmin; lpte->wStackBottom = pInstData->stackbottom; diff -urN wine-20050419/dlls/kernel/tests/.cvsignore wine-20050524/dlls/kernel/tests/.cvsignore --- wine-20050419/dlls/kernel/tests/.cvsignore 2004-09-08 01:28:32.000000000 +0200 +++ wine-20050524/dlls/kernel/tests/.cvsignore 2005-04-24 19:37:52.000000000 +0200 @@ -19,6 +19,7 @@ pipe.ok process.ok profile.ok +sync.ok testlist.c thread.ok time.ok diff -urN wine-20050419/dlls/kernel/tests/Makefile.in wine-20050524/dlls/kernel/tests/Makefile.in --- wine-20050419/dlls/kernel/tests/Makefile.in 2004-09-08 01:28:32.000000000 +0200 +++ wine-20050524/dlls/kernel/tests/Makefile.in 2005-04-24 19:37:52.000000000 +0200 @@ -26,6 +26,7 @@ pipe.c \ process.c \ profile.c \ + sync.c \ thread.c \ time.c \ timer.c \ diff -urN wine-20050419/dlls/kernel/tests/file.c wine-20050524/dlls/kernel/tests/file.c --- wine-20050419/dlls/kernel/tests/file.c 2005-04-19 13:59:46.000000000 +0200 +++ wine-20050524/dlls/kernel/tests/file.c 2005-05-06 17:44:32.000000000 +0200 @@ -1277,7 +1277,7 @@ ok( hmap == NULL, "mapping should fail\n"); /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */ - /* On XP you can now map again, on Win 95 you can not. */ + /* On XP you can now map again, on Win 95 you cannot. */ ok( CloseHandle( handle ), "can't close file handle\n"); ok( DeleteFileA( filename ), "DeleteFile failed after map\n" ); diff -urN wine-20050419/dlls/kernel/tests/pipe.c wine-20050524/dlls/kernel/tests/pipe.c --- wine-20050419/dlls/kernel/tests/pipe.c 2005-03-24 20:05:02.000000000 +0100 +++ wine-20050524/dlls/kernel/tests/pipe.c 2005-05-18 17:33:20.000000000 +0200 @@ -20,7 +20,6 @@ #include #include -#include #include #include diff -urN wine-20050419/dlls/kernel/tests/sync.c wine-20050524/dlls/kernel/tests/sync.c --- wine-20050419/dlls/kernel/tests/sync.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/kernel/tests/sync.c 2005-04-24 19:37:52.000000000 +0200 @@ -0,0 +1,117 @@ +/* + * Synchronization tests + * + * Copyright 2005 Mike McCormack for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include "wine/test.h" + +static void test_signalandwait(void) +{ + DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL); + HMODULE kernel32; + DWORD r; + HANDLE event[2], semaphore[2], file; + + kernel32 = GetModuleHandle("kernel32"); + pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait"); + + if (!pSignalObjectAndWait) + return; + + /* events */ + event[0] = CreateEvent(NULL, 0, 0, NULL); + event[1] = CreateEvent(NULL, 1, 1, NULL); + + ok( event[0] && event[1], "failed to create event flags\n"); + + /* invalid parameters */ + r = pSignalObjectAndWait(NULL, NULL, 0, 0); + ok( r == WAIT_FAILED, "should fail\n"); + + r = pSignalObjectAndWait(event[0], NULL, 0, FALSE); + ok( r == WAIT_FAILED, "should fail\n"); + + r = pSignalObjectAndWait(NULL, event[0], 0, FALSE); + ok( r == WAIT_FAILED, "should fail\n"); + + + /* valid parameters */ + r = pSignalObjectAndWait(event[0], event[1], 0, FALSE); + ok( r == WAIT_OBJECT_0, "should succeed\n"); + + /* event[0] is now signalled */ + r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); + ok( r == WAIT_OBJECT_0, "should succeed\n"); + + /* event[0] is not signalled */ + r = WaitForSingleObject(event[0], 0); + ok( r == WAIT_TIMEOUT, "event was signalled\n"); + + r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); + ok( r == WAIT_OBJECT_0, "should succeed\n"); + + /* clear event[1] and check for a timeout */ + ok(ResetEvent(event[1]), "failed to clear event[1]\n"); + r = pSignalObjectAndWait(event[0], event[1], 0, FALSE); + ok( r == WAIT_TIMEOUT, "should timeout\n"); + + CloseHandle(event[0]); + CloseHandle(event[1]); + + + /* semaphores */ + semaphore[0] = CreateSemaphore( NULL, 0, 1, NULL ); + semaphore[1] = CreateSemaphore( NULL, 1, 1, NULL ); + ok( semaphore[0] && semaphore[1], "failed to create semaphore\n"); + + r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE); + ok( r == WAIT_OBJECT_0, "should succeed\n"); + + r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE); + ok( r == WAIT_FAILED, "should fail\n"); + + r = ReleaseSemaphore(semaphore[0],1,NULL); + ok( r == FALSE, "should fail\n"); + + r = ReleaseSemaphore(semaphore[1],1,NULL); + ok( r == TRUE, "should succeed\n"); + + CloseHandle(semaphore[0]); + CloseHandle(semaphore[1]); + + /* try a registry key */ + file = CreateFile("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); + r = pSignalObjectAndWait(file, file, 0, FALSE); + ok( r == WAIT_FAILED, "should fail\n"); + todo_wine { + ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n"); + } + CloseHandle(file); +} + +START_TEST(sync) +{ + test_signalandwait(); +} diff -urN wine-20050419/dlls/kernel/thread.c wine-20050524/dlls/kernel/thread.c --- wine-20050419/dlls/kernel/thread.c 2005-02-21 22:02:12.000000000 +0100 +++ wine-20050524/dlls/kernel/thread.c 2005-05-16 19:52:10.000000000 +0200 @@ -38,8 +38,8 @@ #include "winbase.h" #include "winerror.h" #include "winnls.h" -#include "module.h" #include "thread.h" +#include "module.h" #include "wine/winbase16.h" #include "wine/exception.h" #include "wine/library.h" diff -urN wine-20050419/dlls/kernel/thunk.c wine-20050524/dlls/kernel/thunk.c --- wine-20050419/dlls/kernel/thunk.c 2005-02-25 15:07:58.000000000 +0100 +++ wine-20050524/dlls/kernel/thunk.c 2005-05-16 21:44:54.000000000 +0200 @@ -21,6 +21,7 @@ */ #include "config.h" +#include "wine/port.h" #include #include @@ -33,6 +34,7 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" +#include "thread.h" #include "winreg.h" #include "winternl.h" #include "wownt32.h" @@ -40,9 +42,8 @@ #include "wine/debug.h" #include "wine/library.h" -#include "module.h" -#include "stackframe.h" #include "kernel_private.h" +#include "kernel16_private.h" WINE_DEFAULT_DEBUG_CHANNEL(thunk); @@ -185,30 +186,39 @@ * * NOTE: needs to preserve all registers! */ -void LogApiThkLSF( LPSTR func, CONTEXT86 *context ) +void WINAPI __regs_LogApiThkLSF( LPSTR func, CONTEXT86 *context ) { TRACE( "%s\n", debugstr_a(func) ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( LogApiThkLSF, 4, 4 ); +#endif /*********************************************************************** * LogApiThkSL (KERNEL32.44) * * NOTE: needs to preserve all registers! */ -void LogApiThkSL( LPSTR func, CONTEXT86 *context ) +void WINAPI __regs_LogApiThkSL( LPSTR func, CONTEXT86 *context ) { TRACE( "%s\n", debugstr_a(func) ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( LogApiThkSL, 4, 4 ); +#endif /*********************************************************************** * LogCBThkSL (KERNEL32.47) * * NOTE: needs to preserve all registers! */ -void LogCBThkSL( LPSTR func, CONTEXT86 *context ) +void WINAPI __regs_LogCBThkSL( LPSTR func, CONTEXT86 *context ) { TRACE( "%s\n", debugstr_a(func) ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( LogCBThkSL, 4, 4 ); +#endif /*********************************************************************** * Generates a FT_Prolog call. @@ -438,7 +448,7 @@ * FIXME: DDJ talks of certain register usage rules; I'm not sure * whether we cover this 100%. */ -void QT_Thunk( CONTEXT86 *context ) +void WINAPI __regs_QT_Thunk( CONTEXT86 *context ) { CONTEXT86 context16; DWORD argsize; @@ -451,8 +461,7 @@ context16.Eip = LOWORD(context->Edx); /* point EBP to the STACK16FRAME on the stack * for the call_to_16 to set up the register content on calling */ - context16.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) - + (WORD)&((STACK16FRAME*)0)->bp; + context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp; /* * used to be (problematic): @@ -474,8 +483,11 @@ * the number of parameters that the Win16 function * accepted (that it popped from the corresponding Win16 stack) */ context->Esp += LOWORD(context16.Esp) - - ( OFFSETOF( NtCurrentTeb()->cur_stack ) - argsize ); + ( OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( QT_Thunk, 0, 0 ); +#endif /********************************************************************** @@ -521,7 +533,7 @@ * ESP is EBP-64 after return. * */ -void FT_Prolog( CONTEXT86 *context ) +void WINAPI __regs_FT_Prolog( CONTEXT86 *context ) { /* Build stack frame */ stack32_push(context, context->Ebp); @@ -541,6 +553,9 @@ *(DWORD *)(context->Ebp - 48) = context->Eax; *(DWORD *)(context->Ebp - 52) = context->Edx; } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( FT_Prolog, 0, 0 ); +#endif /********************************************************************** * FT_Thunk (KERNEL32.@) @@ -562,7 +577,7 @@ * of arguments, so that the single DWORD bitmap is no longer * sufficient ... */ -void FT_Thunk( CONTEXT86 *context ) +void WINAPI __regs_FT_Thunk( CONTEXT86 *context ) { DWORD mapESPrelative = *(DWORD *)(context->Ebp - 20); DWORD callTarget = *(DWORD *)(context->Ebp - 52); @@ -578,8 +593,7 @@ context16.SegGs = wine_get_gs(); context16.SegCs = HIWORD(callTarget); context16.Eip = LOWORD(callTarget); - context16.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) - + (WORD)&((STACK16FRAME*)0)->bp; + context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp; argsize = context->Ebp-context->Esp-0x40; if (argsize > sizeof(newstack)) argsize = sizeof(newstack); @@ -591,8 +605,8 @@ if (mapESPrelative & (1 << i)) { SEGPTR *arg = (SEGPTR *)newstack[i]; - *arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->cur_stack), - OFFSETOF(NtCurrentTeb()->cur_stack) - argsize + *arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->WOW32Reserved), + OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize + (*(LPBYTE *)arg - oldstack)); } @@ -602,14 +616,31 @@ context->Ecx = context16.Ecx; context->Esp += LOWORD(context16.Esp) - - ( OFFSETOF( NtCurrentTeb()->cur_stack ) - argsize ); + ( OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize ); /* Copy modified buffers back to 32-bit stack */ memcpy( oldstack, newstack, argsize ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( FT_Thunk, 0, 0 ); +#endif -/********************************************************************** - * FT_ExitNN (KERNEL32.218 - 232) +/*********************************************************************** + * FT_Exit0 (KERNEL32.@) + * FT_Exit4 (KERNEL32.@) + * FT_Exit8 (KERNEL32.@) + * FT_Exit12 (KERNEL32.@) + * FT_Exit16 (KERNEL32.@) + * FT_Exit20 (KERNEL32.@) + * FT_Exit24 (KERNEL32.@) + * FT_Exit28 (KERNEL32.@) + * FT_Exit32 (KERNEL32.@) + * FT_Exit36 (KERNEL32.@) + * FT_Exit40 (KERNEL32.@) + * FT_Exit44 (KERNEL32.@) + * FT_Exit48 (KERNEL32.@) + * FT_Exit52 (KERNEL32.@) + * FT_Exit56 (KERNEL32.@) * * One of the FT_ExitNN functions is called at the end of the thunk code. * It removes the stack frame created by FT_Prolog, moves the function @@ -619,7 +650,7 @@ * and perform a return to the CALLER of the thunk code (while removing * the given number of arguments from the caller's stack). */ -static void FT_Exit(CONTEXT86 *context, int nPopArgs) +static inline void FT_Exit(CONTEXT86 *context) { /* Return value is in EBX */ context->Eax = context->Ebx; @@ -635,84 +666,36 @@ /* Pop return address to CALLER of thunk code */ context->Eip = stack32_pop(context); - /* Remove arguments */ - context->Esp += nPopArgs; } -/*********************************************************************** - * FT_Exit0 (KERNEL32.@) - */ -void FT_Exit0(CONTEXT86 *context) { FT_Exit(context, 0); } - -/*********************************************************************** - * FT_Exit4 (KERNEL32.@) - */ -void FT_Exit4(CONTEXT86 *context) { FT_Exit(context, 4); } - -/*********************************************************************** - * FT_Exit8 (KERNEL32.@) - */ -void FT_Exit8(CONTEXT86 *context) { FT_Exit(context, 8); } +#ifdef DEFINE_REGS_ENTRYPOINT -/*********************************************************************** - * FT_Exit12 (KERNEL32.@) - */ -void FT_Exit12(CONTEXT86 *context) { FT_Exit(context, 12); } +#define DEFINE_FT_Exit(n) \ +void WINAPI __regs_FT_Exit ## n(CONTEXT86 *context) \ +{ \ + FT_Exit(context); \ + context->Esp += n; \ +} \ +DEFINE_REGS_ENTRYPOINT( FT_Exit ## n, 0, 0 ) + +DEFINE_FT_Exit(0); +DEFINE_FT_Exit(4); +DEFINE_FT_Exit(8); +DEFINE_FT_Exit(12); +DEFINE_FT_Exit(16); +DEFINE_FT_Exit(20); +DEFINE_FT_Exit(24); +DEFINE_FT_Exit(28); +DEFINE_FT_Exit(32); +DEFINE_FT_Exit(36); +DEFINE_FT_Exit(40); +DEFINE_FT_Exit(44); +DEFINE_FT_Exit(48); +DEFINE_FT_Exit(52); +DEFINE_FT_Exit(56); -/*********************************************************************** - * FT_Exit16 (KERNEL32.@) - */ -void FT_Exit16(CONTEXT86 *context) { FT_Exit(context, 16); } +#endif /* DEFINE_REGS_ENTRYPOINT */ -/*********************************************************************** - * FT_Exit20 (KERNEL32.@) - */ -void FT_Exit20(CONTEXT86 *context) { FT_Exit(context, 20); } - -/*********************************************************************** - * FT_Exit24 (KERNEL32.@) - */ -void FT_Exit24(CONTEXT86 *context) { FT_Exit(context, 24); } - -/*********************************************************************** - * FT_Exit28 (KERNEL32.@) - */ -void FT_Exit28(CONTEXT86 *context) { FT_Exit(context, 28); } - -/*********************************************************************** - * FT_Exit32 (KERNEL32.@) - */ -void FT_Exit32(CONTEXT86 *context) { FT_Exit(context, 32); } - -/*********************************************************************** - * FT_Exit36 (KERNEL32.@) - */ -void FT_Exit36(CONTEXT86 *context) { FT_Exit(context, 36); } - -/*********************************************************************** - * FT_Exit40 (KERNEL32.@) - */ -void FT_Exit40(CONTEXT86 *context) { FT_Exit(context, 40); } - -/*********************************************************************** - * FT_Exit44 (KERNEL32.@) - */ -void FT_Exit44(CONTEXT86 *context) { FT_Exit(context, 44); } - -/*********************************************************************** - * FT_Exit48 (KERNEL32.@) - */ -void FT_Exit48(CONTEXT86 *context) { FT_Exit(context, 48); } - -/*********************************************************************** - * FT_Exit52 (KERNEL32.@) - */ -void FT_Exit52(CONTEXT86 *context) { FT_Exit(context, 52); } - -/*********************************************************************** - * FT_Exit56 (KERNEL32.@) - */ -void FT_Exit56(CONTEXT86 *context) { FT_Exit(context, 56); } /*********************************************************************** * ThunkInitLS (KERNEL32.43) @@ -780,7 +763,7 @@ * in the BL register by the called 16-bit routine. * */ -void Common32ThkLS( CONTEXT86 *context ) +void WINAPI __regs_Common32ThkLS( CONTEXT86 *context ) { CONTEXT86 context16; DWORD argsize; @@ -792,8 +775,7 @@ context16.Edi = LOWORD(context->Ecx); context16.SegCs = HIWORD(context->Eax); context16.Eip = LOWORD(context->Eax); - context16.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) - + (WORD)&((STACK16FRAME*)0)->bp; + context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp; argsize = HIWORD(context->Edx) * 4; @@ -811,6 +793,9 @@ /* Clean up caller's stack frame */ context->Esp += LOBYTE(context16.Ebx); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( Common32ThkLS, 0, 0 ); +#endif /*********************************************************************** * OT_32ThkLSF (KERNEL32.40) @@ -839,7 +824,7 @@ * (Note that this function seems only to be used for * OLECLI32 -> OLECLI and OLESVR32 -> OLESVR thunking.) */ -void OT_32ThkLSF( CONTEXT86 *context ) +void WINAPI __regs_OT_32ThkLSF( CONTEXT86 *context ) { CONTEXT86 context16; DWORD argsize; @@ -850,8 +835,7 @@ context16.SegGs = wine_get_gs(); context16.SegCs = HIWORD(context->Edx); context16.Eip = LOWORD(context->Edx); - context16.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) - + (WORD)&((STACK16FRAME*)0)->bp; + context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + (WORD)&((STACK16FRAME*)0)->bp; argsize = 2 * *(WORD *)context->Esp + 2; @@ -864,8 +848,11 @@ (LPBYTE)CURRENT_STACK16 - argsize, argsize ); context->Esp += LOWORD(context16.Esp) - - ( OFFSETOF( NtCurrentTeb()->cur_stack ) - argsize ); + ( OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize ); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( OT_32ThkLSF, 0, 0 ); +#endif /*********************************************************************** * ThunkInitLSF (KERNEL32.41) @@ -948,7 +935,7 @@ * Note: The two DWORD arguments get popped off the stack. * */ -void FT_PrologPrime( CONTEXT86 *context ) +void WINAPI __regs_FT_PrologPrime( CONTEXT86 *context ) { DWORD targetTableOffset; LPBYTE relayCode; @@ -965,6 +952,9 @@ /* Jump to the call stub just created */ context->Eip = (DWORD)relayCode; } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( FT_PrologPrime, 0, 0 ); +#endif /*********************************************************************** * QT_ThunkPrime (KERNEL32.90) @@ -977,7 +967,7 @@ * EAX start of relay code * */ -void QT_ThunkPrime( CONTEXT86 *context ) +void WINAPI __regs_QT_ThunkPrime( CONTEXT86 *context ) { DWORD targetTableOffset; LPBYTE relayCode; @@ -994,6 +984,9 @@ /* Jump to the call stub just created */ context->Eip = (DWORD)relayCode; } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( QT_ThunkPrime, 0, 0 ); +#endif /*********************************************************************** * ThunkInitSL (KERNEL32.46) @@ -1118,7 +1111,7 @@ /********************************************************************** * W32S_BackTo32 (KERNEL32.51) */ -void W32S_BackTo32( CONTEXT86 *context ) +void WINAPI __regs_W32S_BackTo32( CONTEXT86 *context ) { LPDWORD stack = (LPDWORD)context->Esp; FARPROC proc = (FARPROC)context->Eip; @@ -1128,6 +1121,9 @@ context->Eip = stack32_pop(context); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( W32S_BackTo32, 0, 0 ); +#endif /********************************************************************** * AllocSLCallback (KERNEL32.@) @@ -1241,7 +1237,7 @@ /*********************************************************************** * K32Thk1632Prolog (KERNEL32.@) */ -void K32Thk1632Prolog( CONTEXT86 *context ) +void WINAPI __regs_K32Thk1632Prolog( CONTEXT86 *context ) { LPBYTE code = (LPBYTE)context->Eip - 5; @@ -1274,35 +1270,38 @@ DWORD argSize = context->Ebp - context->Esp; char *stack16 = (char *)context->Esp - 4; - char *stack32 = (char *)NtCurrentTeb()->cur_stack - argSize; + char *stack32 = (char *)NtCurrentTeb()->WOW32Reserved - argSize; STACK16FRAME *frame16 = (STACK16FRAME *)stack16 - 1; - TRACE("before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n", - context->Ebp, context->Esp, NtCurrentTeb()->cur_stack); + TRACE("before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %p\n", + context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved); memset(frame16, '\0', sizeof(STACK16FRAME)); - frame16->frame32 = (STACK32FRAME *)NtCurrentTeb()->cur_stack; + frame16->frame32 = NtCurrentTeb()->WOW32Reserved; frame16->ebp = context->Ebp; memcpy(stack32, stack16, argSize); - NtCurrentTeb()->cur_stack = MAKESEGPTR(stackSel, (DWORD)frame16 - stackBase); + NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR(stackSel, (DWORD)frame16 - stackBase); context->Esp = (DWORD)stack32 + 4; context->Ebp = context->Esp + argSize; - TRACE("after SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n", - context->Ebp, context->Esp, NtCurrentTeb()->cur_stack); + TRACE("after SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %p\n", + context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved); } /* entry_point is never used again once the entry point has been called. Thus we re-use it to hold the Win16Lock count */ ReleaseThunkLock(&CURRENT_STACK16->entry_point); } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( K32Thk1632Prolog, 0, 0 ); +#endif /*********************************************************************** * K32Thk1632Epilog (KERNEL32.@) */ -void K32Thk1632Epilog( CONTEXT86 *context ) +void WINAPI __regs_K32Thk1632Epilog( CONTEXT86 *context ) { LPBYTE code = (LPBYTE)context->Eip - 13; @@ -1313,25 +1312,28 @@ if ( code[5] == 0xFF && code[6] == 0x55 && code[7] == 0xFC && code[13] == 0x66 && code[14] == 0xCB) { - STACK16FRAME *frame16 = MapSL(NtCurrentTeb()->cur_stack); + STACK16FRAME *frame16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); char *stack16 = (char *)(frame16 + 1); DWORD argSize = frame16->ebp - (DWORD)stack16; char *stack32 = (char *)frame16->frame32 - argSize; DWORD nArgsPopped = context->Esp - (DWORD)stack32; - TRACE("before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n", - context->Ebp, context->Esp, NtCurrentTeb()->cur_stack); + TRACE("before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %p\n", + context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved); - NtCurrentTeb()->cur_stack = (DWORD)frame16->frame32; + NtCurrentTeb()->WOW32Reserved = frame16->frame32; context->Esp = (DWORD)stack16 + nArgsPopped; context->Ebp = frame16->ebp; - TRACE("after SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n", - context->Ebp, context->Esp, NtCurrentTeb()->cur_stack); + TRACE("after SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %p\n", + context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved); } } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( K32Thk1632Epilog, 0, 0 ); +#endif /********************************************************************* * PK16FNF [KERNEL32.91] @@ -2101,7 +2103,7 @@ /********************************************************************** * CommonUnimpStub (KERNEL32.17) */ -void CommonUnimpStub( CONTEXT86 *context ) +void WINAPI __regs_CommonUnimpStub( CONTEXT86 *context ) { FIXME("generic stub: %s\n", ((LPSTR)context->Eax ? (LPSTR)context->Eax : "?")); @@ -2116,6 +2118,9 @@ context->Esp += (context->Ecx & 0x0f) * 4; } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( CommonUnimpStub, 0, 0 ); +#endif /********************************************************************** * HouseCleanLogicallyDeadHandles (KERNEL32.33) @@ -2205,7 +2210,7 @@ frame32 = pFrame->frame32; while (frame32 && frame32->frame16) { - if (OFFSETOF(frame32->frame16) < OFFSETOF(NtCurrentTeb()->cur_stack)) + if (OFFSETOF(frame32->frame16) < OFFSETOF(NtCurrentTeb()->WOW32Reserved)) break; /* Something strange is going on */ if (OFFSETOF(frame32->frame16) > lpbuf[2]) { diff -urN wine-20050419/dlls/kernel/time.c wine-20050524/dlls/kernel/time.c --- wine-20050419/dlls/kernel/time.c 2005-02-25 15:07:58.000000000 +0100 +++ wine-20050524/dlls/kernel/time.c 2005-05-18 20:20:23.000000000 +0200 @@ -33,6 +33,9 @@ #ifdef HAVE_SYS_TIMES_H # include #endif +#ifdef HAVE_MACHINE_LIMITS_H +#include +#endif #define NONAMELESSUNION #define NONAMELESSSTRUCT diff -urN wine-20050419/dlls/kernel/toolhelp.c wine-20050524/dlls/kernel/toolhelp.c --- wine-20050419/dlls/kernel/toolhelp.c 2005-03-24 22:01:38.000000000 +0100 +++ wine-20050524/dlls/kernel/toolhelp.c 2005-05-24 12:12:06.000000000 +0200 @@ -30,181 +30,16 @@ #include #include "windef.h" #include "winbase.h" -#include "wine/winbase16.h" #include "winerror.h" -#include "local.h" #include "tlhelp32.h" #include "toolhelp.h" #include "wine/server.h" +#include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(toolhelp); -/* FIXME: to make this work, we have to call back all these registered - * functions from all over the WINE code. Someone with more knowledge than - * me please do that. -Marcus - */ -static struct notify -{ - HTASK16 htask; - FARPROC16 lpfnCallback; - WORD wFlags; -} *notifys = NULL; - -static int nrofnotifys = 0; - -static FARPROC16 HookNotify = NULL; - -/*********************************************************************** - * NotifyRegister (TOOLHELP.73) - */ -BOOL16 WINAPI NotifyRegister16( HTASK16 htask, FARPROC16 lpfnCallback, - WORD wFlags ) -{ - int i; - - FIXME("(%x,%lx,%x), semi-stub.\n", - htask, (DWORD)lpfnCallback, wFlags ); - if (!htask) htask = GetCurrentTask(); - for (i=0;idwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount(); - return TRUE; -} - -/*********************************************************************** - * SystemHeapInfo (TOOLHELP.71) - */ -BOOL16 WINAPI SystemHeapInfo16( SYSHEAPINFO *pHeapInfo ) -{ - WORD user = LoadLibrary16( "USER.EXE" ); - WORD gdi = LoadLibrary16( "GDI.EXE" ); - pHeapInfo->wUserFreePercent = (int)LOCAL_CountFree(user) * 100 / LOCAL_HeapSize(user); - pHeapInfo->wGDIFreePercent = (int)LOCAL_CountFree(gdi) * 100 / LOCAL_HeapSize(gdi); - pHeapInfo->hUserSegment = user; - pHeapInfo->hGDISegment = gdi; - FreeLibrary16( user ); - FreeLibrary16( gdi ); - return TRUE; -} - - -/*********************************************************************** - * ToolHelpHook (KERNEL.341) - * see "Undocumented Windows" - */ -FARPROC16 WINAPI ToolHelpHook16(FARPROC16 lpfnNotifyHandler) -{ - FARPROC16 tmp; - - FIXME("(%p), stub.\n", lpfnNotifyHandler); - tmp = HookNotify; - HookNotify = lpfnNotifyHandler; - /* just return previously installed notification function */ - return tmp; -} - - /*********************************************************************** * CreateToolhelp32Snapshot (KERNEL32.@) */ @@ -401,20 +236,20 @@ /*********************************************************************** - * TOOLHELP_Module32Next + * TOOLHELP_Module32NextW * * Implementation of Module32First/Next */ -static BOOL TOOLHELP_Module32Next( HANDLE handle, LPMODULEENTRY32 lpme, BOOL first ) +static BOOL TOOLHELP_Module32NextW( HANDLE handle, LPMODULEENTRY32W lpme, BOOL first ) { BOOL ret; WCHAR exe[MAX_PATH]; DWORD len; - if (lpme->dwSize < sizeof (MODULEENTRY32)) + if (lpme->dwSize < sizeof (MODULEENTRY32W)) { SetLastError( ERROR_INSUFFICIENT_BUFFER ); - ERR("Result buffer too small (req: %d, was: %ld)\n", sizeof(MODULEENTRY32), lpme->dwSize); + ERR("Result buffer too small (req: %d, was: %ld)\n", sizeof(MODULEENTRY32W), lpme->dwSize); return FALSE; } SERVER_START_REQ( next_module ) @@ -424,7 +259,7 @@ wine_server_set_reply( req, exe, sizeof(exe) ); if ((ret = !wine_server_call_err( req ))) { - const char* ptr; + const WCHAR* ptr; lpme->th32ModuleID = 1; /* toolhelp internal id, never used */ lpme->th32ProcessID = reply->pid; lpme->GlblcntUsage = 0xFFFF; /* FIXME */ @@ -432,12 +267,12 @@ lpme->modBaseAddr = reply->base; lpme->modBaseSize = reply->size; lpme->hModule = reply->base; - len = WideCharToMultiByte( CP_ACP, 0, exe, wine_server_reply_size(reply) / sizeof(WCHAR), - lpme->szExePath, sizeof(lpme->szExePath) - 1, NULL, NULL ); + len = wine_server_reply_size(reply) / sizeof(WCHAR); + memcpy(lpme->szExePath, exe, wine_server_reply_size(reply)); lpme->szExePath[len] = 0; - if ((ptr = strrchr(lpme->szExePath, '\\'))) ptr++; + if ((ptr = strrchrW(lpme->szExePath, '\\'))) ptr++; else ptr = lpme->szExePath; - lstrcpynA( lpme->szModule, ptr, sizeof(lpme->szModule) ); + lstrcpynW( lpme->szModule, ptr, sizeof(lpme->szModule)/sizeof(lpme->szModule[0])); } } SERVER_END_REQ; @@ -445,13 +280,65 @@ } /*********************************************************************** + * TOOLHELP_Module32NextA + * + * Implementation of Module32First/Next + */ +static BOOL TOOLHELP_Module32NextA( HANDLE handle, LPMODULEENTRY32 lpme, BOOL first ) +{ + BOOL ret; + MODULEENTRY32W mew; + + if (lpme->dwSize < sizeof (MODULEENTRY32)) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + ERR("Result buffer too small (req: %d, was: %ld)\n", sizeof(MODULEENTRY32), lpme->dwSize); + return FALSE; + } + + mew.dwSize = sizeof(mew); + if ((ret = TOOLHELP_Module32NextW( handle, &mew, first ))) + { + lpme->th32ModuleID = mew.th32ModuleID; + lpme->th32ProcessID = mew.th32ProcessID; + lpme->GlblcntUsage = mew.GlblcntUsage; + lpme->ProccntUsage = mew.ProccntUsage; + lpme->modBaseAddr = mew.modBaseAddr; + lpme->hModule = mew.hModule; + WideCharToMultiByte( CP_ACP, 0, mew.szModule, -1, lpme->szModule, sizeof(lpme->szModule), NULL, NULL ); + WideCharToMultiByte( CP_ACP, 0, mew.szExePath, -1, lpme->szExePath, sizeof(lpme->szExePath), NULL, NULL ); + } + return ret; +} + +/*********************************************************************** + * Module32FirstW (KERNEL32.@) + * + * Return info about the "first" module in a toolhelp32 snapshot + */ +BOOL WINAPI Module32FirstW(HANDLE hSnapshot, LPMODULEENTRY32W lpme) +{ + return TOOLHELP_Module32NextW( hSnapshot, lpme, TRUE ); +} + +/*********************************************************************** * Module32First (KERNEL32.@) * * Return info about the "first" module in a toolhelp32 snapshot */ BOOL WINAPI Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme) { - return TOOLHELP_Module32Next( hSnapshot, lpme, TRUE ); + return TOOLHELP_Module32NextA( hSnapshot, lpme, TRUE ); +} + +/*********************************************************************** + * Module32NextW (KERNEL32.@) + * + * Return info about the "next" module in a toolhelp32 snapshot + */ +BOOL WINAPI Module32NextW(HANDLE hSnapshot, LPMODULEENTRY32W lpme) +{ + return TOOLHELP_Module32NextW( hSnapshot, lpme, FALSE ); } /*********************************************************************** @@ -461,7 +348,7 @@ */ BOOL WINAPI Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme) { - return TOOLHELP_Module32Next( hSnapshot, lpme, FALSE ); + return TOOLHELP_Module32NextA( hSnapshot, lpme, FALSE ); } /************************************************************************ diff -urN wine-20050419/dlls/kernel/toolhelp16.c wine-20050524/dlls/kernel/toolhelp16.c --- wine-20050419/dlls/kernel/toolhelp16.c 1970-01-01 01:00:00.000000000 +0100 +++ wine-20050524/dlls/kernel/toolhelp16.c 2005-05-24 12:12:06.000000000 +0200 @@ -0,0 +1,208 @@ +/* + * Misc Toolhelp functions + * + * Copyright 1996 Marcus Meissner + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include "windef.h" +#include "winbase.h" +#include "wine/winbase16.h" +#include "winerror.h" +#include "toolhelp.h" +#include "wine/server.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(toolhelp); + +/* FIXME: to make this work, we have to call back all these registered + * functions from all over the WINE code. Someone with more knowledge than + * me please do that. -Marcus + */ + +static struct notify +{ + HTASK16 htask; + FARPROC16 lpfnCallback; + WORD wFlags; +} *notifys = NULL; + +static int nrofnotifys = 0; + +static FARPROC16 HookNotify = NULL; + +/*********************************************************************** + * NotifyRegister (TOOLHELP.73) + */ +BOOL16 WINAPI NotifyRegister16( HTASK16 htask, FARPROC16 lpfnCallback, + WORD wFlags ) +{ + int i; + + FIXME("(%x,%lx,%x), semi-stub.\n", + htask, (DWORD)lpfnCallback, wFlags ); + if (!htask) htask = GetCurrentTask(); + for (i=0;idwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount(); + return TRUE; +} + +/*********************************************************************** + * SystemHeapInfo (TOOLHELP.71) + */ +BOOL16 WINAPI SystemHeapInfo16( SYSHEAPINFO *pHeapInfo ) +{ + STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); + HANDLE16 oldDS = stack16->ds; + WORD user = LoadLibrary16( "USER.EXE" ); + WORD gdi = LoadLibrary16( "GDI.EXE" ); + stack16->ds = user; + pHeapInfo->wUserFreePercent = (int)LocalCountFree16() * 100 / LocalHeapSize16(); + stack16->ds = gdi; + pHeapInfo->wGDIFreePercent = (int)LocalCountFree16() * 100 / LocalHeapSize16(); + stack16->ds = oldDS; + pHeapInfo->hUserSegment = user; + pHeapInfo->hGDISegment = gdi; + FreeLibrary16( user ); + FreeLibrary16( gdi ); + return TRUE; +} + + +/*********************************************************************** + * ToolHelpHook (KERNEL.341) + * see "Undocumented Windows" + */ +FARPROC16 WINAPI ToolHelpHook16(FARPROC16 lpfnNotifyHandler) +{ + FARPROC16 tmp; + + FIXME("(%p), stub.\n", lpfnNotifyHandler); + tmp = HookNotify; + HookNotify = lpfnNotifyHandler; + /* just return previously installed notification function */ + return tmp; +} diff -urN wine-20050419/dlls/kernel/version.rc wine-20050524/dlls/kernel/version.rc --- wine-20050419/dlls/kernel/version.rc 2004-03-30 01:05:20.000000000 +0200 +++ wine-20050524/dlls/kernel/version.rc 2005-05-04 11:47:13.000000000 +0200 @@ -18,10 +18,10 @@ #define WINE_FILENAME_STR "kernel32.dll" -/* these values come from Windows 2000 SP4 */ -#define WINE_FILEVERSION 5,0,2195,6688 -#define WINE_FILEVERSION_STR "5.00.2195.6688" -#define WINE_PRODUCTVERSION 5,0,2195,6688 -#define WINE_PRODUCTVERSION_STR "5.00.2195.6688" +/* these values come from Windows XP SP2 */ +#define WINE_FILEVERSION 5,1,2600,2180 +#define WINE_FILEVERSION_STR "5.01.2600.2180" +#define WINE_PRODUCTVERSION 5,1,2600,2180 +#define WINE_PRODUCTVERSION_STR "5.01.2600.2180" #include "wine/wine_common_ver.rc" diff -urN wine-20050419/dlls/kernel/volume.c wine-20050524/dlls/kernel/volume.c --- wine-20050419/dlls/kernel/volume.c 2005-02-26 18:46:34.000000000 +0100 +++ wine-20050524/dlls/kernel/volume.c 2005-05-06 17:44:32.000000000 +0200 @@ -215,237 +215,6 @@ } -/* create symlinks for the DOS drives; helper for VOLUME_CreateDevices */ -static int create_drives( int devices_only ) -{ - static const WCHAR PathW[] = {'P','a','t','h',0}; - static const WCHAR DeviceW[] = {'D','e','v','i','c','e',0}; - WCHAR driveW[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\', - 'W','i','n','e','\\','W','i','n','e','\\', - 'C','o','n','f','i','g','\\','D','r','i','v','e',' ','A',0}; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; - char tmp[1024*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; - char dest[1024]; - WCHAR *p, name[3]; - HKEY hkey; - DWORD dummy; - int i, count = 0; - - attr.Length = sizeof(attr); - attr.RootDirectory = 0; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - - /* create symlinks for the drive roots */ - - if (!devices_only) for (i = 0; i < 26; i++) - { - RtlInitUnicodeString( &nameW, driveW ); - nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; - if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; - - RtlInitUnicodeString( &nameW, PathW ); - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) - { - WCHAR path[1024]; - WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - ExpandEnvironmentStringsW( data, path, sizeof(path)/sizeof(WCHAR) ); - - p = path + strlenW(path) - 1; - while ((p > path) && (*p == '/')) *p-- = '\0'; - - name[0] = 'a' + i; - name[1] = ':'; - name[2] = 0; - - if (path[0] != '/') - { - /* relative paths are relative to config dir */ - memmove( path + 3, path, (strlenW(path) + 1) * sizeof(WCHAR) ); - path[0] = '.'; - path[1] = '.'; - path[2] = '/'; - } - if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, name, path )) - { - WideCharToMultiByte(CP_UNIXCP, 0, path, -1, dest, sizeof(dest), NULL, NULL); - MESSAGE( "Created symlink %s/dosdevices/%c: -> %s\n", - wine_get_config_dir(), 'a' + i, dest ); - count++; - } - } - NtClose( hkey ); - } - - /* create symlinks for the drive devices */ - - for (i = 0; i < 26; i++) - { - RtlInitUnicodeString( &nameW, driveW ); - nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; - if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; - - RtlInitUnicodeString( &nameW, DeviceW ); - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) - { - char *path, *p; - WCHAR devname[] = {'A',':',':',0 }; - WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - WideCharToMultiByte(CP_UNIXCP, 0, data, -1, dest, sizeof(dest), NULL, NULL); - path = get_dos_device_path( devname ); - p = path + strlen(path); - p[-3] = 'a' + i; - if (!symlink( dest, path )) - { - MESSAGE( "Created symlink %s/dosdevices/%c:: -> %s\n", - wine_get_config_dir(), 'a' + i, dest ); - count++; - } - HeapFree( GetProcessHeap(), 0, path ); - } - NtClose( hkey ); - } - - return count; -} - - -/*********************************************************************** - * VOLUME_CreateDevices - * - * Create the device files for the new device naming scheme. - * Should go away after a transition period. - */ -void VOLUME_CreateDevices(void) -{ - const char *config_dir = wine_get_config_dir(); - char *buffer; - int i, count = 0; - - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, - strlen(config_dir) + sizeof("/dosdevices/a::") ))) - return; - - strcpy( buffer, config_dir ); - strcat( buffer, "/dosdevices" ); - - if (!mkdir( buffer, 0777 )) /* we created it, so now create the devices */ - { - HKEY hkey; - DWORD dummy; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; - WCHAR *p, *devnameW; - char tmp[128]; - WCHAR com[5] = {'C','O','M','1',0}; - WCHAR lpt[5] = {'L','P','T','1',0}; - - static const WCHAR serialportsW[] = {'M','a','c','h','i','n','e','\\', - 'S','o','f','t','w','a','r','e','\\', - 'W','i','n','e','\\','W','i','n','e','\\', - 'C','o','n','f','i','g','\\', - 'S','e','r','i','a','l','P','o','r','t','s',0}; - static const WCHAR parallelportsW[] = {'M','a','c','h','i','n','e','\\', - 'S','o','f','t','w','a','r','e','\\', - 'W','i','n','e','\\','W','i','n','e','\\', - 'C','o','n','f','i','g','\\', - 'P','a','r','a','l','l','e','l','P','o','r','t','s',0}; - - attr.Length = sizeof(attr); - attr.RootDirectory = 0; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - RtlInitUnicodeString( &nameW, serialportsW ); - - if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) - { - RtlInitUnicodeString( &nameW, com ); - for (i = 1; i <= 9; i++) - { - com[3] = '0' + i; - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, - tmp, sizeof(tmp), &dummy )) - { - devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - if ((p = strchrW( devnameW, ',' ))) *p = 0; - if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, com, devnameW )) - { - char devname[32]; - WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, - devname, sizeof(devname), NULL, NULL); - MESSAGE( "Created symlink %s/dosdevices/com%d -> %s\n", config_dir, i, devname ); - count++; - } - } - } - NtClose( hkey ); - } - - RtlInitUnicodeString( &nameW, parallelportsW ); - if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) - { - RtlInitUnicodeString( &nameW, lpt ); - for (i = 1; i <= 9; i++) - { - lpt[3] = '0' + i; - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, - tmp, sizeof(tmp), &dummy )) - { - devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - if ((p = strchrW( devnameW, ',' ))) *p = 0; - if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, lpt, devnameW )) - { - char devname[32]; - WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, - devname, sizeof(devname), NULL, NULL); - MESSAGE( "Created symlink %s/dosdevices/lpt%d -> %s\n", config_dir, i, devname ); - count++; - } - } - } - NtClose( hkey ); - } - count += create_drives( FALSE ); - } - else - { - struct stat st; - int i; - - /* it is possible that the serial/parallel devices have been created but */ - /* not the drives; check for at least one drive symlink to catch that case */ - strcat( buffer, "/a:" ); - for (i = 0; i < 26; i++) - { - buffer[strlen(buffer)-2] = 'a' + i; - if (!lstat( buffer, &st )) break; - } - if (i == 26) count += create_drives( FALSE ); - else - { - strcat( buffer, ":" ); - for (i = 0; i < 26; i++) - { - buffer[strlen(buffer)-3] = 'a' + i; - if (!lstat( buffer, &st )) break; - } - if (i == 26) count += create_drives( TRUE ); - } - } - - if (count) - MESSAGE( "\nYou can now remove the [SerialPorts], [ParallelPorts], and [Drive] sections\n" - "in your configuration file, they are replaced by the above symlinks.\n\n" ); - - HeapFree( GetProcessHeap(), 0, buffer ); -} - - /****************************************************************** * VOLUME_FindCdRomDataBestVoldesc */ @@ -1423,7 +1192,7 @@ * DRIVE_UNKNOWN unable to find out anything about the drive * DRIVE_NO_ROOT_DIR nonexistent root dir * DRIVE_REMOVABLE the disk can be removed from the machine - * DRIVE_FIXED the disk can not be removed from the machine + * DRIVE_FIXED the disk cannot be removed from the machine * DRIVE_REMOTE network disk * DRIVE_CDROM CDROM drive * DRIVE_RAMDISK virtual disk in RAM diff -urN wine-20050419/dlls/kernel/vxd.c wine-20050524/dlls/kernel/vxd.c --- wine-20050419/dlls/kernel/vxd.c 2004-08-18 02:04:58.000000000 +0200 +++ wine-20050524/dlls/kernel/vxd.c 2005-05-07 20:25:51.000000000 +0200 @@ -28,7 +28,9 @@ # include #endif #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #include #include @@ -276,7 +278,7 @@ * VxDCall7 (KERNEL32.8) * VxDCall8 (KERNEL32.9) */ -void VxDCall( DWORD service, CONTEXT86 *context ) +void WINAPI __regs_VxDCall( DWORD service, CONTEXT86 *context ) { int i; VxDCallProc proc = NULL; @@ -302,6 +304,9 @@ context->Eax = 0xffffffff; /* FIXME */ } } +#ifdef DEFINE_REGS_ENTRYPOINT +DEFINE_REGS_ENTRYPOINT( VxDCall, 4, 4 ); +#endif /*********************************************************************** diff -urN wine-20050419/dlls/kernel/windebug.spec wine-20050524/dlls/kernel/windebug.spec --- wine-20050419/dlls/kernel/windebug.spec 2002-06-21 21:15:47.000000000 +0200 +++ wine-20050524/dlls/kernel/windebug.spec 2005-05-23 12:12:26.000000000 +0200 @@ -1,3 +1,3 @@ 1 stub WINDEBUG - 2 stub WEP +# 2 stub WEP 3 pascal -register WinNotify() WinNotify16 diff -urN wine-20050419/dlls/kernel/wowthunk.c wine-20050524/dlls/kernel/wowthunk.c --- wine-20050419/dlls/kernel/wowthunk.c 2004-09-28 21:18:06.000000000 +0200 +++ wine-20050524/dlls/kernel/wowthunk.c 2005-05-16 21:44:54.000000000 +0200 @@ -30,12 +30,11 @@ #include "winerror.h" #include "wownt32.h" #include "excpt.h" +#include "thread.h" #include "winreg.h" #include "winternl.h" -#include "miscemu.h" -#include "module.h" -#include "stackframe.h" #include "kernel_private.h" +#include "kernel16_private.h" #include "wine/exception.h" #include "wine/debug.h" @@ -266,7 +265,7 @@ { /* unwinding: restore the stack pointer in the TEB, and leave the Win16 mutex */ STACK32FRAME *frame32 = (STACK32FRAME *)((char *)frame - offsetof(STACK32FRAME,frame)); - NtCurrentTeb()->cur_stack = frame32->frame16; + NtCurrentTeb()->WOW32Reserved = (void *)frame32->frame16; _LeaveWin16Lock(); } else if (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION || @@ -620,7 +619,7 @@ context->SegCs, LOWORD(context->Eip), context->SegDs ); while (count) DPRINTF( ",%04x", wstack[--count] ); DPRINTF(") ss:sp=%04x:%04x", - SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) ); + SELECTOROF(NtCurrentTeb()->WOW32Reserved), OFFSETOF(NtCurrentTeb()->WOW32Reserved) ); DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x bp=%04x es=%04x fs=%04x\n", (WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx, (WORD)context->Edx, (WORD)context->Esi, (WORD)context->Edi, @@ -675,8 +674,8 @@ if (TRACE_ON(relay)) { DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x ", - GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack), - OFFSETOF(NtCurrentTeb()->cur_stack)); + GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->WOW32Reserved), + OFFSETOF(NtCurrentTeb()->WOW32Reserved)); DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x bp=%04x sp=%04x\n", (WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx, (WORD)context->Edx, (WORD)context->Ebp, (WORD)context->Esp ); @@ -694,10 +693,10 @@ DPRINTF("%04lx:CallTo16(func=%04x:%04x,ds=%04x", GetCurrentThreadId(), HIWORD(vpfn16), LOWORD(vpfn16), - SELECTOROF(NtCurrentTeb()->cur_stack) ); + SELECTOROF(NtCurrentTeb()->WOW32Reserved) ); while (count) DPRINTF( ",%04x", wstack[--count] ); DPRINTF(") ss:sp=%04x:%04x\n", - SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) ); + SELECTOROF(NtCurrentTeb()->WOW32Reserved), OFFSETOF(NtCurrentTeb()->WOW32Reserved) ); SYSLEVEL_CheckNotLevel( 2 ); } @@ -720,8 +719,8 @@ if (TRACE_ON(relay)) { DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x retval=%08lx\n", - GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack), - OFFSETOF(NtCurrentTeb()->cur_stack), ret); + GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->WOW32Reserved), + OFFSETOF(NtCurrentTeb()->WOW32Reserved), ret); SYSLEVEL_CheckNotLevel( 2 ); } } @@ -776,7 +775,7 @@ return 0; } - /* if the file can not be found, call LoadLibraryExA anyway, since it might be + /* if the file cannot be found, call LoadLibraryExA anyway, since it might be a builtin module. This case is handled in MODULE_LoadLibraryExA */ if ((p = strrchr( lpszLibFile, '.' )) && !strchr( p, '\\' )) /* got an extension */ diff -urN wine-20050419/dlls/lzexpand/.cvsignore wine-20050524/dlls/lzexpand/.cvsignore --- wine-20050419/dlls/lzexpand/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/lzexpand/.cvsignore 2005-05-07 14:39:56.000000000 +0200 @@ -1,4 +1,4 @@ Makefile +liblz32.def lz32.dll.dbg.c -lz32.spec.def lzexpand.spec.c diff -urN wine-20050419/dlls/lzexpand/Makefile.in wine-20050524/dlls/lzexpand/Makefile.in --- wine-20050419/dlls/lzexpand/Makefile.in 2004-11-21 17:05:14.000000000 +0100 +++ wine-20050524/dlls/lzexpand/Makefile.in 2005-05-09 16:42:34.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = lz32.dll +IMPORTLIB = liblz32.$(IMPLIBEXT) IMPORTS = kernel32 EXTRALIBS = $(LIBUNICODE) diff -urN wine-20050419/dlls/make_dlls wine-20050524/dlls/make_dlls --- wine-20050419/dlls/make_dlls 2004-08-24 04:29:48.000000000 +0200 +++ wine-20050524/dlls/make_dlls 2005-05-13 15:57:55.000000000 +0200 @@ -25,7 +25,9 @@ my $makefiles = `find . -name Makefile.in -print`; my %directories = (); -my %implib_dirs = (); +my %importlibs = (); +my %static_implibs = (); +my %staticlib_dirs = (); my %altnames = (); # list of special dlls that can be switched on or off by configure @@ -63,7 +65,7 @@ $module = $1; if ($module =~ /^lib.*\.a$/) { - ($implib_dirs{$module} = $i) =~ s/^\.\/(.*)\/[^\/]+$/$1/; + ($staticlib_dirs{$module} = $i) =~ s/^\.\/(.*)\/[^\/]+$/$1/; } else { @@ -71,6 +73,16 @@ } next; } + if (/^IMPORTLIB\s*=\s*([a-zA-Z0-9_.]+)\.\$\(IMPLIBEXT\)/) + { + $importlibs{$module} = $1; + next; + } + if (/^IMPLIB_SRCS\s*=/) + { + $static_implibs{$module} = 1; + next; + } if (/^SPEC_SRCS16\s*=\s*(.*)/) { my $specs = $1; @@ -128,7 +140,7 @@ } printf NEWMAKE "\n\nSUBDIRS = \\\n\t\$(BASEDIRS)"; -foreach my $dir (sort (keys %special_dlls, values %implib_dirs)) +foreach my $dir (sort (keys %special_dlls, values %staticlib_dirs)) { printf NEWMAKE " \\\n\t%s", $dir; } @@ -155,7 +167,7 @@ $targets16{sprintf("%s.so",$i)} = 1; } } -foreach my $mod (sort keys %implib_dirs) { $targets{$mod} = 1; } +foreach my $mod (sort keys %staticlib_dirs) { $targets{$mod} = 1; } print NEWMAKE < #include #include #include -#include +#ifdef HAVE_SYS_STAT_H +# include +#endif #include #include "mpg123.h" diff -urN wine-20050419/dlls/mscms/.cvsignore wine-20050524/dlls/mscms/.cvsignore --- wine-20050419/dlls/mscms/.cvsignore 2004-11-19 19:06:41.000000000 +0100 +++ wine-20050524/dlls/mscms/.cvsignore 2005-05-07 14:39:55.000000000 +0200 @@ -1,4 +1,4 @@ Makefile +libmscms.def mscms.dll.dbg.c -mscms.spec.def version.res diff -urN wine-20050419/dlls/mscms/Makefile.in wine-20050524/dlls/mscms/Makefile.in --- wine-20050419/dlls/mscms/Makefile.in 2005-02-21 19:38:15.000000000 +0100 +++ wine-20050524/dlls/mscms/Makefile.in 2005-05-09 16:42:33.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = mscms.dll +IMPORTLIB = libmscms.$(IMPLIBEXT) IMPORTS = kernel32 ntdll C_SRCS = \ diff -urN wine-20050419/dlls/msdmo/.cvsignore wine-20050524/dlls/msdmo/.cvsignore --- wine-20050419/dlls/msdmo/.cvsignore 2004-03-24 04:36:48.000000000 +0100 +++ wine-20050524/dlls/msdmo/.cvsignore 2005-05-07 14:39:55.000000000 +0200 @@ -1,4 +1,4 @@ Makefile +libmsdmo.def msdmo.dll.dbg.c -msdmo.spec.def rsrc.res diff -urN wine-20050419/dlls/msdmo/Makefile.in wine-20050524/dlls/msdmo/Makefile.in --- wine-20050419/dlls/msdmo/Makefile.in 2004-01-27 01:11:17.000000000 +0100 +++ wine-20050524/dlls/msdmo/Makefile.in 2005-05-09 16:42:33.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = msdmo.dll +IMPORTLIB = libmsdmo.$(IMPLIBEXT) IMPORTS = ole32 user32 advapi32 kernel32 EXTRALIBS = -luuid diff -urN wine-20050419/dlls/mshtml/.cvsignore wine-20050524/dlls/mshtml/.cvsignore --- wine-20050419/dlls/mshtml/.cvsignore 2004-03-24 04:36:47.000000000 +0100 +++ wine-20050524/dlls/mshtml/.cvsignore 2005-05-07 14:39:55.000000000 +0200 @@ -1,3 +1,3 @@ Makefile +libmshtml.def mshtml.dll.dbg.c -mshtml.spec.def diff -urN wine-20050419/dlls/mshtml/Makefile.in wine-20050524/dlls/mshtml/Makefile.in --- wine-20050419/dlls/mshtml/Makefile.in 2005-04-14 13:30:50.000000000 +0200 +++ wine-20050524/dlls/mshtml/Makefile.in 2005-05-09 16:42:33.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = mshtml.dll +IMPORTLIB = libmshtml.$(IMPLIBEXT) IMPORTS = user32 gdi32 advapi32 kernel32 ntdll EXTRALIBS = $(LIBUNICODE) -lstrmiids -luuid EXTRADEFS = -DCOM_NO_WINDOWS_H diff -urN wine-20050419/dlls/mshtml/main.c wine-20050524/dlls/mshtml/main.c --- wine-20050419/dlls/mshtml/main.c 2005-04-14 13:30:50.000000000 +0200 +++ wine-20050524/dlls/mshtml/main.c 2005-04-20 17:18:43.000000000 +0200 @@ -249,7 +249,11 @@ return hres; } -/* appears to have the same prototype as WinMain */ +/*********************************************************************** + * RunHTMLApplication (MSHTML.@) + * + * Appears to have the same prototype as WinMain. + */ INT WINAPI RunHTMLApplication( HINSTANCE hinst, HINSTANCE hPrevInst, LPCSTR szCmdLine, INT nCmdShow ) { diff -urN wine-20050419/dlls/mshtml/oleobj.c wine-20050524/dlls/mshtml/oleobj.c --- wine-20050419/dlls/mshtml/oleobj.c 2005-04-15 18:12:45.000000000 +0200 +++ wine-20050524/dlls/mshtml/oleobj.c 2005-05-24 13:44:26.000000000 +0200 @@ -143,7 +143,7 @@ TRACE("(%p)->(%ld %p %p %ld %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect); - if(iVerb != OLEIVERB_SHOW) { + if(iVerb != OLEIVERB_SHOW && iVerb != OLEIVERB_UIACTIVATE) { FIXME("iVerb = %ld not supported\n", iVerb); return E_NOTIMPL; } diff -urN wine-20050419/dlls/msi/.cvsignore wine-20050524/dlls/msi/.cvsignore --- wine-20050419/dlls/msi/.cvsignore 2005-02-08 13:12:29.000000000 +0100 +++ wine-20050524/dlls/msi/.cvsignore 2005-05-07 14:39:55.000000000 +0200 @@ -1,8 +1,8 @@ Makefile cond.tab.c cond.tab.h +libmsi.def msi.dll.dbg.c msi.res -msi.spec.def sql.tab.c sql.tab.h diff -urN wine-20050419/dlls/msi/Makefile.in wine-20050524/dlls/msi/Makefile.in --- wine-20050419/dlls/msi/Makefile.in 2005-03-29 13:28:57.000000000 +0200 +++ wine-20050524/dlls/msi/Makefile.in 2005-05-09 16:42:33.000000000 +0200 @@ -3,6 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = msi.dll +IMPORTLIB = libmsi.$(IMPLIBEXT) IMPORTS = shell32 cabinet oleaut32 ole32 version user32 gdi32 advapi32 kernel32 EXTRALIBS = -luuid $(LIBUNICODE) diff -urN wine-20050419/dlls/msi/action.c wine-20050524/dlls/msi/action.c --- wine-20050419/dlls/msi/action.c 2005-04-11 18:10:33.000000000 +0200 +++ wine-20050524/dlls/msi/action.c 2005-05-23 18:24:20.000000000 +0200 @@ -99,6 +99,7 @@ static UINT ACTION_ResolveSource(MSIPACKAGE *package); static UINT ACTION_ExecuteAction(MSIPACKAGE *package); static UINT ACTION_RegisterFonts(MSIPACKAGE *package); +static UINT ACTION_PublishComponents(MSIPACKAGE *package); /* @@ -324,7 +325,7 @@ { szInstallServices, NULL}, { szPatchFiles, NULL}, { szProcessComponents, ACTION_ProcessComponents }, - { szPublishComponents, NULL}, + { szPublishComponents, ACTION_PublishComponents }, { szPublishFeatures, ACTION_PublishFeatures }, { szPublishProduct, ACTION_PublishProduct }, { szRegisterClassInfo, ACTION_RegisterClassInfo }, @@ -380,6 +381,13 @@ memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR)); } +inline static void reduce_to_shortfilename(WCHAR* filename) +{ + LPWSTR p = strchrW(filename,'|'); + if (p) + *p = 0; +} + WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index) { UINT rc; @@ -598,6 +606,7 @@ { HeapFree(GetProcessHeap(),0,package->files[i].File); HeapFree(GetProcessHeap(),0,package->files[i].FileName); + HeapFree(GetProcessHeap(),0,package->files[i].ShortName); HeapFree(GetProcessHeap(),0,package->files[i].Version); HeapFree(GetProcessHeap(),0,package->files[i].Language); HeapFree(GetProcessHeap(),0,package->files[i].SourcePath); @@ -630,15 +639,16 @@ MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row); msiobj_release(&row->hdr); - msi_dialog_check_messages(package->dialog, NULL); + msi_dialog_check_messages(NULL); } static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record) { static const WCHAR Query_t[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'A','c','t','i','o', 'n','T','e','x','t',' ','W','H','E','R','E',' ', - 'A','c','t','i','o','n',' ','=', ' ','\'','%','s','\'',0}; + '`','A','c','t','i','o', 'n','T','e','x','t','`',' ', + 'W','H','E','R','E',' ', '`','A','c','t','i','o','n','`',' ','=', + ' ','\'','%','s','\'',0}; WCHAR message[1024]; UINT rc; MSIQUERY * view; @@ -655,12 +665,14 @@ if (rc != ERROR_SUCCESS) { MSI_ViewClose(view); + msiobj_release(&view->hdr); return; } rc = MSI_ViewFetch(view,&row); if (rc != ERROR_SUCCESS) { MSI_ViewClose(view); + msiobj_release(&view->hdr); return; } @@ -705,8 +717,9 @@ {'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0}; static const WCHAR Query_t[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'A','c','t','i','o', 'n','T','e','x','t',' ','W','H','E','R','E', ' ', - 'A','c','t','i','o','n',' ','=', ' ','\'','%','s','\'',0}; + '`','A','c','t','i','o', 'n','T','e','x','t','`',' ', + 'W','H','E','R','E', ' ','`','A','c','t','i','o','n','`',' ','=', + ' ','\'','%','s','\'',0}; WCHAR message[1024]; WCHAR timet[0x100]; UINT rc; @@ -1005,14 +1018,14 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'I','n','s','t','a','l','l','E','x','e','c','u','t','e', - 'S','e','q','u','e','n','c','e',' ', 'W','H','E','R','E',' ', - 'S','e','q','u','e','n','c','e',' ', '=',' ','%','i',0}; + '`','I','n','s','t','a','l','l','E','x','e','c','u','t','e', + 'S','e','q','u','e','n','c','e','`',' ', 'W','H','E','R','E',' ', + '`','S','e','q','u','e','n','c','e','`',' ', '=',' ','%','i',0}; static const WCHAR UISeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e', - ' ', 'W','H','E','R','E',' ', 'S','e','q','u','e','n','c','e', + '`','I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e', + '`', ' ', 'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`', ' ', '=',' ','%','i',0}; if (UI) @@ -1090,18 +1103,19 @@ UINT rc; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', - 'I','n','s','t','a','l','l','E','x','e','c','u','t','e', - 'S','e','q','u','e','n','c','e',' ', 'W','H','E','R','E',' ', - 'S','e','q','u','e','n','c','e',' ', '>',' ','%','i',' ', + '`','I','n','s','t','a','l','l','E','x','e','c','u','t','e', + 'S','e','q','u','e','n','c','e','`',' ', 'W','H','E','R','E',' ', + '`','S','e','q','u','e','n','c','e','`',' ', '>',' ','%','i',' ', 'O','R','D','E','R',' ', 'B','Y',' ', - 'S','e','q','u','e','n','c','e',0 }; + '`','S','e','q','u','e','n','c','e','`',0 }; MSIRECORD * row = 0; static const WCHAR IVQuery[] = - {'S','E','L','E','C','T',' ','S','e','q','u','e','n','c','e',' ', - 'F','R','O','M',' ','I','n','s','t','a','l','l', - 'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e',' ', - 'W','H','E','R','E',' ','A','c','t','i','o','n',' ','=',' ','`', - 'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e','`', 0}; + {'S','E','L','E','C','T',' ','`','S','e','q','u','e','n','c','e','`', + ' ', 'F','R','O','M',' ','`','I','n','s','t','a','l','l', + 'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e','`',' ', + 'W','H','E','R','E',' ','`','A','c','t','i','o','n','`',' ','=', + ' ','\'', 'I','n','s','t','a','l','l', + 'V','a','l','i','d','a','t','e','\'', 0}; INT seq = 0; @@ -1225,10 +1239,12 @@ UINT rc; static const WCHAR ExecSeqQuery [] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e', - ' ','W','H','E','R','E',' ', 'S','e','q','u','e','n','c','e',' ', + '`','I','n','s','t','a','l','l', + 'U','I','S','e','q','u','e','n','c','e','`', + ' ','W','H','E','R','E',' ', + '`','S','e','q','u','e','n','c','e','`',' ', '>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ', - 'S','e','q','u','e','n','c','e',0}; + '`','S','e','q','u','e','n','c','e','`',0}; rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view); @@ -1420,7 +1436,7 @@ if (!handled) handled = ACTION_HandleDialogBox(package, action, &rc); - msi_dialog_check_messages( package->dialog, NULL ); + msi_dialog_check_messages( NULL ); if (!handled) { @@ -1493,9 +1509,10 @@ static UINT ACTION_CreateFolders(MSIPACKAGE *package) { static const WCHAR ExecSeqQuery[] = - {'S','E','L','E','C','T',' ','D','i','r','e','c','t','o','r','y','_', + {'S','E','L','E','C','T',' ', + '`','D','i','r','e','c','t','o','r','y','_','`', ' ','F','R','O','M',' ', - 'C','r','e','a','t','e','F','o','l','d','e','r',0 }; + '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 }; UINT rc; MSIQUERY *view; MSIFOLDER *folder; @@ -1606,7 +1623,7 @@ sz = 96; MSI_RecordGetStringW(row,6,package->components[index].KeyPath,&sz); - package->components[index].Installed = INSTALLSTATE_UNKNOWN; + package->components[index].Installed = INSTALLSTATE_ABSENT; package->components[index].Action = INSTALLSTATE_UNKNOWN; package->components[index].ActionRequest = INSTALLSTATE_UNKNOWN; @@ -1620,14 +1637,18 @@ int index = package->loaded_features; DWORD sz; static const WCHAR Query1[] = - {'S','E','L','E','C','T',' ','C','o','m','p','o','n','e','n','t','_', - ' ','F','R','O','M',' ','F','e','a','t','u','r','e', - 'C','o','m','p','o','n','e','n','t','s',' ','W','H','E','R','E',' ', - 'F','e', 'a','t','u','r','e','_','=','\'','%','s','\'',0}; + {'S','E','L','E','C','T',' ', + '`','C','o','m','p','o','n','e','n','t','_','`', + ' ','F','R','O','M',' ','`','F','e','a','t','u','r','e', + 'C','o','m','p','o','n','e','n','t','s','`',' ', + 'W','H','E','R','E',' ', + '`','F','e', 'a','t','u','r','e','_','`',' ','=','\'','%','s','\'',0}; static const WCHAR Query2[] = {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ', - 'C','o','m','p','o','n','e','n','t',' ','W','H','E','R','E',' ', - 'C','o','m','p','o','n','e','n','t','=','\'','%','s','\'',0}; + '`','C','o','m','p','o','n','e','n','t','`',' ', + 'W','H','E','R','E',' ', + '`','C','o','m','p','o','n','e','n','t','`',' ', + '=','\'','%','s','\'',0}; MSIQUERY * view; MSIQUERY * view2; MSIRECORD * row2; @@ -1673,7 +1694,7 @@ package->features[index].Attributes= MSI_RecordGetInteger(row,8); - package->features[index].Installed = INSTALLSTATE_UNKNOWN; + package->features[index].Installed = INSTALLSTATE_ABSENT; package->features[index].Action = INSTALLSTATE_UNKNOWN; package->features[index].ActionRequest = INSTALLSTATE_UNKNOWN; @@ -1712,6 +1733,7 @@ c_indx); package->features[index].Components[cnt] = c_indx; package->features[index].ComponentCount ++; + msiobj_release( &row2->hdr ); continue; } @@ -1751,61 +1773,6 @@ msiobj_release(&view->hdr); } -/* - * I am not doing any of the costing functionality yet. - * Mostly looking at doing the Component and Feature loading - * - * The native MSI does A LOT of modification to tables here. Mostly adding - * a lot of temporary columns to the Feature and Component tables. - * - * note: Native msi also tracks the short filename. But I am only going to - * track the long ones. Also looking at this directory table - * it appears that the directory table does not get the parents - * resolved base on property only based on their entries in the - * directory table. - */ -static UINT ACTION_CostInitialize(MSIPACKAGE *package) -{ - MSIQUERY * view; - MSIRECORD * row; - UINT rc; - static const WCHAR Query_all[] = - {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', - 'F','e','a','t','u','r','e',0}; - static const WCHAR szCosting[] = - {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 }; - static const WCHAR szZero[] = { '0', 0 }; - - MSI_SetPropertyW(package, szCosting, szZero); - MSI_SetPropertyW(package, cszRootDrive , c_colon); - - rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view); - if (rc != ERROR_SUCCESS) - return rc; - rc = MSI_ViewExecute(view,0); - if (rc != ERROR_SUCCESS) - { - MSI_ViewClose(view); - msiobj_release(&view->hdr); - return rc; - } - while (1) - { - DWORD rc; - - rc = MSI_ViewFetch(view,&row); - if (rc != ERROR_SUCCESS) - break; - - load_feature(package,row); - msiobj_release(&row->hdr); - } - MSI_ViewClose(view); - msiobj_release(&view->hdr); - - return ERROR_SUCCESS; -} - static UINT load_file(MSIPACKAGE* package, MSIRECORD * row) { DWORD index = package->loaded_files; @@ -1838,8 +1805,10 @@ HeapFree(GetProcessHeap(), 0, buffer); package->files[index].FileName = load_dynamic_stringW(row,3); - reduce_to_longfilename(package->files[index].FileName); + + package->files[index].ShortName = load_dynamic_stringW(row,3); + reduce_to_shortfilename(package->files[index].ShortName); package->files[index].FileSize = MSI_RecordGetInteger(row,4); package->files[index].Version = load_dynamic_stringW(row, 5); @@ -1855,15 +1824,15 @@ return ERROR_SUCCESS; } -static UINT ACTION_FileCost(MSIPACKAGE *package) +static UINT load_all_files(MSIPACKAGE *package) { MSIQUERY * view; MSIRECORD * row; UINT rc; static const WCHAR Query[] = {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', - 'F','i','l','e',' ', 'O','R','D','E','R',' ','B','Y',' ', - 'S','e','q','u','e','n','c','e', 0}; + '`','F','i','l','e','`',' ', 'O','R','D','E','R',' ','B','Y',' ', + '`','S','e','q','u','e','n','c','e','`', 0}; if (!package) return ERROR_INVALID_HANDLE; @@ -1897,16 +1866,88 @@ return ERROR_SUCCESS; } + +/* + * I am not doing any of the costing functionality yet. + * Mostly looking at doing the Component and Feature loading + * + * The native MSI does A LOT of modification to tables here. Mostly adding + * a lot of temporary columns to the Feature and Component tables. + * + * note: Native msi also tracks the short filename. But I am only going to + * track the long ones. Also looking at this directory table + * it appears that the directory table does not get the parents + * resolved base on property only based on their entries in the + * directory table. + */ +static UINT ACTION_CostInitialize(MSIPACKAGE *package) +{ + MSIQUERY * view; + MSIRECORD * row; + UINT rc; + static const WCHAR Query_all[] = + {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', + '`','F','e','a','t','u','r','e','`',0}; + static const WCHAR szCosting[] = + {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 }; + static const WCHAR szZero[] = { '0', 0 }; + WCHAR buffer[3]; + DWORD sz = 3; + + MSI_GetPropertyW(package, szCosting, buffer, &sz); + if (buffer[0]=='1') + return ERROR_SUCCESS; + + MSI_SetPropertyW(package, szCosting, szZero); + MSI_SetPropertyW(package, cszRootDrive , c_colon); + + rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view); + if (rc != ERROR_SUCCESS) + return rc; + rc = MSI_ViewExecute(view,0); + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + msiobj_release(&view->hdr); + return rc; + } + while (1) + { + DWORD rc; + + rc = MSI_ViewFetch(view,&row); + if (rc != ERROR_SUCCESS) + break; + + load_feature(package,row); + msiobj_release(&row->hdr); + } + MSI_ViewClose(view); + msiobj_release(&view->hdr); + + load_all_files(package); + + return ERROR_SUCCESS; +} + +static UINT ACTION_FileCost(MSIPACKAGE *package) +{ + return ERROR_SUCCESS; +} + + static INT load_folder(MSIPACKAGE *package, const WCHAR* dir) { static const WCHAR Query[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'D','i','r','e','c', 't','o','r','y',' ','W','H','E','R','E',' ','`', - 'D','i','r','e','c','t', 'o','r','y','`',' ','=',' ','`','%','s','`', + '`','D','i','r','e','c', 't','o','r','y','`',' ', + 'W','H','E','R','E',' ', '`', 'D','i','r','e','c','t', 'o','r','y','`', + ' ','=',' ','\'','%','s','\'', 0}; UINT rc; MSIQUERY * view; LPWSTR ptargetdir, targetdir, parent, srcdir; + LPWSTR shortname = NULL; MSIRECORD * row = 0; INT index = -1; DWORD i; @@ -1972,15 +2013,16 @@ /* for now only pick long filename versions */ if (strchrW(targetdir,'|')) { + shortname = targetdir; targetdir = strchrW(targetdir,'|'); *targetdir = 0; targetdir ++; } + /* for the sourcedir pick the short filename */ if (srcdir && strchrW(srcdir,'|')) { - srcdir= strchrW(srcdir,'|'); - *srcdir= 0; - srcdir ++; + LPWSTR p = strchrW(srcdir,'|'); + *p = 0; } /* now check for root dirs */ @@ -1999,9 +2041,12 @@ if (srcdir) package->folders[index].SourceDefault = strdupW(srcdir); + else if (shortname) + package->folders[index].SourceDefault = strdupW(shortname); else if (targetdir) package->folders[index].SourceDefault = strdupW(targetdir); HeapFree(GetProcessHeap(), 0, ptargetdir); + TRACE(" SourceDefault = %s\n",debugstr_w(package->folders[index].SourceDefault)); parent = load_dynamic_stringW(row,2); if (parent) @@ -2105,6 +2150,7 @@ else if (source && package->folders[i].ResolvedSource) { path = strdupW(package->folders[i].ResolvedSource); + TRACE(" (source)already resolved to %s\n",debugstr_w(path)); return path; } else if (!source && package->folders[i].Property) @@ -2136,6 +2182,7 @@ else { path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL); + TRACE(" (source)resolved into %s\n",debugstr_w(path)); package->folders[i].ResolvedSource = strdupW(path); } HeapFree(GetProcessHeap(),0,p); @@ -2201,17 +2248,25 @@ { MSICOMPONENT* component = &package->components[feature->Components[i]]; + TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n", + newstate, debugstr_w(component->Component), component->Installed, + component->Action, component->ActionRequest); + if (!component->Enabled) continue; else { if (newstate == INSTALLSTATE_LOCAL) + { component->ActionRequest = INSTALLSTATE_LOCAL; + component->Action = INSTALLSTATE_LOCAL; + } else { int j,k; component->ActionRequest = newstate; + component->Action = newstate; /*if any other feature wants is local we need to set it local*/ for (j = 0; @@ -2225,12 +2280,19 @@ { if (package->features[j].ActionRequest == INSTALLSTATE_LOCAL) + { + TRACE("Saved by %s\n", debugstr_w(package->features[j].Feature)); component->ActionRequest = INSTALLSTATE_LOCAL; + component->Action = INSTALLSTATE_LOCAL; + } break; } } } } + TRACE("Result (%i): Component %s (Installed %i, Action %i, Request %i)\n", + newstate, debugstr_w(component->Component), component->Installed, + component->Action, component->ActionRequest); } } @@ -2344,10 +2406,26 @@ BOOL feature_state = ((package->features[i].Level > 0) && (package->features[i].Level <= install_level)); - if (feature_state) + if ((feature_state) && + (package->features[i].Action == INSTALLSTATE_UNKNOWN)) { - package->features[i].ActionRequest = INSTALLSTATE_LOCAL; - package->features[i].Action = INSTALLSTATE_LOCAL; + if (package->features[i].Attributes & + msidbFeatureAttributesFavorSource) + { + package->features[i].ActionRequest = INSTALLSTATE_SOURCE; + package->features[i].Action = INSTALLSTATE_SOURCE; + } + else if (package->features[i].Attributes & + msidbFeatureAttributesFavorAdvertise) + { + package->features[i].ActionRequest =INSTALLSTATE_ADVERTISED; + package->features[i].Action =INSTALLSTATE_ADVERTISED; + } + else + { + package->features[i].ActionRequest = INSTALLSTATE_LOCAL; + package->features[i].Action = INSTALLSTATE_LOCAL; + } } } } @@ -2380,6 +2458,27 @@ component->Action = INSTALLSTATE_LOCAL; component->ActionRequest = INSTALLSTATE_LOCAL; } + else if (feature->ActionRequest == INSTALLSTATE_SOURCE) + { + if ((component->Action == INSTALLSTATE_UNKNOWN) || + (component->Action == INSTALLSTATE_ABSENT) || + (component->Action == INSTALLSTATE_ADVERTISED)) + + { + component->Action = INSTALLSTATE_SOURCE; + component->ActionRequest = INSTALLSTATE_SOURCE; + } + } + else if (feature->ActionRequest == INSTALLSTATE_ADVERTISED) + { + if ((component->Action == INSTALLSTATE_UNKNOWN) || + (component->Action == INSTALLSTATE_ABSENT)) + + { + component->Action = INSTALLSTATE_ADVERTISED; + component->ActionRequest = INSTALLSTATE_ADVERTISED; + } + } else if (feature->ActionRequest == INSTALLSTATE_ABSENT) { if (component->Action == INSTALLSTATE_UNKNOWN) @@ -2415,10 +2514,10 @@ { static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'D','i','r','e','c','t','o','r','y',0}; + '`','D','i','r','e','c','t','o','r','y','`',0}; static const WCHAR ConditionQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'C','o','n','d','i','t','i','o','n',0}; + '`','C','o','n','d','i','t','i','o','n','`',0}; static const WCHAR szCosting[] = {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 }; static const WCHAR szlevel[] = @@ -2428,6 +2527,12 @@ MSIQUERY * view; DWORD i; LPWSTR level; + DWORD sz = 3; + WCHAR buffer[3]; + + MSI_GetPropertyW(package, szCosting, buffer, &sz); + if (buffer[0]=='1') + return ERROR_SUCCESS; TRACE("Building Directory properties\n"); @@ -2669,6 +2774,7 @@ if (the_file == INVALID_HANDLE_VALUE) { + ERR("Unable to create file %s\n",debugstr_w(source)); rc = ERROR_FUNCTION_FAILED; goto end; } @@ -2771,7 +2877,7 @@ LPWSTR tracknametmp; static const WCHAR tmpprefix[] = {'C','A','B','T','M','P','_',0}; - if (data->file_name && strcmp(data->file_name,pfdin->psz1)) + if (data->file_name && lstrcmpiA(data->file_name,pfdin->psz1)) return 0; file = cabinet_alloc((len+1)*sizeof(char)); @@ -2884,8 +2990,8 @@ return ret; } -static UINT ready_media_for_file(MSIPACKAGE *package, UINT sequence, - WCHAR* path, WCHAR* file) +static UINT ready_media_for_file(MSIPACKAGE *package, WCHAR* path, + MSIFILE* file) { UINT rc; MSIQUERY * view; @@ -2893,24 +2999,30 @@ static WCHAR source[MAX_PATH]; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', - 'M','e','d','i','a',' ','W','H','E','R','E',' ', - 'L','a','s','t','S','e','q','u','e','n','c','e',' ','>','=',' ','%', - 'i',' ','O','R','D','E','R',' ','B','Y',' ', - 'L','a','s','t','S','e','q','u','e','n','c','e',0}; + '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', + '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=', + ' ','%', 'i',' ','O','R','D','E','R',' ','B','Y',' ', + '`','L','a','s','t','S','e','q','u','e','n','c','e','`',0}; WCHAR Query[1024]; WCHAR cab[0x100]; DWORD sz=0x100; INT seq; static UINT last_sequence = 0; - if (sequence <= last_sequence) + if (file->Attributes & msidbFileAttributesNoncompressed) + { + TRACE("Uncompressed File, no media to ready.\n"); + return ERROR_SUCCESS; + } + + if (file->Sequence <= last_sequence) { - TRACE("Media already ready (%u, %u)\n",sequence,last_sequence); - /*extract_a_cabinet_file(package, source,path,file); */ + TRACE("Media already ready (%u, %u)\n",file->Sequence,last_sequence); + /*extract_a_cabinet_file(package, source,path,file->File); */ return ERROR_SUCCESS; } - sprintfW(Query,ExecSeqQuery,sequence); + sprintfW(Query,ExecSeqQuery,file->Sequence); rc = MSI_DatabaseOpenViewW(package->db, Query, &view); if (rc != ERROR_SUCCESS) @@ -3038,12 +3150,10 @@ if ((file->State == 1) || (file->State == 2)) { LPWSTR p; - INT len; MSICOMPONENT* comp = NULL; TRACE("Installing %s\n",debugstr_w(file->File)); - rc = ready_media_for_file(package,file->Sequence,path_to_source, - file->File); + rc = ready_media_for_file(package, path_to_source, file); /* * WARNING! * our file table could change here because a new temp file @@ -3068,11 +3178,18 @@ HeapFree(GetProcessHeap(),0,file->TargetPath); file->TargetPath = build_directory_name(2, p, file->FileName); + HeapFree(GetProcessHeap(),0,p); + + if (file->Attributes & msidbFileAttributesNoncompressed) + { + p = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL); + file->SourcePath = build_directory_name(2, p, file->ShortName); + HeapFree(GetProcessHeap(),0,p); + } + else + file->SourcePath = build_directory_name(2, path_to_source, + file->File); - len = strlenW(path_to_source) + strlenW(file->File) + 2; - file->SourcePath = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR)); - strcpyW(file->SourcePath, path_to_source); - strcatW(file->SourcePath, file->File); TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath), debugstr_w(file->TargetPath)); @@ -3088,16 +3205,26 @@ msiobj_release( &uirow->hdr ); ui_progress(package,2,file->FileSize,0,0); - if (!MoveFileW(file->SourcePath,file->TargetPath)) + + if (file->Attributes & msidbFileAttributesNoncompressed) + rc = CopyFileW(file->SourcePath,file->TargetPath,FALSE); + else + rc = MoveFileW(file->SourcePath, file->TargetPath); + + if (!rc) { rc = GetLastError(); - ERR("Unable to move file (%s -> %s) (error %d)\n", + ERR("Unable to move/copy file (%s -> %s) (error %d)\n", debugstr_w(file->SourcePath), debugstr_w(file->TargetPath), rc); if (rc == ERROR_ALREADY_EXISTS && file->State == 2) { - CopyFileW(file->SourcePath,file->TargetPath,FALSE); - DeleteFileW(file->SourcePath); + if (!CopyFileW(file->SourcePath,file->TargetPath,FALSE)) + ERR("Unable to copy file (%s -> %s) (error %ld)\n", + debugstr_w(file->SourcePath), + debugstr_w(file->TargetPath), GetLastError()); + if (!(file->Attributes & msidbFileAttributesNoncompressed)) + DeleteFileW(file->SourcePath); rc = 0; } else if (rc == ERROR_FILE_NOT_FOUND) @@ -3105,14 +3232,17 @@ ERR("Source File Not Found! Continuing\n"); rc = 0; } - else + else if (file->Attributes & msidbFileAttributesVital) { - ERR("Ignoring Error and continuing...\n"); + ERR("Ignoring Error and continuing (nonvital file)...\n"); rc = 0; } } else + { file->State = 4; + rc = ERROR_SUCCESS; + } } } @@ -3151,7 +3281,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'D','u','p','l','i','c','a','t','e','F','i','l','e',0}; + '`','D','u','p','l','i','c','a','t','e','F','i','l','e','`',0}; if (!package) return ERROR_INVALID_HANDLE; @@ -3304,21 +3434,35 @@ { LPWSTR ptr; CHAR byte[5]; - LPWSTR deformated; + LPWSTR deformated = NULL; int count; deformat_string(package, &value[2], &deformated); /* binary value type */ - ptr = deformated; - *type=REG_BINARY; - *size = strlenW(ptr)/2; + ptr = deformated; + *type = REG_BINARY; + if (strlenW(ptr)%2) + *size = (strlenW(ptr)/2)+1; + else + *size = strlenW(ptr)/2; + data = HeapAlloc(GetProcessHeap(),0,*size); - + byte[0] = '0'; byte[1] = 'x'; byte[4] = 0; count = 0; + /* if uneven pad with a zero in front */ + if (strlenW(ptr)%2) + { + byte[2]= '0'; + byte[3]= *ptr; + ptr++; + data[count] = (BYTE)strtol(byte,NULL,0); + count ++; + TRACE("Uneven byte count\n"); + } while (*ptr) { byte[2]= *ptr; @@ -3395,7 +3539,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'R','e','g','i','s','t','r','y',0 }; + '`','R','e','g','i','s','t','r','y','`',0 }; if (!package) return ERROR_INVALID_HANDLE; @@ -3438,6 +3582,7 @@ MSIRECORD * uirow; LPWSTR uikey; INT root; + BOOL check_first = FALSE; rc = MSI_ViewFetch(view,&row); if (rc != ERROR_SUCCESS) @@ -3483,6 +3628,7 @@ { HeapFree(GetProcessHeap(),0,name); name = NULL; + check_first = TRUE; } } @@ -3545,8 +3691,32 @@ deformat_string(package, name, &deformated); - TRACE("Setting value %s\n",debugstr_w(deformated)); - RegSetValueExW(hkey, deformated, 0, type, value_data, size); + /* get the double nulls to terminate SZ_MULTI */ + if (type == REG_MULTI_SZ) + size +=sizeof(WCHAR); + + if (!check_first) + { + TRACE("Setting value %s of %s\n",debugstr_w(deformated), + debugstr_w(uikey)); + RegSetValueExW(hkey, deformated, 0, type, value_data, size); + } + else + { + DWORD sz = 0; + rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz); + if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) + { + TRACE("value %s of %s checked already exists\n", + debugstr_w(deformated), debugstr_w(uikey)); + } + else + { + TRACE("Checked and setting value %s of %s\n", + debugstr_w(deformated), debugstr_w(uikey)); + RegSetValueExW(hkey, deformated, 0, type, value_data, size); + } + } uirow = MSI_CreateRecord(3); MSI_RecordSetStringW(uirow,2,deformated); @@ -3589,7 +3759,7 @@ DWORD total = 0; static const WCHAR q1[]= {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', - 'R','e','g','i','s','t','r','y',0}; + '`','R','e','g','i','s','t','r','y','`',0}; UINT rc; MSIQUERY * view; MSIRECORD * row = 0; @@ -3629,6 +3799,14 @@ total += package->files[i].FileSize; ui_progress(package,0,total,0,0); + for(i = 0; i < package->loaded_features; i++) + { + MSIFEATURE* feature = &package->features[i]; + TRACE("Feature: %s; Installed: %i; Action %i; Request %i\n", + debugstr_w(feature->Feature), feature->Installed, feature->Action, + feature->ActionRequest); + } + return ERROR_SUCCESS; } @@ -3639,7 +3817,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n',0}; + '`','L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','`',0}; static const WCHAR title[]= {'I','n','s','t','a','l','l',' ','F','a', 'i','l','e','d',0}; @@ -3708,8 +3886,9 @@ LPWSTR key,deformated,buffer,name,deformated_name; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'R','e','g','i','s','t','r','y',' ','W','H','E','R','E',' ', - 'R','e','g','i','s','t','r','y',' ','=',' ' ,'`','%','s','`',0 }; + '`','R','e','g','i','s','t','r','y','`',' ', + 'W','H','E','R','E',' ', '`','R','e','g','i','s','t','r','y','`', + ' ','=',' ' ,'\'','%','s','\'',0 }; static const WCHAR fmt[]={'%','0','2','i',':','\\','%','s','\\',0}; static const WCHAR fmt2[]= {'%','0','2','i',':','\\','%','s','\\','%','s',0}; @@ -3941,9 +4120,6 @@ MSIRECORD * uirow; squash_guid(package->components[i].ComponentId,squished_cc); - rc = RegCreateKeyW(hkey,squished_cc,&hkey2); - if (rc != ERROR_SUCCESS) - continue; keypath = resolve_keypath(package,i); package->components[i].FullKeypath = keypath; @@ -3951,8 +4127,9 @@ /* do the refcounting */ ACTION_RefCountComponent( package, i); - TRACE("Component %s, Keypath=%s, RefCount=%i\n", - debugstr_w(package->components[i].Component), + TRACE("Component %s (%s), Keypath=%s, RefCount=%i\n", + debugstr_w(package->components[i].Component), + debugstr_w(squished_cc), debugstr_w(package->components[i].FullKeypath), package->components[i].RefCount); /* @@ -3962,6 +4139,10 @@ if (ACTION_VerifyComponentForAction(package, i, INSTALLSTATE_LOCAL)) { + rc = RegCreateKeyW(hkey,squished_cc,&hkey2); + if (rc != ERROR_SUCCESS) + continue; + if (keypath) { RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPVOID)keypath, @@ -3996,6 +4177,11 @@ INSTALLSTATE_ABSENT)) { DWORD res; + + rc = RegOpenKeyW(hkey,squished_cc,&hkey2); + if (rc != ERROR_SUCCESS) + continue; + RegDeleteValueW(hkey2,squished_pc); /* if the key is empty delete it */ @@ -4088,7 +4274,7 @@ MSIRECORD * row = 0; static const WCHAR Query[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'T','y','p','e','L','i','b',0}; + '`','T','y','p','e','L','i','b','`',0}; if (!package) return ERROR_INVALID_HANDLE; @@ -4217,8 +4403,8 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'A','p','p','I' ,'d',' ','w','h','e','r','e',' ', - 'A','p','p','I','d','=','`','%','s','`',0}; + '`','A','p','p','I' ,'d','`',' ','W','H','E','R','E',' ', + '`','A','p','p','I','d','`',' ','=','\'','%','s','\'',0}; HKEY hkey2,hkey3; LPWSTR buffer=0; @@ -4347,7 +4533,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'C','l','a','s','s',0}; + '`','C','l','a','s','s','`',0}; static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 }; static const WCHAR szProgID[] = { 'P','r','o','g','I','D',0 }; static const WCHAR szAppID[] = { 'A','p','p','I','D',0 }; @@ -4404,8 +4590,10 @@ continue; } - if (!ACTION_VerifyComponentForAction(package, index, - INSTALLSTATE_LOCAL)) + if ((!ACTION_VerifyComponentForAction(package, index, + INSTALLSTATE_LOCAL)) && + (!ACTION_VerifyComponentForAction(package, index, + INSTALLSTATE_ADVERTISED))) { TRACE("Skipping class reg due to disabled component\n"); msiobj_release(&row->hdr); @@ -4662,8 +4850,8 @@ MSIRECORD * row = 0; static const WCHAR Query_t[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'P','r','o','g' ,'I','d',' ','W','H','E','R','E',' ', - 'P','r','o','g','I','d',' ','=',' ','`' ,'%','s','`',0}; + '`','P','r','o','g' ,'I','d','`',' ','W','H','E','R','E',' ', + '`','P','r','o','g','I','d','`',' ','=',' ','\'' ,'%','s','\'',0}; if (!package) return ERROR_INVALID_HANDLE; @@ -4776,7 +4964,7 @@ MSIRECORD * row = 0; static const WCHAR Query[] = {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', - 'P','r','o','g','I','d',0}; + '`','P','r','o','g','I','d','`',0}; if (!package) return ERROR_INVALID_HANDLE; @@ -4851,8 +5039,8 @@ MSIQUERY * view; MSIRECORD * row = 0; static const WCHAR Query[] = - {'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ', - 'S','h','o','r','t','c','u','t',0}; + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','S','h','o','r','t','c','u','t','`',0}; IShellLinkW *sl; IPersistFile *pf; HRESULT res; @@ -5054,7 +5242,7 @@ MSIRECORD * row = 0; static const WCHAR Query[]= {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'I','c','o','n',0}; + '`','I','c','o','n','`',0}; DWORD sz; /* for registry stuff */ LPWSTR productcode; @@ -5215,7 +5403,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'I','n','i','F','i','l','e',0}; + '`','I','n','i','F','i','l','e','`',0}; static const WCHAR szWindowsFolder[] = {'W','i','n','d','o','w','s','F','o','l','d','e','r',0}; @@ -5357,10 +5545,11 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'S','e','l','f','R','e','g',0}; + '`','S','e','l','f','R','e','g','`',0}; static const WCHAR ExeStr[] = - {'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','s',' ',0}; + {'r','e','g','s','v','r','3','2','.','e','x','e',' ','\"',0}; + static const WCHAR close[] = {'\"',0}; STARTUPINFOW si; PROCESS_INFORMATION info; BOOL brc; @@ -5414,13 +5603,14 @@ filename = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR)); strcpyW(filename,ExeStr); strcatW(filename,package->files[index].TargetPath); + strcatW(filename,close); TRACE("Registering %s\n",debugstr_w(filename)); brc = CreateProcessW(NULL, filename, NULL, NULL, FALSE, 0, NULL, c_colon, &si, &info); if (brc) - msi_dialog_check_messages(package->dialog, info.hProcess); + msi_dialog_check_messages(info.hProcess); HeapFree(GetProcessHeap(),0,filename); msiobj_release(&row->hdr); @@ -5460,9 +5650,12 @@ GUID clsid; int j; INT size; + BOOL absent = FALSE; - if (!ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_LOCAL)) - continue; + if (!ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_LOCAL) && + !ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_SOURCE) && + !ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_ADVERTISED)) + absent = TRUE; size = package->features[i].ComponentCount*21; size +=1; @@ -5476,14 +5669,18 @@ { WCHAR buf[21]; memset(buf,0,sizeof(buf)); - TRACE("From %s\n",debugstr_w(package->components + if (package->components + [package->features[i].Components[j]].ComponentId[0]!=0) + { + TRACE("From %s\n",debugstr_w(package->components [package->features[i].Components[j]].ComponentId)); - CLSIDFromString(package->components + CLSIDFromString(package->components [package->features[i].Components[j]].ComponentId, &clsid); - encode_base85_guid(&clsid,buf); - TRACE("to %s\n",debugstr_w(buf)); - strcatW(data,buf); + encode_base85_guid(&clsid,buf); + TRACE("to %s\n",debugstr_w(buf)); + strcatW(data,buf); + } } if (package->features[i].Feature_Parent[0]) { @@ -5497,9 +5694,23 @@ (LPSTR)data,size); HeapFree(GetProcessHeap(),0,data); - size = strlenW(package->features[i].Feature_Parent)*sizeof(WCHAR); - RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ, + if (!absent) + { + size = strlenW(package->features[i].Feature_Parent)*sizeof(WCHAR); + RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ, (LPSTR)package->features[i].Feature_Parent,size); + } + else + { + size = (strlenW(package->features[i].Feature_Parent)+2)* + sizeof(WCHAR); + data = HeapAlloc(GetProcessHeap(),0,size); + data[0] = 0x6; + strcpyW(&data[1],package->features[i].Feature_Parent); + RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ, + (LPSTR)data,size); + HeapFree(GetProcessHeap(),0,data); + } } end: @@ -5625,7 +5836,10 @@ snprintfW(path,sizeof(path)/sizeof(path[0]),installerPathFmt,windir); create_full_pathW(path); TRACE("Copying to local package %s\n",debugstr_w(packagefile)); - CopyFileW(package->PackagePath,packagefile,FALSE); + if (!CopyFileW(package->PackagePath,packagefile,FALSE)) + ERR("Unable to copy package (%s -> %s) (error %ld)\n", + debugstr_w(package->PackagePath), debugstr_w(packagefile), + GetLastError()); size = strlenW(packagefile)*sizeof(WCHAR); RegSetValueExW(hkey,szLocalPackage,0,REG_SZ,(LPSTR)packagefile,size); @@ -5793,7 +6007,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'E','x','t','e','n','s','i','o','n',0}; + '`','E','x','t','e','n','s','i','o','n','`',0}; static const WCHAR szContentType[] = {'C','o','n','t','e','n','t',' ','T','y','p','e',0 }; HKEY hkey; @@ -5842,8 +6056,10 @@ continue; } - if (!ACTION_VerifyComponentForAction(package, index, - INSTALLSTATE_LOCAL)) + if ((!ACTION_VerifyComponentForAction(package, index, + INSTALLSTATE_LOCAL)) && + (!ACTION_VerifyComponentForAction(package, index, + INSTALLSTATE_ADVERTISED))) { TRACE("Skipping extension reg due to disabled component\n"); msiobj_release(&row->hdr); @@ -5916,7 +6132,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'M','I','M','E',0}; + '`','M','I','M','E','`',0}; static const WCHAR szExten[] = {'E','x','t','e','n','s','i','o','n',0 }; HKEY hkey; @@ -6042,6 +6258,8 @@ size = strlenW(buffer)*sizeof(WCHAR); RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPSTR)buffer,size); } + else + RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,NULL,0); i++; } @@ -6057,7 +6275,7 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package) { UINT rc; - rc = ACTION_ProcessExecSequence(package,TRUE); + rc = ACTION_ProcessExecSequence(package,FALSE); return rc; } @@ -6187,6 +6405,8 @@ } CloseHandle(handle); } + else + ERR("Unable to open font file %s\n", debugstr_w(filename)); TRACE("Returning fontname %s\n",debugstr_w(ret)); return ret; @@ -6199,7 +6419,7 @@ MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - 'F','o','n','t',0}; + '`','F','o','n','t','`',0}; static const WCHAR regfont1[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', @@ -6215,16 +6435,22 @@ HKEY hkey1; HKEY hkey2; + TRACE("%p\n", package); + rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view); if (rc != ERROR_SUCCESS) - return rc; + { + TRACE("MSI_DatabaseOpenViewW failed: %d\n", rc); + return ERROR_SUCCESS; + } rc = MSI_ViewExecute(view, 0); if (rc != ERROR_SUCCESS) { MSI_ViewClose(view); msiobj_release(&view->hdr); - return rc; + TRACE("MSI_ViewExecute returned %d\n", rc); + return ERROR_SUCCESS; } RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1); @@ -6289,10 +6515,143 @@ RegCloseKey(hkey1); RegCloseKey(hkey2); + TRACE("returning %d\n", rc); + return rc; +} + +static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) +{ + MSIPACKAGE *package = (MSIPACKAGE*)param; + LPWSTR productid=NULL, compgroupid=NULL; + LPWSTR feature=NULL; + LPWSTR text = NULL; + LPWSTR qualifier = NULL; + LPWSTR component = NULL; + GUID clsid; + WCHAR productid_85[21]; + WCHAR component_85[21]; + HKEY hkey; + UINT rc = ERROR_SUCCESS; + UINT index; + /* + * I have a fair bit of confusion as to when a < is used and when a > is + * used. I do not think i have it right... + * + * Ok it appears that the > is used if there is a guid for the compoenent + * and the < is used if not. + */ + static WCHAR fmt1[] = {'%','s','%','s','<',0,0}; + static WCHAR fmt2[] = {'%','s','%','s','>','%','s',0,0}; + LPWSTR output = NULL; + DWORD sz = 0; + INT component_index; + + component = load_dynamic_stringW(rec,3); + component_index = get_loaded_component(package,component); + + if (!ACTION_VerifyComponentForAction(package, component_index, + INSTALLSTATE_LOCAL) && + !ACTION_VerifyComponentForAction(package, component_index, + INSTALLSTATE_SOURCE) && + !ACTION_VerifyComponentForAction(package, component_index, + INSTALLSTATE_ADVERTISED)) + { + TRACE("Skipping: Component %s not scheduled for install\n", + debugstr_w(component)); + HeapFree(GetProcessHeap(),0,component); + return ERROR_SUCCESS; + } + + memset(productid_85,0,sizeof(productid_85)); + memset(component_85,0,sizeof(component_85)); + compgroupid = load_dynamic_stringW(rec,1); + + rc = MSIREG_OpenUserComponentsKey(compgroupid, &hkey, TRUE); + if (rc != ERROR_SUCCESS) + goto end; + + productid = load_dynamic_property(package,szProductCode,NULL); + CLSIDFromString(productid, &clsid); + + encode_base85_guid(&clsid,productid_85); + + text = load_dynamic_stringW(rec,4); + qualifier = load_dynamic_stringW(rec,2); + + feature = load_dynamic_stringW(rec,5); + + index = get_loaded_component(package, component); + CLSIDFromString(package->components[index].ComponentId, &clsid); + encode_base85_guid(&clsid,component_85); + + TRACE("Doing something with this... %s = %s %s %s %s\n", + debugstr_w(qualifier), debugstr_w(productid_85), + debugstr_w(feature), debugstr_w(text), debugstr_w(component_85)); + + sz = lstrlenW(productid_85) + lstrlenW(feature); + if (text) + sz += lstrlenW(text); + if (component && index >= 0) + sz += lstrlenW(component_85); + + sz+=3; + sz *= sizeof(WCHAR); + + output = HeapAlloc(GetProcessHeap(),0,sz); + memset(output,0,sz); + + if (component && index >= 0) + sprintfW(output,fmt2,productid_85,feature,component_85); + else + sprintfW(output,fmt1,productid_85,feature); + + if (text) + strcatW(output,text); + + sz = (lstrlenW(output)+2) * sizeof(WCHAR); + RegSetValueExW(hkey, qualifier,0,REG_MULTI_SZ, (LPBYTE)output, sz); + +end: + RegCloseKey(hkey); + HeapFree(GetProcessHeap(),0,output); + HeapFree(GetProcessHeap(),0,compgroupid); + HeapFree(GetProcessHeap(),0,component); + HeapFree(GetProcessHeap(),0,productid); + HeapFree(GetProcessHeap(),0,feature); + HeapFree(GetProcessHeap(),0,text); + HeapFree(GetProcessHeap(),0,qualifier); + + return rc; +} + +/* + * At present I am ignorning the advertised components part of this and only + * focusing on the qualified component sets + */ +static UINT ACTION_PublishComponents(MSIPACKAGE *package) +{ + UINT rc; + MSIQUERY * view; + static const WCHAR ExecSeqQuery[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','P','u','b','l','i','s','h', + 'C','o','m','p','o','n','e','n','t','`',0}; + + rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view); + if (rc != ERROR_SUCCESS) + return ERROR_SUCCESS; + + rc = MSI_IterateRecords(view, NULL, ITERATE_PublishComponent, package); + msiobj_release(&view->hdr); + return rc; } /* Msi functions that seem appropriate here */ + +/*********************************************************************** + * MsiDoActionA (MSI.@) + */ UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction ) { LPWSTR szwAction; @@ -6316,6 +6675,9 @@ return rc; } +/*********************************************************************** + * MsiDoActionW (MSI.@) + */ UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction ) { MSIPACKAGE *package; @@ -6461,6 +6823,9 @@ } +/*********************************************************************** + * MsiSetTargetPathA (MSI.@) + */ UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder, LPCSTR szFolderPath) { @@ -6519,7 +6884,7 @@ HeapFree(GetProcessHeap(),0,folder->Property); folder->Property = build_directory_name(2, szFolderPath, NULL); - if (strcmpiW(path, folder->Property) == 0) + if (lstrcmpiW(path, folder->Property) == 0) { /* * Resolved Target has not really changed, so just @@ -6550,6 +6915,9 @@ return ERROR_SUCCESS; } +/*********************************************************************** + * MsiSetTargetPathW (MSI.@) + */ UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, LPCWSTR szFolderPath) { @@ -6604,7 +6972,9 @@ return TRUE; } -/* +/*********************************************************************** + * MsiSetFeatureStateA (MSI.@) + * * According to the docs, when this is called it immediately recalculates * all the component states as well */ @@ -6626,11 +6996,42 @@ return rc; } + + +UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature, + INSTALLSTATE iState) +{ + INT index, i; + UINT rc = ERROR_SUCCESS; + + TRACE(" %s to %i\n",debugstr_w(szFeature), iState); + + index = get_loaded_feature(package,szFeature); + if (index < 0) + return ERROR_UNKNOWN_FEATURE; + + package->features[index].ActionRequest= iState; + package->features[index].Action= iState; + + ACTION_UpdateComponentStates(package,szFeature); + + /* update all the features that are children of this feature */ + for (i = 0; i < package->loaded_features; i++) + { + if (strcmpW(szFeature, package->features[i].Feature_Parent) == 0) + MSI_SetFeatureStateW(package, package->features[i].Feature, iState); + } + + return rc; +} + +/*********************************************************************** + * MsiSetFeatureStateW (MSI.@) + */ UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, INSTALLSTATE iState) { MSIPACKAGE* package; - INT index; UINT rc = ERROR_SUCCESS; TRACE(" %s to %i\n",debugstr_w(szFeature), iState); @@ -6639,17 +7040,8 @@ if (!package) return ERROR_INVALID_HANDLE; - index = get_loaded_feature(package,szFeature); - if (index < 0) - { - rc = ERROR_UNKNOWN_FEATURE; - goto end; - } - - package->features[index].ActionRequest= iState; - ACTION_UpdateComponentStates(package,szFeature); + rc = MSI_SetFeatureStateW(package,szFeature,iState); -end: msiobj_release( &package->hdr ); return rc; } @@ -6706,6 +7098,9 @@ return ret; } +/*********************************************************************** + * MsiGetComponentStateA (MSI.@) + */ UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szComponent, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) { @@ -6745,6 +7140,9 @@ return ERROR_SUCCESS; } +/*********************************************************************** + * MsiGetComponentStateW (MSI.@) + */ UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szComponent, INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) { diff -urN wine-20050419/dlls/msi/action.h wine-20050524/dlls/msi/action.h --- wine-20050419/dlls/msi/action.h 2005-03-16 12:31:35.000000000 +0100 +++ wine-20050524/dlls/msi/action.h 2005-05-18 15:23:52.000000000 +0200 @@ -82,6 +82,7 @@ LPWSTR File; INT ComponentIndex; LPWSTR FileName; + LPWSTR ShortName; INT FileSize; LPWSTR Version; LPWSTR Language; diff -urN wine-20050419/dlls/msi/appsearch.c wine-20050524/dlls/msi/appsearch.c --- wine-20050419/dlls/msi/appsearch.c 2005-03-28 16:17:52.000000000 +0200 +++ wine-20050524/dlls/msi/appsearch.c 2005-05-10 10:27:00.000000000 +0200 @@ -23,8 +23,10 @@ #include "windef.h" #include "winbase.h" +#include "winreg.h" #include "msi.h" #include "msiquery.h" +#include "msidefs.h" #include "winver.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -243,6 +245,9 @@ 'R','e','g','L','o','c','a','t','o','r',' ', 'w','h','e','r','e',' ','S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0}; + static const WCHAR dwordFmt[] = { '#','%','d','\0' }; + static const WCHAR expandSzFmt[] = { '#','%','%','%','s','\0' }; + static const WCHAR binFmt[] = { '#','x','%','x','\0' }; TRACE("(package %p, appFound %p, sig %p)\n", package, appFound, sig); *appFound = FALSE; @@ -250,7 +255,11 @@ if (rc == ERROR_SUCCESS) { MSIRECORD *row = 0; - LPWSTR keyPath; + LPWSTR keyPath = NULL, valueName = NULL, propertyValue = NULL; + int root, type; + HKEY rootKey, key = NULL; + DWORD sz = 0, regType, i; + LPBYTE value = NULL; rc = MSI_ViewExecute(view, 0); if (rc != ERROR_SUCCESS) @@ -266,13 +275,121 @@ goto end; } - /* get key path */ + root = MSI_RecordGetInteger(row,2); keyPath = load_dynamic_stringW(row,3); - FIXME("AppSearch unimplemented for RegLocator (key path %s)\n", - debugstr_w(keyPath)); - HeapFree(GetProcessHeap(), 0, keyPath); + /* FIXME: keyPath needs to be expanded for properties */ + valueName = load_dynamic_stringW(row,4); + /* FIXME: valueName probably does too */ + type = MSI_RecordGetInteger(row,5); + + if ((type & 0x0f) != msidbLocatorTypeRawValue) + { + FIXME("AppSearch unimplemented for type %d (key path %s, value %s)\n", + type, debugstr_w(keyPath), debugstr_w(valueName)); + goto end; + } + + switch (root) + { + case msidbRegistryRootClassesRoot: + rootKey = HKEY_CLASSES_ROOT; + break; + case msidbRegistryRootCurrentUser: + rootKey = HKEY_CURRENT_USER; + break; + case msidbRegistryRootLocalMachine: + rootKey = HKEY_LOCAL_MACHINE; + break; + case msidbRegistryRootUsers: + rootKey = HKEY_USERS; + break; + default: + WARN("Unknown root key %d\n", root); + goto end; + } + + rc = RegCreateKeyW(rootKey, keyPath, &key); + if (rc) + { + TRACE("RegCreateKeyW returned %d\n", rc); + rc = ERROR_SUCCESS; + goto end; + } + rc = RegQueryValueExW(key, valueName, NULL, NULL, NULL, &sz); + if (rc) + { + TRACE("RegQueryValueExW returned %d\n", rc); + rc = ERROR_SUCCESS; + goto end; + } + /* FIXME: sanity-check sz before allocating (is there an upper-limit + * on the value of a property?) + */ + value = HeapAlloc(GetProcessHeap(), 0, sz); + rc = RegQueryValueExW(key, valueName, NULL, ®Type, value, &sz); + if (rc) + { + TRACE("RegQueryValueExW returned %d\n", rc); + rc = ERROR_SUCCESS; + goto end; + } + + switch (regType) + { + case REG_SZ: + if (*(LPWSTR)value == '#') + { + /* escape leading pound with another */ + propertyValue = HeapAlloc(GetProcessHeap(), 0, + sz + sizeof(WCHAR)); + propertyValue[0] = '#'; + strcpyW(propertyValue + 1, (LPWSTR)value); + } + else + { + propertyValue = HeapAlloc(GetProcessHeap(), 0, sz); + strcpyW(propertyValue, (LPWSTR)value); + } + break; + case REG_DWORD: + /* 7 chars for digits, 1 for NULL, 1 for #, and 1 for sign + * char if needed + */ + propertyValue = HeapAlloc(GetProcessHeap(), 0, + 10 * sizeof(WCHAR)); + sprintfW(propertyValue, dwordFmt, *(DWORD *)value); + break; + case REG_EXPAND_SZ: + /* space for extra #% characters in front */ + propertyValue = HeapAlloc(GetProcessHeap(), 0, + sz + 2 * sizeof(WCHAR)); + sprintfW(propertyValue, expandSzFmt, (LPWSTR)value); + break; + case REG_BINARY: + /* 3 == length of "#x" */ + propertyValue = HeapAlloc(GetProcessHeap(), 0, + (sz * 3 + 1) * sizeof(WCHAR)); + for (i = 0; i < sz; i++) + sprintfW(propertyValue + i * 3, binFmt, value[i]); + break; + default: + WARN("unimplemented for values of type %ld\n", regType); + goto end; + } + + TRACE("found registry value, setting %s to %s\n", + debugstr_w(sig->Property), debugstr_w(propertyValue)); + rc = MSI_SetPropertyW(package, sig->Property, propertyValue); + *appFound = TRUE; end: + HeapFree(GetProcessHeap(), 0, propertyValue); + HeapFree(GetProcessHeap(), 0, value); + RegCloseKey(key); + + HeapFree(GetProcessHeap(), 0, keyPath); + HeapFree(GetProcessHeap(), 0, valueName); + msiobj_release(&row->hdr); MSI_ViewClose(view); msiobj_release(&view->hdr); diff -urN wine-20050419/dlls/msi/cond.y wine-20050524/dlls/msi/cond.y --- wine-20050419/dlls/msi/cond.y 2005-04-18 12:30:56.000000000 +0200 +++ wine-20050524/dlls/msi/cond.y 2005-05-18 19:46:38.000000000 +0200 @@ -181,7 +181,7 @@ } | value_s { - $$ = $1[0] ? MSICONDITION_TRUE : MSICONDITION_FALSE; + $$ = ($1 && $1[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE; } | value_i comp_op_i value_i { @@ -739,7 +739,9 @@ TRACE("Evaluating %s\n",debugstr_w(szCondition)); - if( szCondition && !COND_parse( &cond ) ) + if ( szCondition == NULL || szCondition[0] == 0) + r = MSICONDITION_NONE; + else if ( !COND_parse( &cond ) ) r = cond.result; else r = MSICONDITION_ERROR; diff -urN wine-20050419/dlls/msi/create.c wine-20050524/dlls/msi/create.c --- wine-20050419/dlls/msi/create.c 2005-02-08 14:44:25.000000000 +0100 +++ wine-20050524/dlls/msi/create.c 2005-05-23 14:08:17.000000000 +0200 @@ -201,20 +201,10 @@ static UINT CREATE_delete( struct tagMSIVIEW *view ) { MSICREATEVIEW *cv = (MSICREATEVIEW*)view; - create_col_info *col; TRACE("%p\n", cv ); - col = cv->col_info; - while( col ) - { - create_col_info *t = col; - col = col->next; - HeapFree( GetProcessHeap(), 0, t->colname ); - HeapFree( GetProcessHeap(), 0, t ); - } msiobj_release( &cv->db->hdr ); - HeapFree( GetProcessHeap(), 0, cv->name ); HeapFree( GetProcessHeap(), 0, cv ); return ERROR_SUCCESS; @@ -250,7 +240,7 @@ cv->view.ops = &create_ops; msiobj_addref( &db->hdr ); cv->db = db; - cv->name = table; /* FIXME: strdupW it? */ + cv->name = table; cv->col_info = col_info; cv->bIsTemp = temp; *view = (MSIVIEW*) cv; diff -urN wine-20050419/dlls/msi/custom.c wine-20050524/dlls/msi/custom.c --- wine-20050419/dlls/msi/custom.c 2005-04-11 18:10:33.000000000 +0200 +++ wine-20050524/dlls/msi/custom.c 2005-05-20 11:40:02.000000000 +0200 @@ -80,9 +80,10 @@ MSIQUERY * view; MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = - {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','C','u','s','t','o' - ,'m','A','c','t','i','o','n',' ','w','h','e','r','e',' ','`','A','c','t','i' - ,'o','n','`',' ','=',' ','`','%','s','`',0}; + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','C','u','s','t','o' ,'m','A','c','t','i','o','n','`', + ' ','W','H','E','R','E',' ','`','A','c','t','i' ,'o','n','`',' ', + '=',' ','\'','%','s','\'',0}; UINT type; LPWSTR source; LPWSTR target; @@ -251,8 +252,9 @@ MSIQUERY * view; MSIRECORD * row = 0; static const WCHAR fmt[] = - {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','B','i' -,'n','a','r','y',' ','w','h','e','r','e',' ','N','a','m','e','=','`','%','s','`',0}; + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E', + ' ','`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0}; HANDLE the_file; CHAR buffer[1024]; @@ -333,7 +335,7 @@ static UINT process_action_return_value(UINT type, HANDLE ThreadHandle) { - DWORD rc; + DWORD rc=0; if (type == 2) { @@ -357,7 +359,8 @@ case ERROR_NO_MORE_ITEMS: return ERROR_SUCCESS; default: - return ERROR_FUNCTION_FAILED; + ERR("Invalid Return Code %lx\n",rc); + return ERROR_INSTALL_FAILURE; } } @@ -372,9 +375,9 @@ /* synchronous */ TRACE("Synchronous Execution of action %s\n",debugstr_w(Name)); if (ProcessHandle) - msi_dialog_check_messages(package->dialog, ProcessHandle); + msi_dialog_check_messages(ProcessHandle); else - msi_dialog_check_messages(package->dialog, ThreadHandle); + msi_dialog_check_messages(ThreadHandle); if (!(type & 0x40)) { @@ -479,7 +482,7 @@ stuff = (thread_struct*)info; rc = ACTION_CallDllFunction(stuff); - TRACE("MSI Thread (0x%lx) finished\n",GetCurrentThreadId()); + TRACE("MSI Thread (0x%lx) finished (rc %li)\n",GetCurrentThreadId(), rc); /* clse all handles for this thread */ MsiCloseAllHandles(); return rc; @@ -630,7 +633,8 @@ static const WCHAR query[] = { 'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ', 'F','R','O','M',' ','`','E','r','r','o','r','`',' ', - 'W','H','E','R','E',' ','`','E','r','r','o','r','`',' ','=',' ','%','s',0 + 'W','H','E','R','E',' ','`','E','r','r','o','r','`',' ','=',' ', + '\'','%','s','\'',0 }; MSIQUERY *view = NULL; MSIRECORD *row = 0; @@ -685,7 +689,7 @@ prop = load_dynamic_property(package,source,&prc); if (!prop) - return prc; + return ERROR_SUCCESS; deformat_string(package,target,&deformated); len = strlenW(prop) + 2; @@ -782,8 +786,7 @@ { TRACE("Waiting on action %s\n", debugstr_w(package->RunningAction[i].name)); - msi_dialog_check_messages(package->dialog, - package->RunningAction[i].handle); + msi_dialog_check_messages(package->RunningAction[i].handle); } HeapFree(GetProcessHeap(),0,package->RunningAction[i].name); diff -urN wine-20050419/dlls/msi/database.c wine-20050524/dlls/msi/database.c --- wine-20050419/dlls/msi/database.c 2005-03-29 13:28:57.000000000 +0200 +++ wine-20050524/dlls/msi/database.c 2005-05-10 18:00:19.000000000 +0200 @@ -65,6 +65,7 @@ DWORD r; free_cached_tables( db ); + msi_destroy_stringtable( db->strings ); r = IStorage_Release( db->storage ); if( r ) ERR("database reference count was not zero (%ld)\n", r); @@ -213,7 +214,8 @@ r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB ); end: - HeapFree( GetProcessHeap(), 0, szwPersist ); + if( HIWORD(szPersist) ) + HeapFree( GetProcessHeap(), 0, szwPersist ); HeapFree( GetProcessHeap(), 0, szwDBPath ); return r; @@ -334,7 +336,7 @@ goto end; } - r = MsiDatabaseImportW( handle, path, file ); + r = MsiDatabaseExportW( handle, table, path, file ); end: HeapFree( GetProcessHeap(), 0, table ); diff -urN wine-20050419/dlls/msi/dialog.c wine-20050524/dlls/msi/dialog.c --- wine-20050419/dlls/msi/dialog.c 2005-04-11 14:47:20.000000000 +0200 +++ wine-20050524/dlls/msi/dialog.c 2005-05-09 21:33:50.000000000 +0200 @@ -44,6 +44,9 @@ const WCHAR szMsiDialogClass[] = { 'M','s','i','D','i','a','l','o','g','C','l','o','s','e','C','l','a','s','s',0 }; +const WCHAR szMsiHiddenWindow[] = { + 'M','s','i','H','i','d','d','e','n','W','i','n','d','o','w',0 +}; const static WCHAR szStatic[] = { 'S','t','a','t','i','c',0 }; const static WCHAR szButton[] = { 'B','U','T','T','O','N', 0 }; @@ -106,6 +109,14 @@ static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +/* dialog sequencing */ + +#define WM_MSI_DIALOG_CREATE (WM_USER+0x100) +#define WM_MSI_DIALOG_DESTROY (WM_USER+0x101) + +static DWORD uiThreadId; +static HWND hMsiHiddenWindow; + INT msi_dialog_scale_unit( msi_dialog *dialog, INT val ) { return (dialog->scale * val + 5) / 10; @@ -725,41 +736,51 @@ return height; } -static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs ) +/* fetch the associated record from the Dialog table */ +static MSIRECORD *msi_get_dialog_record( msi_dialog *dialog ) { static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ','D','i','a','l','o','g',' ', 'W','H','E','R','E',' ', '`','D','i','a','l','o','g','`',' ','=',' ','\'','%','s','\'',0}; - static const WCHAR df[] = { - 'D','e','f','a','u','l','t','U','I','F','o','n','t',0 }; - msi_dialog *dialog = (msi_dialog*) cs->lpCreateParams; MSIPACKAGE *package = dialog->package; MSIQUERY *view = NULL; MSIRECORD *rec = NULL; - DWORD width, height; - LPCWSTR text; - LPWSTR title = NULL; UINT r; - TRACE("%p %p\n", dialog, package); - - dialog->hwnd = hwnd; - SetWindowLongPtrW( hwnd, GWLP_USERDATA, (LONG_PTR) dialog ); + TRACE("%p %s\n", dialog, debugstr_w(dialog->name) ); - /* fetch the associated record from the Dialog table */ r = MSI_OpenQuery( package->db, &view, query, dialog->name ); if( r != ERROR_SUCCESS ) { ERR("query failed for dialog %s\n", debugstr_w(dialog->name)); - return -1; + return NULL; } MSI_ViewExecute( view, NULL ); MSI_ViewFetch( view, &rec ); MSI_ViewClose( view ); msiobj_release( &view->hdr ); + return rec; +} + +static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs ) +{ + static const WCHAR df[] = { + 'D','e','f','a','u','l','t','U','I','F','o','n','t',0 }; + msi_dialog *dialog = (msi_dialog*) cs->lpCreateParams; + MSIRECORD *rec = NULL; + DWORD width, height; + LPCWSTR text; + LPWSTR title = NULL; + + TRACE("%p %p\n", dialog, dialog->package); + + dialog->hwnd = hwnd; + SetWindowLongPtrW( hwnd, GWLP_USERDATA, (LONG_PTR) dialog ); + + rec = msi_get_dialog_record( dialog ); if( !rec ) { TRACE("No record found for dialog %s\n", debugstr_w(dialog->name)); @@ -1004,7 +1025,8 @@ { msi_dialog *dialog = (LPVOID) GetWindowLongPtrW( hwnd, GWLP_USERDATA ); - TRACE(" 0x%04x\n", msg); + TRACE("0x%04x\n", msg); + switch (msg) { case WM_CREATE: @@ -1020,13 +1042,43 @@ return DefWindowProcW(hwnd, msg, wParam, lParam); } +static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC) GetPropW(hWnd, szButtonData); + + TRACE("hWnd %p msg %04x wParam 0x%08x lParam 0x%08lx\n", hWnd, msg, wParam, lParam); + + if (msg == WM_COMMAND) /* Forward notifications to dialog */ + SendMessageW(GetParent(hWnd), msg, wParam, lParam); + + return CallWindowProcW(oldproc, hWnd, msg, wParam, lParam); +} + +static LRESULT WINAPI MSIHiddenWindowProc( HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam ) +{ + msi_dialog *dialog = (msi_dialog*) lParam; + + TRACE("%d %p\n", msg, dialog); + + switch (msg) + { + case WM_MSI_DIALOG_CREATE: + return msi_dialog_run_message_loop( dialog ); + case WM_MSI_DIALOG_DESTROY: + msi_dialog_destroy( dialog ); + return 0; + } + return DefWindowProcW( hwnd, msg, wParam, lParam ); +} + /* functions that interface to other modules within MSI */ msi_dialog *msi_dialog_create( MSIPACKAGE* package, LPCWSTR szDialogName, msi_dialog_event_handler event_handler ) { + MSIRECORD *rec = NULL; msi_dialog *dialog; - HWND hwnd; TRACE("%p %s\n", package, debugstr_w(szDialogName)); @@ -1036,73 +1088,112 @@ if( !dialog ) return NULL; strcpyW( dialog->name, szDialogName ); + msiobj_addref( &package->hdr ); dialog->package = package; dialog->event_handler = event_handler; + dialog->finished = 0; - /* create the dialog window, don't show it yet */ - hwnd = CreateWindowW( szMsiDialogClass, szDialogName, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, NULL, dialog ); - if( !hwnd ) + /* verify that the dialog exists */ + rec = msi_get_dialog_record( dialog ); + if( !rec ) { - ERR("Failed to create dialog %s\n", debugstr_w( szDialogName )); - msi_dialog_destroy( dialog ); + HeapFree( GetProcessHeap(), 0, dialog ); return NULL; } + dialog->attributes = MSI_RecordGetInteger( rec, 6 ); + msiobj_release( &rec->hdr ); return dialog; } +static void msi_process_pending_messages(void) +{ + MSG msg; + + while( PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &msg ); + DispatchMessageW( &msg ); + } +} + void msi_dialog_end_dialog( msi_dialog *dialog ) { + TRACE("%p\n", dialog); dialog->finished = 1; + PostMessageW(dialog->hwnd, WM_NULL, 0, 0); } -UINT msi_dialog_run_message_loop( msi_dialog *dialog ) +void msi_dialog_check_messages( HANDLE handle ) { - MSG msg; + DWORD r; - if( dialog->attributes & msidbDialogAttributesVisible ) + /* in threads other than the UI thread, block */ + if( uiThreadId != GetCurrentThreadId() ) { - ShowWindow( dialog->hwnd, SW_SHOW ); - UpdateWindow( dialog->hwnd ); + if( handle ) + WaitForSingleObject( handle, INFINITE ); + return; } - if( dialog->attributes & msidbDialogAttributesModal ) + /* there's two choices for the UI thread */ + while (1) { - while( !dialog->finished && GetMessageW( &msg, 0, 0, 0 ) ) - { - TranslateMessage( &msg ); - DispatchMessageW( &msg ); - } - } - else - return ERROR_IO_PENDING; + msi_process_pending_messages(); - return ERROR_SUCCESS; + if( !handle ) + break; + + /* + * block here until somebody creates a new dialog or + * the handle we're waiting on becomes ready + */ + r = MsgWaitForMultipleObjects( 1, &handle, 0, INFINITE, QS_ALLINPUT ); + if( r == WAIT_OBJECT_0 ) + break; + } } -void msi_dialog_check_messages( msi_dialog *dialog, HANDLE handle ) +UINT msi_dialog_run_message_loop( msi_dialog *dialog ) { - MSG msg; - DWORD r; + HWND hwnd; + + if( !(dialog->attributes & msidbDialogAttributesVisible) ) + return ERROR_SUCCESS; + + if( uiThreadId != GetCurrentThreadId() ) + return SendMessageW( hMsiHiddenWindow, WM_MSI_DIALOG_CREATE, 0, (LPARAM) dialog ); + + /* create the dialog window, don't show it yet */ + hwnd = CreateWindowW( szMsiDialogClass, dialog->name, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, NULL, dialog ); + if( !hwnd ) + { + ERR("Failed to create dialog %s\n", debugstr_w( dialog->name )); + return ERROR_FUNCTION_FAILED; + } - do + ShowWindow( hwnd, SW_SHOW ); + UpdateWindow( hwnd ); + + if( dialog->attributes & msidbDialogAttributesModal ) { - while( PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ) ) + while( !dialog->finished ) { - TranslateMessage( &msg ); - DispatchMessageW( &msg ); + MsgWaitForMultipleObjects( 0, NULL, 0, INFINITE, QS_ALLEVENTS ); + msi_process_pending_messages(); } - if( !handle ) - break; - r = MsgWaitForMultipleObjects( 1, &handle, 0, INFINITE, QS_ALLEVENTS ); } - while( WAIT_OBJECT_0 != r ); + else + return ERROR_IO_PENDING; + + return ERROR_SUCCESS; } void msi_dialog_do_preview( msi_dialog *dialog ) { + TRACE("\n"); dialog->attributes |= msidbDialogAttributesVisible; dialog->attributes &= ~msidbDialogAttributesModal; msi_dialog_run_message_loop( dialog ); @@ -1110,6 +1201,12 @@ void msi_dialog_destroy( msi_dialog *dialog ) { + if( uiThreadId != GetCurrentThreadId() ) + { + SendMessageW( hMsiHiddenWindow, WM_MSI_DIALOG_DESTROY, 0, (LPARAM) dialog ); + return; + } + if( dialog->hwnd ) ShowWindow( dialog->hwnd, SW_HIDE ); @@ -1138,11 +1235,12 @@ if( dialog->hwnd ) DestroyWindow( dialog->hwnd ); + msiobj_release( &dialog->package->hdr ); dialog->package = NULL; HeapFree( GetProcessHeap(), 0, dialog ); } -void msi_dialog_register_class( void ) +BOOL msi_dialog_register_class( void ) { WNDCLASSW cls; @@ -1155,22 +1253,28 @@ cls.lpszMenuName = NULL; cls.lpszClassName = szMsiDialogClass; - RegisterClassW( &cls ); -} + if( !RegisterClassW( &cls ) ) + return FALSE; -void msi_dialog_unregister_class( void ) -{ - UnregisterClassW( szMsiDialogClass, NULL ); -} + cls.lpfnWndProc = MSIHiddenWindowProc; + cls.lpszClassName = szMsiHiddenWindow; -static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldproc = (WNDPROC) GetPropW(hWnd, szButtonData); + if( !RegisterClassW( &cls ) ) + return FALSE; - TRACE("hWnd %p msg %04x wParam 0x%08x lParam 0x%08lx\n", hWnd, msg, wParam, lParam); + uiThreadId = GetCurrentThreadId(); - if (msg == WM_COMMAND) /* Forward notifications to dialog */ - SendMessageW(GetParent(hWnd), msg, wParam, lParam); + hMsiHiddenWindow = CreateWindowW( szMsiHiddenWindow, NULL, WS_OVERLAPPED, + 0, 0, 100, 100, NULL, NULL, NULL, NULL ); + if( !hMsiHiddenWindow ) + return FALSE; - return CallWindowProcW(oldproc, hWnd, msg, wParam, lParam); + return TRUE; +} + +void msi_dialog_unregister_class( void ) +{ + DestroyWindow( hMsiHiddenWindow ); + UnregisterClassW( szMsiDialogClass, NULL ); + uiThreadId = 0; } diff -urN wine-20050419/dlls/msi/insert.c wine-20050524/dlls/msi/insert.c --- wine-20050419/dlls/msi/insert.c 2005-02-08 14:44:25.000000000 +0100 +++ wine-20050524/dlls/msi/insert.c 2005-05-23 14:08:17.000000000 +0200 @@ -233,7 +233,6 @@ sv = iv->sv; if( sv ) sv->ops->delete( sv ); - delete_value_list( iv->vals ); msiobj_release( &iv->db->hdr ); HeapFree( GetProcessHeap(), 0, iv ); diff -urN wine-20050419/dlls/msi/msi.c wine-20050524/dlls/msi/msi.c --- wine-20050419/dlls/msi/msi.c 2005-03-29 13:28:57.000000000 +0200 +++ wine-20050524/dlls/msi/msi.c 2005-05-23 18:23:54.000000000 +0200 @@ -35,6 +35,8 @@ #include "wincrypt.h" #include "winver.h" #include "winuser.h" +#include "wine/unicode.h" +#include "action.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -56,6 +58,8 @@ WCHAR gszLogFile[MAX_PATH]; HINSTANCE msi_hInstance; +static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0}; + UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct) { UINT r; @@ -249,7 +253,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState, LPCWSTR szCommandLine) { - MSIHANDLE handle; + MSIHANDLE handle = -1; MSIPACKAGE* package; UINT rc; HKEY hkey=0,hkey1=0; @@ -327,6 +331,8 @@ HeapFree(GetProcessHeap(),0,commandline); end: RegCloseKey(hkey); + if (handle != -1) + MsiCloseHandle(handle); return rc; } @@ -417,11 +423,38 @@ UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer) { - FIXME("%s %p\n",debugstr_w(szComponent), szBuffer); + UINT rc; + HKEY hkey; + WCHAR szSquished[GUID_SIZE]; + DWORD sz = GUID_SIZE; + static const WCHAR szPermKey[] = + { '0','0','0','0','0','0','0','0','0','0','0','0', + '0','0','0','0','0','0','0', '0','0','0','0','0', + '0','0','0','0','0','0','0','0',0}; + + TRACE("%s %p\n",debugstr_w(szComponent), szBuffer); if (NULL == szComponent) return ERROR_INVALID_PARAMETER; - return ERROR_CALL_NOT_IMPLEMENTED; + + rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE); + if (rc != ERROR_SUCCESS) + return ERROR_UNKNOWN_COMPONENT; + + rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL); + if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0) + { + sz = GUID_SIZE; + rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL); + } + + RegCloseKey(hkey); + + if (rc != ERROR_SUCCESS) + return ERROR_INSTALL_FAILURE; + + unsquash_guid(szSquished, szBuffer); + return ERROR_SUCCESS; } UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, @@ -472,6 +505,14 @@ { MSIHANDLE hProduct; UINT r; + static const WCHAR szPackageCode[] = + {'P','a','c','k','a','g','e','C','o','d','e',0}; + static const WCHAR szVersionString[] = + {'V','e','r','s','i','o','n','S','t','r','i','n','g',0}; + static const WCHAR szProductVersion[] = + {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0}; + static const WCHAR szAssignmentType[] = + {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0}; FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute), szBuffer, pcchValueBuf); @@ -480,13 +521,66 @@ return ERROR_INVALID_PARAMETER; if (NULL == szProduct || NULL == szAttribute) return ERROR_INVALID_PARAMETER; + + /* check for special properties */ + if (strcmpW(szAttribute, szPackageCode)==0) + { + HKEY hkey; + WCHAR squished[GUID_SIZE]; + WCHAR package[200]; + DWORD sz = sizeof(squished); + + r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE); + if (r != ERROR_SUCCESS) + return ERROR_UNKNOWN_PRODUCT; + + r = RegQueryValueExW(hkey, szPackageCode, NULL, NULL, + (LPBYTE)squished, &sz); + if (r != ERROR_SUCCESS) + { + RegCloseKey(hkey); + return ERROR_UNKNOWN_PRODUCT; + } - r = MsiOpenProductW(szProduct, &hProduct); - if (ERROR_SUCCESS != r) - return r; + unsquash_guid(squished, package); + *pcchValueBuf = strlenW(package); + if (strlenW(package) > *pcchValueBuf) + { + RegCloseKey(hkey); + return ERROR_MORE_DATA; + } + else + strcpyW(szBuffer, package); + + RegCloseKey(hkey); + r = ERROR_SUCCESS; + } + else if (strcmpW(szAttribute, szVersionString)==0) + { + r = MsiOpenProductW(szProduct, &hProduct); + if (ERROR_SUCCESS != r) + return r; + + r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf); + MsiCloseHandle(hProduct); + } + else if (strcmpW(szAttribute, szAssignmentType)==0) + { + FIXME("0 (zero) if advertised, 1(one) if per machine.\n"); + if (szBuffer) + szBuffer[0] = 1; + r = ERROR_SUCCESS; + } + else + { + r = MsiOpenProductW(szProduct, &hProduct); + if (ERROR_SUCCESS != r) + return r; + + r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf); + MsiCloseHandle(hProduct); + } - r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf); - MsiCloseHandle(hProduct); return r; } @@ -967,6 +1061,9 @@ return rrc; } +/****************************************************************** + * MsiQueryFeatureStateA [MSI.@] + */ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature) { INSTALLSTATE rc; @@ -998,15 +1095,37 @@ return rc; } +/****************************************************************** + * MsiQueryFeatureStateW [MSI.@] + * + * This does not verify that the Feature is functional. So i am only going to + * check the existence of the key in the registry. This should tell me if it is + * installed. + */ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) { - FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature)); - /* - * Iterates all the features components and the features parents components - */ - return INSTALLSTATE_LOCAL; + UINT rc; + DWORD sz = 0; + HKEY hkey; + + TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature)); + + rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE); + if (rc != ERROR_SUCCESS) + return INSTALLSTATE_UNKNOWN; + + rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz); + RegCloseKey(hkey); + + if (rc == ERROR_SUCCESS) + return INSTALLSTATE_LOCAL; + else + return INSTALLSTATE_ABSENT; } +/****************************************************************** + * MsiGetFileVersionA [MSI.@] + */ UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf, DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf) { @@ -1052,6 +1171,9 @@ return ret; } +/****************************************************************** + * MsiGetFileVersionW [MSI.@] + */ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf) { @@ -1192,7 +1314,7 @@ static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl }; /****************************************************************** - * DllGetClassObject [MSI.@] + * DllGetClassObject [MSI.@] */ HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { @@ -1211,7 +1333,7 @@ } /****************************************************************** - * DllGetVersion [MSI.@] + * DllGetVersion [MSI.@] */ HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi) { @@ -1229,7 +1351,7 @@ } /****************************************************************** - * DllCanUnloadNow [MSI.@] + * DllCanUnloadNow [MSI.@] */ BOOL WINAPI MSI_DllCanUnloadNow(void) { @@ -1269,6 +1391,9 @@ return INSTALLSTATE_LOCAL; } +/*********************************************************************** + * MsiUseFeatureExA [MSI.@] + */ INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature, DWORD dwInstallMode, DWORD dwReserved) { @@ -1297,22 +1422,191 @@ DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf, DWORD* pcchPathBuf) { - FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent), + HKEY hkey; + UINT rc; + LPWSTR info; + DWORD sz; + LPWSTR product = NULL; + LPWSTR component = NULL; + LPWSTR ptr; + GUID clsid; + + TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent), debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct), Unused1, Unused2, lpPathBuf, pcchPathBuf); + + rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE); + if (rc != ERROR_SUCCESS) + return ERROR_INDEX_ABSENT; + + sz = 0; + rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz); + if (sz <= 0) + { + RegCloseKey(hkey); + return ERROR_INDEX_ABSENT; + } + + info = HeapAlloc(GetProcessHeap(),0,sz); + rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz); + if (rc != ERROR_SUCCESS) + { + RegCloseKey(hkey); + HeapFree(GetProcessHeap(),0,info); + return ERROR_INDEX_ABSENT; + } + + /* find the component */ + ptr = strchrW(&info[20],'>'); + if (ptr) + ptr++; + else + { + RegCloseKey(hkey); + HeapFree(GetProcessHeap(),0,info); + return ERROR_INDEX_ABSENT; + } + + if (!szProduct) + { + decode_base85_guid(info,&clsid); + StringFromCLSID(&clsid, &product); + } + decode_base85_guid(ptr,&clsid); + StringFromCLSID(&clsid, &component); + + if (!szProduct) + rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf); + else + rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf); + + RegCloseKey(hkey); + HeapFree(GetProcessHeap(),0,info); + HeapFree(GetProcessHeap(),0,product); + HeapFree(GetProcessHeap(),0,component); + + if (rc == INSTALLSTATE_LOCAL) + return ERROR_SUCCESS; + else + return ERROR_FILE_NOT_FOUND; +} - return ERROR_INDEX_ABSENT; +/*********************************************************************** + * MsiProvideQualifiedComponentW [MSI.@] + */ +UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent, + LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf, + DWORD* pcchPathBuf) +{ + return MsiProvideQualifiedComponentExW(szComponent, szQualifier, + dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf); +} + +/*********************************************************************** + * MsiProvideQualifiedComponentA [MSI.@] + */ +UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent, + LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf, + DWORD* pcchPathBuf) +{ + LPWSTR szwComponent, szwQualifier, lpwPathBuf; + DWORD pcchwPathBuf; + UINT rc; + + TRACE("%s %s %li %p %p\n",szComponent, szQualifier, + dwInstallMode, lpPathBuf, pcchPathBuf); + + szwComponent= strdupAtoW( szComponent); + szwQualifier= strdupAtoW( szQualifier); + + lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR)); + + pcchwPathBuf = *pcchPathBuf; + + rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier, + dwInstallMode, lpwPathBuf, &pcchwPathBuf); + + HeapFree(GetProcessHeap(),0,szwComponent); + HeapFree(GetProcessHeap(),0,szwQualifier); + *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf, + lpPathBuf, *pcchPathBuf, NULL, NULL); + + HeapFree(GetProcessHeap(),0,lpwPathBuf); + return rc; } USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf, DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf, DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf) { - FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf, + HKEY hkey; + DWORD sz; + UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS; + static const WCHAR szOwner[] = {'R','e','g','O','w','n','e','r',0}; + static const WCHAR szCompany[] = {'R','e','g','C','o','m','p','a','n','y',0}; + static const WCHAR szSerial[] = {'P','r','o','d','u','c','t','I','D',0}; + + TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf, pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf, pcchSerialBuf); - return USERINFOSTATE_UNKNOWN; + rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE); + if (rc != ERROR_SUCCESS) + return USERINFOSTATE_UNKNOWN; + + if (lpUserNameBuf) + { + sz = *lpUserNameBuf * sizeof(WCHAR); + rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, (LPBYTE)lpUserNameBuf, + &sz); + } + if (!lpUserNameBuf && pcchUserNameBuf) + { + sz = 0; + rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, NULL, &sz); + } + + if (pcchUserNameBuf) + *pcchUserNameBuf = sz / sizeof(WCHAR); + + if (lpOrgNameBuf) + { + sz = *pcchOrgNameBuf * sizeof(WCHAR); + rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL, + (LPBYTE)lpOrgNameBuf, &sz); + } + if (!lpOrgNameBuf && pcchOrgNameBuf) + { + sz = 0; + rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL, NULL, &sz); + } + + if (pcchOrgNameBuf) + *pcchOrgNameBuf = sz / sizeof(WCHAR); + + if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA && + rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA) + { + RegCloseKey(hkey); + return USERINFOSTATE_ABSENT; + } + + if (lpSerialBuf) + { + sz = *pcchSerialBuf * sizeof(WCHAR); + RegQueryValueExW( hkey, szSerial, NULL, NULL, (LPBYTE)lpSerialBuf, + &sz); + } + if (!lpSerialBuf && pcchSerialBuf) + { + sz = 0; + rc = RegQueryValueExW( hkey, szSerial, NULL, NULL, NULL, &sz); + } + if (pcchSerialBuf) + *pcchSerialBuf = sz / sizeof(WCHAR); + + RegCloseKey(hkey); + return USERINFOSTATE_PRESENT; } USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf, @@ -1328,20 +1622,68 @@ UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct) { - FIXME("%s\n",debugstr_w(szProduct)); - return ERROR_CALL_NOT_IMPLEMENTED; + MSIHANDLE handle; + UINT rc; + MSIPACKAGE *package; + static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0}; + + TRACE("(%s)\n",debugstr_w(szProduct)); + + rc = MsiOpenProductW(szProduct,&handle); + if (rc != ERROR_SUCCESS) + return ERROR_INVALID_PARAMETER; + + package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE); + rc = ACTION_PerformUIAction(package, szFirstRun); + msiobj_release( &package->hdr ); + + MsiCloseHandle(handle); + + return rc; } UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct) { - FIXME("%s\n",debugstr_a(szProduct)); - return ERROR_CALL_NOT_IMPLEMENTED; + MSIHANDLE handle; + UINT rc; + MSIPACKAGE *package; + static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0}; + + TRACE("(%s)\n",debugstr_a(szProduct)); + + rc = MsiOpenProductA(szProduct,&handle); + if (rc != ERROR_SUCCESS) + return ERROR_INVALID_PARAMETER; + + package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE); + rc = ACTION_PerformUIAction(package, szFirstRun); + msiobj_release( &package->hdr ); + + MsiCloseHandle(handle); + + return rc; } UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved) { - FIXME("%ld\n", dwReserved); - return ERROR_CALL_NOT_IMPLEMENTED; + WCHAR path[MAX_PATH]; + + if(dwReserved) { + FIXME("Don't know how to handle argument %ld\n", dwReserved); + return ERROR_CALL_NOT_IMPLEMENTED; + } + + if(!GetWindowsDirectoryW(path, MAX_PATH)) { + FIXME("GetWindowsDirectory failed unexpected! Error %ld\n", + GetLastError()); + return ERROR_CALL_NOT_IMPLEMENTED; + } + + strcatW(path, installerW); + + CreateDirectoryW(path, NULL); + + return 0; } UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget, diff -urN wine-20050419/dlls/msi/msi.spec wine-20050524/dlls/msi/msi.spec --- wine-20050419/dlls/msi/msi.spec 2005-03-23 11:24:53.000000000 +0100 +++ wine-20050524/dlls/msi/msi.spec 2005-05-20 20:59:20.000000000 +0200 @@ -18,8 +18,8 @@ 18 stdcall MsiDatabaseApplyTransformA(long str long) 19 stdcall MsiDatabaseApplyTransformW(long wstr long) 20 stdcall MsiDatabaseCommit(long) -21 stub MsiDatabaseExportA -22 stub MsiDatabaseExportW +21 stdcall MsiDatabaseExportA(long str str str) +22 stdcall MsiDatabaseExportW(long wstr wstr wstr) 23 stdcall MsiDatabaseGenerateTransformA(long long str long long) 24 stdcall MsiDatabaseGenerateTransformW(long long wstr long long) 25 stdcall MsiDatabaseGetPrimaryKeysA(long str ptr) @@ -78,7 +78,7 @@ 78 stdcall MsiGetSummaryInformationW(long wstr long ptr) 79 stdcall MsiGetTargetPathA(long str ptr ptr) 80 stdcall MsiGetTargetPathW(long wstr ptr ptr) -81 stub MsiGetUserInfoA +81 stdcall MsiGetUserInfoA(str ptr ptr ptr ptr ptr ptr) 82 stdcall MsiGetUserInfoW(wstr ptr ptr ptr ptr ptr ptr) 83 stub MsiInstallMissingComponentA 84 stub MsiInstallMissingComponentW @@ -105,8 +105,8 @@ 105 stdcall MsiProvideComponentFromDescriptorA(str ptr ptr ptr) 106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr) 107 stub MsiProvideComponentW -108 stub MsiProvideQualifiedComponentA -109 stub MsiProvideQualifiedComponentW +108 stdcall MsiProvideQualifiedComponentA(str str long ptr ptr) +109 stdcall MsiProvideQualifiedComponentW(str str long ptr ptr) 110 stdcall MsiQueryFeatureStateA(str str) 111 stdcall MsiQueryFeatureStateW(wstr wstr) 112 stdcall MsiQueryProductStateA(str) diff -urN wine-20050419/dlls/msi/msi_Fr.rc wine-20050524/dlls/msi/msi_Fr.rc --- wine-20050419/dlls/msi/msi_Fr.rc 2005-02-16 22:10:02.000000000 +0100 +++ wine-20050524/dlls/msi/msi_Fr.rc 2005-05-04 11:52:47.000000000 +0200 @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { diff -urN wine-20050419/dlls/msi/msipriv.h wine-20050524/dlls/msi/msipriv.h --- wine-20050419/dlls/msi/msipriv.h 2005-04-11 14:47:20.000000000 +0200 +++ wine-20050524/dlls/msi/msipriv.h 2005-05-23 14:08:17.000000000 +0200 @@ -30,6 +30,7 @@ #include "objbase.h" #include "objidl.h" #include "wine/unicode.h" +#include "wine/list.h" #define MSI_DATASIZEMASK 0x00ff #define MSITYPE_VALID 0x0100 @@ -77,6 +78,7 @@ MSIVIEW *view; UINT row; MSIDATABASE *db; + struct list mem; } MSIQUERY; /* maybe we can use a Variant instead of doing it ourselves? */ @@ -288,7 +290,7 @@ extern UINT msi_string_get_codepage( string_table *st ); -extern UINT VIEW_find_column( MSIVIEW *view, LPWSTR name, UINT *n ); +extern UINT VIEW_find_column( MSIVIEW *view, LPCWSTR name, UINT *n ); extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name ); @@ -342,6 +344,7 @@ extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR ); extern UINT MSI_GetComponentStateW( MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE * ); extern UINT MSI_GetFeatureStateW( MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE * ); +extern UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE*, LPCWSTR, INSTALLSTATE ); /* for deformating */ extern UINT MSI_FormatRecordW(MSIPACKAGE* package, MSIRECORD* record, @@ -357,6 +360,7 @@ extern UINT MSIREG_OpenFeatures(HKEY* key); extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenComponents(HKEY* key); +extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create); extern UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create); extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create); @@ -367,10 +371,10 @@ extern msi_dialog *msi_dialog_create( MSIPACKAGE*, LPCWSTR, msi_dialog_event_handler ); extern UINT msi_dialog_run_message_loop( msi_dialog* ); extern void msi_dialog_end_dialog( msi_dialog* ); -extern void msi_dialog_check_messages( msi_dialog*, HANDLE ); +extern void msi_dialog_check_messages( HANDLE ); extern void msi_dialog_do_preview( msi_dialog* ); extern void msi_dialog_destroy( msi_dialog* ); -extern void msi_dialog_register_class( void ); +extern BOOL msi_dialog_register_class( void ); extern void msi_dialog_unregister_class( void ); /* UI globals */ diff -urN wine-20050419/dlls/msi/msiquery.c wine-20050524/dlls/msi/msiquery.c --- wine-20050419/dlls/msi/msiquery.c 2005-03-24 20:04:06.000000000 +0100 +++ wine-20050524/dlls/msi/msiquery.c 2005-05-23 14:08:17.000000000 +0200 @@ -41,13 +41,19 @@ void MSI_CloseView( MSIOBJECTHDR *arg ) { MSIQUERY *query = (MSIQUERY*) arg; + struct list *ptr, *t; if( query->view && query->view->ops->delete ) query->view->ops->delete( query->view ); msiobj_release( &query->db->hdr ); + + LIST_FOR_EACH_SAFE( ptr, t, &query->mem ) + { + HeapFree( GetProcessHeap(), 0, ptr ); + } } -UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n ) +UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n ) { LPWSTR col_name; UINT i, count, r; @@ -120,8 +126,9 @@ query->row = 0; query->db = db; query->view = NULL; + list_init( &query->mem ); - r = MSI_ParseSQL( db, szQuery, &query->view ); + r = MSI_ParseSQL( db, szQuery, &query->view, &query->mem ); if( r == ERROR_SUCCESS ) { msiobj_addref( &query->hdr ); @@ -141,7 +148,7 @@ /* figure out how much space we need to allocate */ va_start(va, fmt); - sz = strlenW(fmt) + 1; + sz = lstrlenW(fmt) + 1; p = fmt; while (*p) { @@ -152,7 +159,7 @@ switch (*p) { case 's': /* a string */ - sz += strlenW(va_arg(va,LPCWSTR)); + sz += lstrlenW(va_arg(va,LPCWSTR)); break; case 'd': case 'i': /* an integer -2147483648 seems to be longest */ diff -urN wine-20050419/dlls/msi/order.c wine-20050524/dlls/msi/order.c --- wine-20050419/dlls/msi/order.c 2005-02-08 14:44:25.000000000 +0100 +++ wine-20050524/dlls/msi/order.c 2005-05-23 12:27:00.000000000 +0200 @@ -264,40 +264,8 @@ ORDER_delete }; -UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ) +static UINT ORDER_AddColumn( MSIORDERVIEW *ov, LPCWSTR name ) { - MSIORDERVIEW *ov = NULL; - UINT count = 0, r; - - TRACE("%p\n", ov ); - - r = table->ops->get_dimensions( table, NULL, &count ); - if( r != ERROR_SUCCESS ) - { - ERR("can't get table dimensions\n"); - return r; - } - - ov = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof *ov + sizeof (UINT) * count ); - if( !ov ) - return ERROR_FUNCTION_FAILED; - - /* fill the structure */ - ov->view.ops = &order_ops; - msiobj_addref( &db->hdr ); - ov->db = db; - ov->table = table; - ov->reorder = NULL; - ov->num_cols = 0; - *view = (MSIVIEW*) ov; - - return ERROR_SUCCESS; -} - -UINT ORDER_AddColumn( MSIVIEW *view, LPWSTR name ) -{ - MSIORDERVIEW *ov = (MSIORDERVIEW*)view; UINT n, count, r; MSIVIEW *table; @@ -332,3 +300,39 @@ return ERROR_SUCCESS; } + +UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, + string_list *columns ) +{ + MSIORDERVIEW *ov = NULL; + UINT count = 0, r; + string_list *x; + + TRACE("%p\n", ov ); + + r = table->ops->get_dimensions( table, NULL, &count ); + if( r != ERROR_SUCCESS ) + { + ERR("can't get table dimensions\n"); + return r; + } + + ov = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof *ov + sizeof (UINT) * count ); + if( !ov ) + return ERROR_FUNCTION_FAILED; + + /* fill the structure */ + ov->view.ops = &order_ops; + msiobj_addref( &db->hdr ); + ov->db = db; + ov->table = table; + ov->reorder = NULL; + ov->num_cols = 0; + *view = (MSIVIEW*) ov; + + for( x = columns; x ; x = x->next ) + ORDER_AddColumn( ov, x->string ); + + return ERROR_SUCCESS; +} diff -urN wine-20050419/dlls/msi/package.c wine-20050524/dlls/msi/package.c --- wine-20050419/dlls/msi/package.c 2005-03-24 20:04:06.000000000 +0100 +++ wine-20050524/dlls/msi/package.c 2005-05-20 11:40:14.000000000 +0200 @@ -73,7 +73,7 @@ 'Y',' ','K','E','Y',' ','`','_','P','r','o','p','e','r','t','y','`',')',0}; static const WCHAR Query[] = { 'S','E','L','E','C','T',' ','*',' ', - 'f','r','o','m',' ','P','r','o','p','e','r','t','y',0}; + 'F','R','O','M',' ','`','P','r','o','p','e','r','t','y','`',0}; static const WCHAR Insert[] = { 'I','N','S','E','R','T',' ','i','n','t','o',' ', '`','_','P','r','o','p','e','r','t','y','`',' ', @@ -139,6 +139,7 @@ WCHAR pth[MAX_PATH]; WCHAR *ptr; OSVERSIONINFOA OSVersion; + MEMORYSTATUSEX msex; DWORD verval; WCHAR verstr[10], bufstr[20]; HDC dc; @@ -202,6 +203,7 @@ static const WCHAR szSix[] = {'6',0 }; static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 }; + static const WCHAR szPhysicalMemory[] = { 'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0 }; static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0}; /* Screen properties */ static const WCHAR szScreenX[] = {'S','c','r','e','e','n','X',0}; @@ -217,7 +219,6 @@ UserLanguageID LogonUser VirtualMemory -PhysicalMemory Intel ShellAdvSupport DefaultUIFont @@ -306,6 +307,12 @@ SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth); strcatW(pth,cszbs); MSI_SetPropertyW(package, WF, pth); + + /* Physical Memory is specified in MB. Using total amount. */ + msex.dwLength = sizeof(msex); + GlobalMemoryStatusEx( &msex ); + sprintfW( bufstr, szScreenFormat, (int)(msex.ullTotalPhys/1024/1024)); + MSI_SetPropertyW(package, szPhysicalMemory, bufstr); SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth); ptr = strchrW(pth,'\\'); @@ -740,9 +747,10 @@ MSIQUERY *view; UINT rc, sz; static const WCHAR select[]= - {'s','e','l','e','c','t',' ','V','a','l','u','e',' ','f','r','o','m',' ' - ,'_','P','r','o','p','e','r','t','y',' ','w','h','e','r','e',' ' - ,'_','P','r','o','p','e','r','t','y','=','`','%','s','`',0}; + {'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ', + 'F','R','O','M',' ' ,'`','_','P','r','o','p','e','r','t','y','`', + ' ','W','H','E','R','E',' ' ,'`','_','P','r','o','p','e','r','t','y','`', + '=','\'','%','s','\'',0}; LPWSTR query; if (!szName) @@ -793,7 +801,7 @@ else { *pchValueBuf = 0; - TRACE("property not found\n"); + TRACE("property %s not found\n", debugstr_w(szName)); } return rc; diff -urN wine-20050419/dlls/msi/query.h wine-20050524/dlls/msi/query.h --- wine-20050419/dlls/msi/query.h 2005-02-14 12:07:13.000000000 +0100 +++ wine-20050524/dlls/msi/query.h 2005-05-23 14:08:17.000000000 +0200 @@ -30,6 +30,7 @@ #include "msi.h" #include "msiquery.h" #include "msipriv.h" +#include "wine/list.h" #define OP_EQ 1 @@ -50,7 +51,6 @@ #define EXPR_SVAL 5 #define EXPR_UVAL 6 #define EXPR_STRCMP 7 -#define EXPR_UTF8 8 #define EXPR_WILDCARD 9 #define EXPR_COL_NUMBER_STRING 10 @@ -83,7 +83,6 @@ LPWSTR sval; LPWSTR column; UINT col_number; - char *utf8; } u; }; @@ -107,7 +106,8 @@ } column_assignment; -UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phView); +UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, + struct list *mem ); UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view ); @@ -116,8 +116,8 @@ UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ); -UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ); -UINT ORDER_AddColumn( MSIVIEW *group, LPWSTR name ); +UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, + string_list *columns ); UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, struct expr *cond ); @@ -133,10 +133,6 @@ UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ); -void delete_expr( struct expr *e ); -void delete_string_list( string_list *sl ); -void delete_value_list( value_list *vl ); - int sqliteGetToken(const WCHAR *z, int *tokenType); #endif /* __WINE_MSI_QUERY_H */ diff -urN wine-20050419/dlls/msi/record.c wine-20050524/dlls/msi/record.c --- wine-20050419/dlls/msi/record.c 2005-04-11 14:47:20.000000000 +0200 +++ wine-20050524/dlls/msi/record.c 2005-05-07 14:13:08.000000000 +0200 @@ -98,6 +98,7 @@ rec = MSI_CreateRecord( cParams ); if( rec ) ret = alloc_msihandle( &rec->hdr ); + msiobj_release( &rec->hdr ); return ret; } diff -urN wine-20050419/dlls/msi/registry.c wine-20050524/dlls/msi/registry.c --- wine-20050419/dlls/msi/registry.c 2005-03-24 16:09:18.000000000 +0100 +++ wine-20050524/dlls/msi/registry.c 2005-05-06 16:33:02.000000000 +0200 @@ -85,6 +85,13 @@ 'C','o','m','p','o','n','e','n','t','s','\\', '%','s',0}; +static const WCHAR szUser_Components_fmt[] = { +'S','o','f','t','w','a','r','e','\\', +'M','i','c','r','o','s','o','f','t','\\', +'I','n','s','t','a','l','l','e','r','\\', +'C','o','m','p','o','n','e','n','t','s','\\', +'%','s',0}; + static const WCHAR szUninstall_fmt[] = { 'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', @@ -388,6 +395,26 @@ return rc; } +UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create) +{ + UINT rc; + WCHAR squished_cc[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n",debugstr_w(szComponent)); + squash_guid(szComponent,squished_cc); + TRACE("squished (%s)\n", debugstr_w(squished_cc)); + + sprintfW(keypath,szUser_Components_fmt,squished_cc); + + if (create) + rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key); + else + rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key); + + return rc; +} + UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create) { UINT rc; @@ -695,26 +722,154 @@ return r; } +/************************************************************************* + * MsiEnumComponentQualifiersA [MSI.@] + * + */ UINT WINAPI MsiEnumComponentQualifiersA( LPSTR szComponent, DWORD iIndex, LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf, LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf) { - FIXME("%s %08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex, + LPWSTR szwComponent; + LPWSTR lpwQualifierBuf; + DWORD pcchwQualifierBuf; + LPWSTR lpwApplicationDataBuf; + DWORD pcchwApplicationDataBuf; + DWORD rc; + DWORD length; + + TRACE("%s %08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex, lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf, pcchApplicationDataBuf); - return ERROR_CALL_NOT_IMPLEMENTED; + + szwComponent = strdupAtoW(szComponent); + + if (lpQualifierBuf) + lpwQualifierBuf = HeapAlloc(GetProcessHeap(),0, (*pcchQualifierBuf) * + sizeof(WCHAR)); + else + lpwQualifierBuf = NULL; + + if (pcchQualifierBuf) + pcchwQualifierBuf = *pcchQualifierBuf; + else + pcchwQualifierBuf = 0; + + if (lpApplicationDataBuf) + lpwApplicationDataBuf = HeapAlloc(GetProcessHeap(),0 , + (*pcchApplicationDataBuf) * sizeof(WCHAR)); + else + lpwApplicationDataBuf = NULL; + + if (pcchApplicationDataBuf) + pcchwApplicationDataBuf = *pcchApplicationDataBuf; + else + pcchwApplicationDataBuf = 0; + + rc = MsiEnumComponentQualifiersW( szwComponent, iIndex, lpwQualifierBuf, + &pcchwQualifierBuf, lpwApplicationDataBuf, + &pcchwApplicationDataBuf); + + /* + * A bit of wizardry to report back the length without the null. + * just in case the buffer is too small and is filled. + */ + if (lpQualifierBuf) + { + length = WideCharToMultiByte(CP_ACP, 0, lpwQualifierBuf, -1, + lpQualifierBuf, *pcchQualifierBuf, NULL, NULL); + + if (*pcchQualifierBuf == length && lpQualifierBuf[length-1]) + *pcchQualifierBuf = length; + else + *pcchQualifierBuf = length - 1; + } + if (lpApplicationDataBuf) + { + length = WideCharToMultiByte(CP_ACP, 0, + lpwApplicationDataBuf, -1, lpApplicationDataBuf, + *pcchApplicationDataBuf, NULL, NULL); + + if (*pcchApplicationDataBuf == length && lpApplicationDataBuf[length-1]) + *pcchApplicationDataBuf = length; + else + *pcchApplicationDataBuf = length - 1; + } + + HeapFree(GetProcessHeap(),0,lpwApplicationDataBuf); + HeapFree(GetProcessHeap(),0,lpwQualifierBuf); + HeapFree(GetProcessHeap(),0,szwComponent); + + return rc; } +/************************************************************************* + * MsiEnumComponentQualifiersW [MSI.@] + * + */ UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex, LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf, LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf ) { - FIXME("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex, + UINT rc; + HKEY key; + DWORD actual_pcchQualifierBuf = 0; + DWORD actual_pcchApplicationDataBuf = 0; + LPWSTR full_buffer = NULL; + DWORD full_buffer_size = 0; + LPWSTR ptr; + + TRACE("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex, lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf, pcchApplicationDataBuf); - return ERROR_CALL_NOT_IMPLEMENTED; + + if (pcchQualifierBuf) + actual_pcchQualifierBuf = *pcchQualifierBuf * sizeof(WCHAR); + if (pcchApplicationDataBuf) + actual_pcchApplicationDataBuf = *pcchApplicationDataBuf * sizeof(WCHAR); + + rc = MSIREG_OpenUserComponentsKey(szComponent, &key, FALSE); + if (rc != ERROR_SUCCESS) + return ERROR_UNKNOWN_COMPONENT; + + full_buffer_size = (52 * sizeof(WCHAR)) + actual_pcchApplicationDataBuf; + full_buffer = HeapAlloc(GetProcessHeap(),0,full_buffer_size); + + rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL, + NULL, (LPBYTE)full_buffer, &full_buffer_size); + + RegCloseKey(key); + + if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) + { + if (lpApplicationDataBuf && pcchApplicationDataBuf) + { + ptr = full_buffer; + /* Skip the first guid */ + ptr += 21; + + /* Skip the name and the component guid if it exists */ + if (strchrW(ptr,'<')) + ptr = strchrW(ptr,'<'); + else + ptr = strchrW(ptr,'>') + 21; + + lstrcpynW(lpApplicationDataBuf,ptr,*pcchApplicationDataBuf); + *pcchApplicationDataBuf = strlenW(ptr); + } + if (lpQualifierBuf && pcchQualifierBuf) + *pcchQualifierBuf /= sizeof(WCHAR); + TRACE("Providing %s and %s\n", debugstr_w(lpQualifierBuf), + debugstr_w(lpApplicationDataBuf)); + } + + return rc; } +/************************************************************************* + * MsiEnumRelatedProductsW [MSI.@] + * + */ UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved, DWORD iProductIndex, LPWSTR lpProductBuf) { @@ -742,6 +897,10 @@ return r; } +/************************************************************************* + * MsiEnumRelatedProductsA [MSI.@] + * + */ UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved, DWORD iProductIndex, LPSTR lpProductBuf) { diff -urN wine-20050419/dlls/msi/sql.y wine-20050524/dlls/msi/sql.y --- wine-20050419/dlls/msi/sql.y 2005-02-14 12:07:13.000000000 +0100 +++ wine-20050524/dlls/msi/sql.y 2005-05-24 11:49:01.000000000 +0200 @@ -30,6 +30,7 @@ #include "windef.h" #include "winbase.h" #include "query.h" +#include "wine/list.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -46,25 +47,22 @@ LPCWSTR command; DWORD n, len; MSIVIEW **view; /* view structure for the resulting query */ + struct list *mem; } SQL_input; -static LPWSTR SQL_getstring( struct sql_str *str ); -static INT SQL_getint( SQL_input *sql ); -static int SQL_lex( void *SQL_lval, SQL_input *info); - -static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in, - string_list *columns ); -static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in, - string_list *columns ); - -static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, - string_list *keys); - -static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r ); -static struct expr * EXPR_column( LPWSTR ); -static struct expr * EXPR_ival( struct sql_str *, int sign); -static struct expr * EXPR_sval( struct sql_str *); -static struct expr * EXPR_wildcard(); +static LPWSTR SQL_getstring( void *info, struct sql_str *str ); +static INT SQL_getint( void *info ); +static int SQL_lex( void *SQL_lval, SQL_input *info ); + +static void *parser_alloc( void *info, unsigned int sz ); + +static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, string_list *keys); + +static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); +static struct expr * EXPR_column( void *info, LPWSTR column ); +static struct expr * EXPR_ival( void *info, struct sql_str *, int sign ); +static struct expr * EXPR_sval( void *info, struct sql_str * ); +static struct expr * EXPR_wildcard( void *info ); %} @@ -127,10 +125,10 @@ %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION COLUMN AGG_FUNCTION. -%type column table string_or_id +%type column table id %type selcollist -%type from unorderedsel oneselect onequery onecreate oneinsert -%type oneupdate onedelete +%type query from fromtable unorderedsel selectfrom +%type oneupdate onedelete oneselect onequery onecreate oneinsert %type expr val column_val const_val %type column_type data_type data_type_l data_count %type column_def table_def @@ -139,51 +137,44 @@ %% -onequery: - oneselect +query: + onequery { SQL_input* sql = (SQL_input*) info; *sql->view = $1; } + ; + +onequery: + oneselect | onecreate - { - SQL_input* sql = (SQL_input*) info; - *sql->view = $1; - } | oneinsert - { - SQL_input* sql = (SQL_input*) info; - *sql->view = $1; - } | oneupdate - { - SQL_input* sql = (SQL_input*) info; - *sql->view = $1; - } | onedelete - { - SQL_input* sql = (SQL_input*) info; - *sql->view = $1; - } ; oneinsert: TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP - { - SQL_input *sql = (SQL_input*) info; - MSIVIEW *insert = NULL; + { + SQL_input *sql = (SQL_input*) info; + MSIVIEW *insert = NULL; + UINT r; - INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); - $$ = insert; - } + r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE ); + if( !insert ) + YYABORT; + $$ = insert; + } | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP - { - SQL_input *sql = (SQL_input*) info; - MSIVIEW *insert = NULL; + { + SQL_input *sql = (SQL_input*) info; + MSIVIEW *insert = NULL; - INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); - $$ = insert; - } + INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE ); + if( !insert ) + YYABORT; + $$ = insert; + } ; onecreate: @@ -195,6 +186,8 @@ if( !$5 ) YYABORT; CREATE_CreateView( sql->db, &create, $3, $5, FALSE ); + if( !create ) + YYABORT; $$ = create; } | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD @@ -205,6 +198,8 @@