Sync to trunk r38500
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Thu, 1 Jan 2009 22:38:03 +0000 (22:38 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Thu, 1 Jan 2009 22:38:03 +0000 (22:38 +0000)
svn path=/branches/ros-amd64-bringup/; revision=38502

389 files changed:
reactos/Doxyfile
reactos/base/applications/calc/convert.c
reactos/base/applications/calc/lang/bg-BG.rc
reactos/base/applications/calc/lang/cs-CZ.rc
reactos/base/applications/calc/lang/de-DE.rc
reactos/base/applications/calc/lang/en-US.rc
reactos/base/applications/calc/lang/es-ES.rc
reactos/base/applications/calc/lang/it-IT.rc
reactos/base/applications/calc/lang/ko-KR.rc
reactos/base/applications/calc/lang/nl-NL.rc
reactos/base/applications/calc/lang/no-NO.rc
reactos/base/applications/calc/lang/pl-PL.rc
reactos/base/applications/calc/lang/ru-RU.rc
reactos/base/applications/calc/lang/sk-SK.rc
reactos/base/applications/calc/lang/uk-UA.rc
reactos/base/applications/calc/resource.h
reactos/base/applications/cmdutils/dbgprint/dbgprint.c
reactos/base/applications/games/solitaire/lang/bg-BG.rc
reactos/base/applications/network/telnet/src/tmapldr.cpp
reactos/base/applications/network/telnet/src/tnmain.cpp
reactos/base/applications/notepad/dialog.c
reactos/base/applications/notepad/lang/bg-BG.rc
reactos/base/applications/notepad/lang/cs-CZ.rc
reactos/base/applications/notepad/lang/da-DK.rc
reactos/base/applications/notepad/lang/de-DE.rc
reactos/base/applications/notepad/lang/el-GR.rc
reactos/base/applications/notepad/lang/en-US.rc
reactos/base/applications/notepad/lang/es-ES.rc
reactos/base/applications/notepad/lang/eu-ES.rc
reactos/base/applications/notepad/lang/fi-FI.rc
reactos/base/applications/notepad/lang/fr-FR.rc
reactos/base/applications/notepad/lang/hu-HU.rc
reactos/base/applications/notepad/lang/id-ID.rc
reactos/base/applications/notepad/lang/it-IT.rc
reactos/base/applications/notepad/lang/ja-JP.rc
reactos/base/applications/notepad/lang/lt-LT.rc
reactos/base/applications/notepad/lang/nl-NL.rc
reactos/base/applications/notepad/lang/no-NO.rc
reactos/base/applications/notepad/lang/pl-PL.rc
reactos/base/applications/notepad/lang/pt-PT.rc
reactos/base/applications/notepad/lang/ru-RU.rc
reactos/base/applications/notepad/lang/sk-SK.rc
reactos/base/applications/notepad/lang/sl-SI.rc
reactos/base/applications/notepad/lang/sv-SE.rc
reactos/base/applications/notepad/lang/th-TH.rc
reactos/base/applications/notepad/lang/uk-UA.rc
reactos/base/applications/notepad/lang/zh-CN.rc
reactos/base/applications/taskmgr/lang/da-DK.rc
reactos/base/applications/tsclient/porting-tools/rdesktop-core-tester/activex.cpp
reactos/base/services/dhcp/compat.c
reactos/base/services/dhcp/dhcp.rbuild
reactos/base/services/dhcp/util.c
reactos/base/services/eventlog/eventlog.c
reactos/base/services/eventlog/eventlog.h
reactos/base/services/eventlog/file.c
reactos/base/services/eventlog/logport.c
reactos/base/setup/reactos/lang/bg-BG.rc
reactos/base/setup/usetup/lang/sk-SK.h
reactos/base/shell/cmd/cmdtable.c
reactos/base/shell/cmd/dir.c
reactos/base/shell/cmd/if.c
reactos/base/shell/cmd/parser.c
reactos/base/shell/explorer/utility/xmlstorage.cpp
reactos/base/shell/explorer/utility/xmlstorage.h
reactos/base/shell/explorer/utility/xs-native.cpp
reactos/base/system/regsvr32/lang/bg-BG.rc [new file with mode: 0644]
reactos/base/system/regsvr32/rsrc.rc
reactos/baseaddress.rbuild
reactos/boot/bootdata/hivesys_i386.inf
reactos/boot/freeldr/freeldr/include/mm.h
reactos/boot/freeldr/freeldr/mm/mm.c
reactos/boot/freeldr/freeldr/windows/peloader.c
reactos/boot/freeldr/freeldr/windows/wlmemory.c
reactos/config-arm.template.rbuild
reactos/config-ppc.template.rbuild
reactos/config.template.rbuild
reactos/dll/3rdparty/mesa32/mesa32.rbuild
reactos/dll/cpl/main/mouse.c
reactos/dll/directx/wine/wined3d/wined3d.rbuild
reactos/dll/ntdll/ldr/startup.c
reactos/dll/win32/advapi32/crypt/crypt.c
reactos/dll/win32/advapi32/sec/misc.c
reactos/dll/win32/advpack/files.c
reactos/dll/win32/advpack/install.c
reactos/dll/win32/advpack/reg.c
reactos/dll/win32/atl/atl_ax.c
reactos/dll/win32/atl/registrar.c
reactos/dll/win32/cabinet/fci.c
reactos/dll/win32/cabinet/fdi.c
reactos/dll/win32/comdlg32/cdlg.h
reactos/dll/win32/comdlg32/cdlg32.c
reactos/dll/win32/comdlg32/cdlg_De.rc
reactos/dll/win32/comdlg32/cdlg_Ja.rc
reactos/dll/win32/comdlg32/cdlg_Si.rc
reactos/dll/win32/comdlg32/cdlg_Zh.rc
reactos/dll/win32/comdlg32/colordlg.c
reactos/dll/win32/comdlg32/filedlg.c
reactos/dll/win32/comdlg32/filedlg16.c
reactos/dll/win32/comdlg32/filedlg31.c
reactos/dll/win32/comdlg32/filedlgbrowser.c
reactos/dll/win32/comdlg32/filedlgbrowser.h
reactos/dll/win32/comdlg32/finddlg32.c
reactos/dll/win32/comdlg32/fontdlg.c
reactos/dll/win32/comdlg32/fontdlg16.c
reactos/dll/win32/comdlg32/printdlg.c
reactos/dll/win32/comdlg32/printdlg16.c
reactos/dll/win32/comdlg32/rsrc.rc
reactos/dll/win32/crypt32/base64.c
reactos/dll/win32/crypt32/cert.c
reactos/dll/win32/crypt32/chain.c
reactos/dll/win32/crypt32/context.c
reactos/dll/win32/crypt32/crl.c
reactos/dll/win32/crypt32/crypt32.rc
reactos/dll/win32/crypt32/crypt32.spec
reactos/dll/win32/crypt32/crypt32_En.rc
reactos/dll/win32/crypt32/crypt32_Fr.rc
reactos/dll/win32/crypt32/crypt32_Ko.rc
reactos/dll/win32/crypt32/crypt32_Pt.rc [new file with mode: 0644]
reactos/dll/win32/crypt32/crypt32_private.h
reactos/dll/win32/crypt32/crypt32_ros.diff [deleted file]
reactos/dll/win32/crypt32/cryptres.h
reactos/dll/win32/crypt32/ctl.c
reactos/dll/win32/crypt32/decode.c
reactos/dll/win32/crypt32/encode.c
reactos/dll/win32/crypt32/filestore.c
reactos/dll/win32/crypt32/main.c
reactos/dll/win32/crypt32/message.c
reactos/dll/win32/crypt32/msg.c
reactos/dll/win32/crypt32/object.c
reactos/dll/win32/crypt32/oid.c
reactos/dll/win32/crypt32/protectdata.c
reactos/dll/win32/crypt32/provstore.c
reactos/dll/win32/crypt32/regstore.c
reactos/dll/win32/crypt32/rootstore.c
reactos/dll/win32/crypt32/sip.c
reactos/dll/win32/crypt32/store.c
reactos/dll/win32/crypt32/str.c
reactos/dll/win32/cryptnet/cryptnet_main.c
reactos/dll/win32/cryptui/cert.bmp [new file with mode: 0644]
reactos/dll/win32/cryptui/certerror.bmp [new file with mode: 0644]
reactos/dll/win32/cryptui/certwarning.bmp [new file with mode: 0644]
reactos/dll/win32/cryptui/checks.bmp [new file with mode: 0644]
reactos/dll/win32/cryptui/cryptui.rbuild
reactos/dll/win32/cryptui/cryptui.rc [new file with mode: 0644]
reactos/dll/win32/cryptui/cryptui.spec
reactos/dll/win32/cryptui/cryptui_En.rc [new file with mode: 0644]
reactos/dll/win32/cryptui/cryptuires.h [new file with mode: 0644]
reactos/dll/win32/cryptui/main.c
reactos/dll/win32/cryptui/smallicons.bmp [new file with mode: 0644]
reactos/dll/win32/devmgr/advprop.c
reactos/dll/win32/devmgr/devmgr.rbuild
reactos/dll/win32/dwmapi/dwmapi.rbuild [new file with mode: 0644]
reactos/dll/win32/dwmapi/dwmapi.spec [new file with mode: 0644]
reactos/dll/win32/dwmapi/dwmapi_main.c [new file with mode: 0644]
reactos/dll/win32/dwmapi/version.rc [new file with mode: 0644]
reactos/dll/win32/fusion/assembly.c
reactos/dll/win32/hlink/link.c
reactos/dll/win32/icmp/icmp.rbuild
reactos/dll/win32/icmp/icmp_main.c
reactos/dll/win32/iphlpapi/iphlpapi_main.c
reactos/dll/win32/iphlpapi/ipstats_reactos.c
reactos/dll/win32/kernel32/file/cnotify.c
reactos/dll/win32/kernel32/file/dir.c
reactos/dll/win32/kernel32/file/file.c
reactos/dll/win32/kernel32/file/move.c
reactos/dll/win32/kernel32/file/volume.c
reactos/dll/win32/kernel32/k32.h
reactos/dll/win32/kernel32/kernel32.rbuild
reactos/dll/win32/kernel32/mem/virtual.c
reactos/dll/win32/kernel32/misc/comm.c
reactos/dll/win32/kernel32/misc/commdcb.c [new file with mode: 0644]
reactos/dll/win32/kernel32/misc/nls.c
reactos/dll/win32/kernel32/misc/profile.c
reactos/dll/win32/kernel32/misc/stubs.c
reactos/dll/win32/kernel32/misc/time.c
reactos/dll/win32/msi/action.c
reactos/dll/win32/msi/alter.c
reactos/dll/win32/msi/appsearch.c
reactos/dll/win32/msi/automation.c
reactos/dll/win32/msi/classes.c
reactos/dll/win32/msi/create.c
reactos/dll/win32/msi/custom.c
reactos/dll/win32/msi/database.c
reactos/dll/win32/msi/delete.c
reactos/dll/win32/msi/dialog.c
reactos/dll/win32/msi/distinct.c
reactos/dll/win32/msi/drop.c [new file with mode: 0644]
reactos/dll/win32/msi/events.c
reactos/dll/win32/msi/files.c
reactos/dll/win32/msi/helpers.c
reactos/dll/win32/msi/insert.c
reactos/dll/win32/msi/install.c
reactos/dll/win32/msi/join.c
reactos/dll/win32/msi/media.c [new file with mode: 0644]
reactos/dll/win32/msi/msi.c
reactos/dll/win32/msi/msi.rbuild
reactos/dll/win32/msi/msi.rc
reactos/dll/win32/msi/msi.spec
reactos/dll/win32/msi/msi_Ko.rc
reactos/dll/win32/msi/msi_Zh.rc [new file with mode: 0644]
reactos/dll/win32/msi/msipriv.h
reactos/dll/win32/msi/msiquery.c
reactos/dll/win32/msi/package.c
reactos/dll/win32/msi/query.h
reactos/dll/win32/msi/record.c
reactos/dll/win32/msi/registry.c
reactos/dll/win32/msi/regsvr.c
reactos/dll/win32/msi/select.c
reactos/dll/win32/msi/source.c
reactos/dll/win32/msi/sql.tab.c
reactos/dll/win32/msi/sql.tab.h
reactos/dll/win32/msi/sql.y
reactos/dll/win32/msi/storages.c
reactos/dll/win32/msi/streams.c
reactos/dll/win32/msi/suminfo.c
reactos/dll/win32/msi/table.c
reactos/dll/win32/msi/tokenize.c
reactos/dll/win32/msi/update.c
reactos/dll/win32/msi/upgrade.c
reactos/dll/win32/msi/where.c
reactos/dll/win32/netcfgx/lang/bg-BG.rc
reactos/dll/win32/netshell/lang/bg-BG.rc
reactos/dll/win32/oleacc/main.c
reactos/dll/win32/oleacc/oleacc.rbuild
reactos/dll/win32/oleacc/oleacc.rc [new file with mode: 0644]
reactos/dll/win32/oleacc/oleacc.spec
reactos/dll/win32/oleacc/oleacc_En.rc [new file with mode: 0644]
reactos/dll/win32/oleacc/oleacc_Fr.rc [new file with mode: 0644]
reactos/dll/win32/oleacc/oleacc_Ko.rc [new file with mode: 0644]
reactos/dll/win32/oleacc/oleacc_Nl.rc [new file with mode: 0644]
reactos/dll/win32/riched20/caret.c
reactos/dll/win32/riched20/clipboard.c
reactos/dll/win32/riched20/editor.c
reactos/dll/win32/riched20/editor.h
reactos/dll/win32/riched20/editstr.h
reactos/dll/win32/riched20/paint.c
reactos/dll/win32/riched20/para.c
reactos/dll/win32/riched20/reader.c
reactos/dll/win32/riched20/riched20.rbuild
reactos/dll/win32/riched20/rtf.h
reactos/dll/win32/riched20/run.c
reactos/dll/win32/riched20/string.c
reactos/dll/win32/riched20/wrap.c
reactos/dll/win32/riched20/writer.c
reactos/dll/win32/rsaenh/md2.c
reactos/dll/win32/rsaenh/mpi.c
reactos/dll/win32/rsaenh/rc2.c
reactos/dll/win32/rsaenh/rsaenh.c
reactos/dll/win32/rsaenh/tomcrypt.h
reactos/dll/win32/secur32/sspi.c
reactos/dll/win32/setupapi/devinst.c
reactos/dll/win32/setupapi/install.c
reactos/dll/win32/setupapi/setupapi.spec
reactos/dll/win32/setupapi/setupapi_private.h
reactos/dll/win32/shell32/fprop.c
reactos/dll/win32/shell32/lang/bg-BG.rc
reactos/dll/win32/shimgvw/lang/bg-BG.rc [new file with mode: 0644]
reactos/dll/win32/shimgvw/rsrc.rc
reactos/dll/win32/syssetup/lang/bg-BG.rc
reactos/dll/win32/user32/controls/edit.c
reactos/dll/win32/user32/windows/bitmap.c
reactos/dll/win32/win32.rbuild
reactos/dll/win32/wininet/internet.h
reactos/dll/win32/wintrust/asn.c
reactos/dll/win32/wintrust/crypt.c
reactos/dll/win32/wintrust/softpub.c
reactos/dll/win32/wintrust/wintrust.rbuild
reactos/dll/win32/wintrust/wintrust.spec
reactos/dll/win32/wintrust/wintrust_main.c
reactos/dll/win32/wintrust/wintrust_priv.h
reactos/dll/win32/ws2_32/misc/stubs.c
reactos/drivers/filesystems/ext2/inc/protos.h
reactos/drivers/filesystems/ext2/inc/struct.h
reactos/drivers/filesystems/ext2/src/DiskIO.c
reactos/drivers/filesystems/ext2/src/cleanup.c
reactos/drivers/filesystems/ext2/src/close.c
reactos/drivers/filesystems/ext2/src/create.c
reactos/drivers/filesystems/ext2/src/dircntrl.c
reactos/drivers/filesystems/ext2/src/ext2init.c
reactos/drivers/filesystems/ext2/src/fastio.c
reactos/drivers/filesystems/ext2/src/fileinfo.c
reactos/drivers/filesystems/ext2/src/flush.c
reactos/drivers/filesystems/ext2/src/fsctrl.c
reactos/drivers/filesystems/ext2/src/io.c
reactos/drivers/filesystems/ext2/src/metadata.c
reactos/drivers/filesystems/ext2/src/misc.c
reactos/drivers/filesystems/ext2/src/read.c
reactos/drivers/filesystems/ext2/src/write.c
reactos/drivers/ksfilter/ks/ks.rbuild
reactos/drivers/ksfilter/ks/worker.c
reactos/drivers/storage/class/disk/disk.c
reactos/drivers/storage/ide/uniata/atapi.h
reactos/drivers/storage/ide/uniata/id_ata.cpp
reactos/drivers/storage/ide/uniata/id_badblock.cpp
reactos/drivers/storage/ide/uniata/id_dma.cpp
reactos/drivers/storage/ide/uniata/id_init.cpp
reactos/drivers/storage/ide/uniata/id_probe.cpp
reactos/drivers/storage/ide/uniata/id_sata.cpp
reactos/drivers/storage/ide/uniata/ntddk_ex.h
reactos/drivers/storage/ide/uniata/scsi.h
reactos/drivers/storage/ide/uniata/uniata.rbuild
reactos/drivers/storage/ide/uniata/warningfixes.diff [new file with mode: 0644]
reactos/drivers/storage/scsiport/scsiport.c
reactos/drivers/usb/nt4compat/usbdriver/etd.c
reactos/drivers/usb/nt4compat/usbdriver/roothub.c
reactos/drivers/usb/nt4compat/usbdriver/uhci.c
reactos/drivers/video/videoprt/int10.c
reactos/drivers/video/videoprt/resource.c
reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c
reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [new file with mode: 0644]
reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild
reactos/hal/halx86/generic/dma.c
reactos/hal/halx86/mp/apic.c
reactos/include/crt/sys/types.h
reactos/include/ddk/ntdef.h
reactos/include/ddk/portcls.h
reactos/include/host/typedefs.h
reactos/include/psdk/cryptdlg.h [new file with mode: 0644]
reactos/include/psdk/cryptuiapi.h
reactos/include/psdk/dwmapi.h [new file with mode: 0644]
reactos/include/psdk/mscat.h
reactos/include/psdk/msi.h
reactos/include/psdk/msidefs.h
reactos/include/psdk/oleacc.h [deleted file]
reactos/include/psdk/scarderr.h [new file with mode: 0644]
reactos/include/psdk/shlguid.h
reactos/include/psdk/srrestoreptapi.h
reactos/include/psdk/urlmon.idl
reactos/include/psdk/wincrypt.h
reactos/include/psdk/windef.h
reactos/include/psdk/windows.h
reactos/include/psdk/wingdi.h
reactos/include/psdk/winscard.h
reactos/include/psdk/winsmcrd.h
reactos/include/psdk/wintrust.h
reactos/include/psdk/winuser.h
reactos/include/reactos/libs/pseh/pseh2.h
reactos/include/reactos/version.h
reactos/include/reactos/wine/config.h
reactos/include/reactos/wine/unicode.h
reactos/lib/3rdparty/icu4ros/icu/source/common/umutex.c
reactos/lib/3rdparty/icu4ros/icu/source/common/unistr.cpp
reactos/lib/drivers/oskittcp/include/freebsd/src/sys/sys/queue.h
reactos/lib/drivers/oskittcp/include/freebsd/src/sys/sys/systm.h
reactos/lib/drivers/oskittcp/include/oskitfreebsd.h
reactos/lib/drivers/oskittcp/oskittcp/in_pcb.c
reactos/lib/drivers/oskittcp/oskittcp/interface.c
reactos/lib/drivers/oskittcp/oskittcp/ip_output.c
reactos/lib/drivers/oskittcp/oskittcp/tcp_input.c
reactos/lib/fslib/ext2lib/Mke2fs.c
reactos/lib/pseh/framebased-gcchack.c
reactos/lib/pseh/i386/framebased-gcchack.S
reactos/lib/rtl/bitmap.c
reactos/ntoskrnl/ex/harderr.c
reactos/ntoskrnl/ex/profile.c
reactos/ntoskrnl/ex/sysinfo.c
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/io/iomgr/device.c
reactos/ntoskrnl/io/iomgr/iomdl.c
reactos/ntoskrnl/io/iomgr/util.c
reactos/ntoskrnl/kd/kdmain.c
reactos/ntoskrnl/ke/i386/kiinit.c
reactos/ntoskrnl/ke/powerpc/thrdini.c
reactos/ntoskrnl/ke/profobj.c
reactos/ntoskrnl/mm/marea.c
reactos/ntoskrnl/mm/mminit.c
reactos/ntoskrnl/mm/rmap.c
reactos/subsystems/win32/win32k/eng/mouse.c
reactos/subsystems/win32/win32k/include/dc.h
reactos/subsystems/win32/win32k/include/text.h
reactos/subsystems/win32/win32k/ntddraw/dxeng.c
reactos/subsystems/win32/win32k/ntuser/cursoricon.c
reactos/subsystems/win32/win32k/ntuser/input.c
reactos/subsystems/win32/win32k/ntuser/misc.c
reactos/subsystems/win32/win32k/ntuser/simplecall.c
reactos/subsystems/win32/win32k/ntuser/window.c
reactos/subsystems/win32/win32k/ntuser/winpos.c
reactos/subsystems/win32/win32k/ntuser/winsta.c
reactos/subsystems/win32/win32k/objects/dc.c
reactos/subsystems/win32/win32k/objects/font.c
reactos/subsystems/win32/win32k/objects/freetype.c
reactos/tools/rbuild/backend/devcpp/devcpp.cpp
reactos/tools/rbuild/backend/mingw/mingw.cpp
reactos/tools/rbuild/backend/mingw/modulehandler.cpp
reactos/tools/rbuild/backend/msvc/msvc.cpp
reactos/tools/rbuild/global.cpp
reactos/tools/rbuild/module.cpp
reactos/tools/rbuild/pch.h

index 824f1f7..0fdd22f 100644 (file)
@@ -1,4 +1,4 @@
-# Doxyfile 1.5.3
+# Doxyfile 1.5.8
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
 # Project related configuration options
 #---------------------------------------------------------------------------
 
-# This tag specifies the encoding used for all characters in the config file that 
-# follow. The default is UTF-8 which is also the encoding used for all text before 
-# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
-# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
-# possible encodings.
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
 
 DOXYFILE_ENCODING      = UTF-8
 
@@ -31,14 +31,14 @@ PROJECT_NAME           = ReactOS
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 
+PROJECT_NUMBER         = "0.4-SVN r?????"
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
 # If a relative path is entered, it will be relative to the location 
 # where doxygen was started. If left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = doxy-doc
+OUTPUT_DIRECTORY       = Doxygen
 
 # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
 # 4096 sub-directories (in 2 levels) under the output directory of each output 
@@ -47,17 +47,18 @@ OUTPUT_DIRECTORY       = doxy-doc
 # source files, where putting all generated files in the same directory would 
 # otherwise cause performance problems for the file system.
 
-CREATE_SUBDIRS         = NO
+CREATE_SUBDIRS         = YES
 
 # The OUTPUT_LANGUAGE tag is used to specify the language in which all 
 # documentation generated by doxygen is written. Doxygen will use this 
 # information to generate all constant output in the proper language. 
 # The default language is English, other supported languages are: 
 # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
-# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
-# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
-# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
-# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, 
+# Spanish, Swedish, and Ukrainian.
 
 OUTPUT_LANGUAGE        = English
 
@@ -146,7 +147,7 @@ SHORT_NAMES            = NO
 # comments will behave just like regular Qt-style comments 
 # (thus requiring an explicit @brief command for a brief description.)
 
-JAVADOC_AUTOBRIEF      = YES
+JAVADOC_AUTOBRIEF      = NO
 
 # If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
 # interpret the first line (until the first dot) of a Qt-style 
@@ -164,13 +165,6 @@ QT_AUTOBRIEF           = NO
 
 MULTILINE_CPP_IS_BRIEF = NO
 
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP         = NO
-
 # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
 # member inherits the documentation from any documented member that it 
 # re-implements.
@@ -186,7 +180,7 @@ SEPARATE_MEMBER_PAGES  = NO
 # The TAB_SIZE tag can be used to set the number of spaces in a tab. 
 # Doxygen uses this value to replace tabs by spaces in code fragments.
 
-TAB_SIZE               = 8
+TAB_SIZE               = 4
 
 # This tag can be used to specify a number of aliases that acts 
 # as commands in the documentation. An alias has the form "name=value". 
@@ -205,14 +199,37 @@ ALIASES                =
 OPTIMIZE_OUTPUT_FOR_C  = YES
 
 # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for Java. 
-# For instance, namespaces will be presented as packages, qualified scopes 
-# will look different, etc.
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
 
 OPTIMIZE_OUTPUT_JAVA   = NO
 
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
-# include (a tag file for) the STL sources as input, then you should 
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses. 
+# With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this tag. 
+# The format is ext=language, where ext is a file extension, and language is one of 
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, 
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat 
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), 
+# use: inc=Fortran f=C
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
 # set this tag to YES in order to let doxygen match functions declarations and 
 # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
 # func(std::string) {}). This also make the inheritance and collaboration 
@@ -220,11 +237,26 @@ OPTIMIZE_OUTPUT_JAVA   = NO
 
 BUILTIN_STL_SUPPORT    = NO
 
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
 # enable parsing support.
 
 CPP_CLI_SUPPORT        = NO
 
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
 # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
 # tag is set to YES, then doxygen will reuse the documentation of the first 
 # member in the group (if any) for the other members of the group. By default 
@@ -240,6 +272,32 @@ DISTRIBUTE_GROUP_DOC   = NO
 
 SUBGROUPING            = YES
 
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = YES
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
 #---------------------------------------------------------------------------
 # Build related configuration options
 #---------------------------------------------------------------------------
@@ -274,10 +332,11 @@ EXTRACT_LOCAL_CLASSES  = YES
 
 EXTRACT_LOCAL_METHODS  = NO
 
-# If this flag is set to YES, the members of anonymous namespaces will be extracted 
-# and appear in the documentation as a namespace called 'anonymous_namespace{file}', 
-# where file will be replaced with the base name of the file that contains the anonymous 
-# namespace. By default anonymous namespace are hidden.
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
 
 EXTRACT_ANON_NSPACES   = NO
 
@@ -315,7 +374,7 @@ HIDE_IN_BODY_DOCS      = NO
 # to NO (the default) then the documentation will be excluded. 
 # Set it to YES to include the internal documentation.
 
-INTERNAL_DOCS          = YES
+INTERNAL_DOCS          = NO
 
 # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
 # file names in lower-case letters. If set to YES upper-case letters are also 
@@ -356,11 +415,17 @@ SORT_MEMBER_DOCS       = YES
 
 SORT_BRIEF_DOCS        = NO
 
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
 # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
 # sorted by fully-qualified names, including namespaces. If set to 
 # NO (the default), the class list will be sorted only by class name, 
 # not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
 # Note: This option applies only to the class list, not to the 
 # alphabetical list.
 
@@ -370,25 +435,25 @@ SORT_BY_SCOPE_NAME     = NO
 # disable (NO) the todo list. This list is created by putting \todo 
 # commands in the documentation.
 
-GENERATE_TODOLIST      = YES
+GENERATE_TODOLIST      = NO
 
 # The GENERATE_TESTLIST tag can be used to enable (YES) or 
 # disable (NO) the test list. This list is created by putting \test 
 # commands in the documentation.
 
-GENERATE_TESTLIST      = YES
+GENERATE_TESTLIST      = NO
 
 # The GENERATE_BUGLIST tag can be used to enable (YES) or 
 # disable (NO) the bug list. This list is created by putting \bug 
 # commands in the documentation.
 
-GENERATE_BUGLIST       = YES
+GENERATE_BUGLIST       = NO
 
 # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
 # disable (NO) the deprecated list. This list is created by putting 
 # \deprecated commands in the documentation.
 
-GENERATE_DEPRECATEDLIST= YES
+GENERATE_DEPRECATEDLIST= NO
 
 # The ENABLED_SECTIONS tag can be used to enable conditional 
 # documentation sections, marked by \if sectionname ... \endif.
@@ -415,11 +480,23 @@ SHOW_USED_FILES        = YES
 # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
 # in the documentation. The default is NO.
 
-SHOW_DIRECTORIES       = NO
+SHOW_DIRECTORIES       = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = NO
 
 # The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from the 
-# version control system). Doxygen will invoke the program by executing (via 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
 # popen()) the command <command> <input-file>, where <command> is the value of 
 # the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
 # provided by doxygen. Whatever the program writes to standard output 
@@ -427,6 +504,15 @@ SHOW_DIRECTORIES       = NO
 
 FILE_VERSION_FILTER    = 
 
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
@@ -470,7 +556,7 @@ WARN_NO_PARAMDOC       = NO
 # $version, which will be replaced by the version of the file (if it could 
 # be obtained via FILE_VERSION_FILTER)
 
-WARN_FORMAT            = "$file:$line: $text "
+WARN_FORMAT            = "$file:$line: $text"
 
 # The WARN_LOGFILE tag can be used to specify a file to which warning 
 # and error messages should be written. If left blank the output is written 
@@ -487,12 +573,13 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories 
 # with spaces.
 
-INPUT                  =
+INPUT                  = 
 
-# This tag can be used to specify the character encoding of the source files that 
-# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
-# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
-# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
 
 INPUT_ENCODING         = UTF-8
 
@@ -501,13 +588,16 @@ INPUT_ENCODING         = UTF-8
 # and *.h) to filter out the source-files in the directories. If left 
 # blank the following patterns are tested: 
 # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
 
 FILE_PATTERNS          = *.c \
-                         *.h \
+                         *.cxx \
                          *.cpp \
-                         *.cc \
-                         *.cx
+                         *.c++ \
+                         *.h \
+                         *.hh \
+                         *.hpp \
+                         *.idl
 
 # The RECURSIVE tag can be used to turn specify whether or not subdirectories 
 # should be searched for input files as well. Possible values are YES and NO. 
@@ -519,8 +609,7 @@ RECURSIVE              = YES
 # excluded from the INPUT source files. This way you can easily exclude a 
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
 
-EXCLUDE                = subsystems/win32/win32k \
-                         base/shell/explorer
+EXCLUDE                = 
 
 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
 # directories that are symbolic links (a Unix filesystem feature) are excluded 
@@ -534,12 +623,13 @@ EXCLUDE_SYMLINKS       = NO
 # against the file with absolute path, so to exclude all test directories 
 # for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = 
+EXCLUDE_PATTERNS       = */.svn
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
-# (namespaces, classes, functions, etc.) that should be excluded from the output. 
-# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
-# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
 
 EXCLUDE_SYMBOLS        = 
 
@@ -561,7 +651,7 @@ EXAMPLE_PATTERNS       =
 # commands irrespective of the value of the RECURSIVE tag. 
 # Possible values are YES and NO. If left blank NO is used.
 
-EXAMPLE_RECURSIVE      = YES
+EXAMPLE_RECURSIVE      = NO
 
 # The IMAGE_PATH tag can be used to specify one or more files or 
 # directories that contain image that are included in the documentation (see 
@@ -601,9 +691,7 @@ FILTER_SOURCE_FILES    = NO
 # If the SOURCE_BROWSER tag is set to YES then a list of source files will 
 # be generated. Documented entities will be cross-referenced with these sources. 
 # Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH 
-# then you must also enable this option. If you don't then doxygen will produce 
-# a warning and turn it on anyway
+# VERBATIM_HEADERS is set to NO.
 
 SOURCE_BROWSER         = YES
 
@@ -618,22 +706,22 @@ INLINE_SOURCES         = YES
 
 STRIP_CODE_COMMENTS    = YES
 
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# If the REFERENCED_BY_RELATION tag is set to YES 
 # then for each documented function all documented 
 # functions referencing it will be listed.
 
-REFERENCED_BY_RELATION = YES
+REFERENCED_BY_RELATION = NO
 
-# If the REFERENCES_RELATION tag is set to YES (the default) 
+# If the REFERENCES_RELATION tag is set to YES 
 # then for each documented function all documented entities 
 # called/used by that function will be listed.
 
-REFERENCES_RELATION    = YES
+REFERENCES_RELATION    = NO
 
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.  Otherwise they will link to the documentstion.
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
 
 REFERENCES_LINK_SOURCE = YES
 
@@ -722,20 +810,46 @@ HTML_STYLESHEET        =
 
 HTML_ALIGN_MEMBERS     = YES
 
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
 # documentation will contain sections that can be hidden and shown after the 
 # page has loaded. For this to work a browser that supports 
 # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
 # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
 
-HTML_DYNAMIC_SECTIONS  = NO
+HTML_DYNAMIC_SECTIONS  = YES
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
 
 # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
 # be used to specify the file name of the resulting .chm file. You 
@@ -757,6 +871,12 @@ HHC_LOCATION           =
 
 GENERATE_CHI           = NO
 
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
 # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
 # controls whether a binary table of contents is generated (YES) or a 
 # normal table of contents (NO) in the .chm file.
@@ -768,6 +888,55 @@ BINARY_TOC             = NO
 
 TOC_EXPAND             = NO
 
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. 
+# For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
 # The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
 # top of each HTML page. The value NO (the default) enables the index and 
 # the value YES disables it.
@@ -779,14 +948,22 @@ DISABLE_INDEX          = NO
 
 ENUM_VALUES_PER_LINE   = 4
 
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to FRAME, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
 # is generated for HTML Help). For this to work a browser that supports 
 # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
 # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list; 
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which 
+# disables this behavior completely. For backwards compatibility with previous 
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE 
+# respectively.
 
-GENERATE_TREEVIEW      = NO
+GENERATE_TREEVIEW      = NONE
 
 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
 # used to set the initial width (in pixels) of the frame in which the tree 
@@ -794,6 +971,14 @@ GENERATE_TREEVIEW      = NO
 
 TREEVIEW_WIDTH         = 250
 
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
 #---------------------------------------------------------------------------
 # configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
@@ -849,13 +1034,13 @@ LATEX_HEADER           =
 # contain links (just like the HTML output) instead of page references 
 # This makes the output suitable for online browsing using a pdf viewer.
 
-PDF_HYPERLINKS         = NO
+PDF_HYPERLINKS         = YES
 
 # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
 # plain latex in the generated Makefile. Set this option to YES to get a 
 # higher quality PDF documentation.
 
-USE_PDFLATEX           = NO
+USE_PDFLATEX           = YES
 
 # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
 # command to the generated LaTeX files. This will instruct LaTeX to keep 
@@ -890,7 +1075,7 @@ RTF_OUTPUT             = rtf
 # RTF documents. This may be useful for small projects and may help to 
 # save some trees in general.
 
-COMPACT_RTF            = YES
+COMPACT_RTF            = NO
 
 # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
 # will contain hyperlink fields. The RTF file will 
@@ -899,7 +1084,7 @@ COMPACT_RTF            = YES
 # programs which support those fields. 
 # Note: wordpad (write) and others do not support links.
 
-RTF_HYPERLINKS         = YES
+RTF_HYPERLINKS         = NO
 
 # Load stylesheet definitions from file. Syntax is similar to doxygen's 
 # config file, i.e. a series of assignments. You only have to provide 
@@ -948,7 +1133,7 @@ MAN_LINKS              = NO
 # generate an XML file that captures the structure of 
 # the code including all documentation.
 
-GENERATE_XML           = YES
+GENERATE_XML           = NO
 
 # The XML_OUTPUT tag is used to specify where the XML pages will be put. 
 # If a relative path is entered the value of OUTPUT_DIRECTORY will be 
@@ -1052,14 +1237,14 @@ SEARCH_INCLUDES        = YES
 # contain include files that are not input files but should be processed by 
 # the preprocessor.
 
-INCLUDE_PATH           = include
+INCLUDE_PATH           = 
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
 # patterns (like *.h and *.hpp) to filter out the header-files in the 
 # directories. If left blank, the patterns specified with FILE_PATTERNS will 
 # be used.
 
-INCLUDE_FILE_PATTERNS  = *.h
+INCLUDE_FILE_PATTERNS  = 
 
 # The PREDEFINED tag can be used to specify one or more macro names that 
 # are defined before the preprocessor is started (similar to the -D option of 
@@ -1099,9 +1284,9 @@ SKIP_FUNCTION_MACROS   = YES
 #   TAGFILES = file1=loc1 "file2 = loc2" ... 
 # where "loc1" and "loc2" can be relative or absolute paths or 
 # URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
 # If a tag file is not located in the directory in which doxygen 
 # is run, you must also specify the path to the tagfile here.
 
@@ -1143,10 +1328,11 @@ PERL_PATH              = /usr/bin/perl
 CLASS_DIAGRAMS         = NO
 
 # You can define message sequence charts within doxygen comments using the \msc 
-# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
-# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
-# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
-# be found in the default search path.
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
 
 MSCGEN_PATH            = 
 
@@ -1154,7 +1340,7 @@ MSCGEN_PATH            =
 # inheritance and usage relations if the target is undocumented 
 # or is not a class.
 
-HIDE_UNDOC_RELATIONS   = NO
+HIDE_UNDOC_RELATIONS   = YES
 
 # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
 # available from the path. This tool is part of Graphviz, a graph visualization 
@@ -1163,6 +1349,29 @@ HIDE_UNDOC_RELATIONS   = NO
 
 HAVE_DOT               = NO
 
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
 # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
 # will generate a graph for each documented class showing the direct and 
 # indirect inheritance relations. Setting this tag to YES will force the 
@@ -1207,19 +1416,19 @@ INCLUDE_GRAPH          = YES
 
 INCLUDED_BY_GRAPH      = YES
 
-# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
-# generate a call dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable call graphs for selected 
-# functions only using the \callgraph command.
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
 
-CALL_GRAPH             = YES
+CALL_GRAPH             = NO
 
-# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
-# generate a caller dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable caller graphs for selected 
-# functions only using the \callergraph command.
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
 
 CALLER_GRAPH           = NO
 
@@ -1230,13 +1439,13 @@ GRAPHICAL_HIERARCHY    = YES
 
 # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
 # then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include
+# in a graphical way. The dependency relations are determined by the #include 
 # relations between the files in the directories.
 
 DIRECTORY_GRAPH        = YES
 
 # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
+# generated by dot. Possible values are png, jpg, or gif 
 # If left blank png will be used.
 
 DOT_IMAGE_FORMAT       = png
@@ -1252,12 +1461,12 @@ DOT_PATH               =
 
 DOTFILE_DIRS           = 
 
-# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
 # nodes that will be shown in the graph. If the number of nodes in a graph 
 # becomes larger than this value, doxygen will truncate the graph, which is 
-# visualized by representing a node as a red box. Note that doxygen if the number 
-# of direct children of the root node in a graph is already larger than 
-# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
 # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
 
 DOT_GRAPH_MAX_NODES    = 50
@@ -1270,13 +1479,13 @@ DOT_GRAPH_MAX_NODES    = 50
 # code bases. Also note that the size of a graph can be further restricted by 
 # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
 
-MAX_DOT_GRAPH_DEPTH    = 0
+MAX_DOT_GRAPH_DEPTH    = 1000
 
 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, which results in a white background. 
-# Warning: Depending on the platform used, enabling this option may lead to 
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
-# read).
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
 
 DOT_TRANSPARENT        = NO
 
@@ -1300,7 +1509,7 @@ GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
 
 #---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
+# Options related to the search engine
 #---------------------------------------------------------------------------
 
 # The SEARCHENGINE tag specifies whether or not a search engine should be 
index d281d44..159a3bf 100644 (file)
@@ -142,6 +142,7 @@ static const conv_t conv_CURRENCY[] = {
     DECLARE_CONV_UNIT(CURRENCY, LUXEMBOURG_FRANC,   "$/40,3399", "$*40,3399")
     DECLARE_CONV_UNIT(CURRENCY, MALTESE_LIRA,       "$/0.42930", "$*0.42930")
     DECLARE_CONV_UNIT(CURRENCY, PORTOGUESE_ESCUDO,  "$/200,482", "$*200,482")
+    DECLARE_CONV_UNIT(CURRENCY, SLOVAK_KORUNA,      "$/30,126",  "$*30,126")
     DECLARE_CONV_UNIT(CURRENCY, SLOVENIAN_TOLAR,    "$/239,640", "$*239,640")
     DECLARE_CONV_UNIT(CURRENCY, SPANISH_PESETA,     "$/166,386", "$*166,386")
     DECLARE_CONV_END
index 3379a17..6d2c7cc 100644 (file)
@@ -522,6 +522,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Luxembourg franc"
     IDS_CURRENCY_MALTESE_LIRA       "Maltese lira"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portoguese escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slovak koruna"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovenian tolar"
     IDS_CURRENCY_SPANISH_PESETA     "Spanish peseta"
 END
index fca7a7d..ad64f9d 100644 (file)
@@ -1,6 +1,6 @@
 /* FILE:        base/applications/calc/lang/cs-CZ.rc
  * TRANSLATOR:  Radek Liska aka Black_Fox (radekliska at gmail dot com)
- * UPDATED:     2008-07-27
+ * UPDATED:     2008-12-29
  */
 
 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
@@ -523,6 +523,7 @@ BEGIN
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portugalské escudo"
     IDS_CURRENCY_AUSTRIAN_SCHILLING "Rakouský \9ailink"
     IDS_CURRENCY_GREEK_DRACHMA      "Øecká drachma"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slovenská koruna"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovinský tolar"
     IDS_CURRENCY_SPANISH_PESETA     "\8apanìlská peseta"
 END
index dd5f279..5b1ad7d 100644 (file)
@@ -521,6 +521,7 @@ BEGIN
     IDS_CURRENCY_DUTCH_GUILDER      "Niederländische Guilder"
     IDS_CURRENCY_AUSTRIAN_SCHILLING "Österreichische Schilling"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portugiesische Escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slowakische Krone"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovenische Tolar"
     IDS_CURRENCY_SPANISH_PESETA     "Spanische Peseta"
     IDS_CURRENCY_CYPRIOT_POUND      "Zypriotische Pfund"
index b723bba..bbe62c6 100644 (file)
@@ -517,6 +517,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Luxembourg franc"
     IDS_CURRENCY_MALTESE_LIRA       "Maltese lira"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portoguese escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slovak koruna"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovenian tolar"
     IDS_CURRENCY_SPANISH_PESETA     "Spanish peseta"
 END
index 0c9db5a..7d4ffe0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *Spanish Language resource file
+ * Spanish Language resource file
  * Traducido por: Javier Remacha 2008
  */
 
@@ -527,6 +527,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Franco Luxemburgués"
     IDS_CURRENCY_MALTESE_LIRA       "Lira Maltesa"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Escudo Portugués"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Corona Eslovaca"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Tolar Esloveno"
     IDS_CURRENCY_SPANISH_PESETA     "Peseta Española"
 END
index bc5f07f..36cf824 100644 (file)
@@ -517,6 +517,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Franco Lussemburghese"
     IDS_CURRENCY_MALTESE_LIRA       "Lira maltese"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Escudo portoghese"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Corona slovacca"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Tallero sloveno"
     IDS_CURRENCY_SPANISH_PESETA     "Peseta spagnola"
 END
index 2f4db08..ba32958 100644 (file)
@@ -1,11 +1,13 @@
 /*
- *Korean translation by manatails007(www.manatails007.org) Seungju Kim
+ *  Korean translation by manatails007 (www.manatails007.org) Seungju Kim
  */
+
 LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
+
 // Dialog
 
 IDD_DIALOG_SCIENTIFIC DIALOGEX 0, 0, 316, 161
-STYLE DS_SHELLFONT | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+STYLE WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 CAPTION "ReactOS °è»ê±â"
 MENU IDR_MENU_SCIENTIFIC_1
 FONT 8, "MS Shell Dlg", 0, 0, 0x1
@@ -151,7 +153,7 @@ BEGIN
                     42,10
     CONTROL         "Radians",IDC_RADIO_RAD,"Button",BS_AUTORADIOBUTTON,192,
                     24,42,10
-    CONTROL         "Grads",IDC_RADIO_GRAD,"Button",BS_AUTORADIOBUTTON,
+    CONTROL         "Gradians",IDC_RADIO_GRAD,"Button",BS_AUTORADIOBUTTON,
                     236,24,44,10
     PUSHBUTTON      "C",IDC_BUTTON_CANC,272,40,40,17,BS_CENTER | BS_VCENTER | 
                     BS_NOTIFY | BS_OWNERDRAW | WS_TABSTOP
@@ -165,7 +167,7 @@ BEGIN
 END
 
 IDD_DIALOG_STANDARD DIALOGEX 0, 0, 172, 127
-STYLE DS_SHELLFONT | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+STYLE WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 CAPTION "ReactOS °è»ê±â"
 MENU IDR_MENU_STANDARD
 FONT 8, "MS Shell Dlg", 0, 0, 0x1
@@ -231,13 +233,91 @@ BEGIN
     DEFPUSHBUTTON   "",IDC_BUTTON_FOCUS,0,0,5,5, NOT WS_VISIBLE
 END
 
+IDD_DIALOG_CONVERSION DIALOGEX 0, 0, 320, 130
+STYLE WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "ReactOS °è»ê±â Á¤º¸"
+MENU IDR_MENU_STANDARD
+FONT 8, "MS Shell Dlg"
+BEGIN
+    PUSHBUTTON      "Convert",IDC_BUTTON_CONVERT,35,105,76,17
+    COMBOBOX        IDC_COMBO_CATEGORY,4,31,140,168,CBS_DROPDOWNLIST | 
+                    WS_VSCROLL | WS_TABSTOP | CBS_SORT
+    LTEXT           "Category:",IDC_STATIC,4,20,56,8
+    COMBOBOX        IDC_COMBO_FROM,4,60,140,168,CBS_DROPDOWNLIST | 
+                    WS_VSCROLL | WS_TABSTOP | CBS_SORT
+    LTEXT           "Convert from:",IDC_STATIC,4,49,56,8
+    COMBOBOX        IDC_COMBO_TO,4,87,140,168,CBS_DROPDOWNLIST | WS_VSCROLL | 
+                    WS_TABSTOP | CBS_SORT
+    LTEXT           "Convert to:",IDC_STATIC,4,76,56,8
+    CONTROL         "C",IDC_BUTTON_CANC,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,276,24,40,17
+    CONTROL         "CE",IDC_BUTTON_CE,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,232,24,40,17
+    CONTROL         "Back",IDC_BUTTON_BACK,"Button",BS_OWNERDRAW | 
+                    BS_CENTER | BS_VCENTER | BS_NOTIFY | WS_TABSTOP,188,24,
+                    40,17
+    RTEXT           "",IDC_TEXT_OUTPUT,4,4,312,12,SS_CENTERIMAGE,
+                    WS_EX_CLIENTEDGE
+    CONTROL         "7",IDC_BUTTON_7,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,188,48,24,17
+    CONTROL         "4",IDC_BUTTON_4,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,188,67,24,17
+    CONTROL         "1",IDC_BUTTON_1,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,188,86,24,17
+    CONTROL         "0",IDC_BUTTON_0,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,188,105,24,17
+    CONTROL         "8",IDC_BUTTON_8,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,214,48,24,17
+    CONTROL         "5",IDC_BUTTON_5,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,214,67,24,17
+    CONTROL         "2",IDC_BUTTON_2,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,214,86,24,17
+    CONTROL         "+/-",IDC_BUTTON_SIGN,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,214,105,24,17
+    CONTROL         "9",IDC_BUTTON_9,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,240,48,24,17
+    CONTROL         "6",IDC_BUTTON_6,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,240,67,24,17
+    CONTROL         "3",IDC_BUTTON_3,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,240,86,24,17
+    CONTROL         ",",IDC_BUTTON_DOT,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,240,105,24,17
+    CONTROL         "/",IDC_BUTTON_DIV,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,266,48,24,17
+    CONTROL         "*",IDC_BUTTON_MULT,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,266,67,24,17
+    CONTROL         "-",IDC_BUTTON_SUB,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,266,86,24,17
+    CONTROL         "+",IDC_BUTTON_ADD,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,266,105,24,17
+    CONTROL         "Sqrt",IDC_BUTTON_SQRT,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,292,48,24,17
+    CONTROL         "%",IDC_BUTTON_PERCENT,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,292,67,24,17
+    CONTROL         "1/x",IDC_BUTTON_RX,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,292,86,24,17
+    CONTROL         "=",IDC_BUTTON_EQU,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,292,105,24,17
+    CTEXT           "",IDC_TEXT_MEMORY,152,24,24,17,SS_CENTERIMAGE,
+                    WS_EX_CLIENTEDGE
+    CONTROL         "MC",IDC_BUTTON_MC,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,152,48,24,17
+    CONTROL         "MR",IDC_BUTTON_MR,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,152,67,24,17
+    CONTROL         "MS",IDC_BUTTON_MS,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,152,86,24,17
+    CONTROL         "M+",IDC_BUTTON_MP,"Button",BS_OWNERDRAW | BS_CENTER | 
+                    BS_VCENTER | BS_NOTIFY | WS_TABSTOP,152,105,24,17
+    DEFPUSHBUTTON   "",IDC_BUTTON_FOCUS,0,0,5,5,NOT WS_VISIBLE
+END
+
 IDD_DIALOG_ABOUT DIALOGEX DISCARDABLE  0, 0, 264, 169
-STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 CAPTION "ReactOS °è»ê±â Á¤º¸"
 FONT 8, "MS Shell Dlg"
 BEGIN
     DEFPUSHBUTTON   "OK",IDOK,105,148,52,16
-    CONTROL         106,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | 
+    CONTROL         IDB_BITMAP_ROS,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | 
                     SS_REALSIZEIMAGE | WS_BORDER,4,4,104,48
     LTEXT           "ReactOS °è»ê±â",IDC_STATIC,120,12,132,8,
                     SS_CENTERIMAGE
@@ -251,7 +331,7 @@ BEGIN
 END
 
 IDD_DIALOG_STAT DIALOGEX DISCARDABLE  0, 0, 163, 85
-STYLE DS_SHELLFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 CAPTION "Statistics box"
 FONT 8, "MS Shell Dlg"
 BEGIN
@@ -265,7 +345,6 @@ BEGIN
                     SS_SUNKEN
 END
 
-
 // Menus
 
 IDR_MENU_SCIENTIFIC_1 MENU DISCARDABLE 
@@ -365,3 +444,260 @@ BEGIN
     IDS_QUICKHELP           "ºü¸¥ µµ¿ò¸»"
 END
 
+// types of conversion
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_CONV_AREA           "Area"
+    IDS_CONV_CONSUMPTION    "Consumption (engines)"
+    IDS_CONV_CURRENCY       "Currencies"
+    IDS_CONV_ENERGY         "Energy"
+    IDS_CONV_LENGTH         "Lenghts"
+    IDS_CONV_POWER          "Power"
+    IDS_CONV_PRESSURE       "Pressure"
+    IDS_CONV_TEMPERATURE    "Temperature"
+    IDS_CONV_VELOCITY       "Velocity"
+    IDS_CONV_VOLUME         "Volume"
+    IDS_CONV_WEIGHT         "Weights"
+END
+
+// TYPES OF AREAS
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_AREA_ACRES                  "Acres"
+    IDS_AREA_ACRES_BRAZIL           "Acres (Brazil)"
+    IDS_AREA_ACRES_FRANCE           "Acres (France)"
+    IDS_AREA_ACRES_SCOTS            "Acres (Scots)"
+    IDS_AREA_ACRES_US               "Acres (US)"
+    IDS_AREA_ARES                   "Ares"
+    IDS_AREA_CHOU                   "Chou"
+    IDS_AREA_DANBO                  "Danbo"
+    IDS_AREA_HECTARES               "Hectares"
+    IDS_AREA_JEONGBO                "Jeongbo"
+    IDS_AREA_MORGEN_HUNGARY         "Morgen (Hungary)"
+    IDS_AREA_MU                     "Mu"
+    IDS_AREA_PING                   "Ping"
+    IDS_AREA_PYEONG                 "Pyeong"
+    IDS_AREA_PYEONGBANGJA           "Pyeongbangja"
+    IDS_AREA_RAI                    "Rai"
+    IDS_AREA_SE                     "Se"
+    IDS_AREA_SQUARE_CENTIMETERS     "Square centimeters"
+    IDS_AREA_SQUARE_CHR             "Square chr"
+    IDS_AREA_SQUARE_FATHOMS         "Square fathoms"
+    IDS_AREA_SQUARE_FATHOMS_HUNGARY "Square fathoms (Hungary)"
+    IDS_AREA_SQUARE_FEET            "Square feet"
+    IDS_AREA_SQUARE_INCHES          "Square inches"
+    IDS_AREA_SQUARE_KILOMETERS      "Square kilometers"
+    IDS_AREA_SQUARE_LAR             "Square lar"
+    IDS_AREA_SQUARE_METER           "Square meter"
+    IDS_AREA_SQUARE_MILES           "Square miles"
+    IDS_AREA_SQUARE_MILLIMETERS     "Square millimeters"
+    IDS_AREA_SQUARE_SHAKU           "Square shaku"
+    IDS_AREA_SQUARE_TSUEN           "Square tsuen"
+    IDS_AREA_SQUARE_VA              "Square va"
+    IDS_AREA_SQUARE_YARD            "Square yard"
+    IDS_AREA_TAN                    "Tan"
+    IDS_AREA_TSUBO                  "Tsubo"
+END
+
+// TYPES OF COMSUMPTIONS
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_CONSUMPTION_KM_PER_L        "Kilometer/liter"
+    IDS_CONSUMPTION_L_PER_100_KM    "Liters/100 kilometers"
+    IDS_CONSUMPTION_MILES_GALLON_UK "Miles/gallon (UK)"
+    IDS_CONSUMPTION_MILES_GALLON_US "Miles/gallon (US)"
+END
+
+// TYPES OF CURRENCIES
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_CURRENCY_AUSTRIAN_SCHILLING "Austrian schilling"
+    IDS_CURRENCY_BELGIAN_FRANC      "Belgian franc"
+    IDS_CURRENCY_CYPRIOT_POUND      "Cypriot pound"
+    IDS_CURRENCY_DEUTSCHE_MARK      "Deutsche Mark"
+    IDS_CURRENCY_DUTCH_GUILDER      "Dutch guilder"
+    IDS_CURRENCY_EURO               "Euro"
+    IDS_CURRENCY_FINNISH_MARKKA     "Finnish markka"
+    IDS_CURRENCY_FRENCH_FRANC       "French franc"
+    IDS_CURRENCY_GREEK_DRACHMA      "Greek Drachma"
+    IDS_CURRENCY_IRISH_POUND        "Irish pound"
+    IDS_CURRENCY_ITALIAN_LIRA       "Italian lira"
+    IDS_CURRENCY_LUXEMBOURG_FRANC   "Luxembourg franc"
+    IDS_CURRENCY_MALTESE_LIRA       "Maltese lira"
+    IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portoguese escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slovak koruna"
+    IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovenian tolar"
+    IDS_CURRENCY_SPANISH_PESETA     "Spanish peseta"
+END
+
+// TYPES OF ENERGIES
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_ENERGY_15_C_CALORIES        "15 ^C calories"
+    IDS_ENERGY_ERGS                 "Ergs"
+    IDS_ENERGY_IT_CALORIES          "International Table calories"
+    IDS_ENERGY_JOULES               "Joules"
+    IDS_ENERGY_KILOJOULES           "Kilojoules"
+    IDS_ENERGY_KILOWATT_HOURS       "Kilowatt hours"
+    IDS_ENERGY_NUTRITION_CALORIES   "Nutrition calories"
+    IDS_ENERGY_TH_CALORIES          "Thermochemical calorie"
+END
+
+// TYPES OF LENGTHS
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_LENGTH_ANGSTROMS            "Angstroms"
+    IDS_LENGTH_ASTRONOMILA_UNITS    "Astronomila units"
+    IDS_LENGTH_BARLEYCORNS          "Barleycorns"
+    IDS_LENGTH_CENTIMETERS          "Centimeters"
+    IDS_LENGTH_CHAINS_UK            "Chains (UK)"
+    IDS_LENGTH_CHI                  "Chi"
+    IDS_LENGTH_CHOU                 "Chou"
+    IDS_LENGTH_CHR                  "Chr"
+    IDS_LENGTH_CUN                  "Cun"
+    IDS_LENGTH_FATHOMS              "Fathoms"
+    IDS_LENGTH_FATHOMS_HUNGARY      "Fathoms (Hungary)"
+    IDS_LENGTH_FEET                 "Feet"
+    IDS_LENGTH_FURLONGS             "Furlongs"
+    IDS_LENGTH_GAN                  "Gan"
+    IDS_LENGTH_HANDS                "Hands"
+    IDS_LENGTH_HUNH                 "Hunh"
+    IDS_LENGTH_INCHES               "Inches"
+    IDS_LENGTH_JA                   "Ja"
+    IDS_LENGTH_JEONG                "Jeong"
+    IDS_LENGTH_KABIET               "Kabiet"
+    IDS_LENGTH_KEN                  "Ken"
+    IDS_LENGTH_KEUB                 "Keub"
+    IDS_LENGTH_KILOMETERS           "Kilometers"
+    IDS_LENGTH_LAR                  "Lar"
+    IDS_LENGTH_LIGHT_YEARS          "Light years"
+    IDS_LENGTH_LINKS_UK             "Links (UK)"
+    IDS_LENGTH_METERS               "Meters"
+    IDS_LENGTH_MILES                "Miles"
+    IDS_LENGTH_MILLIMETERS          "Millimeters"
+    IDS_LENGTH_NAUTICAL_MILES       "Nautical miles"
+    IDS_LENGTH_NIEU                 "Nieu"
+    IDS_LENGTH_PARSECS              "Parsecs"
+    IDS_LENGTH_PICAS                "Picas"
+    IDS_LENGTH_RI_JAPAN             "Ri (Japan)"
+    IDS_LENGTH_RI_KOREA             "Ri (Korea)"
+    IDS_LENGTH_SAWK                 "Sawk"
+    IDS_LENGTH_SEN                  "Sen"
+    IDS_LENGTH_SHAKU                "Shaku"
+    IDS_LENGTH_SPAN                 "Span"
+    IDS_LENGTH_SUN                  "Sun"
+    IDS_LENGTH_TSUEN                "Tsuen"
+    IDS_LENGTH_VA                   "Va"
+    IDS_LENGTH_YARDS                "Yards"
+    IDS_LENGTH_YOTE                 "Yote"
+    IDS_LENGTH_ZHANG                "Zhang"
+END
+
+// TYPES OF POWERS
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_POWER_HORSEPOWER            "Horsepower"
+    IDS_POWER_KILOWATTS             "Kilowatts"
+    IDS_POWER_MEGAWATTS             "Megawatts"
+    IDS_POWER_WATTS                 "Watts"
+END
+
+// TYPE OF PRESSURES
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_PRESSURE_ATMOSPHERES        "Atmospheres"
+    IDS_PRESSURE_BARS               "Bars"
+    IDS_PRESSURE_MM_OF_MERCURY      "Millimeters of mercury"
+    IDS_PRESSURE_PASCALS            "Pascals"
+    IDS_PRESSURE_PSI                "Pounds-force per square inch"
+END
+
+// TYPES OF TEMPERATURES
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_TEMPERATURE_CELSIUS         "Celsius"
+    IDS_TEMPERATURE_FAHRENHEIT      "Fahrenheit"
+    IDS_TEMPERATURE_KELVIN          "Kelvin"
+    IDS_TEMPERATURE_RANKINE         "Rankine"
+END
+
+// TYPES OF VELOCITIES
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_VELOCITY_FEET_HOUR          "Feet/hour"
+    IDS_VELOCITY_KILOMETERS_HOUR    "Kilometers/hour"
+    IDS_VELOCITY_KNOTS              "Knots"
+    IDS_VELOCITY_MACH               "Mach"
+    IDS_VELOCITY_METERS_SECOND      "Meters/second"
+    IDS_VELOCITY_MILES_HOUR         "Miles/hour"
+END
+
+// TYPES OF VOLUMES
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_VOLUME_BARRELS_UK           "Barrels (UK)"
+    IDS_VOLUME_BARRELS_OIL          "Barrels oil"
+    IDS_VOLUME_BUN                  "Bun"
+    IDS_VOLUME_BUSHELS_UK           "Bushels (UK)"
+    IDS_VOLUME_BUSHELS_US           "Bushels (US)"
+    IDS_VOLUME_CUBIC_CENTIMETERS    "Cubic centimeters"
+    IDS_VOLUME_CUBIC_FEET           "Cubic feet"
+    IDS_VOLUME_CUBIC_INCHES         "Cubic inches"
+    IDS_VOLUME_CUBIC_METERS         "Cubic meters"
+    IDS_VOLUME_CUBIC_YARDS          "Cubic yards"
+    IDS_VOLUME_DOE                  "Doe"
+    IDS_VOLUME_FLUID_OUNCES_UK      "Fluid ounces (UK)"
+    IDS_VOLUME_FLUID_OUNCES_US      "Fluid ounces (US)"
+    IDS_VOLUME_GALLONS_UK           "Gallons (UK)"
+    IDS_VOLUME_GALLONS_DRY_US       "Gallons, dry (US)"
+    IDS_VOLUME_GALLONS_LIQUID_US    "Gallons, liquid (US)"
+    IDS_VOLUME_GOU                  "Gou"
+    IDS_VOLUME_HOP                  "Hop"
+    IDS_VOLUME_ICCE                 "Icce"
+    IDS_VOLUME_KWIAN                "Kwian"
+    IDS_VOLUME_LITERS               "Liters"
+    IDS_VOLUME_MAL                  "Mal"
+    IDS_VOLUME_MILLILITERS          "Milliliters"
+    IDS_VOLUME_PINTS_UK             "Pints (UK)"
+    IDS_VOLUME_PINTS_DRY_US         "Pints, dry (US)"
+    IDS_VOLUME_PINTS_LIQUID_US      "Pints, liquid (US)"
+    IDS_VOLUME_QUARTS_UK            "Quarts (UK)"
+    IDS_VOLUME_QUARTS_DRY_US        "Quarts, dry (US)"
+    IDS_VOLUME_QUARTS_LIQUID_US     "Quarts, liquid (US)"
+    IDS_VOLUME_SEKI                 "Seki"
+    IDS_VOLUME_SYOU                 "Syou"
+    IDS_VOLUME_TANANLOUNG           "Tananloung"
+    IDS_VOLUME_TANG                 "Tang"
+    IDS_VOLUME_TO                   "To"
+END
+
+// TYPES OF WEIGHTS
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_WEIGHT_BAHT                 "Baht"
+    IDS_WEIGHT_CARATS               "Carats"
+    IDS_WEIGHT_CHUNG                "Chung"
+    IDS_WEIGHT_DON                  "Don"
+    IDS_WEIGHT_GEUN                 "Geun"
+    IDS_WEIGHT_GRAMS                "Grams"
+    IDS_WEIGHT_GWAN                 "Gwan"
+    IDS_WEIGHT_HARB                 "Harb"
+    IDS_WEIGHT_JIN_CHINA            "Jin (China)"
+    IDS_WEIGHT_JIN_TAIWAN           "Jin (Taiwan)"
+    IDS_WEIGHT_KAN                  "Kan"
+    IDS_WEIGHT_KILOGRAMS            "Kilograms"
+    IDS_WEIGHT_KIN                  "Kin"
+    IDS_WEIGHT_LIANG_CHINA          "Liang (China)"
+    IDS_WEIGHT_LIANG_TAIWAN         "Liang (Taiwan)"
+    IDS_WEIGHT_MONME                "Monme"
+    IDS_WEIGHT_OUNCES_AVOIRDUPOIS   "Ounces, avoirdupois"
+    IDS_WEIGHT_OUNCES_TROY          "Ounces, troy"
+    IDS_WEIGHT_POUNDS               "Pounds"
+    IDS_WEIGHT_QUINTAL_METRIC       "Quintal (metric)"
+    IDS_WEIGHT_SALOUNG              "Saloung"
+    IDS_WEIGHT_STONES               "Stones"
+    IDS_WEIGHT_TAMLUNG              "Tamlung"
+    IDS_WEIGHT_TONNES               "Tonnes"
+    IDS_WEIGHT_TONS_UK              "Tons (UK)"
+    IDS_WEIGHT_TONS_US              "Tons (US)"
+END
index 4c8e427..f62e0bf 100644 (file)
@@ -1,4 +1,3 @@
-
 LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
 
 // Dialog
@@ -523,6 +522,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Luxembourg franc"
     IDS_CURRENCY_MALTESE_LIRA       "Maltese lira"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portoguese escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slowaakse kroon"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovenian tolar"
     IDS_CURRENCY_SPANISH_PESETA     "Spanish peseta"
 END
index 32714c9..bb2937d 100644 (file)
@@ -518,6 +518,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Luxembourg franc"
     IDS_CURRENCY_MALTESE_LIRA       "Maltese lira"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portoguese escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slovakisk koruna"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovenian tolar"
     IDS_CURRENCY_SPANISH_PESETA     "Spanish peseta"
 END
index b5f73ff..4ddd2e9 100644 (file)
@@ -529,6 +529,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Luksemburski frank"
     IDS_CURRENCY_MALTESE_LIRA       "Maltañskie liry"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portugalskie escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "S³owacka korona"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "S³oveñski tolar"
     IDS_CURRENCY_SPANISH_PESETA     "Hiszpañska peseta"
 END
index 41f94b4..2b0a589 100644 (file)
@@ -522,6 +522,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Ëþêñåìáóðãñêèé ôðàíê"
     IDS_CURRENCY_MALTESE_LIRA       "Ìàëüòèéñêàÿ ëèðà"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Ïîðòóãàëüñêîå ýñêóäî"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Ñëîâàöêàÿ êðîíà"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Ñëîâåíñêèé òîëàð"
     IDS_CURRENCY_SPANISH_PESETA     "Èñïàíñêàÿ ïåñåòà"
 END
index 2081cd1..9ba44c3 100644 (file)
@@ -1,6 +1,6 @@
 /* TRANSLATOR :  Mário Kaèmár /Mario Kacmar/ aka Kario (kario@szm.sk)
  * DATE OF TR.:  30-01-2008
- * LAST CHANGE:  30-08-2008
+ * LAST CHANGE:  29-12-2008
  * ---------------------------------------
  * TODO:
  * 1. treba usporiada\9d jednotky pod¾a abecedy
@@ -350,7 +350,6 @@ BEGIN
                     SS_SUNKEN
 END
 
-
 // Menus
 
 IDR_MENU_SCIENTIFIC_1 MENU DISCARDABLE 
@@ -531,6 +530,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Luxembourg franc"
     IDS_CURRENCY_MALTESE_LIRA       "Maltese lira"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portoguese escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Slovenská koruna"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovinský toliar"
     IDS_CURRENCY_SPANISH_PESETA     "\8apanielska peseta"
 END
index fcc7e7f..dd133c2 100644 (file)
@@ -530,6 +530,7 @@ BEGIN
     IDS_CURRENCY_LUXEMBOURG_FRANC   "Luxembourg franc"
     IDS_CURRENCY_MALTESE_LIRA       "Maltese lira"
     IDS_CURRENCY_PORTOGUESE_ESCUDO  "Portoguese escudo"
+    IDS_CURRENCY_SLOVAK_KORUNA      "Ñëîâàöüêà êðîíà"
     IDS_CURRENCY_SLOVENIAN_TOLAR    "Slovenian tolar"
     IDS_CURRENCY_SPANISH_PESETA     "Spanish peseta"
 END
index d49db7a..add3f98 100644 (file)
 #define IDS_CURRENCY_LUXEMBOURG_FRANC   2311
 #define IDS_CURRENCY_MALTESE_LIRA       2312
 #define IDS_CURRENCY_PORTOGUESE_ESCUDO  2313
-#define IDS_CURRENCY_SLOVENIAN_TOLAR    2314
-#define IDS_CURRENCY_SPANISH_PESETA     2315
+#define IDS_CURRENCY_SLOVAK_KORUNA      2314
+#define IDS_CURRENCY_SLOVENIAN_TOLAR    2315
+#define IDS_CURRENCY_SPANISH_PESETA     2316
 
 /* TYPES OF ENERGIES */
 #define IDS_ENERGY_15_C_CALORIES        2400
index 451c7af..87ab64f 100644 (file)
@@ -31,7 +31,7 @@ int _tmain(int argc, TCHAR ** argv)
                return -1;
        }
 
-       if (_tcsstr(argv[1], "--winetest") && (argc == 3)) 
+       if (_tcsstr(argv[1], "--winetest") && (argc == 3))
        {
                char   psBuffer[128];
                char   psBuffer2[128];
@@ -63,6 +63,7 @@ int _tmain(int argc, TCHAR ** argv)
                                                        char *nlptr2 = strchr(psBuffer2, '\n');
                                                        if (nlptr2)
                                                                *nlptr2 = '\0';
+                                                       puts(psBuffer2);
                                                        OutputDebugStringA(psBuffer2);
                                                }
                                                _pclose(pPipe2);
@@ -72,7 +73,7 @@ int _tmain(int argc, TCHAR ** argv)
                        _pclose(pPipe);
                }
        }
-       else if (_tcsstr(argv[1], "--process") && (argc == 3)) 
+       else if (_tcsstr(argv[1], "--process") && (argc == 3))
        {
                char   psBuffer[128];
                FILE   *pPipe;
@@ -82,6 +83,7 @@ int _tmain(int argc, TCHAR ** argv)
                {
                        while(fgets(psBuffer, 128, pPipe))
                        {
+                               puts(psBuffer);
                                OutputDebugStringA(psBuffer);
                        }
                        _pclose(pPipe);
@@ -112,6 +114,7 @@ int _tmain(int argc, TCHAR ** argv)
                        }
                        offset++;
                }
+               _putts(buf);
                OutputDebugString(buf);
                HeapFree(GetProcessHeap(), 0, buf);
        }
index 31f8028..190e2c2 100644 (file)
@@ -50,7 +50,7 @@ BEGIN
     IDS_SOL_ABOUT   "Solitaire by J Brown\n\nCardLib version 1.0."
     IDS_SOL_QUIT    "Äà ïðåêðàòÿ ëè èãðàòà?"
     IDS_SOL_WIN     "Ïîçäðàâëåíèÿ, ïîáåäèõòå!!"
-    IDS_SOL_DEAL    "Deal again?"
+    IDS_SOL_DEAL    "Íîâî ðàçäàâàíå?"
 END
 
 
index e642fc5..18e2d62 100644 (file)
@@ -588,7 +588,7 @@ int TMapLoader::Load(const char * filename, const char * szActiveEmul) {
 #ifdef KEYDEBUG
                        printit("\r                                                                      \r");
 #endif
-                       AllOk = SA.Add(temps);;
+                       AllOk = SA.Add(temps);
                        if ( !AllOk ) break;
                } else {
                        //       cerr << "Unexpected line '" << buf << "'\n";
index 5cbb669..011686b 100644 (file)
@@ -143,7 +143,7 @@ struct cmdHistory * cfgets (char *buf, unsigned int length, struct cmdHistory *c
                                        MustRefresh = 1;
                                        break;
                                case VK_RIGHT:          //crn@ozemail.com.au (added ctrl+arrow)
-                                       if (cursor < current)
+                                       if (cursor < current) {
                                                if (InputRecord.Event.KeyEvent.dwControlKeyState &
                                                        (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
                                                        unsigned int j, k;
@@ -159,8 +159,9 @@ struct cmdHistory * cfgets (char *buf, unsigned int length, struct cmdHistory *c
                                                        cursor++;
                                                MustRefresh = 1;
                                                break;
+                                       }
                                case VK_LEFT:           //crn@ozemail.com.au (added ctrl+arrow)
-                                       if (cursor > 0)
+                                       if (cursor > 0) {
                                                if(InputRecord.Event.KeyEvent.dwControlKeyState &
                                                        (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
                                                        int j, k;
@@ -176,6 +177,7 @@ struct cmdHistory * cfgets (char *buf, unsigned int length, struct cmdHistory *c
                                                        cursor--;
                                                MustRefresh = 1;
                                                break;
+                                       }
                                case VK_HOME:
                                        if (cursor>0) cursor = 0;
                                        MustRefresh = 1;
index 7dc02ce..1c35b54 100644 (file)
@@ -676,16 +676,15 @@ VOID DIALOG_EditTimeDate(VOID)
 {
     SYSTEMTIME   st;
     TCHAR        szDate[MAX_STRING_LEN];
-    static const TCHAR space[] = _T(" ");
+    TCHAR        szText[MAX_STRING_LEN * 2 + 2];
 
     GetLocalTime(&st);
 
     GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szDate, MAX_STRING_LEN);
-    SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);
-
-    SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)space);
-
+    _tcscpy(szText, szDate);
+    _tcscat(szText, _T(" "));
     GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szDate, MAX_STRING_LEN);
+    _tcscat(szText, szDate);
     SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);
 }
 
index 20aa32c..39ed8e5 100644 (file)
@@ -29,7 +29,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -40,54 +42,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Ôàéë"
-       BEGIN
-               MENUITEM "&Íîâ...",           CMD_NEW
-               MENUITEM "&Îòâàðÿíå\tCtrl+O",     CMD_OPEN
-               MENUITEM "&Çàïèñ\tCtrl+S",     CMD_SAVE
-               MENUITEM "Çàïèñ &êàòî...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Íàñòðîéêà íà ñòðàíèöàòà...",    CMD_PAGE_SETUP
-               MENUITEM "Îò&ïå÷àòâàíå",            CMD_PRINT
-               MENUITEM "Íàñòðîéêà íà ïå÷àòà÷à...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "Èç&õîä",             CMD_EXIT
-       END
-       POPUP "&Îáðàáîòêà"
-       BEGIN
-               MENUITEM "&Îòìÿíà\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Îò&ðÿçâàíå\tCtrl+X",      CMD_CUT
-               MENUITEM "&Çàïîìíÿíå\tCtrl+C",     CMD_COPY
-               MENUITEM "&Ïîñòàâÿíå\tCtrl+V",    CMD_PASTE
-               MENUITEM "&Èçòðèâàíå\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Òúðñåíå...\tCtrl+F",  CMD_SEARCH
-               MENUITEM "Òúðñåíå íà &ñëåäâàùîòî\tF3",    CMD_SEARCH_NEXT
-               MENUITEM "Çàìÿíà\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Îòèâàíå íà...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Èçáîð íà âñè&÷êè\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "&Âðåìå/äàòà\tF5",    CMD_TIME_DATE
-       END
-       POPUP "Î&ôîðìëåíèå"
-       BEGIN
-               MENUITEM "&Ïðåíàñÿíå íà äúëãèòå ðåäîâå",  CMD_WRAP
-               MENUITEM "&Øðèôò...",          CMD_FONT
-       END
-       POPUP "&Èçãëåä"
-       BEGIN
-               MENUITEM "Ëåíòà íà &ñúñòîÿíèåòî",    CMD_STATUSBAR
-       END
-       POPUP "Ïîìî&ù"
-       BEGIN
-               MENUITEM "&Ñúäúðæàíèå",         CMD_HELP_CONTENTS
-               MENUITEM "&Òúðñåíå...",        CMD_HELP_SEARCH
-               MENUITEM "&Ïîìîù çà ïîìîùòà",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Çà"             CMD_ABOUT
-               MENUITEM "Ñ&âåäåíèÿ",      CMD_ABOUT_WINE
-       END
+    POPUP "&Ôàéë"
+    BEGIN
+        MENUITEM "&Íîâ\tCtrl+N",               CMD_NEW
+        MENUITEM "&Îòâàðÿíå\tCtrl+O",          CMD_OPEN
+        MENUITEM "&Çàïèñ\tCtrl+S",             CMD_SAVE
+        MENUITEM "Çàïèñ &êàòî...",             CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Íàñòðîéêà íà ñòðàíèöàòà...", CMD_PAGE_SETUP
+        MENUITEM "Îò&ïå÷àòâàíå\tCtrl+P",       CMD_PRINT
+        MENUITEM "Íàñòðîéêà íà ïå÷àòà÷à...",   CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Èç&õîä",                     CMD_EXIT
+    END
+    POPUP "&Îáðàáîòêà"
+    BEGIN
+        MENUITEM "&Îòìÿíà\tCtrl+Z",            CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Îò&ðÿçâàíå\tCtrl+X",         CMD_CUT
+        MENUITEM "&Çàïîìíÿíå\tCtrl+C",         CMD_COPY
+        MENUITEM "&Ïîñòàâÿíå\tCtrl+V",         CMD_PASTE
+        MENUITEM "&Èçòðèâàíå\tDel",            CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Òúðñåíå...\tCtrl+F",        CMD_SEARCH
+        MENUITEM "Òúðñåíå íà &ñëåäâàùîòî\tF3", CMD_SEARCH_NEXT
+        MENUITEM "Çàìÿíà\tCtrl+H",             CMD_REPLACE
+        MENUITEM "Îòèâàíå íà...\tCtrl+G",      CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Èçáîð íà âñè&÷êè\tCtrl+A",   CMD_SELECT_ALL
+        MENUITEM "&Âðåìå/äàòà\tF5",            CMD_TIME_DATE
+    END
+    POPUP "Î&ôîðìëåíèå"
+    BEGIN
+        MENUITEM "&Ïðåíàñÿíå íà äúëãèòå ðåäîâå", CMD_WRAP
+        MENUITEM "&Øðèôò...",                    CMD_FONT
+    END
+    POPUP "&Èçãëåä"
+    BEGIN
+        MENUITEM "Ëåíòà íà &ñúñòîÿíèåòî", CMD_STATUSBAR
+    END
+    POPUP "Ïîìî&ù"
+    BEGIN
+        MENUITEM "&Ñúäúðæàíèå",       CMD_HELP_CONTENTS
+        MENUITEM "&Òúðñåíå...",       CMD_HELP_SEARCH
+        MENUITEM "&Ïîìîù çà ïîìîùòà", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Çà"                CMD_ABOUT
+        MENUITEM "Ñ&âåäåíèÿ",         CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
@@ -201,5 +203,5 @@ STRING_UTF8,                                    "UTF-8"
 STRING_CRLF,                                    "Óüèíäîóüñ"
 STRING_LF,                                      "Þíèêñ"
 STRING_CR,                                      "Ìàê"
-STRING_LINE_COLUMN,                             "Line %d, column %d"
+STRING_LINE_COLUMN,                             "Ðåä %d, ñòúëá %d"
 END
index 065f051..4a46efa 100644 (file)
@@ -31,7 +31,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -42,54 +44,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Soubor"
-       BEGIN
-               MENUITEM "&Nový...",               CMD_NEW
-               MENUITEM "&Otevøít\tCtrl+O",       CMD_OPEN
-               MENUITEM "&Ulo\9eit\tCtrl+S",        CMD_SAVE
-               MENUITEM "Ulo\9eit j&ako...",        CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Tisk",                  CMD_PRINT
-               MENUITEM "Nas&tavení stránky...",  CMD_PAGE_SETUP
-               MENUITEM "Nastavení tiská&rny...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Konec",                 CMD_EXIT
-       END
-       POPUP "U&pravit"
-       BEGIN
-               MENUITEM "&Zpìt\tCtrl+Z",          CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Vyjmou&t\tCtrl+X",       CMD_CUT
-               MENUITEM "&Kopírovat\tCtrl+C",     CMD_COPY
-               MENUITEM "&Vlo\9eit\tCtrl+V",        CMD_PASTE
-               MENUITEM "&Smazat\tDel",           CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Hledej\tCtrl+F",        CMD_SEARCH
-               MENUITEM "&Najdi dal\9aí\tF3",       CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Vybrat v\9a&e\tCtrl+A",    CMD_SELECT_ALL
-               MENUITEM "È&as/Datum\tF5",         CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "Zalo&mit dlouhé øádky",  CMD_WRAP
-               MENUITEM "&Písmo...",              CMD_FONT
-       END
-       POPUP "&Zobrazit"
-       BEGIN
-               MENUITEM "&Stavový øádek",    CMD_STATUSBAR
-       END
-       POPUP "&Nápovìda"
-       BEGIN
-               MENUITEM "&Obsah",                 CMD_HELP_CONTENTS
-               MENUITEM "&Najít...",              CMD_HELP_SEARCH
-               MENUITEM "&Pomoc k nápovìdì",      CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&O programu"                  CMD_ABOUT
-               MENUITEM "Inf&o...",               CMD_ABOUT_WINE
-       END
+    POPUP "&Soubor"
+    BEGIN
+        MENUITEM "&Nový\tCtrl+N",          CMD_NEW
+        MENUITEM "&Otevøít\tCtrl+O",       CMD_OPEN
+        MENUITEM "&Ulo\9eit\tCtrl+S",        CMD_SAVE
+        MENUITEM "Ulo\9eit j&ako...",        CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Tisk\tCtrl+P",          CMD_PRINT
+        MENUITEM "Nas&tavení stránky...",  CMD_PAGE_SETUP
+        MENUITEM "Nastavení tiská&rny...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Konec",                 CMD_EXIT
+    END
+    POPUP "U&pravit"
+    BEGIN
+        MENUITEM "&Zpìt\tCtrl+Z",       CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Vyjmou&t\tCtrl+X",    CMD_CUT
+        MENUITEM "&Kopírovat\tCtrl+C",  CMD_COPY
+        MENUITEM "&Vlo\9eit\tCtrl+V",     CMD_PASTE
+        MENUITEM "&Smazat\tDel",        CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Hledej\tCtrl+F",     CMD_SEARCH
+        MENUITEM "&Najdi dal\9aí\tF3",    CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",     CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",    CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Vybrat v\9a&e\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "È&as/Datum\tF5",      CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "Zalo&mit dlouhé øádky", CMD_WRAP
+        MENUITEM "&Písmo...",             CMD_FONT
+    END
+    POPUP "&Zobrazit"
+    BEGIN
+        MENUITEM "&Stavový øádek", CMD_STATUSBAR
+    END
+    POPUP "&Nápovìda"
+    BEGIN
+        MENUITEM "&Obsah",            CMD_HELP_CONTENTS
+        MENUITEM "&Najít...",         CMD_HELP_SEARCH
+        MENUITEM "&Pomoc k nápovìdì", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&O programu"        CMD_ABOUT
+        MENUITEM "Inf&o...",          CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 44ecfbc..9f02960 100644 (file)
@@ -28,7 +28,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -39,54 +41,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Fil"
-       BEGIN
-               MENUITEM "&Ny...",            CMD_NEW
-               MENUITEM "Å&bn\tEnter",       CMD_OPEN
-               MENUITEM "&Gem",              CMD_SAVE
-               MENUITEM "Gem so&m...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Side&opsætning...", CMD_PAGE_SETUP
-               MENUITEM "&Udskriv",          CMD_PRINT
-               MENUITEM "&Indstil printer...",       CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Afslut",           CMD_EXIT
-       END
-       POPUP "&Rediger"
-       BEGIN
-               MENUITEM "&Fortryd\tCtrl+Z",  CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Klip\tCtrl+X",     CMD_CUT
-               MENUITEM "K&opier\tCtrl+C",   CMD_COPY
-               MENUITEM "Sæt &ind\tCtrl+V",  CMD_PASTE
-               MENUITEM "&Slet\tDel",        CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Søg...",           CMD_SEARCH
-               MENUITEM "&Find næste\tF3",   CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Marker &alt",       CMD_SELECT_ALL
-               MENUITEM "&Dato/tid\tF5",     CMD_TIME_DATE
-       END
-       POPUP "&Søg"
-       BEGIN
-               MENUITEM "&Wrap long lines",  CMD_WRAP
-               MENUITEM "&Font...",          CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
+    POPUP "&Fil"
+    BEGIN
+        MENUITEM "&Ny\tCtrl+N",         CMD_NEW
+        MENUITEM "Å&bn\tEnter",         CMD_OPEN
+        MENUITEM "&Gem",                CMD_SAVE
+        MENUITEM "Gem so&m...",         CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Side&opsætning...",   CMD_PAGE_SETUP
+        MENUITEM "&Udskriv\tCtrl+P",    CMD_PRINT
+        MENUITEM "&Indstil printer...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Afslut",             CMD_EXIT
+    END
+    POPUP "&Rediger"
+    BEGIN
+        MENUITEM "&Fortryd\tCtrl+Z", CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Klip\tCtrl+X",    CMD_CUT
+        MENUITEM "K&opier\tCtrl+C",  CMD_COPY
+        MENUITEM "Sæt &ind\tCtrl+V", CMD_PASTE
+        MENUITEM "&Slet\tDel",       CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Søg...",          CMD_SEARCH
+        MENUITEM "&Find næste\tF3",  CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",  CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G", CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Marker &alt",      CMD_SELECT_ALL
+        MENUITEM "&Dato/tid\tF5",    CMD_TIME_DATE
+    END
+    POPUP "&Søg"
+    BEGIN
+        MENUITEM "&Wrap long lines", CMD_WRAP
+        MENUITEM "&Font...",         CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
         END
-       POPUP "&Hjælp"
-       BEGIN
-               MENUITEM "&Indhold",          CMD_HELP_CONTENTS
-               MENUITEM "&Søg efter hjælp om...",    CMD_HELP_SEARCH
-               MENUITEM "&Brug af Hjælp",    CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "&Om Notesblok",         CMD_ABOUT_WINE
-       END
+    POPUP "&Hjælp"
+    BEGIN
+        MENUITEM "&Indhold",               CMD_HELP_CONTENTS
+        MENUITEM "&Søg efter hjælp om...", CMD_HELP_SEARCH
+        MENUITEM "&Brug af Hjælp",         CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"                  CMD_ABOUT
+        MENUITEM "&Om Notesblok",          CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index e64bd1c..34ae54e 100644 (file)
@@ -29,7 +29,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -40,54 +42,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Datei"
-       BEGIN
-               MENUITEM "&Neu...",           CMD_NEW
-               MENUITEM "Ö&ffnen...",        CMD_OPEN
-               MENUITEM "&Speichern",        CMD_SAVE
-               MENUITEM "Speichern &unter...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Seite ein&richten...",      CMD_PAGE_SETUP
-               MENUITEM "&Drucken",          CMD_PRINT
-               MENUITEM "Drucker&einrichtung...",    CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Beenden",          CMD_EXIT
-       END
-       POPUP "&Bearbeiten"
-       BEGIN
-               MENUITEM "&Rückgängig\tStrg+Z",       CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Ausschneiden\tStrg+X",     CMD_CUT
-               MENUITEM "&Kopieren\tStrg+C",         CMD_COPY
-               MENUITEM "&Einfügen\tStrg+V",         CMD_PASTE
-               MENUITEM "&Löschen\tEntf",    CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "Suchen...", CMD_SEARCH
-               MENUITEM "&Weitersuchen\tF3", CMD_SEARCH_NEXT
-               MENUITEM "&Ersetzen\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Gehe zu...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Alles &markieren",  CMD_SELECT_ALL
-               MENUITEM "&Uhrzeit/Datum\tF5",        CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Zeilenumbruch",    CMD_WRAP
-               MENUITEM "&Schriftart...",      CMD_FONT
-       END
-       POPUP "&Ansicht"
-       BEGIN
-               MENUITEM "Status&leiste",    CMD_STATUSBAR
-       END
-       POPUP "&Hilfe"
-       BEGIN
-               MENUITEM "&Inhalt",           CMD_HELP_CONTENTS
-               MENUITEM "&Suchen...",        CMD_HELP_SEARCH
-               MENUITEM "&Hilfe benutzen",   CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Über"             CMD_ABOUT
-               MENUITEM "Inf&o",       CMD_ABOUT_WINE
-       END
+    POPUP "&Datei"
+    BEGIN
+        MENUITEM "&Neu\tStrg+N",           CMD_NEW
+        MENUITEM "Ö&ffnen\tStrg+O",        CMD_OPEN
+        MENUITEM "&Speichern\tStrg+S",     CMD_SAVE
+        MENUITEM "Speichern &unter...",    CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Seite ein&richten...",   CMD_PAGE_SETUP
+        MENUITEM "&Drucken\tStrg+P",        CMD_PRINT
+        MENUITEM "Drucker&einrichtung...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Beenden",               CMD_EXIT
+    END
+    POPUP "&Bearbeiten"
+    BEGIN
+        MENUITEM "&Rückgängig\tStrg+Z",   CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Ausschneiden\tStrg+X", CMD_CUT
+        MENUITEM "&Kopieren\tStrg+C",     CMD_COPY
+        MENUITEM "&Einfügen\tStrg+V",     CMD_PASTE
+        MENUITEM "&Löschen\tEntf",        CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "Suchen...",             CMD_SEARCH
+        MENUITEM "&Weitersuchen\tF3",     CMD_SEARCH_NEXT
+        MENUITEM "&Ersetzen\tStrg+H",     CMD_REPLACE
+        MENUITEM "Gehe zu...\tStrg+G",    CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Alles &markieren",      CMD_SELECT_ALL
+        MENUITEM "&Uhrzeit/Datum\tF5",    CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Zeilenumbruch", CMD_WRAP
+        MENUITEM "&Schriftart...", CMD_FONT
+    END
+    POPUP "&Ansicht"
+    BEGIN
+        MENUITEM "Status&leiste", CMD_STATUSBAR
+    END
+    POPUP "&Hilfe"
+    BEGIN
+        MENUITEM "&Inhalt",         CMD_HELP_CONTENTS
+        MENUITEM "&Suchen...",      CMD_HELP_SEARCH
+        MENUITEM "&Hilfe benutzen", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Über"            CMD_ABOUT
+        MENUITEM "Inf&o",           CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 8be10f8..fece828 100644 (file)
@@ -27,7 +27,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -38,54 +40,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Áñ÷åßï"
-       BEGIN
-               MENUITEM "&ÍÝï...",           CMD_NEW
-               MENUITEM "&¢íïéãìá\tCtrl+O",     CMD_OPEN
-               MENUITEM "ÁðïèÞêåõ&óç\tCtrl+S",     CMD_SAVE
-               MENUITEM "ÁðïèÞêåõóç &ùò...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Å&ðéëïãÝò óåëßäáò...",    CMD_PAGE_SETUP
-               MENUITEM "&Åêôýðùóç",            CMD_PRINT
-               MENUITEM "ÅðéëïãÝò åê&ôõðùôÞ ...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "¸&îïäïò",             CMD_EXIT
-       END
-       POPUP "&Edit"
-       BEGIN
-               MENUITEM "Á&íáßñåóç\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Áðïêï&ðÞ\tCtrl+X",      CMD_CUT
-               MENUITEM "&ÁíôéãñáöÞ\tCtrl+C",     CMD_COPY
-               MENUITEM "&Åðéêüëëçóç\tCtrl+V",    CMD_PASTE
-               MENUITEM "&ÄéáãñáöÞ\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Åýñåóç...\tCtrl+F",  CMD_SEARCH
-               MENUITEM "Åýñåóç å&ðüìåíïõ\tF3",    CMD_SEARCH_NEXT
-               MENUITEM "ÁíôéêáôÜóôáóç\tCtrl+H",   CMD_REPLACE
-               MENUITEM "&ÌåôÜâáóç óôï...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "ÅðéëïãÞ &¼ëùí\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "&¿ñá/Çìåñïìçíßá\tF5",    CMD_TIME_DATE
-       END
-       POPUP "Ö&ïñìÜ"
-       BEGIN
-               MENUITEM "&ÅìöÜíéóç ìåãÜëùí ãñáììþí",  CMD_WRAP
-               MENUITEM "&ÃñáììáôïóåéñÜ...",          CMD_FONT
-       END
-       POPUP "&ÅìöÜíéóç"
-       BEGIN
-               MENUITEM "ÃñáììÞ &êáôÜóôáóçò",    CMD_STATUSBAR
-       END
-       POPUP "&ÂïÞèåéá"
-       BEGIN
-               MENUITEM "&Ðåñéå÷üìåíá",         CMD_HELP_CONTENTS
-               MENUITEM "&ÁíáæÞôçóç...",        CMD_HELP_SEARCH
-               MENUITEM "&ÂïÞèåéá óôç âïÞèåéá",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "Ðëçñï&öïñßåò",      CMD_ABOUT_WINE
-       END
+    POPUP "&Áñ÷åßï"
+    BEGIN
+        MENUITEM "&ÍÝï\tCtrl+N",           CMD_NEW
+        MENUITEM "&¢íïéãìá\tCtrl+O",       CMD_OPEN
+        MENUITEM "ÁðïèÞêåõ&óç\tCtrl+S",    CMD_SAVE
+        MENUITEM "ÁðïèÞêåõóç &ùò...",      CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Å&ðéëïãÝò óåëßäáò...",   CMD_PAGE_SETUP
+        MENUITEM "&Åêôýðùóç\tCtrl+P",      CMD_PRINT
+        MENUITEM "ÅðéëïãÝò åê&ôõðùôÞ ...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "¸&îïäïò",                CMD_EXIT
+    END
+    POPUP "&Edit"
+    BEGIN
+        MENUITEM "Á&íáßñåóç\tCtrl+Z",        CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Áðïêï&ðÞ\tCtrl+X",         CMD_CUT
+        MENUITEM "&ÁíôéãñáöÞ\tCtrl+C",       CMD_COPY
+        MENUITEM "&Åðéêüëëçóç\tCtrl+V",      CMD_PASTE
+        MENUITEM "&ÄéáãñáöÞ\tDel",           CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Åýñåóç...\tCtrl+F",       CMD_SEARCH
+        MENUITEM "Åýñåóç å&ðüìåíïõ\tF3",     CMD_SEARCH_NEXT
+        MENUITEM "ÁíôéêáôÜóôáóç\tCtrl+H",    CMD_REPLACE
+        MENUITEM "&ÌåôÜâáóç óôï...\tCtrl+G", CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "ÅðéëïãÞ &¼ëùí\tCtrl+A",    CMD_SELECT_ALL
+        MENUITEM "&¿ñá/Çìåñïìçíßá\tF5",      CMD_TIME_DATE
+    END
+    POPUP "Ö&ïñìÜ"
+    BEGIN
+        MENUITEM "&ÅìöÜíéóç ìåãÜëùí ãñáììþí", CMD_WRAP
+        MENUITEM "&ÃñáììáôïóåéñÜ...",         CMD_FONT
+    END
+    POPUP "&ÅìöÜíéóç"
+    BEGIN
+        MENUITEM "ÃñáììÞ &êáôÜóôáóçò", CMD_STATUSBAR
+    END
+    POPUP "&ÂïÞèåéá"
+    BEGIN
+        MENUITEM "&Ðåñéå÷üìåíá",         CMD_HELP_CONTENTS
+        MENUITEM "&ÁíáæÞôçóç...",        CMD_HELP_SEARCH
+        MENUITEM "&ÂïÞèåéá óôç âïÞèåéá", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"                CMD_ABOUT
+        MENUITEM "Ðëçñï&öïñßåò",         CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index c4c5607..8e364df 100644 (file)
@@ -29,7 +29,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -40,54 +42,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&File"
-       BEGIN
-               MENUITEM "&New...",           CMD_NEW
-               MENUITEM "&Open\tCtrl+O",     CMD_OPEN
-               MENUITEM "&Save\tCtrl+S",     CMD_SAVE
-               MENUITEM "Save &as...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Page Se&tup...",    CMD_PAGE_SETUP
-               MENUITEM "&Print",            CMD_PRINT
-               MENUITEM "P&rinter Setup...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "E&xit",             CMD_EXIT
-       END
-       POPUP "&Edit"
-       BEGIN
-               MENUITEM "&Undo\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Cu&t\tCtrl+X",      CMD_CUT
-               MENUITEM "&Copy\tCtrl+C",     CMD_COPY
-               MENUITEM "&Paste\tCtrl+V",    CMD_PASTE
-               MENUITEM "&Delete\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Find...\tCtrl+F",  CMD_SEARCH
-               MENUITEM "Find &next\tF3",    CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Select &all\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "&Time/Date\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Wrap long lines",  CMD_WRAP
-               MENUITEM "&Font...",          CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "&Help"
-       BEGIN
-               MENUITEM "&Contents",         CMD_HELP_CONTENTS
-               MENUITEM "&Search...",        CMD_HELP_SEARCH
-               MENUITEM "&Help on help",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "Inf&o",      CMD_ABOUT_WINE
-       END
+    POPUP "&File"
+    BEGIN
+        MENUITEM "&New\tCtrl+N",      CMD_NEW
+        MENUITEM "&Open...\tCtrl+O",  CMD_OPEN
+        MENUITEM "&Save\tCtrl+S",     CMD_SAVE
+        MENUITEM "Save &as...",       CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Page Se&tup...",    CMD_PAGE_SETUP
+        MENUITEM "&Print\tCtrl+P",    CMD_PRINT
+        MENUITEM "P&rinter Setup...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "E&xit",             CMD_EXIT
+    END
+    POPUP "&Edit"
+    BEGIN
+        MENUITEM "&Undo\tCtrl+Z",       CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Cu&t\tCtrl+X",        CMD_CUT
+        MENUITEM "&Copy\tCtrl+C",       CMD_COPY
+        MENUITEM "&Paste\tCtrl+V",      CMD_PASTE
+        MENUITEM "&Delete\tDel",        CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Find...\tCtrl+F",    CMD_SEARCH
+        MENUITEM "Find &next\tF3",      CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",     CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",    CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Select &all\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "&Time/Date\tF5",      CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Wrap long lines", CMD_WRAP
+        MENUITEM "&Font...",         CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&Contents",     CMD_HELP_CONTENTS
+        MENUITEM "&Search...",    CMD_HELP_SEARCH
+        MENUITEM "&Help on help", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"         CMD_ABOUT
+        MENUITEM "Inf&o",         CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 16e8f8b..e89296b 100644 (file)
@@ -31,7 +31,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -42,54 +44,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Archivo"
-       BEGIN
-               MENUITEM "&Nuevo...",                   CMD_NEW
-               MENUITEM "&Abrir\tCtrl+O",              CMD_OPEN
-               MENUITEM "&Guardar\tCtrl+S",            CMD_SAVE
-               MENUITEM "Guardar &como...",            CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Imprimir",                   CMD_PRINT
-               MENUITEM "Configurar &página...",       CMD_PAGE_SETUP
-               MENUITEM "Configuración &impresora...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Salir",                      CMD_EXIT
-       END
-       POPUP "&Edición"
-       BEGIN
-               MENUITEM "&Deshacer\tCtrl+Z",         CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Cor&tar\tCtrl+X",           CMD_CUT
-               MENUITEM "&Copiar\tCtrl+C",           CMD_COPY
-               MENUITEM "&Pegar\tCtrl+V",            CMD_PASTE
-               MENUITEM "&Eliminar\tDel",            CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Buscar\tCtrl+F",       CMD_SEARCH
-               MENUITEM "Buscar &siguiente\tF3", CMD_SEARCH_NEXT
-               MENUITEM "Reemplazar\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Ir a...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Seleccionar t&odo\tCtrl+A", CMD_SELECT_ALL
-               MENUITEM "&Hora y fecha\tF5",         CMD_TIME_DATE
-       END
-       POPUP "F&ormato"
-       BEGIN
-               MENUITEM "&Ajuste de línea",          CMD_WRAP
-               MENUITEM "Tipo de &letra...",         CMD_FONT
-       END
-       POPUP "&Ver"
-       BEGIN
-               MENUITEM "Barra d&e estado",    CMD_STATUSBAR
+    POPUP "&Archivo"
+    BEGIN
+        MENUITEM "&Nuevo\tCtrl+N",              CMD_NEW
+        MENUITEM "&Abrir\tCtrl+O",              CMD_OPEN
+        MENUITEM "&Guardar\tCtrl+S",            CMD_SAVE
+        MENUITEM "Guardar &como...",            CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Imprimir\tCtrl+P",           CMD_PRINT
+        MENUITEM "Configurar &página...",       CMD_PAGE_SETUP
+        MENUITEM "Configuración &impresora...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Salir",                      CMD_EXIT
+    END
+    POPUP "&Edición"
+    BEGIN
+        MENUITEM "&Deshacer\tCtrl+Z",         CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Cor&tar\tCtrl+X",           CMD_CUT
+        MENUITEM "&Copiar\tCtrl+C",           CMD_COPY
+        MENUITEM "&Pegar\tCtrl+V",            CMD_PASTE
+        MENUITEM "&Eliminar\tDel",            CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Buscar\tCtrl+F",           CMD_SEARCH
+        MENUITEM "Buscar &siguiente\tF3",     CMD_SEARCH_NEXT
+        MENUITEM "Reemplazar\tCtrl+H",        CMD_REPLACE
+        MENUITEM "Ir a...\tCtrl+G",           CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Seleccionar t&odo\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "&Hora y fecha\tF5",         CMD_TIME_DATE
+    END
+    POPUP "F&ormato"
+    BEGIN
+        MENUITEM "&Ajuste de línea",  CMD_WRAP
+        MENUITEM "Tipo de &letra...", CMD_FONT
+    END
+    POPUP "&Ver"
+    BEGIN
+        MENUITEM "Barra d&e estado", CMD_STATUSBAR
         END
-       POPUP "A&yuda"
-       BEGIN
-               MENUITEM "Í&ndice",               CMD_HELP_CONTENTS
-               MENUITEM "&Buscar...",            CMD_HELP_SEARCH
-               MENUITEM "A&yuda sobre la ayuda", CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Acerca de"             CMD_ABOUT
-               MENUITEM "&Información...",      CMD_ABOUT_WINE
-       END
+    POPUP "A&yuda"
+    BEGIN
+        MENUITEM "Í&ndice",               CMD_HELP_CONTENTS
+        MENUITEM "&Buscar...",            CMD_HELP_SEARCH
+        MENUITEM "A&yuda sobre la ayuda", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Acerca de"             CMD_ABOUT
+        MENUITEM "&Información...",       CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 819c1db..80bd6b4 100644 (file)
@@ -7,7 +7,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -18,54 +20,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Fitxategia"
-       BEGIN
-               MENUITEM "&Berria...",                   CMD_NEW
-               MENUITEM "&Ireki\tCtrl+O",              CMD_OPEN
-               MENUITEM "&Gorde\tCtrl+S",            CMD_SAVE
-               MENUITEM "Gorde &honela...",            CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Inprimatu",                   CMD_PRINT
-               MENUITEM "Prestatu &orrialdea...",       CMD_PAGE_SETUP
-               MENUITEM "Inprimatzeko &aurrebista...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Irten",                      CMD_EXIT
-       END
-       POPUP "&Edizioa"
-       BEGIN
-               MENUITEM "&Desegin\tCtrl+Z",         CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Ebaki\tCtrl+X",           CMD_CUT
-               MENUITEM "&Kopiatu\tCtrl+C",           CMD_COPY
-               MENUITEM "&Itsasi\tCtrl+V",            CMD_PASTE
-               MENUITEM "&Ezabatu\tDel",            CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Bilatu\tCtrl+F",       CMD_SEARCH
-               MENUITEM "Bilatu &hurrengoa\tF3", CMD_SEARCH_NEXT
-               MENUITEM "Ordeztu\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Joan...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Hautatu dena\tCtrl+A", CMD_SELECT_ALL
-               MENUITEM "&Ordua eta data\tF5",         CMD_TIME_DATE
-       END
-       POPUP "Formatua"
-       BEGIN
-               MENUITEM "&Lerrokatu",          CMD_WRAP
-               MENUITEM "Letra-tipoa...",         CMD_FONT
-       END
-       POPUP "&Ikusi"
-       BEGIN
-               MENUITEM "Egoera-barra",    CMD_STATUSBAR
+    POPUP "&Fitxategia"
+    BEGIN
+        MENUITEM "&Berria\tCtrl+N",             CMD_NEW
+        MENUITEM "&Ireki\tCtrl+O",              CMD_OPEN
+        MENUITEM "&Gorde\tCtrl+S",              CMD_SAVE
+        MENUITEM "Gorde &honela...",            CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Inprimatu\tCtrl+P",          CMD_PRINT
+        MENUITEM "Prestatu &orrialdea...",      CMD_PAGE_SETUP
+        MENUITEM "Inprimatzeko &aurrebista...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Irten",                      CMD_EXIT
+    END
+    POPUP "&Edizioa"
+    BEGIN
+        MENUITEM "&Desegin\tCtrl+Z",      CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Ebaki\tCtrl+X",         CMD_CUT
+        MENUITEM "&Kopiatu\tCtrl+C",      CMD_COPY
+        MENUITEM "&Itsasi\tCtrl+V",       CMD_PASTE
+        MENUITEM "&Ezabatu\tDel",         CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Bilatu\tCtrl+F",       CMD_SEARCH
+        MENUITEM "Bilatu &hurrengoa\tF3", CMD_SEARCH_NEXT
+        MENUITEM "Ordeztu\tCtrl+H",       CMD_REPLACE
+        MENUITEM "Joan...\tCtrl+G",       CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Hautatu dena\tCtrl+A",  CMD_SELECT_ALL
+        MENUITEM "&Ordua eta data\tF5",   CMD_TIME_DATE
+    END
+    POPUP "Formatua"
+    BEGIN
+        MENUITEM "&Lerrokatu",     CMD_WRAP
+        MENUITEM "Letra-tipoa...", CMD_FONT
+    END
+    POPUP "&Ikusi"
+    BEGIN
+        MENUITEM "Egoera-barra", CMD_STATUSBAR
         END
-       POPUP "Laguntza"
-       BEGIN
-               MENUITEM "Í&ndizea",               CMD_HELP_CONTENTS
-               MENUITEM "&Bilatu...",            CMD_HELP_SEARCH
-               MENUITEM "Laguntzari buruz laguntza", CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Ohar-blokari buruz"             CMD_ABOUT
-               MENUITEM "&Informazioa...",      CMD_ABOUT_WINE
-       END
+    POPUP "Laguntza"
+    BEGIN
+        MENUITEM "Í&ndizea",                  CMD_HELP_CONTENTS
+        MENUITEM "&Bilatu...",                CMD_HELP_SEARCH
+        MENUITEM "Laguntzari buruz laguntza", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Ohar-blokari buruz"        CMD_ABOUT
+        MENUITEM "&Informazioa...",           CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 13378c4..8cbe9ed 100644 (file)
@@ -28,7 +28,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -39,54 +41,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Tiedosto"
-       BEGIN
-               MENUITEM "&Uusi...",            CMD_NEW
-               MENUITEM "&Avaa",               CMD_OPEN
-               MENUITEM "Ta&lleta",            CMD_SAVE
-               MENUITEM "Talleta &nimellä...", CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "T&ulosta",            CMD_PRINT
-               MENUITEM "&Sivun asetukset...", CMD_PAGE_SETUP
-               MENUITEM "&Kirjoittimen asetukset...",  CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Poistu",             CMD_EXIT
-       END
-       POPUP "&Muokkaa"
-       BEGIN
-               MENUITEM "&Palauta\tCtrl+Z",    CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Leikkaa\tCtrl+X",    CMD_CUT
-               MENUITEM "&Kopioi\tCtrl+C",     CMD_COPY
-               MENUITEM "L&iitä\tCtrl+V",      CMD_PASTE
-               MENUITEM "P&oista\tDel",        CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "Etsi...",             CMD_SEARCH
-               MENUITEM "Etsi &seuraava\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "&Valitse kaikki",     CMD_SELECT_ALL
-               MENUITEM "&Aika/Päivämäärä\tF5",        CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "Ka&tkaise pitkä rivi",        CMD_WRAP
-               MENUITEM "&Font...",          CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "&Apua"
-       BEGIN
-               MENUITEM "&Sisältö",            CMD_HELP_CONTENTS
-               MENUITEM "&Etsi...",            CMD_HELP_SEARCH
-               MENUITEM "Apua &Opastuksesta",  CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "Inf&o...",    CMD_ABOUT_WINE
-       END
+    POPUP "&Tiedosto"
+    BEGIN
+        MENUITEM "&Uusi\tCtrl+N",              CMD_NEW
+        MENUITEM "&Avaa\tCtrl+O",              CMD_OPEN
+        MENUITEM "Ta&lleta\tCtrl+S",           CMD_SAVE
+        MENUITEM "Talleta &nimellä...",        CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "T&ulosta\tCtrl+P",           CMD_PRINT
+        MENUITEM "&Sivun asetukset...",        CMD_PAGE_SETUP
+        MENUITEM "&Kirjoittimen asetukset...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Poistu",                    CMD_EXIT
+    END
+    POPUP "&Muokkaa"
+    BEGIN
+        MENUITEM "&Palauta\tCtrl+Z",     CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Leikkaa\tCtrl+X",     CMD_CUT
+        MENUITEM "&Kopioi\tCtrl+C",      CMD_COPY
+        MENUITEM "L&iitä\tCtrl+V",       CMD_PASTE
+        MENUITEM "P&oista\tDel",         CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "Etsi...",              CMD_SEARCH
+        MENUITEM "Etsi &seuraava\tF3",   CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",      CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",     CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "&Valitse kaikki",      CMD_SELECT_ALL
+        MENUITEM "&Aika/Päivämäärä\tF5", CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "Ka&tkaise pitkä rivi", CMD_WRAP
+        MENUITEM "&Font...",             CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Apua"
+    BEGIN
+        MENUITEM "&Sisältö",           CMD_HELP_CONTENTS
+        MENUITEM "&Etsi...",           CMD_HELP_SEARCH
+        MENUITEM "Apua &Opastuksesta", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"              CMD_ABOUT
+        MENUITEM "Inf&o...",           CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
@@ -163,33 +165,33 @@ END
 
 STRINGTABLE DISCARDABLE
 BEGIN
-STRING_PAGESETUP_HEADERVALUE,  "&n"        /* FIXME */
-STRING_PAGESETUP_FOOTERVALUE,  "Sivu &s"   /* FIXME */
-STRING_PAGESETUP_LEFTVALUE,            "20 mm"     /* FIXME */
-STRING_PAGESETUP_RIGHTVALUE,   "20 mm"     /* FIXME */
-STRING_PAGESETUP_TOPVALUE,             "25 mm"     /* FIXME */
-STRING_PAGESETUP_BOTTOMVALUE,  "25 mm"     /* FIXME */
+STRING_PAGESETUP_HEADERVALUE,    "&n"        /* FIXME */
+STRING_PAGESETUP_FOOTERVALUE,    "Sivu &s"   /* FIXME */
+STRING_PAGESETUP_LEFTVALUE,        "20 mm"     /* FIXME */
+STRING_PAGESETUP_RIGHTVALUE,    "20 mm"     /* FIXME */
+STRING_PAGESETUP_TOPVALUE,        "25 mm"     /* FIXME */
+STRING_PAGESETUP_BOTTOMVALUE,    "25 mm"     /* FIXME */
 
-STRING_NOTEPAD,                                        "Notepad"
-STRING_ERROR,                                  "VIRHE"
-STRING_WARNING,                                        "VAROITUS"
-STRING_INFO,                                   "Tiedoitus"
+STRING_NOTEPAD,                    "Notepad"
+STRING_ERROR,                    "VIRHE"
+STRING_WARNING,                    "VAROITUS"
+STRING_INFO,                    "Tiedoitus"
 
-STRING_UNTITLED,                               "(otsikoimaton)"
+STRING_UNTITLED,                "(otsikoimaton)"
 
-STRING_ALL_FILES,                              "Kaikki tiedostot (*.*)"
-STRING_TEXT_FILES_TXT,                 "Teksti tiedostot (*.txt)"
+STRING_ALL_FILES,                "Kaikki tiedostot (*.*)"
+STRING_TEXT_FILES_TXT,            "Teksti tiedostot (*.txt)"
 
-STRING_TOOLARGE,                               "Tiedosto '%s' on liian suuri.\n \
+STRING_TOOLARGE,                "Tiedosto '%s' on liian suuri.\n \
 Please use a different editor."
-STRING_NOTEXT,                                 "Et syöttänyt lainkaan tekstiä. \
+STRING_NOTEXT,                    "Et syöttänyt lainkaan tekstiä. \
 \nKirjoita jotain ja yritä uudelleen"
-STRING_DOESNOTEXIST,                           "File '%s'\ndoes not exist\n\n \
+STRING_DOESNOTEXIST,                "File '%s'\ndoes not exist\n\n \
 Do you want to create a new file ?"
-STRING_NOTSAVED,                               "File '%s'\nhas been modified\n\n \
+STRING_NOTSAVED,                "File '%s'\nhas been modified\n\n \
 Would you like to save the changes ?"
-STRING_NOTFOUND,                                       "'%s' ei löydy."
-STRING_OUT_OF_MEMORY,                  "Muistia ei ole riittävästi tämän \
+STRING_NOTFOUND,                    "'%s' ei löydy."
+STRING_OUT_OF_MEMORY,            "Muistia ei ole riittävästi tämän \
 \ntehtävän tekemiseksi. Sulje jokin sovellus vapauttaaksesi\n \
 muistia."
 STRING_CANNOTFIND                               "Cannot find '%s'"
index 0e8eaaa..455ec47 100644 (file)
@@ -29,7 +29,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -40,54 +42,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Fichier"
-       BEGIN
-               MENUITEM "&Nouveau...",       CMD_NEW
-               MENUITEM "&Ouvrir\tCtrl+O",   CMD_OPEN
-               MENUITEM "&Enregistrer\tCtrl+S", CMD_SAVE
-               MENUITEM "Enregistrer &sous...", CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Im&primer",         CMD_PRINT
-               MENUITEM "&Mise en page...",  CMD_PAGE_SETUP
-               MENUITEM "&Configuration de l'imprimante...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Quitter",          CMD_EXIT
-       END
-       POPUP "&Edition"
-       BEGIN
-               MENUITEM "&Annuler\tCtrl+Z",  CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Co&uper\tCtrl+X",   CMD_CUT
-               MENUITEM "&Copier\tCtrl+C",   CMD_COPY
-               MENUITEM "C&oller\tCtrl+V",   CMD_PASTE
-               MENUITEM "&Effacer\tDel",     CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Rechercher\tCtrl+F", CMD_SEARCH
-               MENUITEM "&Suivant\tF3",      CMD_SEARCH_NEXT
-               MENUITEM "Remplacer\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Atteindre...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Tout &sélectionner\tCtrl+A", CMD_SELECT_ALL
-               MENUITEM "&Heure/Date\tF5",   CMD_TIME_DATE
-       END
-       POPUP "&Format"
-       BEGIN
-               MENUITEM "&Retour à la ligne", CMD_WRAP
-               MENUITEM "&Police...",        CMD_FONT
-       END
-       POPUP "Affichage"
-       BEGIN
-               MENUITEM "Barre d'état",    CMD_STATUSBAR
-       END
-       POPUP "&Aide"
-       BEGIN
-               MENUITEM "&Sommaire",         CMD_HELP_CONTENTS
-               MENUITEM "&Rechercher...",    CMD_HELP_SEARCH
-               MENUITEM "&Utiliser l'aide",  CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&À propos"             CMD_ABOUT
-               MENUITEM "Inf&o...",        CMD_ABOUT_WINE
-       END
+    POPUP "&Fichier"
+    BEGIN
+        MENUITEM "&Nouveau\tCtrl+N",                  CMD_NEW
+        MENUITEM "&Ouvrir\tCtrl+O",                   CMD_OPEN
+        MENUITEM "&Enregistrer\tCtrl+S",              CMD_SAVE
+        MENUITEM "Enregistrer &sous...",              CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Im&primer\tCtrl+P",                 CMD_PRINT
+        MENUITEM "&Mise en page...",                  CMD_PAGE_SETUP
+        MENUITEM "&Configuration de l'imprimante...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Quitter",                          CMD_EXIT
+    END
+    POPUP "&Edition"
+    BEGIN
+        MENUITEM "&Annuler\tCtrl+Z",           CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Co&uper\tCtrl+X",            CMD_CUT
+        MENUITEM "&Copier\tCtrl+C",            CMD_COPY
+        MENUITEM "C&oller\tCtrl+V",            CMD_PASTE
+        MENUITEM "&Effacer\tDel",              CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Rechercher\tCtrl+F",        CMD_SEARCH
+        MENUITEM "&Suivant\tF3",               CMD_SEARCH_NEXT
+        MENUITEM "Remplacer\tCtrl+H",          CMD_REPLACE
+        MENUITEM "Atteindre...\tCtrl+G",       CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Tout &sélectionner\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "&Heure/Date\tF5",            CMD_TIME_DATE
+    END
+    POPUP "&Format"
+    BEGIN
+        MENUITEM "&Retour à la ligne", CMD_WRAP
+        MENUITEM "&Police...",         CMD_FONT
+    END
+    POPUP "Affichage"
+    BEGIN
+        MENUITEM "Barre d'état", CMD_STATUSBAR
+    END
+    POPUP "&Aide"
+    BEGIN
+        MENUITEM "&Sommaire",        CMD_HELP_CONTENTS
+        MENUITEM "&Rechercher...",   CMD_HELP_SEARCH
+        MENUITEM "&Utiliser l'aide", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&À propos"         CMD_ABOUT
+        MENUITEM "Inf&o...",         CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 86ba21d..6435871 100644 (file)
@@ -30,7 +30,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -41,54 +43,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Fájl"
-       BEGIN
-               MENUITEM "Ú&j",           CMD_NEW
-               MENUITEM "Meg&nyitás...",             CMD_OPEN
-               MENUITEM "&Mentés",             CMD_SAVE
-               MENUITEM "Mentés má&sként...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Oldalbeállítás...",    CMD_PAGE_SETUP
-               MENUITEM "Nyom&tatás...",            CMD_PRINT
-               MENUITEM "Nyomtató &beállítás...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Kilépés",             CMD_EXIT
-       END
-       POPUP "S&zerkesztés"
-       BEGIN
-               MENUITEM "&Visszavonás\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Kivá&gás\tCtrl+X",      CMD_CUT
-               MENUITEM "&Másolás\tCtrl+C",     CMD_COPY
-               MENUITEM "&Beillesztés\tCtrl+V",    CMD_PASTE
-               MENUITEM "Tör&lés\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Keresés...",           CMD_SEARCH
-               MENUITEM "Köve&tkezõ keresése\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "&Az összes kijelölése",       CMD_SELECT_ALL
-               MENUITEM "&Idõ/dátum\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Hosszú sorok tördelése",  CMD_WRAP
-               MENUITEM "&Font...",          CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "&Súgó"
-       BEGIN
-               MENUITEM "&Témakörök",         CMD_HELP_CONTENTS
-               MENUITEM "&Keresés...",        CMD_HELP_SEARCH
-               MENUITEM "&Használat",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "Inf&ormáció...",      CMD_ABOUT_WINE
-       END
+    POPUP "&Fájl"
+    BEGIN
+        MENUITEM "Ú&j\tCtrl+N",            CMD_NEW
+        MENUITEM "Meg&nyitás\tCtrl+O",     CMD_OPEN
+        MENUITEM "&Mentés\tCtrl+S",        CMD_SAVE
+        MENUITEM "Mentés má&sként...",     CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Oldalbeállítás...",     CMD_PAGE_SETUP
+        MENUITEM "Nyom&tatás\tCtrl+P",     CMD_PRINT
+        MENUITEM "Nyomtató &beállítás...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Kilépés",               CMD_EXIT
+    END
+    POPUP "S&zerkesztés"
+    BEGIN
+        MENUITEM "&Visszavonás\tCtrl+Z",    CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Kivá&gás\tCtrl+X",        CMD_CUT
+        MENUITEM "&Másolás\tCtrl+C",        CMD_COPY
+        MENUITEM "&Beillesztés\tCtrl+V",    CMD_PASTE
+        MENUITEM "Tör&lés\tDel",            CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Keresés...",             CMD_SEARCH
+        MENUITEM "Köve&tkezõ keresése\tF3", CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",         CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",        CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "&Az összes kijelölése",   CMD_SELECT_ALL
+        MENUITEM "&Idõ/dátum\tF5",          CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Hosszú sorok tördelése", CMD_WRAP
+        MENUITEM "&Font...",                CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Súgó"
+    BEGIN
+        MENUITEM "&Témakörök",     CMD_HELP_CONTENTS
+        MENUITEM "&Keresés...",    CMD_HELP_SEARCH
+        MENUITEM "&Használat",     CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"          CMD_ABOUT
+        MENUITEM "Inf&ormáció...", CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 59b5ef7..95011bf 100644 (file)
@@ -29,8 +29,10 @@ BEGIN
     "^C", CMD_COPY
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
-    "H",  CMD_REPLACE, VIRTKEY, CONTROL
+    "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -41,54 +43,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&File"
-       BEGIN
-               MENUITEM "Bar&u...",              CMD_NEW
-               MENUITEM "&Buka\tCtrl+O",         CMD_OPEN
-               MENUITEM "&Simpan\tCtrl+S",       CMD_SAVE
-               MENUITEM "Simpan seb&agai...",    CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Se&tup Halaman...",     CMD_PAGE_SETUP
-               MENUITEM "&Cetak",                CMD_PRINT
-               MENUITEM "P&rinter Setup...",     CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Keluar",               CMD_EXIT
-       END
-       POPUP "&Edit"
-       BEGIN
-               MENUITEM "&Undo\tCtrl+Z",         CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Cu&t\tCtrl+X",          CMD_CUT
-               MENUITEM "&Copy\tCtrl+C",         CMD_COPY
-               MENUITEM "&Paste\tCtrl+V",        CMD_PASTE
-               MENUITEM "&Hapus\tDel",           CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "Ca&ri...\tCtrl+F",      CMD_SEARCH
-               MENUITEM "Cari berikut&nya\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Ganti\tCtrl+H",         CMD_REPLACE
-               MENUITEM "Pergi Ke...\tCtrl+G",   CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Pilih semu&a\tCtrl+A",  CMD_SELECT_ALL
-               MENUITEM "&Jam/Tanggal\tF5",      CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Gulung baris panjang", CMD_WRAP
-               MENUITEM "&Font...",              CMD_FONT
-       END
-       POPUP "&Lihat"
-       BEGIN
-               MENUITEM "Status&bar",            CMD_STATUSBAR
-       END
-       POPUP "&Bantuan"
-       BEGIN
-               MENUITEM "&Daftar Isi",           CMD_HELP_CONTENTS
-               MENUITEM "&Cari...",              CMD_HELP_SEARCH
-               MENUITEM "&Bantuan pada bantuan", CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Tentang"               CMD_ABOUT
-               MENUITEM "Inf&o",                 CMD_ABOUT_WINE
-       END
+    POPUP "&File"
+    BEGIN
+        MENUITEM "Bar&u\tCtrl+N",      CMD_NEW
+        MENUITEM "&Buka\tCtrl+O",      CMD_OPEN
+        MENUITEM "&Simpan\tCtrl+S",    CMD_SAVE
+        MENUITEM "Simpan seb&agai...", CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Se&tup Halaman...",  CMD_PAGE_SETUP
+        MENUITEM "&Cetak\tCtrl+P",     CMD_PRINT
+        MENUITEM "P&rinter Setup...",  CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Keluar",            CMD_EXIT
+    END
+    POPUP "&Edit"
+    BEGIN
+        MENUITEM "&Undo\tCtrl+Z",        CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Cu&t\tCtrl+X",         CMD_CUT
+        MENUITEM "&Copy\tCtrl+C",        CMD_COPY
+        MENUITEM "&Paste\tCtrl+V",       CMD_PASTE
+        MENUITEM "&Hapus\tDel",          CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "Ca&ri...\tCtrl+F",     CMD_SEARCH
+        MENUITEM "Cari berikut&nya\tF3", CMD_SEARCH_NEXT
+        MENUITEM "Ganti\tCtrl+H",        CMD_REPLACE
+        MENUITEM "Pergi Ke...\tCtrl+G",  CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Pilih semu&a\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "&Jam/Tanggal\tF5",     CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Gulung baris panjang", CMD_WRAP
+        MENUITEM "&Font...",              CMD_FONT
+    END
+    POPUP "&Lihat"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Bantuan"
+    BEGIN
+        MENUITEM "&Daftar Isi",           CMD_HELP_CONTENTS
+        MENUITEM "&Cari...",              CMD_HELP_SEARCH
+        MENUITEM "&Bantuan pada bantuan", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Tentang"               CMD_ABOUT
+        MENUITEM "Inf&o",                 CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 542f27d..df964a1 100644 (file)
@@ -32,7 +32,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -43,54 +45,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&File"
-       BEGIN
-               MENUITEM "&Nuovo",           CMD_NEW
-               MENUITEM "&Apri...\tCtrl+O",     CMD_OPEN
-               MENUITEM "&Salva\tCtrl+S",     CMD_SAVE
-               MENUITEM "Sal&va con nome...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "S&tampa",            CMD_PRINT
-               MENUITEM "I&mposta pagina...",    CMD_PAGE_SETUP
-               MENUITEM "&Configurazione stampante...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Esci",             CMD_EXIT
-       END
-       POPUP "&Modifica"
-       BEGIN
-               MENUITEM "&Annulla\tCtrl+Z",      CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Taglia\tCtrl+X",       CMD_CUT
-               MENUITEM "&Copia\tCtrl+C",        CMD_COPY
-               MENUITEM "I&ncolla\tCtrl+V",      CMD_PASTE
-               MENUITEM "E&limina\tDel",         CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "Tr&ova\tCtrl+F",        CMD_SEARCH
-               MENUITEM "T&rova successivo\tF3", CMD_SEARCH_NEXT
-               MENUITEM "Sostituisci\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Vai a...\tCtrl+G",      CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Sele&ziona tutto\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "Ora/&Data\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormato"
-       BEGIN
-               MENUITEM "&A capo automatico",    CMD_WRAP
-               MENUITEM "&Imposta carattere...", CMD_FONT
-       END
-       POPUP "&Visualizza"
-       BEGIN
-               MENUITEM "&Barra di stato",    CMD_STATUSBAR
-       END
-       POPUP "&?"
-       BEGIN
-               MENUITEM "&Guida in linea",         CMD_HELP_CONTENTS
-               MENUITEM "&Trova...",        CMD_HELP_SEARCH
-               MENUITEM "&Aiuto sulla Guida",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "Informazioni &su blocco note"             CMD_ABOUT
-               MENUITEM "Inf&o...",      CMD_ABOUT_WINE
-       END
+    POPUP "&File"
+    BEGIN
+        MENUITEM "&Nuovo\tCtrl+N",               CMD_NEW
+        MENUITEM "&Apri...\tCtrl+O",             CMD_OPEN
+        MENUITEM "&Salva\tCtrl+S",               CMD_SAVE
+        MENUITEM "Sal&va con nome...",           CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "S&tampa\tCtrl+P",              CMD_PRINT
+        MENUITEM "I&mposta pagina...",           CMD_PAGE_SETUP
+        MENUITEM "&Configurazione stampante...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Esci",                        CMD_EXIT
+    END
+    POPUP "&Modifica"
+    BEGIN
+        MENUITEM "&Annulla\tCtrl+Z",         CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Taglia\tCtrl+X",          CMD_CUT
+        MENUITEM "&Copia\tCtrl+C",           CMD_COPY
+        MENUITEM "I&ncolla\tCtrl+V",         CMD_PASTE
+        MENUITEM "E&limina\tDel",            CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "Tr&ova\tCtrl+F",           CMD_SEARCH
+        MENUITEM "T&rova successivo\tF3",    CMD_SEARCH_NEXT
+        MENUITEM "Sostituisci\tCtrl+H",      CMD_REPLACE
+        MENUITEM "Vai a...\tCtrl+G",         CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Sele&ziona tutto\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "Ora/&Data\tF5",            CMD_TIME_DATE
+    END
+    POPUP "F&ormato"
+    BEGIN
+        MENUITEM "&A capo automatico",    CMD_WRAP
+        MENUITEM "&Imposta carattere...", CMD_FONT
+    END
+    POPUP "&Visualizza"
+    BEGIN
+        MENUITEM "&Barra di stato", CMD_STATUSBAR
+    END
+    POPUP "&?"
+    BEGIN
+        MENUITEM "&Guida in linea",             CMD_HELP_CONTENTS
+        MENUITEM "&Trova...",                   CMD_HELP_SEARCH
+        MENUITEM "&Aiuto sulla Guida",          CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "Informazioni &su blocco note" CMD_ABOUT
+        MENUITEM "Inf&o...",                    CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 03536de..a1a077b 100644 (file)
@@ -29,7 +29,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -40,54 +42,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "\83t\83@\83C\83\8b(&F)"
-       BEGIN
-               MENUITEM "\90V\8bK\8dì\90¬(&N)...",         CMD_NEW
-               MENUITEM "\8aJ\82­(&O)\tCtrl+O",        CMD_OPEN
-               MENUITEM "\95Û\91¶(&S)\tCtrl+S",        CMD_SAVE
-               MENUITEM "\96¼\91O\82ð\95t\82¯\82Ä\95Û\91¶(&A)...", CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "\83y\81[\83W\90Ý\92è(&T)...",       CMD_PAGE_SETUP
-               MENUITEM "\88ó\8dü(&P)",                CMD_PRINT
-               MENUITEM "\83v\83\8a\83\93\83^\82Ì\90Ý\92è(&R)...",   CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "\8fI\97¹(&X)",                CMD_EXIT
-       END
-       POPUP "\95Ò\8fW(&E)"
-       BEGIN
-               MENUITEM "\8c³\82É\96ß\82·(&U)\tCtrl+Z",    CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "\90Ø\82è\8eæ\82è(&T)\tCtrl+X",    CMD_CUT
-               MENUITEM "\83R\83s\81[(&C)\tCtrl+C",      CMD_COPY
-               MENUITEM "\83y\81[\83X\83g(&P)\tCtrl+V",    CMD_PASTE
-               MENUITEM "\8dí\8f\9c(&D)\tDel",           CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "\8c\9f\8dõ(&S)\tCtrl+F",        CMD_SEARCH
-               MENUITEM "\8e\9f\82Ì\8có\95â\82ð\8c\9f\8dõ(&S)\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "\92u\8a·\tCtrl+H",            CMD_REPLACE
-               MENUITEM "\8ds\82Ö\88Ú\93®...\tCtrl+G",     CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "\91S\82Ä\91I\91ð(&A)\tCtrl+A",    CMD_SELECT_ALL
-               MENUITEM "\93ú\95t\82Æ\8e\9e\8d\8f\82Ì\91}\93ü(&T)\tF5", CMD_TIME_DATE
-       END
-       POPUP "\8f\91\8e®(&O)"
-       BEGIN
-               MENUITEM "\92·\82¢\8ds\82ð\90Ü\82è\95Ô\82·(&W)",    CMD_WRAP
-               MENUITEM "\83t\83H\83\93\83g(&F)...",         CMD_FONT
-       END
-       POPUP "\95\\\8e¦(&V)"
-       BEGIN
-               MENUITEM "\83X\83e\81[\83^\83\83o\81[(&B)",     CMD_STATUSBAR
-       END
-       POPUP "\83w\83\8b\83v(&H)"
-       BEGIN
-               MENUITEM "\96Ú\8e\9f(&C)",                CMD_HELP_CONTENTS
-               MENUITEM "\8c\9f\8dõ(&S)...",             CMD_HELP_SEARCH
-               MENUITEM "\83w\83\8b\83v\82Ì\8eg\82¢\95û(&H)",      CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"                   CMD_ABOUT
-               MENUITEM "\8fî\95ñ(&O)"                 CMD_ABOUT_WINE
-       END
+    POPUP "\83t\83@\83C\83\8b(&F)"
+    BEGIN
+        MENUITEM "\90V\8bK\8dì\90¬(&N)\tCtrl+N",       CMD_NEW
+        MENUITEM "\8aJ\82­(&O)\tCtrl+O",        CMD_OPEN
+        MENUITEM "\95Û\91¶(&S)\tCtrl+S",        CMD_SAVE
+        MENUITEM "\96¼\91O\82ð\95t\82¯\82Ä\95Û\91¶(&A)...", CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "\83y\81[\83W\90Ý\92è(&T)...",         CMD_PAGE_SETUP
+        MENUITEM "\88ó\8dü(&P)\tCtrl+P",         CMD_PRINT
+        MENUITEM "\83v\83\8a\83\93\83^\82Ì\90Ý\92è(&R)...",    CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "\8fI\97¹(&X)",                 CMD_EXIT
+    END
+    POPUP "\95Ò\8fW(&E)"
+    BEGIN
+        MENUITEM "\8c³\82É\96ß\82·(&U)\tCtrl+Z",   CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "\90Ø\82è\8eæ\82è(&T)\tCtrl+X",    CMD_CUT
+        MENUITEM "\83R\83s\81[(&C)\tCtrl+C",      CMD_COPY
+        MENUITEM "\83y\81[\83X\83g(&P)\tCtrl+V",    CMD_PASTE
+        MENUITEM "\8dí\8f\9c(&D)\tDel",            CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "\8c\9f\8dõ(&S)\tCtrl+F",        CMD_SEARCH
+        MENUITEM "\8e\9f\82Ì\8có\95â\82ð\8c\9f\8dõ(&S)\tF3",  CMD_SEARCH_NEXT
+        MENUITEM "\92u\8a·\tCtrl+H",           CMD_REPLACE
+        MENUITEM "\8ds\82Ö\88Ú\93®...\tCtrl+G",     CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "\91S\82Ä\91I\91ð(&A)\tCtrl+A",   CMD_SELECT_ALL
+        MENUITEM "\93ú\95t\82Æ\8e\9e\8d\8f\82Ì\91}\93ü(&T)\tF5", CMD_TIME_DATE
+    END
+    POPUP "\8f\91\8e®(&O)"
+    BEGIN
+        MENUITEM "\92·\82¢\8ds\82ð\90Ü\82è\95Ô\82·(&W)", CMD_WRAP
+        MENUITEM "\83t\83H\83\93\83g(&F)...",    CMD_FONT
+    END
+    POPUP "\95\\\8e¦(&V)"
+    BEGIN
+        MENUITEM "\83X\83e\81[\83^\83\83o\81[(&B)", CMD_STATUSBAR
+    END
+    POPUP "\83w\83\8b\83v(&H)"
+    BEGIN
+        MENUITEM "\96Ú\8e\9f(&C)",           CMD_HELP_CONTENTS
+        MENUITEM "\8c\9f\8dõ(&S)...",         CMD_HELP_SEARCH
+        MENUITEM "\83w\83\8b\83v\82Ì\8eg\82¢\95û(&H)", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"              CMD_ABOUT
+        MENUITEM "\8fî\95ñ(&O)"             CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 07d0b8d..03613e3 100644 (file)
@@ -31,7 +31,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -42,54 +44,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Byla"
-       BEGIN
-               MENUITEM "&Nauja...",           CMD_NEW
-               MENUITEM "&Atverti\tCtrl+O",     CMD_OPEN
-               MENUITEM "Á&raðyti\tCtrl+S",     CMD_SAVE
-               MENUITEM "Áraðyti &kaip...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "P&uslapio nuostatos...",    CMD_PAGE_SETUP
-               MENUITEM "&Spausdinti",            CMD_PRINT
-               MENUITEM "S&pausdintuvo nuostatos...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Baigti",             CMD_EXIT
-       END
-       POPUP "&Redaguoti"
-       BEGIN
-               MENUITEM "&Atðaukti\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Iðkirpti\tCtrl+X",      CMD_CUT
-               MENUITEM "&Kopijuoti\tCtrl+C",     CMD_COPY
-               MENUITEM "Á&dëti\tCtrl+V",    CMD_PASTE
-               MENUITEM "&Trinti\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "I&eðkoti...\tCtrl+F",  CMD_SEARCH
-               MENUITEM "Ieðk&oti toliau\tF3",    CMD_SEARCH_NEXT
-               MENUITEM "Pakeisti\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Eiti á...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Paþymëti &viskà\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "&Laikas ir data\tF5",    CMD_TIME_DATE
-       END
-       POPUP "&Formatas"
-       BEGIN
-               MENUITEM "&Lauþyti eilutes",  CMD_WRAP
-               MENUITEM "Ð&riftas...",          CMD_FONT
-       END
-       POPUP "R&odymas"
-       BEGIN
-               MENUITEM "&Bûsenos juosta",    CMD_STATUSBAR
-       END
-       POPUP "&Pagalba"
-       BEGIN
-               MENUITEM "&Turinys",         CMD_HELP_CONTENTS
-               MENUITEM "&Ieðkoti...",        CMD_HELP_SEARCH
-               MENUITEM "&Pagalba",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Apie Notepad"             CMD_ABOUT
-               MENUITEM "Apie &Wine",      CMD_ABOUT_WINE
-       END
+    POPUP "&Byla"
+    BEGIN
+        MENUITEM "&Nauja\tCtrl+N",             CMD_NEW
+        MENUITEM "&Atverti\tCtrl+O",           CMD_OPEN
+        MENUITEM "Á&raðyti\tCtrl+S",           CMD_SAVE
+        MENUITEM "Áraðyti &kaip...",           CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "P&uslapio nuostatos...",     CMD_PAGE_SETUP
+        MENUITEM "&Spausdinti\tCtrl+P",        CMD_PRINT
+        MENUITEM "S&pausdintuvo nuostatos...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Baigti",                    CMD_EXIT
+    END
+    POPUP "&Redaguoti"
+    BEGIN
+        MENUITEM "&Atðaukti\tCtrl+Z",       CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Iðkirpti\tCtrl+X",       CMD_CUT
+        MENUITEM "&Kopijuoti\tCtrl+C",      CMD_COPY
+        MENUITEM "Á&dëti\tCtrl+V",          CMD_PASTE
+        MENUITEM "&Trinti\tDel",            CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "I&eðkoti...\tCtrl+F",     CMD_SEARCH
+        MENUITEM "Ieðk&oti toliau\tF3",     CMD_SEARCH_NEXT
+        MENUITEM "Pakeisti\tCtrl+H",        CMD_REPLACE
+        MENUITEM "Eiti á...\tCtrl+G",       CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Paþymëti &viskà\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "&Laikas ir data\tF5",     CMD_TIME_DATE
+    END
+    POPUP "&Formatas"
+    BEGIN
+        MENUITEM "&Lauþyti eilutes", CMD_WRAP
+        MENUITEM "Ð&riftas...",      CMD_FONT
+    END
+    POPUP "R&odymas"
+    BEGIN
+        MENUITEM "&Bûsenos juosta", CMD_STATUSBAR
+    END
+    POPUP "&Pagalba"
+    BEGIN
+        MENUITEM "&Turinys",     CMD_HELP_CONTENTS
+        MENUITEM "&Ieðkoti...",  CMD_HELP_SEARCH
+        MENUITEM "&Pagalba",     CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Apie Notepad" CMD_ABOUT
+        MENUITEM "Apie &Wine",   CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index da4c8ad..93c4c6d 100644 (file)
@@ -27,7 +27,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -38,54 +40,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Bestand"
-       BEGIN
-               MENUITEM "&Nieuw...",                CMD_NEW
-               MENUITEM "&Openen\tCtrl+O",          CMD_OPEN
-               MENUITEM "O&pslaan\tCtrl+p",         CMD_SAVE
-               MENUITEM "Ops&laan als...",          CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Afdrukken",       CMD_PRINT
-               MENUITEM "Pagina-in&stelling...",  CMD_PAGE_SETUP
-               MENUITEM "Printerinstellingen...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Afsluiten",             CMD_EXIT
-       END
-       POPUP "Be&werken"
-       BEGIN
-               MENUITEM "&Ongedaan maken\tCtrl+Z",    CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "K&nippen\tCtrl+X",           CMD_CUT
-               MENUITEM "&Kopiëren\tCtrl+C",         CMD_COPY
-               MENUITEM "&Plakken\tCtrl+V",           CMD_PASTE
-               MENUITEM "&Verwijderen\tDel",          CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Zoeken\tCtrl+Z",       CMD_SEARCH
-               MENUITEM "&Volgende zoeken\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "&Alles selecteren\tCtrl+A",  CMD_SELECT_ALL
-               MENUITEM "Tijd/&datum\tF5",            CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "A&utomatische terugloop",    CMD_WRAP
-               MENUITEM "&Lettertype instellen...",   CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "&Help"
-       BEGIN
-               MENUITEM "&Help-onderwerpen",  CMD_HELP_CONTENTS
-               MENUITEM "&Zoeken...",         CMD_HELP_SEARCH
-               MENUITEM "&Hulp bij Help",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "Inf&o...",        CMD_ABOUT_WINE
-       END
+    POPUP "&Bestand"
+    BEGIN
+        MENUITEM "&Nieuw\tCtrl+N",         CMD_NEW
+        MENUITEM "&Openen\tCtrl+O",        CMD_OPEN
+        MENUITEM "O&pslaan\tCtrl+S",       CMD_SAVE
+        MENUITEM "Ops&laan als...",        CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Afdrukken\tCtrl+P",     CMD_PRINT
+        MENUITEM "Pagina-in&stelling...",  CMD_PAGE_SETUP
+        MENUITEM "Printerinstellingen...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Afsluiten",             CMD_EXIT
+    END
+    POPUP "Be&werken"
+    BEGIN
+        MENUITEM "&Ongedaan maken\tCtrl+Z",   CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "K&nippen\tCtrl+X",          CMD_CUT
+        MENUITEM "&Kopiëren\tCtrl+C",         CMD_COPY
+        MENUITEM "&Plakken\tCtrl+V",          CMD_PASTE
+        MENUITEM "&Verwijderen\tDel",         CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Zoeken\tCtrl+Z",           CMD_SEARCH
+        MENUITEM "&Volgende zoeken\tF3",      CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",           CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",          CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "&Alles selecteren\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "Tijd/&datum\tF5",           CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "A&utomatische terugloop",  CMD_WRAP
+        MENUITEM "&Lettertype instellen...", CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&Help-onderwerpen", CMD_HELP_CONTENTS
+        MENUITEM "&Zoeken...",        CMD_HELP_SEARCH
+        MENUITEM "&Hulp bij Help",    CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"             CMD_ABOUT
+        MENUITEM "Inf&o...",          CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 5304657..42161e6 100644 (file)
@@ -28,8 +28,10 @@ BEGIN
     "^C", CMD_COPY
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
-    "H", CMD_REPLACE, VIRTKEY, CONTROL 
+    "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -40,54 +42,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Fil"
-       BEGIN
-               MENUITEM "&Ny...",           CMD_NEW
-               MENUITEM "&Åpne\tCtrl+O",     CMD_OPEN
-               MENUITEM "&Lagre\tCtrl+S",     CMD_SAVE
-               MENUITEM "Lagre &som...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Side &Innstillinger...",    CMD_PAGE_SETUP
-               MENUITEM "&Utskrift",            CMD_PRINT
-               MENUITEM "U&tskrift innstillinger...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "A&vslutt",             CMD_EXIT
-       END
-       POPUP "&Rediger"
-       BEGIN
-               MENUITEM "&Angre\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "Klipp &ut\tCtrl+X",      CMD_CUT
-               MENUITEM "&Kopier\tCtrl+C",     CMD_COPY
-               MENUITEM "&Lim inn\tCtrl+V",    CMD_PASTE
-               MENUITEM "&Slett\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Finn...\tCtrl+F",  CMD_SEARCH
-               MENUITEM "Finn &neste\tF3",    CMD_SEARCH_NEXT
-               MENUITEM "Erstatt\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Gå til...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Merk &alt\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "&Klokkeslett/dato\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Tekstbryting",  CMD_WRAP
-               MENUITEM "&Skrift...",          CMD_FONT
-       END
-       POPUP "&Vis"
-       BEGIN
-               MENUITEM "Status&linje",    CMD_STATUSBAR
-       END
-       POPUP "&Hjelp"
-       BEGIN
-               MENUITEM "&Emner i hjelp",         CMD_HELP_CONTENTS
-               MENUITEM "&Søk",        CMD_HELP_SEARCH
-               MENUITEM "&Hjelp om hjelp",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Om"             CMD_ABOUT
-               MENUITEM "&Infomasjon",      CMD_ABOUT_WINE
-       END
+    POPUP "&Fil"
+    BEGIN
+        MENUITEM "&Ny\tCtrl+N",                CMD_NEW
+        MENUITEM "&Åpne\tCtrl+O",              CMD_OPEN
+        MENUITEM "&Lagre\tCtrl+S",             CMD_SAVE
+        MENUITEM "Lagre &som...",              CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Side &Innstillinger...",     CMD_PAGE_SETUP
+        MENUITEM "&Utskrift\tCtrl+P",          CMD_PRINT
+        MENUITEM "U&tskrift innstillinger...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "A&vslutt",                   CMD_EXIT
+    END
+    POPUP "&Rediger"
+    BEGIN
+        MENUITEM "&Angre\tCtrl+Z",        CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Klipp &ut\tCtrl+X",     CMD_CUT
+        MENUITEM "&Kopier\tCtrl+C",       CMD_COPY
+        MENUITEM "&Lim inn\tCtrl+V",      CMD_PASTE
+        MENUITEM "&Slett\tDel",           CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Finn...\tCtrl+F",      CMD_SEARCH
+        MENUITEM "Finn &neste\tF3",       CMD_SEARCH_NEXT
+        MENUITEM "Erstatt\tCtrl+H",       CMD_REPLACE
+        MENUITEM "Gå til...\tCtrl+G",     CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Merk &alt\tCtrl+A",     CMD_SELECT_ALL
+        MENUITEM "&Klokkeslett/dato\tF5", CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Tekstbryting", CMD_WRAP
+        MENUITEM "&Skrift...",    CMD_FONT
+    END
+    POPUP "&Vis"
+    BEGIN
+        MENUITEM "Status&linje", CMD_STATUSBAR
+    END
+    POPUP "&Hjelp"
+    BEGIN
+        MENUITEM "&Emner i hjelp",  CMD_HELP_CONTENTS
+        MENUITEM "&Søk",            CMD_HELP_SEARCH
+        MENUITEM "&Hjelp om hjelp", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Om"              CMD_ABOUT
+        MENUITEM "&Infomasjon",     CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index a8355ff..8202812 100644 (file)
@@ -36,7 +36,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -47,54 +49,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Plik"
-       BEGIN
-               MENUITEM "&Nowy...",           CMD_NEW
-               MENUITEM "&Otwórz\tCtrl+O",     CMD_OPEN
-               MENUITEM "&Zapisz\tCtrl+S",     CMD_SAVE
-               MENUITEM "Z&apisz jako...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Drukuj",            CMD_PRINT
-               MENUITEM "&Ustawienia strony...",    CMD_PAGE_SETUP
-               MENUITEM "Ustawienia &drukarki...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "Zakoñ&cz",             CMD_EXIT
-       END
-       POPUP "&Edycja"
-       BEGIN
-               MENUITEM "&Cofnij\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Wytnij\tCtrl+X",      CMD_CUT
-               MENUITEM "&Kopiuj\tCtrl+C",     CMD_COPY
-               MENUITEM "Wkl&ej\tCtrl+V",    CMD_PASTE
-               MENUITEM "&Usuñ\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Znajd\9f\tCtrl+F",   CMD_SEARCH
-               MENUITEM "Z&najd\9f nastêpny\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Zamieñ\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Id\9f do...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Zaznacz w&szystko\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "Godzina/&Data\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Zawijanie wierszy",  CMD_WRAP
-               MENUITEM "Czci&onka...",          CMD_FONT
-       END
-       POPUP "P&odgl¹d"
-       BEGIN
-               MENUITEM "Pasek &stanu",    CMD_STATUSBAR
-       END
-       POPUP "Pomo&c"
-       BEGIN
-               MENUITEM "&Tematy pomocy",         CMD_HELP_CONTENTS
-               MENUITEM "&Szukaj...",        CMD_HELP_SEARCH
-               MENUITEM "Pomo&c",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Notatnik - informacje"             CMD_ABOUT
-               MENUITEM "&ReactOS - informacje",      CMD_ABOUT_WINE
-       END
+    POPUP "&Plik"
+    BEGIN
+        MENUITEM "&Nowy\tCtrl+N",           CMD_NEW
+        MENUITEM "&Otwórz\tCtrl+O",         CMD_OPEN
+        MENUITEM "&Zapisz\tCtrl+S",         CMD_SAVE
+        MENUITEM "Z&apisz jako...",         CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Drukuj\tCtrl+P",         CMD_PRINT
+        MENUITEM "&Ustawienia strony...",   CMD_PAGE_SETUP
+        MENUITEM "Ustawienia &drukarki...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Zakoñ&cz",                CMD_EXIT
+    END
+    POPUP "&Edycja"
+    BEGIN
+        MENUITEM "&Cofnij\tCtrl+Z",           CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Wytnij\tCtrl+X",           CMD_CUT
+        MENUITEM "&Kopiuj\tCtrl+C",           CMD_COPY
+        MENUITEM "Wkl&ej\tCtrl+V",            CMD_PASTE
+        MENUITEM "&Usuñ\tDel",                CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Znajd\9f\tCtrl+F",           CMD_SEARCH
+        MENUITEM "Z&najd\9f nastêpny\tF3",      CMD_SEARCH_NEXT
+        MENUITEM "Zamieñ\tCtrl+H",            CMD_REPLACE
+        MENUITEM "Id\9f do...\tCtrl+G",         CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Zaznacz w&szystko\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "Godzina/&Data\tF5",         CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Zawijanie wierszy", CMD_WRAP
+        MENUITEM "Czci&onka...",       CMD_FONT
+    END
+    POPUP "P&odgl¹d"
+    BEGIN
+        MENUITEM "Pasek &stanu", CMD_STATUSBAR
+    END
+    POPUP "Pomo&c"
+    BEGIN
+        MENUITEM "&Tematy pomocy",        CMD_HELP_CONTENTS
+        MENUITEM "&Szukaj...",            CMD_HELP_SEARCH
+        MENUITEM "Pomo&c",                CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Notatnik - informacje" CMD_ABOUT
+        MENUITEM "&ReactOS - informacje", CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 4a5cae4..5aa4a3f 100644 (file)
@@ -30,7 +30,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -41,54 +43,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Arquivo"
-       BEGIN
-               MENUITEM "&Novo...",            CMD_NEW
-               MENUITEM "A&brir",              CMD_OPEN
-               MENUITEM "&Salvar",             CMD_SAVE
-               MENUITEM "Salvar &como...",     CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Imprimir",           CMD_PRINT
-               MENUITEM "C&onfigurar página...",       CMD_PAGE_SETUP
-               MENUITEM "Configurar i&mpressora...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "Sai&r",               CMD_EXIT
-       END
-       POPUP "&Editar"
-       BEGIN
-               MENUITEM "&Desfazer\tCtrl+Z", CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Recortar\tCtrl+X",   CMD_CUT
-               MENUITEM "&Copiar\tCtrl+C",     CMD_COPY
-               MENUITEM "C&olar\tCtrl+V",      CMD_PASTE
-               MENUITEM "E&xcluir\tDel",       CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Localizar...",       CMD_SEARCH
-               MENUITEM "Localizar &próxima\tF3",      CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Selecionar &tudo",    CMD_SELECT_ALL
-               MENUITEM "&Data/Hora\tF5",      CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Quebrar automática de linha",        CMD_WRAP
-               MENUITEM "&Fonte...",          CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "&Ajuda"
-       BEGIN
-               MENUITEM "&Conteúdo",           CMD_HELP_CONTENTS
-               MENUITEM "&Procurar...",        CMD_HELP_SEARCH
-               MENUITEM "&Ajuda na ajuda",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "&Informações...",     CMD_ABOUT_WINE
-       END
+    POPUP "&Arquivo"
+    BEGIN
+        MENUITEM "&Novo\tCtrl+N",             CMD_NEW
+        MENUITEM "A&brir\tCtrl+O",            CMD_OPEN
+        MENUITEM "&Salvar\tCtrl+S",           CMD_SAVE
+        MENUITEM "Salvar &como...",           CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Imprimir\tCtrl+P",         CMD_PRINT
+        MENUITEM "C&onfigurar página...",     CMD_PAGE_SETUP
+        MENUITEM "Configurar i&mpressora...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Sai&r",                     CMD_EXIT
+    END
+    POPUP "&Editar"
+    BEGIN
+        MENUITEM "&Desfazer\tCtrl+Z",      CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Recortar\tCtrl+X",      CMD_CUT
+        MENUITEM "&Copiar\tCtrl+C",        CMD_COPY
+        MENUITEM "C&olar\tCtrl+V",         CMD_PASTE
+        MENUITEM "E&xcluir\tDel",          CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Localizar...",          CMD_SEARCH
+        MENUITEM "Localizar &próxima\tF3", CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",        CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",       CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Selecionar &tudo",       CMD_SELECT_ALL
+        MENUITEM "&Data/Hora\tF5",         CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Quebrar automática de linha", CMD_WRAP
+        MENUITEM "&Fonte...",                    CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Ajuda"
+    BEGIN
+        MENUITEM "&Conteúdo",       CMD_HELP_CONTENTS
+        MENUITEM "&Procurar...",    CMD_HELP_SEARCH
+        MENUITEM "&Ajuda na ajuda", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"           CMD_ABOUT
+        MENUITEM "&Informações...", CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
@@ -164,33 +166,33 @@ BEGIN
 END
 STRINGTABLE DISCARDABLE
 BEGIN
-STRING_PAGESETUP_HEADERVALUE,  "&n"        /* FIXME */
-STRING_PAGESETUP_FOOTERVALUE,  "Página &s"   /* FIXME */
-STRING_PAGESETUP_LEFTVALUE,            "20 mm"     /* FIXME */
-STRING_PAGESETUP_RIGHTVALUE,   "20 mm"     /* FIXME */
-STRING_PAGESETUP_TOPVALUE,             "25 mm"     /* FIXME */
-STRING_PAGESETUP_BOTTOMVALUE,  "25 mm"     /* FIXME */
+STRING_PAGESETUP_HEADERVALUE,    "&n"        /* FIXME */
+STRING_PAGESETUP_FOOTERVALUE,    "Página &s"   /* FIXME */
+STRING_PAGESETUP_LEFTVALUE,        "20 mm"     /* FIXME */
+STRING_PAGESETUP_RIGHTVALUE,    "20 mm"     /* FIXME */
+STRING_PAGESETUP_TOPVALUE,        "25 mm"     /* FIXME */
+STRING_PAGESETUP_BOTTOMVALUE,    "25 mm"     /* FIXME */
 
-STRING_NOTEPAD,                                        "Notepad"
-STRING_ERROR,                                  "ERRO"
-STRING_WARNING,                                        "AVISO"
-STRING_INFO,                                   "Informação"
+STRING_NOTEPAD,                    "Notepad"
+STRING_ERROR,                    "ERRO"
+STRING_WARNING,                    "AVISO"
+STRING_INFO,                    "Informação"
 
-STRING_UNTITLED,                               "(sem nome)"
+STRING_UNTITLED,                "(sem nome)"
 
-STRING_ALL_FILES,                              "Todos os arquivos (*.*)"
-STRING_TEXT_FILES_TXT,                 "Arquivos texto (*.txt)"
+STRING_ALL_FILES,                "Todos os arquivos (*.*)"
+STRING_TEXT_FILES_TXT,            "Arquivos texto (*.txt)"
 
-STRING_TOOLARGE,                               "Arquivo '%s' é muito longo para o notepad.\n \
+STRING_TOOLARGE,                "Arquivo '%s' é muito longo para o notepad.\n \
 Por favor use um editor diferente."
-STRING_NOTEXT,                                 "Você não digitou nenhum texto. \
+STRING_NOTEXT,                    "Você não digitou nenhum texto. \
 \nPor favor digite alguma coisa e tente novamente"
-STRING_DOESNOTEXIST,                           "Arquivo '%s'\nnão existe\n\n \
+STRING_DOESNOTEXIST,                "Arquivo '%s'\nnão existe\n\n \
 Você deseja criar um novo arquivo?"
-STRING_NOTSAVED,                               "Arquivo '%s'\nfoi modificado\n\n \
+STRING_NOTSAVED,                "Arquivo '%s'\nfoi modificado\n\n \
 Gostaria de salvar as alteraçÕes?"
-STRING_NOTFOUND,                                       "'%s' não pode ser encontrado."
-STRING_OUT_OF_MEMORY,                  "Não há memória suficiente para completar essa \
+STRING_NOTFOUND,                    "'%s' não pode ser encontrado."
+STRING_OUT_OF_MEMORY,            "Não há memória suficiente para completar essa \
 tarefa. \nFeche uma ou mais aplicações para aumentar a quantidade de memória livre."
 STRING_CANNOTFIND                               "Cannot find '%s'"
 STRING_ANSI,                                    "ANSI"
index 186d37a..c19efa2 100644 (file)
@@ -27,7 +27,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -38,54 +40,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Ôàéë"
-       BEGIN
-               MENUITEM "Ñîçä&àòü",                CMD_NEW
-               MENUITEM "&Îòêðûòü...",             CMD_OPEN
-               MENUITEM "&Ñîõðàíèòü",              CMD_SAVE
-               MENUITEM "Ñîõðàíèòü &êàê...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Ïàðà&ìåòðû ñòðàíèöû...",  CMD_PAGE_SETUP
-               MENUITEM "&Ïå÷àòàòü",               CMD_PRINT
-               MENUITEM "&Íàñòðîéêà ïðèíòåðà...",  CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "Â&ûõîä",                  CMD_EXIT
-       END
-       POPUP "&Ïðàâêà"
-       BEGIN
-               MENUITEM "&Îòìåíèòü\tCtrl+Z",       CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Âûðåçàòü\tCtrl+X",       CMD_CUT
-               MENUITEM "&Êîïèðîâàòü\tCtrl+C",     CMD_COPY
-               MENUITEM "Âñò&àâèòü\tCtrl+V",       CMD_PASTE
-               MENUITEM "&Óäàëèòü\tDel",           CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Íàéòè",                  CMD_SEARCH
-               MENUITEM "Íàéòè &äàëåå\tF3",        CMD_SEARCH_NEXT
-               MENUITEM "Çàìåíèòü\tCtrl+H",        CMD_REPLACE
-               MENUITEM "Ïåðåéòè ê...\tCtrl+G",    CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Âûäåëèòü â&ñå",           CMD_SELECT_ALL
-               MENUITEM "Âðåì&ÿ è äàòà\tF5",       CMD_TIME_DATE
-       END
-       POPUP "Ôî&ðìàò"
-       BEGIN
-               MENUITEM "&Ïåðåíîñ ïî ñëîâàì",      CMD_WRAP
-               MENUITEM "&Øðèôò...",               CMD_FONT
-       END
-       POPUP "&Âèä"
-       BEGIN
-               MENUITEM "Ñòðîêà &ñîñòîÿíèÿ",       CMD_STATUSBAR
-       END
-       POPUP "&Ñïðàâêà"
-       BEGIN
-               MENUITEM "&Ñîäåðæàíèå",             CMD_HELP_CONTENTS
-               MENUITEM "&Ïîèñê...",               CMD_HELP_SEARCH
-               MENUITEM "&Èñïîëüçîâàíèå ñïðàâêè",  CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&Πïðîãðàììå"             CMD_ABOUT
-               MENUITEM "&Ñâåäåíèÿ...",            CMD_ABOUT_WINE
-       END
+    POPUP "&Ôàéë"
+    BEGIN
+        MENUITEM "Ñîçä&àòü\tCtrl+N",       CMD_NEW
+        MENUITEM "&Îòêðûòü\tCtrl+O",       CMD_OPEN
+        MENUITEM "&Ñîõðàíèòü\tCtrl+S",     CMD_SAVE
+        MENUITEM "Ñîõðàíèòü &êàê...",      CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Ïàðà&ìåòðû ñòðàíèöû...", CMD_PAGE_SETUP
+        MENUITEM "&Ïå÷àòàòü\tCtrl+P",      CMD_PRINT
+        MENUITEM "&Íàñòðîéêà ïðèíòåðà...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Â&ûõîä",                 CMD_EXIT
+    END
+    POPUP "&Ïðàâêà"
+    BEGIN
+        MENUITEM "&Îòìåíèòü\tCtrl+Z",    CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Âûðåçàòü\tCtrl+X",    CMD_CUT
+        MENUITEM "&Êîïèðîâàòü\tCtrl+C",  CMD_COPY
+        MENUITEM "Âñò&àâèòü\tCtrl+V",    CMD_PASTE
+        MENUITEM "&Óäàëèòü\tDel",        CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Íàéòè",               CMD_SEARCH
+        MENUITEM "Íàéòè &äàëåå\tF3",     CMD_SEARCH_NEXT
+        MENUITEM "Çàìåíèòü\tCtrl+H",     CMD_REPLACE
+        MENUITEM "Ïåðåéòè ê...\tCtrl+G", CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Âûäåëèòü â&ñå",        CMD_SELECT_ALL
+        MENUITEM "Âðåì&ÿ è äàòà\tF5",    CMD_TIME_DATE
+    END
+    POPUP "Ôî&ðìàò"
+    BEGIN
+        MENUITEM "&Ïåðåíîñ ïî ñëîâàì", CMD_WRAP
+        MENUITEM "&Øðèôò...",          CMD_FONT
+    END
+    POPUP "&Âèä"
+    BEGIN
+        MENUITEM "Ñòðîêà &ñîñòîÿíèÿ", CMD_STATUSBAR
+    END
+    POPUP "&Ñïðàâêà"
+    BEGIN
+        MENUITEM "&Ñîäåðæàíèå",            CMD_HELP_CONTENTS
+        MENUITEM "&Ïîèñê...",              CMD_HELP_SEARCH
+        MENUITEM "&Èñïîëüçîâàíèå ñïðàâêè", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Πïðîãðàììå"            CMD_ABOUT
+        MENUITEM "&Ñâåäåíèÿ...",           CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 04411c4..e1f48d4 100644 (file)
@@ -7,7 +7,7 @@
  *  Translation:
  *  TRANSLATOR :  Mário Kaèmár /Mario Kacmar/ aka Kario (kario@szm.sk)
  *  DATE OF TR.:  xx-xx-2007 
- *  LAST CHANGE:  04-11-2008
+ *  LAST CHANGE:  27-12-2008
  */
 
 LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
@@ -19,7 +19,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -30,54 +32,53 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Súbor"
-       BEGIN
-               MENUITEM "&Nový...",            CMD_NEW
-               MENUITEM "&Otvori\9d",            CMD_OPEN
-               MENUITEM "&Ulo\9ei\9d",             CMD_SAVE
-               MENUITEM "Ulo\9ei\9d &ako...",      CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "&Tlaèi\9d",             CMD_PRINT
-               MENUITEM "Nasta&venie strany...",       CMD_PAGE_SETUP
-               MENUITEM "Nastavenie tlaèia&rne...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Skonèi\9d",            CMD_EXIT
+    POPUP "&Súbor"
+    BEGIN
+        MENUITEM "&Nový\tCtrl+N",            CMD_NEW
+        MENUITEM "&Otvori\9d...\tCtrl+O",       CMD_OPEN
+        MENUITEM "&Ulo\9ei\9d\tCtrl+S",           CMD_SAVE
+        MENUITEM "Ulo\9ei\9d &ako...",            CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Tlaèi\9d\tCtrl+P",           CMD_PRINT
+        MENUITEM "Nasta&venie strany...",    CMD_PAGE_SETUP
+        MENUITEM "Nastavenie tlaèia&rne...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Skonèi\9d",                  CMD_EXIT
  END
-       POPUP "Úpr&avy"
-       BEGIN
-               MENUITEM "&Spä\9d\tCtrl+Z",       CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Vystrihnú\9d\tCtrl+X", CMD_CUT
-               MENUITEM "&Kopírova\9d\tCtrl+C",  CMD_COPY
-               MENUITEM "Pri&lepi\9d\tCtrl+V",   CMD_PASTE
-               MENUITEM "&Odstráni\9d\tDel",     CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&H¾ada\9d", CMD_SEARCH
-               MENUITEM "H¾a&da\9d ïalej\tF3",   CMD_SEARCH_NEXT
-               MENUITEM "&Nahradi\9d\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Pr&ejs\9d na...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Vy&bra\9d v\9aetko",      CMD_SELECT_ALL
-               MENUITEM "Èas alebo dátu&m\tF5",        CMD_TIME_DATE
-       END
-       POPUP "F&ormát"
-       BEGIN
-               MENUITEM "&Zalomi\9d text",       CMD_WRAP
-               MENUITEM "&Písmo...",          CMD_FONT
+    POPUP "Úpr&avy"
+    BEGIN
+        MENUITEM "&Spä\9d\tCtrl+Z",         CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Vystrihnú\9d\tCtrl+X",   CMD_CUT
+        MENUITEM "&Kopírova\9d\tCtrl+C",    CMD_COPY
+        MENUITEM "Pri&lepi\9d\tCtrl+V",     CMD_PASTE
+        MENUITEM "&Odstráni\9d\tDel",       CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&H¾ada\9d",               CMD_SEARCH
+        MENUITEM "H¾a&da\9d ïalej\tF3",     CMD_SEARCH_NEXT
+        MENUITEM "&Nahradi\9d\tCtrl+H",     CMD_REPLACE
+        MENUITEM "Pr&ejs\9d na...\tCtrl+G", CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Vy&bra\9d v\9aetko",        CMD_SELECT_ALL
+        MENUITEM "Èas alebo dátu&m\tF5", CMD_TIME_DATE
+    END
+    POPUP "F&ormát"
+    BEGIN
+        MENUITEM "&Zalomi\9d text", CMD_WRAP
+        MENUITEM "&Písmo...",    CMD_FONT
         END
-       POPUP "&Zobrazi\9d"
-       BEGIN
-               MENUITEM "Stavový &riadok",    CMD_STATUSBAR
-       END
-       POPUP "&Pomocník"
-       BEGIN
-               MENUITEM "&Témy Pomocníka",             CMD_HELP_CONTENTS
-               MENUITEM "&H¾ada\9d...",  CMD_HELP_SEARCH
-               MENUITEM "&Pomoc",      CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM SEPARATOR
-               MENUITEM "È&o je Poznámkový blok"             CMD_ABOUT
-               MENUITEM "Èo je &Víno (Wine)",  CMD_ABOUT_WINE
+    POPUP "&Zobrazi\9d"
+    BEGIN
+        MENUITEM "Stavový &riadok", CMD_STATUSBAR
+    END
+    POPUP "&Pomocník"
+    BEGIN
+        MENUITEM "&Témy Pomocníka",       CMD_HELP_CONTENTS
+        MENUITEM "&H¾ada\9d...",             CMD_HELP_SEARCH
+        MENUITEM "&Pomoc",                CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "È&o je Poznámkový blok" CMD_ABOUT
+        MENUITEM "Èo je &Víno (Wine)",    CMD_ABOUT_WINE
   END
  END
 
@@ -155,33 +156,33 @@ END
 
 STRINGTABLE DISCARDABLE
 BEGIN
-STRING_PAGESETUP_HEADERVALUE,  "&n"        /* FIXME */
-STRING_PAGESETUP_FOOTERVALUE,  "Strana &s"   /* FIXME */
-STRING_PAGESETUP_LEFTVALUE,            "20 mm"     /* FIXME */
-STRING_PAGESETUP_RIGHTVALUE,   "20 mm"     /* FIXME */
-STRING_PAGESETUP_TOPVALUE,             "25 mm"     /* FIXME */
-STRING_PAGESETUP_BOTTOMVALUE,  "25 mm"     /* FIXME */
+STRING_PAGESETUP_HEADERVALUE,    "&n"        /* FIXME */
+STRING_PAGESETUP_FOOTERVALUE,    "Strana &s"   /* FIXME */
+STRING_PAGESETUP_LEFTVALUE,        "20 mm"     /* FIXME */
+STRING_PAGESETUP_RIGHTVALUE,    "20 mm"     /* FIXME */
+STRING_PAGESETUP_TOPVALUE,        "25 mm"     /* FIXME */
+STRING_PAGESETUP_BOTTOMVALUE,    "25 mm"     /* FIXME */
 
-STRING_NOTEPAD,                                        "Poznámkový blok"
-STRING_ERROR,                                  "CHYBA"
-STRING_WARNING,                                        "UPOZORNENIE"
-STRING_INFO,                                   "Informácie"
+STRING_NOTEPAD,                    "Poznámkový blok"
+STRING_ERROR,                    "CHYBA"
+STRING_WARNING,                    "UPOZORNENIE"
+STRING_INFO,                    "Informácie"
 
-STRING_UNTITLED,                               "(bez názvu)"
+STRING_UNTITLED,                "(bez názvu)"
 
-STRING_ALL_FILES,                              "V\9aetky súbory (*.*)"
-STRING_TEXT_FILES_TXT,                 "Textové súbory (*.txt)"
+STRING_ALL_FILES,                "V\9aetky súbory (*.*)"
+STRING_TEXT_FILES_TXT,            "Textové súbory (*.txt)"
 
-STRING_TOOLARGE,                               "Súbor '%s' je pre Poznámkový blok príli\9a ve¾ký.\n \
+STRING_TOOLARGE,                "Súbor '%s' je pre Poznámkový blok príli\9a ve¾ký.\n \
 Na otvorenie súboru pou\9eite iný editor."
-STRING_NOTEXT,                                 "Nevlo\9eili ste \9eiadny text. \
+STRING_NOTEXT,                    "Nevlo\9eili ste \9eiadny text. \
 \nProsím, napí\9ate nieèo a skúste to znova."
-STRING_DOESNOTEXIST,                           "Nie je mo\9ené nájs\9d súbor '%s'\n\n \
+STRING_DOESNOTEXIST,                "Nie je mo\9ené nájs\9d súbor '%s'\n\n \
 Chcete vytvori\9d nový súbor?"
-STRING_NOTSAVED,                               "Text súboru '%s'\nsa zmenil.\n\n \
+STRING_NOTSAVED,                "Text súboru '%s'\nsa zmenil.\n\n \
 Chcete ulo\9ei\9d zmeny?"
-STRING_NOTFOUND,                                       "Nie je mo\9ené nájs\9d '%s' ."
-STRING_OUT_OF_MEMORY,                  "Nedostatok pamäte na dokonèenie tejto operácie. Zatvorte jednu \n \
+STRING_NOTFOUND,                    "Nie je mo\9ené nájs\9d '%s' ."
+STRING_OUT_OF_MEMORY,            "Nedostatok pamäte na dokonèenie tejto operácie. Zatvorte jednu \n \
 alebo viac aplikácií, aby sa uvo¾nila pamä\9d a skúste to znova."
 STRING_CANNOTFIND                               "Nemo\9eno nájs\9d '%s'"
 STRING_ANSI,                                    "ANSI"
index 8c3c3a8..2ea6d05 100644 (file)
@@ -27,7 +27,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -38,54 +40,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Datoteka"
-       BEGIN
-               MENUITEM "&Nova",           CMD_NEW
-               MENUITEM "&Odpri ...",             CMD_OPEN
-               MENUITEM "&Shrani",             CMD_SAVE
-               MENUITEM "Shrani &kot ...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Na&tisni",            CMD_PRINT
-               MENUITEM "P&riprava strani ...",    CMD_PAGE_SETUP
-               MENUITEM "&Tiskalnik ...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "Iz&hod",             CMD_EXIT
-       END
-       POPUP "&Urejanje"
-       BEGIN
-               MENUITEM "&Razveljavi\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Izre\9ei\tCtrl+X",      CMD_CUT
-               MENUITEM "&Kopiraj\tCtrl+C",     CMD_COPY
-               MENUITEM "&Prilepi\tCtrl+V",    CMD_PASTE
-               MENUITEM "Izbri&\9ai\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "&Najdi ...",           CMD_SEARCH
-               MENUITEM "Na&daljuj iskanje\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Izberi &vse",       CMD_SELECT_ALL
-               MENUITEM "Èas/&Datum\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "Pr&elom vrstice",  CMD_WRAP
-               MENUITEM "&Font...",          CMD_FONT
+    POPUP "&Datoteka"
+    BEGIN
+        MENUITEM "&Nova\tCtrl+N",        CMD_NEW
+        MENUITEM "&Odpri\tCtrl+O",       CMD_OPEN
+        MENUITEM "&Shrani\tCtrl+S",      CMD_SAVE
+        MENUITEM "Shrani &kot ...",      CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Na&tisni\tCtrl+P",     CMD_PRINT
+        MENUITEM "P&riprava strani ...", CMD_PAGE_SETUP
+        MENUITEM "&Tiskalnik ...",       CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Iz&hod",               CMD_EXIT
+    END
+    POPUP "&Urejanje"
+    BEGIN
+        MENUITEM "&Razveljavi\tCtrl+Z",   CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Izre\9ei\tCtrl+X",       CMD_CUT
+        MENUITEM "&Kopiraj\tCtrl+C",      CMD_COPY
+        MENUITEM "&Prilepi\tCtrl+V",      CMD_PASTE
+        MENUITEM "Izbri&\9ai\tDel",         CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "&Najdi ...",            CMD_SEARCH
+        MENUITEM "Na&daljuj iskanje\tF3", CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",       CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",      CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Izberi &vse",           CMD_SELECT_ALL
+        MENUITEM "Èas/&Datum\tF5",        CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "Pr&elom vrstice", CMD_WRAP
+        MENUITEM "&Font...",        CMD_FONT
         END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "&Pomoè"
-       BEGIN
-               MENUITEM "&Teme pomoèi",         CMD_HELP_CONTENTS
-               MENUITEM "&Najdi ...",        CMD_HELP_SEARCH
-               MENUITEM "&O pomoèi",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "Inf&ormacije ...",      CMD_ABOUT_WINE
-       END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Pomoè"
+    BEGIN
+        MENUITEM "&Teme pomoèi",     CMD_HELP_CONTENTS
+        MENUITEM "&Najdi ...",       CMD_HELP_SEARCH
+        MENUITEM "&O pomoèi",        CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"            CMD_ABOUT
+        MENUITEM "Inf&ormacije ...", CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 4b54bbc..d3713ac 100644 (file)
@@ -30,7 +30,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -41,54 +43,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "&Arkiv"
-       BEGIN
-               MENUITEM "&Ny...",            CMD_NEW
-               MENUITEM "&Öppna",            CMD_OPEN
-               MENUITEM "&Spara",            CMD_SAVE
-               MENUITEM "Spara so&m...",     CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "Skriv &ut...",         CMD_PRINT
-               MENUITEM "Utskrifts&format...",    CMD_PAGE_SETUP
-               MENUITEM "Skrivar&inställningar...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "&Avsluta",          CMD_EXIT
-       END
-       POPUP "&Redigera"
-       BEGIN
-               MENUITEM "&Ångra\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "&Klipp ut\tCtrl+X",    CMD_CUT
-               MENUITEM "K&opiera\tCtrl+C",  CMD_COPY
-               MENUITEM "K&listra in\tCtrl+V",       CMD_PASTE
-               MENUITEM "&Ta bort\tDel",     CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "Sök...",            CMD_SEARCH
-               MENUITEM "&Sök nästa\tF3",    CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "Markera &allt",     CMD_SELECT_ALL
-               MENUITEM "&Tid/datum\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "&Automatiskt radbyte",      CMD_WRAP
-               MENUITEM "&Font...",          CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "&Hjälp"
-       BEGIN
-               MENUITEM "&Innehåll",         CMD_HELP_CONTENTS
-               MENUITEM "&Sök...",           CMD_HELP_SEARCH
-               MENUITEM "Anvisningar för hjälpen",    CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "Inf&ormation...",         CMD_ABOUT_WINE
-       END
+    POPUP "&Arkiv"
+    BEGIN
+        MENUITEM "&Ny\tCtrl+N",              CMD_NEW
+        MENUITEM "&Öppna\tCtrl+O",           CMD_OPEN
+        MENUITEM "&Spara\tCtrl+S",           CMD_SAVE
+        MENUITEM "Spara so&m...",            CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Skriv &ut\tCtrl+P",        CMD_PRINT
+        MENUITEM "Utskrifts&format...",      CMD_PAGE_SETUP
+        MENUITEM "Skrivar&inställningar...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Avsluta",                 CMD_EXIT
+    END
+    POPUP "&Redigera"
+    BEGIN
+        MENUITEM "&Ångra\tCtrl+Z",      CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Klipp ut\tCtrl+X",   CMD_CUT
+        MENUITEM "K&opiera\tCtrl+C",    CMD_COPY
+        MENUITEM "K&listra in\tCtrl+V", CMD_PASTE
+        MENUITEM "&Ta bort\tDel",       CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "Sök...",              CMD_SEARCH
+        MENUITEM "&Sök nästa\tF3",      CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",     CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",    CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Markera &allt",       CMD_SELECT_ALL
+        MENUITEM "&Tid/datum\tF5",      CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "&Automatiskt radbyte", CMD_WRAP
+        MENUITEM "&Font...",             CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "&Hjälp"
+    BEGIN
+        MENUITEM "&Innehåll",               CMD_HELP_CONTENTS
+        MENUITEM "&Sök...",                 CMD_HELP_SEARCH
+        MENUITEM "Anvisningar för hjälpen", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"                   CMD_ABOUT
+        MENUITEM "Inf&ormation...",         CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
@@ -191,7 +193,7 @@ Vill du skapa en ny fil?"
 STRING_NOTSAVED,                                "Filen '%s'\nhar ändrats.\n\n \
 Vill du spara ändringarna?"
 STRING_NOTFOUND,                                        "'%s' hittades inte."
-STRING_OUT_OF_MEMORY,                  "Det finns inte tillräckligt med minne för att kunna slutföra \
+STRING_OUT_OF_MEMORY,            "Det finns inte tillräckligt med minne för att kunna slutföra \
 den här åtgärden. \nAvsluta ett eller flera program för att frigöra mer minne."
 STRING_CANNOTFIND                               "Cannot find '%s'"
 STRING_ANSI,                                    "ANSI"
index bdb359e..9e8c2ce 100644 (file)
@@ -27,7 +27,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -38,54 +40,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "á¿éÁ"
-       BEGIN
-               MENUITEM "ÊÃéÒ§ãËÁè...",        CMD_NEW
-               MENUITEM "à»Ô´...\tCtrl+O",   CMD_OPEN
-               MENUITEM "ºÑ¹·×¡\tCtrl+S",     CMD_SAVE
-               MENUITEM "ºÑ¹·×¡à»ç¹...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "¾ÔÁ¾ì",            CMD_PRINT
-               MENUITEM "»ÃѺáµè§Ë¹éÒ...",    CMD_PAGE_SETUP
-               MENUITEM "»ÃѺáµè§à¤Ã×èͧ¾ÔÁ¾ì...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "ÍÍ¡",             CMD_EXIT
+    POPUP "á¿éÁ"
+    BEGIN
+        MENUITEM "ÊÃéÒ§ãËÁè\tCtrl+N",       CMD_NEW
+        MENUITEM "à»Ô´...\tCtrl+O",         CMD_OPEN
+        MENUITEM "ºÑ¹·×¡\tCtrl+S",          CMD_SAVE
+        MENUITEM "ºÑ¹·×¡à»ç¹...",           CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "¾ÔÁ¾ì\tCtrl+P",           CMD_PRINT
+        MENUITEM "»ÃѺáµè§Ë¹éÒ...",         CMD_PAGE_SETUP
+        MENUITEM "»ÃѺáµè§à¤Ã×èͧ¾ÔÁ¾ì...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "ÍÍ¡",                     CMD_EXIT
+    END
+    POPUP "á¡éä¢"
+    BEGIN
+        MENUITEM "àÃÕ¡¤×¹\tCtrl+Z",     CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "µÑ´\tCtrl+X",          CMD_CUT
+        MENUITEM "µÑ´ÅÍ¡\tCtrl+C",       CMD_COPY
+        MENUITEM "ÇÒ§\tCtrl+V",          CMD_PASTE
+        MENUITEM "ź\tDel",              CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "¤é¹ËÒ\tCtrl+F",        CMD_SEARCH
+        MENUITEM "¤é¹ËÒµèÍä»\tF3",       CMD_SEARCH_NEXT
+        MENUITEM "Replace\tCtrl+H",      CMD_REPLACE
+        MENUITEM "Go To...\tCtrl+G",     CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "àÅ×Í¡·Ñé§ËÁ´\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "Çѹ·Õè/\tF5",          CMD_TIME_DATE
+    END
+    POPUP "F&ormat"
+    BEGIN
+        MENUITEM "ËèͺÃ÷ѴÂÒÇ",      CMD_WRAP
+        MENUITEM "ÃٻẺ´ÑÇÍÑ¡ÉÃ...", CMD_FONT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "Status&bar", CMD_STATUSBAR
+    END
+    POPUP "ªèÇÂàËÅÕÍ"
+    BEGIN
+        MENUITEM "à¹×éÍËÒ",            CMD_HELP_CONTENTS
+        MENUITEM "¤é¹ËÒ...",           CMD_HELP_SEARCH
+        MENUITEM "à¡ÕèÂǡѺªèÇÂàËÅÕÍ", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&About"              CMD_ABOUT
+        MENUITEM "ÃÒÂÅÐàÍÕ´...",      CMD_ABOUT_WINE
     END
-       POPUP "á¡éä¢"
-       BEGIN
-               MENUITEM "àÃÕ¡¤×¹\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "µÑ´\tCtrl+X",      CMD_CUT
-               MENUITEM "µÑ´ÅÍ¡\tCtrl+C",     CMD_COPY
-               MENUITEM "ÇÒ§\tCtrl+V",    CMD_PASTE
-               MENUITEM "ź\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "¤é¹ËÒ\tCtrl+F",   CMD_SEARCH
-               MENUITEM "¤é¹ËÒµèÍä»\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Replace\tCtrl+H",   CMD_REPLACE
-               MENUITEM "Go To...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "àÅ×Í¡·Ñé§ËÁ´\tCtrl+A",       CMD_SELECT_ALL
-               MENUITEM "Çѹ·Õè/\tF5",    CMD_TIME_DATE
-       END
-       POPUP "F&ormat"
-       BEGIN
-               MENUITEM "ËèͺÃ÷ѴÂÒÇ",  CMD_WRAP
-               MENUITEM "ÃٻẺ´ÑÇÍÑ¡ÉÃ...",          CMD_FONT
-       END
-       POPUP "&View"
-       BEGIN
-               MENUITEM "Status&bar",    CMD_STATUSBAR
-       END
-       POPUP "ªèÇÂàËÅÕÍ"
-       BEGIN
-               MENUITEM "à¹×éÍËÒ",         CMD_HELP_CONTENTS
-               MENUITEM "¤é¹ËÒ...",        CMD_HELP_SEARCH
-               MENUITEM "à¡ÕèÂǡѺªèÇÂàËÅÕÍ",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "&About"             CMD_ABOUT
-               MENUITEM "ÃÒÂÅÐàÍÕ´...", CMD_ABOUT_WINE
-       END
 END
 
 /* Dialog `Page setup' */
index 11cc718..4a7f194 100644 (file)
@@ -27,7 +27,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -38,54 +40,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
- POPUP "&Ôàéë"
- BEGIN
-  MENUITEM "&Ñòâîðèòè",              CMD_NEW
-  MENUITEM "&³äêðèòè...\tCtrl+O",   CMD_OPEN
-  MENUITEM "&Ç&áåðåãòè\tCtrl+S",     CMD_SAVE
-  MENUITEM "Çáåðåãòè &ÿê...",        CMD_SAVE_AS
-  MENUITEM SEPARATOR
-  MENUITEM "Ïàðà&ìåòðè ñòîð³íêè...", CMD_PAGE_SETUP
-  MENUITEM "Ä&ðóê",                  CMD_PRINT
-  MENUITEM "Íàñòðîéêà &ïðèíòåðà...", CMD_PRINTER_SETUP
-  MENUITEM SEPARATOR
-  MENUITEM "Â&èõ³ä",                 CMD_EXIT
- END
-POPUP "&Ïðàâêà"
- BEGIN
-  MENUITEM "&Ñêàñóâàòè\tCtrl+Z",     CMD_UNDO
-  MENUITEM SEPARATOR
-  MENUITEM "&Âèð³çàòè\tCtrl+X",      CMD_CUT
-  MENUITEM "&Êîï³þâàòè\tCtrl+C",     CMD_COPY
-  MENUITEM "Âñò&àâèòè\tCtrl+V",      CMD_PASTE
-  MENUITEM "Â&èäàëèòè\tDel",         CMD_DELETE
-  MENUITEM SEPARATOR
-  MENUITEM "Ç&íàéòè...\tCtrl+F",     CMD_SEARCH
-  MENUITEM "Çíà&éòè äàë³\tF3",       CMD_SEARCH_NEXT
-  MENUITEM "&Çàì³íèòè\tCtrl+H",      CMD_REPLACE
-  MENUITEM "Ïåðåé&òè...\tCtrl+G",    CMD_GOTO
-  MENUITEM SEPARATOR
-  MENUITEM "Âèä³&ëèòè âñå\tCtrl+A",  CMD_SELECT_ALL
-  MENUITEM "&Äàòà é ÷àñ\tF5",        CMD_TIME_DATE
- END
-POPUP "Ôîð&ìàò"
- BEGIN
-  MENUITEM "&Ïåðåíîñ ïî ñëîâàõ",     CMD_WRAP
-  MENUITEM "&Øðèôò...",              CMD_FONT
-END
-POPUP "&Âèãëÿä"
- BEGIN
-  MENUITEM "&Ðÿäîê ñòàíó",           CMD_STATUSBAR
-END
-POPUP "&Äîâ³äêà"
- BEGIN
-  MENUITEM "&Çì³ñò",                 CMD_HELP_CONTENTS
-  MENUITEM "&Ïîøóê...",              CMD_HELP_SEARCH
-  MENUITEM "&Help on help",          CMD_HELP_ON_HELP
-  MENUITEM SEPARATOR
-               MENUITEM "&Ïðî"      CMD_ABOUT
-  MENUITEM "&Ïðî ïðîãðàìó",          CMD_ABOUT_WINE
- END
   POPUP "&Ôàéë"
   BEGIN
+        MENUITEM "&Ñòâîðèòè\tCtrl+N",      CMD_NEW
+        MENUITEM "&³äêðèòè...\tCtrl+O",   CMD_OPEN
+        MENUITEM "&Ç&áåðåãòè\tCtrl+S",     CMD_SAVE
+        MENUITEM "Çáåðåãòè &ÿê...",        CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "Ïàðà&ìåòðè ñòîð³íêè...", CMD_PAGE_SETUP
+        MENUITEM "Ä&ðóê\tCtrl+P",          CMD_PRINT
+        MENUITEM "Íàñòðîéêà &ïðèíòåðà...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Â&èõ³ä",                 CMD_EXIT
   END
+    POPUP "&Ïðàâêà"
   BEGIN
+        MENUITEM "&Ñêàñóâàòè\tCtrl+Z",    CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "&Âèð³çàòè\tCtrl+X",     CMD_CUT
+        MENUITEM "&Êîï³þâàòè\tCtrl+C",    CMD_COPY
+        MENUITEM "Âñò&àâèòè\tCtrl+V",     CMD_PASTE
+        MENUITEM "Â&èäàëèòè\tDel",        CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "Ç&íàéòè...\tCtrl+F",    CMD_SEARCH
+        MENUITEM "Çíà&éòè äàë³\tF3",      CMD_SEARCH_NEXT
+        MENUITEM "&Çàì³íèòè\tCtrl+H",     CMD_REPLACE
+        MENUITEM "Ïåðåé&òè...\tCtrl+G",   CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "Âèä³&ëèòè âñå\tCtrl+A", CMD_SELECT_ALL
+        MENUITEM "&Äàòà é ÷àñ\tF5",       CMD_TIME_DATE
   END
+    POPUP "Ôîð&ìàò"
   BEGIN
+        MENUITEM "&Ïåðåíîñ ïî ñëîâàõ", CMD_WRAP
+        MENUITEM "&Øðèôò...",          CMD_FONT
+    END
+    POPUP "&Âèãëÿä"
   BEGIN
+        MENUITEM "&Ðÿäîê ñòàíó", CMD_STATUSBAR
+    END
+    POPUP "&Äîâ³äêà"
   BEGIN
+        MENUITEM "&Çì³ñò",        CMD_HELP_CONTENTS
+        MENUITEM "&Ïîøóê...",     CMD_HELP_SEARCH
+        MENUITEM "&Help on help", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "&Ïðî"           CMD_ABOUT
+        MENUITEM "&Ïðî ïðîãðàìó", CMD_ABOUT_WINE
   END
 END
 
 /* Dialog `Page setup' */
index fe179b7..53a03bd 100644 (file)
@@ -28,7 +28,9 @@ BEGIN
     "^F", CMD_SEARCH
     "^G", CMD_GOTO
     "H", CMD_REPLACE, VIRTKEY, CONTROL
+    "^N", CMD_NEW
     "^O", CMD_OPEN
+    "^P", CMD_PRINT
     "^S", CMD_SAVE
     "^V", CMD_PASTE
     "^X", CMD_CUT
@@ -39,54 +41,54 @@ END
 
 MAIN_MENU MENU
 BEGIN
-       POPUP "Îļþ(&F)"
-       BEGIN
-               MENUITEM "н¨(&N)...",           CMD_NEW
-               MENUITEM "´ò¿ª(&O)",             CMD_OPEN
-               MENUITEM "±£´æ(&S)",             CMD_SAVE
-               MENUITEM "Áí´æΪ(&A)...",       CMD_SAVE_AS
-               MENUITEM SEPARATOR
-               MENUITEM "´òÓ¡(&P)",            CMD_PRINT
-               MENUITEM "Ò³ÃæÉèÖÃ(&T)...",    CMD_PAGE_SETUP
-               MENUITEM "´òÓ¡ÉèÖÃ(&R)...", CMD_PRINTER_SETUP
-               MENUITEM SEPARATOR
-               MENUITEM "Í˳ö(&E)",             CMD_EXIT
-       END
-       POPUP "±à¼­(&E)"
-       BEGIN
-               MENUITEM "³·Ïû(&U)\tCtrl+Z",     CMD_UNDO
-               MENUITEM SEPARATOR
-               MENUITEM "¼ôÇÐ(&T)\tCtrl+X",      CMD_CUT
-               MENUITEM "¸´ÖÆ(&C)\tCtrl+C",     CMD_COPY
-               MENUITEM "Õ³Ìù(&P)\tCtrl+V",    CMD_PASTE
-               MENUITEM "ɾ³ý(&D)\tDel",      CMD_DELETE
-               MENUITEM SEPARATOR
-               MENUITEM "ËÑË÷(&S)",           CMD_SEARCH
-               MENUITEM "ËÑË÷ÏÂÒ»¸ö(&S)\tF3",  CMD_SEARCH_NEXT
-               MENUITEM "Ìæ»»\tCtrl+H",   CMD_REPLACE
-               MENUITEM "תµ½...\tCtrl+G",  CMD_GOTO
-               MENUITEM SEPARATOR
-               MENUITEM "ȫѡ(&A)",       CMD_SELECT_ALL
-               MENUITEM "²åÈëÈÕÆÚ¡¢Ê±¼ä(&T)\tF5",    CMD_TIME_DATE
-       END
-       POPUP "¸ñʽ(&O)"
-       BEGIN
-               MENUITEM "×Ô¶¯»»ÐÐ(&W)",  CMD_WRAP
-               MENUITEM "×ÖÌå(&F)...",          CMD_FONT
-       END
-       POPUP "²é¿´(&V)"
-       BEGIN
-               MENUITEM "״̬À¸(&B)",    CMD_STATUSBAR
-       END
-       POPUP "°ïÖú(&H)"
-       BEGIN
-               MENUITEM "ÄÚÈÝ(&C)",         CMD_HELP_CONTENTS
-               MENUITEM "ËÑË÷(&S)...",        CMD_HELP_SEARCH
-               MENUITEM "ÈçºÎʹÓðïÖú(&H)",     CMD_HELP_ON_HELP
-               MENUITEM SEPARATOR
-               MENUITEM "¹ØÓÚ(&A)"             CMD_ABOUT
-               MENUITEM "×ÊÁÏÐÅÏ¢(&O)...",      CMD_ABOUT_WINE
-       END
+    POPUP "Îļþ(&F)"
+    BEGIN
+        MENUITEM "н¨(&N)...",     CMD_NEW
+        MENUITEM "´ò¿ª(&O)",        CMD_OPEN
+        MENUITEM "±£´æ(&S)",        CMD_SAVE
+        MENUITEM "Áí´æΪ(&A)...",   CMD_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "´òÓ¡(&P)",        CMD_PRINT
+        MENUITEM "Ò³ÃæÉèÖÃ(&T)...", CMD_PAGE_SETUP
+        MENUITEM "´òÓ¡ÉèÖÃ(&R)...", CMD_PRINTER_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Í˳ö(&E)",        CMD_EXIT
+    END
+    POPUP "±à¼­(&E)"
+    BEGIN
+        MENUITEM "³·Ïû(&U)\tCtrl+Z",       CMD_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "¼ôÇÐ(&T)\tCtrl+X",       CMD_CUT
+        MENUITEM "¸´ÖÆ(&C)\tCtrl+C",       CMD_COPY
+        MENUITEM "Õ³Ìù(&P)\tCtrl+V",       CMD_PASTE
+        MENUITEM "ɾ³ý(&D)\tDel",          CMD_DELETE
+        MENUITEM SEPARATOR
+        MENUITEM "ËÑË÷(&S)",               CMD_SEARCH
+        MENUITEM "ËÑË÷ÏÂÒ»¸ö(&S)\tF3",     CMD_SEARCH_NEXT
+        MENUITEM "Ìæ»»\tCtrl+H",           CMD_REPLACE
+        MENUITEM "תµ½...\tCtrl+G",        CMD_GOTO
+        MENUITEM SEPARATOR
+        MENUITEM "ȫѡ(&A)",               CMD_SELECT_ALL
+        MENUITEM "²åÈëÈÕÆÚ¡¢Ê±¼ä(&T)\tF5", CMD_TIME_DATE
+    END
+    POPUP "¸ñʽ(&O)"
+    BEGIN
+        MENUITEM "×Ô¶¯»»ÐÐ(&W)", CMD_WRAP
+        MENUITEM "×ÖÌå(&F)...",  CMD_FONT
+    END
+    POPUP "²é¿´(&V)"
+    BEGIN
+        MENUITEM "״̬À¸(&B)", CMD_STATUSBAR
+    END
+    POPUP "°ïÖú(&H)"
+    BEGIN
+        MENUITEM "ÄÚÈÝ(&C)",         CMD_HELP_CONTENTS
+        MENUITEM "ËÑË÷(&S)...",      CMD_HELP_SEARCH
+        MENUITEM "ÈçºÎʹÓðïÖú(&H)", CMD_HELP_ON_HELP
+        MENUITEM SEPARATOR
+        MENUITEM "¹ØÓÚ(&A)"          CMD_ABOUT
+        MENUITEM "×ÊÁÏÐÅÏ¢(&O)...",  CMD_ABOUT_WINE
+    END
 END
 
 /* Dialog `Page setup' */
index 476400e..6f98a54 100644 (file)
@@ -198,7 +198,6 @@ END
 
 IDD_PROCESS_PAGE DIALOGEX DISCARDABLE  0, 0, 247, 210
 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
-CAPTION "KMK"
 FONT 8, "MS Shell Dlg"
 BEGIN
     CONTROL         "List2",IDC_PROCESSLIST,"SysListView32",LVS_REPORT |
@@ -366,7 +365,7 @@ BEGIN
     CONTROL         "&Billede Navn",IDC_IMAGENAME,"Button",BS_AUTOCHECKBOX |
                     WS_DISABLED | WS_TABSTOP,7,28,56,10
     CONTROL         "&PID (Process Identifikation)",IDC_PID,"Button",
-                    BS_AUTOCHECKBOX | WS_TABSTOP,7, 39, 100, 10
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,39,100,10
     CONTROL         "&CPU Forbrug",IDC_CPUUSAGE,"Button",BS_AUTOCHECKBOX |
                     WS_TABSTOP,7,50,53,10
     CONTROL         "CPU &Tid",IDC_CPUTIME,"Button",BS_AUTOCHECKBOX |
@@ -605,7 +604,71 @@ BEGIN
     IDS_LICENSE             "Dette program er fri software; du kan formidle det og/eller ændre det 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.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA."
 END
 
-#endif    // English (U.S.) resources
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_TAB_APPS                  "Applications"
+    IDS_TAB_PROCESSES             "Processes"
+    IDS_TAB_PERFORMANCE           "Performance"
+    IDS_TAB_TASK                  "Task"
+    IDS_TAB_STATUS                "Status"
+    IDS_TAB_IMAGENAME             "Image Name"
+    IDS_TAB_PID                   "PID"
+    IDS_TAB_USERNAME              "Username"
+    IDS_TAB_SESSIONID             "Session ID"
+    IDS_TAB_CPU                   "CPU"
+    IDS_TAB_CPUTIME               "CPU Time"
+    IDS_TAB_MEMUSAGE              "Mem Usage"
+    IDS_TAB_PEAKMEMUSAGE          "Peak Mem Usage"
+    IDS_TAB_MEMDELTA              "Mem Delta"
+    IDS_TAB_PAGEFAULT             "Page Faults"
+    IDS_TAB_PFDELTA               "PF Delta"
+    IDS_TAB_VMSIZE                "VM Size"
+    IDS_TAB_PAGEDPOOL             "Paged Pool"
+    IDS_TAB_NPPOOL                "NP Pool"
+    IDS_TAB_BASEPRI               "Base Pri"
+    IDS_TAB_HANDLES               "Handles"
+    IDS_TAB_THREADS               "Threads"
+    IDS_TAB_USERPBJECTS           "USER Objects"
+    IDS_TAB_GDIOBJECTS            "GDI Objects"
+    IDS_TAB_IOREADS               "I/O Reads"
+    IDS_TAB_IOWRITES              "I/O Writes"
+    IDS_TAB_IOOTHER               "I/O Other"
+    IDS_TAB_IOREADBYTES           "I/O Read Bytes"
+    IDS_TAB_IOWRITESBYTES         "I/O Write Bytes"
+    IDS_TAB_IOOTHERBYTES          "I/O Other Bytes"
+    IDS_MENU_SELECTCOLUMNS        "&Select Columns..."
+    IDS_MENU_16BITTASK            "&Show 16-bit tasks"
+    IDS_MENU_WINDOWS              "&Windows"
+    IDS_MENU_LARGEICONS           "Lar&ge Icons"
+    IDS_MENU_SMALLICONS           "S&mall Icons"
+    IDS_MENU_DETAILS              "&Details"
+    IDS_MENU_ONEGRAPHALLCPUS      "&One Graph, All CPUs"
+    IDS_MENU_ONEGRAPHPERCPU       "One Graph &Per CPU"
+    IDS_MENU_CPUHISTORY           "&CPU History"
+    IDS_MENU_SHOWKERNELTIMES      "&Show Kernel Times"
+    IDS_CREATENEWTASK             "Create New Task"
+    IDS_CREATENEWTASK_DESC        "Type the name of a program, folder, document, or Internet resource, and Task Manager will open it for you."
+    IDS_MSG_ACCESSPROCESSAFF      "Unable to Access or Set Process Affinity"
+    IDS_MSG_PROCESSONEPRO         "The process must have affinity with at least one processor."
+    IDS_MSG_INVALIDOPTION         "Invalid Option"
+    IDS_MSG_UNABLEDEBUGPROCESS    "Unable to Debug Process"
+    IDS_MSG_WARNINGDEBUG          "WARNING: Debugging this process may result in loss of data.\nAre you sure you wish to attach the debugger?"
+    IDS_MSG_TASKMGRWARNING        "Task Manager Warning"
+    IDS_MSG_WARNINGTERMINATING    "WARNING: Terminating a process can cause undesired\nresults including loss of data and system instability. The\nprocess will not be given the chance to save its state or\ndata before it is terminated. Are you sure you want to\nterminate the process?"
+    IDS_MSG_UNABLETERMINATEPRO    "Unable to Terminate Process"
+    IDS_MSG_UNABLECHANGEPRIORITY  "Unable to Change Priority"
+    IDS_MSG_WARNINGCHANGEPRIORITY "WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"
+    IDS_MSG_TRAYICONCPUUSAGE      "CPU Usage: %d%%"
+    IDS_STATUS_MEMUSAGE           "Mem Usage: %dK / %dK"
+    IDS_STATUS_CPUUSAGE           "CPU Usage: %3d%%"
+    IDS_STATUS_PROCESSES          "Processes: %d"
+    IDS_Not_Responding            "Not Responding"
+    IDS_Running                   "Running"
+END
+
+
+#endif    // Danish resources
 /////////////////////////////////////////////////////////////////////////////
 
 
index f93fe53..80a03b6 100644 (file)
@@ -4029,7 +4029,7 @@ public:
                wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
                wcex.lpszClassName = TEXT("MissTosca_Control");
 
-               return RegisterClassEx(&wcex);;
+               return RegisterClassEx(&wcex);
        }
 
        static void Shutdown()
index ec132ca..83c9c12 100644 (file)
@@ -32,11 +32,36 @@ u_int32_t arc4random()
 
 
 int inet_aton(const char *cp, struct in_addr *inp)
+/* inet_addr code from ROS, slightly modified. */
 {
-       inp->S_un.S_addr = inet_addr(cp);
-       if (INADDR_NONE == inp->S_un.S_addr)
+       ULONG Octets[4] = {0,0,0,0};
+       ULONG i = 0;
+
+       if(!cp)
                return 0;
 
+       while(*cp)
+       {
+               CHAR c = *cp;
+               cp++;
+
+               if(c == '.')
+               {
+                       i++;
+                       continue;
+               }
+
+               if(c < '0' || c > '9')
+                       return 0;
+
+               Octets[i] *= 10;
+               Octets[i] += (c - '0');
+
+               if(Octets[i] > 255)
+                       return 0;
+               }
+
+       inp->S_un.S_addr = (Octets[3] << 24) + (Octets[2] << 16) + (Octets[1] << 8) + Octets[0];
        return 1;
 }
 
index 2c11e75..0953ca8 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<module name="dhcp" type="win32cui" installbase="system32" installname="dhcp.exe" allowwarnings="true">
+<module name="dhcp" type="win32cui" installbase="system32" installname="dhcp.exe">
        <include base="dhcp">.</include>
        <include base="dhcp">include</include>
        <library>ntdll</library>
index 2dd7623..fdf3075 100644 (file)
@@ -121,7 +121,7 @@ int read_client_conf(void) {
        if (lpCompName !=NULL) {
            memcpy(lpCompName, ComputerName, ComputerNameSize + 1);
            /* Send our hostname, some dhcpds use this to update DNS */
-           config->send_options[DHO_HOST_NAME].data = (u_int8_t*)strlwr(lpCompName);
+           config->send_options[DHO_HOST_NAME].data = (u_int8_t*)_strlwr(lpCompName);
            config->send_options[DHO_HOST_NAME].len = ComputerNameSize;
            debug("Hostname: %s, length: %d",
                  config->send_options[DHO_HOST_NAME].data,
index 8582e94..9a2ddab 100644 (file)
@@ -271,24 +271,24 @@ VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime, DWORD * pEventTime)
     *pEventTime = (Time.ll - u1970.ll) / 10000000;
 }
 
-VOID PRINT_HEADER(PFILE_HEADER header)
+VOID PRINT_HEADER(PEVENTLOGHEADER header)
 {
-    DPRINT("SizeOfHeader = %d\n", header->SizeOfHeader);
+    DPRINT("HeaderSize = %d\n", header->HeaderSize);
     DPRINT("Signature = 0x%x\n", header->Signature);
     DPRINT("MajorVersion = %d\n", header->MajorVersion);
     DPRINT("MinorVersion = %d\n", header->MinorVersion);
-    DPRINT("FirstRecordOffset = %d\n", header->FirstRecordOffset);
-    DPRINT("EofOffset = 0x%x\n", header->EofOffset);
-    DPRINT("NextRecord = %d\n", header->NextRecord);
-    DPRINT("OldestRecord = %d\n", header->OldestRecord);
-    DPRINT("unknown1 = 0x%x\n", header->unknown1);
-    DPRINT("unknown2 = 0x%x\n", header->unknown2);
-    DPRINT("SizeOfHeader2 = %d\n", header->SizeOfHeader2);
+    DPRINT("StartOffset = %d\n", header->StartOffset);
+    DPRINT("EndOffset = 0x%x\n", header->EndOffset);
+    DPRINT("CurrentRecordNumber = %d\n", header->CurrentRecordNumber);
+    DPRINT("OldestRecordNumber = %d\n", header->OldestRecordNumber);
+    DPRINT("MaxSize = 0x%x\n", header->MaxSize);
+    DPRINT("Retention = 0x%x\n", header->Retention);
+    DPRINT("EndHeaderSize = %d\n", header->EndHeaderSize);
     DPRINT("Flags: ");
-    if (header->Flags & LOGFILE_FLAG1)  DPRINT("LOGFILE_FLAG1 ");
-    if (header->Flags & LOGFILE_FLAG2)  DPRINT("| LOGFILE_FLAG2 ");
-    if (header->Flags & LOGFILE_FLAG3)  DPRINT("| LOGFILE_FLAG3 ");
-    if (header->Flags & LOGFILE_FLAG4)  DPRINT("| LOGFILE_FLAG4");
+    if (header->Flags & ELF_LOGFILE_HEADER_DIRTY)  DPRINT("ELF_LOGFILE_HEADER_DIRTY");
+    if (header->Flags & ELF_LOGFILE_HEADER_WRAP)  DPRINT("| ELF_LOGFILE_HEADER_WRAP ");
+    if (header->Flags & ELF_LOGGFILE_LOGFULL_WRITTEN)  DPRINT("| ELF_LOGGFILE_LOGFULL_WRITTEN ");
+    if (header->Flags & ELF_LOGFILE_ARCHIVE_SET)  DPRINT("| ELF_LOGFILE_ARCHIVE_SET ");
     DPRINT("\n");
 }
 
index 54c2b30..4cbfe1a 100644 (file)
@@ -36,43 +36,41 @@ typedef struct _IO_ERROR_LPC
 #define LOGFILE_SIGNATURE 0x654c664c
 
 /*
- *  FIXME
  *  Flags used in logfile header
  */
-#define LOGFILE_FLAG1 1
-#define LOGFILE_FLAG2 2
-#define LOGFILE_FLAG3 4
-#define LOGFILE_FLAG4 8
-
-typedef struct
-{
-    DWORD SizeOfHeader;
-    DWORD Signature;
-    DWORD MajorVersion;
-    DWORD MinorVersion;
-    DWORD FirstRecordOffset;
-    DWORD EofOffset;
-    DWORD NextRecord;
-    DWORD OldestRecord;
-    DWORD unknown1;
-    DWORD Flags;
-    DWORD unknown2;
-    DWORD SizeOfHeader2;
-} FILE_HEADER, *PFILE_HEADER;
-
-typedef struct
-{
-    DWORD Size1;
-    DWORD Ones;                 // Must be 0x11111111
-    DWORD Twos;                 // Must be 0x22222222
-    DWORD Threes;               // Must be 0x33333333
-    DWORD Fours;                // Must be 0x44444444
-    DWORD StartOffset;
-    DWORD EndOffset;
-    DWORD NextRecordNumber;
-    DWORD OldestRecordNumber;
-    DWORD Size2;
-} EOF_RECORD, *PEOF_RECORD;
+#define ELF_LOGFILE_HEADER_DIRTY 1
+#define ELF_LOGFILE_HEADER_WRAP 2
+#define ELF_LOGGFILE_LOGFULL_WRITTEN 4
+#define ELF_LOGFILE_ARCHIVE_SET 8
+
+/* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
+typedef struct _EVENTLOGHEADER {
+    ULONG HeaderSize;
+    ULONG Signature;
+    ULONG MajorVersion;
+    ULONG MinorVersion;
+    ULONG StartOffset;
+    ULONG EndOffset;
+    ULONG CurrentRecordNumber;
+    ULONG OldestRecordNumber;
+    ULONG MaxSize;
+    ULONG Flags;
+    ULONG Retention;
+    ULONG EndHeaderSize;
+} EVENTLOGHEADER, *PEVENTLOGHEADER;
+
+typedef struct _EVENTLOGEOF {
+    ULONG RecordSizeBeginning;
+    ULONG Ones;
+    ULONG Twos;
+    ULONG Threes;
+    ULONG Fours;
+    ULONG BeginRecord;
+    ULONG EndRecord;
+    ULONG CurrentRecordNumber;
+    ULONG OldestRecordNumber;
+    ULONG RecordSizeEnd;
+} EVENTLOGEOF, *PEVENTLOGEOF;
 
 typedef struct
 {
@@ -83,7 +81,7 @@ typedef struct
 typedef struct
 {
     HANDLE hFile;
-    FILE_HEADER Header;
+    EVENTLOGHEADER Header;
     WCHAR *LogName;
     WCHAR *FileName;
     CRITICAL_SECTION cs;
@@ -165,7 +163,7 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
 /* eventlog.c */
 extern HANDLE MyHeap;
 
-VOID PRINT_HEADER(PFILE_HEADER header);
+VOID PRINT_HEADER(PEVENTLOGHEADER header);
 
 VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
 
index 82dce7c..3588959 100644 (file)
@@ -20,24 +20,24 @@ static CRITICAL_SECTION LogFileListCs;
 BOOL LogfInitializeNew(PLOGFILE LogFile)
 {
     DWORD dwWritten;
-    EOF_RECORD EofRec;
+    EVENTLOGEOF EofRec;
 
-    ZeroMemory(&LogFile->Header, sizeof(FILE_HEADER));
+    ZeroMemory(&LogFile->Header, sizeof(EVENTLOGHEADER));
     SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
     SetEndOfFile(LogFile->hFile);
 
-    LogFile->Header.SizeOfHeader = sizeof(FILE_HEADER);
-    LogFile->Header.SizeOfHeader2 = sizeof(FILE_HEADER);
-    LogFile->Header.FirstRecordOffset = sizeof(FILE_HEADER);
-    LogFile->Header.EofOffset = sizeof(FILE_HEADER);
+    LogFile->Header.HeaderSize = sizeof(EVENTLOGHEADER);
+    LogFile->Header.EndHeaderSize = sizeof(EVENTLOGHEADER);
+    LogFile->Header.StartOffset = sizeof(EVENTLOGHEADER);
+    LogFile->Header.EndOffset = sizeof(EVENTLOGHEADER);
     LogFile->Header.MajorVersion = MAJORVER;
     LogFile->Header.MinorVersion = MINORVER;
-    LogFile->Header.NextRecord = 1;
+    LogFile->Header.CurrentRecordNumber = 1;
 
     LogFile->Header.Signature = LOGFILE_SIGNATURE;
     if (!WriteFile(LogFile->hFile,
                    &LogFile->Header,
-                   sizeof(FILE_HEADER),
+                   sizeof(EVENTLOGHEADER),
                    &dwWritten,
                    NULL))
     {
@@ -49,16 +49,16 @@ BOOL LogfInitializeNew(PLOGFILE LogFile)
     EofRec.Twos = 0x22222222;
     EofRec.Threes = 0x33333333;
     EofRec.Fours = 0x44444444;
-    EofRec.Size1 = sizeof(EOF_RECORD);
-    EofRec.Size2 = sizeof(EOF_RECORD);
-    EofRec.NextRecordNumber = LogFile->Header.NextRecord;
-    EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
-    EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
-    EofRec.EndOffset = LogFile->Header.EofOffset;
+    EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF);
+    EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF);
+    EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
+    EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
+    EofRec.BeginRecord = LogFile->Header.StartOffset;
+    EofRec.EndRecord = LogFile->Header.EndOffset;
 
     if (!WriteFile(LogFile->hFile,
                    &EofRec,
-                   sizeof(EOF_RECORD),
+                   sizeof(EVENTLOGEOF),
                    &dwWritten,
                    NULL))
     {
@@ -92,7 +92,7 @@ BOOL LogfInitializeExisting(PLOGFILE LogFile)
 
     if (!ReadFile(LogFile->hFile,
                   &LogFile->Header,
-                  sizeof(FILE_HEADER),
+                  sizeof(EVENTLOGHEADER),
                   &dwRead,
                   NULL))
     {
@@ -100,14 +100,14 @@ BOOL LogfInitializeExisting(PLOGFILE LogFile)
         return FALSE;
     }
 
-    if (dwRead != sizeof(FILE_HEADER))
+    if (dwRead != sizeof(EVENTLOGHEADER))
     {
         DPRINT("EventLog: Invalid file %S.\n", LogFile->FileName);
         return LogfInitializeNew(LogFile);
     }
 
-    if (LogFile->Header.SizeOfHeader != sizeof(FILE_HEADER) ||
-        LogFile->Header.SizeOfHeader2 != sizeof(FILE_HEADER))
+    if (LogFile->Header.HeaderSize != sizeof(EVENTLOGHEADER) ||
+        LogFile->Header.EndHeaderSize != sizeof(EVENTLOGHEADER))
     {
         DPRINT("EventLog: Invalid header size in %S.\n", LogFile->FileName);
         return LogfInitializeNew(LogFile);
@@ -120,10 +120,10 @@ BOOL LogfInitializeExisting(PLOGFILE LogFile)
         return LogfInitializeNew(LogFile);
     }
 
-    if (LogFile->Header.EofOffset > GetFileSize(LogFile->hFile, NULL) + 1)
+    if (LogFile->Header.EndOffset > GetFileSize(LogFile->hFile, NULL) + 1)
     {
         DPRINT("EventLog: Invalid eof offset %x in %S.\n",
-               LogFile->Header.EofOffset, LogFile->FileName);
+               LogFile->Header.EndOffset, LogFile->FileName);
         return LogfInitializeNew(LogFile);
     }
 
@@ -204,7 +204,7 @@ BOOL LogfInitializeExisting(PLOGFILE LogFile)
 
         if (*pdwRecSize2 != dwRecSize)
         {
-            DPRINT1("Invalid size2 of record %d (%x) in %S\n",
+            DPRINT1("Invalid RecordSizeEnd of record %d (%x) in %S\n",
                     dwRecordsNumber, *pdwRecSize2, LogFile->LogName);
             HeapFree(MyHeap, 0, RecBuf);
             break;
@@ -224,8 +224,8 @@ BOOL LogfInitializeExisting(PLOGFILE LogFile)
         HeapFree(MyHeap, 0, RecBuf);
     }  // for(;;)
 
-    LogFile->Header.NextRecord = dwRecordsNumber + 1;
-    LogFile->Header.OldestRecord = dwRecordsNumber ? 1 : 0;  // FIXME
+    LogFile->Header.CurrentRecordNumber = dwRecordsNumber + 1;
+    LogFile->Header.OldestRecordNumber = dwRecordsNumber ? 1 : 0;  // FIXME
 
     if (!SetFilePointer(LogFile->hFile, 0, NULL, FILE_CURRENT) ==
         INVALID_SET_FILE_POINTER)
@@ -236,7 +236,7 @@ BOOL LogfInitializeExisting(PLOGFILE LogFile)
 
     if (!WriteFile(LogFile->hFile,
                    &LogFile->Header,
-                   sizeof(FILE_HEADER),
+                   sizeof(EVENTLOGHEADER),
                    &dwRead,
                    NULL))
     {
@@ -648,7 +648,7 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
 {
     DWORD dwWritten;
     SYSTEMTIME st;
-    EOF_RECORD EofRec;
+    EVENTLOGEOF EofRec;
 
     if (!Buffer)
         return FALSE;
@@ -659,7 +659,7 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
     EnterCriticalSection(&LogFile->cs);
 
     if (SetFilePointer(LogFile->hFile,
-                       LogFile->Header.EofOffset,
+                       LogFile->Header.EndOffset,
                        NULL,
                        FILE_BEGIN) == INVALID_SET_FILE_POINTER)
     {
@@ -676,33 +676,33 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
     }
 
     if (!LogfAddOffsetInformation(LogFile,
-                                  LogFile->Header.NextRecord,
-                                  LogFile->Header.EofOffset))
+                                  LogFile->Header.CurrentRecordNumber,
+                                  LogFile->Header.EndOffset))
     {
         LeaveCriticalSection(&LogFile->cs);
         return FALSE;
     }
 
-    LogFile->Header.NextRecord++;
-    LogFile->Header.EofOffset += dwWritten;
+    LogFile->Header.CurrentRecordNumber++;
+    LogFile->Header.EndOffset += dwWritten;
 
-    if (LogFile->Header.OldestRecord == 0)
-        LogFile->Header.OldestRecord = 1;
+    if (LogFile->Header.OldestRecordNumber == 0)
+        LogFile->Header.OldestRecordNumber = 1;
 
     EofRec.Ones = 0x11111111;
     EofRec.Twos = 0x22222222;
     EofRec.Threes = 0x33333333;
     EofRec.Fours = 0x44444444;
-    EofRec.Size1 = sizeof(EOF_RECORD);
-    EofRec.Size2 = sizeof(EOF_RECORD);
-    EofRec.NextRecordNumber = LogFile->Header.NextRecord;
-    EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
-    EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
-    EofRec.EndOffset = LogFile->Header.EofOffset;
+    EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF);
+    EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF);
+    EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
+    EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
+    EofRec.BeginRecord = LogFile->Header.StartOffset;
+    EofRec.EndRecord = LogFile->Header.EndOffset;
 
     if (!WriteFile(LogFile->hFile,
                    &EofRec,
-                   sizeof(EOF_RECORD),
+                   sizeof(EVENTLOGEOF),
                    &dwWritten,
                    NULL))
     {
@@ -721,7 +721,7 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
 
     if (!WriteFile(LogFile->hFile,
                    &LogFile->Header,
-                   sizeof(FILE_HEADER),
+                   sizeof(EVENTLOGHEADER),
                    &dwWritten,
                    NULL))
     {
@@ -757,7 +757,7 @@ ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
 
 DWORD LogfGetOldestRecord(PLOGFILE LogFile)
 {
-    return LogFile->Header.OldestRecord;
+    return LogFile->Header.OldestRecordNumber;
 }
 
 BOOL LogfAddOffsetInformation(PLOGFILE LogFile, ULONG ulNumber, ULONG ulOffset)
index 0db58ac..d82cf4c 100644 (file)
@@ -143,7 +143,7 @@ NTSTATUS ProcessPortMessage(VOID)
         {
             DPRINT("Received datagram\n");
             Message = (PIO_ERROR_LOG_MESSAGE) & Request.Message;
-            ulRecNum = SystemLog ? SystemLog->Header.NextRecord : 0;
+            ulRecNum = SystemLog ? SystemLog->Header.CurrentRecordNumber : 0;
 
             pRec = (PEVENTLOGRECORD) LogfAllocAndBuildNewRecord(&dwRecSize,
                     ulRecNum, Message->Type, Message->EntryData.EventCategory,
index df15c47..a46ad02 100644 (file)
@@ -76,8 +76,8 @@ BEGIN
 
     CONTROL "Ñëàãàíå íà íà÷àëåí çàðåæäà÷ (MBR) íà òâúðäèÿ äèñê", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
     CONTROL "Áåç ñëàãàíå íà íà÷àëåí çàðåæäà÷", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11
-    PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
-    PUSHBUTTON "&Cancel", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
+    PUSHBUTTON "&Äîáðå", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
+    PUSHBUTTON "&Îòêàç", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
 END
 
 IDD_PROCESSPAGE DIALOGEX 0, 0, 317, 193
@@ -103,7 +103,7 @@ BEGIN
  
     LTEXT "Êîãàòî íàòèñíåòå \84Êðàé\94, êîìïþòúðúò âè ùå ñå ïðåçàïóñíå.", IDC_STATIC, 20, 80, 277, 10
     CONTROL "", IDC_RESTART_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 20, 120, 277, 8
-    LTEXT "Àêî â óñòðîéñòâîòî èìà ÊÄ, ãî èçâàäåòå. Ñëåä òîâà íàòèñíåòå \84Ïðèêëþ÷âàíå\93, çà ä àïðåçàïóñíåòå êîìïþòúðà.\93, IDC_STATIC, 10, 180, 297, 20
+    LTEXT "Àêî â óñòðîéñòâîòî èìà ÊÄ, ãî èçâàäåòå. Ñëåä òîâà íàòèñíåòå \84Ïðèêëþ÷âàíå\93, çà äà ïðåçàïóñíåòå êîìïþòúðà.\93, IDC_STATIC, 10, 180, 297, 20
 END
 
 
index a702153..0cf6be9 100644 (file)
@@ -1,7 +1,7 @@
 /* TRANSLATOR:  M rio Ka\9fm r /Mario Kacmar/ aka Kario (kario@szm.sk)
  * DATE OF TR:  22-01-2008
  * Encoding  :  Latin II (852)
- * LastChange:  01-12-2008
+ * LastChange:  14-12-2008
  */
 
 #ifndef LANG_SK_SK_H__
@@ -1215,7 +1215,7 @@ static MUI_ENTRY skSKDeletePartitionEntries[] =
     {
         6,
         8,
-        "Vybrali Ste si odstr nenie oblasti",
+        "Vybrali ste si odstr nenie oblasti",
         TEXT_STYLE_NORMAL
     },
     {
@@ -1323,7 +1323,8 @@ MUI_ERROR skSKErrorEntries[] =
     },
     {
         //ERROR_WRITE_BOOT,
-        "Setup failed to install FAT bootcode on the system partition.",
+        "Inçtal toru sa nepodarilo nainçtalova\9c zav dzac¡ k¢d s£borov\82ho\n"
+        "syst\82mu FAT na syst\82mov£ part¡ciu.",
         "ENTER = Reçtart po\9f¡ta\9fa"
     },
     {
@@ -1374,7 +1375,8 @@ MUI_ERROR skSKErrorEntries[] =
     },
     {
         //ERROR_INSTALL_BOOTCODE,
-        "Setup failed to install the FAT bootcode on the system partition.",
+        "Inçtal toru sa nepodarilo nainçtalova\9c zav dzac¡ k¢d s£borov\82ho\n"
+        "syst\82mu FAT na syst\82mov£ part¡ciu.",
         "ENTER = Reçtart po\9f¡ta\9fa"
     },
     {
@@ -1598,7 +1600,7 @@ MUI_STRING skSKStrings[] =
     {STRING_PARTITIONSIZE,
      "Ve\96kos\9c novej oblasti:"},
     {STRING_CHOOSENEWPARTITION,
-     "Zvolili Ste vytvorenie novej oblasti na"},
+     "Zvolili ste vytvorenie novej oblasti na"},
     {STRING_HDDSIZE,
     "Zadajte, pros¡m, ve\96kos\9c novej oblasti v megabajtoch."},
     {STRING_CREATEPARTITION,
@@ -1606,7 +1608,7 @@ MUI_STRING skSKStrings[] =
     {STRING_PARTFORMAT,
     "T to oblas\9c sa bude form tova\9c ako Ôalçia."},
     {STRING_NONFORMATTEDPART,
-    "Zvolili Ste inçtal ciu syst\82mu ReactOS na nov£ alebo nenaform tovan£ oblas\9c."},
+    "Zvolili ste inçtal ciu syst\82mu ReactOS na nov£ alebo nenaform tovan£ oblas\9c."},
     {STRING_INSTALLONPART,
     "Inçtal tor nainçtaluje syst\82m ReactOS na oblas\9c"},
     {STRING_CHECKINGPART,
index 9fc7cd2..516844f 100644 (file)
@@ -120,7 +120,7 @@ COMMAND cmds[] =
        {_T("history"), 0, CommandHistory},
 #endif
 
-//     {_T("if"), 0, cmd_if},
+       {_T("if"), 0, cmd_if},
 
 #ifdef INCLUDE_CMD_LABEL
        {_T("label"), 0, cmd_label},
index deead6c..2c43fe5 100644 (file)
@@ -989,7 +989,7 @@ DirPrintNewList(LPWIN32_FIND_DATA ptrFiles[],       /* [IN]Files' Info */
   INT iSizeFormat;
   ULARGE_INTEGER u64FileSize;
 
-  for (i = 0;i < dwCount;i++)
+  for (i = 0; i < dwCount && !bCtrlBreak; i++)
   {
     /* Calculate size */
     if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
@@ -1097,7 +1097,7 @@ DirPrintWideList(LPWIN32_FIND_DATA ptrFiles[],    /* [IN] Files' Info */
   /* Calculate the lines that will be printed */
   iLines = (USHORT)((dwCount + iColumns - 1) / iColumns);
 
-  for (i = 0; i < iLines; i++)
+  for (i = 0; i < iLines && !bCtrlBreak; i++)
   {
     for (j = 0; j < iColumns; j++)
     {
@@ -1154,7 +1154,7 @@ TCHAR szSize[30];                         /* The size of file */
 int iSizeFormat;                               /* The format of size field */
 ULARGE_INTEGER u64FileSize;            /* The file size */
 
-       for(i = 0;i < dwCount;i++)
+       for (i = 0; i < dwCount && !bCtrlBreak; i++)
        {
                /* Broke 8.3 format */
                if (*ptrFiles[i]->cAlternateFileName )
@@ -1228,7 +1228,7 @@ DirPrintBareList(LPWIN32_FIND_DATA ptrFiles[],    /* [IN] Files' Info */
        TCHAR szFullName[MAX_PATH];
        DWORD i;
 
-       for (i = 0; i < dwCount; i++)
+       for (i = 0; i < dwCount && !bCtrlBreak; i++)
        {
                if ((_tcscmp(ptrFiles[i]->cFileName, _T(".")) == 0) ||
                    (_tcscmp(ptrFiles[i]->cFileName, _T("..")) == 0))
@@ -1681,6 +1681,15 @@ ULARGE_INTEGER u64Temp;                                  /* A temporary counter */
 
        /* Free array */
        cmd_free(ptrFileArray);
+       /* Free linked list */
+       while (ptrStartNode)
+       {
+               ptrNextNode = ptrStartNode->ptrNext;
+               cmd_free(ptrStartNode);
+               ptrStartNode = ptrNextNode;
+               dwCount --;
+       }
+
        if (CheckCtrlBreak(BREAK_INPUT))
                return 1;
 
@@ -1741,15 +1750,6 @@ ULARGE_INTEGER u64Temp;                                  /* A temporary counter */
                FindClose(hRecSearch);
        }
 
-       /* Free linked list */
-       while (ptrStartNode)
-       {
-               ptrNextNode = ptrStartNode->ptrNext;
-               cmd_free(ptrStartNode);
-               ptrStartNode = ptrNextNode;
-               dwCount --;
-       }
-
        return 0;
 }
 
index c462ce0..ae848e8 100644 (file)
@@ -49,13 +49,8 @@ static INT GenericCmp(INT (*StringCmp)(LPCTSTR, LPCTSTR),
        return StringCmp(Left, Right);
 }
 
-BOOL ExecuteIf(PARSED_COMMAND *Cmd)
+INT cmd_if (LPTSTR param)
 {
-       INT result = FALSE; /* when set cause 'then' clause to be executed */
-       LPTSTR param;
-
-#if 0
-       /* FIXME: need to handle IF /?; will require special parsing */
        TRACE ("cmd_if: (\'%s\')\n", debugstr_aw(param));
 
        if (!_tcsncmp (param, _T("/?"), 2))
@@ -63,7 +58,15 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
                ConOutResPaging(TRUE,STRING_IF_HELP1);
                return 0;
        }
-#endif
+
+       error_syntax(param);
+       return 1;
+}
+
+BOOL ExecuteIf(PARSED_COMMAND *Cmd)
+{
+       INT result = FALSE; /* when set cause 'then' clause to be executed */
+       LPTSTR param;
 
        if (Cmd->If.Operator == IF_CMDEXTVERSION)
        {
index 7c35a57..6bbee17 100644 (file)
@@ -332,7 +332,7 @@ static PARSED_COMMAND *ParseIf(void)
        memset(Cmd, 0, sizeof(PARSED_COMMAND));
        Cmd->Type = C_IF;
 
-       int Type = ParseToken(0, STANDARD_SEPS);
+       int Type = CurrentTokenType;
        if (_tcsicmp(CurrentToken, _T("/I")) == 0)
        {
                Cmd->If.Flags |= IFFLAG_IGNORECASE;
@@ -488,13 +488,19 @@ static PARSED_COMMAND *ParseCommandPart(void)
        /* Check for special forms */
        if (_tcsicmp(ParsedLine, _T("if")) == 0)
        {
-               if (RedirList)
+               ParseToken(0, STANDARD_SEPS);
+               /* Do special parsing only if it's not followed by /? */
+               if (_tcscmp(CurrentToken, _T("/?")) != 0)
                {
-                       ParseError();
-                       FreeRedirection(RedirList);
-                       return NULL;
+                       if (RedirList)
+                       {
+                               ParseError();
+                               FreeRedirection(RedirList);
+                               return NULL;
+                       }
+                       return ParseIf();
                }
-               return ParseIf();
+               Pos = _stpcpy(Pos, _T(" /?"));
        }
 
        /* Now get the tail */
index b1a18ad..eae1d6f 100644 (file)
@@ -471,9 +471,16 @@ std::string EncodeXMLString(const XS_String& str, bool cdata)
 }
 
  /// decode XML string literals
-XS_String DecodeXMLString(const XS_String& str)
+XS_String DecodeXMLString(const std::string& str)
 {
-       LPCXSSTR s = str.c_str();
+#ifdef XS_STRING_UTF8
+       const XS_String& str_utf8 = str;
+#else
+       XS_String str_utf8;
+       assign_utf8(str_utf8, str.c_str(), str.length());
+#endif
+
+       LPCXSSTR s = str_utf8.c_str();
        LPXSSTR buffer = (LPXSSTR)alloca(sizeof(XS_CHAR)*XS_len(s));
        LPXSSTR o = buffer;
 
@@ -514,7 +521,7 @@ XS_String DecodeXMLString(const XS_String& str)
 
 
  /// write node with children tree to output stream using original white space
-void XMLNode::write_worker(std::ostream& out) const
+void XMLNode::original_write_worker(std::ostream& out) const
 {
        out << _leading << '<' << EncodeXMLString(*this);
 
@@ -522,10 +529,15 @@ void XMLNode::write_worker(std::ostream& out) const
                out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
 
        if (!_children.empty() || !_content.empty()) {
-               out << '>' << _content;
+               out << '>';
+
+               if (_cdata_content)
+                       out << EncodeXMLString(DecodeXMLString(_content), true);
+               else
+                       out << _content;
 
                for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
-                       (*it)->write_worker(out);
+                       (*it)->original_write_worker(out);
 
                out << _end_leading << "</" << EncodeXMLString(*this) << '>';
        } else
@@ -619,7 +631,9 @@ void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int
        else {
                out << '>';
 
-               if (!*content)
+               if (_cdata_content)
+                       out << EncodeXMLString(DecodeXMLString(_content), true);
+               else if (!*content)
                        out << format._endl;
                else
                        out << content;
@@ -886,11 +900,15 @@ void XMLReaderBase::EndElementHandler()
        if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
                s += 9;
                p = (e-=3);
+
+               _pos->_cdata_content = true;
        } else {
                 // search for content end leaving only white space for _end_leading
                for(p=e; p>s; --p)
                        if (!isspace((unsigned char)p[-1]))
                                break;
+
+               _pos->_cdata_content = false;
        }
 
        if (p != s)
index b16ef90..d5d83f2 100644 (file)
@@ -484,7 +484,7 @@ inline std::string get_utf8(const XS_String& s)
 #endif // XS_STRING_UTF8
 
 extern std::string EncodeXMLString(const XS_String& str, bool cdata=false);
-extern XS_String DecodeXMLString(const XS_String& str);
+extern XS_String DecodeXMLString(const std::string& str);
 
 
 #ifdef __GNUC__
@@ -961,13 +961,15 @@ struct XMLNode : public XS_String
        friend struct XPathElement;
 
        XMLNode(const XS_String& name)
-        :      XS_String(name)
+        :      XS_String(name),
+               _cdata_content(false)
        {
        }
 
        XMLNode(const XS_String& name, const std::string& leading)
         :      XS_String(name),
-               _leading(leading)
+               _leading(leading),
+               _cdata_content(false)
        {
        }
 
@@ -977,10 +979,11 @@ struct XMLNode : public XS_String
                _leading(other._leading),
                _content(other._content),
                _end_leading(other._end_leading),
-               _trailing(other._trailing)
+               _trailing(other._trailing),
 #ifdef XMLNODE_LOCATION
-               , _location(other._location)
+               _location(other._location),
 #endif
+               _cdata_content(false)
        {
                for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
                        _children.push_back(new XMLNode(**it));
@@ -994,10 +997,11 @@ struct XMLNode : public XS_String
                _leading(other._leading),
                _content(other._content),
                _end_leading(other._end_leading),
-               _trailing(other._trailing)
+               _trailing(other._trailing),
 #ifdef XMLNODE_LOCATION
-               , _location(other._location)
+               _location(other._location),
 #endif
+               _cdata_content(false)
        {
 //             assert(copy_no_children==COPY_NOCHILDREN);
        }
@@ -1153,23 +1157,41 @@ struct XMLNode : public XS_String
                return _attributes;
        }
 
+        /// read element node content
        XS_String get_content() const
        {
-#ifdef XS_STRING_UTF8
-               const XS_String& ret = _content;
-#else
-               XS_String ret;
-               assign_utf8(ret, _content.c_str(), _content.length());
-#endif
+               return DecodeXMLString(_content);
+       }
 
-               return DecodeXMLString(ret.c_str());
+        /// read content of a subnode specified by an XPath expression
+       XS_String get_sub_content(const XPath& xpath) const
+       {
+               const XMLNode* node = find_relative(xpath);
+
+               if (node)
+                       return node->get_content();
+               else
+                       return XS_EMPTY_STR;
        }
 
+        /// set element node content
        void set_content(const XS_String& s, bool cdata=false)
        {
                _content.assign(EncodeXMLString(s.c_str(), cdata));
        }
 
+        /// set content of a subnode specified by an XPath expression
+       bool set_sub_content(const XPath& xpath, const XS_String& s, bool cdata=false)
+       {
+               XMLNode* node = find_relative(xpath);
+
+               if (node) {
+                       node->set_content(s, cdata);
+                       return true;
+               } else
+                       return false;
+       }
+
 #ifdef XMLNODE_LOCATION
        const XMLLocation& get_location() const {return _location;}
 #endif
@@ -1187,10 +1209,10 @@ struct XMLNode : public XS_String
                        break;
 
                  case FORMAT_ORIGINAL:
-                       write_worker(out);
+                       original_write_worker(out);
                        break;
 
-               default:         // FORMAT_SMART
+                 default:      // FORMAT_SMART
                        smart_write_worker(out, format, indent);
                }
 
@@ -1222,6 +1244,8 @@ protected:
        XMLLocation     _location;
 #endif
 
+       bool    _cdata_content;
+
        XMLNode* get_first_child() const
        {
                if (!_children.empty())
@@ -1242,7 +1266,7 @@ protected:
         /// create a new node tree using the given XPath filter expression
        XMLNode* filter(XPath::const_iterator from, const XPath::const_iterator& to) const;
 
-       void    write_worker(std::ostream& out) const;
+       void    original_write_worker(std::ostream& out) const;
        void    plain_write_worker(std::ostream& out) const;
        void    pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
        void    smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
index 7f56dd2..3b19171 100644 (file)
@@ -206,14 +206,12 @@ struct Buffer
 
 #ifdef XS_STRING_UTF8
                        XS_String name_str(attr_name, attr_len);
-                       XS_String value_str(value, value_len);
 #else
-                       XS_String name_str, value_str;
+                       XS_String name_str;
                        assign_utf8(name_str, attr_name, attr_len);
-                       assign_utf8(value_str, value, value_len);
 #endif
 
-                       attributes[name_str] = DecodeXMLString(value_str);
+                       attributes[name_str] = DecodeXMLString(std::string(value, value_len));
                }
        }
 
diff --git a/reactos/base/system/regsvr32/lang/bg-BG.rc b/reactos/base/system/regsvr32/lang/bg-BG.rc
new file mode 100644 (file)
index 0000000..6f2710e
--- /dev/null
@@ -0,0 +1,28 @@
+#include "resource.h"
+
+LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_UsageMessage, "%s\n\nUsage: regsvr32 [/u] [/s] [/c] [/n] [/i[:cmdline]] dllname\n\
+/u -   Unregister server\n\
+/s -   Silent; display no message boxes\n\
+/c -   Console output\n\
+/i -   Call DllInstall passing it an optional [cmdline]; when used with /u calls dll uninstall\n\
+/n -   Do not call DllRegisterServer; this option must be used with /i"
+
+IDS_NoDllSpecified,  "Íå å óêàçàíî èìå íà DLL."
+
+IDS_InvalidFlag,     "Íåðàçïîçíàò ñòÿã: %s"
+
+IDS_SwitchN_NoI,     "Íåðàçïîçíàò ñòÿã: /n ñòðÿáâà äà ñå èçïîëçâà ñ êëþ÷à /i"
+
+IDS_DllNotLoaded,    "Íåóñïåøíî LoadLibrary('%s').\nGetLastError âðúùà 0x%08x."
+
+IDS_MissingEntry,    "%s áå çàðåäåí, íî âõîäíàòà òî÷êà %s íå å íàìåðåíà.\n\n\
+Âúçìîæíî å %s äà å íåèçíîñèì èëè â ïàìåòòà äà ñå íàìèðà ïîâðåäåíà âåðñèÿ íà %s. Ìîæåòå äà èçïîëçâàòå PView, çà äà ãî îòêðèåòå è ïðåìàõíåòå."
+
+IDS_FailureMessage,  "%s â %s íå óñïÿ.\nÂúðíàòà ãðåøêà: 0x%08x"
+
+IDS_SuccessMessage   "%s â %s óñïÿ."
+END
index 40f5a83..088183d 100644 (file)
@@ -3,6 +3,7 @@
 
 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 
+#include "lang/bg-BG.rc"
 #include "lang/cs-CZ.rc"
 #include "lang/de-DE.rc"
 #include "lang/en-US.rc"
index e45862d..55967b5 100644 (file)
@@ -7,6 +7,7 @@
   <property name="BASEADDRESS_DEVENUM" value="0x35680000" />
   <property name="BASEADDRESS_RSABASE" value="0x35700000" />
   <property name="BASEADDRESS_RSAENH" value="0x35780000" />
+  <property name="BASEADDRESS_DWMAPI" value="0x4A3F0000" />
   <property name="BASEADDRESS_MPRAPI" value="0x4C400000" />
   <property name="BASEADDRESS_PSTOREC" value="0x513D0000" />
   <property name="BASEADDRESS_LPK" value="0x516C0000" />
index 497285a..9795461 100644 (file)
@@ -890,22 +890,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","ImagePath",0x00020000,"system32
 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Start",0x00010001,0x00000001
 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008
 
-; Green driver
-;HKLM,"SYSTEM\CurrentControlSet\Services\green","ErrorControl",0x00010001,0x00000000
-;HKLM,"SYSTEM\CurrentControlSet\Services\green","Group",0x00000000,"Extended base"
-;HKLM,"SYSTEM\CurrentControlSet\Services\green","ImagePath",0x00020000,"system32\drivers\green.sys"
-;HKLM,"SYSTEM\CurrentControlSet\Services\green","Start",0x00010001,0x00000001
-;HKLM,"SYSTEM\CurrentControlSet\Services\green","Type",0x00010001,0x00000001
-;HKLM,"SYSTEM\CurrentControlSet\Services\green\Parameters","AttachedDevice",0x00000000,"\Device\Serial0"
-
-; i8042 port driver
-HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","ErrorControl",0x00010001,0x00000000
-HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Group",0x00000000,"Keyboard Port"
-HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","ImagePath",0x00020000,"system32\drivers\i8042prt.sys"
-HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Start",0x00010001,0x00000001
-HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Type",0x00010001,0x00000001
-HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt\Parameters","BreakOnSysRq",0x00010001,0x00000001
-
 ; Kernel-Mode Tests
 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000
 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base"
index 916f5ea..6ee257d 100644 (file)
@@ -105,6 +105,7 @@ ULONG               MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCoun
 VOID   MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount);        // Removes entries in the memory map that describe memory above 4G
 VOID   MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount);  // Sets the LastFreePageHint to the last usable page of memory
 BOOLEAN        MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount);     // Returns TRUE if the specified pages of memory are available, otherwise FALSE
+VOID   MmSetMemoryType(PVOID MemoryAddress, ULONG MemorySize, TYPE_OF_MEMORY NewType); // Use with EXTREME caution!
 
 ULONG          GetSystemMemorySize(VOID);                                                              // Returns the amount of total memory in the system
 PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries);                      // Returns a pointer to the memory mapping table and a number of entries in it
index 23a9ae1..445c75a 100644 (file)
@@ -182,6 +182,22 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_
        return MemPointer;
 }
 
+VOID MmSetMemoryType(PVOID MemoryAddress, ULONG MemorySize, TYPE_OF_MEMORY NewType)
+{
+       ULONG           PagesNeeded;
+       ULONG           StartPageNumber;
+
+       // Find out how many blocks it will take to
+       // satisfy this allocation
+       PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
+
+       // Get the starting page number
+       StartPageNumber = MmGetPageNumberFromAddress(MemoryAddress);
+
+       // Set new type for these pages
+       MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, NewType);
+}
+
 PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
 {
        ULONG           PagesNeeded;
index aa5e3ad..5737808 100644 (file)
@@ -405,7 +405,7 @@ WinLdrLoadImage(IN PCHAR FileName,
                /* Size of data is less than the virtual size - fill up the remainder with zeroes */
                if (SizeOfRawData < VirtualSize)
                {
-                       DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): SORD %d < VS %d", SizeOfRawData, VirtualSize));
+                       DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize));
                        RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
                }
 
index 8156f96..9720929 100644 (file)
@@ -133,13 +133,15 @@ MempAllocatePageTables()
        TotalSize = (1+1+NumPageTables*2)*MM_PAGE_SIZE;
 
        // PDE+HAL+KernelPTEs == MemoryData
-       Buffer = MmAllocateMemoryWithType(
-               TotalSize - NumPageTables*MM_PAGE_SIZE, LoaderMemoryData);
+       Buffer = MmAllocateMemoryWithType(TotalSize, LoaderMemoryData);
 
        // Physical PTEs = FirmwareTemporary
-       PhysicalPageTablesBuffer = MmAllocateMemoryWithType(
-               NumPageTables*MM_PAGE_SIZE, LoaderFirmwareTemporary);
+       PhysicalPageTablesBuffer = (PUCHAR)Buffer + TotalSize - NumPageTables*MM_PAGE_SIZE;
+       MmSetMemoryType(PhysicalPageTablesBuffer,
+                       NumPageTables*MM_PAGE_SIZE,
+                       LoaderFirmwareTemporary);
 
+       // This check is now redundant
        if (Buffer + (TotalSize - NumPageTables*MM_PAGE_SIZE) !=
                PhysicalPageTablesBuffer)
        {
index 68f7604..1103510 100644 (file)
 
 
 <!--
-       Which CPU ReactOS should be optimized for. Specify one of:
+       Generate instructions for this CPU type. Specify one of:
                armv5te
 
-       See GCC manual for more CPU names and which CPUs GCC can optimize for.
+       See GCC manual for more CPU names.
 -->
 <property name="OARCH" value="armv5te" />
 
 
+<!--
+       Which CPU ReactOS should be optimized for. See GCC manual for CPU names.
+-->
+<property name="TUNE" value="" />
+
+
 <!--
        What level of optimisation to use.
                0 = off (will not work)
index 316bb52..a13c0db 100644 (file)
 
 <!--
        Sub-architecture to build for. Specify one of:
-               xbox
+               ??
 -->
 <property name="SARCH" value="" />
 
 
 <!--
-       Which CPU ReactOS should be optimized for. Specify one of:
-               i486, i586, pentium, pentium2, pentium3, pentium4, athlon-xp, athlon-mp,
-               k6-2
+       Generate instructions for this CPU type. Specify one of:
+               ??
 
-       See GCC manual for more CPU names and which CPUs GCC can optimize for.
+       See GCC manual for more CPU names.
 -->
 <property name="OARCH" value="" />
 
+<!--
+       Which CPU ReactOS should be optimized for. See GCC manual for CPU names.
+-->
+<property name="TUNE" value="" />
+
 
 <!--
        Whether to compile for an uniprocessor or multiprocessor machine.
index ae5fba3..799fecd 100644 (file)
 
 
 <!--
-       Which CPU ReactOS should be optimized for. Specify one of:
-               i486, i586, pentium, pentium2, pentium3, pentium4, athlon-xp, athlon-mp,
-               k6-2
+       Generate instructions for this CPU type. Specify one of:
+               native, i386, i486, pentium, pentium-mmx, pentiumpro, i686,
+               pentium2, pentium3, pentium-m, pentium4, prescott, nocona,
+               core2, k6, k6-2, athlon, athlon-xp, opteron, opteron-sse3,
+               barcelona, winchip-c6, winchip2, c3, c3-2, geode
 
-       See GCC manual for more CPU names and which CPUs GCC can optimize for.
+       See GCC manual for more CPU names.
 -->
 <property name="OARCH" value="pentium" />
 
 
+<!--
+       Which CPU ReactOS should be optimized for. Specify one of the above
+       CPUs or generic. When this option is not used, GCC will optimize for
+       the processor specified by OARCH.
+-->
+<property name="TUNE" value="i686" />
+
+
 <!--
        What level of optimisation to use.
                0 = off (will not work)
index 051c534..b26db14 100644 (file)
@@ -3,6 +3,7 @@
 <module name="mesa32" type="win32dll" entrypoint="0" baseaddress="${BASEADDRESS_MESA32}" installbase="system32" installname="mesa32.dll" allowwarnings="true" crt="msvcrt">
        <importlibrary definition="src/drivers/windows/icd/mesa.def" />
        <linkerflag>-enable-stdcall-fixup</linkerflag>
+       <compilerflag>-w</compilerflag>
        <library>ntdll</library>
        <library>kernel32</library>
        <library>user32</library>
index bab1dd8..2442393 100644 (file)
@@ -333,7 +333,6 @@ ButtonProc(IN HWND hwndDlg,
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
                         SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
                     }
-                    SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, 0);
                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                     break;
 
index 6c74744..cf81629 100644 (file)
@@ -2,6 +2,7 @@
 <!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
 <module name="wined3d" type="win32dll" installbase="system32" installname="wined3d.dll" allowwarnings ="true" crt="msvcrt">
        <importlibrary definition="wined3d.def" />
+       <compilerflag compiler="cc">-Wno-format</compilerflag>
        <include base="wined3d">.</include>
        <include base="ReactOS">include/reactos/wine</include>
        <define name="__WINESRC__" />
index 350d944..6ee4906 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
- * FILE:            lib/ntdll/ldr/startup.c
+ * FILE:            dll/ntdll/ldr/startup.c
  * PURPOSE:         Process startup for PE executables
  * PROGRAMMERS:     Jean Michault
  *                  Rex Jolliff (rex@lvcablemodem.com)
 #include <debug.h>
 #include <win32k/callback.h>
 
-VOID RtlInitializeHeapManager (VOID);
+VOID RtlInitializeHeapManager(VOID);
 VOID LdrpInitLoader(VOID);
 VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
+NTSTATUS LdrpAttachThread(VOID);
+VOID RtlpInitializeVectoredExceptionHandling(VOID);
 
 /* GLOBALS *******************************************************************/
 
-
+PLDR_DATA_TABLE_ENTRY ExeModule;
 static RTL_CRITICAL_SECTION PebLock;
 static RTL_CRITICAL_SECTION LoaderLock;
 static RTL_BITMAP TlsBitMap;
 static RTL_BITMAP TlsExpansionBitMap;
-PLDR_DATA_TABLE_ENTRY ExeModule;
-
-NTSTATUS LdrpAttachThread (VOID);
-
-VOID RtlpInitializeVectoredExceptionHandling(VOID);
-
+static volatile BOOLEAN LdrpInitialized = FALSE;
+static LONG LdrpInitLock = 0;
 
 #define VALUE_BUFFER_SIZE 256
 
-BOOLEAN FASTCALL
-ReadCompatibilitySetting(HANDLE Key, LPWSTR Value, PKEY_VALUE_PARTIAL_INFORMATION ValueInfo, DWORD *Buffer)
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+FASTCALL
+ReadCompatibilitySetting(HANDLE Key,
+                         LPWSTR Value,
+                         PKEY_VALUE_PARTIAL_INFORMATION ValueInfo,
+                         DWORD * Buffer)
 {
-       UNICODE_STRING ValueName;
-       NTSTATUS Status;
-       ULONG Length;
-
-       RtlInitUnicodeString(&ValueName, Value);
-       Status = NtQueryValueKey(Key,
-               &ValueName,
-               KeyValuePartialInformation,
-               ValueInfo,
-               VALUE_BUFFER_SIZE,
-               &Length);
-
-       if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_DWORD))
-       {
-               RtlFreeUnicodeString(&ValueName);
-               return FALSE;
-       }
-       RtlCopyMemory(Buffer, &ValueInfo->Data[0], sizeof(DWORD));
-       RtlFreeUnicodeString(&ValueName);
-       return TRUE;
+    UNICODE_STRING ValueName;
+    NTSTATUS Status;
+    ULONG Length;
+
+    RtlInitUnicodeString(&ValueName, Value);
+    Status = NtQueryValueKey(Key,
+                             &ValueName,
+                             KeyValuePartialInformation,
+                             ValueInfo,
+                             VALUE_BUFFER_SIZE,
+                             &Length);
+
+    if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_DWORD))
+    {
+        RtlFreeUnicodeString(&ValueName);
+        return FALSE;
+    }
+
+    RtlCopyMemory(Buffer, &ValueInfo->Data[0], sizeof(DWORD));
+    RtlFreeUnicodeString(&ValueName);
+    return TRUE;
 }
 
-VOID FASTCALL
+VOID
+FASTCALL
 LoadImageFileExecutionOptions(PPEB Peb)
 {
     NTSTATUS Status = STATUS_SUCCESS;
@@ -72,430 +78,456 @@ LoadImageFileExecutionOptions(PPEB Peb)
 
     if (Peb->ProcessParameters &&
         Peb->ProcessParameters->ImagePathName.Length > 0)
-      {
+    {
         DPRINT("%wZ\n", &Peb->ProcessParameters->ImagePathName);
 
         ImagePathName = Peb->ProcessParameters->ImagePathName;
         ImageName.Buffer = ImagePathName.Buffer + ImagePathName.Length / sizeof(WCHAR);
         ImageName.Length = 0;
+
         while (ImagePathName.Buffer < ImageName.Buffer)
         {
             ImageName.Buffer--;
             if (*ImageName.Buffer == L'\\')
             {
-               ImageName.Buffer++;
-               break;
+                ImageName.Buffer++;
+                break;
             }
         }
-        ImageName.Length = ImagePathName.Length - (ImageName.Buffer - ImagePathName.Buffer) * sizeof(WCHAR);
-        ImageName.MaximumLength = ImageName.Length + ImagePathName.MaximumLength - ImagePathName.Length;
+
+        ImageName.Length = ImagePathName.Length -
+            (ImageName.Buffer - ImagePathName.Buffer) * sizeof(WCHAR);
+        ImageName.MaximumLength = ImageName.Length +
+            ImagePathName.MaximumLength - ImagePathName.Length;
 
         DPRINT("%wZ\n", &ImageName);
 
         /* global flag */
-        Status = LdrQueryImageFileExecutionOptions (&ImageName,
-                                                   L"GlobalFlag",
-                                                   REG_SZ,
-                                                   (PVOID)ValueBuffer,
-                                                   sizeof(ValueBuffer),
-                                                   &ValueSize);
+        Status = LdrQueryImageFileExecutionOptions(&ImageName,
+                                                   L"GlobalFlag",
+                                                   REG_SZ,
+                                                   (PVOID)ValueBuffer,
+                                                   sizeof(ValueBuffer),
+                                                   &ValueSize);
         if (NT_SUCCESS(Status))
-          {
+        {
             ValueString.Buffer = ValueBuffer;
-           ValueString.Length = ValueSize - sizeof(WCHAR);
-           ValueString.MaximumLength = sizeof(ValueBuffer);
-           Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value);
+            ValueString.Length = ValueSize - sizeof(WCHAR);
+            ValueString.MaximumLength = sizeof(ValueBuffer);
+            Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value);
             if (NT_SUCCESS(Status))
-              {
+            {
                 Peb->NtGlobalFlag |= Value;
-               DPRINT("GlobalFlag: Key='%S', Value=0x%lx\n", ValueBuffer, Value);
-              }
-         }
+                DPRINT("GlobalFlag: Key='%S', Value=0x%lx\n", ValueBuffer, Value);
+            }
+        }
         /*
-        * FIXME:
-        *   read more options
+         *  FIXME:
+         *   read more options
          */
-      }
+    }
 }
 
+BOOLEAN
+FASTCALL
+LoadCompatibilitySettings(PPEB Peb)
+{
+    NTSTATUS Status;
+    HANDLE UserKey = NULL;
+    HANDLE KeyHandle;
+    HANDLE SubKeyHandle;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(
+        L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
+    UNICODE_STRING ValueName;
+    UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
+    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+    ULONG Length;
+    DWORD MajorVersion, MinorVersion, BuildNumber, PlatformId,
+          SPMajorVersion, SPMinorVersion = 0;
 
+    if (Peb->ProcessParameters &&
+        (Peb->ProcessParameters->ImagePathName.Length > 0))
+    {
+        Status = RtlOpenCurrentUser(KEY_READ, &UserKey);
+        if (!NT_SUCCESS(Status))
+        {
+            return FALSE;
+        }
 
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   UserKey,
+                                   NULL);
 
-BOOLEAN FASTCALL
-LoadCompatibilitySettings(PPEB Peb)
-{
-       NTSTATUS Status;
-       HANDLE UserKey = NULL;
-       HANDLE KeyHandle;
-       HANDLE SubKeyHandle;
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       UNICODE_STRING KeyName = RTL_CONSTANT_STRING(
-    L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
-       UNICODE_STRING ValueName;
-       UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
-       PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
-       ULONG Length;
-       DWORD MajorVersion, MinorVersion, BuildNumber, PlatformId,
-                 SPMajorVersion, SPMinorVersion= 0;
-
-       if(Peb->ProcessParameters &&
-               (Peb->ProcessParameters->ImagePathName.Length > 0))
-       {
-               Status = RtlOpenCurrentUser(KEY_READ,
-                                   &UserKey);
-               if (!NT_SUCCESS(Status))
-               {
-                       return FALSE;
-               }
-
-               InitializeObjectAttributes(&ObjectAttributes,
-                       &KeyName,
-                       OBJ_CASE_INSENSITIVE,
-                       UserKey,
-                       NULL);
-
-               Status = NtOpenKey(&KeyHandle,
-                                       KEY_QUERY_VALUE,
-                                       &ObjectAttributes);
-
-               if (!NT_SUCCESS(Status))
-               {
-                       if (UserKey) NtClose(UserKey);
-                       return FALSE;
-               }
-
-               /* query version name for application */
-               ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
-               Status = NtQueryValueKey(KeyHandle,
-                       &Peb->ProcessParameters->ImagePathName,
-                       KeyValuePartialInformation,
-                       ValueBuffer,
-                       VALUE_BUFFER_SIZE,
-                       &Length);
-
-               if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_SZ))
-               {
-                       NtClose(KeyHandle);
-                       if (UserKey) NtClose(UserKey);
-                       return FALSE;
-               }
-
-               ValueName.Length = ValueInfo->DataLength;
-               ValueName.MaximumLength = ValueInfo->DataLength;
-               ValueName.Buffer = (PWSTR)ValueInfo->Data;
-
-               /* load version info */
-               InitializeObjectAttributes(&ObjectAttributes,
-                       &ValueName,
-                       OBJ_CASE_INSENSITIVE,
-                       KeyHandle,
-                       NULL);
-
-               Status = NtOpenKey(&SubKeyHandle,
-                                       KEY_QUERY_VALUE,
-                                       &ObjectAttributes);
-
-               if (!NT_SUCCESS(Status))
-               {
-                       NtClose(KeyHandle);
-                       if (UserKey) NtClose(UserKey);
-                       return FALSE;
-               }
-
-               DPRINT("Loading version information for: %wZ\n", &ValueName);
-
-               /* read settings from registry */
-               if(!ReadCompatibilitySetting(SubKeyHandle, L"MajorVersion", ValueInfo, &MajorVersion))
-                       goto finish;
-               if(!ReadCompatibilitySetting(SubKeyHandle, L"MinorVersion", ValueInfo, &MinorVersion))
-                       goto finish;
-               if(!ReadCompatibilitySetting(SubKeyHandle, L"BuildNumber", ValueInfo, &BuildNumber))
-                       goto finish;
-               if(!ReadCompatibilitySetting(SubKeyHandle, L"PlatformId", ValueInfo, &PlatformId))
-                       goto finish;
-
-               /* now assign the settings */
-               Peb->OSMajorVersion = (ULONG)MajorVersion;
-               Peb->OSMinorVersion = (ULONG)MinorVersion;
-               Peb->OSBuildNumber = (USHORT)BuildNumber;
-               Peb->OSPlatformId = (ULONG)PlatformId;
-
-               /* optional service pack version numbers */
-               if(ReadCompatibilitySetting(SubKeyHandle, L"SPMajorVersion", ValueInfo, &SPMajorVersion) &&
-                  ReadCompatibilitySetting(SubKeyHandle, L"SPMinorVersion", ValueInfo, &SPMinorVersion))
-                       Peb->OSCSDVersion = ((SPMajorVersion & 0xFF) << 8) | (SPMinorVersion & 0xFF);
+        Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &ObjectAttributes);
+
+        if (!NT_SUCCESS(Status))
+        {
+            if (UserKey)
+                NtClose(UserKey);
+            return FALSE;
+        }
+
+        /* query version name for application */
+        ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION) ValueBuffer;
+        Status = NtQueryValueKey(KeyHandle,
+                                 &Peb->ProcessParameters->ImagePathName,
+                                 KeyValuePartialInformation,
+                                 ValueBuffer,
+                                 VALUE_BUFFER_SIZE,
+                                 &Length);
+
+        if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_SZ))
+        {
+            NtClose(KeyHandle);
+            if (UserKey)
+                NtClose(UserKey);
+            return FALSE;
+        }
+
+        ValueName.Length = ValueInfo->DataLength;
+        ValueName.MaximumLength = ValueInfo->DataLength;
+        ValueName.Buffer = (PWSTR) ValueInfo->Data;
+
+        /* load version info */
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &ValueName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   KeyHandle,
+                                   NULL);
+
+        Status = NtOpenKey(&SubKeyHandle, KEY_QUERY_VALUE, &ObjectAttributes);
+
+        if (!NT_SUCCESS(Status))
+        {
+            NtClose(KeyHandle);
+            if (UserKey)
+                NtClose(UserKey);
+            return FALSE;
+        }
+
+        DPRINT("Loading version information for: %wZ\n", &ValueName);
+
+        /* read settings from registry */
+        if (!ReadCompatibilitySetting(SubKeyHandle, L"MajorVersion", ValueInfo, &MajorVersion))
+            goto finish;
+        if (!ReadCompatibilitySetting(SubKeyHandle, L"MinorVersion", ValueInfo, &MinorVersion))
+            goto finish;
+        if (!ReadCompatibilitySetting(SubKeyHandle, L"BuildNumber", ValueInfo, &BuildNumber))
+            goto finish;
+        if (!ReadCompatibilitySetting(SubKeyHandle, L"PlatformId", ValueInfo, &PlatformId))
+            goto finish;
+
+        /* now assign the settings */
+        Peb->OSMajorVersion =  (ULONG) MajorVersion;
+        Peb->OSMinorVersion =  (ULONG) MinorVersion;
+        Peb->OSBuildNumber  = (USHORT) BuildNumber;
+        Peb->OSPlatformId   =  (ULONG) PlatformId;
+
+        /* optional service pack version numbers */
+        if (ReadCompatibilitySetting(SubKeyHandle,
+                                     L"SPMajorVersion",
+                                     ValueInfo,
+                                     &SPMajorVersion) &&
+            ReadCompatibilitySetting(SubKeyHandle,
+                                     L"SPMinorVersion",
+                                     ValueInfo,
+                                     &SPMinorVersion))
+        {
+            Peb->OSCSDVersion = ((SPMajorVersion & 0xFF) << 8) |
+                                (SPMinorVersion & 0xFF);
+        }
 
 finish:
-               /* we're finished */
-               NtClose(SubKeyHandle);
-               NtClose(KeyHandle);
-               if (UserKey) NtClose(UserKey);
-               return TRUE;
-       }
-       return FALSE;
+        /* we're finished */
+        NtClose(SubKeyHandle);
+        NtClose(KeyHandle);
+        if (UserKey)
+            NtClose(UserKey);
+        return TRUE;
+    }
+
+    return FALSE;
 }
 
-/* FUNCTIONS *****************************************************************/
-
+static
 VOID
-NTAPI
-LdrpInit(PCONTEXT Context,
-         PVOID SystemArgument1,
-         PVOID SystemArgument2)
+LdrpInit2(PCONTEXT Context,
+          PVOID SystemArgument1,
+          PVOID SystemArgument2)
 {
-   PIMAGE_NT_HEADERS NTHeaders;
-   PEPFUNC EntryPoint;
-   PIMAGE_DOS_HEADER PEDosHeader;
-   PVOID ImageBase;
-   PPEB Peb = NtCurrentPeb();
-   PLDR_DATA_TABLE_ENTRY NtModule;  // ntdll
-   NLSTABLEINFO NlsTable;
-   WCHAR FullNtDllPath[MAX_PATH];
-   SYSTEM_BASIC_INFORMATION SystemInformation;
-   NTSTATUS Status;
-   PVOID BaseAddress = SystemArgument1;
-
-   DPRINT("LdrpInit()\n");
-   DPRINT("Peb %p\n", Peb);
-   ImageBase = Peb->ImageBaseAddress;
-   DPRINT("ImageBase %p\n", ImageBase);
-
-   if (NtCurrentPeb()->Ldr == NULL)
-     {
-       if (ImageBase <= (PVOID)0x1000)
-         {
-           DPRINT("ImageBase is null\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
-         }
-
-       /*  If MZ header exists  */
-       PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
-       DPRINT("PEDosHeader %p\n", PEDosHeader);
-
-       if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
-           PEDosHeader->e_lfanew == 0L ||
-           *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE)
-         {
-           DPRINT1("Image has bad header\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
-         }
-
-       /* normalize process parameters */
-       RtlNormalizeProcessParams (Peb->ProcessParameters);
-
-       /* Initialize NLS data */
-       RtlInitNlsTables (Peb->AnsiCodePageData,
-                         Peb->OemCodePageData,
-                         Peb->UnicodeCaseTableData,
-                         &NlsTable);
-       RtlResetRtlTranslations (&NlsTable);
-
-       NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
-
-       /* Get number of processors */
-       DPRINT("Here\n");
-       Status = ZwQuerySystemInformation(SystemBasicInformation,
-                                        &SystemInformation,
-                                        sizeof(SYSTEM_BASIC_INFORMATION),
-                                        NULL);
-        DPRINT("Here2\n");
-       if (!NT_SUCCESS(Status))
-         {
-          ZwTerminateProcess(NtCurrentProcess(), Status);
-        }
-
-       Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors;
-
-       /* Initialize Critical Section Data */
-       RtlpInitDeferedCriticalSection();
-
-       /* create process heap */
-       RtlInitializeHeapManager();
-       Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
-                                        NULL,
-                                        NTHeaders->OptionalHeader.SizeOfHeapReserve,
-                                        NTHeaders->OptionalHeader.SizeOfHeapCommit,
-                                        NULL,
-                                        NULL);
-       if (Peb->ProcessHeap == 0)
-         {
-           DPRINT1("Failed to create process heap\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
-         }
-
-       /* initialized vectored exception handling */
-       RtlpInitializeVectoredExceptionHandling();
-
-       /* initalize peb lock support */
-       RtlInitializeCriticalSection (&PebLock);
-       Peb->FastPebLock = &PebLock;
-       Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
-       Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
-
-       /* initialize tls bitmaps */
-       RtlInitializeBitMap (&TlsBitMap,
-                            Peb->TlsBitmapBits,
-                            TLS_MINIMUM_AVAILABLE);
-       RtlInitializeBitMap (&TlsExpansionBitMap,
-                            Peb->TlsExpansionBitmapBits,
-                            TLS_EXPANSION_SLOTS);
-
-       Peb->TlsBitmap = &TlsBitMap;
-       Peb->TlsExpansionBitmap = &TlsExpansionBitMap;
-       Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE;
-
-       /* Initialize table of callbacks for the kernel. */
-       Peb->KernelCallbackTable =
-         RtlAllocateHeap(RtlGetProcessHeap(),
-                         0,
-                         sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1));
-       if (Peb->KernelCallbackTable == NULL)
-         {
-           DPRINT1("Failed to create callback table\n");
-           ZwTerminateProcess(NtCurrentProcess(),STATUS_INSUFFICIENT_RESOURCES);
-         }
-
-       /* initalize loader lock */
-       RtlInitializeCriticalSection (&LoaderLock);
-       Peb->LoaderLock = &LoaderLock;
-
-       /* create loader information */
-       Peb->Ldr = (PPEB_LDR_DATA)RtlAllocateHeap (Peb->ProcessHeap,
-                                                  0,
-                                                  sizeof(PEB_LDR_DATA));
-       if (Peb->Ldr == NULL)
-         {
-           DPRINT1("Failed to create loader data\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
-         }
-       Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
-       Peb->Ldr->Initialized = FALSE;
-       Peb->Ldr->SsHandle = NULL;
-       InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
-       InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
-       InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
-
-       /* Load compatibility settings */
-       LoadCompatibilitySettings(Peb);
-
-       /* Load execution options */
-       LoadImageFileExecutionOptions(Peb);
-
-       /* build full ntdll path */
-       wcscpy (FullNtDllPath, SharedUserData->NtSystemRoot);
-       wcscat (FullNtDllPath, L"\\system32\\ntdll.dll");
-
-       /* add entry for ntdll */
-       NtModule = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap (Peb->ProcessHeap,
-                                                0,
-                                                sizeof(LDR_DATA_TABLE_ENTRY));
-       if (NtModule == NULL)
-         {
-           DPRINT1("Failed to create loader module entry (NTDLL)\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
-        }
-       memset(NtModule, 0, sizeof(LDR_DATA_TABLE_ENTRY));
-
-       NtModule->DllBase = BaseAddress;
-       NtModule->EntryPoint = 0; /* no entry point */
-       RtlCreateUnicodeString (&NtModule->FullDllName,
-                               FullNtDllPath);
-       RtlCreateUnicodeString (&NtModule->BaseDllName,
-                               L"ntdll.dll");
-       NtModule->Flags = LDRP_IMAGE_DLL|LDRP_ENTRY_PROCESSED;
-
-       NtModule->LoadCount = -1; /* don't unload */
-       NtModule->TlsIndex = -1;
-       NtModule->SectionPointer = NULL;
-       NtModule->CheckSum = 0;
-
-       NTHeaders = RtlImageNtHeader (NtModule->DllBase);
-       NtModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
-       NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
-
-       InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
-                      &NtModule->InLoadOrderLinks);
-       InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
-                      &NtModule->InInitializationOrderModuleList);
+    PIMAGE_NT_HEADERS NTHeaders;
+    PEPFUNC EntryPoint;
+    PIMAGE_DOS_HEADER PEDosHeader;
+    PVOID ImageBase;
+    PPEB Peb = NtCurrentPeb();
+    PLDR_DATA_TABLE_ENTRY NtModule;     // ntdll
+    NLSTABLEINFO NlsTable;
+    WCHAR FullNtDllPath[MAX_PATH];
+    SYSTEM_BASIC_INFORMATION SystemInformation;
+    NTSTATUS Status;
+    PVOID BaseAddress = SystemArgument1;
+
+    DPRINT("LdrpInit()\n");
+    DPRINT("Peb %p\n", Peb);
+    ImageBase = Peb->ImageBaseAddress;
+    DPRINT("ImageBase %p\n", ImageBase);
+
+    if (ImageBase <= (PVOID) 0x1000)
+    {
+        DPRINT("ImageBase is null\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
+    }
+
+    /*  If MZ header exists  */
+    PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
+    DPRINT("PEDosHeader %p\n", PEDosHeader);
+
+    if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
+        PEDosHeader->e_lfanew == 0L ||
+        *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE)
+    {
+        DPRINT1("Image has bad header\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
+    }
+
+    /* normalize process parameters */
+    RtlNormalizeProcessParams(Peb->ProcessParameters);
+
+    /* Initialize NLS data */
+    RtlInitNlsTables(Peb->AnsiCodePageData,
+                     Peb->OemCodePageData,
+                     Peb->UnicodeCaseTableData,
+                     &NlsTable);
+    RtlResetRtlTranslations(&NlsTable);
+
+    NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
+
+    /* Get number of processors */
+    DPRINT("Here\n");
+    Status = ZwQuerySystemInformation(SystemBasicInformation,
+                                      &SystemInformation,
+                                      sizeof(SYSTEM_BASIC_INFORMATION),
+                                      NULL);
+    DPRINT("Here2\n");
+    if (!NT_SUCCESS(Status))
+    {
+        ZwTerminateProcess(NtCurrentProcess(), Status);
+    }
+
+    Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors;
+
+    /* Initialize Critical Section Data */
+    RtlpInitDeferedCriticalSection();
+
+    /* create process heap */
+    RtlInitializeHeapManager();
+    Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
+                                     NULL,
+                                     NTHeaders->OptionalHeader.SizeOfHeapReserve,
+                                     NTHeaders->OptionalHeader.SizeOfHeapCommit,
+                                     NULL,
+                                     NULL);
+    if (Peb->ProcessHeap == 0)
+    {
+        DPRINT1("Failed to create process heap\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+    /* initialized vectored exception handling */
+    RtlpInitializeVectoredExceptionHandling();
+
+    /* initalize peb lock support */
+    RtlInitializeCriticalSection(&PebLock);
+    Peb->FastPebLock = &PebLock;
+    Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
+    Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
+
+    /* initialize tls bitmaps */
+    RtlInitializeBitMap(&TlsBitMap, Peb->TlsBitmapBits, TLS_MINIMUM_AVAILABLE);
+    RtlInitializeBitMap(&TlsExpansionBitMap, Peb->TlsExpansionBitmapBits, TLS_EXPANSION_SLOTS);
+
+    Peb->TlsBitmap = &TlsBitMap;
+    Peb->TlsExpansionBitmap = &TlsExpansionBitMap;
+    Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE;
+
+    /* Initialize table of callbacks for the kernel. */
+    Peb->KernelCallbackTable = RtlAllocateHeap(RtlGetProcessHeap(),
+                                               0,
+                                               sizeof(PVOID) *
+                                                (USER32_CALLBACK_MAXIMUM + 1));
+    if (Peb->KernelCallbackTable == NULL)
+    {
+        DPRINT1("Failed to create callback table\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+    /* initalize loader lock */
+    RtlInitializeCriticalSection(&LoaderLock);
+    Peb->LoaderLock = &LoaderLock;
+
+    /* create loader information */
+    Peb->Ldr = (PPEB_LDR_DATA) RtlAllocateHeap(Peb->ProcessHeap,
+                                               0,
+                                               sizeof(PEB_LDR_DATA));
+    if (Peb->Ldr == NULL)
+    {
+        DPRINT1("Failed to create loader data\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+    Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
+    Peb->Ldr->Initialized = FALSE;
+    Peb->Ldr->SsHandle = NULL;
+    InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
+    InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
+    InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
+
+    /* Load compatibility settings */
+    LoadCompatibilitySettings(Peb);
+
+    /* Load execution options */
+    LoadImageFileExecutionOptions(Peb);
+
+    /* build full ntdll path */
+    wcscpy(FullNtDllPath, SharedUserData->NtSystemRoot);
+    wcscat(FullNtDllPath, L"\\system32\\ntdll.dll");
+
+    /* add entry for ntdll */
+    NtModule = (PLDR_DATA_TABLE_ENTRY)
+                RtlAllocateHeap(Peb->ProcessHeap,
+                                0,
+                                sizeof(LDR_DATA_TABLE_ENTRY));
+    if (NtModule == NULL)
+    {
+        DPRINT1("Failed to create loader module entry (NTDLL)\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
+    }
+    memset(NtModule, 0, sizeof(LDR_DATA_TABLE_ENTRY));
+
+    NtModule->DllBase = BaseAddress;
+    NtModule->EntryPoint = 0;       /* no entry point */
+    RtlCreateUnicodeString(&NtModule->FullDllName, FullNtDllPath);
+    RtlCreateUnicodeString(&NtModule->BaseDllName, L"ntdll.dll");
+    NtModule->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_PROCESSED;
+
+    NtModule->LoadCount = -1;       /* don't unload */
+    NtModule->TlsIndex = -1;
+    NtModule->SectionPointer = NULL;
+    NtModule->CheckSum = 0;
+
+    NTHeaders = RtlImageNtHeader(NtModule->DllBase);
+    NtModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
+    NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
+
+    InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
+                   &NtModule->InLoadOrderLinks);
+    InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
+                   &NtModule->InInitializationOrderModuleList);
 
 #if defined(DBG) || defined(KDBG)
 
-       LdrpLoadUserModuleSymbols(NtModule);
+    LdrpLoadUserModuleSymbols(NtModule);
 
 #endif /* DBG || KDBG */
-     }
-
-   if (NtCurrentPeb()->Ldr->Initialized == FALSE)
-     {
-       /* add entry for executable (becomes first list entry) */
-       ExeModule = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap (Peb->ProcessHeap,
-                                                 0,
-                                                 sizeof(LDR_DATA_TABLE_ENTRY));
-       if (ExeModule == NULL)
-         {
-           DPRINT1("Failed to create loader module infomation\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
-         }
-       ExeModule->DllBase = Peb->ImageBaseAddress;
-
-       if ((Peb->ProcessParameters == NULL) ||
-           (Peb->ProcessParameters->ImagePathName.Length == 0))
-         {
-           DPRINT1("Failed to access the process parameter block\n");
-           ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
-         }
-
-       RtlCreateUnicodeString(&ExeModule->FullDllName,
-                              Peb->ProcessParameters->ImagePathName.Buffer);
-       RtlCreateUnicodeString(&ExeModule->BaseDllName,
-                              wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1);
-
-       DPRINT("BaseDllName '%wZ'  FullDllName '%wZ'\n",
-              &ExeModule->BaseDllName,
-              &ExeModule->FullDllName);
-
-       ExeModule->Flags = LDRP_ENTRY_PROCESSED;
-       ExeModule->LoadCount = -1; /* don't unload */
-       ExeModule->TlsIndex = -1;
-       ExeModule->SectionPointer = NULL;
-       ExeModule->CheckSum = 0;
-
-       NTHeaders = RtlImageNtHeader (ExeModule->DllBase);
-       ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
-       ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
-
-       InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
-                      &ExeModule->InLoadOrderLinks);
-
-       LdrpInitLoader();
+
+    /* add entry for executable (becomes first list entry) */
+    ExeModule = (PLDR_DATA_TABLE_ENTRY)
+                 RtlAllocateHeap(Peb->ProcessHeap,
+                                 0,
+                                 sizeof(LDR_DATA_TABLE_ENTRY));
+    if (ExeModule == NULL)
+    {
+        DPRINT1("Failed to create loader module infomation\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+    ExeModule->DllBase = Peb->ImageBaseAddress;
+
+    if ((Peb->ProcessParameters == NULL) ||
+        (Peb->ProcessParameters->ImagePathName.Length == 0))
+    {
+        DPRINT1("Failed to access the process parameter block\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
+    }
+
+    RtlCreateUnicodeString(&ExeModule->FullDllName,
+                           Peb->ProcessParameters->ImagePathName.Buffer);
+    RtlCreateUnicodeString(&ExeModule->BaseDllName,
+                           wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1);
+
+    DPRINT("BaseDllName '%wZ'  FullDllName '%wZ'\n", &ExeModule->BaseDllName, &ExeModule->FullDllName);
+
+    ExeModule->Flags = LDRP_ENTRY_PROCESSED;
+    ExeModule->LoadCount = -1;      /* don't unload */
+    ExeModule->TlsIndex = -1;
+    ExeModule->SectionPointer = NULL;
+    ExeModule->CheckSum = 0;
+
+    NTHeaders = RtlImageNtHeader(ExeModule->DllBase);
+    ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
+    ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
+
+    InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
+                   &ExeModule->InLoadOrderLinks);
+
+    LdrpInitLoader();
 
 #if defined(DBG) || defined(KDBG)
 
-       LdrpLoadUserModuleSymbols(ExeModule);
+    LdrpLoadUserModuleSymbols(ExeModule);
 
 #endif /* DBG || KDBG */
 
-       EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
-       ExeModule->EntryPoint = EntryPoint;
+    EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
+    ExeModule->EntryPoint = EntryPoint;
 
-       /* all required dlls are loaded now */
-       Peb->Ldr->Initialized = TRUE;
+    /* all required dlls are loaded now */
+    Peb->Ldr->Initialized = TRUE;
 
-       /* Check before returning that we can run the image safely. */
-       if (EntryPoint == NULL)
-         {
-           DPRINT1("Failed to initialize image\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
-         }
+    /* Check before returning that we can run the image safely. */
+    if (EntryPoint == NULL)
+    {
+        DPRINT1("Failed to initialize image\n");
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
+    }
 
-       /* Break into debugger */
-       if (Peb->BeingDebugged) DbgBreakPoint();
-     }
+    /* Break into debugger */
+    if (Peb->BeingDebugged)
+        DbgBreakPoint();
+}
+
+VOID
+NTAPI
+LdrpInit(PCONTEXT Context,
+         PVOID SystemArgument1,
+         PVOID SystemArgument2)
+{
+    if (!LdrpInitialized)
+    {
+        if (!_InterlockedExchange(&LdrpInitLock, 1))
+        {
+            LdrpInit2(Context, SystemArgument1, SystemArgument2);
+            LdrpInitialized = TRUE;
+        }
+        else
+        {
+            LARGE_INTEGER Interval = {{-200000, -1}};
+
+            do
+            {
+                NtDelayExecution(FALSE, &Interval);
+            }
+            while (!LdrpInitialized);
+        }
+    }
 
-   /* attach the thread */
-   RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
-   LdrpAttachThread();
-   RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
+    /* attach the thread */
+    RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
+    LdrpAttachThread();
+    RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
 }
 
 /* EOF */
index cbe68b5..19b85b7 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <advapi32.h>
 #include "crypt.h"
-#include <winefs.h>
 
 #include <wine/debug.h>
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
index 7897233..4fcfb7e 100644 (file)
@@ -1261,9 +1261,9 @@ LookupAccountNameA(LPCSTR SystemName,
         WideCharToMultiByte(CP_ACP,
                             0,
                             lpReferencedDomainNameW,
-                            *hReferencedDomainNameLength,
+                            *hReferencedDomainNameLength + 1,
                             ReferencedDomainName,
-                            *hReferencedDomainNameLength,
+                            *hReferencedDomainNameLength + 1,
                             NULL,
                             NULL);
     }
@@ -1301,6 +1301,12 @@ LookupAccountNameW(LPCWSTR lpSystemName,
     TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName, lpAccountName,
           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
 
+    if (!ADVAPI_IsLocalComputer(lpSystemName))
+    {
+        SetLastError(RPC_S_SERVER_UNAVAILABLE);
+        return FALSE;
+    }
+
     for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
     {
         if (!wcscmp(lpAccountName, ACCOUNT_SIDS[i].account))
@@ -1343,13 +1349,16 @@ LookupAccountNameW(LPCWSTR lpSystemName,
     if (ReferencedDomainName != NULL && (*cchReferencedDomainName > wcslen(dm)))
         wcscpy(ReferencedDomainName, dm);
 
-    if (*cchReferencedDomainName <= wcslen(dm))
+    if ((*cchReferencedDomainName <= wcslen(dm)) || (!ret))
     {
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
         ret = FALSE;
+        *cchReferencedDomainName = wcslen(dm) + 1;
+    }
+    else
+    {
+        *cchReferencedDomainName = wcslen(dm);
     }
-
-    *cchReferencedDomainName = wcslen(dm)+1;
 
     FreeSid(pSid);
 
@@ -1452,6 +1461,12 @@ LookupPrivilegeValueW(LPCWSTR SystemName,
     };
   unsigned Priv;
 
+  if (!ADVAPI_IsLocalComputer(SystemName))
+    {
+        SetLastError(RPC_S_SERVER_UNAVAILABLE);
+        return FALSE;
+    }
+
   if (NULL != SystemName && L'\0' != *SystemName)
     {
       FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
@@ -1592,6 +1607,7 @@ LookupPrivilegeNameW(LPCWSTR lpSystemName,
         SetLastError(RPC_S_SERVER_UNAVAILABLE);
         return FALSE;
     }
+
     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
     {
index 3aabc08..63f4080 100644 (file)
@@ -627,7 +627,7 @@ static DWORD fill_file_list(SESSION *session, LPCSTR szCabName, LPCSTR szFileLis
     struct FILELIST *pNode;
 
     session->Operation |= EXTRACT_FILLFILELIST;
-    if (pExtract(session, szCabName))
+    if (pExtract(session, szCabName) != S_OK)
     {
         session->Operation &= ~EXTRACT_FILLFILELIST;
         return -1;
index 0ec5ceb..129ea82 100644 (file)
@@ -91,7 +91,7 @@ static HRESULT del_dirs_callback(HINF hinf, PCWSTR field, const void *arg)
                                MAX_INF_STRING_LENGTH, &size))
             continue;
 
-        if (DelNodeW(directory, ADN_DEL_IF_EMPTY))
+        if (DelNodeW(directory, ADN_DEL_IF_EMPTY) != S_OK)
             hr = E_FAIL;
     }
 
@@ -161,7 +161,7 @@ static HRESULT register_ocxs_callback(HINF hinf, PCWSTR field, const void *arg)
         hm = LoadLibraryExW(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
         if (hm)
         {
-            if (do_ocx_reg(hm, TRUE))
+            if (do_ocx_reg(hm, TRUE) != S_OK)
                 hr = E_FAIL;
 
             FreeLibrary(hm);
@@ -196,7 +196,7 @@ static HRESULT run_setup_commands_callback(HINF hinf, PCWSTR field, const void *
                                MAX_INF_STRING_LENGTH, &size))
             continue;
 
-        if (launch_exe(buffer, info->working_dir, NULL))
+        if (launch_exe(buffer, info->working_dir, NULL) != S_OK)
             hr = E_FAIL;
     }
 
index bcb6cb9..9a43015 100644 (file)
@@ -230,7 +230,7 @@ HRESULT WINAPI RegInstallW(HMODULE hm, LPCWSTR pszSection, const STRTABLEW* pstT
     if(!create_tmp_ini_file(hm, tmp_ini_path))
         return E_FAIL;
 
-    if (write_predefined_strings(hm, tmp_ini_path))
+    if (write_predefined_strings(hm, tmp_ini_path) != S_OK)
         goto done;
 
     /* Write the additional string table */
index 1d8a67c..c98cba7 100644 (file)
@@ -117,7 +117,7 @@ BOOL WINAPI AtlAxWinInit(void)
  */
 
 
-static ULONG WINAPI IOCS_AddRef(IOCS *This)
+static ULONG IOCS_AddRef(IOCS *This)
 {
     ULONG ref = InterlockedIncrement(&This->ref);
 
@@ -132,7 +132,7 @@ static ULONG WINAPI IOCS_AddRef(IOCS *This)
 #define THIS2IOLEINPLACEFRAME(This) ((IOleInPlaceFrame*)&This->lpOleInPlaceFrameVtbl)
 #define THIS2IOLECONTROLSITE(This) ((IOleControlSite*)&This->lpOleControlSiteVtbl)
 
-static HRESULT WINAPI IOCS_QueryInterface(IOCS *This, REFIID riid, void **ppv)
+static HRESULT IOCS_QueryInterface(IOCS *This, REFIID riid, void **ppv)
 {
     *ppv = NULL;
 
@@ -166,7 +166,7 @@ static HRESULT WINAPI IOCS_QueryInterface(IOCS *This, REFIID riid, void **ppv)
 }
 
 static HRESULT IOCS_Detach( IOCS *This );
-static ULONG WINAPI IOCS_Release(IOCS *This)
+static ULONG IOCS_Release(IOCS *This)
 {
     ULONG ref = InterlockedDecrement(&This->ref);
 
@@ -752,7 +752,7 @@ static HRESULT IOCS_Detach( IOCS *This ) /* remove subclassing */
     if ( This->hWnd )
     {
         SetWindowLongPtrW( This->hWnd, GWLP_WNDPROC, (ULONG_PTR) This->OrigWndProc );
-        SetWindowLongPtrW( This->hWnd, GWLP_USERDATA, (LONG_PTR) NULL );
+        SetWindowLongPtrW( This->hWnd, GWLP_USERDATA, 0 );
         This->hWnd = NULL;
     }
     if ( This->control )
@@ -1244,7 +1244,7 @@ HWND WINAPI AtlAxCreateDialogW(HINSTANCE hInst, LPCWSTR name, HWND owner, DLGPRO
     hgl = LoadResource (hInst, hrsrc);
     if ( !hgl )
         return NULL;
-    ptr = (LPCDLGTEMPLATEW)LockResource ( hgl );
+    ptr = LockResource ( hgl );
     if (!ptr)
     {
         FreeResource( hgl );
index 2b921c5..d3ca9b0 100644 (file)
@@ -242,7 +242,7 @@ static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOO
                 strbuf_write(buf->str, &name, -1);
             }else if(key_type == DO_DELETE) {
                 TRACE("Deleting %s\n", debugstr_w(buf->str));
-                lres = RegDeleteTreeW(parent_key, buf->str);
+                RegDeleteTreeW(parent_key, buf->str);
             }else {
                 if(key_type == FORCE_REMOVE)
                     RegDeleteTreeW(parent_key, buf->str);
@@ -439,7 +439,7 @@ static HRESULT resource_register(Registrar *This, LPCOLESTR resFileName,
     if(hins) {
         src = FindResourceW(hins, szID, szType);
         if(src) {
-            regstra = (LPSTR)LoadResource(hins, src);
+            regstra = LoadResource(hins, src);
             reslen = SizeofResource(hins, src);
             if(regstra) {
                 len = MultiByteToWideChar(CP_ACP, 0, regstra, reslen, NULL, 0)+1;
index ea745a6..ed413f8 100644 (file)
@@ -462,7 +462,7 @@ static cab_ULONG fci_get_checksum(const void *pv, UINT cb, CHECKSUM seed)
     case 2:
       ul |= (((ULONG)(*pb++)) <<  8);
     case 1:
-      ul |= *pb++;
+      ul |= *pb;
     default:
       break;
   }
index 454776a..4923404 100644 (file)
@@ -911,6 +911,7 @@ static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
 {
   if (inlen != outlen) return DECR_ILLEGALDATA;
+  if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
   memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
   return DECR_OK;
 }
@@ -924,7 +925,7 @@ static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t)
 
   /* Go through linked list, freeing from the allocated (t[-1]) address. */
   p = t;
-  while (p != (struct Ziphuft *)NULL)
+  while (p != NULL)
   {
     q = (--p)->v.t;
     PFDI_FREE(hfdi, p);
@@ -969,7 +970,7 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
   } while (--i);
   if (ZIP(c)[0] == n)                /* null input--all zero length codes */
   {
-    *t = (struct Ziphuft *)NULL;
+    *t = NULL;
     *m = 0;
     return 0;
   }
@@ -1017,8 +1018,8 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
   p = ZIP(v);                        /* grab values in bit order */
   h = -1;                       /* no tables yet--level -1 */
   w = l[-1] = 0;                /* no bits decoded yet */
-  ZIP(u)[0] = (struct Ziphuft *)NULL;   /* just to keep compilers happy */
-  q = (struct Ziphuft *)NULL;      /* ditto */
+  ZIP(u)[0] = NULL;             /* just to keep compilers happy */
+  q = NULL;                     /* ditto */
   z = 0;                        /* ditto */
 
   /* go through the bit lengths (k already is bits in shortest code) */
@@ -1060,7 +1061,7 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
           return 3;             /* not enough memory */
         }
         *t = q + 1;             /* link to list for Ziphuft_free() */
-        *(t = &(q->v.t)) = (struct Ziphuft *)NULL;
+        *(t = &(q->v.t)) = NULL;
         ZIP(u)[h] = ++q;             /* table starts after link */
 
         /* connect to last table, if there is one */
@@ -2258,6 +2259,56 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state
   return DECR_OK;
 }
 
+static void free_decompression_temps(HFDI hfdi, struct fdi_folder *fol,
+  fdi_decomp_state *decomp_state)
+{
+  switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
+  case cffoldCOMPTYPE_LZX:
+    if (LZX(window)) {
+      PFDI_FREE(hfdi, LZX(window));
+      LZX(window) = NULL;
+    }
+    break;
+  case cffoldCOMPTYPE_QUANTUM:
+    if (QTM(window)) {
+      PFDI_FREE(hfdi, QTM(window));
+      QTM(window) = NULL;
+    }
+    break;
+  }
+}
+
+static void free_decompression_mem(HFDI hfdi, struct fdi_folder *fol,
+  fdi_decomp_state *decomp_state, struct fdi_file *file)
+{
+  while (decomp_state) {
+    fdi_decomp_state *prev_fds;
+
+    PFDI_CLOSE(hfdi, CAB(cabhf));
+
+    /* free the storage remembered by mii */
+    if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
+    if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
+    if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
+    if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
+
+    while (CAB(firstfol)) {
+      fol = CAB(firstfol);
+      CAB(firstfol) = CAB(firstfol)->next;
+      PFDI_FREE(hfdi, fol);
+    }
+    while (CAB(firstfile)) {
+      file = CAB(firstfile);
+      if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
+      CAB(firstfile) = CAB(firstfile)->next;
+      PFDI_FREE(hfdi, file);
+    }
+    prev_fds = decomp_state;
+    decomp_state = CAB(next);
+    PFDI_FREE(hfdi, prev_fds);
+  }
+}
+
 /***********************************************************************
  *             FDICopy (CABINET.22)
  *
@@ -2442,8 +2493,7 @@ BOOL __cdecl FDICopy(
   cab_UBYTE         buf[64];
   struct fdi_folder *fol = NULL, *linkfol = NULL; 
   struct fdi_file   *file = NULL, *linkfile = NULL;
-  fdi_decomp_state _decomp_state;
-  fdi_decomp_state *decomp_state = &_decomp_state;
+  fdi_decomp_state *decomp_state;
 
   TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
         "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
@@ -2454,6 +2504,11 @@ BOOL __cdecl FDICopy(
     return FALSE;
   }
 
+  if (!(decomp_state = PFDI_ALLOC(hfdi, sizeof(fdi_decomp_state))))
+  {
+      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
+  }
   ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
 
   pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
@@ -2777,7 +2832,7 @@ BOOL __cdecl FDICopy(
 
       if (file->offset > CAB(offset)) {
         /* decode bytes and send them to /dev/null */
-        switch ((err = fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser))) {
+        switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
           case DECR_OK:
             break;
           case DECR_USERABORT:
@@ -2839,99 +2894,18 @@ BOOL __cdecl FDICopy(
     }
   }
 
-  /* free decompression temps */
-  switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
-  case cffoldCOMPTYPE_LZX:
-    if (LZX(window)) {
-      PFDI_FREE(hfdi, LZX(window));
-      LZX(window) = NULL;
-    }
-    break;
-  case cffoldCOMPTYPE_QUANTUM:
-    if (QTM(window)) {
-      PFDI_FREE(hfdi, QTM(window));
-      QTM(window) = NULL;
-    }
-    break;
-  }
-
-  while (decomp_state) {
-    fdi_decomp_state *prev_fds;
-
-    PFDI_CLOSE(hfdi, CAB(cabhf));
-
-    /* free the storage remembered by mii */
-    if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
-    if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
-    if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
-    if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
-
-    while (CAB(firstfol)) {
-      fol = CAB(firstfol);
-      CAB(firstfol) = CAB(firstfol)->next;
-      PFDI_FREE(hfdi, fol);
-    }
-    while (CAB(firstfile)) {
-      file = CAB(firstfile);
-      if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
-      CAB(firstfile) = CAB(firstfile)->next;
-      PFDI_FREE(hfdi, file);
-    }
-    prev_fds = decomp_state;
-    decomp_state = CAB(next);
-    if (prev_fds != &_decomp_state)
-      PFDI_FREE(hfdi, prev_fds);
-  }
+  free_decompression_temps(hfdi, fol, decomp_state);
+  free_decompression_mem(hfdi, fol, decomp_state, file);
  
   return TRUE;
 
   bail_and_fail: /* here we free ram before error returns */
 
-  /* free decompression temps */
-  switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
-  case cffoldCOMPTYPE_LZX:
-    if (LZX(window)) {
-      PFDI_FREE(hfdi, LZX(window));
-      LZX(window) = NULL;
-    }
-    break;
-  case cffoldCOMPTYPE_QUANTUM:
-    if (QTM(window)) {
-      PFDI_FREE(hfdi, QTM(window));
-      QTM(window) = NULL;
-    }
-    break;
-  }
+  free_decompression_temps(hfdi, fol, decomp_state);
 
   if (filehf) PFDI_CLOSE(hfdi, filehf);
 
-  while (decomp_state) {
-    fdi_decomp_state *prev_fds;
-
-    PFDI_CLOSE(hfdi, CAB(cabhf));
-
-    /* free the storage remembered by mii */
-    if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
-    if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
-    if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
-    if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
-
-    while (CAB(firstfol)) {
-      fol = CAB(firstfol);
-      CAB(firstfol) = CAB(firstfol)->next;
-      PFDI_FREE(hfdi, fol);
-    }
-    while (CAB(firstfile)) {
-      file = CAB(firstfile);
-      if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
-      CAB(firstfile) = CAB(firstfile)->next;
-      PFDI_FREE(hfdi, file);
-    }
-    prev_fds = decomp_state;
-    decomp_state = CAB(next);
-    if (prev_fds != &_decomp_state)
-      PFDI_FREE(hfdi, prev_fds);
-  }
+  free_decompression_mem(hfdi, fol, decomp_state, file);
 
   return FALSE;
 }
index d0c0591..c85f877 100644 (file)
@@ -30,7 +30,7 @@
 extern HINSTANCE       COMDLG32_hInstance;
 
 void   COMDLG32_SetCommDlgExtendedError(DWORD err);
-LPVOID COMDLG32_AllocMem(int size);
+LPVOID COMDLG32_AllocMem(int size) __WINE_ALLOC_SIZE(1);
 
 /* handle<-handle16 conversion */
 #define HINSTANCE_32(h16)           ((HINSTANCE)(ULONG_PTR)(h16))
@@ -182,12 +182,8 @@ extern UINT (WINAPI *COMDLG32_PIDL_ILGetSize)(LPCITEMIDLIST);
 /* SHELL */
 extern LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD);
 extern DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
-extern BOOL (WINAPI *COMDLG32_SHGetFolderPathA)(HWND,int,HANDLE,DWORD,LPSTR);
 extern BOOL (WINAPI *COMDLG32_SHGetFolderPathW)(HWND,int,HANDLE,DWORD,LPWSTR);
 
-extern BOOL  WINAPI GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType);
-extern BOOL  WINAPI GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType);
-
 /*
  * Internal Functions
  * Do NOT Export to other programs and dlls
index 0f0f69b..afa3c61 100644 (file)
@@ -52,7 +52,6 @@ UINT (WINAPI *COMDLG32_PIDL_ILGetSize)(LPCITEMIDLIST);
 /* SHELL */
 LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD);
 DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
-BOOL (WINAPI *COMDLG32_SHGetFolderPathA)(HWND,int,HANDLE,DWORD,LPSTR);
 BOOL (WINAPI *COMDLG32_SHGetFolderPathW)(HWND,int,HANDLE,DWORD,LPWSTR);
 
 /***********************************************************************
@@ -102,13 +101,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
 
                GPA(COMDLG32_SHAlloc, SHELL32_hInstance, (LPCSTR)196L);
                GPA(COMDLG32_SHFree, SHELL32_hInstance, (LPCSTR)195L);
-               /* for the first versions of shell32 SHGetFolderPathA is in SHFOLDER.DLL */
-               COMDLG32_SHGetFolderPathA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFolderPathA");
-               if (!COMDLG32_SHGetFolderPathA)
-               {
-                 SHFOLDER_hInstance = LoadLibraryA("SHFOLDER.DLL");
-                 GPA(COMDLG32_SHGetFolderPathA, SHFOLDER_hInstance,"SHGetFolderPathA");
-               }
 
                /* for the first versions of shell32 SHGetFolderPathW is in SHFOLDER.DLL */
                COMDLG32_SHGetFolderPathW = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFolderPathW");
index 721b20c..ed2c944 100644 (file)
@@ -400,7 +400,7 @@ Bitte geben sie einen Wert zwischen %d und %d an."
     PD32_GENERIC_ERROR                    "Ein unbekannter Fehler ist aufgetreten."
     PD32_DRIVER_UNKNOWN                   "Unbekannter Druckertreiber."
     PD32_NO_DEVICES                       "Bevor Sie drucker-relevante Aufgaben ausführen können, \
-    wie die Seiteneinrichtung oder ein Dokument zu drucken,\
+    wie die Seiteneinrichtung oder ein Dokument zu drucken, \
     müssen Sie einen Drucker installieren. Bitte führen Sie dies zuerst aus und versuchen Sie es erneut."
 
     PD32_DEFAULT_PRINTER                  "Standard Drucker; "
index f849cfc..8f8c668 100644 (file)
  * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES.
  */
 
+/* UTF-8 */
+#pragma code_page(65001)
+
 LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
 
 OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\83t\83@\83C\83\8b\82ð\8aJ\82­"
-FONT 9, "MS UI Gothic"
+CAPTION "ファイルを開く"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\83t\83@\83C\83\8b\96¼(&N):", 1090, 6, 6, 76, 9
- EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LTEXT "ファイル名(&N):", 1090, 6, 6, 76, 9
+ EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
  LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "\83f\83B\83\8c\83N\83g\83\8a(&D):", -1, 110, 6, 92, 9
+ LTEXT "ディレクトリ(&D):", -1, 110, 6, 92, 9
  LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
  LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "\83t\83@\83C\83\8b\82Ì\8eí\97Þ(&T):", 1089, 6, 104, 90, 9
- COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- LTEXT "\83h\83\89\83C\83u(&V):", 1091, 110, 104, 92, 9
- COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- DEFPUSHBUTTON "OK", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "·¬Ý¾Ù", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÍÙÌß(&H)", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
- CHECKBOX "\8fã\8f\91\82«\8bÖ\8e~(&R)", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ LTEXT "ファイルの種類(&T):", 1089, 6, 104, 90, 9
+ COMBOBOX cmb1, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "ドライブ(&V):", 1091, 110, 104, 92, 9
+ COMBOBOX cmb2, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "開く", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "キャンセル", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "ヘルプ(&H)", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "上書き禁止(&R)", chx1, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
 }
 
 
 SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\96¼\91O\82ð\82Â\82¯\82Ä\95Û\91"
-FONT 9, "MS UI Gothic"
+CAPTION "名前をつけて保存"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\83t\83@\83C\83\8b\96¼(&N):", 1090, 6, 6, 76, 9
- EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LTEXT "ファイル名(&N):", 1090, 6, 6, 76, 9
+ EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
  LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "\83f\83B\83\8c\83N\83g\83\8a(&D):", -1, 110, 6, 92, 9
+ LTEXT "ディレクトリ(&D):", -1, 110, 6, 92, 9
  LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
  LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "\83t\83@\83C\83\8b\82Ì\8eí\97Þ(&T):", 1089, 6, 104, 90, 9
- COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- LTEXT "\83h\83\89\83C\83u(&V):", 1091, 110, 104, 92, 9
- COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- DEFPUSHBUTTON "OK", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "·¬Ý¾Ù", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÍÙÌß(&H)", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
- CHECKBOX "\8fã\8f\91\82«\8bÖ\8e~(&R)", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ LTEXT "ファイルの種類(&T):", 1089, 6, 104, 90, 9
+ COMBOBOX cmb1, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "ドライブ(&V):", 1091, 110, 104, 92, 9
+ COMBOBOX cmb2, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "保存", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "キャンセル", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "ヘルプ(&H)", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "上書き禁止(&R)", chx1, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
 }
 
 
 PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\88ó\8dü"
-FONT 9, "MS UI Gothic"
+CAPTION "印刷"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\8eg\97p\82·\82éÌßØÝÀ:", 1088, 6, 6, 40, 9
- LTEXT "\92Ê\8fí\8eg\82¤ÌßØÝÀ", 1089, 60, 6, 150, 9
- GROUPBOX "\88ó\8dü\94Í\88Í\82Ì\91I\91ð", 1072, 6, 30, 160, 65, BS_GROUPBOX
- RADIOBUTTON "\91S\83y\81[\83W(&A)", 1056, 16, 45, 60, 12
- RADIOBUTTON "\91I\91ð\82µ\82½\95\94\95ª(&E)", 1057, 16, 60, 60, 12
- RADIOBUTTON "\83y\81[\83W\8ew\92è(&P)", 1058, 16, 75, 60, 12
- DEFPUSHBUTTON "OK", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "·¬Ý¾Ù", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÌßØÝÀ\82Ì\90Ý\92è(&S)", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
- LTEXT "Íß°¼Þ\82©\82ç(&F):", 1090, 60, 80, 30, 9
- LTEXT "Íß°¼Þ\82Ü\82Å(&T):", 1091, 120, 80, 30, 9
- LTEXT "\88ó\8e\9a\95i\8e¿(&Q):", 1092, 6, 100, 76, 9
- COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- CHECKBOX "\83t\83@\83C\83\8b\82Ö\8fo\97Í(&L)", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- CHECKBOX "Condensed", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ LTEXT "使用するプリンタ:", 1088, 6, 6, 40, 9
+ LTEXT "", 1089, 60, 6, 150, 9
+ GROUPBOX "印刷範囲の選択", grp1, 6, 30, 160, 65, BS_GROUPBOX
+ RADIOBUTTON "全ページ(&A)", rad1, 16, 45, 60, 12
+ RADIOBUTTON "選択した部分(&E)", rad2, 16, 60, 60, 12
+ RADIOBUTTON "ページ設定(&P)", rad3, 16, 75, 60, 12
+ DEFPUSHBUTTON "印刷", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "キャンセル", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "プリンタの設定(&S)", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "ページから(&F):", 1090, 60, 80, 30, 9
+ LTEXT "ページまで(&T):", 1091, 120, 80, 30, 9
+ LTEXT "印字品質(&Q):", 1092, 6, 100, 76, 9
+ COMBOBOX cmb1, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ CHECKBOX "ファイルへ出力(&L)", chx1, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Condensed", chx2, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
 }
 
 
 PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\83v\83\8a\83\93\83^\82Ì\90Ý\92è"
-FONT 9, "MS UI Gothic"
+CAPTION "プリンタの設定"
+FONT 9, "MS Shell Dlg"
 {
- GROUPBOX "\83v\83\8a\83\93\83^\82Ì\91I\91ð", 1072, 6, 10, 180, 65, BS_GROUPBOX
- RADIOBUTTON "\92Ê\8fí\8eg\82¤\83v\83\8a\83\93\83^(&D)", 1056, 16, 20, 80, 12
- LTEXT "(\92Ê\8fí\8eg\82¤\83v\83\8a\83\93\83^\82ª\90Ý\92è\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ)", 1088, 35, 35, 120, 9
- RADIOBUTTON "\82»\82Ì\91¼\82Ì\83v\83\8a\83\93\83^(&P)", 1057, 16, 50, 80, 12
- COMBOBOX 1136, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- DEFPUSHBUTTON "OK", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "·¬Ý¾Ù", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "&Setup", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
- GROUPBOX "\88ó\8dü\82Ì\8cü\82«", 1073, 6, 85, 100, 50, BS_GROUPBOX
- RADIOBUTTON "\8fc(&R)", 1058, 50, 100, 40, 12
- RADIOBUTTON "\89¡(&L)", 1059, 50, 115, 40, 12
- ICON "LANDSCAP", 1097, 10, 95, 32, 32
- ICON "PORTRAIT", 1098, 10, 95, 32, 32
- GROUPBOX "\97p\8e\86\82Ì\91I\91ð", 1074, 120, 85, 180, 50, BS_GROUPBOX
- LTEXT "\97p\8e\86»²½Þ(&Z)", 1089, 130, 95, 30, 9
- LTEXT "\8b\8b\8e\86\95û\96@(&S)", 1090, 130, 110, 30, 9
- COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "プリンタの選択", grp1, 6, 10, 180, 65, BS_GROUPBOX
+ RADIOBUTTON "通常使うプリンタ(&D)", rad1, 16, 20, 80, 12
+ LTEXT "(通常使うプリンタが設定されていません)", 1088, 35, 35, 120, 9
+ RADIOBUTTON "その他のプリンタ(&P)", rad2, 16, 50, 80, 12
+ COMBOBOX cmb1, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "キャンセル", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "設定(&S)", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ GROUPBOX "印刷の向き", grp2, 6, 85, 100, 50, BS_GROUPBOX
+ RADIOBUTTON "縦(&R)", rad3, 50, 100, 50, 12
+ RADIOBUTTON "横(&L)", rad4, 50, 115, 50, 12
+ ICON "LANDSCAP", stc10, 10, 95, 32, 32
+ ICON "PORTRAIT", stc11, 10, 95, 32, 32
+ GROUPBOX "用紙の選択", grp3, 120, 85, 180, 50, BS_GROUPBOX
+ LTEXT "用紙サイズ(&Z)", 1089, 130, 95, 30, 9
+ LTEXT "給紙方法(&S)", 1090, 130, 110, 30, 9
+ COMBOBOX cmb2, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX cmb3, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
 }
 
 
 CHOOSE_FONT DIALOG DISCARDABLE  13, 54, 264, 147
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\83t\83H\83\93\83g\82Ì\8ew\92è"
-FONT 9, "MS UI Gothic"
+CAPTION "フォントの指定"
+FONT 9, "MS Shell Dlg"
 {
-    LTEXT           "Ì«ÝÄ\96¼(&F):",1088 ,6,3,40,9
-    COMBOBOX        1136 ,6,13,94,54,  CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+    LTEXT           "フォント名(&F):",stc1 ,6,3,40,9
+    COMBOBOX        cmb1, 6,13,94,54,  CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
                     CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
-    LTEXT           "½À²Ù(&Y):",1089 ,108,3,44,9
-    COMBOBOX        1137,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+    LTEXT           "スタイル(&Y):",stc2 ,108,3,44,9
+    COMBOBOX        cmb2,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
                     WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
-    LTEXT           "»²½Þ(&S):",1090,179,3,30,9
-    COMBOBOX        1138,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+    LTEXT           "サイズ(&S):",stc3,179,3,30,9
+    COMBOBOX        cmb3,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
                     WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT
-    DEFPUSHBUTTON   "OK",IDOK,218,6,40,14,WS_GROUP
-    PUSHBUTTON      "·¬Ý¾Ù",IDCANCEL,218,23,40,14,WS_GROUP
-    PUSHBUTTON      "\95\8e\9a\8fü\82è(&A)", 1026,218,40,40,14,WS_GROUP
-    PUSHBUTTON      "ÍÙÌß(&H)" , 1038,218,57,40,14,WS_GROUP
-    GROUPBOX        "\95\8e\9a\8fü\82è",1072,6,72,84,34,WS_GROUP
-    CHECKBOX       "\8eæ\82è\8fÁ\82µ\90ü(&K)", 1040, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
-    CHECKBOX       "\89º\90ü(&U)", 1041, 10,94,50,10, BS_AUTOCHECKBOX
-    LTEXT           "\90F(&C):", 1091 ,6,110,30,9
-    COMBOBOX        1139,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS |
+    DEFPUSHBUTTON   "OK",IDOK,218,6,40,14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+    PUSHBUTTON      "キャンセル",IDCANCEL,218,23,40,14,WS_GROUP | WS_TABSTOP
+    PUSHBUTTON      "適用(&A)", psh3,218,40,40,14,WS_GROUP | WS_TABSTOP
+    PUSHBUTTON      "ヘルプ(&H)" , pshHelp,218,57,40,14,WS_GROUP | WS_TABSTOP
+    GROUPBOX        "文字飾り",grp1,6,72,84,34,WS_GROUP
+    CHECKBOX       "取り消し線(&K)", chx1, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX       "下線(&U)", chx2, 10,94,50,10, BS_AUTOCHECKBOX
+    LTEXT           "色(&C):", stc4 ,6,110,30,9
+    COMBOBOX        cmb4,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS |
                    CBS_AUTOHSCROLL |  WS_BORDER | WS_VSCROLL | WS_TABSTOP
-    GROUPBOX        "\83T\83\93\83v\83\8b",grp2,98,72,120,36,WS_GROUP
+    GROUPBOX        "サンプル",grp2,98,72,120,36,WS_GROUP
     CTEXT           "AaBbYyZz",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE
-    LTEXT           "Scr&ipt (translate):",stc7 ,98,114,80,9
+    LTEXT           "文字セット(&I):",stc7 ,98,114,40,9
     COMBOBOX        cmb5,98,124,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS |
                    CBS_AUTOHSCROLL |   WS_VSCROLL | WS_TABSTOP
 }
@@ -149,23 +152,23 @@ FONT 9, "MS UI Gothic"
 
 CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 185
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\90F\82Ì\90Ý\92è"
-FONT 9, "MS UI Gothic"
+CAPTION "色の設定"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\8aî\96{\90F(&B):",   1088, 4,    4,  140, 10
- LTEXT "\8dì\90¬\82µ\82½\90F(&C):",  1089, 4,   106, 140, 10
- LTEXT "\90F |",  1090, 150, 151,  48, 10
- LTEXT   "\90Ô(&R):", 726 /*1094*/,249,126,24,10
+ LTEXT "基本色(&B):",   1088, 4,    4,  140, 10
+ LTEXT "作成した色(&C):",  1089, 4,   106, 140, 10
+ LTEXT "色 |  純色(&I)",  1090, 150, 151,  48, 10
+ LTEXT   "(&R):", 726 /*1094*/,249,126,24,10
  EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT   "\97Î(&G):",727/*1095*/,249,140,24,10
+ LTEXT   "(&G):",727/*1095*/,249,140,24,10
  EDITTEXT 707, 275,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT   "\90Â(&B):",728 /*1096*/,249,154,24,10
+ LTEXT   "(&B):",728 /*1096*/,249,154,24,10
  EDITTEXT 708, 275,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT  "\90F\8d\87\82¢(&U):" ,723 /*1091*/,202,126,22,10
+ LTEXT  "色合い(&H):" ,723 /*1091*/,202,126,22,10
  EDITTEXT 703, 226,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT  "\91N\82â\82©\82³(&S):" ,724 /*1092*/,202,140,22,10
+ LTEXT  "鮮やかさ(&S):" ,724 /*1092*/,202,140,22,10
  EDITTEXT 704, 226,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT  "\96¾\82é\82³(&L):" ,725 /*1093*/,202,154,22,10
+ LTEXT  "明るさ(&L):" ,725 /*1093*/,202,154,22,10
  EDITTEXT 705, 226,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
  CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86
  CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28
@@ -173,174 +176,312 @@ FONT 9, "MS UI Gothic"
  CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
  CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
  DEFPUSHBUTTON "OK",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "·¬Ý¾Ù", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÍÙÌß(&H)", 1038,100,166, 44, 14
- PUSHBUTTON "\92Ç\89Á(&A)",    712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "\90F\82Ì\8dì\90¬(&D)...", 719/*1025*/,   4, 150, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "キャンセル", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "ヘルプ", pshHelp,100,166, 44, 14
+ PUSHBUTTON "色の追加(&A)",    712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "色の作成(&D) >>", 719/*1025*/,   4, 150, 142, 14, WS_GROUP | WS_TABSTOP
  PUSHBUTTON  "&i",713,300,200,4,14   /* just a dummy:  'i' is  like  &i  in "sol&id"  */
 }
 
 
 FINDDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\95\8e\9a\97ñ\82Ì\8c\9f\8dõ"
-FONT 9, "MS UI Gothic"
+CAPTION "文字列の検索"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\8c\9f\8dõ\82·\82é\95\8e\9a\97ñ(&N):", -1, 4, 8, 42, 8
- EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
- CHECKBOX "\92P\8cê\92P\88Ê\82Å\8c\9f\8dõ(&W)", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- CHECKBOX "\91å\95\8e\9a\82Æ\8f¬\95\8e\9a\82ð\8bæ\95Ê\82·\82é(&C)", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP
- GROUPBOX "\8c\9f\8dõ\82·\82é\95û\8cü", 1072, 107, 26, 68, 28
- CONTROL "\8fã\82Ö\8cü\82©\82Á\82Ä(&U)", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12
- CONTROL "\89º\82Ö\8cü\82©\82Á\82Ä(&D)", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12
-
- DEFPUSHBUTTON "\8e\9f\82ð\8c\9f\8dõ(&F)", IDOK, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "·¬Ý¾Ù", 2, IDCANCEL, 23, 50, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÍÙÌß(&H)", pshHelp, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "検索する文字列(&N):", -1, 4, 8, 42, 8
+ EDITTEXT edt1, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "単語単位で検索(&W)", chx1, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "大文字と小文字を区別する(&C)", chx2, 4, 42, 89, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ GROUPBOX "検索する方向", grp1, 107, 26, 68, 28
+ CONTROL "上へ(&U)", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 30, 12
+ CONTROL "下へ(&D)", rad2, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12
+
+ DEFPUSHBUTTON "次を検索(&F)", IDOK, 182,  5, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "キャンセル", IDCANCEL         , 182, 23, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "ヘルプ(&H)", pshHelp    , 182, 45, 50, 14, WS_GROUP | WS_TABSTOP
 }
 
 
 REPLACEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "\95\8e\9a\97ñ\82Ì\92u\8a·"
-FONT 9, "MS UI Gothic"
+CAPTION "文字列の置換"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\92u\8a·\91O\82Ì\95\8e\9a\97ñ(&N):", -1, 4, 9, 48, 8
- EDITTEXT 1152, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT "\92u\8a·\8cã\82Ì\95\8e\9a\97ñ(&P):", -1, 4, 26, 48, 8
- EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
- CHECKBOX "\92P\8cê\92P\88Ê\82Å\8c\9f\8dõ(&W)", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- CHECKBOX "\91å\95\8e\9a\82Æ\8f¬\95\8e\9a\82ð\8bæ\95Ê\82·\82é(&C)", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-
- DEFPUSHBUTTON "\8e\9f\82ð\8c\9f\8dõ(&F)", IDOK, 174, 4, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "\92u\8a·\82µ\82Ä\8e\9f\82É(&R)", psh1, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "\82·\82×\82Ä\82ð\92u\8a·(&A)", psh2, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "·¬Ý¾Ù", IDCANCEL, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÍÙÌß(&H)", pshHelp, 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "置換前の文字列(&N):", -1, 4, 9, 48, 8
+ EDITTEXT edt1, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT "置換後の文字列(&P):", -1, 4, 26, 48, 8
+ EDITTEXT edt2, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "単語単位で検索(&W)", chx1, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "大文字と小文字を区別する(&C)", chx2, 5, 62, 89, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+
+ DEFPUSHBUTTON "次を検索(&F)", IDOK, 174,  4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "置換して次に(&R)", psh1      , 174, 21, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "すべてを置換(&A)", psh2 , 174, 38, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "キャンセル", IDCANCEL         , 174, 55, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "ヘルプ(&H)", pshHelp    , 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
 }
 
 
 PRINT32 DIALOG LOADONCALL MOVEABLE DISCARDABLE  32, 32, 288, 186
 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
       DS_CONTEXTHELP | DS_3DLOOK
-CAPTION "\88ó\8dü"
-FONT 9, "MS UI Gothic"
+CAPTION "印刷"
+FONT 9, "MS Shell Dlg"
 {
     DEFPUSHBUTTON   "OK",     IDOK,     180,164, 48,14, WS_GROUP | BS_DEFPUSHBUTTON
-    PUSHBUTTON      "·¬Ý¾Ù", IDCANCEL, 232,164, 48,14, WS_GROUP
-    PUSHBUTTON      "ÍÙÌß(&H)",  pshHelp,  50, 161, 48,14, WS_GROUP
+    PUSHBUTTON      "キャンセル", IDCANCEL, 232,164, 48,14, WS_GROUP
+    PUSHBUTTON      "ヘルプ(&H)",  pshHelp,  50, 161, 48,14, WS_GROUP
 
-    GROUPBOX        "ÌßØÝÀ",        grp4,   8,  4, 272,84, WS_GROUP
-    CONTROL         "̧²Ù\82Ö\8fo\97Í(&L)", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,64,12
-    PUSHBUTTON      "ÌßÛÊßè(&P)",    psh2, 212, 17,  60,14, WS_GROUP
-    LTEXT           "ÌßØÝÀ\96¼(&N):",         stc6,  16, 20,  36,8
+    GROUPBOX        "プリンタ",        grp4,   8,  4, 272,84, WS_GROUP
+    CONTROL         "ファイルへ出力(&L)", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,64,12
+    PUSHBUTTON      "プロパティ(&P)",    psh2, 212, 17,  60,14, WS_GROUP
+    LTEXT           "プリンタ名(&N):",         stc6,  16, 20,  36,8
     COMBOBOX                          cmb4,  52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
-    LTEXT           "\8fó\91Ô:",        stc8,  16, 36,  36,10, SS_NOPREFIX
+    LTEXT           "状態:",        stc8,  16, 36,  36,10, SS_NOPREFIX
     LTEXT           "Dummy State",    stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
-    LTEXT           "\8eí\97Þ:",          stc7,  16, 48,  36,10, SS_NOPREFIX
+    LTEXT           "種類:",          stc7,  16, 48,  36,10, SS_NOPREFIX
     LTEXT           "Dummy Type",     stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
-    LTEXT           "\8fê\8f\8a:",         stc10, 16, 60,  36,10, SS_NOPREFIX
+    LTEXT           "場所:",         stc10, 16, 60,  36,10, SS_NOPREFIX
     LTEXT           "Dummy Location", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
-    LTEXT           "ºÒÝÄ:",       stc9,  16, 72,  36,10, SS_NOPREFIX
+    LTEXT           "コメント:",       stc9,  16, 72,  36,10, SS_NOPREFIX
     LTEXT           "Dummy Remark",   stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
 
-    GROUPBOX        "\88ó\8dü\95\94\90\94",         grp2, 160, 92, 120,64, WS_GROUP
-    LTEXT           "\95\94\90\94(&C):",stc5,168,108,68,8
+    GROUPBOX        "印刷部数",         grp2, 160, 92, 120,64, WS_GROUP
+    LTEXT           "部数(&C):",stc5,168,108,68,8
     ICON            "",               ico3, 162,124,  76,24, WS_GROUP | SS_CENTERIMAGE
-    CONTROL         "\95\94\92P\88Ê\82Å\88ó\8dü(&O)",       chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,36,12
-    EDITTEXT                          edt3, 240,106,  32,12, WS_GROUP | ES_NUMBER
+    CONTROL         "部単位で印刷(&O)",       chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,225,130,51,12
+    EDITTEXT                          edt3, 225,106,  51,12, WS_GROUP | ES_NUMBER
 
-    GROUPBOX        "\88ó\8dü\94Í\88Í",    grp1,   8,92,  144,64, WS_GROUP
-    CONTROL         "\82·\82×\82Ä(&A)",           rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12
-    CONTROL         "Íß°¼Þ\8ew\92è(&G)",         rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12
-    CONTROL         "\91I\91ð\82µ\82½\95\94\95ª(&S)",     rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12
+    GROUPBOX        "印刷範囲",    grp1,   8,92,  144,64, WS_GROUP
+    CONTROL         "すべて(&A)",           rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12
+    CONTROL         "ページ指定(&G)",         rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12
+    CONTROL         "選択した部分(&S)",     rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12
     EDITTEXT                          edt1,  74,122,  26,12, WS_GROUP | ES_NUMBER
     EDITTEXT                          edt2, 118,122,  26,12, WS_GROUP | ES_NUMBER
-    RTEXT           "Íß°¼Þ\82©\82ç(&F)",         stc2,  52,124,  20,8
-    RTEXT           "Íß°¼Þ\82Ü\82Å(&T)",           stc3, 100,124,  16,8
+    RTEXT           "ページから(&F):",         stc2,  52,124,  20,8
+    RTEXT           "ページまで(&T):",           stc3, 100,124,  16,8
 }
 
 PRINT32_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE  32, 32, 288, 178
 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
       DS_CONTEXTHELP | DS_3DLOOK
-CAPTION "\88ó\8dü\82Ì\90Ý\92è"
-FONT 9, "MS UI Gothic"
+CAPTION "印刷の設定"
+FONT 9, "MS Shell Dlg"
 BEGIN
     DEFPUSHBUTTON   "OK",IDOK,180,156,48,14,WS_GROUP
-    PUSHBUTTON      "Cancel",IDCANCEL,232,156,48,14
+    PUSHBUTTON      "キャンセル",IDCANCEL,232,156,48,14
 /*    PUSHBUTTON      "Network...", psh5, 284,156,48,14 */
 
-    GROUPBOX        "ÌßØÝÀ",        grp4,   8,  4, 272,84, WS_GROUP
-    PUSHBUTTON      "ÌßÛÊßè(&P)",    psh2, 212, 17,  60,14, WS_GROUP
-    LTEXT           "ÌßØÝÀ\96¼(&N):",         stc6,  16, 20,  36,8
+    GROUPBOX        "プリンタ",        grp4,   8,  4, 272,84, WS_GROUP
+    PUSHBUTTON      "プロパティ(&P)",    psh2, 212, 17,  60,14, WS_GROUP
+    LTEXT           "プリンタ名(&N):",         stc6,  16, 20,  36,8
     COMBOBOX                          cmb1,  52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
-    LTEXT           "\8fó\91Ô:",        stc8,  16, 36,  36,10, SS_NOPREFIX
+    LTEXT           "状態:",        stc8,  16, 36,  36,10, SS_NOPREFIX
     LTEXT           "Dummy State",    stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
-    LTEXT           "\8eí\97Þ:",          stc7,  16, 48,  36,10, SS_NOPREFIX
+    LTEXT           "種類:",          stc7,  16, 48,  36,10, SS_NOPREFIX
     LTEXT           "Dummy Type",     stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
-    LTEXT           "\8fê\8f\8a:",         stc10, 16, 60,  36,10, SS_NOPREFIX
+    LTEXT           "場所:",         stc10, 16, 60,  36,10, SS_NOPREFIX
     LTEXT           "Dummy Location", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
-    LTEXT           "ºÒÝÄ:",       stc9,  16, 72,  36,10, SS_NOPREFIX
+    LTEXT           "コメント:",       stc9,  16, 72,  36,10, SS_NOPREFIX
     LTEXT           "Dummy Remark",   stc13, 52, 72, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
 
-    GROUPBOX        "\97p\8e\86",          grp2,   8, 92, 164,56, WS_GROUP
-    LTEXT           "\97p\8e\86»²½Þ(&Z):",         stc2,  16,108,  36, 8
+    GROUPBOX        "用紙",          grp2,   8, 92, 164,56, WS_GROUP
+    LTEXT           "用紙サイズ(&Z):",         stc2,  16,108,  36, 8
     COMBOBOX                          cmb2,  52,106, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
     LTEXT           "&Source:",       stc3,  16,128,  36, 8
     COMBOBOX                          cmb3,  52,126, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
 
-    GROUPBOX        "\88ó\8dü\95û\8cü",    grp1, 180, 92, 100,56, WS_GROUP
+    GROUPBOX        "印刷方向",    grp1, 180, 92, 100,56, WS_GROUP
     ICON            "",               ico1, 195,112,  18,20, WS_GROUP
-    CONTROL         "\8fc(&O)",      rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |WS_TABSTOP,224,106,52,12
-    CONTROL         "\89¡(&A)",     rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12
+    CONTROL         "縦(&O)",      rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |WS_TABSTOP,224,106,52,12
+    CONTROL         "横(&A)",     rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12
+END
+
+PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 240, 240
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "ページ設定"
+FONT 9, "MS Shell Dlg"
+BEGIN
+  CONTROL "", rct1, "Static", SS_WHITERECT, 80, 8, 80, 80
+  CONTROL "", rct2, "Static", SS_GRAYRECT, 160, 12, 4, 80
+  CONTROL "", rct3, "Static", SS_GRAYRECT,  84, 88, 80, 4
+  GROUPBOX "用紙", grp2, 8, 96, 224, 56, BS_GROUPBOX
+  LTEXT "サイズ(&S):", stc2, 16, 112, 36, 8
+  COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL
+  LTEXT "給紙方法(&T):", stc3, 16, 132, 36, 8
+  COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL
+  GROUPBOX "印刷の向き", grp1, 8, 156, 64, 56, BS_GROUPBOX
+  AUTORADIOBUTTON "縦(&P)", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON
+  AUTORADIOBUTTON "横(&L)", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON
+  GROUPBOX "余白", grp4, 80, 156, 152, 56, BS_GROUPBOX
+  LTEXT "左(&E):", stc15, 88, 172, 21, 8
+  EDITTEXT edt4, 111, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  LTEXT "右(&R):", stc16, 159, 172, 27, 8
+  EDITTEXT edt6, 187, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  LTEXT "上(&O):", stc17, 88, 192, 21, 8
+  EDITTEXT edt5, 111, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  LTEXT "下(&B):", stc18, 159, 192, 23, 8
+  EDITTEXT edt7, 187, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  DEFPUSHBUTTON "OK", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON
+  PUSHBUTTON "キャンセル", IDCANCEL, 126, 220, 50, 14
+  PUSHBUTTON "プリンタ(&R)...", psh3, 184, 220, 48, 14
 END
 
 NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164
 STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN
-CAPTION "̧²Ù\82ð\8aJ\82­"
-FONT 9, "MS UI Gothic"
+CAPTION "ファイルを開く"
+FONT 9, "MS Shell Dlg"
 {
-    LTEXT      "̧²Ù\82Ì\8fê\8f\8a(&I):",IDC_LOOKINSTATIC,5,6,52,8, SS_NOTIFY
-    COMBOBOX   IDC_LOOKIN,56,3,132,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    LTEXT      "ファイルの場所(&I):",IDC_LOOKINSTATIC,4,6,43,8, SS_NOTIFY
+    COMBOBOX   IDC_LOOKIN,49,3,132,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
 
-    LTEXT      "" , IDC_TOOLBARSTATIC, 188, 2, 82, 17, NOT WS_GROUP | NOT WS_VISIBLE
+    LTEXT      "" , IDC_TOOLBARSTATIC, 181, 2, 102, 17, NOT WS_GROUP | NOT WS_VISIBLE
     LISTBOX    IDC_SHELLSTATIC,4,20,272,85, LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_HSCROLL | NOT WS_VISIBLE
 
-    LTEXT      "̧²Ù\96¼(&N):",IDC_FILENAMESTATIC,5,112,48,8, SS_NOTIFY
-    EDITTEXT   IDC_FILENAME,56,110,153,12,ES_AUTOHSCROLL
+    LTEXT      "ファイル名(&N):",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY
+    EDITTEXT   IDC_FILENAME,54,110,155,12,ES_AUTOHSCROLL
 
-    LTEXT      "̧²Ù\82Ì\8eí\97Þ(&T):",IDC_FILETYPESTATIC,5,128,52,8, SS_NOTIFY
-    COMBOBOX   IDC_FILETYPE,56,126,153,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT      "ファイルの種類(&T):",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY
+    COMBOBOX   IDC_FILETYPE,54,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 
-    CONTROL    "\93Ç\82Ý\8eæ\82è\90ê\97p̧²Ù\82Æ\82µ\82Ä\8aJ\82­(&R)",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10
+    CONTROL    "読み取り専用ファイルとして開く(&R)",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10
 
-    DEFPUSHBUTTON      "\8aJ\82­(&O)",              IDOK,222,110,50,14
-    PUSHBUTTON         "·¬Ý¾Ù",                 IDCANCEL,222,128,50,14
-    PUSHBUTTON         "ÍÙÌß(&H)",              pshHelp,222,145,50,14
+    DEFPUSHBUTTON      "開く(&O)",            IDOK,222,110,50,14
+    PUSHBUTTON         "キャンセル",               IDCANCEL,222,128,50,14
+    PUSHBUTTON         "ヘルプ(&H)",                 pshHelp,222,145,50,14
 }
 
 STRINGTABLE DISCARDABLE
 {
     IDS_ABOUTBOX            "&About FolderPicker Test"
-    IDS_DOCUMENTFOLDERS     "Document Folders"
-    IDS_PERSONAL            "My Documents"
-    IDS_FAVORITES           "\82¨\8bC\82É\93ü\82è"
-    IDS_PATH                "System Path"
-    IDS_DESKTOP             "ÃÞ½¸Ä¯Ìß"
-    IDS_FONTS               "Fonts"
-    IDS_MYCOMPUTER          "ϲ ºÝËß­°À"
+    IDS_DOCUMENTFOLDERS     "ドキュメント フォルダ"
+    IDS_PERSONAL            "マイ ドキュメント"
+    IDS_FAVORITES           "お気に入り"
+    IDS_PATH                "システム パス"
+    IDS_DESKTOP             "デスクトップ"
+    IDS_FONTS               "フォント"
+    IDS_MYCOMPUTER          "マイ コンピュータ"
 }
 
 STRINGTABLE DISCARDABLE
 {
-    IDS_SYSTEMFOLDERS       "System Folders"
-    IDS_LOCALHARDRIVES      "Local Hard Drives"
-    IDS_FILENOTFOUND        "̧²Ù\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ\81B"
-    IDS_VERIFYFILE          "̧²Ù\96¼\82ð\8am\94F\82µ\82Ä\82­\82¾\82³\82¢\81B"
-    IDS_CREATEFILE          "\82±\82Ì̧²Ù\82Í\91\8dÝ\82µ\82Ü\82¹\82ñ\81B\n\8dì\90¬\82µ\82Ü\82·\82©?"
-    IDS_OVERWRITEFILE       "File already exists.\nDo you want to replace it?"
+    IDS_SYSTEMFOLDERS       "システム フォルダ"
+    IDS_LOCALHARDRIVES      "ローカル ハード ドライブ"
+    IDS_FILENOTFOUND        "ファイルが見つかりません。"
+    IDS_VERIFYFILE          "ファイル名を確認してください。"
+    IDS_CREATEFILE          "このファイルは存在しません。\n作成しますか?"
+    IDS_OVERWRITEFILE       "ファイルは既に存在します。\n上書きしますか?"
     IDS_INVALID_FILENAME_TITLE "Invalid character(s) in path"
-    IDS_INVALID_FILENAME    "A filename cannot contain any of the following characters:\n                          / : < > |"
+    IDS_INVALID_FILENAME    "ファイル名には以下の文字は使えません:\n                          / : < > |"
     IDS_PATHNOTEXISTING     "Path does not exist"
     IDS_FILENOTEXISTING     "File does not exist"
 }
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_UPFOLDER         "Up One Level"
+    IDS_NEWFOLDER        "Create New Folder"
+    IDS_LISTVIEW         "List"
+    IDS_REPORTVIEW       "Details"
+    IDS_TODESKTOP        "Browse to Desktop"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    PD32_PRINT_TITLE       "Print"
+
+    PD32_VALUE_UREADABLE                  "Unreadable Entry"
+    PD32_INVALID_PAGE_RANGE "This value does not lie within the page range.\n\
+Please enter a value between %d and %d."
+    PD32_FROM_NOT_ABOVE_TO                "The 'from' entry cannot exceed the \
+'to' entry."
+    PD32_MARGINS_OVERLAP                  "Margins overlap or fall outside \
+Paper boundaries.\nPlease reenter margins."
+    PD32_NR_OF_COPIES_EMPTY               "The number of 'Number of copies' \
+value cannot be empty."
+    PD32_TOO_LARGE_COPIES                 "This large number of copies is not \
+supported by your printer.\nPlease enter a value between 1 and %d."
+    PD32_PRINT_ERROR                      "A printer error occurred."
+    PD32_NO_DEFAULT_PRINTER               "No default printer defined."
+    PD32_CANT_FIND_PRINTER                "Cannot find the printer."
+    PD32_OUT_OF_MEMORY                    "Out of memory."
+    PD32_GENERIC_ERROR                    "An error occurred."
+    PD32_DRIVER_UNKNOWN                   "Unknown printer driver."
+    PD32_NO_DEVICES                       "Before you can perform printer-related tasks \
+such as page setup or printing a document, you need to install a printer. \
+Please install one and retry."
+
+    PD32_DEFAULT_PRINTER                  "Default Printer; "
+    PD32_NR_OF_DOCUMENTS_IN_QUEUE         "There are %d documents in the queue"
+    PD32_MARGINS_IN_INCHES                "Margins [inches]"
+    PD32_MARGINS_IN_MILIMETERS            "Margins [mm]"
+    PD32_MILIMETERS                       "mm"
+
+    PD32_PRINTER_STATUS_READY             "Ready"
+    PD32_PRINTER_STATUS_PAUSED            "Paused; "
+    PD32_PRINTER_STATUS_ERROR             "Error; "
+    PD32_PRINTER_STATUS_PENDING_DELETION  "Pending deletion; "
+    PD32_PRINTER_STATUS_PAPER_JAM         "Paper jam; "
+    PD32_PRINTER_STATUS_PAPER_OUT         "Out of paper; "
+    PD32_PRINTER_STATUS_MANUAL_FEED       "Feed paper manual; "
+    PD32_PRINTER_STATUS_PAPER_PROBLEM     "Paper problem; "
+    PD32_PRINTER_STATUS_OFFLINE           "Printer offline; "
+    PD32_PRINTER_STATUS_IO_ACTIVE         "I/O Active; "
+    PD32_PRINTER_STATUS_BUSY              "Busy; "
+    PD32_PRINTER_STATUS_PRINTING          "Printing; "
+    PD32_PRINTER_STATUS_OUTPUT_BIN_FULL   "Output tray is full; "
+    PD32_PRINTER_STATUS_NOT_AVAILABLE     "Not available; "
+    PD32_PRINTER_STATUS_WAITING           "Waiting; "
+    PD32_PRINTER_STATUS_PROCESSING        "Processing; "
+    PD32_PRINTER_STATUS_INITIALIZING      "Initialising; "
+    PD32_PRINTER_STATUS_WARMING_UP        "Warming up; "
+    PD32_PRINTER_STATUS_TONER_LOW         "Toner low; "
+    PD32_PRINTER_STATUS_NO_TONER          "No toner; "
+    PD32_PRINTER_STATUS_PAGE_PUNT         "Page punt; "
+    PD32_PRINTER_STATUS_USER_INTERVENTION "Interrupted by user; "
+    PD32_PRINTER_STATUS_OUT_OF_MEMORY     "Out of memory; "
+    PD32_PRINTER_STATUS_DOOR_OPEN         "The printer door is open; "
+    PD32_PRINTER_STATUS_SERVER_UNKNOWN    "Print server unknown; "
+    PD32_PRINTER_STATUS_POWER_SAVE        "Power save mode; "
+}
+
+STRINGTABLE DISCARDABLE /* Font styles */
+{
+    IDS_FONT_REGULAR       "標準"
+    IDS_FONT_BOLD          "太字"
+    IDS_FONT_ITALIC        "斜体"
+    IDS_FONT_BOLD_ITALIC   "太字 斜体"
+}
+
+STRINGTABLE DISCARDABLE /* Color names */
+{
+    IDS_COLOR_BLACK     "黒"
+    IDS_COLOR_MAROON    "茶色"
+    IDS_COLOR_GREEN     "緑"
+    IDS_COLOR_OLIVE     "オリーブ"
+    IDS_COLOR_NAVY      "紺"
+    IDS_COLOR_PURPLE    "紫"
+    IDS_COLOR_TEAL      "青緑"
+    IDS_COLOR_GRAY      "灰色"
+    IDS_COLOR_SILVER    "銀色"
+    IDS_COLOR_RED       "赤"
+    IDS_COLOR_LIME      "黄緑"
+    IDS_COLOR_YELLOW    "黄"
+    IDS_COLOR_BLUE      "青"
+    IDS_COLOR_FUCHSIA   "赤紫"
+    IDS_COLOR_AQUA      "水色"
+    IDS_COLOR_WHITE     "白"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_FONT_SIZE   "Select a font size between %d and %d points."
+    IDS_SAVE_BUTTON "保存(&S)"
+    IDS_SAVE_IN     "保存する場所(&I):"
+    IDS_SAVE        "保存"
+    IDS_SAVE_AS     "名前を付けて保存"
+    IDS_OPEN_FILE   "ファイルを開く"
+}
+
+#pragma code_page(default)
index 4a06e1a..59d5e0e 100644 (file)
@@ -48,7 +48,7 @@ FONT 8, "MS Shell Dlg"
 
 SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Shrani kot..."
+CAPTION "Shrani kot ..."
 FONT 8, "MS Shell Dlg"
 {
  LTEXT "Ime &datoteke:", 1090, 6, 6, 76, 9
@@ -270,7 +270,7 @@ FONT 8, "MS Shell Dlg"
 BEGIN
     DEFPUSHBUTTON   "V redu",IDOK,180,156,48,14,WS_GROUP
     PUSHBUTTON      "Prekliči",IDCANCEL,232,156,48,14
-/*    PUSHBUTTON      "Omrežje...", psh5, 284,156,48,14 */
+/*    PUSHBUTTON      "Omrežje ...", psh5, 284,156,48,14 */
 
     GROUPBOX        "Tiskalnik",        grp4,   8,  4, 272,84, WS_GROUP
     PUSHBUTTON      "&Lastnosti",    psh2, 212, 17,  60,14, WS_GROUP
@@ -324,7 +324,7 @@ BEGIN
   EDITTEXT edt7, 187, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
   DEFPUSHBUTTON "V redu", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON
   PUSHBUTTON "Prekliči", IDCANCEL, 126, 220, 50, 14
-  PUSHBUTTON "&Tiskalnik...", psh3, 184, 220, 48, 14
+  PUSHBUTTON "&Tiskalnik ...", psh3, 184, 220, 48, 14
 END
 
 NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164
index 77bcc00..0306974 100644 (file)
@@ -1,5 +1,9 @@
 /*
+ * comdlg32 (Traditional Chinese Resource)
+ *
  * Copyright 2000 Aric Stewart
+ * Copyright 2002 Tisheng Chen
+ * Copyright 2008 Hongbo Ni <hongbo.at.njstar.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES.
  */
 
+/* Chinese text is encoded in UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+
+OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "打开"
+FONT 9, "MS Shell Dlg"
+{
+ LTEXT "文件名(&N):", 1090, 6, 6, 76, 9
+ EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "文件夹(&D):", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "文件类型(&T):", 1089, 6, 104, 90, 9
+ COMBOBOX cmb1, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "驱动器(&v):", 1091, 110, 104, 92, 9
+ COMBOBOX cmb2, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "打开", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "帮助(&H)", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "只读(&R)", chx1, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "另存为..."
+FONT 9, "MS Shell Dlg"
+{
+ LTEXT "文件名(&N):", 1090, 6, 6, 76, 9
+ EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "目录(&D):", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "文件类型(&T):", 1089, 6, 104, 90, 9
+ COMBOBOX cmb1, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "驱动器(&v):", 1091, 110, 104, 92, 9
+ COMBOBOX cmb2, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "保存", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "帮助(&H)", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "只读(&R)", chx1, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "打印"
+FONT 9, "MS Shell Dlg"
+{
+ LTEXT "打印机:", 1088, 6, 6, 40, 9
+ LTEXT "", 1089, 60, 6, 150, 9
+ GROUPBOX "打印范围", grp1, 6, 30, 160, 65, BS_GROUPBOX
+ RADIOBUTTON "全部(&A)", rad1, 16, 45, 60, 12
+ RADIOBUTTON "选择的范围(&e)", rad2, 16, 60, 60, 12
+ RADIOBUTTON "页数(&G)", rad3, 16, 75, 60, 12
+ DEFPUSHBUTTON "确定", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "设置(&S)", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "从(&F):", 1090, 60, 80, 30, 9
+ LTEXT "到(&T):", 1091, 120, 80, 30, 9
+ LTEXT "打印质量(&Q):", 1092, 6, 100, 76, 9
+ COMBOBOX cmb1, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ CHECKBOX "打印到文件(&l):", chx1, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "压小", chx2, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "打印设置"
+FONT 9, "MS Shell Dlg"
+{
+ GROUPBOX "打印机", grp1, 6, 10, 180, 65, BS_GROUPBOX
+ RADIOBUTTON "默认打印机(&D)", rad1, 16, 20, 80, 12
+ LTEXT "[无]", 1088, 35, 35, 120, 9
+ RADIOBUTTON "指定的打印机(&P)", rad2, 16, 50, 80, 12
+ COMBOBOX cmb1, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "确定", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "设置(&S)", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ GROUPBOX "方向(&O)", grp2, 6, 85, 100, 50, BS_GROUPBOX
+ RADIOBUTTON "纵向(&P)", rad3, 50, 100, 40, 12
+ RADIOBUTTON "横向(&L)", rad4, 50, 115, 40, 12
+ ICON "LANDSCAP", stc10, 10, 95, 32, 32
+ ICON "PORTRAIT", stc11, 10, 95, 32, 32
+ GROUPBOX "纸张", grp3, 120, 85, 180, 50, BS_GROUPBOX
+ LTEXT "纸张大小(&Z)", 1089, 130, 95, 30, 9
+ LTEXT "纸张来源(&S)", 1090, 130, 110, 30, 9
+ COMBOBOX cmb2, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX cmb3, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+}
+
+
+CHOOSE_FONT DIALOG DISCARDABLE  13, 54, 264, 147
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "字体"
+FONT 9, "MS Shell Dlg"
+{
+    LTEXT           "字体(&F):",1088 ,6,3,40,9
+    COMBOBOX        cmb1, 6,13,94,54,  CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "字体样式(&y):",1089 ,108,3,44,9
+    COMBOBOX        cmb2,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "大小(&S):",1090,179,3,30,9
+    COMBOBOX        cmb3,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT
+    DEFPUSHBUTTON   "确定",IDOK,218,6,40,14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+    PUSHBUTTON      "取消",IDCANCEL,218,23,40,14,WS_GROUP | WS_TABSTOP
+    PUSHBUTTON      "应用(&A)", psh3,218,40,40,14,WS_GROUP | WS_TABSTOP
+    PUSHBUTTON      "帮助(&H)" , pshHelp,218,57,40,14,WS_GROUP | WS_TABSTOP
+    GROUPBOX        "效果",1072,6,72,84,34,WS_GROUP
+    CHECKBOX       "删除线(&k)", chx1, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX       "下划线(&U)", chx2, 10,94,50,10, BS_AUTOCHECKBOX
+    LTEXT           "颜色(&C):", 1091 ,6,110,30,9
+    COMBOBOX        cmb4,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS |
+                   CBS_AUTOHSCROLL |  WS_BORDER | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "示例",grp2,98,72,120,36,WS_GROUP
+    CTEXT           "中文字体AaBbYyZz",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE
+    LTEXT           "语言(&i):",stc7,98,114,80,9
+    COMBOBOX        cmb5,98,124,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+                   CBS_AUTOHSCROLL |   WS_VSCROLL | WS_TABSTOP
+}
+
+
+CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 185
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "颜色"
+FONT 9, "MS Shell Dlg"
+{
+ LTEXT "基本颜色(&B):",   1088, 4,    4,  140, 10
+ LTEXT "自定制颜色(&C):",  1089, 4,   106, 140, 10
+ LTEXT "颜色|纯色(&O)",  1090, 150, 151,  48, 10
+ LTEXT   "红(&R):", 726 /*1094*/,249,126,24,10
+ EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT   "绿(&G):",727/*1095*/,249,140,24,10
+ EDITTEXT 707, 275,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT   "蓝(&B):",728 /*1096*/,249,154,24,10
+ EDITTEXT 708, 275,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "色调(&E):" ,723 /*1091*/,202,126,22,10
+ EDITTEXT 703, 226,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "饱和度(&S):" ,724 /*1092*/,202,140,22,10
+ EDITTEXT 704, 226,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "亮度(&L)" ,725 /*1093*/,202,154,22,10
+ EDITTEXT 705, 226,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86
+ CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28
+ CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116
+ CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
+ CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
+ DEFPUSHBUTTON "确定",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "帮助", pshHelp,100,166, 44, 14
+ PUSHBUTTON "添加到自定义颜色(&A)", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "规定自定义颜色(&D)>>", 719/*1025*/,   4, 150, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON  "&i",713,300,200,4,14   /* just a dummy:  'i' is  like  &i  in "sol&id"  */
+}
+
+
+FINDDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "查找"
+FONT 9, "MS Shell Dlg"
+{
+ LTEXT "查找(&n):", -1, 4, 8, 42, 8
+ EDITTEXT edt1, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "全字匹配(&W)", chx1, 4, 26, 64, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "区分大小写(&C)", chx2, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ GROUPBOX "方向", 1072, 78, 28, 97, 28
+ CONTROL "向上(&U)", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 83, 40, 42, 12
+ CONTROL "向下(&D)", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 128, 40, 42, 12
+
+ DEFPUSHBUTTON "找下一个(&F)", IDOK, 182,  5, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "取消", IDCANCEL  , 182, 23, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "帮助(&H)", pshHelp       , 182, 45, 50, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+REPLACEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "替换"
+FONT 9, "MS Shell Dlg"
+{
+ LTEXT "查找(&n):", -1, 4, 9, 48, 8
+ EDITTEXT edt1, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT "替换为(&p):", -1, 4, 26, 48, 8
+ EDITTEXT edt2, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "全字匹配(&W)", chx1, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "区分大小写(&C)", chx2, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+
+ DEFPUSHBUTTON "找下一个(&F)", IDOK, 174,  4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "替换(&R)", psh1  , 174, 21, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "全部替换(&A)", psh2 , 174, 38, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", IDCANCEL  , 174, 55, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "帮助(&H)", pshHelp       , 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT32 DIALOG LOADONCALL MOVEABLE DISCARDABLE  32, 32, 288, 186
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
+      DS_CONTEXTHELP | DS_3DLOOK
+CAPTION "打印"
+FONT 9, "MS Shell Dlg"
+{
+    DEFPUSHBUTTON   "确定",     IDOK,     180,164, 48,14, WS_GROUP | BS_DEFPUSHBUTTON
+    PUSHBUTTON      "取消", IDCANCEL, 232,164, 48,14, WS_GROUP
+    PUSHBUTTON      "帮助(&H)",  pshHelp,  50, 161, 48,14, WS_GROUP
+
+    GROUPBOX        "打印机",        grp4,   8,  4, 272,84, WS_GROUP
+    CONTROL         "打印到文件(&l)", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,64,12
+    PUSHBUTTON      "属性(&P)",    psh2, 212, 17,  60,14, WS_GROUP
+    LTEXT           "名称(&N):",         stc6,  16, 20,  36,8
+    COMBOBOX                          cmb4,  52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
+    LTEXT           "状态:",        stc8,  16, 36,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy State",    stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+    LTEXT           "型号:",          stc7,  16, 48,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy Type",     stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+    LTEXT           "位置:",         stc10, 16, 60,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy Location", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+    LTEXT           "备注:",       stc9,  16, 72,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy Remark",   stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+
+    GROUPBOX        "份数",         grp2, 160, 92, 120,64, WS_GROUP
+    LTEXT           "份数(&C):",stc5,168,108,68,8
+    ICON            "",               ico3, 162,124,  76,24, WS_GROUP | SS_CENTERIMAGE
+    CONTROL         "自动分页(&o)",   chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,36,12
+    EDITTEXT                          edt3, 240,106,  32,12, WS_GROUP | ES_NUMBER
+
+    GROUPBOX        "打印范围",    grp1,   8,92,  144,64, WS_GROUP
+    CONTROL         "全部(&A)",           rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12
+    CONTROL         "页数(&G)",         rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12
+    CONTROL         "选择的范围(&S)",     rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12
+    EDITTEXT                          edt1,  74,122,  26,12, WS_GROUP | ES_NUMBER
+    EDITTEXT                          edt2, 118,122,  26,12, WS_GROUP | ES_NUMBER
+    RTEXT           "从(&f):",         stc2,  52,124,  20,8
+    RTEXT           "到(&t):",           stc3, 100,124,  16,8
+}
+
+PRINT32_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE  32, 32, 288, 178
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
+      DS_CONTEXTHELP | DS_3DLOOK
+CAPTION "打印设置"
+FONT 9, "MS Shell Dlg"
+BEGIN
+    DEFPUSHBUTTON   "确定",IDOK,180,156,48,14,WS_GROUP
+    PUSHBUTTON      "取消",IDCANCEL,232,156,48,14
+/*    PUSHBUTTON      "Network...", psh5, 284,156,48,14 */
+
+    GROUPBOX        "打印机",        grp4,   8,  4, 272,84, WS_GROUP
+    PUSHBUTTON      "属性(&P)",    psh2, 212, 17,  60,14, WS_GROUP
+    LTEXT           "名称(&N):",         stc6,  16, 20,  36,8
+    COMBOBOX                          cmb1,  52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
+    LTEXT           "状态:",        stc8,  16, 36,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy State",    stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+    LTEXT           "型号:",          stc7,  16, 48,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy Type",     stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+    LTEXT           "位置:",         stc10, 16, 60,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy Location", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+    LTEXT           "备注:",       stc9,  16, 72,  36,10, SS_NOPREFIX
+    LTEXT           "Dummy Remark",   stc13, 52, 72, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP
+
+    GROUPBOX        "纸张",          grp2,   8, 92, 164,56, WS_GROUP
+    LTEXT           "纸张大小(&z):",         stc2,  16,108,  36, 8
+    COMBOBOX                          cmb2,  52,106, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
+    LTEXT           "纸张来源(&S):",       stc3,  16,128,  36, 8
+    COMBOBOX                          cmb3,  52,126, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP
+
+    GROUPBOX        "方向",    grp1, 180, 92, 100,56, WS_GROUP
+    ICON            "",               ico1, 195,112,  18,20, WS_GROUP
+    CONTROL         "纵向(&P)",      rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |WS_TABSTOP,224,106,52,12
+    CONTROL         "横向(&L)",     rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12
+END
+
+PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 240, 240
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "页面设置"
+FONT 9, "MS Shell Dlg"
+BEGIN
+  CONTROL "", rct1, "Static", SS_WHITERECT, 80, 8, 80, 80
+  CONTROL "", rct2, "Static", SS_GRAYRECT, 160, 12, 4, 80
+  CONTROL "", rct3, "Static", SS_GRAYRECT,  84, 88, 80, 4
+  GROUPBOX "纸张", grp2, 8, 96, 224, 56, BS_GROUPBOX
+  LTEXT "大小(&S):", stc2, 16, 112, 36, 8
+  COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL
+  LTEXT "来源(&S):", stc3, 16, 132, 36, 8
+  COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL
+  GROUPBOX "方向(&O)", grp1, 8, 156, 64, 56, BS_GROUPBOX
+  AUTORADIOBUTTON "纵向(&P)", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON
+  AUTORADIOBUTTON "横向(&L)", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON
+  GROUPBOX "边距", grp4, 80, 156, 152, 56, BS_GROUPBOX
+  LTEXT "左(&e):", stc15, 88, 172, 21, 8
+  EDITTEXT edt4, 111, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  LTEXT "右(&R):", stc16, 159, 172, 27, 8
+  EDITTEXT edt6, 187, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  LTEXT "上(&o):", stc17, 88, 192, 21, 8
+  EDITTEXT edt5, 111, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  LTEXT "下(&B):", stc18, 159, 192, 23, 8
+  EDITTEXT edt7, 187, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER
+  DEFPUSHBUTTON "确定", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON
+  PUSHBUTTON "取消", IDCANCEL, 126, 220, 50, 14
+  PUSHBUTTON "打印机(&P)...", psh3, 184, 220, 48, 14
+END
+
+NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164
+STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN
+CAPTION "打开"
+FONT 9, "MS Shell Dlg"
+{
+    LTEXT      "搜寻(&I)",IDC_LOOKINSTATIC,4,6,43,8, SS_NOTIFY
+    COMBOBOX   IDC_LOOKIN,49,3,132,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+
+    LTEXT      "" , IDC_TOOLBARSTATIC, 181, 2, 102, 17, NOT WS_GROUP | NOT WS_VISIBLE
+    LISTBOX    IDC_SHELLSTATIC,4,20,272,85, LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_HSCROLL | NOT WS_VISIBLE
+
+    LTEXT      "文件名(&N):",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY
+    EDITTEXT   IDC_FILENAME,54,110,155,12,ES_AUTOHSCROLL
+
+    LTEXT      "文件类型(&t)",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY
+    COMBOBOX   IDC_FILETYPE,54,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+    CONTROL    "只读(&r)",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10
+
+    DEFPUSHBUTTON      "打开(&O)",            IDOK,222,110,50,14
+    PUSHBUTTON         "取消",                IDCANCEL,222,128,50,14
+    PUSHBUTTON         "帮助(&H)",            pshHelp,222,145,50,14
+}
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_ABOUTBOX            "关于文件夹选择器(&A)"
+    IDS_DOCUMENTFOLDERS     "文档目录"
+    IDS_PERSONAL            "我的文档"
+    IDS_FAVORITES           "收藏夹"
+    IDS_PATH                "系统路径"
+    IDS_DESKTOP             "桌面"
+    IDS_FONTS               "字体"
+    IDS_MYCOMPUTER          "我的电脑"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_SYSTEMFOLDERS       "系统文件夹"
+    IDS_LOCALHARDRIVES      "本地硬盘驱动器"
+    IDS_FILENOTFOUND        "找不到文件"
+    IDS_VERIFYFILE          "请检验是否给予正确的文件名称。"
+    IDS_CREATEFILE          "找不到文件\n是否创建新文件?"
+    IDS_OVERWRITEFILE       "文件已经存在。\n要替换吗?"
+    IDS_INVALID_FILENAME_TITLE "文件名中存在无效的字符"
+    IDS_INVALID_FILENAME    "文件名中不能包含任何一下字符::\n                          / : < > |"
+    IDS_PATHNOTEXISTING     "文件夹不存在"
+    IDS_FILENOTEXISTING     "文件不存在"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_UPFOLDER         "向上移一层"
+    IDS_NEWFOLDER        "新建文件夹"
+    IDS_LISTVIEW         "列表"
+    IDS_REPORTVIEW       "详细资料"
+    IDS_TODESKTOP        "查看桌面"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    PD32_PRINT_TITLE       "打印"
+
+    PD32_VALUE_UREADABLE                  "数值不可读"
+    PD32_INVALID_PAGE_RANGE               "这个值不在页数范围。\n \
+请输入一个 %d 和 %d 之间的数。"
+    PD32_FROM_NOT_ABOVE_TO                "'从'项的值不能大于'到'项的值。"
+    PD32_MARGINS_OVERLAP                  "页边距重迭或落于纸外,\n请重新输入页边距。"
+    PD32_NR_OF_COPIES_EMPTY               "'份数' 项不能空."
+    PD32_TOO_LARGE_COPIES                 "你的打印机不支持这么大的份数。\n \
+请输入一个 1 和 %d 之间的数。"
+    PD32_PRINT_ERROR                      "打印机错误。"
+    PD32_NO_DEFAULT_PRINTER               "没有默认打印机。"
+    PD32_CANT_FIND_PRINTER                "找不到打印机。"
+    PD32_OUT_OF_MEMORY                    "内存不够。"
+    PD32_GENERIC_ERROR                    "出现一些错误。"
+    PD32_DRIVER_UNKNOWN                   "找不到打印机驱动器。"
+    PD32_NO_DEVICES                       "在使用与打印机有关功能(页面设置, 打印文件)之前, \
+你必须先装打印机。请装一个打印机再试。"
+
+    PD32_DEFAULT_PRINTER                  "默认打印机; "
+    PD32_NR_OF_DOCUMENTS_IN_QUEUE         "有 %d 个文档正在等待打印"
+    PD32_MARGINS_IN_INCHES                "页边距 [英寸]"
+    PD32_MARGINS_IN_MILIMETERS            "页边距 [毫米]"
+    PD32_MILIMETERS                       "毫米"
+
+    PD32_PRINTER_STATUS_READY             "待命"
+    PD32_PRINTER_STATUS_PAUSED            "暂停; "
+    PD32_PRINTER_STATUS_ERROR             "错误; "
+    PD32_PRINTER_STATUS_PENDING_DELETION  "等待删除; "
+    PD32_PRINTER_STATUS_PAPER_JAM         "卡纸; "
+    PD32_PRINTER_STATUS_PAPER_OUT         "无纸; "
+    PD32_PRINTER_STATUS_MANUAL_FEED       "手动进纸; "
+    PD32_PRINTER_STATUS_PAPER_PROBLEM     "纸的问题; "
+    PD32_PRINTER_STATUS_OFFLINE           "打印机离线; "
+    PD32_PRINTER_STATUS_IO_ACTIVE         "I/O 活动; "
+    PD32_PRINTER_STATUS_BUSY              "繁忙; "
+    PD32_PRINTER_STATUS_PRINTING          "正在打印; "
+    PD32_PRINTER_STATUS_OUTPUT_BIN_FULL   "出纸托盘已满; "
+    PD32_PRINTER_STATUS_NOT_AVAILABLE     "不可用; "
+    PD32_PRINTER_STATUS_WAITING           "等待; "
+    PD32_PRINTER_STATUS_PROCESSING        "正在处理; "
+    PD32_PRINTER_STATUS_INITIALIZING      "正在启动; "
+    PD32_PRINTER_STATUS_WARMING_UP        "预热; "
+    PD32_PRINTER_STATUS_TONER_LOW         "墨低; "
+    PD32_PRINTER_STATUS_NO_TONER          "没墨; "
+    PD32_PRINTER_STATUS_PAGE_PUNT         "页内存超支; "
+    PD32_PRINTER_STATUS_USER_INTERVENTION "用户干预; "
+    PD32_PRINTER_STATUS_OUT_OF_MEMORY     "内存不够; "
+    PD32_PRINTER_STATUS_DOOR_OPEN         "打印机盖是打开的; "
+    PD32_PRINTER_STATUS_SERVER_UNKNOWN    "找不到打印服务器; "
+    PD32_PRINTER_STATUS_POWER_SAVE        "省电状态; "
+}
+
+
 LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
-#pragma code_page(936)  /* FIXME: default for CHINESE_TRADITIONAL is 950 */
 
 OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "é_\86¢"
-FONT 8, "MS Shell Dlg"
+CAPTION "é\96\8bå\95\9f"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\99n°¸Ãû·Q(&N):", 1090, 6, 6, 100, 9
+ LTEXT "檔案名稱(&N):", 1090, 6, 6, 100, 9
  EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
  LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "Ä¿ä\9b(&D):", -1, 110, 6, 92, 9
+ LTEXT "目錄(&D):", -1, 110, 6, 92, 9
  LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
  LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "\99n°¸î\90ÐÍ(&T):", 1089, 6, 104, 90, 9
+ LTEXT "檔案類型(&T):", 1089, 6, 104, 90, 9
  COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- LTEXT "´Åµú\99C(&V):", 1091, 110, 104, 92, 9
+ LTEXT "磁碟機(&V):", 1091, 110, 104, 92, 9
  COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- DEFPUSHBUTTON "é_\86¢", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "È¡Ïû", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÇóÖú(&H)", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
- CHECKBOX "Ψ×x(&R)", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "é\96\8bå\95\9f", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "求助(&H)", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "唯讀(&R)", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
 }
 
 
 SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Áí´æÐÂ\99n..."
-FONT 8, "MS Shell Dlg"
+CAPTION "另存新檔..."
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\99n°¸Ãû·Q(&N):", 1090, 6, 6, 76, 9
+ LTEXT "檔案名稱(&N):", 1090, 6, 6, 76, 9
  EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
  LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "Ä¿ä\9b(&D):", -1, 110, 6, 92, 9
+ LTEXT "目錄(&D):", -1, 110, 6, 92, 9
  LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
  LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
- LTEXT "´æ\99\90ÐÍ(&T):", 1089, 6, 104, 90, 9
+ LTEXT "存檔類型(&T):", 1089, 6, 104, 90, 9
  COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- LTEXT "´Åµú\99C(&V):", 1091, 110, 104, 92, 9
+ LTEXT "磁碟機(&V):", 1091, 110, 104, 92, 9
  COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- DEFPUSHBUTTON "Áí´æÐÂ\99n", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "È¡Ïû", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÇóÖú(&H)", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
- CHECKBOX "Ψ×x(&R)", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "另存新檔", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "求助(&H)", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "唯讀(&R)", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
 }
 
 CHOOSE_FONT DIALOG DISCARDABLE  13, 54, 294, 147
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "×ÖÐÍ"
-FONT 8, "MS Shell Dlg"
+CAPTION "字型"
+FONT 9, "MS Shell Dlg"
 {
-    LTEXT           "×ÖÐÍ(&F):",1088 ,6,3,40,9
+    LTEXT           "字型(&F):",1088 ,6,3,40,9
     COMBOBOX        1136 ,6,13,124,54,  CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
                     CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
-    LTEXT           "×ÖÐÍ\98Óʽ(&Y):",1089 ,138,3,44,9
+    LTEXT           "字型樣式(&Y):",1089 ,138,3,44,9
     COMBOBOX        1137,138,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
                     WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
-    LTEXT           "´óС(&S):",1090,209,3,30,9
+    LTEXT           "大小(&S):",1090,209,3,30,9
     COMBOBOX        1138,209,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
                     WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT
-    DEFPUSHBUTTON   "´_¶¨",IDOK,248,6,40,14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
-    PUSHBUTTON      "È¡Ïû",IDCANCEL,248,23,40,14,WS_GROUP | WS_TABSTOP
-    PUSHBUTTON      "Ì×ÓÃ(&A)", 1026,248,40,40,14,WS_GROUP | WS_TABSTOP
-    PUSHBUTTON      "ÇóÖú(&H)" , 1038,248,57,40,14,WS_GROUP | WS_TABSTOP
-    GROUPBOX        "Ч¹û",1072,6,72,84,34,WS_GROUP
-    CHECKBOX       "\84h³ý¾\80(&K)", 1040, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
-    CHECKBOX       "µ×¾\80(&U)", 1041, 10,94,50,10, BS_AUTOCHECKBOX
-    LTEXT           "É«²Ê(&C):", 1091 ,6,110,30,9
+    DEFPUSHBUTTON   "確定",IDOK,248,6,40,14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+    PUSHBUTTON      "取消",IDCANCEL,248,23,40,14,WS_GROUP | WS_TABSTOP
+    PUSHBUTTON      "套用(&A)", 1026,248,40,40,14,WS_GROUP | WS_TABSTOP
+    PUSHBUTTON      "求助(&H)" , 1038,248,57,40,14,WS_GROUP | WS_TABSTOP
+    GROUPBOX        "效果",1072,6,72,84,34,WS_GROUP
+    CHECKBOX       "刪除線(&K)", 1040, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX       "底線(&U)", 1041, 10,94,50,10, BS_AUTOCHECKBOX
+    LTEXT           "色彩(&C):", 1091 ,6,110,30,9
     COMBOBOX        1139,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS |
                    CBS_AUTOHSCROLL |  WS_BORDER | WS_VSCROLL | WS_TABSTOP
-    GROUPBOX        "¹ Àý",grp2,98,72,120,36,WS_GROUP
+    GROUPBOX        "範例",grp2,98,72,120,36,WS_GROUP
     CTEXT           "AaBbYyZz",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE
-    LTEXT           "Scr&ipt (translate):",stc7 ,98,114,80,9
+    LTEXT           "语言:",stc7 ,98,114,80,9
     COMBOBOX        cmb5,98,124,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS |
                    CBS_AUTOHSCROLL |   WS_VSCROLL | WS_TABSTOP
 }
@@ -100,133 +526,188 @@ FONT 8, "MS Shell Dlg"
 
 CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 185
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "É«²Ê"
-FONT 8, "MS Shell Dlg"
+CAPTION "色彩"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "»ù±¾É«²Ê(&B):",   1088, 4,    4,  140, 10
- LTEXT "×Ô¶¨É«²Ê(&C):",  1089, 4,   106, 140, 10
- LTEXT "É«²Ê | \8c\8dÐÄ(&I)",  1090, 150, 151,  48, 10
- LTEXT   "¼t(&R):", 726 /*1094*/,249,126,24,10
+ LTEXT "基本色彩(&B):",   1088, 4,    4,  140, 10
+ LTEXT "自定色彩(&C):",  1089, 4,   106, 140, 10
+ LTEXT "色彩 | 實心(&I)",  1090, 150, 151,  48, 10
+ LTEXT   "(&R):", 726 /*1094*/,249,126,24,10
  EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT   "¾G(&G):",727/*1095*/,249,140,24,10
+ LTEXT   "(&G):",727/*1095*/,249,140,24,10
  EDITTEXT 707, 275,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT   "Ë{(&B):",728 /*1096*/,249,154,24,10
+ LTEXT   "(&B):",728 /*1096*/,249,154,24,10
  EDITTEXT 708, 275,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT  "É«Õ{(&H):" ,723 /*1091*/,202,126,22,10
+ LTEXT  "色調(&H):" ,723 /*1091*/,202,126,22,10
  EDITTEXT 703, 226,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT  "\9dâ¶È(&S):" ,724 /*1092*/,202,140,22,10
+ LTEXT  "濃度(&S):" ,724 /*1092*/,202,140,22,10
  EDITTEXT 704, 226,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT  "ÁÁ¶È(&L):" ,725 /*1093*/,202,154,22,10
+ LTEXT  "亮度(&L):" ,725 /*1093*/,202,154,22,10
  EDITTEXT 705, 226,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP
  CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86
  CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28
  CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116
  CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
  CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
- DEFPUSHBUTTON "´_¶¨",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "È¡Ïû", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÇóÖú(&H)", 1038,100,166, 44, 14
- PUSHBUTTON "ÐÂÔö×Ô¶¨É«²Ê(&A)",    712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "¶¨Áx×Ô¶¨É«²Ê(&D) >>", 719/*1025*/,   4, 150, 142, 14, WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "確定",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "求助(&H)", 1038,100,166, 44, 14
+ PUSHBUTTON "新增自定色彩(&A)",    712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "定義自定色彩(&D) >>", 719/*1025*/,   4, 150, 142, 14, WS_GROUP | WS_TABSTOP
  PUSHBUTTON  "&i",713,300,200,4,14   /* just a dummy:  'i' is  like  &i  in "sol&id"  */
 }
 
 
 FINDDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 263, 62
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "ËÑ\8c¤"
-FONT 8, "MS Shell Dlg"
+CAPTION "搜尋"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "ËÑ\8c¤Ä¿\98Ë(&N):", -1, 4, 8, 50, 8
+ LTEXT "搜尋目標(&N):", -1, 4, 8, 50, 8
  EDITTEXT 1152, 61, 7, 130, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
- CHECKBOX "È«×ÖÆ´\8c\91í\9a·ûºÏ(&W)", 1040, 4, 26, 89, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- CHECKBOX "´óС\8c\91Ò\95\9eéÏà®\90(&C)", 1041, 4, 42, 89, 12, BS_AUTOCHECKBOX | WS_TABSTOP
- GROUPBOX "·½Ïò", 1072, 95, 26, 97, 28
- CONTROL "ÏòÉÏ(&U)", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 100, 38, 45, 12
- CONTROL "ÏòÏÂ(&D)", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 145, 38, 45, 12
+ CHECKBOX "全字拼寫須符合(&W)", 1040, 4, 26, 89, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "大小寫視為相異(&C)", 1041, 4, 42, 89, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ GROUPBOX "方向", 1072, 95, 26, 97, 28
+ CONTROL "向上(&U)", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 100, 38, 45, 12
+ CONTROL "向下(&D)", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 145, 38, 45, 12
 
- DEFPUSHBUTTON "ÕÒÏÂÒ»\82\80(&F)", IDOK, 199,  5, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
- PUSHBUTTON "È¡Ïû", IDCANCEL    , 199, 23, 60, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÇóÖú(&H)", pshHelp         , 199, 45, 60, 14, WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "找下一個(&F)", IDOK, 199,  5, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "取消", IDCANCEL  , 199, 23, 60, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "求助(&H)", pshHelp       , 199, 45, 60, 14, WS_GROUP | WS_TABSTOP
 }
 
 
 REPLACEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 263, 94
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "È¡´ú"
-FONT 8, "MS Shell Dlg"
+CAPTION "取代"
+FONT 9, "MS Shell Dlg"
 {
- LTEXT "\8c¤ÕÒÄ¿\98Ë(&N):", -1, 4, 9, 50, 8
+ LTEXT "尋找目標(&N):", -1, 4, 9, 50, 8
  EDITTEXT 1152, 61, 7, 130, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
- LTEXT "È¡´ú\9eé(&P):", -1, 4, 26, 50, 8
+ LTEXT "取代為(&P):", -1, 4, 26, 50, 8
  EDITTEXT 1153, 61, 24, 130, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
- CHECKBOX "È«×ÖÆ´\8c\91í\9a·ûºÏ(&W)", 1040, 5, 46, 89, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- CHECKBOX "´óС\8c\91Ò\95\9eéÏë®\90(&C)", 1041, 5, 62, 89, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ CHECKBOX "全字拼寫須符合(&W)", 1040, 5, 46, 89, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "大小寫視為相異(&C)", 1041, 5, 62, 89, 12, BS_AUTOCHECKBOX | WS_TABSTOP
 
- DEFPUSHBUTTON "ÕÒÏÂÒ»\82\80(&F)", IDOK, 199,  4, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
- PUSHBUTTON "È¡´ú(&R)", psh1    , 199, 21, 60, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "È¡´úÈ«²¿(&A)", psh2 , 199, 38, 60, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "È¡Ïû", IDCANCEL    , 199, 55, 60, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "ÇóÖú(&H)", pshHelp         , 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "找下一個(&F)", IDOK, 199,  4, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "取代(&R)", psh1  , 199, 21, 60, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取代全部(&A)", psh2 , 199, 38, 60, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "取消", IDCANCEL  , 199, 55, 60, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "求助(&H)", pshHelp       , 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
 }
 
 NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164
 STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN
-CAPTION "é_\86¢Åf\99n"
-FONT 8, "MS Shell Dlg"
+CAPTION "é\96\8bå\95\9fè\88\8aæª\94"
+FONT 9, "MS Shell Dlg"
 {
-    LTEXT      "ËÑ\8c¤Î»ÖÃ(&I)",IDC_LOOKINSTATIC,4,6,43,8, SS_NOTIFY
+    LTEXT      "搜尋位置(&I)",IDC_LOOKINSTATIC,4,6,43,8, SS_NOTIFY
     COMBOBOX   IDC_LOOKIN,52,3,130,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
 
     LTEXT      "" , IDC_TOOLBARSTATIC, 181, 2, 102, 17, NOT WS_GROUP | NOT WS_VISIBLE
     LISTBOX    IDC_SHELLSTATIC,4,20,272,85, LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_HSCROLL | NOT WS_VISIBLE
 
-    LTEXT      "\99n°¸Ãû·Q(&N):",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY
+    LTEXT      "檔案名稱(&N):",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY
     EDITTEXT   IDC_FILENAME,59,110,155,12,ES_AUTOHSCROLL
 
-    LTEXT      "\99n°¸î\90ÐÍ(&T):",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY
+    LTEXT      "檔案類型(&T):",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY
     COMBOBOX   IDC_FILETYPE,59,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 
-    CONTROL    "é_\86¢³ÉΨ×x(&R)",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10
+    CONTROL    "é\96\8bå\95\9fæ\88\90å\94¯è®\80(&R)",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10
 
-    DEFPUSHBUTTON      "é_\86¢(&O)",              IDOK,222,110,50,14
-    PUSHBUTTON         "È¡Ïû",          IDCANCEL,222,128,50,14
-    PUSHBUTTON         "ÇóÖú(&H)",              pshHelp,222,145,50,14
+    DEFPUSHBUTTON      "é\96\8bå\95\9f(&O)",            IDOK,222,110,50,14
+    PUSHBUTTON         "取消",                IDCANCEL,222,128,50,14
+    PUSHBUTTON         "求助(&H)",            pshHelp,222,145,50,14
 }
 
 STRINGTABLE DISCARDABLE
 {
-    IDS_ABOUTBOX            "&About FolderPicker Test"
-    IDS_DOCUMENTFOLDERS     "Îļþ\8aA"
-    IDS_PERSONAL            "ÎÒµÄÎļþ"
-    IDS_FAVORITES           "ÎÒµÄ×î\90Û"
-    IDS_PATH                "ϵ½y·\8f½"
-    IDS_DESKTOP             "×ÀÃæ"
-    IDS_FONTS               "×ÖÐÍ"
-    IDS_MYCOMPUTER          "ÎÒµÄë\8aÄX"
+    IDS_ABOUTBOX            "关于資料夹选择器(&A)"
+    IDS_DOCUMENTFOLDERS     "資料夾"
+    IDS_PERSONAL            "我的檔案"
+    IDS_FAVORITES           "我的最愛"
+    IDS_PATH                "系統路徑"
+    IDS_DESKTOP             "桌面"
+    IDS_FONTS               "字型"
+    IDS_MYCOMPUTER          "我的電腦"
 }
 
 STRINGTABLE DISCARDABLE
 {
-    IDS_SYSTEMFOLDERS       "System Folders"
-    IDS_LOCALHARDRIVES      "Local Hard Drives"
-    IDS_FILENOTFOUND        "File not found"
-    IDS_VERIFYFILE          "Please verify if the correct file name was given"
-    IDS_CREATEFILE          "File does not exist\nDo you want to create file"
-    IDS_OVERWRITEFILE       "File does already exist.\nDo you want to replace it?"
-    IDS_INVALID_FILENAME_TITLE "Invalid character(s) in path"
-    IDS_INVALID_FILENAME    "A filename cannot contain any of the following characters:\n                          / : < > |"
-    IDS_PATHNOTEXISTING     "Path does not exist"
-    IDS_FILENOTEXISTING     "File does not exist"
+    IDS_SYSTEMFOLDERS       "系統資料夾"
+    IDS_LOCALHARDRIVES      "本地硬盤驅動器"
+    IDS_FILENOTFOUND        "找不到檔案"
+    IDS_VERIFYFILE          "請檢驗是否給予正確的檔案名稱。"
+    IDS_CREATEFILE          "找不到檔案\n是否創建新檔案?"
+    IDS_OVERWRITEFILE       "檔案已經存在。\n要替換嗎?"
+    IDS_INVALID_FILENAME_TITLE "檔案名中存在無效的字符"
+    IDS_INVALID_FILENAME    "檔案名中不能包含任何一下字符::\n                          / : < > |"
+    IDS_PATHNOTEXISTING     "資料夾不存在"
+    IDS_FILENOTEXISTING     "檔案不存在"
 }
 
 STRINGTABLE DISCARDABLE
 {
-    IDS_UPFOLDER         "ÏòÉÏÒ»\8cÓ"
-    IDS_NEWFOLDER        "½¨Á¢ÐÂÙYÁÏ\8aA"
-    IDS_LISTVIEW         "Çå\86Î"
-    IDS_REPORTVIEW       "Ô\94¼\9aÙYÁÏ"
-    IDS_TODESKTOP        "ï@ʾ×ÀÃæ"
+    IDS_UPFOLDER         "向上一層"
+    IDS_NEWFOLDER        "建立新資料夾"
+    IDS_LISTVIEW         "清單"
+    IDS_REPORTVIEW       "詳細資料"
+    IDS_TODESKTOP        "顯示桌面"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    PD32_PRINT_TITLE       "列印"
+
+    PD32_VALUE_UREADABLE                  "數值不可讀"
+    PD32_INVALID_PAGE_RANGE               "這個值不在頁數範圍。\n \
+請輸入一個 %d 和 %d 之間的數。"
+    PD32_FROM_NOT_ABOVE_TO                "'從'項的值不能大於'到'項的值。"
+    PD32_MARGINS_OVERLAP                  "邊緣空白重迭或落於紙外,\n請重新輸入邊緣空白。"
+    PD32_NR_OF_COPIES_EMPTY               "'份數' 項不能空."
+    PD32_TOO_LARGE_COPIES                 "你的印表機不支持這麼大的份數。\n \
+請輸入一個 1 和 %d 之間的數。"
+    PD32_PRINT_ERROR                      "印表機錯誤。"
+    PD32_NO_DEFAULT_PRINTER               "沒有默認印表機。"
+    PD32_CANT_FIND_PRINTER                "找不到印表機。"
+    PD32_OUT_OF_MEMORY                    "內存不夠。"
+    PD32_GENERIC_ERROR                    "出現一些錯誤。"
+    PD32_DRIVER_UNKNOWN                   "找不到印表機驅動器。"
+    PD32_NO_DEVICES                       "在使用與印表機有關功能(版面設定, 列印檔案)之前, \
+你必須先裝印表機。請裝一個印表機再試。"
+
+    PD32_DEFAULT_PRINTER                  "默認印表機; "
+    PD32_NR_OF_DOCUMENTS_IN_QUEUE         "有 %d 個文檔正在等待列印"
+    PD32_MARGINS_IN_INCHES                "邊緣空白 [英寸]"
+    PD32_MARGINS_IN_MILIMETERS            "邊緣空白 [毫米]"
+    PD32_MILIMETERS                       "毫米"
+
+    PD32_PRINTER_STATUS_READY             "待命"
+    PD32_PRINTER_STATUS_PAUSED            "暫停; "
+    PD32_PRINTER_STATUS_ERROR             "錯誤; "
+    PD32_PRINTER_STATUS_PENDING_DELETION  "等待刪除; "
+    PD32_PRINTER_STATUS_PAPER_JAM         "卡紙; "
+    PD32_PRINTER_STATUS_PAPER_OUT         "無紙; "
+    PD32_PRINTER_STATUS_MANUAL_FEED       "手動進紙; "
+    PD32_PRINTER_STATUS_PAPER_PROBLEM     "紙的問題; "
+    PD32_PRINTER_STATUS_OFFLINE           "印表機離線; "
+    PD32_PRINTER_STATUS_IO_ACTIVE         "I/O 活動; "
+    PD32_PRINTER_STATUS_BUSY              "繁忙; "
+    PD32_PRINTER_STATUS_PRINTING          "正在列印; "
+    PD32_PRINTER_STATUS_OUTPUT_BIN_FULL   "出紙托盤已滿; "
+    PD32_PRINTER_STATUS_NOT_AVAILABLE     "不可用; "
+    PD32_PRINTER_STATUS_WAITING           "等待; "
+    PD32_PRINTER_STATUS_PROCESSING        "正在處理; "
+    PD32_PRINTER_STATUS_INITIALIZING      "正在啓動; "
+    PD32_PRINTER_STATUS_WARMING_UP        "預熱; "
+    PD32_PRINTER_STATUS_TONER_LOW         "墨低; "
+    PD32_PRINTER_STATUS_NO_TONER          "沒墨; "
+    PD32_PRINTER_STATUS_PAGE_PUNT         "頁處理內存超支; "
+    PD32_PRINTER_STATUS_USER_INTERVENTION "用戶干預; "
+    PD32_PRINTER_STATUS_OUT_OF_MEMORY     "內存不夠; "
+    PD32_PRINTER_STATUS_DOOR_OPEN         "印表機蓋是打開的; "
+    PD32_PRINTER_STATUS_SERVER_UNKNOWN    "找不到列印服務器; "
+    PD32_PRINTER_STATUS_POWER_SAVE        "省電狀態; "
 }
 
 #pragma code_page(default)
index 1b4c0d5..d4a43af 100644 (file)
@@ -166,7 +166,7 @@ int CC_RGBtoHSL(char c, int r, int g, int b)
           else
           {
            result = mmdif * 240;       /* 0...61200=255*240 */
-           result /= (mmsum > 255 ? mmsum = 510 - mmsum : mmsum); /* 0..255 */
+           result /= (mmsum > 255 ? 510 - mmsum : mmsum); /* 0..255 */
           }
           break;
   /* hue */
@@ -463,7 +463,7 @@ void CC_PaintTriangle( HWND hDlg, int y)
  RECT rect;
  HBRUSH hbr;
  HWND hwnd = GetDlgItem(hDlg, 0x2be);
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
 
  if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6)))   /* if full size */
  {
@@ -509,7 +509,7 @@ void CC_PaintCross( HWND hDlg, int x, int y)
  int w = GetDialogBaseUnits() - 1;
  int wc = GetDialogBaseUnits() * 3 / 4;
  HWND hwnd = GetDlgItem(hDlg, 0x2c6);
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
  RECT rect;
  POINT point, p;
  HPEN hPen;
@@ -560,7 +560,7 @@ static void CC_PrepareColorGraph( HWND hDlg )
 {
  int sdif, hdif, xdif, ydif, r, g, b, hue, sat;
  HWND hwnd = GetDlgItem(hDlg, 0x2c6);
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
  HBRUSH hbrush;
  HDC hdc ;
  RECT rect, client;
@@ -603,7 +603,7 @@ static void CC_PrepareColorGraph( HWND hDlg )
 static void CC_PaintColorGraph( HWND hDlg )
 {
  HWND hwnd = GetDlgItem( hDlg, 0x2c6 );
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
  HDC  hDC;
  RECT rect;
  if (IsWindowVisible(hwnd))   /* if full size */
@@ -663,7 +663,7 @@ static void CC_PaintLumBar( HWND hDlg, int hue, int sat )
 void CC_EditSetRGB( HWND hDlg, COLORREF cr )
 {
  char buffer[10];
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
  int r = GetRValue(cr);
  int g = GetGValue(cr);
  int b = GetBValue(cr);
@@ -686,7 +686,7 @@ void CC_EditSetRGB( HWND hDlg, COLORREF cr )
 void CC_EditSetHSL( HWND hDlg, int h, int s, int l )
 {
  char buffer[10];
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
 
  if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6) ))   /* if full size */
  {
@@ -708,7 +708,7 @@ void CC_EditSetHSL( HWND hDlg, int h, int s, int l )
 void CC_SwitchToFullSize( HWND hDlg, COLORREF result, LPCRECT lprect )
 {
  int i;
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
 
  EnableWindow( GetDlgItem(hDlg, 0x2cf), FALSE);
  CC_PrepareColorGraph(hDlg);
@@ -744,7 +744,7 @@ static void CC_PaintPredefColorArray( HWND hDlg, int rows, int cols)
  HDC  hdc;
  HBRUSH hBrush;
  int dx, dy, i, j, k;
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
 
  GetClientRect(hwnd, &rect);
  dx = rect.right / cols;
@@ -791,7 +791,7 @@ void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, const COLORREF *lpcr
  HDC  hdc;
  HBRUSH hBrush;
  int dx, dy, i, j, k;
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
 
  GetClientRect(hwnd, &rect);
 
@@ -961,7 +961,8 @@ LRESULT CC_WMCommand( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode,
     UINT cokmsg;
     HDC hdc;
     COLORREF *cr;
-    LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+    LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
+
     TRACE("CC_WMCommand wParam=%lx lParam=%lx\n", wParam, lParam);
     switch (LOWORD(wParam))
     {
@@ -1083,7 +1084,7 @@ LRESULT CC_WMCommand( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode,
 LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam )
 {
     PAINTSTRUCT ps;
-    LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+    LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
 
     BeginPaint(hDlg, &ps);
     /* we have to paint dialog children except text and buttons */
@@ -1104,7 +1105,8 @@ LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam )
  */
 LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam )
 {
-   LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+   LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
+
    if (lpp->capturedGraph)
    {
        lpp->capturedGraph = 0;
@@ -1120,7 +1122,7 @@ LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam )
  */
 LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam )
 {
-   LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+   LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
    int r, g, b;
 
    if (lpp->capturedGraph)
@@ -1158,7 +1160,7 @@ LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam )
  */
 LRESULT CC_WMLButtonDown( HWND hDlg, WPARAM wParam, LPARAM lParam )
 {
-   LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+   LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
    int r, g, b, i;
    i = 0;
 
@@ -1217,7 +1219,8 @@ static INT_PTR CALLBACK ColorDlgProc( HWND hDlg, UINT message,
 {
 
  int res;
- LPCCPRIV lpp = (LPCCPRIV) GetPropW( hDlg, szColourDialogProp );
+ LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp );
+
  if (message != WM_INITDIALOG)
  {
   if (!lpp)
index bc7b51b..e1eedd1 100644 (file)
@@ -220,6 +220,8 @@ static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPWST
 IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
 LPITEMIDLIST  GetParentPidl(LPITEMIDLIST pidl);
 static LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPWSTR lpcstrFileName);
+static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl);
+static UINT GetNumSelected( IDataObject *doSelected );
 
 /* Shell memory allocation */
 static void *MemAlloc(UINT size);
@@ -240,7 +242,7 @@ static BOOL BrowseSelectedFolder(HWND hwnd);
  * OUT : TRUE on success
  *       FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
  */
-static BOOL WINAPI GetFileName95(FileOpenDlgInfos *fodInfos)
+static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
 {
 
     LRESULT lRes;
@@ -312,7 +314,7 @@ static BOOL WINAPI GetFileName95(FileOpenDlgInfos *fodInfos)
  * IN  : The OPENFILENAMEA initialisation structure passed to
  *       GetOpenFileNameA win api function (see filedlg.c)
  */
-BOOL  WINAPI GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
+static BOOL GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
 {
   BOOL ret;
   FileOpenDlgInfos fodInfos;
@@ -449,7 +451,7 @@ BOOL  WINAPI GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
  * Call GetFileName95 with this structure and clean the memory.
  *
  */
-BOOL  WINAPI GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
+static BOOL GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
 {
   BOOL ret;
   FileOpenDlgInfos fodInfos;
@@ -822,8 +824,7 @@ static HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos, HWND hwnd)
 LRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode)
 {
     LRESULT hook_result = 0;
-
-    FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndParentDlg,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = GetPropA(hwndParentDlg,FileOpenDlgInfosStr);
 
     TRACE("%p 0x%04x\n",hwndParentDlg, uCode);
 
@@ -862,7 +863,7 @@ static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result
 {
     UINT len, total;
     WCHAR *p, *buffer;
-    FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
     TRACE("CDM_GETFILEPATH:\n");
 
@@ -902,7 +903,7 @@ static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result
 */
 static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
     WCHAR lpstrPath[MAX_PATH];
     INT_PTR retval;
 
@@ -1107,7 +1108,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   TBADDBITMAP tba[2];
   RECT rectTB;
   RECT rectlook;
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   tba[0].hInst = HINST_COMMCTRL;
   tba[0].nID   = IDB_VIEW_SMALL_COLOR;
@@ -1164,7 +1165,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, 12, (LPARAM) &tba[0]);
   SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, 1, (LPARAM) &tba[1]);
 
-  SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) &tbb);
+  SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) tbb);
   SendMessageW(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0);
 
   /* Set the window text with the text specified in the OPENFILENAME structure */
@@ -1388,6 +1389,10 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
       LoadStringW(COMDLG32_hInstance, IDS_SAVE_IN, buf, sizeof(buf)/sizeof(WCHAR));
       SetDlgItemTextW(hwnd, IDC_LOOKINSTATIC, buf);
   }
+
+  /* Initialize the filter combo box */
+  FILEDLG95_FILETYPE_Init(hwnd);
+
   return 0;
 }
 
@@ -1476,9 +1481,6 @@ static LRESULT FILEDLG95_FillControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
   /* Initialize the Look In combo box */
   FILEDLG95_LOOKIN_Init(fodInfos->DlgInfos.hwndLookInCB);
 
-  /* Initialize the filter combo box */
-  FILEDLG95_FILETYPE_Init(hwnd);
-
   /* Browse to the initial directory */
   IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId, SBSP_ABSOLUTE);
 
@@ -1507,7 +1509,7 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   WORD wNotifyCode = HIWORD(wParam); /* notification code */
   WORD wID = LOWORD(wParam);         /* item, control, or accelerator identifier */
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   switch(wID)
   {
@@ -1567,8 +1569,7 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
  */
 static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
 {
-
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("\n");
 
@@ -1627,7 +1628,7 @@ BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCo
 {
   WCHAR   lpstrPathSpec[MAX_PATH] = {0};
   UINT   nCount, nSizePath;
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("\n");
 
@@ -1755,7 +1756,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
   WCHAR lpstrTemp[MAX_PATH];
   LPSHELLFOLDER lpsf = NULL;
   int nOpenAction;
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("hwnd=%p\n", hwnd);
 
@@ -2221,7 +2222,7 @@ ret:
  */
 static LRESULT FILEDLG95_SHELL_Init(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("\n");
 
@@ -2256,9 +2257,9 @@ static LRESULT FILEDLG95_SHELL_Init(HWND hwnd)
  */
 static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
-
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
   IContextMenu * pcm;
+
   TRACE("(%p,%p)\n", hwnd, lpVerb);
 
   if(SUCCEEDED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView,
@@ -2287,7 +2288,7 @@ static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
  */
 static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("\n");
 
@@ -2309,7 +2310,7 @@ static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
  */
 static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
   LPITEMIDLIST pidl;
   HRESULT hres;
 
@@ -2328,7 +2329,7 @@ static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd)
  */
 static void FILEDLG95_SHELL_Clean(HWND hwnd)
 {
-    FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
     TRACE("\n");
 
@@ -2353,7 +2354,7 @@ static void FILEDLG95_SHELL_Clean(HWND hwnd)
  */
 static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
   int nFilters = 0;  /* number of filters */
   int nFilterIndexCB;
 
@@ -2468,7 +2469,7 @@ static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
  */
 static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   switch(wNotifyCode)
   {
@@ -2534,7 +2535,7 @@ static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCWSTR lpstrExt)
  */
 static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
   int iPos;
   int iCount = CBGetCount(fodInfos->DlgInfos.hwndFileTypeCB);
 
@@ -2671,9 +2672,7 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
   int iIndentation;
   TEXTMETRICW tm;
   LPSFOLDER tmpFolder;
-
-
-  LookInInfos *liInfos = (LookInInfos *)GetPropA(pDIStruct->hwndItem,LookInInfosStr);
+  LookInInfos *liInfos = GetPropA(pDIStruct->hwndItem,LookInInfosStr);
 
   TRACE("\n");
 
@@ -2777,7 +2776,7 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
  */
 static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
 {
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("%p\n", fodInfos);
 
@@ -2827,7 +2826,7 @@ static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
   if(!pidl)
     return -1;
 
-  if(!(liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr)))
+  if(!(liInfos = GetPropA(hwnd,LookInInfosStr)))
     return -1;
 
   tmpFolder = MemAlloc(sizeof(SFOLDER));
@@ -2923,7 +2922,7 @@ int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl)
 
   iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidl,SEARCH_PIDL);
 
-  liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
+  liInfos = GetPropA(hwnd,LookInInfosStr);
 
   if(iItemPos < 0)
   {
@@ -2960,8 +2959,7 @@ int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl)
 static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd)
 {
   int iItemPos;
-
-  LookInInfos *liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
+  LookInInfos *liInfos = GetPropA(hwnd,LookInInfosStr);
 
   TRACE("\n");
 
@@ -3018,7 +3016,7 @@ static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMet
  */
 static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
 {
-    FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
     int iPos;
     int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB);
 
@@ -3054,7 +3052,7 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
     LPWSTR            lpstrAllFile, lpstrCurrFile;
 
     TRACE("\n");
-    fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+    fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
     /* Count how many files we have */
     nFileSelected = GetNumSelected( fodInfos->Shell.FOIDataObject );
@@ -3169,7 +3167,7 @@ static HRESULT COMDLG32_StrRetToStrNW (LPWSTR dest, DWORD len, LPSTRRET src, LPI
  */
 static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed)
 {
-       FileOpenDlgInfos *fodInfos  = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+       FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
        UINT nStrCharCount = 0; /* index in src buffer */
        UINT nFileIndex = 0;    /* index in dest buffer */
        UINT nFileCount = 0;    /* number of files */
@@ -3274,7 +3272,7 @@ LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex)
         return NULL;
        
     /* Set the FORMATETC structure*/
-    SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
+    SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLISTA), TYMED_HGLOBAL);
 
     /* Get the pidls from IDataObject */
     if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
@@ -3295,7 +3293,7 @@ LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex)
  * Return the number of selected items in the DataObject.
  *
 */
-UINT GetNumSelected( IDataObject *doSelected )
+static UINT GetNumSelected( IDataObject *doSelected )
 {
     UINT retVal = 0;
     STGMEDIUM medium;
@@ -3306,7 +3304,7 @@ UINT GetNumSelected( IDataObject *doSelected )
     if (!doSelected) return 0;
 
     /* Set the FORMATETC structure*/
-    SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
+    SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLISTA), TYMED_HGLOBAL);
 
     /* Get the pidls from IDataObject */
     if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
@@ -3434,7 +3432,7 @@ static LPITEMIDLIST GetPidlFromName(IShellFolder *lpsf,LPWSTR lpcstrFileName)
 
 /*
 */
-BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl)
+static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl)
 {
        ULONG uAttr  = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
        HRESULT ret;
@@ -3454,7 +3452,7 @@ BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl)
 static BOOL BrowseSelectedFolder(HWND hwnd)
 {
   BOOL bBrowseSelFolder = FALSE;
-  FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("\n");
 
index a722a2b..f8b5432 100644 (file)
@@ -44,7 +44,7 @@ typedef struct tagFD16_PRIVATE
 
 /************************************************************************
  *                              FD16_MapOfnStruct16          [internal]
- *      map a 16 bits structure to an Unicode one
+ *      map a 16 bits structure to a Unicode one
  */
 static void FD16_MapOfnStruct16(const OPENFILENAME16 *ofn16, LPOPENFILENAMEW ofnW, BOOL open)
 {
index c8fcf7e..6b2a379 100644 (file)
@@ -312,8 +312,10 @@ static void FD31_UpdateResult(const FD31_DATA *lfs, const WCHAR *tmpstr)
     if (lenstr2 > 3)
         tmpstr2[lenstr2++]='\\';
     lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2);
-    if (ofnW->lpstrFile)
-        lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile);
+    if (!ofnW->lpstrFile)
+        return;
+
+    lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile);
 
     /* set filename offset */
     p = PathFindFileNameW(ofnW->lpstrFile);
@@ -690,7 +692,7 @@ static LPWSTR FD31_DupToW(LPCSTR str, DWORD size)
 
 /************************************************************************
  *                              FD31_MapOfnStructA          [internal]
- *      map a 32 bits Ansi structure to an Unicode one
+ *      map a 32 bits Ansi structure to a Unicode one
  */
 void FD31_MapOfnStructA(const OPENFILENAMEA *ofnA, LPOPENFILENAMEW ofnW, BOOL open)
 {
index 2015a49..f933f15 100644 (file)
@@ -194,7 +194,7 @@ static HRESULT COMDLG32_StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPC
 IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
 {
     IShellBrowserImpl *sb;
-    FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndOwner,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = GetPropA(hwndOwner,FileOpenDlgInfosStr);
 
     sb=(IShellBrowserImpl*)COMDLG32_SHAlloc(sizeof(IShellBrowserImpl));
 
@@ -361,7 +361,7 @@ static HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
     TRACE("(%p)(pidl=%p,flags=0x%08x)\n", This, pidl, wFlags);
     COMDLG32_DumpSBSPFlags(wFlags);
 
-    fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
+    fodInfos = GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
 
     /* Format the pidl according to its parameter's category */
     if(wFlags & SBSP_RELATIVE)
@@ -569,7 +569,7 @@ static HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *ifac
 
     TRACE("(%p)\n", This);
 
-    fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
+    fodInfos = GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
 
     if(!(*ppshv = fodInfos->Shell.FOIShellView))
     {
@@ -773,7 +773,7 @@ static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDl
 
     TRACE("(%p)\n", This);
 
-    fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
+    fodInfos = GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
 
     /* If the selected object is not a folder, send an IDOK command to parent window */
     if((pidl = GetPidlFromDataObject(fodInfos->Shell.FOIDataObject, 1)))
@@ -827,7 +827,7 @@ static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBr
             break;
         case CDBOSC_KILLFOCUS:
            {
-               FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
+                FileOpenDlgInfos *fodInfos = GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
                if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
                {
                    WCHAR szSave[16];
@@ -862,7 +862,7 @@ static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBr
 
     TRACE("(%p)\n", This);
 
-    fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
+    fodInfos = GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
 
     ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK;
     IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
@@ -900,7 +900,7 @@ static HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *if
 
     IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface);
 
-    fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
+    fodInfos = GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
     TRACE("(%p do=%p view=%p)\n", This, fodInfos->Shell.FOIDataObject, fodInfos->Shell.FOIShellView);
 
     /* release old selections */
index 2342d3d..f8da75e 100644 (file)
@@ -148,10 +148,6 @@ IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner);
 
 
 LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex);
-UINT GetNumSelected(IDataObject *doSelected);
-
-/* pidl handling */
-BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl);
 
 /* Functions used by the EDIT box */
 void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd);
index 353da90..80c8e8b 100644 (file)
@@ -175,7 +175,7 @@ Replace:
  */
 static INT_PTR CALLBACK COMDLG32_FindReplaceDlgProc(HWND hDlgWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
 {
-       COMDLG32_FR_Data *pdata = (COMDLG32_FR_Data *)GetPropA(hDlgWnd, (LPSTR)COMDLG32_Atom);
+       COMDLG32_FR_Data *pdata = GetPropA(hDlgWnd, (LPSTR)COMDLG32_Atom);
        INT_PTR retval = TRUE;
 
        if(iMsg == WM_INITDIALOG)
@@ -417,7 +417,7 @@ static HWND COMDLG32_FR_DoFindReplace(
                goto cleanup;
        }
 
-        if((rcs = (LPDLGTEMPLATEW)LockResource(loadrc)) == NULL)
+        if((rcs = LockResource(loadrc)) == NULL)
         {
                error = CDERR_LOCKRESFAILURE;
                goto cleanup;
@@ -453,7 +453,7 @@ HWND WINAPI FindTextA(
        if(!COMDLG32_FR_CheckPartial(pfr, FALSE))
                return 0;
 
-       if((pdata = (COMDLG32_FR_Data *)COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL)
+        if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL)
                return 0; /* Error has been set */
 
         pdata->user_fr.fra = pfr;
@@ -476,7 +476,7 @@ HWND WINAPI ReplaceTextA(
        if(!COMDLG32_FR_CheckPartial(pfr, TRUE))
                return 0;
 
-       if((pdata = (COMDLG32_FR_Data *)COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL)
+        if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL)
                return 0; /* Error has been set */
 
         pdata->user_fr.fra = pfr;
@@ -507,8 +507,8 @@ HWND WINAPI FindTextW(
 
         len = WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, pfr->wFindWhatLen,
                                    NULL, 0, NULL, NULL );
-        if((pdata = (COMDLG32_FR_Data *)COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data) + len)) == NULL)
-            return 0; /* Error has been set */
+        if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data) + len)) == NULL)
+                return 0; /* Error has been set */
 
         pdata->user_fr.frw = pfr;
         pdata->fr = *(LPFINDREPLACEA)pfr;      /* FINDREPLACEx have same size */
@@ -543,9 +543,8 @@ HWND WINAPI ReplaceTextW(
                                     NULL, 0, NULL, NULL );
         len2 = WideCharToMultiByte( CP_ACP, 0, pfr->lpstrReplaceWith, pfr->wReplaceWithLen,
                                     NULL, 0, NULL, NULL );
-       if((pdata = (COMDLG32_FR_Data *)COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data)
-                                                          + len1 + len2)) == NULL)
-            return 0; /* Error has been set */
+        if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data) + len1 + len2)) == NULL)
+                return 0; /* Error has been set */
 
         pdata->user_fr.frw = pfr;
         pdata->fr = *(LPFINDREPLACEA)pfr;      /* FINDREPLACEx have same size */
index 2532f2f..470b7d3 100644 (file)
@@ -150,7 +150,7 @@ static const struct {
 
 void _dump_cf_flags(DWORD cflags)
 {
-    int i;
+    unsigned int i;
 
     for (i = 0; i < sizeof(cfflags)/sizeof(cfflags[0]); i++)
         if (cfflags[i].mask & cflags)
@@ -428,7 +428,7 @@ static int AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf)
 static int SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf)
 {
     static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
-    int i;
+    unsigned int i;
 
     for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++)
         if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return 1;
@@ -1072,7 +1072,7 @@ static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFO
                         LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
 
     if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
-        len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, -1, 0, 0);
+        len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
         WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
         HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
     }
@@ -1146,7 +1146,7 @@ INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
     int len;
 
     if (uMsg!=WM_INITDIALOG) {
-        lpcfw = (LPCHOOSEFONTW)GetPropW(hDlg, strWineFontData);
+        lpcfw = GetPropW(hDlg, strWineFontData);
         if (!lpcfw)
             return FALSE;
         if (CFn_HookCallChk32(lpcfw))
@@ -1209,7 +1209,7 @@ INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
 
     if (uMsg!=WM_INITDIALOG)
     {
-        lpcf=(LPCHOOSEFONTW)GetPropW(hDlg, strWineFontData);
+        lpcf= GetPropW(hDlg, strWineFontData);
         if (!lpcf)
             return FALSE;
         if (CFn_HookCallChk32(lpcf))
index 9a85729..c7be1d3 100644 (file)
@@ -187,7 +187,7 @@ BOOL16 WINAPI ChooseFont16(LPCHOOSEFONT16 lpChFont)
 
     if (lpChFont->Flags & CF_ENABLETEMPLATEHANDLE)
     {
-        if (!(template = LockResource16( lpChFont->hInstance )))
+        if (!LockResource16( lpChFont->hInstance ))
         {
             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
             return FALSE;
@@ -204,7 +204,7 @@ BOOL16 WINAPI ChooseFont16(LPCHOOSEFONT16 lpChFont)
             return FALSE;
         }
         if (!(hDlgTmpl16 = LoadResource16( lpChFont->hInstance, hResInfo )) ||
-            !(template = LockResource16( hDlgTmpl16 )))
+            !LockResource16( hDlgTmpl16 ))
         {
             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
             return FALSE;
index 808a33c..bdc2a0d 100644 (file)
@@ -75,6 +75,11 @@ static const struct pd_flags psd_flags[] = {
 static WNDPROC lpfnStaticWndProc;
 /* the text of the fake document to render for the Page Setup dialog */
 static WCHAR wszFakeDocumentText[1024];
+static const WCHAR pd32_collateW[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
+static const WCHAR pd32_nocollateW[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
+static const WCHAR pd32_portraitW[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 };
+static const WCHAR pd32_landscapeW[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 };
+static const WCHAR propW[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0};
 
 /***********************************************************************
  *    PRINTDLG_OpenDefaultPrinter
@@ -304,8 +309,13 @@ static BOOL PRINTDLG_UpdatePrintDlgA(HWND hDlg,
         if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */
            WORD nToPage;
            WORD nFromPage;
+            BOOL translated;
            nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
-           nToPage   = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
+           nToPage   = GetDlgItemInt(hDlg, edt2, &translated, FALSE);
+
+           /* if no ToPage value is entered, use the FromPage value */
+           if(!translated) nToPage = nFromPage;
+
            if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
                nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) {
                WCHAR resourcestr[256];
@@ -402,8 +412,13 @@ static BOOL PRINTDLG_UpdatePrintDlgW(HWND hDlg,
         if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */
            WORD nToPage;
            WORD nFromPage;
+            BOOL translated;
            nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
-           nToPage   = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
+           nToPage   = GetDlgItemInt(hDlg, edt2, &translated, FALSE);
+
+           /* if no ToPage value is entered, use the FromPage value */
+           if(!translated) nToPage = nFromPage;
+
            if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
                nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) {
                WCHAR resourcestr[256];
@@ -941,9 +956,12 @@ BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name,
     lpdm = PrintStructures->lpDevMode;  /* use this as a shortcut */
 
     if(!(lppd->Flags & PD_PRINTSETUP)) {
-      /* Print range (All/Range/Selection) */
-        SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
-       SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
+       /* Print range (All/Range/Selection) */
+       if(lppd->nFromPage != 0xffff)
+           SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
+       if(lppd->nToPage != 0xffff)
+           SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
+
        CheckRadioButton(hDlg, rad1, rad3, rad1);               /* default */
        if (lppd->Flags & PD_NOSELECTION)
            EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
@@ -1022,7 +1040,7 @@ BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name,
                HWND hQuality = GetDlgItem(hDlg, cmb1);
                LONG* Resolutions;
                char buf[255];
-               int i;
+               DWORD i;
                int dpiX, dpiY;
                HDC hPrinterDC = CreateDCA(PrintStructures->lpPrinterInfo->pDriverName,
                                           PrintStructures->lpPrinterInfo->pPrinterName,
@@ -1107,11 +1125,11 @@ static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name,
        return FALSE;
     }
     GetPrinterW(hprn, 2, NULL, 0, &needed);
-    PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*needed);
+    PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed);
     GetPrinterW(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed,
                &needed);
     GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
-    PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*needed);
+    PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,needed);
     if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo,
            needed, &needed)) {
        ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures->lpPrinterInfo->pPrinterName));
@@ -1145,9 +1163,12 @@ static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name,
     lpdm = PrintStructures->lpDevMode;  /* use this as a shortcut */
 
     if(!(lppd->Flags & PD_PRINTSETUP)) {
-      /* Print range (All/Range/Selection) */
-        SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
-       SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
+       /* Print range (All/Range/Selection) */
+       if(lppd->nFromPage != 0xffff)
+           SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
+       if(lppd->nToPage != 0xffff)
+           SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
+
        CheckRadioButton(hDlg, rad1, rad3, rad1);               /* default */
        if (lppd->Flags & PD_NOSELECTION)
            EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
@@ -1378,10 +1399,6 @@ static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam,
 static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam,
                                     PRINT_PTRW* PrintStructures)
 {
-    static const WCHAR PD32_COLLATE[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
-    static const WCHAR PD32_NOCOLLATE[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
-    static const WCHAR PD32_PORTRAIT[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 };
-    static const WCHAR PD32_LANDSCAPE[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 };
     LPPRINTDLGW lppd = PrintStructures->lpPrintDlg;
     DEVNAMES *pdn;
     DEVMODEW *pdm;
@@ -1392,15 +1409,15 @@ static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam,
     /* We load these with LoadImage because they are not a standard
        size and we don't want them rescaled */
     PrintStructures->hCollateIcon =
-      LoadImageW(COMDLG32_hInstance, PD32_COLLATE, IMAGE_ICON, 0, 0, 0);
+      LoadImageW(COMDLG32_hInstance, pd32_collateW, IMAGE_ICON, 0, 0, 0);
     PrintStructures->hNoCollateIcon =
-      LoadImageW(COMDLG32_hInstance, PD32_NOCOLLATE, IMAGE_ICON, 0, 0, 0);
+      LoadImageW(COMDLG32_hInstance, pd32_nocollateW, IMAGE_ICON, 0, 0, 0);
 
     /* These can be done with LoadIcon */
     PrintStructures->hPortraitIcon =
-      LoadIconW(COMDLG32_hInstance, PD32_PORTRAIT);
+      LoadIconW(COMDLG32_hInstance, pd32_portraitW);
     PrintStructures->hLandscapeIcon =
-      LoadIconW(COMDLG32_hInstance, PD32_LANDSCAPE);
+      LoadIconW(COMDLG32_hInstance, pd32_landscapeW);
 
     /* display the collate/no_collate icon */
     SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
@@ -1837,7 +1854,7 @@ static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
     INT_PTR res = FALSE;
 
     if (uMsg!=WM_INITDIALOG) {
-        PrintStructures = (PRINT_PTRA*)GetPropA(hDlg,"__WINE_PRINTDLGDATA");
+        PrintStructures = GetPropA(hDlg,"__WINE_PRINTDLGDATA");
        if (!PrintStructures)
            return FALSE;
     } else {
@@ -1882,12 +1899,11 @@ static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
 static INT_PTR CALLBACK PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
                                       LPARAM lParam)
 {
-    static const WCHAR propW[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0};
     PRINT_PTRW* PrintStructures;
     INT_PTR res = FALSE;
 
     if (uMsg!=WM_INITDIALOG) {
-       PrintStructures = (PRINT_PTRW*) GetPropW(hDlg, propW);
+        PrintStructures = GetPropW(hDlg, propW);
        if (!PrintStructures)
            return FALSE;
     } else {
@@ -2267,11 +2283,11 @@ BOOL WINAPI PrintDlgW(LPPRINTDLGW lppd)
        }
 
        GetPrinterW(hprn, 2, NULL, 0, &needed);
-       pbuf = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*needed);
+       pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
        GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed);
 
        GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
-       dbuf = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*needed);
+       dbuf = HeapAlloc(GetProcessHeap(),0,needed);
        if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) {
            ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
                GetLastError(),debugstr_w(pbuf->pPrinterName));
@@ -3199,7 +3215,7 @@ PRINTDLG_PagePaintProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
         return CallWindowProcA(lpfnStaticWndProc, hWnd, uMsg, wParam, lParam);
 
     /* Processing WM_PAINT message */
-    pda = (PageSetupDataA*)GetPropA(hWnd, "__WINE_PAGESETUPDLGDATA");
+    pda = GetPropA(hWnd, "__WINE_PAGESETUPDLGDATA");
     if (!pda) {
         WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
         return FALSE;
@@ -3388,7 +3404,7 @@ PRINTDLG_PageDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
        PRINTDLG_PS_ChangePaperPrev(pda);
        return TRUE;
     } else {
-       pda = (PageSetupDataA*)GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA");
+        pda = GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA");
        if (!pda) {
            WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
            return FALSE;
@@ -3474,7 +3490,7 @@ PageDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
        return TRUE;
     } else {
-       pdw = (PageSetupDataW*)GetPropW(hDlg, __WINE_PAGESETUPDLGDATA);
+        pdw = GetPropW(hDlg, __WINE_PAGESETUPDLGDATA);
        if (!pdw) {
            WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
            return FALSE;
@@ -3749,13 +3765,16 @@ HRESULT WINAPI PrintDlgExA(LPPRINTDLGEXA lppd)
  * driver-specific property pages.
  *
  * BUGS
- *   Only a Stub
+ *   Not fully implemented
  *
  */
 HRESULT WINAPI PrintDlgExW(LPPRINTDLGEXW lppd)
 {
+    DWORD     ret = E_FAIL;
+    LPVOID    ptr;
+
+    FIXME("(%p) not fully implemented\n", lppd);
 
-    FIXME("(%p) stub\n", lppd);
     if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXW))) {
         return E_INVALIDARG;
     }
@@ -3764,5 +3783,76 @@ HRESULT WINAPI PrintDlgExW(LPPRINTDLGEXW lppd)
         return E_HANDLE;
     }
 
+    if (lppd->Flags & PD_RETURNDEFAULT) {
+        PRINTER_INFO_2W *pbuf;
+        DRIVER_INFO_2W  *dbuf;
+        HANDLE hprn;
+        DWORD needed = 1024;
+        BOOL bRet;
+
+        if (lppd->hDevMode || lppd->hDevNames) {
+            WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
+            COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
+            return E_INVALIDARG;
+        }
+        if (!PRINTDLG_OpenDefaultPrinter(&hprn)) {
+            WARN("Can't find default printer\n");
+            COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
+            return E_FAIL;
+        }
+
+        pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
+        bRet = GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed);
+        if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+            HeapFree(GetProcessHeap(), 0, pbuf);
+            pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
+            bRet = GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed);
+        }
+        if (!bRet) {
+            HeapFree(GetProcessHeap(), 0, pbuf);
+            ClosePrinter(hprn);
+            return E_FAIL;
+        }
+
+        needed = 1024;
+        dbuf = HeapAlloc(GetProcessHeap(), 0, needed);
+        bRet = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed);
+        if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+            HeapFree(GetProcessHeap(), 0, dbuf);
+            dbuf = HeapAlloc(GetProcessHeap(), 0, needed);
+            bRet = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed);
+        }
+        if (!bRet) {
+            ERR("GetPrinterDriverW failed, last error %d, fix your config for printer %s!\n",
+                GetLastError(), debugstr_w(pbuf->pPrinterName));
+            HeapFree(GetProcessHeap(), 0, dbuf);
+            HeapFree(GetProcessHeap(), 0, pbuf);
+            COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
+            ClosePrinter(hprn);
+            return E_FAIL;
+        }
+        ClosePrinter(hprn);
+
+        PRINTDLG_CreateDevNamesW(&(lppd->hDevNames),
+                      dbuf->pDriverPath,
+                      pbuf->pPrinterName,
+                      pbuf->pPortName);
+        lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize +
+                         pbuf->pDevMode->dmDriverExtra);
+        if (lppd->hDevMode) {
+            ptr = GlobalLock(lppd->hDevMode);
+            if (ptr) {
+                memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize +
+                    pbuf->pDevMode->dmDriverExtra);
+                GlobalUnlock(lppd->hDevMode);
+                ret = S_OK;
+            }
+        }
+        HeapFree(GetProcessHeap(), 0, pbuf);
+        HeapFree(GetProcessHeap(), 0, dbuf);
+
+        return ret;
+    }
+
     return E_NOTIMPL;
 }
index b23ef0b..9e86706 100644 (file)
@@ -527,7 +527,7 @@ BOOL16 CALLBACK PrintDlgProc16(HWND16 hDlg16, UINT16 uMsg, WPARAM16 wParam,
     BOOL16 res = FALSE;
 
     if (uMsg!=WM_INITDIALOG) {
-        PrintStructures = (PRINT_PTRA16*)GetPropA(hDlg,"__WINE_PRINTDLGDATA");
+        PrintStructures = GetPropA(hDlg,"__WINE_PRINTDLGDATA");
        if (!PrintStructures)
            return FALSE;
     } else {
index 1b1dad3..18dac1b 100644 (file)
@@ -43,7 +43,6 @@
  */
 #include "cdlg_Bg.rc"
 #include "cdlg_Ca.rc"
-#include "cdlg_Cn.rc"
 #include "cdlg_Cs.rc"
 #include "cdlg_Da.rc"
 #include "cdlg_De.rc"
index 72cfe13..17e05d9 100644 (file)
@@ -7,7 +7,7 @@
  * 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 of the License, or (at your option) any later version.
+ * 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
@@ -25,6 +25,7 @@
 #include "winerror.h"
 #include "wincrypt.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 
@@ -35,6 +36,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 #define X509_HEADER          "-----BEGIN X509 CRL-----"
 #define X509_TRAILER         "-----END X509 CRL-----"
 
+static const WCHAR CERT_HEADER_W[] = {
+'-','-','-','-','-','B','E','G','I','N',' ','C','E','R','T','I','F','I','C',
+'A','T','E','-','-','-','-','-',0 };
+static const WCHAR CERT_TRAILER_W[] = {
+'-','-','-','-','-','E','N','D',' ','C','E','R','T','I','F','I','C','A','T',
+'E','-','-','-','-','-',0 };
+static const WCHAR CERT_REQUEST_HEADER_W[] = {
+'-','-','-','-','-','B','E','G','I','N',' ','N','E','W',' ','C','E','R','T',
+'I','F','I','C','A','T','E','R','E','Q','U','E','S','T','-','-','-','-','-',0 };
+static const WCHAR CERT_REQUEST_TRAILER_W[] = {
+'-','-','-','-','-','E','N','D',' ','N','E','W',' ','C','E','R','T','I','F',
+'I','C','A','T','E','R','E','Q','U','E','S','T','-','-','-','-','-',0 };
+static const WCHAR X509_HEADER_W[] = {
+'-','-','-','-','-','B','E','G','I','N',' ','X','5','0','9',' ','C','R','L',
+'-','-','-','-','-',0 };
+static const WCHAR X509_TRAILER_W[] = {
+'-','-','-','-','-','E','N','D',' ','X','5','0','9',' ','C','R','L','-','-',
+'-','-','-',0 };
+
 static const char b64[] =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
@@ -260,7 +280,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
     return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString);
 }
 
-static inline BYTE decodeBase64Byte(char c)
+static inline BYTE decodeBase64Byte(int c)
 {
     BYTE ret;
 
@@ -577,3 +597,303 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
         SetLastError(ret);
     return (ret == ERROR_SUCCESS) ? TRUE : FALSE;
 }
+
+static LONG decodeBase64BlockW(const WCHAR *in_buf, int in_len,
+ const WCHAR **nextBlock, PBYTE out_buf, DWORD *out_len)
+{
+    int len = in_len, i;
+    const WCHAR *d = in_buf;
+    int  ip0, ip1, ip2, ip3;
+
+    if (len < 4)
+        return ERROR_INVALID_DATA;
+
+    i = 0;
+    if (d[2] == '=')
+    {
+        if ((ip0 = decodeBase64Byte(d[0])) > 63)
+            return ERROR_INVALID_DATA;
+        if ((ip1 = decodeBase64Byte(d[1])) > 63)
+            return ERROR_INVALID_DATA;
+
+        if (out_buf)
+            out_buf[i] = (ip0 << 2) | (ip1 >> 4);
+        i++;
+    }
+    else if (d[3] == '=')
+    {
+        if ((ip0 = decodeBase64Byte(d[0])) > 63)
+            return ERROR_INVALID_DATA;
+        if ((ip1 = decodeBase64Byte(d[1])) > 63)
+            return ERROR_INVALID_DATA;
+        if ((ip2 = decodeBase64Byte(d[2])) > 63)
+            return ERROR_INVALID_DATA;
+
+        if (out_buf)
+        {
+            out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4);
+            out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2);
+        }
+        i += 2;
+    }
+    else
+    {
+        if ((ip0 = decodeBase64Byte(d[0])) > 63)
+            return ERROR_INVALID_DATA;
+        if ((ip1 = decodeBase64Byte(d[1])) > 63)
+            return ERROR_INVALID_DATA;
+        if ((ip2 = decodeBase64Byte(d[2])) > 63)
+            return ERROR_INVALID_DATA;
+        if ((ip3 = decodeBase64Byte(d[3])) > 63)
+            return ERROR_INVALID_DATA;
+
+        if (out_buf)
+        {
+            out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4);
+            out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2);
+            out_buf[i + 2] = (ip2 << 6) |  ip3;
+        }
+        i += 3;
+    }
+    if (len >= 6 && d[4] == '\r' && d[5] == '\n')
+        *nextBlock = d + 6;
+    else if (len >= 5 && d[4] == '\n')
+        *nextBlock = d + 5;
+    else if (len >= 4 && d[4])
+        *nextBlock = d + 4;
+    else
+        *nextBlock = NULL;
+    *out_len = i;
+    return ERROR_SUCCESS;
+}
+
+/* Unlike CryptStringToBinaryW, cchString is guaranteed to be the length of the
+ * string to convert.
+ */
+typedef LONG (*StringToBinaryWFunc)(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
+
+static LONG Base64ToBinaryW(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    LONG ret = ERROR_SUCCESS;
+    const WCHAR *nextBlock;
+    DWORD outLen = 0;
+
+    nextBlock = pszString;
+    while (nextBlock && !ret)
+    {
+        DWORD len = 0;
+
+        ret = decodeBase64BlockW(nextBlock, cchString - (nextBlock - pszString),
+         &nextBlock, pbBinary ? pbBinary + outLen : NULL, &len);
+        if (!ret)
+            outLen += len;
+        if (cchString - (nextBlock - pszString) <= 0)
+            nextBlock = NULL;
+    }
+    *pcbBinary = outLen;
+    if (!ret)
+    {
+        if (pdwSkip)
+            *pdwSkip = 0;
+        if (pdwFlags)
+            *pdwFlags = CRYPT_STRING_BASE64;
+    }
+    else if (ret == ERROR_INSUFFICIENT_BUFFER)
+    {
+        if (!pbBinary)
+            ret = ERROR_SUCCESS;
+    }
+    return ret;
+}
+
+static LONG Base64WithHeaderAndTrailerToBinaryW(LPCWSTR pszString,
+ DWORD cchString, LPCWSTR header, LPCWSTR trailer, BYTE *pbBinary,
+ DWORD *pcbBinary, DWORD *pdwSkip)
+{
+    LONG ret;
+    LPCWSTR ptr;
+
+    if (cchString > strlenW(header) + strlenW(trailer)
+     && (ptr = strstrW(pszString, header)) != NULL)
+    {
+        LPCWSTR trailerSpot = pszString + cchString - strlenW(trailer);
+
+        if (pszString[cchString - 1] == '\n')
+        {
+            cchString--;
+            trailerSpot--;
+        }
+        if (pszString[cchString - 1] == '\r')
+        {
+            cchString--;
+            trailerSpot--;
+        }
+        if (!strncmpW(trailerSpot, trailer, strlenW(trailer)))
+        {
+            if (pdwSkip)
+                *pdwSkip = ptr - pszString;
+            ptr += strlenW(header);
+            if (*ptr == '\r') ptr++;
+            if (*ptr == '\n') ptr++;
+            cchString -= ptr - pszString + strlenW(trailer);
+            ret = Base64ToBinaryW(ptr, cchString, pbBinary, pcbBinary, NULL,
+             NULL);
+        }
+        else
+            ret = ERROR_INVALID_DATA;
+    }
+    else
+        ret = ERROR_INVALID_DATA;
+    return ret;
+}
+
+static LONG Base64HeaderToBinaryW(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString,
+     CERT_HEADER_W, CERT_TRAILER_W, pbBinary, pcbBinary, pdwSkip);
+
+    if (!ret && pdwFlags)
+        *pdwFlags = CRYPT_STRING_BASE64HEADER;
+    return ret;
+}
+
+static LONG Base64RequestHeaderToBinaryW(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString,
+     CERT_REQUEST_HEADER_W, CERT_REQUEST_TRAILER_W, pbBinary, pcbBinary,
+     pdwSkip);
+
+    if (!ret && pdwFlags)
+        *pdwFlags = CRYPT_STRING_BASE64REQUESTHEADER;
+    return ret;
+}
+
+static LONG Base64X509HeaderToBinaryW(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString,
+     X509_HEADER_W, X509_TRAILER_W, pbBinary, pcbBinary, pdwSkip);
+
+    if (!ret && pdwFlags)
+        *pdwFlags = CRYPT_STRING_BASE64X509CRLHEADER;
+    return ret;
+}
+
+static LONG Base64AnyToBinaryW(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    LONG ret;
+
+    ret = Base64HeaderToBinaryW(pszString, cchString, pbBinary, pcbBinary,
+     pdwSkip, pdwFlags);
+    if (ret == ERROR_INVALID_DATA)
+        ret = Base64ToBinaryW(pszString, cchString, pbBinary, pcbBinary,
+         pdwSkip, pdwFlags);
+    return ret;
+}
+
+static LONG DecodeBinaryToBinaryW(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    LONG ret = ERROR_SUCCESS;
+
+    if (*pcbBinary < cchString)
+    {
+        if (!pbBinary)
+            *pcbBinary = cchString;
+        else
+        {
+            ret = ERROR_INSUFFICIENT_BUFFER;
+            *pcbBinary = cchString;
+        }
+    }
+    else
+    {
+        if (cchString)
+            memcpy(pbBinary, pszString, cchString * sizeof(WCHAR));
+        *pcbBinary = cchString * sizeof(WCHAR);
+    }
+    return ret;
+}
+
+static LONG DecodeAnyW(LPCWSTR pszString, DWORD cchString,
+ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    LONG ret;
+
+    ret = Base64HeaderToBinaryW(pszString, cchString, pbBinary, pcbBinary,
+     pdwSkip, pdwFlags);
+    if (ret == ERROR_INVALID_DATA)
+        ret = Base64ToBinaryW(pszString, cchString, pbBinary, pcbBinary,
+         pdwSkip, pdwFlags);
+    if (ret == ERROR_INVALID_DATA)
+        ret = DecodeBinaryToBinaryW(pszString, cchString, pbBinary, pcbBinary,
+         pdwSkip, pdwFlags);
+    return ret;
+}
+
+BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString,
+ DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary,
+ DWORD *pdwSkip, DWORD *pdwFlags)
+{
+    StringToBinaryWFunc decoder;
+    LONG ret;
+
+    TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_w(pszString),
+     cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);
+
+    if (!pszString)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    /* Only the bottom byte contains valid types */
+    if (dwFlags & 0xfffffff0)
+    {
+        SetLastError(ERROR_INVALID_DATA);
+        return FALSE;
+    }
+    switch (dwFlags)
+    {
+    case CRYPT_STRING_BASE64_ANY:
+        decoder = Base64AnyToBinaryW;
+        break;
+    case CRYPT_STRING_BASE64:
+        decoder = Base64ToBinaryW;
+        break;
+    case CRYPT_STRING_BASE64HEADER:
+        decoder = Base64HeaderToBinaryW;
+        break;
+    case CRYPT_STRING_BASE64REQUESTHEADER:
+        decoder = Base64RequestHeaderToBinaryW;
+        break;
+    case CRYPT_STRING_BASE64X509CRLHEADER:
+        decoder = Base64X509HeaderToBinaryW;
+        break;
+    case CRYPT_STRING_BINARY:
+        decoder = DecodeBinaryToBinaryW;
+        break;
+    case CRYPT_STRING_ANY:
+        decoder = DecodeAnyW;
+        break;
+    case CRYPT_STRING_HEX:
+    case CRYPT_STRING_HEXASCII:
+    case CRYPT_STRING_HEXADDR:
+    case CRYPT_STRING_HEXASCIIADDR:
+        FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
+        /* fall through */
+    default:
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    if (!cchString)
+        cchString = strlenW(pszString);
+    ret = decoder(pszString, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags);
+    if (ret)
+        SetLastError(ret);
+    return (ret == ERROR_SUCCESS) ? TRUE : FALSE;
+}
index d9ab229..8b5f2e8 100644 (file)
@@ -37,7 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
  * CertGetCertificateContextProperty, and are particular to the store in which
  * the property exists (which is separate from the context.)
  */
-static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
+static BOOL CertContext_GetProperty(void *context, DWORD dwPropId,
  void *pvData, DWORD *pcbData);
 
 /* Internal version of CertSetCertificateContextProperty that sets properties
@@ -45,7 +45,7 @@ static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
  * type.) Doesn't handle special cases, since they're handled by
  * CertSetCertificateContextProperty anyway.
  */
-static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
+static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
  DWORD dwFlags, const void *pvData);
 
 BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore,
@@ -88,7 +88,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType,
     {
         BYTE *data = NULL;
 
-        cert = (PCERT_CONTEXT)Context_CreateDataContext(sizeof(CERT_CONTEXT));
+        cert = Context_CreateDataContext(sizeof(CERT_CONTEXT));
         if (!cert)
             goto end;
         data = CryptMemAlloc(cbCertEncoded);
@@ -188,7 +188,7 @@ static BOOL CertContext_CopyParam(void *pvData, DWORD *pcbData, const void *pb,
     return ret;
 }
 
-static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
+static BOOL CertContext_GetProperty(void *context, DWORD dwPropId,
  void *pvData, DWORD *pcbData)
 {
     PCCERT_CONTEXT pCertContext = (PCCERT_CONTEXT)context;
@@ -440,7 +440,7 @@ static BOOL CertContext_SetKeyProvInfoProperty(PCONTEXT_PROPERTY_LIST properties
     return ret;
 }
 
-static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
+static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
  DWORD dwFlags, const void *pvData)
 {
     PCONTEXT_PROPERTY_LIST properties =
@@ -468,6 +468,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
         case CERT_SIGNATURE_HASH_PROP_ID:
         case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
         case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
+        case CERT_EXTENDED_ERROR_INFO_PROP_ID:
         case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
         case CERT_ENROLLMENT_PROP_ID:
         case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
@@ -475,7 +476,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
         {
             if (pvData)
             {
-                const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
+                const CRYPT_DATA_BLOB *blob = pvData;
 
                 ret = ContextPropertyList_SetProperty(properties, dwPropId,
                  blob->pbData, blob->cbData);
@@ -490,7 +491,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
         case CERT_DATE_STAMP_PROP_ID:
             if (pvData)
                 ret = ContextPropertyList_SetProperty(properties, dwPropId,
-                 (const BYTE *)pvData, sizeof(FILETIME));
+                 pvData, sizeof(FILETIME));
             else
             {
                 ContextPropertyList_RemoveProperty(properties, dwPropId);
@@ -501,7 +502,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
         {
             if (pvData)
             {
-                const CERT_KEY_CONTEXT *keyContext = (const CERT_KEY_CONTEXT *)pvData;
+                const CERT_KEY_CONTEXT *keyContext = pvData;
 
                 if (keyContext->cbSize != sizeof(CERT_KEY_CONTEXT))
                 {
@@ -521,8 +522,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
         }
         case CERT_KEY_PROV_INFO_PROP_ID:
             if (pvData)
-                ret = CertContext_SetKeyProvInfoProperty(properties,
-                 (const CRYPT_KEY_PROV_INFO *)pvData);
+                ret = CertContext_SetKeyProvInfoProperty(properties, pvData);
             else
             {
                 ContextPropertyList_RemoveProperty(properties, dwPropId);
@@ -540,13 +540,17 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
             {
                 if (!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
                     CryptReleaseContext(keyContext.hCryptProv, 0);
-                if (pvData)
-                    keyContext.hCryptProv = *(const HCRYPTPROV *)pvData;
-                else
-                    keyContext.hCryptProv = 0;
-                ret = CertContext_SetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
-                 0, &keyContext);
             }
+            keyContext.cbSize = sizeof(keyContext);
+            if (pvData)
+                keyContext.hCryptProv = *(const HCRYPTPROV *)pvData;
+            else
+            {
+                keyContext.hCryptProv = 0;
+                keyContext.dwKeySpec = AT_SIGNATURE;
+            }
+            ret = CertContext_SetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
+             0, &keyContext);
             break;
         }
         default:
@@ -600,13 +604,18 @@ static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert,
          CERT_KEY_PROV_INFO_PROP_ID, 0, &size);
         if (ret)
         {
-            info = (PCRYPT_KEY_PROV_INFO)HeapAlloc(GetProcessHeap(), 0, size);
+            info = HeapAlloc(GetProcessHeap(), 0, size);
             if (info)
             {
                 ret = CertGetCertificateContextProperty(pCert,
                  CERT_KEY_PROV_INFO_PROP_ID, info, &size);
                 allocated = TRUE;
             }
+            else
+            {
+                SetLastError(ERROR_OUTOFMEMORY);
+                ret = FALSE;
+            }
         }
         else
             SetLastError(CRYPT_E_NO_KEY_PROPERTY);
@@ -655,8 +664,7 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
          CERT_KEY_PROV_INFO_PROP_ID, 0, &size);
         if (ret)
         {
-            info = (PCRYPT_KEY_PROV_INFO)HeapAlloc(
-             GetProcessHeap(), 0, size);
+            info = HeapAlloc(GetProcessHeap(), 0, size);
             ret = CertGetCertificateContextProperty(pCert,
              CERT_KEY_PROV_INFO_PROP_ID, info, &size);
             if (ret)
index 77032ac..e713362 100644 (file)
@@ -251,7 +251,7 @@ static void CRYPT_CheckSimpleChainForCycles(PCERT_SIMPLE_CHAIN chain)
     if (cyclicCertIndex)
     {
         chain->rgpElement[cyclicCertIndex]->TrustStatus.dwErrorStatus
-         |= CERT_TRUST_IS_CYCLIC;
+         |= CERT_TRUST_IS_CYCLIC | CERT_TRUST_INVALID_BASIC_CONSTRAINTS;
         /* Release remaining certs */
         for (i = cyclicCertIndex + 1; i < chain->cElement; i++)
             CRYPT_FreeChainElement(chain->rgpElement[i]);
@@ -304,7 +304,7 @@ static BOOL CRYPT_AddCertToSimpleChain(PCertificateChainEngine engine,
                 chain->rgpElement[chain->cElement - 2]->TrustStatus.dwInfoStatus
                  = subjectInfoStatus;
             /* FIXME: initialize the rest of element */
-            if (chain->cElement % engine->CycleDetectionModulus)
+            if (!(chain->cElement % engine->CycleDetectionModulus))
                 CRYPT_CheckSimpleChainForCycles(chain);
             CRYPT_CombineTrustStatus(&chain->TrustStatus,
              &element->TrustStatus);
@@ -560,14 +560,13 @@ static void CRYPT_FindMatchingNameEntry(const CERT_ALT_NAME_ENTRY *constraint,
  DWORD errorIfFound, DWORD errorIfNotFound)
 {
     DWORD i;
-    BOOL defined = FALSE, match = FALSE;
+    BOOL match = FALSE;
 
     for (i = 0; i < subjectName->cAltEntry; i++)
     {
         if (subjectName->rgAltEntry[i].dwAltNameChoice ==
          constraint->dwAltNameChoice)
         {
-            defined = TRUE;
             switch (constraint->dwAltNameChoice)
             {
             case CERT_ALT_NAME_RFC822_NAME:
@@ -595,16 +594,6 @@ static void CRYPT_FindMatchingNameEntry(const CERT_ALT_NAME_ENTRY *constraint,
             }
         }
     }
-    /* Microsoft's implementation of name constraint checking appears at odds
-     * with RFC 3280:
-     * According to MSDN, CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT is set
-     * when a name constraint is present, but that name form is not defined in
-     * the end certificate.  According to RFC 3280, "if no name of the type is
-     * in the certificate, the name is acceptable."
-     * I follow Microsoft here.
-     */
-    if (!defined)
-        *trustErrorStatus |= CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT;
     *trustErrorStatus |= match ? errorIfFound : errorIfNotFound;
 }
 
@@ -645,10 +634,6 @@ static void CRYPT_CheckNameConstraints(
         }
         else
         {
-            /* See above comment on CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT.
-             * I match Microsoft's implementation here as well.
-             */
-            *trustErrorStatus |= CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT;
             if (nameConstraints->cPermittedSubtree)
                 *trustErrorStatus |=
                  CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT;
@@ -766,6 +751,16 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
                 constraints.dwPathLenConstraint--;
             }
         }
+        if (CRYPT_IsSimpleChainCyclic(chain))
+        {
+            /* If the chain is cyclic, then the path length constraints
+             * are violated, because the chain is infinitely long.
+             */
+            pathLengthConstraintViolated = TRUE;
+            chain->TrustStatus.dwErrorStatus |=
+             CERT_TRUST_IS_PARTIAL_CHAIN |
+             CERT_TRUST_INVALID_BASIC_CONSTRAINTS;
+        }
         /* FIXME: check valid usages */
         CRYPT_CombineTrustStatus(&chain->TrustStatus,
          &chain->rgpElement[i]->TrustStatus);
@@ -922,6 +917,7 @@ static BOOL CRYPT_BuildSimpleChain(PCertificateChainEngine engine,
         else
         {
             TRACE("Couldn't find issuer, halting chain creation\n");
+            chain->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_PARTIAL_CHAIN;
             break;
         }
     }
@@ -1795,7 +1791,7 @@ BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID,
             set = CryptInitOIDFunctionSet(
              CRYPT_OID_VERIFY_CERTIFICATE_CHAIN_POLICY_FUNC, 0);
         CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING, szPolicyOID, 0,
-         (void **)&verifyPolicy, hFunc);
+         (void **)&verifyPolicy, &hFunc);
     }
     if (verifyPolicy)
         ret = verifyPolicy(szPolicyOID, pChainContext, pPolicyPara,
index a5b749f..fa7922f 100644 (file)
@@ -173,6 +173,7 @@ void Context_CopyProperties(const void *to, const void *from,
 
     toProperties = Context_GetProperties((void *)to, contextSize);
     fromProperties = Context_GetProperties((void *)from, contextSize);
+    assert(toProperties && fromProperties);
     ContextPropertyList_Copy(toProperties, fromProperties);
 }
 
@@ -206,7 +207,7 @@ static inline struct list *ContextList_ContextToEntry(struct ContextList *list,
     struct list *ret;
 
     if (context)
-        ret = (struct list *)Context_GetExtra(context, list->contextSize);
+        ret = Context_GetExtra(context, list->contextSize);
     else
         ret = NULL;
     return ret;
@@ -287,7 +288,7 @@ void ContextList_Delete(struct ContextList *list, void *context)
     list->contextInterface->free(context);
 }
 
-void ContextList_Empty(struct ContextList *list)
+static void ContextList_Empty(struct ContextList *list)
 {
     struct list *entry, *next;
 
index 23c623f..9ae0d5d 100644 (file)
@@ -50,7 +50,7 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
     {
         BYTE *data = NULL;
 
-        crl = (PCRL_CONTEXT)Context_CreateDataContext(sizeof(CRL_CONTEXT));
+        crl = Context_CreateDataContext(sizeof(CRL_CONTEXT));
         if (!crl)
             goto end;
         data = CryptMemAlloc(cbCrlEncoded);
index af0d77c..1afa8a7 100644 (file)
@@ -30,4 +30,5 @@
 #include "crypt32_Ko.rc"
 #include "crypt32_Nl.rc"
 #include "crypt32_No.rc"
+#include "crypt32_Pt.rc"
 #include "crypt32_Sv.rc"
index 8476345..c06bca1 100644 (file)
@@ -35,6 +35,7 @@
 @ stdcall CertEnumCTLsInStore(ptr ptr)
 @ stdcall CertEnumCertificateContextProperties(ptr long)
 @ stdcall CertEnumCertificatesInStore(long ptr)
+@ stdcall CertEnumPhysicalStore(ptr long ptr ptr)
 @ stdcall CertEnumSystemStore(long ptr ptr ptr)
 @ stdcall CertFindAttribute(str long ptr)
 @ stdcall CertFindCRLInStore(long long long long ptr ptr)
@@ -98,7 +99,7 @@
 @ stdcall CryptBinaryToStringA(ptr long long ptr ptr)
 @ stub CryptBinaryToStringW # (ptr long long ptr ptr)
 @ stdcall CryptStringToBinaryA(str long long ptr ptr ptr ptr)
-@ stub CryptStringToBinaryW # (wstr long long ptr ptr ptr ptr)
+@ stdcall CryptStringToBinaryW (wstr long long ptr ptr ptr ptr)
 @ stdcall CryptAcquireContextU(ptr wstr wstr long long) advapi32.CryptAcquireContextW
 @ stdcall CryptAcquireCertificatePrivateKey(ptr long ptr ptr ptr ptr)
 @ stub CryptCloseAsyncHandle
 @ stdcall CryptVerifyCertificateSignature(long long ptr long ptr)
 @ stdcall CryptVerifyCertificateSignatureEx(long long long ptr long ptr long ptr)
 @ stdcall CryptVerifyDetachedMessageHash(ptr ptr long long ptr ptr ptr ptr)
-@ stub CryptVerifyDetachedMessageSignature
-@ stub CryptVerifyMessageHash
+@ stdcall CryptVerifyDetachedMessageSignature(ptr long ptr long long ptr ptr ptr)
+@ stdcall CryptVerifyMessageHash(ptr ptr long ptr ptr ptr ptr)
 @ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr)
 @ stub CryptVerifyMessageSignatureWithKey
 @ stub CryptVerifySignatureU
index 38e3b2e..ace77d2 100644 (file)
@@ -172,3 +172,66 @@ STRINGTABLE DISCARDABLE
     IDS_LOCALIZEDNAME_CA "Intermediate Certification Authorities"
     IDS_LOCALIZEDNAME_ADDRESSBOOK "Other People"
 }
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_KEY_ID "KeyID="
+    IDS_CERT_ISSUER "Certificate Issuer"
+    IDS_CERT_SERIAL_NUMBER "Certificate Serial Number="
+    IDS_ALT_NAME_OTHER_NAME "Other Name="
+    IDS_ALT_NAME_RFC822_NAME "Email Address="
+    IDS_ALT_NAME_DNS_NAME "DNS Name="
+    IDS_ALT_NAME_DIRECTORY_NAME "Directory Address"
+    IDS_ALT_NAME_URL "URL="
+    IDS_ALT_NAME_IP_ADDRESS "IP Address="
+    IDS_ALT_NAME_MASK "Mask="
+    IDS_ALT_NAME_REGISTERED_ID "Registered ID="
+    IDS_USAGE_UNKNOWN "Unknown Key Usage"
+    IDS_SUBJECT_TYPE "Subject Type="
+    IDS_SUBJECT_TYPE_CA "CA"
+    IDS_SUBJECT_TYPE_END_CERT "End Entity"
+    IDS_PATH_LENGTH "Path Length Constraint="
+    IDS_PATH_LENGTH_NONE "None"
+    IDS_INFO_NOT_AVAILABLE "Information Not Available"
+    IDS_AIA "Authority Info Access"
+    IDS_ACCESS_METHOD "Access Method="
+    IDS_ACCESS_METHOD_OCSP "OCSP"
+    IDS_ACCESS_METHOD_CA_ISSUERS "CA Issuers"
+    IDS_ACCESS_METHOD_UNKNOWN "Unknown Access Method"
+    IDS_ACCESS_LOCATION "Alternative Name"
+    IDS_CRL_DIST_POINT "CRL Distribution Point"
+    IDS_CRL_DIST_POINT_NAME "Distribution Point Name"
+    IDS_CRL_DIST_POINT_FULL_NAME "Full Name"
+    IDS_CRL_DIST_POINT_RDN_NAME "RDN Name"
+    IDS_CRL_DIST_POINT_REASON "CRL Reason="
+    IDS_CRL_DIST_POINT_ISSUER "CRL Issuer"
+    IDS_REASON_KEY_COMPROMISE "Key Compromise"
+    IDS_REASON_CA_COMPROMISE "CA Compromise"
+    IDS_REASON_AFFILIATION_CHANGED "Affiliation Changed"
+    IDS_REASON_SUPERSEDED "Superseded"
+    IDS_REASON_CESSATION_OF_OPERATION "Operation Ceased"
+    IDS_REASON_CERTIFICATE_HOLD "Certificate Hold"
+    IDS_FINANCIAL_CRITERIA "Financial Information="
+    IDS_FINANCIAL_CRITERIA_AVAILABLE "Available"
+    IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE "Not Available"
+    IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA "Meets Criteria="
+    IDS_YES "Yes"
+    IDS_NO "No"
+    IDS_DIGITAL_SIGNATURE "Digital Signature"
+    IDS_NON_REPUDIATION "Non-Repudiation"
+    IDS_KEY_ENCIPHERMENT "Key Encipherment"
+    IDS_DATA_ENCIPHERMENT "Data Encipherment"
+    IDS_KEY_AGREEMENT "Key Agreement"
+    IDS_CERT_SIGN "Certificate Signing"
+    IDS_OFFLINE_CRL_SIGN "Off-line CRL Signing"
+    IDS_CRL_SIGN "CRL Signing"
+    IDS_ENCIPHER_ONLY "Encipher Only"
+    IDS_DECIPHER_ONLY "Decipher Only"
+    IDS_NETSCAPE_SSL_CLIENT "SSL Client Authentication"
+    IDS_NETSCAPE_SSL_SERVER "SSL Server Authentication"
+    IDS_NETSCAPE_SMIME "S/MIME"
+    IDS_NETSCAPE_SIGN "Signature"
+    IDS_NETSCAPE_SSL_CA "SSL CA"
+    IDS_NETSCAPE_SMIME_CA "S/MIME CA"
+    IDS_NETSCAPE_SIGN_CA "Signature CA"
+}
index 06a11f9..08a1898 100644 (file)
@@ -87,7 +87,7 @@ STRINGTABLE DISCARDABLE
     IDS_ENROLLMENT_NAME_VALUE_PAIR "Enrollment Name Value Pair"
     IDS_OS_VERSION "Version du système d'exploitation"
     IDS_ENROLLMENT_CSP "Enrollment CSP"
-    IDS_CRL_NUMBER "CRL Number"
+    IDS_CRL_NUMBER "Numéro CRL"
     IDS_DELTA_CRL_INDICATOR "Delta CRL Indicator"
     IDS_ISSUING_DIST_POINT "Issuing Distribution Point"
     IDS_FRESHEST_CRL "Freshest CRL"
@@ -98,8 +98,8 @@ STRINGTABLE DISCARDABLE
     IDS_APPLICATION_POLICIES "Application Policies"
     IDS_APPLICATION_POLICY_MAPPINGS "Application Policy Mappings"
     IDS_APPLICATION_POLICY_CONSTRAINTS "Application Policy Constraints"
-    IDS_CMC_DATA "CMC Data"
-    IDS_CMC_RESPONSE "CMC Response"
+    IDS_CMC_DATA "Données CMC"
+    IDS_CMC_RESPONSE "Réponse CMC"
     IDS_UNSIGNED_CMC_REQUEST "Unsigned CMC Request"
     IDS_CMC_STATUS_INFO "CMC Status Info"
     IDS_CMC_EXTENSIONS "CMC Extensions"
@@ -172,3 +172,66 @@ STRINGTABLE DISCARDABLE
     IDS_LOCALIZEDNAME_CA "Autorités intermédiaires"
     IDS_LOCALIZEDNAME_ADDRESSBOOK "Autres personnes"
 }
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_KEY_ID "KeyID="
+    IDS_CERT_ISSUER "Certificate Issuer"
+    IDS_CERT_SERIAL_NUMBER "Certificate Serial Number="
+    IDS_ALT_NAME_OTHER_NAME "Other Name="
+    IDS_ALT_NAME_RFC822_NAME "Email Address="
+    IDS_ALT_NAME_DNS_NAME "DNS Name="
+    IDS_ALT_NAME_DIRECTORY_NAME "Directory Address"
+    IDS_ALT_NAME_URL "URL="
+    IDS_ALT_NAME_IP_ADDRESS "Adresse IP="
+    IDS_ALT_NAME_MASK "Mask="
+    IDS_ALT_NAME_REGISTERED_ID "Registered ID="
+    IDS_USAGE_UNKNOWN "Unknown Key Usage"
+    IDS_SUBJECT_TYPE "Subject Type="
+    IDS_SUBJECT_TYPE_CA "CA"
+    IDS_SUBJECT_TYPE_END_CERT "End Entity"
+    IDS_PATH_LENGTH "Path Length Constraint="
+    IDS_PATH_LENGTH_NONE "Aucune"
+    IDS_INFO_NOT_AVAILABLE "Information Not Available"
+    IDS_AIA "Authority Info Access"
+    IDS_ACCESS_METHOD "Access Method="
+    IDS_ACCESS_METHOD_OCSP "OCSP"
+    IDS_ACCESS_METHOD_CA_ISSUERS "CA Issuers"
+    IDS_ACCESS_METHOD_UNKNOWN "Unknown Access Method"
+    IDS_ACCESS_LOCATION "Alternative Name"
+    IDS_CRL_DIST_POINT "CRL Distribution Point"
+    IDS_CRL_DIST_POINT_NAME "Distribution Point Name"
+    IDS_CRL_DIST_POINT_FULL_NAME "Full Name"
+    IDS_CRL_DIST_POINT_RDN_NAME "RDN Name"
+    IDS_CRL_DIST_POINT_REASON "CRL Reason="
+    IDS_CRL_DIST_POINT_ISSUER "CRL Issuer"
+    IDS_REASON_KEY_COMPROMISE "Key Compromise"
+    IDS_REASON_CA_COMPROMISE "CA Compromise"
+    IDS_REASON_AFFILIATION_CHANGED "Affiliation Changed"
+    IDS_REASON_SUPERSEDED "Superseded"
+    IDS_REASON_CESSATION_OF_OPERATION "Operation Ceased"
+    IDS_REASON_CERTIFICATE_HOLD "Certificate Hold"
+    IDS_FINANCIAL_CRITERIA "Financial Information="
+    IDS_FINANCIAL_CRITERIA_AVAILABLE "Available"
+    IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE "Not Available"
+    IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA "Meets Criteria="
+    IDS_YES "Oui"
+    IDS_NO "Non"
+    IDS_DIGITAL_SIGNATURE "Signature numérique"
+    IDS_NON_REPUDIATION "Non-répudiation"
+    IDS_KEY_ENCIPHERMENT "Key Encipherment"
+    IDS_DATA_ENCIPHERMENT "Data Encipherment"
+    IDS_KEY_AGREEMENT "Key Agreement"
+    IDS_CERT_SIGN "Certificate Signing"
+    IDS_OFFLINE_CRL_SIGN "Off-line CRL Signing"
+    IDS_CRL_SIGN "CRL Signing"
+    IDS_ENCIPHER_ONLY "Chiffrement seul"
+    IDS_DECIPHER_ONLY "Déchiffrement seul"
+    IDS_NETSCAPE_SSL_CLIENT "SSL Client Authentication"
+    IDS_NETSCAPE_SSL_SERVER "SSL Server Authentication"
+    IDS_NETSCAPE_SMIME "S/MIME"
+    IDS_NETSCAPE_SIGN "Signature"
+    IDS_NETSCAPE_SSL_CA "SSL CA"
+    IDS_NETSCAPE_SMIME_CA "S/MIME CA"
+    IDS_NETSCAPE_SIGN_CA "Signature CA"
+}
index cdb89fc..2968e52 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
+LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
 {
@@ -118,7 +118,7 @@ STRINGTABLE DISCARDABLE
     IDS_KEY_RECOVERY_AGENT "Å° º¹±¸ °ü¸®ÀÚ"
     IDS_CERTIFICATE_TEMPLATE "ÀÎÁõ ÁÖÇü(Template) Á¤º¸"
     IDS_ENTERPRISE_ROOT_OID "±â¾÷ ·çÆ® OID"
-    IDS_RDN_DUMMY_SIGNER "°¡Â¥ »çÀÎÀÚ(Dummy Signer)"
+    IDS_RDN_DUMMY_SIGNER "´õ¹Ì »çÀÎÀÚ"
     IDS_ARCHIVED_KEY_ATTR "¾ÏȣȭµÈ °³ÀΠŰ"
     IDS_CRL_SELF_CDP "¹ßÇàµÈ CRL À§Ä¡"
     IDS_REQUIRE_CERT_CHAIN_POLICY "°­Á¦ ÀÎÁõ Ã¼ÀΠÁ¤Ã¥(Enforce Certificate Chain Policy)"
@@ -159,7 +159,7 @@ STRINGTABLE DISCARDABLE
     IDS_IPSEC_IKE_INTERMEDIATE "IP º¸¾È  IKE ¼ö´Ü(intermediate)"
     IDS_FILE_RECOVERY "ÆÄÀÏ º¹±¸"
     IDS_ROOT_LIST_SIGNER "·çÆ® ¸ñ·Ï ¼­¸íÀÚ"
-    IDS_ANY_APPLICATION_POLICIES "¸ðµç Ç®±×¸²ÀÇ ¹æħ"
+    IDS_ANY_APPLICATION_POLICIES "¸ðµç ÇÁ·Î±×·¥ÀÇ ¹æħ"
     IDS_DS_EMAIL_REPLICATION "µð·ºÅ丮 ¼­ºñ½º À̸ÞÀÏ ÀÀ´ä"
     IDS_ENROLLMENT_AGENT "ÀÎÁõ ¿ä±¸ °ü¸®ÀÚ"
     IDS_LIFETIME_SIGNING "Æò»ý ¼­¸í"
@@ -168,8 +168,71 @@ STRINGTABLE DISCARDABLE
 
 STRINGTABLE DISCARDABLE
 {
-    IDS_LOCALIZEDNAME_ROOT "½Åȸ ÇÒ ¼ö Àִ ·çÆ® °Ë»çÁõ±â°ü"
-    IDS_LOCALIZEDNAME_MY "°³ÀÎÀû"
-    IDS_LOCALIZEDNAME_CA "Áß°£ °ËÁõ ±â°ü¤¤Intermediate Certification Authorities"
+    IDS_LOCALIZEDNAME_ROOT "½Åȸ ÇÒ ¼ö Àִ ·çÆ® °ËÁõ±â°ü"
+    IDS_LOCALIZEDNAME_MY "°³ÀÎ"
+    IDS_LOCALIZEDNAME_CA "Áß°³ °ËÁõ ±â°ü"
     IDS_LOCALIZEDNAME_ADDRESSBOOK "´Ù¸¥ »ç¶÷"
 }
+
+STRINGTABLE DISCARDABLE
+{
+IDS_KEY_ID "KeyID="
+IDS_CERT_ISSUER "ÀÎÁõ¼­ ¹ßÇàÀÚ "
+IDS_CERT_SERIAL_NUMBER "ÀÎÁõ¼­ ½Ã¸®¾ó ¹øÈ£="
+IDS_ALT_NAME_OTHER_NAME "´Ù¸¥ À̸§="
+IDS_ALT_NAME_RFC822_NAME "À̸ÞÀÏ ÁÖ¼Ò="
+IDS_ALT_NAME_DNS_NAME "DNS À̸§="
+IDS_ALT_NAME_DIRECTORY_NAME "µð·ºÅ丮  ÁÖ¼Ò"
+IDS_ALT_NAME_URL "URL="
+IDS_ALT_NAME_IP_ADDRESS "IP ÁÖ¼Ò="
+IDS_ALT_NAME_MASK "¸¶½ºÅ©="
+IDS_ALT_NAME_REGISTERED_ID "µî·ÏµÈ ID="
+IDS_USAGE_UNKNOWN "¾Ë¼ö ¾ø´Â Å° »ç¿ë"
+IDS_SUBJECT_TYPE "Á¦¸ñ Çü½Ä="
+IDS_SUBJECT_TYPE_CA "CA"
+IDS_SUBJECT_TYPE_END_CERT "¿£Æ¼Æ¼ ³¡"
+IDS_PATH_LENGTH "Á¦ÇѵȠ°æ·Î ±æÀÌ ="
+IDS_PATH_LENGTH_NONE "¾øÀ½"
+IDS_INFO_NOT_AVAILABLE "Á¤º¸°¡ ¾øÀ½"
+IDS_AIA "±ÇÇÑ Á¤º¸ Á¢±Ù"
+IDS_ACCESS_METHOD "Á¢±Ù ¹æ¹ý="
+IDS_ACCESS_METHOD_OCSP "OCSP"
+IDS_ACCESS_METHOD_CA_ISSUERS "CA ¹ßÇàÀÚ"
+IDS_ACCESS_METHOD_UNKNOWN "¾Ë ¼ö ¾ø´Â Á¢±Ù ¹æ¹ý"
+IDS_ACCESS_LOCATION "´ëü À̸§"
+IDS_CRL_DIST_POINT "CRL ºÐ¹è Æ÷ÀÎÆ®"
+IDS_CRL_DIST_POINT_NAME "ºÐ¹è Æ÷ÀÎÆ® À̸§"
+IDS_CRL_DIST_POINT_FULL_NAME "Àüü À̸§"
+IDS_CRL_DIST_POINT_RDN_NAME "RDN À̸§"
+IDS_CRL_DIST_POINT_REASON "CRL ¿øÀÎ="
+IDS_CRL_DIST_POINT_ISSUER "CRL ¹ßÇàÀÚ"
+IDS_REASON_KEY_COMPROMISE "Key ÇùÁ¤"
+IDS_REASON_CA_COMPROMISE "CA ÇùÁ¤"
+IDS_REASON_AFFILIATION_CHANGED "°¡ÀÔÀÌ º¯°æµÊ"
+IDS_REASON_SUPERSEDED "´ëü"
+IDS_REASON_CESSATION_OF_OPERATION "ÀÛ¾÷ ÁßÁö"
+IDS_REASON_CERTIFICATE_HOLD "ÀÎÁõ¼­ À¯Áö"
+IDS_FINANCIAL_CRITERIA "À繫 Á¤º¸="
+IDS_FINANCIAL_CRITERIA_AVAILABLE "°¡´ÉÇÔ"
+IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE "ºÒ°¡´ÉÇÔ"
+IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA "¸Â´Â ±âÁØ ="
+IDS_YES "¿¹"
+IDS_NO "¾Æ´Ï¿À"
+IDS_DIGITAL_SIGNATURE " ÀüÀÚ ¼­¸í"
+IDS_NON_REPUDIATION "ºÎÀΠ¹æÁö"
+IDS_KEY_ENCIPHERMENT "Å° ¾Ïȣȭ"
+IDS_DATA_ENCIPHERMENT "µ¥ÀÌÅÍ ¾Ïȣȭ"
+IDS_KEY_AGREEMENT "Å° º¸Áõ¼­t"
+IDS_CERT_SIGN "Áõ¸í¼­ ¼­¸í"
+IDS_OFFLINE_CRL_SIGN "¿ÀÇÁ¶óÀΠCRL »çÀÎ"
+IDS_CRL_SIGN "CRL ¼­¸í"
+IDS_ENCIPHER_ONLY "¿ÀÁ÷ ¾Ïȣȭ¸¸ ÇÔ"
+IDS_DECIPHER_ONLY "¿ÀÁ÷ º¹È£È­¸¸"
+IDS_NETSCAPE_SSL_CLIENT "SSL Å¬¶óÀ̾ðÆ® ÀÎÁõ"
+IDS_NETSCAPE_SSL_SERVER "SSL ¼­¹ö ÀÎÁõ"
+IDS_NETSCAPE_SMIME "S/MIME"
+IDS_NETSCAPE_SIGN "¼­¸í"
+IDS_NETSCAPE_SSL_CA "SSL CA"
+IDS_NETSCAPE_SMIME_CA "S/MIME CA"
+IDS_NETSCAPE_SIGN_CA " CA ¼­¸í"
+}
diff --git a/reactos/dll/win32/crypt32/crypt32_Pt.rc b/reactos/dll/win32/crypt32/crypt32_Pt.rc
new file mode 100644 (file)
index 0000000..424f8ea
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * crypt32 dll resources
+ *
+ * Copyright (C) 2008 Ricardo Filipe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_AUTHORITY_KEY_ID "Identificador da Chave de Autoridade"
+    IDS_KEY_ATTRIBUTES "Atributos da Chave"
+    IDS_KEY_USAGE_RESTRICTION "Restrições ao uso da Chave"
+    IDS_SUBJECT_ALT_NAME "Nome Alternativo do Sujeito"
+    IDS_ISSUER_ALT_NAME "Nome Alternativo do Emissor"
+    IDS_BASIC_CONSTRAINTS "Restrições Básicas"
+    IDS_KEY_USAGE "Uso da Chave"
+    IDS_CERT_POLICIES "Políticas de Certificados"
+    IDS_SUBJECT_KEY_IDENTIFIER "Identificador da Chave do Sujeito"
+    IDS_CRL_REASON_CODE "Código de Razão CRL"
+    IDS_CRL_DIST_POINTS "Pontos de Distribuição CRL"
+    IDS_ENHANCED_KEY_USAGE "Uso da Chave melhorado"
+    IDS_AUTHORITY_INFO_ACCESS "Acesso Autorizado a Informação"
+    IDS_CERT_EXTENSIONS "Extensões de Certificados"
+    IDS_NEXT_UPDATE_LOCATION "Localização da próxima actualização"
+    IDS_YES_OR_NO_TRUST "Confiança Sim ou Não"
+    IDS_EMAIL_ADDRESS "Endereço de Email"
+    IDS_UNSTRUCTURED_NAME "Nome não estruturado"
+    IDS_CONTENT_TYPE "Tipo de Conteúdo"
+    IDS_MESSAGE_DIGEST "Resumo da mensagem"
+    IDS_SIGNING_TIME "Tempo de assinatura"
+    IDS_COUNTER_SIGN "Contra assinar"
+    IDS_CHALLENGE_PASSWORD "Desafiar Password"
+    IDS_UNSTRUCTURED_ADDRESS "Endereço não estruturado"
+    IDS_SMIME_CAPABILITIES "Capacidades SMIME"
+    IDS_PREFER_SIGNED_DATA "Preferir Dados Assinados"
+    IDS_CPS "CPS"
+    IDS_USER_NOTICE "Aviso de Utilizador"
+    IDS_OCSP "Protocolo de Estado de Certificados Online"
+    IDS_CA_ISSUER "Emissor de Certificados Autorizados"
+    IDS_CERT_TEMPLATE_NAME "Nome de Certificação por Template"
+    IDS_CERT_TYPE "Tipo de Certificado"
+    IDS_CERT_MANIFOLD "Agrupador de Certificados"
+    IDS_NETSCAPE_CERT_TYPE "Tipo de Certificados Netscape"
+    IDS_NETSCAPE_BASE_URL "URL Base Netscape"
+    IDS_NETSCAPE_REVOCATION_URL "URL Revogação Netscape"
+    IDS_NETSCAPE_CA_REVOCATION_URL "URL Revogação CA Netscape"
+    IDS_NETSCAPE_CERT_RENEWAL_URL "URL Renovação de Certificados Netscape"
+    IDS_NETSCAPE_CA_POLICY_URL "URL Política CA Netscape"
+    IDS_NETSCAPE_SSL_SERVER_NAME "Netscape SSL ServerName"
+    IDS_NETSCAPE_COMMENT "Comentário Netscape"
+    IDS_SPC_SP_AGENCY_INFO "SpcSpAgencyInfo"
+    IDS_SPC_FINANCIAL_CRITERIA "SpcFinancialCriteria"
+    IDS_SPC_MINIMAL_CRITERIA "SpcMinimalCriteria"
+    IDS_COUNTRY "País/Região"
+    IDS_ORGANIZATION "Organização"
+    IDS_ORGANIZATIONAL_UNIT "Unidade Organizacional"
+    IDS_COMMON_NAME "Nome Comum"
+    IDS_LOCALITY "Localidade"
+    IDS_STATE_OR_PROVINCE "Estado ou Província"
+    IDS_TITLE "Título"
+    IDS_GIVEN_NAME "Nome Dado"
+    IDS_INITIALS "Iniciais"
+    IDS_SUR_NAME "Apelido"
+    IDS_DOMAIN_COMPONENT "Componente de Domínio"
+    IDS_STREET_ADDRESS "Endereço da Rua"
+    IDS_SERIAL_NUMBER "Número de série"
+    IDS_CA_VERSION "Versão CA"
+    IDS_CROSS_CA_VERSION "Versão Cruzada CA"
+    IDS_SERIALIZED_SIG_SERIAL_NUMBER "Número de Série Assinado Serializado"
+    IDS_PRINCIPAL_NAME "Nome Principal"
+    IDS_WINDOWS_PRODUCT_UPDATE "Actualização de Produto Windows"
+    IDS_ENROLLMENT_NAME_VALUE_PAIR "Par de Inscrição Nome Valor"
+    IDS_OS_VERSION "Versão do SO"
+    IDS_ENROLLMENT_CSP "Inscrição CSP"
+    IDS_CRL_NUMBER "Número CRL"
+    IDS_DELTA_CRL_INDICATOR "Indicador Delta CRL"
+    IDS_ISSUING_DIST_POINT "Emissão de Ponto de Distribuição"
+    IDS_FRESHEST_CRL "CRL Mais Recente"
+    IDS_NAME_CONSTRAINTS "Restrições de Nome"
+    IDS_POLICY_MAPPINGS "Mapeamento de Políticas"
+    IDS_POLICY_CONSTRAINTS "Restrições de Políticas"
+    IDS_CROSS_CERT_DIST_POINTS "Cross-Certificate Distribution Points"
+    IDS_APPLICATION_POLICIES "Políticas da Aplicação"
+    IDS_APPLICATION_POLICY_MAPPINGS "Mapeamento das Políticas da Aplicação"
+    IDS_APPLICATION_POLICY_CONSTRAINTS "Restrições da Política da Aplicação"
+    IDS_CMC_DATA "Dados CMC"
+    IDS_CMC_RESPONSE "Resposta CMC"
+    IDS_UNSIGNED_CMC_REQUEST "Pedido CMC não assinado"
+    IDS_CMC_STATUS_INFO "Informação de Estado CMC"
+    IDS_CMC_EXTENSIONS "Extensões CMC"
+    IDS_CMC_ATTRIBUTES "Atributos CMC"
+    IDS_PKCS_7_DATA "Dados PKCS 7"
+    IDS_PKCS_7_SIGNED "Assinado PKCS 7"
+    IDS_PKCS_7_ENVELOPED "PKCS 7 Enveloped"
+    IDS_PKCS_7_SIGNED_ENVELOPED "PKCS 7 Signed Enveloped"
+    IDS_PKCS_7_DIGESTED "PKCS 7 Resumido"
+    IDS_PKCS_7_ENCRYPTED "PKCS 7 Cifrado"
+    IDS_PREVIOUS_CA_CERT_HASH "Hash Certificado CA prévio"
+    IDS_CRL_VIRTUAL_BASE "Número CRL de Base Virtual"
+    IDS_CRL_NEXT_PUBLISH "Próxima Publicação CRL"
+    IDS_CA_EXCHANGE "Certificado de Cifra CA"
+    IDS_KEY_RECOVERY_AGENT "Agente Recuperador de Chaves"
+    IDS_CERTIFICATE_TEMPLATE "Informação do Template do Certificado"
+    IDS_ENTERPRISE_ROOT_OID "Enterprise Root OID"
+    IDS_RDN_DUMMY_SIGNER "Dummy Signer"
+    IDS_ARCHIVED_KEY_ATTR "Chave Privada Cifrada"
+    IDS_CRL_SELF_CDP "Localizações CRL Publicadas"
+    IDS_REQUIRE_CERT_CHAIN_POLICY "Forçar Política Encadeada de Certificados"
+    IDS_TRANSACTION_ID "Id da transacção"
+    IDS_SENDER_NONCE "Sender Nonce"
+    IDS_RECIPIENT_NONCE "Recipient Nonce"
+    IDS_REG_INFO "Registo de Informação"
+    IDS_GET_CERTIFICATE "Obter Certificado"
+    IDS_GET_CRL "Obter CRL"
+    IDS_REVOKE_REQUEST "Revogar Pedido"
+    IDS_QUERY_PENDING "Consulta Pendente"
+    IDS_SORTED_CTL "Lista Confiável de Certificados"
+    IDS_ARCHIVED_KEY_CERT_HASH "Hash de Certificados Chave Arquivados"
+    IDS_PRIVATE_KEY_USAGE_PERIOD "Período de Uso da Chave Privada"
+    IDS_CLIENT_INFORMATION "Informação do Cliente"
+    IDS_SERVER_AUTHENTICATION "Autenticação do Servidor"
+    IDS_CLIENT_AUTHENTICATION "Autenticação do Cliente"
+    IDS_CODE_SIGNING "Assinatura de Código"
+    IDS_SECURE_EMAIL "Email seguro"
+    IDS_TIME_STAMPING "Selo Temporal"
+    IDS_MICROSOFT_TRUST_LIST_SIGNING "Assinatura da Lista Confiável da Microsoft"
+    IDS_MICROSOFT_TIME_STAMPING "Selo Temporal da Microsoft"
+    IDS_IPSEC_END_SYSTEM "Sistema de segurança IP"
+    IDS_IPSEC_TUNNEL "Terminação do Túnel de Segurança IP"
+    IDS_IPSEC_USER "Utilizador Seguro IP"
+    IDS_EFS "Cifrando Sistema de Ficheiros"
+    IDS_WHQL_CRYPTO "Verificação de Driver de Hardware Windows"
+    IDS_NT5_CRYPTO "Verificação de Componentes de Sistema Windows"
+    IDS_OEM_WHQL_CRYPTO "Verificação de Componentes de Sistema OEM Windows"
+    IDS_EMBEDDED_NT_CRYPTO "Verificação de Componentes de Sistema Windows Embebida"
+    IDS_KEY_PACK_LICENSES "Licenças de Pacotes de Chaves"
+    IDS_LICENSE_SERVER "Verificação de Licença de Servidor"
+    IDS_SMART_CARD_LOGON "Smart Card Logon"
+    IDS_DIGITAL_RIGHTS "Direitos Digitais"
+    IDS_QUALIFIED_SUBORDINATION "Subordinação Qualificada"
+    IDS_KEY_RECOVERY "Recuperação de chaves"
+    IDS_DOCUMENT_SIGNING "Assinatura de Documento"
+    IDS_IPSEC_IKE_INTERMEDIATE "Segurança IP Intermédia IKE"
+    IDS_FILE_RECOVERY "Recuperação de Ficheiros"
+    IDS_ROOT_LIST_SIGNER "Root List Signer"
+    IDS_ANY_APPLICATION_POLICIES "Políticas de todas as aplicações"
+    IDS_DS_EMAIL_REPLICATION "Replicação do Directório de Serviço Email"
+    IDS_ENROLLMENT_AGENT "Agente de Pedido de Certificados"
+    IDS_LIFETIME_SIGNING "Assinatura de tempo de vida"
+    IDS_ANY_CERT_POLICY "Políticas para todas as emissões"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_LOCALIZEDNAME_ROOT "Autoridades de Certificação de Raiz Confiáveis"
+    IDS_LOCALIZEDNAME_MY "Pessoal"
+    IDS_LOCALIZEDNAME_CA "Autoridades de Certificação Intermédias"
+    IDS_LOCALIZEDNAME_ADDRESSBOOK "Outras pessoas"
+}
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_KEY_ID "KeyID="
+    IDS_CERT_ISSUER "Emissor do Certificado: "
+    IDS_CERT_SERIAL_NUMBER "Número de Série do Certificado="
+    IDS_ALT_NAME_OTHER_NAME "Outro Nome="
+    IDS_ALT_NAME_RFC822_NAME "Endereço Email="
+    IDS_ALT_NAME_DNS_NAME "Nome DNS="
+    IDS_ALT_NAME_DIRECTORY_NAME "Nome do Directório="
+    IDS_ALT_NAME_URL "URL="
+    IDS_ALT_NAME_IP_ADDRESS "Endereço IP="
+    IDS_ALT_NAME_MASK "Máscara="
+    IDS_ALT_NAME_REGISTERED_ID "ID Registado="
+    IDS_USAGE_UNKNOWN "Uso de Chave Desconhecido"
+    IDS_SUBJECT_TYPE "Tipo de Sujeito="
+    IDS_SUBJECT_TYPE_CA "CA"
+    IDS_SUBJECT_TYPE_END_CERT "Fim de Entidade"
+    IDS_PATH_LENGTH "Restrição de tamanho de caminho="
+    IDS_PATH_LENGTH_NONE "Nenhum"
+    IDS_INFO_NOT_AVAILABLE "Informação não Disponível"
+    IDS_AIA "Acesso à Informação de Autoridade"
+    IDS_ACCESS_METHOD "Método de Acesso="
+    IDS_ACCESS_METHOD_OCSP "OCSP"
+    IDS_ACCESS_METHOD_CA_ISSUERS "Emissores CA"
+    IDS_ACCESS_METHOD_UNKNOWN "Método de Acesso Desconhecido"
+    IDS_ACCESS_LOCATION "Nome Alternativo"
+    IDS_CRL_DIST_POINT "Ponto de Distribuição CRL"
+    IDS_CRL_DIST_POINT_NAME "Nome do Ponto de Distribuição"
+    IDS_CRL_DIST_POINT_FULL_NAME "Nome Completo"
+    IDS_CRL_DIST_POINT_RDN_NAME "Nome RDN"
+    IDS_CRL_DIST_POINT_REASON "Razão CRL="
+    IDS_CRL_DIST_POINT_ISSUER "Emissor CRL"
+    IDS_REASON_KEY_COMPROMISE "Compromisso da Chave"
+    IDS_REASON_CA_COMPROMISE "Compromisso CA"
+    IDS_REASON_AFFILIATION_CHANGED "Mudança de afiliação"
+    IDS_REASON_SUPERSEDED "Supercedente"
+    IDS_REASON_CESSATION_OF_OPERATION "Operação terminada"
+    IDS_REASON_CERTIFICATE_HOLD "Certificado em espera"
+    IDS_FINANCIAL_CRITERIA "Informação Financeira="
+    IDS_FINANCIAL_CRITERIA_AVAILABLE "Disponível"
+    IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE "Não Disponível"
+    IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA "Conforme os Critérios="
+    IDS_YES "Sim"
+    IDS_NO "Não"
+}
index 46bc8c5..46d4797 100644 (file)
@@ -123,7 +123,9 @@ BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
  */
 HCRYPTPROV CRYPT_GetDefaultProvider(void);
 
-void crypt_oid_init(HINSTANCE hinst);
+HINSTANCE hInstance;
+
+void crypt_oid_init(void);
 void crypt_oid_free(void);
 void crypt_sip_free(void);
 void root_store_free(void);
@@ -284,6 +286,13 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store);
  */
 void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info);
 
+/**
+ *  String functions
+ */
+
+DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent,
+ PCERT_NAME_BLOB pName, DWORD dwStrType, LPWSTR psz, DWORD csz);
+
 /**
  *  Context functions
  */
@@ -370,8 +379,15 @@ void *ContextList_Enum(struct ContextList *list, void *pPrev);
 
 void ContextList_Delete(struct ContextList *list, void *context);
 
-void ContextList_Empty(struct ContextList *list);
-
 void ContextList_Free(struct ContextList *list);
 
+/**
+ *  Utilities.
+ */
+
+/* Align up to a DWORD_PTR boundary
+ */
+#define ALIGN_DWORD_PTR(x) (((x) + sizeof(DWORD_PTR) - 1) & ~(sizeof(DWORD_PTR) - 1))
+#define POINTER_ALIGN_DWORD_PTR(p) ((LPVOID)ALIGN_DWORD_PTR((DWORD_PTR)(p)))
+
 #endif
diff --git a/reactos/dll/win32/crypt32/crypt32_ros.diff b/reactos/dll/win32/crypt32/crypt32_ros.diff
deleted file mode 100644 (file)
index 0269692..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- D:/Wine-CVS/wine/dlls/crypt32/rootstore.c  Sat Feb 16 22:49:56 2008
-+++ D:/ReactOS-Trunk/reactos/dll/win32/crypt32/rootstore.c     Sat May 10 20:30:25 2008
-@@ -317,7 +317,7 @@
-     DIR *dir;
-     TRACE("(%s, %p)\n", debugstr_a(path), store);
--
-+    /* UNIX functions = bad for reactos
-     dir = opendir(path);
-     if (dir)
-     {
-@@ -340,6 +340,7 @@
-             CryptMemFree(filebuf);
-         }
-     }
-+    */
-     return ret;
- }
index 32c8169..6d0ac46 100644 (file)
 #define IDS_LOCALIZEDNAME_CA 1143
 #define IDS_LOCALIZEDNAME_ADDRESSBOOK 1144
 
+#define IDS_KEY_ID 1200
+#define IDS_CERT_ISSUER 1201
+#define IDS_CERT_SERIAL_NUMBER 1202
+#define IDS_ALT_NAME_OTHER_NAME 1203
+#define IDS_ALT_NAME_RFC822_NAME 1204
+#define IDS_ALT_NAME_DNS_NAME 1205
+#define IDS_ALT_NAME_DIRECTORY_NAME 1206
+#define IDS_ALT_NAME_URL 1207
+#define IDS_ALT_NAME_IP_ADDRESS 1208
+#define IDS_ALT_NAME_MASK 1209
+#define IDS_ALT_NAME_REGISTERED_ID 1210
+#define IDS_USAGE_UNKNOWN 1211
+#define IDS_SUBJECT_TYPE 1212
+#define IDS_SUBJECT_TYPE_CA 1213
+#define IDS_SUBJECT_TYPE_END_CERT 1214
+#define IDS_PATH_LENGTH 1215
+#define IDS_PATH_LENGTH_NONE 1216
+#define IDS_INFO_NOT_AVAILABLE 1218
+#define IDS_AIA 1219
+#define IDS_ACCESS_METHOD 1220
+#define IDS_ACCESS_METHOD_OCSP 1221
+#define IDS_ACCESS_METHOD_CA_ISSUERS 1222
+#define IDS_ACCESS_METHOD_UNKNOWN 1223
+#define IDS_ACCESS_LOCATION 1224
+#define IDS_CRL_DIST_POINT 1225
+#define IDS_CRL_DIST_POINT_NAME 1226
+#define IDS_CRL_DIST_POINT_FULL_NAME 1227
+#define IDS_CRL_DIST_POINT_RDN_NAME 1228
+#define IDS_CRL_DIST_POINT_REASON 1229
+#define IDS_CRL_DIST_POINT_ISSUER 1230
+#define IDS_REASON_KEY_COMPROMISE 1231
+#define IDS_REASON_CA_COMPROMISE 1232
+#define IDS_REASON_AFFILIATION_CHANGED 1233
+#define IDS_REASON_SUPERSEDED 1234
+#define IDS_REASON_CESSATION_OF_OPERATION 1235
+#define IDS_REASON_CERTIFICATE_HOLD 1236
+#define IDS_FINANCIAL_CRITERIA 1237
+#define IDS_FINANCIAL_CRITERIA_AVAILABLE 1238
+#define IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE 1239
+#define IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA 1240
+#define IDS_YES 1241
+#define IDS_NO 1242
+#define IDS_DIGITAL_SIGNATURE 1243
+#define IDS_NON_REPUDIATION 1244
+#define IDS_KEY_ENCIPHERMENT 1245
+#define IDS_DATA_ENCIPHERMENT 1246
+#define IDS_KEY_AGREEMENT 1247
+#define IDS_CERT_SIGN 1248
+#define IDS_OFFLINE_CRL_SIGN 1249
+#define IDS_CRL_SIGN 1250
+#define IDS_ENCIPHER_ONLY 1251
+#define IDS_DECIPHER_ONLY 1252
+#define IDS_NETSCAPE_SSL_CLIENT 1253
+#define IDS_NETSCAPE_SSL_SERVER 1254
+#define IDS_NETSCAPE_SMIME 1255
+#define IDS_NETSCAPE_SIGN 1256
+#define IDS_NETSCAPE_SSL_CA 1257
+#define IDS_NETSCAPE_SMIME_CA 1258
+#define IDS_NETSCAPE_SIGN_CA 1259
+
 #endif /* ndef __WINE_CRYPTRES_H__ */
index 9b6d2e0..ffac667 100644 (file)
@@ -382,8 +382,7 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
              (BYTE *)&ctlInfo, &size);
             if (ret)
             {
-                ctl = (PCTL_CONTEXT)Context_CreateDataContext(
-                 sizeof(CTL_CONTEXT));
+                ctl = Context_CreateDataContext(sizeof(CTL_CONTEXT));
                 if (ctl)
                 {
                     BYTE *data = CryptMemAlloc(cbCtlEncoded);
index eb782d3..fa06510 100644 (file)
@@ -96,6 +96,7 @@ static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
  DWORD *pcbDecoded);
+/* Doesn't check the tag, assumes the caller does so */
 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
@@ -361,9 +362,7 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
                         if (ret)
                         {
                             /* Account for alignment padding */
-                            if (items[i].size % sizeof(DWORD_PTR))
-                                items[i].size += sizeof(DWORD_PTR) -
-                                 items[i].size % sizeof(DWORD_PTR);
+                            items[i].size = ALIGN_DWORD_PTR(items[i].size);
                             TRACE("item %d size: %d\n", i, items[i].size);
                             if (nextData && items[i].hasPointer &&
                              items[i].size > items[i].minSize)
@@ -377,26 +376,10 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
                             }
                             else
                             {
-                                if (itemLen == CMSG_INDEFINITE_LENGTH)
-                                {
-                                    if (itemDecoded > itemEncodedLen - 2 ||
-                                     *(ptr + itemDecoded) != 0 ||
-                                     *(ptr + itemDecoded + 1) != 0)
-                                    {
-                                        TRACE("expected 0 TLV\n");
-                                        SetLastError(CRYPT_E_ASN1_CORRUPT);
-                                        ret = FALSE;
-                                    }
-                                    else
-                                        itemDecoded += 2;
-                                }
-                                if (ret)
-                                {
-                                    ptr += itemDecoded;
-                                    decoded += itemDecoded;
-                                    TRACE("item %d: decoded %d bytes\n", i,
-                                     itemDecoded);
-                                }
+                                ptr += itemDecoded;
+                                decoded += itemDecoded;
+                                TRACE("item %d: decoded %d bytes\n", i,
+                                 itemDecoded);
                             }
                         }
                         else if (items[i].optional &&
@@ -475,6 +458,11 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
      cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
      startingPointer);
 
+    if (!cbEncoded)
+    {
+        SetLastError(CRYPT_E_ASN1_EOD);
+        return FALSE;
+    }
     if (pbEncoded[0] == ASN_SEQUENCE)
     {
         DWORD dataLen;
@@ -946,7 +934,7 @@ static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
 {
@@ -1116,7 +1104,7 @@ static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
 {
@@ -1625,48 +1613,59 @@ static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
         {
         case ASN_NUMERICSTRING:
             valueType = CERT_RDN_NUMERIC_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_PRINTABLESTRING:
             valueType = CERT_RDN_PRINTABLE_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_IA5STRING:
             valueType = CERT_RDN_IA5_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_T61STRING:
             valueType = CERT_RDN_T61_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_VIDEOTEXSTRING:
             valueType = CERT_RDN_VIDEOTEX_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_GRAPHICSTRING:
             valueType = CERT_RDN_GRAPHIC_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_VISIBLESTRING:
             valueType = CERT_RDN_VISIBLE_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_GENERALSTRING:
             valueType = CERT_RDN_GENERAL_STRING;
-            bytesNeeded += dataLen * 2;
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
             break;
         case ASN_UNIVERSALSTRING:
             valueType = CERT_RDN_UNIVERSAL_STRING;
-            bytesNeeded += dataLen / 2;
+            if (dataLen)
+                bytesNeeded += dataLen / 2 + sizeof(WCHAR);
             break;
         case ASN_BMPSTRING:
             valueType = CERT_RDN_BMP_STRING;
-            bytesNeeded += dataLen;
+            if (dataLen)
+                bytesNeeded += dataLen + sizeof(WCHAR);
             break;
         case ASN_UTF8STRING:
             valueType = CERT_RDN_UTF8_STRING;
-            bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
-             (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
+            if (dataLen)
+                bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
+                 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
             break;
         default:
             SetLastError(CRYPT_E_ASN1_BADTAG);
@@ -1706,23 +1705,29 @@ static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
                     value->Value.cbData = dataLen * 2;
                     for (i = 0; i < dataLen; i++)
                         str[i] = pbEncoded[1 + lenBytes + i];
+                    str[i] = 0;
                     break;
                 case ASN_UNIVERSALSTRING:
                     value->Value.cbData = dataLen / 2;
                     for (i = 0; i < dataLen / 4; i++)
                         str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
                          | pbEncoded[1 + lenBytes + 2 * i + 3];
+                    str[i] = 0;
                     break;
                 case ASN_BMPSTRING:
                     value->Value.cbData = dataLen;
                     for (i = 0; i < dataLen / 2; i++)
                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
                          pbEncoded[1 + lenBytes + 2 * i + 1];
+                    str[i] = 0;
                     break;
                 case ASN_UTF8STRING:
                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
+                    value->Value.pbData[value->Value.cbData / sizeof(WCHAR)]
+                     = 0;
+                    value->Value.cbData += sizeof(WCHAR);
                     break;
                 }
             }
@@ -2237,6 +2242,342 @@ static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
     return ret;
 }
 
+static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+    BOOL ret = TRUE;
+    DWORD dataLen;
+    LPSTR *pStr = pvStructInfo;
+
+    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+    {
+        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+        DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
+
+        if (pbEncoded[0] != ASN_IA5STRING)
+        {
+            SetLastError(CRYPT_E_ASN1_CORRUPT);
+            ret = FALSE;
+        }
+        else
+        {
+            bytesNeeded += dataLen;
+            if (pcbDecoded)
+                *pcbDecoded = 1 + lenBytes + dataLen;
+            if (!pvStructInfo)
+                *pcbStructInfo = bytesNeeded;
+            else if (*pcbStructInfo < bytesNeeded)
+            {
+                *pcbStructInfo = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                *pcbStructInfo = bytesNeeded;
+                if (dataLen)
+                {
+                    LPSTR str = *pStr;
+
+                    assert(str);
+                    memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
+                    str[dataLen] = 0;
+                }
+                else
+                    *pStr = NULL;
+            }
+        }
+    }
+    return ret;
+}
+
+static BOOL CRYPT_AsnDecodeIntArray(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+     CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
+    struct GenericArray *array = pvStructInfo;
+    BOOL ret;
+
+    TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
+
+    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
+     NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
+     array ? array->rgItems : NULL);
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
+static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+    BOOL ret;
+    struct AsnDecodeSequenceItem items[] = {
+     { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
+       pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
+       offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
+     { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
+       cNoticeNumbers), CRYPT_AsnDecodeIntArray, sizeof(struct GenericArray),
+       FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
+       rgNoticeNumbers), 0 },
+    };
+    DWORD bytesNeeded;
+
+    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+     pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
+     NULL);
+    if (ret)
+    {
+        /* The caller is expecting a pointer to a
+         * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
+         * CRYPT_AsnDecodeSequence is decoding a
+         * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.  Increment the bytes
+         * needed, and decode again if the requisite space is available.
+         */
+        bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
+        if (!pvStructInfo)
+            *pcbStructInfo = bytesNeeded;
+        else if (*pcbStructInfo < bytesNeeded)
+        {
+            *pcbStructInfo = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
+
+            *pcbStructInfo = bytesNeeded;
+            /* The pointer (pvStructInfo) passed in points to the first dynamic
+             * pointer, so use it as the pointer to the
+             * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
+             * appropriate offset for the first dynamic pointer within the
+             * notice reference by pointing to the first memory location past
+             * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
+             */
+            noticeRef =
+             *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
+            noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
+             sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
+            ret = CRYPT_AsnDecodeSequence(items,
+             sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
+             NULL, noticeRef, &bytesNeeded, pcbDecoded,
+             noticeRef->pszOrganization);
+        }
+    }
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
+static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+    BOOL ret = TRUE;
+    DWORD dataLen;
+
+    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+    {
+        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+        DWORD bytesNeeded = sizeof(LPWSTR);
+
+        switch (pbEncoded[0])
+        {
+        case ASN_NUMERICSTRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_PRINTABLESTRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_IA5STRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_T61STRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_VIDEOTEXSTRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_GRAPHICSTRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_VISIBLESTRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_GENERALSTRING:
+            if (dataLen)
+                bytesNeeded += (dataLen + 1) * 2;
+            break;
+        case ASN_UNIVERSALSTRING:
+            if (dataLen)
+                bytesNeeded += dataLen / 2 + sizeof(WCHAR);
+            break;
+        case ASN_BMPSTRING:
+            if (dataLen)
+                bytesNeeded += dataLen + sizeof(WCHAR);
+            break;
+        case ASN_UTF8STRING:
+            if (dataLen)
+                bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
+                 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
+            break;
+        default:
+            SetLastError(CRYPT_E_ASN1_BADTAG);
+            return FALSE;
+        }
+
+        if (pcbDecoded)
+            *pcbDecoded = 1 + lenBytes + dataLen;
+        if (!pvStructInfo)
+            *pcbStructInfo = bytesNeeded;
+        else if (*pcbStructInfo < bytesNeeded)
+        {
+            *pcbStructInfo = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            LPWSTR *pStr = pvStructInfo;
+
+            *pcbStructInfo = bytesNeeded;
+            if (dataLen)
+            {
+                DWORD i;
+                LPWSTR str = *(LPWSTR *)pStr;
+
+                assert(str);
+                switch (pbEncoded[0])
+                {
+                case ASN_NUMERICSTRING:
+                case ASN_PRINTABLESTRING:
+                case ASN_IA5STRING:
+                case ASN_T61STRING:
+                case ASN_VIDEOTEXSTRING:
+                case ASN_GRAPHICSTRING:
+                case ASN_VISIBLESTRING:
+                case ASN_GENERALSTRING:
+                    for (i = 0; i < dataLen; i++)
+                        str[i] = pbEncoded[1 + lenBytes + i];
+                    str[i] = 0;
+                    break;
+                case ASN_UNIVERSALSTRING:
+                    for (i = 0; i < dataLen / 4; i++)
+                        str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
+                         | pbEncoded[1 + lenBytes + 2 * i + 3];
+                    str[i] = 0;
+                    break;
+                case ASN_BMPSTRING:
+                    for (i = 0; i < dataLen / 2; i++)
+                        str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
+                         pbEncoded[1 + lenBytes + 2 * i + 1];
+                    str[i] = 0;
+                    break;
+                case ASN_UTF8STRING:
+                {
+                    int len = MultiByteToWideChar(CP_UTF8, 0,
+                     (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
+                     str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
+                    str[len] = 0;
+                    break;
+                }
+                }
+            }
+            else
+                *pStr = NULL;
+        }
+    }
+    return ret;
+}
+
+static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
+ const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
+ DWORD *pcbStructInfo, DWORD *pcbDecoded)
+{
+    BOOL ret;
+    struct AsnDecodeSequenceItem items[] = {
+     { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
+       pNoticeReference), CRYPT_AsnDecodeNoticeReference,
+       sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
+       offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
+     { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
+       CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
+       offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
+    };
+    PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
+
+    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, *pcbStructInfo);
+
+    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+     pcbDecoded, notice ? notice->pNoticeReference : NULL);
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
+ DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret = FALSE;
+
+    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pDecodePara, pvStructInfo, *pcbStructInfo);
+
+    __TRY
+    {
+        DWORD bytesNeeded;
+
+        ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
+         cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
+         NULL);
+        if (ret)
+        {
+            if (!pvStructInfo)
+                *pcbStructInfo = bytesNeeded;
+            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+             pvStructInfo, pcbStructInfo, bytesNeeded)))
+            {
+                PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
+
+                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+                    pvStructInfo = *(BYTE **)pvStructInfo;
+                notice = pvStructInfo;
+                notice->pNoticeReference =
+                 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
+                 ((BYTE *)pvStructInfo +
+                 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
+                ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
+                 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+                 pvStructInfo, &bytesNeeded, NULL);
+            }
+        }
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
  DWORD *pcbDecoded)
@@ -2581,7 +2922,7 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
             {
                 *pcbStructInfo = bytesNeeded;
                 /* MS used values one greater than the asn1 ones.. sigh */
-                entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
+                entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
                 switch (pbEncoded[0] & ASN_TYPE_MASK)
                 {
                 case 1: /* rfc822Name */
@@ -2599,7 +2940,6 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
                     break;
                 }
                 case 4: /* directoryName */
-                    entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
                     /* The data are memory-equivalent with the IPAddress case,
                      * fall-through
                      */
@@ -3115,6 +3455,100 @@ static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
     return ret;
 }
 
+static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+    struct AsnDecodeSequenceItem items[] = {
+     { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
+       pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
+       FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
+       0 },
+     { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
+       CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
+       offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
+    };
+    BOOL ret;
+    CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
+
+    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+     pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
+    return ret;
+}
+
+static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+    BOOL ret;
+    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+     CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
+     offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
+    struct GenericArray *entries = pvStructInfo;
+
+    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
+     NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
+     entries ? entries->rgItems : NULL);
+    TRACE("Returning %d (%08x)\n", ret, GetLastError());
+    return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
+ DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
+{
+    struct AsnDecodeSequenceItem items[] = {
+     { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
+       CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
+       offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
+     { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
+       CRYPT_AsnDecodePolicyQualifiers, sizeof(struct GenericArray), TRUE,
+       TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
+    };
+    CERT_POLICY_INFO *info = pvStructInfo;
+    BOOL ret;
+
+    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+     pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret = FALSE;
+
+    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+    __TRY
+    {
+        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+         CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
+         offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
+
+        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
+         pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    return ret;
+}
+
 #define RSA1_MAGIC 0x31415352
 
 struct DECODED_RSA_PUB_KEY
@@ -3294,64 +3728,54 @@ static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
 {
     BOOL ret;
+    DWORD bytesNeeded, dataLen;
+    BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
 
     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
      pvStructInfo, *pcbStructInfo, pcbDecoded);
 
-    if (pbEncoded[0] == ASN_BITSTRING)
+    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
     {
-        DWORD bytesNeeded, dataLen;
-        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
-
-        if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+        if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
+            bytesNeeded = sizeof(CRYPT_BIT_BLOB);
+        else
+            bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
+        if (pcbDecoded)
+            *pcbDecoded = 1 + lenBytes + dataLen;
+        if (!pvStructInfo)
+            *pcbStructInfo = bytesNeeded;
+        else if (*pcbStructInfo < bytesNeeded)
+        {
+            *pcbStructInfo = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
         {
+            CRYPT_BIT_BLOB *blob;
+
+            *pcbStructInfo = bytesNeeded;
+            blob = (CRYPT_BIT_BLOB *)pvStructInfo;
+            blob->cbData = dataLen - 1;
+            blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
-                bytesNeeded = sizeof(CRYPT_BIT_BLOB);
-            else
-                bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
-            if (pcbDecoded)
-                *pcbDecoded = 1 + lenBytes + dataLen;
-            if (!pvStructInfo)
-                *pcbStructInfo = bytesNeeded;
-            else if (*pcbStructInfo < bytesNeeded)
             {
-                *pcbStructInfo = bytesNeeded;
-                SetLastError(ERROR_MORE_DATA);
-                ret = FALSE;
+                blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
             }
             else
             {
-                CRYPT_BIT_BLOB *blob;
-
-                *pcbStructInfo = bytesNeeded;
-                blob = (CRYPT_BIT_BLOB *)pvStructInfo;
-                blob->cbData = dataLen - 1;
-                blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
-                if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
-                {
-                    blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
-                }
-                else
+                assert(blob->pbData);
+                if (blob->cbData)
                 {
-                    assert(blob->pbData);
-                    if (blob->cbData)
-                    {
-                        BYTE mask = 0xff << blob->cUnusedBits;
+                    BYTE mask = 0xff << blob->cUnusedBits;
 
-                        memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
-                         blob->cbData);
-                        blob->pbData[blob->cbData - 1] &= mask;
-                    }
+                    memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
+                     blob->cbData);
+                    blob->pbData[blob->cbData - 1] &= mask;
                 }
             }
         }
     }
-    else
-    {
-        SetLastError(CRYPT_E_ASN1_BADTAG);
-        ret = FALSE;
-    }
-    TRACE("returning %d (%08x)\n", ret, GetLastError());
     return ret;
 }
 
@@ -3368,7 +3792,17 @@ static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
     {
         DWORD bytesNeeded;
 
-        if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
+        if (!cbEncoded)
+        {
+            SetLastError(CRYPT_E_ASN1_CORRUPT);
+            ret = FALSE;
+        }
+        else if (pbEncoded[0] != ASN_BITSTRING)
+        {
+            SetLastError(CRYPT_E_ASN1_BADTAG);
+            ret = FALSE;
+        }
+        else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
         {
             if (!pvStructInfo)
@@ -3450,7 +3884,7 @@ static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
 
         if (!cbEncoded)
         {
-            SetLastError(CRYPT_E_ASN1_CORRUPT);
+            SetLastError(CRYPT_E_ASN1_EOD);
             ret = FALSE;
         }
         else if (pbEncoded[0] != ASN_INTEGER)
@@ -4245,11 +4679,12 @@ static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
        CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
        offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
     };
+    CRL_DIST_POINT *point = (CRL_DIST_POINT *)pvStructInfo;
     BOOL ret;
 
     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
-     pcbDecoded, NULL);
+     pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
     return ret;
 }
 
@@ -4808,6 +5243,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
         case LOWORD(X509_BASIC_CONSTRAINTS2):
             decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
             break;
+        case LOWORD(X509_CERT_POLICIES):
+            decodeFunc = CRYPT_AsnDecodeCertPolicies;
+            break;
         case LOWORD(RSA_CSP_PUBLICKEYBLOB):
             decodeFunc = CRYPT_AsnDecodeRsaPubKey;
             break;
@@ -4869,6 +5307,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
         case LOWORD(PKCS_SMIME_CAPABILITIES):
             decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
             break;
+        case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
+            decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
+            break;
         case LOWORD(PKCS_ATTRIBUTES):
             decodeFunc = CRYPT_AsnDecodePKCSAttributes;
             break;
@@ -4918,6 +5359,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
         decodeFunc = CRYPT_AsnDecodeAltName;
     else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
         decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
+    else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
+        decodeFunc = CRYPT_AsnDecodeCertPolicies;
     else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
         decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
     else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
@@ -4926,6 +5369,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
         decodeFunc = CRYPT_AsnDecodeNameConstraints;
     else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
         decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
+    else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
+        decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
     else if (!strcmp(lpszStructType, szOID_CTL))
         decodeFunc = CRYPT_AsnDecodeCTL;
     return decodeFunc;
@@ -4975,11 +5420,6 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    if (!cbEncoded)
-    {
-        SetLastError(CRYPT_E_ASN1_EOD);
-        return FALSE;
-    }
     if (cbEncoded > MAX_ENCODED_LEN)
     {
         SetLastError(CRYPT_E_ASN1_LARGE);
@@ -5027,11 +5467,6 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    if (!cbEncoded)
-    {
-        SetLastError(CRYPT_E_ASN1_EOD);
-        return FALSE;
-    }
     if (cbEncoded > MAX_ENCODED_LEN)
     {
         SetLastError(CRYPT_E_ASN1_LARGE);
index 9e7ed44..2440d16 100644 (file)
@@ -539,7 +539,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCertInfo(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry,
+static BOOL CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry,
  BYTE *pbEncoded, DWORD *pcbEncoded)
 {
     struct AsnEncodeSequenceItem items[3] = {
@@ -796,7 +796,7 @@ BOOL WINAPI CRYPT_AsnEncodeOid(DWORD dwCertEncodingType,
         const char *ptr;
         int val1, val2;
 
-        if (sscanf(pszObjId, "%d.%d.%n", &val1, &val2, &firstPos) != 2)
+        if (sscanf(pszObjId, "%d.%d%n", &val1, &val2, &firstPos) != 2)
         {
             SetLastError(CRYPT_E_ASN1_ERROR);
             return FALSE;
@@ -804,6 +804,11 @@ BOOL WINAPI CRYPT_AsnEncodeOid(DWORD dwCertEncodingType,
         bytesNeeded++;
         firstByte = val1 * 40 + val2;
         ptr = pszObjId + firstPos;
+        if (*ptr == '.')
+        {
+            ptr++;
+            firstPos++;
+        }
         while (ret && *ptr)
         {
             int pos;
@@ -900,7 +905,7 @@ static BOOL CRYPT_AsnEncodeStringCoerce(const CERT_NAME_VALUE *value,
     LPCSTR str = (LPCSTR)value->Value.pbData;
     DWORD bytesNeeded, lenBytes, encodedLen;
 
-    encodedLen = value->Value.cbData ? value->Value.cbData : lstrlenA(str);
+    encodedLen = value->Value.cbData ? value->Value.cbData : strlen(str);
     CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
     bytesNeeded = 1 + lenBytes + encodedLen;
     if (!pbEncoded)
@@ -970,7 +975,7 @@ static BOOL CRYPT_AsnEncodeUTF8String(const CERT_NAME_VALUE *value,
     DWORD bytesNeeded, lenBytes, encodedLen, strLen;
 
     strLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
-     lstrlenW(str);
+     strlenW(str);
     encodedLen = WideCharToMultiByte(CP_UTF8, 0, str, strLen, NULL, 0, NULL,
      NULL);
     CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
@@ -1078,7 +1083,7 @@ static BOOL WINAPI CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType,
  CERT_RDN_ATTR *attr, CryptEncodeObjectExFunc nameValueEncodeFunc,
  BYTE *pbEncoded, DWORD *pcbEncoded)
 {
@@ -1271,7 +1276,7 @@ static BOOL WINAPI CRYPT_DEREncodeItemsAsSet(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn,
+static BOOL CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn,
  CryptEncodeObjectExFunc nameValueEncodeFunc, BYTE *pbEncoded,
  DWORD *pcbEncoded)
 {
@@ -1470,7 +1475,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCTLSubjectAlgorithm(
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeCTLEntry(const CTL_ENTRY *entry,
+static BOOL CRYPT_AsnEncodeCTLEntry(const CTL_ENTRY *entry,
  BYTE *pbEncoded, DWORD *pcbEncoded)
 {
     struct AsnEncodeSequenceItem items[2] = {
@@ -1604,7 +1609,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCTL(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeSMIMECapability(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnEncodeSMIMECapability(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
@@ -1697,6 +1702,114 @@ static BOOL WINAPI CRYPT_AsnEncodeSMIMECapabilities(DWORD dwCertEncodingType,
     return ret;
 }
 
+static BOOL WINAPI CRYPT_AsnEncodeNoticeNumbers(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    const CERT_POLICY_QUALIFIER_NOTICE_REFERENCE *noticeRef = pvStructInfo;
+    DWORD bytesNeeded, dataLen, lenBytes, i;
+    BOOL ret = TRUE;
+
+    for (i = 0, dataLen = 0; ret && i < noticeRef->cNoticeNumbers; i++)
+    {
+        DWORD size;
+
+        ret = CRYPT_AsnEncodeInt(dwCertEncodingType, X509_INTEGER,
+         &noticeRef->rgNoticeNumbers[i], 0, NULL, NULL, &size);
+        if (ret)
+            dataLen += size;
+    }
+    if (ret)
+    {
+        CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
+        bytesNeeded = 1 + lenBytes + dataLen;
+        if (!pbEncoded)
+            *pcbEncoded = bytesNeeded;
+        else
+        {
+            if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
+             pcbEncoded, bytesNeeded)))
+            {
+                if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
+                    pbEncoded = *(BYTE **)pbEncoded;
+                *pbEncoded++ = ASN_SEQUENCE;
+                CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
+                pbEncoded += lenBytes;
+                for (i = 0; i < noticeRef->cNoticeNumbers; i++)
+                {
+                    DWORD size = dataLen;
+
+                    ret = CRYPT_AsnEncodeInt(dwCertEncodingType, X509_INTEGER,
+                     &noticeRef->rgNoticeNumbers[i], 0, NULL, pbEncoded, &size);
+                    pbEncoded += size;
+                    dataLen -= size;
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnEncodeNoticeReference(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    const CERT_POLICY_QUALIFIER_NOTICE_REFERENCE *noticeRef = pvStructInfo;
+    BOOL ret;
+    CERT_NAME_VALUE orgValue = { CERT_RDN_IA5_STRING,
+     { 0, (LPBYTE)noticeRef->pszOrganization } };
+    struct AsnEncodeSequenceItem items[] = {
+     { &orgValue, CRYPT_AsnEncodeNameValue, 0 },
+     { noticeRef, CRYPT_AsnEncodeNoticeNumbers, 0 },
+    };
+
+    ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
+     sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+     pcbEncoded);
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnEncodePolicyQualifierUserNotice(
+ DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
+ DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret = FALSE;
+
+    __TRY
+    {
+        const CERT_POLICY_QUALIFIER_USER_NOTICE *notice = pvStructInfo;
+        struct AsnEncodeSequenceItem items[2];
+        CERT_NAME_VALUE displayTextValue;
+        DWORD cItem = 0;
+
+        ret = TRUE;
+        if (notice->pNoticeReference)
+        {
+            items[cItem].encodeFunc = CRYPT_AsnEncodeNoticeReference;
+            items[cItem].pvStructInfo = notice->pNoticeReference;
+            cItem++;
+        }
+        if (notice->pszDisplayText)
+        {
+            displayTextValue.dwValueType = CERT_RDN_BMP_STRING;
+            displayTextValue.Value.cbData = 0;
+            displayTextValue.Value.pbData = (LPBYTE)notice->pszDisplayText;
+            items[cItem].encodeFunc = CRYPT_AsnEncodeNameValue;
+            items[cItem].pvStructInfo = &displayTextValue;
+            cItem++;
+        }
+        ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
+         dwFlags, pEncodePara, pbEncoded, pcbEncoded);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    return ret;
+}
+
 static BOOL WINAPI CRYPT_AsnEncodePKCSAttribute(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@@ -1830,7 +1943,7 @@ static BOOL CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE *value,
     DWORD bytesNeeded, lenBytes, encodedLen;
 
     encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
-     lstrlenW(str);
+     strlenW(str);
     CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
     bytesNeeded = 1 + lenBytes + encodedLen;
     if (!pbEncoded)
@@ -1871,7 +1984,7 @@ static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value,
     DWORD bytesNeeded, lenBytes, encodedLen;
 
     encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
-     lstrlenW(str);
+     strlenW(str);
     CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
     bytesNeeded = 1 + lenBytes + encodedLen;
     if (!pbEncoded)
@@ -1925,7 +2038,7 @@ static BOOL CRYPT_AsnEncodePrintableString(const CERT_NAME_VALUE *value,
     DWORD bytesNeeded, lenBytes, encodedLen;
 
     encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
-     lstrlenW(str);
+     strlenW(str);
     CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
     bytesNeeded = 1 + lenBytes + encodedLen;
     if (!pbEncoded)
@@ -1972,7 +2085,7 @@ static BOOL CRYPT_AsnEncodeIA5String(const CERT_NAME_VALUE *value,
     DWORD bytesNeeded, lenBytes, encodedLen;
 
     encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
-     lstrlenW(str);
+     strlenW(str);
     CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
     bytesNeeded = 1 + lenBytes + encodedLen;
     if (!pbEncoded)
@@ -2020,7 +2133,7 @@ static BOOL CRYPT_AsnEncodeUniversalString(const CERT_NAME_VALUE *value,
 
     /* FIXME: doesn't handle composite characters */
     strLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
-     lstrlenW(str);
+     strlenW(str);
     CRYPT_EncodeLen(strLen * 4, NULL, &lenBytes);
     bytesNeeded = 1 + lenBytes + strLen * 4;
     if (!pbEncoded)
@@ -2550,7 +2663,7 @@ static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId2(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeAccessDescription(
+static BOOL CRYPT_AsnEncodeAccessDescription(
  const CERT_ACCESS_DESCRIPTION *descr, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
     struct AsnEncodeSequenceItem items[] = {
@@ -2704,6 +2817,162 @@ static BOOL WINAPI CRYPT_AsnEncodeBasicConstraints2(DWORD dwCertEncodingType,
     return ret;
 }
 
+static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    DWORD cPolicyQualifier = *(DWORD *)pvStructInfo;
+    const CERT_POLICY_QUALIFIER_INFO *rgPolicyQualifier =
+     *(const CERT_POLICY_QUALIFIER_INFO **)
+     ((LPBYTE)pvStructInfo + sizeof(DWORD));
+    BOOL ret;
+
+    if (!cPolicyQualifier)
+    {
+        *pcbEncoded = 0;
+        ret = TRUE;
+    }
+    else
+    {
+        struct AsnEncodeSequenceItem items[2] = {
+         { NULL, CRYPT_AsnEncodeOid, 0 },
+         { NULL, CRYPT_CopyEncodedBlob, 0 },
+        };
+        DWORD bytesNeeded = 0, lenBytes, size, i;
+
+        ret = TRUE;
+        for (i = 0; ret && i < cPolicyQualifier; i++)
+        {
+            items[0].pvStructInfo = rgPolicyQualifier[i].pszPolicyQualifierId;
+            items[1].pvStructInfo = &rgPolicyQualifier[i].Qualifier;
+            ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
+             sizeof(items) / sizeof(items[0]),
+             dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &size);
+            if (ret)
+                bytesNeeded += size;
+        }
+        CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
+        bytesNeeded += 1 + lenBytes;
+        if (ret)
+        {
+            if (!pbEncoded)
+                *pcbEncoded = bytesNeeded;
+            else
+            {
+                if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
+                 pbEncoded, pcbEncoded, bytesNeeded)))
+                {
+                    if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
+                        pbEncoded = *(BYTE **)pbEncoded;
+                    *pbEncoded++ = ASN_SEQUENCEOF;
+                    CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
+                     &lenBytes);
+                    pbEncoded += lenBytes;
+                    for (i = 0; ret && i < cPolicyQualifier; i++)
+                    {
+                        items[0].pvStructInfo =
+                         rgPolicyQualifier[i].pszPolicyQualifierId;
+                        items[1].pvStructInfo =
+                         &rgPolicyQualifier[i].Qualifier;
+                        size = bytesNeeded;
+                        ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
+                         sizeof(items) / sizeof(items[0]),
+                         dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, pbEncoded,
+                         &size);
+                        if (ret)
+                        {
+                            pbEncoded += size;
+                            bytesNeeded -= size;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+static BOOL CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType,
+ const CERT_POLICY_INFO *info, DWORD dwFlags, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    struct AsnEncodeSequenceItem items[2] = {
+     { info->pszPolicyIdentifier, CRYPT_AsnEncodeOid, 0 },
+     { &info->cPolicyQualifier,   CRYPT_AsnEncodeCertPolicyQualifiers, 0 },
+    };
+    BOOL ret;
+
+    if (!info->pszPolicyIdentifier)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
+     sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded);
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnEncodeCertPolicies(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    BOOL ret = FALSE;
+
+    __TRY
+    {
+        const CERT_POLICIES_INFO *info = pvStructInfo;
+        DWORD bytesNeeded = 0, lenBytes, size, i;
+
+        ret = TRUE;
+        for (i = 0; ret && i < info->cPolicyInfo; i++)
+        {
+            ret = CRYPT_AsnEncodeCertPolicy(dwCertEncodingType,
+             &info->rgPolicyInfo[i], dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL,
+             &size);
+            if (ret)
+                bytesNeeded += size;
+        }
+        CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
+        bytesNeeded += 1 + lenBytes;
+        if (ret)
+        {
+            if (!pbEncoded)
+                *pcbEncoded = bytesNeeded;
+            else
+            {
+                if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
+                 pbEncoded, pcbEncoded, bytesNeeded)))
+                {
+                    if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
+                        pbEncoded = *(BYTE **)pbEncoded;
+                    *pbEncoded++ = ASN_SEQUENCEOF;
+                    CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
+                     &lenBytes);
+                    pbEncoded += lenBytes;
+                    for (i = 0; ret && i < info->cPolicyInfo; i++)
+                    {
+                        size = bytesNeeded;
+                        ret = CRYPT_AsnEncodeCertPolicy(dwCertEncodingType,
+                         &info->rgPolicyInfo[i],
+                         dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pbEncoded, &size);
+                        if (ret)
+                        {
+                            pbEncoded += size;
+                            bytesNeeded -= size;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    return ret;
+}
+
 static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@@ -2900,7 +3169,7 @@ static BOOL WINAPI CRYPT_AsnEncodeBitsSwapBytes(DWORD dwCertEncodingType,
     return ret;
 }
 
-BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType,
+static BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
@@ -3148,7 +3417,7 @@ static BOOL WINAPI CRYPT_AsnEncodeUtcTime(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeGeneralizedTime(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnEncodeGeneralizedTime(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
@@ -3569,7 +3838,7 @@ static BOOL WINAPI CRYPT_AsnEncodeIssuingDistPoint(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnEncodeGeneralSubtree(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnEncodeGeneralSubtree(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
@@ -4002,6 +4271,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
         case LOWORD(X509_BASIC_CONSTRAINTS2):
             encodeFunc = CRYPT_AsnEncodeBasicConstraints2;
             break;
+        case LOWORD(X509_CERT_POLICIES):
+            encodeFunc = CRYPT_AsnEncodeCertPolicies;
+            break;
         case LOWORD(RSA_CSP_PUBLICKEYBLOB):
             encodeFunc = CRYPT_AsnEncodeRsaPubKey;
             break;
@@ -4063,6 +4335,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
         case LOWORD(PKCS_SMIME_CAPABILITIES):
             encodeFunc = CRYPT_AsnEncodeSMIMECapabilities;
             break;
+        case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
+            encodeFunc = CRYPT_AsnEncodePolicyQualifierUserNotice;
+            break;
         case LOWORD(PKCS_ATTRIBUTES):
             encodeFunc = CRYPT_AsnEncodePKCSAttributes;
             break;
@@ -4112,6 +4387,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
         encodeFunc = CRYPT_AsnEncodeAltName;
     else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
         encodeFunc = CRYPT_AsnEncodeCRLDistPoints;
+    else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
+        encodeFunc = CRYPT_AsnEncodeCertPolicies;
     else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
         encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage;
     else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
@@ -4120,6 +4397,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
         encodeFunc = CRYPT_AsnEncodeNameConstraints;
     else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
         encodeFunc = CRYPT_AsnEncodeAuthorityInfoAccess;
+    else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
+        encodeFunc = CRYPT_AsnEncodePolicyQualifierUserNotice;
     else if (!strcmp(lpszStructType, szOID_CTL))
         encodeFunc = CRYPT_AsnEncodeCTL;
     return encodeFunc;
index cfa29b3..a33b828 100644 (file)
@@ -338,7 +338,7 @@ PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
              CERT_QUERY_CONTENT_FLAG_CERT |
              CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
              CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
-             CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL,
+             CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &contentType, NULL,
              &memStore, NULL, NULL);
             if (ret)
             {
index 922dd19..d93163c 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 
 static HCRYPTPROV hDefProv;
+HINSTANCE hInstance;
 
-BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
+BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
 {
     switch (fdwReason)
     {
         case DLL_PROCESS_ATTACH:
-            DisableThreadLibraryCalls(hInstance);
-            crypt_oid_init(hInstance);
+            hInstance = hInst;
+            DisableThreadLibraryCalls(hInst);
+            crypt_oid_init();
             break;
         case DLL_PROCESS_DETACH:
             crypt_oid_free();
@@ -177,7 +179,7 @@ HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(DWORD reserved)
     if (reserved)
     {
         SetLastError(E_INVALIDARG);
-        return (HCRYPTPROV)0;
+        return 0;
     }
     ret = CRYPT_GetDefaultProvider();
     CryptContextAddRef(ret, NULL, 0);
@@ -243,13 +245,3 @@ ASN1encoding_t WINAPI I_CryptGetAsn1Encoder(HCRYPTASN1MODULE x)
     FIXME("(%08x): stub\n", x);
     return NULL;
 }
-
-BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
- DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType,
- const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat)
-{
-    FIXME("(%08x, %d, %d, %p, %s, %p, %d, %p, %p): stub\n",
-     dwCertEncodingType, dwFormatType, dwFormatStrType, pFormatStruct,
-     debugstr_a(lpszStructType), pbEncoded, cbEncoded, pbFormat, pcbFormat);
-    return FALSE;
-}
index 9413dd6..7551cce 100644 (file)
@@ -60,27 +60,6 @@ LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
     return count;
 }
 
-static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src,
- DWORD len)
-{
-    BOOL ret = TRUE;
-
-    if (!pvData)
-        *pcbData = len;
-    else if (*pcbData < len)
-    {
-        *pcbData = len;
-        SetLastError(ERROR_MORE_DATA);
-        ret = FALSE;
-    }
-    else
-    {
-        *pcbData = len;
-        memcpy(pvData, src, len);
-    }
-    return ret;
-}
-
 static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
  DWORD dwSignerIndex)
 {
@@ -101,6 +80,8 @@ static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
             }
         }
     }
+    else
+        SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE);
     return certInfo;
 }
 
@@ -124,13 +105,87 @@ static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg,
      pVerifyPara->dwMsgAndCertEncodingType, certInfo, store);
 }
 
+BOOL WINAPI CryptVerifyDetachedMessageSignature(
+ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex,
+ const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned,
+ const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[],
+ PCCERT_CONTEXT *ppSignerCert)
+{
+    BOOL ret = FALSE;
+    HCRYPTMSG msg;
+
+    TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex,
+     pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned,
+     rgcbToBeSigned, ppSignerCert);
+
+    if (ppSignerCert)
+        *ppSignerCert = NULL;
+    if (!pVerifyPara ||
+     pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) ||
+     GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) !=
+     PKCS_7_ASN_ENCODING)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+
+    msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType,
+     CMSG_DETACHED_FLAG, 0, pVerifyPara->hCryptProv, NULL, NULL);
+    if (msg)
+    {
+        ret = CryptMsgUpdate(msg, pbDetachedSignBlob, cbDetachedSignBlob, TRUE);
+        if (ret)
+        {
+            DWORD i;
+
+            for (i = 0; ret && i < cToBeSigned; i++)
+                ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
+                 i == cToBeSigned - 1 ? TRUE : FALSE);
+        }
+        if (ret)
+        {
+            CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
+             dwSignerIndex);
+
+            ret = FALSE;
+            if (certInfo)
+            {
+                HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG,
+                 pVerifyPara->dwMsgAndCertEncodingType,
+                 pVerifyPara->hCryptProv, 0, msg);
+
+                if (store)
+                {
+                    PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate(
+                     msg, pVerifyPara, certInfo, store);
+
+                    if (cert)
+                    {
+                        ret = CryptMsgControl(msg, 0,
+                         CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
+                        if (ret && ppSignerCert)
+                            *ppSignerCert = cert;
+                        else
+                            CertFreeCertificateContext(cert);
+                    }
+                    else
+                        SetLastError(CRYPT_E_NOT_FOUND);
+                    CertCloseStore(store, 0);
+                }
+                CryptMemFree(certInfo);
+            }
+        }
+        CryptMsgClose(msg);
+    }
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
 BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
  BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
 {
     BOOL ret = FALSE;
-    DWORD size;
-    CRYPT_CONTENT_INFO *contentInfo;
     HCRYPTMSG msg;
 
     TRACE("(%p, %d, %p, %d, %p, %p, %p)\n",
@@ -150,26 +205,14 @@ BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
         return FALSE;
     }
 
-    if (!CryptDecodeObjectEx(pVerifyPara->dwMsgAndCertEncodingType,
-     PKCS_CONTENT_INFO, pbSignedBlob, cbSignedBlob,
-     CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
-     (LPBYTE)&contentInfo, &size))
-        return FALSE;
-    if (strcmp(contentInfo->pszObjId, szOID_RSA_signedData))
-    {
-        LocalFree(contentInfo);
-        SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE);
-        return FALSE;
-    }
-    msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0,
-     CMSG_SIGNED, pVerifyPara->hCryptProv, NULL, NULL);
+    msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0, 0,
+     pVerifyPara->hCryptProv, NULL, NULL);
     if (msg)
     {
-        ret = CryptMsgUpdate(msg, contentInfo->Content.pbData,
-         contentInfo->Content.cbData, TRUE);
+        ret = CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE);
         if (ret && pcbDecoded)
-            ret = CRYPT_CopyParam(pbDecoded, pcbDecoded,
-             contentInfo->Content.pbData, contentInfo->Content.cbData);
+            ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbDecoded,
+             pcbDecoded);
         if (ret)
         {
             CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
@@ -203,7 +246,6 @@ BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
         }
         CryptMsgClose(msg);
     }
-    LocalFree(contentInfo);
     TRACE("returning %d\n", ret);
     return ret;
 }
@@ -318,3 +360,45 @@ BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,
     }
     return ret;
 }
+
+BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,
+ BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed,
+ DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash)
+{
+    HCRYPTMSG msg;
+    BOOL ret = FALSE;
+
+    TRACE("(%p, %p, %d, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob,
+     cbHashedBlob, pbToBeHashed, pcbToBeHashed, pbComputedHash,
+     pcbComputedHash);
+
+    if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
+     PKCS_7_ASN_ENCODING)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, 0, 0,
+     pHashPara->hCryptProv, NULL, NULL);
+    if (msg)
+    {
+        ret = CryptMsgUpdate(msg, pbHashedBlob, cbHashedBlob, TRUE);
+        if (ret)
+        {
+            ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
+            if (ret && pcbToBeHashed)
+                ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0,
+                 pbToBeHashed, pcbToBeHashed);
+            if (ret && pcbComputedHash)
+                ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
+                 pbComputedHash, pcbComputedHash);
+        }
+        CryptMsgClose(msg);
+    }
+    return ret;
+}
index 1c07e05..7c90d75 100644 (file)
@@ -46,7 +46,7 @@ typedef BOOL (*CryptMsgUpdateFunc)(HCRYPTMSG hCryptMsg, const BYTE *pbData,
 typedef BOOL (*CryptMsgControlFunc)(HCRYPTMSG hCryptMsg, DWORD dwFlags,
  DWORD dwCtrlType, const void *pvCtrlPara);
 
-BOOL CRYPT_DefaultMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
+static BOOL CRYPT_DefaultMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
  DWORD dwCtrlType, const void *pvCtrlPara)
 {
     TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara);
@@ -1341,7 +1341,7 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags,
         return NULL;
     }
     if (info->cbSize == sizeof(CMSG_SIGNED_ENCODE_INFO_WITH_CMS) &&
-     info->rgAttrCertEncoded)
+     info->cAttrCertEncoded)
     {
         FIXME("CMSG_SIGNED_ENCODE_INFO with CMS fields unsupported\n");
         return NULL;
@@ -1723,15 +1723,13 @@ static BOOL CDecodeMsg_FinalizeHashedContent(CDecodeMsg *msg,
         {
             /* Unlike for non-detached messages, the data were never stored as
              * the content param, but were saved in msg->detached_data instead.
-             * Set the content property with the detached data so the data may
-             * be hashed.
              */
-            ContextPropertyList_SetProperty(msg->properties,
-             CMSG_CONTENT_PARAM, msg->detached_data.pbData,
-             msg->detached_data.cbData);
+            content.pbData = msg->detached_data.pbData;
+            content.cbData = msg->detached_data.cbData;
         }
-        ret = ContextPropertyList_FindProperty(msg->properties,
-         CMSG_CONTENT_PARAM, &content);
+        else
+            ret = ContextPropertyList_FindProperty(msg->properties,
+             CMSG_CONTENT_PARAM, &content);
         if (ret)
             ret = CryptHashData(msg->u.hash, content.pbData, content.cbData, 0);
     }
@@ -1972,8 +1970,7 @@ static inline void CRYPT_CopyAttributes(CRYPT_ATTRIBUTES *out,
     {
         DWORD i;
 
-        if ((*nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
-            *nextData += (*nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+        *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
         out->rgAttr = (CRYPT_ATTRIBUTE *)*nextData;
         *nextData += in->cAttr * sizeof(CRYPT_ATTRIBUTE);
         for (i = 0; i < in->cAttr; i++)
@@ -1989,8 +1986,7 @@ static inline void CRYPT_CopyAttributes(CRYPT_ATTRIBUTES *out,
                 DWORD j;
 
                 out->rgAttr[i].cValue = in->rgAttr[i].cValue;
-                if ((*nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
-                    *nextData += (*nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+                *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
                 out->rgAttr[i].rgValue = (PCRYPT_DATA_BLOB)*nextData;
                 *nextData += in->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
                 for (j = 0; j < in->rgAttr[i].cValue; j++)
@@ -2010,15 +2006,13 @@ static DWORD CRYPT_SizeOfAttributes(const CRYPT_ATTRIBUTES *attr)
         if (attr->rgAttr[i].pszObjId)
             size += strlen(attr->rgAttr[i].pszObjId) + 1;
         /* align pointer */
-        if (size % sizeof(DWORD_PTR))
-            size += size % sizeof(DWORD_PTR);
+        size = ALIGN_DWORD_PTR(size);
         size += attr->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
         for (j = 0; j < attr->rgAttr[i].cValue; j++)
             size += attr->rgAttr[i].rgValue[j].cbData;
     }
     /* align pointer again to be conservative */
-    if (size % sizeof(DWORD_PTR))
-        size += size % sizeof(DWORD_PTR);
+    size = ALIGN_DWORD_PTR(size);
     return size;
 }
 
@@ -2096,8 +2090,7 @@ static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData,
     size += in->HashEncryptionAlgorithm.Parameters.cbData;
     size += in->EncryptedHash.cbData;
     /* align pointer */
-    if (size % sizeof(DWORD_PTR))
-        size += size % sizeof(DWORD_PTR);
+    size = ALIGN_DWORD_PTR(size);
     size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
     size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
     if (!pvData)
@@ -2135,9 +2128,7 @@ static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData,
             CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
              &in->HashEncryptionAlgorithm, &nextData);
             CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
-            /* align pointer */
-            if ((nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
-                nextData += (nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+            nextData = POINTER_ALIGN_DWORD_PTR(nextData);
             CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
             CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
         }
@@ -2169,8 +2160,7 @@ static BOOL CRYPT_CopyCMSSignerInfo(void *pvData, DWORD *pcbData,
     size += in->HashEncryptionAlgorithm.Parameters.cbData;
     size += in->EncryptedHash.cbData;
     /* align pointer */
-    if (size % sizeof(DWORD_PTR))
-        size += size % sizeof(DWORD_PTR);
+    size = ALIGN_DWORD_PTR(size);
     size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
     size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
     if (!pvData)
@@ -2205,9 +2195,7 @@ static BOOL CRYPT_CopyCMSSignerInfo(void *pvData, DWORD *pcbData,
         CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
          &in->HashEncryptionAlgorithm, &nextData);
         CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
-        /* align pointer */
-        if ((nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
-            nextData += (nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+        nextData = POINTER_ALIGN_DWORD_PTR(nextData);
         CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
         CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
         ret = TRUE;
@@ -2556,6 +2544,11 @@ static BOOL CDecodeSignedMsg_VerifySignature(CDecodeMsg *msg, PCERT_INFO info)
     BOOL ret = FALSE;
     DWORD i;
 
+    if (!msg->u.signed_data.signerHandles)
+    {
+        SetLastError(NTE_BAD_SIGNATURE);
+        return FALSE;
+    }
     for (i = 0; !ret && i < msg->u.signed_data.info->cSignerInfo; i++)
     {
         PCMSG_CMS_SIGNER_INFO signerInfo =
@@ -2598,6 +2591,8 @@ static BOOL CDecodeSignedMsg_VerifySignatureEx(CDecodeMsg *msg,
         SetLastError(ERROR_INVALID_PARAMETER);
     else if (para->dwSignerIndex >= msg->u.signed_data.info->cSignerInfo)
         SetLastError(CRYPT_E_SIGNER_NOT_FOUND);
+    else if (!msg->u.signed_data.signerHandles)
+        SetLastError(NTE_BAD_SIGNATURE);
     else
     {
         switch (para->dwSignerType)
index 05a6c5f..202f458 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 #include <stdarg.h>
+#define NONAMELESSUNION
 #include "windef.h"
 #include "winbase.h"
 #include "wincrypt.h"
 #include "mssip.h"
+#include "winuser.h"
+#include "wintrust.h"
 #include "crypt32_private.h"
+#include "cryptres.h"
+#include "wine/unicode.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@@ -56,15 +61,46 @@ static BOOL CRYPT_ReadBlobFromFile(LPCWSTR fileName, PCERT_BLOB blob)
     return ret;
 }
 
+static BOOL CRYPT_QueryContextBlob(const CERT_BLOB *blob,
+ DWORD dwExpectedContentTypeFlags, HCERTSTORE store,
+ DWORD *contentType, const void **ppvContext)
+{
+    BOOL ret = FALSE;
+
+    if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT)
+    {
+        ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING,
+         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
+        if (ret && contentType)
+            *contentType = CERT_QUERY_CONTENT_CERT;
+    }
+    if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL))
+    {
+        ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
+         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
+        if (ret && contentType)
+            *contentType = CERT_QUERY_CONTENT_CRL;
+    }
+    if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
+    {
+        ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
+         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
+        if (ret && contentType)
+            *contentType = CERT_QUERY_CONTENT_CTL;
+    }
+    return ret;
+}
+
 static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject,
- DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType,
- DWORD *pdwContentType, HCERTSTORE *phCertStore, const void **ppvContext)
+ DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
+ DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
+ HCERTSTORE *phCertStore, const void **ppvContext)
 {
     CERT_BLOB fileBlob;
     const CERT_BLOB *blob;
     HCERTSTORE store;
-    DWORD contentType;
     BOOL ret;
+    DWORD formatType = 0;
 
     switch (dwObjectType)
     {
@@ -86,36 +122,54 @@ static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject,
     if (!ret)
         return FALSE;
 
+    ret = FALSE;
     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
      CERT_STORE_CREATE_NEW_FLAG, NULL);
-    ret = FALSE;
-    if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT)
-    {
-        ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING,
-         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
-        if (ret)
-            contentType = CERT_QUERY_CONTENT_CERT;
-    }
-    if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL))
+    if (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY)
     {
-        ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
-         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
+        ret = CRYPT_QueryContextBlob(blob, dwExpectedContentTypeFlags, store,
+         pdwContentType, ppvContext);
         if (ret)
-            contentType = CERT_QUERY_CONTENT_CRL;
+            formatType = CERT_QUERY_FORMAT_BINARY;
     }
-    if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
+    if (!ret &&
+     (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED))
     {
-        ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
-         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
+        CRYPT_DATA_BLOB trimmed = { blob->cbData, blob->pbData };
+        CRYPT_DATA_BLOB decoded;
+
+        while (trimmed.cbData && !trimmed.pbData[trimmed.cbData - 1])
+            trimmed.cbData--;
+        ret = CryptStringToBinaryA((LPSTR)trimmed.pbData, trimmed.cbData,
+         CRYPT_STRING_BASE64_ANY, NULL, &decoded.cbData, NULL, NULL);
         if (ret)
-            contentType = CERT_QUERY_CONTENT_CTL;
+        {
+            decoded.pbData = CryptMemAlloc(decoded.cbData);
+            if (decoded.pbData)
+            {
+                ret = CryptStringToBinaryA((LPSTR)trimmed.pbData,
+                 trimmed.cbData, CRYPT_STRING_BASE64_ANY, decoded.pbData,
+                 &decoded.cbData, NULL, NULL);
+                if (ret)
+                {
+                    ret = CRYPT_QueryContextBlob(&decoded,
+                     dwExpectedContentTypeFlags, store, pdwContentType,
+                     ppvContext);
+                    if (ret)
+                        formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
+                }
+                CryptMemFree(decoded.pbData);
+            }
+            else
+                ret = FALSE;
+        }
     }
     if (ret)
     {
         if (pdwMsgAndCertEncodingType)
             *pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
-        if (pdwContentType)
-            *pdwContentType = contentType;
+        if (pdwFormatType)
+            *pdwFormatType = formatType;
         if (phCertStore)
             *phCertStore = CertDuplicateStore(store);
     }
@@ -158,6 +212,7 @@ static BOOL CRYPT_QuerySerializedContextObject(DWORD dwObjectType,
     if (!ret)
         return FALSE;
 
+    ret = FALSE;
     context = CRYPT_ReadSerializedElement(blob->pbData, blob->cbData,
      CERT_STORE_ALL_CONTEXT_FLAG, &contextType);
     if (context)
@@ -267,16 +322,127 @@ static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
     return ret;
 }
 
+static BOOL CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB *blob,
+ DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg)
+{
+    DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+    BOOL ret = FALSE;
+    HCRYPTMSG msg;
+
+    if ((msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL)))
+    {
+        ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
+        if (ret)
+        {
+            DWORD type, len = sizeof(type);
+
+            ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len);
+            if (ret)
+            {
+                if (type != CMSG_SIGNED)
+                {
+                    SetLastError(ERROR_INVALID_DATA);
+                    ret = FALSE;
+                }
+            }
+        }
+        if (!ret)
+        {
+            CryptMsgClose(msg);
+            msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_SIGNED, 0, NULL,
+             NULL);
+            if (msg)
+            {
+                ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
+                if (!ret)
+                {
+                    CryptMsgClose(msg);
+                    msg = NULL;
+                }
+            }
+        }
+    }
+    if (ret)
+    {
+        if (pdwMsgAndCertEncodingType)
+            *pdwMsgAndCertEncodingType = encodingType;
+        if (pdwContentType)
+            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
+        if (phMsg)
+            *phMsg = msg;
+    }
+    return ret;
+}
+
+static BOOL CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB *blob,
+ DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg)
+{
+    DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+    BOOL ret = FALSE;
+    HCRYPTMSG msg;
+
+    if ((msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL)))
+    {
+        ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
+        if (ret)
+        {
+            DWORD type, len = sizeof(type);
+
+            ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len);
+            if (ret)
+            {
+                if (type != CMSG_DATA)
+                {
+                    SetLastError(ERROR_INVALID_DATA);
+                    ret = FALSE;
+                }
+            }
+        }
+        if (!ret)
+        {
+            CryptMsgClose(msg);
+            msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_DATA, 0,
+             NULL, NULL);
+            if (msg)
+            {
+                ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
+                if (!ret)
+                {
+                    CryptMsgClose(msg);
+                    msg = NULL;
+                }
+            }
+        }
+    }
+    if (ret)
+    {
+        if (pdwMsgAndCertEncodingType)
+            *pdwMsgAndCertEncodingType = encodingType;
+        if (pdwContentType)
+            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
+        if (phMsg)
+            *phMsg = msg;
+    }
+    return ret;
+}
+
 /* Used to decode non-embedded messages */
 static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
- DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType,
- DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
+ DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
+ DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
+ HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
 {
     CERT_BLOB fileBlob;
     const CERT_BLOB *blob;
     BOOL ret;
     HCRYPTMSG msg = NULL;
     DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+    DWORD formatType = 0;
+
+    TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject,
+     dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
+     pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
+     phMsg);
 
     switch (dwObjectType)
     {
@@ -299,89 +465,103 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
         return FALSE;
 
     ret = FALSE;
-    /* Try it first as a PKCS content info */
-    if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) ||
-     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
+    if (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY)
+    {
+        /* Try it first as a signed message */
+        if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
+            ret = CRYPT_QuerySignedMessage(blob, pdwMsgAndCertEncodingType,
+             pdwContentType, &msg);
+        /* Failing that, try as an unsigned message */
+        if (!ret &&
+         (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
+            ret = CRYPT_QueryUnsignedMessage(blob, pdwMsgAndCertEncodingType,
+             pdwContentType, &msg);
+        if (ret)
+            formatType = CERT_QUERY_FORMAT_BINARY;
+    }
+    if (!ret &&
+     (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED))
     {
-        msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL);
-        if (msg)
+        CRYPT_DATA_BLOB trimmed = { blob->cbData, blob->pbData };
+        CRYPT_DATA_BLOB decoded;
+
+        while (trimmed.cbData && !trimmed.pbData[trimmed.cbData - 1])
+            trimmed.cbData--;
+        ret = CryptStringToBinaryA((LPSTR)trimmed.pbData, trimmed.cbData,
+         CRYPT_STRING_BASE64_ANY, NULL, &decoded.cbData, NULL, NULL);
+        if (ret)
         {
-            ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
-            if (ret)
+            decoded.pbData = CryptMemAlloc(decoded.cbData);
+            if (decoded.pbData)
             {
-                DWORD type, len = sizeof(type);
-
-                ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len);
+                ret = CryptStringToBinaryA((LPSTR)trimmed.pbData,
+                 trimmed.cbData, CRYPT_STRING_BASE64_ANY, decoded.pbData,
+                 &decoded.cbData, NULL, NULL);
                 if (ret)
                 {
-                    if ((dwExpectedContentTypeFlags &
-                     CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED))
-                    {
-                        if (type != CMSG_SIGNED)
-                        {
-                            SetLastError(ERROR_INVALID_DATA);
-                            ret = FALSE;
-                        }
-                        else if (pdwContentType)
-                            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
-                    }
-                    else if ((dwExpectedContentTypeFlags &
+                    /* Try it first as a signed message */
+                    if (dwExpectedContentTypeFlags &
+                     CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
+                        ret = CRYPT_QuerySignedMessage(&decoded,
+                         pdwMsgAndCertEncodingType, pdwContentType, &msg);
+                    /* Failing that, try as an unsigned message */
+                    if (!ret && (dwExpectedContentTypeFlags &
                      CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
-                    {
-                        if (type != CMSG_DATA)
-                        {
-                            SetLastError(ERROR_INVALID_DATA);
-                            ret = FALSE;
-                        }
-                        else if (pdwContentType)
-                            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED;
-                    }
+                        ret = CRYPT_QueryUnsignedMessage(&decoded,
+                         pdwMsgAndCertEncodingType, pdwContentType, &msg);
+                    if (ret)
+                        formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
                 }
+                CryptMemFree(decoded.pbData);
             }
-            if (!ret)
-            {
-                CryptMsgClose(msg);
-                msg = NULL;
-            }
-        }
-    }
-    /* Failing that, try explicitly typed messages */
-    if (!ret &&
-     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED))
-    {
-        msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_SIGNED, 0, NULL, NULL);
-        if (msg)
-        {
-            ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
-            if (!ret)
-            {
-                CryptMsgClose(msg);
-                msg = NULL;
-            }
+            else
+                ret = FALSE;
         }
-        if (msg && pdwContentType)
-            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
-    }
-    if (!ret &&
-     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
-    {
-        msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_DATA, 0, NULL, NULL);
-        if (msg)
+        if (!ret && !(blob->cbData % sizeof(WCHAR)))
         {
-            ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
-            if (!ret)
+            CRYPT_DATA_BLOB decoded;
+            LPWSTR str = (LPWSTR)blob->pbData;
+            DWORD strLen = blob->cbData / sizeof(WCHAR);
+
+            /* Try again, assuming the input string is UTF-16 base64 */
+            while (strLen && !str[strLen - 1])
+                strLen--;
+            ret = CryptStringToBinaryW(str, strLen, CRYPT_STRING_BASE64_ANY,
+             NULL, &decoded.cbData, NULL, NULL);
+            if (ret)
             {
-                CryptMsgClose(msg);
-                msg = NULL;
+                decoded.pbData = CryptMemAlloc(decoded.cbData);
+                if (decoded.pbData)
+                {
+                    ret = CryptStringToBinaryW(str, strLen,
+                     CRYPT_STRING_BASE64_ANY, decoded.pbData, &decoded.cbData,
+                     NULL, NULL);
+                    if (ret)
+                    {
+                        /* Try it first as a signed message */
+                        if (dwExpectedContentTypeFlags &
+                         CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
+                            ret = CRYPT_QuerySignedMessage(&decoded,
+                             pdwMsgAndCertEncodingType, pdwContentType, &msg);
+                        /* Failing that, try as an unsigned message */
+                        if (!ret && (dwExpectedContentTypeFlags &
+                         CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
+                            ret = CRYPT_QueryUnsignedMessage(&decoded,
+                             pdwMsgAndCertEncodingType, pdwContentType, &msg);
+                        if (ret)
+                            formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
+                    }
+                    CryptMemFree(decoded.pbData);
+                }
+                else
+                    ret = FALSE;
             }
         }
-        if (msg && pdwContentType)
-            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED;
     }
-    if (pdwMsgAndCertEncodingType)
-        *pdwMsgAndCertEncodingType = encodingType;
-    if (msg)
+    if (ret)
     {
+        if (pdwFormatType)
+            *pdwFormatType = formatType;
         if (phMsg)
             *phMsg = msg;
         if (phCertStore)
@@ -407,7 +587,7 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
 
     if (dwObjectType != CERT_QUERY_OBJECT_FILE)
     {
-        FIXME("don't know what to do for type %d embedded signed messages\n",
+        WARN("don't know what to do for type %d embedded signed messages\n",
          dwObjectType);
         SetLastError(E_INVALIDARG);
         return FALSE;
@@ -449,8 +629,9 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
                             ret = CRYPT_QueryMessageObject(
                              CERT_QUERY_OBJECT_BLOB, &blob,
                              CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
-                             pdwMsgAndCertEncodingType, NULL, phCertStore,
-                             phMsg);
+                             CERT_QUERY_FORMAT_FLAG_BINARY,
+                             pdwMsgAndCertEncodingType, NULL, NULL,
+                             phCertStore, phMsg);
                             if (ret && pdwContentType)
                                 *pdwContentType =
                                  CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED;
@@ -487,18 +668,25 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
      dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType,
      pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext);
 
-    if (dwExpectedContentTypeFlags & unimplementedTypes)
-        WARN("unimplemented for types %08x\n",
-         dwExpectedContentTypeFlags & unimplementedTypes);
-    if (!(dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY))
+    if (dwObjectType != CERT_QUERY_OBJECT_BLOB &&
+     dwObjectType != CERT_QUERY_OBJECT_FILE)
+    {
+        WARN("unsupported type %d\n", dwObjectType);
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if (!pvObject)
     {
-        FIXME("unimplemented for anything but binary\n");
-        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+        WARN("missing required argument\n");
+        SetLastError(E_INVALIDARG);
         return FALSE;
     }
+    if (dwExpectedContentTypeFlags & unimplementedTypes)
+        WARN("unimplemented for types %08x\n",
+         dwExpectedContentTypeFlags & unimplementedTypes);
+
     if (pdwFormatType)
         *pdwFormatType = CERT_QUERY_FORMAT_BINARY;
-
     if (phCertStore)
         *phCertStore = NULL;
     if (phMsg)
@@ -512,8 +700,9 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
      (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
     {
         ret = CRYPT_QueryContextObject(dwObjectType, pvObject,
-         dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
-         phCertStore, ppvContext);
+         dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
+         pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
+         ppvContext);
     }
     if (!ret &&
      (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE))
@@ -535,7 +724,8 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
      (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)))
     {
         ret = CRYPT_QueryMessageObject(dwObjectType, pvObject,
-         dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
+         dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
+         pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
          phCertStore, phMsg);
     }
     if (!ret &&
@@ -545,6 +735,1852 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
          dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
          phCertStore, phMsg);
     }
+    if (!ret)
+        SetLastError(CRYPT_E_NO_MATCH);
     TRACE("returning %d\n", ret);
     return ret;
 }
+
+static BOOL WINAPI CRYPT_FormatHexString(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    BOOL ret;
+    DWORD bytesNeeded;
+
+    if (cbEncoded)
+        bytesNeeded = (cbEncoded * 3) * sizeof(WCHAR);
+    else
+        bytesNeeded = sizeof(WCHAR);
+    if (!pbFormat)
+    {
+        *pcbFormat = bytesNeeded;
+        ret = TRUE;
+    }
+    else if (*pcbFormat < bytesNeeded)
+    {
+        *pcbFormat = bytesNeeded;
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        static const WCHAR fmt[] = { '%','0','2','x',' ',0 };
+        static const WCHAR endFmt[] = { '%','0','2','x',0 };
+        DWORD i;
+        LPWSTR ptr = pbFormat;
+
+        *pcbFormat = bytesNeeded;
+        if (cbEncoded)
+        {
+            for (i = 0; i < cbEncoded; i++)
+            {
+                if (i < cbEncoded - 1)
+                    ptr += sprintfW(ptr, fmt, pbEncoded[i]);
+                else
+                    ptr += sprintfW(ptr, endFmt, pbEncoded[i]);
+            }
+        }
+        else
+            *ptr = 0;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+#define MAX_STRING_RESOURCE_LEN 128
+
+static const WCHAR commaSpace[] = { ',',' ',0 };
+
+struct BitToString
+{
+    BYTE bit;
+    int id;
+    WCHAR str[MAX_STRING_RESOURCE_LEN];
+};
+
+static BOOL CRYPT_FormatBits(BYTE bits, const struct BitToString *map,
+ DWORD mapEntries, void *pbFormat, DWORD *pcbFormat, BOOL *first)
+{
+    DWORD bytesNeeded = sizeof(WCHAR);
+    int i;
+    BOOL ret = TRUE, localFirst = *first;
+
+    for (i = 0; i < mapEntries; i++)
+        if (bits & map[i].bit)
+        {
+            if (!localFirst)
+                bytesNeeded += strlenW(commaSpace) * sizeof(WCHAR);
+            localFirst = FALSE;
+            bytesNeeded += strlenW(map[i].str) * sizeof(WCHAR);
+        }
+    if (!pbFormat)
+    {
+        *first = localFirst;
+        *pcbFormat = bytesNeeded;
+    }
+    else if (*pcbFormat < bytesNeeded)
+    {
+        *first = localFirst;
+        *pcbFormat = bytesNeeded;
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        LPWSTR str = pbFormat;
+
+        localFirst = *first;
+        *pcbFormat = bytesNeeded;
+        for (i = 0; i < mapEntries; i++)
+            if (bits & map[i].bit)
+            {
+                if (!localFirst)
+                {
+                    strcpyW(str, commaSpace);
+                    str += strlenW(commaSpace);
+                }
+                localFirst = FALSE;
+                strcpyW(str, map[i].str);
+                str += strlenW(map[i].str);
+            }
+        *first = localFirst;
+    }
+    return ret;
+}
+
+static struct BitToString keyUsageByte0Map[] = {
+ { CERT_DIGITAL_SIGNATURE_KEY_USAGE, IDS_DIGITAL_SIGNATURE, { 0 } },
+ { CERT_NON_REPUDIATION_KEY_USAGE, IDS_NON_REPUDIATION, { 0 } },
+ { CERT_KEY_ENCIPHERMENT_KEY_USAGE, IDS_KEY_ENCIPHERMENT, { 0 } },
+ { CERT_DATA_ENCIPHERMENT_KEY_USAGE, IDS_DATA_ENCIPHERMENT, { 0 } },
+ { CERT_KEY_AGREEMENT_KEY_USAGE, IDS_KEY_AGREEMENT, { 0 } },
+ { CERT_KEY_CERT_SIGN_KEY_USAGE, IDS_CERT_SIGN, { 0 } },
+ { CERT_OFFLINE_CRL_SIGN_KEY_USAGE, IDS_OFFLINE_CRL_SIGN, { 0 } },
+ { CERT_CRL_SIGN_KEY_USAGE, IDS_CRL_SIGN, { 0 } },
+ { CERT_ENCIPHER_ONLY_KEY_USAGE, IDS_ENCIPHER_ONLY, { 0 } },
+};
+static struct BitToString keyUsageByte1Map[] = {
+ { CERT_DECIPHER_ONLY_KEY_USAGE, IDS_DECIPHER_ONLY, { 0 } },
+};
+
+static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    DWORD size;
+    CRYPT_BIT_BLOB *bits;
+    BOOL ret;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_KEY_USAGE,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &bits, &size)))
+    {
+        WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
+        DWORD bytesNeeded = sizeof(WCHAR);
+
+        LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
+         sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+        if (!bits->cbData || bits->cbData > 2)
+        {
+            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                LPWSTR str = pbFormat;
+
+                *pcbFormat = bytesNeeded;
+                strcpyW(str, infoNotAvailable);
+            }
+        }
+        else
+        {
+            static BOOL stringsLoaded = FALSE;
+            int i;
+            DWORD bitStringLen;
+            BOOL first = TRUE;
+
+            if (!stringsLoaded)
+            {
+                for (i = 0;
+                 i < sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]);
+                 i++)
+                    LoadStringW(hInstance, keyUsageByte0Map[i].id,
+                     keyUsageByte0Map[i].str, MAX_STRING_RESOURCE_LEN);
+                for (i = 0;
+                 i < sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]);
+                 i++)
+                    LoadStringW(hInstance, keyUsageByte1Map[i].id,
+                     keyUsageByte1Map[i].str, MAX_STRING_RESOURCE_LEN);
+                stringsLoaded = TRUE;
+            }
+            CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
+             sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
+             NULL, &bitStringLen, &first);
+            bytesNeeded += bitStringLen;
+            if (bits->cbData == 2)
+            {
+                CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
+                 sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+                 NULL, &bitStringLen, &first);
+                bytesNeeded += bitStringLen;
+            }
+            bytesNeeded += 3 * sizeof(WCHAR); /* " (" + ")" */
+            CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
+             bits->cbData, NULL, &size);
+            bytesNeeded += size;
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                LPWSTR str = pbFormat;
+
+                bitStringLen = bytesNeeded;
+                first = TRUE;
+                CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
+                 sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
+                 str, &bitStringLen, &first);
+                str += bitStringLen / sizeof(WCHAR) - 1;
+                if (bits->cbData == 2)
+                {
+                    bitStringLen = bytesNeeded;
+                    CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
+                     sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+                     str, &bitStringLen, &first);
+                    str += bitStringLen / sizeof(WCHAR) - 1;
+                }
+                *str++ = ' ';
+                *str++ = '(';
+                CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
+                 bits->cbData, str, &size);
+                str += size / sizeof(WCHAR) - 1;
+                *str++ = ')';
+                *str = 0;
+            }
+        }
+        LocalFree(bits);
+    }
+    return ret;
+}
+
+static const WCHAR crlf[] = { '\r','\n',0 };
+
+static WCHAR subjectTypeHeader[MAX_STRING_RESOURCE_LEN];
+static WCHAR subjectTypeCA[MAX_STRING_RESOURCE_LEN];
+static WCHAR subjectTypeEndCert[MAX_STRING_RESOURCE_LEN];
+static WCHAR pathLengthHeader[MAX_STRING_RESOURCE_LEN];
+
+static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    DWORD size;
+    CERT_BASIC_CONSTRAINTS2_INFO *info;
+    BOOL ret;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BASIC_CONSTRAINTS2,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
+    {
+        static const WCHAR pathFmt[] = { '%','d',0 };
+        static BOOL stringsLoaded = FALSE;
+        DWORD bytesNeeded = sizeof(WCHAR); /* space for the NULL terminator */
+        WCHAR pathLength[MAX_STRING_RESOURCE_LEN];
+        LPCWSTR sep, subjectType;
+        DWORD sepLen;
+
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            sep = crlf;
+            sepLen = strlenW(crlf) * sizeof(WCHAR);
+        }
+        else
+        {
+            sep = commaSpace;
+            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
+        }
+
+        if (!stringsLoaded)
+        {
+            LoadStringW(hInstance, IDS_SUBJECT_TYPE, subjectTypeHeader,
+             sizeof(subjectTypeHeader) / sizeof(subjectTypeHeader[0]));
+            LoadStringW(hInstance, IDS_SUBJECT_TYPE_CA, subjectTypeCA,
+             sizeof(subjectTypeCA) / sizeof(subjectTypeCA[0]));
+            LoadStringW(hInstance, IDS_SUBJECT_TYPE_END_CERT,
+             subjectTypeEndCert,
+             sizeof(subjectTypeEndCert) / sizeof(subjectTypeEndCert[0]));
+            LoadStringW(hInstance, IDS_PATH_LENGTH, pathLengthHeader,
+             sizeof(pathLengthHeader) / sizeof(pathLengthHeader[0]));
+            stringsLoaded = TRUE;
+        }
+        bytesNeeded += strlenW(subjectTypeHeader) * sizeof(WCHAR);
+        if (info->fCA)
+            subjectType = subjectTypeCA;
+        else
+            subjectType = subjectTypeEndCert;
+        bytesNeeded += strlenW(subjectType) * sizeof(WCHAR);
+        bytesNeeded += sepLen;
+        bytesNeeded += strlenW(pathLengthHeader) * sizeof(WCHAR);
+        if (info->fPathLenConstraint)
+            sprintfW(pathLength, pathFmt, info->dwPathLenConstraint);
+        else
+            LoadStringW(hInstance, IDS_PATH_LENGTH_NONE, pathLength,
+             sizeof(pathLength) / sizeof(pathLength[0]));
+        bytesNeeded += strlenW(pathLength) * sizeof(WCHAR);
+        if (!pbFormat)
+            *pcbFormat = bytesNeeded;
+        else if (*pcbFormat < bytesNeeded)
+        {
+            *pcbFormat = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            LPWSTR str = pbFormat;
+
+            *pcbFormat = bytesNeeded;
+            strcpyW(str, subjectTypeHeader);
+            str += strlenW(subjectTypeHeader);
+            strcpyW(str, subjectType);
+            str += strlenW(subjectType);
+            strcpyW(str, sep);
+            str += sepLen / sizeof(WCHAR);
+            strcpyW(str, pathLengthHeader);
+            str += strlenW(pathLengthHeader);
+            strcpyW(str, pathLength);
+            str += strlenW(pathLength);
+        }
+        LocalFree(info);
+    }
+    return ret;
+}
+
+static BOOL CRYPT_FormatHexStringWithPrefix(CRYPT_DATA_BLOB *blob, int id,
+ LPWSTR str, DWORD *pcbStr)
+{
+    WCHAR buf[MAX_STRING_RESOURCE_LEN];
+    DWORD bytesNeeded;
+    BOOL ret;
+
+    LoadStringW(hInstance, id, buf, sizeof(buf) / sizeof(buf[0]));
+    CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL,
+     blob->pbData, blob->cbData, NULL, &bytesNeeded);
+    bytesNeeded += strlenW(buf) * sizeof(WCHAR);
+    if (!str)
+    {
+        *pcbStr = bytesNeeded;
+        ret = TRUE;
+    }
+    else if (*pcbStr < bytesNeeded)
+    {
+        *pcbStr = bytesNeeded;
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        *pcbStr = bytesNeeded;
+        strcpyW(str, buf);
+        str += strlenW(str);
+        bytesNeeded -= strlenW(str) * sizeof(WCHAR);
+        ret = CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL,
+         blob->pbData, blob->cbData, str, &bytesNeeded);
+    }
+    return ret;
+}
+
+static BOOL CRYPT_FormatKeyId(CRYPT_DATA_BLOB *keyId, LPWSTR str,
+ DWORD *pcbStr)
+{
+    return CRYPT_FormatHexStringWithPrefix(keyId, IDS_KEY_ID, str, pcbStr);
+}
+
+static BOOL CRYPT_FormatCertSerialNumber(CRYPT_DATA_BLOB *serialNum, LPWSTR str,
+ DWORD *pcbStr)
+{
+    return CRYPT_FormatHexStringWithPrefix(serialNum, IDS_CERT_SERIAL_NUMBER,
+     str, pcbStr);
+}
+
+static const WCHAR indent[] = { ' ',' ',' ',' ',' ',0 };
+static const WCHAR colonCrlf[] = { ':','\r','\n',0 };
+
+static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
+ CERT_ALT_NAME_ENTRY *entry, LPWSTR str, DWORD *pcbStr)
+{
+    BOOL ret;
+    WCHAR buf[MAX_STRING_RESOURCE_LEN];
+    WCHAR mask[MAX_STRING_RESOURCE_LEN];
+    WCHAR ipAddrBuf[32];
+    WCHAR maskBuf[16];
+    DWORD bytesNeeded = sizeof(WCHAR);
+    DWORD strType = CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG;
+
+    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        bytesNeeded += indentLevel * strlenW(indent) * sizeof(WCHAR);
+    switch (entry->dwAltNameChoice)
+    {
+    case CERT_ALT_NAME_RFC822_NAME:
+        LoadStringW(hInstance, IDS_ALT_NAME_RFC822_NAME, buf,
+         sizeof(buf) / sizeof(buf[0]));
+        bytesNeeded += strlenW(entry->u.pwszRfc822Name) * sizeof(WCHAR);
+        ret = TRUE;
+        break;
+    case CERT_ALT_NAME_DNS_NAME:
+        LoadStringW(hInstance, IDS_ALT_NAME_DNS_NAME, buf,
+         sizeof(buf) / sizeof(buf[0]));
+        bytesNeeded += strlenW(entry->u.pwszDNSName) * sizeof(WCHAR);
+        ret = TRUE;
+        break;
+    case CERT_ALT_NAME_DIRECTORY_NAME:
+    {
+        DWORD directoryNameLen;
+
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            strType |= CERT_NAME_STR_CRLF_FLAG;
+        directoryNameLen = cert_name_to_str_with_indent(X509_ASN_ENCODING,
+         indentLevel + 1, &entry->u.DirectoryName, strType, NULL, 0);
+        LoadStringW(hInstance, IDS_ALT_NAME_DIRECTORY_NAME, buf,
+         sizeof(buf) / sizeof(buf[0]));
+        bytesNeeded += (directoryNameLen - 1) * sizeof(WCHAR);
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            bytesNeeded += strlenW(colonCrlf) * sizeof(WCHAR);
+        else
+            bytesNeeded += sizeof(WCHAR); /* '=' */
+        ret = TRUE;
+        break;
+    }
+    case CERT_ALT_NAME_URL:
+        LoadStringW(hInstance, IDS_ALT_NAME_URL, buf,
+         sizeof(buf) / sizeof(buf[0]));
+        bytesNeeded += strlenW(entry->u.pwszURL) * sizeof(WCHAR);
+        ret = TRUE;
+        break;
+    case CERT_ALT_NAME_IP_ADDRESS:
+    {
+        static const WCHAR ipAddrWithMaskFmt[] = { '%','d','.','%','d','.',
+         '%','d','.','%','d','/','%','d','.','%','d','.','%','d','.','%','d',0
+        };
+        static const WCHAR ipAddrFmt[] = { '%','d','.','%','d','.','%','d',
+         '.','%','d',0 };
+
+        LoadStringW(hInstance, IDS_ALT_NAME_IP_ADDRESS, buf,
+         sizeof(buf) / sizeof(buf[0]));
+        if (entry->u.IPAddress.cbData == 8)
+        {
+            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            {
+                LoadStringW(hInstance, IDS_ALT_NAME_MASK, mask,
+                 sizeof(mask) / sizeof(mask[0]));
+                bytesNeeded += strlenW(mask) * sizeof(WCHAR);
+                sprintfW(ipAddrBuf, ipAddrFmt,
+                 entry->u.IPAddress.pbData[0],
+                 entry->u.IPAddress.pbData[1],
+                 entry->u.IPAddress.pbData[2],
+                 entry->u.IPAddress.pbData[3]);
+                bytesNeeded += strlenW(ipAddrBuf) * sizeof(WCHAR);
+                /* indent again, for the mask line */
+                bytesNeeded += indentLevel * strlenW(indent) * sizeof(WCHAR);
+                sprintfW(maskBuf, ipAddrFmt,
+                 entry->u.IPAddress.pbData[4],
+                 entry->u.IPAddress.pbData[5],
+                 entry->u.IPAddress.pbData[6],
+                 entry->u.IPAddress.pbData[7]);
+                bytesNeeded += strlenW(maskBuf) * sizeof(WCHAR);
+                bytesNeeded += strlenW(crlf) * sizeof(WCHAR);
+            }
+            else
+            {
+                sprintfW(ipAddrBuf, ipAddrWithMaskFmt,
+                 entry->u.IPAddress.pbData[0],
+                 entry->u.IPAddress.pbData[1],
+                 entry->u.IPAddress.pbData[2],
+                 entry->u.IPAddress.pbData[3],
+                 entry->u.IPAddress.pbData[4],
+                 entry->u.IPAddress.pbData[5],
+                 entry->u.IPAddress.pbData[6],
+                 entry->u.IPAddress.pbData[7]);
+                bytesNeeded += (strlenW(ipAddrBuf) + 1) * sizeof(WCHAR);
+            }
+            ret = TRUE;
+        }
+        else
+        {
+            FIXME("unknown IP address format (%d bytes)\n",
+             entry->u.IPAddress.cbData);
+            ret = FALSE;
+        }
+        break;
+    }
+    default:
+        FIXME("unimplemented for %d\n", entry->dwAltNameChoice);
+        ret = FALSE;
+    }
+    if (ret)
+    {
+        bytesNeeded += strlenW(buf) * sizeof(WCHAR);
+        if (!str)
+            *pcbStr = bytesNeeded;
+        else if (*pcbStr < bytesNeeded)
+        {
+            *pcbStr = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            DWORD i;
+
+            *pcbStr = bytesNeeded;
+            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            {
+                for (i = 0; i < indentLevel; i++)
+                {
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                }
+            }
+            strcpyW(str, buf);
+            str += strlenW(str);
+            switch (entry->dwAltNameChoice)
+            {
+            case CERT_ALT_NAME_RFC822_NAME:
+            case CERT_ALT_NAME_DNS_NAME:
+            case CERT_ALT_NAME_URL:
+                strcpyW(str, entry->u.pwszURL);
+                break;
+            case CERT_ALT_NAME_DIRECTORY_NAME:
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                {
+                    strcpyW(str, colonCrlf);
+                    str += strlenW(colonCrlf);
+                }
+                else
+                    *str++ = '=';
+                cert_name_to_str_with_indent(X509_ASN_ENCODING,
+                 indentLevel + 1, &entry->u.DirectoryName, strType, str,
+                 bytesNeeded / sizeof(WCHAR));
+                break;
+            case CERT_ALT_NAME_IP_ADDRESS:
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                {
+                    strcpyW(str, ipAddrBuf);
+                    str += strlenW(ipAddrBuf);
+                    strcpyW(str, crlf);
+                    str += strlenW(crlf);
+                    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                    {
+                        for (i = 0; i < indentLevel; i++)
+                        {
+                            strcpyW(str, indent);
+                            str += strlenW(indent);
+                        }
+                    }
+                    strcpyW(str, mask);
+                    str += strlenW(mask);
+                    strcpyW(str, maskBuf);
+                }
+                else
+                    strcpyW(str, ipAddrBuf);
+                break;
+            }
+        }
+    }
+    return ret;
+}
+
+static BOOL CRYPT_FormatAltNameInfo(DWORD dwFormatStrType, DWORD indentLevel,
+ CERT_ALT_NAME_INFO *name, LPWSTR str, DWORD *pcbStr)
+{
+    DWORD i, size, bytesNeeded = 0;
+    BOOL ret = TRUE;
+    LPCWSTR sep;
+    DWORD sepLen;
+
+    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+    {
+        sep = crlf;
+        sepLen = strlenW(crlf) * sizeof(WCHAR);
+    }
+    else
+    {
+        sep = commaSpace;
+        sepLen = strlenW(commaSpace) * sizeof(WCHAR);
+    }
+
+    for (i = 0; ret && i < name->cAltEntry; i++)
+    {
+        ret = CRYPT_FormatAltNameEntry(dwFormatStrType, indentLevel,
+         &name->rgAltEntry[i], NULL, &size);
+        if (ret)
+        {
+            bytesNeeded += size - sizeof(WCHAR);
+            if (i < name->cAltEntry - 1)
+                bytesNeeded += sepLen;
+        }
+    }
+    if (ret)
+    {
+        bytesNeeded += sizeof(WCHAR);
+        if (!str)
+            *pcbStr = bytesNeeded;
+        else if (*pcbStr < bytesNeeded)
+        {
+            *pcbStr = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            *pcbStr = bytesNeeded;
+            for (i = 0; ret && i < name->cAltEntry; i++)
+            {
+                ret = CRYPT_FormatAltNameEntry(dwFormatStrType, indentLevel,
+                 &name->rgAltEntry[i], str, &size);
+                if (ret)
+                {
+                    str += size / sizeof(WCHAR) - 1;
+                    if (i < name->cAltEntry - 1)
+                    {
+                        strcpyW(str, sep);
+                        str += sepLen / sizeof(WCHAR);
+                    }
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+static const WCHAR colonSep[] = { ':',' ',0 };
+
+static BOOL WINAPI CRYPT_FormatAltName(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    BOOL ret;
+    CERT_ALT_NAME_INFO *info;
+    DWORD size;
+
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_ALTERNATE_NAME,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
+    {
+        ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 0, info, pbFormat, pcbFormat);
+        LocalFree(info);
+    }
+    return ret;
+}
+
+static BOOL CRYPT_FormatCertIssuer(DWORD dwFormatStrType,
+ CERT_ALT_NAME_INFO *issuer, LPWSTR str, DWORD *pcbStr)
+{
+    WCHAR buf[MAX_STRING_RESOURCE_LEN];
+    DWORD bytesNeeded, sepLen;
+    LPCWSTR sep;
+    BOOL ret;
+
+    LoadStringW(hInstance, IDS_CERT_ISSUER, buf, sizeof(buf) / sizeof(buf[0]));
+    ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, NULL,
+     &bytesNeeded);
+    bytesNeeded += strlenW(buf) * sizeof(WCHAR);
+    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+    {
+        sep = colonCrlf;
+        sepLen = strlenW(colonCrlf) * sizeof(WCHAR);
+    }
+    else
+    {
+        sep = colonSep;
+        sepLen = strlenW(colonSep) * sizeof(WCHAR);
+    }
+    bytesNeeded += sepLen;
+    if (ret)
+    {
+        if (!str)
+            *pcbStr = bytesNeeded;
+        else if (*pcbStr < bytesNeeded)
+        {
+            *pcbStr = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            *pcbStr = bytesNeeded;
+            strcpyW(str, buf);
+            bytesNeeded -= strlenW(str) * sizeof(WCHAR);
+            str += strlenW(str);
+            strcpyW(str, sep);
+            str += sepLen / sizeof(WCHAR);
+            ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, str,
+             &bytesNeeded);
+        }
+    }
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    CERT_AUTHORITY_KEY_ID2_INFO *info;
+    DWORD size;
+    BOOL ret = FALSE;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_AUTHORITY_KEY_ID2,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
+    {
+        DWORD bytesNeeded = sizeof(WCHAR); /* space for the NULL terminator */
+        LPCWSTR sep;
+        DWORD sepLen;
+        BOOL needSeparator = FALSE;
+
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            sep = crlf;
+            sepLen = strlenW(crlf) * sizeof(WCHAR);
+        }
+        else
+        {
+            sep = commaSpace;
+            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
+        }
+
+        if (info->KeyId.cbData)
+        {
+            needSeparator = TRUE;
+            ret = CRYPT_FormatKeyId(&info->KeyId, NULL, &size);
+            if (ret)
+            {
+                /* don't include NULL-terminator more than once */
+                bytesNeeded += size - sizeof(WCHAR);
+            }
+        }
+        if (info->AuthorityCertIssuer.cAltEntry)
+        {
+            if (needSeparator)
+                bytesNeeded += sepLen;
+            needSeparator = TRUE;
+            ret = CRYPT_FormatCertIssuer(dwFormatStrType,
+             &info->AuthorityCertIssuer, NULL, &size);
+            if (ret)
+            {
+                /* don't include NULL-terminator more than once */
+                bytesNeeded += size - sizeof(WCHAR);
+            }
+        }
+        if (info->AuthorityCertSerialNumber.cbData)
+        {
+            if (needSeparator)
+                bytesNeeded += sepLen;
+            ret = CRYPT_FormatCertSerialNumber(
+             &info->AuthorityCertSerialNumber, NULL, &size);
+            if (ret)
+            {
+                /* don't include NULL-terminator more than once */
+                bytesNeeded += size - sizeof(WCHAR);
+            }
+        }
+        if (ret)
+        {
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                LPWSTR str = pbFormat;
+
+                *pcbFormat = bytesNeeded;
+                needSeparator = FALSE;
+                if (info->KeyId.cbData)
+                {
+                    needSeparator = TRUE;
+                    /* Overestimate size available, it's already been checked
+                     * above.
+                     */
+                    size = bytesNeeded;
+                    ret = CRYPT_FormatKeyId(&info->KeyId, str, &size);
+                    if (ret)
+                        str += size / sizeof(WCHAR) - 1;
+                }
+                if (info->AuthorityCertIssuer.cAltEntry)
+                {
+                    if (needSeparator)
+                    {
+                        strcpyW(str, sep);
+                        str += sepLen / sizeof(WCHAR);
+                    }
+                    needSeparator = TRUE;
+                    /* Overestimate size available, it's already been checked
+                     * above.
+                     */
+                    size = bytesNeeded;
+                    ret = CRYPT_FormatCertIssuer(dwFormatStrType,
+                     &info->AuthorityCertIssuer, str, &size);
+                    if (ret)
+                        str += size / sizeof(WCHAR) - 1;
+                }
+                if (info->AuthorityCertSerialNumber.cbData)
+                {
+                    if (needSeparator)
+                    {
+                        strcpyW(str, sep);
+                        str += sepLen / sizeof(WCHAR);
+                    }
+                    /* Overestimate size available, it's already been checked
+                     * above.
+                     */
+                    size = bytesNeeded;
+                    ret = CRYPT_FormatCertSerialNumber(
+                     &info->AuthorityCertSerialNumber, str, &size);
+                }
+            }
+        }
+        LocalFree(info);
+    }
+    return ret;
+}
+
+static WCHAR aia[MAX_STRING_RESOURCE_LEN];
+static WCHAR accessMethod[MAX_STRING_RESOURCE_LEN];
+static WCHAR ocsp[MAX_STRING_RESOURCE_LEN];
+static WCHAR caIssuers[MAX_STRING_RESOURCE_LEN];
+static WCHAR unknown[MAX_STRING_RESOURCE_LEN];
+static WCHAR accessLocation[MAX_STRING_RESOURCE_LEN];
+
+static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    CERT_AUTHORITY_INFO_ACCESS *info;
+    DWORD size;
+    BOOL ret = FALSE;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType,
+     X509_AUTHORITY_INFO_ACCESS, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG,
+     NULL, &info, &size)))
+    {
+        DWORD bytesNeeded = sizeof(WCHAR);
+
+        if (!info->cAccDescr)
+        {
+            WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
+
+            LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
+             sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                *pcbFormat = bytesNeeded;
+                strcpyW((LPWSTR)pbFormat, infoNotAvailable);
+            }
+        }
+        else
+        {
+            static const WCHAR numFmt[] = { '%','d',0 };
+            static const WCHAR equal[] = { '=',0 };
+            static BOOL stringsLoaded = FALSE;
+            DWORD i;
+            LPCWSTR headingSep, accessMethodSep, locationSep;
+            WCHAR accessDescrNum[11];
+
+            if (!stringsLoaded)
+            {
+                LoadStringW(hInstance, IDS_AIA, aia,
+                 sizeof(aia) / sizeof(aia[0]));
+                LoadStringW(hInstance, IDS_ACCESS_METHOD, accessMethod,
+                 sizeof(accessMethod) / sizeof(accessMethod[0]));
+                LoadStringW(hInstance, IDS_ACCESS_METHOD_OCSP, ocsp,
+                 sizeof(ocsp) / sizeof(ocsp[0]));
+                LoadStringW(hInstance, IDS_ACCESS_METHOD_CA_ISSUERS, caIssuers,
+                 sizeof(caIssuers) / sizeof(caIssuers[0]));
+                LoadStringW(hInstance, IDS_ACCESS_METHOD_UNKNOWN, unknown,
+                 sizeof(unknown) / sizeof(unknown[0]));
+                LoadStringW(hInstance, IDS_ACCESS_LOCATION, accessLocation,
+                 sizeof(accessLocation) / sizeof(accessLocation[0]));
+                stringsLoaded = TRUE;
+            }
+            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            {
+                headingSep = crlf;
+                accessMethodSep = crlf;
+                locationSep = colonCrlf;
+            }
+            else
+            {
+                headingSep = colonSep;
+                accessMethodSep = commaSpace;
+                locationSep = equal;
+            }
+
+            for (i = 0; ret && i < info->cAccDescr; i++)
+            {
+                /* Heading */
+                bytesNeeded += sizeof(WCHAR); /* left bracket */
+                sprintfW(accessDescrNum, numFmt, i + 1);
+                bytesNeeded += strlenW(accessDescrNum) * sizeof(WCHAR);
+                bytesNeeded += sizeof(WCHAR); /* right bracket */
+                bytesNeeded += strlenW(aia) * sizeof(WCHAR);
+                bytesNeeded += strlenW(headingSep) * sizeof(WCHAR);
+                /* Access method */
+                bytesNeeded += strlenW(accessMethod) * sizeof(WCHAR);
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                    bytesNeeded += strlenW(indent) * sizeof(WCHAR);
+                if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
+                 szOID_PKIX_OCSP))
+                    bytesNeeded += strlenW(ocsp) * sizeof(WCHAR);
+                else if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
+                 szOID_PKIX_CA_ISSUERS))
+                    bytesNeeded += strlenW(caIssuers) * sizeof(caIssuers);
+                else
+                    bytesNeeded += strlenW(unknown) * sizeof(WCHAR);
+                bytesNeeded += sizeof(WCHAR); /* space */
+                bytesNeeded += sizeof(WCHAR); /* left paren */
+                bytesNeeded += strlen(info->rgAccDescr[i].pszAccessMethod)
+                 * sizeof(WCHAR);
+                bytesNeeded += sizeof(WCHAR); /* right paren */
+                /* Delimiter between access method and location */
+                bytesNeeded += strlenW(accessMethodSep) * sizeof(WCHAR);
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                    bytesNeeded += strlenW(indent) * sizeof(WCHAR);
+                bytesNeeded += strlenW(accessLocation) * sizeof(WCHAR);
+                bytesNeeded += strlenW(locationSep) * sizeof(WCHAR);
+                ret = CRYPT_FormatAltNameEntry(dwFormatStrType, 2,
+                 &info->rgAccDescr[i].AccessLocation, NULL, &size);
+                if (ret)
+                    bytesNeeded += size - sizeof(WCHAR);
+                /* Need extra delimiter between access method entries */
+                if (i < info->cAccDescr - 1)
+                    bytesNeeded += strlenW(accessMethodSep) * sizeof(WCHAR);
+            }
+            if (ret)
+            {
+                if (!pbFormat)
+                    *pcbFormat = bytesNeeded;
+                else if (*pcbFormat < bytesNeeded)
+                {
+                    *pcbFormat = bytesNeeded;
+                    SetLastError(ERROR_MORE_DATA);
+                    ret = FALSE;
+                }
+                else
+                {
+                    LPWSTR str = pbFormat;
+                    DWORD altNameEntrySize;
+
+                    *pcbFormat = bytesNeeded;
+                    for (i = 0; ret && i < info->cAccDescr; i++)
+                    {
+                        LPCSTR oidPtr;
+
+                        *str++ = '[';
+                        sprintfW(accessDescrNum, numFmt, i + 1);
+                        strcpyW(str, accessDescrNum);
+                        str += strlenW(accessDescrNum);
+                        *str++ = ']';
+                        strcpyW(str, aia);
+                        str += strlenW(aia);
+                        strcpyW(str, headingSep);
+                        str += strlenW(headingSep);
+                        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                        {
+                            strcpyW(str, indent);
+                            str += strlenW(indent);
+                        }
+                        strcpyW(str, accessMethod);
+                        str += strlenW(accessMethod);
+                        if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
+                         szOID_PKIX_OCSP))
+                        {
+                            strcpyW(str, ocsp);
+                            str += strlenW(ocsp);
+                        }
+                        else if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
+                         szOID_PKIX_CA_ISSUERS))
+                        {
+                            strcpyW(str, caIssuers);
+                            str += strlenW(caIssuers);
+                        }
+                        else
+                        {
+                            strcpyW(str, unknown);
+                            str += strlenW(unknown);
+                        }
+                        *str++ = ' ';
+                        *str++ = '(';
+                        for (oidPtr = info->rgAccDescr[i].pszAccessMethod;
+                         *oidPtr; oidPtr++, str++)
+                            *str = *oidPtr;
+                        *str++ = ')';
+                        strcpyW(str, accessMethodSep);
+                        str += strlenW(accessMethodSep);
+                        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                        {
+                            strcpyW(str, indent);
+                            str += strlenW(indent);
+                        }
+                        strcpyW(str, accessLocation);
+                        str += strlenW(accessLocation);
+                        strcpyW(str, locationSep);
+                        str += strlenW(locationSep);
+                        /* This overestimates the size available, but that
+                         * won't matter since we checked earlier whether enough
+                         * space for the entire string was available.
+                         */
+                        altNameEntrySize = bytesNeeded;
+                        ret = CRYPT_FormatAltNameEntry(dwFormatStrType, 2,
+                         &info->rgAccDescr[i].AccessLocation, str,
+                         &altNameEntrySize);
+                        if (ret)
+                            str += altNameEntrySize / sizeof(WCHAR) - 1;
+                        if (i < info->cAccDescr - 1)
+                        {
+                            strcpyW(str, accessMethodSep);
+                            str += strlenW(accessMethodSep);
+                        }
+                    }
+                }
+            }
+        }
+        LocalFree(info);
+    }
+    return ret;
+}
+
+static WCHAR keyCompromise[MAX_STRING_RESOURCE_LEN];
+static WCHAR caCompromise[MAX_STRING_RESOURCE_LEN];
+static WCHAR affiliationChanged[MAX_STRING_RESOURCE_LEN];
+static WCHAR superseded[MAX_STRING_RESOURCE_LEN];
+static WCHAR operationCeased[MAX_STRING_RESOURCE_LEN];
+static WCHAR certificateHold[MAX_STRING_RESOURCE_LEN];
+
+struct reason_map_entry
+{
+    BYTE   reasonBit;
+    LPWSTR reason;
+    int    id;
+};
+static struct reason_map_entry reason_map[] = {
+ { CRL_REASON_KEY_COMPROMISE_FLAG, keyCompromise, IDS_REASON_KEY_COMPROMISE },
+ { CRL_REASON_CA_COMPROMISE_FLAG, caCompromise, IDS_REASON_CA_COMPROMISE },
+ { CRL_REASON_AFFILIATION_CHANGED_FLAG, affiliationChanged,
+   IDS_REASON_AFFILIATION_CHANGED },
+ { CRL_REASON_SUPERSEDED_FLAG, superseded, IDS_REASON_SUPERSEDED },
+ { CRL_REASON_CESSATION_OF_OPERATION_FLAG, operationCeased,
+   IDS_REASON_CESSATION_OF_OPERATION },
+ { CRL_REASON_CERTIFICATE_HOLD_FLAG, certificateHold,
+   IDS_REASON_CERTIFICATE_HOLD },
+};
+
+static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
+ const CRYPT_BIT_BLOB *reasonFlags, LPWSTR str, DWORD *pcbStr)
+{
+    static const WCHAR sep[] = { ',',' ',0 };
+    static const WCHAR bitsFmt[] = { ' ','(','%','0','2','x',')',0 };
+    static BOOL stringsLoaded = FALSE;
+    int i, numReasons = 0;
+    BOOL ret = TRUE;
+    DWORD bytesNeeded = sizeof(WCHAR);
+    WCHAR bits[6];
+
+    if (!stringsLoaded)
+    {
+        for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+            LoadStringW(hInstance, reason_map[i].id, reason_map[i].reason,
+             MAX_STRING_RESOURCE_LEN);
+        stringsLoaded = TRUE;
+    }
+    /* No need to check reasonFlags->cbData, we already know it's positive.
+     * Ignore any other bytes, as they're for undefined bits.
+     */
+    for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+    {
+        if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
+        {
+            bytesNeeded += strlenW(reason_map[i].reason) * sizeof(WCHAR);
+            if (numReasons++)
+                bytesNeeded += strlenW(sep) * sizeof(WCHAR);
+        }
+    }
+    sprintfW(bits, bitsFmt, reasonFlags->pbData[0]);
+    bytesNeeded += strlenW(bits);
+    if (!str)
+        *pcbStr = bytesNeeded;
+    else if (*pcbStr < bytesNeeded)
+    {
+        *pcbStr = bytesNeeded;
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        *pcbStr = bytesNeeded;
+        for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+        {
+            if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
+            {
+                strcpyW(str, reason_map[i].reason);
+                str += strlenW(reason_map[i].reason);
+                if (i < sizeof(reason_map) / sizeof(reason_map[0]) - 1 &&
+                 numReasons)
+                {
+                    strcpyW(str, sep);
+                    str += strlenW(sep);
+                }
+            }
+        }
+        strcpyW(str, bits);
+    }
+    return ret;
+}
+
+static WCHAR crlDistPoint[MAX_STRING_RESOURCE_LEN];
+static WCHAR distPointName[MAX_STRING_RESOURCE_LEN];
+static WCHAR fullName[MAX_STRING_RESOURCE_LEN];
+static WCHAR rdnName[MAX_STRING_RESOURCE_LEN];
+static WCHAR reason[MAX_STRING_RESOURCE_LEN];
+static WCHAR issuer[MAX_STRING_RESOURCE_LEN];
+
+static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    CRL_DIST_POINTS_INFO *info;
+    DWORD size;
+    BOOL ret = FALSE;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CRL_DIST_POINTS,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
+    {
+        static const WCHAR numFmt[] = { '%','d',0 };
+        static const WCHAR colon[] = { ':',0 };
+        static BOOL stringsLoaded = FALSE;
+        DWORD bytesNeeded = sizeof(WCHAR); /* space for NULL terminator */
+        BOOL haveAnEntry = FALSE;
+        LPCWSTR headingSep, nameSep;
+        WCHAR distPointNum[11];
+        DWORD i;
+
+        if (!stringsLoaded)
+        {
+            LoadStringW(hInstance, IDS_CRL_DIST_POINT, crlDistPoint,
+             sizeof(crlDistPoint) / sizeof(crlDistPoint[0]));
+            LoadStringW(hInstance, IDS_CRL_DIST_POINT_NAME, distPointName,
+             sizeof(distPointName) / sizeof(distPointName[0]));
+            LoadStringW(hInstance, IDS_CRL_DIST_POINT_FULL_NAME, fullName,
+             sizeof(fullName) / sizeof(fullName[0]));
+            LoadStringW(hInstance, IDS_CRL_DIST_POINT_RDN_NAME, rdnName,
+             sizeof(rdnName) / sizeof(rdnName[0]));
+            LoadStringW(hInstance, IDS_CRL_DIST_POINT_REASON, reason,
+             sizeof(reason) / sizeof(reason[0]));
+            LoadStringW(hInstance, IDS_CRL_DIST_POINT_ISSUER, issuer,
+             sizeof(issuer) / sizeof(issuer[0]));
+            stringsLoaded = TRUE;
+        }
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            headingSep = crlf;
+            nameSep = colonCrlf;
+        }
+        else
+        {
+            headingSep = colonSep;
+            nameSep = colon;
+        }
+
+        for (i = 0; ret && i < info->cDistPoint; i++)
+        {
+            CRL_DIST_POINT *distPoint = &info->rgDistPoint[i];
+
+            if (distPoint->DistPointName.dwDistPointNameChoice !=
+             CRL_DIST_POINT_NO_NAME)
+            {
+                bytesNeeded += strlenW(distPointName) * sizeof(WCHAR);
+                bytesNeeded += strlenW(nameSep) * sizeof(WCHAR);
+                if (distPoint->DistPointName.dwDistPointNameChoice ==
+                 CRL_DIST_POINT_FULL_NAME)
+                    bytesNeeded += strlenW(fullName) * sizeof(WCHAR);
+                else
+                    bytesNeeded += strlenW(rdnName) * sizeof(WCHAR);
+                bytesNeeded += strlenW(nameSep) * sizeof(WCHAR);
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                    bytesNeeded += 2 * strlenW(indent) * sizeof(WCHAR);
+                /* The indent level (3) is higher than when used as the issuer,
+                 * because the name is subordinate to the name type (full vs.
+                 * RDN.)
+                 */
+                ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 3,
+                 &distPoint->DistPointName.u.FullName, NULL, &size);
+                if (ret)
+                    bytesNeeded += size - sizeof(WCHAR);
+                haveAnEntry = TRUE;
+            }
+            else if (distPoint->ReasonFlags.cbData)
+            {
+                bytesNeeded += strlenW(reason) * sizeof(WCHAR);
+                ret = CRYPT_FormatReason(dwFormatStrType,
+                 &distPoint->ReasonFlags, NULL, &size);
+                if (ret)
+                    bytesNeeded += size - sizeof(WCHAR);
+                haveAnEntry = TRUE;
+            }
+            else if (distPoint->CRLIssuer.cAltEntry)
+            {
+                bytesNeeded += strlenW(issuer) * sizeof(WCHAR);
+                bytesNeeded += strlenW(nameSep) * sizeof(WCHAR);
+                ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 2,
+                 &distPoint->CRLIssuer, NULL, &size);
+                if (ret)
+                    bytesNeeded += size - sizeof(WCHAR);
+                haveAnEntry = TRUE;
+            }
+            if (haveAnEntry)
+            {
+                bytesNeeded += sizeof(WCHAR); /* left bracket */
+                sprintfW(distPointNum, numFmt, i + 1);
+                bytesNeeded += strlenW(distPointNum) * sizeof(WCHAR);
+                bytesNeeded += sizeof(WCHAR); /* right bracket */
+                bytesNeeded += strlenW(crlDistPoint) * sizeof(WCHAR);
+                bytesNeeded += strlenW(headingSep) * sizeof(WCHAR);
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                    bytesNeeded += strlenW(indent) * sizeof(WCHAR);
+            }
+        }
+        if (!haveAnEntry)
+        {
+            WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
+
+            LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
+             sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                *pcbFormat = bytesNeeded;
+                strcpyW((LPWSTR)pbFormat, infoNotAvailable);
+            }
+        }
+        else
+        {
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                LPWSTR str = pbFormat;
+
+                *pcbFormat = bytesNeeded;
+                for (i = 0; ret && i < info->cDistPoint; i++)
+                {
+                    CRL_DIST_POINT *distPoint = &info->rgDistPoint[i];
+
+                    *str++ = '[';
+                    sprintfW(distPointNum, numFmt, i + 1);
+                    strcpyW(str, distPointNum);
+                    str += strlenW(distPointNum);
+                    *str++ = ']';
+                    strcpyW(str, crlDistPoint);
+                    str += strlenW(crlDistPoint);
+                    strcpyW(str, headingSep);
+                    str += strlenW(headingSep);
+                    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                    {
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                    }
+                    if (distPoint->DistPointName.dwDistPointNameChoice !=
+                     CRL_DIST_POINT_NO_NAME)
+                    {
+                        DWORD altNameSize = bytesNeeded;
+
+                        strcpyW(str, distPointName);
+                        str += strlenW(distPointName);
+                        strcpyW(str, nameSep);
+                        str += strlenW(nameSep);
+                        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                        {
+                            strcpyW(str, indent);
+                            str += strlenW(indent);
+                            strcpyW(str, indent);
+                            str += strlenW(indent);
+                        }
+                        if (distPoint->DistPointName.dwDistPointNameChoice ==
+                         CRL_DIST_POINT_FULL_NAME)
+                        {
+                            strcpyW(str, fullName);
+                            str += strlenW(fullName);
+                        }
+                        else
+                        {
+                            strcpyW(str, rdnName);
+                            str += strlenW(rdnName);
+                        }
+                        strcpyW(str, nameSep);
+                        str += strlenW(nameSep);
+                        ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 3,
+                         &distPoint->DistPointName.u.FullName, str,
+                         &altNameSize);
+                        if (ret)
+                            str += altNameSize / sizeof(WCHAR) - 1;
+                    }
+                    else if (distPoint->ReasonFlags.cbData)
+                    {
+                        DWORD reasonSize = bytesNeeded;
+
+                        strcpyW(str, reason);
+                        str += strlenW(reason);
+                        ret = CRYPT_FormatReason(dwFormatStrType,
+                         &distPoint->ReasonFlags, str, &reasonSize);
+                        if (ret)
+                            str += reasonSize / sizeof(WCHAR) - 1;
+                    }
+                    else if (distPoint->CRLIssuer.cAltEntry)
+                    {
+                        DWORD crlIssuerSize = bytesNeeded;
+
+                        strcpyW(str, issuer);
+                        str += strlenW(issuer);
+                        strcpyW(str, nameSep);
+                        str += strlenW(nameSep);
+                        ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 2,
+                         &distPoint->CRLIssuer, str,
+                         &crlIssuerSize);
+                        if (ret)
+                            str += crlIssuerSize / sizeof(WCHAR) - 1;
+                    }
+                }
+            }
+        }
+        LocalFree(info);
+    }
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    CERT_ENHKEY_USAGE *usage;
+    DWORD size;
+    BOOL ret = FALSE;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_ENHANCED_KEY_USAGE,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &usage, &size)))
+    {
+        WCHAR unknown[MAX_STRING_RESOURCE_LEN];
+        DWORD i;
+        DWORD bytesNeeded = sizeof(WCHAR); /* space for the NULL terminator */
+        LPCWSTR sep;
+        DWORD sepLen;
+
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            sep = crlf;
+            sepLen = strlenW(crlf) * sizeof(WCHAR);
+        }
+        else
+        {
+            sep = commaSpace;
+            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
+        }
+
+        LoadStringW(hInstance, IDS_USAGE_UNKNOWN, unknown,
+         sizeof(unknown) / sizeof(unknown[0]));
+        for (i = 0; i < usage->cUsageIdentifier; i++)
+        {
+            PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+             usage->rgpszUsageIdentifier[i], CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
+
+            if (info)
+                bytesNeeded += strlenW(info->pwszName) * sizeof(WCHAR);
+            else
+                bytesNeeded += strlenW(unknown) * sizeof(WCHAR);
+            bytesNeeded += sizeof(WCHAR); /* space */
+            bytesNeeded += sizeof(WCHAR); /* left paren */
+            bytesNeeded += strlen(usage->rgpszUsageIdentifier[i]) *
+             sizeof(WCHAR);
+            bytesNeeded += sizeof(WCHAR); /* right paren */
+            if (i < usage->cUsageIdentifier - 1)
+                bytesNeeded += sepLen;
+        }
+        if (!pbFormat)
+            *pcbFormat = bytesNeeded;
+        else if (*pcbFormat < bytesNeeded)
+        {
+            *pcbFormat = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            LPWSTR str = pbFormat;
+
+            *pcbFormat = bytesNeeded;
+            for (i = 0; i < usage->cUsageIdentifier; i++)
+            {
+                PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+                 usage->rgpszUsageIdentifier[i],
+                 CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
+                LPCSTR oidPtr;
+
+                if (info)
+                {
+                    strcpyW(str, info->pwszName);
+                    str += strlenW(info->pwszName);
+                }
+                else
+                {
+                    strcpyW(str, unknown);
+                    str += strlenW(unknown);
+                }
+                *str++ = ' ';
+                *str++ = '(';
+                for (oidPtr = usage->rgpszUsageIdentifier[i]; *oidPtr; oidPtr++)
+                    *str++ = *oidPtr;
+                *str++ = ')';
+                *str = 0;
+                if (i < usage->cUsageIdentifier - 1)
+                {
+                    strcpyW(str, sep);
+                    str += sepLen / sizeof(WCHAR);
+                }
+            }
+        }
+        LocalFree(usage);
+    }
+    return ret;
+}
+
+static struct BitToString netscapeCertTypeMap[] = {
+ { NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_CLIENT, { 0 } },
+ { NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_SERVER, { 0 } },
+ { NETSCAPE_SMIME_CERT_TYPE, IDS_NETSCAPE_SMIME, { 0 } },
+ { NETSCAPE_SIGN_CERT_TYPE, IDS_NETSCAPE_SIGN, { 0 } },
+ { NETSCAPE_SSL_CA_CERT_TYPE, IDS_NETSCAPE_SSL_CA, { 0 } },
+ { NETSCAPE_SMIME_CA_CERT_TYPE, IDS_NETSCAPE_SMIME_CA, { 0 } },
+ { NETSCAPE_SIGN_CA_CERT_TYPE, IDS_NETSCAPE_SIGN_CA, { 0 } },
+};
+
+static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    DWORD size;
+    CRYPT_BIT_BLOB *bits;
+    BOOL ret;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BITS,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &bits, &size)))
+    {
+        WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
+        DWORD bytesNeeded = sizeof(WCHAR);
+
+        LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
+         sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+        if (!bits->cbData || bits->cbData > 1)
+        {
+            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                LPWSTR str = pbFormat;
+
+                *pcbFormat = bytesNeeded;
+                strcpyW(str, infoNotAvailable);
+            }
+        }
+        else
+        {
+            static BOOL stringsLoaded = FALSE;
+            int i;
+            DWORD bitStringLen;
+            BOOL first = TRUE;
+
+            if (!stringsLoaded)
+            {
+                for (i = 0; i < sizeof(netscapeCertTypeMap) /
+                 sizeof(netscapeCertTypeMap[0]); i++)
+                    LoadStringW(hInstance, netscapeCertTypeMap[i].id,
+                     netscapeCertTypeMap[i].str, MAX_STRING_RESOURCE_LEN);
+                stringsLoaded = TRUE;
+            }
+            CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
+             sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
+             NULL, &bitStringLen, &first);
+            bytesNeeded += bitStringLen;
+            bytesNeeded += 3 * sizeof(WCHAR); /* " (" + ")" */
+            CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
+             bits->cbData, NULL, &size);
+            bytesNeeded += size;
+            if (!pbFormat)
+                *pcbFormat = bytesNeeded;
+            else if (*pcbFormat < bytesNeeded)
+            {
+                *pcbFormat = bytesNeeded;
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+            {
+                LPWSTR str = pbFormat;
+
+                bitStringLen = bytesNeeded;
+                first = TRUE;
+                CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
+                 sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
+                 str, &bitStringLen, &first);
+                str += bitStringLen / sizeof(WCHAR) - 1;
+                *str++ = ' ';
+                *str++ = '(';
+                CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
+                 bits->cbData, str, &size);
+                str += size / sizeof(WCHAR) - 1;
+                *str++ = ')';
+                *str = 0;
+            }
+        }
+        LocalFree(bits);
+    }
+    return ret;
+}
+
+static WCHAR financialCriteria[MAX_STRING_RESOURCE_LEN];
+static WCHAR available[MAX_STRING_RESOURCE_LEN];
+static WCHAR notAvailable[MAX_STRING_RESOURCE_LEN];
+static WCHAR meetsCriteria[MAX_STRING_RESOURCE_LEN];
+static WCHAR yes[MAX_STRING_RESOURCE_LEN];
+static WCHAR no[MAX_STRING_RESOURCE_LEN];
+
+static BOOL WINAPI CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    SPC_FINANCIAL_CRITERIA criteria;
+    DWORD size = sizeof(criteria);
+    BOOL ret = FALSE;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType,
+     SPC_FINANCIAL_CRITERIA_STRUCT, pbEncoded, cbEncoded, 0, NULL, &criteria,
+     &size)))
+    {
+        static BOOL stringsLoaded = FALSE;
+        DWORD bytesNeeded = sizeof(WCHAR);
+        LPCWSTR sep;
+        DWORD sepLen;
+
+        if (!stringsLoaded)
+        {
+            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA, financialCriteria,
+             sizeof(financialCriteria) / sizeof(financialCriteria[0]));
+            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_AVAILABLE, available,
+             sizeof(available) / sizeof(available[0]));
+            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE,
+             notAvailable, sizeof(notAvailable) / sizeof(notAvailable[0]));
+            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA,
+             meetsCriteria, sizeof(meetsCriteria) / sizeof(meetsCriteria[0]));
+            LoadStringW(hInstance, IDS_YES, yes, sizeof(yes) / sizeof(yes[0]));
+            LoadStringW(hInstance, IDS_NO, no, sizeof(no) / sizeof(no[0]));
+            stringsLoaded = TRUE;
+        }
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            sep = crlf;
+            sepLen = strlenW(crlf) * sizeof(WCHAR);
+        }
+        else
+        {
+            sep = commaSpace;
+            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
+        }
+        bytesNeeded += strlenW(financialCriteria) * sizeof(WCHAR);
+        if (criteria.fFinancialInfoAvailable)
+        {
+            bytesNeeded += strlenW(available) * sizeof(WCHAR);
+            bytesNeeded += sepLen;
+            bytesNeeded += strlenW(meetsCriteria) * sizeof(WCHAR);
+            if (criteria.fMeetsCriteria)
+                bytesNeeded += strlenW(yes) * sizeof(WCHAR);
+            else
+                bytesNeeded += strlenW(no) * sizeof(WCHAR);
+        }
+        else
+            bytesNeeded += strlenW(notAvailable) * sizeof(WCHAR);
+        if (!pbFormat)
+            *pcbFormat = bytesNeeded;
+        else if (*pcbFormat < bytesNeeded)
+        {
+            *pcbFormat = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            LPWSTR str = pbFormat;
+
+            *pcbFormat = bytesNeeded;
+            strcpyW(str, financialCriteria);
+            str += strlenW(financialCriteria);
+            if (criteria.fFinancialInfoAvailable)
+            {
+                strcpyW(str, available);
+                str += strlenW(available);
+                strcpyW(str, sep);
+                str += sepLen / sizeof(WCHAR);
+                strcpyW(str, meetsCriteria);
+                str += strlenW(meetsCriteria);
+                if (criteria.fMeetsCriteria)
+                    strcpyW(str, yes);
+                else
+                    strcpyW(str, no);
+            }
+            else
+            {
+                strcpyW(str, notAvailable);
+                str += strlenW(notAvailable);
+            }
+        }
+    }
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_FormatUnicodeString(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    CERT_NAME_VALUE *value;
+    DWORD size;
+    BOOL ret;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_UNICODE_ANY_STRING,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &value, &size)))
+    {
+        if (!pbFormat)
+            *pcbFormat = value->Value.cbData;
+        else if (*pcbFormat < value->Value.cbData)
+        {
+            *pcbFormat = value->Value.cbData;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            LPWSTR str = pbFormat;
+
+            *pcbFormat = value->Value.cbData;
+            strcpyW(str, (LPWSTR)value->Value.pbData);
+        }
+    }
+    return ret;
+}
+
+typedef BOOL (WINAPI *CryptFormatObjectFunc)(DWORD, DWORD, DWORD, void *,
+ LPCSTR, const BYTE *, DWORD, void *, DWORD *);
+
+static CryptFormatObjectFunc CRYPT_GetBuiltinFormatFunction(DWORD encodingType,
+ DWORD formatStrType, LPCSTR lpszStructType)
+{
+    CryptFormatObjectFunc format = NULL;
+
+    if ((encodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
+    {
+        SetLastError(ERROR_FILE_NOT_FOUND);
+        return NULL;
+    }
+    if (!HIWORD(lpszStructType))
+    {
+        switch (LOWORD(lpszStructType))
+        {
+        case LOWORD(X509_KEY_USAGE):
+            format = CRYPT_FormatKeyUsage;
+            break;
+        case LOWORD(X509_ALTERNATE_NAME):
+            format = CRYPT_FormatAltName;
+            break;
+        case LOWORD(X509_BASIC_CONSTRAINTS2):
+            format = CRYPT_FormatBasicConstraints2;
+            break;
+        case LOWORD(X509_AUTHORITY_KEY_ID2):
+            format = CRYPT_FormatAuthorityKeyId2;
+            break;
+        case LOWORD(X509_AUTHORITY_INFO_ACCESS):
+            format = CRYPT_FormatAuthorityInfoAccess;
+            break;
+        case LOWORD(X509_CRL_DIST_POINTS):
+            format = CRYPT_FormatCRLDistPoints;
+            break;
+        case LOWORD(X509_ENHANCED_KEY_USAGE):
+            format = CRYPT_FormatEnhancedKeyUsage;
+            break;
+        case LOWORD(SPC_FINANCIAL_CRITERIA_STRUCT):
+            format = CRYPT_FormatSpcFinancialCriteria;
+            break;
+        }
+    }
+    else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
+        format = CRYPT_FormatAltName;
+    else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
+        format = CRYPT_FormatAltName;
+    else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
+        format = CRYPT_FormatKeyUsage;
+    else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
+        format = CRYPT_FormatAltName;
+    else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
+        format = CRYPT_FormatAltName;
+    else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
+        format = CRYPT_FormatBasicConstraints2;
+    else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
+        format = CRYPT_FormatAuthorityInfoAccess;
+    else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
+        format = CRYPT_FormatAuthorityKeyId2;
+    else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
+        format = CRYPT_FormatCRLDistPoints;
+    else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
+        format = CRYPT_FormatEnhancedKeyUsage;
+    else if (!strcmp(lpszStructType, szOID_NETSCAPE_CERT_TYPE))
+        format = CRYPT_FormatNetscapeCertType;
+    else if (!strcmp(lpszStructType, szOID_NETSCAPE_BASE_URL) ||
+     !strcmp(lpszStructType, szOID_NETSCAPE_REVOCATION_URL) ||
+     !strcmp(lpszStructType, szOID_NETSCAPE_CA_REVOCATION_URL) ||
+     !strcmp(lpszStructType, szOID_NETSCAPE_CERT_RENEWAL_URL) ||
+     !strcmp(lpszStructType, szOID_NETSCAPE_CA_POLICY_URL) ||
+     !strcmp(lpszStructType, szOID_NETSCAPE_SSL_SERVER_NAME) ||
+     !strcmp(lpszStructType, szOID_NETSCAPE_COMMENT))
+        format = CRYPT_FormatUnicodeString;
+    else if (!strcmp(lpszStructType, SPC_FINANCIAL_CRITERIA_OBJID))
+        format = CRYPT_FormatSpcFinancialCriteria;
+    return format;
+}
+
+BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
+ DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType,
+ const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat)
+{
+    CryptFormatObjectFunc format = NULL;
+    HCRYPTOIDFUNCADDR hFunc = NULL;
+    BOOL ret = FALSE;
+
+    TRACE("(%08x, %d, %08x, %p, %s, %p, %d, %p, %p)\n", dwCertEncodingType,
+     dwFormatType, dwFormatStrType, pFormatStruct, debugstr_a(lpszStructType),
+     pbEncoded, cbEncoded, pbFormat, pcbFormat);
+
+    if (!(format = CRYPT_GetBuiltinFormatFunction(dwCertEncodingType,
+     dwFormatStrType, lpszStructType)))
+    {
+        static HCRYPTOIDFUNCSET set = NULL;
+
+        if (!set)
+            set = CryptInitOIDFunctionSet(CRYPT_OID_FORMAT_OBJECT_FUNC, 0);
+        CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
+         (void **)&format, &hFunc);
+    }
+    if (!format && (dwCertEncodingType & CERT_ENCODING_TYPE_MASK) ==
+     X509_ASN_ENCODING && !(dwFormatStrType & CRYPT_FORMAT_STR_NO_HEX))
+        format = CRYPT_FormatHexString;
+    if (format)
+        ret = format(dwCertEncodingType, dwFormatType, dwFormatStrType,
+         pFormatStruct, lpszStructType, pbEncoded, cbEncoded, pbFormat,
+         pcbFormat);
+    if (hFunc)
+        CryptFreeOIDFunctionAddress(hFunc, 0);
+    return ret;
+}
index 5a71c74..b4aae66 100644 (file)
@@ -37,13 +37,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 
 static const WCHAR DllW[] = { 'D','l','l',0 };
 
-static void init_oid_info(HINSTANCE hinst);
+static void init_oid_info(void);
 static void free_function_sets(void);
 static void free_oid_info(void);
 
-void crypt_oid_init(HINSTANCE hinst)
+void crypt_oid_init(void)
 {
-    init_oid_info(hinst);
+    init_oid_info();
 }
 
 void crypt_oid_free(void)
@@ -993,9 +993,9 @@ BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
     return ret;
 }
 
-static void oid_init_localizednames(HINSTANCE hInstance)
+static void oid_init_localizednames(void)
 {
-    int i;
+    unsigned int i;
 
     for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
     {
@@ -1008,7 +1008,7 @@ static void oid_init_localizednames(HINSTANCE hInstance)
  */
 LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
 {
-    int i;
+    unsigned int i;
 
     for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
     {
@@ -1367,11 +1367,11 @@ struct OIDInfo {
     struct list entry;
 };
 
-static void init_oid_info(HINSTANCE hinst)
+static void init_oid_info(void)
 {
     DWORD i;
 
-    oid_init_localizednames(hinst);
+    oid_init_localizednames();
     for (i = 0; i < sizeof(oidInfoConstructors) /
      sizeof(oidInfoConstructors[0]); i++)
     {
@@ -1402,7 +1402,8 @@ static void init_oid_info(HINSTANCE hinst)
         else
         {
             LPCWSTR stringresource;
-            int len = LoadStringW(hinst, (UINT_PTR)oidInfoConstructors[i].pwszName,
+            int len = LoadStringW(hInstance,
+             (UINT_PTR)oidInfoConstructors[i].pwszName,
              (LPWSTR)&stringresource, 0);
 
             if (len)
index d3e0034..d86dd8e 100644 (file)
@@ -607,8 +607,7 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr,
     pInfo->hash_len=CRYPT32_PROTECTDATA_HASH_LEN;
 
     /* allocate memory to hold a salt */
-    pInfo->salt.cbData=CRYPT32_PROTECTDATA_SALT_LEN;
-    if ((pInfo->salt.pbData=CryptMemAlloc(pInfo->salt.cbData)))
+    if ((pInfo->salt.pbData=CryptMemAlloc(CRYPT32_PROTECTDATA_SALT_LEN)))
     {
         /* generate random salt */
         if (!CryptGenRandom(hProv, pInfo->salt.cbData, pInfo->salt.pbData))
@@ -617,6 +616,7 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr,
             free_protect_data(pInfo);
             return FALSE;
         }
+        pInfo->salt.cbData=CRYPT32_PROTECTDATA_SALT_LEN;
     }
 
     /* debug: show our salt */
index fba11eb..70dba64 100644 (file)
@@ -78,7 +78,7 @@ static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
     /* dirty trick: replace the returned context's hCertStore with
      * store.
      */
-    if (ppStoreContext)
+    if (ret && ppStoreContext)
         (*(PCERT_CONTEXT *)ppStoreContext)->hCertStore = store;
     return ret;
 }
@@ -145,7 +145,7 @@ static BOOL CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
     /* dirty trick: replace the returned context's hCertStore with
      * store.
      */
-    if (ppStoreContext)
+    if (ret && ppStoreContext)
         (*(PCRL_CONTEXT *)ppStoreContext)->hCertStore = store;
     return ret;
 }
@@ -212,7 +212,7 @@ static BOOL CRYPT_ProvAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
     /* dirty trick: replace the returned context's hCertStore with
      * store.
      */
-    if (ppStoreContext)
+    if (ret && ppStoreContext)
         (*(PCTL_CONTEXT *)ppStoreContext)->hCertStore = store;
     return ret;
 }
index 5574a5e..7b9d67c 100644 (file)
@@ -332,7 +332,7 @@ static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
     CryptMemFree(store);
 }
 
-static BOOL WINAPI CRYPT_RegWriteContext(PWINE_REGSTOREINFO store,
+static BOOL CRYPT_RegWriteContext(PWINE_REGSTOREINFO store,
  const void *context, DWORD dwFlags)
 {
     BOOL ret;
index ba90730..116c934 100644 (file)
@@ -22,7 +22,9 @@
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
+#ifdef HAVE_DIRENT_H
 #include <dirent.h>
+#endif
 #include <fcntl.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -313,11 +315,12 @@ static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store,
  */
 static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store)
 {
+#ifdef HAVE_READDIR
     BOOL ret = FALSE;
     DIR *dir;
 
     TRACE("(%s, %p)\n", debugstr_a(path), store);
-    /* UNIX functions = bad for reactos
+
     dir = opendir(path);
     if (dir)
     {
@@ -340,8 +343,11 @@ static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store)
             CryptMemFree(filebuf);
         }
     }
-    */
     return ret;
+#else
+    FIXME("not implemented without readdir available\n");
+    return FALSE;
+#endif
 }
 
 /* Opens path, which may be a file or a directory, and imports any certificates
@@ -432,6 +438,7 @@ static const char * const CRYPT_knownLocations[] = {
  "/etc/ssl/certs/ca-certificates.crt",
  "/etc/ssl/certs",
  "/etc/pki/tls/certs/ca-bundle.crt",
+ "/usr/local/share/certs/",
 };
 
 static const BYTE authenticode[] = {
@@ -656,7 +663,7 @@ static const BYTE rootcertauthority[] = {
 0xf8,0x04,0x4d,0x30,0x92,0x3d,0x6e,0x21,0x14,0x21,0xc9,0x3d,0xe0,0xc3,0xfd,0x8a,
 0x6b,0x9d,0x4a,0xfd,0xd1,0xa1,0x9d,0x99,0x43,0x77,0x3f,0xb0,0xda };
 
-struct CONST_BLOB {
+static const struct CONST_BLOB {
     const BYTE *pb;
     DWORD       cb;
 } msRootCerts[] = {
index 8258e79..e207457 100644 (file)
@@ -315,6 +315,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
     /* FIXME, find out if there is a name for this GUID */
     static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
     static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }};
+    static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
     static const WORD dosHdr = IMAGE_DOS_SIGNATURE;
     static const BYTE cabHdr[] = { 'M','S','C','F' };
     BYTE hdr[SIP_MAX_MAGIC_NUMBER];
@@ -355,6 +356,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
         goto cleanup;
     }
 
+    TRACE("file magic = 0x%02x%02x%02x%02x\n", hdr[0], hdr[1], hdr[2], hdr[3]);
     /* As everything is in place now we start looking at the file header */
     if (!memcmp(hdr, &dosHdr, sizeof(dosHdr)))
     {
@@ -371,6 +373,61 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
         bRet = TRUE;
         goto cleanup;
     }
+    /* If it's asn.1-encoded, it's probably a .cat file. */
+    if (hdr[0] == 0x30)
+    {
+        DWORD fileLen = GetFileSize(hFile, NULL);
+
+        TRACE("fileLen = %d\n", fileLen);
+        /* Sanity-check length */
+        if (hdr[1] < 0x80 && fileLen == 2 + hdr[1])
+        {
+            *pgSubject = catGUID;
+            SetLastError(S_OK);
+            bRet = TRUE;
+            goto cleanup;
+        }
+        else if (hdr[1] == 0x80)
+        {
+            /* Indefinite length, can't verify with just the header, assume it
+             * is.
+             */
+            *pgSubject = catGUID;
+            SetLastError(S_OK);
+            bRet = TRUE;
+            goto cleanup;
+        }
+        else
+        {
+            BYTE lenBytes = hdr[1] & 0x7f;
+
+            if (lenBytes == 1 && fileLen == 2 + lenBytes + hdr[2])
+            {
+                *pgSubject = catGUID;
+                SetLastError(S_OK);
+                bRet = TRUE;
+                goto cleanup;
+            }
+            else if (lenBytes == 2 && fileLen == 2 + lenBytes +
+             (hdr[2] << 8 | hdr[3]))
+            {
+                *pgSubject = catGUID;
+                SetLastError(S_OK);
+                bRet = TRUE;
+                goto cleanup;
+            }
+            else if (fileLen > 0xffff)
+            {
+                /* The file size must be greater than 2 bytes in length, so
+                 * assume it is a .cat file
+                 */
+                *pgSubject = catGUID;
+                SetLastError(S_OK);
+                bRet = TRUE;
+                goto cleanup;
+            }
+        }
+    }
 
     /* Check for supported functions using CryptSIPDllIsMyFileType */
     /* max length of szFullKey depends on our code only, so we won't overrun */
index 6d9177e..1519c96 100644 (file)
@@ -156,7 +156,7 @@ static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
 
     TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
 
-    context = (PCERT_CONTEXT)ContextList_Add(ms->certs, cert, toReplace);
+    context = ContextList_Add(ms->certs, cert, toReplace);
     if (context)
     {
         context->hCertStore = store;
@@ -197,7 +197,7 @@ static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
 
     TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
 
-    context = (PCRL_CONTEXT)ContextList_Add(ms->crls, crl, toReplace);
+    context = ContextList_Add(ms->crls, crl, toReplace);
     if (context)
     {
         context->hCertStore = store;
@@ -238,7 +238,7 @@ static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
 
     TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
 
-    context = (PCTL_CONTEXT)ContextList_Add(ms->ctls, ctl, toReplace);
+    context = ContextList_Add(ms->ctls, ctl, toReplace);
     if (context)
     {
         context->hCertStore = store;
@@ -1321,7 +1321,7 @@ BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
             rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
                 NULL);
             if (!rc)
-                ret = pfnEnum(name, 0, &info, NULL, pvArg);
+                ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
         } while (ret && !rc);
         if (ret && rc != ERROR_NO_MORE_ITEMS)
             SetLastError(rc);
@@ -1330,3 +1330,16 @@ BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
         SetLastError(rc);
     return ret;
 }
+
+BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
+ void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
+{
+    if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
+        FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
+         pfnEnum);
+    else
+        FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w((LPCWSTR)pvSystemStore),
+         dwFlags, pvArg,
+         pfnEnum);
+    return FALSE;
+}
index 7a739a8..d3bca2b 100644 (file)
@@ -167,7 +167,7 @@ static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz)
 
     if (psz)
     {
-        chars = min(lstrlenA(prefix), csz);
+        chars = min(strlen(prefix), csz);
         memcpy(psz, prefix, chars);
         *(psz + chars) = '=';
         chars++;
@@ -304,7 +304,7 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz)
     {
         DWORD i;
 
-        chars = min(lstrlenA(prefix), csz);
+        chars = min(strlen(prefix), csz);
         for (i = 0; i < chars; i++)
             *(psz + i) = prefix[i];
         *(psz + chars) = '=';
@@ -328,7 +328,7 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz)
 
     if (psz)
     {
-        chars = min(lstrlenW(prefix), csz);
+        chars = min(strlenW(prefix), csz);
         memcpy(psz, prefix, chars * sizeof(WCHAR));
         *(psz + chars) = '=';
         chars++;
@@ -338,8 +338,10 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz)
     return chars;
 }
 
-DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
- DWORD dwStrType, LPWSTR psz, DWORD csz)
+static const WCHAR indent[] = { ' ',' ',' ',' ',' ',0 };
+
+DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel,
+ PCERT_NAME_BLOB pName, DWORD dwStrType, LPWSTR psz, DWORD csz)
 {
     static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
      CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
@@ -352,8 +354,6 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
     BOOL bRet;
     CERT_NAME_INFO *info;
 
-    TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType,
-     psz, csz);
     if (dwStrType & unsupportedFlags)
         FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags);
 
@@ -402,6 +402,22 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
                     else
                         prefixA = rdn->rgRDNAttr[j].pszObjId;
                 }
+                if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
+                {
+                    DWORD k;
+
+                    for (k = 0; k < indentLevel; k++)
+                    {
+                        if (psz)
+                        {
+                            chars = min(strlenW(indent), csz - ret - 1);
+                            memcpy(psz + ret, indent, chars * sizeof(WCHAR));
+                        }
+                        else
+                            chars = strlenW(indent);
+                        ret += chars;
+                    }
+                }
                 if (prefixW)
                 {
                     /* - 1 is needed to account for the NULL terminator. */
@@ -448,6 +464,19 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
     }
     else
         ret++;
+    return ret;
+}
+
+DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
+ DWORD dwStrType, LPWSTR psz, DWORD csz)
+{
+    BOOL ret;
+
+    TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType,
+     psz, csz);
+
+    ret = cert_name_to_str_with_indent(dwCertEncodingType, 0, pName, dwStrType,
+     psz, csz);
     TRACE("Returning %s\n", debugstr_w(psz));
     return ret;
 }
@@ -478,7 +507,7 @@ BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500,
             {
                 if (!ret)
                 {
-                    DWORD i;
+                    LONG i;
 
                     *ppszError = pszX500;
                     for (i = 0; i < errorStr - x500; i++)
@@ -665,7 +694,7 @@ static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType,
     {
         if (value->end > value->start)
         {
-            DWORD i;
+            LONG i;
             LPWSTR ptr = (LPWSTR)nameValue.Value.pbData;
 
             for (i = 0; i < value->end - value->start; i++)
index ffd4d64..7a79371 100644 (file)
 
 #include "config.h"
 #include "wine/port.h"
-#include <stdio.h>
 
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+#define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS
+
+#include <stdio.h>
+#include <stdarg.h>
 
 #include "windef.h"
-#include "wine/debug.h"
 #include "winbase.h"
 #include "winnt.h"
 #include "winnls.h"
 #include "wininet.h"
 #include "objbase.h"
-#define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS
 #include "wincrypt.h"
 
+#include "wine/debug.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(cryptnet);
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
@@ -397,57 +400,61 @@ static BOOL CRYPT_GetObjectFromFile(HANDLE hFile, PCRYPT_BLOB_ARRAY pObject)
     return ret;
 }
 
-/* FIXME: should make wininet cache all downloads instead */
 static BOOL CRYPT_GetObjectFromCache(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
  PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
 {
     BOOL ret = FALSE;
-    INTERNET_CACHE_ENTRY_INFOW cacheInfo = { sizeof(cacheInfo), 0 };
-    DWORD size = sizeof(cacheInfo);
+    INTERNET_CACHE_ENTRY_INFOW *pCacheInfo = NULL;
+    DWORD size = 0;
 
     TRACE("(%s, %p, %p)\n", debugstr_w(pszURL), pObject, pAuxInfo);
 
-    if (GetUrlCacheEntryInfoW(pszURL, &cacheInfo, &size) ||
-     GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+    ret = GetUrlCacheEntryInfoW(pszURL, NULL, &size);
+    if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+    {
+        pCacheInfo = CryptMemAlloc(size);
+        if (pCacheInfo)
+            ret = TRUE;
+        else
+            SetLastError(ERROR_OUTOFMEMORY);
+    }
+    if (ret && (ret = GetUrlCacheEntryInfoW(pszURL, pCacheInfo, &size)))
     {
         FILETIME ft;
 
         GetSystemTimeAsFileTime(&ft);
-        if (CompareFileTime(&cacheInfo.ExpireTime, &ft) >= 0)
+        if (CompareFileTime(&pCacheInfo->ExpireTime, &ft) >= 0)
         {
-            LPINTERNET_CACHE_ENTRY_INFOW pCacheInfo = CryptMemAlloc(size);
+            HANDLE hFile = CreateFileW(pCacheInfo->lpszLocalFileName,
+             GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
-            if (pCacheInfo)
+            if (hFile != INVALID_HANDLE_VALUE)
             {
-                if (GetUrlCacheEntryInfoW(pszURL, pCacheInfo, &size))
+                if ((ret = CRYPT_GetObjectFromFile(hFile, pObject)))
                 {
-                    HANDLE hFile = CreateFileW(pCacheInfo->lpszLocalFileName,
-                     GENERIC_READ, 0, NULL, OPEN_EXISTING,
-                     FILE_ATTRIBUTE_NORMAL, NULL);
-
-                    if (hFile != INVALID_HANDLE_VALUE)
-                    {
-                        if ((ret = CRYPT_GetObjectFromFile(hFile, pObject)))
-                        {
-                            if (pAuxInfo && pAuxInfo->cbSize >=
-                             offsetof(CRYPT_RETRIEVE_AUX_INFO,
-                             pLastSyncTime) + sizeof(PFILETIME) &&
-                             pAuxInfo->pLastSyncTime)
-                                memcpy(pAuxInfo->pLastSyncTime,
-                                 &pCacheInfo->LastSyncTime,
-                                 sizeof(FILETIME));
-                        }
-                        CloseHandle(hFile);
-                    }
+                    if (pAuxInfo && pAuxInfo->cbSize >=
+                     offsetof(CRYPT_RETRIEVE_AUX_INFO,
+                     pLastSyncTime) + sizeof(PFILETIME) &&
+                     pAuxInfo->pLastSyncTime)
+                        memcpy(pAuxInfo->pLastSyncTime,
+                         &pCacheInfo->LastSyncTime,
+                         sizeof(FILETIME));
                 }
-                CryptMemFree(pCacheInfo);
+                CloseHandle(hFile);
             }
             else
-                SetLastError(ERROR_OUTOFMEMORY);
+            {
+                DeleteUrlCacheEntryW(pszURL);
+                ret = FALSE;
+            }
         }
         else
+        {
             DeleteUrlCacheEntryW(pszURL);
+            ret = FALSE;
+        }
     }
+    CryptMemFree(pCacheInfo);
     TRACE("returning %d\n", ret);
     return ret;
 }
@@ -597,30 +604,73 @@ static BOOL CRYPT_DownloadObject(DWORD dwRetrievalFlags, HINTERNET hHttp,
     return ret;
 }
 
+/* Finds the object specified by pszURL in the cache.  If it's not found,
+ * creates a new cache entry for the object and writes the object to it.
+ * Sets the expiration time of the cache entry to expires.
+ */
 static void CRYPT_CacheURL(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
  DWORD dwRetrievalFlags, FILETIME expires)
 {
     WCHAR cacheFileName[MAX_PATH];
+    DWORD size = 0;
+    BOOL ret, create = FALSE;
+
+    GetUrlCacheEntryInfoW(pszURL, NULL, &size);
+    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+    {
+        INTERNET_CACHE_ENTRY_INFOW *info = CryptMemAlloc(size);
+
+        if (info)
+        {
+            FILETIME ft;
 
-    /* FIXME: let wininet directly cache instead */
-    if (CreateUrlCacheEntryW(pszURL, pObject->rgBlob[0].cbData, NULL,
-     cacheFileName, 0))
+            ret = GetUrlCacheEntryInfoW(pszURL, info, &size);
+            if (ret)
+                lstrcpyW(cacheFileName, info->lpszLocalFileName);
+            /* Check if the existing cache entry is up to date.  If it isn't,
+             * overwite it with the new value.
+             */
+            GetSystemTimeAsFileTime(&ft);
+            if (CompareFileTime(&info->ExpireTime, &ft) < 0)
+                create = TRUE;
+            CryptMemFree(info);
+        }
+        else
+            ret = FALSE;
+    }
+    else
+    {
+        ret = CreateUrlCacheEntryW(pszURL, pObject->rgBlob[0].cbData, NULL,
+         cacheFileName, 0);
+        create = TRUE;
+    }
+    if (ret)
     {
-        HANDLE hCacheFile = CreateFileW(cacheFileName, GENERIC_WRITE, 0, NULL,
-         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+        DWORD entryType;
+        FILETIME ft = { 0 };
 
-        if (hCacheFile != INVALID_HANDLE_VALUE)
+        if (create)
         {
-            DWORD bytesWritten, entryType;
-            FILETIME ft = { 0 };
+            HANDLE hCacheFile = CreateFileW(cacheFileName, GENERIC_WRITE, 0,
+             NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+            if (hCacheFile != INVALID_HANDLE_VALUE)
+            {
+                DWORD bytesWritten;
 
+                WriteFile(hCacheFile, pObject->rgBlob[0].pbData,
+                 pObject->rgBlob[0].cbData, &bytesWritten, NULL);
+                CloseHandle(hCacheFile);
+            }
+            else
+                ret = FALSE;
+        }
+        if (ret)
+        {
             if (!(dwRetrievalFlags & CRYPT_STICKY_CACHE_RETRIEVAL))
                 entryType = NORMAL_CACHE_ENTRY;
             else
                 entryType = STICKY_CACHE_ENTRY;
-            WriteFile(hCacheFile, pObject->rgBlob[0].pbData,
-             pObject->rgBlob[0].cbData, &bytesWritten, NULL);
-            CloseHandle(hCacheFile);
             CommitUrlCacheEntryW(pszURL, cacheFileName, expires, ft, entryType,
              NULL, 0, NULL, NULL);
         }
@@ -1272,6 +1322,63 @@ static BOOL CRYPT_GetCreateFunction(LPCSTR pszObjectOid,
     return ret;
 }
 
+typedef BOOL (*get_object_expiration_func)(void *pvContext,
+ FILETIME *expiration);
+
+static BOOL CRYPT_GetExpirationFromCert(void *pvObject, FILETIME *expiration)
+{
+    PCCERT_CONTEXT cert = (PCCERT_CONTEXT)pvObject;
+
+    *expiration = cert->pCertInfo->NotAfter;
+    return TRUE;
+}
+
+static BOOL CRYPT_GetExpirationFromCRL(void *pvObject, FILETIME *expiration)
+{
+    PCCRL_CONTEXT cert = (PCCRL_CONTEXT)pvObject;
+
+    *expiration = cert->pCrlInfo->NextUpdate;
+    return TRUE;
+}
+
+static BOOL CRYPT_GetExpirationFromCTL(void *pvObject, FILETIME *expiration)
+{
+    PCCTL_CONTEXT cert = (PCCTL_CONTEXT)pvObject;
+
+    *expiration = cert->pCtlInfo->NextUpdate;
+    return TRUE;
+}
+
+static BOOL CRYPT_GetExpirationFunction(LPCSTR pszObjectOid,
+ get_object_expiration_func *getExpiration)
+{
+    BOOL ret;
+
+    if (!HIWORD(pszObjectOid))
+    {
+        switch (LOWORD(pszObjectOid))
+        {
+        case LOWORD(CONTEXT_OID_CERTIFICATE):
+            *getExpiration = CRYPT_GetExpirationFromCert;
+            ret = TRUE;
+            break;
+        case LOWORD(CONTEXT_OID_CRL):
+            *getExpiration = CRYPT_GetExpirationFromCRL;
+            ret = TRUE;
+            break;
+        case LOWORD(CONTEXT_OID_CTL):
+            *getExpiration = CRYPT_GetExpirationFromCTL;
+            ret = TRUE;
+            break;
+        default:
+            ret = FALSE;
+        }
+    }
+    else
+        ret = FALSE;
+    return ret;
+}
+
 /***********************************************************************
  *    CryptRetrieveObjectByUrlW (CRYPTNET.@)
  */
@@ -1308,7 +1415,17 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid,
          pAuxInfo);
         if (ret)
         {
+            get_object_expiration_func getExpiration;
+
             ret = create(pszObjectOid, dwRetrievalFlags, &object, ppvObject);
+            if (ret && !(dwRetrievalFlags & CRYPT_DONT_CACHE_RESULT) &&
+             CRYPT_GetExpirationFunction(pszObjectOid, &getExpiration))
+            {
+                FILETIME expires;
+
+                if (getExpiration(*ppvObject, &expires))
+                    CRYPT_CacheURL(pszURL, &object, dwRetrievalFlags, expires);
+            }
             freeObject(pszObjectOid, &object, freeContext);
         }
     }
diff --git a/reactos/dll/win32/cryptui/cert.bmp b/reactos/dll/win32/cryptui/cert.bmp
new file mode 100644 (file)
index 0000000..1f44f36
Binary files /dev/null and b/reactos/dll/win32/cryptui/cert.bmp differ
diff --git a/reactos/dll/win32/cryptui/certerror.bmp b/reactos/dll/win32/cryptui/certerror.bmp
new file mode 100644 (file)
index 0000000..98bce50
Binary files /dev/null and b/reactos/dll/win32/cryptui/certerror.bmp differ
diff --git a/reactos/dll/win32/cryptui/certwarning.bmp b/reactos/dll/win32/cryptui/certwarning.bmp
new file mode 100644 (file)
index 0000000..5961d9f
Binary files /dev/null and b/reactos/dll/win32/cryptui/certwarning.bmp differ
diff --git a/reactos/dll/win32/cryptui/checks.bmp b/reactos/dll/win32/cryptui/checks.bmp
new file mode 100644 (file)
index 0000000..d3f1b66
Binary files /dev/null and b/reactos/dll/win32/cryptui/checks.bmp differ
index 4c557e2..08451e0 100644 (file)
@@ -8,8 +8,17 @@
        <include base="ReactOS">include/reactos/wine</include>
        <define name="__WINESRC__" />
        <file>main.c</file>
+       <file>cryptui.rc</file>
        <library>wine</library>
        <library>kernel32</library>
+       <library>user32</library>
+       <library>ole32</library>
+       <library>crypt32</library>
+       <library>gdi32</library>
+       <library>uuid</library>
+       <library>urlmon</library>
+       <library>wintrust</library>
+       <library>comctl32</library>
        <library>ntdll</library>
 </module>
 </group>
diff --git a/reactos/dll/win32/cryptui/cryptui.rc b/reactos/dll/win32/cryptui/cryptui.rc
new file mode 100644 (file)
index 0000000..71dc3a0
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * cryptui dll resources
+ *
+ * Copyright 2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "commctrl.h"
+#include "dlgs.h"
+
+#include "cryptuires.h"
+
+/* @makedep: smallicons.bmp */
+IDB_SMALL_ICONS BITMAP LOADONCALL DISCARDABLE smallicons.bmp
+
+/* @makedep: cert.bmp */
+IDB_CERT BITMAP LOADONCALL DISCARDABLE cert.bmp
+
+/* @makedep: certerror.bmp */
+IDB_CERT_ERROR BITMAP LOADONCALL DISCARDABLE certerror.bmp
+
+/* @makedep: certwarning.bmp */
+IDB_CERT_WARNING BITMAP LOADONCALL DISCARDABLE certwarning.bmp
+
+/* @makedep: checks.bmp */
+IDB_CHECKS BITMAP LOADONCALL DISCARDABLE checks.bmp
+
+#include "cryptui_En.rc"
index b023ed2..9c5a861 100644 (file)
 11 stub CryptUIDlgViewCRLW
 12 stub CryptUIDlgViewCTLA
 13 stub CryptUIDlgViewCTLW
-14 stub CryptUIDlgViewCertificateA
+14 stdcall CryptUIDlgViewCertificateA(ptr ptr)
 15 stub CryptUIDlgViewCertificatePropertiesA
 16 stub CryptUIDlgViewCertificatePropertiesW
-17 stub CryptUIDlgViewCertificateW
-18 stub CryptUIDlgViewContext
+17 stdcall CryptUIDlgViewCertificateW(ptr ptr)
+18 stdcall CryptUIDlgViewContext(long ptr ptr wstr long ptr)
 19 stub CryptUIDlgViewSignerInfoA
 20 stub CryptUIDlgViewSignerInfoW
 21 stub CryptUIFreeCertificatePropertiesPagesA
@@ -34,7 +34,7 @@
 34 stub CryptUIWizExport
 35 stub CryptUIWizFreeCertRequestNoDS
 36 stub CryptUIWizFreeDigitalSignContext
-37 stub CryptUIWizImport
+37 stdcall CryptUIWizImport(long ptr wstr ptr ptr)
 38 stub CryptUIWizQueryCertRequestNoDS
 39 stub CryptUIWizSubmitCertRequestNoDS
 40 stub DllRegisterServer
diff --git a/reactos/dll/win32/cryptui/cryptui_En.rc b/reactos/dll/win32/cryptui/cryptui_En.rc
new file mode 100644 (file)
index 0000000..f904fa7
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * cryptui dll resources
+ *
+ * Copyright 2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_CERTIFICATE "Certificate"
+    IDS_CERTIFICATEINFORMATION "Certificate Information"
+    IDS_CERT_INFO_BAD_SIG "This certificate has an invalid signature.  The certificate may have been altered or corrupted."
+    IDS_CERT_INFO_UNTRUSTED_CA "This root certificate is not trusted.  To trust it, add it to your system's trusted root certificate store."
+    IDS_CERT_INFO_UNTRUSTED_ROOT "This certificate could not be validated to a trusted root certificate."
+    IDS_CERT_INFO_PARTIAL_CHAIN "This certificate's issuer could not be found."
+    IDS_CERT_INFO_BAD_PURPOSES "All the intended purposes of this certificate could not be verified."
+    IDS_CERT_INFO_PURPOSES "This cerificate is intended for the following purposes:"
+    IDS_SUBJECT_HEADING "Issued to: "
+    IDS_ISSUER_HEADING "Issued by: "
+    IDS_VALID_FROM "Valid from "
+    IDS_VALID_TO " to "
+    IDS_CERTIFICATE_BAD_SIGNATURE "This certificate has an invalid signature."
+    IDS_CERTIFICATE_BAD_TIME "This certificate has expired or is not yet valid."
+    IDS_CERTIFICATE_BAD_TIMENEST "This certificate's validity period exceeds that of its issuer."
+    IDS_CERTIFICATE_REVOKED "This certificate was revoked by its issuer."
+    IDS_CERTIFICATE_VALID "This certificate is OK."
+    IDS_FIELD "Field"
+    IDS_VALUE "Value"
+    IDS_FIELDS_ALL "<All>"
+    IDS_FIELDS_V1 "Version 1 Fields Only"
+    IDS_FIELDS_EXTENSIONS "Extensions Only"
+    IDS_FIELDS_CRITICAL_EXTENSIONS "Critical Extensions Only"
+    IDS_FIELDS_PROPERTIES "Properties Only"
+    IDS_FIELD_VERSION "Version"
+    IDS_FIELD_SERIAL_NUMBER "Serial number"
+    IDS_FIELD_ISSUER "Issuer"
+    IDS_FIELD_VALID_FROM "Valid from"
+    IDS_FIELD_VALID_TO "Valid to"
+    IDS_FIELD_SUBJECT "Subject"
+    IDS_FIELD_PUBLIC_KEY "Public key"
+    IDS_FIELD_PUBLIC_KEY_FORMAT "%s (%d bits)"
+    IDS_PROP_HASH "SHA1 hash"
+    IDS_PROP_ENHKEY_USAGE "Enhanced key usage (property)"
+    IDS_PROP_FRIENDLY_NAME "Friendly name"
+    IDS_PROP_DESCRIPTION "Description"
+    IDS_CERTIFICATE_PROPERTIES "Certificate Properties"
+    IDS_CERTIFICATE_PURPOSE_ERROR "Please enter an OID in the form 1.2.3.4"
+    IDS_CERTIFICATE_PURPOSE_EXISTS "The OID you entered already exists."
+    IDS_PURPOSE_SERVER_AUTH "Ensures the identify of a remote computer"
+    IDS_PURPOSE_CLIENT_AUTH "Proves your identity to a remote computer"
+    IDS_PURPOSE_CODE_SIGNING "Ensures software came from software publisher\nProtects software from alteration after publication"
+    IDS_PURPOSE_EMAIL_PROTECTION "Protects e-mail messges"
+    IDS_PURPOSE_IPSEC "Allows secure communication over the Internet"
+    IDS_PURPOSE_TIMESTAMP_SIGNING "Allows data to be signed with the current time"
+    IDS_PURPOSE_CTL_USAGE_SIGNING "Allows you to digitally sign a certificate trust list"
+    IDS_PURPOSE_EFS "Allows data on disk to be encrypted"
+    IDS_PURPOSE_EFS_RECOVERY "File Recovery"
+    IDS_PURPOSE_WHQL "Windows Hardware Driver Verification"
+    IDS_PURPOSE_NT5 "Windows System Component Verification"
+    IDS_PURPOSE_OEM_WHQL "OEM Windows System Component Verification"
+    IDS_PURPOSE_EMBEDDED_NT "Embedded Windows System Component Verification"
+    IDS_PURPOSE_ROOT_LIST_SIGNER "Root List Signer"
+    IDS_PURPOSE_QUALIFIED_SUBORDINATION "Qualified Subordination"
+    IDS_PURPOSE_KEY_RECOVERY "Key Recovery"
+    IDS_PURPOSE_DOCUMENT_SIGNING "Document Signing"
+    IDS_PURPOSE_LIFETIME_SIGNING "Lifetime Signing"
+    IDS_PURPOSE_DRM "Digital Rights"
+    IDS_PURPOSE_LICENSES "Key Pack Licenses"
+    IDS_PURPOSE_LICENSE_SERVER "License Server Verification"
+    IDS_PURPOSE_ENROLLMENT_AGENT "Certificate Request Agent"
+    IDS_PURPOSE_SMARTCARD_LOGON "Smart Card Logon"
+    IDS_PURPOSE_CA_EXCHANGE "Private Key Archival"
+    IDS_PURPOSE_KEY_RECOVERY_AGENT "Key Recovery Agent"
+    IDS_PURPOSE_DS_EMAIL_REPLICATION "Directory Service Email Replication"
+}
+
+IDD_GENERAL DIALOG DISCARDABLE 0, 0, 255, 236
+CAPTION "General"
+STYLE WS_VISIBLE
+FONT 8, "MS Shell Dlg"
+BEGIN
+  CONTROL "", IDC_STATIC, "Static", WS_BORDER|SS_WHITERECT, 6,10,241,200
+  CONTROL "", IDC_CERTIFICATE_ICON,"RichEdit20W",
+    ES_READONLY|WS_DISABLED,8,11,26,26
+  CONTROL "", IDC_CERTIFICATE_INFO,"RichEdit20W",
+    ES_READONLY|WS_DISABLED,34,11,212,26
+  CONTROL "", IDC_STATIC, "Static", SS_BLACKFRAME, 16,37,222,1
+  CONTROL "", IDC_CERTIFICATE_STATUS,"RichEdit20W",
+    ES_READONLY|ES_MULTILINE|WS_DISABLED,8,38,238,78
+  CONTROL "", IDC_STATIC, "Static", SS_BLACKFRAME, 16,116,222,1
+  CONTROL "", IDC_CERTIFICATE_NAMES,"RichEdit20W",
+    ES_READONLY|ES_MULTILINE|WS_DISABLED,8,117,238,91
+  PUSHBUTTON "&Install Certificate...", IDC_ADDTOSTORE,103,216,70,14
+  PUSHBUTTON "Issuer &Statement", IDC_ISSUERSTATEMENT,177,216,70,14
+END
+
+IDD_DETAIL DIALOG DISCARDABLE 0, 0, 255, 236
+CAPTION "Details"
+STYLE WS_VISIBLE
+FONT 8, "MS Shell Dlg"
+BEGIN
+  LTEXT "&Show:", stc1, 6,12,40,14
+  COMBOBOX IDC_DETAIL_SELECT, 28,10,100,14,
+    CBS_DROPDOWNLIST|WS_BORDER|WS_VSCROLL|WS_TABSTOP
+  CONTROL "", IDC_DETAIL_LIST, "SysListView32",
+    LVS_REPORT|LVS_SINGLESEL|WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER,
+    6,28,241,100
+  CONTROL "", IDC_DETAIL_VALUE, "RichEdit20W",
+    ES_READONLY|ES_MULTILINE|WS_TABSTOP, 6,136,241,70
+  PUSHBUTTON "&Edit Properties...", IDC_EDITPROPERTIES,103,216,70,14
+  PUSHBUTTON "&Copy to File...", IDC_EXPORT,177,216,70,14
+END
+
+IDD_HIERARCHY DIALOG DISCARDABLE 0, 0, 255, 236
+CAPTION "Certification Path"
+STYLE WS_VISIBLE
+FONT 8, "MS Shell Dlg"
+BEGIN
+  GROUPBOX "Certification &path", grp1,6,10,245,165, BS_GROUPBOX
+  CONTROL "",IDC_CERTPATH, "SysTreeView32", TVS_HASLINES|WS_BORDER,
+    13,22,231,130
+  PUSHBUTTON "&View Certificate", IDC_VIEWCERTIFICATE,175,156,70,14
+  LTEXT "Certificate &status:", IDC_CERTIFICATESTATUS,6,183,70,14
+  CONTROL "", IDC_CERTIFICATESTATUSTEXT,"RichEdit20W",
+    WS_BORDER|ES_READONLY|ES_MULTILINE|WS_DISABLED,6,195,245,36
+END
+
+IDD_USERNOTICE DIALOG DISCARDABLE 0, 0, 255, 256
+CAPTION "Disclaimer"
+STYLE WS_VISIBLE
+FONT 8, "MS Shell Dlg"
+BEGIN
+  CONTROL "", IDC_USERNOTICE,"RichEdit20W",
+    WS_BORDER|ES_READONLY|ES_MULTILINE|WS_DISABLED,6,10,241,200
+  PUSHBUTTON "Close", IDOK,103,216,70,14
+  PUSHBUTTON "More &Info", IDC_CPS,177,216,70,14
+END
+
+IDD_CERT_PROPERTIES_GENERAL DIALOG DISCARDABLE 0, 0, 255, 236
+CAPTION "General"
+STYLE WS_VISIBLE
+FONT 8, "MS Shell Dlg"
+BEGIN
+  LTEXT "&Friendly name:", stc1, 6,14,60,14
+  EDITTEXT IDC_FRIENDLY_NAME, 60,12,191,14, ES_AUTOHSCROLL|WS_TABSTOP
+  LTEXT "&Description:", stc2, 6,32,60,14
+  EDITTEXT IDC_DESCRIPTION, 60,30,191,14, ES_AUTOVSCROLL|ES_MULTILINE|WS_TABSTOP|WS_VSCROLL
+  GROUPBOX "Certificate purposes", grp1,6,48,245,165, BS_GROUPBOX
+  AUTORADIOBUTTON "&Enable all purposes for this certificate",
+    IDC_ENABLE_ALL_PURPOSES, 12,58,180,14, BS_AUTORADIOBUTTON|WS_TABSTOP
+  AUTORADIOBUTTON "D&isable all purposes for this certificate",
+    IDC_DISABLE_ALL_PURPOSES, 12,70,180,14, BS_AUTORADIOBUTTON
+  AUTORADIOBUTTON "Enable &only the following purposes for this certificate:",
+    IDC_ENABLE_SELECTED_PURPOSES, 12,82,180,14, BS_AUTORADIOBUTTON
+  CONTROL "", IDC_CERTIFICATE_USAGES,"SysListView32",
+    LVS_REPORT|LVS_NOCOLUMNHEADER|LVS_SINGLESEL|WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER,
+    24,100,220,90
+  PUSHBUTTON "Add &Purpose...", IDC_ADD_PURPOSE,184,194,60,14
+END
+
+IDD_ADD_CERT_PURPOSE DIALOG DISCARDABLE 0,0,200,68
+CAPTION "Add Purpose"
+FONT 8, "MS Shell Dlg"
+BEGIN
+  LTEXT "Add the object identifier (OID) for the certificate purpose you wish to add:",
+    stc1, 6,6,190,28
+  EDITTEXT IDC_NEW_PURPOSE, 6,28,190,14, ES_AUTOVSCROLL|ES_MULTILINE|WS_TABSTOP|WS_VSCROLL
+  PUSHBUTTON "OK", IDOK, 33,48,60,14
+  PUSHBUTTON "Cancel", IDCANCEL, 100,48,60,14
+END
diff --git a/reactos/dll/win32/cryptui/cryptuires.h b/reactos/dll/win32/cryptui/cryptuires.h
new file mode 100644 (file)
index 0000000..9e18852
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef __CRYPTUIRES_H_
+#define __CRYPTUIRES_H_
+
+#define IDS_CERTIFICATE 1000
+#define IDS_CERTIFICATEINFORMATION 1001
+#define IDS_CERT_INFO_BAD_SIG 1002
+#define IDS_CERT_INFO_UNTRUSTED_CA 1003
+#define IDS_CERT_INFO_UNTRUSTED_ROOT 1004
+#define IDS_CERT_INFO_PARTIAL_CHAIN 1005
+#define IDS_CERT_INFO_BAD_PURPOSES 1006
+#define IDS_CERT_INFO_PURPOSES 1007
+
+#define IDS_SUBJECT_HEADING 1010
+#define IDS_ISSUER_HEADING 1011
+#define IDS_VALID_FROM 1012
+#define IDS_VALID_TO 1013
+#define IDS_CERTIFICATE_BAD_SIGNATURE 1014
+#define IDS_CERTIFICATE_BAD_TIME 1015
+#define IDS_CERTIFICATE_BAD_TIMENEST 1016
+#define IDS_CERTIFICATE_REVOKED 1017
+#define IDS_CERTIFICATE_VALID 1018
+#define IDS_FIELD 1019
+#define IDS_VALUE 1020
+#define IDS_FIELDS_ALL 1021
+#define IDS_FIELDS_V1 1022
+#define IDS_FIELDS_EXTENSIONS 1023
+#define IDS_FIELDS_CRITICAL_EXTENSIONS 1024
+#define IDS_FIELDS_PROPERTIES 1025
+#define IDS_FIELD_VERSION 1026
+#define IDS_FIELD_SERIAL_NUMBER 1027
+#define IDS_FIELD_ISSUER 1028
+#define IDS_FIELD_VALID_FROM 1029
+#define IDS_FIELD_VALID_TO 1030
+#define IDS_FIELD_SUBJECT 1031
+#define IDS_FIELD_PUBLIC_KEY 1032
+#define IDS_FIELD_PUBLIC_KEY_FORMAT 1033
+#define IDS_PROP_HASH 1034
+#define IDS_PROP_ENHKEY_USAGE 1035
+#define IDS_PROP_FRIENDLY_NAME 1036
+#define IDS_PROP_DESCRIPTION 1037
+#define IDS_CERTIFICATE_PROPERTIES 1038
+#define IDS_CERTIFICATE_PURPOSE_ERROR 1039
+#define IDS_CERTIFICATE_PURPOSE_EXISTS 1040
+
+#define IDS_PURPOSE_SERVER_AUTH 1100
+#define IDS_PURPOSE_CLIENT_AUTH 1101
+#define IDS_PURPOSE_CODE_SIGNING 1102
+#define IDS_PURPOSE_EMAIL_PROTECTION 1103
+#define IDS_PURPOSE_IPSEC 1104
+#define IDS_PURPOSE_TIMESTAMP_SIGNING 1105
+#define IDS_PURPOSE_CTL_USAGE_SIGNING 1106
+#define IDS_PURPOSE_EFS 1107
+#define IDS_PURPOSE_EFS_RECOVERY 1108
+#define IDS_PURPOSE_WHQL 1109
+#define IDS_PURPOSE_NT5 1110
+#define IDS_PURPOSE_OEM_WHQL 1111
+#define IDS_PURPOSE_EMBEDDED_NT 1112
+#define IDS_PURPOSE_ROOT_LIST_SIGNER 1113
+#define IDS_PURPOSE_QUALIFIED_SUBORDINATION 1114
+#define IDS_PURPOSE_KEY_RECOVERY 1115
+#define IDS_PURPOSE_DOCUMENT_SIGNING 1116
+#define IDS_PURPOSE_LIFETIME_SIGNING 1117
+#define IDS_PURPOSE_DRM 1118
+#define IDS_PURPOSE_LICENSES 1119
+#define IDS_PURPOSE_LICENSE_SERVER 1120
+#define IDS_PURPOSE_ENROLLMENT_AGENT 1121
+#define IDS_PURPOSE_SMARTCARD_LOGON 1122
+#define IDS_PURPOSE_CA_EXCHANGE 1123
+#define IDS_PURPOSE_KEY_RECOVERY_AGENT 1124
+#define IDS_PURPOSE_DS_EMAIL_REPLICATION 1125
+
+#define IDD_GENERAL 100
+#define IDD_DETAIL 101
+#define IDD_HIERARCHY 102
+#define IDD_USERNOTICE 103
+#define IDD_CERT_PROPERTIES_GENERAL 104
+#define IDD_ADD_CERT_PURPOSE 105
+
+#define IDB_SMALL_ICONS 200
+#define IDB_CERT 201
+#define IDB_CERT_ERROR 202
+#define IDB_CERT_WARNING 203
+#define IDB_CHECKS 204
+
+#define IDC_STATIC 2000
+#define IDC_CERTIFICATE_ICON 2001
+#define IDC_CERTIFICATE_INFO 2002
+#define IDC_CERTIFICATE_STATUS 2003
+#define IDC_CERTIFICATE_NAMES 2004
+#define IDC_ADDTOSTORE 2005
+#define IDC_ISSUERSTATEMENT 2006
+
+#define IDC_DETAIL_SELECT 2100
+#define IDC_DETAIL_LIST 2101
+#define IDC_DETAIL_VALUE 2102
+#define IDC_EDITPROPERTIES 2103
+#define IDC_EXPORT 2104
+
+#define IDC_VIEWCERTIFICATE 2200
+#define IDC_CERTPATH 2201
+#define IDC_CERTIFICATESTATUS 2202
+#define IDC_CERTIFICATESTATUSTEXT 2203
+
+#define IDC_USERNOTICE 2300
+#define IDC_CPS 2301
+
+#define IDC_FRIENDLY_NAME 2400
+#define IDC_DESCRIPTION 2401
+#define IDC_ENABLE_ALL_PURPOSES 2402
+#define IDC_DISABLE_ALL_PURPOSES 2403
+#define IDC_ENABLE_SELECTED_PURPOSES 2404
+#define IDC_CERTIFICATE_USAGES 2405
+#define IDC_ADD_PURPOSE 2406
+
+#define IDC_NEW_PURPOSE 2500
+
+#endif /* ndef __CRYPTUIRES_H_ */
index 8784915..82a877f 100644 (file)
 
 #include <stdarg.h>
 
+#define COBJMACROS
+#define NONAMELESSUNION
+
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
 #include "winuser.h"
+#include "softpub.h"
+#include "wingdi.h"
+#include "richedit.h"
+#include "ole2.h"
+#include "richole.h"
+#include "commctrl.h"
 #include "cryptuiapi.h"
+#include "cryptuires.h"
+#include "urlmon.h"
+#include "hlink.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(cryptui);
 
+static HINSTANCE hInstance;
+
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
     TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
@@ -37,6 +53,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
         case DLL_WINE_PREATTACH:
             return FALSE;    /* prefer native version */
         case DLL_PROCESS_ATTACH:
+            hInstance = hinstDLL;
             DisableThreadLibraryCalls(hinstDLL);
             break;
         case DLL_PROCESS_DETACH:
@@ -55,3 +72,3089 @@ BOOL WINAPI CryptUIDlgCertMgr(PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr)
     FIXME("(%p): stub\n", pCryptUICertMgr);
     return FALSE;
 }
+
+/***********************************************************************
+ *             CryptUIDlgViewCertificateA (CRYPTUI.@)
+ */
+BOOL WINAPI CryptUIDlgViewCertificateA(
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTA pCertViewInfo, BOOL *pfPropertiesChanged)
+{
+    CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
+    LPWSTR title = NULL;
+    BOOL ret;
+
+    TRACE("(%p, %p)\n", pCertViewInfo, pfPropertiesChanged);
+
+    memcpy(&viewInfo, pCertViewInfo, sizeof(viewInfo));
+    if (pCertViewInfo->szTitle)
+    {
+        int len = MultiByteToWideChar(CP_ACP, 0, pCertViewInfo->szTitle, -1,
+         NULL, 0);
+
+        title = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        if (title)
+        {
+            MultiByteToWideChar(CP_ACP, 0, pCertViewInfo->szTitle, -1, title,
+             len);
+            viewInfo.szTitle = title;
+        }
+        else
+        {
+            ret = FALSE;
+            goto error;
+        }
+    }
+    if (pCertViewInfo->cPropSheetPages)
+    {
+        FIXME("ignoring additional prop sheet pages\n");
+        viewInfo.cPropSheetPages = 0;
+    }
+    ret = CryptUIDlgViewCertificateW(&viewInfo, pfPropertiesChanged);
+    HeapFree(GetProcessHeap(), 0, title);
+error:
+    return ret;
+}
+
+struct ReadStringStruct
+{
+    LPCWSTR buf;
+    LONG pos;
+    LONG len;
+};
+
+static DWORD CALLBACK read_text_callback(DWORD_PTR dwCookie, LPBYTE buf,
+ LONG cb, LONG *pcb)
+{
+    struct ReadStringStruct *string = (struct ReadStringStruct *)dwCookie;
+    LONG cch = min(cb / sizeof(WCHAR), string->len - string->pos);
+
+    TRACE("(%p, %p, %d, %p)\n", string, buf, cb, pcb);
+
+    memmove(buf, string->buf + string->pos, cch * sizeof(WCHAR));
+    string->pos += cch;
+    *pcb = cch * sizeof(WCHAR);
+    return 0;
+}
+
+static void add_unformatted_text_to_control(HWND hwnd, LPCWSTR text, LONG len)
+{
+    struct ReadStringStruct string;
+    EDITSTREAM editstream;
+
+    TRACE("(%p, %s)\n", hwnd, debugstr_wn(text, len));
+
+    string.buf = text;
+    string.pos = 0;
+    string.len = len;
+    editstream.dwCookie = (DWORD_PTR)&string;
+    editstream.dwError = 0;
+    editstream.pfnCallback = read_text_callback;
+    SendMessageW(hwnd, EM_STREAMIN, SF_TEXT | SFF_SELECTION | SF_UNICODE,
+     (LPARAM)&editstream);
+}
+
+static void add_string_resource_to_control(HWND hwnd, int id)
+{
+    LPWSTR str;
+    LONG len;
+
+    len = LoadStringW(hInstance, id, (LPWSTR)&str, 0);
+    add_unformatted_text_to_control(hwnd, str, len);
+}
+
+static void add_text_with_paraformat_to_control(HWND hwnd, LPCWSTR text,
+ LONG len, const PARAFORMAT2 *fmt)
+{
+    add_unformatted_text_to_control(hwnd, text, len);
+    SendMessageW(hwnd, EM_SETPARAFORMAT, 0, (LPARAM)fmt);
+}
+
+static void add_string_resource_with_paraformat_to_control(HWND hwnd, int id,
+ const PARAFORMAT2 *fmt)
+{
+    LPWSTR str;
+    LONG len;
+
+    len = LoadStringW(hInstance, id, (LPWSTR)&str, 0);
+    add_text_with_paraformat_to_control(hwnd, str, len, fmt);
+}
+
+static LPWSTR get_cert_name_string(PCCERT_CONTEXT pCertContext, DWORD dwType,
+ DWORD dwFlags)
+{
+    LPWSTR buf = NULL;
+    DWORD len;
+
+    len = CertGetNameStringW(pCertContext, dwType, dwFlags, NULL, NULL, 0);
+    if (len)
+    {
+        buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        if (buf)
+            CertGetNameStringW(pCertContext, dwType, dwFlags, NULL, buf, len);
+    }
+    return buf;
+}
+
+static void add_cert_string_to_control(HWND hwnd, PCCERT_CONTEXT pCertContext,
+ DWORD dwType, DWORD dwFlags)
+{
+    LPWSTR name = get_cert_name_string(pCertContext, dwType, dwFlags);
+
+    if (name)
+    {
+        /* Don't include NULL-terminator in output */
+        DWORD len = lstrlenW(name);
+
+        add_unformatted_text_to_control(hwnd, name, len);
+        HeapFree(GetProcessHeap(), 0, name);
+    }
+}
+
+static void add_icon_to_control(HWND hwnd, int id)
+{
+    HRESULT hr;
+    LPRICHEDITOLE richEditOle = NULL;
+    LPOLEOBJECT object = NULL;
+    CLSID clsid;
+    LPOLECACHE oleCache = NULL;
+    FORMATETC formatEtc;
+    DWORD conn;
+    LPDATAOBJECT dataObject = NULL;
+    HBITMAP bitmap = NULL;
+    RECT rect;
+    STGMEDIUM stgm;
+    REOBJECT reObject;
+
+    TRACE("(%p, %d)\n", hwnd, id);
+
+    SendMessageW(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&richEditOle);
+    if (!richEditOle)
+        goto end;
+    hr = OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject,
+     (void**)&object);
+    if (FAILED(hr))
+        goto end;
+    hr = IOleObject_GetUserClassID(object, &clsid);
+    if (FAILED(hr))
+        goto end;
+    hr = IOleObject_QueryInterface(object, &IID_IOleCache, (void**)&oleCache);
+    if (FAILED(hr))
+        goto end;
+    formatEtc.cfFormat = CF_BITMAP;
+    formatEtc.ptd = NULL;
+    formatEtc.dwAspect = DVASPECT_CONTENT;
+    formatEtc.lindex = -1;
+    formatEtc.tymed = TYMED_GDI;
+    hr = IOleCache_Cache(oleCache, &formatEtc, 0, &conn);
+    if (FAILED(hr))
+        goto end;
+    hr = IOleObject_QueryInterface(object, &IID_IDataObject,
+     (void**)&dataObject);
+    if (FAILED(hr))
+        goto end;
+    bitmap = LoadImageW(hInstance, MAKEINTRESOURCEW(id), IMAGE_BITMAP, 0, 0,
+     LR_DEFAULTSIZE | LR_LOADTRANSPARENT);
+    if (!bitmap)
+        goto end;
+    rect.left = rect.top = 0;
+    rect.right = GetSystemMetrics(SM_CXICON);
+    rect.bottom = GetSystemMetrics(SM_CYICON);
+    stgm.tymed = TYMED_GDI;
+    stgm.u.hBitmap = bitmap;
+    stgm.pUnkForRelease = NULL;
+    hr = IDataObject_SetData(dataObject, &formatEtc, &stgm, TRUE);
+    if (FAILED(hr))
+        goto end;
+
+    reObject.cbStruct = sizeof(reObject);
+    reObject.cp = REO_CP_SELECTION;
+    reObject.clsid = clsid;
+    reObject.poleobj = object;
+    reObject.pstg = NULL;
+    reObject.polesite = NULL;
+    reObject.sizel.cx = reObject.sizel.cy = 0;
+    reObject.dvaspect = DVASPECT_CONTENT;
+    reObject.dwFlags = 0;
+    reObject.dwUser = 0;
+
+    IRichEditOle_InsertObject(richEditOle, &reObject);
+
+end:
+    if (dataObject)
+        IDataObject_Release(dataObject);
+    if (oleCache)
+        IOleCache_Release(oleCache);
+    if (object)
+        IOleObject_Release(object);
+    if (richEditOle)
+        IRichEditOle_Release(richEditOle);
+}
+
+#define MY_INDENT 200
+
+static void add_oid_text_to_control(HWND hwnd, char *oid)
+{
+    WCHAR nl = '\n';
+    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, oid, 0);
+    PARAFORMAT2 parFmt;
+
+    parFmt.cbSize = sizeof(parFmt);
+    parFmt.dwMask = PFM_STARTINDENT;
+    parFmt.dxStartIndent = MY_INDENT * 3;
+    if (oidInfo)
+    {
+        add_text_with_paraformat_to_control(hwnd, oidInfo->pwszName,
+         lstrlenW(oidInfo->pwszName), &parFmt);
+        add_unformatted_text_to_control(hwnd, &nl, 1);
+    }
+}
+
+#define MAX_STRING_LEN 512
+
+struct OIDToString
+{
+    LPCSTR oid;
+    int    id;
+};
+
+/* The following list MUST be lexicographically sorted by OID */
+static struct OIDToString oidMap[] = {
+ /* 1.3.6.1.4.1.311.10.3.1 */
+ { szOID_KP_CTL_USAGE_SIGNING, IDS_PURPOSE_CTL_USAGE_SIGNING },
+ /* 1.3.6.1.4.1.311.10.3.4 */
+ { szOID_KP_EFS, IDS_PURPOSE_EFS },
+ /* 1.3.6.1.4.1.311.10.3.4.1 */
+ { szOID_EFS_RECOVERY, IDS_PURPOSE_EFS_RECOVERY },
+ /* 1.3.6.1.4.1.311.10.3.5 */
+ { szOID_WHQL_CRYPTO, IDS_PURPOSE_WHQL },
+ /* 1.3.6.1.4.1.311.10.3.6 */
+ { szOID_NT5_CRYPTO, IDS_PURPOSE_NT5 },
+ /* 1.3.6.1.4.1.311.10.3.7 */
+ { szOID_OEM_WHQL_CRYPTO, IDS_PURPOSE_OEM_WHQL },
+ /* 1.3.6.1.4.1.311.10.3.8 */
+ { szOID_EMBEDDED_NT_CRYPTO, IDS_PURPOSE_EMBEDDED_NT },
+ /* 1.3.6.1.4.1.311.10.3.9 */
+ { szOID_ROOT_LIST_SIGNER, IDS_PURPOSE_ROOT_LIST_SIGNER },
+ /* 1.3.6.1.4.1.311.10.3.10 */
+ { szOID_KP_QUALIFIED_SUBORDINATION, IDS_PURPOSE_QUALIFIED_SUBORDINATION },
+ /* 1.3.6.1.4.1.311.10.3.11 */
+ { szOID_KP_KEY_RECOVERY, IDS_PURPOSE_KEY_RECOVERY },
+ /* 1.3.6.1.4.1.311.10.3.12 */
+ { szOID_KP_DOCUMENT_SIGNING, IDS_PURPOSE_DOCUMENT_SIGNING },
+ /* 1.3.6.1.4.1.311.10.3.13 */
+ { szOID_KP_LIFETIME_SIGNING, IDS_PURPOSE_LIFETIME_SIGNING },
+ /* 1.3.6.1.4.1.311.10.5.1 */
+ { szOID_DRM, IDS_PURPOSE_DRM },
+ /* 1.3.6.1.4.1.311.10.6.1 */
+ { szOID_LICENSES, IDS_PURPOSE_LICENSES },
+ /* 1.3.6.1.4.1.311.10.6.2 */
+ { szOID_LICENSE_SERVER, IDS_PURPOSE_LICENSE_SERVER },
+ /* 1.3.6.1.4.1.311.20.2.1 */
+ { szOID_ENROLLMENT_AGENT, IDS_PURPOSE_ENROLLMENT_AGENT },
+ /* 1.3.6.1.4.1.311.20.2.2 */
+ { szOID_KP_SMARTCARD_LOGON, IDS_PURPOSE_SMARTCARD_LOGON },
+ /* 1.3.6.1.4.1.311.21.5 */
+ { szOID_KP_CA_EXCHANGE, IDS_PURPOSE_CA_EXCHANGE },
+ /* 1.3.6.1.4.1.311.21.6 */
+ { szOID_KP_KEY_RECOVERY_AGENT, IDS_PURPOSE_KEY_RECOVERY_AGENT },
+ /* 1.3.6.1.4.1.311.21.19 */
+ { szOID_DS_EMAIL_REPLICATION, IDS_PURPOSE_DS_EMAIL_REPLICATION },
+ /* 1.3.6.1.5.5.7.3.1 */
+ { szOID_PKIX_KP_SERVER_AUTH, IDS_PURPOSE_SERVER_AUTH },
+ /* 1.3.6.1.5.5.7.3.2 */
+ { szOID_PKIX_KP_CLIENT_AUTH, IDS_PURPOSE_CLIENT_AUTH },
+ /* 1.3.6.1.5.5.7.3.3 */
+ { szOID_PKIX_KP_CODE_SIGNING, IDS_PURPOSE_CODE_SIGNING },
+ /* 1.3.6.1.5.5.7.3.4 */
+ { szOID_PKIX_KP_EMAIL_PROTECTION, IDS_PURPOSE_EMAIL_PROTECTION },
+ /* 1.3.6.1.5.5.7.3.5 */
+ { szOID_PKIX_KP_IPSEC_END_SYSTEM, IDS_PURPOSE_IPSEC },
+ /* 1.3.6.1.5.5.7.3.6 */
+ { szOID_PKIX_KP_IPSEC_TUNNEL, IDS_PURPOSE_IPSEC },
+ /* 1.3.6.1.5.5.7.3.7 */
+ { szOID_PKIX_KP_IPSEC_USER, IDS_PURPOSE_IPSEC },
+ /* 1.3.6.1.5.5.7.3.8 */
+ { szOID_PKIX_KP_TIMESTAMP_SIGNING, IDS_PURPOSE_TIMESTAMP_SIGNING },
+};
+
+static struct OIDToString *findSupportedOID(LPCSTR oid)
+{
+    int indexHigh = sizeof(oidMap) / sizeof(oidMap[0]) - 1, indexLow = 0, i;
+    struct OIDToString *ret = NULL;
+
+    for (i = (indexLow + indexHigh) / 2; !ret && indexLow <= indexHigh;
+     i = (indexLow + indexHigh) / 2)
+    {
+        int cmp;
+
+        cmp = strcmp(oid, oidMap[i].oid);
+        if (!cmp)
+            ret = &oidMap[i];
+        else if (cmp > 0)
+            indexLow = i + 1;
+        else
+            indexHigh = i - 1;
+    }
+    return ret;
+}
+
+static void add_local_oid_text_to_control(HWND text, LPCSTR oid)
+{
+    struct OIDToString *entry;
+    WCHAR nl = '\n';
+    PARAFORMAT2 parFmt;
+
+    parFmt.cbSize = sizeof(parFmt);
+    parFmt.dwMask = PFM_STARTINDENT;
+    parFmt.dxStartIndent = MY_INDENT * 3;
+    if ((entry = findSupportedOID(oid)))
+    {
+        WCHAR *str, *linebreak, *ptr;
+        BOOL multiline = FALSE;
+        int len;
+
+        len = LoadStringW(hInstance, entry->id, (LPWSTR)&str, 0);
+        ptr = str;
+        do {
+            if ((linebreak = memchrW(ptr, '\n', len)))
+            {
+                WCHAR copy[MAX_STRING_LEN];
+
+                multiline = TRUE;
+                /* The source string contains a newline, which the richedit
+                 * control won't find since it's interpreted as a paragraph
+                 * break.  Therefore copy up to the newline.  lstrcpynW always
+                 * NULL-terminates, so pass one more than the length of the
+                 * source line so the copy includes the entire line and the
+                 * NULL-terminator.
+                 */
+                lstrcpynW(copy, ptr, linebreak - ptr + 1);
+                add_text_with_paraformat_to_control(text, copy,
+                 linebreak - ptr, &parFmt);
+                ptr = linebreak + 1;
+                add_unformatted_text_to_control(text, &nl, 1);
+            }
+            else if (multiline && *ptr)
+            {
+                /* Add the last line */
+                add_text_with_paraformat_to_control(text, ptr,
+                 len - (ptr - str), &parFmt);
+                add_unformatted_text_to_control(text, &nl, 1);
+            }
+        } while (linebreak);
+        if (!multiline)
+        {
+            add_text_with_paraformat_to_control(text, str, len, &parFmt);
+            add_unformatted_text_to_control(text, &nl, 1);
+        }
+    }
+    else
+    {
+        WCHAR *oidW = HeapAlloc(GetProcessHeap(), 0,
+         (strlen(oid) + 1) * sizeof(WCHAR));
+
+        if (oidW)
+        {
+            LPCSTR src;
+            WCHAR *dst;
+
+            for (src = oid, dst = oidW; *src; src++, dst++)
+                *dst = *src;
+            *dst = 0;
+            add_text_with_paraformat_to_control(text, oidW, lstrlenW(oidW),
+             &parFmt);
+            add_unformatted_text_to_control(text, &nl, 1);
+            HeapFree(GetProcessHeap(), 0, oidW);
+        }
+    }
+}
+
+static void display_app_usages(HWND text, PCCERT_CONTEXT cert,
+ BOOL *anyUsageAdded)
+{
+    static char any_app_policy[] = szOID_ANY_APPLICATION_POLICY;
+    WCHAR nl = '\n';
+    CHARFORMATW charFmt;
+    PCERT_EXTENSION policyExt;
+    if (!*anyUsageAdded)
+    {
+        PARAFORMAT2 parFmt;
+
+        parFmt.cbSize = sizeof(parFmt);
+        parFmt.dwMask = PFM_STARTINDENT;
+        parFmt.dxStartIndent = MY_INDENT;
+        add_string_resource_with_paraformat_to_control(text,
+         IDS_CERT_INFO_PURPOSES, &parFmt);
+        add_unformatted_text_to_control(text, &nl, 1);
+        *anyUsageAdded = TRUE;
+    }
+    memset(&charFmt, 0, sizeof(charFmt));
+    charFmt.cbSize = sizeof(charFmt);
+    charFmt.dwMask = CFM_BOLD;
+    charFmt.dwEffects = 0;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    if ((policyExt = CertFindExtension(szOID_APPLICATION_CERT_POLICIES,
+     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
+    {
+        CERT_POLICIES_INFO *policies;
+        DWORD size;
+
+        if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT_POLICIES,
+         policyExt->Value.pbData, policyExt->Value.cbData,
+         CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size))
+        {
+            DWORD i;
+
+            for (i = 0; i < policies->cPolicyInfo; i++)
+            {
+                DWORD j;
+
+                for (j = 0; j < policies->rgPolicyInfo[i].cPolicyQualifier; j++)
+                    add_local_oid_text_to_control(text,
+                     policies->rgPolicyInfo[i].rgPolicyQualifier[j].
+                     pszPolicyQualifierId);
+            }
+            LocalFree(policies);
+        }
+    }
+    else
+        add_oid_text_to_control(text, any_app_policy);
+}
+
+static BOOL display_cert_usages(HWND text, PCCERT_CONTEXT cert,
+ BOOL *anyUsageAdded)
+{
+    WCHAR nl = '\n';
+    DWORD size;
+    BOOL badUsages = FALSE;
+
+    if (CertGetEnhancedKeyUsage(cert, 0, NULL, &size))
+    {
+        CHARFORMATW charFmt;
+        static char any_cert_policy[] = szOID_ANY_CERT_POLICY;
+        PCERT_ENHKEY_USAGE usage = HeapAlloc(GetProcessHeap(), 0, size);
+
+        if (usage)
+        {
+            if (CertGetEnhancedKeyUsage(cert, 0, usage, &size))
+            {
+                DWORD i;
+
+                if (!*anyUsageAdded)
+                {
+                    PARAFORMAT2 parFmt;
+
+                    parFmt.cbSize = sizeof(parFmt);
+                    parFmt.dwMask = PFM_STARTINDENT;
+                    parFmt.dxStartIndent = MY_INDENT;
+                    add_string_resource_with_paraformat_to_control(text,
+                     IDS_CERT_INFO_PURPOSES, &parFmt);
+                    add_unformatted_text_to_control(text, &nl, 1);
+                    *anyUsageAdded = TRUE;
+                }
+                memset(&charFmt, 0, sizeof(charFmt));
+                charFmt.cbSize = sizeof(charFmt);
+                charFmt.dwMask = CFM_BOLD;
+                charFmt.dwEffects = 0;
+                SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION,
+                 (LPARAM)&charFmt);
+                if (!usage->cUsageIdentifier)
+                    add_oid_text_to_control(text, any_cert_policy);
+                else
+                    for (i = 0; i < usage->cUsageIdentifier; i++)
+                        add_local_oid_text_to_control(text,
+                         usage->rgpszUsageIdentifier[i]);
+            }
+            else
+                badUsages = TRUE;
+            HeapFree(GetProcessHeap(), 0, usage);
+        }
+        else
+            badUsages = TRUE;
+    }
+    else
+        badUsages = TRUE;
+    return badUsages;
+}
+
+static void set_policy_text(HWND text,
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
+{
+    BOOL includeCertUsages = FALSE, includeAppUsages = FALSE;
+    BOOL badUsages = FALSE, anyUsageAdded = FALSE;
+
+    if (pCertViewInfo->cPurposes)
+    {
+        DWORD i;
+
+        for (i = 0; i < pCertViewInfo->cPurposes; i++)
+        {
+            if (!strcmp(pCertViewInfo->rgszPurposes[i], szOID_ANY_CERT_POLICY))
+                includeCertUsages = TRUE;
+            else if (!strcmp(pCertViewInfo->rgszPurposes[i],
+             szOID_ANY_APPLICATION_POLICY))
+                includeAppUsages = TRUE;
+            else
+                badUsages = TRUE;
+        }
+    }
+    else
+        includeAppUsages = includeCertUsages = TRUE;
+    if (includeAppUsages)
+        display_app_usages(text, pCertViewInfo->pCertContext, &anyUsageAdded);
+    if (includeCertUsages)
+        badUsages = display_cert_usages(text, pCertViewInfo->pCertContext,
+         &anyUsageAdded);
+    if (badUsages)
+    {
+        PARAFORMAT2 parFmt;
+
+        parFmt.cbSize = sizeof(parFmt);
+        parFmt.dwMask = PFM_STARTINDENT;
+        parFmt.dxStartIndent = MY_INDENT;
+        add_string_resource_with_paraformat_to_control(text,
+         IDS_CERT_INFO_BAD_PURPOSES, &parFmt);
+    }
+}
+
+static CRYPT_OBJID_BLOB *find_policy_qualifier(CERT_POLICIES_INFO *policies,
+ LPCSTR policyOid)
+{
+    CRYPT_OBJID_BLOB *ret = NULL;
+    DWORD i;
+
+    for (i = 0; !ret && i < policies->cPolicyInfo; i++)
+    {
+        DWORD j;
+
+        for (j = 0; !ret && j < policies->rgPolicyInfo[i].cPolicyQualifier; j++)
+            if (!strcmp(policies->rgPolicyInfo[i].rgPolicyQualifier[j].
+             pszPolicyQualifierId, policyOid))
+                ret = &policies->rgPolicyInfo[i].rgPolicyQualifier[j].
+                 Qualifier;
+    }
+    return ret;
+}
+
+static WCHAR *get_cps_str_from_qualifier(CRYPT_OBJID_BLOB *qualifier)
+{
+    LPWSTR qualifierStr = NULL;
+    CERT_NAME_VALUE *qualifierValue;
+    DWORD size;
+
+    if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME_VALUE,
+     qualifier->pbData, qualifier->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
+     &qualifierValue, &size))
+    {
+        size = CertRDNValueToStrW(qualifierValue->dwValueType,
+         &qualifierValue->Value, NULL, 0);
+        qualifierStr = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
+        if (qualifierStr)
+            CertRDNValueToStrW(qualifierValue->dwValueType,
+             &qualifierValue->Value, qualifierStr, size);
+        LocalFree(qualifierValue);
+    }
+    return qualifierStr;
+}
+
+static WCHAR *get_user_notice_from_qualifier(CRYPT_OBJID_BLOB *qualifier)
+{
+    LPWSTR str = NULL;
+    CERT_POLICY_QUALIFIER_USER_NOTICE *qualifierValue;
+    DWORD size;
+
+    if (CryptDecodeObjectEx(X509_ASN_ENCODING,
+     X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
+     qualifier->pbData, qualifier->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
+     &qualifierValue, &size))
+    {
+        str = HeapAlloc(GetProcessHeap(), 0,
+         (strlenW(qualifierValue->pszDisplayText) + 1) * sizeof(WCHAR));
+        if (str)
+            strcpyW(str, qualifierValue->pszDisplayText);
+        LocalFree(qualifierValue);
+    }
+    return str;
+}
+
+struct IssuerStatement
+{
+    LPWSTR cps;
+    LPWSTR userNotice;
+};
+
+static void set_issuer_statement(HWND hwnd,
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
+{
+    PCERT_EXTENSION policyExt;
+
+    if (!(pCertViewInfo->dwFlags & CRYPTUI_DISABLE_ISSUERSTATEMENT) &&
+     (policyExt = CertFindExtension(szOID_CERT_POLICIES,
+     pCertViewInfo->pCertContext->pCertInfo->cExtension,
+     pCertViewInfo->pCertContext->pCertInfo->rgExtension)))
+    {
+        CERT_POLICIES_INFO *policies;
+        DWORD size;
+
+        if (CryptDecodeObjectEx(X509_ASN_ENCODING, policyExt->pszObjId,
+         policyExt->Value.pbData, policyExt->Value.cbData,
+         CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size))
+        {
+            CRYPT_OBJID_BLOB *qualifier;
+            LPWSTR cps = NULL, userNotice = NULL;
+
+            if ((qualifier = find_policy_qualifier(policies,
+             szOID_PKIX_POLICY_QUALIFIER_CPS)))
+                cps = get_cps_str_from_qualifier(qualifier);
+            if ((qualifier = find_policy_qualifier(policies,
+             szOID_PKIX_POLICY_QUALIFIER_USERNOTICE)))
+                userNotice = get_user_notice_from_qualifier(qualifier);
+            if (cps || userNotice)
+            {
+                struct IssuerStatement *issuerStatement =
+                 HeapAlloc(GetProcessHeap(), 0, sizeof(struct IssuerStatement));
+
+                if (issuerStatement)
+                {
+                    issuerStatement->cps = cps;
+                    issuerStatement->userNotice = userNotice;
+                    EnableWindow(GetDlgItem(hwnd, IDC_ISSUERSTATEMENT), TRUE);
+                    SetWindowLongPtrW(hwnd, DWLP_USER,
+                     (ULONG_PTR)issuerStatement);
+                }
+            }
+            LocalFree(policies);
+        }
+    }
+}
+
+static void set_cert_info(HWND hwnd,
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
+{
+    CHARFORMATW charFmt;
+    PARAFORMAT2 parFmt;
+    HWND icon = GetDlgItem(hwnd, IDC_CERTIFICATE_ICON);
+    HWND text = GetDlgItem(hwnd, IDC_CERTIFICATE_INFO);
+    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
+     (CRYPT_PROVIDER_DATA *)pCertViewInfo->u.pCryptProviderData,
+     pCertViewInfo->idxSigner, pCertViewInfo->fCounterSigner,
+     pCertViewInfo->idxCounterSigner);
+    CRYPT_PROVIDER_CERT *root =
+     &provSigner->pasCertChain[provSigner->csCertChain - 1];
+
+    if (!provSigner->pChainContext ||
+     (provSigner->pChainContext->TrustStatus.dwErrorStatus &
+     CERT_TRUST_IS_PARTIAL_CHAIN))
+        add_icon_to_control(icon, IDB_CERT_WARNING);
+    else if (!root->fTrustedRoot)
+        add_icon_to_control(icon, IDB_CERT_ERROR);
+    else
+        add_icon_to_control(icon, IDB_CERT);
+
+    memset(&charFmt, 0, sizeof(charFmt));
+    charFmt.cbSize = sizeof(charFmt);
+    charFmt.dwMask = CFM_BOLD;
+    charFmt.dwEffects = CFE_BOLD;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    /* FIXME: vertically center text */
+    parFmt.cbSize = sizeof(parFmt);
+    parFmt.dwMask = PFM_STARTINDENT;
+    parFmt.dxStartIndent = MY_INDENT;
+    add_string_resource_with_paraformat_to_control(text,
+     IDS_CERTIFICATEINFORMATION, &parFmt);
+
+    text = GetDlgItem(hwnd, IDC_CERTIFICATE_STATUS);
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    if (provSigner->dwError == TRUST_E_CERT_SIGNATURE)
+        add_string_resource_with_paraformat_to_control(text,
+         IDS_CERT_INFO_BAD_SIG, &parFmt);
+    else if (!provSigner->pChainContext ||
+     (provSigner->pChainContext->TrustStatus.dwErrorStatus &
+     CERT_TRUST_IS_PARTIAL_CHAIN))
+        add_string_resource_with_paraformat_to_control(text,
+         IDS_CERT_INFO_PARTIAL_CHAIN, &parFmt);
+    else if (!root->fTrustedRoot)
+    {
+        if (provSigner->csCertChain == 1 && root->fSelfSigned)
+            add_string_resource_with_paraformat_to_control(text,
+             IDS_CERT_INFO_UNTRUSTED_CA, &parFmt);
+        else
+            add_string_resource_with_paraformat_to_control(text,
+             IDS_CERT_INFO_UNTRUSTED_ROOT, &parFmt);
+    }
+    else
+    {
+        set_policy_text(text, pCertViewInfo);
+        set_issuer_statement(hwnd, pCertViewInfo);
+    }
+}
+
+static void set_cert_name_string(HWND hwnd, PCCERT_CONTEXT cert,
+ DWORD nameFlags, int heading)
+{
+    WCHAR nl = '\n';
+    HWND text = GetDlgItem(hwnd, IDC_CERTIFICATE_NAMES);
+    CHARFORMATW charFmt;
+    PARAFORMAT2 parFmt;
+
+    memset(&charFmt, 0, sizeof(charFmt));
+    charFmt.cbSize = sizeof(charFmt);
+    charFmt.dwMask = CFM_BOLD;
+    charFmt.dwEffects = CFE_BOLD;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    parFmt.cbSize = sizeof(parFmt);
+    parFmt.dwMask = PFM_STARTINDENT;
+    parFmt.dxStartIndent = MY_INDENT * 3;
+    add_string_resource_with_paraformat_to_control(text, heading, &parFmt);
+    charFmt.dwEffects = 0;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    add_cert_string_to_control(text, cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+     nameFlags);
+    add_unformatted_text_to_control(text, &nl, 1);
+    add_unformatted_text_to_control(text, &nl, 1);
+    add_unformatted_text_to_control(text, &nl, 1);
+
+}
+
+static void add_date_string_to_control(HWND hwnd, const FILETIME *fileTime)
+{
+    WCHAR dateFmt[80]; /* sufficient for all versions of LOCALE_SSHORTDATE */
+    WCHAR date[80];
+    SYSTEMTIME sysTime;
+
+    GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt,
+     sizeof(dateFmt) / sizeof(dateFmt[0]));
+    FileTimeToSystemTime(fileTime, &sysTime);
+    GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date,
+     sizeof(date) / sizeof(date[0]));
+    add_unformatted_text_to_control(hwnd, date, lstrlenW(date));
+}
+
+static void set_cert_validity_period(HWND hwnd, PCCERT_CONTEXT cert)
+{
+    WCHAR nl = '\n';
+    HWND text = GetDlgItem(hwnd, IDC_CERTIFICATE_NAMES);
+    CHARFORMATW charFmt;
+    PARAFORMAT2 parFmt;
+
+    memset(&charFmt, 0, sizeof(charFmt));
+    charFmt.cbSize = sizeof(charFmt);
+    charFmt.dwMask = CFM_BOLD;
+    charFmt.dwEffects = CFE_BOLD;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    parFmt.cbSize = sizeof(parFmt);
+    parFmt.dwMask = PFM_STARTINDENT;
+    parFmt.dxStartIndent = MY_INDENT * 3;
+    add_string_resource_with_paraformat_to_control(text, IDS_VALID_FROM,
+     &parFmt);
+    charFmt.dwEffects = 0;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    add_date_string_to_control(text, &cert->pCertInfo->NotBefore);
+    charFmt.dwEffects = CFE_BOLD;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    add_string_resource_to_control(text, IDS_VALID_TO);
+    charFmt.dwEffects = 0;
+    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
+    add_date_string_to_control(text, &cert->pCertInfo->NotAfter);
+    add_unformatted_text_to_control(text, &nl, 1);
+}
+
+static void set_general_info(HWND hwnd,
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
+{
+    set_cert_info(hwnd, pCertViewInfo);
+    set_cert_name_string(hwnd, pCertViewInfo->pCertContext, 0,
+     IDS_SUBJECT_HEADING);
+    set_cert_name_string(hwnd, pCertViewInfo->pCertContext,
+     CERT_NAME_ISSUER_FLAG, IDS_ISSUER_HEADING);
+    set_cert_validity_period(hwnd, pCertViewInfo->pCertContext);
+}
+
+static LRESULT CALLBACK user_notice_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
+ LPARAM lp)
+{
+    LRESULT ret = 0;
+    HWND text;
+    struct IssuerStatement *issuerStatement;
+
+    switch (msg)
+    {
+    case WM_INITDIALOG:
+        text = GetDlgItem(hwnd, IDC_USERNOTICE);
+        issuerStatement = (struct IssuerStatement *)lp;
+        add_unformatted_text_to_control(text, issuerStatement->userNotice,
+         strlenW(issuerStatement->userNotice));
+        if (issuerStatement->cps)
+            SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)issuerStatement->cps);
+        else
+            EnableWindow(GetDlgItem(hwnd, IDC_CPS), FALSE);
+        break;
+    case WM_COMMAND:
+        switch (wp)
+        {
+        case IDOK:
+            EndDialog(hwnd, IDOK);
+            ret = TRUE;
+            break;
+        case IDC_CPS:
+        {
+            IBindCtx *bctx = NULL;
+            LPWSTR cps;
+
+            CreateBindCtx(0, &bctx);
+            cps = (LPWSTR)GetWindowLongPtrW(hwnd, DWLP_USER);
+            HlinkSimpleNavigateToString(cps, NULL, NULL, NULL, bctx, NULL,
+             HLNF_OPENINNEWWINDOW, 0);
+            IBindCtx_Release(bctx);
+            break;
+        }
+        }
+    }
+    return ret;
+}
+
+static void show_user_notice(HWND hwnd, struct IssuerStatement *issuerStatement)
+{
+    DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDD_USERNOTICE), hwnd,
+     user_notice_dlg_proc, (LPARAM)issuerStatement);
+}
+
+static LRESULT CALLBACK general_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
+ LPARAM lp)
+{
+    PROPSHEETPAGEW *page;
+    PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo;
+
+    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);
+
+    switch (msg)
+    {
+    case WM_INITDIALOG:
+        page = (PROPSHEETPAGEW *)lp;
+        pCertViewInfo = (PCCRYPTUI_VIEWCERTIFICATE_STRUCTW)page->lParam;
+        if (pCertViewInfo->dwFlags & CRYPTUI_DISABLE_ADDTOSTORE)
+            ShowWindow(GetDlgItem(hwnd, IDC_ADDTOSTORE), FALSE);
+        EnableWindow(GetDlgItem(hwnd, IDC_ISSUERSTATEMENT), FALSE);
+        set_general_info(hwnd, pCertViewInfo);
+        break;
+    case WM_COMMAND:
+        switch (wp)
+        {
+        case IDC_ADDTOSTORE:
+            FIXME("call CryptUIWizImport\n");
+            break;
+        case IDC_ISSUERSTATEMENT:
+        {
+            struct IssuerStatement *issuerStatement =
+             (struct IssuerStatement *)GetWindowLongPtrW(hwnd, DWLP_USER);
+
+            if (issuerStatement)
+            {
+                if (issuerStatement->userNotice)
+                    show_user_notice(hwnd, issuerStatement);
+                else if (issuerStatement->cps)
+                {
+                    IBindCtx *bctx = NULL;
+
+                    CreateBindCtx(0, &bctx);
+                    HlinkSimpleNavigateToString(issuerStatement->cps, NULL,
+                     NULL, NULL, bctx, NULL, HLNF_OPENINNEWWINDOW, 0);
+                    IBindCtx_Release(bctx);
+                }
+            }
+            break;
+        }
+        }
+        break;
+    }
+    return 0;
+}
+
+static UINT CALLBACK general_callback_proc(HWND hwnd, UINT msg,
+ PROPSHEETPAGEW *page)
+{
+    struct IssuerStatement *issuerStatement;
+
+    switch (msg)
+    {
+    case PSPCB_RELEASE:
+        issuerStatement =
+         (struct IssuerStatement *)GetWindowLongPtrW(hwnd, DWLP_USER);
+        if (issuerStatement)
+        {
+            HeapFree(GetProcessHeap(), 0, issuerStatement->cps);
+            HeapFree(GetProcessHeap(), 0, issuerStatement->userNotice);
+            HeapFree(GetProcessHeap(), 0, issuerStatement);
+        }
+        break;
+    }
+    return 1;
+}
+
+static void init_general_page(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
+ PROPSHEETPAGEW *page)
+{
+    memset(page, 0, sizeof(PROPSHEETPAGEW));
+    page->dwSize = sizeof(PROPSHEETPAGEW);
+    page->dwFlags = PSP_USECALLBACK;
+    page->pfnCallback = general_callback_proc;
+    page->hInstance = hInstance;
+    page->u.pszTemplate = MAKEINTRESOURCEW(IDD_GENERAL);
+    page->pfnDlgProc = general_dlg_proc;
+    page->lParam = (LPARAM)pCertViewInfo;
+}
+
+typedef WCHAR * (*field_format_func)(PCCERT_CONTEXT cert);
+
+static WCHAR *field_format_version(PCCERT_CONTEXT cert)
+{
+    static const WCHAR fmt[] = { 'V','%','d',0 };
+    WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, 12 * sizeof(WCHAR));
+
+    if (buf)
+        sprintfW(buf, fmt, cert->pCertInfo->dwVersion);
+    return buf;
+}
+
+static WCHAR *format_hex_string(void *pb, DWORD cb)
+{
+    WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, (cb * 3 + 1) * sizeof(WCHAR));
+
+    if (buf)
+    {
+        static const WCHAR fmt[] = { '%','0','2','x',' ',0 };
+        DWORD i;
+        WCHAR *ptr;
+
+        for (i = 0, ptr = buf; i < cb; i++, ptr += 3)
+            sprintfW(ptr, fmt, ((BYTE *)pb)[i]);
+    }
+    return buf;
+}
+
+static WCHAR *field_format_serial_number(PCCERT_CONTEXT cert)
+{
+    return format_hex_string(cert->pCertInfo->SerialNumber.pbData,
+     cert->pCertInfo->SerialNumber.cbData);
+}
+
+static WCHAR *field_format_issuer(PCCERT_CONTEXT cert)
+{
+    return get_cert_name_string(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+     CERT_NAME_ISSUER_FLAG);
+}
+
+static WCHAR *field_format_detailed_cert_name(PCERT_NAME_BLOB name)
+{
+    WCHAR *str = NULL;
+    DWORD len = CertNameToStrW(X509_ASN_ENCODING, name,
+     CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, NULL, 0);
+
+    if (len)
+    {
+        str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        if (str)
+            CertNameToStrW(X509_ASN_ENCODING, name,
+             CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, str, len);
+    }
+    return str;
+}
+
+static WCHAR *field_format_detailed_issuer(PCCERT_CONTEXT cert, void *param)
+{
+    return field_format_detailed_cert_name(&cert->pCertInfo->Issuer);
+}
+
+static WCHAR *field_format_subject(PCCERT_CONTEXT cert)
+{
+    return get_cert_name_string(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0);
+}
+
+static WCHAR *field_format_detailed_subject(PCCERT_CONTEXT cert, void *param)
+{
+    return field_format_detailed_cert_name(&cert->pCertInfo->Subject);
+}
+
+static WCHAR *format_long_date(const FILETIME *fileTime)
+{
+    WCHAR dateFmt[80]; /* long enough for LOCALE_SLONGDATE */
+    DWORD len;
+    WCHAR *buf = NULL;
+    SYSTEMTIME sysTime;
+
+    /* FIXME: format isn't quite right, want time too */
+    GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SLONGDATE, dateFmt,
+     sizeof(dateFmt) / sizeof(dateFmt[0]));
+    FileTimeToSystemTime(fileTime, &sysTime);
+    len = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, NULL, 0);
+    if (len)
+    {
+        buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        if (buf)
+            GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, buf,
+             len);
+    }
+    return buf;
+}
+
+static WCHAR *field_format_from_date(PCCERT_CONTEXT cert)
+{
+    return format_long_date(&cert->pCertInfo->NotBefore);
+}
+
+static WCHAR *field_format_to_date(PCCERT_CONTEXT cert)
+{
+    return format_long_date(&cert->pCertInfo->NotAfter);
+}
+
+static WCHAR *field_format_public_key(PCCERT_CONTEXT cert)
+{
+    PCCRYPT_OID_INFO oidInfo;
+    WCHAR *buf = NULL;
+
+    oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+     cert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId, 0);
+    if (oidInfo)
+    {
+        WCHAR fmt[MAX_STRING_LEN];
+
+        if (LoadStringW(hInstance, IDS_FIELD_PUBLIC_KEY_FORMAT, fmt,
+         sizeof(fmt) / sizeof(fmt[0])))
+        {
+            /* Allocate the output buffer.  Use the number of bytes in the
+             * public key as a conservative (high) estimate for the number of
+             * digits in its output.
+             * The output is of the form (in English)
+             * "<public key algorithm> (<public key bit length> bits)".
+             * Ordinarily having two positional parameters in a string is not a
+             * good idea, but as this isn't a sentence fragment, it shouldn't
+             * be word-order dependent.
+             */
+            buf = HeapAlloc(GetProcessHeap(), 0,
+             (strlenW(fmt) + strlenW(oidInfo->pwszName) +
+             cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData * 8)
+             * sizeof(WCHAR));
+            if (buf)
+                sprintfW(buf, fmt, oidInfo->pwszName,
+                 CertGetPublicKeyLength(X509_ASN_ENCODING,
+                  &cert->pCertInfo->SubjectPublicKeyInfo));
+        }
+    }
+    return buf;
+}
+
+static WCHAR *field_format_detailed_public_key(PCCERT_CONTEXT cert, void *param)
+{
+    return format_hex_string(
+     cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
+     cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData);
+}
+
+struct field_value_data;
+struct detail_data
+{
+    PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo;
+    BOOL *pfPropertiesChanged;
+    int cFields;
+    struct field_value_data *fields;
+};
+
+typedef void (*add_fields_func)(HWND hwnd, struct detail_data *data);
+
+typedef WCHAR *(*create_detailed_value_func)(PCCERT_CONTEXT cert, void *param);
+
+struct field_value_data
+{
+    create_detailed_value_func create;
+    LPWSTR detailed_value;
+    void *param;
+};
+
+static void add_field_value_data(struct detail_data *data,
+ create_detailed_value_func create, void *param)
+{
+    if (data->cFields)
+        data->fields = HeapReAlloc(GetProcessHeap(), 0, data->fields,
+         (data->cFields + 1) * sizeof(struct field_value_data));
+    else
+        data->fields = HeapAlloc(GetProcessHeap(), 0,
+         sizeof(struct field_value_data));
+    if (data->fields)
+    {
+        data->fields[data->cFields].create = create;
+        data->fields[data->cFields].detailed_value = NULL;
+        data->fields[data->cFields].param = param;
+        data->cFields++;
+    }
+}
+
+static void add_field_and_value_to_list(HWND hwnd, struct detail_data *data,
+ LPWSTR field, LPWSTR value, create_detailed_value_func create, void *param)
+{
+    LVITEMW item;
+    int iItem = SendMessageW(hwnd, LVM_GETITEMCOUNT, 0, 0);
+
+    item.mask = LVIF_TEXT | LVIF_PARAM;
+    item.iItem = iItem;
+    item.iSubItem = 0;
+    item.pszText = field;
+    item.lParam = (LPARAM)data;
+    SendMessageW(hwnd, LVM_INSERTITEMW, 0, (LPARAM)&item);
+    if (value)
+    {
+        item.pszText = value;
+        item.iSubItem = 1;
+        SendMessageW(hwnd, LVM_SETITEMTEXTW, iItem, (LPARAM)&item);
+    }
+    add_field_value_data(data, create, param);
+}
+
+static void add_string_id_and_value_to_list(HWND hwnd, struct detail_data *data,
+ int id, LPWSTR value, create_detailed_value_func create, void *param)
+{
+    WCHAR buf[MAX_STRING_LEN];
+
+    LoadStringW(hInstance, id, buf, sizeof(buf) / sizeof(buf[0]));
+    add_field_and_value_to_list(hwnd, data, buf, value, create, param);
+}
+
+struct v1_field
+{
+    int id;
+    field_format_func format;
+    create_detailed_value_func create_detailed_value;
+};
+
+static void add_v1_field(HWND hwnd, struct detail_data *data,
+ const struct v1_field *field)
+{
+    WCHAR *val = field->format(data->pCertViewInfo->pCertContext);
+
+    if (val)
+    {
+        add_string_id_and_value_to_list(hwnd, data, field->id, val,
+         field->create_detailed_value, NULL);
+        HeapFree(GetProcessHeap(), 0, val);
+    }
+}
+
+static const struct v1_field v1_fields[] = {
+ { IDS_FIELD_VERSION, field_format_version, NULL },
+ { IDS_FIELD_SERIAL_NUMBER, field_format_serial_number, NULL },
+ { IDS_FIELD_ISSUER, field_format_issuer, field_format_detailed_issuer },
+ { IDS_FIELD_VALID_FROM, field_format_from_date, NULL },
+ { IDS_FIELD_VALID_TO, field_format_to_date, NULL },
+ { IDS_FIELD_SUBJECT, field_format_subject, field_format_detailed_subject },
+ { IDS_FIELD_PUBLIC_KEY, field_format_public_key,
+   field_format_detailed_public_key }
+};
+
+static void add_v1_fields(HWND hwnd, struct detail_data *data)
+{
+    int i;
+    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;
+
+    /* The last item in v1_fields is the public key, which is not in the loop
+     * because it's a special case.
+     */
+    for (i = 0; i < sizeof(v1_fields) / sizeof(v1_fields[0]) - 1; i++)
+        add_v1_field(hwnd, data, &v1_fields[i]);
+    if (cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData)
+        add_v1_field(hwnd, data, &v1_fields[i]);
+}
+
+static WCHAR *crypt_format_extension(PCERT_EXTENSION ext, DWORD formatStrType)
+{
+    WCHAR *str = NULL;
+    DWORD size;
+
+    if (CryptFormatObject(X509_ASN_ENCODING, 0, formatStrType, NULL,
+     ext->pszObjId, ext->Value.pbData, ext->Value.cbData, NULL, &size))
+    {
+        str = HeapAlloc(GetProcessHeap(), 0, size);
+        CryptFormatObject(X509_ASN_ENCODING, 0, formatStrType, NULL,
+         ext->pszObjId, ext->Value.pbData, ext->Value.cbData, str, &size);
+    }
+    return str;
+}
+
+static WCHAR *field_format_extension_hex_with_ascii(PCERT_EXTENSION ext)
+{
+    WCHAR *str = NULL;
+
+    if (ext->Value.cbData)
+    {
+        /* The output is formatted as:
+         * <hex bytes>  <ascii bytes>\n
+         * where <hex bytes> is a string of up to 8 bytes, output as %02x,
+         * and <ascii bytes> is the ASCII equivalent of each byte, or '.' if
+         * the byte is not printable.
+         * So, for example, the extension value consisting of the following
+         * bytes:
+         *   0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,
+         *   0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67
+         * is output as:
+         *   30 14 31 12 30 10 06 03  0.1.0...
+         *   55 04 03 13 09 4a 75 61  U....Jua
+         *   6e 20 4c 61 6e 67        n Lang
+         * The allocation size therefore requires:
+         * - 4 characters per character in an 8-byte line
+         *   (2 for the hex format, one for the space, one for the ASCII value)
+         * - 3 more characters per 8-byte line (two spaces and a newline)
+         * - 1 character for the terminating nul
+         * FIXME: should use a fixed-width font for this
+         */
+        DWORD lines = (ext->Value.cbData + 7) / 8;
+
+        str = HeapAlloc(GetProcessHeap(), 0,
+         (lines * 8 * 4 + lines * 3 + 1) * sizeof(WCHAR));
+        if (str)
+        {
+            static const WCHAR fmt[] = { '%','0','2','x',' ',0 };
+            DWORD i, j;
+            WCHAR *ptr;
+
+            for (i = 0, ptr = str; i < ext->Value.cbData; i += 8)
+            {
+                /* Output as hex bytes first */
+                for (j = i; j < min(i + 8, ext->Value.cbData); j++, ptr += 3)
+                    sprintfW(ptr, fmt, ext->Value.pbData[j]);
+                /* Pad the hex output with spaces for alignment */
+                if (j == ext->Value.cbData && j % 8)
+                {
+                    static const WCHAR pad[] = { ' ',' ',' ' };
+
+                    for (; j % 8; j++, ptr += sizeof(pad) / sizeof(pad[0]))
+                        memcpy(ptr, pad, sizeof(pad));
+                }
+                /* The last sprintfW included a space, so just insert one
+                 * more space between the hex bytes and the ASCII output
+                 */
+                *ptr++ = ' ';
+                /* Output as ASCII bytes */
+                for (j = i; j < min(i + 8, ext->Value.cbData); j++, ptr++)
+                {
+                    if (isprintW(ext->Value.pbData[j]) &&
+                     !isspaceW(ext->Value.pbData[j]))
+                        *ptr = ext->Value.pbData[j];
+                    else
+                        *ptr = '.';
+                }
+                *ptr++ = '\n';
+            }
+            *ptr++ = '\0';
+        }
+    }
+    return str;
+}
+
+static WCHAR *field_format_detailed_extension(PCCERT_CONTEXT cert, void *param)
+{
+    PCERT_EXTENSION ext = param;
+    LPWSTR str = crypt_format_extension(ext,
+     CRYPT_FORMAT_STR_MULTI_LINE | CRYPT_FORMAT_STR_NO_HEX);
+
+    if (!str)
+        str = field_format_extension_hex_with_ascii(ext);
+    return str;
+}
+
+static void add_cert_extension_detail(HWND hwnd, struct detail_data *data,
+ PCERT_EXTENSION ext)
+{
+    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+     ext->pszObjId, 0);
+    LPWSTR val = crypt_format_extension(ext, 0);
+
+    if (oidInfo)
+        add_field_and_value_to_list(hwnd, data, (LPWSTR)oidInfo->pwszName,
+         val, field_format_detailed_extension, ext);
+    else
+    {
+        DWORD len = strlen(ext->pszObjId);
+        LPWSTR oidW = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+
+        if (oidW)
+        {
+            DWORD i;
+
+            for (i = 0; i <= len; i++)
+                oidW[i] = ext->pszObjId[i];
+            add_field_and_value_to_list(hwnd, data, oidW, val,
+             field_format_detailed_extension, ext);
+            HeapFree(GetProcessHeap(), 0, oidW);
+        }
+    }
+    HeapFree(GetProcessHeap(), 0, val);
+}
+
+static void add_all_extensions(HWND hwnd, struct detail_data *data)
+{
+    DWORD i;
+    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;
+
+    for (i = 0; i < cert->pCertInfo->cExtension; i++)
+        add_cert_extension_detail(hwnd, data, &cert->pCertInfo->rgExtension[i]);
+}
+
+static void add_critical_extensions(HWND hwnd, struct detail_data *data)
+{
+    DWORD i;
+    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;
+
+    for (i = 0; i < cert->pCertInfo->cExtension; i++)
+        if (cert->pCertInfo->rgExtension[i].fCritical)
+            add_cert_extension_detail(hwnd, data,
+             &cert->pCertInfo->rgExtension[i]);
+}
+
+typedef WCHAR * (*prop_to_value_func)(void *pb, DWORD cb);
+
+struct prop_id_to_string_id
+{
+    DWORD prop;
+    int id;
+    BOOL prop_is_string;
+    prop_to_value_func prop_to_value;
+};
+
+static WCHAR *format_enhanced_key_usage_value(void *pb, DWORD cb)
+{
+    CERT_EXTENSION ext;
+
+    ext.pszObjId = (LPSTR)X509_ENHANCED_KEY_USAGE;
+    ext.fCritical = FALSE;
+    ext.Value.pbData = pb;
+    ext.Value.cbData = cb;
+    return crypt_format_extension(&ext, 0);
+}
+
+/* Logically the access state should also be checked, and IDC_EDITPROPERTIES
+ * disabled for read-only certificates, but native doesn't appear to do that.
+ */
+static const struct prop_id_to_string_id prop_id_map[] = {
+ { CERT_HASH_PROP_ID, IDS_PROP_HASH, FALSE, format_hex_string },
+ { CERT_FRIENDLY_NAME_PROP_ID, IDS_PROP_FRIENDLY_NAME, TRUE, NULL },
+ { CERT_DESCRIPTION_PROP_ID, IDS_PROP_DESCRIPTION, TRUE, NULL },
+ { CERT_ENHKEY_USAGE_PROP_ID, IDS_PROP_ENHKEY_USAGE, FALSE,
+   format_enhanced_key_usage_value },
+};
+
+static void add_properties(HWND hwnd, struct detail_data *data)
+{
+    DWORD i;
+    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;
+
+    for (i = 0; i < sizeof(prop_id_map) / sizeof(prop_id_map[0]); i++)
+    {
+        DWORD cb;
+
+        if (CertGetCertificateContextProperty(cert, prop_id_map[i].prop, NULL,
+         &cb))
+        {
+            BYTE *pb;
+            WCHAR *val = NULL;
+
+            /* FIXME: MS adds a separate value for the signature hash
+             * algorithm.
+             */
+            pb = HeapAlloc(GetProcessHeap(), 0, cb);
+            if (pb)
+            {
+                if (CertGetCertificateContextProperty(cert,
+                 prop_id_map[i].prop, pb, &cb))
+                {
+                    if (prop_id_map[i].prop_is_string)
+                    {
+                        val = (LPWSTR)pb;
+                        /* Don't double-free pb */
+                        pb = NULL;
+                    }
+                    else
+                        val = prop_id_map[i].prop_to_value(pb, cb);
+                }
+                HeapFree(GetProcessHeap(), 0, pb);
+            }
+            add_string_id_and_value_to_list(hwnd, data, prop_id_map[i].id, val,
+             NULL, NULL);
+        }
+    }
+}
+
+static void add_all_fields(HWND hwnd, struct detail_data *data)
+{
+    add_v1_fields(hwnd, data);
+    add_all_extensions(hwnd, data);
+    add_properties(hwnd, data);
+}
+
+struct selection_list_item
+{
+    int id;
+    add_fields_func add;
+};
+
+const struct selection_list_item listItems[] = {
+ { IDS_FIELDS_ALL, add_all_fields },
+ { IDS_FIELDS_V1, add_v1_fields },
+ { IDS_FIELDS_EXTENSIONS, add_all_extensions },
+ { IDS_FIELDS_CRITICAL_EXTENSIONS, add_critical_extensions },
+ { IDS_FIELDS_PROPERTIES, add_properties },
+};
+
+static void create_show_list(HWND hwnd, struct detail_data *data)
+{
+    HWND cb = GetDlgItem(hwnd, IDC_DETAIL_SELECT);
+    WCHAR buf[MAX_STRING_LEN];
+    int i;
+
+    for (i = 0; i < sizeof(listItems) / sizeof(listItems[0]); i++)
+    {
+        int index;
+
+        LoadStringW(hInstance, listItems[i].id, buf,
+         sizeof(buf) / sizeof(buf[0]));
+        index = SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
+        SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)data);
+    }
+    SendMessageW(cb, CB_SETCURSEL, 0, 0);
+}
+
+static void create_listview_columns(HWND hwnd)
+{
+    HWND lv = GetDlgItem(hwnd, IDC_DETAIL_LIST);
+    RECT rc;
+    WCHAR buf[MAX_STRING_LEN];
+    LVCOLUMNW column;
+
+    SendMessageW(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
+    GetWindowRect(lv, &rc);
+    LoadStringW(hInstance, IDS_FIELD, buf, sizeof(buf) / sizeof(buf[0]));
+    column.mask = LVCF_WIDTH | LVCF_TEXT;
+    column.cx = (rc.right - rc.left) / 2 - 2;
+    column.pszText = buf;
+    SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
+    LoadStringW(hInstance, IDS_VALUE, buf, sizeof(buf) / sizeof(buf[0]));
+    SendMessageW(lv, LVM_INSERTCOLUMNW, 1, (LPARAM)&column);
+}
+
+static void set_fields_selection(HWND hwnd, struct detail_data *data, int sel)
+{
+    HWND list = GetDlgItem(hwnd, IDC_DETAIL_LIST);
+
+    if (sel >= 0 && sel < sizeof(listItems) / sizeof(listItems[0]))
+    {
+        SendMessageW(list, LVM_DELETEALLITEMS, 0, 0);
+        listItems[sel].add(list, data);
+    }
+}
+
+static void create_cert_details_list(HWND hwnd, struct detail_data *data)
+{
+    create_show_list(hwnd, data);
+    create_listview_columns(hwnd);
+    set_fields_selection(hwnd, data, 0);
+}
+
+typedef enum {
+    CheckBitmapIndexUnchecked = 1,
+    CheckBitmapIndexChecked = 2,
+    CheckBitmapIndexDisabledUnchecked = 3,
+    CheckBitmapIndexDisabledChecked = 4
+} CheckBitmapIndex;
+
+static void add_purpose(HWND hwnd, LPCSTR oid)
+{
+    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
+    PCRYPT_OID_INFO info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+     sizeof(CRYPT_OID_INFO));
+
+    if (info)
+    {
+        char *oidCopy = HeapAlloc(GetProcessHeap(), 0, strlen(oid) + 1);
+
+        if (oidCopy)
+        {
+            LVITEMA item;
+
+            strcpy(oidCopy, oid);
+            info->cbSize = sizeof(CRYPT_OID_INFO);
+            info->pszOID = oidCopy;
+            item.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
+            item.state = INDEXTOSTATEIMAGEMASK(CheckBitmapIndexChecked);
+            item.stateMask = LVIS_STATEIMAGEMASK;
+            item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
+            item.iSubItem = 0;
+            item.lParam = (LPARAM)info;
+            item.pszText = oidCopy;
+            SendMessageA(lv, LVM_INSERTITEMA, 0, (LPARAM)&item);
+        }
+        else
+            HeapFree(GetProcessHeap(), 0, info);
+    }
+}
+
+static BOOL is_valid_oid(LPCSTR oid)
+{
+    BOOL ret;
+
+    if (oid[0] != '0' && oid[0] != '1' && oid[0] != '2')
+        ret = FALSE;
+    else if (oid[1] != '.')
+        ret = FALSE;
+    else if (!oid[2])
+        ret = FALSE;
+    else
+    {
+        const char *ptr;
+        BOOL expectNum = TRUE;
+
+        for (ptr = oid + 2, ret = TRUE; ret && *ptr; ptr++)
+        {
+            if (expectNum)
+            {
+                if (!isdigit(*ptr))
+                    ret = FALSE;
+                else if (*(ptr + 1) == '.')
+                    expectNum = FALSE;
+            }
+            else
+            {
+                if (*ptr != '.')
+                    ret = FALSE;
+                else if (!(*(ptr + 1)))
+                    ret = FALSE;
+                else
+                    expectNum = TRUE;
+            }
+        }
+    }
+    return ret;
+}
+
+static BOOL is_oid_in_list(HWND hwnd, LPCSTR oid)
+{
+    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
+    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+     (void *)oid, CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
+    BOOL ret = FALSE;
+
+    if (oidInfo)
+    {
+        LVFINDINFOW findInfo;
+
+        findInfo.flags = LVFI_PARAM;
+        findInfo.lParam = (LPARAM)oidInfo;
+        if (SendMessageW(lv, LVM_FINDITEMW, -1, (LPARAM)&findInfo) != -1)
+            ret = TRUE;
+    }
+    else
+    {
+        LVFINDINFOA findInfo;
+
+        findInfo.flags = LVFI_STRING;
+        findInfo.psz = oid;
+        if (SendMessageW(lv, LVM_FINDITEMA, -1, (LPARAM)&findInfo) != -1)
+            ret = TRUE;
+    }
+    return ret;
+}
+
+#define MAX_PURPOSE 255
+
+static LRESULT CALLBACK add_purpose_dlg_proc(HWND hwnd, UINT msg,
+ WPARAM wp, LPARAM lp)
+{
+    LRESULT ret = 0;
+    char buf[MAX_PURPOSE + 1];
+
+    switch (msg)
+    {
+    case WM_INITDIALOG:
+        SendMessageW(GetDlgItem(hwnd, IDC_NEW_PURPOSE), EM_SETLIMITTEXT,
+         MAX_PURPOSE, 0);
+        ShowScrollBar(GetDlgItem(hwnd, IDC_NEW_PURPOSE), SB_VERT, FALSE);
+        SetWindowLongPtrW(hwnd, DWLP_USER, lp);
+        break;
+    case WM_COMMAND:
+        switch (HIWORD(wp))
+        {
+        case EN_CHANGE:
+            if (LOWORD(wp) == IDC_NEW_PURPOSE)
+            {
+                /* Show/hide scroll bar on description depending on how much
+                 * text it has.
+                 */
+                HWND description = GetDlgItem(hwnd, IDC_NEW_PURPOSE);
+                int lines = SendMessageW(description, EM_GETLINECOUNT, 0, 0);
+
+                ShowScrollBar(description, SB_VERT, lines > 1);
+            }
+            break;
+        case BN_CLICKED:
+            switch (LOWORD(wp))
+            {
+            case IDOK:
+                SendMessageA(GetDlgItem(hwnd, IDC_NEW_PURPOSE), WM_GETTEXT,
+                 sizeof(buf) / sizeof(buf[0]), (LPARAM)buf);
+                if (!buf[0])
+                {
+                    /* An empty purpose is the same as cancelling */
+                    EndDialog(hwnd, IDCANCEL);
+                    ret = TRUE;
+                }
+                else if (!is_valid_oid(buf))
+                {
+                    WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];
+
+                    LoadStringW(hInstance, IDS_CERTIFICATE_PURPOSE_ERROR, error,
+                     sizeof(error) / sizeof(error[0]));
+                    LoadStringW(hInstance, IDS_CERTIFICATE_PROPERTIES, title,
+                     sizeof(title) / sizeof(title[0]));
+                    MessageBoxW(hwnd, error, title, MB_ICONERROR | MB_OK);
+                }
+                else if (is_oid_in_list(
+                 (HWND)GetWindowLongPtrW(hwnd, DWLP_USER), buf))
+                {
+                    WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];
+
+                    LoadStringW(hInstance, IDS_CERTIFICATE_PURPOSE_EXISTS,
+                     error, sizeof(error) / sizeof(error[0]));
+                    LoadStringW(hInstance, IDS_CERTIFICATE_PROPERTIES, title,
+                     sizeof(title) / sizeof(title[0]));
+                    MessageBoxW(hwnd, error, title, MB_ICONEXCLAMATION | MB_OK);
+                }
+                else
+                {
+                    HWND parent = (HWND)GetWindowLongPtrW(hwnd, DWLP_USER);
+
+                    add_purpose(parent, buf);
+                    EndDialog(hwnd, wp);
+                    ret = TRUE;
+                }
+                break;
+            case IDCANCEL:
+                EndDialog(hwnd, wp);
+                ret = TRUE;
+                break;
+            }
+            break;
+        }
+        break;
+    }
+    return ret;
+}
+
+static WCHAR *get_cert_property_as_string(PCCERT_CONTEXT cert, DWORD prop)
+{
+    WCHAR *name = NULL;
+    DWORD cb;
+
+    if (CertGetCertificateContextProperty(cert, prop, NULL, &cb))
+    {
+        name = HeapAlloc(GetProcessHeap(), 0, cb);
+        if (name)
+        {
+            if (!CertGetCertificateContextProperty(cert, prop, (LPBYTE)name,
+             &cb))
+            {
+                HeapFree(GetProcessHeap(), 0, name);
+                name = NULL;
+            }
+        }
+    }
+    return name;
+}
+
+static void redraw_states(HWND list, BOOL enabled)
+{
+    int items = SendMessageW(list, LVM_GETITEMCOUNT, 0, 0), i;
+
+    for (i = 0; i < items; i++)
+    {
+        BOOL change = FALSE;
+        int state;
+
+        state = SendMessageW(list, LVM_GETITEMSTATE, i, LVIS_STATEIMAGEMASK);
+        /* This reverses the INDEXTOSTATEIMAGEMASK shift.  There doesn't appear
+         * to be a handy macro for it.
+         */
+        state >>= 12;
+        if (enabled)
+        {
+            if (state == CheckBitmapIndexDisabledChecked)
+            {
+                state = CheckBitmapIndexChecked;
+                change = TRUE;
+            }
+            if (state == CheckBitmapIndexDisabledUnchecked)
+            {
+                state = CheckBitmapIndexUnchecked;
+                change = TRUE;
+            }
+        }
+        else
+        {
+            if (state == CheckBitmapIndexChecked)
+            {
+                state = CheckBitmapIndexDisabledChecked;
+                change = TRUE;
+            }
+            if (state == CheckBitmapIndexUnchecked)
+            {
+                state = CheckBitmapIndexDisabledUnchecked;
+                change = TRUE;
+            }
+        }
+        if (change)
+        {
+            LVITEMW item;
+
+            item.state = INDEXTOSTATEIMAGEMASK(state);
+            item.stateMask = LVIS_STATEIMAGEMASK;
+            SendMessageW(list, LVM_SETITEMSTATE, i, (LPARAM)&item);
+        }
+    }
+}
+
+typedef enum {
+    PurposeEnableAll = 0,
+    PurposeDisableAll,
+    PurposeEnableSelected
+} PurposeSelection;
+
+static void select_purposes(HWND hwnd, PurposeSelection selection)
+{
+    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
+
+    switch (selection)
+    {
+    case PurposeEnableAll:
+    case PurposeDisableAll:
+        EnableWindow(lv, FALSE);
+        redraw_states(lv, FALSE);
+        EnableWindow(GetDlgItem(hwnd, IDC_ADD_PURPOSE), FALSE);
+        break;
+    case PurposeEnableSelected:
+        EnableWindow(lv, TRUE);
+        redraw_states(lv, TRUE);
+        EnableWindow(GetDlgItem(hwnd, IDC_ADD_PURPOSE), TRUE);
+    }
+}
+
+extern BOOL WINAPI WTHelperGetKnownUsages(DWORD action,
+ PCCRYPT_OID_INFO **usages);
+
+static void add_known_usage(HWND lv, PCCRYPT_OID_INFO info)
+{
+    LVITEMW item;
+
+    item.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
+    item.state = INDEXTOSTATEIMAGEMASK(CheckBitmapIndexDisabledChecked);
+    item.stateMask = LVIS_STATEIMAGEMASK;
+    item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
+    item.iSubItem = 0;
+    item.lParam = (LPARAM)info;
+    item.pszText = (LPWSTR)info->pwszName;
+    SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
+}
+
+struct edit_cert_data
+{
+    PCCERT_CONTEXT cert;
+    BOOL *pfPropertiesChanged;
+    HIMAGELIST imageList;
+};
+
+static void show_cert_usages(HWND hwnd, struct edit_cert_data *data)
+{
+    PCCERT_CONTEXT cert = data->cert;
+    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
+    PCERT_ENHKEY_USAGE usage;
+    DWORD size;
+    PCCRYPT_OID_INFO *usages;
+    RECT rc;
+    LVCOLUMNW column;
+    PurposeSelection purposeSelection;
+
+    GetWindowRect(lv, &rc);
+    column.mask = LVCF_WIDTH;
+    column.cx = rc.right - rc.left;
+    SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
+    SendMessageW(lv, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)data->imageList);
+
+    /* Get enhanced key usage.  Have to check for a property and an extension
+     * separately, because CertGetEnhancedKeyUsage will succeed and return an
+     * empty usage if neither is set.  Unfortunately an empty usage implies
+     * no usage is allowed, so we have to distinguish between the two cases.
+     */
+    if (CertGetEnhancedKeyUsage(cert, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
+     NULL, &size))
+    {
+        usage = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!CertGetEnhancedKeyUsage(cert,
+         CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
+        {
+            HeapFree(GetProcessHeap(), 0, usage);
+            usage = NULL;
+        }
+        else if (usage->cUsageIdentifier)
+            purposeSelection = PurposeEnableSelected;
+        else
+            purposeSelection = PurposeDisableAll;
+    }
+    else if (CertGetEnhancedKeyUsage(cert, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
+     NULL, &size))
+    {
+        usage = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!CertGetEnhancedKeyUsage(cert,
+         CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
+        {
+            HeapFree(GetProcessHeap(), 0, usage);
+            usage = NULL;
+        }
+        else if (usage->cUsageIdentifier)
+            purposeSelection = PurposeEnableAll;
+        else
+            purposeSelection = PurposeDisableAll;
+    }
+    else
+    {
+        purposeSelection = PurposeEnableAll;
+        usage = NULL;
+    }
+    if (usage)
+    {
+        DWORD i;
+
+        for (i = 0; i < usage->cUsageIdentifier; i++)
+        {
+            PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+             usage->rgpszUsageIdentifier[i], CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
+
+            if (info)
+                add_known_usage(lv, info);
+            else
+                add_purpose(hwnd, usage->rgpszUsageIdentifier[i]);
+        }
+        HeapFree(GetProcessHeap(), 0, usage);
+    }
+    else
+    {
+        if (WTHelperGetKnownUsages(1, &usages))
+        {
+            PCCRYPT_OID_INFO *ptr;
+
+            for (ptr = usages; *ptr; ptr++)
+                add_known_usage(lv, *ptr);
+            WTHelperGetKnownUsages(2, &usages);
+        }
+    }
+    select_purposes(hwnd, purposeSelection);
+    SendMessageW(GetDlgItem(hwnd, IDC_ENABLE_ALL_PURPOSES + purposeSelection),
+     BM_CLICK, 0, 0);
+}
+
+static void set_general_cert_properties(HWND hwnd, struct edit_cert_data *data)
+{
+    PCCERT_CONTEXT cert = data->cert;
+    WCHAR *str;
+
+    if ((str = get_cert_property_as_string(cert, CERT_FRIENDLY_NAME_PROP_ID)))
+    {
+        SendMessageW(GetDlgItem(hwnd, IDC_FRIENDLY_NAME), WM_SETTEXT, 0,
+         (LPARAM)str);
+        HeapFree(GetProcessHeap(), 0, str);
+    }
+    if ((str = get_cert_property_as_string(cert, CERT_DESCRIPTION_PROP_ID)))
+    {
+        SendMessageW(GetDlgItem(hwnd, IDC_DESCRIPTION), WM_SETTEXT, 0,
+         (LPARAM)str);
+        HeapFree(GetProcessHeap(), 0, str);
+    }
+    show_cert_usages(hwnd, data);
+}
+
+static void toggle_usage(HWND hwnd, int iItem)
+{
+    LVITEMW item;
+    int res;
+    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
+
+    item.mask = LVIF_STATE;
+    item.iItem = iItem;
+    item.iSubItem = 0;
+    item.stateMask = LVIS_STATEIMAGEMASK;
+    res = SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item);
+    if (res)
+    {
+        int state = item.state >> 12;
+
+        item.state = INDEXTOSTATEIMAGEMASK(
+         state == CheckBitmapIndexChecked ? CheckBitmapIndexUnchecked :
+         CheckBitmapIndexChecked);
+        SendMessageW(lv, LVM_SETITEMSTATE, iItem, (LPARAM)&item);
+    }
+}
+
+static void set_cert_string_property(PCCERT_CONTEXT cert, DWORD prop,
+ LPWSTR str)
+{
+    if (str && strlenW(str))
+    {
+        CRYPT_DATA_BLOB blob;
+
+        blob.pbData = (BYTE *)str;
+        blob.cbData = (strlenW(str) + 1) * sizeof(WCHAR);
+        CertSetCertificateContextProperty(cert, prop, 0, &blob);
+    }
+    else
+        CertSetCertificateContextProperty(cert, prop, 0, NULL);
+}
+
+#define WM_REFRESH_VIEW WM_USER + 0
+
+static BOOL CALLBACK refresh_propsheet_pages(HWND hwnd, LPARAM lParam)
+{
+    if ((GetClassLongW(hwnd, GCW_ATOM) == WC_DIALOG))
+        SendMessageW(hwnd, WM_REFRESH_VIEW, 0, 0);
+    return TRUE;
+}
+
+#define MAX_FRIENDLY_NAME 40
+#define MAX_DESCRIPTION 255
+
+static void apply_general_changes(HWND hwnd)
+{
+    WCHAR buf[MAX_DESCRIPTION + 1];
+    struct edit_cert_data *data =
+     (struct edit_cert_data *)GetWindowLongPtrW(hwnd, DWLP_USER);
+
+    SendMessageW(GetDlgItem(hwnd, IDC_FRIENDLY_NAME), WM_GETTEXT,
+     sizeof(buf) / sizeof(buf[0]), (LPARAM)buf);
+    set_cert_string_property(data->cert, CERT_FRIENDLY_NAME_PROP_ID, buf);
+    SendMessageW(GetDlgItem(hwnd, IDC_DESCRIPTION), WM_GETTEXT,
+     sizeof(buf) / sizeof(buf[0]), (LPARAM)buf);
+    set_cert_string_property(data->cert, CERT_DESCRIPTION_PROP_ID, buf);
+    if (IsDlgButtonChecked(hwnd, IDC_ENABLE_ALL_PURPOSES))
+    {
+        /* Setting a NULL usage removes the enhanced key usage property. */
+        CertSetEnhancedKeyUsage(data->cert, NULL);
+    }
+    else if (IsDlgButtonChecked(hwnd, IDC_DISABLE_ALL_PURPOSES))
+    {
+        CERT_ENHKEY_USAGE usage = { 0, NULL };
+
+        CertSetEnhancedKeyUsage(data->cert, &usage);
+    }
+    else if (IsDlgButtonChecked(hwnd, IDC_ENABLE_SELECTED_PURPOSES))
+    {
+        HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
+        CERT_ENHKEY_USAGE usage = { 0, NULL };
+        int purposes = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0), i;
+        LVITEMW item;
+
+        item.mask = LVIF_STATE | LVIF_PARAM;
+        item.iSubItem = 0;
+        item.stateMask = LVIS_STATEIMAGEMASK;
+        for (i = 0; i < purposes; i++)
+        {
+            item.iItem = i;
+            if (SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item))
+            {
+                int state = item.state >> 12;
+
+                if (state == CheckBitmapIndexChecked)
+                {
+                    CRYPT_OID_INFO *info = (CRYPT_OID_INFO *)item.lParam;
+
+                    if (usage.cUsageIdentifier)
+                        usage.rgpszUsageIdentifier =
+                         HeapReAlloc(GetProcessHeap(), 0,
+                         usage.rgpszUsageIdentifier,
+                         (usage.cUsageIdentifier + 1) * sizeof(LPSTR));
+                    else
+                        usage.rgpszUsageIdentifier =
+                         HeapAlloc(GetProcessHeap(), 0, sizeof(LPSTR));
+                    if (usage.rgpszUsageIdentifier)
+                        usage.rgpszUsageIdentifier[usage.cUsageIdentifier++] =
+                         (LPSTR)info->pszOID;
+                }
+            }
+        }
+        CertSetEnhancedKeyUsage(data->cert, &usage);
+        HeapFree(GetProcessHeap(), 0, usage.rgpszUsageIdentifier);
+    }
+    EnumChildWindows(GetParent(GetParent(hwnd)), refresh_propsheet_pages, 0);
+    if (data->pfPropertiesChanged)
+        *data->pfPropertiesChanged = TRUE;
+}
+
+static LRESULT CALLBACK cert_properties_general_dlg_proc(HWND hwnd, UINT msg,
+ WPARAM wp, LPARAM lp)
+{
+    PROPSHEETPAGEW *page;
+
+    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);
+
+    switch (msg)
+    {
+    case WM_INITDIALOG:
+    {
+        HWND description = GetDlgItem(hwnd, IDC_DESCRIPTION);
+        struct detail_data *detailData;
+        struct edit_cert_data *editData;
+
+        page = (PROPSHEETPAGEW *)lp;
+        detailData = (struct detail_data *)page->lParam;
+        SendMessageW(GetDlgItem(hwnd, IDC_FRIENDLY_NAME), EM_SETLIMITTEXT,
+         MAX_FRIENDLY_NAME, 0);
+        SendMessageW(description, EM_SETLIMITTEXT, MAX_DESCRIPTION, 0);
+        ShowScrollBar(description, SB_VERT, FALSE);
+        editData = HeapAlloc(GetProcessHeap(), 0,
+         sizeof(struct edit_cert_data));
+        if (editData)
+        {
+            editData->imageList = ImageList_Create(16, 16,
+             ILC_COLOR4 | ILC_MASK, 4, 0);
+            if (editData->imageList)
+            {
+                HBITMAP bmp;
+                COLORREF backColor = RGB(255, 0, 255);
+
+                bmp = LoadBitmapW(hInstance, MAKEINTRESOURCEW(IDB_CHECKS));
+                ImageList_AddMasked(editData->imageList, bmp, backColor);
+                DeleteObject(bmp);
+                ImageList_SetBkColor(editData->imageList, CLR_NONE);
+            }
+            editData->cert = detailData->pCertViewInfo->pCertContext;
+            editData->pfPropertiesChanged = detailData->pfPropertiesChanged;
+            SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)editData);
+            set_general_cert_properties(hwnd, editData);
+        }
+        break;
+    }
+    case WM_NOTIFY:
+    {
+        NMHDR *hdr = (NMHDR *)lp;
+        NMITEMACTIVATE *nm;
+
+        switch (hdr->code)
+        {
+        case NM_CLICK:
+            nm = (NMITEMACTIVATE *)lp;
+            toggle_usage(hwnd, nm->iItem);
+            SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
+            break;
+        case PSN_APPLY:
+            apply_general_changes(hwnd);
+            break;
+        }
+        break;
+    }
+    case WM_COMMAND:
+        switch (HIWORD(wp))
+        {
+        case EN_CHANGE:
+            SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
+            if (LOWORD(wp) == IDC_DESCRIPTION)
+            {
+                /* Show/hide scroll bar on description depending on how much
+                 * text it has.
+                 */
+                HWND description = GetDlgItem(hwnd, IDC_DESCRIPTION);
+                int lines = SendMessageW(description, EM_GETLINECOUNT, 0, 0);
+
+                ShowScrollBar(description, SB_VERT, lines > 1);
+            }
+            break;
+        case BN_CLICKED:
+            switch (LOWORD(wp))
+            {
+            case IDC_ADD_PURPOSE:
+                if (DialogBoxParamW(hInstance,
+                 MAKEINTRESOURCEW(IDD_ADD_CERT_PURPOSE), hwnd,
+                 add_purpose_dlg_proc, (LPARAM)hwnd) == IDOK)
+                    SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
+                break;
+            case IDC_ENABLE_ALL_PURPOSES:
+            case IDC_DISABLE_ALL_PURPOSES:
+            case IDC_ENABLE_SELECTED_PURPOSES:
+                SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
+                select_purposes(hwnd, LOWORD(wp) - IDC_ENABLE_ALL_PURPOSES);
+                break;
+            }
+            break;
+        }
+        break;
+    }
+    return 0;
+}
+
+static UINT CALLBACK cert_properties_general_callback(HWND hwnd, UINT msg,
+ PROPSHEETPAGEW *page)
+{
+    HWND lv;
+    int cItem, i;
+    struct edit_cert_data *data;
+
+    switch (msg)
+    {
+    case PSPCB_RELEASE:
+        lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
+        cItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
+        for (i = 0; i < cItem; i++)
+        {
+            LVITEMW item;
+
+            item.mask = LVIF_PARAM;
+            item.iItem = i;
+            item.iSubItem = 0;
+            if (SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item) && item.lParam)
+            {
+                PCRYPT_OID_INFO info = (PCRYPT_OID_INFO)item.lParam;
+
+                if (info->cbSize == sizeof(CRYPT_OID_INFO) && !info->dwGroupId)
+                {
+                    HeapFree(GetProcessHeap(), 0, (LPSTR)info->pszOID);
+                    HeapFree(GetProcessHeap(), 0, info);
+                }
+            }
+        }
+        data = (struct edit_cert_data *)GetWindowLongPtrW(hwnd, DWLP_USER);
+        if (data)
+        {
+            ImageList_Destroy(data->imageList);
+            HeapFree(GetProcessHeap(), 0, data);
+        }
+        break;
+    }
+    return 1;
+}
+
+static void show_edit_cert_properties_dialog(HWND parent,
+ struct detail_data *data)
+{
+    PROPSHEETHEADERW hdr;
+    PROPSHEETPAGEW page; /* FIXME: need to add a cross-certificate page */
+
+    TRACE("(%p)\n", data);
+
+    memset(&page, 0, sizeof(PROPSHEETPAGEW));
+    page.dwSize = sizeof(page);
+    page.dwFlags = PSP_USECALLBACK;
+    page.pfnCallback = cert_properties_general_callback;
+    page.hInstance = hInstance;
+    page.u.pszTemplate = MAKEINTRESOURCEW(IDD_CERT_PROPERTIES_GENERAL);
+    page.pfnDlgProc = cert_properties_general_dlg_proc;
+    page.lParam = (LPARAM)data;
+
+    memset(&hdr, 0, sizeof(hdr));
+    hdr.dwSize = sizeof(hdr);
+    hdr.hwndParent = parent;
+    hdr.dwFlags = PSH_PROPSHEETPAGE;
+    hdr.hInstance = hInstance;
+    hdr.pszCaption = MAKEINTRESOURCEW(IDS_CERTIFICATE_PROPERTIES);
+    hdr.u3.ppsp = &page;
+    hdr.nPages = 1;
+    PropertySheetW(&hdr);
+}
+
+static void free_detail_fields(struct detail_data *data)
+{
+    DWORD i;
+
+    for (i = 0; i < data->cFields; i++)
+        HeapFree(GetProcessHeap(), 0, data->fields[i].detailed_value);
+    HeapFree(GetProcessHeap(), 0, data->fields);
+    data->fields = NULL;
+    data->cFields = 0;
+}
+
+static void refresh_details_view(HWND hwnd)
+{
+    HWND cb = GetDlgItem(hwnd, IDC_DETAIL_SELECT);
+    int curSel;
+    struct detail_data *data;
+
+    curSel = SendMessageW(cb, CB_GETCURSEL, 0, 0);
+    /* Actually, any index will do, since they all store the same data value */
+    data = (struct detail_data *)SendMessageW(cb, CB_GETITEMDATA, curSel, 0);
+    free_detail_fields(data);
+    set_fields_selection(hwnd, data, curSel);
+}
+
+static LRESULT CALLBACK detail_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
+ LPARAM lp)
+{
+    PROPSHEETPAGEW *page;
+    struct detail_data *data;
+
+    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);
+
+    switch (msg)
+    {
+    case WM_INITDIALOG:
+        page = (PROPSHEETPAGEW *)lp;
+        data = (struct detail_data *)page->lParam;
+        create_cert_details_list(hwnd, data);
+        if (!(data->pCertViewInfo->dwFlags & CRYPTUI_ENABLE_EDITPROPERTIES))
+            EnableWindow(GetDlgItem(hwnd, IDC_EDITPROPERTIES), FALSE);
+        if (data->pCertViewInfo->dwFlags & CRYPTUI_DISABLE_EXPORT)
+            EnableWindow(GetDlgItem(hwnd, IDC_EXPORT), FALSE);
+        break;
+    case WM_NOTIFY:
+    {
+        NMITEMACTIVATE *nm;
+        HWND list = GetDlgItem(hwnd, IDC_DETAIL_LIST);
+
+        nm = (NMITEMACTIVATE*)lp;
+        if (nm->hdr.hwndFrom == list && nm->uNewState & LVN_ITEMACTIVATE
+         && nm->hdr.code == LVN_ITEMCHANGED)
+        {
+            data = (struct detail_data *)nm->lParam;
+            if (nm->iItem >= 0 && data && nm->iItem < data->cFields)
+            {
+                WCHAR buf[MAX_STRING_LEN], *val = NULL;
+                HWND valueCtl = GetDlgItem(hwnd, IDC_DETAIL_VALUE);
+
+                if (data->fields[nm->iItem].create)
+                    val = data->fields[nm->iItem].create(
+                     data->pCertViewInfo->pCertContext,
+                     data->fields[nm->iItem].param);
+                else
+                {
+                    LVITEMW item;
+                    int res;
+
+                    item.cchTextMax = sizeof(buf) / sizeof(buf[0]);
+                    item.mask = LVIF_TEXT;
+                    item.pszText = buf;
+                    item.iItem = nm->iItem;
+                    item.iSubItem = 1;
+                    res = SendMessageW(list, LVM_GETITEMW, 0, (LPARAM)&item);
+                    if (res)
+                        val = buf;
+                }
+                /* Select all the text in the control, the next update will
+                 * replace it
+                 */
+                SendMessageW(valueCtl, EM_SETSEL, 0, -1);
+                add_unformatted_text_to_control(valueCtl, val,
+                 val ? strlenW(val) : 0);
+                if (val != buf)
+                    HeapFree(GetProcessHeap(), 0, val);
+            }
+        }
+        break;
+    }
+    case WM_COMMAND:
+        switch (wp)
+        {
+        case IDC_EXPORT:
+            FIXME("call CryptUIWizExport\n");
+            break;
+        case IDC_EDITPROPERTIES:
+        {
+            HWND cb = GetDlgItem(hwnd, IDC_DETAIL_SELECT);
+            int curSel;
+
+            curSel = SendMessageW(cb, CB_GETCURSEL, 0, 0);
+            /* Actually, any index will do, since they all store the same
+             * data value
+             */
+            data = (struct detail_data *)SendMessageW(cb, CB_GETITEMDATA,
+             curSel, 0);
+            show_edit_cert_properties_dialog(GetParent(hwnd), data);
+            break;
+        }
+        case ((CBN_SELCHANGE << 16) | IDC_DETAIL_SELECT):
+            refresh_details_view(hwnd);
+            break;
+        }
+        break;
+    case WM_REFRESH_VIEW:
+        refresh_details_view(hwnd);
+        break;
+    }
+    return 0;
+}
+
+static UINT CALLBACK detail_callback(HWND hwnd, UINT msg,
+ PROPSHEETPAGEW *page)
+{
+    struct detail_data *data;
+
+    switch (msg)
+    {
+    case PSPCB_RELEASE:
+        data = (struct detail_data *)page->lParam;
+        free_detail_fields(data);
+        HeapFree(GetProcessHeap(), 0, data);
+        break;
+    }
+    return 0;
+}
+
+static BOOL init_detail_page(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
+ BOOL *pfPropertiesChanged, PROPSHEETPAGEW *page)
+{
+    BOOL ret;
+    struct detail_data *data = HeapAlloc(GetProcessHeap(), 0,
+     sizeof(struct detail_data));
+
+    if (data)
+    {
+        data->pCertViewInfo = pCertViewInfo;
+        data->pfPropertiesChanged = pfPropertiesChanged;
+        data->cFields = 0;
+        data->fields = NULL;
+        memset(page, 0, sizeof(PROPSHEETPAGEW));
+        page->dwSize = sizeof(PROPSHEETPAGEW);
+        page->dwFlags = PSP_USECALLBACK;
+        page->pfnCallback = detail_callback;
+        page->hInstance = hInstance;
+        page->u.pszTemplate = MAKEINTRESOURCEW(IDD_DETAIL);
+        page->pfnDlgProc = detail_dlg_proc;
+        page->lParam = (LPARAM)data;
+        ret = TRUE;
+    }
+    else
+        ret = FALSE;
+    return ret;
+}
+
+struct hierarchy_data
+{
+    PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo;
+    HIMAGELIST imageList;
+    DWORD selectedCert;
+};
+
+static LPARAM index_to_lparam(struct hierarchy_data *data, DWORD index)
+{
+    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
+     (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
+     data->pCertViewInfo->idxSigner, data->pCertViewInfo->fCounterSigner,
+     data->pCertViewInfo->idxCounterSigner);
+
+    /* Takes advantage of the fact that a pointer is 32-bit aligned, and
+     * therefore always even.
+     */
+    if (index == provSigner->csCertChain - 1)
+        return (LPARAM)data;
+    return index << 1 | 1;
+}
+
+static inline DWORD lparam_to_index(struct hierarchy_data *data, LPARAM lp)
+{
+    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
+     (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
+     data->pCertViewInfo->idxSigner, data->pCertViewInfo->fCounterSigner,
+     data->pCertViewInfo->idxCounterSigner);
+
+    if (!(lp & 1))
+        return provSigner->csCertChain - 1;
+    return lp >> 1;
+}
+
+static struct hierarchy_data *get_hierarchy_data_from_tree_item(HWND tree,
+ HTREEITEM hItem)
+{
+    struct hierarchy_data *data = NULL;
+    HTREEITEM root = NULL;
+
+    do {
+        HTREEITEM parent = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM,
+         TVGN_PARENT, (LPARAM)hItem);
+
+        if (!parent)
+            root = hItem;
+        hItem = parent;
+    } while (hItem);
+    if (root)
+    {
+        TVITEMW item;
+
+        item.mask = TVIF_PARAM;
+        item.hItem = root;
+        SendMessageW(tree, TVM_GETITEMW, 0, (LPARAM)&item);
+        data = (struct hierarchy_data *)item.lParam;
+    }
+    return data;
+}
+
+static WCHAR *get_cert_display_name(PCCERT_CONTEXT cert)
+{
+    WCHAR *name = get_cert_property_as_string(cert, CERT_FRIENDLY_NAME_PROP_ID);
+
+    if (!name)
+        name = get_cert_name_string(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0);
+    return name;
+}
+
+static void show_cert_chain(HWND hwnd, struct hierarchy_data *data)
+{
+    HWND tree = GetDlgItem(hwnd, IDC_CERTPATH);
+    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
+     (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
+     data->pCertViewInfo->idxSigner, data->pCertViewInfo->fCounterSigner,
+     data->pCertViewInfo->idxCounterSigner);
+    DWORD i;
+    HTREEITEM parent = NULL;
+
+    SendMessageW(tree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)data->imageList);
+    for (i = provSigner->csCertChain; i; i--)
+    {
+        LPWSTR name;
+
+        name = get_cert_display_name(provSigner->pasCertChain[i - 1].pCert);
+        if (name)
+        {
+            TVINSERTSTRUCTW tvis;
+
+            tvis.hParent = parent;
+            tvis.hInsertAfter = TVI_LAST;
+            tvis.u.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_IMAGE |
+             TVIF_SELECTEDIMAGE | TVIF_PARAM;
+            tvis.u.item.pszText = name;
+            tvis.u.item.state = TVIS_EXPANDED;
+            tvis.u.item.stateMask = TVIS_EXPANDED;
+            if (i == 1 &&
+             (provSigner->pChainContext->TrustStatus.dwErrorStatus &
+             CERT_TRUST_IS_PARTIAL_CHAIN))
+            {
+                /* The root of the chain has a special case:  if the chain is
+                 * a partial chain, the icon is a warning icon rather than an
+                 * error icon.
+                 */
+                tvis.u.item.iImage = 2;
+            }
+            else if (provSigner->pasCertChain[i - 1].pChainElement->TrustStatus.
+             dwErrorStatus == 0)
+                tvis.u.item.iImage = 0;
+            else
+                tvis.u.item.iImage = 1;
+            tvis.u.item.iSelectedImage = tvis.u.item.iImage;
+            tvis.u.item.lParam = index_to_lparam(data, i - 1);
+            parent = (HTREEITEM)SendMessageW(tree, TVM_INSERTITEMW, 0,
+             (LPARAM)&tvis);
+            HeapFree(GetProcessHeap(), 0, name);
+        }
+    }
+}
+
+static void set_certificate_status(HWND hwnd, CRYPT_PROVIDER_CERT *cert)
+{
+    /* Select all the text in the control, the next update will replace it */
+    SendMessageW(hwnd, EM_SETSEL, 0, -1);
+    /* Set the highest priority error messages first. */
+    if (!(cert->dwConfidence & CERT_CONFIDENCE_SIG))
+        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_BAD_SIGNATURE);
+    else if (!(cert->dwConfidence & CERT_CONFIDENCE_TIME))
+        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_BAD_TIME);
+    else if (!(cert->dwConfidence & CERT_CONFIDENCE_TIMENEST))
+        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_BAD_TIMENEST);
+    else if (cert->dwRevokedReason)
+        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_REVOKED);
+    else
+        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_VALID);
+}
+
+static void set_certificate_status_for_end_cert(HWND hwnd,
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
+{
+    HWND status = GetDlgItem(hwnd, IDC_CERTIFICATESTATUSTEXT);
+    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
+     (CRYPT_PROVIDER_DATA *)pCertViewInfo->u.pCryptProviderData,
+     pCertViewInfo->idxSigner, pCertViewInfo->fCounterSigner,
+     pCertViewInfo->idxCounterSigner);
+    CRYPT_PROVIDER_CERT *provCert = WTHelperGetProvCertFromChain(provSigner,
+     pCertViewInfo->idxCert);
+
+    set_certificate_status(status, provCert);
+}
+
+static void show_cert_hierarchy(HWND hwnd, struct hierarchy_data *data)
+{
+    /* Disable view certificate button until a certificate is selected */
+    EnableWindow(GetDlgItem(hwnd, IDC_VIEWCERTIFICATE), FALSE);
+    show_cert_chain(hwnd, data);
+    set_certificate_status_for_end_cert(hwnd, data->pCertViewInfo);
+}
+
+static void show_dialog_for_selected_cert(HWND hwnd)
+{
+    HWND tree = GetDlgItem(hwnd, IDC_CERTPATH);
+    TVITEMW item;
+    struct hierarchy_data *data;
+    DWORD selection;
+
+    memset(&item, 0, sizeof(item));
+    item.mask = TVIF_HANDLE | TVIF_PARAM;
+    item.hItem = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM, TVGN_CARET,
+     (LPARAM)NULL);
+    SendMessageW(tree, TVM_GETITEMW, 0, (LPARAM)&item);
+    data = get_hierarchy_data_from_tree_item(tree, item.hItem);
+    selection = lparam_to_index(data, item.lParam);
+    if (selection != 0)
+    {
+        CRYPT_PROVIDER_SGNR *provSigner;
+        CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
+        BOOL changed = FALSE;
+
+        provSigner = WTHelperGetProvSignerFromChain(
+         (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
+         data->pCertViewInfo->idxSigner,
+         data->pCertViewInfo->fCounterSigner,
+         data->pCertViewInfo->idxCounterSigner);
+        memset(&viewInfo, 0, sizeof(viewInfo));
+        viewInfo.dwSize = sizeof(viewInfo);
+        viewInfo.dwFlags = data->pCertViewInfo->dwFlags;
+        viewInfo.szTitle = data->pCertViewInfo->szTitle;
+        viewInfo.pCertContext = provSigner->pasCertChain[selection].pCert;
+        viewInfo.cStores = data->pCertViewInfo->cStores;
+        viewInfo.rghStores = data->pCertViewInfo->rghStores;
+        viewInfo.cPropSheetPages = data->pCertViewInfo->cPropSheetPages;
+        viewInfo.rgPropSheetPages = data->pCertViewInfo->rgPropSheetPages;
+        viewInfo.nStartPage = data->pCertViewInfo->nStartPage;
+        CryptUIDlgViewCertificateW(&viewInfo, &changed);
+        if (changed)
+        {
+            /* Delete the contents of the tree */
+            SendMessageW(tree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
+            /* Reinitialize the tree */
+            show_cert_hierarchy(hwnd, data);
+        }
+    }
+}
+
+static LRESULT CALLBACK hierarchy_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
+ LPARAM lp)
+{
+    PROPSHEETPAGEW *page;
+    struct hierarchy_data *data;
+    LRESULT ret = 0;
+    HWND tree = GetDlgItem(hwnd, IDC_CERTPATH);
+
+    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);
+
+    switch (msg)
+    {
+    case WM_INITDIALOG:
+        page = (PROPSHEETPAGEW *)lp;
+        data = (struct hierarchy_data *)page->lParam;
+        show_cert_hierarchy(hwnd, data);
+        break;
+    case WM_NOTIFY:
+    {
+        NMHDR *hdr;
+
+        hdr = (NMHDR *)lp;
+        switch (hdr->code)
+        {
+        case TVN_SELCHANGEDW:
+        {
+            NMTREEVIEWW *nm = (NMTREEVIEWW*)lp;
+            DWORD selection;
+            CRYPT_PROVIDER_SGNR *provSigner;
+
+            data = get_hierarchy_data_from_tree_item(tree, nm->itemNew.hItem);
+            selection = lparam_to_index(data, nm->itemNew.lParam);
+            provSigner = WTHelperGetProvSignerFromChain(
+             (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
+             data->pCertViewInfo->idxSigner,
+             data->pCertViewInfo->fCounterSigner,
+             data->pCertViewInfo->idxCounterSigner);
+            EnableWindow(GetDlgItem(hwnd, IDC_VIEWCERTIFICATE), selection != 0);
+            set_certificate_status(GetDlgItem(hwnd, IDC_CERTIFICATESTATUSTEXT),
+             &provSigner->pasCertChain[selection]);
+            break;
+        }
+        case NM_DBLCLK:
+            show_dialog_for_selected_cert(hwnd);
+            SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
+            ret = 1;
+            break;
+        }
+        break;
+    }
+    case WM_COMMAND:
+        switch (wp)
+        {
+        case IDC_VIEWCERTIFICATE:
+            show_dialog_for_selected_cert(hwnd);
+            break;
+        }
+        break;
+    case WM_REFRESH_VIEW:
+    {
+        TVITEMW item;
+
+        /* Get hierarchy data */
+        memset(&item, 0, sizeof(item));
+        item.mask = TVIF_HANDLE | TVIF_PARAM;
+        item.hItem = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM, TVGN_ROOT,
+         (LPARAM)NULL);
+        data = get_hierarchy_data_from_tree_item(tree, item.hItem);
+        /* Delete the contents of the tree */
+        SendMessageW(tree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
+        /* Reinitialize the tree */
+        show_cert_hierarchy(hwnd, data);
+        break;
+    }
+    }
+    return ret;
+}
+
+static UINT CALLBACK hierarchy_callback(HWND hwnd, UINT msg,
+ PROPSHEETPAGEW *page)
+{
+    struct hierarchy_data *data;
+
+    switch (msg)
+    {
+    case PSPCB_RELEASE:
+        data = (struct hierarchy_data *)page->lParam;
+        ImageList_Destroy(data->imageList);
+        HeapFree(GetProcessHeap(), 0, data);
+        break;
+    }
+    return 0;
+}
+
+static BOOL init_hierarchy_page(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
+ PROPSHEETPAGEW *page)
+{
+    struct hierarchy_data *data = HeapAlloc(GetProcessHeap(), 0,
+     sizeof(struct hierarchy_data));
+    BOOL ret = FALSE;
+
+    if (data)
+    {
+        data->imageList = ImageList_Create(16, 16, ILC_COLOR4 | ILC_MASK, 2, 0);
+        if (data->imageList)
+        {
+            HBITMAP bmp;
+            COLORREF backColor = RGB(255, 0, 255);
+
+            data->pCertViewInfo = pCertViewInfo;
+            data->selectedCert = 0xffffffff;
+
+            bmp = LoadBitmapW(hInstance, MAKEINTRESOURCEW(IDB_SMALL_ICONS));
+            ImageList_AddMasked(data->imageList, bmp, backColor);
+            DeleteObject(bmp);
+            ImageList_SetBkColor(data->imageList, CLR_NONE);
+
+            memset(page, 0, sizeof(PROPSHEETPAGEW));
+            page->dwSize = sizeof(PROPSHEETPAGEW);
+            page->dwFlags = PSP_USECALLBACK;
+            page->hInstance = hInstance;
+            page->u.pszTemplate = MAKEINTRESOURCEW(IDD_HIERARCHY);
+            page->pfnDlgProc = hierarchy_dlg_proc;
+            page->lParam = (LPARAM)data;
+            page->pfnCallback = hierarchy_callback;
+            ret = TRUE;
+        }
+        else
+            HeapFree(GetProcessHeap(), 0, data);
+    }
+    return ret;
+}
+
+static int CALLBACK cert_prop_sheet_proc(HWND hwnd, UINT msg, LPARAM lp)
+{
+    RECT rc;
+    POINT topLeft;
+
+    TRACE("(%p, %08x, %08lx)\n", hwnd, msg, lp);
+
+    switch (msg)
+    {
+    case PSCB_INITIALIZED:
+        /* Get cancel button's position.. */
+        GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rc);
+        topLeft.x = rc.left;
+        topLeft.y = rc.top;
+        ScreenToClient(hwnd, &topLeft);
+        /* hide the cancel button.. */
+        ShowWindow(GetDlgItem(hwnd, IDCANCEL), FALSE);
+        /* get the OK button's size.. */
+        GetWindowRect(GetDlgItem(hwnd, IDOK), &rc);
+        /* and move the OK button to the cancel button's original position. */
+        MoveWindow(GetDlgItem(hwnd, IDOK), topLeft.x, topLeft.y,
+         rc.right - rc.left, rc.bottom - rc.top, FALSE);
+        GetWindowRect(GetDlgItem(hwnd, IDOK), &rc);
+        break;
+    }
+    return 0;
+}
+
+static BOOL show_cert_dialog(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
+ CRYPT_PROVIDER_CERT *provCert, BOOL *pfPropertiesChanged)
+{
+    static const WCHAR riched[] = { 'r','i','c','h','e','d','2','0',0 };
+    DWORD nPages;
+    PROPSHEETPAGEW *pages;
+    BOOL ret = FALSE;
+    HMODULE lib = LoadLibraryW(riched);
+
+    nPages = pCertViewInfo->cPropSheetPages + 1; /* one for the General tab */
+    if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_DETAILPAGE))
+        nPages++;
+    if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_HIERARCHYPAGE))
+        nPages++;
+    pages = HeapAlloc(GetProcessHeap(), 0, nPages * sizeof(PROPSHEETPAGEW));
+    if (pages)
+    {
+        PROPSHEETHEADERW hdr;
+        CRYPTUI_INITDIALOG_STRUCT *init = NULL;
+        DWORD i;
+
+        memset(&hdr, 0, sizeof(hdr));
+        hdr.dwSize = sizeof(hdr);
+        hdr.dwFlags = PSH_NOAPPLYNOW | PSH_PROPSHEETPAGE | PSH_USECALLBACK;
+        hdr.hInstance = hInstance;
+        if (pCertViewInfo->szTitle)
+            hdr.pszCaption = pCertViewInfo->szTitle;
+        else
+            hdr.pszCaption = MAKEINTRESOURCEW(IDS_CERTIFICATE);
+        init_general_page(pCertViewInfo, &pages[hdr.nPages++]);
+        if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_DETAILPAGE))
+        {
+            if (init_detail_page(pCertViewInfo, pfPropertiesChanged,
+             &pages[hdr.nPages]))
+                hdr.nPages++;
+        }
+        if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_HIERARCHYPAGE))
+        {
+            if (init_hierarchy_page(pCertViewInfo, &pages[hdr.nPages]))
+                hdr.nPages++;
+        }
+        /* Copy each additional page, and create the init dialog struct for it
+         */
+        if (pCertViewInfo->cPropSheetPages)
+        {
+            init = HeapAlloc(GetProcessHeap(), 0,
+             pCertViewInfo->cPropSheetPages *
+             sizeof(CRYPTUI_INITDIALOG_STRUCT));
+            if (init)
+            {
+                for (i = 0; i < pCertViewInfo->cPropSheetPages; i++)
+                {
+                    memcpy(&pages[hdr.nPages + i],
+                     &pCertViewInfo->rgPropSheetPages[i],
+                     sizeof(PROPSHEETPAGEW));
+                    init[i].lParam = pCertViewInfo->rgPropSheetPages[i].lParam;
+                    init[i].pCertContext = pCertViewInfo->pCertContext;
+                    pages[hdr.nPages + i].lParam = (LPARAM)&init[i];
+                }
+                if (pCertViewInfo->nStartPage & 0x8000)
+                {
+                    /* Start page index is relative to the number of default
+                     * pages
+                     */
+                    hdr.u2.nStartPage = pCertViewInfo->nStartPage + hdr.nPages;
+                }
+                else
+                    hdr.u2.nStartPage = pCertViewInfo->nStartPage;
+                hdr.nPages = nPages;
+                ret = TRUE;
+            }
+            else
+                SetLastError(ERROR_OUTOFMEMORY);
+        }
+        else
+        {
+            /* Ignore the relative flag if there aren't any additional pages */
+            hdr.u2.nStartPage = pCertViewInfo->nStartPage & 0x7fff;
+            ret = TRUE;
+        }
+        if (ret)
+        {
+            INT_PTR l;
+
+            hdr.u3.ppsp = pages;
+            hdr.pfnCallback = cert_prop_sheet_proc;
+            l = PropertySheetW(&hdr);
+            if (l == 0)
+            {
+                SetLastError(ERROR_CANCELLED);
+                ret = FALSE;
+            }
+        }
+        HeapFree(GetProcessHeap(), 0, init);
+        HeapFree(GetProcessHeap(), 0, pages);
+    }
+    else
+        SetLastError(ERROR_OUTOFMEMORY);
+    FreeLibrary(lib);
+    return ret;
+}
+
+/***********************************************************************
+ *             CryptUIDlgViewCertificateW (CRYPTUI.@)
+ */
+BOOL WINAPI CryptUIDlgViewCertificateW(
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo, BOOL *pfPropertiesChanged)
+{
+    static GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
+    CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
+    WINTRUST_DATA wvt;
+    WINTRUST_CERT_INFO cert;
+    BOOL ret = FALSE;
+    CRYPT_PROVIDER_SGNR *signer;
+    CRYPT_PROVIDER_CERT *provCert = NULL;
+
+    TRACE("(%p, %p)\n", pCertViewInfo, pfPropertiesChanged);
+
+    if (pCertViewInfo->dwSize != sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    /* Make a local copy in case we have to call WinVerifyTrust ourselves */
+    memcpy(&viewInfo, pCertViewInfo, sizeof(viewInfo));
+    if (!viewInfo.u.hWVTStateData)
+    {
+        memset(&wvt, 0, sizeof(wvt));
+        wvt.cbStruct = sizeof(wvt);
+        wvt.dwUIChoice = WTD_UI_NONE;
+        if (viewInfo.dwFlags &
+         CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT)
+            wvt.fdwRevocationChecks |= WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
+        if (viewInfo.dwFlags & CRYPTUI_ENABLE_REVOCATION_CHECK_END_CERT)
+            wvt.fdwRevocationChecks |= WTD_REVOCATION_CHECK_END_CERT;
+        if (viewInfo.dwFlags & CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN)
+            wvt.fdwRevocationChecks |= WTD_REVOCATION_CHECK_CHAIN;
+        wvt.dwUnionChoice = WTD_CHOICE_CERT;
+        memset(&cert, 0, sizeof(cert));
+        cert.cbStruct = sizeof(cert);
+        cert.psCertContext = (CERT_CONTEXT *)viewInfo.pCertContext;
+        cert.chStores = viewInfo.cStores;
+        cert.pahStores = viewInfo.rghStores;
+        wvt.u.pCert = &cert;
+        wvt.dwStateAction = WTD_STATEACTION_VERIFY;
+        WinVerifyTrust(NULL, &generic_cert_verify, &wvt);
+        viewInfo.u.pCryptProviderData =
+         WTHelperProvDataFromStateData(wvt.hWVTStateData);
+        signer = WTHelperGetProvSignerFromChain(
+         (CRYPT_PROVIDER_DATA *)viewInfo.u.pCryptProviderData, 0, FALSE, 0);
+        provCert = WTHelperGetProvCertFromChain(signer, 0);
+        ret = TRUE;
+    }
+    else
+    {
+        viewInfo.u.pCryptProviderData =
+         WTHelperProvDataFromStateData(viewInfo.u.hWVTStateData);
+        signer = WTHelperGetProvSignerFromChain(
+         (CRYPT_PROVIDER_DATA *)viewInfo.u.pCryptProviderData,
+         viewInfo.idxSigner, viewInfo.fCounterSigner,
+         viewInfo.idxCounterSigner);
+        provCert = WTHelperGetProvCertFromChain(signer, viewInfo.idxCert);
+        ret = TRUE;
+    }
+    if (ret)
+    {
+        ret = show_cert_dialog(&viewInfo, provCert, pfPropertiesChanged);
+        if (!viewInfo.u.hWVTStateData)
+        {
+            wvt.dwStateAction = WTD_STATEACTION_CLOSE;
+            WinVerifyTrust(NULL, &generic_cert_verify, &wvt);
+        }
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *             CryptUIDlgViewContext (CRYPTUI.@)
+ */
+BOOL WINAPI CryptUIDlgViewContext(DWORD dwContextType, LPVOID pvContext,
+ HWND hwnd, LPCWSTR pwszTitle, DWORD dwFlags, LPVOID pvReserved)
+{
+    BOOL ret;
+
+    TRACE("(%d, %p, %p, %s, %08x, %p)\n", dwContextType, pvContext, hwnd,
+     debugstr_w(pwszTitle), dwFlags, pvReserved);
+
+    switch (dwContextType)
+    {
+    case CERT_STORE_CERTIFICATE_CONTEXT:
+    {
+        CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
+
+        memset(&viewInfo, 0, sizeof(viewInfo));
+        viewInfo.dwSize = sizeof(viewInfo);
+        viewInfo.hwndParent = hwnd;
+        viewInfo.szTitle = pwszTitle;
+        viewInfo.pCertContext = pvContext;
+        ret = CryptUIDlgViewCertificateW(&viewInfo, NULL);
+        break;
+    }
+    default:
+        FIXME("unimplemented for context type %d\n", dwContextType);
+        SetLastError(E_INVALIDARG);
+        ret = FALSE;
+    }
+    return ret;
+}
+
+static PCCERT_CONTEXT make_cert_from_file(LPCWSTR fileName)
+{
+    HANDLE file;
+    DWORD size, encoding = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+    BYTE *buffer;
+    PCCERT_CONTEXT cert;
+
+    file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
+     OPEN_EXISTING, 0, NULL);
+    if (file == INVALID_HANDLE_VALUE)
+    {
+        WARN("can't open certificate file %s\n", debugstr_w(fileName));
+        return NULL;
+    }
+    if ((size = GetFileSize(file, NULL)))
+    {
+        if ((buffer = HeapAlloc(GetProcessHeap(), 0, size)))
+        {
+            DWORD read;
+            if (!ReadFile(file, buffer, size, &read, NULL) || read != size)
+            {
+                WARN("can't read certificate file %s\n", debugstr_w(fileName));
+                HeapFree(GetProcessHeap(), 0, buffer);
+                CloseHandle(file);
+                return NULL;
+            }
+        }
+    }
+    else
+    {
+        WARN("empty file %s\n", debugstr_w(fileName));
+        CloseHandle(file);
+        return NULL;
+    }
+    CloseHandle(file);
+    cert = CertCreateCertificateContext(encoding, buffer, size);
+    HeapFree(GetProcessHeap(), 0, buffer);
+    return cert;
+}
+
+/* Decodes a cert's basic constraints extension (either szOID_BASIC_CONSTRAINTS
+ * or szOID_BASIC_CONSTRAINTS2, whichever is present) to determine if it
+ * should be a CA.  If neither extension is present, returns
+ * defaultIfNotSpecified.
+ */
+static BOOL is_ca_cert(PCCERT_CONTEXT cert, BOOL defaultIfNotSpecified)
+{
+    BOOL isCA = defaultIfNotSpecified;
+    PCERT_EXTENSION ext = CertFindExtension(szOID_BASIC_CONSTRAINTS,
+     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
+
+    if (ext)
+    {
+        CERT_BASIC_CONSTRAINTS_INFO *info;
+        DWORD size = 0;
+
+        if (CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS,
+         ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
+         NULL, (LPBYTE)&info, &size))
+        {
+            if (info->SubjectType.cbData == 1)
+                isCA = info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG;
+            LocalFree(info);
+        }
+    }
+    else
+    {
+        ext = CertFindExtension(szOID_BASIC_CONSTRAINTS2,
+         cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
+        if (ext)
+        {
+            CERT_BASIC_CONSTRAINTS2_INFO info;
+            DWORD size = sizeof(CERT_BASIC_CONSTRAINTS2_INFO);
+
+            if (CryptDecodeObjectEx(X509_ASN_ENCODING,
+             szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
+             0, NULL, &info, &size))
+                isCA = info.fCA;
+        }
+    }
+    return isCA;
+}
+
+static HCERTSTORE choose_store_for_cert(PCCERT_CONTEXT cert)
+{
+    static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
+     'B','o','o','k',0 };
+    static const WCHAR CA[] = { 'C','A',0 };
+    LPCWSTR storeName;
+
+    if (is_ca_cert(cert, TRUE))
+        storeName = CA;
+    else
+        storeName = AddressBook;
+    return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
+     CERT_SYSTEM_STORE_CURRENT_USER, storeName);
+}
+
+BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardTitle,
+                             PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc, HCERTSTORE hDestCertStore)
+{
+    BOOL ret;
+    HCERTSTORE store;
+    const CERT_CONTEXT *cert;
+    BOOL freeCert = FALSE;
+
+    TRACE("(0x%08x, %p, %s, %p, %p)\n", dwFlags, hwndParent, debugstr_w(pwszWizardTitle),
+          pImportSrc, hDestCertStore);
+
+    if (!(dwFlags & CRYPTUI_WIZ_NO_UI)) FIXME("UI not implemented\n");
+
+    if (!pImportSrc ||
+     pImportSrc->dwSize != sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO))
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+
+    switch (pImportSrc->dwSubjectChoice)
+    {
+    case CRYPTUI_WIZ_IMPORT_SUBJECT_FILE:
+        if (!(cert = make_cert_from_file(pImportSrc->u.pwszFileName)))
+        {
+            WARN("unable to create certificate context\n");
+            return FALSE;
+        }
+        else
+            freeCert = TRUE;
+        break;
+    case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT:
+        cert = pImportSrc->u.pCertContext;
+        if (!cert)
+        {
+            SetLastError(E_INVALIDARG);
+            return FALSE;
+        }
+        break;
+    default:
+        FIXME("source type not implemented: %u\n", pImportSrc->dwSubjectChoice);
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if (hDestCertStore) store = hDestCertStore;
+    else
+    {
+        if (!(store = choose_store_for_cert(cert)))
+        {
+            WARN("unable to open certificate store\n");
+            CertFreeCertificateContext(cert);
+            return FALSE;
+        }
+    }
+    ret = CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
+
+    if (!hDestCertStore) CertCloseStore(store, 0);
+    if (freeCert)
+        CertFreeCertificateContext(cert);
+    return ret;
+}
diff --git a/reactos/dll/win32/cryptui/smallicons.bmp b/reactos/dll/win32/cryptui/smallicons.bmp
new file mode 100644 (file)
index 0000000..a936781
Binary files /dev/null and b/reactos/dll/win32/cryptui/smallicons.bmp differ
index ff7147b..27fd8ce 100644 (file)
@@ -1537,7 +1537,7 @@ GetDeviceAndComputerName(LPWSTR lpString,
         if (*lpString == L'/')
         {
             lpString++;
-            if(!wcsnicmp(lpString, L"DeviceID", 8))
+            if(!_wcsnicmp(lpString, L"DeviceID", 8))
             {
                 lpString += 9;
                 if (*lpString != L'\0')
@@ -1553,7 +1553,7 @@ GetDeviceAndComputerName(LPWSTR lpString,
                     ret = TRUE;
                 }
             }
-            else if (!wcsnicmp(lpString, L"MachineName", 11))
+            else if (!_wcsnicmp(lpString, L"MachineName", 11))
             {
                 lpString += 12;
                 if (*lpString != L'\0')
index 293ff14..be165a3 100644 (file)
@@ -1,4 +1,4 @@
-<module name="devmgr" type="win32dll" baseaddress="${BASEADDRESS_DEVENUM}" installbase="system32" installname="devmgr.dll" allowwarnings="true" unicode="yes">
+<module name="devmgr" type="win32dll" baseaddress="${BASEADDRESS_DEVENUM}" installbase="system32" installname="devmgr.dll" unicode="yes">
        <include base="devmgr">.</include>
        <importlibrary definition="devmgr.spec" />
        <library>kernel32</library>
diff --git a/reactos/dll/win32/dwmapi/dwmapi.rbuild b/reactos/dll/win32/dwmapi/dwmapi.rbuild
new file mode 100644 (file)
index 0000000..778500e
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<group>
+<module name="dwmapi" type="win32dll" baseaddress="${BASEADDRESS_DWMAPI}" installbase="system32" installname="dwmapi.dll" allowwarnings="true">
+       <importlibrary definition="dwmapi.spec" />
+       <include base="dwmapi">.</include>
+       <include base="ReactOS">include/reactos/wine</include>
+       <define name="__WINESRC__" />
+       <file>dwmapi_main.c</file>
+       <file>version.rc</file>
+       <library>wine</library>
+       <library>kernel32</library>
+       <library>ntdll</library>
+</module>
+</group>
diff --git a/reactos/dll/win32/dwmapi/dwmapi.spec b/reactos/dll/win32/dwmapi/dwmapi.spec
new file mode 100644 (file)
index 0000000..63ee2f5
--- /dev/null
@@ -0,0 +1,44 @@
+100 stub @
+101 stub @
+102 stdcall DwmEnableComposition (long)
+103 stub @
+104 stub @
+105 stub @
+106 stub @
+107 stub @
+108 stub @
+109 stub @
+110 stub @
+111 stub @
+112 stub @
+113 stub @
+
+115 stub @
+116 stub @
+117 stub @
+118 stub @
+119 stub @
+120 stub @
+
+@ stub DwmAttachMilContent
+@ stub DwmDefWindowProc
+@ stub DwmDetachMilContent
+@ stub DwmEnableBlurBehindWindow
+@ stub DwmEnableMMCSS
+@ stdcall DwmExtendFrameIntoClientArea(long ptr)
+@ stdcall DwmFlush()
+@ stdcall DwmGetColorizationColor(ptr long)
+@ stub DwmGetCompositionTimingInfo
+@ stub DwmGetGraphicsStreamClient
+@ stub DwmGetGraphicsStreamTransformHint
+@ stub DwmGetTransportAttributes
+@ stub DwmGetWindowAttribute
+@ stdcall DwmIsCompositionEnabled(ptr)
+@ stub DwmModifyPreviousDxFrameDuration
+@ stub DwmQueryThumbnailSourceSize
+@ stub DwmRegisterThumbnail
+@ stub DwmSetDxFrameDuration
+@ stub DwmSetPresentParameters
+@ stdcall DwmSetWindowAttribute(long long ptr long)
+@ stdcall DwmUnregisterThumbnail(long)
+@ stub DwmUpdateThumbnailProperties
diff --git a/reactos/dll/win32/dwmapi/dwmapi_main.c b/reactos/dll/win32/dwmapi/dwmapi_main.c
new file mode 100644 (file)
index 0000000..e306c56
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Dwmapi
+ *
+ * Copyright 2007 Andras Kovacs
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+#include "config.h"
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#define COBJMACROS
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "dwmapi.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dwmapi);
+
+
+/* At process attach */
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+{
+    switch(fdwReason)
+    {
+    case DLL_WINE_PREATTACH:
+        return FALSE;  /* prefer native version */
+    case DLL_PROCESS_ATTACH:
+        DisableThreadLibraryCalls( hInstDLL );
+        break;
+    }
+    return TRUE;
+}
+
+/**********************************************************************
+ *           DwmIsCompositionEnabled         (DWMAPI.@)
+ */
+HRESULT WINAPI DwmIsCompositionEnabled(BOOL *enabled)
+{
+    FIXME("%p\n", enabled);
+
+    *enabled = FALSE;
+    return S_OK;
+}
+
+/**********************************************************************
+ *           DwmEnableComposition         (DWMAPI.102)
+ */
+HRESULT WINAPI DwmEnableComposition(UINT uCompositionAction)
+{
+    FIXME("(%d) stub\n", uCompositionAction);
+
+    return S_OK;
+}
+
+/**********************************************************************
+ *           DwmExtendFrameIntoClientArea    (DWMAPI.@)
+ */
+HRESULT WINAPI DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS* margins)
+{
+    FIXME("(%p, %p) stub\n", hwnd, margins);
+
+    return E_NOTIMPL;
+}
+
+/**********************************************************************
+ *           DwmGetColorizationColor      (DWMAPI.@)
+ */
+HRESULT WINAPI DwmGetColorizationColor(DWORD *colorization, BOOL opaque_blend)
+{
+    FIXME("(%p, %d) stub\n", colorization, opaque_blend);
+
+    return E_NOTIMPL;
+}
+
+/**********************************************************************
+ *                  DwmFlush              (DWMAPI.@)
+ */
+HRESULT WINAPI DwmFlush()
+{
+    FIXME("() stub\n");
+
+    return E_NOTIMPL;
+}
+
+/**********************************************************************
+ *           DwmSetWindowAttribute         (DWMAPI.@)
+ */
+HRESULT WINAPI DwmSetWindowAttribute(HWND hwnd, DWORD attributenum, LPCVOID attribute, DWORD size)
+{
+    FIXME("(%p, %x, %p, %x) stub\n", hwnd, attributenum, attribute, size);
+
+    return E_NOTIMPL;
+}
+
+/**********************************************************************
+ *           DwmUnregisterThumbnail         (DWMAPI.@)
+ */
+HRESULT WINAPI DwmUnregisterThumbnail(HTHUMBNAIL thumbnail)
+{
+    FIXME("(%p) stub\n", thumbnail);
+
+    return E_NOTIMPL;
+}
diff --git a/reactos/dll/win32/dwmapi/version.rc b/reactos/dll/win32/dwmapi/version.rc
new file mode 100644 (file)
index 0000000..b76f194
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2007 Andras Kovacs
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Desktop Window Manager API"
+#define WINE_FILENAME_STR "dwmapi.dll"
+#define WINE_FILEVERSION 6,0,6000,16386
+#define WINE_FILEVERSION_STR "6.0.6000.16386"
+#define WINE_PRODUCTVERSION 6,0,6000,16386
+#define WINE_PRODUCTVERSION_STR "6.0.6000.16386"
+
+#include "wine/wine_common_ver.rc"
index 75ca048..dfa4492 100644 (file)
@@ -502,7 +502,7 @@ static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
     ULONG currofs;
 
     currofs = offset;
-    assembly->tableshdr = (METADATATABLESHDR *)assembly_data_offset(assembly, currofs);
+    assembly->tableshdr = assembly_data_offset(assembly, currofs);
     if (!assembly->tableshdr)
         return E_FAIL;
 
@@ -514,7 +514,7 @@ static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
                        sizeof(DWORD) : sizeof(WORD);
 
     currofs += sizeof(METADATATABLESHDR);
-    assembly->numrows = (DWORD *)assembly_data_offset(assembly, currofs);
+    assembly->numrows = assembly_data_offset(assembly, currofs);
     if (!assembly->numrows)
         return E_FAIL;
 
@@ -628,9 +628,9 @@ static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
                 return hr;
         }
         else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings"))
-            assembly->strings = (BYTE *)assembly_data_offset(assembly, ofs);
+            assembly->strings = assembly_data_offset(assembly, ofs);
         else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob"))
-            assembly->blobs = (BYTE *)assembly_data_offset(assembly, ofs);
+            assembly->blobs = assembly_data_offset(assembly, ofs);
 
         ptr += lstrlenA(stream) + 1;
         ptr = (BYTE *)(((UINT_PTR)ptr + 3) & ~3); /* align on DWORD boundary */
@@ -883,7 +883,7 @@ HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token)
     if (offset == -1)
         return E_FAIL;
 
-    asmtbl = (ASSEMBLYTABLE *)assembly_data_offset(assembly, offset);
+    asmtbl = assembly_data_offset(assembly, offset);
     if (!asmtbl)
         return E_FAIL;
 
index ff34556..20841f8 100644 (file)
@@ -441,14 +441,14 @@ static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc,
 static HRESULT WINAPI IHlink_fnSetAdditonalParams(IHlink* iface,
         LPCWSTR pwzAdditionalParams)
 {
-    FIXME("\n");
+    TRACE("Not implemented in native IHlink\n");
     return E_NOTIMPL;
 }
 
 static HRESULT WINAPI IHlink_fnGetAdditionalParams(IHlink* iface,
         LPWSTR* ppwzAdditionalParams)
 {
-    FIXME("\n");
+    TRACE("Not implemented in native IHlink\n");
     return E_NOTIMPL;
 }
 
index 28c0bbf..9800bfb 100644 (file)
@@ -1,4 +1,4 @@
-<module name="icmp" type="win32dll" entrypoint="0" baseaddress="${BASEADDRESS_ICMP}" installbase="system32" installname="icmp.dll" allowwarnings="true">
+<module name="icmp" type="win32dll" baseaddress="${BASEADDRESS_ICMP}" installbase="system32" installname="icmp.dll" allowwarnings="true">
        <importlibrary definition="icmp.spec" />
        <include base="icmp">.</include>
        <include base="ReactOS">include/reactos/wine</include>
index d9f2658..abd4ca1 100644 (file)
@@ -143,6 +143,22 @@ static int in_cksum(u_short *addr, int len)
  * Exported Routines.
  */
 
+BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+  WSADATA wsaData;
+
+  switch (fdwReason) {
+    case DLL_PROCESS_ATTACH:
+      WSAStartup(MAKEWORD(2, 2), &wsaData);
+      break;
+
+    case DLL_PROCESS_DETACH:
+      WSACleanup();
+      break;
+  }
+  return TRUE;
+}
+
 /***********************************************************************
  *             IcmpCreateFile (ICMP.@)
  */
index 2fecb30..3a11a8d 100644 (file)
@@ -1253,45 +1253,45 @@ static int IpNetTableSorter(const void *a, const void *b)
  */
 DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOrder)
 {
-  DWORD ret;
+  DWORD ret = NO_ERROR;
 
-  TRACE("pIpNetTable %p, pdwSize %p, bOrder %ld\n", pIpNetTable, pdwSize,
+  TRACE("pIpNetTable %p, pdwSize %p, bOrder %d\n", pIpNetTable, pdwSize,
    (DWORD)bOrder);
   if (!pdwSize)
     ret = ERROR_INVALID_PARAMETER;
   else {
     DWORD numEntries = getNumArpEntries();
-    ULONG size = sizeof(MIB_IPNETTABLE) + (numEntries - 1) *
-     sizeof(MIB_IPNETROW);
+    ULONG size = sizeof(MIB_IPNETTABLE);
 
+    if (numEntries > 1)
+      size += (numEntries - 1) * sizeof(MIB_IPNETROW);
     if (!pIpNetTable || *pdwSize < size) {
       *pdwSize = size;
       ret = ERROR_INSUFFICIENT_BUFFER;
     }
     else {
       PMIB_IPNETTABLE table = getArpTable();
-
       if (table) {
-        size = sizeof(MIB_IPNETTABLE) + (table->dwNumEntries - 1) *
-         sizeof(MIB_IPNETROW);
+        size = sizeof(MIB_IPNETTABLE);
+        if (table->dwNumEntries > 1)
+          size += (table->dwNumEntries - 1) * sizeof(MIB_IPNETROW);
         if (*pdwSize < size) {
           *pdwSize = size;
           ret = ERROR_INSUFFICIENT_BUFFER;
         }
         else {
+          *pdwSize = size;
           memcpy(pIpNetTable, table, size);
           if (bOrder)
             qsort(pIpNetTable->table, pIpNetTable->dwNumEntries,
              sizeof(MIB_IPNETROW), IpNetTableSorter);
           ret = NO_ERROR;
         }
-        free(table);
+        HeapFree(GetProcessHeap(), 0, table);
       }
-      else
-        ret = ERROR_OUTOFMEMORY;
     }
   }
-  TRACE("returning %ld\n", ret);
+  TRACE("returning %d\n", ret);
   return ret;
 }
 
@@ -1527,6 +1527,12 @@ DWORD WINAPI GetPerAdapterInfo(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterIn
   if (!pOutBufLen)
     return ERROR_INVALID_PARAMETER;
 
+  if (!pPerAdapterInfo || *pOutBufLen < sizeof(IP_PER_ADAPTER_INFO))
+  {
+    *pOutBufLen = sizeof(IP_PER_ADAPTER_INFO);
+    return ERROR_BUFFER_OVERFLOW;
+  }
+
   ifName = getInterfaceNameByIndex(IfIndex);
   if (!ifName)
     return ERROR_INVALID_PARAMETER;
@@ -1659,58 +1665,60 @@ static int TcpTableSorter(const void *a, const void *b)
 /******************************************************************
  *    GetTcpTable (IPHLPAPI.@)
  *
+ * Get the table of active TCP connections.
  *
  * PARAMS
- *
- *  pTcpTable [In/Out]
- *  pdwSize [In/Out]
- *  bOrder [In]
+ *  pTcpTable [Out]    buffer for TCP connections table
+ *  pdwSize   [In/Out] length of output buffer
+ *  bOrder    [In]     whether to order the table
  *
  * RETURNS
- *
- *  DWORD
- *
+ *  Success: NO_ERROR
+ *  Failure: error code from winerror.h
+ *
+ * NOTES
+ *  If pdwSize is less than required, the function will return 
+ *  ERROR_INSUFFICIENT_BUFFER, and *pdwSize will be set to 
+ *  the required byte size.
+ *  If bOrder is true, the returned table will be sorted, first by
+ *  local address and port number, then by remote address and port
+ *  number.
  */
 DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder)
 {
-  DWORD ret;
+  DWORD ret = NO_ERROR;
 
-  TRACE("pTcpTable %p, pdwSize %p, bOrder %ld\n", pTcpTable, pdwSize,
+  TRACE("pTcpTable %p, pdwSize %p, bOrder %d\n", pTcpTable, pdwSize,
    (DWORD)bOrder);
   if (!pdwSize)
     ret = ERROR_INVALID_PARAMETER;
   else {
     DWORD numEntries = getNumTcpEntries();
-    ULONG size = sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW);
+    DWORD size = sizeof(MIB_TCPTABLE);
 
+    if (numEntries > 1)
+      size += (numEntries - 1) * sizeof(MIB_TCPROW);
     if (!pTcpTable || *pdwSize < size) {
       *pdwSize = size;
       ret = ERROR_INSUFFICIENT_BUFFER;
     }
     else {
-      PMIB_TCPTABLE table = getTcpTable();
-
-      if (table) {
-        size = sizeof(MIB_TCPTABLE) + (table->dwNumEntries - 1) *
-         sizeof(MIB_TCPROW);
-        if (*pdwSize < size) {
-          *pdwSize = size;
-          ret = ERROR_INSUFFICIENT_BUFFER;
-        }
-        else {
-          memcpy(pTcpTable, table, size);
-          if (bOrder)
-            qsort(pTcpTable->table, pTcpTable->dwNumEntries,
-             sizeof(MIB_TCPROW), TcpTableSorter);
-          ret = NO_ERROR;
-        }
-        free(table);
-      }
-      else
-        ret = ERROR_OUTOFMEMORY;
-    }
+      PMIB_TCPTABLE pTcpTable = getTcpTable();
+         if (pTcpTable)
+      {
+        size = sizeof(MIB_TCPTABLE);
+        if (pTcpTable->dwNumEntries > 1)
+          size += (pTcpTable->dwNumEntries - 1) * sizeof(MIB_TCPROW);
+        *pdwSize = size;
+
+           if (bOrder)
+          qsort(pTcpTable->table, pTcpTable->dwNumEntries,
+               sizeof(MIB_TCPROW), TcpTableSorter);
+        ret = NO_ERROR;
+         }
+       }
   }
-  TRACE("returning %ld\n", ret);
+  TRACE("returning %d\n", ret);
   return ret;
 }
 
index 8b13451..d0a6178 100644 (file)
@@ -549,7 +549,10 @@ DWORD getNumArpEntries(void)
                                        &returnSize );
 
            if( status == STATUS_SUCCESS ) totalNumber += returnSize;
-           if( IpArpTable ) tdiFreeThingSet( IpArpTable );
+               if( IpArpTable ) {
+                       tdiFreeThingSet( IpArpTable );
+                       IpArpTable = NULL;
+               }
        }
     }
 
index 2321eb8..59f6165 100644 (file)
@@ -92,12 +92,7 @@ FindFirstChangeNotificationW (
                         &ObjectAttributes,
                         &IoStatus,
                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-                        FILE_DIRECTORY_FILE);
-
-   /*
-   FIXME: I think we should use FILE_OPEN_FOR_BACKUP_INTENT. See M$ Q188321
-   -Gunnar
-   */
+                        FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
 
    RtlFreeHeap(RtlGetProcessHeap(),
                0,
@@ -122,6 +117,7 @@ FindFirstChangeNotificationW (
                                         (BOOLEAN)bWatchSubtree);
    if (!NT_SUCCESS(Status))
    {
+      NtClose(hDir);
       SetLastErrorByStatus(Status);
       return INVALID_HANDLE_VALUE;
    }
@@ -185,24 +181,62 @@ ReadDirectoryChangesW(
     LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine /* OPTIONAL???????? */
     )
 {
+   PVOID CompletionRoutine;
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatus;
+   HANDLE EventHandle;
+   PIO_APC_ROUTINE IoApcRoutine;
 
    if (lpOverlapped )
+   {
+      if (lpCompletionRoutine)
+      {
+          CompletionRoutine = (PVOID) lpCompletionRoutine;
+          EventHandle = NULL;
+          IoApcRoutine = ApcRoutine;
+      }
+      else
+      {
+          if (((ULONG_PTR) lpOverlapped->hEvent & 1) == 0)
+              CompletionRoutine = (PVOID) lpOverlapped;
+          else
+              CompletionRoutine = NULL;
+
+          EventHandle = lpOverlapped->hEvent;
+          IoApcRoutine = NULL;
+      }
+
       lpOverlapped->Internal = STATUS_PENDING;
+   }
+   else
+   {
+       EventHandle = NULL;
+       IoApcRoutine = NULL;
+       CompletionRoutine = NULL;
+   }
 
    Status = NtNotifyChangeDirectoryFile(
       hDirectory,
-      lpOverlapped ? lpOverlapped->hEvent : NULL,
-      lpCompletionRoutine ? ApcRoutine : NULL, /* ApcRoutine OPTIONAL???? */
-      lpCompletionRoutine, /* ApcContext */
-      lpOverlapped ? (PIO_STATUS_BLOCK)lpOverlapped : &IoStatus,
+      EventHandle,
+      IoApcRoutine,
+      CompletionRoutine, /* ApcContext */
+      lpOverlapped ? (PIO_STATUS_BLOCK)lpOverlapped->Internal : &IoStatus,
       lpBuffer,
       nBufferLength,
       dwNotifyFilter,
       (BOOLEAN)bWatchSubtree
       );
 
+   if ((Status == STATUS_PENDING) && (!lpOverlapped))
+   {
+       Status = NtWaitForSingleObject(hDirectory, FALSE, NULL);
+
+       if (NT_SUCCESS(Status))
+       {
+           Status = IoStatus.Status;
+       }
+   }
+
    if (!NT_SUCCESS(Status))
    {
       SetLastErrorByStatus(Status);
index 928f8a3..e728591 100644 (file)
@@ -116,15 +116,14 @@ CreateDirectoryW (
                                    (lpSecurityAttributes ? lpSecurityAttributes->lpSecurityDescriptor : NULL));
 
         Status = NtCreateFile (&DirectoryHandle,
-                               FILE_LIST_DIRECTORY | SYNCHRONIZE |
-                                   FILE_OPEN_FOR_BACKUP_INTENT,
+                               FILE_LIST_DIRECTORY | SYNCHRONIZE,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                NULL,
                                FILE_ATTRIBUTE_NORMAL,
                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                FILE_CREATE,
-                               FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+                               FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT,
                                NULL,
                                0);
 
index f457604..111601a 100644 (file)
@@ -236,9 +236,35 @@ OpenFile(LPCSTR lpFileName,
 
        if (lpReOpenBuff == NULL)
        {
-               return FALSE;
+               return HFILE_ERROR;
+       }
+
+    lpReOpenBuff->cBytes = sizeof(OFSTRUCT);
+    lpReOpenBuff->nErrCode = 0;
+
+       if (uStyle & OF_REOPEN) lpFileName = lpReOpenBuff->szPathName;
+
+       if (!lpFileName)
+       {
+               return HFILE_ERROR;
        }
 
+       if (!GetFullPathNameA(lpFileName,
+                                                 sizeof(lpReOpenBuff->szPathName),
+                                                 lpReOpenBuff->szPathName,
+                                                 NULL))
+       {
+           lpReOpenBuff->nErrCode = GetLastError();
+               return HFILE_ERROR;
+       }
+
+    if (uStyle & OF_PARSE)
+    {
+        lpReOpenBuff->fFixedDisk = (GetDriveTypeA(lpReOpenBuff->szPathName) != DRIVE_REMOVABLE);
+        TRACE("(%s): OF_PARSE, res = '%s'\n", lpFileName, lpReOpenBuff->szPathName);
+        return 0;
+    }
+
        if ((uStyle & OF_CREATE) == OF_CREATE)
        {
                DWORD Sharing;
@@ -280,9 +306,21 @@ OpenFile(LPCSTR lpFileName,
 
        if (Len == 0 || Len > OFS_MAXPATHNAME)
        {
+               lpReOpenBuff->nErrCode = GetLastError();
                return (HFILE)INVALID_HANDLE_VALUE;
        }
 
+    if (uStyle & OF_DELETE)
+    {
+        if (!DeleteFileW(PathNameW))
+               {
+                       lpReOpenBuff->nErrCode = GetLastError();
+                       return HFILE_ERROR;
+               }
+        TRACE("(%s): OF_DELETE return = OK\n", lpFileName);
+        return TRUE;
+    }
+
        FileName.Buffer = lpReOpenBuff->szPathName;
        FileName.Length = 0;
        FileName.MaximumLength = OFS_MAXPATHNAME;
@@ -306,14 +344,6 @@ OpenFile(LPCSTR lpFileName,
        // FILE_SHARE_READ
        // FILE_NO_INTERMEDIATE_BUFFERING
 
-       if ((uStyle & OF_PARSE) == OF_PARSE)
-       {
-               RtlFreeHeap(RtlGetProcessHeap(),
-                            0,
-                            FileNameString.Buffer);
-               return (HFILE)NULL;
-       }
-
        ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
        ObjectAttributes.RootDirectory = NULL;
        ObjectAttributes.ObjectName = &FileNameString;
@@ -328,11 +358,9 @@ OpenFile(LPCSTR lpFileName,
                              FILE_SHARE_READ,
                              FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
 
-       RtlFreeHeap(RtlGetProcessHeap(),
-                    0,
-                    FileNameString.Buffer);
+       RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameString.Buffer);
 
-       lpReOpenBuff->nErrCode = (WORD)RtlNtStatusToDosError(errCode);
+       lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
 
        if (!NT_SUCCESS(errCode))
        {
@@ -340,6 +368,12 @@ OpenFile(LPCSTR lpFileName,
                return (HFILE)INVALID_HANDLE_VALUE;
        }
 
+       if (uStyle & OF_EXIST)
+       {
+               NtClose(FileHandle);
+               return TRUE;
+       }
+
        return (HFILE)FileHandle;
 }
 
@@ -1785,4 +1819,167 @@ OpenFileById(IN HANDLE hFile,
     return INVALID_HANDLE_VALUE;
 }
 
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+ReplaceFileA(
+    LPCSTR  lpReplacedFileName,
+    LPCSTR  lpReplacementFileName,
+    LPCSTR  lpBackupFileName,
+    DWORD   dwReplaceFlags,
+    LPVOID  lpExclude,
+    LPVOID  lpReserved
+    )
+{
+    WCHAR *replacedW, *replacementW, *backupW = NULL;
+    BOOL ret;
+
+    /* This function only makes sense when the first two parameters are defined */
+    if (!lpReplacedFileName || !(replacedW = FilenameA2W(lpReplacedFileName, TRUE)))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (!lpReplacementFileName || !(replacementW = FilenameA2W(lpReplacementFileName, TRUE)))
+    {
+        HeapFree(GetProcessHeap(), 0, replacedW);
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* The backup parameter, however, is optional */
+    if (lpBackupFileName)
+    {
+        if (!(backupW = FilenameA2W(lpBackupFileName, TRUE)))
+        {
+            HeapFree(GetProcessHeap(), 0, replacedW);
+            HeapFree(GetProcessHeap(), 0, replacementW);
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return FALSE;
+        }
+    }
+
+    ret = ReplaceFileW(replacedW, replacementW, backupW, dwReplaceFlags, lpExclude, lpReserved);
+    HeapFree(GetProcessHeap(), 0, replacedW);
+    HeapFree(GetProcessHeap(), 0, replacementW);
+    HeapFree(GetProcessHeap(), 0, backupW);
+
+    return ret;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+WINAPI
+ReplaceFileW(
+    LPCWSTR lpReplacedFileName,
+    LPCWSTR lpReplacementFileName,
+    LPCWSTR lpBackupFileName,
+    DWORD   dwReplaceFlags,
+    LPVOID  lpExclude,
+    LPVOID  lpReserved
+    )
+{
+    HANDLE hReplaced = NULL, hReplacement = NULL, hBackup = NULL;
+    UNICODE_STRING NtReplacedName, NtReplacementName;
+    DWORD Error = ERROR_SUCCESS;
+    NTSTATUS Status;
+    BOOL Ret = FALSE;
+    IO_STATUS_BLOCK IoStatusBlock;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+
+    if (dwReplaceFlags)
+        FIXME("Ignoring flags %x\n", dwReplaceFlags);
+
+    /* First two arguments are mandatory */
+    if (!lpReplacedFileName || !lpReplacementFileName)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Open the "replaced" file for reading and writing */
+    if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &NtReplacedName, NULL, NULL)))
+    {
+        Error = ERROR_PATH_NOT_FOUND;
+        goto Cleanup;
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &NtReplacedName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&hReplaced,
+                        GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+            Error = ERROR_FILE_NOT_FOUND;
+        else
+            Error = ERROR_UNABLE_TO_REMOVE_REPLACED;
+        goto Cleanup;
+    }
+
+    /*
+     * Open the replacement file for reading, writing, and deleting
+     * (writing and deleting are needed when finished)
+     */
+    if (!(RtlDosPathNameToNtPathName_U(lpReplacementFileName, &NtReplacementName, NULL, NULL)))
+    {
+        Error = ERROR_PATH_NOT_FOUND;
+        goto Cleanup;
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &NtReplacementName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&hReplacement,
+                        GENERIC_READ | GENERIC_WRITE | DELETE | WRITE_DAC | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        0,
+                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+
+    if (!NT_SUCCESS(Status))
+    {
+        Error = RtlNtStatusToDosError(Status);
+        goto Cleanup;
+    }
+
+    /* Not success :( */
+    FIXME("ReplaceFileW not implemented, but it is returned TRUE!\n");
+    Ret = TRUE;
+
+    /* Perform resource cleanup */
+Cleanup:
+    if (hBackup) NtClose(hBackup);
+    if (hReplaced) NtClose(hReplaced);
+    if (hReplacement) NtClose(hReplacement);
+
+    RtlFreeUnicodeString(&NtReplacementName);
+    RtlFreeUnicodeString(&NtReplacedName);
+
+    /* If there was an error, set the error code */
+    if(!Ret)
+    {
+        TRACE("ReplaceFileW failed (error=%d)\n", Error);
+        SetLastError(Error);
+    }
+    return Ret;
+}
+
 /* EOF */
index 287d831..ef1b372 100644 (file)
@@ -249,8 +249,8 @@ MoveFileWithProgressW (
        if (dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT)
                return add_boot_rename_entry( lpExistingFileName, lpNewFileName, dwFlags );
 
-    if (dwFlags & MOVEFILE_WRITE_THROUGH)
-        FIXME("MOVEFILE_WRITE_THROUGH unimplemented\n");
+//    if (dwFlags & MOVEFILE_WRITE_THROUGH)
+//        FIXME("MOVEFILE_WRITE_THROUGH unimplemented\n");
 
     if (!lpNewFileName)
         return DeleteFileW(lpExistingFileName);
@@ -272,31 +272,37 @@ MoveFileWithProgressW (
                                NULL,
                                NULL);
 
-    errCode = NtOpenFile(&hNewFile, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatusBlock, 0,
-                         FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
+    errCode = NtOpenFile( &hNewFile,
+                          GENERIC_READ | GENERIC_WRITE,
+                          &ObjectAttributes,
+                          &IoStatusBlock,
+                          0,
+                          FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
+                          ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0) );
 
-       if (NT_SUCCESS(errCode)) /* Destination exists */
-       {
+    if (NT_SUCCESS(errCode)) /* Destination exists */
+    {
         NtClose(hNewFile);
 
         if (!(dwFlags & MOVEFILE_REPLACE_EXISTING))
         {
                        SetLastError(ERROR_ALREADY_EXISTS);
                        return FALSE;
-               }
-               else if (GetFileAttributesW(lpNewFileName) & FILE_ATTRIBUTE_DIRECTORY)
-               {
-                       SetLastError(ERROR_ACCESS_DENIED);
-                       return FALSE;
-               }
        }
+       else if (GetFileAttributesW(lpNewFileName) & FILE_ATTRIBUTE_DIRECTORY)
+       {
+               SetLastError(ERROR_ACCESS_DENIED);
+               return FALSE;
+       }
+    }
 
        hFile = CreateFileW (lpExistingFileName,
                             GENERIC_ALL,
                             FILE_SHARE_WRITE|FILE_SHARE_READ,
                             NULL,
                             OPEN_EXISTING,
-                            FILE_FLAG_BACKUP_SEMANTICS,
+                            FILE_FLAG_BACKUP_SEMANTICS |
+                            ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_FLAG_WRITE_THROUGH : 0),
                             NULL);
 
        if (hFile == INVALID_HANDLE_VALUE)
index 7061f91..bdafa17 100644 (file)
@@ -81,7 +81,7 @@ InternalOpenDirW(LPCWSTR DirName,
 /*
  * @implemented
  */
-/* Synced to Wine-? */
+/* Synced to Wine-2008/12/28 */
 DWORD WINAPI
 GetLogicalDriveStringsA(DWORD nBufferLength,
                        LPSTR lpBuffer)
@@ -98,8 +98,8 @@ GetLogicalDriveStringsA(DWORD nBufferLength,
      }
 
 
-   if (count * 4 <= nBufferLength)
-     {
+   if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
+
        LPSTR p = lpBuffer;
 
        for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
@@ -111,7 +111,7 @@ GetLogicalDriveStringsA(DWORD nBufferLength,
             *p++ = '\0';
          }
        *p = '\0';
-     }
+
     return (count * 4);
 }
 
@@ -119,7 +119,7 @@ GetLogicalDriveStringsA(DWORD nBufferLength,
 /*
  * @implemented
  */
-/* Synced to Wine-? */
+/* Synced to Wine-2008/12/28 */
 DWORD WINAPI
 GetLogicalDriveStringsW(DWORD nBufferLength,
                        LPWSTR lpBuffer)
@@ -135,19 +135,19 @@ GetLogicalDriveStringsW(DWORD nBufferLength,
           count++;
      }
 
-    if (count * 4 <=  nBufferLength)
-    {
-        LPWSTR p = lpBuffer;
-        for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
-            if (dwDriveMap & (1<<drive))
-            {
-                *p++ = (WCHAR)('A' + drive);
-                *p++ = (WCHAR)':';
-                *p++ = (WCHAR)'\\';
-                *p++ = (WCHAR)'\0';
-            }
-        *p = (WCHAR)'\0';
-    }
+    if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
+
+    LPWSTR p = lpBuffer;
+    for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
+        if (dwDriveMap & (1<<drive))
+        {
+            *p++ = (WCHAR)('A' + drive);
+            *p++ = (WCHAR)':';
+            *p++ = (WCHAR)'\\';
+            *p++ = (WCHAR)'\0';
+        }
+    *p = (WCHAR)'\0';
+
     return (count * 4);
 }
 
@@ -872,6 +872,12 @@ GetVolumeNameForVolumeMountPointW(
    BOOL Result;
    NTSTATUS Status;
 
+   if (!VolumeMountPoint || !VolumeMountPoint[0])
+   {
+       SetLastError(ERROR_PATH_NOT_FOUND);
+       return FALSE;
+   }
+
    /*
     * First step is to convert the passed volume mount point name to
     * an NT acceptable name.
index 503cca5..bc55db7 100755 (executable)
@@ -13,7 +13,6 @@
 
 /* PSDK/NDK Headers */
 #define WIN32_NO_STATUS
-#define _KERNEL32_
 #include <windows.h>
 #include <tlhelp32.h>
 
index 046685f..89c80be 100644 (file)
@@ -5,6 +5,7 @@
                <include base="kernel32_base">.</include>
                <include base="kernel32_base">include</include>
                <include base="ReactOS">include/reactos/subsys</include>
+               <define name="_KERNEL32_" />
                <define name="_DISABLE_TIDENTS" />
                <define name="_WIN32_WINNT">0x0600</define>
                <define name="__NO_CTYPE_INLINES" />
@@ -64,6 +65,7 @@
                        <file>collation.c</file>
                        <file>casemap.c</file>
                        <file>comm.c</file>
+                       <file>commdcb.c</file>
                        <file>computername.c</file>
                        <file>console.c</file>
                        <file>dllmain.c</file>
index aa0b6e5..48640b1 100644 (file)
@@ -76,20 +76,26 @@ VirtualFreeEx(IN HANDLE hProcess,
 {
     NTSTATUS Status;
 
-    /* Free the memory */
-    Status = NtFreeVirtualMemory(hProcess,
-                                 (PVOID *)&lpAddress,
-                                 &dwSize,
-                                 dwFreeType);
-    if (!NT_SUCCESS(Status))
+    if (dwSize == 0 || !(dwFreeType & MEM_RELEASE))
     {
-        /* We failed */
-        SetLastErrorByStatus(Status);
-        return FALSE;
+        /* Free the memory */
+        Status = NtFreeVirtualMemory(hProcess,
+                                     &lpAddress,
+                                     &dwSize,
+                                     dwFreeType);
+        if (!NT_SUCCESS(Status))
+        {
+            /* We failed */
+            SetLastErrorByStatus(Status);
+            return FALSE;
+        }
+
+        /* Return success */
+        return TRUE;
     }
 
-    /* Return success */
-    return TRUE;
+    SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
+    return FALSE;
 }
 
 /*
@@ -217,7 +223,7 @@ VirtualQueryEx(IN HANDLE hProcess,
                                   (LPVOID)lpAddress,
                                   MemoryBasicInformation,
                                   lpBuffer,
-                                  sizeof(MEMORY_BASIC_INFORMATION),
+                                  dwLength,
                                   &ResultLength);
     if (!NT_SUCCESS(Status))
     {
@@ -257,4 +263,37 @@ VirtualUnlock(IN LPVOID lpAddress,
     return TRUE;
 }
 
+/*
+ * @implemented
+ */
+UINT
+WINAPI
+GetWriteWatch(
+    DWORD  dwFlags,
+    PVOID  lpBaseAddress,
+    SIZE_T dwRegionSize,
+    PVOID *lpAddresses,
+    PULONG_PTR lpdwCount,
+    PULONG lpdwGranularity
+    )
+{
+    NTSTATUS Status;
+
+    Status = NtGetWriteWatch(GetCurrentProcess(),
+                             dwFlags,
+                             lpBaseAddress,
+                             dwRegionSize,
+                             lpAddresses,
+                             lpdwCount,
+                             lpdwGranularity);
+
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastError(RtlNtStatusToDosError(Status));
+        return -1;
+    }
+
+    return 0;
+}
+
 /* EOF */
index 10d7867..8bed46d 100644 (file)
@@ -17,6 +17,7 @@
  *                  ST  (05/04/2005) implemented CommConfigDialog
  *                  DP  (11/06/2005) implemented GetCommConfig
  *                  DP  (12/06/2005) implemented SetCommConfig
+ *                  KJK (26/12/2008) reimplemented BuildCommDCB & BuildCommDCBAndTimeouts elsewhere
  *
  */
 
 #define NDEBUG
 #include <debug.h>
 
-/* BUILDCOMMDCB & BUILDCOMMDCBANDTIMEOUTS */
-
-/* STRINGS */
-static const WCHAR lpszSerialUI[] = { 
+static const WCHAR lpszSerialUI[] = {
    's','e','r','i','a','l','u','i','.','d','l','l',0 };
 
-/* TYPES */
-
-/* Pointer to a callback that handles a particular parameter */
-typedef BOOL (*COMMDCB_PARAM_CALLBACK)(DCB *, COMMTIMEOUTS *, BOOL *, LPWSTR *);
-
-/* Symbolic flag of any length */
-typedef struct _COMMDCB_PARAM_STRFLAG
-{
-    UNICODE_STRING String;
-    ULONG_PTR Value;
-} COMMDCB_PARAM_STRFLAG, *PCOMMDCB_PARAM_STRFLAG;
-
-/* One char long symbolic flag */
-typedef struct _COMMDCB_PARAM_CHARFLAG
-{
-    WCHAR Char;
-    ULONG_PTR Value;
-} COMMDCB_PARAM_CHARFLAG, *PCOMMDCB_PARAM_CHARFLAG;
-
-/* MACROS */
-
-/* Declare a parameter handler */
-#define COMMDCB_PARAM_HANDLER(__P__) \
- BOOL COMMDCB_ ## __P__ ## Param \
- ( \
-     DCB * Dcb, \
-     COMMTIMEOUTS * Timeouts, \
-     BOOL *StopBitsSet, \
-     LPWSTR *StrTail \
- )
-
-/* UTILITIES */
-/*
- Lookup a string flag and return its numerical value. The flags array must be
- sorted - a dichotomycal search is performed
-*/
-static BOOL
-COMMDCB_LookupStrFlag(PUNICODE_STRING Flag,
-                      PCOMMDCB_PARAM_STRFLAG Flags,
-                      int FlagCount,
-                      PULONG_PTR Value)
-{
-    /* Lower and upper bound for dichotomycal search */
-    int nLowerBound = 0;
-    int nUpperBound = FlagCount - 1;
-
-    do
-    {
-        LONG nComparison;
-        /* pick the element in the middle of the area of interest as the pivot */
-        int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
-
-        /* compare the string with the pivot */
-        nComparison = RtlCompareUnicodeString(Flag,
-                                              &Flags[nCurFlag].String,
-                                              TRUE);
-
-        /* string is equal */
-        if(nComparison == 0)
-        {
-            /* return the flag's value */
-            *Value = Flags[nCurFlag].Value;
-
-            /* success */
-            return TRUE;
-        }
-        else if(nComparison < 0)
-        {
-            /*
-             * restrict the search to the first half of the current slice, minus the pivot
-             */
-            nUpperBound = nCurFlag - 1;
-        }
-        else
-        {
-            /*
-             * restrict the search to the second half of the current slice, minus the pivot
-             */
-            nLowerBound = nCurFlag + 1;
-        }
-    } while(nLowerBound <= nUpperBound);
-
-    /* string not found: failure */
-    return FALSE;
-}
-
-/* PARSERS */
-/*
- Find the next character flag and return its numerical value. The flags array
- must be sorted - a dichotomycal search is performed
-*/
-static BOOL
-COMMDCB_ParseCharFlag(LPWSTR *StrTail,
-                      PCOMMDCB_PARAM_CHARFLAG Flags,
-                      int FlagCount,
-                      PULONG_PTR Value)
-{
-    /* Lower and upper bound for dichotomycal search */
-    int nLowerBound = 0;
-    int nUpperBound = FlagCount - 1;
-    /* get the first character as the flag */
-    WCHAR wcFlag = (*StrTail)[0];
-
-    /* premature end of string, or the character is whitespace */
-    if(!wcFlag || iswspace(wcFlag))
-        return FALSE;
-
-    /* uppercase the character for case-insensitive search */
-    wcFlag = towupper(wcFlag);
-
-    /* skip the character flag */
-    (*StrTail)++;
-
-    /* see COMMDCB_LookupStrFlag for a description of the algorithm */
-    do
-    {
-        LONG nComparison;
-        int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
-
-        nComparison = wcFlag - towupper(Flags[nCurFlag].Char);
-
-        if(nComparison == 0)
-        {
-            *Value = Flags[nCurFlag].Value;
-
-            return TRUE;
-        }
-        else if(nComparison < 0)
-        {
-            nUpperBound = nCurFlag - 1;
-        }
-        else
-        {
-            nLowerBound = nCurFlag + 1;
-        }
-    } while(nUpperBound >= nLowerBound);
-
-    /* flag not found: failure */
-    return FALSE;
-}
-
-/*
- Find the next string flag and return its numerical value. The flags array must
- be sorted - a dichotomycal search is performed
-*/
-static BOOL
-COMMDCB_ParseStrFlag(LPWSTR *StrTail,
-                     PCOMMDCB_PARAM_STRFLAG Flags,
-                     int FlagCount,
-                     PULONG_PTR Value)
-{
-    LPWSTR pwcNewTail;
-    UNICODE_STRING wstrFlag;
-
-    /* scan the string until the first space character or the terminating null */
-    for(pwcNewTail = *StrTail;
-        pwcNewTail[0] && !iswspace(pwcNewTail[0]);
-        pwcNewTail++);
-
-    /* string flag empty */
-    if(pwcNewTail == *StrTail)
-        return FALSE;
-
-    /* build the UNICODE_STRING description of the string flag */
-    wstrFlag.Buffer = *StrTail;
-    wstrFlag.Length = (pwcNewTail - *StrTail) * sizeof(WCHAR);
-    wstrFlag.MaximumLength = wstrFlag.Length;
-
-    /* skip the string flag */
-    *StrTail = pwcNewTail;
-
-    /* lookup the string flag's value and return it */
-    return COMMDCB_LookupStrFlag(&wstrFlag, Flags, FlagCount, Value);
-}
-
-/*
- Parse a boolean value in the symbolic form on/off
-*/
-static BOOL
-COMMDCB_ParseBool(LPWSTR *StrTail,
-                  PBOOL Value)
-{
-    BOOL bRetVal;
-    ULONG_PTR nValue;
-    static COMMDCB_PARAM_STRFLAG a_BoolFlags[] = {
-       { RTL_CONSTANT_STRING(L"off"), FALSE },
-       { RTL_CONSTANT_STRING(L"on"),  TRUE }
-    };
-
-    /* try to recognize the next flag as a boolean */
-    bRetVal = COMMDCB_ParseStrFlag(StrTail,
-                                   a_BoolFlags,
-                                   sizeof(a_BoolFlags) / sizeof(a_BoolFlags[0]),
-                                   &nValue);
-
-
-    if(!bRetVal)
-        return FALSE;
-
-    /* success */
-    *Value = (nValue ? TRUE : FALSE);
-    return TRUE;
-}
-
-/*
- Parse a decimal integer
-*/
-static BOOL
-COMMDCB_ParseInt(LPWSTR *StrTail,
-                 DWORD *Value)
-{
-    LPWSTR pwcPrevTail = *StrTail;
-    DWORD nValue = wcstoul(*StrTail, StrTail, 10);
-
-    /* no character was consumed: failure */
-    if(pwcPrevTail == *StrTail)
-        return FALSE;
-
-    /* success */
-    *Value = nValue;
-    return TRUE;
-}
-
-/* PARAMETER HANDLERS */
-/* baud= */
-COMMDCB_PARAM_HANDLER(baud)
-{
-    DWORD nValue;
-
-    (void)Timeouts;
-
-    /* parse the baudrate */
-    if(!COMMDCB_ParseInt(StrTail, &nValue))
-        return FALSE;
-
-    switch(nValue)
-    {
-        /* documented abbreviations */
-        case 11:
-            Dcb->BaudRate = 110;
-            break;
-        case 15:
-            Dcb->BaudRate = 150;
-            break;
-        case 30:
-            Dcb->BaudRate = 300;
-            break;
-        case 60:
-            Dcb->BaudRate = 600;
-            break;
-        case 12:
-            Dcb->BaudRate = 1200;
-            break;
-        case 24:
-            Dcb->BaudRate = 2400;
-            break;
-        case 48:
-            Dcb->BaudRate = 4800;
-            break;
-        case 96:
-            Dcb->BaudRate = 9600;
-            break;
-        case 19:
-            Dcb->BaudRate = 19200;
-            break;
-
-        /* literal value */
-        default:
-            Dcb->BaudRate = nValue;
-            break;
-    }
-
-    /* if the stop bits haven't been specified explicitely */
-    if(!(*StopBitsSet))
-    {
-        /* default the stop bits to 2 for 110 baud */
-        if(Dcb->BaudRate == 110)
-            Dcb->StopBits = TWOSTOPBITS;
-        /* else, default the stop bits to 1 */
-        else
-            Dcb->StopBits = ONESTOPBIT;
-    }
-
-    /* success */
-    return TRUE;
-}
-
-/* data= */
-COMMDCB_PARAM_HANDLER(data)
-{
-    DWORD nValue;
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the data bits */
-    if(!COMMDCB_ParseInt(StrTail, &nValue))
-        return FALSE;
-
-    /* value out of range: failure */
-    if(nValue < 5 || nValue > 8)
-        return FALSE;
-
-    /* success */
-    Dcb->ByteSize = (BYTE)nValue;
-    return TRUE;
-}
-
-/* dtr= */
-COMMDCB_PARAM_HANDLER(dtr)
-{
-    BOOL bRetVal;
-    ULONG_PTR nValue;
-    static COMMDCB_PARAM_STRFLAG a_DTRFlags[] = {
-        { RTL_CONSTANT_STRING(L"hs"),  DTR_CONTROL_HANDSHAKE },
-        { RTL_CONSTANT_STRING(L"off"), DTR_CONTROL_DISABLE },
-        { RTL_CONSTANT_STRING(L"on"),  DTR_CONTROL_ENABLE }
-    };
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    bRetVal = COMMDCB_ParseStrFlag(StrTail,
-                                   a_DTRFlags,
-                                   sizeof(a_DTRFlags) / sizeof(a_DTRFlags[0]),
-                                   &nValue);
-
-    /* failure */
-    if(!bRetVal)
-        return FALSE;
-
-    /* success */
-    Dcb->fDtrControl = nValue;
-    return TRUE;
-}
-
-/* idsr= */
-COMMDCB_PARAM_HANDLER(idsr)
-{
-    BOOL bValue;
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    if(!COMMDCB_ParseBool(StrTail, &bValue))
-       return FALSE;
-
-    /* success */
-    Dcb->fDsrSensitivity = bValue;
-    return TRUE;
-}
-
-/* octs= */
-COMMDCB_PARAM_HANDLER(octs)
-{
-    BOOL bValue;
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    if(!COMMDCB_ParseBool(StrTail, &bValue))
-        return FALSE;
-
-    /* success */
-    Dcb->fOutxCtsFlow = bValue;
-    return TRUE;
-}
-
-/* odsr= */
-COMMDCB_PARAM_HANDLER(odsr)
-{
-    BOOL bValue;
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    if(!COMMDCB_ParseBool(StrTail, &bValue))
-        return FALSE;
-
-    /* success */
-    Dcb->fOutxDsrFlow = bValue;
-    return TRUE;
-}
-
-/* parity= */
-COMMDCB_PARAM_HANDLER(parity)
-{
-    BOOL bRetVal;
-    ULONG_PTR nValue;
-    static COMMDCB_PARAM_CHARFLAG a_ParityFlags[] = {
-        { L'e', EVENPARITY },
-        { L'm', MARKPARITY },
-        { L'n', NOPARITY },
-        { L'o', ODDPARITY },
-        { L's', SPACEPARITY }
-    };
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    bRetVal = COMMDCB_ParseCharFlag(StrTail,
-                                    a_ParityFlags,
-                                    sizeof(a_ParityFlags) / sizeof(a_ParityFlags[0]),
-                                    &nValue);
-
-    /* failure */
-    if(!bRetVal)
-        return FALSE;
-
-    /* success */
-    Dcb->Parity = (BYTE)nValue;
-    return TRUE;
-}
-
-/* rts= */
-COMMDCB_PARAM_HANDLER(rts)
-{
-    DWORD nRetVal;
-    ULONG_PTR nValue;
-    static COMMDCB_PARAM_STRFLAG a_RTSFlags[] = {
-        { RTL_CONSTANT_STRING(L"hs"),  RTS_CONTROL_HANDSHAKE },
-        { RTL_CONSTANT_STRING(L"off"), RTS_CONTROL_DISABLE },
-        { RTL_CONSTANT_STRING(L"on"),  RTS_CONTROL_ENABLE },
-        { RTL_CONSTANT_STRING(L"tg"),  RTS_CONTROL_TOGGLE }
-    };
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    nRetVal = COMMDCB_ParseStrFlag(StrTail,
-                                   a_RTSFlags,
-                                   sizeof(a_RTSFlags) / sizeof(a_RTSFlags[0]),
-                                   &nValue);
-
-    /* failure */
-    if(!nRetVal)
-        return FALSE;
-
-    /* success */
-    Dcb->fRtsControl = nValue;
-    return TRUE;
-}
-
-/* stop= */
-COMMDCB_PARAM_HANDLER(stop)
-{
-    BOOL bRetVal;
-    ULONG_PTR nValue;
-    static COMMDCB_PARAM_STRFLAG a_StopFlags[] = {
-        { RTL_CONSTANT_STRING(L"1"),   ONESTOPBIT },
-        { RTL_CONSTANT_STRING(L"1.5"), ONE5STOPBITS },
-        { RTL_CONSTANT_STRING(L"2"),   TWOSTOPBITS }
-    };
-
-    (void)Timeouts;
-
-    /* parse the flag */
-    bRetVal = COMMDCB_ParseStrFlag(StrTail,
-                                   a_StopFlags,
-                                   sizeof(a_StopFlags) / sizeof(a_StopFlags[0]),
-                                   &nValue);
-
-    /* failure */
-    if(!bRetVal)
-        return FALSE;
-
-    /* tell the baud= handler that the stop bits have been specified explicitely */
-    *StopBitsSet = TRUE;
-
-    /* success */
-    Dcb->StopBits = (BYTE)nValue;
-    return TRUE;
-}
-
-/* to= */
-COMMDCB_PARAM_HANDLER(to)
-{
-    BOOL bValue;
-
-    (void)Dcb;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    if(!COMMDCB_ParseBool(StrTail, &bValue))
-        return FALSE;
-
-    /* for BuildCommDCB(), Timeouts is NULL */
-    if(Timeouts)
-    {
-        /* why? no idea. All values taken from Windows 2000 with experimentation */
-        Timeouts->ReadIntervalTimeout = 0;
-        Timeouts->ReadTotalTimeoutMultiplier = 0;
-        Timeouts->ReadTotalTimeoutConstant = 0;
-        Timeouts->WriteTotalTimeoutMultiplier = 0;
-
-        if(bValue)
-        {
-            /* timeout */
-            Timeouts->WriteTotalTimeoutConstant = 60000;
-        }
-        else
-        {
-            /* no timeout */
-            Timeouts->WriteTotalTimeoutConstant = 0;
-        }
-    }
-
-    /* success */
-    return TRUE;
-}
-
-/* xon= */
-COMMDCB_PARAM_HANDLER(xon)
-{
-    BOOL bValue;
-
-    (void)Timeouts;
-    (void)StopBitsSet;
-
-    /* parse the flag */
-    if(!COMMDCB_ParseBool(StrTail, &bValue))
-        return FALSE;
-
-    if(bValue)
-    {
-        /* XON/XOFF */
-        Dcb->fInX = Dcb->fOutX = TRUE;
-    }
-    else
-    {
-        /* no XON/XOFF */
-        Dcb->fInX = Dcb->fOutX = FALSE;
-    }
-
-    /* success */
-    return TRUE;
-}
-
-/* FUNCTIONS */
-#define COMMDCB_PARAM(__P__) \
- { \
-  RTL_CONSTANT_STRING(L""UNICODIZE(#__P__ )), \
-  (ULONG_PTR)&COMMDCB_ ## __P__ ## Param \
- }
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBAndTimeoutsW(LPCWSTR lpDef,
-                         LPDCB lpDCB,
-                         LPCOMMTIMEOUTS lpCommTimeouts)
-{
-    /* tell the baud= handler that the stop bits should be defaulted */
-    BOOL bStopBitsSet = FALSE;
-
-    /* parameter validation */
-    if(lpDCB->DCBlength != sizeof(DCB))
-        goto InvalidParam;
-
-    /* set defaults */
-    lpDCB->StopBits = ONESTOPBIT;
-
-    /*
-     * The documentation for MODE says that data= defaults to 7, but BuildCommDCB
-     * doesn't seem to set it
-     */
-    /* lpDCB->ByteSize = 7; */
-
-    /* skip COMx[n] */
-    if(lpDef[0] &&
-       towupper(lpDef[0]) == L'C' &&
-       lpDef[1] &&
-       towupper(lpDef[1]) == L'O' &&
-       lpDef[2] &&
-       towupper(lpDef[2]) == L'M')
-    {
-        DWORD nDummy;
-
-        /* skip "COM" */
-        lpDef += 3;
-
-        /* premature end of string */
-        if(!lpDef[0])
-            goto InvalidParam;
-
-        /* skip "x" */
-        if(!COMMDCB_ParseInt((LPWSTR *)&lpDef, &nDummy))
-            goto InvalidParam;
-
-        /* skip ":" */
-        if(lpDef[0] == L':')
-            lpDef++;
-    }
-
-    /* skip leading whitespace */
-    while(lpDef[0] && iswspace(lpDef[0]))
-        lpDef++;
-
-    /* repeat until the end of the string */
-    while(lpDef[0])
-    {
-        static COMMDCB_PARAM_STRFLAG a_Params[] = {
-            COMMDCB_PARAM(baud),
-            COMMDCB_PARAM(data),
-            COMMDCB_PARAM(dtr),
-            COMMDCB_PARAM(idsr),
-            COMMDCB_PARAM(octs),
-            COMMDCB_PARAM(odsr),
-            COMMDCB_PARAM(parity),
-            COMMDCB_PARAM(rts),
-            COMMDCB_PARAM(stop),
-            COMMDCB_PARAM(to),
-            COMMDCB_PARAM(xon)
-        };
-        BOOL bRetVal;
-        COMMDCB_PARAM_CALLBACK pCallback;
-        UNICODE_STRING wstrParam;
-        LPWSTR pwcPrevTail = (LPWSTR)lpDef;
-
-        /* get the parameter */
-        while(lpDef[0] && lpDef[0] != L'=')
-            lpDef++;
-
-        /* premature end of string */
-        if(!lpDef[0])
-            goto InvalidParam;
-
-        /* build the parameter's UNICODE_STRING */
-        wstrParam.Buffer = pwcPrevTail;
-        wstrParam.Length = (lpDef - pwcPrevTail) * sizeof(WCHAR);
-        wstrParam.MaximumLength = wstrParam.Length;
-
-        /* skip the "=" */
-        lpDef++;
-
-        /* lookup the callback for the parameter */
-        bRetVal = COMMDCB_LookupStrFlag(&wstrParam,
-                                        a_Params,
-                                        sizeof(a_Params) / sizeof(a_Params[0]),
-                                        (ULONG_PTR *)&pCallback);
-
-        /* invalid parameter */
-        if(!bRetVal)
-            goto InvalidParam;
-
-        /* call the callback to parse the parameter's argument */
-        if(!pCallback(lpDCB, lpCommTimeouts, &bStopBitsSet, (LPWSTR *)&lpDef))
-            goto InvalidParam;
-
-        /* skip trailing whitespace */
-        while(lpDef[0] && iswspace(lpDef[0]))
-            lpDef++;
-    }
-
-    /* success */
-    return TRUE;
-
-InvalidParam:
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return FALSE;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBAndTimeoutsA(LPCSTR lpDef,
-                         LPDCB lpDCB,
-                         LPCOMMTIMEOUTS lpCommTimeouts)
-{
-    NTSTATUS Status;
-    BOOL bRetVal;
-    ANSI_STRING strDef;
-    UNICODE_STRING wstrDef;
-
-    RtlInitAnsiString(&strDef, (LPSTR)lpDef);
-
-    Status = RtlAnsiStringToUnicodeString(&wstrDef, &strDef, TRUE);
-
-    if(!NT_SUCCESS(Status))
-    {
-        SetLastErrorByStatus(Status);
-        return FALSE;
-    }
-
-    bRetVal = BuildCommDCBAndTimeoutsW(wstrDef.Buffer, lpDCB, lpCommTimeouts);
-
-    RtlFreeUnicodeString(&wstrDef);
-
-    return bRetVal;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB)
-{
-    return BuildCommDCBAndTimeoutsA(lpDef, lpDCB, NULL);
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB)
-{
-    return BuildCommDCBAndTimeoutsW(lpDef, lpDCB, NULL);
-}
-
-
 /*
  * @implemented
  */
@@ -905,7 +179,7 @@ CommConfigDialogW(LPCWSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC)
        result = drvCommDlgW(lpszName, hWnd, lpCC);
        SetLastError(result);
        FreeLibrary(hSerialuiDll);
-       
+
        return (result == ERROR_SUCCESS ? TRUE : FALSE);
 }
 
@@ -976,7 +250,7 @@ GetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize)
                return FALSE;
        }
 
-       if( (NULL == lpdwSize) 
+       if( (NULL == lpdwSize)
                || (NULL == lpCC) ) {
                        DPRINT("GetCommConfig() - invalid parameter\n");
                        SetLastError(ERROR_INVALID_PARAMETER);
diff --git a/reactos/dll/win32/kernel32/misc/commdcb.c b/reactos/dll/win32/kernel32/misc/commdcb.c
new file mode 100644 (file)
index 0000000..8de2bf2
--- /dev/null
@@ -0,0 +1,673 @@
+/*
+       Copyright (c) 2008 KJK::Hyperion
+
+       Permission is hereby granted, free of charge, to any person obtaining a
+       copy of this software and associated documentation files (the "Software"),
+       to deal in the Software without restriction, including without limitation
+       the rights to use, copy, modify, merge, publish, distribute, sublicense,
+       and/or sell copies of the Software, and to permit persons to whom the
+       Software is furnished to do so, subject to the following conditions:
+
+       The above copyright notice and this permission notice shall be included in
+       all copies or substantial portions of the Software.
+
+       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+       IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+       FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+       AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+       LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+       FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+       DEALINGS IN THE SOFTWARE.
+*/
+
+/* Parses a mode string for a serial port, in the same syntax as the mode.com command */
+
+#if defined(__REACTOS__) && defined(_KERNEL32_)
+#include <k32.h>
+
+#define DCB_BuildCommDCBA            BuildCommDCBA
+#define DCB_BuildCommDCBAndTimeoutsA BuildCommDCBAndTimeoutsA
+#define DCB_BuildCommDCBW            BuildCommDCBW
+#define DCB_BuildCommDCBAndTimeoutsW BuildCommDCBAndTimeoutsW
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+static
+void DCB_SkipSpace(const char ** ppTail)
+{
+       while(**ppTail && isspace(**ppTail))
+               ++ *ppTail;
+}
+
+static
+size_t DCB_SkipNonSpace(const char ** ppTail)
+{
+       const char * pOriginal = *ppTail;
+
+       while(**ppTail && !isspace(**ppTail))
+               ++ *ppTail;
+
+       return *ppTail - pOriginal;
+}
+
+static
+BOOL DCB_SetBaudRate(unsigned long baudRate, LPDCB lpDCB)
+{
+       switch(baudRate)
+       {
+       case 11: lpDCB->BaudRate = 110; break;
+       case 15: lpDCB->BaudRate = 150; break;
+       case 30: lpDCB->BaudRate = 300; break;
+       case 60: lpDCB->BaudRate = 600; break;
+       case 12: lpDCB->BaudRate = 1200; break;
+       case 24: lpDCB->BaudRate = 2400; break;
+       case 48: lpDCB->BaudRate = 4800; break;
+       case 96: lpDCB->BaudRate = 9600; break;
+       case 19: lpDCB->BaudRate = 19200; break;
+       default: lpDCB->BaudRate = baudRate; break;
+       }
+
+       return TRUE;
+}
+
+static
+BYTE DCB_SetParity(char parity, LPDCB lpDCB)
+{
+       switch(parity)
+       {
+       case 'N':
+       case 'n':
+               lpDCB->Parity = 0;
+               break;
+
+       case 'O':
+       case 'o':
+               lpDCB->Parity = 1;
+               break;
+
+       case 'E':
+       case 'e':
+               lpDCB->Parity = 2;
+               break;
+
+       case 'M':
+       case 'm':
+               lpDCB->Parity = 3;
+               break;
+
+       case 'S':
+       case 's':
+               lpDCB->Parity = 4;
+               break;
+
+       default:
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static
+BYTE DCB_SetDataBits(unsigned long dataBits, LPDCB lpDCB)
+{
+       BOOL bRet;
+
+       bRet = dataBits >= 5 && dataBits <= 8;
+
+       if(!bRet)
+               return bRet;
+
+       lpDCB->ByteSize = (BYTE)dataBits;
+       return bRet;
+}
+
+static
+BOOL DCB_ParseOldSeparator(const char ** ppTail)
+{
+       BOOL bRet;
+
+       bRet = **ppTail == 0;
+
+       if(bRet)
+               return bRet;
+
+       bRet = **ppTail == ',';
+
+       if(bRet)
+       {
+               ++ *ppTail;
+               return bRet;
+       }
+
+       return bRet;
+}
+
+static
+unsigned long DCB_ParseOldNumber(const char ** ppTail, unsigned long nDefault)
+{
+       char * pNumTail;
+       unsigned long number;
+
+       DCB_SkipSpace(ppTail);
+
+       if(!isdigit(**ppTail))
+               return nDefault;
+
+       number = strtoul(*ppTail, &pNumTail, 10);
+       *ppTail = pNumTail;
+
+       DCB_SkipSpace(ppTail);
+       return number;
+}
+
+static
+char DCB_ParseOldCharacter(const char ** ppTail, char cDefault)
+{
+       char character;
+
+       DCB_SkipSpace(ppTail);
+
+       if(**ppTail == 0 || **ppTail == ',')
+               return cDefault;
+
+       character = **ppTail;
+       ++ *ppTail;
+
+       DCB_SkipSpace(ppTail);
+       return character;
+}
+
+static
+const char * DCB_ParseOldString(const char ** ppTail, const char * pDefault, size_t * pLength)
+{
+       const char * string;
+
+       DCB_SkipSpace(ppTail);
+
+       if(**ppTail == 0 || **ppTail == ',')
+               return pDefault;
+
+       string = *ppTail;
+
+       *pLength = 0;
+
+       while(**ppTail != 0 && **ppTail != ',' && !isspace(**ppTail))
+       {
+               ++ *ppTail;
+               ++ *pLength;
+       }
+
+       DCB_SkipSpace(ppTail);
+       return string;
+}
+
+static
+BOOL
+DCB_ParseOldMode(const char * pTail, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
+{
+       BOOL bRet;
+
+       unsigned long baudRate;
+       char parity;
+       unsigned long dataBits;
+       size_t stopBitsLength;
+       const char * stopBits;
+       char retry;
+
+       /* Baud rate */
+       baudRate = DCB_ParseOldNumber(&pTail, 0);
+       bRet = DCB_ParseOldSeparator(&pTail);
+       bRet = bRet && DCB_SetBaudRate(baudRate, lpDCB);
+
+       if(!bRet)
+               return bRet;
+
+       /* Parity */
+       parity = DCB_ParseOldCharacter(&pTail, 'E');
+       bRet = DCB_ParseOldSeparator(&pTail);
+       bRet = bRet && DCB_SetParity(parity, lpDCB);
+
+       if(!bRet)
+               return bRet;
+
+       /* Data bits */
+       dataBits = DCB_ParseOldNumber(&pTail, 7);
+       bRet = DCB_ParseOldSeparator(&pTail);
+       bRet = bRet && DCB_SetDataBits(dataBits, lpDCB);
+
+       if(!bRet)
+               return bRet;
+
+       /* Stop bits */
+       stopBitsLength = 1;
+       stopBits = DCB_ParseOldString(&pTail, baudRate == 110 ? "2" : "1", &stopBitsLength);
+       bRet = DCB_ParseOldSeparator(&pTail);
+
+       if(!bRet)
+               return bRet;
+
+       if(strncmp(stopBits, "1", stopBitsLength) == 0)
+               lpDCB->StopBits = 0;
+       else if(strncmp(stopBits, "1.5", stopBitsLength) == 0)
+               lpDCB->StopBits = 1;
+       else if(strncmp(stopBits, "2", stopBitsLength) == 0)
+               lpDCB->StopBits = 2;
+       else
+               return FALSE;
+
+       /* Retry */
+       retry = DCB_ParseOldCharacter(&pTail, 0);
+       bRet = *pTail == 0;
+
+       if(!bRet)
+               return bRet;
+
+       switch(retry)
+       {
+       case 0:
+               lpDCB->fInX = FALSE;
+               lpDCB->fOutX = FALSE;
+               lpDCB->fOutxCtsFlow = FALSE;
+               lpDCB->fOutxDsrFlow = FALSE;
+               lpDCB->fDtrControl = DTR_CONTROL_ENABLE;
+               lpDCB->fRtsControl = RTS_CONTROL_ENABLE;
+               break;
+
+       case 'p':
+       case 'P':
+               lpDCB->fInX = FALSE;
+               lpDCB->fOutX = FALSE;
+               lpDCB->fOutxCtsFlow = TRUE;
+               lpDCB->fOutxDsrFlow = TRUE;
+               lpDCB->fDtrControl = DTR_CONTROL_HANDSHAKE;
+               lpDCB->fRtsControl = RTS_CONTROL_HANDSHAKE;
+               break;
+
+       case 'x':
+       case 'X':
+               lpDCB->fInX = TRUE;
+               lpDCB->fOutX = TRUE;
+               lpDCB->fOutxCtsFlow = FALSE;
+               lpDCB->fOutxDsrFlow = FALSE;
+               lpDCB->fDtrControl = DTR_CONTROL_ENABLE;
+               lpDCB->fRtsControl = RTS_CONTROL_ENABLE;
+               break;
+
+       default:
+               return FALSE;
+       }
+
+       return bRet;
+}
+
+static
+BOOL DCB_ParseNewNumber(const char * pString, size_t cchString, unsigned long * pNumber)
+{
+       BOOL bRet;
+       char * pStringEnd;
+       unsigned long number;
+
+       bRet = cchString > 0;
+
+       if(!bRet)
+               return bRet;
+
+       number = strtoul(pString, &pStringEnd, 10);
+
+       bRet = pStringEnd - pString == cchString;
+
+       if(!bRet)
+               return bRet;
+
+       *pNumber = number;
+       return bRet;
+}
+
+static
+BOOL DCB_ParseNewBoolean(const char * pString, size_t cchString, BOOL * pBoolean)
+{
+       BOOL bRet;
+
+       bRet = _strnicmp(pString, "on", cchString) == 0;
+
+       if(bRet)
+       {
+               *pBoolean = bRet;
+               return bRet;
+       }
+
+       bRet = _strnicmp(pString, "off", cchString) == 0;
+
+       if(bRet)
+       {
+               *pBoolean = !bRet;
+               return bRet;
+       }
+
+       return bRet;
+}
+
+static
+BOOL
+DCB_ParseNewMode(const char * pTail, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
+{
+       BOOL bRet;
+       BOOL stopBitsSet = FALSE;
+
+       lpDCB->StopBits = 0;
+
+       while(*pTail)
+       {
+               const char * pArg;
+               size_t cchArg;
+               size_t cchArgName;
+               size_t cchArgValue;
+               const char * pArgName;
+               const char * pArgValue;
+               unsigned long nArgValue;
+               BOOL fArgValue;
+
+               pArg = pTail;
+               cchArg = DCB_SkipNonSpace(&pTail);
+               DCB_SkipSpace(&pTail);
+
+               for(cchArgName = 0; cchArgName < cchArg; ++ cchArgName)
+               {
+                       if(pArg[cchArgName] == '=')
+                               break;
+               }
+
+               bRet = cchArgName < cchArg;
+
+               if(!bRet)
+                       return bRet;
+
+               cchArgValue = cchArg - cchArgName - 1;
+               pArgName = pArg;
+               pArgValue = pArg + cchArgName + 1;
+
+               if(_strnicmp(pArgName, "baud", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewNumber(pArgValue, cchArgValue, &nArgValue);
+                       bRet = bRet && DCB_SetBaudRate(nArgValue, lpDCB);
+
+                       if(bRet)
+                       {
+                               if(lpDCB->BaudRate == 110 && !stopBitsSet)
+                                       lpDCB->StopBits = 2;
+                               else
+                                       lpDCB->StopBits = 0;
+                       }
+               }
+               else if(_strnicmp(pArgName, "parity", cchArgName) == 0)
+               {
+                       bRet = cchArgValue == 1;
+                       bRet = bRet && DCB_SetParity(pArgValue[0], lpDCB);
+               }
+               else if(_strnicmp(pArgName, "data", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewNumber(pArgValue, cchArgValue, &nArgValue);
+                       bRet = bRet && DCB_SetDataBits(nArgValue, lpDCB);
+               }
+               else if(_strnicmp(pArgName, "stop", cchArgName) == 0)
+               {
+                       stopBitsSet = TRUE;
+
+                       if(strncmp(pArgValue, "1", cchArgValue) == 0)
+                               lpDCB->StopBits = 0;
+                       else if(strncmp(pArgValue, "1.5", cchArgValue) == 0)
+                               lpDCB->StopBits = 1;
+                       else if(strncmp(pArgValue, "2", cchArgValue) == 0)
+                               lpDCB->StopBits = 2;
+                       else
+                               bRet = FALSE;
+               }
+               else if(_strnicmp(pArgName, "to", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
+
+                       if(bRet)
+                       {
+                               if(lpCommTimeouts)
+                               {
+                                       memset(lpCommTimeouts, 0, sizeof(*lpCommTimeouts));
+
+                                       if(fArgValue)
+                                               lpCommTimeouts->WriteTotalTimeoutConstant = 60000;
+                               }
+                       }
+               }
+               else if(_strnicmp(pArgName, "xon", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
+
+                       if(bRet)
+                       {
+                               lpDCB->fInX = !!fArgValue;
+                               lpDCB->fOutX = !!fArgValue;
+                       }
+               }
+               else if(_strnicmp(pArgName, "odsr", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
+
+                       if(bRet)
+                               lpDCB->fOutxDsrFlow = !!fArgValue;
+               }
+               else if(_strnicmp(pArgName, "octs", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
+
+                       if(bRet)
+                               lpDCB->fOutxCtsFlow = !!fArgValue;
+               }
+               else if(_strnicmp(pArgName, "dtr", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
+
+                       if(bRet)
+                       {
+                               if(fArgValue)
+                                       lpDCB->fDtrControl = DTR_CONTROL_ENABLE;
+                               else
+                                       lpDCB->fDtrControl = DTR_CONTROL_DISABLE;
+                       }
+                       else
+                       {
+                               bRet = _strnicmp(pArgValue, "hs", cchArgValue) == 0;
+
+                               if(bRet)
+                                       lpDCB->fDtrControl = DTR_CONTROL_HANDSHAKE;
+                       }
+               }
+               else if(_strnicmp(pArgName, "rts", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
+
+                       if(bRet)
+                       {
+                               if(fArgValue)
+                                       lpDCB->fRtsControl = RTS_CONTROL_ENABLE;
+                               else
+                                       lpDCB->fRtsControl = RTS_CONTROL_DISABLE;
+                       }
+                       else
+                       {
+                               bRet = _strnicmp(pArgValue, "hs", cchArgValue) == 0;
+
+                               if(bRet)
+                                       lpDCB->fRtsControl = RTS_CONTROL_HANDSHAKE;
+                               else
+                               {
+                                       bRet = _strnicmp(pArgValue, "tg", cchArgValue) == 0;
+
+                                       if(bRet)
+                                               lpDCB->fRtsControl = RTS_CONTROL_TOGGLE;
+                               }
+                       }
+               }
+               else if(_strnicmp(pArgName, "idsr", cchArgName) == 0)
+               {
+                       bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
+
+                       if(bRet)
+                               lpDCB->fDsrSensitivity = !!fArgValue;
+               }
+               else
+                       bRet = FALSE;
+
+               if(!bRet)
+                       return bRet;
+       }
+
+       return TRUE;
+}
+
+static
+BOOL
+DCB_ValidPort(unsigned long nPort)
+{
+       BOOL bRet;
+       DWORD dwErr;
+       WCHAR szPort[3 + 10 + 1];
+
+       dwErr = GetLastError();
+
+       _snwprintf(szPort, sizeof(szPort) / sizeof(szPort[0]), L"COM%lu", nPort);
+
+       bRet = QueryDosDeviceW(szPort, NULL, 0) == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER;
+
+       if(!bRet)
+               dwErr = ERROR_INVALID_PARAMETER;
+
+       SetLastError(dwErr);
+       return bRet;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+DCB_BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
+{
+       BOOL bRet;
+       LPCSTR pTail = lpDef;
+       DCB DCBCopy;
+
+       if(_strnicmp(pTail, "COM", 3) == 0)
+       {
+               char * pNumTail;
+               unsigned long nPort;
+
+               pTail += 3;
+
+               if(!isdigit(*pTail))
+                       return FALSE;
+
+               nPort = strtoul(pTail, &pNumTail, 10);
+               pTail = pNumTail;
+
+               bRet = DCB_ValidPort(nPort);
+
+               if(!bRet)
+                       return bRet;
+
+               DCB_SkipSpace(&pTail);
+
+               if(*pTail == ':')
+                       ++ pTail;
+
+               DCB_SkipSpace(&pTail);
+       }
+
+       DCBCopy = *lpDCB;
+
+       if(isdigit(*pTail))
+               bRet = DCB_ParseOldMode(pTail, &DCBCopy, lpCommTimeouts);
+       else
+               bRet = DCB_ParseNewMode(pTail, &DCBCopy, lpCommTimeouts);
+
+       if(!bRet)
+               SetLastError(ERROR_INVALID_PARAMETER);
+       else
+               *lpDCB = DCBCopy;
+
+       return bRet;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+DCB_BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB)
+{
+    return DCB_BuildCommDCBAndTimeoutsA(lpDef, lpDCB, NULL);
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+DCB_BuildCommDCBAndTimeoutsW(LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
+{
+       BOOL bRet;
+       HANDLE hHeap;
+       BOOL bInvalidChars;
+       LPSTR pszAscii;
+       int cchAscii;
+       DWORD dwErr;
+
+       dwErr = ERROR_INVALID_PARAMETER;
+       cchAscii = WideCharToMultiByte(20127, 0, lpDef, -1, NULL, 0, NULL, NULL);
+
+       bRet = cchAscii > 0;
+
+       if(bRet)
+       {
+               hHeap = GetProcessHeap();
+               pszAscii = HeapAlloc(hHeap, 0, cchAscii);
+
+               bRet = pszAscii != NULL;
+
+               if(bRet)
+               {
+                       bInvalidChars = FALSE;
+                       cchAscii = WideCharToMultiByte(20127, 0, lpDef, -1, pszAscii, cchAscii, NULL, &bInvalidChars);
+
+                       bRet = cchAscii > 0 && !bInvalidChars;
+
+                       if(bRet)
+                               bRet = DCB_BuildCommDCBAndTimeoutsA(pszAscii, lpDCB, lpCommTimeouts);
+
+                       HeapFree(hHeap, 0, pszAscii);
+               }
+               else
+                       dwErr = ERROR_OUTOFMEMORY;
+       }
+
+       if(!bRet)
+               SetLastError(dwErr);
+
+       return bRet;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+DCB_BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB)
+{
+    return DCB_BuildCommDCBAndTimeoutsW(lpDef, lpDCB, NULL);
+}
+
+/* EOF */
index b185dda..86afb7e 100644 (file)
@@ -379,7 +379,7 @@ IntMultiByteToWideCharUTF8(DWORD Flags,
         WideChar = Char & UTF8Mask[Length];
         while (Length && MultiByteString < MbsEnd)
         {
-            WideChar = (WideChar << 6) | *MultiByteString++;
+            WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
             Length--;
         }
         *WideCharString++ = WideChar;
index ea3e08d..5180a94 100644 (file)
@@ -88,17 +88,18 @@ static __inline WCHAR *memchrW( const WCHAR *ptr, WCHAR ch, size_t n )
     const WCHAR *end;
     for (end = ptr + n; ptr < end; ptr++)
         if (*ptr == ch)
-            return (WCHAR *)ptr;
+            return (WCHAR *)(ULONG_PTR)ptr;
     return NULL;
 }
 
 static __inline WCHAR *memrchrW( const WCHAR *ptr, WCHAR ch, size_t n )
 {
-    const WCHAR *end, *ret = NULL;
+    const WCHAR *end;
+    WCHAR *ret = NULL;
     for (end = ptr + n; ptr < end; ptr++)
         if (*ptr == ch)
-            ret = ptr;
-    return (WCHAR *)ret;
+            ret = (WCHAR *)(ULONG_PTR)ptr;
+    return ret;
 }
 
 /***********************************************************************
@@ -139,7 +140,7 @@ static __inline void PROFILE_ByteSwapShortBuffer(WCHAR * buffer, int len)
 static __inline void PROFILE_WriteMarker(HANDLE hFile, ENCODING encoding)
 {
     DWORD dwBytesWritten;
-    DWORD bom;
+    WCHAR bom;
     switch (encoding)
     {
     case ENCODING_ANSI:
@@ -283,12 +284,8 @@ static void PROFILE_Free( PROFILESECTION *section )
 /* returns 1 if a character white space else 0 */
 static __inline int PROFILE_isspaceW(WCHAR c)
 {
-   if (iswspace(c))
-       return 1;
-   if (c=='\r' || c==0x1a)
-       return 1;
-   /* CR and ^Z (DOS EOF) are spaces too  (found on CD-ROMs) */
-   return 0;
+    /* ^Z (DOS EOF) is a space too  (found on CD-ROMs) */
+    return isspace(c) || c == 0x1a;
 }
 
 
@@ -325,7 +322,7 @@ static __inline ENCODING PROFILE_DetectTextEncoding(const void * buffer, int * l
  */
 static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
 {
-    void *pBuffer;
+    void *buffer_base, *pBuffer;
     WCHAR * szFile;
     const WCHAR *szLineStart, *szLineEnd;
     const WCHAR *szValueStart, *szEnd, *next_line;
@@ -341,22 +338,22 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
     if (dwFileSize == INVALID_FILE_SIZE)
         return NULL;
 
-    pBuffer = HeapAlloc(GetProcessHeap(), 0 , dwFileSize);
-    if (!pBuffer)
+    buffer_base = HeapAlloc(GetProcessHeap(), 0 , dwFileSize);
+    if (!buffer_base)
         return NULL;
 
-    if (!ReadFile(hFile, pBuffer, dwFileSize, &dwFileSize, NULL))
+    if (!ReadFile(hFile, buffer_base, dwFileSize, &dwFileSize, NULL))
     {
-        HeapFree(GetProcessHeap(), 0, pBuffer);
+        HeapFree(GetProcessHeap(), 0, buffer_base);
         DPRINT("Error %ld reading file\n", GetLastError());
         return NULL;
     }
 
     len = dwFileSize;
-    *pEncoding = PROFILE_DetectTextEncoding(pBuffer, &len);
+    *pEncoding = PROFILE_DetectTextEncoding(buffer_base, &len);
     /* len is set to the number of bytes in the character marker.
      * we want to skip these bytes */
-    pBuffer = (char *)pBuffer + len;
+    pBuffer = (char *)buffer_base + len;
     dwFileSize -= len;
     switch (*pEncoding)
     {
@@ -367,7 +364,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
         szFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
         if (!szFile)
         {
-            HeapFree(GetProcessHeap(), 0, pBuffer);
+            HeapFree(GetProcessHeap(), 0, buffer_base);
             return NULL;
         }
         MultiByteToWideChar(CP_ACP, 0, (char *)pBuffer, dwFileSize, szFile, len);
@@ -381,7 +378,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
         szFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
         if (!szFile)
         {
-            HeapFree(GetProcessHeap(), 0, pBuffer);
+            HeapFree(GetProcessHeap(), 0, buffer_base);
             return NULL;
         }
         MultiByteToWideChar(CP_UTF8, 0, (char *)pBuffer, dwFileSize, szFile, len);
@@ -390,20 +387,20 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
 
     case ENCODING_UTF16LE:
         DPRINT("UTF16 Little Endian encoding\n");
-        szFile = (WCHAR *)pBuffer + 1;
+        szFile = (WCHAR *)pBuffer;// + 1;
         szEnd = (WCHAR *)((char *)pBuffer + dwFileSize);
         break;
 
     case ENCODING_UTF16BE:
         DPRINT("UTF16 Big Endian encoding\n");
-        szFile = (WCHAR *)pBuffer + 1;
+        szFile = (WCHAR *)pBuffer;// + 1;
         szEnd = (WCHAR *)((char *)pBuffer + dwFileSize);
         PROFILE_ByteSwapShortBuffer(szFile, dwFileSize / sizeof(WCHAR));
         break;
 
     default:
         DPRINT("encoding type %d not implemented\n", *pEncoding);
-        HeapFree(GetProcessHeap(), 0, pBuffer);
+        HeapFree(GetProcessHeap(), 0, buffer_base);
         return NULL;
     }
 
@@ -412,7 +409,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
     {
         if (szFile != pBuffer)
             HeapFree(GetProcessHeap(), 0, szFile);
-        HeapFree(GetProcessHeap(), 0, pBuffer);
+        HeapFree(GetProcessHeap(), 0, buffer_base);
         return NULL;
     }
     first_section->name[0] = 0;
@@ -427,6 +424,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
     {
         szLineStart = next_line;
         next_line = memchrW(szLineStart, '\n', szEnd - szLineStart);
+        if (!next_line) next_line = memchrW(szLineStart, '\r', szEnd - szLineStart);
         if (!next_line) next_line = szEnd;
         else next_line++;
         szLineEnd = next_line;
@@ -435,7 +433,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
 
         /* get rid of white space */
         while (szLineStart < szLineEnd && PROFILE_isspaceW(*szLineStart)) szLineStart++;
-        while ((szLineEnd > szLineStart) && ((szLineEnd[-1] == '\n') || (PROFILE_isspaceW(szLineEnd[-1]) && szLineEnd[-1] != ' '))) szLineEnd--;
+        while ((szLineEnd > szLineStart) && PROFILE_isspaceW(szLineEnd[-1])) szLineEnd--;
 
         if (szLineStart >= szLineEnd)
             continue;
@@ -510,7 +508,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
     }
     if (szFile != pBuffer)
         HeapFree(GetProcessHeap(), 0, szFile);
-    HeapFree(GetProcessHeap(), 0, pBuffer);
+    HeapFree(GetProcessHeap(), 0, buffer_base);
     return first_section;
 }
 
@@ -688,7 +686,8 @@ static BOOL PROFILE_FlushFile(void)
 
     if (!CurProfile->changed) return TRUE;
 
-    hFile = CreateFileW(CurProfile->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    hFile = CreateFileW(CurProfile->filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+                        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 
     if (hFile == INVALID_HANDLE_VALUE)
     {
@@ -724,12 +723,33 @@ static void PROFILE_ReleaseFile(void)
 }
 
 
+/***********************************************************************
+ *
+ * Compares a file time with the current time. If the file time is
+ * at least 2.1 seconds in the past, return true.
+ *
+ * Intended as cache safety measure: The time resolution on FAT is
+ * two seconds, so files that are not at least two seconds old might
+ * keep their time even on modification, so don't cache them.
+ */
+static BOOL is_not_current(FILETIME * ft)
+{
+    FILETIME Now;
+    LONGLONG ftll, nowll;
+    GetSystemTimeAsFileTime(&Now);
+    ftll = ((LONGLONG)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
+    nowll = ((LONGLONG)Now.dwHighDateTime << 32) + Now.dwLowDateTime;
+    DPRINT("%08x;%08x\n",(unsigned)ftll+21000000,(unsigned)nowll);
+    return ftll + 21000000 < nowll;
+}
+
+
 /***********************************************************************
  *           PROFILE_Open
  *
  * Open a profile file, checking the cached file first.
  */
-static BOOL PROFILE_Open( LPCWSTR filename )
+static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access )
 {
     WCHAR windirW[MAX_PATH];
     WCHAR buffer[MAX_PATH];
@@ -775,7 +795,9 @@ static BOOL PROFILE_Open( LPCWSTR filename )
 
     DPRINT("path: %S\n", buffer);
 
-    hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    hFile = CreateFileW(buffer, GENERIC_READ | (write_access ? GENERIC_WRITE : 0),
+                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
     if ((hFile == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_FILE_NOT_FOUND))
     {
@@ -797,21 +819,21 @@ static BOOL PROFILE_Open( LPCWSTR filename )
              CurProfile=tempProfile;
           }
           if (hFile != INVALID_HANDLE_VALUE)
+                 {
              GetFileTime(hFile, NULL, NULL, &LastWriteTime);
-          else
-             LastWriteTime.dwHighDateTime = LastWriteTime.dwLowDateTime = 0;
-          if (memcmp(&CurProfile->LastWriteTime, &LastWriteTime, sizeof(FILETIME)))
-          {
-             DPRINT("(%S): already opened (mru = %d)\n",
-                    buffer, i );
-          }
-          else
-          {
-              DPRINT("(%S): already opened, needs refreshing (mru = %d)\n",
-                     buffer, i );
-          }
-          if (hFile != INVALID_HANDLE_VALUE)
-             CloseHandle(hFile);
+             if (!memcmp( &CurProfile->LastWriteTime, &LastWriteTime, sizeof(FILETIME) ) &&
+                 is_not_current(&LastWriteTime))
+                                DPRINT("(%S): already opened (mru=%d)\n", buffer, i);
+                        else
+                        {
+                 DPRINT("(%S): already opened, needs refreshing (mru=%d)\n", buffer, i);
+                 CurProfile->section = PROFILE_Load(hFile, &CurProfile->encoding);
+                 CurProfile->LastWriteTime = LastWriteTime;
+                        }
+                        CloseHandle(hFile);
+                 }
+          else DPRINT("(%S): already opened (mru = %d)\n", buffer, i );
+
           return TRUE;
        }
     }
@@ -984,15 +1006,15 @@ static INT PROFILE_GetString( LPCWSTR section, LPCWSTR key_name,
     PROFILEKEY *key = NULL;
     static const WCHAR empty_strW[] = { 0 };
 
-    if (!buffer) return 0;
+    if (!buffer || !len) return 0;
 
     if (!def_val) def_val = empty_strW;
     if (key_name)
     {
         if (!key_name[0])
         {
-            /* Win95 returns 0 on keyname "". Tested with Likse32 bon 000227 */
-            return 0;
+            PROFILE_CopyEntry(buffer, def_val, len, TRUE);
+            return wcslen(buffer);
         }
         key = PROFILE_Find( &CurProfile->section, section, key_name, FALSE, FALSE);
         PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
@@ -1112,7 +1134,7 @@ static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
                   BOOL win32 )
 {
     int     ret;
-    LPCWSTR pDefVal = NULL;
+    LPWSTR defval_tmp = NULL;
 
     DPRINT("%S, %S, %S, %p, %u, %S\n",
            section, entry,
@@ -1121,52 +1143,40 @@ static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
     /* strip any trailing ' ' of def_val. */
     if (def_val)
     {
-        LPCWSTR p = &def_val[wcslen(def_val)]; /* even "" works ! */
+        LPCWSTR p = def_val + wcslen(def_val) - 1;
 
-        while (p > def_val)
-        {
+        while (p > def_val && *p == ' ')
             p--;
-            if ((*p) != ' ')
-                break;
-        }
 
-        if (*p == ' ') /* ouch, contained trailing ' ' */
+        if (p >= def_val)
         {
-           int len = (int)(p - def_val);
-           LPWSTR p;
-
-           p = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
-           if(p == NULL)
-           {
-               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               return FALSE;
-           }
-           memcpy(p, def_val, len * sizeof(WCHAR));
-           p[len] = '\0';
-           pDefVal = p;
+           int len = (int)(p - def_val) + 1;
+
+           defval_tmp = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+                  memcpy(defval_tmp, def_val, len * sizeof(WCHAR));
+           defval_tmp[len] = '\0';
+           def_val = defval_tmp;
         }
     }
 
-    if (!pDefVal)
-        pDefVal = (LPCWSTR)def_val;
-
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename )) {
+    if (PROFILE_Open( filename, FALSE )) {
         if (win32 && (section == NULL))
             ret = PROFILE_GetSectionNames(buffer, len);
         else
             /* PROFILE_GetString can handle the 'entry == NULL' case */
-            ret = PROFILE_GetString( section, entry, pDefVal, buffer, len, win32 );
-    } else {
-       lstrcpynW( buffer, pDefVal, len );
+            ret = PROFILE_GetString( section, entry, def_val, buffer, len, win32 );
+    } else if (buffer && def_val) {
+       lstrcpynW( buffer, def_val, len );
        ret = wcslen( buffer );
     }
+       else
+           ret = 0;
 
     RtlLeaveCriticalSection( &PROFILE_CritSect );
 
-    if (pDefVal != def_val) /* allocated */
-        HeapFree(GetProcessHeap(), 0, (void*)pDefVal);
+    HeapFree(GetProcessHeap(), 0, defval_tmp);
 
     DPRINT("returning %S, %d\n", buffer, ret);
 
@@ -1302,7 +1312,7 @@ UINT WINAPI GetPrivateProfileIntW( LPCWSTR section, LPCWSTR entry,
         return (UINT)def_val;
 
     RtlInitUnicodeString( &bufferW, buffer );
-    RtlUnicodeStringToInteger( &bufferW, 10, &result);
+    RtlUnicodeStringToInteger( &bufferW, 0, &result); // 10
     return result;
 }
 
@@ -1350,7 +1360,7 @@ DWORD WINAPI GetPrivateProfileSectionW( LPCWSTR section, LPWSTR buffer,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename ))
+    if (PROFILE_Open( filename, FALSE ))
         ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, TRUE, FALSE);
 
     RtlLeaveCriticalSection( &PROFILE_CritSect );
@@ -1434,12 +1444,12 @@ BOOL WINAPI WritePrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
 
     if (!section && !entry && !string) /* documented "file flush" case */
     {
-        if (!filename || PROFILE_Open( filename ))
+        if (!filename || PROFILE_Open( filename, TRUE ))
         {
             if (CurProfile) PROFILE_ReleaseFile();  /* always return FALSE in this case */
         }
     }
-    else if (PROFILE_Open( filename ))
+    else if (PROFILE_Open( filename, TRUE ))
     {
         if (!section) {
             DPRINT1("(NULL?, %S, %S, %S)?\n",
@@ -1494,12 +1504,12 @@ BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
 
     if (!section && !string)
     {
-        if (!filename || PROFILE_Open( filename ))
+        if (!filename || PROFILE_Open( filename, TRUE ))
         {
             if (CurProfile) PROFILE_ReleaseFile();  /* always return FALSE in this case */
         }
         }
-    else if (PROFILE_Open( filename )) {
+    else if (PROFILE_Open( filename, TRUE )) {
         if (!string) {/* delete the named section*/
             ret = PROFILE_SetString(section,NULL,NULL, FALSE);
             PROFILE_FlushFile();
@@ -1628,7 +1638,7 @@ DWORD WINAPI GetPrivateProfileSectionNamesW( LPWSTR buffer, DWORD size,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename ))
+    if (PROFILE_Open( filename, FALSE ))
         ret = PROFILE_GetSectionNames(buffer, size);
 
     RtlLeaveCriticalSection( &PROFILE_CritSect );
@@ -1685,7 +1695,7 @@ BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename ))
+    if (PROFILE_Open( filename, FALSE ))
     {
         PROFILEKEY *k = PROFILE_Find ( &CurProfile->section, section, key, FALSE, FALSE);
         if (k)
@@ -1814,7 +1824,7 @@ BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename ))
+    if (PROFILE_Open( filename, TRUE ))
     {
         ret = PROFILE_SetString( section, key, outstring, FALSE);
         PROFILE_FlushFile();
index 61cfaf4..aa8bf1f 100644 (file)
@@ -478,24 +478,6 @@ GetNumaProcessorNode(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-UINT
-WINAPI
-GetWriteWatch(
-    DWORD  dwFlags,
-    PVOID  lpBaseAddress,
-    SIZE_T dwRegionSize,
-    PVOID *lpAddresses,
-    PULONG_PTR lpdwCount,
-    PULONG lpdwGranularity
-    )
-{
-    STUB;
-    return 0;
-}
-
 /*
  * @unimplemented
  */
@@ -883,24 +865,6 @@ GetVolumePathNamesForVolumeNameW(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-ReplaceFileW(
-    LPCWSTR lpReplacedFileName,
-    LPCWSTR lpReplacementFileName,
-    LPCWSTR lpBackupFileName,
-    DWORD   dwReplaceFlags,
-    LPVOID  lpExclude,
-    LPVOID  lpReserved
-    )
-{
-    STUB;
-    return 0;
-}
-
 /*
  * @unimplemented
  */
@@ -1042,24 +1006,6 @@ GetVolumePathNamesForVolumeNameA(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-ReplaceFileA(
-    LPCSTR  lpReplacedFileName,
-    LPCSTR  lpReplacementFileName,
-    LPCSTR  lpBackupFileName,
-    DWORD   dwReplaceFlags,
-    LPVOID  lpExclude,
-    LPVOID  lpReserved
-    )
-{
-    STUB;
-    return 0;
-}
-
 /*
  * @unimplemented
  */
index 93ce6f5..32d1d17 100644 (file)
 
 typedef struct __DOSTIME
 {
-  WORD Second:5;
-  WORD Minute:6;
-  WORD Hour:5;
+    WORD Second:5;
+    WORD Minute:6;
+    WORD Hour:5;
 } DOSTIME, *PDOSTIME;
 
 typedef struct __DOSDATE
 {
-  WORD Day:5;
-  WORD Month:4;
-  WORD Year:5;
+    WORD Day:5;
+    WORD Month:4;
+    WORD Year:5;
 } DOSDATE, *PDOSDATE;
 
-#define TICKSPERMIN        600000000
+#define TICKSPERMIN 600000000
 
 #define LL2FILETIME( ll, pft )\
     (pft)->dwLowDateTime = (UINT)(ll); \
@@ -43,15 +43,15 @@ typedef struct __DOSDATE
 
 static const int MonthLengths[2][12] =
 {
-       { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
-       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
 };
 
 /* STATIC FUNTIONS **********************************************************/
 
 static inline int IsLeapYear(int Year)
 {
-       return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
+    return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
 }
 
 /***********************************************************************
@@ -70,8 +70,8 @@ static inline int IsLeapYear(int Year)
  *   1 if date > compareDate
  *  -2 if an error occurs
  */
-static int TIME_DayLightCompareDate( const SYSTEMTIME *date,
-    const SYSTEMTIME *compareDate )
+static int
+TIME_DayLightCompareDate(const SYSTEMTIME *date, const SYSTEMTIME *compareDate)
 {
     int limit_day, dayinsecs;
 
@@ -131,8 +131,9 @@ static int TIME_DayLightCompareDate( const SYSTEMTIME *date,
  *      TIME_ZONE_ID_STANDARD   Current time is standard time
  *      TIME_ZONE_ID_DAYLIGHT   Current time is daylight savings time
  */
-static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
-    FILETIME *lpFileTime, BOOL islocal )
+static
+DWORD
+TIME_CompTimeZoneID( const TIME_ZONE_INFORMATION *pTZinfo, FILETIME *lpFileTime, BOOL islocal )
 {
     int ret;
     BOOL beforeStandardDate, afterDaylightDate;
@@ -141,8 +142,6 @@ static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
     SYSTEMTIME SysTime;
     FILETIME ftTemp;
 
-    ZeroMemory (&SysTime, sizeof (SysTime));
-
     if (pTZinfo->DaylightDate.wMonth != 0)
     {
         /* if year is 0 then date is in day-of-week format, otherwise
@@ -162,7 +161,7 @@ static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
         if (!islocal) {
             FILETIME2LL( lpFileTime, llTime );
             llTime -= ( pTZinfo->Bias + pTZinfo->DaylightBias )
-                * (LONGLONG) TICKSPERMIN;
+                * (LONGLONG)TICKSPERMIN;
             LL2FILETIME( llTime, &ftTemp)
             lpFileTime = &ftTemp;
         }
@@ -178,7 +177,7 @@ static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
 
         if (!islocal) {
             llTime -= ( pTZinfo->StandardBias - pTZinfo->DaylightBias )
-                * (LONGLONG) TICKSPERMIN;
+                * (LONGLONG)TICKSPERMIN;
             LL2FILETIME( llTime, &ftTemp)
             FileTimeToSystemTime(lpFileTime, &SysTime);
         }
@@ -218,11 +217,11 @@ static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
  * RETURNS
  *  TRUE when the time zone bias was calculated.
  */
-static BOOL TIME_GetTimezoneBias( const TIME_ZONE_INFORMATION *pTZinfo,
-    FILETIME *lpFileTime, BOOL islocal, LONG *pBias )
+static BOOL
+TIME_GetTimezoneBias(const TIME_ZONE_INFORMATION *pTZinfo, FILETIME *lpFileTime, BOOL islocal, LONG *pBias)
 {
     LONG bias = pTZinfo->Bias;
-    DWORD tzid = TIME_CompTimeZoneID( pTZinfo, lpFileTime, islocal);
+    DWORD tzid = TIME_CompTimeZoneID(pTZinfo, lpFileTime, islocal);
 
     if( tzid == TIME_ZONE_ID_INVALID)
         return FALSE;
@@ -242,39 +241,34 @@ static BOOL TIME_GetTimezoneBias( const TIME_ZONE_INFORMATION *pTZinfo,
  */
 BOOL
 WINAPI
-FileTimeToDosDateTime(
-                     CONST FILETIME *lpFileTime,
-                     LPWORD lpFatDate,
-                     LPWORD lpFatTime
-                     )
+FileTimeToDosDateTime(CONST FILETIME *lpFileTime,
+                      LPWORD lpFatDate,
+                      LPWORD lpFatTime)
 {
-   PDOSTIME  pdtime=(PDOSTIME) lpFatTime;
-   PDOSDATE  pddate=(PDOSDATE) lpFatDate;
-   SYSTEMTIME SystemTime = { 0, 0, 0, 0, 0, 0, 0, 0 };
+    PDOSTIME  pdtime=(PDOSTIME) lpFatTime;
+    PDOSDATE  pddate=(PDOSDATE) lpFatDate;
+    SYSTEMTIME SystemTime = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
-   if ( lpFileTime == NULL )
-               return FALSE;
+    if (lpFileTime == NULL)
+        return FALSE;
 
-   if ( lpFatDate == NULL )
-           return FALSE;
+    if (lpFatDate == NULL)
+        return FALSE;
 
-   if ( lpFatTime == NULL )
-           return FALSE;
+    if (lpFatTime == NULL)
+        return FALSE;
 
-   FileTimeToSystemTime(
-                    lpFileTime,
-                    &SystemTime
-                    );
+    FileTimeToSystemTime(lpFileTime, &SystemTime);
 
-   pdtime->Second = SystemTime.wSecond / 2;
-   pdtime->Minute = SystemTime.wMinute;
-   pdtime->Hour = SystemTime.wHour;
+    pdtime->Second = SystemTime.wSecond / 2;
+    pdtime->Minute = SystemTime.wMinute;
+    pdtime->Hour = SystemTime.wHour;
 
-   pddate->Day = SystemTime.wDay;
-   pddate->Month = SystemTime.wMonth;
-   pddate->Year = SystemTime.wYear - 1980;
+    pddate->Day = SystemTime.wDay;
+    pddate->Month = SystemTime.wMonth;
+    pddate->Year = SystemTime.wYear - 1980;
 
-   return TRUE;
+    return TRUE;
 }
 
 
@@ -283,31 +277,29 @@ FileTimeToDosDateTime(
  */
 BOOL
 WINAPI
-DosDateTimeToFileTime(
-                     WORD wFatDate,
-                     WORD wFatTime,
-                     LPFILETIME lpFileTime
-                     )
+DosDateTimeToFileTime(WORD wFatDate,
+                      WORD wFatTime,
+                      LPFILETIME lpFileTime)
 {
-   PDOSTIME  pdtime = (PDOSTIME) &wFatTime;
-   PDOSDATE  pddate = (PDOSDATE) &wFatDate;
-   SYSTEMTIME SystemTime;
+    PDOSTIME  pdtime = (PDOSTIME) &wFatTime;
+    PDOSDATE  pddate = (PDOSDATE) &wFatDate;
+    SYSTEMTIME SystemTime;
 
-   if ( lpFileTime == NULL )
-               return FALSE;
+    if (lpFileTime == NULL)
+        return FALSE;
 
-   SystemTime.wMilliseconds = 0;
-   SystemTime.wSecond = pdtime->Second * 2;
-   SystemTime.wMinute = pdtime->Minute;
-   SystemTime.wHour = pdtime->Hour;
+    SystemTime.wMilliseconds = 0;
+    SystemTime.wSecond = pdtime->Second * 2;
+    SystemTime.wMinute = pdtime->Minute;
+    SystemTime.wHour = pdtime->Hour;
 
-   SystemTime.wDay = pddate->Day;
-   SystemTime.wMonth = pddate->Month;
-   SystemTime.wYear = 1980 + pddate->Year;
+    SystemTime.wDay = pddate->Day;
+    SystemTime.wMonth = pddate->Month;
+    SystemTime.wYear = 1980 + pddate->Year;
 
-   SystemTimeToFileTime(&SystemTime,lpFileTime);
+    SystemTimeToFileTime(&SystemTime,lpFileTime);
 
-   return TRUE;
+    return TRUE;
 }
 
 
@@ -316,37 +308,35 @@ DosDateTimeToFileTime(
  */
 LONG
 WINAPI
-CompareFileTime(
-               CONST FILETIME *lpFileTime1,
-               CONST FILETIME *lpFileTime2
-               )
+CompareFileTime(CONST FILETIME *lpFileTime1, CONST FILETIME *lpFileTime2)
 {
-  if ( lpFileTime1 == NULL )
-       return 0;
-  if ( lpFileTime2 == NULL )
-       return 0;
+    if (lpFileTime1 == NULL)
+        return 0;
+    if (lpFileTime2 == NULL)
+        return 0;
 
-  if (*((PLONGLONG)lpFileTime1) > *((PLONGLONG)lpFileTime2))
-       return 1;
-  else if (*((PLONGLONG)lpFileTime1) < *((PLONGLONG)lpFileTime2))
-       return -1;
+    if (*((PLONGLONG)lpFileTime1) > *((PLONGLONG)lpFileTime2))
+        return 1;
+    else if (*((PLONGLONG)lpFileTime1) < *((PLONGLONG)lpFileTime2))
+        return -1;
 
-  return 0;
+    return 0;
 }
 
 
 /*
  * @implemented
  */
-VOID WINAPI
-GetSystemTimeAsFileTime (PFILETIME lpFileTime)
+VOID
+WINAPI
+GetSystemTimeAsFileTime(PFILETIME lpFileTime)
 {
-  do
+    do
     {
-      lpFileTime->dwHighDateTime = SharedUserData->SystemTime.High1Time;
-      lpFileTime->dwLowDateTime = SharedUserData->SystemTime.LowPart;
+        lpFileTime->dwHighDateTime = SharedUserData->SystemTime.High1Time;
+        lpFileTime->dwLowDateTime = SharedUserData->SystemTime.LowPart;
     }
-  while (lpFileTime->dwHighDateTime != (DWORD)SharedUserData->SystemTime.High2Time);
+    while (lpFileTime->dwHighDateTime != (DWORD)SharedUserData->SystemTime.High2Time);
 }
 
 
@@ -355,32 +345,28 @@ GetSystemTimeAsFileTime (PFILETIME lpFileTime)
  */
 BOOL
 WINAPI
-SystemTimeToFileTime(
-    CONST SYSTEMTIME *  lpSystemTime,
-    LPFILETIME  lpFileTime
-   )
-
+SystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime)
 {
-  TIME_FIELDS TimeFields;
-  LARGE_INTEGER liTime;
-
-  TimeFields.Year = lpSystemTime->wYear;
-  TimeFields.Month = lpSystemTime->wMonth;
-  TimeFields.Day = lpSystemTime->wDay;
-  TimeFields.Hour = lpSystemTime->wHour;
-  TimeFields.Minute = lpSystemTime->wMinute;
-  TimeFields.Second = lpSystemTime->wSecond;
-  TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
-
-  if (RtlTimeFieldsToTime (&TimeFields, &liTime))
-  {
-     lpFileTime->dwLowDateTime = liTime.u.LowPart;
-     lpFileTime->dwHighDateTime = liTime.u.HighPart;
-     return TRUE;
-  }
-
-  SetLastError(ERROR_INVALID_PARAMETER);
-  return FALSE;
+    TIME_FIELDS TimeFields;
+    LARGE_INTEGER liTime;
+
+    TimeFields.Year = lpSystemTime->wYear;
+    TimeFields.Month = lpSystemTime->wMonth;
+    TimeFields.Day = lpSystemTime->wDay;
+    TimeFields.Hour = lpSystemTime->wHour;
+    TimeFields.Minute = lpSystemTime->wMinute;
+    TimeFields.Second = lpSystemTime->wSecond;
+    TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
+
+    if (RtlTimeFieldsToTime (&TimeFields, &liTime))
+    {
+        lpFileTime->dwLowDateTime = liTime.u.LowPart;
+        lpFileTime->dwHighDateTime = liTime.u.HighPart;
+        return TRUE;
+    }
+
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
 }
 
 
@@ -389,32 +375,29 @@ SystemTimeToFileTime(
  */
 BOOL
 WINAPI
-FileTimeToSystemTime(
-                    CONST FILETIME *lpFileTime,
-                    LPSYSTEMTIME lpSystemTime
-                    )
+FileTimeToSystemTime(CONST FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime)
 {
-  TIME_FIELDS TimeFields;
-  LARGE_INTEGER liTime;
+    TIME_FIELDS TimeFields;
+    LARGE_INTEGER liTime;
 
-  if(lpFileTime->dwHighDateTime & 0x80000000)
-   return FALSE;
+    if (lpFileTime->dwHighDateTime & 0x80000000)
+        return FALSE;
 
-  liTime.u.LowPart = lpFileTime->dwLowDateTime;
-  liTime.u.HighPart = lpFileTime->dwHighDateTime;
+    liTime.u.LowPart = lpFileTime->dwLowDateTime;
+    liTime.u.HighPart = lpFileTime->dwHighDateTime;
 
-  RtlTimeToTimeFields(&liTime, &TimeFields);
+    RtlTimeToTimeFields(&liTime, &TimeFields);
 
-  lpSystemTime->wYear = TimeFields.Year;
-  lpSystemTime->wMonth = TimeFields.Month;
-  lpSystemTime->wDay = TimeFields.Day;
-  lpSystemTime->wHour = TimeFields.Hour;
-  lpSystemTime->wMinute = TimeFields.Minute;
-  lpSystemTime->wSecond = TimeFields.Second;
-  lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
-  lpSystemTime->wDayOfWeek = TimeFields.Weekday;
+    lpSystemTime->wYear = TimeFields.Year;
+    lpSystemTime->wMonth = TimeFields.Month;
+    lpSystemTime->wDay = TimeFields.Day;
+    lpSystemTime->wHour = TimeFields.Hour;
+    lpSystemTime->wMinute = TimeFields.Minute;
+    lpSystemTime->wSecond = TimeFields.Second;
+    lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
+    lpSystemTime->wDayOfWeek = TimeFields.Weekday;
 
-  return TRUE;
+    return TRUE;
 }
 
 
@@ -423,24 +406,20 @@ FileTimeToSystemTime(
  */
 BOOL
 WINAPI
-FileTimeToLocalFileTime(
-                       CONST FILETIME *lpFileTime,
-                       LPFILETIME lpLocalFileTime
-                       )
+FileTimeToLocalFileTime(CONST FILETIME *lpFileTime, LPFILETIME lpLocalFileTime)
 {
-  LARGE_INTEGER TimeZoneBias;
+    LARGE_INTEGER TimeZoneBias;
 
-  do
+    do
     {
-      TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
-      TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
+        TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
+        TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
     }
-  while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
+    while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
 
-  *((PLONGLONG)lpLocalFileTime) =
-    *((PLONGLONG)lpFileTime) - TimeZoneBias.QuadPart;
+    *((PLONGLONG)lpLocalFileTime) = *((PLONGLONG)lpFileTime) - TimeZoneBias.QuadPart;
 
-  return TRUE;
+    return TRUE;
 }
 
 
@@ -449,161 +428,165 @@ FileTimeToLocalFileTime(
  */
 BOOL
 WINAPI
-LocalFileTimeToFileTime(
-                       CONST FILETIME *lpLocalFileTime,
-                       LPFILETIME lpFileTime
-                       )
+LocalFileTimeToFileTime(CONST FILETIME *lpLocalFileTime, LPFILETIME lpFileTime)
 {
-  LARGE_INTEGER TimeZoneBias;
+    LARGE_INTEGER TimeZoneBias;
 
-  do
+    do
     {
-      TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
-      TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
+        TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
+        TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
     }
-  while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
+    while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
 
-  *((PLONGLONG)lpFileTime) =
-    *((PLONGLONG)lpLocalFileTime) + TimeZoneBias.QuadPart;
+    *((PLONGLONG)lpFileTime) = *((PLONGLONG)lpLocalFileTime) + TimeZoneBias.QuadPart;
 
-  return TRUE;
+    return TRUE;
 }
 
 
 /*
  * @implemented
  */
-VOID WINAPI
+VOID
+WINAPI
 GetLocalTime(LPSYSTEMTIME lpSystemTime)
 {
-  FILETIME FileTime;
-  FILETIME LocalFileTime;
+    FILETIME FileTime;
+    FILETIME LocalFileTime;
 
-  GetSystemTimeAsFileTime(&FileTime);
-  FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
-  FileTimeToSystemTime(&LocalFileTime, lpSystemTime);
+    GetSystemTimeAsFileTime(&FileTime);
+    FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
+    FileTimeToSystemTime(&LocalFileTime, lpSystemTime);
 }
 
 
 /*
  * @implemented
  */
-VOID WINAPI
+VOID
+WINAPI
 GetSystemTime(LPSYSTEMTIME lpSystemTime)
 {
-  FILETIME FileTime;
+    FILETIME FileTime;
 
-  GetSystemTimeAsFileTime(&FileTime);
-  FileTimeToSystemTime(&FileTime, lpSystemTime);
+    GetSystemTimeAsFileTime(&FileTime);
+    FileTimeToSystemTime(&FileTime, lpSystemTime);
 }
 
 
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
 {
-  FILETIME LocalFileTime;
-  LARGE_INTEGER FileTime;
-  NTSTATUS Status;
-
-  SystemTimeToFileTime(lpSystemTime, &LocalFileTime);
-  LocalFileTimeToFileTime(&LocalFileTime, (FILETIME *)&FileTime);
-  Status = NtSetSystemTime(&FileTime, &FileTime);
-  if (!NT_SUCCESS(Status))
-    return FALSE;
-  return TRUE;
+    FILETIME LocalFileTime;
+    LARGE_INTEGER FileTime;
+    NTSTATUS Status;
+
+    SystemTimeToFileTime(lpSystemTime, &LocalFileTime);
+    LocalFileTimeToFileTime(&LocalFileTime, (FILETIME *)&FileTime);
+    Status = NtSetSystemTime(&FileTime, &FileTime);
+    if (!NT_SUCCESS(Status))
+        return FALSE;
+    return TRUE;
 }
 
 
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
 {
-  LARGE_INTEGER NewSystemTime;
-  NTSTATUS Status;
+    LARGE_INTEGER NewSystemTime;
+    NTSTATUS Status;
 
-  SystemTimeToFileTime(lpSystemTime, (PFILETIME)&NewSystemTime);
-  Status = NtSetSystemTime(&NewSystemTime, &NewSystemTime);
-  if (!NT_SUCCESS(Status))
-    return FALSE;
-  return TRUE;
+    SystemTimeToFileTime(lpSystemTime, (PFILETIME)&NewSystemTime);
+    Status = NtSetSystemTime(&NewSystemTime, &NewSystemTime);
+    if (!NT_SUCCESS(Status))
+        return FALSE;
+    return TRUE;
 }
 
 
 /*
  * @implemented
  */
-DWORD WINAPI
+DWORD
+WINAPI
 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
 {
-   NTSTATUS Status;
+    NTSTATUS Status;
 
-   DPRINT("GetTimeZoneInformation()\n");
+    DPRINT("GetTimeZoneInformation()\n");
 
-   Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
-                                    lpTimeZoneInformation,
-                                    sizeof(TIME_ZONE_INFORMATION),
-                                    NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       SetLastErrorByStatus(Status);
-       return TIME_ZONE_ID_INVALID;
-     }
+    Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
+                                      lpTimeZoneInformation,
+                                      sizeof(TIME_ZONE_INFORMATION),
+                                      NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastErrorByStatus(Status);
+        return TIME_ZONE_ID_INVALID;
+    }
 
-   return(SharedUserData->TimeZoneId);
+    return(SharedUserData->TimeZoneId);
 }
 
 
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
 {
-   NTSTATUS Status;
-
-   DPRINT("SetTimeZoneInformation()\n");
-
-   Status = RtlSetTimeZoneInformation((LPTIME_ZONE_INFORMATION)lpTimeZoneInformation);
-   if (!NT_SUCCESS(Status))
-     {
-       DPRINT1("RtlSetTimeZoneInformation() failed (Status %lx)\n", Status);
-       SetLastErrorByStatus(Status);
-       return FALSE;
-     }
-
-   Status = NtSetSystemInformation(SystemCurrentTimeZoneInformation,
-                                  (PVOID)lpTimeZoneInformation,
-                                  sizeof(TIME_ZONE_INFORMATION));
-   if (!NT_SUCCESS(Status))
-     {
-       DPRINT1("NtSetSystemInformation() failed (Status %lx)\n", Status);
-       SetLastErrorByStatus(Status);
-       return FALSE;
-     }
-
-   return TRUE;
+    NTSTATUS Status;
+
+    DPRINT("SetTimeZoneInformation()\n");
+
+    Status = RtlSetTimeZoneInformation((LPTIME_ZONE_INFORMATION)lpTimeZoneInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlSetTimeZoneInformation() failed (Status %lx)\n", Status);
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+
+    Status = NtSetSystemInformation(SystemCurrentTimeZoneInformation,
+                                    (PVOID)lpTimeZoneInformation,
+                                    sizeof(TIME_ZONE_INFORMATION));
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtSetSystemInformation() failed (Status %lx)\n", Status);
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
 /*
  * @implemented
  */
-DWORD WINAPI
+DWORD
+WINAPI
 GetTickCount(VOID)
 {
-  return (DWORD)((ULONGLONG)SharedUserData->TickCountLowDeprecated * SharedUserData->TickCountMultiplier / 16777216);
+    return (DWORD)((ULONGLONG)SharedUserData->TickCountLowDeprecated * SharedUserData->TickCountMultiplier / 16777216);
 }
 
 
 /*
  * @implemented
  */
-ULONGLONG WINAPI
+ULONGLONG
+WINAPI
 GetTickCount64(VOID)
 {
     return (ULONGLONG)SharedUserData->TickCountLowDeprecated * (ULONGLONG)SharedUserData->TickCountMultiplier / 16777216;
@@ -613,36 +596,44 @@ GetTickCount64(VOID)
 /*
  * @implemented
  */
-BOOL WINAPI
-SystemTimeToTzSpecificLocalTime(
-                                CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation,
+BOOL
+WINAPI
+SystemTimeToTzSpecificLocalTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation,
                                 CONST SYSTEMTIME *lpUniversalTime,
-                                LPSYSTEMTIME lpLocalTime
-                               )
+                                LPSYSTEMTIME lpLocalTime)
 {
-  TIME_ZONE_INFORMATION TimeZoneInformation;
-  LPTIME_ZONE_INFORMATION lpTzInfo;
-  LARGE_INTEGER FileTime;
-
-  if (!lpTimeZoneInformation)
-  {
-    GetTimeZoneInformation(&TimeZoneInformation);
-    lpTzInfo = &TimeZoneInformation;
-  }
-  else
-    lpTzInfo = (LPTIME_ZONE_INFORMATION)lpTimeZoneInformation;
-
-  if (!lpUniversalTime)
-    return FALSE;
+    TIME_ZONE_INFORMATION TzInfo;
+    FILETIME FileTime;
+    LONGLONG llTime;
+    LONG lBias;
 
-  if (!lpLocalTime)
-    return FALSE;
+    if (lpTimeZoneInformation != NULL)
+    {
+        TzInfo = *lpTimeZoneInformation;
+    }
+    else
+    {
+        if (GetTimeZoneInformation(&TzInfo) == TIME_ZONE_ID_INVALID)
+            return FALSE;
+    }
+
+    if (!lpUniversalTime || !lpLocalTime)
+        return FALSE;
+
+    if (!SystemTimeToFileTime(lpUniversalTime, &FileTime))
+        return FALSE;
+
+    FILETIME2LL(&FileTime, llTime)
+
+    if (!TIME_GetTimezoneBias(&TzInfo, &FileTime, FALSE, &lBias))
+        return FALSE;
+
+    /* convert minutes to 100-nanoseconds-ticks */
+    llTime -= (LONGLONG)lBias * TICKSPERMIN;
 
-  SystemTimeToFileTime(lpUniversalTime, (PFILETIME)&FileTime);
-  FileTime.QuadPart -= (lpTzInfo->Bias * TICKSPERMIN);
-  FileTimeToSystemTime((PFILETIME)&FileTime, lpLocalTime);
+    LL2FILETIME( llTime, &FileTime)
 
-  return TRUE;
+    return FileTimeToSystemTime(&FileTime, lpLocalTime);
 }
 
 
@@ -651,11 +642,9 @@ SystemTimeToTzSpecificLocalTime(
  */
 BOOL
 WINAPI
-TzSpecificLocalTimeToSystemTime(
-    CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation,
-    CONST SYSTEMTIME *lpLocalTime,
-    LPSYSTEMTIME lpUniversalTime
-    )
+TzSpecificLocalTimeToSystemTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation,
+                                CONST SYSTEMTIME *lpLocalTime,
+                                LPSYSTEMTIME lpUniversalTime)
 {
     FILETIME ft;
     LONG lBias;
@@ -687,55 +676,57 @@ TzSpecificLocalTimeToSystemTime(
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
-                       PDWORD lpTimeIncrement,
-                       PBOOL lpTimeAdjustmentDisabled)
+                        PDWORD lpTimeIncrement,
+                        PBOOL lpTimeAdjustmentDisabled)
 {
-   SYSTEM_QUERY_TIME_ADJUST_INFORMATION Buffer;
-   NTSTATUS Status;
-
-   Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
-                                    &Buffer,
-                                    sizeof(SYSTEM_QUERY_TIME_ADJUST_INFORMATION),
-                                    NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       SetLastErrorByStatus(Status);
-       return FALSE;
-     }
-
-   *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
-   *lpTimeIncrement = (DWORD)Buffer.TimeIncrement;
-   *lpTimeAdjustmentDisabled = (BOOL)Buffer.Enable;
-
-   return TRUE;
+    SYSTEM_QUERY_TIME_ADJUST_INFORMATION Buffer;
+    NTSTATUS Status;
+
+    Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
+                                      &Buffer,
+                                      sizeof(SYSTEM_QUERY_TIME_ADJUST_INFORMATION),
+                                      NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+
+    *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
+    *lpTimeIncrement = (DWORD)Buffer.TimeIncrement;
+    *lpTimeAdjustmentDisabled = (BOOL)Buffer.Enable;
+
+    return TRUE;
 }
 
 
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
-                       BOOL bTimeAdjustmentDisabled)
+                        BOOL bTimeAdjustmentDisabled)
 {
-   NTSTATUS Status;
-   SYSTEM_SET_TIME_ADJUST_INFORMATION Buffer;
-
-   Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
-   Buffer.Enable = (BOOLEAN)bTimeAdjustmentDisabled;
-
-   Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
-                                  &Buffer,
-                                  sizeof(SYSTEM_SET_TIME_ADJUST_INFORMATION));
-   if (!NT_SUCCESS(Status))
-     {
-       SetLastErrorByStatus(Status);
-       return FALSE;
-     }
-
-   return TRUE;
+    NTSTATUS Status;
+    SYSTEM_SET_TIME_ADJUST_INFORMATION Buffer;
+
+    Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
+    Buffer.Enable = (BOOLEAN)bTimeAdjustmentDisabled;
+
+    Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
+                                    &Buffer,
+                                    sizeof(SYSTEM_SET_TIME_ADJUST_INFORMATION));
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
@@ -744,39 +735,37 @@ SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
  */
 BOOL
 WINAPI
-GetSystemTimes(
-    LPFILETIME lpIdleTime,
-    LPFILETIME lpKernelTime,
-    LPFILETIME lpUserTime
-    )
+GetSystemTimes(LPFILETIME lpIdleTime,
+               LPFILETIME lpKernelTime,
+               LPFILETIME lpUserTime)
 {
-   SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcPerfInfo;
-   NTSTATUS Status;
+    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcPerfInfo;
+    NTSTATUS Status;
 
-   Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation,
-                                     &SysProcPerfInfo,
-                                     sizeof(SysProcPerfInfo),
-                                     NULL);
+    Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation,
+                                      &SysProcPerfInfo,
+                                      sizeof(SysProcPerfInfo),
+                                      NULL);
 
-   if (!NT_SUCCESS(Status))
-     {
+    if (!NT_SUCCESS(Status))
+    {
         SetLastErrorByStatus(Status);
         return FALSE;
-     }
+    }
 /*
-       Good only for one processor system.
+    Good only for one processor system.
  */
 
-   lpIdleTime->dwLowDateTime = SysProcPerfInfo.IdleTime.LowPart;
-   lpIdleTime->dwHighDateTime = SysProcPerfInfo.IdleTime.HighPart;
+    lpIdleTime->dwLowDateTime = SysProcPerfInfo.IdleTime.LowPart;
+    lpIdleTime->dwHighDateTime = SysProcPerfInfo.IdleTime.HighPart;
 
-   lpKernelTime->dwLowDateTime = SysProcPerfInfo.KernelTime.LowPart;
-   lpKernelTime->dwHighDateTime = SysProcPerfInfo.KernelTime.HighPart;
+    lpKernelTime->dwLowDateTime = SysProcPerfInfo.KernelTime.LowPart;
+    lpKernelTime->dwHighDateTime = SysProcPerfInfo.KernelTime.HighPart;
 
-   lpUserTime->dwLowDateTime = SysProcPerfInfo.UserTime.LowPart;
-   lpUserTime->dwHighDateTime = SysProcPerfInfo.UserTime.HighPart;
+    lpUserTime->dwLowDateTime = SysProcPerfInfo.UserTime.LowPart;
+    lpUserTime->dwHighDateTime = SysProcPerfInfo.UserTime.HighPart;
 
-   return TRUE;
+    return TRUE;
 }
 
 /* EOF */
index 5bb7008..3a32a06 100644 (file)
@@ -288,7 +288,8 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
     msiobj_release(&row->hdr);
 }
 
-UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine )
+UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine,
+                             BOOL preserve_case )
 {
     LPCWSTR ptr,ptr2;
     BOOL quote;
@@ -323,6 +324,10 @@ UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine )
         prop = msi_alloc((len+1)*sizeof(WCHAR));
         memcpy(prop,ptr,len*sizeof(WCHAR));
         prop[len]=0;
+
+        if (!preserve_case)
+            struprW(prop);
+
         ptr2++;
        
         len = 0; 
@@ -475,6 +480,44 @@ static UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si
     return ret;
 }
 
+static UINT msi_set_media_source_prop(MSIPACKAGE *package)
+{
+    MSIQUERY *view;
+    MSIRECORD *rec = NULL;
+    LPWSTR patch;
+    LPCWSTR prop;
+    UINT r;
+
+    static const WCHAR szPatch[] = {'P','A','T','C','H',0};
+    static const WCHAR query[] = {'S','E','L','E','C','T',' ',
+        '`','S','o','u','r','c','e','`',' ','F','R','O','M',' ',
+        '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
+        '`','S','o','u','r','c','e','`',' ','I','S',' ',
+        'N','O','T',' ','N','U','L','L',0};
+
+    r = MSI_DatabaseOpenViewW(package->db, query, &view);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_ViewExecute(view, 0);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    if (MSI_ViewFetch(view, &rec) == ERROR_SUCCESS)
+    {
+        prop = MSI_RecordGetString(rec, 1);
+        patch = msi_dup_property(package, szPatch);
+        MSI_SetPropertyW(package, prop, patch);
+        msi_free(patch);
+    }
+
+done:
+    if (rec) msiobj_release(&rec->hdr);
+    msiobj_release(&view->hdr);
+
+    return r;
+}
+
 static UINT msi_parse_patch_summary( MSIPACKAGE *package, MSIDATABASE *patch_db )
 {
     MSISUMMARYINFO *si;
@@ -485,20 +528,33 @@ static UINT msi_parse_patch_summary( MSIPACKAGE *package, MSIDATABASE *patch_db
     if (!si)
         return ERROR_FUNCTION_FAILED;
 
-    msi_check_patch_applicable( package, si );
+    if (msi_check_patch_applicable( package, si ) != ERROR_SUCCESS)
+    {
+        TRACE("Patch not applicable\n");
+        return ERROR_SUCCESS;
+    }
+
+    package->patch = msi_alloc(sizeof(MSIPATCHINFO));
+    if (!package->patch)
+        return ERROR_OUTOFMEMORY;
+
+    package->patch->patchcode = msi_suminfo_dup_string(si, PID_REVNUMBER);
+    if (!package->patch->patchcode)
+        return ERROR_OUTOFMEMORY;
 
     /* enumerate the substorage */
     str = msi_suminfo_dup_string( si, PID_LASTAUTHOR );
+    package->patch->transforms = str;
+
     substorage = msi_split_string( str, ';' );
     for ( i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++ )
         r = msi_apply_substorage_transform( package, patch_db, substorage[i] );
-    msi_free( substorage );
-    msi_free( str );
-
-    /* FIXME: parse the sources in PID_REVNUMBER and do something with them... */
 
+    msi_free( substorage );
     msiobj_release( &si->hdr );
 
+    msi_set_media_source_prop(package);
+
     return r;
 }
 
@@ -727,7 +783,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
         msi_set_sourcedir_props(package, FALSE);
     }
 
-    msi_parse_command_line( package, szCommandLine );
+    msi_parse_command_line( package, szCommandLine, FALSE );
 
     msi_apply_transforms( package );
     msi_apply_patches( package );
@@ -1193,7 +1249,7 @@ static UINT load_component( MSIRECORD *row, LPVOID param )
     comp->KeyPath = msi_dup_record_field( row, 6 );
 
     comp->Installed = INSTALLSTATE_UNKNOWN;
-    msi_component_set_state( comp, INSTALLSTATE_UNKNOWN );
+    msi_component_set_state(package, comp, INSTALLSTATE_UNKNOWN);
 
     return ERROR_SUCCESS;
 }
@@ -1327,7 +1383,7 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
     feature->Attributes = MSI_RecordGetInteger(row,8);
 
     feature->Installed = INSTALLSTATE_UNKNOWN;
-    msi_feature_set_state( feature, INSTALLSTATE_UNKNOWN );
+    msi_feature_set_state(package, feature, INSTALLSTATE_UNKNOWN);
 
     list_add_tail( &package->features, &feature->entry );
 
@@ -1457,7 +1513,12 @@ static UINT load_file(MSIRECORD *row, LPVOID param)
     file->Component = get_loaded_component( package, component );
 
     if (!file->Component)
-        ERR("Unfound Component %s\n",debugstr_w(component));
+    {
+        WARN("Component not found: %s\n", debugstr_w(component));
+        msi_free(file->File);
+        msi_free(file);
+        return ERROR_SUCCESS;
+    }
 
     file->FileName = msi_dup_record_field( row, 3 );
     reduce_to_longfilename( file->FileName );
@@ -1476,7 +1537,12 @@ static UINT load_file(MSIRECORD *row, LPVOID param)
     /* if the compressed bits are not set in the file attributes,
      * then read the information from the package word count property
      */
-    if (file->Attributes & msidbFileAttributesCompressed)
+    if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
+    {
+        file->IsCompressed = FALSE;
+    }
+    else if (file->Attributes &
+             (msidbFileAttributesCompressed | msidbFileAttributesPatchAdded))
     {
         file->IsCompressed = TRUE;
     }
@@ -1489,25 +1555,6 @@ static UINT load_file(MSIRECORD *row, LPVOID param)
         file->IsCompressed = package->WordCount & msidbSumInfoSourceTypeCompressed;
     }
 
-    if (!file->IsCompressed)
-    {
-        LPWSTR p, path;
-
-        p = resolve_folder(package, file->Component->Directory,
-                           TRUE, FALSE, TRUE, NULL);
-        path = build_directory_name(2, p, file->ShortName);
-
-        if (file->LongName &&
-            GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
-        {
-            msi_free(path);
-            path = build_directory_name(2, p, file->LongName);
-        }
-
-        file->SourcePath = path;
-        msi_free(p);
-    }
-
     load_file_hash(package, file);
 
     TRACE("File Loaded (%s)\n",debugstr_w(file->File));  
@@ -1688,65 +1735,53 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
 static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
 {
     MSICOMPONENT *comp;
+    INSTALLSTATE state;
+    UINT r;
 
-    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
-    {
-        INSTALLSTATE res;
+    state = MsiQueryProductStateW(package->ProductCode);
 
+    LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
+    {
         if (!comp->ComponentId)
             continue;
 
-        res = MsiGetComponentPathW( package->ProductCode,
-                                    comp->ComponentId, NULL, NULL);
-        if (res < 0)
-            res = INSTALLSTATE_ABSENT;
-        comp->Installed = res;
+        if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT)
+            comp->Installed = INSTALLSTATE_ABSENT;
+        else
+        {
+            r = MsiQueryComponentStateW(package->ProductCode, NULL,
+                                        package->Context, comp->ComponentId,
+                                        &comp->Installed);
+            if (r != ERROR_SUCCESS)
+                comp->Installed = INSTALLSTATE_ABSENT;
+        }
     }
 }
 
-/* scan for and update current install states */
-static void ACTION_UpdateFeatureInstallStates(MSIPACKAGE *package)
+static void ACTION_GetFeatureInstallStates(MSIPACKAGE *package)
 {
-    MSICOMPONENT *comp;
     MSIFEATURE *feature;
+    INSTALLSTATE state;
+
+    state = MsiQueryProductStateW(package->ProductCode);
 
     LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
     {
-        ComponentList *cl;
-        INSTALLSTATE res = INSTALLSTATE_ABSENT;
-
-        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
+        if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT)
+            feature->Installed = INSTALLSTATE_ABSENT;
+        else
         {
-            comp= cl->component;
-
-            if (!comp->ComponentId)
-            {
-                res = INSTALLSTATE_ABSENT;
-                break;
-            }
-
-            if (res == INSTALLSTATE_ABSENT)
-                res = comp->Installed;
-            else
-            {
-                if (res == comp->Installed)
-                    continue;
-
-                if (res != INSTALLSTATE_DEFAULT && res != INSTALLSTATE_LOCAL &&
-                    res != INSTALLSTATE_SOURCE)
-                {
-                    res = INSTALLSTATE_INCOMPLETE;
-                }
-            }
+            feature->Installed = MsiQueryFeatureStateW(package->ProductCode,
+                                                       feature->Feature);
         }
-        feature->Installed = res;
     }
 }
 
-static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property, 
-                                    INSTALLSTATE state)
+static BOOL process_state_property(MSIPACKAGE* package, int level,
+                                   LPCWSTR property, INSTALLSTATE state)
 {
     static const WCHAR all[]={'A','L','L',0};
+    static const WCHAR remove[] = {'R','E','M','O','V','E',0};
     LPWSTR override;
     MSIFEATURE *feature;
 
@@ -1756,8 +1791,12 @@ static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property,
 
     LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
     {
+        if (lstrcmpW(property, remove) &&
+            (feature->Level <= 0 || feature->Level > level))
+            continue;
+
         if (strcmpiW(override,all)==0)
-            msi_feature_set_state( feature, state );
+            msi_feature_set_state(package, feature, state);
         else
         {
             LPWSTR ptr = override;
@@ -1768,7 +1807,7 @@ static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property,
                 if ((ptr2 && strncmpW(ptr,feature->Feature, ptr2-ptr)==0)
                     || (!ptr2 && strcmpW(ptr,feature->Feature)==0))
                 {
-                    msi_feature_set_state( feature, state );
+                    msi_feature_set_state(package, feature, state);
                     break;
                 }
                 if (ptr2)
@@ -1788,7 +1827,7 @@ static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property,
 
 UINT MSI_SetFeatureStates(MSIPACKAGE *package)
 {
-    int install_level;
+    int level;
     static const WCHAR szlevel[] =
         {'I','N','S','T','A','L','L','L','E','V','E','L',0};
     static const WCHAR szAddLocal[] =
@@ -1808,7 +1847,7 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
 
     TRACE("Checking Install Level\n");
 
-    install_level = msi_get_property_int( package, szlevel, 1 );
+    level = msi_get_property_int(package, szlevel, 1);
 
     /* ok here is the _real_ rub
      * all these activation/deactivation things happen in order and things
@@ -1829,26 +1868,26 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
      * REMOVE are the big ones, since we don't handle administrative installs
      * yet anyway.
      */
-    override |= process_state_property(package,szAddLocal,INSTALLSTATE_LOCAL);
-    override |= process_state_property(package,szRemove,INSTALLSTATE_ABSENT);
-    override |= process_state_property(package,szAddSource,INSTALLSTATE_SOURCE);
-    override |= process_state_property(package,szReinstall,INSTALLSTATE_LOCAL);
+    override |= process_state_property(package, level, szAddLocal, INSTALLSTATE_LOCAL);
+    override |= process_state_property(package, level, szRemove, INSTALLSTATE_ABSENT);
+    override |= process_state_property(package, level, szAddSource, INSTALLSTATE_SOURCE);
+    override |= process_state_property(package, level, szReinstall, INSTALLSTATE_LOCAL);
 
     if (!override)
     {
         LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
         {
             BOOL feature_state = ((feature->Level > 0) &&
-                             (feature->Level <= install_level));
+                                  (feature->Level <= level));
 
             if ((feature_state) && (feature->Action == INSTALLSTATE_UNKNOWN))
             {
                 if (feature->Attributes & msidbFeatureAttributesFavorSource)
-                    msi_feature_set_state( feature, INSTALLSTATE_SOURCE );
+                    msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE);
                 else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
-                    msi_feature_set_state( feature, INSTALLSTATE_ADVERTISED );
+                    msi_feature_set_state(package, feature, INSTALLSTATE_ADVERTISED);
                 else
-                    msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
+                    msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
             }
         }
 
@@ -1857,11 +1896,11 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
         {
             FeatureList *fl;
 
-            if (feature->Level > 0 && feature->Level <= install_level)
+            if (feature->Level > 0 && feature->Level <= level)
                 continue;
 
             LIST_FOR_EACH_ENTRY( fl, &feature->Children, FeatureList, entry )
-                msi_feature_set_state( fl->feature, INSTALLSTATE_UNKNOWN );
+                msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN);
         }
     }
     else
@@ -1894,7 +1933,7 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
                 cl->component->ForceLocalState &&
                 feature->Action == INSTALLSTATE_SOURCE)
             {
-                msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
+                msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
                 break;
             }
         }
@@ -1946,34 +1985,34 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
         {
             if ((component->Attributes & msidbComponentAttributesSourceOnly) &&
                  !component->ForceLocalState)
-                msi_component_set_state( component, INSTALLSTATE_SOURCE );
+                msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
             else
-                msi_component_set_state( component, INSTALLSTATE_LOCAL );
+                msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
             continue;
         }
 
         /* if any feature is local, the component must be local too */
         if (component->hasLocalFeature)
         {
-            msi_component_set_state( component, INSTALLSTATE_LOCAL );
+            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
             continue;
         }
 
         if (component->hasSourceFeature)
         {
-            msi_component_set_state( component, INSTALLSTATE_SOURCE );
+            msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
             continue;
         }
 
         if (component->hasAdvertiseFeature)
         {
-            msi_component_set_state( component, INSTALLSTATE_ADVERTISED );
+            msi_component_set_state(package, component, INSTALLSTATE_ADVERTISED);
             continue;
         }
 
         TRACE("nobody wants component %s\n", debugstr_w(component->Component));
         if (component->anyAbsent)
-            msi_component_set_state(component, INSTALLSTATE_ABSENT);
+            msi_component_set_state(package, component, INSTALLSTATE_ABSENT);
     }
 
     LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
@@ -1981,7 +2020,7 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
         if (component->Action == INSTALLSTATE_DEFAULT)
         {
             TRACE("%s was default, setting to local\n", debugstr_w(component->Component));
-            msi_component_set_state( component, INSTALLSTATE_LOCAL );
+            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
         }
 
         TRACE("Result: Component %s (Installed %i, Action %i)\n",
@@ -2124,7 +2163,6 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package )
         {
             file->state = msifs_missing;
             comp->Cost += file->FileSize;
-            comp->Installed = INSTALLSTATE_INCOMPLETE;
             continue;
         }
 
@@ -2138,7 +2176,6 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package )
             {
                 file->state = msifs_overwrite;
                 comp->Cost += file->FileSize;
-                comp->Installed = INSTALLSTATE_INCOMPLETE;
             }
             else
                 file->state = msifs_present;
@@ -2178,9 +2215,6 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
     MSIQUERY * view;
     LPWSTR level;
 
-    if ( 1 == msi_get_property_int( package, szCosting, 0 ) )
-        return ERROR_SUCCESS;
-
     TRACE("Building Directory properties\n");
 
     rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
@@ -2193,6 +2227,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
 
     /* read components states from the registry */
     ACTION_GetComponentInstallStates(package);
+    ACTION_GetFeatureInstallStates(package);
 
     TRACE("File calculations\n");
     msi_check_file_install_states( package );
@@ -2215,6 +2250,8 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
             TRACE("Disabling component %s\n", debugstr_w(comp->Component));
             comp->Enabled = FALSE;
         }
+        else
+            comp->Enabled = TRUE;
     }
 
     MSI_SetPropertyW(package,szCosting,szOne);
@@ -2227,8 +2264,6 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
     /* FIXME: check volume disk space */
     MSI_SetPropertyW(package, szOutOfDiskSpace, szZero);
 
-    ACTION_UpdateFeatureInstallStates(package);
-
     return MSI_SetFeatureStates(package);
 }
 
@@ -2834,13 +2869,6 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
         ACTION_WriteSharedDLLsCount( comp->FullKeypath, comp->RefCount );
 }
 
-/*
- * Ok further analysis makes me think that this work is
- * actually done in the PublishComponents and PublishFeatures
- * step, and not here.  It appears like the keypath and all that is
- * resolved in this step, however actually written in the Publish steps.
- * But we will leave it here for now because it is unclear
- */
 static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
 {
     WCHAR squished_pc[GUID_SIZE];
@@ -2851,8 +2879,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
 
     TRACE("\n");
 
-    /* writes the Component values to the registry */
-
     squash_guid(package->ProductCode,squished_pc);
     ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0);
 
@@ -2869,7 +2895,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
         msi_free(comp->FullKeypath);
         comp->FullKeypath = resolve_keypath( package, comp );
 
-        /* do the refcounting */
         ACTION_RefCountComponent( package, comp );
 
         TRACE("Component %s (%s), Keypath=%s, RefCount=%i\n",
@@ -2877,19 +2902,19 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
                             debugstr_w(squished_cc),
                             debugstr_w(comp->FullKeypath),
                             comp->RefCount);
-        /*
-         * Write the keypath out if the component is to be registered
-         * and delete the key if the component is to be unregistered
-         */
-        if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL))
+
+        if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL) ||
+            ACTION_VerifyComponentForAction( comp, INSTALLSTATE_SOURCE))
         {
             if (!comp->FullKeypath)
                 continue;
 
             if (package->Context == MSIINSTALLCONTEXT_MACHINE)
-                rc = MSIREG_OpenLocalUserDataComponentKey(comp->ComponentId, &hkey, TRUE);
+                rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, szLocalSid,
+                                                     &hkey, TRUE);
             else
-                rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, &hkey, TRUE);
+                rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, NULL,
+                                                     &hkey, TRUE);
 
             if (rc != ERROR_SUCCESS)
                 continue;
@@ -2904,15 +2929,53 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
                 msi_reg_set_val_str(hkey, szPermKey, comp->FullKeypath);
             }
 
-            msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath);
+            if (comp->Action == INSTALLSTATE_LOCAL)
+                msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath);
+            else
+            {
+                MSIFILE *file;
+                MSIRECORD *row;
+                LPWSTR ptr, ptr2;
+                WCHAR source[MAX_PATH];
+                WCHAR base[MAX_PATH];
+                LPWSTR sourcepath;
+
+                static const WCHAR fmt[] = {'%','0','2','d','\\',0};
+                static const WCHAR query[] = {
+                    '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',' ',
+                    '`','D','i','s','k','I','d','`',0};
+
+                file = get_loaded_file(package, comp->KeyPath);
+                if (!file)
+                    continue;
+
+                row = MSI_QueryGetRecord(package->db, query, file->Sequence);
+                sprintfW(source, fmt, MSI_RecordGetInteger(row, 1));
+                ptr2 = strrchrW(source, '\\') + 1;
+                msiobj_release(&row->hdr);
+
+                lstrcpyW(base, package->PackagePath);
+                ptr = strrchrW(base, '\\');
+                *(ptr + 1) = '\0';
+
+                sourcepath = resolve_file_source(package, file);
+                ptr = sourcepath + lstrlenW(base);
+                lstrcpyW(ptr2, ptr);
+                msi_free(sourcepath);
+
+                msi_reg_set_val_str(hkey, squished_pc, source);
+            }
             RegCloseKey(hkey);
         }
         else if (ACTION_VerifyComponentForAction(comp, INSTALLSTATE_ABSENT))
         {
             if (package->Context == MSIINSTALLCONTEXT_MACHINE)
-                MSIREG_DeleteLocalUserDataComponentKey(comp->ComponentId);
+                MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid);
             else
-                MSIREG_DeleteUserDataComponentKey(comp->ComponentId);
+                MSIREG_DeleteUserDataComponentKey(comp->ComponentId, NULL);
         }
 
         /* UI stuff */
@@ -2963,7 +3026,7 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType,
 
     TRACE("trying %s\n", debugstr_w(tl_struct->path));
     res = LoadTypeLib(tl_struct->path,&tl_struct->ptLib);
-    if (!SUCCEEDED(res))
+    if (FAILED(res))
     {
         msi_free(tl_struct->path);
         tl_struct->path = NULL;
@@ -2994,7 +3057,10 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
     MSICOMPONENT *comp;
     MSIFILE *file;
     typelib_struct tl_struct;
+    ITypeLib *tlib;
     HMODULE module;
+    HRESULT hr;
+
     static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
 
     component = MSI_RecordGetString(row,3);
@@ -3042,7 +3108,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
             res = RegisterTypeLib(tl_struct.ptLib,tl_struct.path,help);
             msi_free(help);
 
-            if (!SUCCEEDED(res))
+            if (FAILED(res))
                 ERR("Failed to register type library %s\n",
                         debugstr_w(tl_struct.path));
             else
@@ -3063,7 +3129,16 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
         msi_free(tl_struct.source);
     }
     else
-        ERR("Could not load file! %s\n", debugstr_w(file->TargetPath));
+    {
+        hr = LoadTypeLibEx(file->TargetPath, REGKIND_REGISTER, &tlib);
+        if (FAILED(hr))
+        {
+            ERR("Failed to load type library: %08x\n", hr);
+            return ERROR_FUNCTION_FAILED;
+        }
+
+        ITypeLib_Release(tlib);
+    }
 
     return ERROR_SUCCESS;
 }
@@ -3544,6 +3619,39 @@ static BOOL msi_check_unpublish(MSIPACKAGE *package)
     return TRUE;
 }
 
+static UINT msi_publish_patch(MSIPACKAGE *package, HKEY prodkey, HKEY hudkey)
+{
+    WCHAR patch_squashed[GUID_SIZE];
+    HKEY patches;
+    LONG res;
+    UINT r = ERROR_FUNCTION_FAILED;
+
+    static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
+
+    res = RegCreateKeyExW(prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
+                          &patches, NULL);
+    if (res != ERROR_SUCCESS)
+        return ERROR_FUNCTION_FAILED;
+
+    squash_guid(package->patch->patchcode, patch_squashed);
+
+    res = RegSetValueExW(patches, szPatches, 0, REG_MULTI_SZ,
+                         (const BYTE *)patch_squashed,
+                         (lstrlenW(patch_squashed) + 1) * sizeof(WCHAR));
+    if (res != ERROR_SUCCESS)
+        goto done;
+
+    res = RegSetValueExW(patches, patch_squashed, 0, REG_SZ,
+                         (const BYTE *)package->patch->transforms,
+                         (lstrlenW(package->patch->transforms) + 1) * sizeof(WCHAR));
+    if (res == ERROR_SUCCESS)
+        r = ERROR_SUCCESS;
+
+done:
+    RegCloseKey(patches);
+    return r;
+}
+
 /*
  * 99% of the work done here is only done for 
  * advertised installs. However this is where the
@@ -3560,31 +3668,27 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
     if (!msi_check_publish(package))
         return ERROR_SUCCESS;
 
-    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
-    {
-        rc = MSIREG_OpenLocalClassesProductKey(package->ProductCode, &hukey, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
-
-        rc = MSIREG_OpenLocalUserDataProductKey(package->ProductCode, &hudkey, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
-    }
-    else
-    {
-        rc = MSIREG_OpenUserProductsKey(package->ProductCode, &hukey, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
+    rc = MSIREG_OpenProductKey(package->ProductCode, package->Context,
+                               &hukey, TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
 
-        rc = MSIREG_OpenUserDataProductKey(package->ProductCode, &hudkey, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
-    }
+    rc = MSIREG_OpenUserDataProductKey(package->ProductCode, package->Context,
+                                       NULL, &hudkey, TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
 
     rc = msi_publish_upgrade_code(package);
     if (rc != ERROR_SUCCESS)
         goto end;
 
+    if (package->patch)
+    {
+        rc = msi_publish_patch(package, hukey, hudkey);
+        if (rc != ERROR_SUCCESS)
+            goto end;
+    }
+
     rc = msi_publish_product_properties(package, hukey);
     if (rc != ERROR_SUCCESS)
         goto end;
@@ -3605,9 +3709,10 @@ end:
 static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
 {
     MSIPACKAGE *package = (MSIPACKAGE*)param;
-    LPCWSTR component,section,key,value,identifier,filename,dirproperty;
+    LPCWSTR component, section, key, value, identifier, dirproperty;
     LPWSTR deformated_section, deformated_key, deformated_value;
-    LPWSTR folder, fullname = NULL;
+    LPWSTR folder, filename, fullname = NULL;
+    LPCWSTR filenameptr;
     MSIRECORD * uirow;
     INT action;
     MSICOMPONENT *comp;
@@ -3630,7 +3735,6 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
     comp->Action = INSTALLSTATE_LOCAL;
 
     identifier = MSI_RecordGetString(row,1); 
-    filename = MSI_RecordGetString(row,2);
     dirproperty = MSI_RecordGetString(row,3);
     section = MSI_RecordGetString(row,4);
     key = MSI_RecordGetString(row,5);
@@ -3641,6 +3745,12 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
     deformat_string(package,key,&deformated_key);
     deformat_string(package,value,&deformated_value);
 
+    filename = msi_dup_record_field(row, 2);
+    if (filename && (filenameptr = strchrW(filename, '|')))
+        filenameptr++;
+    else
+        filenameptr = filename;
+
     if (dirproperty)
     {
         folder = resolve_folder(package, dirproperty, FALSE, FALSE, TRUE, NULL);
@@ -3656,7 +3766,7 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
         goto cleanup;
     }
 
-    fullname = build_directory_name(2, folder, filename);
+    fullname = build_directory_name(2, folder, filenameptr);
 
     if (action == 0)
     {
@@ -3691,7 +3801,9 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
     MSI_RecordSetStringW(uirow,4,deformated_value);
     ui_actiondata(package,szWriteIniValues,uirow);
     msiobj_release( &uirow->hdr );
+
 cleanup:
+    msi_free(filename);
     msi_free(fullname);
     msi_free(folder);
     msi_free(deformated_key);
@@ -3759,7 +3871,11 @@ static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
                     &si, &info);
 
     if (brc)
+    {
+        CloseHandle(info.hThread);
         msi_dialog_check_messages(info.hProcess);
+        CloseHandle(info.hProcess);
+    }
 
     msi_free(FullName);
 
@@ -3805,34 +3921,20 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
     MSIFEATURE *feature;
     UINT rc;
     HKEY hkey;
-    HKEY userdata;
+    HKEY userdata = NULL;
 
     if (!msi_check_publish(package))
         return ERROR_SUCCESS;
 
-    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
-    {
-        rc = MSIREG_OpenLocalClassesFeaturesKey(package->ProductCode,
-                                                &hkey, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
-
-        rc = MSIREG_OpenLocalUserDataFeaturesKey(package->ProductCode,
-                                                 &userdata, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
-    }
-    else
-    {
-        rc = MSIREG_OpenUserFeaturesKey(package->ProductCode, &hkey, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
+    rc = MSIREG_OpenFeaturesKey(package->ProductCode, package->Context,
+                                &hkey, TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
 
-        rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode,
-                                            &userdata, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto end;
-    }
+    rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context,
+                                        &userdata, TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
 
     /* here the guids are base 85 encoded */
     LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
@@ -3930,14 +4032,16 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature)
 
     TRACE("unpublishing feature %s\n", debugstr_w(feature->Feature));
 
-    r = MSIREG_OpenUserFeaturesKey(package->ProductCode, &hkey, FALSE);
+    r = MSIREG_OpenFeaturesKey(package->ProductCode, package->Context,
+                               &hkey, FALSE);
     if (r == ERROR_SUCCESS)
     {
         RegDeleteValueW(hkey, feature->Feature);
         RegCloseKey(hkey);
     }
 
-    r = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, &hkey, FALSE);
+    r = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context,
+                                       &hkey, FALSE);
     if (r == ERROR_SUCCESS)
     {
         RegDeleteValueW(hkey, feature->Feature);
@@ -4145,18 +4249,10 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
     if (rc != ERROR_SUCCESS)
         return rc;
 
-    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
-    {
-        rc = MSIREG_OpenLocalSystemInstallProps(package->ProductCode, &props, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto done;
-    }
-    else
-    {
-        rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE);
-        if (rc != ERROR_SUCCESS)
-            goto done;
-    }
+    rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context,
+                                 NULL, &props, TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto done;
 
     msi_make_package_local(package, props);
 
@@ -4229,11 +4325,20 @@ static UINT msi_unpublish_product(MSIPACKAGE *package)
         goto done;
 
     MSIREG_DeleteProductKey(package->ProductCode);
-    MSIREG_DeleteUserProductKey(package->ProductCode);
     MSIREG_DeleteUserDataProductKey(package->ProductCode);
-    MSIREG_DeleteUserFeaturesKey(package->ProductCode);
     MSIREG_DeleteUninstallKey(package->ProductCode);
 
+    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
+    {
+        MSIREG_DeleteLocalClassesProductKey(package->ProductCode);
+        MSIREG_DeleteLocalClassesFeaturesKey(package->ProductCode);
+    }
+    else
+    {
+        MSIREG_DeleteUserProductKey(package->ProductCode);
+        MSIREG_DeleteUserFeaturesKey(package->ProductCode);
+    }
+
     upgrade = msi_dup_property(package, szUpgradeCode);
     if (upgrade)
     {
@@ -4405,11 +4510,8 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package)
     if (!productid)
         return ERROR_SUCCESS;
 
-    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
-        rc = MSIREG_OpenLocalSystemInstallProps(package->ProductCode, &hkey, TRUE);
-    else
-        rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &hkey, TRUE);
-
+    rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context,
+                                 NULL, &hkey, TRUE);
     if (rc != ERROR_SUCCESS)
         goto end;
 
@@ -5522,7 +5624,8 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
 {
     MSIPACKAGE *package = param;
     MSICOMPONENT *comp;
-    LPCWSTR sourcename, destname;
+    LPCWSTR sourcename;
+    LPWSTR destname = NULL;
     LPWSTR sourcedir = NULL, destdir = NULL;
     LPWSTR source = NULL, dest = NULL;
     int options;
@@ -5540,7 +5643,6 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
     }
 
     sourcename = MSI_RecordGetString(rec, 3);
-    destname = MSI_RecordGetString(rec, 4);
     options = MSI_RecordGetInteger(rec, 7);
 
     sourcedir = msi_dup_property(package, MSI_RecordGetString(rec, 5));
@@ -5575,11 +5677,20 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
 
     wildcards = strchrW(source, '*') || strchrW(source, '?');
 
-    if (!destname && !wildcards)
+    if (MSI_RecordIsNull(rec, 4))
     {
-        destname = strdupW(sourcename);
-        if (!destname)
-            goto done;
+        if (!wildcards)
+        {
+            destname = strdupW(sourcename);
+            if (!destname)
+                goto done;
+        }
+    }
+    else
+    {
+        destname = strdupW(MSI_RecordGetString(rec, 4));
+        if (destname)
+            reduce_to_longfilename(destname);
     }
 
     size = 0;
@@ -5616,6 +5727,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
 done:
     msi_free(sourcedir);
     msi_free(destdir);
+    msi_free(destname);
     msi_free(source);
     msi_free(dest);
 
@@ -5641,6 +5753,18 @@ static UINT ACTION_MoveFiles( MSIPACKAGE *package )
     return rc;
 }
 
+typedef struct tagMSIASSEMBLY
+{
+    struct list entry;
+    MSICOMPONENT *component;
+    MSIFEATURE *feature;
+    MSIFILE *file;
+    LPWSTR manifest;
+    LPWSTR application;
+    DWORD attributes;
+    BOOL installed;
+} MSIASSEMBLY;
+
 static HRESULT (WINAPI *pCreateAssemblyCache)(IAssemblyCache **ppAsmCache,
                                               DWORD dwReserved);
 static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion,
@@ -5683,14 +5807,32 @@ static BOOL init_functionpointers(void)
     return TRUE;
 }
 
-static UINT install_assembly(LPWSTR path)
+static UINT install_assembly(MSIPACKAGE *package, MSIASSEMBLY *assembly,
+                             LPWSTR path)
 {
     IAssemblyCache *cache;
     HRESULT hr;
     UINT r = ERROR_FUNCTION_FAILED;
 
-    if (!init_functionpointers() || !pCreateAssemblyCache)
-        return ERROR_FUNCTION_FAILED;
+    TRACE("installing assembly: %s\n", debugstr_w(path));
+
+    if (assembly->feature)
+        msi_feature_set_state(package, assembly->feature, INSTALLSTATE_LOCAL);
+
+    if (assembly->manifest)
+        FIXME("Manifest unhandled\n");
+
+    if (assembly->application)
+    {
+        FIXME("Assembly should be privately installed\n");
+        return ERROR_SUCCESS;
+    }
+
+    if (assembly->attributes == msidbAssemblyAttributesWin32)
+    {
+        FIXME("Win32 assemblies not handled\n");
+        return ERROR_SUCCESS;
+    }
 
     hr = pCreateAssemblyCache(&cache, 0);
     if (FAILED(hr))
@@ -5707,106 +5849,350 @@ done:
     return r;
 }
 
-static UINT ITERATE_PublishAssembly( MSIRECORD *rec, LPVOID param )
+typedef struct tagASSEMBLY_LIST
 {
-    MSIPACKAGE *package = param;
-    MSICOMPONENT *comp;
-    MSIFEATURE *feature;
-    MSIFILE *file;
-    WCHAR path[MAX_PATH];
-    LPCWSTR app;
-    DWORD attr;
-    UINT r;
+    MSIPACKAGE *package;
+    IAssemblyCache *cache;
+    struct list *assemblies;
+} ASSEMBLY_LIST;
+
+typedef struct tagASSEMBLY_NAME
+{
+    LPWSTR name;
+    LPWSTR version;
+    LPWSTR culture;
+    LPWSTR pubkeytoken;
+} ASSEMBLY_NAME;
+
+static UINT parse_assembly_name(MSIRECORD *rec, LPVOID param)
+{
+    ASSEMBLY_NAME *asmname = (ASSEMBLY_NAME *)param;
+    LPCWSTR name = MSI_RecordGetString(rec, 2);
+    LPWSTR val = msi_dup_record_field(rec, 3);
+
+    static const WCHAR Name[] = {'N','a','m','e',0};
+    static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
+    static const WCHAR Culture[] = {'C','u','l','t','u','r','e',0};
+    static const WCHAR PublicKeyToken[] = {
+        'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
+
+    if (!lstrcmpW(name, Name))
+        asmname->name = val;
+    else if (!lstrcmpW(name, Version))
+        asmname->version = val;
+    else if (!lstrcmpW(name, Culture))
+        asmname->culture = val;
+    else if (!lstrcmpW(name, PublicKeyToken))
+        asmname->pubkeytoken = val;
+    else
+        msi_free(val);
 
-    comp = get_loaded_component(package, MSI_RecordGetString(rec, 1));
-    if (!comp || !comp->Enabled ||
-        !(comp->Action & (INSTALLSTATE_LOCAL | INSTALLSTATE_SOURCE)))
+    return ERROR_SUCCESS;
+}
+
+static void append_str(LPWSTR *str, DWORD *size, LPCWSTR append)
+{
+    if (!*str)
     {
-        ERR("Component not set for install, not publishing assembly\n");
+        *size = lstrlenW(append) + 1;
+        *str = msi_alloc((*size) * sizeof(WCHAR));
+        lstrcpyW(*str, append);
+        return;
+    }
+
+    (*size) += lstrlenW(append);
+    *str = msi_realloc(*str, (*size) * sizeof(WCHAR));
+    lstrcatW(*str, append);
+}
+
+static BOOL check_assembly_installed(MSIDATABASE *db, IAssemblyCache *cache,
+                                     MSICOMPONENT *comp)
+{
+    ASSEMBLY_INFO asminfo;
+    ASSEMBLY_NAME name;
+    MSIQUERY *view;
+    LPWSTR disp;
+    DWORD size;
+    BOOL found;
+    UINT r;
+
+    static const WCHAR separator[] = {',',' ',0};
+    static const WCHAR Version[] = {'V','e','r','s','i','o','n','=',0};
+    static const WCHAR Culture[] = {'C','u','l','t','u','r','e','=',0};
+    static const WCHAR PublicKeyToken[] = {
+        'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0};
+    static const WCHAR query[] = {
+        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+        '`','M','s','i','A','s','s','e','m','b','l','y','N','a','m','e','`',' ',
+        'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
+        '=','\'','%','s','\'',0};
+
+    disp = NULL;
+    found = FALSE;
+    ZeroMemory(&name, sizeof(ASSEMBLY_NAME));
+    ZeroMemory(&asminfo, sizeof(ASSEMBLY_INFO));
+
+    r = MSI_OpenQuery(db, &view, query, comp->Component);
+    if (r != ERROR_SUCCESS)
         return ERROR_SUCCESS;
+
+    MSI_IterateRecords(view, NULL, parse_assembly_name, &name);
+    msiobj_release(&view->hdr);
+
+    if (!name.name)
+    {
+        ERR("No assembly name specified!\n");
+        goto done;
     }
 
-    feature = find_feature_by_name(package, MSI_RecordGetString(rec, 2));
-    if (feature)
-        msi_feature_set_state(feature, INSTALLSTATE_LOCAL);
+    append_str(&disp, &size, name.name);
 
-    if (MSI_RecordGetString(rec, 3))
-        FIXME("Manifest unhandled\n");
+    if (name.version)
+    {
+        append_str(&disp, &size, separator);
+        append_str(&disp, &size, Version);
+        append_str(&disp, &size, name.version);
+    }
 
-    app = MSI_RecordGetString(rec, 4);
-    if (app)
+    if (name.culture)
     {
-        FIXME("Assembly should be privately installed\n");
-        return ERROR_SUCCESS;
+        append_str(&disp, &size, separator);
+        append_str(&disp, &size, Culture);
+        append_str(&disp, &size, name.culture);
     }
 
-    attr = MSI_RecordGetInteger(rec, 5);
-    if (attr == msidbAssemblyAttributesWin32)
+    if (name.pubkeytoken)
     {
-        FIXME("Win32 assemblies not handled\n");
+        append_str(&disp, &size, separator);
+        append_str(&disp, &size, PublicKeyToken);
+        append_str(&disp, &size, name.pubkeytoken);
+    }
+
+    asminfo.cbAssemblyInfo = sizeof(ASSEMBLY_INFO);
+    IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE,
+                                     disp, &asminfo);
+    found = (asminfo.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED);
+
+done:
+    msiobj_release(&view->hdr);
+    msi_free(disp);
+    msi_free(name.name);
+    msi_free(name.version);
+    msi_free(name.culture);
+    msi_free(name.pubkeytoken);
+
+    return found;
+}
+
+static UINT load_assembly(MSIRECORD *rec, LPVOID param)
+{
+    ASSEMBLY_LIST *list = (ASSEMBLY_LIST *)param;
+    MSIASSEMBLY *assembly;
+
+    assembly = msi_alloc_zero(sizeof(MSIASSEMBLY));
+    if (!assembly)
+        return ERROR_OUTOFMEMORY;
+
+    assembly->component = get_loaded_component(list->package, MSI_RecordGetString(rec, 1));
+
+    if (!assembly->component || !assembly->component->Enabled ||
+        !(assembly->component->Action & (INSTALLSTATE_LOCAL | INSTALLSTATE_SOURCE)))
+    {
+        TRACE("Component not set for install, not publishing assembly\n");
+        msi_free(assembly);
         return ERROR_SUCCESS;
     }
 
-    /* FIXME: extract all files belonging to this component */
-    file = msi_find_file(package, comp->KeyPath);
-    if (!file)
+    assembly->feature = find_feature_by_name(list->package, MSI_RecordGetString(rec, 2));
+    assembly->file = msi_find_file(list->package, assembly->component->KeyPath);
+
+    if (!assembly->file)
     {
-        ERR("File %s not found\n", debugstr_w(comp->KeyPath));
+        ERR("File %s not found\n", debugstr_w(assembly->component->KeyPath));
         return ERROR_FUNCTION_FAILED;
     }
 
-    GetTempPathW(MAX_PATH, path);
+    assembly->manifest = strdupW(MSI_RecordGetString(rec, 3));
+    assembly->application = strdupW(MSI_RecordGetString(rec, 4));
+    assembly->attributes = MSI_RecordGetInteger(rec, 5);
+    assembly->installed = check_assembly_installed(list->package->db,
+                                                   list->cache,
+                                                   assembly->component);
+
+    list_add_head(list->assemblies, &assembly->entry);
+    return ERROR_SUCCESS;
+}
+
+static UINT load_assemblies(MSIPACKAGE *package, struct list *assemblies)
+{
+    IAssemblyCache *cache = NULL;
+    ASSEMBLY_LIST list;
+    MSIQUERY *view;
+    HRESULT hr;
+    UINT r;
+
+    static const WCHAR query[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         '`','M','s','i','A','s','s','e','m','b','l','y','`',0};
+
+    r = MSI_DatabaseOpenViewW(package->db, query, &view);
+    if (r != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    hr = pCreateAssemblyCache(&cache, 0);
+    if (FAILED(hr))
+        return ERROR_FUNCTION_FAILED;
+
+    list.package = package;
+    list.cache = cache;
+    list.assemblies = assemblies;
+
+    r = MSI_IterateRecords(view, NULL, load_assembly, &list);
+    msiobj_release(&view->hdr);
+
+    IAssemblyCache_Release(cache);
+
+    return r;
+}
 
-    if (file->IsCompressed)
+static void free_assemblies(struct list *assemblies)
+{
+    struct list *item, *cursor;
+
+    LIST_FOR_EACH_SAFE(item, cursor, assemblies)
     {
-        r = msi_extract_file(package, file, path);
-        if (r != ERROR_SUCCESS)
-        {
-            ERR("Failed to extract temporary assembly\n");
-            return r;
-        }
+        MSIASSEMBLY *assembly = LIST_ENTRY(item, MSIASSEMBLY, entry);
 
-        PathAddBackslashW(path);
-        lstrcatW(path, file->FileName);
+        list_remove(&assembly->entry);
+        msi_free(assembly->application);
+        msi_free(assembly->manifest);
+        msi_free(assembly);
     }
-    else
-    {
-        PathAddBackslashW(path);
-        lstrcatW(path, file->FileName);
+}
+
+static BOOL find_assembly(struct list *assemblies, LPCWSTR file, MSIASSEMBLY **out)
+{
+    MSIASSEMBLY *assembly;
 
-        if (!CopyFileW(file->SourcePath, path, FALSE))
+    LIST_FOR_EACH_ENTRY(assembly, assemblies, MSIASSEMBLY, entry)
+    {
+        if (!lstrcmpW(assembly->file->File, file))
         {
-            ERR("Failed to copy temporary assembly: %d\n", GetLastError());
-            return ERROR_FUNCTION_FAILED;
+            *out = assembly;
+            return TRUE;
         }
     }
 
-    r = install_assembly(path);
-    if (r != ERROR_SUCCESS)
-        ERR("Failed to install assembly\n");
+    return FALSE;
+}
 
-    /* FIXME: write Installer assembly reg values */
+static BOOL installassembly_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
+                               LPWSTR *path, DWORD *attrs, PVOID user)
+{
+    MSIASSEMBLY *assembly;
+    WCHAR temppath[MAX_PATH];
+    struct list *assemblies = (struct list *)user;
+    UINT r;
 
-    return r;
+    if (!find_assembly(assemblies, file, &assembly))
+        return FALSE;
+
+    GetTempPathW(MAX_PATH, temppath);
+    PathAddBackslashW(temppath);
+    lstrcatW(temppath, assembly->file->FileName);
+
+    if (action == MSICABEXTRACT_BEGINEXTRACT)
+    {
+        if (assembly->installed)
+            return FALSE;
+
+        *path = strdupW(temppath);
+        *attrs = assembly->file->Attributes;
+    }
+    else if (action == MSICABEXTRACT_FILEEXTRACTED)
+    {
+        assembly->installed = TRUE;
+
+        r = install_assembly(package, assembly, temppath);
+        if (r != ERROR_SUCCESS)
+            ERR("Failed to install assembly\n");
+    }
+
+    return TRUE;
 }
 
 static UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package )
 {
-    UINT rc;
-    MSIQUERY *view;
+    UINT r;
+    struct list assemblies = LIST_INIT(assemblies);
+    MSIASSEMBLY *assembly;
+    MSIMEDIAINFO *mi;
 
-    static const WCHAR ExecSeqQuery[] =
-        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
-         '`','M','s','i','A','s','s','e','m','b','l','y','`',0};
+    if (!init_functionpointers() || !pCreateAssemblyCache)
+        return ERROR_FUNCTION_FAILED;
 
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
-    if (rc != ERROR_SUCCESS)
-        return ERROR_SUCCESS;
+    r = load_assemblies(package, &assemblies);
+    if (r != ERROR_SUCCESS)
+        goto done;
 
-    rc = MSI_IterateRecords(view, NULL, ITERATE_PublishAssembly, package);
-    msiobj_release(&view->hdr);
+    if (list_empty(&assemblies))
+        goto done;
 
-    return rc;
+    mi = msi_alloc_zero(sizeof(MSIMEDIAINFO));
+    if (!mi)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    LIST_FOR_EACH_ENTRY(assembly, &assemblies, MSIASSEMBLY, entry)
+    {
+        if (assembly->installed && !mi->is_continuous)
+            continue;
+
+        if (assembly->file->Sequence > mi->last_sequence || mi->is_continuous ||
+            (assembly->file->IsCompressed && !mi->is_extracted))
+        {
+            MSICABDATA data;
+
+            r = ready_media(package, assembly->file, mi);
+            if (r != ERROR_SUCCESS)
+            {
+                ERR("Failed to ready media\n");
+                break;
+            }
+
+            data.mi = mi;
+            data.package = package;
+            data.cb = installassembly_cb;
+            data.user = &assemblies;
+
+            if (assembly->file->IsCompressed &&
+                !msi_cabextract(package, mi, &data))
+            {
+                ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
+                r = ERROR_FUNCTION_FAILED;
+                break;
+            }
+        }
+
+        if (!assembly->file->IsCompressed)
+        {
+            LPWSTR source = resolve_file_source(package, assembly->file);
+
+            r = install_assembly(package, assembly, source);
+            if (r != ERROR_SUCCESS)
+                ERR("Failed to install assembly\n");
+
+            msi_free(source);
+        }
+
+        /* FIXME: write Installer assembly reg values */
+    }
+
+done:
+    free_assemblies(&assemblies);
+    return r;
 }
 
 static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
index 892ad35..3252f6a 100644 (file)
@@ -242,6 +242,7 @@ static const MSIVIEWOPS alter_ops =
     NULL,
     NULL,
     NULL,
+    NULL,
 };
 
 UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, column_info *colinfo, int hold )
index 0743aee..dc885bc 100644 (file)
@@ -155,6 +155,73 @@ static void ACTION_FreeSignature(MSISIGNATURE *sig)
     msi_free(sig->Languages);
 }
 
+static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig)
+{
+    VS_FIXEDFILEINFO *info;
+    DWORD attr, handle, size;
+    LPWSTR val = NULL;
+    LPBYTE buffer;
+
+    static const WCHAR root[] = {'\\',0};
+
+    if (!sig->File)
+    {
+        PathRemoveFileSpecW(path);
+        PathAddBackslashW(path);
+
+        attr = GetFileAttributesW(path);
+        if (attr != INVALID_FILE_ATTRIBUTES &&
+            (attr & FILE_ATTRIBUTE_DIRECTORY))
+            return strdupW(path);
+
+        return NULL;
+    }
+
+    attr = GetFileAttributesW(path);
+    if (attr == INVALID_FILE_ATTRIBUTES || attr == FILE_ATTRIBUTE_DIRECTORY)
+        return NULL;
+
+    size = GetFileVersionInfoSizeW(path, &handle);
+    if (!size)
+        return strdupW(path);
+
+    buffer = msi_alloc(size);
+    if (!buffer)
+        return NULL;
+
+    if (!GetFileVersionInfoW(path, 0, size, buffer))
+        goto done;
+
+    if (!VerQueryValueW(buffer, root, (LPVOID)&info, &size) || !info)
+        goto done;
+
+    if (sig->MinVersionLS || sig->MinVersionMS)
+    {
+        if (info->dwFileVersionMS < sig->MinVersionMS)
+            goto done;
+
+        if (info->dwFileVersionMS == sig->MinVersionMS &&
+            info->dwFileVersionLS < sig->MinVersionLS)
+            goto done;
+    }
+
+    if (sig->MaxVersionLS || sig->MaxVersionMS)
+    {
+        if (info->dwFileVersionMS > sig->MaxVersionMS)
+            goto done;
+
+        if (info->dwFileVersionMS == sig->MaxVersionMS &&
+            info->dwFileVersionLS > sig->MaxVersionLS)
+            goto done;
+    }
+
+    val = strdupW(path);
+
+done:
+    msi_free(buffer);
+    return val;
+}
+
 static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig)
 {
     static const WCHAR query[] =  {
@@ -211,7 +278,7 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS
 
     if (type != msidbLocatorTypeDirectory && sigpresent && !isdir)
     {
-        *appValue = strdupW(path);
+        *appValue = app_search_file(path, sig);
     }
     else if (!sigpresent && (type != msidbLocatorTypeDirectory || isdir))
     {
@@ -225,6 +292,15 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS
 
         *appValue = strdupW(path);
     }
+    else if (sigpresent)
+    {
+        PathAddBackslashW(path);
+        lstrcatW(path, MSI_RecordGetString(rec, 2));
+
+        attr = GetFileAttributesW(path);
+        if (attr != INVALID_FILE_ATTRIBUTES && attr != FILE_ATTRIBUTE_DIRECTORY)
+            *appValue = strdupW(path);
+    }
 
 done:
     if (rec) msiobj_release(&rec->hdr);
@@ -236,8 +312,9 @@ static void ACTION_ConvertRegValue(DWORD regType, const BYTE *value, DWORD sz,
  LPWSTR *appValue)
 {
     static const WCHAR dwordFmt[] = { '#','%','d','\0' };
-    static const WCHAR expandSzFmt[] = { '#','%','%','%','s','\0' };
-    static const WCHAR binFmt[] = { '#','x','%','x','\0' };
+    static const WCHAR binPre[] = { '#','x','\0' };
+    static const WCHAR binFmt[] = { '%','0','2','X','\0' };
+    LPWSTR ptr;
     DWORD i;
 
     switch (regType)
@@ -264,15 +341,17 @@ static void ACTION_ConvertRegValue(DWORD regType, const BYTE *value, DWORD sz,
             sprintfW(*appValue, dwordFmt, *(const DWORD *)value);
             break;
         case REG_EXPAND_SZ:
-            /* space for extra #% characters in front */
-            *appValue = msi_alloc(sz + 2 * sizeof(WCHAR));
-            sprintfW(*appValue, expandSzFmt, (LPCWSTR)value);
+            sz = ExpandEnvironmentStringsW((LPCWSTR)value, NULL, 0);
+            *appValue = msi_alloc(sz * sizeof(WCHAR));
+            ExpandEnvironmentStringsW((LPCWSTR)value, *appValue, sz);
             break;
         case REG_BINARY:
-            /* 3 == length of "#x<nibble>" */
-            *appValue = msi_alloc((sz * 3 + 1) * sizeof(WCHAR));
-            for (i = 0; i < sz; i++)
-                sprintfW(*appValue + i * 3, binFmt, value[i]);
+            /* #x<nibbles>\0 */
+            *appValue = msi_alloc((sz * 2 + 3) * sizeof(WCHAR));
+            lstrcpyW(*appValue, binPre);
+            ptr = *appValue + lstrlenW(binPre);
+            for (i = 0; i < sz; i++, ptr += 2)
+                sprintfW(ptr, binFmt, value[i]);
             break;
         default:
             WARN("unimplemented for values of type %d\n", regType);
@@ -293,6 +372,7 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNAT
         'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0};
     LPWSTR keyPath = NULL, valueName = NULL;
     LPWSTR deformatted = NULL;
+    LPWSTR ptr = NULL, end;
     int root, type;
     HKEY rootKey, key = NULL;
     DWORD sz = 0, regType;
@@ -365,13 +445,18 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNAT
     if (sz == 0)
         goto end;
 
+    if ((ptr = strchrW((LPWSTR)value, '"')) && (end = strchrW(++ptr, '"')))
+        *end = '\0';
+    else
+        ptr = (LPWSTR)value;
+
     switch (type & 0x0f)
     {
     case msidbLocatorTypeDirectory:
-        rc = ACTION_SearchDirectory(package, sig, (LPWSTR)value, 0, appValue);
+        rc = ACTION_SearchDirectory(package, sig, ptr, 0, appValue);
         break;
     case msidbLocatorTypeFileName:
-        *appValue = strdupW((LPWSTR)value);
+        *appValue = app_search_file(ptr, sig);
         break;
     case msidbLocatorTypeRawValue:
         ACTION_ConvertRegValue(regType, value, sz, appValue);
@@ -393,6 +478,32 @@ end:
     return ERROR_SUCCESS;
 }
 
+static LPWSTR get_ini_field(LPWSTR buf, int field)
+{
+    LPWSTR beg, end;
+    int i = 1;
+
+    if (field == 0)
+        return strdupW(buf);
+
+    beg = buf;
+    while ((end = strchrW(beg, ',')) && i < field)
+    {
+        beg = end + 1;
+        while (*beg && *beg == ' ')
+            beg++;
+
+        i++;
+    }
+
+    end = strchrW(beg, ',');
+    if (!end)
+        end = beg + lstrlenW(beg);
+
+    *end = '\0';
+    return strdupW(beg);
+}
+
 static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue,
  MSISIGNATURE *sig)
 {
@@ -434,13 +545,13 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue,
         switch (type & 0x0f)
         {
         case msidbLocatorTypeDirectory:
-            FIXME("unimplemented for Directory (%s)\n", debugstr_w(buf));
+            ACTION_SearchDirectory(package, sig, buf, 0, appValue);
             break;
         case msidbLocatorTypeFileName:
-            FIXME("unimplemented for File (%s)\n", debugstr_w(buf));
+            *appValue = app_search_file(buf, sig);
             break;
         case msidbLocatorTypeRawValue:
-            *appValue = strdupW(buf);
+            *appValue = get_ini_field(buf, field);
             break;
         }
     }
@@ -483,7 +594,7 @@ static void ACTION_ExpandAnyPath(MSIPACKAGE *package, WCHAR *src, WCHAR *dst,
         ptr = src;
 
     deformat_string(package, ptr, &deformatted);
-    if (!deformatted || lstrlenW(deformatted) > len - 1)
+    if (!deformatted || strlenW(deformatted) > len - 1)
     {
         msi_free(deformatted);
         return;
@@ -546,11 +657,12 @@ static UINT ACTION_FileVersionMatches(const MSISIGNATURE *sig, LPCWSTR filePath,
                          HIWORD(sig->MinVersionLS),
                          LOWORD(sig->MinVersionLS));
                     }
-                    else if (info->dwFileVersionMS < sig->MinVersionMS
-                     || (info->dwFileVersionMS == sig->MinVersionMS &&
-                     info->dwFileVersionLS < sig->MinVersionLS))
+                    else if ((sig->MaxVersionMS || sig->MaxVersionLS) &&
+                             (info->dwFileVersionMS > sig->MaxVersionMS ||
+                              (info->dwFileVersionMS == sig->MaxVersionMS &&
+                               info->dwFileVersionLS > sig->MaxVersionLS)))
                     {
-                        TRACE("Greater than minimum version %d.%d.%d.%d\n",
+                        TRACE("Greater than maximum version %d.%d.%d.%d\n",
                          HIWORD(sig->MaxVersionMS),
                          LOWORD(sig->MaxVersionMS),
                          HIWORD(sig->MaxVersionLS),
@@ -622,79 +734,92 @@ static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig,
 static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
  MSISIGNATURE *sig, LPCWSTR dir, int depth)
 {
-    static const WCHAR starDotStarW[] = { '*','.','*',0 };
+    HANDLE hFind;
+    WIN32_FIND_DATAW findData;
     UINT rc = ERROR_SUCCESS;
     size_t dirLen = lstrlenW(dir), fileLen = lstrlenW(sig->File);
+    WCHAR subpath[MAX_PATH];
     WCHAR *buf;
 
+    static const WCHAR dot[] = {'.',0};
+    static const WCHAR dotdot[] = {'.','.',0};
+    static const WCHAR starDotStarW[] = { '*','.','*',0 };
+
     TRACE("Searching directory %s for file %s, depth %d\n", debugstr_w(dir),
-     debugstr_w(sig->File), depth);
+          debugstr_w(sig->File), depth);
 
     if (depth < 0)
-        return ERROR_INVALID_PARAMETER;
+        return ERROR_SUCCESS;
 
     *appValue = NULL;
     /* We need the buffer in both paths below, so go ahead and allocate it
      * here.  Add two because we might need to add a backslash if the dir name
      * isn't backslash-terminated.
      */
-    buf = msi_alloc( (dirLen + max(fileLen, lstrlenW(starDotStarW)) + 2) * sizeof(WCHAR));
-    if (buf)
-    {
-        /* a depth of 0 implies we should search dir, so go ahead and search */
-        HANDLE hFind;
-        WIN32_FIND_DATAW findData;
+    buf = msi_alloc( (dirLen + max(fileLen, strlenW(starDotStarW)) + 2) * sizeof(WCHAR));
+    if (!buf)
+        return ERROR_OUTOFMEMORY;
 
-        memcpy(buf, dir, dirLen * sizeof(WCHAR));
-        if (buf[dirLen - 1] != '\\')
-            buf[dirLen++ - 1] = '\\';
-        memcpy(buf + dirLen, sig->File, (fileLen + 1) * sizeof(WCHAR));
-        hFind = FindFirstFileW(buf, &findData);
-        if (hFind != INVALID_HANDLE_VALUE)
+    lstrcpyW(buf, dir);
+    PathAddBackslashW(buf);
+    lstrcatW(buf, sig->File);
+
+    hFind = FindFirstFileW(buf, &findData);
+    if (hFind != INVALID_HANDLE_VALUE)
+    {
+        if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
         {
             BOOL matches;
 
-            /* assuming Signature can't contain wildcards for the file name,
-             * so don't bother with FindNextFileW here.
-             */
-            if (!(rc = ACTION_FileMatchesSig(sig, &findData, buf, &matches))
-             && matches)
+            rc = ACTION_FileMatchesSig(sig, &findData, buf, &matches);
+            if (rc == ERROR_SUCCESS && matches)
             {
                 TRACE("found file, returning %s\n", debugstr_w(buf));
                 *appValue = buf;
             }
-            FindClose(hFind);
         }
-        if (rc == ERROR_SUCCESS && !*appValue && depth > 0)
+        FindClose(hFind);
+    }
+
+    if (rc == ERROR_SUCCESS && !*appValue)
+    {
+        lstrcpyW(buf, dir);
+        PathAddBackslashW(buf);
+        lstrcatW(buf, starDotStarW);
+
+        hFind = FindFirstFileW(buf, &findData);
+        if (hFind != INVALID_HANDLE_VALUE)
         {
-            HANDLE hFind;
-            WIN32_FIND_DATAW findData;
-
-            memcpy(buf, dir, dirLen * sizeof(WCHAR));
-            if (buf[dirLen - 1] != '\\')
-                buf[dirLen++ - 1] = '\\';
-            lstrcpyW(buf + dirLen, starDotStarW);
-            hFind = FindFirstFileW(buf, &findData);
-            if (hFind != INVALID_HANDLE_VALUE)
+            if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
+                lstrcmpW(findData.cFileName, dot) &&
+                lstrcmpW(findData.cFileName, dotdot))
+            {
+                lstrcpyW(subpath, dir);
+                PathAppendW(subpath, findData.cFileName);
+                rc = ACTION_RecurseSearchDirectory(package, appValue, sig,
+                                                   subpath, depth - 1);
+            }
+
+            while (rc == ERROR_SUCCESS && !*appValue &&
+                   FindNextFileW(hFind, &findData) != 0)
             {
+                if (!lstrcmpW(findData.cFileName, dot) ||
+                    !lstrcmpW(findData.cFileName, dotdot))
+                    continue;
+
+                lstrcpyW(subpath, dir);
+                PathAppendW(subpath, findData.cFileName);
                 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                    rc = ACTION_RecurseSearchDirectory(package, appValue, sig,
-                     findData.cFileName, depth - 1);
-                while (rc == ERROR_SUCCESS && !*appValue &&
-                 FindNextFileW(hFind, &findData) != 0)
-                {
-                    if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                        rc = ACTION_RecurseSearchDirectory(package, appValue,
-                         sig, findData.cFileName, depth - 1);
-                }
-                FindClose(hFind);
+                    rc = ACTION_RecurseSearchDirectory(package, appValue,
+                                                       sig, subpath, depth - 1);
             }
+
+            FindClose(hFind);
         }
-        if (!*appValue)
-            msi_free(buf);
     }
-    else
-        rc = ERROR_OUTOFMEMORY;
+
+    if (!*appValue)
+        msi_free(buf);
 
     return rc;
 }
@@ -731,20 +856,22 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
  LPCWSTR path, int depth, LPWSTR *appValue)
 {
     UINT rc;
+    DWORD attr;
+    LPWSTR val = NULL;
 
     TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth,
      appValue);
+
     if (ACTION_IsFullPath(path))
     {
         if (sig->File)
-            rc = ACTION_RecurseSearchDirectory(package, appValue, sig,
-             path, depth);
+            rc = ACTION_RecurseSearchDirectory(package, &val, sig, path, depth);
         else
         {
             /* Recursively searching a directory makes no sense when the
              * directory to search is the thing you're trying to find.
              */
-            rc = ACTION_CheckDirectory(package, path, appValue);
+            rc = ACTION_CheckDirectory(package, path, &val);
         }
     }
     else
@@ -754,24 +881,39 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
         int i;
 
         rc = ERROR_SUCCESS;
-        *appValue = NULL;
-        for (i = 0; rc == ERROR_SUCCESS && !*appValue && i < 26; i++)
-            if (drives & (1 << i))
-            {
-                pathWithDrive[0] = 'A' + i;
-                if (GetDriveTypeW(pathWithDrive) == DRIVE_FIXED)
-                {
-                    lstrcpynW(pathWithDrive + 3, path,
-                              sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3);
-                    if (sig->File)
-                        rc = ACTION_RecurseSearchDirectory(package, appValue,
-                         sig, pathWithDrive, depth);
-                    else
-                        rc = ACTION_CheckDirectory(package, pathWithDrive,
-                         appValue);
-                }
-            }
+        for (i = 0; rc == ERROR_SUCCESS && !val && i < 26; i++)
+        {
+            if (!(drives & (1 << i)))
+                continue;
+
+            pathWithDrive[0] = 'A' + i;
+            if (GetDriveTypeW(pathWithDrive) != DRIVE_FIXED)
+                continue;
+
+            lstrcpynW(pathWithDrive + 3, path,
+                      sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3);
+
+            if (sig->File)
+                rc = ACTION_RecurseSearchDirectory(package, &val, sig,
+                                                   pathWithDrive, depth);
+            else
+                rc = ACTION_CheckDirectory(package, pathWithDrive, &val);
+        }
+    }
+
+    attr = GetFileAttributesW(val);
+    if ((attr & FILE_ATTRIBUTE_DIRECTORY) &&
+        val && val[lstrlenW(val) - 1] != '\\')
+    {
+        val = msi_realloc(val, (lstrlenW(val) + 2) * sizeof(WCHAR));
+        if (!val)
+            rc = ERROR_OUTOFMEMORY;
+        else
+            PathAddBackslashW(val);
     }
+
+    *appValue = val;
+
     TRACE("returning %d\n", rc);
     return rc;
 }
@@ -787,17 +929,16 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU
         'D','r','L','o','c','a','t','o','r',' ',
         'w','h','e','r','e',' ',
         'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0};
-    LPWSTR parentName = NULL, path = NULL, parent = NULL;
+    LPWSTR parentName = NULL, parent = NULL;
+    WCHAR path[MAX_PATH];
     WCHAR expanded[MAX_PATH];
     MSIRECORD *row;
     int depth;
+    DWORD sz;
     UINT rc;
 
     TRACE("%s\n", debugstr_w(sig->Name));
 
-    msi_free(sig->File);
-    sig->File = NULL;
-
     *appValue = NULL;
 
     row = MSI_QueryGetRecord( package->db, query, sig->Name );
@@ -817,33 +958,35 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU
         ACTION_FreeSignature(&parentSig);
         msi_free(parentName);
     }
-    /* now look for path */
-    path = msi_dup_record_field(row,3);
+
+    sz = MAX_PATH;
+    MSI_RecordGetStringW(row, 3, path, &sz);
+
     if (MSI_RecordIsNull(row,4))
         depth = 0;
     else
         depth = MSI_RecordGetInteger(row,4);
+
     ACTION_ExpandAnyPath(package, path, expanded, MAX_PATH);
-    msi_free(path);
+
     if (parent)
     {
-        path = msi_alloc((strlenW(parent) + strlenW(expanded) + 1) * sizeof(WCHAR));
-        if (!path)
+        if (!(GetFileAttributesW(parent) & FILE_ATTRIBUTE_DIRECTORY))
         {
-            rc = ERROR_OUTOFMEMORY;
-            goto end;
+            PathRemoveFileSpecW(parent);
+            PathAddBackslashW(parent);
         }
+
         strcpyW(path, parent);
         strcatW(path, expanded);
     }
     else
-        path = expanded;
+        strcpyW(path, expanded);
+
+    PathAddBackslashW(path);
 
     rc = ACTION_SearchDirectory(package, sig, path, depth, appValue);
 
-end:
-    if (path != expanded)
-        msi_free(path);
     msi_free(parent);
     msiobj_release(&row->hdr);
 
index c15126a..3b01266 100644 (file)
@@ -336,7 +336,7 @@ static HRESULT WINAPI AutomationObject_GetIDsOfNames(
     hr = ITypeInfo_GetIDsOfNames(This->iTypeInfo, rgszNames, cNames, rgDispId);
     if (hr == DISP_E_UNKNOWNNAME)
     {
-        int idx;
+        UINT idx;
         for (idx=0; idx<cNames; idx++)
         {
             if (rgDispId[idx] == DISPID_UNKNOWN)
@@ -441,7 +441,7 @@ static HRESULT WINAPI AutomationObject_Invoke(
     if (pVarResult == &varResultDummy) VariantClear(pVarResult);
 
     /* Free function name if we retrieved it */
-    if (bstrName) SysFreeString(bstrName);
+    SysFreeString(bstrName);
 
     TRACE("Returning 0x%08x, %s\n", hr, SUCCEEDED(hr) ? "ok" : "not ok");
 
@@ -618,7 +618,7 @@ static ULONG WINAPI ListEnumerator_Release(IEnumVARIANT* iface)
 static HRESULT WINAPI ListEnumerator_Next(IEnumVARIANT* iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
 {
     ListEnumerator *This = (ListEnumerator *)iface;
-    ListData *data = (ListData *)private_data(This->pObj);
+    ListData *data = private_data(This->pObj);
     ULONG idx, local;
 
     TRACE("(%p,%uld,%p,%p)\n", iface, celt, rgVar, pCeltFetched);
@@ -645,7 +645,7 @@ static HRESULT WINAPI ListEnumerator_Next(IEnumVARIANT* iface, ULONG celt, VARIA
 static HRESULT WINAPI ListEnumerator_Skip(IEnumVARIANT* iface, ULONG celt)
 {
     ListEnumerator *This = (ListEnumerator *)iface;
-    ListData *data = (ListData *)private_data(This->pObj);
+    ListData *data = private_data(This->pObj);
 
     TRACE("(%p,%uld)\n", iface, celt);
 
@@ -708,7 +708,7 @@ static const struct IEnumVARIANTVtbl ListEnumerator_Vtbl =
 /* Helper function that copies a passed parameter instead of using VariantChangeType like the actual DispGetParam.
    This function is only for VARIANT type parameters that have several types that cannot be properly discriminated
    using DispGetParam/VariantChangeType. */
-static HRESULT WINAPI DispGetParam_CopyOnly(
+static HRESULT DispGetParam_CopyOnly(
         DISPPARAMS *pdispparams, /* [in] Parameter list */
         UINT        *position,    /* [in] Position of parameter to copy in pdispparams; on return will contain calculated position */
         VARIANT    *pvarResult)  /* [out] Destination for resulting variant */
@@ -988,7 +988,7 @@ static HRESULT WINAPI ListImpl_Invoke(
         EXCEPINFO* pExcepInfo,
         UINT* puArgErr)
 {
-    ListData *data = (ListData *)private_data(This);
+    ListData *data = private_data(This);
     HRESULT hr;
     VARIANTARG varg0;
     IUnknown *pUnk = NULL;
@@ -1868,7 +1868,7 @@ static HRESULT WINAPI InstallerImpl_Invoke(
                     V_DISPATCH(pVarResult) = pDispatch;
 
                     /* Save product strings */
-                    ldata = (ListData *)private_data((AutomationObject *)pDispatch);
+                    ldata = private_data((AutomationObject *)pDispatch);
                     if (!(ldata->pVars = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*idx)))
                         ERR("Out of memory\n");
                     else
@@ -1914,7 +1914,7 @@ static HRESULT WINAPI InstallerImpl_Invoke(
                     V_DISPATCH(pVarResult) = pDispatch;
 
                     /* Save product strings */
-                    ldata = (ListData *)private_data((AutomationObject *)pDispatch);
+                    ldata = private_data((AutomationObject *)pDispatch);
                     if (!(ldata->pVars = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*idx)))
                         ERR("Out of memory\n");
                     else
index 45254ef..cf889c1 100644 (file)
@@ -461,6 +461,9 @@ static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR name )
     if (!name)
         return NULL;
 
+    if (name[0] == '.')
+        name++;
+
     /* check for extensions already loaded */
     LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry )
     {
index ed8713c..0c61c76 100644 (file)
@@ -137,6 +137,7 @@ static const MSIVIEWOPS create_ops =
     NULL,
     NULL,
     NULL,
+    NULL,
 };
 
 static UINT check_columns( column_info *col_info )
@@ -157,7 +158,7 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
 {
     MSICREATEVIEW *cv = NULL;
     UINT r;
-    const column_info *col;
+    column_info *col;
     BOOL temp = TRUE;
 
     TRACE("%p\n", cv );
@@ -171,11 +172,13 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
         return ERROR_FUNCTION_FAILED;
 
     for( col = col_info; col; col = col->next )
+    {
+        if (!col->table)
+            col->table = strdupW(table);
+
         if( !col->temporary )
-        {
             temp = FALSE;
-            break;
-        }
+    }
 
     /* fill the structure */
     cv->view.ops = &create_ops;
index 71864d5..66a7ce6 100644 (file)
@@ -659,7 +659,7 @@ static UINT get_action_info( const GUID *guid, INT *type, MSIHANDLE *handle,
     return ERROR_SUCCESS;
 }
 
-static DWORD WINAPI ACTION_CallDllFunction( const GUID *guid )
+static DWORD ACTION_CallDllFunction( const GUID *guid )
 {
     MsiCustomActionEntryPoint fn;
     MSIHANDLE hPackage, handle;
@@ -744,7 +744,7 @@ static DWORD WINAPI DllThread( LPVOID arg )
     return rc;
 }
 
-static DWORD WINAPI ACTION_CAInstallPackage(const GUID *guid)
+static DWORD ACTION_CAInstallPackage(const GUID *guid)
 {
     msi_custom_action_info *info;
     UINT r = ERROR_FUNCTION_FAILED;
@@ -1147,7 +1147,7 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
     return wait_process_handle(package, type, info.hProcess, action);
 }
 
-static DWORD WINAPI ACTION_CallScript( const GUID *guid )
+static DWORD ACTION_CallScript( const GUID *guid )
 {
     msi_custom_action_info *info;
     MSIHANDLE hPackage;
index 2900860..4667006 100644 (file)
@@ -35,6 +35,7 @@
 #include "objidl.h"
 #include "objbase.h"
 #include "msiserver.h"
+#include "query.h"
 
 #include "initguid.h"
 
@@ -125,7 +126,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
             IStorage_SetClass( stg, &CLSID_MsiDatabase );
             /* create the _Tables stream */
             r = write_stream_data(stg, szTables, NULL, 0, TRUE);
-            if (!FAILED(r))
+            if (SUCCEEDED(r))
                 r = msi_init_string_table( stg );
         }
         created = TRUE;
@@ -204,7 +205,6 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
     if( !db->strings )
         goto end;
 
-    msi_table_set_strref( db->bytes_per_strref );
     ret = ERROR_SUCCESS;
 
     msiobj_addref( &db->hdr );
@@ -557,25 +557,16 @@ static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *t
                                      int num_columns, int num_records)
 {
     UINT r;
-    DWORD i, size;
+    int i;
     MSIQUERY *view;
     MSIRECORD *rec;
-    LPWSTR query;
 
     static const WCHAR select[] = {
         'S','E','L','E','C','T',' ','*',' ',
         'F','R','O','M',' ','`','%','s','`',0
     };
 
-    size = lstrlenW(select) + lstrlenW(labels[0]) - 1;
-    query = msi_alloc(size * sizeof(WCHAR));
-    if (!query)
-        return ERROR_OUTOFMEMORY;
-
-    sprintfW(query, select, labels[0]);
-
-    r = MSI_DatabaseOpenViewW(db, query, &view);
-    msi_free(query);
+    r = MSI_OpenQuery(db, &view, select, labels[0]);
     if (r != ERROR_SUCCESS)
         return r;
 
@@ -984,6 +975,514 @@ end:
     return r;
 }
 
+UINT WINAPI MsiDatabaseMergeA(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge,
+                              LPCSTR szTableName)
+{
+    UINT r;
+    LPWSTR table;
+
+    TRACE("(%ld, %ld, %s)\n", hDatabase, hDatabaseMerge,
+          debugstr_a(szTableName));
+
+    table = strdupAtoW(szTableName);
+    r = MsiDatabaseMergeW(hDatabase, hDatabaseMerge, table);
+
+    msi_free(table);
+    return r;
+}
+
+typedef struct _tagMERGETABLE
+{
+    struct list entry;
+    struct list rows;
+    LPWSTR name;
+    DWORD numconflicts;
+} MERGETABLE;
+
+typedef struct _tagMERGEROW
+{
+    struct list entry;
+    MSIRECORD *data;
+} MERGEROW;
+
+typedef struct _tagMERGEDATA
+{
+    MSIDATABASE *db;
+    MSIDATABASE *merge;
+    MERGETABLE *curtable;
+    MSIQUERY *curview;
+    struct list *tabledata;
+} MERGEDATA;
+
+static UINT merge_verify_colnames(MSIQUERY *dbview, MSIQUERY *mergeview)
+{
+    MSIRECORD *dbrec, *mergerec;
+    UINT r, i, count;
+
+    r = MSI_ViewGetColumnInfo(dbview, MSICOLINFO_NAMES, &dbrec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_ViewGetColumnInfo(mergeview, MSICOLINFO_NAMES, &mergerec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    count = MSI_RecordGetFieldCount(dbrec);
+    for (i = 1; i <= count; i++)
+    {
+        if (!MSI_RecordGetString(mergerec, i))
+            break;
+
+        if (lstrcmpW(MSI_RecordGetString(dbrec, i),
+                     MSI_RecordGetString(mergerec, i)))
+        {
+            r = ERROR_DATATYPE_MISMATCH;
+            goto done;
+        }
+    }
+
+    msiobj_release(&dbrec->hdr);
+    msiobj_release(&mergerec->hdr);
+    dbrec = mergerec = NULL;
+
+    r = MSI_ViewGetColumnInfo(dbview, MSICOLINFO_TYPES, &dbrec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_ViewGetColumnInfo(mergeview, MSICOLINFO_TYPES, &mergerec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    count = MSI_RecordGetFieldCount(dbrec);
+    for (i = 1; i <= count; i++)
+    {
+        if (!MSI_RecordGetString(mergerec, i))
+            break;
+
+        if (lstrcmpW(MSI_RecordGetString(dbrec, i),
+                     MSI_RecordGetString(mergerec, i)))
+        {
+            r = ERROR_DATATYPE_MISMATCH;
+            break;
+        }
+    }
+
+done:
+    msiobj_release(&dbrec->hdr);
+    msiobj_release(&mergerec->hdr);
+
+    return r;
+}
+
+static UINT merge_verify_primary_keys(MSIDATABASE *db, MSIDATABASE *mergedb,
+                                      LPCWSTR table)
+{
+    MSIRECORD *dbrec, *mergerec = NULL;
+    UINT r, i, count;
+
+    r = MSI_DatabaseGetPrimaryKeys(db, table, &dbrec);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_DatabaseGetPrimaryKeys(mergedb, table, &mergerec);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    count = MSI_RecordGetFieldCount(dbrec);
+    if (count != MSI_RecordGetFieldCount(mergerec))
+    {
+        r = ERROR_DATATYPE_MISMATCH;
+        goto done;
+    }
+
+    for (i = 1; i <= count; i++)
+    {
+        if (lstrcmpW(MSI_RecordGetString(dbrec, i),
+                     MSI_RecordGetString(mergerec, i)))
+        {
+            r = ERROR_DATATYPE_MISMATCH;
+            goto done;
+        }
+    }
+
+done:
+    msiobj_release(&dbrec->hdr);
+    msiobj_release(&mergerec->hdr);
+
+    return r;
+}
+
+static LPWSTR get_key_value(MSIQUERY *view, LPCWSTR key, MSIRECORD *rec)
+{
+    MSIRECORD *colnames;
+    LPWSTR str;
+    UINT r, i = 0;
+    int cmp;
+
+    r = MSI_ViewGetColumnInfo(view, MSICOLINFO_NAMES, &colnames);
+    if (r != ERROR_SUCCESS)
+        return NULL;
+
+    do
+    {
+        str = msi_dup_record_field(colnames, ++i);
+        cmp = lstrcmpW(key, str);
+        msi_free(str);
+    } while (cmp);
+
+    msiobj_release(&colnames->hdr);
+    return msi_dup_record_field(rec, i);
+}
+
+static LPWSTR create_diff_row_query(MSIDATABASE *merge, MSIQUERY *view,
+                                    LPWSTR table, MSIRECORD *rec)
+{
+    LPWSTR query = NULL, clause = NULL;
+    LPWSTR ptr = NULL, val;
+    LPCWSTR setptr;
+    DWORD size = 1, oldsize;
+    LPCWSTR key;
+    MSIRECORD *keys;
+    UINT r, i, count;
+
+    static const WCHAR keyset[] = {
+        '`','%','s','`',' ','=',' ','%','s',' ','A','N','D',' ',0};
+    static const WCHAR lastkeyset[] = {
+        '`','%','s','`',' ','=',' ','%','s',' ',0};
+    static const WCHAR fmt[] = {'S','E','L','E','C','T',' ','*',' ',
+        'F','R','O','M',' ','`','%','s','`',' ',
+        'W','H','E','R','E',' ','%','s',0};
+
+    r = MSI_DatabaseGetPrimaryKeys(merge, table, &keys);
+    if (r != ERROR_SUCCESS)
+        return NULL;
+
+    clause = msi_alloc_zero(size * sizeof(WCHAR));
+    if (!clause)
+        goto done;
+
+    ptr = clause;
+    count = MSI_RecordGetFieldCount(keys);
+    for (i = 1; i <= count; i++)
+    {
+        key = MSI_RecordGetString(keys, i);
+        val = get_key_value(view, key, rec);
+
+        if (i == count)
+            setptr = lastkeyset;
+        else
+            setptr = keyset;
+
+        oldsize = size;
+        size += lstrlenW(setptr) + lstrlenW(key) + lstrlenW(val) - 4;
+        clause = msi_realloc(clause, size * sizeof (WCHAR));
+        if (!clause)
+        {
+            msi_free(val);
+            goto done;
+        }
+
+        ptr = clause + oldsize - 1;
+        sprintfW(ptr, setptr, key, val);
+        msi_free(val);
+    }
+
+    size = lstrlenW(fmt) + lstrlenW(table) + lstrlenW(clause) + 1;
+    query = msi_alloc(size * sizeof(WCHAR));
+    if (!query)
+        goto done;
+
+    sprintfW(query, fmt, table, clause);
+
+done:
+    msi_free(clause);
+    msiobj_release(&keys->hdr);
+    return query;
+}
+
+static UINT merge_diff_row(MSIRECORD *rec, LPVOID param)
+{
+    MERGEDATA *data = (MERGEDATA *)param;
+    MERGETABLE *table = data->curtable;
+    MERGEROW *mergerow;
+    MSIQUERY *dbview;
+    MSIRECORD *row;
+    LPWSTR query;
+    UINT r;
+
+    query = create_diff_row_query(data->merge, data->curview, table->name, rec);
+    if (!query)
+        return ERROR_OUTOFMEMORY;
+
+    r = MSI_DatabaseOpenViewW(data->db, query, &dbview);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = MSI_ViewExecute(dbview, NULL);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = MSI_ViewFetch(dbview, &row);
+    if (r == ERROR_SUCCESS && !MSI_RecordsAreEqual(rec, row))
+    {
+        table->numconflicts++;
+        goto done;
+    }
+    else if (r != ERROR_NO_MORE_ITEMS)
+        goto done;
+
+    mergerow = msi_alloc(sizeof(MERGEROW));
+    if (!mergerow)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    mergerow->data = MSI_CloneRecord(rec);
+    if (!mergerow->data)
+    {
+        r = ERROR_OUTOFMEMORY;
+        msi_free(mergerow);
+        goto done;
+    }
+
+    list_add_tail(&table->rows, &mergerow->entry);
+
+done:
+    msi_free(query);
+    msiobj_release(&row->hdr);
+    msiobj_release(&dbview->hdr);
+    return r;
+}
+
+static UINT merge_diff_tables(MSIRECORD *rec, LPVOID param)
+{
+    MERGEDATA *data = (MERGEDATA *)param;
+    MERGETABLE *table;
+    MSIQUERY *dbview;
+    MSIQUERY *mergeview = NULL;
+    LPCWSTR name;
+    UINT r;
+
+    static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ',
+        'F','R','O','M',' ','`','%','s','`',0};
+
+    name = MSI_RecordGetString(rec, 1);
+
+    r = MSI_OpenQuery(data->db, &dbview, query, name);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_OpenQuery(data->merge, &mergeview, query, name);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = merge_verify_colnames(dbview, mergeview);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = merge_verify_primary_keys(data->db, data->merge, name);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    table = msi_alloc(sizeof(MERGETABLE));
+    if (!table)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    list_init(&table->rows);
+    table->name = strdupW(name);
+    table->numconflicts = 0;
+    data->curtable = table;
+    data->curview = mergeview;
+
+    r = MSI_IterateRecords(mergeview, NULL, merge_diff_row, data);
+    if (r != ERROR_SUCCESS)
+    {
+        msi_free(table->name);
+        msi_free(table);
+        goto done;
+    }
+
+    list_add_tail(data->tabledata, &table->entry);
+
+done:
+    msiobj_release(&dbview->hdr);
+    msiobj_release(&mergeview->hdr);
+    return r;
+}
+
+static UINT gather_merge_data(MSIDATABASE *db, MSIDATABASE *merge,
+                              struct list *tabledata)
+{
+    UINT r;
+    MSIQUERY *view;
+    MERGEDATA data;
+
+    static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ',
+        'F','R','O','M',' ','`','_','T','a','b','l','e','s','`',0};
+
+    r = MSI_DatabaseOpenViewW(merge, query, &view);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    data.db = db;
+    data.merge = merge;
+    data.tabledata = tabledata;
+    r = MSI_IterateRecords(view, NULL, merge_diff_tables, &data);
+
+    msiobj_release(&view->hdr);
+    return r;
+}
+
+static UINT merge_table(MSIDATABASE *db, MERGETABLE *table)
+{
+    UINT r;
+    MERGEROW *row;
+    MSIVIEW *tv;
+
+    LIST_FOR_EACH_ENTRY(row, &table->rows, MERGEROW, entry)
+    {
+        r = TABLE_CreateView(db, table->name, &tv);
+        if (r != ERROR_SUCCESS)
+            return r;
+
+        r = tv->ops->insert_row(tv, row->data, FALSE);
+        tv->ops->delete(tv);
+
+        if (r != ERROR_SUCCESS)
+            return r;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+static UINT update_merge_errors(MSIDATABASE *db, LPCWSTR error,
+                                LPWSTR table, DWORD numconflicts)
+{
+    UINT r;
+    MSIQUERY *view;
+
+    static const WCHAR create[] = {
+        'C','R','E','A','T','E',' ','T','A','B','L','E',' ',
+        '`','%','s','`',' ','(','`','T','a','b','l','e','`',' ',
+        'C','H','A','R','(','2','5','5',')',' ','N','O','T',' ',
+        'N','U','L','L',',',' ','`','N','u','m','R','o','w','M','e','r','g','e',
+        'C','o','n','f','l','i','c','t','s','`',' ','S','H','O','R','T',' ',
+        'N','O','T',' ','N','U','L','L',' ','P','R','I','M','A','R','Y',' ',
+        'K','E','Y',' ','`','T','a','b','l','e','`',')',0};
+    static const WCHAR insert[] = {
+        'I','N','S','E','R','T',' ','I','N','T','O',' ',
+        '`','%','s','`',' ','(','`','T','a','b','l','e','`',',',' ',
+        '`','N','u','m','R','o','w','M','e','r','g','e',
+        'C','o','n','f','l','i','c','t','s','`',')',' ','V','A','L','U','E','S',
+        ' ','(','\'','%','s','\'',',',' ','%','d',')',0};
+
+    if (!TABLE_Exists(db, error))
+    {
+        r = MSI_OpenQuery(db, &view, create, error);
+        if (r != ERROR_SUCCESS)
+            return r;
+
+        r = MSI_ViewExecute(view, NULL);
+        msiobj_release(&view->hdr);
+        if (r != ERROR_SUCCESS)
+            return r;
+    }
+
+    r = MSI_OpenQuery(db, &view, insert, error, table, numconflicts);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_ViewExecute(view, NULL);
+    msiobj_release(&view->hdr);
+    return r;
+}
+
+static void merge_free_rows(MERGETABLE *table)
+{
+    struct list *item, *cursor;
+
+    LIST_FOR_EACH_SAFE(item, cursor, &table->rows)
+    {
+        MERGEROW *row = LIST_ENTRY(item, MERGEROW, entry);
+
+        list_remove(&row->entry);
+        merge_free_rows(table);
+        msiobj_release(&row->data->hdr);
+        msi_free(row);
+    }
+}
+
+UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge,
+                              LPCWSTR szTableName)
+{
+    struct list tabledata = LIST_INIT(tabledata);
+    struct list *item, *cursor;
+    MSIDATABASE *db, *merge;
+    MERGETABLE *table;
+    BOOL conflicts;
+    UINT r;
+
+    TRACE("(%ld, %ld, %s)\n", hDatabase, hDatabaseMerge,
+          debugstr_w(szTableName));
+
+    if (szTableName && !*szTableName)
+        return ERROR_INVALID_TABLE;
+
+    db = msihandle2msiinfo(hDatabase, MSIHANDLETYPE_DATABASE);
+    merge = msihandle2msiinfo(hDatabaseMerge, MSIHANDLETYPE_DATABASE);
+    if (!db || !merge)
+    {
+        r = ERROR_INVALID_HANDLE;
+        goto done;
+    }
+
+    r = gather_merge_data(db, merge, &tabledata);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    conflicts = FALSE;
+    LIST_FOR_EACH_ENTRY(table, &tabledata, MERGETABLE, entry)
+    {
+        if (table->numconflicts)
+        {
+            conflicts = TRUE;
+
+            r = update_merge_errors(db, szTableName, table->name,
+                                    table->numconflicts);
+            if (r != ERROR_SUCCESS)
+                break;
+        }
+        else
+        {
+            r = merge_table(db, table);
+            if (r != ERROR_SUCCESS)
+                break;
+        }
+    }
+
+    LIST_FOR_EACH_SAFE(item, cursor, &tabledata)
+    {
+        MERGETABLE *table = LIST_ENTRY(item, MERGETABLE, entry);
+
+        list_remove(&table->entry);
+        merge_free_rows(table);
+        msi_free(table->name);
+        msi_free(table);
+    }
+
+    if (conflicts)
+        r = ERROR_FUNCTION_FAILED;
+
+done:
+    msiobj_release(&db->hdr);
+    msiobj_release(&merge->hdr);
+    return r;
+}
+
 MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle )
 {
     MSIDBSTATE ret = MSIDBSTATE_READ;
index 8d37324..3db2783 100644 (file)
@@ -191,7 +191,8 @@ static const MSIVIEWOPS delete_ops =
     NULL,
     NULL,
     NULL,
-    NULL
+    NULL,
+    NULL,
 };
 
 UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
index 8c7c59a..8be1cc7 100644 (file)
@@ -1204,12 +1204,15 @@ static UINT msi_dialog_combo_control( msi_dialog *dialog, MSIRECORD *rec )
     return ERROR_SUCCESS;
 }
 
+/* length of 2^32 + 1 */
+#define MAX_NUM_DIGITS 11
+
 static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec )
 {
     msi_control *control;
     LPCWSTR prop, text;
     LPWSTR val, begin, end;
-    WCHAR num[10];
+    WCHAR num[MAX_NUM_DIGITS];
     DWORD limit;
 
     control = msi_dialog_add_control( dialog, rec, szEdit,
@@ -1222,7 +1225,9 @@ static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec )
         begin = strchrW( text, '{' );
         end = strchrW( text, '}' );
 
-        if ( begin && end && end > begin )
+        if ( begin && end && end > begin &&
+             begin[0] >= '0' && begin[0] <= '9' &&
+             end - begin < MAX_NUM_DIGITS)
         {
             lstrcpynW( num, begin + 1, end - begin );
             limit = atolW( num );
@@ -1383,7 +1388,7 @@ msi_maskedit_set_text( struct msi_maskedit_info *info, LPCWSTR text )
     p = text;
     for( i = 0; i < info->num_groups; i++ )
     {
-        if( info->group[i].len < lstrlenW( p ) )
+        if( info->group[i].len < strlenW( p ) )
         {
             LPWSTR chunk = strdupW( p );
             chunk[ info->group[i].len ] = 0;
@@ -1909,7 +1914,7 @@ msi_seltree_menu( HWND hwnd, HTREEITEM hItem )
     case INSTALLSTATE_LOCAL:
     case INSTALLSTATE_ADVERTISED:
     case INSTALLSTATE_ABSENT:
-        msi_feature_set_state( feature, r );
+        msi_feature_set_state(package, feature, r);
         break;
     default:
         FIXME("select feature and all children\n");
@@ -2242,6 +2247,7 @@ static UINT msi_listbox_add_items( struct msi_listbox_info *info, LPCWSTR proper
         return r;
 
     /* just get the number of records */
+    count = 0;
     r = MSI_IterateRecords( view, &count, NULL, NULL );
 
     info->num_items = count;
index 6a29c5a..6c21b88 100644 (file)
@@ -296,6 +296,7 @@ static const MSIVIEWOPS distinct_ops =
     NULL,
     NULL,
     DISTINCT_sort,
+    NULL,
 };
 
 UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
diff --git a/reactos/dll/win32/msi/drop.c b/reactos/dll/win32/msi/drop.c
new file mode 100644 (file)
index 0000000..20ab441
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2008 James Hawkins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msidb);
+
+typedef struct tagMSIDROPVIEW
+{
+    MSIVIEW view;
+    MSIDATABASE *db;
+    MSIVIEW *table;
+    column_info *colinfo;
+    INT hold;
+} MSIDROPVIEW;
+
+static UINT DROP_execute(struct tagMSIVIEW *view, MSIRECORD *record)
+{
+    MSIDROPVIEW *dv = (MSIDROPVIEW*)view;
+    UINT r;
+
+    TRACE("%p %p\n", dv, record);
+
+    if( !dv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    r = dv->table->ops->execute(dv->table, record);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    return dv->table->ops->drop(dv->table);
+}
+
+static UINT DROP_close(struct tagMSIVIEW *view)
+{
+    MSIDROPVIEW *dv = (MSIDROPVIEW*)view;
+
+    TRACE("%p\n", dv);
+
+    return ERROR_SUCCESS;
+}
+
+static UINT DROP_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
+{
+    MSIDROPVIEW *dv = (MSIDROPVIEW*)view;
+
+    TRACE("%p %p %p\n", dv, rows, cols);
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static const MSIVIEWOPS drop_ops =
+{
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    DROP_execute,
+    DROP_close,
+    DROP_get_dimensions,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+};
+
+UINT DROP_CreateView(MSIDATABASE *db, MSIVIEW **view, LPCWSTR name)
+{
+    MSIDROPVIEW *dv;
+    UINT r;
+
+    TRACE("%p %s\n", view, debugstr_w(name));
+
+    dv = msi_alloc_zero(sizeof *dv);
+    if(!dv)
+        return ERROR_FUNCTION_FAILED;
+
+    r = TABLE_CreateView(db, name, &dv->table);
+    if (r != ERROR_SUCCESS || !dv->table)
+        return r;
+
+    dv->view.ops = &drop_ops;
+    dv->db = db;
+
+    *view = (MSIVIEW *)dv;
+
+    return ERROR_SUCCESS;
+}
index 6b6ead9..cb70b69 100644 (file)
@@ -104,7 +104,7 @@ static UINT ControlEvent_EndDialog(MSIPACKAGE* package, LPCWSTR argument,
     else if (lstrcmpW(argument, szRetry) == 0)
         package->CurrentInstallState = ERROR_INSTALL_SUSPEND;
     else if (lstrcmpW(argument, szIgnore) == 0)
-        package->CurrentInstallState = -1;
+        package->CurrentInstallState = ERROR_SUCCESS;
     else if (lstrcmpW(argument, szReturn) == 0)
     {
         msi_dialog *parent = msi_dialog_get_parent(dialog);
@@ -180,7 +180,7 @@ static UINT ControlEvent_AddLocal(MSIPACKAGE* package, LPCWSTR argument,
     else
     {
         LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
-            msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
+            msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
 
         ACTION_UpdateComponentStates(package,argument);
     }
@@ -200,7 +200,7 @@ static UINT ControlEvent_Remove(MSIPACKAGE* package, LPCWSTR argument,
     else
     {
         LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
-            msi_feature_set_state( feature, INSTALLSTATE_ABSENT );
+            msi_feature_set_state(package, feature, INSTALLSTATE_ABSENT);
 
         ACTION_UpdateComponentStates(package,argument);
     }
@@ -220,7 +220,7 @@ static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument,
     else
     {
         LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
-            msi_feature_set_state( feature, INSTALLSTATE_SOURCE );
+            msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE);
         ACTION_UpdateComponentStates(package,argument);
     }
     return ERROR_SUCCESS;
index 842a72d..5036efd 100644 (file)
@@ -39,7 +39,6 @@
 #include "fdi.h"
 #include "msi.h"
 #include "msidefs.h"
-#include "msvcrt/fcntl.h"
 #include "msipriv.h"
 #include "winuser.h"
 #include "winreg.h"
@@ -55,183 +54,6 @@ extern const WCHAR szPatchFiles[];
 extern const WCHAR szRemoveDuplicateFiles[];
 extern const WCHAR szRemoveFiles[];
 
-static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};
-
-static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPWSTR source_root)
-{
-    WCHAR volume_name[MAX_PATH + 1];
-
-    if (!GetVolumeInformationW(source_root, volume_name, MAX_PATH + 1,
-                               NULL, NULL, NULL, NULL, 0))
-    {
-        ERR("Failed to get volume information\n");
-        return FALSE;
-    }
-
-    return !lstrcmpW(mi->volume_label, volume_name);
-}
-
-static UINT msi_change_media( MSIPACKAGE *package, MSIMEDIAINFO *mi )
-{
-    LPSTR msg;
-    LPWSTR error, error_dialog;
-    LPWSTR source_dir;
-    UINT r = ERROR_SUCCESS;
-
-    static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
-    static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
-
-    if ( (msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE && !gUIHandlerA )
-        return ERROR_SUCCESS;
-
-    error = generate_error_string( package, 1302, 1, mi->disk_prompt );
-    error_dialog = msi_dup_property( package, error_prop );
-    source_dir = msi_dup_property( package, cszSourceDir );
-    PathStripToRootW(source_dir);
-
-    while ( r == ERROR_SUCCESS &&
-            !source_matches_volume(mi, source_dir) )
-    {
-        r = msi_spawn_error_dialog( package, error_dialog, error );
-
-        if (gUIHandlerA)
-        {
-            msg = strdupWtoA( error );
-            gUIHandlerA( gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg );
-            msi_free(msg);
-        }
-    }
-
-    msi_free( error );
-    msi_free( error_dialog );
-    msi_free( source_dir );
-
-    return r;
-}
-
-/*
- * This is a helper function for handling embedded cabinet media
- */
-static UINT writeout_cabinet_stream(MSIPACKAGE *package, LPCWSTR stream_name,
-                                    WCHAR* source)
-{
-    UINT rc;
-    USHORT* data;
-    UINT    size;
-    DWORD   write;
-    HANDLE  the_file;
-    WCHAR tmp[MAX_PATH];
-
-    rc = read_raw_stream_data(package->db,stream_name,&data,&size); 
-    if (rc != ERROR_SUCCESS)
-        return rc;
-
-    write = MAX_PATH;
-    if (MSI_GetPropertyW(package, cszTempFolder, tmp, &write))
-        GetTempPathW(MAX_PATH,tmp);
-
-    GetTempFileNameW(tmp,stream_name,0,source);
-
-    track_tempfile(package, source);
-    the_file = CreateFileW(source, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
-                           FILE_ATTRIBUTE_NORMAL, NULL);
-
-    if (the_file == INVALID_HANDLE_VALUE)
-    {
-        ERR("Unable to create file %s\n",debugstr_w(source));
-        rc = ERROR_FUNCTION_FAILED;
-        goto end;
-    }
-
-    WriteFile(the_file,data,size,&write,NULL);
-    CloseHandle(the_file);
-    TRACE("wrote %i bytes to %s\n",write,debugstr_w(source));
-end:
-    msi_free(data);
-    return rc;
-}
-
-
-/* Support functions for FDI functions */
-typedef struct
-{
-    MSIPACKAGE* package;
-    MSIMEDIAINFO *mi;
-} CabData;
-
-static void * cabinet_alloc(ULONG cb)
-{
-    return msi_alloc(cb);
-}
-
-static void cabinet_free(void *pv)
-{
-    msi_free(pv);
-}
-
-static INT_PTR cabinet_open(char *pszFile, int oflag, int pmode)
-{
-    HANDLE handle;
-    DWORD dwAccess = 0;
-    DWORD dwShareMode = 0;
-    DWORD dwCreateDisposition = OPEN_EXISTING;
-    switch (oflag & _O_ACCMODE)
-    {
-    case _O_RDONLY:
-        dwAccess = GENERIC_READ;
-        dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
-        break;
-    case _O_WRONLY:
-        dwAccess = GENERIC_WRITE;
-        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
-        break;
-    case _O_RDWR:
-        dwAccess = GENERIC_READ | GENERIC_WRITE;
-        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
-        break;
-    }
-    if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
-        dwCreateDisposition = CREATE_NEW;
-    else if (oflag & _O_CREAT)
-        dwCreateDisposition = CREATE_ALWAYS;
-    handle = CreateFileA( pszFile, dwAccess, dwShareMode, NULL, 
-                          dwCreateDisposition, 0, NULL );
-    if (handle == INVALID_HANDLE_VALUE)
-        return 0;
-    return (INT_PTR) handle;
-}
-
-static UINT cabinet_read(INT_PTR hf, void *pv, UINT cb)
-{
-    HANDLE handle = (HANDLE) hf;
-    DWORD dwRead;
-    if (ReadFile(handle, pv, cb, &dwRead, NULL))
-        return dwRead;
-    return 0;
-}
-
-static UINT cabinet_write(INT_PTR hf, void *pv, UINT cb)
-{
-    HANDLE handle = (HANDLE) hf;
-    DWORD dwWritten;
-    if (WriteFile(handle, pv, cb, &dwWritten, NULL))
-        return dwWritten;
-    return 0;
-}
-
-static int cabinet_close(INT_PTR hf)
-{
-    HANDLE handle = (HANDLE) hf;
-    return CloseHandle(handle) ? 0 : -1;
-}
-
-static long cabinet_seek(INT_PTR hf, long dist, int seektype)
-{
-    HANDLE handle = (HANDLE) hf;
-    /* flags are compatible and so are passed straight through */
-    return SetFilePointer(handle, dist, NULL, seektype);
-}
-
 static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *action )
 {
     MSIRECORD *uirow;
@@ -252,213 +74,6 @@ static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *ac
     ui_progress( package, 2, f->FileSize, 0, 0);
 }
 
-static UINT msi_media_get_disk_info( MSIPACKAGE *package, MSIMEDIAINFO *mi )
-{
-    MSIRECORD *row;
-    LPWSTR ptr;
-
-    static const WCHAR query[] =
-        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
-         '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
-         '`','D','i','s','k','I','d','`',' ','=',' ','%','i',0};
-
-    row = MSI_QueryGetRecord(package->db, query, mi->disk_id);
-    if (!row)
-    {
-        TRACE("Unable to query row\n");
-        return ERROR_FUNCTION_FAILED;
-    }
-
-    mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
-    mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
-    mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
-
-    if (!mi->first_volume)
-        mi->first_volume = strdupW(mi->volume_label);
-
-    ptr = strrchrW(mi->source, '\\') + 1;
-    lstrcpyW(ptr, mi->cabinet);
-    msiobj_release(&row->hdr);
-
-    return ERROR_SUCCESS;
-}
-
-static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
-{
-    TRACE("(%d)\n", fdint);
-
-    switch (fdint)
-    {
-    case fdintPARTIAL_FILE:
-    {
-        CabData *data = (CabData *)pfdin->pv;
-        data->mi->is_continuous = FALSE;
-        return 0;
-    }
-    case fdintNEXT_CABINET:
-    {
-        CabData *data = (CabData *)pfdin->pv;
-        MSIMEDIAINFO *mi = data->mi;
-        LPWSTR cab = strdupAtoW(pfdin->psz1);
-        UINT rc;
-
-        msi_free(mi->disk_prompt);
-        msi_free(mi->cabinet);
-        msi_free(mi->volume_label);
-        mi->disk_prompt = NULL;
-        mi->cabinet = NULL;
-        mi->volume_label = NULL;
-
-        mi->disk_id++;
-        mi->is_continuous = TRUE;
-
-        rc = msi_media_get_disk_info(data->package, mi);
-        if (rc != ERROR_SUCCESS)
-        {
-            msi_free(cab);
-            ERR("Failed to get next cabinet information: %d\n", rc);
-            return -1;
-        }
-
-        if (lstrcmpiW(mi->cabinet, cab))
-        {
-            msi_free(cab);
-            ERR("Continuous cabinet does not match the next cabinet in the Media table\n");
-            return -1;
-        }
-
-        msi_free(cab);
-
-        TRACE("Searching for %s\n", debugstr_w(mi->source));
-
-        if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
-            rc = msi_change_media(data->package, mi);
-
-        if (rc != ERROR_SUCCESS)
-            return -1;
-
-        return 0;
-    }
-    case fdintCOPY_FILE:
-    {
-        CabData *data = (CabData*) pfdin->pv;
-        HANDLE handle;
-        LPWSTR file;
-        MSIFILE *f;
-        DWORD attrs;
-
-        file = strdupAtoW(pfdin->psz1);
-        f = get_loaded_file(data->package, file);
-        msi_free(file);
-
-        if (!f)
-        {
-            WARN("unknown file in cabinet (%s)\n",debugstr_a(pfdin->psz1));
-            return 0;
-        }
-
-        if (f->state != msifs_missing && f->state != msifs_overwrite)
-        {
-            TRACE("Skipping extraction of %s\n",debugstr_a(pfdin->psz1));
-            return 0;
-        }
-
-        msi_file_update_ui( data->package, f, szInstallFiles );
-
-        TRACE("extracting %s\n", debugstr_w(f->TargetPath) );
-
-        attrs = f->Attributes & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
-        if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
-
-        handle = CreateFileW( f->TargetPath, GENERIC_READ | GENERIC_WRITE, 0,
-                              NULL, CREATE_ALWAYS, attrs, NULL );
-        if ( handle == INVALID_HANDLE_VALUE )
-        {
-            if ( GetFileAttributesW( f->TargetPath ) != INVALID_FILE_ATTRIBUTES )
-                f->state = msifs_installed;
-            else
-                ERR("failed to create %s (error %d)\n",
-                    debugstr_w( f->TargetPath ), GetLastError() );
-
-            return 0;
-        }
-
-        f->state = msifs_installed;
-        return (INT_PTR) handle;
-    }
-    case fdintCLOSE_FILE_INFO:
-    {
-        CabData *data = (CabData*) pfdin->pv;
-        FILETIME ft;
-        FILETIME ftLocal;
-        HANDLE handle = (HANDLE) pfdin->hf;
-
-        data->mi->is_continuous = FALSE;
-
-        if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
-            return -1;
-        if (!LocalFileTimeToFileTime(&ft, &ftLocal))
-            return -1;
-        if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
-            return -1;
-        CloseHandle(handle);
-        return 1;
-    }
-    default:
-        return 0;
-    }
-}
-
-/***********************************************************************
- *            msi_cabextract
- *
- * Extract files from a cab file.
- */
-BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi,
-                    PFNFDINOTIFY notify, LPVOID data)
-{
-    LPSTR cabinet, cab_path = NULL;
-    LPWSTR ptr;
-    HFDI hfdi;
-    ERF erf;
-    BOOL ret = FALSE;
-
-    TRACE("Extracting %s\n", debugstr_w(mi->source));
-
-    hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read,
-                     cabinet_write, cabinet_close, cabinet_seek, 0, &erf);
-    if (!hfdi)
-    {
-        ERR("FDICreate failed\n");
-        return FALSE;
-    }
-
-    ptr = strrchrW(mi->source, '\\') + 1;
-    cabinet = strdupWtoA(ptr);
-    if (!cabinet)
-        goto done;
-
-    cab_path = strdupWtoA(mi->source);
-    if (!cab_path)
-        goto done;
-
-    cab_path[ptr - mi->source] = '\0';
-
-    ret = FDICopy(hfdi, cabinet, cab_path, 0, notify, NULL, data);
-    if (!ret)
-        ERR("FDICopy failed\n");
-
-done:
-    FDIDestroy(hfdi);
-    msi_free(cabinet);
-    msi_free(cab_path);
-
-    if (ret)
-        mi->is_extracted = TRUE;
-
-    return ret;
-}
-
 /* compares the version of a file read from the filesystem and
  * the version specified in the File table
  */
@@ -477,209 +92,6 @@ static int msi_compare_file_version(MSIFILE *file)
     return lstrcmpW(version, file->Version);
 }
 
-void msi_free_media_info( MSIMEDIAINFO *mi )
-{
-    msi_free( mi->disk_prompt );
-    msi_free( mi->cabinet );
-    msi_free( mi->volume_label );
-    msi_free( mi->first_volume );
-    msi_free( mi );
-}
-
-UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
-{
-    MSIRECORD *row;
-    LPWSTR source_dir;
-    LPWSTR source;
-    DWORD options;
-    UINT r;
-
-    static const WCHAR query[] = {
-        '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',' ','A','N','D',' ','`','D','i','s','k','I','d','`',' ','>','=',
-        ' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ',
-        '`','D','i','s','k','I','d','`',0
-    };
-
-    row = MSI_QueryGetRecord(package->db, query, file->Sequence, mi->disk_id);
-    if (!row)
-    {
-        TRACE("Unable to query row\n");
-        return ERROR_FUNCTION_FAILED;
-    }
-
-    mi->is_extracted = FALSE;
-    mi->disk_id = MSI_RecordGetInteger(row, 1);
-    mi->last_sequence = MSI_RecordGetInteger(row, 2);
-    msi_free(mi->disk_prompt);
-    mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
-    msi_free(mi->cabinet);
-    mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
-    msi_free(mi->volume_label);
-    mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
-    msiobj_release(&row->hdr);
-
-    if (!mi->first_volume)
-        mi->first_volume = strdupW(mi->volume_label);
-
-    source_dir = msi_dup_property(package, cszSourceDir);
-    lstrcpyW(mi->source, source_dir);
-
-    PathStripToRootW(source_dir);
-    mi->type = GetDriveTypeW(source_dir);
-
-    if (file->IsCompressed && mi->cabinet)
-    {
-        if (mi->cabinet[0] == '#')
-        {
-            r = writeout_cabinet_stream(package, &mi->cabinet[1], mi->source);
-            if (r != ERROR_SUCCESS)
-            {
-                ERR("Failed to extract cabinet stream\n");
-                return ERROR_FUNCTION_FAILED;
-            }
-        }
-        else
-            lstrcatW(mi->source, mi->cabinet);
-    }
-
-    options = MSICODE_PRODUCT;
-    if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE)
-    {
-        source = source_dir;
-        options |= MSISOURCETYPE_MEDIA;
-    }
-    else if (package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL))
-    {
-        source = package->BaseURL;
-        options |= MSISOURCETYPE_URL;
-    }
-    else
-    {
-        source = mi->source;
-        options |= MSISOURCETYPE_NETWORK;
-    }
-
-    msi_package_add_media_disk(package, package->Context,
-                               MSICODE_PRODUCT, mi->disk_id,
-                               mi->volume_label, mi->disk_prompt);
-
-    msi_package_add_info(package, package->Context,
-                         options, INSTALLPROPERTY_LASTUSEDSOURCEW, source);
-
-    msi_free(source_dir);
-    return ERROR_SUCCESS;
-}
-
-/* FIXME: search NETWORK and URL sources as well */
-UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi)
-{
-    WCHAR source[MAX_PATH];
-    WCHAR volume[MAX_PATH];
-    WCHAR prompt[MAX_PATH];
-    DWORD volumesz, promptsz;
-    DWORD index, size, id;
-    UINT r;
-
-    size = MAX_PATH;
-    r = MsiSourceListGetInfoW(package->ProductCode, NULL,
-                              package->Context, MSICODE_PRODUCT,
-                              INSTALLPROPERTY_LASTUSEDSOURCEW, source, &size);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    index = 0;
-    volumesz = MAX_PATH;
-    promptsz = MAX_PATH;
-    while (MsiSourceListEnumMediaDisksW(package->ProductCode, NULL,
-                                        package->Context,
-                                        MSICODE_PRODUCT, index++, &id,
-                                        volume, &volumesz, prompt, &promptsz) == ERROR_SUCCESS)
-    {
-        mi->disk_id = id;
-        mi->volume_label = msi_realloc(mi->volume_label, ++volumesz * sizeof(WCHAR));
-        lstrcpyW(mi->volume_label, volume);
-        mi->disk_prompt = msi_realloc(mi->disk_prompt, ++promptsz * sizeof(WCHAR));
-        lstrcpyW(mi->disk_prompt, prompt);
-
-        if (source_matches_volume(mi, source))
-        {
-            /* FIXME: what about SourceDir */
-            lstrcpyW(mi->source, source);
-            lstrcatW(mi->source, mi->cabinet);
-            return ERROR_SUCCESS;
-        }
-    }
-
-    return ERROR_FUNCTION_FAILED;
-}
-
-static UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
-{
-    UINT rc = ERROR_SUCCESS;
-
-    /* media info for continuous cabinet is already loaded */
-    if (mi->is_continuous)
-        return ERROR_SUCCESS;
-
-    rc = msi_load_media_info(package, file, mi);
-    if (rc != ERROR_SUCCESS)
-    {
-        ERR("Unable to load media info\n");
-        return ERROR_FUNCTION_FAILED;
-    }
-
-    /* cabinet is internal, no checks needed */
-    if (!mi->cabinet || mi->cabinet[0] == '#')
-        return ERROR_SUCCESS;
-
-    /* package should be downloaded */
-    if (file->IsCompressed &&
-        GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES &&
-        package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL))
-    {
-        WCHAR temppath[MAX_PATH];
-
-        msi_download_file(mi->source, temppath);
-        lstrcpyW(mi->source, temppath);
-        return ERROR_SUCCESS;
-    }
-
-    /* check volume matches, change media if not */
-    if (mi->volume_label && mi->disk_id > 1 &&
-        lstrcmpW(mi->first_volume, mi->volume_label))
-    {
-        LPWSTR source = msi_dup_property(package, cszSourceDir);
-        BOOL matches;
-
-        matches = source_matches_volume(mi, source);
-        msi_free(source);
-
-        if ((mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) && !matches)
-        {
-            rc = msi_change_media(package, mi);
-            if (rc != ERROR_SUCCESS)
-                return rc;
-        }
-    }
-
-    if (file->IsCompressed &&
-        GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
-    {
-        /* FIXME: this might be done earlier in the install process */
-        rc = find_published_source(package, mi);
-        if (rc != ERROR_SUCCESS)
-        {
-            ERR("Cabinet not found: %s\n", debugstr_w(mi->source));
-            return ERROR_INSTALL_FAILURE;
-        }
-    }
-
-    return ERROR_SUCCESS;
-}
-
 static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key, 
                             MSIFILE** file)
 {
@@ -713,28 +125,28 @@ static void schedule_install_files(MSIPACKAGE *package)
     }
 }
 
-static UINT copy_file(MSIFILE *file)
+static UINT copy_file(MSIFILE *file, LPWSTR source)
 {
     BOOL ret;
 
-    ret = CopyFileW(file->SourcePath, file->TargetPath, FALSE);
-    if (ret)
-    {
-        file->state = msifs_installed;
-        return ERROR_SUCCESS;
-    }
+    ret = CopyFileW(source, file->TargetPath, FALSE);
+    if (!ret)
+        return GetLastError();
 
-    return GetLastError();
+    SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL);
+
+    file->state = msifs_installed;
+    return ERROR_SUCCESS;
 }
 
-static UINT copy_install_file(MSIFILE *file)
+static UINT copy_install_file(MSIFILE *file, LPWSTR source)
 {
     UINT gle;
 
-    TRACE("Copying %s to %s\n", debugstr_w(file->SourcePath),
+    TRACE("Copying %s to %s\n", debugstr_w(source),
           debugstr_w(file->TargetPath));
 
-    gle = copy_file(file);
+    gle = copy_file(file, source);
     if (gle == ERROR_SUCCESS)
         return gle;
 
@@ -747,7 +159,7 @@ static UINT copy_install_file(MSIFILE *file)
     {
         SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL);
 
-        gle = copy_file(file);
+        gle = copy_file(file, source);
         TRACE("Overwriting existing file: %d\n", gle);
     }
 
@@ -770,6 +182,40 @@ static BOOL check_dest_hash_matches(MSIFILE *file)
     return !memcmp(&hash, &file->hash, sizeof(MSIFILEHASHINFO));
 }
 
+static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
+                            LPWSTR *path, DWORD *attrs, PVOID user)
+{
+    static MSIFILE *f = NULL;
+
+    if (action == MSICABEXTRACT_BEGINEXTRACT)
+    {
+        f = get_loaded_file(package, file);
+        if (!f)
+        {
+            WARN("unknown file in cabinet (%s)\n", debugstr_w(file));
+            return FALSE;
+        }
+
+        if (f->state != msifs_missing && f->state != msifs_overwrite)
+        {
+            TRACE("Skipping extraction of %s\n", debugstr_w(file));
+            return FALSE;
+        }
+
+        msi_file_update_ui(package, f, szInstallFiles);
+
+        *path = strdupW(f->TargetPath);
+        *attrs = f->Attributes;
+    }
+    else if (action == MSICABEXTRACT_FILEEXTRACTED)
+    {
+        f->state = msifs_installed;
+        f = NULL;
+    }
+
+    return TRUE;
+}
+
 /*
  * ACTION_InstallFiles()
  * 
@@ -819,7 +265,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
         if (file->Sequence > mi->last_sequence || mi->is_continuous ||
             (file->IsCompressed && !mi->is_extracted))
         {
-            CabData data;
+            MSICABDATA data;
 
             rc = ready_media(package, file, mi);
             if (rc != ERROR_SUCCESS)
@@ -830,9 +276,11 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
 
             data.mi = mi;
             data.package = package;
+            data.cb = installfiles_cb;
+            data.user = NULL;
 
             if (file->IsCompressed &&
-                !msi_cabextract(package, mi, cabinet_notify, &data))
+                !msi_cabextract(package, mi, &data))
             {
                 ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
                 rc = ERROR_FUNCTION_FAILED;
@@ -842,28 +290,34 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
 
         if (!file->IsCompressed)
         {
-            TRACE("file paths %s to %s\n", debugstr_w(file->SourcePath),
+            LPWSTR source = resolve_file_source(package, file);
+
+            TRACE("file paths %s to %s\n", debugstr_w(source),
                   debugstr_w(file->TargetPath));
 
             msi_file_update_ui(package, file, szInstallFiles);
-            rc = copy_install_file(file);
+            rc = copy_install_file(file, source);
             if (rc != ERROR_SUCCESS)
             {
-                ERR("Failed to copy %s to %s (%d)\n", debugstr_w(file->SourcePath),
+                ERR("Failed to copy %s to %s (%d)\n", debugstr_w(source),
                     debugstr_w(file->TargetPath), rc);
                 rc = ERROR_INSTALL_FAILURE;
+                msi_free(source);
                 break;
             }
+
+            msi_free(source);
         }
         else if (file->state != msifs_installed)
         {
-            ERR("compressed file wasn't extracted (%s)\n", debugstr_w(file->TargetPath));
+            ERR("compressed file wasn't extracted (%s)\n",
+                debugstr_w(file->TargetPath));
             rc = ERROR_INSTALL_FAILURE;
             break;
         }
     }
 
-    msi_free_media_info( mi );
+    msi_free_media_info(mi);
     return rc;
 }
 
@@ -986,35 +440,134 @@ UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
     return rc;
 }
 
+static BOOL verify_comp_for_removal(MSICOMPONENT *comp, UINT install_mode)
+{
+    INSTALLSTATE request = comp->ActionRequest;
+
+    if (request == INSTALLSTATE_UNKNOWN)
+        return FALSE;
+
+    if (install_mode == msidbRemoveFileInstallModeOnInstall &&
+        (request == INSTALLSTATE_LOCAL || request == INSTALLSTATE_SOURCE))
+        return TRUE;
+
+    if (request == INSTALLSTATE_ABSENT)
+    {
+        if (!comp->ComponentId)
+            return FALSE;
+
+        if (install_mode == msidbRemoveFileInstallModeOnRemove)
+            return TRUE;
+    }
+
+    if (install_mode == msidbRemoveFileInstallModeOnBoth)
+        return TRUE;
+
+    return FALSE;
+}
+
+static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param)
+{
+    MSIPACKAGE *package = (MSIPACKAGE*)param;
+    MSICOMPONENT *comp;
+    LPCWSTR component, filename, dirprop;
+    UINT install_mode;
+    LPWSTR dir = NULL, path = NULL;
+    DWORD size;
+    UINT r;
+
+    component = MSI_RecordGetString(row, 2);
+    filename = MSI_RecordGetString(row, 3);
+    dirprop = MSI_RecordGetString(row, 4);
+    install_mode = MSI_RecordGetInteger(row, 5);
+
+    comp = get_loaded_component(package, component);
+    if (!comp)
+    {
+        ERR("Invalid component: %s\n", debugstr_w(component));
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    if (!verify_comp_for_removal(comp, install_mode))
+    {
+        TRACE("Skipping removal due to missing conditions\n");
+        comp->Action = comp->Installed;
+        return ERROR_SUCCESS;
+    }
+
+    dir = msi_dup_property(package, dirprop);
+    if (!dir)
+        return ERROR_OUTOFMEMORY;
+
+    size = (filename != NULL) ? lstrlenW(filename) : 0;
+    size += lstrlenW(dir) + 2;
+    path = msi_alloc(size * sizeof(WCHAR));
+    if (!path)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    lstrcpyW(path, dir);
+    PathAddBackslashW(path);
+
+    if (filename)
+    {
+        lstrcatW(path, filename);
+
+        TRACE("Deleting misc file: %s\n", debugstr_w(path));
+        DeleteFileW(path);
+    }
+    else
+    {
+        TRACE("Removing misc directory: %s\n", debugstr_w(path));
+        RemoveDirectoryW(path);
+    }
+
+done:
+    msi_free(path);
+    msi_free(dir);
+    return ERROR_SUCCESS;
+}
+
 UINT ACTION_RemoveFiles( MSIPACKAGE *package )
 {
+    MSIQUERY *view;
     MSIFILE *file;
+    UINT r;
+
+    static const WCHAR query[] = {
+        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+        '`','R','e','m','o','v','e','F','i','l','e','`',0};
+
+    r = MSI_DatabaseOpenViewW(package->db, query, &view);
+    if (r == ERROR_SUCCESS)
+    {
+        MSI_IterateRecords(view, NULL, ITERATE_RemoveFiles, package);
+        msiobj_release(&view->hdr);
+    }
 
     LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
     {
         MSIRECORD *uirow;
         LPWSTR uipath, p;
 
-        if ( !file->Component )
-            continue;
-        if ( file->Component->Installed == INSTALLSTATE_LOCAL )
-            continue;
-
         if ( file->state == msifs_installed )
             ERR("removing installed file %s\n", debugstr_w(file->TargetPath));
 
-        if ( file->state != msifs_present )
+        if ( file->Component->ActionRequest != INSTALLSTATE_ABSENT ||
+             file->Component->Installed == INSTALLSTATE_SOURCE )
             continue;
 
-        /* only remove a file if the version to be installed
-         * is strictly newer than the old file
+        /* don't remove a file if the old file
+         * is strictly newer than the version to be installed
          */
-        if ( msi_compare_file_version( file ) >= 0 )
+        if ( msi_compare_file_version( file ) < 0 )
             continue;
 
         TRACE("removing %s\n", debugstr_w(file->File) );
         if ( !DeleteFileW( file->TargetPath ) )
-            ERR("failed to delete %s\n",  debugstr_w(file->TargetPath) );
+            TRACE("failed to delete %s\n",  debugstr_w(file->TargetPath));
         file->state = msifs_missing;
 
         /* the UI chunk */
index aba3bd9..ea36b3d 100644 (file)
 #include <stdarg.h>
 
 #include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
 #include "wine/debug.h"
 #include "msipriv.h"
 #include "winuser.h"
-#include "winreg.h"
-#include "shlwapi.h"
 #include "wine/unicode.h"
 #include "msidefs.h"
 
@@ -45,6 +41,7 @@ const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};
 const WCHAR cszSOURCEDIR[] = {'S','O','U','R','C','E','D','I','R',0};
 const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};
 const WCHAR cszbs[]={'\\',0};
+const WCHAR szLocalSid[] = {'S','-','1','-','5','-','1','8',0};
 
 LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name )
 {
@@ -165,6 +162,25 @@ MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir )
     return NULL;
 }
 
+void msi_reset_folders( MSIPACKAGE *package, BOOL source )
+{
+    MSIFOLDER *folder;
+
+    LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
+    {
+        if ( source )
+        {
+            msi_free( folder->ResolvedSource );
+            folder->ResolvedSource = NULL;
+        }
+        else
+        {
+            msi_free( folder->ResolvedTarget );
+            folder->ResolvedTarget = NULL;
+        }
+    }
+}
+
 static LPWSTR get_source_root( MSIPACKAGE *package )
 {
     LPWSTR path, p;
@@ -222,6 +238,34 @@ static void clean_spaces_from_path( LPWSTR p )
     }
 }
 
+LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file)
+{
+    LPWSTR p, path;
+
+    TRACE("Working to resolve source of file %s\n", debugstr_w(file->File));
+
+    if (file->IsCompressed)
+        return NULL;
+
+    p = resolve_folder(package, file->Component->Directory,
+                       TRUE, FALSE, TRUE, NULL);
+    path = build_directory_name(2, p, file->ShortName);
+
+    if (file->LongName &&
+        GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
+    {
+        msi_free(path);
+        path = build_directory_name(2, p, file->LongName);
+    }
+
+    msi_free(p);
+
+    TRACE("file %s source resolves to %s\n", debugstr_w(file->File),
+          debugstr_w(path));
+
+    return path;
+}
+
 LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 
                       BOOL set_prop, BOOL load_prop, MSIFOLDER **folder)
 {
@@ -393,7 +437,7 @@ UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action)
 
 void msi_free_action_script(MSIPACKAGE *package, UINT script)
 {
-    int i;
+    UINT i;
     for (i = 0; i < package->script->ActionCount[script]; i++)
         msi_free(package->script->Actions[script][i]);
 
@@ -522,7 +566,6 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
         msi_free( file->LongName );
         msi_free( file->Version );
         msi_free( file->Language );
-        msi_free( file->SourcePath );
         msi_free( file->TargetPath );
         msi_free( file );
     }
@@ -618,6 +661,13 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
         msi_free(package->script);
     }
 
+    if (package->patch)
+    {
+        msi_free(package->patch->patchcode);
+        msi_free(package->patch->transforms);
+        msi_free(package->patch);
+    }
+
     msi_free(package->BaseURL);
     msi_free(package->PackagePath);
     msi_free(package->ProductCode);
@@ -797,9 +847,6 @@ BOOL ACTION_VerifyComponentForAction( const MSICOMPONENT* comp, INSTALLSTATE che
     if (!comp)
         return FALSE;
 
-    if (comp->Installed == check)
-        return FALSE;
-
     if (comp->ActionRequest == check)
         return TRUE;
     else
@@ -895,7 +942,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
             continue;
  
         if (newstate == INSTALLSTATE_LOCAL)
-            msi_component_set_state( component, INSTALLSTATE_LOCAL );
+            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
         else 
         {
             ComponentList *clist;
@@ -903,7 +950,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
 
             component->hasLocalFeature = FALSE;
 
-            msi_component_set_state( component, newstate );
+            msi_component_set_state(package, component, newstate);
 
             /*if any other feature wants is local we need to set it local*/
             LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
@@ -926,14 +973,14 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
                         if (component->Attributes & msidbComponentAttributesOptional)
                         {
                             if (f->Attributes & msidbFeatureAttributesFavorSource)
-                                msi_component_set_state( component, INSTALLSTATE_SOURCE );
+                                msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
                             else
-                                msi_component_set_state( component, INSTALLSTATE_LOCAL );
+                                msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
                         }
                         else if (component->Attributes & msidbComponentAttributesSourceOnly)
-                            msi_component_set_state( component, INSTALLSTATE_SOURCE );
+                            msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
                         else
-                            msi_component_set_state( component, INSTALLSTATE_LOCAL );
+                            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
                     }
                 }
             }
@@ -970,7 +1017,7 @@ UINT register_unique_action(MSIPACKAGE *package, LPCWSTR action)
 
 BOOL check_unique_action(const MSIPACKAGE *package, LPCWSTR action)
 {
-    INT i;
+    UINT i;
 
     if (!package->script)
         return FALSE;
@@ -1039,132 +1086,3 @@ void msi_ui_error( DWORD msg_id, DWORD type )
 
     MessageBoxW( NULL, text, title, type );
 }
-
-typedef struct
-{
-    MSIPACKAGE *package;
-    MSIMEDIAINFO *mi;
-    MSIFILE *file;
-    LPWSTR destination;
-} CabData;
-
-static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
-{
-    TRACE("(%d)\n", fdint);
-
-    switch (fdint)
-    {
-    case fdintNEXT_CABINET:
-    {
-        ERR("continuous cabinets not handled\n");
-        return 0;
-    }
-
-    case fdintCOPY_FILE:
-    {
-        CabData *data = (CabData*) pfdin->pv;
-        LPWSTR file, path;
-        DWORD attrs, size;
-        HANDLE handle;
-        MSIFILE *f;
-
-        file = strdupAtoW(pfdin->psz1);
-        f = get_loaded_file(data->package, file);
-        msi_free(file);
-
-        if (!f)
-        {
-            WARN("unknown file in cabinet (%s)\n",debugstr_a(pfdin->psz1));
-            return 0;
-        }
-
-        if (lstrcmpW(f->File, data->file->File))
-            return 0;
-
-        size = lstrlenW(data->destination) + lstrlenW(data->file->FileName) + 2;
-        path = msi_alloc(size * sizeof(WCHAR));
-        lstrcpyW(path, data->destination);
-        PathAddBackslashW(path);
-        lstrcatW(path, data->file->FileName);
-
-        TRACE("extracting %s\n", debugstr_w(path));
-
-        attrs = f->Attributes & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
-        if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
-
-        handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0,
-                             NULL, CREATE_ALWAYS, attrs, NULL);
-        if (handle == INVALID_HANDLE_VALUE)
-        {
-            if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
-                ERR("failed to create %s (error %d)\n",
-                    debugstr_w(path), GetLastError());
-
-            msi_free(path);
-            return 0;
-        }
-
-        msi_free(path);
-        return (INT_PTR)handle;
-    }
-
-    case fdintCLOSE_FILE_INFO:
-    {
-        FILETIME ft;
-        FILETIME ftLocal;
-        HANDLE handle = (HANDLE)pfdin->hf;
-
-        if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
-            return -1;
-        if (!LocalFileTimeToFileTime(&ft, &ftLocal))
-            return -1;
-        if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
-            return -1;
-        CloseHandle(handle);
-        return 1;
-    }
-
-    default:
-        return 0;
-    }
-}
-
-UINT msi_extract_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR destdir)
-{
-    MSIMEDIAINFO *mi;
-    CabData data;
-    UINT r;
-
-    mi = msi_alloc_zero(sizeof(MSIMEDIAINFO));
-    if (!mi)
-        return ERROR_OUTOFMEMORY;
-
-    r = msi_load_media_info(package, file, mi);
-    if (r != ERROR_SUCCESS)
-        goto done;
-
-    if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
-    {
-        r = find_published_source(package, mi);
-        if (r != ERROR_SUCCESS)
-        {
-            ERR("Cabinet not found: %s\n", debugstr_w(mi->source));
-            return ERROR_INSTALL_FAILURE;
-        }
-    }
-
-    data.package = package;
-    data.mi = mi;
-    data.file = file;
-    data.destination = destdir;
-
-    if (!msi_cabextract(package, mi, cabinet_notify, &data))
-    {
-        ERR("Failed to extract cabinet file\n");
-        r = ERROR_FUNCTION_FAILED;
-    }
-
-done:
-    msi_free_media_info(mi);
-    return r;
-}
index 55ac234..0907126 100644 (file)
@@ -239,6 +239,7 @@ static const MSIVIEWOPS insert_ops =
     NULL,
     NULL,
     NULL,
+    NULL,
 };
 
 static UINT count_column_info( const column_info *ci )
index 6415459..bcb68c3 100644 (file)
@@ -215,8 +215,8 @@ UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
 /***********************************************************************
  * MsiGetTargetPath   (internal)
  */
-static UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
-                                      awstring *szPathBuf, LPDWORD pcchPathBuf )
+static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
+                               awstring *szPathBuf, LPDWORD pcchPathBuf )
 {
     MSIPACKAGE *package;
     LPWSTR path;
@@ -774,7 +774,7 @@ UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
         feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
         return ERROR_FUNCTION_FAILED;
 
-    msi_feature_set_state( feature, iState );
+    msi_feature_set_state(package, feature, iState);
 
     ACTION_UpdateComponentStates(package,szFeature);
 
index 756db6f..34de3b1 100644 (file)
@@ -306,6 +306,7 @@ static const MSIVIEWOPS join_ops =
     NULL,
     NULL,
     JOIN_sort,
+    NULL,
 };
 
 UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR tables )
diff --git a/reactos/dll/win32/msi/media.c b/reactos/dll/win32/msi/media.c
new file mode 100644 (file)
index 0000000..a236eba
--- /dev/null
@@ -0,0 +1,648 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2008 James Hawkins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "fdi.h"
+#include "msipriv.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "wine/unicode.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/* from msvcrt/fcntl.h */
+#define _O_RDONLY      0
+#define _O_WRONLY      1
+#define _O_RDWR        2
+#define _O_ACCMODE     (_O_RDONLY|_O_WRONLY|_O_RDWR)
+#define _O_APPEND      0x0008
+#define _O_RANDOM      0x0010
+#define _O_SEQUENTIAL  0x0020
+#define _O_TEMPORARY   0x0040
+#define _O_NOINHERIT   0x0080
+#define _O_CREAT       0x0100
+#define _O_TRUNC       0x0200
+#define _O_EXCL        0x0400
+#define _O_SHORT_LIVED 0x1000
+#define _O_TEXT        0x4000
+#define _O_BINARY      0x8000
+
+static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPWSTR source_root)
+{
+    WCHAR volume_name[MAX_PATH + 1];
+
+    if (!GetVolumeInformationW(source_root, volume_name, MAX_PATH + 1,
+                               NULL, NULL, NULL, NULL, 0))
+    {
+        ERR("Failed to get volume information\n");
+        return FALSE;
+    }
+
+    return !lstrcmpW(mi->volume_label, volume_name);
+}
+
+static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
+{
+    LPSTR msg;
+    LPWSTR error, error_dialog;
+    LPWSTR source_dir;
+    UINT r = ERROR_SUCCESS;
+
+    static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
+    static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
+
+    if ((msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) ==
+         INSTALLUILEVEL_NONE && !gUIHandlerA)
+        return ERROR_SUCCESS;
+
+    error = generate_error_string(package, 1302, 1, mi->disk_prompt);
+    error_dialog = msi_dup_property(package, error_prop);
+    source_dir = msi_dup_property(package, cszSourceDir);
+    PathStripToRootW(source_dir);
+
+    while (r == ERROR_SUCCESS &&
+           !source_matches_volume(mi, source_dir))
+    {
+        r = msi_spawn_error_dialog(package, error_dialog, error);
+
+        if (gUIHandlerA)
+        {
+            msg = strdupWtoA(error);
+            gUIHandlerA(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg);
+            msi_free(msg);
+        }
+    }
+
+    msi_free(error);
+    msi_free(error_dialog);
+    msi_free(source_dir);
+
+    return r;
+}
+
+static UINT writeout_cabinet_stream(MSIPACKAGE *package, LPCWSTR stream,
+                                    WCHAR* source)
+{
+    UINT rc;
+    USHORT* data;
+    UINT size;
+    DWORD write;
+    HANDLE hfile;
+    WCHAR tmp[MAX_PATH];
+
+    static const WCHAR cszTempFolder[]= {
+       'T','e','m','p','F','o','l','d','e','r',0};
+
+    rc = read_raw_stream_data(package->db, stream, &data, &size);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    write = MAX_PATH;
+    if (MSI_GetPropertyW(package, cszTempFolder, tmp, &write))
+        GetTempPathW(MAX_PATH, tmp);
+
+    GetTempFileNameW(tmp, stream, 0, source);
+
+    track_tempfile(package, source);
+    hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+                        FILE_ATTRIBUTE_NORMAL, NULL);
+
+    if (hfile == INVALID_HANDLE_VALUE)
+    {
+        ERR("Unable to create file %s\n", debugstr_w(source));
+        rc = ERROR_FUNCTION_FAILED;
+        goto end;
+    }
+
+    WriteFile(hfile, data, size, &write, NULL);
+    CloseHandle(hfile);
+    TRACE("wrote %i bytes to %s\n", write, debugstr_w(source));
+
+end:
+    msi_free(data);
+    return rc;
+}
+
+static void *cabinet_alloc(ULONG cb)
+{
+    return msi_alloc(cb);
+}
+
+static void cabinet_free(void *pv)
+{
+    msi_free(pv);
+}
+
+static INT_PTR cabinet_open(char *pszFile, int oflag, int pmode)
+{
+    HANDLE handle;
+    DWORD dwAccess = 0;
+    DWORD dwShareMode = 0;
+    DWORD dwCreateDisposition = OPEN_EXISTING;
+
+    switch (oflag & _O_ACCMODE)
+    {
+    case _O_RDONLY:
+        dwAccess = GENERIC_READ;
+        dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
+        break;
+    case _O_WRONLY:
+        dwAccess = GENERIC_WRITE;
+        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+        break;
+    case _O_RDWR:
+        dwAccess = GENERIC_READ | GENERIC_WRITE;
+        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+        break;
+    }
+
+    if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
+        dwCreateDisposition = CREATE_NEW;
+    else if (oflag & _O_CREAT)
+        dwCreateDisposition = CREATE_ALWAYS;
+
+    handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
+                         dwCreateDisposition, 0, NULL);
+    if (handle == INVALID_HANDLE_VALUE)
+        return 0;
+
+    return (INT_PTR)handle;
+}
+
+static UINT cabinet_read(INT_PTR hf, void *pv, UINT cb)
+{
+    HANDLE handle = (HANDLE)hf;
+    DWORD read;
+
+    if (ReadFile(handle, pv, cb, &read, NULL))
+        return read;
+
+    return 0;
+}
+
+static UINT cabinet_write(INT_PTR hf, void *pv, UINT cb)
+{
+    HANDLE handle = (HANDLE)hf;
+    DWORD written;
+
+    if (WriteFile(handle, pv, cb, &written, NULL))
+        return written;
+
+    return 0;
+}
+
+static int cabinet_close(INT_PTR hf)
+{
+    HANDLE handle = (HANDLE)hf;
+    return CloseHandle(handle) ? 0 : -1;
+}
+
+static long cabinet_seek(INT_PTR hf, long dist, int seektype)
+{
+    HANDLE handle = (HANDLE)hf;
+    /* flags are compatible and so are passed straight through */
+    return SetFilePointer(handle, dist, NULL, seektype);
+}
+
+static UINT msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi)
+{
+    MSIRECORD *row;
+    LPWSTR ptr;
+
+    static const WCHAR query[] = {
+        'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+        '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
+        '`','D','i','s','k','I','d','`',' ','=',' ','%','i',0};
+
+    row = MSI_QueryGetRecord(package->db, query, mi->disk_id);
+    if (!row)
+    {
+        TRACE("Unable to query row\n");
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
+    mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
+    mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
+
+    if (!mi->first_volume)
+        mi->first_volume = strdupW(mi->volume_label);
+
+    ptr = strrchrW(mi->source, '\\') + 1;
+    lstrcpyW(ptr, mi->cabinet);
+    msiobj_release(&row->hdr);
+
+    return ERROR_SUCCESS;
+}
+
+static INT_PTR cabinet_partial_file(FDINOTIFICATIONTYPE fdint,
+                                    PFDINOTIFICATION pfdin)
+{
+    MSICABDATA *data = (MSICABDATA *)pfdin->pv;
+    data->mi->is_continuous = FALSE;
+    return 0;
+}
+
+static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint,
+                                    PFDINOTIFICATION pfdin)
+{
+    MSICABDATA *data = (MSICABDATA *)pfdin->pv;
+    MSIMEDIAINFO *mi = data->mi;
+    LPWSTR cab = strdupAtoW(pfdin->psz1);
+    INT_PTR res = -1;
+    UINT rc;
+
+    msi_free(mi->disk_prompt);
+    msi_free(mi->cabinet);
+    msi_free(mi->volume_label);
+    mi->disk_prompt = NULL;
+    mi->cabinet = NULL;
+    mi->volume_label = NULL;
+
+    mi->disk_id++;
+    mi->is_continuous = TRUE;
+
+    rc = msi_media_get_disk_info(data->package, mi);
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("Failed to get next cabinet information: %d\n", rc);
+        goto done;
+    }
+
+    if (lstrcmpiW(mi->cabinet, cab))
+    {
+        ERR("Continuous cabinet does not match the next cabinet in the Media table\n");
+        goto done;
+    }
+
+    TRACE("Searching for %s\n", debugstr_w(mi->source));
+
+    res = 0;
+    if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
+    {
+        if (msi_change_media(data->package, mi) != ERROR_SUCCESS)
+            res = -1;
+    }
+
+done:
+    msi_free(cab);
+    return res;
+}
+
+static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
+                                 PFDINOTIFICATION pfdin)
+{
+    MSICABDATA *data = (MSICABDATA*)pfdin->pv;
+    HANDLE handle = 0;
+    LPWSTR path = NULL;
+    DWORD attrs;
+
+    data->curfile = strdupAtoW(pfdin->psz1);
+    if (!data->cb(data->package, data->curfile, MSICABEXTRACT_BEGINEXTRACT, &path,
+                  &attrs, data->user))
+        goto done;
+
+    TRACE("extracting %s\n", debugstr_w(path));
+
+    attrs = attrs & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
+    if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
+
+    handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0,
+                         NULL, CREATE_ALWAYS, attrs, NULL);
+    if (handle == INVALID_HANDLE_VALUE)
+    {
+        if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
+            ERR("failed to create %s (error %d)\n",
+                debugstr_w(path), GetLastError());
+
+        goto done;
+    }
+
+done:
+    msi_free(path);
+
+    return (INT_PTR)handle;
+}
+
+static INT_PTR cabinet_close_file_info(FDINOTIFICATIONTYPE fdint,
+                                       PFDINOTIFICATION pfdin)
+{
+    MSICABDATA *data = (MSICABDATA*)pfdin->pv;
+    FILETIME ft;
+    FILETIME ftLocal;
+    HANDLE handle = (HANDLE)pfdin->hf;
+
+    data->mi->is_continuous = FALSE;
+
+    if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
+        return -1;
+    if (!LocalFileTimeToFileTime(&ft, &ftLocal))
+        return -1;
+    if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
+        return -1;
+
+    CloseHandle(handle);
+
+    data->cb(data->package, data->curfile, MSICABEXTRACT_FILEEXTRACTED, NULL, NULL,
+             data->user);
+
+    msi_free(data->curfile);
+    data->curfile = NULL;
+
+    return 1;
+}
+
+static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
+{
+    TRACE("(%d)\n", fdint);
+
+    switch (fdint)
+    {
+    case fdintPARTIAL_FILE:
+        return cabinet_partial_file(fdint, pfdin);
+
+    case fdintNEXT_CABINET:
+        return cabinet_next_cabinet(fdint, pfdin);
+
+    case fdintCOPY_FILE:
+        return cabinet_copy_file(fdint, pfdin);
+
+    case fdintCLOSE_FILE_INFO:
+        return cabinet_close_file_info(fdint, pfdin);
+
+    default:
+        return 0;
+    }
+}
+
+/***********************************************************************
+ *            msi_cabextract
+ *
+ * Extract files from a cab file.
+ */
+BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data)
+{
+    LPSTR cabinet, cab_path = NULL;
+    LPWSTR ptr;
+    HFDI hfdi;
+    ERF erf;
+    BOOL ret = FALSE;
+
+    TRACE("Extracting %s\n", debugstr_w(mi->source));
+
+    hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read,
+                     cabinet_write, cabinet_close, cabinet_seek, 0, &erf);
+    if (!hfdi)
+    {
+        ERR("FDICreate failed\n");
+        return FALSE;
+    }
+
+    ptr = strrchrW(mi->source, '\\') + 1;
+    cabinet = strdupWtoA(ptr);
+    if (!cabinet)
+        goto done;
+
+    cab_path = strdupWtoA(mi->source);
+    if (!cab_path)
+        goto done;
+
+    cab_path[ptr - mi->source] = '\0';
+
+    ret = FDICopy(hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data);
+    if (!ret)
+        ERR("FDICopy failed\n");
+
+done:
+    FDIDestroy(hfdi);
+    msi_free(cabinet);
+    msi_free(cab_path);
+
+    if (ret)
+        mi->is_extracted = TRUE;
+
+    return ret;
+}
+
+void msi_free_media_info(MSIMEDIAINFO *mi)
+{
+    msi_free(mi->disk_prompt);
+    msi_free(mi->cabinet);
+    msi_free(mi->volume_label);
+    msi_free(mi->first_volume);
+    msi_free(mi);
+}
+
+UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
+{
+    MSIRECORD *row;
+    LPWSTR source_dir;
+    LPWSTR source;
+    DWORD options;
+    UINT r;
+
+    static const WCHAR query[] = {
+        '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',' ','A','N','D',' ','`','D','i','s','k','I','d','`',' ','>','=',
+        ' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ',
+        '`','D','i','s','k','I','d','`',0};
+
+    row = MSI_QueryGetRecord(package->db, query, file->Sequence, mi->disk_id);
+    if (!row)
+    {
+        TRACE("Unable to query row\n");
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    mi->is_extracted = FALSE;
+    mi->disk_id = MSI_RecordGetInteger(row, 1);
+    mi->last_sequence = MSI_RecordGetInteger(row, 2);
+    msi_free(mi->disk_prompt);
+    mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
+    msi_free(mi->cabinet);
+    mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
+    msi_free(mi->volume_label);
+    mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
+    msiobj_release(&row->hdr);
+
+    if (!mi->first_volume)
+        mi->first_volume = strdupW(mi->volume_label);
+
+    source_dir = msi_dup_property(package, cszSourceDir);
+    lstrcpyW(mi->source, source_dir);
+
+    PathStripToRootW(source_dir);
+    mi->type = GetDriveTypeW(source_dir);
+
+    if (file->IsCompressed && mi->cabinet)
+    {
+        if (mi->cabinet[0] == '#')
+        {
+            r = writeout_cabinet_stream(package, &mi->cabinet[1], mi->source);
+            if (r != ERROR_SUCCESS)
+            {
+                ERR("Failed to extract cabinet stream\n");
+                return ERROR_FUNCTION_FAILED;
+            }
+        }
+        else
+            lstrcatW(mi->source, mi->cabinet);
+    }
+
+    options = MSICODE_PRODUCT;
+    if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE)
+    {
+        source = source_dir;
+        options |= MSISOURCETYPE_MEDIA;
+    }
+    else if (package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL))
+    {
+        source = package->BaseURL;
+        options |= MSISOURCETYPE_URL;
+    }
+    else
+    {
+        source = mi->source;
+        options |= MSISOURCETYPE_NETWORK;
+    }
+
+    msi_package_add_media_disk(package, package->Context,
+                               MSICODE_PRODUCT, mi->disk_id,
+                               mi->volume_label, mi->disk_prompt);
+
+    msi_package_add_info(package, package->Context,
+                         options, INSTALLPROPERTY_LASTUSEDSOURCEW, source);
+
+    msi_free(source_dir);
+    return ERROR_SUCCESS;
+}
+
+/* FIXME: search NETWORK and URL sources as well */
+UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi)
+{
+    WCHAR source[MAX_PATH];
+    WCHAR volume[MAX_PATH];
+    WCHAR prompt[MAX_PATH];
+    DWORD volumesz, promptsz;
+    DWORD index, size, id;
+    UINT r;
+
+    size = MAX_PATH;
+    r = MsiSourceListGetInfoW(package->ProductCode, NULL,
+                              package->Context, MSICODE_PRODUCT,
+                              INSTALLPROPERTY_LASTUSEDSOURCEW, source, &size);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    index = 0;
+    volumesz = MAX_PATH;
+    promptsz = MAX_PATH;
+    while (MsiSourceListEnumMediaDisksW(package->ProductCode, NULL,
+                                        package->Context,
+                                        MSICODE_PRODUCT, index++, &id,
+                                        volume, &volumesz, prompt, &promptsz) == ERROR_SUCCESS)
+    {
+        mi->disk_id = id;
+        mi->volume_label = msi_realloc(mi->volume_label, ++volumesz * sizeof(WCHAR));
+        lstrcpyW(mi->volume_label, volume);
+        mi->disk_prompt = msi_realloc(mi->disk_prompt, ++promptsz * sizeof(WCHAR));
+        lstrcpyW(mi->disk_prompt, prompt);
+
+        if (source_matches_volume(mi, source))
+        {
+            /* FIXME: what about SourceDir */
+            lstrcpyW(mi->source, source);
+            lstrcatW(mi->source, mi->cabinet);
+            return ERROR_SUCCESS;
+        }
+    }
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
+{
+    UINT rc = ERROR_SUCCESS;
+
+    /* media info for continuous cabinet is already loaded */
+    if (mi->is_continuous)
+        return ERROR_SUCCESS;
+
+    rc = msi_load_media_info(package, file, mi);
+    if (rc != ERROR_SUCCESS)
+    {
+        ERR("Unable to load media info\n");
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    /* cabinet is internal, no checks needed */
+    if (!mi->cabinet || mi->cabinet[0] == '#')
+        return ERROR_SUCCESS;
+
+    /* package should be downloaded */
+    if (file->IsCompressed &&
+        GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES &&
+        package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL))
+    {
+        WCHAR temppath[MAX_PATH];
+
+        msi_download_file(mi->source, temppath);
+        lstrcpyW(mi->source, temppath);
+        return ERROR_SUCCESS;
+    }
+
+    /* check volume matches, change media if not */
+    if (mi->volume_label && mi->disk_id > 1 &&
+        lstrcmpW(mi->first_volume, mi->volume_label))
+    {
+        LPWSTR source = msi_dup_property(package, cszSourceDir);
+        BOOL matches;
+
+        matches = source_matches_volume(mi, source);
+        msi_free(source);
+
+        if ((mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) && !matches)
+        {
+            rc = msi_change_media(package, mi);
+            if (rc != ERROR_SUCCESS)
+                return rc;
+        }
+    }
+
+    if (file->IsCompressed &&
+        GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
+    {
+        rc = find_published_source(package, mi);
+        if (rc != ERROR_SUCCESS)
+        {
+            ERR("Cabinet not found: %s\n", debugstr_w(mi->source));
+            return ERROR_INSTALL_FAILURE;
+        }
+    }
+
+    return ERROR_SUCCESS;
+}
index 0bd23fa..9a5c54a 100644 (file)
@@ -45,6 +45,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
 
 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
 
+static UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
+{
+    HKEY hkey = NULL;
+
+    *context = MSIINSTALLCONTEXT_NONE;
+
+    if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+                              &hkey, FALSE) == ERROR_SUCCESS)
+        *context = MSIINSTALLCONTEXT_USERMANAGED;
+    else if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                                   &hkey, FALSE) == ERROR_SUCCESS)
+        *context = MSIINSTALLCONTEXT_MACHINE;
+    else if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                                   &hkey, FALSE) == ERROR_SUCCESS)
+        *context = MSIINSTALLCONTEXT_USERUNMANAGED;
+
+    RegCloseKey(hkey);
+
+    if (*context == MSIINSTALLCONTEXT_NONE)
+        return ERROR_UNKNOWN_PRODUCT;
+
+    return ERROR_SUCCESS;
+}
+
 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
 {
     UINT r;
@@ -66,69 +90,73 @@ UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
     return r;
 }
 
-static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
+static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
 {
-    LPWSTR path = NULL;
     UINT r;
-    HKEY hKeyProduct = NULL;
-    DWORD count, type;
+    HKEY props;
+    LPWSTR path;
+    MSIINSTALLCONTEXT context;
 
-    TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
+    static const WCHAR managed[] = {
+        'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0};
+    static const WCHAR local[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
 
-    r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
-    if( r != ERROR_SUCCESS )
-    {
-        r = ERROR_UNKNOWN_PRODUCT;
-        goto end;
-    }
+    TRACE("%s %p\n", debugstr_w(szProduct), package);
 
-    /* find the size of the path */
-    type = count = 0;
-    r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
-                          NULL, &type, NULL, &count );
-    if( r != ERROR_SUCCESS )
-    {
-        r = ERROR_UNKNOWN_PRODUCT;
-        goto end;
-    }
+    r = msi_locate_product(szProduct, &context);
+    if (r != ERROR_SUCCESS)
+        return r;
 
-    /* now alloc and fetch the path of the database to open */
-    path = msi_alloc( count );
-    if( !path )
-        goto end;
+    r = MSIREG_OpenInstallProps(szProduct, context, NULL, &props, FALSE);
+    if (r != ERROR_SUCCESS)
+        return ERROR_UNKNOWN_PRODUCT;
+
+    if (context == MSIINSTALLCONTEXT_USERMANAGED)
+        path = msi_reg_get_val_str(props, managed);
+    else
+        path = msi_reg_get_val_str(props, local);
+
+    r = ERROR_UNKNOWN_PRODUCT;
 
-    r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
-                          NULL, &type, (LPBYTE) path, &count );
-    if( r != ERROR_SUCCESS )
+    if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
+        goto done;
+
+    if (PathIsRelativeW(path))
     {
-        r = ERROR_UNKNOWN_PRODUCT;
-        goto end;
+        r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
+        goto done;
     }
 
-    r = MSI_OpenPackageW( path, ppackage );
-
-end:
-    msi_free( path );
-    if( hKeyProduct )
-        RegCloseKey( hKeyProduct );
+    r = MSI_OpenPackageW(path, package);
 
+done:
+    RegCloseKey(props);
+    msi_free(path);
     return r;
 }
 
-UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
+UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
 {
-   MSIPACKAGE *package = NULL;
-   UINT r;
+    MSIPACKAGE *package = NULL;
+    WCHAR squished_pc[GUID_SIZE];
+    UINT r;
+
+    if (!szProduct || !squash_guid(szProduct, squished_pc))
+        return ERROR_INVALID_PARAMETER;
+
+    if (!phProduct)
+        return ERROR_INVALID_PARAMETER;
+
+    r = MSI_OpenProductW(szProduct, &package);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    *phProduct = alloc_msihandle(&package->hdr);
+    if (!*phProduct)
+        r = ERROR_NOT_ENOUGH_MEMORY;
 
-   r = MSI_OpenProductW( szProduct, &package );
-   if( r == ERROR_SUCCESS )
-   {
-       *phProduct = alloc_msihandle( &package->hdr );
-       if (! *phProduct)
-           r = ERROR_NOT_ENOUGH_MEMORY;
-       msiobj_release( &package->hdr );
-   }
-   return r;
+    msiobj_release(&package->hdr);
+    return r;
 }
 
 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
@@ -342,47 +370,103 @@ done:
     return r;
 }
 
+UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
+        DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
+{
+    FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath),
+          cPatchInfo, pPatchInfo);
+
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
+        DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
+{
+    FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath),
+          cPatchInfo, pPatchInfo);
+
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context,
+                             MSIPACKAGE **package)
+{
+    UINT r;
+    DWORD sz;
+    HKEY props;
+    LPWSTR localpack;
+    WCHAR sourcepath[MAX_PATH];
+    WCHAR filename[MAX_PATH];
+
+    static const WCHAR szLocalPackage[] = {
+        'L','o','c','a','l','P','a','c','k','a','g','e',0};
+
+
+    r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
+    if (r != ERROR_SUCCESS)
+        return ERROR_BAD_CONFIGURATION;
+
+    localpack = msi_reg_get_val_str(props, szLocalPackage);
+    if (localpack)
+    {
+        lstrcpyW(sourcepath, localpack);
+        msi_free(localpack);
+    }
+
+    if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+    {
+        sz = sizeof(sourcepath);
+        MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
+                              INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
+
+        sz = sizeof(filename);
+        MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
+                              INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
+
+        lstrcatW(sourcepath, filename);
+    }
+
+    if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+        return ERROR_INSTALL_SOURCE_ABSENT;
+
+    return MSI_OpenPackageW(sourcepath, package);
+}
+
 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
                         INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
 {
     MSIPACKAGE* package = NULL;
+    MSIINSTALLCONTEXT context;
     UINT r;
     DWORD sz;
     WCHAR sourcepath[MAX_PATH];
-    WCHAR filename[MAX_PATH];
+    LPWSTR commandline;
+
     static const WCHAR szInstalled[] = {
         ' ','I','n','s','t','a','l','l','e','d','=','1',0};
-    LPWSTR commandline;
+    static const WCHAR szRemoveAll[] = {
+        ' ','R','E','M','O','V','E','=','A','L','L',0};
+    static const WCHAR szMachine[] = {
+        ' ','A','L','L','U','S','E','R','S','=','1',0};
 
     TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
           debugstr_w(szCommandLine));
 
-    if (eInstallState != INSTALLSTATE_LOCAL &&
-        eInstallState != INSTALLSTATE_DEFAULT)
+    if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
+        return ERROR_INVALID_PARAMETER;
+
+    if (eInstallState == INSTALLSTATE_ADVERTISED ||
+        eInstallState == INSTALLSTATE_SOURCE)
     {
-        FIXME("Not implemented for anything other than local installs\n");
+        FIXME("State %d not implemented\n", eInstallState);
         return ERROR_CALL_NOT_IMPLEMENTED;
     }
 
-    sz = sizeof(sourcepath);
-    MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
-            MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
-            &sz);
-
-    sz = sizeof(filename);
-    MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
-            MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
-
-    lstrcatW(sourcepath,filename);
-
-    /*
-     * ok 1, we need to find the msi file for this product.
-     *    2, find the source dir for the files
-     *    3, do the configure/install.
-     *    4, cleanupany runonce entry.
-     */
+    r = msi_locate_product(szProduct, &context);
+    if (r != ERROR_SUCCESS)
+        return r;
 
-    r = MSI_OpenProductW( szProduct, &package );
+    r = msi_open_package(szProduct, context, &package);
     if (r != ERROR_SUCCESS)
         return r;
 
@@ -391,8 +475,14 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
     if (szCommandLine)
         sz += lstrlenW(szCommandLine);
 
+    if (eInstallState == INSTALLSTATE_ABSENT)
+        sz += lstrlenW(szRemoveAll);
+
+    if (context == MSIINSTALLCONTEXT_MACHINE)
+        sz += lstrlenW(szMachine);
+
     commandline = msi_alloc(sz * sizeof(WCHAR));
-    if (!commandline )
+    if (!commandline)
     {
         r = ERROR_OUTOFMEMORY;
         goto end;
@@ -405,6 +495,12 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
     if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
         lstrcatW(commandline,szInstalled);
 
+    if (eInstallState == INSTALLSTATE_ABSENT)
+        lstrcatW(commandline, szRemoveAll);
+
+    if (context == MSIINSTALLCONTEXT_MACHINE)
+        lstrcatW(commandline, szMachine);
+
     r = MSI_InstallPackage( package, sourcepath, commandline );
 
     msi_free(commandline);
@@ -514,8 +610,8 @@ UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
     if (!squash_guid(szComponent, squished_comp))
         return ERROR_INVALID_PARAMETER;
 
-    if (MSIREG_OpenUserDataComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS &&
-        MSIREG_OpenLocalSystemComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS)
+    if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &compkey, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &compkey, FALSE) != ERROR_SUCCESS)
     {
         return ERROR_UNKNOWN_COMPONENT;
     }
@@ -543,9 +639,12 @@ UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
         sz = GUID_SIZE;
         unsquash_guid(squished_prod, szBuffer);
 
-        if (MSIREG_OpenLocalManagedProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
-            MSIREG_OpenUserProductsKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
-            MSIREG_OpenLocalClassesProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS)
+        if (MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERMANAGED,
+                                  &prodkey, FALSE) == ERROR_SUCCESS ||
+            MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERUNMANAGED,
+                                  &prodkey, FALSE) == ERROR_SUCCESS ||
+            MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_MACHINE,
+                                  &prodkey, FALSE) == ERROR_SUCCESS)
         {
             RegCloseKey(prodkey);
             rc = ERROR_SUCCESS;
@@ -583,15 +682,15 @@ static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
     return strdupW(temp);
 }
 
-static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
-                                      awstring *szValue, LPDWORD pcchValueBuf)
+static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
+                               awstring *szValue, LPDWORD pcchValueBuf)
 {
+    MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
     UINT r = ERROR_UNKNOWN_PROPERTY;
     HKEY prodkey, userdata, source;
     LPWSTR val = NULL;
     WCHAR squished_pc[GUID_SIZE];
     WCHAR packagecode[GUID_SIZE];
-    BOOL classes = FALSE;
     BOOL badconfig = FALSE;
     LONG res;
     DWORD save, type = REG_NONE;
@@ -615,22 +714,17 @@ static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
     if (!squash_guid(szProduct, squished_pc))
         return ERROR_INVALID_PARAMETER;
 
-    r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
-    if (r != ERROR_SUCCESS)
+    if ((r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+                                   &prodkey, FALSE)) != ERROR_SUCCESS &&
+        (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                                   &prodkey, FALSE)) != ERROR_SUCCESS &&
+        (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                                      &prodkey, FALSE)) == ERROR_SUCCESS)
     {
-        r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
-        if (r != ERROR_SUCCESS)
-        {
-            r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
-            if (r == ERROR_SUCCESS)
-                classes = TRUE;
-        }
+        context = MSIINSTALLCONTEXT_MACHINE;
     }
 
-    if (classes)
-        MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
-    else
-        MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
+    MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
 
     if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
         !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
@@ -726,7 +820,7 @@ static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
     {
         save = *pcchValueBuf;
 
-        if (lstrlenW(val) < *pcchValueBuf)
+        if (strlenW(val) < *pcchValueBuf)
             r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
         else if (szValue->str.a || szValue->str.w)
             r = ERROR_MORE_DATA;
@@ -872,7 +966,7 @@ static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
 
     if (out)
     {
-        if (lstrlenW(val) >= *size)
+        if (strlenW(val) >= *size)
         {
             r = ERROR_MORE_DATA;
             if (*size > 0)
@@ -933,13 +1027,17 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
     if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
         return ERROR_INVALID_PARAMETER;
 
-    MSIREG_OpenLocalManagedProductKey(szProductCode, &managed, FALSE);
-    MSIREG_OpenUserProductsKey(szProductCode, &prod, FALSE);
+    /* FIXME: dwContext is provided, no need to search for it */
+    MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERMANAGED,
+                          &managed, FALSE);
+    MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERUNMANAGED,
+                          &prod, FALSE);
+
+    MSIREG_OpenInstallProps(szProductCode, dwContext, NULL, &props, FALSE);
 
     if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
     {
         package = INSTALLPROPERTY_LOCALPACKAGEW;
-        MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
 
         if (!props && !prod)
             goto done;
@@ -947,7 +1045,6 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
     else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
     {
         package = managed_local_package;
-        MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
 
         if (!props && !managed)
             goto done;
@@ -955,8 +1052,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
     else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
     {
         package = INSTALLPROPERTY_LOCALPACKAGEW;
-        MSIREG_OpenLocalSystemProductKey(szProductCode, &props, FALSE);
-        MSIREG_OpenLocalClassesProductKey(szProductCode, &classes, FALSE);
+        MSIREG_OpenProductKey(szProductCode, dwContext, &classes, FALSE);
 
         if (!props && !classes)
             goto done;
@@ -1083,6 +1179,223 @@ done:
     return r;
 }
 
+UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode,
+                               LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
+                               LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
+{
+    LPWSTR patch = NULL, product = NULL, usersid = NULL;
+    LPWSTR property = NULL, val = NULL;
+    DWORD len;
+    UINT r;
+
+    TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_a(szPatchCode),
+          debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext,
+          debugstr_a(szProperty), lpValue, pcchValue);
+
+    if (lpValue && !pcchValue)
+        return ERROR_INVALID_PARAMETER;
+
+    if (szPatchCode) patch = strdupAtoW(szPatchCode);
+    if (szProductCode) product = strdupAtoW(szProductCode);
+    if (szUserSid) usersid = strdupAtoW(szUserSid);
+    if (szProperty) property = strdupAtoW(szProperty);
+
+    len = 0;
+    r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
+                           NULL, &len);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    val = msi_alloc(++len * sizeof(WCHAR));
+    if (!val)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
+                           val, &len);
+    if (r != ERROR_SUCCESS || !pcchValue)
+        goto done;
+
+    if (lpValue)
+        WideCharToMultiByte(CP_ACP, 0, val, -1, lpValue,
+                            *pcchValue - 1, NULL, NULL);
+
+    len = lstrlenW(val);
+    if ((*val && *pcchValue < len + 1) || !lpValue)
+    {
+        if (lpValue)
+        {
+            r = ERROR_MORE_DATA;
+            lpValue[*pcchValue - 1] = '\0';
+        }
+
+        *pcchValue = len * sizeof(WCHAR);
+    }
+    else
+        *pcchValue = len;
+
+done:
+    msi_free(val);
+    msi_free(patch);
+    msi_free(product);
+    msi_free(usersid);
+    msi_free(property);
+
+    return r;
+}
+
+UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
+                               LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
+                               LPCWSTR szProperty, LPWSTR lpValue, DWORD *pcchValue)
+{
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR squished_patch[GUID_SIZE];
+    HKEY udprod = 0, prod = 0, props = 0;
+    HKEY patch = 0, patches = 0;
+    HKEY udpatch = 0, datakey = 0;
+    HKEY prodpatches = 0;
+    LPWSTR val = NULL;
+    UINT r = ERROR_UNKNOWN_PRODUCT;
+    DWORD len;
+    LONG res;
+
+    static const WCHAR szEmpty[] = {0};
+    static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
+    static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
+    static const WCHAR szManagedPackage[] = {'M','a','n','a','g','e','d',
+        'L','o','c','a','l','P','a','c','k','a','g','e',0};
+
+    TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_w(szPatchCode),
+          debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext,
+          debugstr_w(szProperty), lpValue, pcchValue);
+
+    if (!szProductCode || !squash_guid(szProductCode, squished_pc))
+        return ERROR_INVALID_PARAMETER;
+
+    if (!szPatchCode || !squash_guid(szPatchCode, squished_patch))
+        return ERROR_INVALID_PARAMETER;
+
+    if (!szProperty)
+        return ERROR_INVALID_PARAMETER;
+
+    if (lpValue && !pcchValue)
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
+        dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
+        dwContext != MSIINSTALLCONTEXT_MACHINE)
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
+        return ERROR_INVALID_PARAMETER;
+
+    if (!lstrcmpW(szUserSid, szLocalSid))
+        return ERROR_INVALID_PARAMETER;
+
+    if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL,
+                                      &udprod, FALSE) != ERROR_SUCCESS)
+        goto done;
+
+    if (MSIREG_OpenInstallProps(szProductCode, dwContext, NULL,
+                                &props, FALSE) != ERROR_SUCCESS)
+        goto done;
+
+    r = ERROR_UNKNOWN_PATCH;
+
+    res = RegOpenKeyExW(udprod, szPatches, 0, KEY_READ, &patches);
+    if (res != ERROR_SUCCESS)
+        goto done;
+
+    res = RegOpenKeyExW(patches, squished_patch, 0, KEY_READ, &patch);
+    if (res != ERROR_SUCCESS)
+        goto done;
+
+    if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW))
+    {
+        if (MSIREG_OpenProductKey(szProductCode, dwContext,
+                                  &prod, FALSE) != ERROR_SUCCESS)
+            goto done;
+
+        res = RegOpenKeyExW(prod, szPatches, 0, KEY_ALL_ACCESS, &prodpatches);
+        if (res != ERROR_SUCCESS)
+            goto done;
+
+        datakey = prodpatches;
+        szProperty = squished_patch;
+    }
+    else
+    {
+        if (MSIREG_OpenUserDataPatchKey(szPatchCode, dwContext,
+                                        &udpatch, FALSE) != ERROR_SUCCESS)
+            goto done;
+
+        if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
+        {
+            if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
+                szProperty = szManagedPackage;
+            datakey = udpatch;
+        }
+        else if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW))
+        {
+            datakey = patch;
+            szProperty = szInstalled;
+        }
+        else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
+        {
+            datakey = udpatch;
+        }
+        else if (!lstrcmpW(szProperty, INSTALLPROPERTY_UNINSTALLABLEW) ||
+                 !lstrcmpW(szProperty, INSTALLPROPERTY_PATCHSTATEW) ||
+                 !lstrcmpW(szProperty, INSTALLPROPERTY_DISPLAYNAMEW) ||
+                 !lstrcmpW(szProperty, INSTALLPROPERTY_MOREINFOURLW))
+        {
+            datakey = patch;
+        }
+        else
+        {
+            r = ERROR_UNKNOWN_PROPERTY;
+            goto done;
+        }
+    }
+
+    val = msi_reg_get_val_str(datakey, szProperty);
+    if (!val)
+        val = strdupW(szEmpty);
+
+    r = ERROR_SUCCESS;
+
+    if (!pcchValue)
+        goto done;
+
+    if (lpValue)
+        lstrcpynW(lpValue, val, *pcchValue);
+
+    len = lstrlenW(val);
+    if ((*val && *pcchValue < len + 1) || !lpValue)
+    {
+        if (lpValue)
+            r = ERROR_MORE_DATA;
+
+        *pcchValue = len * sizeof(WCHAR);
+    }
+
+    *pcchValue = len;
+
+done:
+    msi_free(val);
+    RegCloseKey(prodpatches);
+    RegCloseKey(prod);
+    RegCloseKey(patch);
+    RegCloseKey(patches);
+    RegCloseKey(udpatch);
+    RegCloseKey(props);
+    RegCloseKey(udprod);
+
+    return r;
+}
+
 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
 {
     LPWSTR szwLogFile = NULL;
@@ -1170,13 +1483,7 @@ static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
     UINT r;
     HKEY hkey;
 
-    if (context == MSIINSTALLCONTEXT_MACHINE)
-        r = MSIREG_OpenLocalClassesProductKey(prodcode, &hkey, FALSE);
-    else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
-        r = MSIREG_OpenUserProductsKey(prodcode, &hkey, FALSE);
-    else
-        r = MSIREG_OpenLocalManagedProductKey(prodcode, &hkey, FALSE);
-
+    r = MSIREG_OpenProductKey(prodcode, context, &hkey, FALSE);
     RegCloseKey(hkey);
     return (r == ERROR_SUCCESS);
 }
@@ -1194,11 +1501,7 @@ static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
         'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
     };
 
-    if (context == MSIINSTALLCONTEXT_MACHINE)
-        r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
-    else
-        r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
-
+    r = MSIREG_OpenInstallProps(prodcode, context, NULL, &hkey, FALSE);
     if (r != ERROR_SUCCESS)
         return FALSE;
 
@@ -1216,22 +1519,21 @@ static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
 
 static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
                                    MSIINSTALLCONTEXT context,
-                                   LPCWSTR comp, DWORD *sz)
+                                   LPCWSTR comp, LPWSTR val, DWORD *sz)
 {
     HKEY hkey;
     LONG res;
     UINT r;
 
     if (context == MSIINSTALLCONTEXT_MACHINE)
-        r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
+        r = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
     else
-        r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
+        r = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
 
     if (r != ERROR_SUCCESS)
         return FALSE;
 
-    *sz = 0;
-    res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, sz);
+    res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, (BYTE *)val, sz);
     if (res != ERROR_SUCCESS)
         return FALSE;
 
@@ -1244,6 +1546,7 @@ UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
                                     LPCWSTR szComponent, INSTALLSTATE *pdwState)
 {
     WCHAR squished_pc[GUID_SIZE];
+    WCHAR val[MAX_PATH];
     BOOL found;
     DWORD sz;
 
@@ -1274,13 +1577,22 @@ UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
 
     *pdwState = INSTALLSTATE_UNKNOWN;
 
-    if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, &sz))
+    sz = MAX_PATH;
+    if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz))
         return ERROR_UNKNOWN_COMPONENT;
 
     if (sz == 0)
         *pdwState = INSTALLSTATE_NOTUSED;
     else
-        *pdwState = INSTALLSTATE_LOCAL;
+    {
+        if (lstrlenW(val) > 2 &&
+            val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9')
+        {
+            *pdwState = INSTALLSTATE_SOURCE;
+        }
+        else
+            *pdwState = INSTALLSTATE_LOCAL;
+    }
 
     return ERROR_SUCCESS;
 }
@@ -1303,9 +1615,9 @@ INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
 
 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
 {
+    MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
     INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
     HKEY prodkey = 0, userdata = 0;
-    BOOL user = TRUE;
     DWORD val;
     UINT r;
 
@@ -1320,30 +1632,19 @@ INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
     if (lstrlenW(szProduct) != GUID_SIZE - 1)
         return INSTALLSTATE_INVALIDARG;
 
-    r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
-    if (r != ERROR_SUCCESS)
+    if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+                              &prodkey, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                              &prodkey, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                              &prodkey, FALSE) == ERROR_SUCCESS)
     {
-        r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
-        if (r != ERROR_SUCCESS)
-        {
-            r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
-            if (r == ERROR_SUCCESS)
-               user = FALSE;
-        }
+        context = MSIINSTALLCONTEXT_MACHINE;
     }
 
-    if (user)
-    {
-        r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
-        if (r != ERROR_SUCCESS)
-            goto done;
-    }
-    else
-    {
-        r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
-        if (r != ERROR_SUCCESS)
-            goto done;
-    }
+    r = MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
+    if (r != ERROR_SUCCESS)
+        goto done;
 
     if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
         goto done;
@@ -1481,7 +1782,7 @@ LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
 {
     LPWSTR bufW;
     LANGID r;
-    DWORD len;
+    INT len;
 
     bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
     r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
@@ -1592,18 +1893,143 @@ HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
-UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
-                                    LPSTR szValue, LPDWORD pccbValue )
+/******************************************************************
+ * MsiGetProductPropertyA      [MSI.@]
+ */
+UINT WINAPI MsiGetProductPropertyA(MSIHANDLE hProduct, LPCSTR szProperty,
+                                   LPSTR szValue, LPDWORD pccbValue)
 {
-    FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    LPWSTR prop = NULL, val = NULL;
+    DWORD len;
+    UINT r;
+
+    TRACE("(%ld, %s, %p, %p)\n", hProduct, debugstr_a(szProperty),
+          szValue, pccbValue);
+
+    if (szValue && !pccbValue)
+        return ERROR_INVALID_PARAMETER;
+
+    if (szProperty) prop = strdupAtoW(szProperty);
+
+    len = 0;
+    r = MsiGetProductPropertyW(hProduct, prop, NULL, &len);
+    if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
+        goto done;
+
+    if (r == ERROR_SUCCESS)
+    {
+        if (szValue) *szValue = '\0';
+        if (pccbValue) *pccbValue = 0;
+        goto done;
+    }
+
+    val = msi_alloc(++len * sizeof(WCHAR));
+    if (!val)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    r = MsiGetProductPropertyW(hProduct, prop, val, &len);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    len = WideCharToMultiByte(CP_ACP, 0, val, -1, NULL, 0, NULL, NULL);
+
+    if (szValue)
+        WideCharToMultiByte(CP_ACP, 0, val, -1, szValue,
+                            *pccbValue, NULL, NULL);
+
+    if (pccbValue)
+    {
+        if (len > *pccbValue)
+            r = ERROR_MORE_DATA;
+
+        *pccbValue = len - 1;
+    }
+
+done:
+    msi_free(prop);
+    msi_free(val);
+
+    return r;
 }
 
-UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
-                                    LPWSTR szValue, LPDWORD pccbValue )
+/******************************************************************
+ * MsiGetProductPropertyW      [MSI.@]
+ */
+UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty,
+                                   LPWSTR szValue, LPDWORD pccbValue)
 {
-    FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    MSIPACKAGE *package;
+    MSIQUERY *view = NULL;
+    MSIRECORD *rec = NULL;
+    LPCWSTR val;
+    UINT r;
+
+    static const WCHAR query[] = {
+       'S','E','L','E','C','T',' ','*',' ','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};
+
+    TRACE("(%ld, %s, %p, %p)\n", hProduct, debugstr_w(szProperty),
+          szValue, pccbValue);
+
+    if (!szProperty)
+        return ERROR_INVALID_PARAMETER;
+
+    if (szValue && !pccbValue)
+        return ERROR_INVALID_PARAMETER;
+
+    package = msihandle2msiinfo(hProduct, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    r = MSI_OpenQuery(package->db, &view, query, szProperty);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = MSI_ViewExecute(view, 0);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = MSI_ViewFetch(view, &rec);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    val = MSI_RecordGetString(rec, 2);
+    if (!val)
+        goto done;
+
+    if (lstrlenW(val) >= *pccbValue)
+    {
+        lstrcpynW(szValue, val, *pccbValue);
+        *pccbValue = lstrlenW(val);
+        r = ERROR_MORE_DATA;
+    }
+    else
+    {
+        lstrcpyW(szValue, val);
+        *pccbValue = lstrlenW(val);
+        r = ERROR_SUCCESS;
+    }
+
+done:
+    if (view)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        if (rec) msiobj_release(&rec->hdr);
+    }
+
+    if (!rec)
+    {
+        if (szValue) *szValue = '\0';
+        if (pccbValue) *pccbValue = 0;
+        r = ERROR_SUCCESS;
+    }
+
+    return r;
 }
 
 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
@@ -1640,8 +2066,8 @@ UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
     return r;
 }
 
-static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
-                                                awstring* lpPathBuf, LPDWORD pcchBuf)
+static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
+                                         awstring* lpPathBuf, LPDWORD pcchBuf)
 {
     WCHAR squished_pc[GUID_SIZE];
     WCHAR squished_comp[GUID_SIZE];
@@ -1668,16 +2094,18 @@ static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szCom
 
     state = INSTALLSTATE_UNKNOWN;
 
-    if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
-        MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
+    if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
+        MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
     {
         path = msi_reg_get_val_str(hkey, squished_pc);
         RegCloseKey(hkey);
 
         state = INSTALLSTATE_ABSENT;
 
-        if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
-            MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
+        if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL,
+                                     &hkey, FALSE) == ERROR_SUCCESS ||
+            MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                                          NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
             msi_reg_get_val_dword(hkey, wininstaller, &version) &&
             GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
         {
@@ -1687,13 +2115,15 @@ static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szCom
     }
 
     if (state != INSTALLSTATE_LOCAL &&
-        (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
-         MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS))
+        (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                               &hkey, FALSE) == ERROR_SUCCESS ||
+         MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                               &hkey, FALSE) == ERROR_SUCCESS))
     {
         RegCloseKey(hkey);
 
-        if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
-            MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
+        if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
+            MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
         {
             msi_free(path);
             path = msi_reg_get_val_str(hkey, squished_pc);
@@ -1813,6 +2243,7 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
     INSTALLSTATE r;
     BOOL missing = FALSE;
     BOOL machine = FALSE;
+    BOOL source = FALSE;
 
     TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
 
@@ -1822,10 +2253,13 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
     if (!squash_guid( szProduct, squishProduct ))
         return INSTALLSTATE_INVALIDARG;
 
-    if (MSIREG_OpenManagedFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
-        MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
+    if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+                               &hkey, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                               &hkey, FALSE) != ERROR_SUCCESS)
     {
-        rc = MSIREG_OpenLocalClassesFeaturesKey(szProduct, &hkey, FALSE);
+        rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                                    &hkey, FALSE);
         if (rc != ERROR_SUCCESS)
             return INSTALLSTATE_UNKNOWN;
 
@@ -1844,9 +2278,13 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
         return r;
 
     if (machine)
-        rc = MSIREG_OpenLocalUserDataFeaturesKey(szProduct, &hkey, FALSE);
+        rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
+                                            MSIINSTALLCONTEXT_MACHINE,
+                                            &hkey, FALSE);
     else
-        rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE);
+        rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
+                                            MSIINSTALLCONTEXT_USERUNMANAGED,
+                                            &hkey, FALSE);
 
     if (rc != ERROR_SUCCESS)
         return INSTALLSTATE_ADVERTISED;
@@ -1873,9 +2311,9 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
         StringFromGUID2(&guid, comp, GUID_SIZE);
 
         if (machine)
-            rc = MSIREG_OpenLocalUserDataComponentKey(comp, &hkey, FALSE);
+            rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
         else
-            rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
+            rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
 
         if (rc != ERROR_SUCCESS)
         {
@@ -1886,6 +2324,12 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
         path = msi_reg_get_val_str(hkey, squishProduct);
         if (!path)
             missing = TRUE;
+        else if (lstrlenW(path) > 2 &&
+                 path[0] >= '0' && path[0] <= '9' &&
+                 path[1] >= '0' && path[1] <= '9')
+        {
+            source = TRUE;
+        }
 
         msi_free(path);
     }
@@ -1896,6 +2340,9 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
     if (missing)
         return INSTALLSTATE_ADVERTISED;
 
+    if (source)
+        return INSTALLSTATE_SOURCE;
+
     return INSTALLSTATE_LOCAL;
 }
 
@@ -2015,7 +2462,7 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
                   HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
             if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
 
-            if (lstrlenW(tmp) >= *pcchVersionBuf)
+            if (strlenW(tmp) >= *pcchVersionBuf)
                 ret = ERROR_MORE_DATA;
 
             *pcchVersionBuf = lstrlenW(tmp);
@@ -2035,7 +2482,7 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
             wsprintfW(tmp, szLangFormat, *lang);
             if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
 
-            if (lstrlenW(tmp) >= *pcchLangBuf)
+            if (strlenW(tmp) >= *pcchLangBuf)
                 ret = ERROR_MORE_DATA;
 
             *pcchLangBuf = lstrlenW(tmp);
@@ -2165,7 +2612,7 @@ INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
 /***********************************************************************
  * MSI_ProvideQualifiedComponentEx [internal]
  */
-static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
+static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
                 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
                 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
                 LPDWORD pcchPathBuf)
@@ -2290,7 +2737,7 @@ UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
 /***********************************************************************
  * MSI_GetUserInfo [internal]
  */
-static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
+static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct,
                 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
                 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
                 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
@@ -2311,15 +2758,20 @@ static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
     if (!szProduct || !squash_guid(szProduct, squished_pc))
         return USERINFOSTATE_INVALIDARG;
 
-    if (MSIREG_OpenLocalManagedProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
-        MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
-        MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
+    if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+                              &hkey, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                              &hkey, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                              &hkey, FALSE) != ERROR_SUCCESS)
     {
         return USERINFOSTATE_UNKNOWN;
     }
 
-    if (MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS &&
-        MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS)
+    if (MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                                NULL, &props, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                                NULL, &props, FALSE) != ERROR_SUCCESS)
     {
         RegCloseKey(hkey);
         return USERINFOSTATE_ABSENT;
@@ -2919,3 +3371,24 @@ UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
     *pfElevated = TRUE;
     return ERROR_SUCCESS;
 }
+
+/***********************************************************************
+ * MsiSetExternalUIRecord     [MSI.@]
+ */
+UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD puiHandler,
+                                    DWORD dwMessageFilter, LPVOID pvContext,
+                                    PINSTALLUI_HANDLER_RECORD ppuiPrevHandler)
+{
+    FIXME("%p %08x %p %p\n", puiHandler, dwMessageFilter ,pvContext,
+                             ppuiPrevHandler);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/***********************************************************************
+ * MsiInstallMissingComponentW     [MSI.@]
+ */
+UINT WINAPI MsiInstallMissingComponentW(LPCWSTR szProduct, LPCWSTR szComponent, INSTALLSTATE eInstallState)
+{
+    FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent), eInstallState);
+    return ERROR_SUCCESS;
+}
index c85f170..0a5f79e 100644 (file)
@@ -20,6 +20,7 @@
        <file>delete.c</file>
        <file>dialog.c</file>
        <file>distinct.c</file>
+       <file>drop.c</file>
        <file>events.c</file>
        <file>files.c</file>
        <file>font.c</file>
@@ -29,6 +30,7 @@
        <file>insert.c</file>
        <file>install.c</file>
        <file>join.c</file>
+       <file>media.c</file>
        <file>msi.c</file>
        <file>msi_main.c</file>
        <file>msiquery.c</file>
index b5aef60..4091184 100644 (file)
@@ -46,6 +46,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 #include "msi_Si.rc"
 #include "msi_Sv.rc"
 #include "msi_Tr.rc"
+#include "msi_Zh.rc"
 
 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 
index fd1ff55..017fdbe 100644 (file)
@@ -22,8 +22,8 @@
 26 stdcall MsiDatabaseGetPrimaryKeysW(long wstr ptr)
 27 stdcall MsiDatabaseImportA(str str long)
 28 stdcall MsiDatabaseImportW(wstr wstr long)
-29 stub MsiDatabaseMergeA
-30 stub MsiDatabaseMergeW
+29 stdcall MsiDatabaseMergeA(long long str)
+30 stdcall MsiDatabaseMergeW(long long wstr)
 31 stdcall MsiDatabaseOpenViewA(long str ptr)
 32 stdcall MsiDatabaseOpenViewW(long wstr ptr)
 33 stdcall MsiDoActionA(long str)
@@ -77,7 +77,7 @@
 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
+84 stdcall MsiInstallMissingComponentW(wstr wstr long)
 85 stub MsiInstallMissingFileA
 86 stub MsiInstallMissingFileW
 87 stdcall MsiInstallProductA(str str)
 240 stub MsiApplyMultiplePatchesW
 241 stub MsiExtractPatchXMLDataA
 242 stub MsiExtractPatchXMLDataW
-243 stub MsiGetPatchInfoExA
-244 stub MsiGetPatchInfoExW
+243 stdcall MsiGetPatchInfoExA(str str str long str ptr ptr)
+244 stdcall MsiGetPatchInfoExW(wstr wstr wstr long wstr ptr ptr)
 245 stdcall MsiEnumProductsExA(str str long long ptr ptr ptr ptr)
 246 stdcall MsiEnumProductsExW(wstr wstr long long ptr ptr ptr ptr)
 247 stdcall MsiGetProductInfoExA(str str long str ptr ptr)
 266 stdcall MsiSourceListGetInfoW(wstr wstr long long wstr ptr ptr)
 267 stdcall MsiSourceListSetInfoA(str str long long str str)
 268 stdcall MsiSourceListSetInfoW(wstr wstr long long wstr wstr)
-269 stub MsiEnumPatchesExA
-270 stub MsiEnumPatchesExW
+269 stdcall MsiEnumPatchesExA(str str long long long ptr ptr ptr ptr ptr)
+270 stdcall MsiEnumPatchesExW(wstr wstr long long long ptr ptr ptr ptr ptr)
 271 stdcall MsiSourceListEnumMediaDisksA(str str long long long ptr ptr ptr ptr ptr)
 272 stdcall MsiSourceListEnumMediaDisksW(wstr wstr long long long ptr ptr ptr ptr ptr)
 273 stdcall MsiSourceListAddMediaDiskA(str str long long long str str)
 274 stdcall MsiSourceListAddMediaDiskW(wstr wstr long long long wstr wstr)
 275 stub MsiSourceListClearMediaDiskA
 276 stub MsiSourceListClearMediaDiskW
-277 stub MsiDetermineApplicablePatchesA
-278 stub MsiDetermineApplicablePatchesW
+277 stdcall MsiDetermineApplicablePatchesA(str long ptr)
+278 stdcall MsiDetermineApplicablePatchesW(wstr long ptr)
 279 stub MsiMessageBoxExA
 280 stub MsiMessageBoxExW
-281 stub MsiSetExternalUIRecord
+281 stdcall MsiSetExternalUIRecord(ptr long ptr ptr)
 
 @ stdcall -private DllCanUnloadNow()
 @ stdcall -private DllGetClassObject(ptr ptr ptr)
index e8f2eec..2bca718 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
+LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
 {
diff --git a/reactos/dll/win32/msi/msi_Zh.rc b/reactos/dll/win32/msi/msi_Zh.rc
new file mode 100644 (file)
index 0000000..86620db
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * MSI (Simplified and Traditional Chinese Resources)
+ *
+ * Copyright 2008 Hongbo Ni <hongbo.at.njstar.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Chinese text is encoded in UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+
+STRINGTABLE DISCARDABLE
+{
+       4 "不能打开所指定的安装软件包. 请检查文件路径后再试."
+       5 "路径 %s 没找到"
+       9 "插入软盘 %s"
+       10 "错误参数"
+       11 "输入包含 %s 的文件夹"
+       12 "本功能的安装源不存在"
+       13 "本功能的网络驱动器不存在"
+       14 "功能来自:"
+       15 "选择包含 %s 的文件夹"
+}
+
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
+
+STRINGTABLE DISCARDABLE
+{
+       4 "不能開啟所指定的安裝軟件包. 請檢查檔案路徑後再試."
+       5 "路徑 %s 沒找到"
+       9 "插入軟碟 %s"
+       10 "錯誤參數"
+       11 "輸入包含 %s 的檔案夾"
+       12 "本功能的安裝源不存在"
+       13 "本功能的網路儲存槽不存在"
+       14 "功能來自:"
+       15 "選擇包含 %s 的檔案夾"
+}
+
+#pragma code_page(default)
index 19abc3f..7c788d4 100644 (file)
@@ -33,6 +33,7 @@
 #include "objidl.h"
 #include "winnls.h"
 #include "wine/list.h"
+#include "wine/debug.h"
 
 #define MSI_DATASIZEMASK 0x00ff
 #define MSITYPE_VALID    0x0100
@@ -143,6 +144,12 @@ typedef struct tagMSIMEDIAINFO
     WCHAR source[MAX_PATH];
 } MSIMEDIAINFO;
 
+typedef struct tagMSIPATCHINFO
+{
+    LPWSTR patchcode;
+    LPWSTR transforms;
+} MSIPATCHINFO;
+
 typedef struct _column_info
 {
     LPCWSTR table;
@@ -273,6 +280,11 @@ typedef struct tagMSIVIEWOPS
      * sort - orders the table by columns
      */
     UINT (*sort)( struct tagMSIVIEW *view, column_info *columns );
+
+    /*
+     * drop - drops the table from the database
+     */
+    UINT (*drop)( struct tagMSIVIEW *view );
 } MSIVIEWOPS;
 
 struct tagMSIVIEW
@@ -288,6 +300,7 @@ typedef struct tagMSIPACKAGE
 {
     MSIOBJECTHDR hdr;
     MSIDATABASE *db;
+    MSIPATCHINFO *patch;
     struct list components;
     struct list features;
     struct list files;
@@ -447,7 +460,6 @@ typedef struct tagMSIFILE
     INT Attributes;
     INT Sequence;
     msi_file_state state;
-    LPWSTR  SourcePath;
     LPWSTR  TargetPath;
     BOOL IsCompressed;
     MSIFILEHASHINFO hash;
@@ -655,8 +667,6 @@ extern HRESULT msi_init_string_table( IStorage *stg );
 extern string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref );
 extern UINT msi_save_string_table( const string_table *st, IStorage *storage );
 
-
-extern void msi_table_set_strref(UINT bytes_per_strref);
 extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name );
 extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table );
 
@@ -680,7 +690,8 @@ extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR);
 extern UINT ACTION_ForceReboot(MSIPACKAGE *package);
 extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable, INT iSequenceMode );
 extern UINT MSI_SetFeatureStates( MSIPACKAGE *package );
-extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine );
+extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine,
+                                    BOOL preserve_case );
 
 /* record internals */
 extern UINT MSI_RecordSetIStream( MSIRECORD *, UINT, IStream *);
@@ -700,6 +711,8 @@ extern UINT MSI_RecordSetStream( MSIRECORD *, UINT, IStream * );
 extern UINT MSI_RecordDataSize( MSIRECORD *, UINT );
 extern UINT MSI_RecordStreamToFile( MSIRECORD *, UINT, LPCWSTR );
 extern UINT MSI_RecordCopyField( MSIRECORD *, UINT, MSIRECORD *, UINT );
+extern MSIRECORD *MSI_CloneRecord( MSIRECORD * );
+extern BOOL MSI_RecordsAreEqual( MSIRECORD *, MSIRECORD * );
 
 /* stream internals */
 extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
@@ -758,38 +771,35 @@ extern BOOL encode_base85_guid(GUID *,LPWSTR);
 extern BOOL decode_base85_guid(LPCWSTR,GUID*);
 extern UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create);
 extern UINT MSIREG_DeleteUninstallKey(LPCWSTR szProduct);
-extern UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+extern UINT MSIREG_OpenProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
+                                  HKEY* key, BOOL create);
+extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
+                                   HKEY *key, BOOL create);
 extern UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create);
+extern UINT MSIREG_OpenInstallerFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
+                                    HKEY *key, BOOL create);
 extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenLocalUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid,
+                                            HKEY *key, BOOL create);
 extern UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenLocalUserDataProductKey(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenLocalSystemInstallProps(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
+extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext,
+                                          LPCWSTR szUserSid, HKEY *key, BOOL create);
+extern UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext,
+                                        HKEY *key, BOOL create);
+extern UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext,
+                                    LPCWSTR szUserSid, HKEY *key, BOOL create);
 extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
 extern UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
 extern UINT MSIREG_DeleteProductKey(LPCWSTR szProduct);
 extern UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct);
 extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct);
-extern UINT MSIREG_OpenLocalSystemProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenLocalClassesFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenManagedFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
-extern UINT MSIREG_OpenLocalUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create);
 extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct);
-extern UINT MSIREG_DeleteLocalUserDataComponentKey(LPCWSTR szComponent);
-extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent);
+extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid);
 extern UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode);
 extern UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create);
+extern UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode);
+extern UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode);
 
 extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name );
 extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val);
@@ -851,16 +861,96 @@ extern UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UIN
 extern void ACTION_FinishCustomActions( const MSIPACKAGE* package);
 extern UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action, UINT script, BOOL execute);
 
-static inline void msi_feature_set_state( MSIFEATURE *feature, INSTALLSTATE state )
+static inline void msi_feature_set_state(MSIPACKAGE *package,
+                                         MSIFEATURE *feature,
+                                         INSTALLSTATE state)
 {
-    feature->ActionRequest = state;
-    feature->Action = state;
+    if (!package->ProductCode)
+    {
+        feature->ActionRequest = state;
+        feature->Action = state;
+    }
+    else if (state == INSTALLSTATE_ABSENT)
+    {
+        switch (feature->Installed)
+        {
+            case INSTALLSTATE_ABSENT:
+                feature->ActionRequest = INSTALLSTATE_UNKNOWN;
+                feature->Action = INSTALLSTATE_UNKNOWN;
+                break;
+            default:
+                feature->ActionRequest = state;
+                feature->Action = state;
+        }
+    }
+    else if (state == INSTALLSTATE_SOURCE)
+    {
+        switch (feature->Installed)
+        {
+            case INSTALLSTATE_ABSENT:
+            case INSTALLSTATE_SOURCE:
+                feature->ActionRequest = state;
+                feature->Action = state;
+                break;
+            case INSTALLSTATE_LOCAL:
+                feature->ActionRequest = INSTALLSTATE_LOCAL;
+                feature->Action = INSTALLSTATE_LOCAL;
+                break;
+            default:
+                feature->ActionRequest = INSTALLSTATE_UNKNOWN;
+                feature->Action = INSTALLSTATE_UNKNOWN;
+        }
+    }
+    else
+    {
+        feature->ActionRequest = state;
+        feature->Action = state;
+    }
 }
 
-static inline void msi_component_set_state( MSICOMPONENT *comp, INSTALLSTATE state )
+static inline void msi_component_set_state(MSIPACKAGE *package,
+                                           MSICOMPONENT *comp,
+                                           INSTALLSTATE state)
 {
-    comp->ActionRequest = state;
-    comp->Action = state;
+    if (!package->ProductCode)
+    {
+        comp->ActionRequest = state;
+        comp->Action = state;
+    }
+    else if (state == INSTALLSTATE_ABSENT)
+    {
+        switch (comp->Installed)
+        {
+            case INSTALLSTATE_LOCAL:
+            case INSTALLSTATE_SOURCE:
+            case INSTALLSTATE_DEFAULT:
+                comp->ActionRequest = state;
+                comp->Action = state;
+                break;
+            default:
+                comp->ActionRequest = INSTALLSTATE_UNKNOWN;
+                comp->Action = INSTALLSTATE_UNKNOWN;
+        }
+    }
+    else if (state == INSTALLSTATE_SOURCE)
+    {
+        if (comp->Installed == INSTALLSTATE_ABSENT ||
+            (comp->Installed == INSTALLSTATE_SOURCE && comp->hasLocalFeature))
+        {
+            comp->ActionRequest = state;
+            comp->Action = state;
+        }
+        else
+        {
+            comp->ActionRequest = INSTALLSTATE_UNKNOWN;
+            comp->Action = INSTALLSTATE_UNKNOWN;
+        }
+    }
+    else
+    {
+        comp->ActionRequest = state;
+        comp->Action = state;
+    }
 }
 
 /* actions in other modules */
@@ -883,10 +973,12 @@ extern LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop);
 extern int msi_get_property_int( MSIPACKAGE *package, LPCWSTR prop, int def );
 extern LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
                       BOOL set_prop, BOOL load_prop, MSIFOLDER **folder);
+extern LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file);
 extern MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component );
 extern MSIFEATURE *get_loaded_feature( MSIPACKAGE* package, LPCWSTR Feature );
 extern MSIFILE *get_loaded_file( MSIPACKAGE* package, LPCWSTR file );
 extern MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir );
+extern void msi_reset_folders( MSIPACKAGE *package, BOOL source );
 extern int track_tempfile(MSIPACKAGE *package, LPCWSTR path);
 extern UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action);
 extern void msi_free_action_script(MSIPACKAGE *package, UINT script);
@@ -906,10 +998,27 @@ extern UINT msi_create_component_directories( MSIPACKAGE *package );
 extern void msi_ui_error( DWORD msg_id, DWORD type );
 extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
                         MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value);
+
+/* media */
+
+typedef BOOL (*PMSICABEXTRACTCB)(MSIPACKAGE *, LPCWSTR, DWORD, LPWSTR *, DWORD *, PVOID);
+
+#define MSICABEXTRACT_BEGINEXTRACT  0x01
+#define MSICABEXTRACT_FILEEXTRACTED 0x02
+
+typedef struct
+{
+    MSIPACKAGE* package;
+    MSIMEDIAINFO *mi;
+    PMSICABEXTRACTCB cb;
+    LPWSTR curfile;
+    PVOID user;
+} MSICABDATA;
+
+extern UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi);
 extern UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi);
 extern void msi_free_media_info(MSIMEDIAINFO *mi);
-extern BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, PFNFDINOTIFY notify, LPVOID data);
-extern UINT msi_extract_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR destdir);
+extern BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data);
 extern UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi);
 
 /* control event stuff */
@@ -937,26 +1046,30 @@ extern void ui_actiondata(MSIPACKAGE *, LPCWSTR, MSIRECORD *);
 /* string consts use a number of places  and defined in helpers.c*/
 extern const WCHAR cszSourceDir[];
 extern const WCHAR cszSOURCEDIR[];
-extern const WCHAR szProductCode[];
 extern const WCHAR cszRootDrive[];
 extern const WCHAR cszbs[];
+extern const WCHAR szLocalSid[];
 
 /* memory allocation macro functions */
+static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
 static inline void *msi_alloc( size_t len )
 {
     return HeapAlloc( GetProcessHeap(), 0, len );
 }
 
+static void *msi_alloc_zero( size_t len ) __WINE_ALLOC_SIZE(1);
 static inline void *msi_alloc_zero( size_t len )
 {
     return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
 }
 
+static void *msi_realloc( void *mem, size_t len ) __WINE_ALLOC_SIZE(2);
 static inline void *msi_realloc( void *mem, size_t len )
 {
     return HeapReAlloc( GetProcessHeap(), 0, mem, len );
 }
 
+static void *msi_realloc_zero( void *mem, size_t len ) __WINE_ALLOC_SIZE(2);
 static inline void *msi_realloc_zero( void *mem, size_t len )
 {
     return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len );
index 4435cd9..3e7a877 100644 (file)
@@ -633,7 +633,7 @@ MSIDBERROR WINAPI MsiViewGetErrorW( MSIHANDLE handle, LPWSTR szColumnNameBuffer,
     MSIQUERY *query = NULL;
     static const WCHAR szError[] = { 0 };
     MSIDBERROR r = MSIDBERROR_NOERROR;
-    int len;
+    DWORD len;
 
     FIXME("%ld %p %p - returns empty error string\n",
           handle, szColumnNameBuffer, pcchBuf );
@@ -645,7 +645,7 @@ MSIDBERROR WINAPI MsiViewGetErrorW( MSIHANDLE handle, LPWSTR szColumnNameBuffer,
     if( !query )
         return MSIDBERROR_INVALIDARG;
 
-    len = lstrlenW( szError );
+    len = strlenW( szError );
     if( szColumnNameBuffer )
     {
         if( *pcchBuf > len )
@@ -665,7 +665,7 @@ MSIDBERROR WINAPI MsiViewGetErrorA( MSIHANDLE handle, LPSTR szColumnNameBuffer,
     static const CHAR szError[] = { 0 };
     MSIQUERY *query = NULL;
     MSIDBERROR r = MSIDBERROR_NOERROR;
-    int len;
+    DWORD len;
 
     FIXME("%ld %p %p - returns empty error string\n",
           handle, szColumnNameBuffer, pcchBuf );
@@ -677,7 +677,7 @@ MSIDBERROR WINAPI MsiViewGetErrorA( MSIHANDLE handle, LPSTR szColumnNameBuffer,
     if( !query )
         return MSIDBERROR_INVALIDARG;
 
-    len = lstrlenA( szError );
+    len = strlen( szError );
     if( szColumnNameBuffer )
     {
         if( *pcchBuf > len )
index 1b5f2d1..018389a 100644 (file)
@@ -731,6 +731,7 @@ static MSIPACKAGE *msi_alloc_package( void )
         list_init( &package->sourcelist_info );
         list_init( &package->sourcelist_media );
 
+        package->patch = NULL;
         package->ActionFormat = NULL;
         package->LastAction = NULL;
         package->dialog = NULL;
@@ -754,7 +755,7 @@ static UINT msi_load_admin_properties(MSIPACKAGE *package)
     if (r != ERROR_SUCCESS)
         return r;
 
-    r = msi_parse_command_line(package, (WCHAR *)data);
+    r = msi_parse_command_line(package, (WCHAR *)data, TRUE);
 
     msi_free(data);
     return r;
@@ -1345,6 +1346,9 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
 
     msiobj_release(&row->hdr);
 
+    if (rc == ERROR_SUCCESS && (!lstrcmpW(szName, cszSourceDir)))
+        msi_reset_folders(package, TRUE);
+
     return rc;
 }
 
index 53dcf63..25bb500 100644 (file)
@@ -117,6 +117,8 @@ UINT STREAMS_CreateView( MSIDATABASE *db, MSIVIEW **view );
 
 UINT STORAGES_CreateView( MSIDATABASE *db, MSIVIEW **view );
 
+UINT DROP_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name );
+
 int sqliteGetToken(const WCHAR *z, int *tokenType);
 
 MSIRECORD *msi_query_merge_record( UINT fields, const column_info *vl, MSIRECORD *rec );
index 9a8abc0..b02fcd1 100644 (file)
@@ -358,15 +358,16 @@ UINT MSI_RecordGetStringA(MSIRECORD *rec, UINT iField,
     case MSIFIELD_WSTR:
         len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
                              NULL, 0 , NULL, NULL);
-        WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
-                             szValue, *pcchValue, NULL, NULL);
+        if (szValue)
+            WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
+                                 szValue, *pcchValue, NULL, NULL);
         if( szValue && *pcchValue && len>*pcchValue )
             szValue[*pcchValue-1] = 0;
         if( len )
             len--;
         break;
     case MSIFIELD_NULL:
-        if( *pcchValue > 0 )
+        if( szValue && *pcchValue > 0 )
             szValue[0] = 0;
         break;
     default:
@@ -903,3 +904,74 @@ UINT MSI_RecordStreamToFile( MSIRECORD *rec, UINT iField, LPCWSTR name )
 
     return r;
 }
+
+MSIRECORD *MSI_CloneRecord(MSIRECORD *rec)
+{
+    MSIRECORD *clone;
+    UINT r, i, count;
+
+    count = MSI_RecordGetFieldCount(rec);
+    clone = MSI_CreateRecord(count);
+    if (!clone)
+        return NULL;
+
+    for (i = 0; i <= count; i++)
+    {
+        if (rec->fields[i].type == MSIFIELD_STREAM)
+        {
+            if (FAILED(IStream_Clone(rec->fields[i].u.stream,
+                                     &clone->fields[i].u.stream)))
+            {
+                msiobj_release(&clone->hdr);
+                return NULL;
+            }
+        }
+        else
+        {
+            r = MSI_RecordCopyField(rec, i, clone, i);
+            if (r != ERROR_SUCCESS)
+            {
+                msiobj_release(&clone->hdr);
+                return NULL;
+            }
+        }
+    }
+
+    return clone;
+}
+
+BOOL MSI_RecordsAreEqual(MSIRECORD *a, MSIRECORD *b)
+{
+    UINT i;
+
+    if (a->count != b->count)
+        return FALSE;
+
+    for (i = 0; i <= a->count; i++)
+    {
+        if (a->fields[i].type != b->fields[i].type)
+            return FALSE;
+
+        switch (a->fields[i].type)
+        {
+            case MSIFIELD_NULL:
+                break;
+
+            case MSIFIELD_INT:
+                if (a->fields[i].u.iVal != b->fields[i].u.iVal)
+                    return FALSE;
+                break;
+
+            case MSIFIELD_WSTR:
+                if (lstrcmpW(a->fields[i].u.szwVal, b->fields[i].u.szwVal))
+                    return FALSE;
+                break;
+
+            case MSIFIELD_STREAM:
+            default:
+                return FALSE;
+        }
+    }
+
+    return TRUE;
+}
index a12a825..9c6f7ff 100644 (file)
@@ -168,35 +168,24 @@ static const WCHAR szUserDataProd_fmt[] = {
 'U','s','e','r','D','a','t','a','\\',
 '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s',0};
 
-static const WCHAR szInstallProperties_fmt[] = {
-'S','o','f','t','w','a','r','e','\\',
-'M','i','c','r','o','s','o','f','t','\\',
-'W','i','n','d','o','w','s','\\',
-'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
-'I','n','s','t','a','l','l','e','r','\\',
-'U','s','e','r','D','a','t','a','\\',
-'%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\',
-'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
-
-static const WCHAR szInstaller_LocalSystemProductCodes_fmt[] = {
+static const WCHAR szUserDataPatch_fmt[] = {
 'S','o','f','t','w','a','r','e','\\',
 'M','i','c','r','o','s','o','f','t','\\',
 'W','i','n','d','o','w','s','\\',
 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
 'I','n','s','t','a','l','l','e','r','\\',
 'U','s','e','r','D','a','t','a','\\',
-'S','-','1','-','5','-','1','8','\\','P','r','o','d','u','c','t','s','\\',
-'%','s','\\','I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
+'%','s','\\','P','a','t','c','h','e','s','\\','%','s',0};
 
-static const WCHAR szInstaller_LocalSystemComponent_fmt[] = {
+static const WCHAR szInstallProperties_fmt[] = {
 'S','o','f','t','w','a','r','e','\\',
 'M','i','c','r','o','s','o','f','t','\\',
 'W','i','n','d','o','w','s','\\',
 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
 'I','n','s','t','a','l','l','e','r','\\',
 'U','s','e','r','D','a','t','a','\\',
-'S','-','1','-','5','-','1','8','\\',
-'C','o','m','p','o','n','e','n','t','s','\\','%','s',0};
+'%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\',
+'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
 
 static const WCHAR szInstaller_LocalClassesProd_fmt[] = {
 'S','o','f','t','w','a','r','e','\\',
@@ -235,12 +224,13 @@ static const WCHAR szInstaller_ClassesUpgrade_fmt[] = {
 'U','p','g','r','a','d','e','C','o','d','e','s','\\',
 '%','s',0};
 
-static const WCHAR localsid[] = {'S','-','1','-','5','-','1','8',0};
-
 BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
 {
     DWORD i,n=0;
 
+    if (lstrlenW(in) != 32)
+        return FALSE;
+
     out[n++]='{';
     for(i=0; i<8; i++)
         out[n++] = in[7-i];
@@ -525,25 +515,48 @@ UINT MSIREG_DeleteUninstallKey(LPCWSTR szProduct)
     return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
 }
 
-UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+UINT MSIREG_OpenProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
+                           HKEY *key, BOOL create)
 {
-    UINT rc;
+    UINT r;
+    LPWSTR usersid;
+    HKEY root = HKEY_LOCAL_MACHINE;
     WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
+    WCHAR keypath[MAX_PATH];
 
-    TRACE("%s\n",debugstr_w(szProduct));
-    if (!squash_guid(szProduct,squished_pc))
+    TRACE("(%s, %d, %d)\n", debugstr_w(szProduct), context, create);
+
+    if (!squash_guid(szProduct, squished_pc))
         return ERROR_FUNCTION_FAILED;
+
     TRACE("squished (%s)\n", debugstr_w(squished_pc));
 
-    sprintfW(keypath,szUserProduct_fmt,squished_pc);
+    if (context == MSIINSTALLCONTEXT_MACHINE)
+    {
+        sprintfW(keypath, szInstaller_LocalClassesProd_fmt, squished_pc);
+    }
+    else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
+    {
+        root = HKEY_CURRENT_USER;
+        sprintfW(keypath, szUserProduct_fmt, squished_pc);
+    }
+    else
+    {
+        r = get_user_sid(&usersid);
+        if (r != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", r);
+            return r;
+        }
+
+        sprintfW(keypath, szInstaller_LocalManagedProd_fmt, usersid, squished_pc);
+        LocalFree(usersid);
+    }
 
     if (create)
-        rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key);
-    else
-        rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key);
+        return RegCreateKeyW(root, keypath, key);
 
-    return rc;
+    return RegOpenKeyW(root, keypath, key);
 }
 
 UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct)
@@ -582,25 +595,48 @@ UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create)
     return rc;
 }
 
-UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
+                            HKEY *key, BOOL create)
 {
-    UINT rc;
+    UINT r;
+    LPWSTR usersid;
+    HKEY root = HKEY_LOCAL_MACHINE;
     WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
+    WCHAR keypath[MAX_PATH];
 
-    TRACE("%s\n",debugstr_w(szProduct));
-    if (!squash_guid(szProduct,squished_pc))
+    TRACE("(%s, %d, %d)\n", debugstr_w(szProduct), context, create);
+
+    if (!squash_guid(szProduct, squished_pc))
         return ERROR_FUNCTION_FAILED;
+
     TRACE("squished (%s)\n", debugstr_w(squished_pc));
 
-    sprintfW(keypath,szUserFeatures_fmt,squished_pc);
+    if (context == MSIINSTALLCONTEXT_MACHINE)
+    {
+        sprintfW(keypath, szInstaller_LocalClassesFeat_fmt, squished_pc);
+    }
+    else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
+    {
+        root = HKEY_CURRENT_USER;
+        sprintfW(keypath, szUserFeatures_fmt, squished_pc);
+    }
+    else
+    {
+        r = get_user_sid(&usersid);
+        if (r != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", r);
+            return r;
+        }
+
+        sprintfW(keypath, szInstaller_LocalManagedFeat_fmt, usersid, squished_pc);
+        LocalFree(usersid);
+    }
 
     if (create)
-        rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key);
-    else
-        rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key);
+        return RegCreateKeyW(root, keypath, key);
 
-    return rc;
+    return RegOpenKeyW(root, keypath, key);
 }
 
 UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct)
@@ -617,7 +653,7 @@ UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct)
     return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
 }
 
-UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+UINT MSIREG_OpenInstallerFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
 {
     UINT rc;
     WCHAR squished_pc[GUID_SIZE];
@@ -638,47 +674,37 @@ UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
     return rc;
 }
 
-UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
+UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
+                                    HKEY *key, BOOL create)
 {
-    UINT rc;
+    UINT r;
+    LPWSTR usersid;
     WCHAR squished_pc[GUID_SIZE];
     WCHAR keypath[0x200];
-    LPWSTR usersid;
 
-    TRACE("%s\n", debugstr_w(szProduct));
+    TRACE("(%s, %d, %d)\n", debugstr_w(szProduct), context, create);
+
     if (!squash_guid(szProduct, squished_pc))
         return ERROR_FUNCTION_FAILED;
+
     TRACE("squished (%s)\n", debugstr_w(squished_pc));
 
-    rc = get_user_sid(&usersid);
-    if (rc != ERROR_SUCCESS || !usersid)
+    if (context == MSIINSTALLCONTEXT_MACHINE)
     {
-        ERR("Failed to retrieve user SID: %d\n", rc);
-        return rc;
+        sprintfW(keypath, szUserDataFeatures_fmt, szLocalSid, squished_pc);
     }
-
-    sprintfW(keypath, szUserDataFeatures_fmt, usersid, squished_pc);
-
-    if (create)
-        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
     else
-        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    LocalFree(usersid);
-    return rc;
-}
-
-UINT MSIREG_OpenLocalUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
-{
-    WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
-
-    TRACE("%s\n", debugstr_w(szProduct));
-    if (!squash_guid(szProduct, squished_pc))
-        return ERROR_FUNCTION_FAILED;
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+    {
+        r = get_user_sid(&usersid);
+        if (r != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", r);
+            return r;
+        }
 
-    sprintfW(keypath, szUserDataFeatures_fmt, localsid, squished_pc);
+        sprintfW(keypath, szUserDataFeatures_fmt, usersid, squished_pc);
+        LocalFree(usersid);
+    }
 
     if (create)
         return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
@@ -707,39 +733,8 @@ UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create)
     return rc;
 }
 
-UINT MSIREG_OpenLocalUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create)
-{
-    WCHAR comp[GUID_SIZE];
-    WCHAR keypath[0x200];
-
-    TRACE("%s\n", debugstr_w(szComponent));
-    if (!squash_guid(szComponent, comp))
-        return ERROR_FUNCTION_FAILED;
-    TRACE("squished (%s)\n", debugstr_w(comp));
-
-    sprintfW(keypath, szUserDataComp_fmt, localsid, comp);
-
-    if (create)
-        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-}
-
-UINT MSIREG_DeleteLocalUserDataComponentKey(LPCWSTR szComponent)
-{
-    WCHAR comp[GUID_SIZE];
-    WCHAR keypath[0x200];
-
-    TRACE("%s\n", debugstr_w(szComponent));
-    if (!squash_guid(szComponent, comp))
-        return ERROR_FUNCTION_FAILED;
-    TRACE("squished (%s)\n", debugstr_w(comp));
-
-    sprintfW(keypath, szUserDataComp_fmt, localsid, comp);
-    return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
-}
-
-UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create)
+UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid,
+                                     HKEY *key, BOOL create)
 {
     UINT rc;
     WCHAR comp[GUID_SIZE];
@@ -751,25 +746,30 @@ UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create
         return ERROR_FUNCTION_FAILED;
     TRACE("squished (%s)\n", debugstr_w(comp));
 
-    rc = get_user_sid(&usersid);
-    if (rc != ERROR_SUCCESS || !usersid)
+    if (!szUserSid)
     {
-        ERR("Failed to retrieve user SID: %d\n", rc);
-        return rc;
-    }
+        rc = get_user_sid(&usersid);
+        if (rc != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", rc);
+            return rc;
+        }
 
-    sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
+        sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
+        LocalFree(usersid);
+    }
+    else
+        sprintfW(keypath, szUserDataComp_fmt, szUserSid, comp);
 
     if (create)
         rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
     else
         rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
 
-    LocalFree(usersid);
     return rc;
 }
 
-UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent)
+UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid)
 {
     UINT rc;
     WCHAR comp[GUID_SIZE];
@@ -781,20 +781,26 @@ UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent)
         return ERROR_FUNCTION_FAILED;
     TRACE("squished (%s)\n", debugstr_w(comp));
 
-    rc = get_user_sid(&usersid);
-    if (rc != ERROR_SUCCESS || !usersid)
+    if (!szUserSid)
     {
-        ERR("Failed to retrieve user SID: %d\n", rc);
-        return rc;
-    }
+        rc = get_user_sid(&usersid);
+        if (rc != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", rc);
+            return rc;
+        }
 
-    sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
+        sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
+        LocalFree(usersid);
+    }
+    else
+        sprintfW(keypath, szUserDataComp_fmt, szUserSid, comp);
 
-    LocalFree(usersid);
     return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
 }
 
-UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
+UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext,
+                                   LPCWSTR szUserSid, HKEY *key, BOOL create)
 {
     UINT rc;
     WCHAR squished_pc[GUID_SIZE];
@@ -806,35 +812,58 @@ UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
         return ERROR_FUNCTION_FAILED;
     TRACE("squished (%s)\n", debugstr_w(squished_pc));
 
-    rc = get_user_sid(&usersid);
-    if (rc != ERROR_SUCCESS || !usersid)
+    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+        sprintfW(keypath, szUserDataProd_fmt, szLocalSid, squished_pc);
+    else if (szUserSid)
+        sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
+    else
     {
-        ERR("Failed to retrieve user SID: %d\n", rc);
-        return rc;
-    }
+        rc = get_user_sid(&usersid);
+        if (rc != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", rc);
+            return rc;
+        }
 
-    sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
+        sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
+        LocalFree(usersid);
+    }
 
     if (create)
         rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
     else
         rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
 
-    LocalFree(usersid);
     return rc;
 }
 
-UINT MSIREG_OpenLocalUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
+UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext,
+                                 HKEY *key, BOOL create)
 {
-    WCHAR squished_pc[GUID_SIZE];
+    UINT rc;
+    WCHAR squished_patch[GUID_SIZE];
     WCHAR keypath[0x200];
+    LPWSTR usersid;
 
-    TRACE("%s\n", debugstr_w(szProduct));
-    if (!squash_guid(szProduct, squished_pc))
+    TRACE("%s\n", debugstr_w(szPatch));
+    if (!squash_guid(szPatch, squished_patch))
         return ERROR_FUNCTION_FAILED;
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+    TRACE("squished (%s)\n", debugstr_w(squished_patch));
 
-    sprintfW(keypath, szUserDataProd_fmt, localsid, squished_pc);
+    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+        sprintfW(keypath, szUserDataPatch_fmt, szLocalSid, squished_patch);
+    else
+    {
+        rc = get_user_sid(&usersid);
+        if (rc != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", rc);
+            return rc;
+        }
+
+        sprintfW(keypath, szUserDataPatch_fmt, usersid, squished_patch);
+        LocalFree(usersid);
+    }
 
     if (create)
         return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
@@ -842,10 +871,11 @@ UINT MSIREG_OpenLocalUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL creat
     return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
 }
 
-static UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, LPCWSTR szUserSID,
-                                    HKEY *key, BOOL create)
+UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext,
+                             LPCWSTR szUserSid, HKEY *key, BOOL create)
 {
     UINT rc;
+    LPWSTR usersid;
     WCHAR squished_pc[GUID_SIZE];
     WCHAR keypath[0x200];
 
@@ -854,39 +884,27 @@ static UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, LPCWSTR szUserSID,
         return ERROR_FUNCTION_FAILED;
     TRACE("squished (%s)\n", debugstr_w(squished_pc));
 
-    sprintfW(keypath, szInstallProperties_fmt, szUserSID, squished_pc);
-
-    if (create)
-        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+        sprintfW(keypath, szInstallProperties_fmt, szLocalSid, squished_pc);
+    else if (szUserSid)
+        sprintfW(keypath, szInstallProperties_fmt, szUserSid, squished_pc);
     else
-        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return rc;
-}
-
-UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY *key,
-                                               BOOL create)
-{
-    UINT rc;
-    LPWSTR usersid;
-
-    rc = get_user_sid(&usersid);
-    if (rc != ERROR_SUCCESS || !usersid)
     {
-        ERR("Failed to retrieve user SID: %d\n", rc);
-        return rc;
-    }
+        rc = get_user_sid(&usersid);
+        if (rc != ERROR_SUCCESS || !usersid)
+        {
+            ERR("Failed to retrieve user SID: %d\n", rc);
+            return rc;
+        }
 
-    rc = MSIREG_OpenInstallProps(szProduct, usersid, key, create);
+        sprintfW(keypath, szInstallProperties_fmt, usersid, squished_pc);
+        LocalFree(usersid);
+    }
 
-    LocalFree(usersid);
-    return rc;
-}
+    if (create)
+        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
 
-UINT MSIREG_OpenLocalSystemInstallProps(LPCWSTR szProduct, HKEY *key,
-                                        BOOL create)
-{
-    return MSIREG_OpenInstallProps(szProduct, localsid, key, create);
+    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
 }
 
 UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct)
@@ -914,27 +932,6 @@ UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct)
     return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
 }
 
-UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
-{
-    UINT rc;
-    WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
-
-    TRACE("%s\n",debugstr_w(szProduct));
-    if (!squash_guid(szProduct,squished_pc))
-        return ERROR_FUNCTION_FAILED;
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
-
-    sprintfW(keypath,szInstaller_Products_fmt,squished_pc);
-
-    if (create)
-        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
-    else
-        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
-
-    return rc;
-}
-
 UINT MSIREG_DeleteProductKey(LPCWSTR szProduct)
 {
     WCHAR squished_pc[GUID_SIZE];
@@ -1028,47 +1025,7 @@ UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode)
     return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
 }
 
-UINT MSIREG_OpenLocalSystemProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
-{
-    WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
-
-    TRACE("%s\n", debugstr_w(szProductCode));
-
-    if (!squash_guid(szProductCode, squished_pc))
-        return ERROR_FUNCTION_FAILED;
-
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
-
-    sprintfW(keypath, szInstaller_LocalSystemProductCodes_fmt, squished_pc);
-
-    if (create)
-        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-}
-
-UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create)
-{
-    WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
-
-    TRACE("%s\n", debugstr_w(szComponent));
-
-    if (!squash_guid(szComponent, squished_pc))
-        return ERROR_FUNCTION_FAILED;
-
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
-
-    sprintfW(keypath, szInstaller_LocalSystemComponent_fmt, squished_pc);
-
-    if (create)
-        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-}
-
-UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
+UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode)
 {
     WCHAR squished_pc[GUID_SIZE];
     WCHAR keypath[0x200];
@@ -1082,13 +1039,10 @@ UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL cr
 
     sprintfW(keypath, szInstaller_LocalClassesProd_fmt, squished_pc);
 
-    if (create)
-        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+    return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
 }
 
-UINT MSIREG_OpenLocalClassesFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
+UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode)
 {
     WCHAR squished_pc[GUID_SIZE];
     WCHAR keypath[0x200];
@@ -1102,70 +1056,7 @@ UINT MSIREG_OpenLocalClassesFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL c
 
     sprintfW(keypath, szInstaller_LocalClassesFeat_fmt, squished_pc);
 
-    if (create)
-        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-}
-
-UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
-{
-    WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
-    LPWSTR usersid;
-    UINT r;
-
-    TRACE("%s\n", debugstr_w(szProductCode));
-
-    if (!squash_guid(szProductCode, squished_pc))
-        return ERROR_FUNCTION_FAILED;
-
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
-
-    r = get_user_sid(&usersid);
-    if (r != ERROR_SUCCESS || !usersid)
-    {
-        ERR("Failed to retrieve user SID: %d\n", r);
-        return r;
-    }
-
-    sprintfW(keypath, szInstaller_LocalManagedProd_fmt, usersid, squished_pc);
-    LocalFree(usersid);
-
-    if (create)
-        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-}
-
-UINT MSIREG_OpenManagedFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
-{
-    WCHAR squished_pc[GUID_SIZE];
-    WCHAR keypath[0x200];
-    LPWSTR usersid;
-    UINT r;
-
-    TRACE("%s\n", debugstr_w(szProductCode));
-
-    if (!squash_guid(szProductCode, squished_pc))
-        return ERROR_FUNCTION_FAILED;
-
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
-
-    r = get_user_sid(&usersid);
-    if (r != ERROR_SUCCESS || !usersid)
-    {
-        ERR("Failed to retrieve user SID: %d\n", r);
-        return r;
-    }
-
-    sprintfW(keypath, szInstaller_LocalManagedFeat_fmt, usersid, squished_pc);
-    LocalFree(usersid);
-
-    if (create)
-        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
-
-    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+    return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
 }
 
 UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create)
@@ -1374,7 +1265,7 @@ UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
     if( !szProduct )
         return ERROR_INVALID_PARAMETER;
 
-    r = MSIREG_OpenFeaturesKey(szProduct,&hkeyProduct,FALSE);
+    r = MSIREG_OpenInstallerFeaturesKey(szProduct,&hkeyProduct,FALSE);
     if( r != ERROR_SUCCESS )
         return ERROR_NO_MORE_ITEMS;
 
@@ -1460,8 +1351,8 @@ UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
     if (!szComponent || !*szComponent || !szProduct)
         return ERROR_INVALID_PARAMETER;
 
-    if (MSIREG_OpenUserDataComponentKey(szComponent, &hkeyComp, FALSE) != ERROR_SUCCESS &&
-        MSIREG_OpenLocalSystemComponentKey(szComponent, &hkeyComp, FALSE) != ERROR_SUCCESS)
+    if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkeyComp, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkeyComp, FALSE) != ERROR_SUCCESS)
         return ERROR_UNKNOWN_COMPONENT;
 
     /* see if there are any products at all */
@@ -1487,7 +1378,7 @@ UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
     return r;
 }
 
-static UINT WINAPI MSI_EnumComponentQualifiers( LPCWSTR szComponent, DWORD iIndex,
+static UINT MSI_EnumComponentQualifiers( LPCWSTR szComponent, DWORD iIndex,
                 awstring *lpQualBuf, LPDWORD pcchQual,
                 awstring *lpAppBuf, LPDWORD pcchAppBuf )
 {
@@ -1699,26 +1590,513 @@ UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved,
     return r;
 }
 
+/***********************************************************************
+ * MsiEnumPatchesExA            [MSI.@]
+ */
+UINT WINAPI MsiEnumPatchesExA(LPCSTR szProductCode, LPCSTR szUserSid,
+        DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPSTR szPatchCode,
+        LPSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext,
+        LPSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
+{
+    LPWSTR prodcode = NULL;
+    LPWSTR usersid = NULL;
+    LPWSTR targsid = NULL;
+    WCHAR patch[GUID_SIZE];
+    WCHAR targprod[GUID_SIZE];
+    DWORD len;
+    UINT r;
+
+    TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n",
+          debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext, dwFilter,
+          dwIndex, szPatchCode, szTargetProductCode, pdwTargetProductContext,
+          szTargetUserSid, pcchTargetUserSid);
+
+    if (szTargetUserSid && !pcchTargetUserSid)
+        return ERROR_INVALID_PARAMETER;
+
+    if (szProductCode) prodcode = strdupAtoW(szProductCode);
+    if (szUserSid) usersid = strdupAtoW(szUserSid);
+
+    r = MsiEnumPatchesExW(prodcode, usersid, dwContext, dwFilter, dwIndex,
+                          patch, targprod, pdwTargetProductContext,
+                          NULL, &len);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    WideCharToMultiByte(CP_ACP, 0, patch, -1, szPatchCode,
+                        GUID_SIZE, NULL, NULL);
+    WideCharToMultiByte(CP_ACP, 0, targprod, -1, szTargetProductCode,
+                        GUID_SIZE, NULL, NULL);
+
+    if (!szTargetUserSid)
+    {
+        if (pcchTargetUserSid)
+            *pcchTargetUserSid = len;
+
+        goto done;
+    }
+
+    targsid = msi_alloc(++len * sizeof(WCHAR));
+    if (!targsid)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    r = MsiEnumPatchesExW(prodcode, usersid, dwContext, dwFilter, dwIndex,
+                          patch, targprod, pdwTargetProductContext,
+                          targsid, &len);
+    if (r != ERROR_SUCCESS || !szTargetUserSid)
+        goto done;
+
+    WideCharToMultiByte(CP_ACP, 0, targsid, -1, szTargetUserSid,
+                        *pcchTargetUserSid, NULL, NULL);
+
+    len = lstrlenW(targsid);
+    if (*pcchTargetUserSid < len + 1)
+    {
+        r = ERROR_MORE_DATA;
+        *pcchTargetUserSid = len * sizeof(WCHAR);
+    }
+    else
+        *pcchTargetUserSid = len;
+
+done:
+    msi_free(prodcode);
+    msi_free(usersid);
+    msi_free(targsid);
+
+    return r;
+}
+
+static UINT msi_get_patch_state(LPCWSTR prodcode, LPCWSTR usersid,
+                                LPWSTR patch, MSIPATCHSTATE *state)
+{
+    DWORD type, val, size;
+    HKEY prod, hkey = 0;
+    HKEY udpatch = 0;
+    LONG res;
+    UINT r = ERROR_NO_MORE_ITEMS;
+
+    static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
+    static const WCHAR szState[] = {'S','t','a','t','e',0};
+
+    *state = MSIPATCHSTATE_INVALID;
+
+    /* FIXME: usersid might not be current user */
+    r = MSIREG_OpenUserDataProductKey(prodcode, MSIINSTALLCONTEXT_USERUNMANAGED,
+                                      NULL, &prod, FALSE);
+    if (r != ERROR_SUCCESS)
+        return ERROR_NO_MORE_ITEMS;
+
+    res = RegOpenKeyExW(prod, szPatches, 0, KEY_READ, &hkey);
+    if (res != ERROR_SUCCESS)
+        goto done;
+
+    res = RegOpenKeyExW(hkey, patch, 0, KEY_READ, &udpatch);
+    if (res != ERROR_SUCCESS)
+        goto done;
+
+    size = sizeof(DWORD);
+    res = RegGetValueW(udpatch, NULL, szState, RRF_RT_DWORD, &type, &val, &size);
+    if (res != ERROR_SUCCESS ||
+        val < MSIPATCHSTATE_APPLIED || val > MSIPATCHSTATE_REGISTERED)
+    {
+        r = ERROR_BAD_CONFIGURATION;
+        goto done;
+    }
+
+    *state = val;
+    r = ERROR_SUCCESS;
+
+done:
+    RegCloseKey(udpatch);
+    RegCloseKey(hkey);
+    RegCloseKey(prod);
+
+    return r;
+}
+
+static UINT msi_check_product_patches(LPCWSTR prodcode, LPCWSTR usersid,
+        MSIINSTALLCONTEXT context, DWORD filter, DWORD index, DWORD *idx,
+        LPWSTR patch, LPWSTR targetprod, MSIINSTALLCONTEXT *targetctx,
+        LPWSTR targetsid, DWORD *sidsize, LPWSTR *transforms)
+{
+    MSIPATCHSTATE state;
+    LPWSTR ptr, patches = NULL;
+    HKEY prod, patchkey = 0;
+    HKEY localprod = 0, localpatch = 0;
+    DWORD type, size;
+    LONG res;
+    UINT temp, r = ERROR_NO_MORE_ITEMS;
+
+    static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
+    static const WCHAR szState[] = {'S','t','a','t','e',0};
+    static const WCHAR szEmpty[] = {0};
+
+    if (MSIREG_OpenProductKey(prodcode, context, &prod, FALSE) != ERROR_SUCCESS)
+        return ERROR_NO_MORE_ITEMS;
+
+    size = 0;
+    res = RegGetValueW(prod, szPatches, szPatches, RRF_RT_ANY, &type, NULL,
+                       &size);
+    if (res != ERROR_SUCCESS)
+        goto done;
+
+    if (type != REG_MULTI_SZ)
+    {
+        r = ERROR_BAD_CONFIGURATION;
+        goto done;
+    }
+
+    patches = msi_alloc(size);
+    if (!patches)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    res = RegGetValueW(prod, szPatches, szPatches, RRF_RT_ANY, &type,
+                       patches, &size);
+    if (res != ERROR_SUCCESS)
+        goto done;
+
+    ptr = patches;
+    for (ptr = patches; *ptr && r == ERROR_NO_MORE_ITEMS; ptr += lstrlenW(ptr))
+    {
+        if (!unsquash_guid(ptr, patch))
+        {
+            r = ERROR_BAD_CONFIGURATION;
+            goto done;
+        }
+
+        size = 0;
+        res = RegGetValueW(prod, szPatches, ptr, RRF_RT_REG_SZ,
+                           &type, NULL, &size);
+        if (res != ERROR_SUCCESS)
+            continue;
+
+        if (transforms)
+        {
+            *transforms = msi_alloc(size);
+            if (!*transforms)
+            {
+                r = ERROR_OUTOFMEMORY;
+                goto done;
+            }
+
+            res = RegGetValueW(prod, szPatches, ptr, RRF_RT_REG_SZ,
+                               &type, *transforms, &size);
+            if (res != ERROR_SUCCESS)
+                continue;
+        }
+
+        if (context == MSIINSTALLCONTEXT_USERMANAGED)
+        {
+            if (!(filter & MSIPATCHSTATE_APPLIED))
+            {
+                temp = msi_get_patch_state(prodcode, usersid, ptr, &state);
+                if (temp == ERROR_BAD_CONFIGURATION)
+                {
+                    r = ERROR_BAD_CONFIGURATION;
+                    goto done;
+                }
+
+                if (temp != ERROR_SUCCESS || !(filter & state))
+                    continue;
+            }
+        }
+        else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
+        {
+            if (!(filter & MSIPATCHSTATE_APPLIED))
+            {
+                temp = msi_get_patch_state(prodcode, usersid, ptr, &state);
+                if (temp == ERROR_BAD_CONFIGURATION)
+                {
+                    r = ERROR_BAD_CONFIGURATION;
+                    goto done;
+                }
+
+                if (temp != ERROR_SUCCESS || !(filter & state))
+                    continue;
+            }
+            else
+            {
+                temp = MSIREG_OpenUserDataPatchKey(patch, context,
+                                                   &patchkey, FALSE);
+                RegCloseKey(patchkey);
+                if (temp != ERROR_SUCCESS)
+                    continue;
+            }
+        }
+        else if (context == MSIINSTALLCONTEXT_MACHINE)
+        {
+            usersid = szEmpty;
+
+            if (MSIREG_OpenUserDataProductKey(prodcode, context, NULL, &localprod, FALSE) == ERROR_SUCCESS &&
+                RegOpenKeyExW(localprod, szPatches, 0, KEY_READ, &localpatch) == ERROR_SUCCESS &&
+                RegOpenKeyExW(localpatch, ptr, 0, KEY_READ, &patchkey) == ERROR_SUCCESS)
+            {
+                res = RegGetValueW(patchkey, NULL, szState, RRF_RT_REG_DWORD,
+                                   &type, &state, &size);
+
+                if (!(filter & state))
+                    res = ERROR_NO_MORE_ITEMS;
+
+                RegCloseKey(patchkey);
+            }
+
+            RegCloseKey(localpatch);
+            RegCloseKey(localprod);
+
+            if (res != ERROR_SUCCESS)
+                continue;
+        }
+
+        if (*idx < index)
+        {
+            (*idx)++;
+            continue;
+        }
+
+        r = ERROR_SUCCESS;
+        if (targetprod)
+            lstrcpyW(targetprod, prodcode);
+
+        if (targetctx)
+            *targetctx = context;
+
+        if (targetsid)
+        {
+            lstrcpynW(targetsid, usersid, *sidsize);
+            if (lstrlenW(usersid) >= *sidsize)
+                r = ERROR_MORE_DATA;
+        }
+
+        if (sidsize)
+        {
+            *sidsize = lstrlenW(usersid);
+            if (!targetsid)
+                *sidsize *= sizeof(WCHAR);
+        }
+    }
+
+done:
+    RegCloseKey(prod);
+    msi_free(patches);
+
+    return r;
+}
+
+static UINT msi_enum_patches(LPCWSTR szProductCode, LPCWSTR szUserSid,
+        DWORD dwContext, DWORD dwFilter, DWORD dwIndex, DWORD *idx,
+        LPWSTR szPatchCode, LPWSTR szTargetProductCode,
+        MSIINSTALLCONTEXT *pdwTargetProductContext, LPWSTR szTargetUserSid,
+        LPDWORD pcchTargetUserSid, LPWSTR *szTransforms)
+{
+    UINT r;
+
+    if (dwContext & MSIINSTALLCONTEXT_USERMANAGED)
+    {
+        r = msi_check_product_patches(szProductCode, szUserSid,
+                                      MSIINSTALLCONTEXT_USERMANAGED, dwFilter,
+                                      dwIndex, idx, szPatchCode,
+                                      szTargetProductCode,
+                                      pdwTargetProductContext, szTargetUserSid,
+                                      pcchTargetUserSid, szTransforms);
+        if (r != ERROR_NO_MORE_ITEMS)
+            goto done;
+    }
+
+    if (dwContext & MSIINSTALLCONTEXT_USERUNMANAGED)
+    {
+        r = msi_check_product_patches(szProductCode, szUserSid,
+                                      MSIINSTALLCONTEXT_USERUNMANAGED, dwFilter,
+                                      dwIndex, idx, szPatchCode,
+                                      szTargetProductCode,
+                                      pdwTargetProductContext, szTargetUserSid,
+                                      pcchTargetUserSid, szTransforms);
+        if (r != ERROR_NO_MORE_ITEMS)
+            goto done;
+    }
+
+    if (dwContext & MSIINSTALLCONTEXT_MACHINE)
+    {
+        r = msi_check_product_patches(szProductCode, szUserSid,
+                                      MSIINSTALLCONTEXT_MACHINE, dwFilter,
+                                      dwIndex, idx, szPatchCode,
+                                      szTargetProductCode,
+                                      pdwTargetProductContext, szTargetUserSid,
+                                      pcchTargetUserSid, szTransforms);
+        if (r != ERROR_NO_MORE_ITEMS)
+            goto done;
+    }
+
+done:
+    return r;
+}
+
+/***********************************************************************
+ * MsiEnumPatchesExW            [MSI.@]
+ */
+UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
+        DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPWSTR szPatchCode,
+        LPWSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext,
+        LPWSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
+{
+    WCHAR squished_pc[GUID_SIZE];
+    DWORD idx = 0;
+    UINT r;
+
+    static int last_index = 0;
+
+    TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n",
+          debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext, dwFilter,
+          dwIndex, szPatchCode, szTargetProductCode, pdwTargetProductContext,
+          szTargetUserSid, pcchTargetUserSid);
+
+    if (!szProductCode || !squash_guid(szProductCode, squished_pc))
+        return ERROR_INVALID_PARAMETER;
+
+    if (!lstrcmpW(szUserSid, szLocalSid))
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwContext & MSIINSTALLCONTEXT_MACHINE && szUserSid)
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwContext <= MSIINSTALLCONTEXT_NONE ||
+        dwContext > MSIINSTALLCONTEXT_ALL)
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwFilter <= MSIPATCHSTATE_INVALID || dwFilter > MSIPATCHSTATE_ALL)
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwIndex && dwIndex - last_index != 1)
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwIndex == 0)
+        last_index = 0;
+
+    r = msi_enum_patches(szProductCode, szUserSid, dwContext, dwFilter,
+                         dwIndex, &idx, szPatchCode, szTargetProductCode,
+                         pdwTargetProductContext, szTargetUserSid,
+                         pcchTargetUserSid, NULL);
+
+    if (r == ERROR_SUCCESS)
+        last_index = dwIndex;
+
+    return r;
+}
+
 /***********************************************************************
  * MsiEnumPatchesA            [MSI.@]
  */
-UINT WINAPI MsiEnumPatchesA( LPCSTR szProduct, DWORD iPatchIndex,
+UINT WINAPI MsiEnumPatchesA(LPCSTR szProduct, DWORD iPatchIndex,
         LPSTR lpPatchBuf, LPSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
 {
-    FIXME("%s %d %p %p %p\n", debugstr_a(szProduct),
-          iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
-    return ERROR_NO_MORE_ITEMS;
+    LPWSTR product, transforms = NULL;
+    WCHAR patch[GUID_SIZE];
+    DWORD len;
+    UINT r;
+
+    TRACE("(%s %d %p %p %p)\n", debugstr_a(szProduct), iPatchIndex,
+          lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
+
+    if (!szProduct || !lpPatchBuf || !lpTransformsBuf || !pcchTransformsBuf)
+        return ERROR_INVALID_PARAMETER;
+
+    product = strdupAtoW(szProduct);
+    if (!product)
+        return ERROR_OUTOFMEMORY;
+
+    len = 0;
+    r = MsiEnumPatchesW(product, iPatchIndex, patch, patch, &len);
+    if (r != ERROR_MORE_DATA)
+        goto done;
+
+    transforms = msi_alloc(len);
+    if (!transforms)
+    {
+        r = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    r = MsiEnumPatchesW(product, iPatchIndex, patch, transforms, &len);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    WideCharToMultiByte(CP_ACP, 0, patch, -1, lpPatchBuf,
+                        GUID_SIZE, NULL, NULL);
+
+    WideCharToMultiByte(CP_ACP, 0, transforms, -1, lpTransformsBuf,
+                        *pcchTransformsBuf - 1, NULL, NULL);
+
+    len = lstrlenW(transforms);
+    if (*pcchTransformsBuf < len + 1)
+    {
+        r = ERROR_MORE_DATA;
+        lpTransformsBuf[*pcchTransformsBuf - 1] = '\0';
+        *pcchTransformsBuf = len * sizeof(WCHAR);
+    }
+    else
+        *pcchTransformsBuf = len;
+
+done:
+    msi_free(transforms);
+    msi_free(product);
+
+    return r;
 }
 
 /***********************************************************************
  * MsiEnumPatchesW            [MSI.@]
  */
-UINT WINAPI MsiEnumPatchesW( LPCWSTR szProduct, DWORD iPatchIndex,
+UINT WINAPI MsiEnumPatchesW(LPCWSTR szProduct, DWORD iPatchIndex,
         LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
 {
-    FIXME("%s %d %p %p %p\n", debugstr_w(szProduct),
-          iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
-    return ERROR_NO_MORE_ITEMS;
+    WCHAR squished_pc[GUID_SIZE];
+    LPWSTR transforms = NULL;
+    HKEY prod;
+    DWORD idx = 0;
+    UINT r;
+
+    TRACE("(%s %d %p %p %p)\n", debugstr_w(szProduct), iPatchIndex,
+          lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
+
+    if (!szProduct || !squash_guid(szProduct, squished_pc))
+        return ERROR_INVALID_PARAMETER;
+
+    if (!lpPatchBuf || !lpTransformsBuf || !pcchTransformsBuf)
+        return ERROR_INVALID_PARAMETER;
+
+    if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+                              &prod, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                              &prod, FALSE) != ERROR_SUCCESS &&
+        MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+                              &prod, FALSE) != ERROR_SUCCESS)
+        return ERROR_UNKNOWN_PRODUCT;
+
+    RegCloseKey(prod);
+
+    r = msi_enum_patches(szProduct, NULL, MSIINSTALLCONTEXT_ALL,
+                         MSIPATCHSTATE_ALL, iPatchIndex, &idx, lpPatchBuf,
+                         NULL, NULL, NULL, NULL, &transforms);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    lstrcpynW(lpTransformsBuf, transforms, *pcchTransformsBuf);
+    if (*pcchTransformsBuf <= lstrlenW(transforms))
+    {
+        r = ERROR_MORE_DATA;
+        *pcchTransformsBuf = lstrlenW(transforms) * sizeof(WCHAR);
+    }
+    else
+        *pcchTransformsBuf = lstrlenW(transforms);
+
+done:
+    msi_free(transforms);
+    return r;
 }
 
 UINT WINAPI MsiEnumProductsExA( LPCSTR szProductCode, LPCSTR szUserSid,
index 47f976b..bac4eb4 100644 (file)
@@ -36,6 +36,7 @@
 #include "oleauto.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 #include "msi.h"
 #include "initguid.h"
@@ -80,6 +81,7 @@ struct regsvr_coclass {
     LPCSTR progid;             /* can be NULL to omit */
     LPCSTR viprogid;           /* can be NULL to omit */
     LPCSTR progid_extra;       /* can be NULL to omit */
+    LPCSTR dllversion;         /* can be NULL to omit */
 };
 
 /* flags for regsvr_coclass.flags */
@@ -123,6 +125,8 @@ static WCHAR const viprogid_keyname[25] = {
     'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
     'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
     0 };
+static WCHAR const dllversion_keyname[11] = {
+    'D', 'l', 'l', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
 static char const tmodel_valuename[] = "ThreadingModel";
 
 /***********************************************************************
@@ -177,7 +181,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list) {
                                  KEY_READ | KEY_WRITE, NULL, &key, NULL);
            if (res != ERROR_SUCCESS) goto error_close_iid_key;
 
-           wsprintfW(buf, fmt, list->num_methods);
+           sprintfW(buf, fmt, list->num_methods);
            res = RegSetValueExW(key, NULL, 0, REG_SZ,
                                 (CONST BYTE*)buf,
                                 (lstrlenW(buf) + 1) * sizeof(WCHAR));
@@ -319,6 +323,22 @@ static HRESULT register_coclasses(struct regsvr_coclass const *list) {
            if (res != ERROR_SUCCESS) goto error_close_clsid_key;
        }
 
+        if (list->dllversion) {
+            HKEY dllver_key;
+
+            res = RegCreateKeyExW(clsid_key, dllversion_keyname, 0, NULL, 0,
+                                  KEY_READ | KEY_WRITE, NULL,
+                                  &dllver_key, NULL);
+            if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+            res = RegSetValueExA(dllver_key, NULL, 0, REG_SZ,
+                                 (CONST BYTE*)list->dllversion,
+                                 lstrlenA(list->dllversion) + 1);
+            RegCloseKey(dllver_key);
+            if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+        }
+
+
     error_close_clsid_key:
        RegCloseKey(clsid_key);
     }
@@ -478,6 +498,8 @@ static struct regsvr_coclass const coclass_list[] = {
        "Apartment",
         PROGID_CLSID,
        "IMsiServer",
+        NULL,
+        NULL,
        NULL
     },    
     {     
@@ -489,7 +511,9 @@ static struct regsvr_coclass const coclass_list[] = {
        NULL,
         PROGID_CLSID,
        "WindowsInstaller.Message",
-       NULL
+        NULL,
+        NULL,
+        "3.1.4000"
     },
     {     
         &CLSID_IMsiServerX1,
@@ -500,6 +524,8 @@ static struct regsvr_coclass const coclass_list[] = {
        "Apartment",
         0,
        "WindowsInstaller.Installer",
+        NULL,
+        NULL,
        NULL
     },
     {     
@@ -511,6 +537,8 @@ static struct regsvr_coclass const coclass_list[] = {
        "Apartment",
         PROGID_CLSID,
        "WindowsInstaller.Installer",
+        NULL,
+        NULL,
        NULL
     },
     {     
@@ -522,6 +550,8 @@ static struct regsvr_coclass const coclass_list[] = {
        "Apartment",
         0,
        "WindowsInstaller.Installer",
+        NULL,
+        NULL,
         NULL
     },
     { NULL }                   /* list terminator */
index 070bbfa..30fabce 100644 (file)
@@ -363,6 +363,7 @@ static const MSIVIEWOPS select_ops =
     NULL,
     NULL,
     SELECT_sort,
+    NULL,
 };
 
 static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name )
index d416f0f..e8e4a11 100644 (file)
@@ -64,21 +64,21 @@ static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions,
         if (dwOptions & MSICODE_PATCH)
             rc = MSIREG_OpenUserPatchesKey(szProduct, &rootkey, create);
         else
-            rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
+            rc = MSIREG_OpenProductKey(szProduct, context, &rootkey, create);
     }
     else if (context == MSIINSTALLCONTEXT_USERMANAGED)
     {
         if (dwOptions & MSICODE_PATCH)
             rc = MSIREG_OpenUserPatchesKey(szProduct, &rootkey, create);
         else
-            rc = MSIREG_OpenLocalManagedProductKey(szProduct, &rootkey, create);
+            rc = MSIREG_OpenProductKey(szProduct, context, &rootkey, create);
     }
     else if (context == MSIINSTALLCONTEXT_MACHINE)
     {
         if (dwOptions & MSICODE_PATCH)
             rc = MSIREG_OpenPatchesKey(szProduct, &rootkey, create);
         else
-            rc = MSIREG_OpenLocalClassesProductKey(szProduct, &rootkey, create);
+            rc = MSIREG_OpenProductKey(szProduct, context, &rootkey, create);
     }
 
     if (rc != ERROR_SUCCESS)
@@ -208,16 +208,19 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
                                          LPWSTR szDiskPrompt, LPDWORD pcchDiskPrompt)
 {
     WCHAR squished_pc[GUID_SIZE];
+    WCHAR convert[11];
     LPWSTR value = NULL;
     LPWSTR data = NULL;
-    LPWSTR ptr;
+    LPWSTR ptr, ptr2;
     HKEY source, media;
     DWORD valuesz, datasz = 0;
     DWORD type;
     DWORD numvals, size;
     LONG res;
     UINT r;
-    static int index = 0;
+    static DWORD index = 0;
+
+    static const WCHAR fmt[] = {'#','%','d',0};
 
     TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p)\n", debugstr_w(szProductCodeOrPatchCode),
           debugstr_w(szUserSid), dwContext, dwOptions, dwIndex, szVolumeLabel,
@@ -285,6 +288,7 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
     if (pdwDiskId)
         *pdwDiskId = atolW(value);
 
+    ptr2 = data;
     ptr = strchrW(data, ';');
     if (!ptr)
         ptr = data;
@@ -293,11 +297,19 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
 
     if (pcchVolumeLabel)
     {
-        size = lstrlenW(data);
+        if (type == REG_DWORD)
+        {
+            sprintfW(convert, fmt, *data);
+            size = lstrlenW(convert);
+            ptr2 = convert;
+        }
+        else
+            size = lstrlenW(data);
+
         if (size >= *pcchVolumeLabel)
             r = ERROR_MORE_DATA;
         else if (szVolumeLabel)
-            lstrcpyW(szVolumeLabel, data);
+            lstrcpyW(szVolumeLabel, ptr2);
 
         *pcchVolumeLabel = size;
     }
@@ -307,6 +319,15 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
         if (!*ptr)
             ptr++;
 
+        if (type == REG_DWORD)
+        {
+            sprintfW(convert, fmt, *ptr);
+            size = lstrlenW(convert);
+            ptr = convert;
+        }
+        else
+            size = lstrlenW(ptr);
+
         size = lstrlenW(ptr);
         if (size >= *pcchDiskPrompt)
             r = ERROR_MORE_DATA;
@@ -339,7 +360,7 @@ UINT WINAPI MsiSourceListEnumSourcesA(LPCSTR szProductCodeOrPatch, LPCSTR szUser
     LPWSTR source = NULL;
     DWORD len = 0;
     UINT r = ERROR_INVALID_PARAMETER;
-    static int index = 0;
+    static DWORD index = 0;
 
     TRACE("(%s, %s, %d, %d, %d, %p, %p)\n", debugstr_a(szProductCodeOrPatch),
           debugstr_a(szUserSid), dwContext, dwOptions, dwIndex, szSource, pcchSource);
@@ -412,7 +433,7 @@ UINT WINAPI MsiSourceListEnumSourcesW(LPCWSTR szProductCodeOrPatch, LPCWSTR szUs
     HKEY subkey = NULL;
     LONG res;
     UINT r = ERROR_INVALID_PARAMETER;
-    static int index = 0;
+    static DWORD index = 0;
 
     static const WCHAR format[] = {'%','d',0};
 
@@ -633,7 +654,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
 
         if (szValue)
         {
-            if (lstrlenW(ptr) < *pcchValue)
+            if (strlenW(ptr) < *pcchValue)
                 lstrcpyW(szValue, ptr);
             else
                 rc = ERROR_MORE_DATA;
@@ -882,12 +903,14 @@ UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName,
             msi_free(psid);
         }
 
-        r = MSIREG_OpenLocalManagedProductKey(szProduct, &hkey, FALSE);
+        r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+                                  &hkey, FALSE);
         if (r == ERROR_SUCCESS)
             context = MSIINSTALLCONTEXT_USERMANAGED;
         else
         {
-            r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
+            r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+                                      &hkey, FALSE);
             if (r != ERROR_SUCCESS)
                 return ERROR_UNKNOWN_PRODUCT;
 
index c96d579..9d2e93c 100644 (file)
      TK_COMMA = 262,
      TK_CREATE = 263,
      TK_DELETE = 264,
-     TK_DISTINCT = 265,
-     TK_DOT = 266,
-     TK_EQ = 267,
-     TK_FREE = 268,
-     TK_FROM = 269,
-     TK_GE = 270,
-     TK_GT = 271,
-     TK_HOLD = 272,
-     TK_ADD = 273,
-     TK_ID = 274,
-     TK_ILLEGAL = 275,
-     TK_INSERT = 276,
-     TK_INT = 277,
-     TK_INTEGER = 278,
-     TK_INTO = 279,
-     TK_IS = 280,
-     TK_KEY = 281,
-     TK_LE = 282,
-     TK_LONG = 283,
-     TK_LONGCHAR = 284,
-     TK_LP = 285,
-     TK_LT = 286,
-     TK_LOCALIZABLE = 287,
-     TK_MINUS = 288,
-     TK_NE = 289,
-     TK_NOT = 290,
-     TK_NULL = 291,
-     TK_OBJECT = 292,
-     TK_OR = 293,
-     TK_ORDER = 294,
-     TK_PRIMARY = 295,
-     TK_RP = 296,
-     TK_SELECT = 297,
-     TK_SET = 298,
-     TK_SHORT = 299,
-     TK_SPACE = 300,
-     TK_STAR = 301,
-     TK_STRING = 302,
-     TK_TABLE = 303,
-     TK_TEMPORARY = 304,
-     TK_UPDATE = 305,
-     TK_VALUES = 306,
-     TK_WHERE = 307,
-     TK_WILDCARD = 308,
-     COLUMN = 310,
-     FUNCTION = 311,
-     COMMENT = 312,
-     UNCLOSED_STRING = 313,
-     SPACE = 314,
-     ILLEGAL = 315,
-     END_OF_FILE = 316,
-     TK_LIKE = 317,
-     TK_NEGATION = 318
+     TK_DROP = 265,
+     TK_DISTINCT = 266,
+     TK_DOT = 267,
+     TK_EQ = 268,
+     TK_FREE = 269,
+     TK_FROM = 270,
+     TK_GE = 271,
+     TK_GT = 272,
+     TK_HOLD = 273,
+     TK_ADD = 274,
+     TK_ID = 275,
+     TK_ILLEGAL = 276,
+     TK_INSERT = 277,
+     TK_INT = 278,
+     TK_INTEGER = 279,
+     TK_INTO = 280,
+     TK_IS = 281,
+     TK_KEY = 282,
+     TK_LE = 283,
+     TK_LONG = 284,
+     TK_LONGCHAR = 285,
+     TK_LP = 286,
+     TK_LT = 287,
+     TK_LOCALIZABLE = 288,
+     TK_MINUS = 289,
+     TK_NE = 290,
+     TK_NOT = 291,
+     TK_NULL = 292,
+     TK_OBJECT = 293,
+     TK_OR = 294,
+     TK_ORDER = 295,
+     TK_PRIMARY = 296,
+     TK_RP = 297,
+     TK_SELECT = 298,
+     TK_SET = 299,
+     TK_SHORT = 300,
+     TK_SPACE = 301,
+     TK_STAR = 302,
+     TK_STRING = 303,
+     TK_TABLE = 304,
+     TK_TEMPORARY = 305,
+     TK_UPDATE = 306,
+     TK_VALUES = 307,
+     TK_WHERE = 308,
+     TK_WILDCARD = 309,
+     COLUMN = 311,
+     FUNCTION = 312,
+     COMMENT = 313,
+     UNCLOSED_STRING = 314,
+     SPACE = 315,
+     ILLEGAL = 316,
+     END_OF_FILE = 317,
+     TK_LIKE = 318,
+     TK_NEGATION = 319
    };
 #endif
 /* Tokens.  */
 #define TK_COMMA 262
 #define TK_CREATE 263
 #define TK_DELETE 264
-#define TK_DISTINCT 265
-#define TK_DOT 266
-#define TK_EQ 267
-#define TK_FREE 268
-#define TK_FROM 269
-#define TK_GE 270
-#define TK_GT 271
-#define TK_HOLD 272
-#define TK_ADD 273
-#define TK_ID 274
-#define TK_ILLEGAL 275
-#define TK_INSERT 276
-#define TK_INT 277
-#define TK_INTEGER 278
-#define TK_INTO 279
-#define TK_IS 280
-#define TK_KEY 281
-#define TK_LE 282
-#define TK_LONG 283
-#define TK_LONGCHAR 284
-#define TK_LP 285
-#define TK_LT 286
-#define TK_LOCALIZABLE 287
-#define TK_MINUS 288
-#define TK_NE 289
-#define TK_NOT 290
-#define TK_NULL 291
-#define TK_OBJECT 292
-#define TK_OR 293
-#define TK_ORDER 294
-#define TK_PRIMARY 295
-#define TK_RP 296
-#define TK_SELECT 297
-#define TK_SET 298
-#define TK_SHORT 299
-#define TK_SPACE 300
-#define TK_STAR 301
-#define TK_STRING 302
-#define TK_TABLE 303
-#define TK_TEMPORARY 304
-#define TK_UPDATE 305
-#define TK_VALUES 306
-#define TK_WHERE 307
-#define TK_WILDCARD 308
-#define COLUMN 310
-#define FUNCTION 311
-#define COMMENT 312
-#define UNCLOSED_STRING 313
-#define SPACE 314
-#define ILLEGAL 315
-#define END_OF_FILE 316
-#define TK_LIKE 317
-#define TK_NEGATION 318
+#define TK_DROP 265
+#define TK_DISTINCT 266
+#define TK_DOT 267
+#define TK_EQ 268
+#define TK_FREE 269
+#define TK_FROM 270
+#define TK_GE 271
+#define TK_GT 272
+#define TK_HOLD 273
+#define TK_ADD 274
+#define TK_ID 275
+#define TK_ILLEGAL 276
+#define TK_INSERT 277
+#define TK_INT 278
+#define TK_INTEGER 279
+#define TK_INTO 280
+#define TK_IS 281
+#define TK_KEY 282
+#define TK_LE 283
+#define TK_LONG 284
+#define TK_LONGCHAR 285
+#define TK_LP 286
+#define TK_LT 287
+#define TK_LOCALIZABLE 288
+#define TK_MINUS 289
+#define TK_NE 290
+#define TK_NOT 291
+#define TK_NULL 292
+#define TK_OBJECT 293
+#define TK_OR 294
+#define TK_ORDER 295
+#define TK_PRIMARY 296
+#define TK_RP 297
+#define TK_SELECT 298
+#define TK_SET 299
+#define TK_SHORT 300
+#define TK_SPACE 301
+#define TK_STAR 302
+#define TK_STRING 303
+#define TK_TABLE 304
+#define TK_TEMPORARY 305
+#define TK_UPDATE 306
+#define TK_VALUES 307
+#define TK_WHERE 308
+#define TK_WILDCARD 309
+#define COLUMN 311
+#define FUNCTION 312
+#define COMMENT 313
+#define UNCLOSED_STRING 314
+#define SPACE 315
+#define ILLEGAL 316
+#define END_OF_FILE 317
+#define TK_LIKE 318
+#define TK_NEGATION 319
 
 
 
@@ -293,7 +295,7 @@ typedef union YYSTYPE {
     int integer;
 } YYSTYPE;
 /* Line 196 of yacc.c.  */
-#line 297 "sql.tab.c"
+#line 299 "sql.tab.c"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -305,7 +307,7 @@ typedef union YYSTYPE {
 
 
 /* Line 219 of yacc.c.  */
-#line 309 "sql.tab.c"
+#line 311 "sql.tab.c"
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
 # define YYSIZE_T __SIZE_TYPE__
@@ -454,22 +456,22 @@ union yyalloc
 #endif
 
 /* YYFINAL -- State number of the termination state. */
-#define YYFINAL  32
+#define YYFINAL  35
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   138
+#define YYLAST   144
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  64
+#define YYNTOKENS  65
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  34
+#define YYNNTS  35
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  79
+#define YYNRULES  81
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  141
+#define YYNSTATES  145
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   318
+#define YYMAXUTOK   319
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -508,7 +510,7 @@ static const unsigned char yytranslate[] =
       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
       45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
-      55,    56,    57,    58,    59,    60,    61,    62,    63
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64
 };
 
 #if YYDEBUG
@@ -517,58 +519,61 @@ static const unsigned char yytranslate[] =
 static const unsigned short int yyprhs[] =
 {
        0,     0,     3,     5,     7,     9,    11,    13,    15,    17,
-      28,    40,    47,    55,    62,    67,    70,    75,    81,    88,
-      90,    92,    97,   101,   103,   106,   108,   111,   114,   116,
-     120,   122,   127,   129,   131,   133,   135,   137,   139,   144,
-     146,   149,   153,   156,   158,   162,   164,   166,   170,   173,
-     176,   178,   182,   186,   190,   194,   198,   202,   206,   210,
-     214,   218,   222,   227,   229,   231,   233,   237,   239,   243,
-     247,   249,   252,   254,   256,   258,   262,   264,   266,   268
+      19,    30,    42,    49,    57,    64,    69,    72,    77,    83,
+      90,    92,    94,    98,   103,   107,   109,   112,   114,   117,
+     120,   122,   126,   128,   133,   135,   137,   139,   141,   143,
+     145,   150,   152,   155,   159,   162,   164,   168,   170,   172,
+     176,   179,   182,   184,   188,   192,   196,   200,   204,   208,
+     212,   216,   220,   224,   228,   233,   235,   237,   239,   243,
+     245,   249,   253,   255,   258,   260,   262,   264,   268,   270,
+     272,   274
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const yysigned_char yyrhs[] =
 {
-      65,     0,    -1,    66,    -1,    80,    -1,    68,    -1,    67,
-      -1,    69,    -1,    70,    -1,    71,    -1,    21,    24,    95,
-      30,    83,    41,    51,    30,    89,    41,    -1,    21,    24,
-      95,    30,    83,    41,    51,    30,    89,    41,    49,    -1,
-       8,    48,    95,    30,    73,    41,    -1,     8,    48,    95,
-      30,    73,    41,    17,    -1,    50,    95,    43,    90,    52,
-      87,    -1,    50,    95,    43,    90,    -1,     9,    84,    -1,
-       3,    48,    95,    72,    -1,     3,    48,    95,    18,    75,
-      -1,     3,    48,    95,    18,    75,    17,    -1,    17,    -1,
-      13,    -1,    74,    40,    26,    83,    -1,    74,     7,    75,
-      -1,    75,    -1,    94,    76,    -1,    77,    -1,    77,    32,
-      -1,    77,    49,    -1,    78,    -1,    78,    35,    36,    -1,
-       6,    -1,     6,    30,    79,    41,    -1,    29,    -1,    44,
-      -1,    22,    -1,    28,    -1,    37,    -1,    97,    -1,    81,
-      39,     5,    83,    -1,    81,    -1,    42,    82,    -1,    42,
-      10,    82,    -1,    83,    84,    -1,    94,    -1,    94,     7,
-      83,    -1,    46,    -1,    85,    -1,    85,    52,    87,    -1,
-      14,    95,    -1,    14,    86,    -1,    95,    -1,    95,     7,
-      86,    -1,    30,    87,    41,    -1,    87,     4,    87,    -1,
-      87,    38,    87,    -1,    93,    12,    88,    -1,    93,    16,
-      88,    -1,    93,    31,    88,    -1,    93,    27,    88,    -1,
-      93,    15,    88,    -1,    93,    34,    88,    -1,    93,    25,
-      36,    -1,    93,    25,    35,    36,    -1,    93,    -1,    92,
-      -1,    92,    -1,    92,     7,    89,    -1,    91,    -1,    91,
-       7,    90,    -1,    94,    12,    92,    -1,    97,    -1,    33,
-      97,    -1,    47,    -1,    53,    -1,    94,    -1,    95,    11,
-      96,    -1,    96,    -1,    96,    -1,    19,    -1,    23,    -1
+      66,     0,    -1,    67,    -1,    82,    -1,    69,    -1,    68,
+      -1,    70,    -1,    71,    -1,    72,    -1,    74,    -1,    22,
+      25,    97,    31,    85,    42,    52,    31,    91,    42,    -1,
+      22,    25,    97,    31,    85,    42,    52,    31,    91,    42,
+      50,    -1,     8,    49,    97,    31,    75,    42,    -1,     8,
+      49,    97,    31,    75,    42,    18,    -1,    51,    97,    44,
+      92,    53,    89,    -1,    51,    97,    44,    92,    -1,     9,
+      86,    -1,     3,    49,    97,    73,    -1,     3,    49,    97,
+      19,    77,    -1,     3,    49,    97,    19,    77,    18,    -1,
+      18,    -1,    14,    -1,    10,    49,    97,    -1,    76,    41,
+      27,    85,    -1,    76,     7,    77,    -1,    77,    -1,    96,
+      78,    -1,    79,    -1,    79,    33,    -1,    79,    50,    -1,
+      80,    -1,    80,    36,    37,    -1,     6,    -1,     6,    31,
+      81,    42,    -1,    30,    -1,    45,    -1,    23,    -1,    29,
+      -1,    38,    -1,    99,    -1,    83,    40,     5,    85,    -1,
+      83,    -1,    43,    84,    -1,    43,    11,    84,    -1,    85,
+      86,    -1,    96,    -1,    96,     7,    85,    -1,    47,    -1,
+      87,    -1,    87,    53,    89,    -1,    15,    97,    -1,    15,
+      88,    -1,    97,    -1,    97,     7,    88,    -1,    31,    89,
+      42,    -1,    89,     4,    89,    -1,    89,    39,    89,    -1,
+      95,    13,    90,    -1,    95,    17,    90,    -1,    95,    32,
+      90,    -1,    95,    28,    90,    -1,    95,    16,    90,    -1,
+      95,    35,    90,    -1,    95,    26,    37,    -1,    95,    26,
+      36,    37,    -1,    95,    -1,    94,    -1,    94,    -1,    94,
+       7,    91,    -1,    93,    -1,    93,     7,    92,    -1,    96,
+      13,    94,    -1,    99,    -1,    34,    99,    -1,    48,    -1,
+      54,    -1,    96,    -1,    97,    12,    98,    -1,    98,    -1,
+      98,    -1,    20,    -1,    24,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short int yyrline[] =
 {
-       0,   124,   124,   132,   133,   134,   135,   136,   137,   141,
-     151,   164,   176,   191,   201,   214,   227,   237,   247,   260,
-     264,   271,   281,   291,   298,   307,   311,   315,   322,   326,
-     333,   337,   341,   345,   349,   353,   357,   364,   373,   386,
-     390,   394,   410,   431,   432,   436,   443,   444,   460,   470,
-     483,   488,   497,   503,   509,   515,   521,   527,   533,   539,
-     545,   551,   557,   566,   567,   571,   578,   589,   590,   598,
-     606,   612,   618,   624,   633,   642,   648,   657,   664,   673
+       0,   124,   124,   132,   133,   134,   135,   136,   137,   138,
+     142,   152,   165,   177,   192,   202,   215,   228,   238,   248,
+     261,   265,   272,   285,   295,   305,   312,   321,   325,   329,
+     336,   340,   347,   351,   355,   359,   363,   367,   371,   378,
+     387,   400,   404,   408,   424,   445,   446,   450,   457,   458,
+     474,   484,   497,   502,   511,   517,   523,   529,   535,   541,
+     547,   553,   559,   565,   571,   580,   581,   585,   592,   603,
+     604,   612,   620,   626,   632,   638,   647,   656,   662,   671,
+     678,   687
 };
 #endif
 
@@ -578,10 +583,10 @@ static const unsigned short int yyrline[] =
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "TK_ALTER", "TK_AND", "TK_BY", "TK_CHAR",
-  "TK_COMMA", "TK_CREATE", "TK_DELETE", "TK_DISTINCT", "TK_DOT", "TK_EQ",
-  "TK_FREE", "TK_FROM", "TK_GE", "TK_GT", "TK_HOLD", "TK_ADD", "TK_ID",
-  "TK_ILLEGAL", "TK_INSERT", "TK_INT", "TK_INTEGER", "TK_INTO", "TK_IS",
-  "TK_KEY", "TK_LE", "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LT",
+  "TK_COMMA", "TK_CREATE", "TK_DELETE", "TK_DROP", "TK_DISTINCT", "TK_DOT",
+  "TK_EQ", "TK_FREE", "TK_FROM", "TK_GE", "TK_GT", "TK_HOLD", "TK_ADD",
+  "TK_ID", "TK_ILLEGAL", "TK_INSERT", "TK_INT", "TK_INTEGER", "TK_INTO",
+  "TK_IS", "TK_KEY", "TK_LE", "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LT",
   "TK_LOCALIZABLE", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NULL", "TK_OBJECT",
   "TK_OR", "TK_ORDER", "TK_PRIMARY", "TK_RP", "TK_SELECT", "TK_SET",
   "TK_SHORT", "TK_SPACE", "TK_STAR", "TK_STRING", "TK_TABLE",
@@ -589,12 +594,12 @@ static const char *const yytname[] =
   "AGG_FUNCTION.", "COLUMN", "FUNCTION", "COMMENT", "UNCLOSED_STRING",
   "SPACE", "ILLEGAL", "END_OF_FILE", "TK_LIKE", "TK_NEGATION", "$accept",
   "query", "onequery", "oneinsert", "onecreate", "oneupdate", "onedelete",
-  "onealter", "alterop", "table_def", "column_def", "column_and_type",
-  "column_type", "data_type_l", "data_type", "data_count", "oneselect",
-  "unorderedsel", "selectfrom", "selcollist", "from", "fromtable",
-  "tablelist", "expr", "val", "constlist", "update_assign_list",
-  "column_assignment", "const_val", "column_val", "column", "table", "id",
-  "number", 0
+  "onealter", "alterop", "onedrop", "table_def", "column_def",
+  "column_and_type", "column_type", "data_type_l", "data_type",
+  "data_count", "oneselect", "unorderedsel", "selectfrom", "selcollist",
+  "from", "fromtable", "tablelist", "expr", "val", "constlist",
+  "update_assign_list", "column_assignment", "const_val", "column_val",
+  "column", "table", "id", "number", 0
 };
 #endif
 
@@ -609,34 +614,36 @@ static const unsigned short int yytoknum[] =
      285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
      295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
      305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
-     315,   316,   317,   318
+     315,   316,   317,   318,   319
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const unsigned char yyr1[] =
 {
-       0,    64,    65,    66,    66,    66,    66,    66,    66,    67,
-      67,    68,    68,    69,    69,    70,    71,    71,    71,    72,
-      72,    73,    74,    74,    75,    76,    76,    76,    77,    77,
-      78,    78,    78,    78,    78,    78,    78,    79,    80,    80,
-      81,    81,    82,    83,    83,    83,    84,    84,    85,    85,
-      86,    86,    87,    87,    87,    87,    87,    87,    87,    87,
-      87,    87,    87,    88,    88,    89,    89,    90,    90,    91,
-      92,    92,    92,    92,    93,    94,    94,    95,    96,    97
+       0,    65,    66,    67,    67,    67,    67,    67,    67,    67,
+      68,    68,    69,    69,    70,    70,    71,    72,    72,    72,
+      73,    73,    74,    75,    76,    76,    77,    78,    78,    78,
+      79,    79,    80,    80,    80,    80,    80,    80,    80,    81,
+      82,    82,    83,    83,    84,    85,    85,    85,    86,    86,
+      87,    87,    88,    88,    89,    89,    89,    89,    89,    89,
+      89,    89,    89,    89,    89,    90,    90,    91,    91,    92,
+      92,    93,    94,    94,    94,    94,    95,    96,    96,    97,
+      98,    99
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const unsigned char yyr2[] =
 {
-       0,     2,     1,     1,     1,     1,     1,     1,     1,    10,
-      11,     6,     7,     6,     4,     2,     4,     5,     6,     1,
-       1,     4,     3,     1,     2,     1,     2,     2,     1,     3,
-       1,     4,     1,     1,     1,     1,     1,     1,     4,     1,
-       2,     3,     2,     1,     3,     1,     1,     3,     2,     2,
-       1,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     4,     1,     1,     1,     3,     1,     3,     3,
-       1,     2,     1,     1,     1,     3,     1,     1,     1,     1
+       0,     2,     1,     1,     1,     1,     1,     1,     1,     1,
+      10,    11,     6,     7,     6,     4,     2,     4,     5,     6,
+       1,     1,     3,     4,     3,     1,     2,     1,     2,     2,
+       1,     3,     1,     4,     1,     1,     1,     1,     1,     1,
+       4,     1,     2,     3,     2,     1,     3,     1,     1,     3,
+       2,     2,     1,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     4,     1,     1,     1,     3,     1,
+       3,     3,     1,     2,     1,     1,     1,     3,     1,     1,
+       1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -644,123 +651,125 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned char yydefact[] =
 {
-       0,     0,     0,     0,     0,     0,     0,     0,     2,     5,
-       4,     6,     7,     8,     3,    39,     0,     0,     0,    15,
-      46,     0,     0,    78,    45,    40,     0,    43,     0,    76,
-       0,    77,     1,     0,     0,     0,    49,    48,     0,     0,
-      41,    42,     0,     0,     0,     0,    20,    19,     0,    16,
-       0,     0,     0,    47,     0,    74,     0,    44,    75,    14,
-      67,     0,    38,    17,     0,     0,     0,    23,    51,    50,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    18,    30,    34,    35,    32,    36,
-      33,    24,    25,    28,    11,     0,     0,    52,    53,    54,
-      79,     0,    72,    73,    55,    64,    63,    70,    59,    56,
-       0,    61,    58,    57,    60,     0,    13,    68,    69,     0,
-      26,    27,     0,    12,    22,     0,    71,    62,     0,     0,
-      37,    29,    21,     0,    31,     0,    65,     9,     0,    10,
-      66
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     2,
+       5,     4,     6,     7,     8,     9,     3,    41,     0,     0,
+       0,    16,    48,     0,     0,     0,    80,    47,    42,     0,
+      45,     0,    78,     0,    79,     1,     0,     0,     0,    51,
+      50,     0,    22,     0,    43,    44,     0,     0,     0,     0,
+      21,    20,     0,    17,     0,     0,     0,    49,     0,    76,
+       0,    46,    77,    15,    69,     0,    40,    18,     0,     0,
+       0,    25,    53,    52,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    19,    32,
+      36,    37,    34,    38,    35,    26,    27,    30,    12,     0,
+       0,    54,    55,    56,    81,     0,    74,    75,    57,    66,
+      65,    72,    61,    58,     0,    63,    60,    59,    62,     0,
+      14,    70,    71,     0,    28,    29,     0,    13,    24,     0,
+      73,    64,     0,     0,    39,    31,    23,     0,    33,     0,
+      67,    10,     0,    11,    68
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const short int yydefgoto[] =
 {
-      -1,     7,     8,     9,    10,    11,    12,    13,    49,    65,
-      66,    63,    91,    92,    93,   129,    14,    15,    25,    26,
-      19,    20,    36,    53,   104,   135,    59,    60,   105,   106,
-      55,    28,    29,   107
+      -1,     8,     9,    10,    11,    12,    13,    14,    53,    15,
+      69,    70,    67,    95,    96,    97,   133,    16,    17,    28,
+      29,    21,    22,    39,    57,   108,   139,    63,    64,   109,
+     110,    59,    31,    32,   111
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -96
-static const yysigned_char yypact[] =
+#define YYPACT_NINF -97
+static const short int yypact[] =
 {
-       0,   -43,   -34,     4,    24,     1,     6,    19,   -96,   -96,
-     -96,   -96,   -96,   -96,   -96,    31,     6,     6,     6,   -96,
-      30,     6,    35,   -96,   -96,   -96,     4,    67,    47,    65,
-      42,   -96,   -96,    81,   101,    59,   -96,    89,    48,    68,
-     -96,   -96,    35,     6,     6,    35,   -96,   -96,     6,   -96,
-       6,     6,    48,     3,    76,   -96,    35,   -96,   -96,    45,
-      95,    93,   -96,    98,    43,    75,    22,   -96,   -96,    89,
-      18,    48,    48,    13,    13,    13,   -23,    13,    13,    13,
-      80,    48,     6,    46,   -96,    87,   -96,   -96,   -96,   -96,
-     -96,   -96,    51,    71,   105,     6,    97,   -96,   -96,   120,
-     -96,   102,   -96,   -96,   -96,   -96,   -96,   -96,   -96,   -96,
-      90,   -96,   -96,   -96,   -96,    77,     3,   -96,   -96,   102,
-     -96,   -96,    91,   -96,   -96,    35,   -96,   -96,    99,    92,
-     -96,   -96,   -96,    46,   -96,    94,   123,    82,    46,   -96,
-     -96
+       4,   -41,   -19,    56,   -14,    42,    14,    59,    72,   -97,
+     -97,   -97,   -97,   -97,   -97,   -97,   -97,    36,    59,    59,
+      59,   -97,    30,    59,    59,     3,   -97,   -97,   -97,    56,
+      82,    79,    80,    50,   -97,   -97,    93,    51,    73,   -97,
+      96,    29,   -97,    74,   -97,   -97,     3,    59,    59,     3,
+     -97,   -97,    59,   -97,    59,    59,    29,    20,    83,   -97,
+       3,   -97,   -97,    57,    99,   100,   -97,    94,    52,    84,
+      21,   -97,   -97,    96,    -1,    29,    29,    54,    54,    54,
+     -26,    54,    54,    54,    85,    29,    59,    53,   -97,    91,
+     -97,   -97,   -97,   -97,   -97,   -97,     6,    78,   106,    59,
+      98,   -97,   -97,   124,   -97,   105,   -97,   -97,   -97,   -97,
+     -97,   -97,   -97,   -97,    95,   -97,   -97,   -97,   -97,    81,
+      20,   -97,   -97,   105,   -97,   -97,    97,   -97,   -97,     3,
+     -97,   -97,   104,    88,   -97,   -97,   -97,    53,   -97,    89,
+     129,    87,    53,   -97,   -97
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yysigned_char yypgoto[] =
 {
-     -96,   -96,   -96,   -96,   -96,   -96,   -96,   -96,   -96,   -96,
-     -96,   -40,   -96,   -96,   -96,   -96,   -96,   -96,   110,   -41,
-     108,   -96,    85,    23,    34,    -1,    56,   -96,   -81,    -8,
-      -5,    17,    10,   -95
+     -97,   -97,   -97,   -97,   -97,   -97,   -97,   -97,   -97,   -97,
+     -97,   -97,   -48,   -97,   -97,   -97,   -97,   -97,   -97,   113,
+     -45,   110,   -97,    86,    10,    38,     0,    58,   -97,   -85,
+     -12,    -6,    13,    -2,   -96
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -78
+#define YYTABLE_NINF -80
 static const short int yytable[] =
 {
-      27,    57,   118,     1,    62,    16,   126,    71,     2,     3,
-      67,    22,   110,   111,    17,    80,    31,    27,    18,    32,
-      23,     4,    71,    30,   130,    23,    31,    31,    31,    95,
-      54,    31,    23,    34,    35,    37,   100,    27,    39,    61,
-      27,    72,     5,    64,    54,    64,   101,    24,    21,    85,
-       6,    27,   136,    58,    23,   124,    72,   136,    43,    97,
-     102,    31,    96,    54,    54,    86,   103,    23,    69,   100,
-      33,    87,    88,    54,    42,    70,   -77,    61,    52,   101,
-      89,    24,    38,   120,   132,    44,    45,    90,    73,    50,
-      64,    74,    75,   102,    98,    99,    51,    81,    56,   103,
-     121,    76,    82,    77,   116,    83,   122,    78,   108,   109,
-      79,   112,   113,   114,    46,    84,    94,   119,    47,    48,
-      27,   115,   123,   125,    71,   100,   127,   131,   128,   133,
-     138,   139,    40,   134,    41,   137,    68,   140,   117
+      30,    61,   122,    75,    66,    34,    71,     1,    18,   130,
+     114,   115,     2,     3,     4,    84,    34,    34,    34,    30,
+      33,    34,    34,    26,    75,    25,     5,   134,    99,    58,
+      19,    37,    38,    40,    26,    23,    42,    43,    76,   124,
+      30,   101,    65,    30,    58,    62,    68,     6,    68,    26,
+      27,   128,   140,    34,    30,     7,   125,   140,    89,    76,
+      56,    27,   100,    58,    58,    50,    74,    24,    73,    51,
+      52,    20,    35,    58,    26,    90,    36,   104,   104,    26,
+      65,    91,    92,    41,   136,   102,   103,   105,   105,    46,
+      93,    47,   -79,    68,    48,   120,    77,    94,    49,    78,
+      79,   106,   106,    55,    54,    60,    86,   107,   107,    80,
+      85,    81,    88,    87,   126,    82,   112,   113,    83,   116,
+     117,   118,   123,    30,   127,   129,    98,   119,    75,   104,
+     138,   141,   131,   132,   135,   137,   142,   143,    44,    45,
+       0,    72,   144,     0,   121
 };
 
-static const unsigned char yycheck[] =
+static const short int yycheck[] =
 {
-       5,    42,    83,     3,    45,    48,   101,     4,     8,     9,
-      50,    10,    35,    36,    48,    56,     6,    22,    14,     0,
-      19,    21,     4,     6,   119,    19,    16,    17,    18,     7,
-      38,    21,    19,    16,    17,    18,    23,    42,    21,    44,
-      45,    38,    42,    48,    52,    50,    33,    46,    24,     6,
-      50,    56,   133,    43,    19,    95,    38,   138,    11,    41,
-      47,    51,    40,    71,    72,    22,    53,    19,    51,    23,
-      39,    28,    29,    81,     7,    52,    11,    82,    30,    33,
-      37,    46,    52,    32,   125,    43,     5,    44,    12,    30,
-      95,    15,    16,    47,    71,    72,     7,    52,    30,    53,
-      49,    25,     7,    27,    81,    12,    35,    31,    74,    75,
-      34,    77,    78,    79,    13,    17,    41,    30,    17,    18,
-     125,    41,    17,    26,     4,    23,    36,    36,    51,    30,
-       7,    49,    22,    41,    26,    41,    51,   138,    82
+       6,    46,    87,     4,    49,     7,    54,     3,    49,   105,
+      36,    37,     8,     9,    10,    60,    18,    19,    20,    25,
+       7,    23,    24,    20,     4,    11,    22,   123,     7,    41,
+      49,    18,    19,    20,    20,    49,    23,    24,    39,    33,
+      46,    42,    48,    49,    56,    47,    52,    43,    54,    20,
+      47,    99,   137,    55,    60,    51,    50,   142,     6,    39,
+      31,    47,    41,    75,    76,    14,    56,    25,    55,    18,
+      19,    15,     0,    85,    20,    23,    40,    24,    24,    20,
+      86,    29,    30,    53,   129,    75,    76,    34,    34,     7,
+      38,    12,    12,    99,    44,    85,    13,    45,     5,    16,
+      17,    48,    48,     7,    31,    31,     7,    54,    54,    26,
+      53,    28,    18,    13,    36,    32,    78,    79,    35,    81,
+      82,    83,    31,   129,    18,    27,    42,    42,     4,    24,
+      42,    42,    37,    52,    37,    31,     7,    50,    25,    29,
+      -1,    55,   142,    -1,    86
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const unsigned char yystos[] =
 {
-       0,     3,     8,     9,    21,    42,    50,    65,    66,    67,
-      68,    69,    70,    71,    80,    81,    48,    48,    14,    84,
-      85,    24,    10,    19,    46,    82,    83,    94,    95,    96,
-      95,    96,     0,    39,    95,    95,    86,    95,    52,    95,
-      82,    84,     7,    11,    43,     5,    13,    17,    18,    72,
-      30,     7,    30,    87,    93,    94,    30,    83,    96,    90,
-      91,    94,    83,    75,    94,    73,    74,    75,    86,    95,
-      87,     4,    38,    12,    15,    16,    25,    27,    31,    34,
-      83,    52,     7,    12,    17,     6,    22,    28,    29,    37,
-      44,    76,    77,    78,    41,     7,    40,    41,    87,    87,
-      23,    33,    47,    53,    88,    92,    93,    97,    88,    88,
-      35,    36,    88,    88,    88,    41,    87,    90,    92,    30,
-      32,    49,    35,    17,    75,    26,    97,    36,    51,    79,
-      97,    36,    83,    30,    41,    89,    92,    41,     7,    49,
-      89
+       0,     3,     8,     9,    10,    22,    43,    51,    66,    67,
+      68,    69,    70,    71,    72,    74,    82,    83,    49,    49,
+      15,    86,    87,    49,    25,    11,    20,    47,    84,    85,
+      96,    97,    98,    97,    98,     0,    40,    97,    97,    88,
+      97,    53,    97,    97,    84,    86,     7,    12,    44,     5,
+      14,    18,    19,    73,    31,     7,    31,    89,    95,    96,
+      31,    85,    98,    92,    93,    96,    85,    77,    96,    75,
+      76,    77,    88,    97,    89,     4,    39,    13,    16,    17,
+      26,    28,    32,    35,    85,    53,     7,    13,    18,     6,
+      23,    29,    30,    38,    45,    78,    79,    80,    42,     7,
+      41,    42,    89,    89,    24,    34,    48,    54,    90,    94,
+      95,    99,    90,    90,    36,    37,    90,    90,    90,    42,
+      89,    92,    94,    31,    33,    50,    36,    18,    77,    27,
+      99,    37,    52,    81,    99,    37,    85,    31,    42,    91,
+      94,    42,     7,    50,    91
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1437,8 +1446,8 @@ yyreduce:
     ;}
     break;
 
-  case 9:
-#line 142 "sql.y"
+  case 10:
+#line 143 "sql.y"
     {
             SQL_input *sql = (SQL_input*) info;
             MSIVIEW *insert = NULL;
@@ -1450,8 +1459,8 @@ yyreduce:
         ;}
     break;
 
-  case 10:
-#line 152 "sql.y"
+  case 11:
+#line 153 "sql.y"
     {
             SQL_input *sql = (SQL_input*) info;
             MSIVIEW *insert = NULL;
@@ -1463,8 +1472,8 @@ yyreduce:
         ;}
     break;
 
-  case 11:
-#line 165 "sql.y"
+  case 12:
+#line 166 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *create = NULL;
@@ -1478,8 +1487,8 @@ yyreduce:
         ;}
     break;
 
-  case 12:
-#line 177 "sql.y"
+  case 13:
+#line 178 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *create = NULL;
@@ -1493,8 +1502,8 @@ yyreduce:
         ;}
     break;
 
-  case 13:
-#line 192 "sql.y"
+  case 14:
+#line 193 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *update = NULL;
@@ -1506,8 +1515,8 @@ yyreduce:
         ;}
     break;
 
-  case 14:
-#line 202 "sql.y"
+  case 15:
+#line 203 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *update = NULL;
@@ -1519,8 +1528,8 @@ yyreduce:
         ;}
     break;
 
-  case 15:
-#line 215 "sql.y"
+  case 16:
+#line 216 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *delete = NULL;
@@ -1532,8 +1541,8 @@ yyreduce:
         ;}
     break;
 
-  case 16:
-#line 228 "sql.y"
+  case 17:
+#line 229 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *alter = NULL;
@@ -1545,8 +1554,8 @@ yyreduce:
         ;}
     break;
 
-  case 17:
-#line 238 "sql.y"
+  case 18:
+#line 239 "sql.y"
     {
             SQL_input *sql = (SQL_input *)info;
             MSIVIEW *alter = NULL;
@@ -1558,8 +1567,8 @@ yyreduce:
         ;}
     break;
 
-  case 18:
-#line 248 "sql.y"
+  case 19:
+#line 249 "sql.y"
     {
             SQL_input *sql = (SQL_input *)info;
             MSIVIEW *alter = NULL;
@@ -1571,22 +1580,35 @@ yyreduce:
         ;}
     break;
 
-  case 19:
-#line 261 "sql.y"
+  case 20:
+#line 262 "sql.y"
     {
             (yyval.integer) = 1;
         ;}
     break;
 
-  case 20:
-#line 265 "sql.y"
+  case 21:
+#line 266 "sql.y"
     {
             (yyval.integer) = -1;
         ;}
     break;
 
-  case 21:
-#line 272 "sql.y"
+  case 22:
+#line 273 "sql.y"
+    {
+            SQL_input* sql = (SQL_input*) info;
+            UINT r;
+
+            (yyval.query) = NULL;
+            r = DROP_CreateView( sql->db, &(yyval.query), (yyvsp[0].string) );
+            if( r != ERROR_SUCCESS || !(yyval.query) )
+                YYABORT;
+        ;}
+    break;
+
+  case 23:
+#line 286 "sql.y"
     {
             if( SQL_MarkPrimaryKeys( (yyvsp[-3].column_list), (yyvsp[0].column_list) ) )
                 (yyval.column_list) = (yyvsp[-3].column_list);
@@ -1595,8 +1617,8 @@ yyreduce:
         ;}
     break;
 
-  case 22:
-#line 282 "sql.y"
+  case 24:
+#line 296 "sql.y"
     {
             column_info *ci;
 
@@ -1608,15 +1630,15 @@ yyreduce:
         ;}
     break;
 
-  case 23:
-#line 292 "sql.y"
+  case 25:
+#line 306 "sql.y"
     {
             (yyval.column_list) = (yyvsp[0].column_list);
         ;}
     break;
 
-  case 24:
-#line 299 "sql.y"
+  case 26:
+#line 313 "sql.y"
     {
             (yyval.column_list) = (yyvsp[-1].column_list);
             (yyval.column_list)->type = ((yyvsp[0].column_type) | MSITYPE_VALID);
@@ -1624,92 +1646,92 @@ yyreduce:
         ;}
     break;
 
-  case 25:
-#line 308 "sql.y"
+  case 27:
+#line 322 "sql.y"
     {
             (yyval.column_type) = (yyvsp[0].column_type);
         ;}
     break;
 
-  case 26:
-#line 312 "sql.y"
+  case 28:
+#line 326 "sql.y"
     {
             (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_LOCALIZABLE;
         ;}
     break;
 
-  case 27:
-#line 316 "sql.y"
+  case 29:
+#line 330 "sql.y"
     {
             (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_TEMPORARY;
         ;}
     break;
 
-  case 28:
-#line 323 "sql.y"
+  case 30:
+#line 337 "sql.y"
     {
             (yyval.column_type) |= MSITYPE_NULLABLE;
         ;}
     break;
 
-  case 29:
-#line 327 "sql.y"
+  case 31:
+#line 341 "sql.y"
     {
             (yyval.column_type) = (yyvsp[-2].column_type);
         ;}
     break;
 
-  case 30:
-#line 334 "sql.y"
+  case 32:
+#line 348 "sql.y"
     {
             (yyval.column_type) = MSITYPE_STRING | 1;
         ;}
     break;
 
-  case 31:
-#line 338 "sql.y"
+  case 33:
+#line 352 "sql.y"
     {
             (yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[-1].column_type);
         ;}
     break;
 
-  case 32:
-#line 342 "sql.y"
+  case 34:
+#line 356 "sql.y"
     {
             (yyval.column_type) = 2;
         ;}
     break;
 
-  case 33:
-#line 346 "sql.y"
+  case 35:
+#line 360 "sql.y"
     {
             (yyval.column_type) = 2;
         ;}
     break;
 
-  case 34:
-#line 350 "sql.y"
+  case 36:
+#line 364 "sql.y"
     {
             (yyval.column_type) = 2;
         ;}
     break;
 
-  case 35:
-#line 354 "sql.y"
+  case 37:
+#line 368 "sql.y"
     {
             (yyval.column_type) = 4;
         ;}
     break;
 
-  case 36:
-#line 358 "sql.y"
+  case 38:
+#line 372 "sql.y"
     {
             (yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID;
         ;}
     break;
 
-  case 37:
-#line 365 "sql.y"
+  case 39:
+#line 379 "sql.y"
     {
             if( ( (yyvsp[0].integer) > 255 ) || ( (yyvsp[0].integer) < 0 ) )
                 YYABORT;
@@ -1717,8 +1739,8 @@ yyreduce:
         ;}
     break;
 
-  case 38:
-#line 374 "sql.y"
+  case 40:
+#line 388 "sql.y"
     {
             UINT r;
 
@@ -1733,15 +1755,15 @@ yyreduce:
         ;}
     break;
 
-  case 40:
-#line 391 "sql.y"
+  case 42:
+#line 405 "sql.y"
     {
             (yyval.query) = (yyvsp[0].query);
         ;}
     break;
 
-  case 41:
-#line 395 "sql.y"
+  case 43:
+#line 409 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -1756,8 +1778,8 @@ yyreduce:
         ;}
     break;
 
-  case 42:
-#line 411 "sql.y"
+  case 44:
+#line 425 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -1777,22 +1799,22 @@ yyreduce:
         ;}
     break;
 
-  case 44:
-#line 433 "sql.y"
+  case 46:
+#line 447 "sql.y"
     {
             (yyvsp[-2].column_list)->next = (yyvsp[0].column_list);
         ;}
     break;
 
-  case 45:
-#line 437 "sql.y"
+  case 47:
+#line 451 "sql.y"
     {
             (yyval.column_list) = NULL;
         ;}
     break;
 
-  case 47:
-#line 445 "sql.y"
+  case 49:
+#line 459 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -1807,8 +1829,8 @@ yyreduce:
         ;}
     break;
 
-  case 48:
-#line 461 "sql.y"
+  case 50:
+#line 475 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -1820,8 +1842,8 @@ yyreduce:
         ;}
     break;
 
-  case 49:
-#line 471 "sql.y"
+  case 51:
+#line 485 "sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -1833,15 +1855,15 @@ yyreduce:
         ;}
     break;
 
-  case 50:
-#line 484 "sql.y"
+  case 52:
+#line 498 "sql.y"
     {
             (yyval.string) = strdupW((yyvsp[0].string));
         ;}
     break;
 
-  case 51:
-#line 489 "sql.y"
+  case 53:
+#line 503 "sql.y"
     {
             (yyval.string) = parser_add_table((yyvsp[0].string), (yyvsp[-2].string));
             if (!(yyval.string))
@@ -1849,8 +1871,8 @@ yyreduce:
         ;}
     break;
 
-  case 52:
-#line 498 "sql.y"
+  case 54:
+#line 512 "sql.y"
     {
             (yyval.expr) = (yyvsp[-1].expr);
             if( !(yyval.expr) )
@@ -1858,8 +1880,8 @@ yyreduce:
         ;}
     break;
 
-  case 53:
-#line 504 "sql.y"
+  case 55:
+#line 518 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_AND, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1867,8 +1889,8 @@ yyreduce:
         ;}
     break;
 
-  case 54:
-#line 510 "sql.y"
+  case 56:
+#line 524 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_OR, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1876,8 +1898,8 @@ yyreduce:
         ;}
     break;
 
-  case 55:
-#line 516 "sql.y"
+  case 57:
+#line 530 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1885,8 +1907,8 @@ yyreduce:
         ;}
     break;
 
-  case 56:
-#line 522 "sql.y"
+  case 58:
+#line 536 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1894,8 +1916,8 @@ yyreduce:
         ;}
     break;
 
-  case 57:
-#line 528 "sql.y"
+  case 59:
+#line 542 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1903,8 +1925,8 @@ yyreduce:
         ;}
     break;
 
-  case 58:
-#line 534 "sql.y"
+  case 60:
+#line 548 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1912,8 +1934,8 @@ yyreduce:
         ;}
     break;
 
-  case 59:
-#line 540 "sql.y"
+  case 61:
+#line 554 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1921,8 +1943,8 @@ yyreduce:
         ;}
     break;
 
-  case 60:
-#line 546 "sql.y"
+  case 62:
+#line 560 "sql.y"
     {
             (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) );
             if( !(yyval.expr) )
@@ -1930,8 +1952,8 @@ yyreduce:
         ;}
     break;
 
-  case 61:
-#line 552 "sql.y"
+  case 63:
+#line 566 "sql.y"
     {
             (yyval.expr) = EXPR_unary( info, (yyvsp[-2].expr), OP_ISNULL );
             if( !(yyval.expr) )
@@ -1939,8 +1961,8 @@ yyreduce:
         ;}
     break;
 
-  case 62:
-#line 558 "sql.y"
+  case 64:
+#line 572 "sql.y"
     {
             (yyval.expr) = EXPR_unary( info, (yyvsp[-3].expr), OP_NOTNULL );
             if( !(yyval.expr) )
@@ -1948,8 +1970,8 @@ yyreduce:
         ;}
     break;
 
-  case 65:
-#line 572 "sql.y"
+  case 67:
+#line 586 "sql.y"
     {
             (yyval.column_list) = parser_alloc_column( info, NULL, NULL );
             if( !(yyval.column_list) )
@@ -1958,8 +1980,8 @@ yyreduce:
         ;}
     break;
 
-  case 66:
-#line 579 "sql.y"
+  case 68:
+#line 593 "sql.y"
     {
             (yyval.column_list) = parser_alloc_column( info, NULL, NULL );
             if( !(yyval.column_list) )
@@ -1969,24 +1991,24 @@ yyreduce:
         ;}
     break;
 
-  case 68:
-#line 591 "sql.y"
+  case 70:
+#line 605 "sql.y"
     {
             (yyval.column_list) = (yyvsp[-2].column_list);
             (yyval.column_list)->next = (yyvsp[0].column_list);
         ;}
     break;
 
-  case 69:
-#line 599 "sql.y"
+  case 71:
+#line 613 "sql.y"
     {
             (yyval.column_list) = (yyvsp[-2].column_list);
             (yyval.column_list)->val = (yyvsp[0].expr);
         ;}
     break;
 
-  case 70:
-#line 607 "sql.y"
+  case 72:
+#line 621 "sql.y"
     {
             (yyval.expr) = EXPR_ival( info, (yyvsp[0].integer) );
             if( !(yyval.expr) )
@@ -1994,8 +2016,8 @@ yyreduce:
         ;}
     break;
 
-  case 71:
-#line 613 "sql.y"
+  case 73:
+#line 627 "sql.y"
     {
             (yyval.expr) = EXPR_ival( info, -(yyvsp[0].integer) );
             if( !(yyval.expr) )
@@ -2003,8 +2025,8 @@ yyreduce:
         ;}
     break;
 
-  case 72:
-#line 619 "sql.y"
+  case 74:
+#line 633 "sql.y"
     {
             (yyval.expr) = EXPR_sval( info, &(yyvsp[0].str) );
             if( !(yyval.expr) )
@@ -2012,8 +2034,8 @@ yyreduce:
         ;}
     break;
 
-  case 73:
-#line 625 "sql.y"
+  case 75:
+#line 639 "sql.y"
     {
             (yyval.expr) = EXPR_wildcard( info );
             if( !(yyval.expr) )
@@ -2021,8 +2043,8 @@ yyreduce:
         ;}
     break;
 
-  case 74:
-#line 634 "sql.y"
+  case 76:
+#line 648 "sql.y"
     {
             (yyval.expr) = EXPR_column( info, (yyvsp[0].column_list) );
             if( !(yyval.expr) )
@@ -2030,8 +2052,8 @@ yyreduce:
         ;}
     break;
 
-  case 75:
-#line 643 "sql.y"
+  case 77:
+#line 657 "sql.y"
     {
             (yyval.column_list) = parser_alloc_column( info, (yyvsp[-2].string), (yyvsp[0].string) );
             if( !(yyval.column_list) )
@@ -2039,8 +2061,8 @@ yyreduce:
         ;}
     break;
 
-  case 76:
-#line 649 "sql.y"
+  case 78:
+#line 663 "sql.y"
     {
             (yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[0].string) );
             if( !(yyval.column_list) )
@@ -2048,15 +2070,15 @@ yyreduce:
         ;}
     break;
 
-  case 77:
-#line 658 "sql.y"
+  case 79:
+#line 672 "sql.y"
     {
             (yyval.string) = (yyvsp[0].string);
         ;}
     break;
 
-  case 78:
-#line 665 "sql.y"
+  case 80:
+#line 679 "sql.y"
     {
             (yyval.string) = SQL_getstring( info, &(yyvsp[0].str) );
             if( !(yyval.string) )
@@ -2064,8 +2086,8 @@ yyreduce:
         ;}
     break;
 
-  case 79:
-#line 674 "sql.y"
+  case 81:
+#line 688 "sql.y"
     {
             (yyval.integer) = SQL_getint( info );
         ;}
@@ -2076,7 +2098,7 @@ yyreduce:
     }
 
 /* Line 1126 of yacc.c.  */
-#line 2080 "sql.tab.c"
+#line 2102 "sql.tab.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -2344,7 +2366,7 @@ yyreturn:
 }
 
 
-#line 679 "sql.y"
+#line 693 "sql.y"
 
 
 static LPWSTR parser_add_table(LPWSTR list, LPWSTR table)
index 91cb27b..16b14eb 100644 (file)
      TK_COMMA = 262,
      TK_CREATE = 263,
      TK_DELETE = 264,
-     TK_DISTINCT = 265,
-     TK_DOT = 266,
-     TK_EQ = 267,
-     TK_FREE = 268,
-     TK_FROM = 269,
-     TK_GE = 270,
-     TK_GT = 271,
-     TK_HOLD = 272,
-     TK_ADD = 273,
-     TK_ID = 274,
-     TK_ILLEGAL = 275,
-     TK_INSERT = 276,
-     TK_INT = 277,
-     TK_INTEGER = 278,
-     TK_INTO = 279,
-     TK_IS = 280,
-     TK_KEY = 281,
-     TK_LE = 282,
-     TK_LONG = 283,
-     TK_LONGCHAR = 284,
-     TK_LP = 285,
-     TK_LT = 286,
-     TK_LOCALIZABLE = 287,
-     TK_MINUS = 288,
-     TK_NE = 289,
-     TK_NOT = 290,
-     TK_NULL = 291,
-     TK_OBJECT = 292,
-     TK_OR = 293,
-     TK_ORDER = 294,
-     TK_PRIMARY = 295,
-     TK_RP = 296,
-     TK_SELECT = 297,
-     TK_SET = 298,
-     TK_SHORT = 299,
-     TK_SPACE = 300,
-     TK_STAR = 301,
-     TK_STRING = 302,
-     TK_TABLE = 303,
-     TK_TEMPORARY = 304,
-     TK_UPDATE = 305,
-     TK_VALUES = 306,
-     TK_WHERE = 307,
-     TK_WILDCARD = 308,
-     COLUMN = 310,
-     FUNCTION = 311,
-     COMMENT = 312,
-     UNCLOSED_STRING = 313,
-     SPACE = 314,
-     ILLEGAL = 315,
-     END_OF_FILE = 316,
-     TK_LIKE = 317,
-     TK_NEGATION = 318
+     TK_DROP = 265,
+     TK_DISTINCT = 266,
+     TK_DOT = 267,
+     TK_EQ = 268,
+     TK_FREE = 269,
+     TK_FROM = 270,
+     TK_GE = 271,
+     TK_GT = 272,
+     TK_HOLD = 273,
+     TK_ADD = 274,
+     TK_ID = 275,
+     TK_ILLEGAL = 276,
+     TK_INSERT = 277,
+     TK_INT = 278,
+     TK_INTEGER = 279,
+     TK_INTO = 280,
+     TK_IS = 281,
+     TK_KEY = 282,
+     TK_LE = 283,
+     TK_LONG = 284,
+     TK_LONGCHAR = 285,
+     TK_LP = 286,
+     TK_LT = 287,
+     TK_LOCALIZABLE = 288,
+     TK_MINUS = 289,
+     TK_NE = 290,
+     TK_NOT = 291,
+     TK_NULL = 292,
+     TK_OBJECT = 293,
+     TK_OR = 294,
+     TK_ORDER = 295,
+     TK_PRIMARY = 296,
+     TK_RP = 297,
+     TK_SELECT = 298,
+     TK_SET = 299,
+     TK_SHORT = 300,
+     TK_SPACE = 301,
+     TK_STAR = 302,
+     TK_STRING = 303,
+     TK_TABLE = 304,
+     TK_TEMPORARY = 305,
+     TK_UPDATE = 306,
+     TK_VALUES = 307,
+     TK_WHERE = 308,
+     TK_WILDCARD = 309,
+     COLUMN = 311,
+     FUNCTION = 312,
+     COMMENT = 313,
+     UNCLOSED_STRING = 314,
+     SPACE = 315,
+     ILLEGAL = 316,
+     END_OF_FILE = 317,
+     TK_LIKE = 318,
+     TK_NEGATION = 319
    };
 #endif
 /* Tokens.  */
 #define TK_COMMA 262
 #define TK_CREATE 263
 #define TK_DELETE 264
-#define TK_DISTINCT 265
-#define TK_DOT 266
-#define TK_EQ 267
-#define TK_FREE 268
-#define TK_FROM 269
-#define TK_GE 270
-#define TK_GT 271
-#define TK_HOLD 272
-#define TK_ADD 273
-#define TK_ID 274
-#define TK_ILLEGAL 275
-#define TK_INSERT 276
-#define TK_INT 277
-#define TK_INTEGER 278
-#define TK_INTO 279
-#define TK_IS 280
-#define TK_KEY 281
-#define TK_LE 282
-#define TK_LONG 283
-#define TK_LONGCHAR 284
-#define TK_LP 285
-#define TK_LT 286
-#define TK_LOCALIZABLE 287
-#define TK_MINUS 288
-#define TK_NE 289
-#define TK_NOT 290
-#define TK_NULL 291
-#define TK_OBJECT 292
-#define TK_OR 293
-#define TK_ORDER 294
-#define TK_PRIMARY 295
-#define TK_RP 296
-#define TK_SELECT 297
-#define TK_SET 298
-#define TK_SHORT 299
-#define TK_SPACE 300
-#define TK_STAR 301
-#define TK_STRING 302
-#define TK_TABLE 303
-#define TK_TEMPORARY 304
-#define TK_UPDATE 305
-#define TK_VALUES 306
-#define TK_WHERE 307
-#define TK_WILDCARD 308
-#define COLUMN 310
-#define FUNCTION 311
-#define COMMENT 312
-#define UNCLOSED_STRING 313
-#define SPACE 314
-#define ILLEGAL 315
-#define END_OF_FILE 316
-#define TK_LIKE 317
-#define TK_NEGATION 318
+#define TK_DROP 265
+#define TK_DISTINCT 266
+#define TK_DOT 267
+#define TK_EQ 268
+#define TK_FREE 269
+#define TK_FROM 270
+#define TK_GE 271
+#define TK_GT 272
+#define TK_HOLD 273
+#define TK_ADD 274
+#define TK_ID 275
+#define TK_ILLEGAL 276
+#define TK_INSERT 277
+#define TK_INT 278
+#define TK_INTEGER 279
+#define TK_INTO 280
+#define TK_IS 281
+#define TK_KEY 282
+#define TK_LE 283
+#define TK_LONG 284
+#define TK_LONGCHAR 285
+#define TK_LP 286
+#define TK_LT 287
+#define TK_LOCALIZABLE 288
+#define TK_MINUS 289
+#define TK_NE 290
+#define TK_NOT 291
+#define TK_NULL 292
+#define TK_OBJECT 293
+#define TK_OR 294
+#define TK_ORDER 295
+#define TK_PRIMARY 296
+#define TK_RP 297
+#define TK_SELECT 298
+#define TK_SET 299
+#define TK_SHORT 300
+#define TK_SPACE 301
+#define TK_STAR 302
+#define TK_STRING 303
+#define TK_TABLE 304
+#define TK_TEMPORARY 305
+#define TK_UPDATE 306
+#define TK_VALUES 307
+#define TK_WHERE 308
+#define TK_WILDCARD 309
+#define COLUMN 311
+#define FUNCTION 312
+#define COMMENT 313
+#define UNCLOSED_STRING 314
+#define SPACE 315
+#define ILLEGAL 316
+#define END_OF_FILE 317
+#define TK_LIKE 318
+#define TK_NEGATION 319
 
 
 
@@ -168,7 +170,7 @@ typedef union YYSTYPE {
     int integer;
 } YYSTYPE;
 /* Line 1447 of yacc.c.  */
-#line 172 "sql.tab.h"
+#line 174 "sql.tab.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
index e610383..7deae21 100644 (file)
@@ -81,7 +81,7 @@ static struct expr * EXPR_wildcard( void *info );
     int integer;
 }
 
-%token TK_ALTER TK_AND TK_BY TK_CHAR TK_COMMA TK_CREATE TK_DELETE
+%token TK_ALTER TK_AND TK_BY TK_CHAR TK_COMMA TK_CREATE TK_DELETE TK_DROP
 %token TK_DISTINCT TK_DOT TK_EQ TK_FREE TK_FROM TK_GE TK_GT TK_HOLD TK_ADD
 %token <str> TK_ID
 %token TK_ILLEGAL TK_INSERT TK_INT
@@ -106,7 +106,7 @@ static struct expr * EXPR_wildcard( void *info );
 %type <column_list> selcollist column column_and_type column_def table_def
 %type <column_list> column_assignment update_assign_list constlist
 %type <query> query from fromtable selectfrom unorderedsel
-%type <query> oneupdate onedelete oneselect onequery onecreate oneinsert onealter
+%type <query> oneupdate onedelete oneselect onequery onecreate oneinsert onealter onedrop
 %type <expr> expr val column_val const_val
 %type <column_type> column_type data_type data_type_l data_count
 %type <integer> number alterop
@@ -135,6 +135,7 @@ onequery:
   | oneupdate
   | onedelete
   | onealter
+  | onedrop
     ;
 
 oneinsert:
@@ -267,6 +268,19 @@ alterop:
         }
   ;
 
+onedrop:
+    TK_DROP TK_TABLE table
+        {
+            SQL_input* sql = (SQL_input*) info;
+            UINT r;
+
+            $$ = NULL;
+            r = DROP_CreateView( sql->db, &$$, $3 );
+            if( r != ERROR_SUCCESS || !$$ )
+                YYABORT;
+        }
+  ;
+
 table_def:
     column_def TK_PRIMARY TK_KEY selcollist
         {
index 7b20dd9..2e21cb8 100644 (file)
@@ -184,7 +184,7 @@ done:
 static UINT STORAGES_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
 {
     MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view;
-    IStorage *stg, *substg;
+    IStorage *stg, *substg = NULL;
     IStream *stm;
     LPWSTR name = NULL;
     HRESULT hr;
@@ -236,7 +236,7 @@ static UINT STORAGES_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec,
 done:
     msi_free(name);
 
-    IStorage_Release(substg);
+    if (substg) IStorage_Release(substg);
     IStorage_Release(stg);
     IStream_Release(stm);
 
@@ -474,6 +474,7 @@ static const MSIVIEWOPS storages_ops =
     NULL,
     NULL,
     NULL,
+    NULL,
 };
 
 static INT add_storages_to_table(MSISTORAGESVIEW *sv)
index 318fb41..e263105 100644 (file)
@@ -438,6 +438,7 @@ static const MSIVIEWOPS streams_ops =
     NULL,
     NULL,
     NULL,
+    NULL,
 };
 
 static INT add_streams_to_table(MSISTREAMSVIEW *sv)
@@ -464,6 +465,9 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
         if (FAILED(hr) || !size)
             break;
 
+        if (stat.type != STGTY_STREAM)
+            continue;
+
         /* table streams are not in the _Streams table */
         if (*stat.pwcsName == 0x4840)
         {
index 5d73c57..148ba8a 100644 (file)
@@ -169,8 +169,7 @@ static UINT propvar_changetype(PROPVARIANT *changed, PROPVARIANT *property, VART
 static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz )
 {
     UINT type;
-    DWORD i;
-    int size;
+    DWORD i, size;
     PROPERTY_DATA *propdata;
     PROPVARIANT property, *ptr;
     PROPVARIANT changed;
index 13c61d4..f54f6b2 100644 (file)
@@ -101,43 +101,33 @@ static WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
 static WCHAR szNumber[]  = { 'N','u','m','b','e','r',0 };
 static WCHAR szType[]    = { 'T','y','p','e',0 };
 
-/* These tables are written into (the .hash_table part).
- * Do not mark them const.
- */
-static MSICOLUMNINFO _Columns_cols[4] = {
+static const MSICOLUMNINFO _Columns_cols[4] = {
     { szColumns, 1, szTable,  MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, 0, NULL },
     { szColumns, 2, szNumber, MSITYPE_VALID | MSITYPE_KEY | 2,     2, 0, NULL },
     { szColumns, 3, szName,   MSITYPE_VALID | MSITYPE_STRING | 64, 4, 0, NULL },
     { szColumns, 4, szType,   MSITYPE_VALID | 2,                   6, 0, NULL },
 };
-static MSICOLUMNINFO _Tables_cols[1] = {
-    { szTables,  1, szName,   MSITYPE_VALID | MSITYPE_STRING | 64, 0, 0, NULL },
+
+static const MSICOLUMNINFO _Tables_cols[1] = {
+    { szTables,  1, szName,   MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, 0, NULL },
 };
 
 #define MAX_STREAM_NAME 0x1f
 
 static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name,
        MSICOLUMNINFO **pcols, UINT *pcount );
-static void table_calc_column_offsets( MSICOLUMNINFO *colinfo, DWORD count );
+static void table_calc_column_offsets( MSIDATABASE *db, MSICOLUMNINFO *colinfo,
+       DWORD count );
 static UINT get_tablecolumns( MSIDATABASE *db,
        LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz);
 static void msi_free_colinfo( MSICOLUMNINFO *colinfo, UINT count );
 
-
-void msi_table_set_strref(UINT bytes_per_strref)
-{
-    _Columns_cols[0].offset = 0;
-    _Columns_cols[1].offset = bytes_per_strref;
-    _Columns_cols[2].offset = _Columns_cols[1].offset + sizeof(USHORT);
-    _Columns_cols[3].offset = _Columns_cols[2].offset + bytes_per_strref;
-}
-
-static inline UINT bytes_per_column( const MSICOLUMNINFO *col )
+static inline UINT bytes_per_column( MSIDATABASE *db, const MSICOLUMNINFO *col )
 {
     if( MSITYPE_IS_BINARY(col->type) )
         return 2;
     if( col->type & MSITYPE_STRING )
-        return _Columns_cols[1].offset;
+        return db->bytes_per_strref;
     if( (col->type & 0xff) > 4 )
         ERR("Invalid column size!\n");
     return col->type & 0xff;
@@ -488,32 +478,29 @@ static void free_table( MSITABLE *table )
     for( i=0; i<table->nonpersistent_row_count; i++ )
         msi_free( table->nonpersistent_data[i] );
     msi_free( table->nonpersistent_data );
-    if( (table->colinfo != _Tables_cols) &&
-        (table->colinfo != _Columns_cols) )
-    {
-        msi_free_colinfo( table->colinfo, table->col_count );
-        msi_free( table->colinfo );
-    }
+    msi_free_colinfo( table->colinfo, table->col_count );
+    msi_free( table->colinfo );
     msi_free( table );
 }
 
-static UINT msi_table_get_row_size( const MSICOLUMNINFO *cols, UINT count )
+static UINT msi_table_get_row_size( MSIDATABASE *db,const MSICOLUMNINFO *cols,
+                                    UINT count )
 {
     const MSICOLUMNINFO *last_col = &cols[count-1];
     if (!count)
         return 0;
-    return last_col->offset + bytes_per_column( last_col );
+    return last_col->offset + bytes_per_column( db, last_col );
 }
 
 /* add this table to the list of cached tables in the database */
-static UINT read_table_from_storage( MSITABLE *t, IStorage *stg )
+static UINT read_table_from_storage( MSIDATABASE *db, MSITABLE *t, IStorage *stg )
 {
     BYTE *rawdata = NULL;
     UINT rawsize = 0, i, j, row_size = 0;
 
     TRACE("%s\n",debugstr_w(t->name));
 
-    row_size = msi_table_get_row_size( t->colinfo, t->col_count );
+    row_size = msi_table_get_row_size( db, t->colinfo, t->col_count );
 
     /* if we can't read the table, just assume that it's empty */
     read_stream_data( stg, t->name, TRUE, &rawdata, &rawsize );
@@ -544,7 +531,7 @@ static UINT read_table_from_storage( MSITABLE *t, IStorage *stg )
         for( j=0; j<t->col_count; j++ )
         {
             UINT ofs = t->colinfo[j].offset;
-            UINT n = bytes_per_column( &t->colinfo[j] );
+            UINT n = bytes_per_column( db, &t->colinfo[j] );
             UINT k;
 
             if ( n != 2 && n != 3 && n != 4 )
@@ -598,6 +585,8 @@ static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO
     if( r != ERROR_SUCCESS )
         return r;
 
+    *pcount = column_count;
+
     /* if there's no columns, there's no table */
     if( column_count == 0 )
         return ERROR_INVALID_PARAMETER;
@@ -616,7 +605,6 @@ static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO
     }
 
     *pcols = columns;
-    *pcount = column_count;
 
     return r;
 }
@@ -672,7 +660,7 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info,
         table->colinfo[ i ].ref_count = 0;
         table->colinfo[ i ].hash_table = NULL;
     }
-    table_calc_column_offsets( table->colinfo, table->col_count);
+    table_calc_column_offsets( db, table->colinfo, table->col_count);
 
     r = TABLE_CreateView( db, szTables, &tv );
     TRACE("CreateView returned %x\n", r);
@@ -800,28 +788,14 @@ static UINT get_table( MSIDATABASE *db, LPCWSTR name, MSITABLE **table_ret )
     table->persistent = TRUE;
     lstrcpyW( table->name, name );
 
-    /* these two tables are special - we know the column types already */
-    if( !lstrcmpW( name, szColumns ) )
-    {
-        table->colinfo = _Columns_cols;
-        table->col_count = sizeof(_Columns_cols)/sizeof(_Columns_cols[0]);
-    }
-    else if( !lstrcmpW( name, szTables ) )
-    {
-        table->colinfo = _Tables_cols;
-        table->col_count = sizeof(_Tables_cols)/sizeof(_Tables_cols[0]);
-    }
-    else
+    r = table_get_column_info( db, name, &table->colinfo, &table->col_count);
+    if (r != ERROR_SUCCESS)
     {
-        r = table_get_column_info( db, name, &table->colinfo, &table->col_count);
-        if (r != ERROR_SUCCESS)
-        {
-            free_table ( table );
-            return r;
-        }
+        free_table ( table );
+        return r;
     }
 
-    r = read_table_from_storage( table, db->storage );
+    r = read_table_from_storage( db, table, db->storage );
     if( r != ERROR_SUCCESS )
     {
         free_table( table );
@@ -844,7 +818,7 @@ static UINT save_table( MSIDATABASE *db, const MSITABLE *t )
 
     TRACE("Saving %s\n", debugstr_w( t->name ) );
 
-    row_size = msi_table_get_row_size( t->colinfo, t->col_count );
+    row_size = msi_table_get_row_size( db, t->colinfo, t->col_count );
 
     rawsize = t->row_count * row_size;
     rawdata = msi_alloc_zero( rawsize );
@@ -863,7 +837,7 @@ static UINT save_table( MSIDATABASE *db, const MSITABLE *t )
 
             *p++ = t->data[j][offset];
             *p++ = t->data[j][offset + 1];
-            if( 4 == bytes_per_column( &t->colinfo[i] ) )
+            if( 4 == bytes_per_column( db, &t->colinfo[i] ) )
             {
                 *p++ = t->data[j][offset + 2];
                 *p++ = t->data[j][offset + 3];
@@ -880,7 +854,8 @@ err:
     return r;
 }
 
-static void table_calc_column_offsets( MSICOLUMNINFO *colinfo, DWORD count )
+static void table_calc_column_offsets( MSIDATABASE *db, MSICOLUMNINFO *colinfo,
+                                       DWORD count )
 {
     DWORD i;
 
@@ -889,7 +864,7 @@ static void table_calc_column_offsets( MSICOLUMNINFO *colinfo, DWORD count )
          assert( (i+1) == colinfo[ i ].number );
          if (i)
              colinfo[i].offset = colinfo[ i - 1 ].offset
-                               + bytes_per_column( &colinfo[ i - 1 ] );
+                               + bytes_per_column( db, &colinfo[ i - 1 ] );
          else
              colinfo[i].offset = 0;
          TRACE("column %d is [%s] with type %08x ofs %d\n",
@@ -898,7 +873,8 @@ static void table_calc_column_offsets( MSICOLUMNINFO *colinfo, DWORD count )
     }
 }
 
-static UINT get_defaulttablecolumns( LPCWSTR name, MSICOLUMNINFO *colinfo, UINT *sz)
+static UINT get_defaulttablecolumns( MSIDATABASE *db, LPCWSTR name,
+                                     MSICOLUMNINFO *colinfo, UINT *sz)
 {
     const MSICOLUMNINFO *p;
     DWORD i, n;
@@ -930,7 +906,7 @@ static UINT get_defaulttablecolumns( LPCWSTR name, MSICOLUMNINFO *colinfo, UINT
         if( colinfo && (i >= *sz) )
             break;
     }
-    table_calc_column_offsets( colinfo, n );
+    table_calc_column_offsets( db, colinfo, n );
     *sz = n;
     return ERROR_SUCCESS;
 }
@@ -971,7 +947,7 @@ static UINT get_tablecolumns( MSIDATABASE *db,
     TRACE("%s\n", debugstr_w(szTableName));
 
     /* first check if there is a default table with that name */
-    r = get_defaulttablecolumns( szTableName, colinfo, sz );
+    r = get_defaulttablecolumns( db, szTableName, colinfo, sz );
     if( ( r == ERROR_SUCCESS ) && *sz )
         return r;
 
@@ -1003,8 +979,8 @@ static UINT get_tablecolumns( MSIDATABASE *db,
             continue;
         if( colinfo )
         {
-            UINT id = read_table_int(table->data, i, _Columns_cols[2].offset, db->bytes_per_strref);
-            UINT col = read_table_int(table->data, i, _Columns_cols[1].offset, sizeof(USHORT)) - (1<<15);
+            UINT id = read_table_int(table->data, i, table->colinfo[2].offset, db->bytes_per_strref);
+            UINT col = read_table_int(table->data, i, table->colinfo[1].offset, sizeof(USHORT)) - (1<<15);
 
             /* check the column number is in range */
             if (col<1 || col>maxcount)
@@ -1023,7 +999,9 @@ static UINT get_tablecolumns( MSIDATABASE *db,
             colinfo[ col - 1 ].tablename = msi_makestring( db, table_id );
             colinfo[ col - 1 ].number = col;
             colinfo[ col - 1 ].colname = msi_makestring( db, id );
-            colinfo[ col - 1 ].type = read_table_int(table->data, i, _Columns_cols[3].offset, sizeof(USHORT)) - (1<<15);
+            colinfo[ col - 1 ].type = read_table_int(table->data, i,
+                                                     table->colinfo[3].offset,
+                                                     sizeof(USHORT)) - (1<<15);
             colinfo[ col - 1 ].offset = 0;
             colinfo[ col - 1 ].ref_count = 0;
             colinfo[ col - 1 ].hash_table = NULL;
@@ -1040,7 +1018,7 @@ static UINT get_tablecolumns( MSIDATABASE *db,
         return ERROR_FUNCTION_FAILED;
     }
 
-    table_calc_column_offsets( colinfo, n );
+    table_calc_column_offsets( db, colinfo, n );
     *sz = n;
 
     return ERROR_SUCCESS;
@@ -1057,7 +1035,10 @@ static void msi_update_table_columns( MSIDATABASE *db, LPCWSTR name )
     msi_free( table->colinfo );
     table_get_column_info( db, name, &table->colinfo, &table->col_count );
 
-    size = msi_table_get_row_size( table->colinfo, table->col_count );
+    if (!table->col_count)
+        return;
+
+    size = msi_table_get_row_size( db, table->colinfo, table->col_count );
     offset = table->colinfo[table->col_count - 1].offset;
 
     for ( n = 0; n < table->row_count; n++ )
@@ -1096,20 +1077,12 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name )
     count = table->row_count;
     for( i=0; i<count; i++ )
         if( table->data[ i ][ 0 ] == table_id )
-            break;
-
-    if (i!=count)
-        return TRUE;
+            return TRUE;
 
     count = table->nonpersistent_row_count;
     for( i=0; i<count; i++ )
         if( table->nonpersistent_data[ i ][ 0 ] == table_id )
-            break;
-
-    if (i!=count)
-        return TRUE;
-
-    TRACE("Searched %d tables, but %d was not found\n", count, table_id );
+            return TRUE;
 
     return FALSE;
 }
@@ -1162,7 +1135,7 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
     else
         data = tv->table->data;
 
-    n = bytes_per_column( &tv->columns[col-1] );
+    n = bytes_per_column( tv->db, &tv->columns[col-1] );
     if (n != 2 && n != 3 && n != 4)
     {
         ERR("oops! what is %d bytes per column?\n", n );
@@ -1277,7 +1250,7 @@ static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val )
     else
         data = tv->table->data;
 
-    n = bytes_per_column( &tv->columns[col-1] );
+    n = bytes_per_column( tv->db, &tv->columns[col-1] );
     if ( n != 2 && n != 3 && n != 4 )
     {
         ERR("oops! what is %d bytes per column?\n", n );
@@ -1351,7 +1324,7 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI
                 val = msi_addstringW( tv->db->strings, 0, sval, -1, 1,
                                       persistent ? StringPersistent : StringNonPersistent );
             }
-            else if ( 2 == bytes_per_column( &tv->columns[ i ] ) )
+            else if ( 2 == bytes_per_column( tv->db, &tv->columns[ i ] ) )
             {
                 val = 0x8000 + MSI_RecordGetInteger( rec, i + 1 );
                 if ( val & 0xffff0000 )
@@ -2081,6 +2054,53 @@ static UINT TABLE_sort(struct tagMSIVIEW *view, column_info *columns)
     return ERROR_SUCCESS;
 }
 
+static UINT TABLE_drop(struct tagMSIVIEW *view)
+{
+    MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
+    MSIVIEW *tables = NULL;
+    MSIRECORD *rec = NULL;
+    UINT r, row;
+    INT i;
+
+    TRACE("dropping table %s\n", debugstr_w(tv->name));
+
+    for (i = tv->table->col_count - 1; i >= 0; i--)
+    {
+        r = TABLE_remove_column(view, tv->table->colinfo[i].tablename,
+                                tv->table->colinfo[i].number);
+        if (r != ERROR_SUCCESS)
+            return r;
+    }
+
+    rec = MSI_CreateRecord(1);
+    if (!rec)
+        return ERROR_OUTOFMEMORY;
+
+    MSI_RecordSetStringW(rec, 1, tv->name);
+
+    r = TABLE_CreateView(tv->db, szTables, &tables);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = msi_table_find_row((MSITABLEVIEW *)tables, rec, &row);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = TABLE_delete_row(tables, row);
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    list_remove(&tv->table->entry);
+    free_table(tv->table);
+    TABLE_delete(view);
+
+done:
+    msiobj_release(&rec->hdr);
+    tables->ops->delete(tables);
+
+    return r;
+}
+
 static const MSIVIEWOPS table_ops =
 {
     TABLE_fetch_int,
@@ -2101,6 +2121,7 @@ static const MSIVIEWOPS table_ops =
     TABLE_add_column,
     TABLE_remove_column,
     TABLE_sort,
+    TABLE_drop,
 };
 
 UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view )
@@ -2138,7 +2159,7 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view )
     tv->db = db;
     tv->columns = tv->table->colinfo;
     tv->num_cols = tv->table->col_count;
-    tv->row_size = msi_table_get_row_size( tv->table->colinfo, tv->table->col_count );
+    tv->row_size = msi_table_get_row_size( db, tv->table->colinfo, tv->table->col_count );
 
     TRACE("%s one row is %d bytes\n", debugstr_w(name), tv->row_size );
 
@@ -2246,7 +2267,7 @@ static MSIRECORD *msi_get_transform_record( const MSITABLEVIEW *tv, const string
         }
         else
         {
-            UINT n = bytes_per_column( &columns[i] );
+            UINT n = bytes_per_column( tv->db, &columns[i] );
             switch( n )
             {
             case 2:
@@ -2457,7 +2478,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
                     ! MSITYPE_IS_BINARY(tv->columns[i].type) )
                     sz += bytes_per_strref;
                 else
-                    sz += bytes_per_column( &tv->columns[i] );
+                    sz += bytes_per_column( tv->db, &tv->columns[i] );
             }
         }
         else
@@ -2479,7 +2500,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
                         ! MSITYPE_IS_BINARY(tv->columns[i].type) )
                         sz += bytes_per_strref;
                     else
-                        sz += bytes_per_column( &tv->columns[i] );
+                        sz += bytes_per_column( tv->db, &tv->columns[i] );
                 }
             }
         }
index 92a1067..aec6f27 100644 (file)
@@ -47,6 +47,7 @@ static const WCHAR CHARACTER_W[] = { 'C','H','A','R','A','C','T','E','R',0 };
 static const WCHAR CREATE_W[] = { 'C','R','E','A','T','E',0 };
 static const WCHAR DELETE_W[] = { 'D','E','L','E','T','E',0 };
 static const WCHAR DISTINCT_W[] = { 'D','I','S','T','I','N','C','T',0 };
+static const WCHAR DROP_W[] = { 'D','R','O','P',0 };
 static const WCHAR FREE_W[] = { 'F','R','E','E',0 };
 static const WCHAR FROM_W[] = { 'F','R','O','M',0 };
 static const WCHAR HOLD_W[] = { 'H','O','L','D',0 };
@@ -89,6 +90,7 @@ static const Keyword aKeywordTable[] = {
   { CREATE_W, TK_CREATE },
   { DELETE_W, TK_DELETE },
   { DISTINCT_W, TK_DISTINCT },
+  { DROP_W, TK_DROP },
   { FREE_W, TK_FREE },
   { FROM_W, TK_FROM },
   { HOLD_W, TK_HOLD },
index 44d30c6..d0c466b 100644 (file)
@@ -222,6 +222,7 @@ static const MSIVIEWOPS update_ops =
     NULL,
     NULL,
     NULL,
+    NULL,
 };
 
 UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR table,
index da95499..d86f973 100644 (file)
@@ -136,15 +136,16 @@ static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param)
             HKEY hukey;
             INT r;
 
-            unsquash_guid(product,productid);
-            rc = MSIREG_OpenUserProductsKey(productid, &hukey, FALSE);
+            unsquash_guid(product, productid);
+            rc = MSIREG_OpenProductKey(productid, package->Context,
+                                       &hukey, FALSE);
             if (rc != ERROR_SUCCESS)
             {
                 rc = ERROR_SUCCESS;
                 index ++;
                 continue;
             }
-          
+
             sz = sizeof(DWORD);
             RegQueryValueExW(hukey, INSTALLPROPERTY_VERSIONW, NULL, NULL,
                     (LPBYTE)&check, &sz);
index 8883496..65f1be9 100644 (file)
@@ -180,7 +180,7 @@ static UINT WHERE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
     if (r != ERROR_SUCCESS)
         return r;
 
-    return wv->table->ops->get_row(view, row, rec);
+    return wv->table->ops->get_row(wv->table, row, rec);
 }
 
 static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
@@ -585,6 +585,7 @@ static const MSIVIEWOPS where_ops =
     NULL,
     NULL,
     WHERE_sort,
+    NULL,
 };
 
 static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr *cond,
index b5a9715..318fd8f 100644 (file)
@@ -28,43 +28,43 @@ END
 
 IDD_TCPIP_ALTCF_DLG DIALOGEX DISCARDABLE  0, 0, 246, 228
 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION
-CAPTION "Alternate Configuration"
+CAPTION "Çàìåñòâàùà íàñòðîéêà"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    LTEXT "If this computer is used on more than one network, enter the alternate IP settings below", -1, 9, 9, 220, 20
-    CONTROL "Au&tomatic private IP address", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 40, 210, 12
+    LTEXT "Àêî êîìïþòúðúò ñå èçïîëçâà â ïîâå÷å îò åäíà ìðåæà, âúâåäåòå çàìåñòâàùè IP íàñòðîéêè îòäîëó", -1, 9, 9, 220, 20
+    CONTROL "&Àâòîìàòè÷íè ëè÷íè IP àäðåñè", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 40, 210, 12
     GROUPBOX "", -1, 9, 55, 228, 80, BS_GROUPBOX
-    CONTROL "U&ser configured", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 55, 70, 12
-    LTEXT "&IP address:", -1, 14, 75, 135, 8
+    CONTROL "Íà&ñòðîåíî îò ïîòðåáèòåëÿ", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 55, 70, 12
+    LTEXT "Àäðåñ çà IP:", -1, 14, 75, 135, 8
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 150, 75, 80, 12
-    LTEXT "S&ubnet mask:", -1, 14, 95, 135, 8
+    LTEXT "Ïîä&ìðåæîâà ìàñêà:", -1, 14, 95, 135, 8
     CONTROL "",IDC_SUBNETMASK,"SysIPAddress32",WS_TABSTOP, 150, 95, 80, 12    
-    LTEXT "&Default gateway:", -1, 14, 115, 135, 8
+    LTEXT "&Ïîäðàçáèðàí ðàçïðåäåëèòåë:", -1, 14, 115, 135, 8
     CONTROL "",IDC_DEFGATEWAY,"SysIPAddress32",WS_TABSTOP, 150, 115, 80, 12
-    LTEXT "&Preferred DNS server:", -1, 14, 150, 135, 8
+    LTEXT "Ïðå&äïî÷èòàí DNS:", -1, 14, 150, 135, 8
     CONTROL "",IDC_DNS1,"SysIPAddress32",WS_TABSTOP, 150, 150, 80, 12
-    LTEXT "&Alternate DNS server:", -1, 14, 165, 180, 8
+    LTEXT "Çà&ìåñòâàù DNS:", -1, 14, 165, 180, 8
     CONTROL "",IDC_DNS2,"SysIPAddress32",WS_TABSTOP, 150, 165, 80, 12
 END
 
 IDD_TCPIP_ADVIP_DLG DIALOGEX DISCARDABLE  0, 0, 247, 247
 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION
-CAPTION "IP Settings"
+CAPTION "Íàñòðîéêè íà IP"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    GROUPBOX "IP addressen", -1, 5, 5, 240, 90
+    GROUPBOX "IP àäðåñè", -1, 5, 5, 240, 90
     CONTROL "", IDC_IPLIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 15, 210, 55
-    PUSHBUTTON "Add...", IDC_IPADD, 60, 75, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Edit...", IDC_IPMOD, 120, 75, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_IPDEL, 180, 75, 50, 14, WS_TABSTOP
-    GROUPBOX "Default gateways:", -1, 5, 100, 240, 90
+    PUSHBUTTON "Äîáàâÿíå...", IDC_IPADD, 60, 75, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îáðàáîòêà...", IDC_IPMOD, 120, 75, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Ïðåìàõâàíå", IDC_IPDEL, 180, 75, 50, 14, WS_TABSTOP
+    GROUPBOX "Ïîäðàçáèðàíè ðàçïðåäåëèòåëè:", -1, 5, 100, 240, 90
     CONTROL "", IDC_GWLIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 110, 210, 55
-    PUSHBUTTON "Add...", IDC_GWADD, 60, 170, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Edit...", IDC_GWMOD, 120, 170, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_GWDEL, 180, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Äîáàâÿíå...", IDC_GWADD, 60, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îáðàáîòêà...", IDC_GWMOD, 120, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Ïðåìàõâàíå", IDC_GWDEL, 180, 170, 50, 14, WS_TABSTOP
     GROUPBOX "", -1, 5, 200, 240, 30
-    CHECKBOX "Automatic metric", IDC_AUTOMETRIC, 9, 200, 90, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    LTEXT "Interface metric:", -1, 15, 215, 90, 12
+    CHECKBOX "Àâòîìàòè÷íè ìåðíè åäèíèöè", IDC_AUTOMETRIC, 9, 200, 90, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    LTEXT "ÌÅðíè åäèíèöè íà èíòåðôåéñà:", -1, 15, 215, 90, 12
     EDITTEXT IDC_METRIC, 110, 212, 50, 12, WS_TABSTOP | ES_NUMBER
 END
 
@@ -74,157 +74,157 @@ CAPTION "DNS"
 FONT 8, "MS Shell Dlg"
 BEGIN
     LISTBOX IDC_DNSADDRLIST, 5, 15, 180, 60, LBS_NOTIFY
-    LTEXT "D&NS server addresses, in order of use:", -1, 5, 5, 180, 12
-    PUSHBUTTON "Up", IDC_DNSADDRUP, 190, 30, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Down", IDC_DNSADDRDOWN, 190, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Add...", IDC_DNSADDRADD, 30, 70, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Edit...", IDC_DNSADDRMOD, 100, 70, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remo&ve", IDC_DNSADDRDEL, 170, 70, 50, 14, WS_TABSTOP
-    LTEXT "The following three settings are applied to all connections with TCP/IP enabled. For resolution of unqualified names:", -1, 5, 90, 220, 24
-    CONTROL "Append &primary and connection specific DNS suffixes", IDC_PRIMSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 110, 160, 12
-    CHECKBOX "Append parent suffi&xes of the primary DNS suffix", IDC_TOPPRIMSUFFIX, 15, 125, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    CONTROL "Append t&hese DNS suffixes(in order):", IDC_SELSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 140, 190, 12
+    LTEXT "Àäðåñè íà DNS, ïî ðåäà íà èçïîëçâàíå:", -1, 5, 5, 180, 12
+    PUSHBUTTON "Íàãîðå", IDC_DNSADDRUP, 190, 30, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Íàäîëó", IDC_DNSADDRDOWN, 190, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Äîáàâÿíå...", IDC_DNSADDRADD, 30, 70, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Îáðàáîòêà...", IDC_DNSADDRMOD, 100, 70, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Ïðå&ìàõâàíå", IDC_DNSADDRDEL, 170, 70, 50, 14, WS_TABSTOP
+    LTEXT "Ñëåäíèòå òðè íàñòðîéêè ñå ïðèëàãàò íà âñè÷êè ñâúðçâàíèÿ, çà êîèòî å ïîçâîëåí TCP/IP. Çà ðàçðåøàâàíå íà íåãîäíè èìåíà:", -1, 5, 90, 220, 24
+    CONTROL "Íàñòàâÿíå íà &ïúðâè÷íèòå è îáîñîáåíèòå çà âðúçêèòå DNS íàñòàâêè", IDC_PRIMSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 110, 160, 12
+    CHECKBOX "Íàñòàâÿíå íà ðîäèòåëñêèòå íà&ñòàâêè êúì ïúðâè÷íàòà DNS íàñòàâêà", IDC_TOPPRIMSUFFIX, 15, 125, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CONTROL "Äîáàâÿíå íà &òåçè DNS íàñòàâêè (ïîäðåä):", IDC_SELSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 140, 190, 12
     LISTBOX IDC_DNSSUFFIXLIST, 5, 155, 180, 60, LBS_NOTIFY
-    PUSHBUTTON "Up", IDC_DNSSUFFIXUP, 190, 170, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Down", IDC_DNSSUFFIXDOWN, 190, 190, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Add...", IDC_DNSSUFFIXADD, 30, 210, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Edit...", IDC_DNSSUFFIXMOD, 100, 210, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remo&ve", IDC_DNSSUFFIXDEL, 170, 210, 50, 14, WS_TABSTOP
-    LTEXT "DNS &suffix for this connection:", -1, 5, 225, 110, 14
+    PUSHBUTTON "Íàãîðå", IDC_DNSSUFFIXUP, 190, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Íàäîëó", IDC_DNSSUFFIXDOWN, 190, 190, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Äîáàâÿíå...", IDC_DNSSUFFIXADD, 30, 210, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Îáðàáîòêà...", IDC_DNSSUFFIXMOD, 100, 210, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Ïðå&ìàõâàíå", IDC_DNSSUFFIXDEL, 170, 210, 50, 14, WS_TABSTOP
+    LTEXT "DNS &íàñòàâêà çà òîâà ñâúðçâàíå:", -1, 5, 225, 110, 14
     EDITTEXT IDC_SUFFIX, 120, 225, 100, 12, WS_TABSTOP
-    CHECKBOX "&Register this connection's addresses in DNS", IDC_REGSUFFIX, 15, 240, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    CHECKBOX "&Use this connection's DNS suffix in DNS registration", IDC_USESUFFIX, 15, 255, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX "Âïèñâàíå íà àäðåñèòå íà òîâà ñâúðçâàíå â DNS:", IDC_REGSUFFIX, 15, 240, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX "Èç&ïîëçâàíå íà DNS íàñòàâêàòà ïðè âïèñâàíåòî íà DNS", IDC_USESUFFIX, 15, 255, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
 
 END
 
 IDD_TCPIP_ADVOPT_DLG DIALOGEX DISCARDABLE  0, 0, 247, 247
 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION
-CAPTION "Options"
+CAPTION "Íàñòðîéêè"
 FONT 8, "MS Shell Dlg"
 BEGIN
     LISTBOX IDC_OPTLIST, 5, 30, 230, 70
-    LTEXT "&Optional settings", -1, 5, 15, 130, 12
-    PUSHBUTTON "&Properties", IDC_OPTPROP, 160, 100, 70, 14, WS_TABSTOP
-    GROUPBOX "Description:", -1, 5, 120, 240, 70
+    LTEXT "&Íåçàäúëæèòåëíè íàñòðîéêè:", -1, 5, 15, 130, 12
+    PUSHBUTTON "&Ñâîéñòâà", IDC_OPTPROP, 160, 100, 70, 14, WS_TABSTOP
+    GROUPBOX "Îïèñàíèå:", -1, 5, 120, 240, 70
     LTEXT "", IDC_OPTDESC, 15, 130, 220, 33
 END
 
 IDD_TCPIPADDIP_DLG DIALOGEX DISCARDABLE  0, 0, 200, 70
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Address"
+CAPTION "TCP/IP àäðåñ"
 FONT 8, "MS Shell Dlg"
 BEGIN
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 100, 15, 80, 12
-    LTEXT "IP address:", -1, 5, 15, 70, 12
-    LTEXT "Subnet mask:", -1, 5, 30, 70, 12
+    LTEXT "IP àäðåñ:", -1, 5, 15, 70, 12
+    LTEXT "Ïîäìðåæîâà ìàñêà:", -1, 5, 30, 70, 12
     CONTROL "",IDC_SUBNETMASK,"SysIPAddress32", WS_TABSTOP, 100, 30, 80, 12
     PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îòêàç", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIPGW_DLG DIALOGEX DISCARDABLE  0, 0, 200, 80
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Gateway Address"
+CAPTION "TCP/IP àäðåñ íà ðàçïðåäåëÿ"
 FONT 8, "MS Shell Dlg"
 BEGIN
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 100, 15, 80, 12
-    LTEXT "Gateway:", -1, 5, 15, 70, 12
-    CHECKBOX "Automatic metric", IDC_USEMETRIC, 15, 30, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    LTEXT "Ðàçïðåäåëèòåë:", -1, 5, 15, 70, 12
+    CHECKBOX "Àâòîìàòè÷íè ìåðíè åäèíèöè", IDC_USEMETRIC, 15, 30, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
     LTEXT "&Metric:", IDC_METRICTXT, 5, 45, 45, 12, WS_DISABLED
     EDITTEXT IDC_METRIC, 100, 45, 50, 12, WS_TABSTOP | ES_NUMBER | WS_DISABLED
     PUSHBUTTON "", IDC_OK, 50, 60, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 60, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îòêàç", IDCANCEL, 110, 60, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIPDNS_DLG DIALOGEX DISCARDABLE  0, 0, 200, 80
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP DNS Server"
+CAPTION "NDS ñúðâúð çà TCP/IP"
 FONT 8, "MS Shell Dlg"
 BEGIN
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 5, 25, 80, 12
-    LTEXT "DNS server:", -1, 5, 10, 120, 12
+    LTEXT "DNS ñúðâúð:", -1, 5, 10, 120, 12
     PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îòêàç", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIPSUFFIX_DLG DIALOGEX DISCARDABLE  0, 0, 200, 80
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Domain Suffix"
+CAPTION "Íàñòàâêà íà èìåíèå çà TCP/IP"
 FONT 8, "MS Shell Dlg"
 BEGIN
     EDITTEXT IDC_SUFFIX, 5, 25, 190, 12, WS_TABSTOP
-    LTEXT "Domain suffix:", -1, 5, 10, 120, 12
+    LTEXT "Íàñòàâêà íà èìåíèåòî:", -1, 5, 10, 120, 12
     PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îòêàç", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIP_FILTER_DLG DIALOGEX DISCARDABLE  0, 0, 305, 220
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Filtering"
+CAPTION "Ïðåñÿâàíå ïî TCP/IP"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    CHECKBOX "Enable TCP/IP-Filtering (All adapters)", IDC_USE_FILTER, 15, 5, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX "Âêëþ÷âàíå íà TCP/IP ïðåñÿâàíå (çà âñè÷êè êàðòè)", IDC_USE_FILTER, 15, 5, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
     GROUPBOX "", -1, 5, 30, 90, 150
-    CONTROL "Permit All", IDC_TCP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 30, 70, 12
-    CONTROL "Permit Only", IDC_TCP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 44, 70, 12
+    CONTROL "Ðàçðåøàâàíå íà âñè÷êè", IDC_TCP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 30, 70, 12
+    CONTROL "Ðàçðåøàâàíå ñàìî íà", IDC_TCP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 44, 70, 12
     CONTROL "", IDC_TCP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 11, 62, 72, 75
-    PUSHBUTTON "Add", IDC_TCP_ADD, 15, 141, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_TCP_DEL, 15, 161, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Äîáàâÿíå", IDC_TCP_ADD, 15, 141, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Ïðåìàõâàíå", IDC_TCP_DEL, 15, 161, 50, 14, WS_TABSTOP
     GROUPBOX "", -1, 105, 30, 90, 150
-    CONTROL "Permit All", IDC_UDP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 30, 70, 12
-    CONTROL "Permit Only", IDC_UDP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 44, 70, 12
+    CONTROL "Ðàçðåøàâàíå íà âñè÷êè", IDC_UDP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 30, 70, 12
+    CONTROL "Ðàçðåøàâàíå ñàìî íà", IDC_UDP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 44, 70, 12
     CONTROL "", IDC_UDP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 111, 62, 72, 75
-    PUSHBUTTON "Add", IDC_UDP_ADD, 115, 141, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_UDP_DEL, 115, 161, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Äîáàâÿíå", IDC_UDP_ADD, 115, 141, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Ïðåìàõâàíå", IDC_UDP_DEL, 115, 161, 50, 14, WS_TABSTOP
     GROUPBOX "", -1, 205, 30, 90, 150
-    CONTROL "Permit All", IDC_IP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 30, 70, 12
-    CONTROL "Permit Only", IDC_IP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 44, 70, 12
+    CONTROL "Ðàçðåøàâàíå íà âñè÷êè", IDC_IP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 30, 70, 12
+    CONTROL "Ðàçðåøàâàíå ñàìî íà", IDC_IP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 44, 70, 12
     CONTROL "", IDC_IP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 211, 62, 72, 75
-    PUSHBUTTON "Add", IDC_IP_ADD, 215, 141, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_IP_DEL, 215, 161, 50, 14, WS_TABSTOP
-    PUSHBUTTON "OK", IDC_OK, 150, 190, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 210, 190, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Äîáàâÿíå", IDC_IP_ADD, 215, 141, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Ïðåìàõâàíå", IDC_IP_DEL, 215, 161, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Äîáðå", IDC_OK, 150, 190, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îòêàç", IDCANCEL, 210, 190, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIP_PORT_DLG DIALOGEX DISCARDABLE  0, 0, 200, 60
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Add Filter"
+CAPTION "Äîáàâÿíå íà ïðåñÿâàíå"
 FONT 8, "MS Shell Dlg"
 BEGIN
     EDITTEXT IDC_PORT_VAL, 5, 30, 70, 12, WS_TABSTOP | ES_NUMBER
     LTEXT "", IDC_PORT_DESC, 5, 15, 40, 12
-    PUSHBUTTON "OK", IDC_OK, 120, 15, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 120, 30, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Äîáðå", IDC_OK, 120, 15, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Îòêàç", IDCANCEL, 120, 30, 50, 14, WS_TABSTOP
 END
 
 STRINGTABLE
 BEGIN
        IDS_NET_CONNECT "Ìðåæoâo ñâúðçâàíå"
-       IDS_NO_IPADDR_SET   "The adapter requires at least one IP address. Please enter one."
-       IDS_NO_SUBMASK_SET  "You have entered an address that is missing its subnet mask. Please add a subnet mask."
-       IDS_TCPFILTERDESC   "TCP/IP filtering allows you to control the type of TCP/IP network traffic that reaches your computer."
-       IDS_TCPFILTER       "TCP/IP Filtering"
-       IDS_IPADDR          "IP address"
-       IDS_SUBMASK         "Subnet mask"
-       IDS_GATEWAY         "Gateway"
+       IDS_NO_IPADDR_SET   "Êàðòàòà èñêà ïîíå åäèí IP àäðåñ. Âúâåäåòå òàêúâ."
+       IDS_NO_SUBMASK_SET  "Âúâåëè ñòå àäðåñ áåç ïîäìðåæîâà ìàñêà. Âúâåäåòå òàêàâà."
+       IDS_TCPFILTERDESC   "Ïðåñÿâàíåòî ïî TCP/IP ïîçâîëÿâà óïðàâëåíèå íà âèäà íà îáìåíà ïî TCP/IP, êîéòî äîñòèãà äî êîìïþòúðà âè."
+       IDS_TCPFILTER       "Ïðåñÿâàíå ïî TCP/IP"
+       IDS_IPADDR          "IP àäðåñ"
+       IDS_SUBMASK         "Ïîäìðåæîâà ìàñêà"
+       IDS_GATEWAY         "Ðàçïðåäåëèòåë"
        IDS_METRIC          "Metric"
-       IDS_DHCPACTIVE      "DHCP Enabled"
-       IDS_AUTOMATIC       "Automatic"
-       IDS_NOITEMSEL       "You have not selected an item. Select one first."
-       IDS_TCPIP           "ReactOS-TCP/IP"
-       IDS_ADD             "Add"
-       IDS_MOD             "OK"
-       IDS_TCP_PORTS       "TCP Ports"
-       IDS_UDP_PORTS       "UDP Ports"
-       IDS_IP_PROTO        "IP protocols"
-       IDS_PORT_RANGE      "Port numbers must be greater than 0 and less than 65536. Please enter a number within this range."
-       IDS_PROT_RANGE      "Protocol numbers must be greater than 0 and less than 256. Please enter a number within this range."
-       IDS_DUP_NUMBER      "The number you are trying to add is already in the list. Please enter a different number."
-       IDS_DISABLE_FILTER  "Disabling this global TCP/IP setting will affect all adapters."
-       IDS_NO_SUFFIX       "The current setting of search method requires at least one DNS suffix. Please enter one or change the setting."
-       IDS_DOMAIN_SUFFIX   "Domain suffix is not a valid suffix."
-       IDS_DNS_SUFFIX      "The DNS domain name ""%s"" is not a valid DNS name."
-       IDS_DUP_SUFFIX      "The DNS suffix is already on the list."
-       IDS_DUP_IPADDR      "The IP address is already on the list."
-       IDS_DUP_GW          "The default gateway is already on the list."
+       IDS_DHCPACTIVE      "SHCP âêëþ÷åí"
+       IDS_AUTOMATIC       "Ñàìî"
+       IDS_NOITEMSEL       "Íå ñòå èçáðàëè ïðåäìåò. Ïúðâî èçáåðåòå íåùî."
+       IDS_TCPIP           "ÐåàêòÎÑ- TCP/IP"
+       IDS_ADD             "Äîáàâÿíå"
+       IDS_MOD             "Äîáðå"
+       IDS_TCP_PORTS       "TCP èçâîäè"
+       IDS_UDP_PORTS       "UDP èçâîäè"
+       IDS_IP_PROTO        "IP ïðîòîêîëè"
+       IDS_PORT_RANGE      "Ñòîéíîñòèòå íà èçâîäèòå òðÿáâà äà ñà ìåæäó 1 è 65535. Âúâåäåòå ÷èñëî â òåçè ãðàíèöè."
+       IDS_PROT_RANGE      "×èñëàòà òðÿáâà äà ñà ìåæäó 1 è 255. Âúâåäåòå ÷èñëî â òåçè ãðàíèöè."
+       IDS_DUP_NUMBER      "×èñëîòî, êîåòî ñå îïèòâàòå äà âúâåäåòå âå÷å å â ñïèñúêà. Âúâåäåòå äðóãî ÷èñëî."
+       IDS_DISABLE_FILTER  "Èçêëþ÷âàíåòî íà òàçè âñåîáùà íàñòðîéêà íà TCP/IP âúçäåéñòâà íà âñè÷êè ìðåæîâè êàðòè."
+       IDS_NO_SUFFIX       "Òåêóùàòà íàñòðîéêà íà ïîõâàòà çà òúðñåíå èçèñêâà ïîíå åäíà DNS íàñòàâêà. Âúâåäåòå òàêàâà èëè ïðîìåíåòå íàñòðîéêàòà."
+       IDS_DOMAIN_SUFFIX   "Íàñòàâêàòà íà èìåíèåòî å íåïðàâèëíà."
+       IDS_DNS_SUFFIX      "Èìåòî íà èìåíèåòî ïî DNS""%s"" is not a valid DNS name."
+       IDS_DUP_SUFFIX      "DNS íàñòàâêàòà âå÷å å â ñïèñúêà."
+       IDS_DUP_IPADDR      "IP àäðåñúò âå÷å å â ñïèñúêà."
+       IDS_DUP_GW          "Ïîäðàçáèðàíèÿò ðàçïðåäåëèòåë âå÷å å â ñïèñúêà."
 END
index b63d03f..a42b9b5 100644 (file)
@@ -70,27 +70,27 @@ END
 
 IDD_LAN_NETSTATUSDETAILS DIALOGEX DISCARDABLE  0, 0, 200,200
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
-CAPTION "Network Connection Details"
+CAPTION "Ïîäðîáíîñòè çà ìðåæîâîòî ñâúðçâàíå"
 FONT 8, "MS Shell Dlg"
 BEGIN
- LTEXT "Network Connection &Details:", -1, 15, 9, 170, 12
+ LTEXT "Ïî&äðîáíîñòè çà ìðåæîâîòî ñâúðçâàíå:", -1, 15, 9, 170, 12
  CONTROL "", IDC_DETAILS, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 25, 170, 130
- PUSHBUTTON "&Close", IDC_CLOSE, 125, 165, 62, 14
+ PUSHBUTTON "&Çàòâàðÿíå", IDC_CLOSE, 125, 165, 62, 14
 END
 
 STRINGTABLE DISCARDABLE
 BEGIN
-       IDS_PHYSICAL_ADDRESS        "Physical Address"
-       IDS_IP_ADDRESS              "IP Address"
-       IDS_SUBNET_MASK             "Subnet Mask"
-       IDS_DEF_GATEWAY             "Default Gateway"
-       IDS_DHCP_SERVER             "DHCP Server"
-       IDS_LEASE_OBTAINED          "Lease Obtained"
-       IDS_LEASE_EXPIRES           "Lease Expires"
-       IDS_DNS_SERVERS             "DNS Servers"
-       IDS_WINS_SERVERS            "WINS Servers"
-       IDS_PROPERTY                "Property"
-       IDS_VALUE                   "Value"
+       IDS_PHYSICAL_ADDRESS        "Ôèçè÷åñêè àäðåñ"
+       IDS_IP_ADDRESS              "Àäðåñ ïî IP"
+       IDS_SUBNET_MASK             "Ïîäìðåæîâà ìàñêà"
+       IDS_DEF_GATEWAY             "Ïîäðàçáèðàí ðàçïðåäåëèòåë"
+       IDS_DHCP_SERVER             "DHCP ñúðâúð"
+       IDS_LEASE_OBTAINED          "Íàåìàíå ïðèäîáèòî"
+       IDS_LEASE_EXPIRES           "Íàåìàíåòî ïðîñðî÷åíî"
+       IDS_DNS_SERVERS             "DNS ñúðâúðè"
+       IDS_WINS_SERVERS            "WINS ñúðâúðè"
+       IDS_PROPERTY                "Ñâîéñòâî"
+       IDS_VALUE                   "Ñòîéíîñò"
        IDS_NETWORKCONNECTION       "Ìðåæîâî ñâúðçâàíå"
        IDS_SHV_COLUMN_NAME         "Èìå"
        IDS_SHV_COLUMN_TYPE         "Âèä"
index 9a6f765..5076e00 100644 (file)
 #include "winuser.h"
 #include "ole2.h"
 
+#include "wine/unicode.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(oleacc);
 
+static HINSTANCE oleacc_handle = 0;
+
 HRESULT WINAPI CreateStdAccessibleObject( HWND hwnd, LONG idObject,
                              REFIID riidInterface, void** ppvObject )
 {
@@ -50,6 +53,21 @@ HRESULT WINAPI AccessibleObjectFromWindow( HWND hwnd, DWORD dwObjectID,
     return E_NOTIMPL;
 }
 
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
+                    LPVOID lpvReserved)
+{
+    TRACE("%p, %d, %p\n", hinstDLL, fdwReason, lpvReserved);
+
+    switch (fdwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+            oleacc_handle = hinstDLL;
+            DisableThreadLibraryCalls(hinstDLL);
+            break;
+    }
+    return TRUE;
+}
+
 HRESULT WINAPI DllRegisterServer(void)
 {
     FIXME("\n");
@@ -67,3 +85,59 @@ void WINAPI GetOleaccVersionInfo(DWORD* pVersion, DWORD* pBuild)
     *pVersion = MAKELONG(2,4); /* Windows XP version of oleacc: 4.2.5406.0 */
     *pBuild = MAKELONG(0,5406);
 }
+
+UINT WINAPI GetRoleTextW(DWORD role, LPWSTR lpRole, UINT rolemax)
+{
+    INT ret;
+    WCHAR *resptr;
+
+    TRACE("%u %p %u\n", role, lpRole, rolemax);
+
+    /* return role text length */
+    if(!lpRole)
+        return LoadStringW(oleacc_handle, role, (LPWSTR)&resptr, 0);
+
+    ret = LoadStringW(oleacc_handle, role, lpRole, rolemax);
+    if(!(ret > 0)){
+        if(rolemax > 0) lpRole[0] = '\0';
+        return 0;
+    }
+
+    return ret;
+}
+
+UINT WINAPI GetRoleTextA(DWORD role, LPSTR lpRole, UINT rolemax)
+{
+    UINT length;
+    WCHAR *roletextW;
+
+    TRACE("%u %p %u\n", role, lpRole, rolemax);
+
+    length = GetRoleTextW(role, NULL, 0);
+    if((length == 0) || (lpRole && !rolemax))
+        return 0;
+
+    roletextW = HeapAlloc(GetProcessHeap(), 0, (length + 1)*sizeof(WCHAR));
+    if(!roletextW)
+        return 0;
+
+    GetRoleTextW(role, roletextW, length + 1);
+
+    length = WideCharToMultiByte( CP_ACP, 0, roletextW, -1, NULL, 0, NULL, NULL );
+
+    if(!lpRole){
+        HeapFree(GetProcessHeap(), 0, roletextW);
+        return length - 1;
+    }
+
+    WideCharToMultiByte( CP_ACP, 0, roletextW, -1, lpRole, rolemax, NULL, NULL );
+
+    if(rolemax < length){
+        lpRole[rolemax-1] = '\0';
+        length = rolemax;
+    }
+
+    HeapFree(GetProcessHeap(), 0, roletextW);
+
+    return length - 1;
+}
index 79c8ec0..1e75379 100644 (file)
@@ -8,8 +8,10 @@
        <include base="ReactOS">include/reactos/wine</include>
        <define name="__WINESRC__" />
        <file>main.c</file>
+       <file>oleacc.rc</file>
        <library>wine</library>
        <library>kernel32</library>
+       <library>user32</library>
        <library>ntdll</library>
 </module>
 </group>
diff --git a/reactos/dll/win32/oleacc/oleacc.rc b/reactos/dll/win32/oleacc/oleacc.rc
new file mode 100644 (file)
index 0000000..8d4709f
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Top level resource file for oleacc
+ *
+ * Copyright 2008 Nikolay Sivov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "windef.h"
+#include "oleacc.h"
+
+#include "oleacc_En.rc"
+#include "oleacc_Fr.rc"
+#include "oleacc_Ko.rc"
+#include "oleacc_Nl.rc"
index 23b84b3..2baeb2b 100644 (file)
@@ -8,8 +8,8 @@
 @ stdcall -private DllRegisterServer()
 @ stdcall -private DllUnregisterServer()
 @ stdcall GetOleaccVersionInfo(ptr ptr)
-@ stub GetRoleTextA
-@ stub GetRoleTextW
+@ stdcall GetRoleTextA(long ptr long)
+@ stdcall GetRoleTextW(long ptr long)
 @ stub GetStateTextA
 @ stub GetStateTextW
 @ stub IID_IAccessible
diff --git a/reactos/dll/win32/oleacc/oleacc_En.rc b/reactos/dll/win32/oleacc/oleacc_En.rc
new file mode 100644 (file)
index 0000000..992d29c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * English resources for oleacc
+ *
+ * Copyright 2008 Nikolay Sivov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+    0 "unknown object" /* undocumented */
+    ROLE_SYSTEM_TITLEBAR    "title bar"
+    ROLE_SYSTEM_MENUBAR     "menu bar"
+    ROLE_SYSTEM_SCROLLBAR   "scroll bar"
+    ROLE_SYSTEM_GRIP        "grip"
+    ROLE_SYSTEM_SOUND       "sound"
+    ROLE_SYSTEM_CURSOR      "cursor"
+    ROLE_SYSTEM_CARET       "caret"
+    ROLE_SYSTEM_ALERT       "alert"
+    ROLE_SYSTEM_WINDOW      "window"
+    ROLE_SYSTEM_CLIENT      "client"
+    ROLE_SYSTEM_MENUPOPUP   "popup menu"
+    ROLE_SYSTEM_MENUITEM    "menu item"
+    ROLE_SYSTEM_TOOLTIP     "tool tip"
+    ROLE_SYSTEM_APPLICATION "application"
+    ROLE_SYSTEM_DOCUMENT    "document"
+    ROLE_SYSTEM_PANE        "pane"
+    ROLE_SYSTEM_CHART       "chart"
+    ROLE_SYSTEM_DIALOG      "dialog"
+    ROLE_SYSTEM_BORDER      "border"
+    ROLE_SYSTEM_GROUPING    "grouping"
+    ROLE_SYSTEM_SEPARATOR   "separator"
+    ROLE_SYSTEM_TOOLBAR     "tool bar"
+    ROLE_SYSTEM_STATUSBAR   "status bar"
+    ROLE_SYSTEM_TABLE        "table"
+    ROLE_SYSTEM_COLUMNHEADER "column header"
+    ROLE_SYSTEM_ROWHEADER    "row header"
+    ROLE_SYSTEM_COLUMN       "column"
+    ROLE_SYSTEM_ROW          "row"
+    ROLE_SYSTEM_CELL         "cell"
+    ROLE_SYSTEM_LINK         "link"
+    ROLE_SYSTEM_HELPBALLOON  "help balloon"
+    ROLE_SYSTEM_CHARACTER    "character"
+    ROLE_SYSTEM_LIST         "list"
+    ROLE_SYSTEM_LISTITEM     "list item"
+    ROLE_SYSTEM_OUTLINE      "outline"
+    ROLE_SYSTEM_OUTLINEITEM  "outline item"
+    ROLE_SYSTEM_PAGETAB      "page tab"
+    ROLE_SYSTEM_PROPERTYPAGE "property page"
+    ROLE_SYSTEM_INDICATOR    "indicator"
+    ROLE_SYSTEM_GRAPHIC      "graphic"
+    ROLE_SYSTEM_STATICTEXT   "static text"
+    ROLE_SYSTEM_TEXT         "text"
+    ROLE_SYSTEM_PUSHBUTTON   "push button"
+    ROLE_SYSTEM_CHECKBUTTON  "check button"
+    ROLE_SYSTEM_RADIOBUTTON  "radio button"
+    ROLE_SYSTEM_COMBOBOX     "combo box"
+    ROLE_SYSTEM_DROPLIST     "drop down"
+    ROLE_SYSTEM_PROGRESSBAR  "progress bar"
+    ROLE_SYSTEM_DIAL         "dial"
+    ROLE_SYSTEM_HOTKEYFIELD  "hot key field"
+    ROLE_SYSTEM_SLIDER       "slider"
+    ROLE_SYSTEM_SPINBUTTON   "spin box"
+    ROLE_SYSTEM_DIAGRAM      "diagram"
+    ROLE_SYSTEM_ANIMATION    "animation"
+    ROLE_SYSTEM_EQUATION     "equation"
+    ROLE_SYSTEM_BUTTONDROPDOWN "drop down button"
+    ROLE_SYSTEM_BUTTONMENU   "menu button"
+    ROLE_SYSTEM_BUTTONDROPDOWNGRID "grid drop down button"
+    ROLE_SYSTEM_WHITESPACE   "white space"
+    ROLE_SYSTEM_PAGETABLIST  "page tab list"
+    ROLE_SYSTEM_CLOCK        "clock"
+    ROLE_SYSTEM_SPLITBUTTON  "split button"
+    ROLE_SYSTEM_IPADDRESS    "IP address"
+    ROLE_SYSTEM_OUTLINEBUTTON "outline button"
+}
diff --git a/reactos/dll/win32/oleacc/oleacc_Fr.rc b/reactos/dll/win32/oleacc/oleacc_Fr.rc
new file mode 100644 (file)
index 0000000..87bea0b
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * French resources for oleacc
+ *
+ * Copyright 2008 Jonathan Ernst
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+{
+    0 "objet inconnu" /* undocumented */
+    ROLE_SYSTEM_TITLEBAR    "barre de titre"
+    ROLE_SYSTEM_MENUBAR     "barre de menu"
+    ROLE_SYSTEM_SCROLLBAR   "barre de défilement"
+    ROLE_SYSTEM_GRIP        "grip"
+    ROLE_SYSTEM_SOUND       "son"
+    ROLE_SYSTEM_CURSOR      "curseur"
+    ROLE_SYSTEM_CARET       "caret"
+    ROLE_SYSTEM_ALERT       "alerte"
+    ROLE_SYSTEM_WINDOW      "fenêtre"
+    ROLE_SYSTEM_CLIENT      "client"
+    ROLE_SYSTEM_MENUPOPUP   "menu popup"
+    ROLE_SYSTEM_MENUITEM    "élément de menu"
+    ROLE_SYSTEM_TOOLTIP     "infobulle"
+    ROLE_SYSTEM_APPLICATION "application"
+    ROLE_SYSTEM_DOCUMENT    "document"
+    ROLE_SYSTEM_PANE        "pane"
+    ROLE_SYSTEM_CHART       "chart"
+    ROLE_SYSTEM_DIALOG      "boîte de dialogue"
+    ROLE_SYSTEM_BORDER      "bordure"
+    ROLE_SYSTEM_GROUPING    "grouping"
+    ROLE_SYSTEM_SEPARATOR   "separateur"
+    ROLE_SYSTEM_TOOLBAR     "barre d'outils"
+    ROLE_SYSTEM_STATUSBAR   "barre d'état"
+    ROLE_SYSTEM_TABLE        "table"
+    ROLE_SYSTEM_COLUMNHEADER "en-tête de colonne"
+    ROLE_SYSTEM_ROWHEADER    "en-tête de ligne"
+    ROLE_SYSTEM_COLUMN       "colonne"
+    ROLE_SYSTEM_ROW          "ligne"
+    ROLE_SYSTEM_CELL         "cellule"
+    ROLE_SYSTEM_LINK         "lien"
+    ROLE_SYSTEM_HELPBALLOON  "bulle d'aide"
+    ROLE_SYSTEM_CHARACTER    "caractère"
+    ROLE_SYSTEM_LIST         "liste"
+    ROLE_SYSTEM_LISTITEM     "élément de liste"
+    ROLE_SYSTEM_OUTLINE      "outline"
+    ROLE_SYSTEM_OUTLINEITEM  "outline item"
+    ROLE_SYSTEM_PAGETAB      "onglet de page"
+    ROLE_SYSTEM_PROPERTYPAGE "page de propriétés"
+    ROLE_SYSTEM_INDICATOR    "indicateur"
+    ROLE_SYSTEM_GRAPHIC      "image"
+    ROLE_SYSTEM_STATICTEXT   "texte statique"
+    ROLE_SYSTEM_TEXT         "texte"
+    ROLE_SYSTEM_PUSHBUTTON   "bouton pressoir"
+    ROLE_SYSTEM_CHECKBUTTON  "case à cocher"
+    ROLE_SYSTEM_RADIOBUTTON  "bouton radio"
+    ROLE_SYSTEM_COMBOBOX     "combo box"
+    ROLE_SYSTEM_DROPLIST     "drop down"
+    ROLE_SYSTEM_PROGRESSBAR  "barre de progression"
+    ROLE_SYSTEM_DIAL         "dial"
+    ROLE_SYSTEM_HOTKEYFIELD  "hot key field"
+    ROLE_SYSTEM_SLIDER       "slider"
+    ROLE_SYSTEM_SPINBUTTON   "spin box"
+    ROLE_SYSTEM_DIAGRAM      "diagramme"
+    ROLE_SYSTEM_ANIMATION    "animation"
+    ROLE_SYSTEM_EQUATION     "équation"
+    ROLE_SYSTEM_BUTTONDROPDOWN "drop down button"
+    ROLE_SYSTEM_BUTTONMENU   "bouton de menu"
+    ROLE_SYSTEM_BUTTONDROPDOWNGRID "grid drop down button"
+    ROLE_SYSTEM_WHITESPACE   "espace blanc"
+    ROLE_SYSTEM_PAGETABLIST  "page tab list"
+    ROLE_SYSTEM_CLOCK        "horloge"
+    ROLE_SYSTEM_SPLITBUTTON  "split button"
+    ROLE_SYSTEM_IPADDRESS    "Adresse IP"
+    ROLE_SYSTEM_OUTLINEBUTTON "outline button"
+}
diff --git a/reactos/dll/win32/oleacc/oleacc_Ko.rc b/reactos/dll/win32/oleacc/oleacc_Ko.rc
new file mode 100644 (file)
index 0000000..a1993f1
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * English resources for oleacc
+ *
+ * Copyright 2008 Nikolay Sivov
+ * Copyright 2008 YunSong Hwang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+    0 "¾Ë ¼ö ¾ø´Â °´Ã¼" /* undocumented */
+    ROLE_SYSTEM_TITLEBAR    "Á¦¸ñ¹Ù"
+    ROLE_SYSTEM_MENUBAR     "¸Þ´º¹Ù"
+    ROLE_SYSTEM_SCROLLBAR   "½ºÅ©·Ñ¹Ù"
+    ROLE_SYSTEM_GRIP        "±×¸³"
+    ROLE_SYSTEM_SOUND       "»ç¿îµå"
+    ROLE_SYSTEM_CURSOR      "Ä¿¼­"
+    ROLE_SYSTEM_CARET       "»ðÀÔ±âÈ£"
+    ROLE_SYSTEM_ALERT       "°æ°í"
+    ROLE_SYSTEM_WINDOW      "â"
+    ROLE_SYSTEM_CLIENT      "Ŭ¶óÀ̾ðÆ®"
+    ROLE_SYSTEM_MENUPOPUP   "Æ˾÷ ¸Þ´º"
+    ROLE_SYSTEM_MENUITEM    "¸Þ´º ¾ÆÀÌÅÛ"
+    ROLE_SYSTEM_TOOLTIP     "µµ±¸ ÆÁ"
+    ROLE_SYSTEM_APPLICATION "ÇÁ·Î±×·¥"
+    ROLE_SYSTEM_DOCUMENT    "¹®¼­"
+    ROLE_SYSTEM_PANE        "Ʋ(pane)"
+    ROLE_SYSTEM_CHART       "Â÷Æ®"
+    ROLE_SYSTEM_DIALOG      "´ëÈ­»óÀÚ"
+    ROLE_SYSTEM_BORDER      "°¡ÀåÀÚ¸®"
+    ROLE_SYSTEM_GROUPING    "Áý´ÜÈ­"
+    ROLE_SYSTEM_SEPARATOR   "ºÐ¸®ÀÚ"
+    ROLE_SYSTEM_TOOLBAR     "µµ±¸¹Ù"
+    ROLE_SYSTEM_STATUSBAR   "»óŹÙ"
+    ROLE_SYSTEM_TABLE        "Å×À̺í"
+    ROLE_SYSTEM_COLUMNHEADER "¼¼·ÎÁÙ Çì´õ"
+    ROLE_SYSTEM_ROWHEADER    "°¡·ÎÁÙ Çì´õ"
+    ROLE_SYSTEM_COLUMN       "¿­"
+    ROLE_SYSTEM_ROW          "°¡·ÎÁÙ"
+    ROLE_SYSTEM_CELL         "¼¿"
+    ROLE_SYSTEM_LINK         "¸µÅ©"
+    ROLE_SYSTEM_HELPBALLOON  "dz¼± µµ¿ò¸»"
+    ROLE_SYSTEM_CHARACTER    "¹®ÀÚ"
+    ROLE_SYSTEM_LIST         "¸ñ·Ï"
+    ROLE_SYSTEM_LISTITEM     "¸ñ·Ï ¾ÆÀÌÅÛ"
+    ROLE_SYSTEM_OUTLINE      "¿Ü°û¼±"
+    ROLE_SYSTEM_OUTLINEITEM  "¿Ü°û¼± ¾ÆÀÌÅÛ"
+    ROLE_SYSTEM_PAGETAB      "ÆäÀÌÁö ÅÇ"
+    ROLE_SYSTEM_PROPERTYPAGE "¼Ó¼º ÆäÀÌÁö"
+    ROLE_SYSTEM_INDICATOR    "Áö½ÃÀÚ"
+    ROLE_SYSTEM_GRAPHIC      "±×¸²"
+    ROLE_SYSTEM_STATICTEXT   "Á¤Àû ¹®ÀÚ"
+    ROLE_SYSTEM_TEXT         "¹®ÀÚ"
+    ROLE_SYSTEM_PUSHBUTTON   "´©¸£±â ¹öÆ°"
+    ROLE_SYSTEM_CHECKBUTTON  "üũ ¹öÆ°"
+    ROLE_SYSTEM_RADIOBUTTON  "¶óµð¿À ¹öÆ°"
+    ROLE_SYSTEM_COMBOBOX     "ÄÞº¸  »óÀÚ"
+    ROLE_SYSTEM_DROPLIST     "µå·ì ´Ù¿î"
+    ROLE_SYSTEM_PROGRESSBAR  "ÁøÇà¹Ù"
+    ROLE_SYSTEM_DIAL         "´ÙÀ̾ó"
+    ROLE_SYSTEM_HOTKEYFIELD  "´ÜÃàÅ° ¸ðÀ½"
+    ROLE_SYSTEM_SLIDER       "½½¶óÀÌ´õ"
+    ROLE_SYSTEM_SPINBUTTON   "½ºÇÉ »óÀÚ"
+    ROLE_SYSTEM_DIAGRAM      "µµÇü"
+    ROLE_SYSTEM_ANIMATION    "¾Ö´Ï¸ÅÀ̼Ç"
+    ROLE_SYSTEM_EQUATION     "¼ö½Ä"
+    ROLE_SYSTEM_BUTTONDROPDOWN "µå·ì ´Ù¿î ¹öÆ°"
+    ROLE_SYSTEM_BUTTONMENU   "¸Þ´º ¹öÆ°"
+    ROLE_SYSTEM_BUTTONDROPDOWNGRID "±×¸³ µå·ì ´Ù¿î ´ÜÃß"
+    ROLE_SYSTEM_WHITESPACE   "ºó °ø°£"
+    ROLE_SYSTEM_PAGETABLIST  "ÆäÀÌÁö ÅÇ ¸ñ·Ï"
+    ROLE_SYSTEM_CLOCK        "½Ã°è"
+    ROLE_SYSTEM_SPLITBUTTON  "³ª´©±â ´ÜÃß"
+    ROLE_SYSTEM_IPADDRESS    "IP ÁÖ¼Ò"
+    ROLE_SYSTEM_OUTLINEBUTTON "¿Ü°û¼± ´ÜÃß"
+}
diff --git a/reactos/dll/win32/oleacc/oleacc_Nl.rc b/reactos/dll/win32/oleacc/oleacc_Nl.rc
new file mode 100644 (file)
index 0000000..b639128
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Dutch resources for oleacc
+ *
+ * Copyright 2008 Frans Kool
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+{
+    0 "onbekend object" /* undocumented */
+    ROLE_SYSTEM_TITLEBAR    "titel balk"
+    ROLE_SYSTEM_MENUBAR     "menu balk"
+    ROLE_SYSTEM_SCROLLBAR   "scroll balk"
+    ROLE_SYSTEM_GRIP        "handvat"
+    ROLE_SYSTEM_SOUND       "geluid"
+    ROLE_SYSTEM_CURSOR      "cursor"
+    ROLE_SYSTEM_CARET       "tekst cursor"
+    ROLE_SYSTEM_ALERT       "alarm"
+    ROLE_SYSTEM_WINDOW      "venster"
+    ROLE_SYSTEM_CLIENT      "client"
+    ROLE_SYSTEM_MENUPOPUP   "popup menu"
+    ROLE_SYSTEM_MENUITEM    "menu item"
+    ROLE_SYSTEM_TOOLTIP     "tool tip"
+    ROLE_SYSTEM_APPLICATION "programma"
+    ROLE_SYSTEM_DOCUMENT    "document"
+    ROLE_SYSTEM_PANE        "sectie"
+    ROLE_SYSTEM_CHART       "diagram"
+    ROLE_SYSTEM_DIALOG      "keuze"
+    ROLE_SYSTEM_BORDER      "randen"
+    ROLE_SYSTEM_GROUPING    "groepering"
+    ROLE_SYSTEM_SEPARATOR   "separator"
+    ROLE_SYSTEM_TOOLBAR     "knoppen balk"
+    ROLE_SYSTEM_STATUSBAR   "status balk"
+    ROLE_SYSTEM_TABLE        "tabel"
+    ROLE_SYSTEM_COLUMNHEADER "kolom hoofd"
+    ROLE_SYSTEM_ROWHEADER    "rij hoofd"
+    ROLE_SYSTEM_COLUMN       "kolom"
+    ROLE_SYSTEM_ROW          "rij"
+    ROLE_SYSTEM_CELL         "cel"
+    ROLE_SYSTEM_LINK         "link"
+    ROLE_SYSTEM_HELPBALLOON  "help ballon"
+    ROLE_SYSTEM_CHARACTER    "karakter"
+    ROLE_SYSTEM_LIST         "lijst"
+    ROLE_SYSTEM_LISTITEM     "lijst onderdeel"
+    ROLE_SYSTEM_OUTLINE      "outline"
+    ROLE_SYSTEM_OUTLINEITEM  "outline onderdeel"
+    ROLE_SYSTEM_PAGETAB      "pagina tab"
+    ROLE_SYSTEM_PROPERTYPAGE "eigenschappen pagina"
+    ROLE_SYSTEM_INDICATOR    "indicator"
+    ROLE_SYSTEM_GRAPHIC      "grafisch"
+    ROLE_SYSTEM_STATICTEXT   "vaste tekst"
+    ROLE_SYSTEM_TEXT         "tekst"
+    ROLE_SYSTEM_PUSHBUTTON   "drukknop"
+    ROLE_SYSTEM_CHECKBUTTON  "aankruisvakje"
+    ROLE_SYSTEM_RADIOBUTTON  "radioknop"
+    ROLE_SYSTEM_COMBOBOX     "combo box"
+    ROLE_SYSTEM_DROPLIST     "selectie box"
+    ROLE_SYSTEM_PROGRESSBAR  "voortgangsbalk"
+    ROLE_SYSTEM_DIAL         "draaiknop"
+    ROLE_SYSTEM_HOTKEYFIELD  "hotkey veld"
+    ROLE_SYSTEM_SLIDER       "schuifknop"
+    ROLE_SYSTEM_SPINBUTTON   "spin box"
+    ROLE_SYSTEM_DIAGRAM      "diagram"
+    ROLE_SYSTEM_ANIMATION    "animation"
+    ROLE_SYSTEM_EQUATION     "formula"
+    ROLE_SYSTEM_BUTTONDROPDOWN "dropdown knop"
+    ROLE_SYSTEM_BUTTONMENU   "menu knop"
+    ROLE_SYSTEM_BUTTONDROPDOWNGRID "dropdown grid knop"
+    ROLE_SYSTEM_WHITESPACE   "lege ruimte"
+    ROLE_SYSTEM_PAGETABLIST  "pagina tab lijst"
+    ROLE_SYSTEM_CLOCK        "klok"
+    ROLE_SYSTEM_SPLITBUTTON  "splits knop"
+    ROLE_SYSTEM_IPADDRESS    "IP adres"
+    ROLE_SYSTEM_OUTLINEBUTTON "outline knop"
+}
index 1780bc0..ab44dac 100644 (file)
@@ -214,8 +214,9 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
       }
 
       *height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
-      *x = run->member.run.pt.x + sz.cx;
-      *y = para->member.para.pt.y + row->member.row.nBaseline + run->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor);
+      *x = c.rcView.left + run->member.run.pt.x + sz.cx;
+      *y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline
+           + run->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor);
       ME_DestroyContext(&c, editor->hWnd);
       return;
     }
@@ -236,10 +237,7 @@ ME_MoveCaret(ME_TextEditor *editor)
   ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height);
   if(editor->bHaveFocus && !ME_IsSelection(editor))
   {
-    RECT rect;
-
-    GetClientRect(editor->hWnd, &rect);
-    x = min(x, rect.right-2);
+    x = min(x, editor->rcFormat.right-1);
     CreateCaret(editor->hWnd, NULL, 0, height);
     SetCaretPos(x, y);
   }
@@ -922,6 +920,9 @@ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y,
   int rx = 0;
   BOOL isExact = TRUE;
 
+  x -= editor->rcFormat.left;
+  y -= editor->rcFormat.top;
+
   if (is_eol)
     *is_eol = 0;
 
@@ -1109,13 +1110,13 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
 
   ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd);
 
-  if (x >= editor->selofs || is_shift)
+  if (x >= editor->rcFormat.left || is_shift)
   {
     if (clickNum > 1)
     {
       editor->pCursors[1] = editor->pCursors[0];
       if (is_shift) {
-          if (x >= editor->selofs)
+          if (x >= editor->rcFormat.left)
               ME_SelectByType(editor, stWord);
           else
               ME_SelectByType(editor, stParagraph);
@@ -1177,16 +1178,10 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
       memcmp(&editor->pCursors[1], &editor->pCursors[3], sizeof(ME_Cursor)))
   {
       /* The scroll the cursor towards the other end, since it was the one
-       * extended by ME_ExtendAnchorSelection
-       */
-      ME_Cursor tmpCursor = editor->pCursors[0];
-      editor->pCursors[0] = editor->pCursors[1];
-      editor->pCursors[1] = tmpCursor;
-      SendMessageW(editor->hWnd, EM_SCROLLCARET, 0, 0);
-      editor->pCursors[1] = editor->pCursors[0];
-      editor->pCursors[0] = tmpCursor;
+       * extended by ME_ExtendAnchorSelection */
+      ME_EnsureVisible(editor, editor->pCursors[1].pRun);
   } else {
-      SendMessageW(editor->hWnd, EM_SCROLLCARET, 0, 0);
+      ME_EnsureVisible(editor, editor->pCursors[0].pRun);
   }
 
   ME_InvalidateSelection(editor);
@@ -1571,11 +1566,9 @@ void ME_SendSelChange(ME_TextEditor *editor)
 
   if (!(editor->nEventMask & ENM_SELCHANGE))
     return;
-  
-  sc.nmhdr.hwndFrom = editor->hWnd;
-  sc.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
+
   sc.nmhdr.code = EN_SELCHANGE;
-  SendMessageW(editor->hWnd, EM_EXGETSEL, 0, (LPARAM)&sc.chrg);
+  ME_GetSelection(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
   sc.seltyp = SEL_EMPTY;
   if (sc.chrg.cpMin != sc.chrg.cpMax)
     sc.seltyp |= SEL_TEXT;
index ce986ed..b26222d 100644 (file)
@@ -334,7 +334,7 @@ static HGLOBAL get_unicode_text(ME_TextEditor *editor, const CHARRANGE *lpchrg)
     pars = ME_CountParagraphsBetween(editor, lpchrg->cpMin, lpchrg->cpMax);
     len = lpchrg->cpMax-lpchrg->cpMin;
     ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR)*(len+pars+1));
-    data = (WCHAR *)GlobalLock(ret);
+    data = GlobalLock(ret);
     len = ME_GetTextW(editor, data, lpchrg->cpMin, len, TRUE);
     data[len] = 0;
     GlobalUnlock(ret);
@@ -359,7 +359,7 @@ static DWORD CALLBACK ME_AppendToHGLOBAL(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG
         int nNewSize = (((nMaxSize+cb+1)|0x1FFFF)+1) & 0xFFFE0000;
         pData->hData = GlobalReAlloc(pData->hData, nNewSize, 0);
     }
-    pDest = (BYTE *)GlobalLock(pData->hData);
+    pDest = GlobalLock(pData->hData);
     memcpy(pDest + pData->nLength, lpBuff, cb);
     pData->nLength += cb;
     pDest[pData->nLength] = '\0';
index f26b367..c93a1e4 100644 (file)
@@ -99,6 +99,7 @@
   - EM_SETFONTSIZE
   - EM_SETIMECOLOR 1.0asian
   - EM_SETIMEOPTIONS 1.0asian
+  - EM_SETIMESTATUS
   - EM_SETLANGOPTIONS 2.0
   - EM_SETLIMITTEXT
   - EM_SETMARGINS
@@ -1425,7 +1426,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
     ME_DisplayItem *para_item;
     style = editor->pBuffer->pDefaultStyle;
     ME_AddRefStyle(style);
-    SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);    
+    ME_SetSelection(editor, 0, 0);
     ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE);
     from = to = 0;
     ME_ClearTempStyle(editor);
@@ -1469,7 +1470,6 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
       memset(&parser, 0, sizeof parser);
       RTFSetEditStream(&parser, &inStream);
       parser.rtfFormat = format&(SF_TEXT|SF_RTF);
-      parser.hwndEdit = editor->hWnd;
       parser.editor = editor;
       parser.style = style;
       WriterInit(&parser);
@@ -1559,7 +1559,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
     ME_GetSelection(editor, &to, &to2);
     /* put the cursor at the top */
     if (!(format & SFF_SELECTION))
-      SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
+      ME_SetSelection(editor, 0, 0);
   }
 
   /* Restore saved undo mode */
@@ -1938,6 +1938,73 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
   return -1;
 }
 
+static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText)
+{
+    int nStart, nCount; /* in chars */
+
+    if (ex->flags & ~(GT_SELECTION | GT_USECRLF))
+      FIXME("GETTEXTEX flags 0x%08x not supported\n", ex->flags & ~(GT_SELECTION | GT_USECRLF));
+
+    if (ex->flags & GT_SELECTION)
+    {
+      ME_GetSelection(editor, &nStart, &nCount);
+      nCount -= nStart;
+    }
+    else
+    {
+      nStart = 0;
+      nCount = 0x7fffffff;
+    }
+    if (ex->codepage == 1200)
+    {
+      nCount = min(nCount, ex->cb / sizeof(WCHAR) - 1);
+      return ME_GetTextW(editor, (LPWSTR)pText, nStart, nCount, ex->flags & GT_USECRLF);
+    }
+    else
+    {
+      /* potentially each char may be a CR, why calculate the exact value with O(N) when
+        we can just take a bigger buffer? :)
+        The above assumption still holds with CR/LF counters, since CR->CRLF expansion
+        occurs only in richedit 2.0 mode, in which line breaks have only one CR
+       */
+      int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
+      LPWSTR buffer;
+      DWORD buflen = ex->cb;
+      LRESULT rc;
+      DWORD flags = 0;
+
+      nCount = min(nCount, ex->cb - 1);
+      buffer = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
+
+      buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags & GT_USECRLF);
+      rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen+1,
+                               (LPSTR)pText, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
+      if (rc) rc--; /* do not count 0 terminator */
+
+      heap_free(buffer);
+      return rc;
+    }
+}
+
+static int ME_GetTextRange(ME_TextEditor *editor, TEXTRANGEW *rng, BOOL unicode)
+{
+    if (unicode)
+      return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin,
+                         rng->chrg.cpMax-rng->chrg.cpMin, 0);
+    else
+    {
+      int nLen = rng->chrg.cpMax-rng->chrg.cpMin;
+      WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
+      int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, 0);
+      /* FIXME this is a potential security hole (buffer overrun)
+         if you know more about wchar->mbyte conversion please explain
+      */
+      WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)rng->lpstrText, nLen+1, NULL, NULL);
+      FREE_OBJ(p);
+      return nChars;
+    }
+}
+
 typedef struct tagME_GlobalDestStruct
 {
   HGLOBAL hData;
@@ -1952,7 +2019,7 @@ static DWORD CALLBACK ME_ReadFromHGLOBALUnicode(DWORD_PTR dwCookie, LPBYTE lpBuf
 
   cb = cb >> 1;
   pDest = (WORD *)lpBuff;
-  pSrc = (WORD *)GlobalLock(pData->hData);
+  pSrc = GlobalLock(pData->hData);
   for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
     pDest[i] = pSrc[pData->nLength+i];
   }
@@ -1969,7 +2036,7 @@ static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, L
   BYTE *pSrc, *pDest;
 
   pDest = lpBuff;
-  pSrc = (BYTE *)GlobalLock(pData->hData);
+  pSrc = GlobalLock(pData->hData);
   for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
     pDest[i] = pSrc[pData->nLength+i];
   }
@@ -2178,10 +2245,176 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
   return FALSE;
 }
 
+static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
+                       LPARAM flags, BOOL unicode)
+{
+  WCHAR wstr;
+
+  if (unicode)
+      wstr = (WCHAR)charCode;
+  else
+  {
+      CHAR charA = charCode;
+      MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1);
+  }
+
+  if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) {
+    MessageBeep(MB_ICONERROR);
+    return 0; /* FIXME really 0 ? */
+  }
+
+  if (((unsigned)wstr)>=' '
+      || (wstr=='\r' && (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE))
+      || wstr=='\t') {
+    ME_Cursor cursor = editor->pCursors[0];
+    ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
+    int from, to;
+    BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
+    ME_GetSelection(editor, &from, &to);
+    if (wstr=='\t'
+        /* v4.1 allows tabs to be inserted with ctrl key down */
+        && !(ctrl_is_down && !editor->bEmulateVersion10)
+        )
+    {
+      ME_DisplayItem *para;
+      BOOL bSelectedRow = FALSE;
+
+      para = ME_GetParagraph(cursor.pRun);
+      if (ME_IsSelection(editor) &&
+          cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
+          to == ME_GetCursorOfs(editor, 0) &&
+          para->member.para.prev_para->type == diParagraph)
+      {
+        para = para->member.para.prev_para;
+        bSelectedRow = TRUE;
+      }
+      if (ME_IsInTable(para))
+      {
+        ME_TabPressedInTable(editor, bSelectedRow);
+        ME_CommitUndo(editor);
+        return 0;
+      }
+    } else if (!editor->bEmulateVersion10) { /* v4.1 */
+      if (para->member.para.nFlags & MEPF_ROWEND) {
+        if (wstr=='\r') {
+          /* Add a new table row after this row. */
+          para = ME_AppendTableRow(editor, para);
+          para = para->member.para.next_para;
+          editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+          editor->pCursors[0].nOffset = 0;
+          editor->pCursors[1] = editor->pCursors[0];
+          ME_CommitUndo(editor);
+          ME_CheckTablesForCorruption(editor);
+          ME_UpdateRepaint(editor);
+          return 0;
+        } else if (from == to) {
+          para = para->member.para.next_para;
+          if (para->member.para.nFlags & MEPF_ROWSTART)
+            para = para->member.para.next_para;
+          editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+          editor->pCursors[0].nOffset = 0;
+          editor->pCursors[1] = editor->pCursors[0];
+        }
+      }
+      else if (para == ME_GetParagraph(editor->pCursors[1].pRun) &&
+               cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 &&
+               para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART &&
+               !para->member.para.prev_para->member.para.nCharOfs)
+      {
+        /* Insert a newline before the table. */
+        WCHAR endl = '\r';
+        para = para->member.para.prev_para;
+        para->member.para.nFlags &= ~MEPF_ROWSTART;
+        editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+        editor->pCursors[1] = editor->pCursors[0];
+        ME_InsertTextFromCursor(editor, 0, &endl, 1,
+                                editor->pCursors[0].pRun->member.run.style);
+        para = editor->pBuffer->pFirst->member.para.next_para;
+        ME_SetDefaultParaFormat(para->member.para.pFmt);
+        para->member.para.nFlags = MEPF_REWRAP;
+        editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+        editor->pCursors[1] = editor->pCursors[0];
+        para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART;
+        ME_CommitCoalescingUndo(editor);
+        ME_CheckTablesForCorruption(editor);
+        ME_UpdateRepaint(editor);
+        return 0;
+      }
+    } else { /* v1.0 - 3.0 */
+      ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
+      if (ME_IsInTable(cursor.pRun))
+      {
+        if (cursor.pRun->member.run.nFlags & MERF_ENDPARA)
+        {
+          if (from == to) {
+            if (wstr=='\r') {
+              ME_ContinueCoalescingTransaction(editor);
+              para = ME_AppendTableRow(editor, para);
+              editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+              editor->pCursors[0].nOffset = 0;
+              editor->pCursors[1] = editor->pCursors[0];
+              ME_CommitCoalescingUndo(editor);
+              ME_UpdateRepaint(editor);
+            } else {
+              /* Text should not be inserted at the end of the table. */
+              MessageBeep(-1);
+            }
+            return 0;
+          }
+        } else if (wstr == '\r') {
+          ME_ContinueCoalescingTransaction(editor);
+          if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
+              !ME_IsInTable(para->member.para.prev_para))
+          {
+            /* Insert newline before table */
+            WCHAR endl = '\r';
+            cursor.pRun = ME_FindItemBack(para, diRun);
+            if (cursor.pRun)
+              editor->pCursors[0].pRun = cursor.pRun;
+            editor->pCursors[0].nOffset = 0;
+            editor->pCursors[1] = editor->pCursors[0];
+            ME_InsertTextFromCursor(editor, 0, &endl, 1,
+                                    editor->pCursors[0].pRun->member.run.style);
+          } else {
+            editor->pCursors[1] = editor->pCursors[0];
+            para = ME_AppendTableRow(editor, para);
+            editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+            editor->pCursors[0].nOffset = 0;
+            editor->pCursors[1] = editor->pCursors[0];
+          }
+          ME_CommitCoalescingUndo(editor);
+          ME_UpdateRepaint(editor);
+          return 0;
+        }
+      }
+    }
+    /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */
+    /* WM_CHAR is restricted to nTextLimit */
+    if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
+    {
+      ME_Style *style = ME_GetInsertStyle(editor, 0);
+      ME_SaveTempStyle(editor);
+      ME_ContinueCoalescingTransaction(editor);
+      if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000))
+        ME_InsertEndRowFromCursor(editor, 0);
+      else
+        ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
+      ME_ReleaseStyle(style);
+      ME_CommitCoalescingUndo(editor);
+      SetCursor(NULL);
+    }
+
+    if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
+
+    ME_UpdateRepaint(editor);
+  }
+  return 0;
+}
+
 /* Process the message and calculate the new click count.
  *
  * returns: The click count if it is mouse down event, else returns 0. */
-static int ME_CalculateClickCount(HWND hWnd, UINT msg, WPARAM wParam,
+static int ME_CalculateClickCount(ME_TextEditor *editor, UINT msg, WPARAM wParam,
                                   LPARAM lParam)
 {
     static int clickNum = 0;
@@ -2203,7 +2436,9 @@ static int ME_CalculateClickCount(HWND hWnd, UINT msg, WPARAM wParam,
     {
         static MSG prevClickMsg;
         MSG clickMsg;
-        clickMsg.hwnd = hWnd;
+        /* Compare the editor instead of the hwnd so that the this
+         * can still be done for windowless richedit controls. */
+        clickMsg.hwnd = (HWND)editor;
         clickMsg.message = msg;
         clickMsg.wParam = wParam;
         clickMsg.lParam = lParam;
@@ -2257,9 +2492,26 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
   }
   ScreenToClient(editor->hWnd, &pt);
 
-  if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_SELECTIONBAR) &&
-      (pt.x < editor->selofs ||
-       (editor->nSelectionType == stLine && GetCapture() == editor->hWnd)))
+  if (editor->nSelectionType == stLine && GetCapture() == editor->hWnd) {
+      SetCursor(hLeft);
+      return TRUE;
+  }
+  if (!editor->bEmulateVersion10 /* v4.1 */ &&
+      pt.y < editor->rcFormat.top &&
+      pt.x < editor->rcFormat.left)
+  {
+      SetCursor(hLeft);
+      return TRUE;
+  }
+  if (pt.y < editor->rcFormat.top || pt.y > editor->rcFormat.bottom)
+  {
+      if (editor->bEmulateVersion10) /* v1.0 - 3.0 */
+          SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW));
+      else /* v4.1 */
+          SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_IBEAM));
+      return TRUE;
+  }
+  if (pt.x < editor->rcFormat.left)
   {
       SetCursor(hLeft);
       return TRUE;
@@ -2295,6 +2547,16 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
   return TRUE;
 }
 
+static void ME_SetDefaultFormatRect(ME_TextEditor *editor)
+{
+  DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE);
+
+  GetClientRect(editor->hWnd, &editor->rcFormat);
+  editor->rcFormat.top += (exstyle & WS_EX_CLIENTEDGE ? 1 : 0);
+  editor->rcFormat.left += 1 + editor->selofs;
+  editor->rcFormat.right -= 1;
+}
+
 static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
 {
   CHARRANGE selrange;
@@ -2343,7 +2605,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
   ed->pCursors[2] = ed->pCursors[0];
   ed->pCursors[3] = ed->pCursors[1];
   ed->nLastTotalLength = ed->nTotalLength = 0;
-  ed->nHeight = 0;
   ed->nUDArrowX = -1;
   ed->nSequence = 0;
   ed->rgbBackColor = -1;
@@ -2379,6 +2640,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
     ed->selofs = SELECTIONBAR_WIDTH;
   else
     ed->selofs = 0;
+  ed->bDefaultFormatRect = TRUE;
   ed->nSelectionType = stPosition;
 
   if (GetWindowLongW(hWnd, GWL_STYLE) & ES_PASSWORD)
@@ -2462,11 +2724,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 }
 
 
-#define UNSUPPORTED_MSG(e) \
-  case e: \
-    FIXME(#e ": stub\n"); \
-    return DefWindowProcW(hWnd, msg, wParam, lParam);
-
 static const char * const edit_messages[] = {
   "EM_GETSEL",
   "EM_SETSEL",
@@ -2507,7 +2764,9 @@ static const char * const edit_messages[] = {
   "EM_GETMARGINS",
   "EM_GETLIMITTEXT",
   "EM_POSFROMCHAR",
-  "EM_CHARFROMPOS"
+  "EM_CHARFROMPOS",
+  "EM_SETIMESTATUS",
+  "EM_GETIMESTATUS"
 };
 
 static const char * const richedit_messages[] = {
@@ -2604,18 +2863,60 @@ get_msg_name(UINT msg)
 static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
                                       LPARAM lParam, BOOL unicode)
 {
-  ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
-  
-  TRACE("hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
+  ME_TextEditor *editor;
+  HRESULT hresult;
+  LRESULT lresult;
+
+  TRACE("enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
         hWnd, msg, get_msg_name(msg), wParam, lParam, unicode);
-  
-  if (!editor && msg != WM_NCCREATE && msg != WM_NCDESTROY) {
-    ERR("called with invalid hWnd %p - application bug?\n", hWnd);
-    return 0; 
+
+  editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
+  if (!editor)
+  {
+    if (msg == WM_NCCREATE)
+    {
+      CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
+      TRACE("WM_NCCREATE: style 0x%08x\n", pcs->style);
+      editor = ME_MakeEditor(hWnd);
+      SetWindowLongPtrW(hWnd, 0, (LONG_PTR)editor);
+      return TRUE;
+    }
+    else if (msg != WM_NCDESTROY)
+    {
+      ERR("called with invalid hWnd %p - application bug?\n", hWnd);
+      return 0;
+    }
   }
 
+  lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
+
+  if (hresult == S_FALSE)
+    lresult = DefWindowProcW(hWnd, msg, wParam, lParam);
+
+  TRACE("exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n",
+        hWnd, msg, get_msg_name(msg), wParam, lParam, unicode, lresult);
+
+  return lresult;
+}
+
+#define UNSUPPORTED_MSG(e) \
+  case e:                  \
+    FIXME(#e ": stub\n");  \
+    *phresult = S_FALSE;   \
+    return 0;
+
+/* Handle messages for windowless and windoweded richedit controls.
+ *
+ * The LRESULT that is returned is a return value for window procs,
+ * and the phresult parameter is the COM return code needed by the
+ * text services interface. */
+LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
+                         LPARAM lParam, BOOL unicode, HRESULT* phresult)
+{
+  *phresult = S_OK;
+
   switch(msg) {
-  
+
   UNSUPPORTED_MSG(EM_DISPLAYBAND)
   UNSUPPORTED_MSG(EM_FINDWORDBREAK)
   UNSUPPORTED_MSG(EM_FMTLINES)
@@ -2623,7 +2924,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   UNSUPPORTED_MSG(EM_GETBIDIOPTIONS)
   UNSUPPORTED_MSG(EM_GETEDITSTYLE)
   UNSUPPORTED_MSG(EM_GETIMECOMPMODE)
-  /* UNSUPPORTED_MSG(EM_GETIMESTATUS) missing in Wine headers */
+  UNSUPPORTED_MSG(EM_GETIMESTATUS)
+  UNSUPPORTED_MSG(EM_SETIMESTATUS)
   UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
   /* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
   UNSUPPORTED_MSG(EM_GETREDONAME)
@@ -2658,7 +2960,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     {
       int vk = (int)((LPMSG)lParam)->wParam;
       /* if style says we want return key */
-      if((vk == VK_RETURN) && (GetWindowLongW(hWnd, GWL_STYLE) & ES_WANTRETURN))
+      if((vk == VK_RETURN) && (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_WANTRETURN))
       {
         code |= DLGC_WANTMESSAGE;
       }
@@ -2670,14 +2972,6 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     }
     return code;
   }
-  case WM_NCCREATE:
-  {
-    CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
-    TRACE("WM_NCCREATE: style 0x%08x\n", pcs->style);
-    editor = ME_MakeEditor(hWnd);
-    SetWindowLongPtrW(hWnd, 0, (LONG_PTR)editor);
-    return TRUE;
-  }
   case EM_EMPTYUNDOBUFFER:
     ME_EmptyUndoStack(editor);
     return 0;
@@ -2723,8 +3017,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   {
     /* these flags are equivalent to the ES_* counterparts */
     DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
-                 ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN;
-    DWORD settings = GetWindowLongW(hWnd, GWL_STYLE) & mask;
+                 ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
+    DWORD settings = GetWindowLongW(editor->hWnd, GWL_STYLE) & mask;
 
     return settings;
   }
@@ -2736,8 +3030,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
      */
     DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
                  ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
-    DWORD raw = GetWindowLongW(hWnd, GWL_STYLE);
+    DWORD raw = GetWindowLongW(editor->hWnd, GWL_STYLE);
     DWORD settings = mask & raw;
+    DWORD oldSettings = settings;
+    DWORD changedSettings;
 
     switch(wParam)
     {
@@ -2753,15 +3049,23 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
       case ECOOP_XOR:
         settings ^= lParam;
     }
-    SetWindowLongW(hWnd, GWL_STYLE, (raw & ~mask) | (settings & mask));
+    SetWindowLongW(editor->hWnd, GWL_STYLE, (raw & ~mask) | (settings & mask));
+
+    changedSettings = oldSettings ^ settings;
 
     if (settings & ECO_AUTOWORDSELECTION)
       FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
-    if (settings & ECO_SELECTIONBAR)
+
+    if (oldSettings ^ settings) {
+      if (settings & ECO_SELECTIONBAR) {
         editor->selofs = SELECTIONBAR_WIDTH;
-    else
+        editor->rcFormat.left += SELECTIONBAR_WIDTH;
+      } else {
         editor->selofs = 0;
-    ME_WrapMarkedParagraphs(editor);
+        editor->rcFormat.left -= SELECTIONBAR_WIDTH;
+      }
+      ME_WrapMarkedParagraphs(editor);
+    }
 
     if (settings & ECO_VERTICAL)
       FIXME("ECO_VERTICAL not implemented yet!\n");
@@ -2895,8 +3199,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
       editor->rgbBackColor = lParam;
       editor->hbrBackground = CreateSolidBrush(editor->rgbBackColor);
     }
-    InvalidateRect(hWnd, NULL, TRUE);
-    UpdateWindow(hWnd);
+    InvalidateRect(editor->hWnd, NULL, TRUE);
+    UpdateWindow(editor->hWnd);
     return lColor;
   }
   case EM_GETMODIFY:
@@ -2912,12 +3216,12 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   }
   case EM_SETREADONLY:
   {
-    long nStyle = GetWindowLongW(hWnd, GWL_STYLE);
+    long nStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
     if (wParam)
       nStyle |= ES_READONLY;
     else
       nStyle &= ~ES_READONLY;
-    SetWindowLongW(hWnd, GWL_STYLE, nStyle);
+    SetWindowLongW(editor->hWnd, GWL_STYLE, nStyle);
     return 0;
   }
   case EM_SETEVENTMASK:
@@ -3060,23 +3364,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     return len;
   }
   case EM_SCROLLCARET:
-  {
-    int top, bottom; /* row's edges relative to document top */
-    int nPos;
-    ME_DisplayItem *para, *row;
-    
-    nPos = ME_GetYScrollPos(editor);
-    row = ME_RowStart(editor->pCursors[0].pRun);
-    para = ME_GetParagraph(row);
-    top = para->member.para.pt.y + row->member.row.pt.y;
-    bottom = top + row->member.row.nHeight;
-    
-    if (top < nPos) /* caret above window */
-      ME_ScrollAbs(editor,  top);
-    else if (nPos + editor->sizeWindow.cy < bottom) /*below*/
-      ME_ScrollAbs(editor, bottom - editor->sizeWindow.cy);
+    ME_EnsureVisible(editor, editor->pCursors[0].pRun);
     return 0;
-  }
   case WM_SETFONT:
   {
     LOGFONTW lf;
@@ -3087,9 +3376,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     if (!wParam)
       wParam = (WPARAM)GetStockObject(SYSTEM_FONT); 
     GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf);
-    hDC = GetDC(hWnd);
+    hDC = GetDC(editor->hWnd);
     ME_CharFormatFromLogFont(hDC, &lf, &fmt); 
-    ReleaseDC(hWnd, hDC);   
+    ReleaseDC(editor->hWnd, hDC);
     ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), &fmt);
     ME_SetDefaultCharFormat(editor, &fmt);
 
@@ -3118,7 +3407,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
           int len = -1;
 
           /* uses default style! */
-          if (!(GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE))
+          if (!(GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE))
           {
             WCHAR * p;
 
@@ -3198,12 +3487,13 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     ex.codepage = unicode ? 1200 : CP_ACP;
     ex.lpDefaultChar = NULL;
     ex.lpUsedDefChar = NULL;
-    rc = RichEditWndProc_common(hWnd, EM_GETTEXTEX, (WPARAM)&ex, unicode ? (LPARAM)bufferW : (LPARAM)bufferA, unicode);
+
+    rc = ME_GetTextEx(editor, &ex, unicode ? (LPARAM)bufferW : (LPARAM)bufferA);
 
     if (unicode)
     {
         memcpy((LPWSTR)lParam, bufferW, wParam * sizeof(WCHAR));
-        if (lstrlenW(bufferW) >= wParam) rc = 0;
+        if (strlenW(bufferW) >= wParam) rc = 0;
     }
     else
     {
@@ -3215,52 +3505,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     return rc;
   }
   case EM_GETTEXTEX:
-  {
-    GETTEXTEX *ex = (GETTEXTEX*)wParam;
-    int nStart, nCount; /* in chars */
-
-    if (ex->flags & ~(GT_SELECTION | GT_USECRLF))
-      FIXME("GETTEXTEX flags 0x%08x not supported\n", ex->flags & ~(GT_SELECTION | GT_USECRLF));
-
-    if (ex->flags & GT_SELECTION)
-    {
-      ME_GetSelection(editor, &nStart, &nCount);
-      nCount -= nStart;
-    }
-    else
-    {
-      nStart = 0;
-      nCount = 0x7fffffff;
-    }
-    if (ex->codepage == 1200)
-    {
-      nCount = min(nCount, ex->cb / sizeof(WCHAR) - 1);
-      return ME_GetTextW(editor, (LPWSTR)lParam, nStart, nCount, ex->flags & GT_USECRLF);
-    }
-    else
-    {
-      /* potentially each char may be a CR, why calculate the exact value with O(N) when
-        we can just take a bigger buffer? :)
-        The above assumption still holds with CR/LF counters, since CR->CRLF expansion
-        occurs only in richedit 2.0 mode, in which line breaks have only one CR
-       */
-      int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
-      LPWSTR buffer;
-      DWORD buflen = ex->cb;
-      LRESULT rc;
-      DWORD flags = 0;
-
-      nCount = min(nCount, ex->cb - 1);
-      buffer = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
-
-      buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags & GT_USECRLF);
-      rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen+1, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
-      if (rc) rc--; /* do not count 0 terminator */
-
-      heap_free(buffer);
-      return rc;
-    }
-  }
+    return ME_GetTextEx(editor, (GETTEXTEX*)wParam, lParam);
   case EM_GETSELTEXT:
   {
     int from, to;
@@ -3269,7 +3514,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     tr.chrg.cpMin = from;
     tr.chrg.cpMax = to;
     tr.lpstrText = (WCHAR *)lParam;
-    return RichEditWndProc_common(hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr, unicode);
+    return ME_GetTextRange(editor, &tr, unicode);
   }
   case EM_GETSCROLLPOS:
   {
@@ -3284,20 +3529,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d emul1.0=%d length=%d\n",
       rng->chrg.cpMin, rng->chrg.cpMax, unicode,
       editor->bEmulateVersion10, ME_GetTextLength(editor));
-    if (unicode)
-      return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, 0);
-    else
-    {
-      int nLen = rng->chrg.cpMax-rng->chrg.cpMin;
-      WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
-      int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, 0);
-      /* FIXME this is a potential security hole (buffer overrun) 
-         if you know more about wchar->mbyte conversion please explain
-      */
-      WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)rng->lpstrText, nLen+1, NULL, NULL);
-      FREE_OBJ(p);
-      return nChars;
-    }
+    return ME_GetTextRange(editor, rng, unicode);
   }
   case EM_GETLINE:
   {
@@ -3338,7 +3570,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     {
       if (run && (run->member.run.nFlags & MERF_ENDPARA))
       {
-        unsigned int i;
+        int i;
         /* Write as many \r as encoded in end-of-paragraph, space allowing */
         for (i = 0; i < run->member.run.nCR && nCharsLeft > 0; i++, nCharsLeft--)
         {
@@ -3544,18 +3776,16 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
         nCharOfs = lParam;
     nLength = ME_GetTextLength(editor);
     nCharOfs = min(nCharOfs, nLength);
+    nCharOfs = max(nCharOfs, 0);
 
     ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
     assert(pRun->type == diRun);
     pt.y = pRun->member.run.pt.y;
     pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset);
-    pt.y += ME_GetParagraph(pRun)->member.para.pt.y;
-    pt.x += editor->selofs;
-    pt.x++; /* for some reason native offsets x by one */
+    pt.y += ME_GetParagraph(pRun)->member.para.pt.y + editor->rcFormat.top;
+    pt.x += editor->rcFormat.left;
 
-    si.cbSize = sizeof(si);
-    si.fMask = SIF_POS;
-    if (GetScrollInfo(editor->hWnd, SB_VERT, &si)) pt.y -= si.nPos;
+    pt.y -= editor->vert_si.nPos;
     si.cbSize = sizeof(si);
     si.fMask = SIF_POS;
     if (GetScrollInfo(editor->hWnd, SB_HORZ, &si)) pt.x -= si.nPos;
@@ -3569,20 +3799,20 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   {
     SCROLLINFO si;
 
-    GetClientRect(hWnd, &editor->rcFormat);
-    if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL)
+    ME_SetDefaultFormatRect(editor);
+    if (GetWindowLongW(editor->hWnd, GWL_STYLE) & WS_HSCROLL)
     { /* Squelch the default horizontal scrollbar it would make */
       ShowScrollBar(editor->hWnd, SB_HORZ, FALSE);
     }
 
     si.cbSize = sizeof(si);
     si.fMask = SIF_PAGE | SIF_RANGE;
-    if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
+    if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
       si.fMask |= SIF_DISABLENOSCROLL;
     si.nMax = (si.fMask & SIF_DISABLENOSCROLL) ? 1 : 0;
     si.nMin = 0;
     si.nPage = 0;
-    SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
+    SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
 
     ME_CommitUndo(editor);
     ME_WrapMarkedParagraphs(editor);
@@ -3591,7 +3821,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   }
   case WM_DESTROY:
     ME_DestroyEditor(editor);
-    SetWindowLongPtrW(hWnd, 0, 0);
+    SetWindowLongPtrW(editor->hWnd, 0, 0);
     return 0;
   case WM_SETCURSOR:
   {
@@ -3604,10 +3834,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
         !ME_FilterEvent(editor, msg, &wParam, &lParam))
       return 0;
-    SetFocus(hWnd);
+    SetFocus(editor->hWnd);
     ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam),
-                   ME_CalculateClickCount(hWnd, msg, wParam, lParam));
-    SetCapture(hWnd);
+                   ME_CalculateClickCount(editor, msg, wParam, lParam));
+    SetCapture(editor->hWnd);
     ME_LinkNotify(editor,msg,wParam,lParam);
     if (!ME_SetCursor(editor)) goto do_default;
     break;
@@ -3616,15 +3846,15 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
         !ME_FilterEvent(editor, msg, &wParam, &lParam))
       return 0;
-    if (GetCapture() == hWnd)
+    if (GetCapture() == editor->hWnd)
       ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
     ME_LinkNotify(editor,msg,wParam,lParam);
     /* Set cursor if mouse is captured, since WM_SETCURSOR won't be received. */
-    if (GetCapture() == hWnd)
+    if (GetCapture() == editor->hWnd)
         ME_SetCursor(editor);
     break;
   case WM_LBUTTONUP:
-    if (GetCapture() == hWnd)
+    if (GetCapture() == editor->hWnd)
       ReleaseCapture();
     if (editor->nSelectionType == stDocument)
       editor->nSelectionType = stPosition;
@@ -3651,11 +3881,39 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   case WM_PAINT:
     {
       HDC hDC;
+      RECT rc;
       PAINTSTRUCT ps;
 
-      hDC = BeginPaint(hWnd, &ps);
+      hDC = BeginPaint(editor->hWnd, &ps);
+      /* Erase area outside of the formatting rectangle */
+      if (ps.rcPaint.top < editor->rcFormat.top)
+      {
+        rc = ps.rcPaint;
+        rc.bottom = editor->rcFormat.top;
+        FillRect(hDC, &rc, editor->hbrBackground);
+        ps.rcPaint.top = editor->rcFormat.top;
+      }
+      if (ps.rcPaint.bottom > editor->rcFormat.bottom) {
+        rc = ps.rcPaint;
+        rc.top = editor->rcFormat.bottom;
+        FillRect(hDC, &rc, editor->hbrBackground);
+        ps.rcPaint.bottom = editor->rcFormat.bottom;
+      }
+      if (ps.rcPaint.left < editor->rcFormat.left) {
+        rc = ps.rcPaint;
+        rc.right = editor->rcFormat.left;
+        FillRect(hDC, &rc, editor->hbrBackground);
+        ps.rcPaint.left = editor->rcFormat.left;
+      }
+      if (ps.rcPaint.right > editor->rcFormat.right) {
+        rc = ps.rcPaint;
+        rc.left = editor->rcFormat.right;
+        FillRect(hDC, &rc, editor->hbrBackground);
+        ps.rcPaint.right = editor->rcFormat.right;
+      }
+
       ME_PaintContent(editor, hDC, FALSE, &ps.rcPaint);
-      EndPaint(hWnd, &ps);
+      EndPaint(editor->hWnd, &ps);
     }
     break;
   case WM_SETFOCUS:
@@ -3673,7 +3931,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   {
     HDC hDC = (HDC)wParam;
     RECT rc;
-    if (GetUpdateRect(hWnd,&rc,TRUE))
+    if (GetUpdateRect(editor->hWnd,&rc,TRUE))
     {
       FillRect(hDC, &rc, editor->hbrBackground);
     }
@@ -3694,170 +3952,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     if (ME_KeyDown(editor, LOWORD(wParam)))
       return 0;
     goto do_default;
-  case WM_CHAR: 
-  {
-    WCHAR wstr;
-
-    if (unicode)
-        wstr = (WCHAR)wParam;
-    else
-    {
-        CHAR charA = wParam;
-        MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1);
-    }
-
-    if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) {
-      MessageBeep(MB_ICONERROR);
-      return 0; /* FIXME really 0 ? */
-    }
-
-    if (((unsigned)wstr)>=' '
-        || (wstr=='\r' && (GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE))
-        || wstr=='\t') {
-      ME_Cursor cursor = editor->pCursors[0];
-      ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
-      int from, to;
-      BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
-      ME_GetSelection(editor, &from, &to);
-      if (wstr=='\t'
-          /* v4.1 allows tabs to be inserted with ctrl key down */
-          && !(ctrl_is_down && !editor->bEmulateVersion10)
-          )
-      {
-        ME_DisplayItem *para;
-        BOOL bSelectedRow = FALSE;
-
-        para = ME_GetParagraph(cursor.pRun);
-        if (ME_IsSelection(editor) &&
-            cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
-            to == ME_GetCursorOfs(editor, 0) &&
-            para->member.para.prev_para->type == diParagraph)
-        {
-          para = para->member.para.prev_para;
-          bSelectedRow = TRUE;
-        }
-        if (ME_IsInTable(para))
-        {
-          ME_TabPressedInTable(editor, bSelectedRow);
-          ME_CommitUndo(editor);
-          return 0;
-        }
-      } else if (!editor->bEmulateVersion10) { /* v4.1 */
-        if (para->member.para.nFlags & MEPF_ROWEND) {
-          if (wstr=='\r') {
-            /* Add a new table row after this row. */
-            para = ME_AppendTableRow(editor, para);
-            para = para->member.para.next_para;
-            editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
-            editor->pCursors[0].nOffset = 0;
-            editor->pCursors[1] = editor->pCursors[0];
-            ME_CommitUndo(editor);
-            ME_CheckTablesForCorruption(editor);
-            ME_UpdateRepaint(editor);
-            return 0;
-          } else if (from == to) {
-            para = para->member.para.next_para;
-            if (para->member.para.nFlags & MEPF_ROWSTART)
-              para = para->member.para.next_para;
-            editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
-            editor->pCursors[0].nOffset = 0;
-            editor->pCursors[1] = editor->pCursors[0];
-          }
-        }
-        else if (para == ME_GetParagraph(editor->pCursors[1].pRun) &&
-                 cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 &&
-                 para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART &&
-                 !para->member.para.prev_para->member.para.nCharOfs)
-        {
-          /* Insert a newline before the table. */
-          WCHAR endl = '\r';
-          para = para->member.para.prev_para;
-          para->member.para.nFlags &= ~MEPF_ROWSTART;
-          editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
-          editor->pCursors[1] = editor->pCursors[0];
-          ME_InsertTextFromCursor(editor, 0, &endl, 1,
-                                  editor->pCursors[0].pRun->member.run.style);
-          para = editor->pBuffer->pFirst->member.para.next_para;
-          ME_SetDefaultParaFormat(para->member.para.pFmt);
-          para->member.para.nFlags = MEPF_REWRAP;
-          editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
-          editor->pCursors[1] = editor->pCursors[0];
-          para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART;
-          ME_CommitCoalescingUndo(editor);
-          ME_CheckTablesForCorruption(editor);
-          ME_UpdateRepaint(editor);
-          return 0;
-        }
-      } else { /* v1.0 - 3.0 */
-        ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
-        if (ME_IsInTable(cursor.pRun))
-        {
-          if (cursor.pRun->member.run.nFlags & MERF_ENDPARA)
-          {
-            if (from == to) {
-              if (wstr=='\r') {
-                ME_ContinueCoalescingTransaction(editor);
-                para = ME_AppendTableRow(editor, para);
-                editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
-                editor->pCursors[0].nOffset = 0;
-                editor->pCursors[1] = editor->pCursors[0];
-                ME_CommitCoalescingUndo(editor);
-                ME_UpdateRepaint(editor);
-              } else {
-                /* Text should not be inserted at the end of the table. */
-                MessageBeep(-1);
-              }
-              return 0;
-            }
-          } else if (wstr == '\r') {
-            ME_ContinueCoalescingTransaction(editor);
-            if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
-                !ME_IsInTable(para->member.para.prev_para))
-            {
-              /* Insert newline before table */
-              WCHAR endl = '\r';
-              cursor.pRun = ME_FindItemBack(para, diRun);
-              if (cursor.pRun)
-                editor->pCursors[0].pRun = cursor.pRun;
-              editor->pCursors[0].nOffset = 0;
-              editor->pCursors[1] = editor->pCursors[0];
-              ME_InsertTextFromCursor(editor, 0, &endl, 1,
-                                      editor->pCursors[0].pRun->member.run.style);
-            } else {
-              editor->pCursors[1] = editor->pCursors[0];
-              para = ME_AppendTableRow(editor, para);
-              editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
-              editor->pCursors[0].nOffset = 0;
-              editor->pCursors[1] = editor->pCursors[0];
-            }
-            ME_CommitCoalescingUndo(editor);
-            ME_UpdateRepaint(editor);
-            return 0;
-          }
-        }
-      }
-      /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */
-      /* WM_CHAR is restricted to nTextLimit */
-      if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
-      {
-        ME_Style *style = ME_GetInsertStyle(editor, 0);
-        ME_SaveTempStyle(editor);
-        ME_ContinueCoalescingTransaction(editor);
-        if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000))
-          ME_InsertEndRowFromCursor(editor, 0);
-        else
-          ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
-        ME_ReleaseStyle(style);
-        ME_CommitCoalescingUndo(editor);
-        SetCursor(NULL);
-      }
-
-      if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
-
-      ME_UpdateRepaint(editor);
-    }
-    return 0;
-  }
+  case WM_CHAR:
+    return ME_Char(editor, wParam, lParam, unicode);
   case WM_UNICHAR:
     if (unicode)
     {
@@ -3867,10 +3963,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
             if(wParam > 0xffff) /* convert to surrogates */
             {
                 wParam -= 0x10000;
-                SendMessageW(editor->hWnd, WM_CHAR, (wParam >> 10) + 0xd800, 0);
-                SendMessageW(editor->hWnd, WM_CHAR, (wParam & 0x03ff) + 0xdc00, 0);
+                ME_Char(editor, (wParam >> 10) + 0xd800, 0, TRUE);
+                ME_Char(editor, (wParam & 0x03ff) + 0xdc00, 0, TRUE);
+            } else {
+              ME_Char(editor, wParam, 0, TRUE);
             }
-            else SendMessageW(editor->hWnd, WM_CHAR, wParam, 0);
         }
         return 0;
     }
@@ -3936,6 +4033,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   case EM_GETRECT:
   {
     *((RECT *)lParam) = editor->rcFormat;
+    if (editor->bDefaultFormatRect)
+      ((RECT *)lParam)->left -= editor->selofs;
     return 0;
   }
   case EM_SETRECT:
@@ -3943,23 +4042,36 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   {
     if (lParam)
     {
+      DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE);
+      int border = (exstyle & WS_EX_CLIENTEDGE) ? 1 : 0;
+      RECT clientRect;
       RECT *rc = (RECT *)lParam;
-      
-      if (wParam)
-      {
-        editor->rcFormat.left += rc->left;
-        editor->rcFormat.top += rc->top;
-        editor->rcFormat.right += rc->right;
-        editor->rcFormat.bottom += rc->bottom;
-      }
-      else
+
+      GetClientRect(editor->hWnd, &clientRect);
+      if (wParam == 0)
       {
-        editor->rcFormat = *rc;
+        editor->rcFormat.top = max(0, rc->top - border);
+        editor->rcFormat.left = max(0, rc->left - border);
+        editor->rcFormat.bottom = min(clientRect.bottom, rc->bottom);
+        editor->rcFormat.right = min(clientRect.right, rc->right + border);
+      } else if (wParam == 1) {
+        /* MSDN incorrectly says a wParam value of 1 causes the
+         * lParam rect to be used as a relative offset,
+         * however, the tests show it just prevents min/max bound
+         * checking. */
+        editor->rcFormat.top = rc->top - border;
+        editor->rcFormat.left = rc->left - border;
+        editor->rcFormat.bottom = rc->bottom;
+        editor->rcFormat.right = rc->right + border;
+      } else {
+        return 0;
       }
+      editor->bDefaultFormatRect = FALSE;
     }
     else
     {
-      GetClientRect(hWnd, &editor->rcFormat);
+      ME_SetDefaultFormatRect(editor);
+      editor->bDefaultFormatRect = TRUE;
     }
     if (msg != EM_SETRECTNP)
       ME_RewrapRepaint(editor);
@@ -3969,12 +4081,21 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     ME_SendRequestResize(editor, TRUE);
     return 0;
   case WM_SETREDRAW:
-    return DefWindowProcW(hWnd, msg, wParam, lParam);
+    goto do_default;
   case WM_SIZE:
   {
-    GetClientRect(hWnd, &editor->rcFormat);
+    RECT clientRect;
+
+    GetClientRect(editor->hWnd, &clientRect);
+    if (editor->bDefaultFormatRect) {
+      ME_SetDefaultFormatRect(editor);
+    } else {
+      editor->rcFormat.right += clientRect.right - editor->prevClientRect.right;
+      editor->rcFormat.bottom += clientRect.bottom - editor->prevClientRect.bottom;
+    }
+    editor->prevClientRect = clientRect;
     ME_RewrapRepaint(editor);
-    return DefWindowProcW(hWnd, msg, wParam, lParam);
+    goto do_default;
   }
   /* IME messages to make richedit controls IME aware */
   case WM_IME_SETCONTEXT:
@@ -3995,7 +4116,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     HIMC hIMC;
 
     ME_Style *style = ME_GetInsertStyle(editor, 0);
-    hIMC = ImmGetContext(hWnd);
+    hIMC = ImmGetContext(editor->hWnd);
     ME_DeleteSelection(editor);
     ME_CommitUndo(editor);
     ME_SaveTempStyle(editor);
@@ -4064,7 +4185,12 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     LRESULT ret;
     int mask = 0;
     int changes = 0;
-    ret = RichEditWndProc_common(hWnd, WM_GETTEXTLENGTH, 0, 0, unicode);
+    GETTEXTLENGTHEX how;
+
+    /* CR/LF conversion required in 2.0 mode, verbatim in 1.0 mode */
+    how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS;
+    how.codepage = unicode ? 1200 : CP_ACP;
+    ret = ME_GetTextLengthEx(editor, &how);
     if (!ret)
     {
       /*Check for valid wParam*/
@@ -4106,7 +4232,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
     break;
   default:
   do_default:
-    return DefWindowProcW(hWnd, msg, wParam, lParam);
+    *phresult = S_FALSE;
+    break;
   }
   return 0L;
 }
@@ -4148,7 +4275,9 @@ LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
   {
     ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
     
+    TRACE("Emulating version 1.0 (hWnd=%p)\n", hWnd);
     editor->bEmulateVersion10 = TRUE;
+    editor->bWordWrap = (GetWindowLongW(hWnd, GWL_STYLE) & ES_AUTOHSCROLL) ? FALSE : TRUE;
     editor->pBuffer->pLast->member.para.nCharOfs = 2;
     assert(editor->pBuffer->pLast->prev->type == diRun);
     assert(editor->pBuffer->pLast->prev->member.run.nFlags & MERF_ENDPARA);
@@ -4329,7 +4458,7 @@ static BOOL ME_RegisterEditorClass(HINSTANCE hInstance)
   wcW.hInstance = NULL; /* hInstance would register DLL-local class */
   wcW.hIcon = NULL;
   wcW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM));
-  wcW.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+  wcW.hbrBackground = GetStockObject(NULL_BRUSH);
   wcW.lpszMenuName = NULL;
 
   if (is_version_nt())
@@ -4355,7 +4484,7 @@ static BOOL ME_RegisterEditorClass(HINSTANCE hInstance)
   wcA.hInstance = NULL; /* hInstance would register DLL-local class */
   wcA.hIcon = NULL;
   wcA.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM));
-  wcA.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+  wcA.hbrBackground = GetStockObject(NULL_BRUSH);
   wcA.lpszMenuName = NULL;
   wcA.lpszClassName = "RichEdit20A";
   if (!RegisterClassA(&wcA)) return FALSE;
@@ -4425,95 +4554,6 @@ LRESULT WINAPI REExtendedRegisterClass(void)
   return result;
 }
 
-int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar) 
-{
-  struct prefix_s {
-    const char *text;
-    int length;
-  } prefixes[12] = {
-    {"http:", 5},
-    {"file:", 6},
-    {"mailto:", 8},
-    {"ftp:", 5},
-    {"https:", 7},
-    {"gopher:", 8},
-    {"nntp:", 6},
-    {"prospero:", 10},
-    {"telnet:", 8},
-    {"news:", 6},
-    {"wais:", 6},
-    {"www.", 5}
-  };
-  CHARRANGE ins_pt;
-  int curf_ef, link_ef, def_ef;
-  int cur_prefx, prefx_cnt;
-  int sel_min, sel_max;
-  int car_pos = 0;
-  int text_pos=-1;
-  int URLmin, URLmax = 0;
-  FINDTEXTA ft;
-  CHARFORMAT2W cur_format;
-  CHARFORMAT2W default_format;
-  CHARFORMAT2W link;
-  RichEditANSIWndProc(editor->hWnd, EM_EXGETSEL, (WPARAM) 0, (LPARAM) &ins_pt);
-  sel_min = ins_pt.cpMin;
-  sel_max = ins_pt.cpMax;
-  if (sel_min==sel_max) 
-    car_pos = sel_min;
-  if (sel_min!=sel_max)
-    car_pos = ME_GetTextLength(editor)+1;   
-  cur_format.cbSize = sizeof(cur_format);
-  default_format.cbSize = sizeof(default_format);
-  RichEditANSIWndProc(editor->hWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cur_format);
-  RichEditANSIWndProc(editor->hWnd, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM) &default_format);
-  link.cbSize = sizeof(link);
-  link.dwMask = CFM_LINK;
-  link.dwEffects = CFE_LINK;
-  curf_ef = cur_format.dwEffects & link.dwEffects;
-  def_ef = default_format.dwEffects & link.dwEffects;
-  link_ef = link.dwEffects & link.dwEffects;
-  if (curf_ef == link_ef) 
-  {
-    if( curChar == '\n' || curChar=='\r' || curChar==' ') 
-    {
-      ME_SetSelection(editor, car_pos, car_pos);
-      RichEditANSIWndProc(editor->hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &default_format);
-      text_pos=-1;
-      return 0;
-    }
-  }
-  if (curf_ef == def_ef)
-  {
-    cur_prefx = 0;
-    prefx_cnt = (sizeof(prefixes)/sizeof(struct prefix_s))-1;
-    while (cur_prefx<=prefx_cnt) 
-    {
-      if (text_pos == -1) 
-      {
-        ft.lpstrText = prefixes[cur_prefx].text;
-        URLmin=max(0,(car_pos-prefixes[cur_prefx].length));
-        URLmax=max(0, car_pos);
-        if ((car_pos == 0) && (ME_GetTextLength(editor) != 0))
-        {
-        URLmax = ME_GetTextLength(editor)+1;
-        }
-        ft.chrg.cpMin = URLmin;
-        ft.chrg.cpMax = URLmax;
-        text_pos=RichEditANSIWndProc(editor->hWnd, EM_FINDTEXT, FR_DOWN, (LPARAM)&ft);   
-        cur_prefx++;
-      }
-      if (text_pos != -1) 
-      {
-        ME_SetCharFormat(editor, text_pos, (URLmax-text_pos), &link);
-        ME_RewrapRepaint(editor);
-        break;
-      }
-    }
-  }
-  return 0;
-}
-
-
 static BOOL isurlspecial(WCHAR c)
 {
   static const WCHAR special_chars[] = {'.','/','%','@','*','|','\\','+','#',0};
@@ -4647,7 +4687,7 @@ BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, int sel_min, int sel_max)
   };
   LPWSTR bufferW = NULL;
   WCHAR bufW[32];
-  int i;
+  unsigned int i;
 
   if (sel_max == -1) sel_max = ME_GetTextLength(editor);
   assert(sel_min <= sel_max);
@@ -4655,9 +4695,9 @@ BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, int sel_min, int sel_max)
   {
     if (sel_max - sel_min < prefixes[i].length) continue;
     if (bufferW == NULL) {
-      bufferW = (LPWSTR)heap_alloc((sel_max - sel_min + 1) * sizeof(WCHAR));
+      bufferW = heap_alloc((sel_max - sel_min + 1) * sizeof(WCHAR));
     }
-    ME_GetTextW(editor, bufferW, sel_min, min(sel_max - sel_min, strlen(prefixes[i].text)), 0);
+    ME_GetTextW(editor, bufferW, sel_min, min(sel_max - sel_min, lstrlenA(prefixes[i].text)), 0);
     MultiByteToWideChar(CP_ACP, 0, prefixes[i].text, -1, bufW, 32);
     if (!lstrcmpW(bufW, bufferW))
     {
index 2c68378..df82073 100644 (file)
@@ -268,11 +268,11 @@ void ME_GetOLEObjectSize(ME_Context *c, ME_Run *run, SIZE *pSize);
 void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src);
 void ME_DeleteReObject(REOBJECT* reo);
 
-/* wintest.c */
-
 /* editor.c */
 ME_TextEditor *ME_MakeEditor(HWND hWnd);
 void ME_DestroyEditor(ME_TextEditor *editor);
+LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
+                         LPARAM lParam, BOOL unicode, HRESULT* phresult);
 void ME_SendOldNotify(ME_TextEditor *editor, int nCode);
 void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam);
 int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);
@@ -282,7 +282,6 @@ void ME_RTFParAttrHook(struct _RTF_Info *info);
 void ME_RTFTblAttrHook(struct _RTF_Info *info);
 void ME_RTFSpecialCharHook(struct _RTF_Info *info);
 void ME_StreamInFill(ME_InStream *stream);
-int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar);
 extern int me_debug;
 extern void DoWrap(ME_TextEditor *editor);
 extern BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_max,
index 248cc02..cde05f9 100644 (file)
@@ -90,7 +90,7 @@ typedef enum {
   diUndoPotentialEndTransaction, /* 20 - allows grouping typed chars for undo */
 } ME_DIType;
 
-#define SELECTIONBAR_WIDTH 9
+#define SELECTIONBAR_WIDTH 8
 
 /******************************** run flags *************************/
 #define MERF_STYLEFLAGS 0x0FFF
@@ -333,7 +333,6 @@ typedef struct tagME_TextEditor
   int nCursors;
   SIZE sizeWindow;
   int nTotalLength, nLastTotalLength;
-  int nHeight;
   int nUDArrowX;
   int nSequence;
   COLORREF rgbBackColor;
@@ -350,7 +349,9 @@ typedef struct tagME_TextEditor
   ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara;
   ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
   int nZoomNumerator, nZoomDenominator;
+  RECT prevClientRect;
   RECT rcFormat;
+  BOOL bDefaultFormatRect;
   BOOL bWordWrap;
   int nInvalidOfs;
   int nTextLimit;
index 40761db..94a1f87 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
 
-void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *rcUpdate) {
+void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *rcUpdate)
+{
   ME_DisplayItem *item;
   ME_Context c;
   int yoffset;
+  int ys, ye;
 
   editor->nSequence++;
   yoffset = ME_GetYScrollPos(editor);
@@ -34,105 +36,70 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
   SetBkMode(hDC, TRANSPARENT);
   ME_MoveCaret(editor); /* Calls ME_WrapMarkedParagraphs */
   item = editor->pBuffer->pFirst->next;
-  c.pt.y -= yoffset;
-  while(item != editor->pBuffer->pLast) {
-    int yTextOffset = 0;
-    int ye;
+  /* This context point is an offset for the paragraph positions stored
+   * during wrapping. It shouldn't be modified during painting. */
+  c.pt.x = c.rcView.left;
+  c.pt.y = c.rcView.top - yoffset;
+  while(item != editor->pBuffer->pLast)
+  {
     assert(item->type == diParagraph);
+
+    ys = c.pt.y + item->member.para.pt.y;
     if (item->member.para.pCell
         != item->member.para.next_para->member.para.pCell)
     {
       ME_Cell *cell = NULL;
       cell = &ME_FindItemBack(item->member.para.next_para, diCell)->member.cell;
-      ye = cell->pt.y + cell->nHeight - yoffset;
+      ye = c.pt.y + cell->pt.y + cell->nHeight;
     } else {
-      ye = c.pt.y + item->member.para.nHeight;
+      ye = ys + item->member.para.nHeight;
     }
-    if (!(item->member.para.nFlags & MEPF_ROWEND) &&
+    if (item->member.para.pCell && !(item->member.para.nFlags & MEPF_ROWEND) &&
         item->member.para.pCell != item->member.para.prev_para->member.para.pCell)
     {
-      ME_DisplayItem *cell;
-      if (item->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART)
-        cell = item->member.para.pCell;
-      else
-        cell = item->member.para.prev_para->member.para.pCell;
-      assert(cell);
       /* the border shifts the text down */
-      yTextOffset = cell->member.cell.yTextOffset;
-      ye += yTextOffset;
+      ys -= item->member.para.pCell->member.cell.yTextOffset;
     }
+
     if (!bOnlyNew || (item->member.para.nFlags & MEPF_REPAINT))
     {
+      /* Draw the pargraph if any of the paragraph is in the update region. */
       BOOL bPaint = (rcUpdate == NULL);
       if (rcUpdate)
-        bPaint = c.pt.y<rcUpdate->bottom && ye>rcUpdate->top;
+        bPaint = ys < rcUpdate->bottom && ye > rcUpdate->top;
       if (bPaint)
       {
-        c.pt.y += yTextOffset;
         ME_DrawParagraph(&c, item);
-        if (!rcUpdate || (rcUpdate->top<=c.pt.y-yTextOffset && rcUpdate->bottom>=ye))
+        /* Clear the repaint flag if the whole paragraph is in the
+         * update region. */
+        if (!rcUpdate || (rcUpdate->top <= ys && rcUpdate->bottom >= ye))
           item->member.para.nFlags &= ~MEPF_REPAINT;
       }
     }
-    if (item->member.para.pCell)
-    {
-      ME_Cell *cell = &item->member.para.pCell->member.cell;
-      ME_DisplayItem *next_para = item->member.para.next_para;
-      c.pt.x = cell->pt.x + cell->nWidth;
-      if (item->member.para.pCell == next_para->member.para.pCell &&
-          !(next_para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND)))
-      {
-        c.pt.y = ye;
-      } else {
-        if (next_para->member.para.nFlags & MEPF_ROWSTART)
-        {
-          cell = &ME_FindItemFwd(next_para, diCell)->member.cell;
-        }
-        else if (next_para->member.para.nFlags & MEPF_ROWEND)
-        {
-          cell = &cell->next_cell->member.cell;
-        }
-        else
-        {
-          cell = &next_para->member.para.pCell->member.cell;
-        }
-        c.pt.y = cell->pt.y - yoffset;
-      }
-    } else if (!(item->member.para.nFlags & MEPF_ROWSTART)) {
-      c.pt.y = ye;
-    }
     item = item->member.para.next_para;
   }
-  if (c.pt.y<c.rcView.bottom) {
+  if (c.pt.y + editor->nTotalLength < c.rcView.bottom)
+  {
+    /* Fill space after the end of the text. */
     RECT rc;
-    int xs = c.rcView.left, xe = c.rcView.right;
-    int ys = c.pt.y, ye = c.rcView.bottom;
-    
+    rc.top = c.pt.y + editor->nTotalLength;
+    rc.left = c.rcView.left;
+    rc.bottom = c.rcView.bottom;
+    rc.right = c.rcView.right;
+
     if (bOnlyNew)
     {
-      int y1 = editor->nTotalLength-yoffset, y2 = editor->nLastTotalLength-yoffset;
-      if (y1<y2)
-        ys = y1, ye = y2+1;
+      /* Only erase region drawn from previous call to ME_PaintContent */
+      if (editor->nTotalLength < editor->nLastTotalLength)
+        rc.bottom = c.pt.y + editor->nLastTotalLength;
       else
-        ys = ye;
-    }
-    
-    if (rcUpdate && ys!=ye)
-    {
-      xs = rcUpdate->left, xe = rcUpdate->right;
-      if (rcUpdate->top > ys)
-        ys = rcUpdate->top;
-      if (rcUpdate->bottom < ye)
-        ye = rcUpdate->bottom;
+        SetRectEmpty(&rc);
     }
 
-    if (ye>ys) {
-      rc.left = xs;
-      rc.top = ys;
-      rc.right = xe;
-      rc.bottom = ye;
+    IntersectRect(&rc, &rc, rcUpdate);
+
+    if (!IsRectEmpty(&rc))
       FillRect(hDC, &rc, c.editor->hbrBackground);
-    }
   }
   if (editor->nTotalLength != editor->nLastTotalLength)
     ME_SendRequestResize(editor, FALSE);
@@ -441,7 +408,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
     if (runofs >= nSelFrom && runofs < nSelTo)
     {
       ME_HighlightSpace(c, x, y, wszSpace, 1, run->style, 0, 0, 1,
-                        c->pt.y + start->member.row.pt.y,
+                        c->pt.y + para->pt.y + start->member.row.pt.y,
                         start->member.row.nHeight);
     }
     return;
@@ -452,8 +419,8 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
     /* wszSpace is used instead of the tab character because otherwise
      * an unwanted symbol can be inserted instead. */
     ME_DrawTextWithStyle(c, x, y, wszSpace, 1, run->style, run->nWidth,
-                         nSelFrom-runofs,nSelTo-runofs,
-                         c->pt.y + start->member.row.pt.y,
+                         nSelFrom-runofs, nSelTo-runofs,
+                         c->pt.y + para->pt.y + start->member.row.pt.y,
                          start->member.row.nHeight);
     return;
   }
@@ -467,13 +434,17 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
       ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText));
       ME_DrawTextWithStyle(c, x, y,
         szMasked->szData, ME_StrVLen(szMasked), run->style, run->nWidth,
-        nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.pt.y, start->member.row.nHeight);
+        nSelFrom-runofs,nSelTo-runofs,
+        c->pt.y + para->pt.y + start->member.row.pt.y,
+        start->member.row.nHeight);
       ME_DestroyString(szMasked);
     }
     else
       ME_DrawTextWithStyle(c, x, y,
         run->strText->szData, ME_StrVLen(run->strText), run->style, run->nWidth,
-        nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.pt.y, start->member.row.nHeight);
+        nSelFrom-runofs,nSelTo-runofs,
+        c->pt.y + para->pt.y + start->member.row.pt.y,
+        start->member.row.nHeight);
   }
 }
 
@@ -728,11 +699,11 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
       int width;
       BOOL atTop = (para->pCell != para->prev_para->member.para.pCell);
       BOOL atBottom = (para->pCell != para->next_para->member.para.pCell);
-      int top = (atTop ? cell->pt.y : para->pt.y) - ME_GetYScrollPos(c->editor);
+      int top = c->pt.y + (atTop ? cell->pt.y : para->pt.y);
       int bottom = (atBottom ?
-                    cell->pt.y + cell->nHeight - ME_GetYScrollPos(c->editor):
+                    c->pt.y + cell->pt.y + cell->nHeight :
                     top + para->nHeight + (atTop ? cell->yTextOffset : 0));
-      rc.left = cell->pt.x;
+      rc.left = c->pt.x + cell->pt.x;
       rc.right = rc.left + cell->nWidth;
       if (atTop) {
         /* Erase gap before text if not all borders are the same height. */
@@ -745,7 +716,7 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
         }
       }
       /* Draw cell borders.
-       * The borders borders are draw in is left, top, bottom, right in order
+       * The order borders are draw in is left, top, bottom, right in order
        * to be consistent with native richedit.  This is noticeable from the
        * overlap of borders of different colours. */
       if (!(para->nFlags & MEPF_ROWEND)) {
@@ -798,10 +769,10 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
           ME_DisplayItem *nextEndCell;
           nextEndCell = ME_FindItemBack(ME_GetTableRowEnd(paraAfterRow), diCell);
           assert(nextEndCell && !nextEndCell->member.cell.next_cell);
-          rc.left = nextEndCell->member.cell.pt.x;
+          rc.left = c->pt.x + nextEndCell->member.cell.pt.x;
           /* FIXME: Native draws FROM the bottom of the table rather than
            * TO the bottom of the table in this case, but just doing so here
-           * will case the next row to erase the border. */
+           * will cause the next row to erase the border. */
           /*
           rc.top = bottom;
           rc.bottom = rc.top + width;
@@ -860,12 +831,12 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
       oldpen = SelectObject(c->hDC, pen);
 
       /* Find the start relative to the text */
-      firstX = ME_FindItemFwd(paragraph, diRun)->member.run.pt.x;
+      firstX = c->pt.x + ME_FindItemFwd(paragraph, diRun)->member.run.pt.x;
       /* Go back by the horizontal gap, which is stored in dxOffset */
       firstX -= ME_twips2pointsX(c, para->pFmt->dxOffset);
       /* The left edge, stored in dxStartIndent affected just the first edge */
       startX = firstX - ME_twips2pointsX(c, para->pFmt->dxStartIndent);
-      rowY = c->pt.y;
+      rowY = c->pt.y + para->pt.y;
       if (para->pFmt->dwMask & PFM_SPACEBEFORE)
         rowY += ME_twips2pointsY(c, para->pFmt->dySpaceBefore);
       nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight;
@@ -907,53 +878,54 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
   }
 }
 
-void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
+void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
+{
   int align = SetTextAlign(c->hDC, TA_BASELINE);
   ME_DisplayItem *p;
   ME_Run *run;
   ME_Paragraph *para = NULL;
   RECT rc, bounds;
-  int y = c->pt.y;
+  int y;
   int height = 0, baseline = 0, no=0;
   BOOL visible = FALSE;
 
-  c->pt.x = c->rcView.left;
-  rc.left = c->rcView.left;
+  rc.left = c->pt.x;
   rc.right = c->rcView.right;
-  for (p = paragraph; p!=paragraph->member.para.next_para; p = p->next) {
+
+  assert(paragraph);
+  para = &paragraph->member.para;
+  y = c->pt.y + para->pt.y;
+  if (para->pCell)
+  {
+    ME_Cell *cell = &para->pCell->member.cell;
+    rc.left = c->pt.x + cell->pt.x;
+    rc.right = rc.left + cell->nWidth;
+  }
+  if (para->nFlags & MEPF_ROWSTART) {
+    ME_Cell *cell = &para->next_para->member.para.pCell->member.cell;
+    rc.right = c->pt.x + cell->pt.x;
+  } else if (para->nFlags & MEPF_ROWEND) {
+    ME_Cell *cell = &para->prev_para->member.para.pCell->member.cell;
+    rc.left = c->pt.x + cell->pt.x + cell->nWidth;
+  }
+  ME_DrawParaDecoration(c, para, y, &bounds);
+  y += bounds.top;
+  rc.left += bounds.left;
+  rc.right -= bounds.right;
+
+  for (p = paragraph->next; p != para->next_para; p = p->next)
+  {
     switch(p->type) {
       case diParagraph:
-        para = &p->member.para;
-        assert(para);
-        if (para->pCell)
-        {
-          ME_Cell *cell = &para->pCell->member.cell;
-          rc.left = cell->pt.x;
-          rc.right = rc.left + cell->nWidth;
-        }
-        if (para->nFlags & MEPF_ROWSTART) {
-          ME_Cell *cell = &para->next_para->member.para.pCell->member.cell;
-          rc.right = cell->pt.x;
-        } else if (para->nFlags & MEPF_ROWEND) {
-          ME_Cell *cell = &para->prev_para->member.para.pCell->member.cell;
-          rc.left = cell->pt.x + cell->nWidth;
-        }
-        ME_DrawParaDecoration(c, para, y, &bounds);
-        y += bounds.top;
+        assert(FALSE);
         break;
       case diStartRow:
-        /* we should have seen a diParagraph before */
-        assert(para);
         y += height;
         rc.top = y;
-        if (para->nFlags & MEPF_ROWSTART) {
-          ME_Cell *cell = &para->next_para->member.para.pCell->member.cell;
-          rc.bottom = y + cell->nHeight;
-        } else if (para->nFlags & MEPF_ROWEND) {
-          ME_Cell *cell = &para->prev_para->member.para.pCell->member.cell;
-          rc.bottom = y + cell->nHeight;
+        if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) {
+          rc.bottom = y + para->nHeight;
         } else {
-          rc.bottom = y+p->member.row.nHeight;
+          rc.bottom = y + p->member.row.nHeight;
         }
         visible = RectVisible(c->hDC, &rc);
         if (visible) {
@@ -976,10 +948,11 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
         assert(para);
         run = &p->member.run;
         if (visible && me_debug) {
-          rc.left = c->rcView.left+run->pt.x;
-          rc.right = c->rcView.left+run->pt.x+run->nWidth;
-          rc.top = c->pt.y+run->pt.y;
-          rc.bottom = c->pt.y+run->pt.y+height;
+          RECT rc;
+          rc.left = c->pt.x + run->pt.x;
+          rc.right = rc.left + run->nWidth;
+          rc.top = c->pt.y + para->pt.y + run->pt.y;
+          rc.bottom = rc.bottom + height;
           TRACE("rc = (%d, %d, %d, %d)\n", rc.left, rc.top, rc.right, rc.bottom);
           if (run->nFlags & MERF_SKIPPED)
             DrawFocusRect(c->hDC, &rc);
@@ -987,28 +960,27 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
             FrameRect(c->hDC, &rc, GetSysColorBrush(COLOR_GRAYTEXT));
         }
         if (visible)
-          ME_DrawRun(c, run->pt.x, c->pt.y+run->pt.y+baseline, p, &paragraph->member.para);
+          ME_DrawRun(c, c->pt.x + run->pt.x,
+                     c->pt.y + para->pt.y + run->pt.y + baseline, p, para);
         if (me_debug)
         {
           /* I'm using %ls, hope wsprintfW is not going to use wrong (4-byte) WCHAR version */
           const WCHAR wszRunDebug[] = {'[','%','d',':','%','x',']',' ','%','l','s',0};
           WCHAR buf[2560];
           POINT pt;
-          pt.x = run->pt.x;
-          pt.y = c->pt.y + run->pt.y;
+          pt.x = c->pt.x + run->pt.x;
+          pt.y = c->pt.y + para->pt.y + run->pt.y;
           wsprintfW(buf, wszRunDebug, no, p->member.run.nFlags, p->member.run.strText->szData);
           ME_DebugWrite(c->hDC, &pt, buf);
         }
-        /* c->pt.x += p->member.run.nWidth; */
         break;
       case diCell:
         /* Clear any space at the bottom of the cell after the text. */
-        if (para->nFlags & MEPF_ROWSTART)
+        if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
           break;
         y += height;
-        rc.top = y;
-        rc.bottom = p->member.cell.pt.y + p->member.cell.nHeight
-                    - ME_GetYScrollPos(c->editor);
+        rc.top = c->pt.y + para->pt.y + para->nHeight;
+        rc.bottom = c->pt.y + p->member.cell.pt.y + p->member.cell.nHeight;
         if (RectVisible(c->hDC, &rc))
         {
           FillRect(c->hDC, &rc, c->editor->hbrBackground);
@@ -1084,7 +1056,7 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type)
   hWnd = editor->hWnd;
   winStyle = GetWindowLongW(hWnd, GWL_STYLE);
   bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
-  bScrollBarWillBeVisible = (editor->nHeight > editor->sizeWindow.cy)
+  bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy)
                             || (winStyle & ES_DISABLENOSCROLL);
   if (bScrollBarIsVisible != bScrollBarWillBeVisible)
   {
@@ -1110,7 +1082,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
   hWnd = editor->hWnd;
   si.cbSize = sizeof(si);
   bScrollBarWasVisible = ME_GetYScrollVisible(editor);
-  bScrollBarWillBeVisible = editor->nHeight > editor->sizeWindow.cy;
+  bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy;
   
   si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
   if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
index 565e323..9cf4d97 100644 (file)
@@ -38,7 +38,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
 
   ME_InitContext(&c, editor, GetDC(editor->hWnd));
 
-  hf = (HFONT)GetStockObject(SYSTEM_FONT);
+  hf = GetStockObject(SYSTEM_FONT);
   assert(hf);
   GetObjectW(hf, sizeof(LOGFONTW), &lf);
   ZeroMemory(&cf, sizeof(cf));
index ced4f7f..0e0d9a0 100644 (file)
@@ -673,7 +673,7 @@ static void _RTFGetToken2(RTF_Info *info)
                }
 
                /* escaped char */
-               /*if (index (":{}\\", c) != (char *) NULL)*/ /* escaped char */
+               /*if (index (":{}\\", c) != NULL)*/ /* escaped char */
                if (c == ':' || c == '{' || c == '}' || c == '\\')
                {
                        info->rtfClass = rtfText;
@@ -2289,7 +2289,7 @@ static RTFKey     rtfKey[] =
        { rtfVersion,   -1,                     "rtf",          0 },
        { rtfDefFont,   -1,                     "deff",         0 },
 
-       { 0,            -1,                     (char *) NULL,  0 }
+       { 0,            -1,                     NULL,           0 }
 };
 #define RTF_KEY_COUNT (sizeof(rtfKey) / sizeof(RTFKey))
 
@@ -2326,7 +2326,7 @@ void LookupInit(void)
 
 void LookupCleanup(void)
 {
-       int i;
+       unsigned int i;
 
        for (i=0; i<RTF_KEY_COUNT*2; i++)
        {
index 32c4edf..5b10d49 100644 (file)
@@ -3,6 +3,7 @@
 <group>
 <module name="riched20" type="win32dll" baseaddress="${BASEADDRESS_RICHED20}" installbase="system32" installname="riched20.dll" allowwarnings="true">
        <importlibrary definition="riched20.spec" />
+       <compilerflag compiler="cc">-Wno-format</compilerflag>
        <include base="riched20">.</include>
        <include base="ReactOS">include/reactos/wine</include>
        <define name="__WINESRC__" />
index 8fc8abc..a276b7c 100644 (file)
@@ -1157,9 +1157,6 @@ struct _RTF_Info {
 
     ME_InStream *stream;
 
-    /* edit window to output to */
-    HWND hwndEdit;
-    
     ME_TextEditor *editor;
     ME_Style *style;
 
index bb34ad8..2823905 100644 (file)
@@ -692,7 +692,7 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
       {
         pos += lDefaultTab - (pos % lDefaultTab);
       }
-      ppos = ME_twips2pointsX(c, pos) + c->editor->selofs;
+      ppos = ME_twips2pointsX(c, pos);
       if (ppos > startx + run->pt.x) {
         size.cx = ppos - startx - run->pt.x;
         break;
@@ -813,7 +813,7 @@ void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W
       undo->nStart = tmp.pRun->member.run.nCharOfs+para->member.para.nCharOfs;
       undo->nLen = tmp.pRun->member.run.strText->nLen;
       undo->di.member.ustyle = tmp.pRun->member.run.style;
-      /* we'd have to addref undo..ustyle and release tmp...style
+      /* we'd have to addref undo...ustyle and release tmp...style
          but they'd cancel each other out so we can do nothing instead */
     }
     else
@@ -872,8 +872,6 @@ static void ME_GetRunCharFormat(ME_TextEditor *editor, ME_DisplayItem *run, CHAR
  */     
 void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
 {
-  int nFrom, nTo;
-  ME_GetSelection(editor, &nFrom, &nTo);
   ME_CopyCharFormat(pFmt, &editor->pBuffer->pDefaultStyle->fmt);
 }
 
index 7da521c..4a5d590 100644 (file)
@@ -342,7 +342,7 @@ ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code)
     int result;
     int buffer_size = WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
                                           NULL, 0, NULL, NULL);
-    char *buffer = (char*)heap_alloc(buffer_size);
+    char *buffer = heap_alloc(buffer_size);
     WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
                         buffer, buffer_size, NULL, NULL);
     result = editor->pfnWordBreak(str->szData, start, str->nLen, code);
index 3ffe09a..7eb844c 100644 (file)
@@ -78,8 +78,7 @@ static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para)
     wc->bWordWrap = TRUE;
   } else {
     wc->nAvailWidth = wc->context->rcView.right - wc->context->rcView.left
-        - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin
-        - wc->context->editor->selofs;
+        - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
   }
   wc->pt.x = wc->context->pt.x;
   if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
@@ -458,7 +457,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
 
 static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp);
 
-static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD beginofs) {
+static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
   ME_DisplayItem *p;
   ME_WrapContext wc;
   int border = 0;
@@ -573,28 +572,26 @@ static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
   }
 }
 
-BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
+BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
+{
   ME_DisplayItem *item;
   ME_Context c;
   BOOL bModified = FALSE;
   int yStart = -1;
-  int yLastPos = 0;
 
   ME_InitContext(&c, editor, GetDC(editor->hWnd));
-  c.pt.x = editor->selofs;
-  editor->nHeight = 0;
+  c.pt.x = 0;
   item = editor->pBuffer->pFirst->next;
   while(item != editor->pBuffer->pLast) {
     BOOL bRedraw = FALSE;
 
     assert(item->type == diParagraph);
-    editor->nHeight = max(editor->nHeight, item->member.para.pt.y);
     if ((item->member.para.nFlags & MEPF_REWRAP)
      || (item->member.para.pt.y != c.pt.y))
       bRedraw = TRUE;
     item->member.para.pt = c.pt;
 
-    ME_WrapTextParagraph(&c, item, editor->selofs);
+    ME_WrapTextParagraph(&c, item);
 
     if (bRedraw)
     {
@@ -605,8 +602,6 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
 
     bModified = bModified | bRedraw;
 
-    yLastPos = max(yLastPos, c.pt.y);
-
     if (item->member.para.nFlags & MEPF_ROWSTART)
     {
       ME_DisplayItem *cell = ME_FindItemFwd(item, diCell);
@@ -698,7 +693,8 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
       c.pt.x = cell->pt.x + cell->nWidth;
       c.pt.y = cell->pt.y;
       cell->next_cell->member.cell.pt = c.pt;
-      c.pt.y += cell->yTextOffset;
+      if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND))
+        c.pt.y += cell->yTextOffset;
     }
     else
     {
@@ -707,7 +703,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
         c.pt.x = item->member.para.pCell->member.cell.pt.x;
       } else {
         /* Normal paragraph */
-        c.pt.x = editor->selofs;
+        c.pt.x = 0;
       }
       c.pt.y += item->member.para.nHeight;
     }
@@ -718,18 +714,10 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
   
   editor->nTotalLength = c.pt.y;
   editor->pBuffer->pLast->member.para.pt.x = 0;
-  editor->pBuffer->pLast->member.para.pt.y = yLastPos;
+  editor->pBuffer->pLast->member.para.pt.y = c.pt.y;
 
   ME_DestroyContext(&c, editor->hWnd);
 
-  /* Each paragraph may contain multiple rows, which should be scrollable, even
-     if the containing paragraph has pt.y == 0 */
-  item = editor->pBuffer->pFirst;
-  while ((item = ME_FindItemFwd(item, diStartRow)) != NULL) {
-    assert(item->type == diStartRow);
-    editor->nHeight = max(editor->nHeight, item->member.row.pt.y);
-  }
-
   if (bModified || editor->nTotalLength < editor->nLastTotalLength)
     ME_InvalidateMarkedParagraphs(editor);
   return bModified;
@@ -749,16 +737,18 @@ void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor)
   item = editor->pBuffer->pFirst;
   while(item != editor->pBuffer->pLast) {
     if (item->member.para.nFlags & MEPF_REPAINT) {
-      rc.top = item->member.para.pt.y - ofs;
-      rc.bottom = item->member.para.pt.y + item->member.para.nHeight - ofs;
+      rc.top = c.rcView.top + item->member.para.pt.y - ofs;
+      rc.bottom = max(c.rcView.top + item->member.para.pt.y
+                      + item->member.para.nHeight - ofs,
+                      c.rcView.bottom);
       InvalidateRect(editor->hWnd, &rc, TRUE);
     }
     item = item->member.para.next_para;
   }
   if (editor->nTotalLength < editor->nLastTotalLength)
   {
-    rc.top = editor->nTotalLength - ofs;
-    rc.bottom = editor->nLastTotalLength - ofs;
+    rc.top = c.rcView.top + editor->nTotalLength - ofs;
+    rc.bottom = c.rcView.top + editor->nLastTotalLength - ofs;
     InvalidateRect(editor->hWnd, &rc, TRUE);
   }
   ME_DestroyContext(&c, editor->hWnd);
index 109ada1..98bb9d3 100644 (file)
@@ -201,7 +201,7 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
 {
   ME_DisplayItem *item = pFirstRun;
   ME_FontTableItem *table = pStream->fonttbl;
-  int i;
+  unsigned int i;
   ME_DisplayItem *pLastPara = ME_GetParagraph(pLastRun);
   ME_DisplayItem *pCell = NULL;
   
@@ -264,7 +264,7 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
         {
           if (borders[i]->width > 0)
           {
-            int j;
+            unsigned int j;
             COLORREF crColor = borders[i]->colorRef;
             for (j = 1; j < pStream->nColorTblLen; j++)
               if (pStream->colortbl[j] == crColor)
@@ -348,7 +348,7 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream,
       {
         if (borders[i]->width)
         {
-          int j;
+          unsigned int j;
           COLORREF crColor = borders[i]->colorRef;
           sprintf(props + strlen(props), "\\clbrdr%c", sideChar[i]);
           sprintf(props + strlen(props), "\\brdrs");
@@ -380,7 +380,7 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream,
     {
       if (borders[i]->width)
       {
-        int j;
+        unsigned int j;
         COLORREF crColor = borders[i]->colorRef;
         sprintf(props + strlen(props), "\\trbrdr%c", sideChar[i]);
         sprintf(props + strlen(props), "\\brdrs");
@@ -555,7 +555,7 @@ static BOOL
 ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
 {
   char props[STREAMOUT_BUFFER_SIZE] = "";
-  int i;
+  unsigned int i;
 
   if (fmt->dwMask & CFM_ALLCAPS && fmt->dwEffects & CFE_ALLCAPS)
     strcat(props, "\\caps");
index 947a359..187d114 100644 (file)
@@ -77,7 +77,7 @@ static void md2_compress(md2_state *md2)
        md2->X[32+j] = md2->X[j] ^ md2->X[16+j];
    }
 
-   t = (unsigned char)0;
+   t = 0;
 
    /* do 18 rounds */
    for (j = 0; j < 18; j++) {
index 20c04fc..e4e8ab8 100644 (file)
 static const int KARATSUBA_MUL_CUTOFF = 88,  /* Min. number of digits before Karatsuba multiplication is used. */
                  KARATSUBA_SQR_CUTOFF = 128; /* Min. number of digits before Karatsuba squaring is used. */
 
+static void bn_reverse(unsigned char *s, int len);
+static int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
+static int s_mp_exptmod (const mp_int * G, const mp_int * X, mp_int * P, mp_int * Y);
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+static int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
+static int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
+static int s_mp_sqr(const mp_int *a, mp_int *b);
+static int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
+static int mp_exptmod_fast(const mp_int *G, const mp_int *X, mp_int *P, mp_int *Y, int mode);
+static int mp_invmod_slow (const mp_int * a, mp_int * b, mp_int * c);
+static int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c);
+static int mp_karatsuba_sqr(const mp_int *a, mp_int *b);
+
 /* computes the modular inverse via binary extended euclidean algorithm, 
  * that is c = 1/a mod b 
  *
  * Based on slow invmod except this is optimized for the case where b is 
  * odd as per HAC Note 14.64 on pp. 610
  */
-int
+static int
 fast_mp_invmod (const mp_int * a, mp_int * b, mp_int * c)
 {
   mp_int  x, y, u, v, B, D;
@@ -175,7 +188,7 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
  *
  * Based on Algorithm 14.32 on pp.601 of HAC.
 */
-int
+static int
 fast_mp_montgomery_reduce (mp_int * x, const mp_int * n, mp_digit rho)
 {
   int     ix, res, olduse;
@@ -335,7 +348,7 @@ fast_mp_montgomery_reduce (mp_int * x, const mp_int * n, mp_digit rho)
  * Based on Algorithm 14.12 on pp.595 of HAC.
  *
  */
-int
+static int
 fast_s_mp_mul_digs (const mp_int * a, const mp_int * b, mp_int * c, int digs)
 {
   int     olduse, res, pa, ix, iz;
@@ -414,7 +427,7 @@ fast_s_mp_mul_digs (const mp_int * a, const mp_int * b, mp_int * c, int digs)
  *
  * Based on Algorithm 14.12 on pp.595 of HAC.
  */
-int
+static int
 fast_s_mp_mul_high_digs (const mp_int * a, const mp_int * b, mp_int * c, int digs)
 {
   int     olduse, res, pa, ix, iz;
@@ -512,7 +525,7 @@ Remove W2 and don't memset W
 
 */
 
-int fast_s_mp_sqr (const mp_int * a, mp_int * b)
+static int fast_s_mp_sqr (const mp_int * a, mp_int * b)
 {
   int       olduse, res, pa, ix, iz;
   mp_digit   W[MP_WARRAY], *tmpx;
@@ -996,7 +1009,7 @@ mp_count_bits (const mp_int * a)
   
   /* take the last digit and count the bits in it */
   q = a->dp[a->used - 1];
-  while (q > ((mp_digit) 0)) {
+  while (q > 0) {
     ++r;
     q >>= ((mp_digit) 1);
   }
@@ -3847,7 +3860,7 @@ mp_zero (mp_int * a)
 }
 
 /* reverse an array, used for radix code */
-void
+static void
 bn_reverse (unsigned char *s, int len)
 {
   int     ix, iy;
@@ -3865,7 +3878,7 @@ bn_reverse (unsigned char *s, int len)
 }
 
 /* low level addition, based on HAC pp.594, Algorithm 14.7 */
-int
+static int
 s_mp_add (mp_int * a, mp_int * b, mp_int * c)
 {
   mp_int *x;
@@ -3952,7 +3965,7 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
   return MP_OKAY;
 }
 
-int s_mp_exptmod (const mp_int * G, const mp_int * X, mp_int * P, mp_int * Y)
+static int s_mp_exptmod (const mp_int * G, const mp_int * X, mp_int * P, mp_int * Y)
 {
   mp_int  M[256], res, mu;
   mp_digit buf;
@@ -4163,7 +4176,7 @@ __M:
  * HAC pp. 595, Algorithm 14.12  Modified so you can control how 
  * many digits of output are created.
  */
-int
+static int
 s_mp_mul_digs (const mp_int * a, const mp_int * b, mp_int * c, int digs)
 {
   mp_int  t;
@@ -4232,7 +4245,7 @@ s_mp_mul_digs (const mp_int * a, const mp_int * b, mp_int * c, int digs)
 /* multiplies |a| * |b| and does not compute the lower digs digits
  * [meant to get the higher part of the product]
  */
-int
+static int
 s_mp_mul_high_digs (const mp_int * a, const mp_int * b, mp_int * c, int digs)
 {
   mp_int  t;
@@ -4288,7 +4301,7 @@ s_mp_mul_high_digs (const mp_int * a, const mp_int * b, mp_int * c, int digs)
 }
 
 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
-int
+static int
 s_mp_sqr (const mp_int * a, mp_int * b)
 {
   mp_int  t;
@@ -4338,7 +4351,7 @@ s_mp_sqr (const mp_int * a, mp_int * b)
       u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
     }
     /* propagate upwards */
-    while (u != ((mp_digit) 0)) {
+    while (u != 0) {
       r       = ((mp_word) *tmpt) + ((mp_word) u);
       *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
       u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
index 82b7bd3..6b0d2a5 100644 (file)
@@ -70,7 +70,7 @@ int rc2_setup(const unsigned char *key, int keylen, int bits, int rounds, rc2_ke
      * key schedule.  One which is normal, and anther which has a hook to
      * use a reduced key length.
      * BSAFE uses the 'retarded' version.  What I previously shipped is
-     * the same as specifying 1024 for the 'bits' parameter.  Bsafe uses
+     * the same as specifying 1024 for the 'bits' parameter.  BSAFE uses
      * a version where the bits parameter is the same as len*8 */
     /* Seems like MS uses the 'retarded' version, too.
      * Adjust effective keylen bits */
index f90bb38..8f4e188 100644 (file)
@@ -657,7 +657,7 @@ static inline void update_hash(CRYPTHASH *pCryptHash, CONST BYTE *pbData, DWORD
             pbTemp = HeapAlloc(GetProcessHeap(), 0, dwDataLen);
             if (!pbTemp) return;
             memcpy(pbTemp, pbData, dwDataLen);
-            RSAENH_CPEncrypt(pCryptHash->hProv, pCryptHash->hKey, (HCRYPTHASH)NULL, FALSE, 0, 
+            RSAENH_CPEncrypt(pCryptHash->hProv, pCryptHash->hKey, 0, FALSE, 0,
                              pbTemp, &dwDataLen, dwDataLen);
             HeapFree(GetProcessHeap(), 0, pbTemp);
             break;
@@ -701,7 +701,7 @@ static inline void finalize_hash(CRYPTHASH *pCryptHash) {
 
         case CALG_MAC:
             dwDataLen = 0;
-            RSAENH_CPEncrypt(pCryptHash->hProv, pCryptHash->hKey, (HCRYPTHASH)NULL, TRUE, 0, 
+            RSAENH_CPEncrypt(pCryptHash->hProv, pCryptHash->hKey, 0, TRUE, 0,
                              pCryptHash->abHashValue, &dwDataLen, pCryptHash->dwHashSize);
             break;
 
@@ -1259,7 +1259,7 @@ static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid,
                           0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 } },
         { CALG_SHA, 15, { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 
                           0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 } },
-        { 0,        0,  {} }
+        { 0,        0,  { 0 } }
     };
     DWORD dwIdxOID, i, j;
 
@@ -1677,7 +1677,7 @@ BOOL WINAPI RSAENH_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
     pCryptHash->hKey = hKey;
     pCryptHash->hProv = hProv;
     pCryptHash->dwState = RSAENH_HASHSTATE_HASHING;
-    pCryptHash->pHMACInfo = (PHMAC_INFO)NULL;
+    pCryptHash->pHMACInfo = NULL;
     pCryptHash->dwHashSize = peaAlgidInfo->dwDefaultLen >> 3;
     init_data_blob(&pCryptHash->tpPRFParams.blobLabel);
     init_data_blob(&pCryptHash->tpPRFParams.blobSeed);
@@ -2826,10 +2826,10 @@ BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam
         {
             CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pbData;
 
-            /* salt length can't be greater than 128 bits = 16 bytes */
-            if (blob->cbData > 16)
+            /* salt length can't be greater than 184 bits = 24 bytes */
+            if (blob->cbData > 24)
             {
-                SetLastError(ERROR_INVALID_PARAMETER);
+                SetLastError(NTE_BAD_DATA);
                 return FALSE;
             }
             memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen, blob->pbData,
@@ -3557,7 +3557,7 @@ BOOL WINAPI RSAENH_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa
 {
     CRYPTHASH *pCryptHash;
     CRYPTKEY *pCryptKey;
-    int i;
+    DWORD i;
 
     TRACE("(hProv=%08lx, hHash=%08lx, dwParam=%08x, pbData=%p, dwFlags=%08x)\n",
            hProv, hHash, dwParam, pbData, dwFlags);
index b76757c..4348620 100644 (file)
@@ -574,27 +574,6 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream);
 #define mp_todecimal(M, S) mp_toradix((M), (S), 10)
 #define mp_tohex(M, S)     mp_toradix((M), (S), 16)
 
-/* lowlevel functions, do not call! */
-int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
-int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
-#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
-int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
-int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
-int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
-int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
-int fast_s_mp_sqr(const mp_int *a, mp_int *b);
-int s_mp_sqr(const mp_int *a, mp_int *b);
-int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c);
-int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
-int mp_karatsuba_sqr(const mp_int *a, mp_int *b);
-int mp_toom_sqr(mp_int *a, mp_int *b);
-int fast_mp_invmod(const mp_int *a, mp_int *b, mp_int *c);
-int mp_invmod_slow (const mp_int * a, mp_int * b, mp_int * c);
-int fast_mp_montgomery_reduce(mp_int *a, const mp_int *m, mp_digit mp);
-int mp_exptmod_fast(const mp_int *G, const mp_int *X, mp_int *P, mp_int *Y, int mode);
-int s_mp_exptmod (const mp_int * G, const mp_int * X, mp_int * P, mp_int * Y);
-void bn_reverse(unsigned char *s, int len);
-
 extern const char *mp_s_rmap;
 
 #define PK_PRIVATE            0        /* PK private keys */
index eb1aa1c..47b1d18 100644 (file)
@@ -3,6 +3,72 @@
 #define NDEBUG
 #include <debug.h>
 
+SECURITY_STATUS WINAPI ApplyControlTokenW(PCtxtHandle Handle, PSecBufferDesc Buffer);
+SECURITY_STATUS WINAPI ApplyControlTokenA(PCtxtHandle Handle, PSecBufferDesc Buffer);
+
+static SecurityFunctionTableA securityFunctionTableA =
+{
+    SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
+    EnumerateSecurityPackagesA,
+    QueryCredentialsAttributesA,
+    AcquireCredentialsHandleA,
+    FreeCredentialsHandle,
+    NULL, /* Reserved2 */
+    InitializeSecurityContextA,
+    AcceptSecurityContext,
+    CompleteAuthToken,
+    DeleteSecurityContext,
+    ApplyControlTokenA,
+    QueryContextAttributesA,
+    ImpersonateSecurityContext,
+    RevertSecurityContext,
+    MakeSignature,
+    VerifySignature,
+    FreeContextBuffer,
+    QuerySecurityPackageInfoA,
+    EncryptMessage, /* Reserved3 */
+    DecryptMessage, /* Reserved4 */
+    ExportSecurityContext,
+    ImportSecurityContextA,
+    AddCredentialsA,
+    NULL, /* Reserved8 */
+    QuerySecurityContextToken,
+    EncryptMessage,
+    DecryptMessage,
+    NULL
+};
+
+static SecurityFunctionTableW securityFunctionTableW =
+{
+    SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
+    EnumerateSecurityPackagesW,
+    QueryCredentialsAttributesW,
+    AcquireCredentialsHandleW,
+    FreeCredentialsHandle,
+    NULL, /* Reserved2 */
+    InitializeSecurityContextW,
+    AcceptSecurityContext,
+    CompleteAuthToken,
+    DeleteSecurityContext,
+    ApplyControlTokenW,
+    QueryContextAttributesW,
+    ImpersonateSecurityContext,
+    RevertSecurityContext,
+    MakeSignature,
+    VerifySignature,
+    FreeContextBuffer,
+    QuerySecurityPackageInfoW,
+    EncryptMessage, /* Reserved3 */
+    DecryptMessage, /* Reserved4 */
+    ExportSecurityContext,
+    ImportSecurityContextW,
+    AddCredentialsW,
+    NULL, /* Reserved8 */
+    QuerySecurityContextToken,
+    EncryptMessage,
+    DecryptMessage,
+    NULL
+};
 
 SECURITY_STATUS
 WINAPI
@@ -32,8 +98,8 @@ FreeContextBuffer (
        PVOID pvoid
        )
 {
-       UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+    HeapFree(GetProcessHeap(), 0, pvoid);
+    return SEC_E_OK;
 }
 
 SECURITY_STATUS
@@ -56,8 +122,8 @@ PSecurityFunctionTableW
 WINAPI
 InitSecurityInterfaceW(VOID)
 {
-       UNIMPLEMENTED;
-       return NULL;
+    DPRINT("InitSecurityInterfaceW() called\n");
+    return &securityFunctionTableW;
 }
 
 SECURITY_STATUS
@@ -116,7 +182,14 @@ QueryContextAttributesA(PCtxtHandle Handle,
                         PVOID Bar)
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (Handle)
+       {
+               Bar = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+
+       return SEC_E_INVALID_HANDLE;
 }
 
 SECURITY_STATUS
@@ -126,7 +199,14 @@ QueryContextAttributesW(PCtxtHandle Handle,
                         PVOID Bar)
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (Handle)
+       {
+               Bar = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+
+       return SEC_E_INVALID_HANDLE;
 }
 
 SECURITY_STATUS
@@ -144,7 +224,15 @@ AcquireCredentialsHandleA (
     )
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (pszPackage)
+       {
+               phCred = NULL;
+               pExpires = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+
+       return SEC_E_SECPKG_NOT_FOUND;
 }
 
 SECURITY_STATUS
@@ -162,7 +250,15 @@ AcquireCredentialsHandleW (
     )
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (pszPackage)
+       {
+               phCred = NULL;
+               pExpires = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+
+       return SEC_E_SECPKG_NOT_FOUND;
 }
 
 SECURITY_STATUS
@@ -243,7 +339,13 @@ QuerySecurityPackageInfoA(
 )
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (pszPackageName)
+       {
+               *ppPackageInfo = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+       return SEC_E_SECPKG_NOT_FOUND;
 }
 
 SECURITY_STATUS
@@ -254,7 +356,13 @@ QuerySecurityPackageInfoW(
 )
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (pszPackageName)
+       {
+               *ppPackageInfo = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+       return SEC_E_SECPKG_NOT_FOUND;
 }
 
 SECURITY_STATUS
@@ -367,7 +475,14 @@ QueryCredentialsAttributesA(
 )
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (phCredential)
+       {
+               pBuffer = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+
+       return SEC_E_INVALID_HANDLE;
 }
 
 SECURITY_STATUS
@@ -379,7 +494,14 @@ QueryCredentialsAttributesW(
 )
 {
        UNIMPLEMENTED;
-       return ERROR_CALL_NOT_IMPLEMENTED;
+
+       if (phCredential)
+       {
+               pBuffer = NULL;
+               return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+
+       return SEC_E_INVALID_HANDLE;
 }
 
 SECURITY_STATUS
@@ -407,8 +529,8 @@ PSecurityFunctionTableA
 WINAPI
 InitSecurityInterfaceA(VOID)
 {
-       UNIMPLEMENTED;
-       return NULL;
+    DPRINT("InitSecurityInterfaceA() called\n");
+    return &securityFunctionTableA;
 }
 
 BOOLEAN
index 22177a5..d3637f0 100644 (file)
@@ -4242,6 +4242,42 @@ SetupDiSetDeviceInstallParamsW(
     return ret;
 }
 
+BOOL WINAPI SetupDiSetDeviceInstallParamsA(
+       HDEVINFO DeviceInfoSet,
+       PSP_DEVINFO_DATA DeviceInfoData,
+       PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
+{
+    SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
+    int len = 0;
+    BOOL ret = FALSE;
+
+    TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
+
+    if (DeviceInstallParams == NULL)
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (DeviceInstallParams->cbSize < sizeof(SP_DEVINSTALL_PARAMS_A))
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else
+    {
+        memcpy(&deviceInstallParamsW, DeviceInstallParams, FIELD_OFFSET(SP_DEVINSTALL_PARAMS_A, DriverPath));
+        deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
+        len = MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, NULL, 0);
+        if (!len)
+        {
+            ERR("DrivePath is NULL\n");
+            ret = FALSE;
+        }
+        else
+        {
+            MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, deviceInstallParamsW.DriverPath, len);
+            ret = SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &deviceInstallParamsW);
+        }
+    }
+
+    TRACE("Returning %d\n", ret);
+    return ret;
+}
+
 static HKEY
 OpenHardwareProfileKey(
     IN HKEY HKLM,
index a1bf52e..484ff4f 100644 (file)
@@ -30,6 +30,7 @@ static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
 static const WCHAR OemFileMask[] = {'o','e','m','*','.','i','n','f',0};
 static const WCHAR OemFileSpecification[] = {'o','e','m','%','l','u','.','i','n','f',0};
 static const WCHAR DotLnk[] = {'.','l','n','k',0};
+static const WCHAR DotServices[]  = {'.','S','e','r','v','i','c','e','s',0};
 
 static const WCHAR DependenciesKey[] = {'D','e','p','e','n','d','e','n','c','i','e','s',0};
 static const WCHAR DescriptionKey[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
@@ -1457,9 +1458,12 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section,
 void WINAPI InstallHinfSectionW( HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show )
 {
     WCHAR *s, *path, section[MAX_PATH];
-    void *callback_context;
+    void *callback_context = NULL;
+    DWORD SectionNameLength;
     UINT mode;
-    HINF hinf;
+    HINF hinf = INVALID_HANDLE_VALUE;
+    BOOL bRebootRequired = FALSE;
+    BOOL ret;
 
     TRACE("hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_w(cmdline));
 
@@ -1475,23 +1479,101 @@ void WINAPI InstallHinfSectionW( HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, I
     while (*s == ' ') s++;
     path = s;
 
+    if (mode & 0x80)
+    {
+        FIXME("default path of the installation not changed\n");
+        mode &= ~0x80;
+    }
+
     hinf = SetupOpenInfFileW( path, NULL, INF_STYLE_WIN4, NULL );
-    if (hinf == INVALID_HANDLE_VALUE) return;
+    if (hinf == INVALID_HANDLE_VALUE)
+    {
+        WARN("SetupOpenInfFileW(%s) failed (Error %u)\n", path, GetLastError());
+        goto cleanup;
+    }
 
-    if (SetupDiGetActualSectionToInstallW(
-        hinf, section, section, sizeof(section)/sizeof(section[0]), NULL, NULL ))
+    ret = SetupDiGetActualSectionToInstallW(
+       hinf, section, section, sizeof(section)/sizeof(section[0]), &SectionNameLength, NULL );
+    if (!ret)
     {
-        callback_context = SetupInitDefaultQueueCallback( hwnd );
-        SetupInstallFromInfSectionW( hwnd, hinf, section, SPINST_ALL, NULL, NULL, SP_COPY_NEWER,
-                                     SetupDefaultQueueCallbackW, callback_context,
-                                     NULL, NULL );
-        SetupTermDefaultQueueCallback( callback_context );
+        WARN("SetupDiGetActualSectionToInstallW() failed (Error %u)\n", GetLastError());
+        goto cleanup;
+    }
+    if (SectionNameLength > MAX_PATH - strlenW(DotServices))
+    {
+        WARN("Section name '%s' too long\n", section);
+        goto cleanup;
+    }
+
+    /* Copy files and add registry entries */
+    callback_context = SetupInitDefaultQueueCallback( hwnd );
+    ret = SetupInstallFromInfSectionW( hwnd, hinf, section, SPINST_ALL, NULL, NULL,
+                                       SP_COPY_NEWER | SP_COPY_IN_USE_NEEDS_REBOOT,
+                                       SetupDefaultQueueCallbackW, callback_context,
+                                       NULL, NULL );
+    if (!ret)
+    {
+        WARN("SetupInstallFromInfSectionW() failed (Error %u)\n", GetLastError());
+        goto cleanup;
+    }
+    /* FIXME: need to check if some files were in use and need reboot
+     * bReboot = ...;
+     */
+
+    /* Install services */
+    wcscat(section, DotServices);
+    ret = SetupInstallServicesFromInfSectionW( hinf, section, 0 );
+    if (!ret && GetLastError() == ERROR_SECTION_NOT_FOUND)
+        ret = TRUE;
+    if (!ret)
+    {
+        WARN("SetupInstallServicesFromInfSectionW() failed (Error %u)\n", GetLastError());
+        goto cleanup;
+    }
+    else if (GetLastError() == ERROR_SUCCESS_REBOOT_REQUIRED)
+    {
+        bRebootRequired = TRUE;
+    }
+
+    /* Check if we need to reboot */
+    switch (mode)
+    {
+        case 0:
+            /* Never reboot */
+            break;
+        case 1:
+            /* Always reboot */
+            ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
+                SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
+            break;
+        case 2:
+            /* Query user before rebooting */
+            SetupPromptReboot(NULL, hwnd, FALSE);
+            break;
+        case 3:
+            /* Reboot if necessary */
+            if (bRebootRequired)
+            {
+                ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
+                    SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
+            }
+            break;
+        case 4:
+            /* If necessary, query user before rebooting */
+            if (bRebootRequired)
+            {
+                SetupPromptReboot(NULL, hwnd, FALSE);
+            }
+            break;
+        default:
+            break;
     }
-    SetupCloseInfFile( hinf );
 
-    /* FIXME: should check the mode and maybe reboot */
-    /* there isn't much point in doing that since we */
-    /* don't yet handle deferred file copies anyway. */
+cleanup:
+    if ( callback_context )
+        SetupTermDefaultQueueCallback( callback_context );
+    if ( hinf != INVALID_HANDLE_VALUE )
+        SetupCloseInfFile( hinf );
 }
 
 
index cb89b25..4f0d761 100644 (file)
 @ stub SetupDiSelectOEMDrv
 @ stdcall SetupDiSetClassInstallParamsA(ptr ptr ptr long)
 @ stdcall SetupDiSetClassInstallParamsW(ptr ptr ptr long)
-@ stub SetupDiSetDeviceInstallParamsA
+@ stdcall SetupDiSetDeviceInstallParamsA(ptr ptr ptr)
 @ stdcall SetupDiSetDeviceInstallParamsW(ptr ptr ptr)
 @ stdcall SetupDiSetDeviceRegistryPropertyA(ptr ptr long ptr long)
 @ stdcall SetupDiSetDeviceRegistryPropertyW(ptr ptr long ptr long)
index 9bc0773..6c6bc33 100644 (file)
@@ -33,6 +33,7 @@
 #include <aclapi.h>
 #include <cfgmgr32.h>
 #include <fdi.h>
+#include <reason.h>
 #include <regstr.h>
 #include <sddl.h>
 #include <setupapi.h>
index f5643ba..28b09a0 100644 (file)
@@ -25,12 +25,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
 #define MAX_PROPERTY_SHEET_PAGE 32
 
 typedef struct _LANGANDCODEPAGE_
-  {
+{
     WORD lang;
     WORD code;
 } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
 
 HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
+
 /*************************************************************************
  *
  * SH_CreatePropertySheetPage [Internal]
@@ -38,6 +39,7 @@ HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_
  * creates a property sheet page from an resource name
  *
  */
+
 HPROPSHEETPAGE
 SH_CreatePropertySheetPage(LPSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle)
 {
@@ -55,7 +57,9 @@ SH_CreatePropertySheetPage(LPSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR
         ERR("failed to find resource name\n");
         return (HPROPSHEETPAGE)0;
     }
+
     lpsztemplate = LoadResource(shell32_hInstance, hRes);
+
     if (lpsztemplate == NULL)
         return (HPROPSHEETPAGE)0;
 
@@ -66,19 +70,15 @@ SH_CreatePropertySheetPage(LPSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR
     ppage.pfnDlgProc = dlgproc;
     ppage.lParam = lParam;
     ppage.pszTitle = szTitle;
+
     if (szTitle)
     {
         ppage.dwFlags |= PSP_USETITLE;
     }
+
     return CreatePropertySheetPageW(&ppage);
 }
 
-
-
-
-
-
-
 /*************************************************************************
  *
  * SH_FileGeneralFileType [Internal]
@@ -90,67 +90,72 @@ SH_CreatePropertySheetPage(LPSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR
  */
 
 BOOL
-SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR * filext)
+SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR *filext)
 {
-     WCHAR name[MAX_PATH];
-     WCHAR value[MAX_PATH];
-     DWORD lname = MAX_PATH;
-     DWORD lvalue = MAX_PATH;
+    WCHAR name[MAX_PATH];
+    WCHAR value[MAX_PATH];
+    DWORD lname = MAX_PATH;
+    DWORD lvalue = MAX_PATH;
+    HKEY hKey;
+    LONG result;
+    HWND hDlgCtrl;
 
-     HKEY hKey;
-     LONG result;
-     HWND hDlgCtrl;
+    TRACE("fileext %s\n", debugstr_w(filext));
 
-     TRACE("fileext %s\n", debugstr_w(filext));
+    if (filext == NULL)
+        return FALSE;
 
-     if (filext == NULL)
-                return FALSE;
+    hDlgCtrl = GetDlgItem(hwndDlg, 14005);
 
-     hDlgCtrl = GetDlgItem(hwndDlg, 14005);
+    if (hDlgCtrl == NULL)
+        return FALSE;
 
-     if (hDlgCtrl == NULL)
-         return FALSE;
+    if (RegOpenKeyW(HKEY_CLASSES_ROOT, filext, &hKey) != ERROR_SUCCESS)
+    {
+        /* the file extension is unknown, so default to string "FileExtension File" */
+        SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)value);
+        swprintf(name, value, &filext[1]);
+        SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)name);
+        return TRUE;
+    }
 
-     if (RegOpenKeyW(HKEY_CLASSES_ROOT, filext, &hKey) != ERROR_SUCCESS)
-     {
-         /* the fileextension is unknown, so default to string "FileExtension File" */
-         SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)value);
-         swprintf(name, value, &filext[1]);
-         SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)name);
-         return TRUE;
-     }
-     result = RegEnumValueW(hKey, 0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
-     RegCloseKey(hKey);
+    result = RegEnumValueW(hKey, 0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
+    RegCloseKey(hKey);
 
     if (result != ERROR_SUCCESS)
         return FALSE;
+
     if (RegOpenKeyW(HKEY_CLASSES_ROOT, value, &hKey) == ERROR_SUCCESS)
     {
         if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", value, MAX_PATH, NULL, 0, NULL) != ERROR_SUCCESS)
         {
             lvalue = lname = MAX_PATH;
-            result = RegEnumValueW(hKey,0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
+            result = RegEnumValueW(hKey, 0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
         }
+
         lname = MAX_PATH;
+
         if (RegGetValueW(hKey, L"DefaultIcon", NULL, RRF_RT_REG_SZ, NULL, name, &lname) == ERROR_SUCCESS)
         {
             UINT IconIndex;
             WCHAR szBuffer[MAX_PATH];
-            WCHAR * Offset;
+            WCHAR *Offset;
             HICON hIcon = 0;
             HRSRC hResource;
             LPVOID pResource = NULL;
             HGLOBAL hGlobal;
             HANDLE hLibrary;
             Offset = wcsrchr(name, L',');
+
             if (Offset)
             {
                 IconIndex = _wtoi(Offset + 2);
                 *Offset = L'\0';
-                name[MAX_PATH-1] = L'\0';
+                name[MAX_PATH - 1] = L'\0';
+
                 if (ExpandEnvironmentStringsW(name, szBuffer, MAX_PATH))
                 {
-                    szBuffer[MAX_PATH-1] = L'\0';
+                    szBuffer[MAX_PATH - 1] = L'\0';
                     hLibrary = LoadLibraryExW(szBuffer, NULL, LOAD_LIBRARY_AS_DATAFILE);
                     if (hLibrary)
                     {
@@ -164,7 +169,13 @@ SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR * filext)
                                 if (pResource != NULL)
                                 {
                                     hIcon = CreateIconFromResource(pResource, SizeofResource(shell32_hInstance, hResource), TRUE, 0x00030000);
-                                    TRACE("hIcon %p,- szBuffer %s IconIndex %u error %u icon %p hResource %p pResource %p\n", hIcon, debugstr_w(szBuffer), IconIndex, MAKEINTRESOURCEW(IconIndex), hResource, pResource);
+                                    TRACE("hIcon %p,- szBuffer %s IconIndex %u error %u icon %p hResource %p pResource %p\n",
+                                          hIcon,
+                                          debugstr_w(szBuffer),
+                                          IconIndex,
+                                          MAKEINTRESOURCEW(IconIndex),
+                                          hResource,
+                                          pResource);
                                     SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)hIcon, 0);
                                 }
                             }
@@ -178,10 +189,12 @@ SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR * filext)
     }
 
     /* file extension type */
-    value[MAX_PATH-1] = L'\0';
+    value[MAX_PATH - 1] = L'\0';
     SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)value);
+
     return TRUE;
 }
+
 /*************************************************************************
  *
  * SHFileGeneralGetFileTimeString [Internal]
@@ -190,12 +203,14 @@ SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR * filext)
  */
 
 BOOL
-SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime, WCHAR * lpResult)
+SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime, WCHAR *lpResult)
 {
     FILETIME ft;
     SYSTEMTIME dt;
     WORD wYear;
-    static const WCHAR wFormat[] = {'%','0','2','d','/','%','0','2','d','/','%','0','4','d',' ',' ','%','0','2','d',':','%','0','2','u',0};
+    static const WCHAR wFormat[] = {
+        '%', '0', '2', 'd', '/', '%', '0', '2', 'd', '/', '%', '0', '4', 'd',
+        ' ', ' ', '%', '0', '2', 'd', ':', '%', '0', '2', 'u', 0 };
 
     if (lpFileTime == NULL || lpResult == NULL)
         return FALSE;
@@ -206,10 +221,11 @@ SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime, WCHAR * lpResult)
     FileTimeToSystemTime(&ft, &dt);
 
     wYear = dt.wYear;
+
     /* ddmmyy */
-    swprintf (lpResult, wFormat, dt.wDay, dt.wMonth, wYear, dt.wHour, dt.wMinute);
+    swprintf(lpResult, wFormat, dt.wDay, dt.wMonth, wYear, dt.wHour, dt.wMinute);
 
-    TRACE("result %s\n",debugstr_w(lpResult));
+    TRACE("result %s\n", debugstr_w(lpResult));
     return TRUE;
 }
 
@@ -222,18 +238,18 @@ SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime, WCHAR * lpResult)
  */
 
 BOOL
-SH_FileGeneralSetText(HWND hwndDlg, WCHAR * lpstr)
+SH_FileGeneralSetText(HWND hwndDlg, WCHAR *lpstr)
 {
     int flength;
     int plength;
-    WCHAR * lpdir;
+    WCHAR *lpdir;
     WCHAR buff[MAX_PATH];
     HWND hDlgCtrl;
 
     if (lpstr == NULL)
         return FALSE;
 
-    lpdir = wcschr(lpstr, '\\'); /* find the last occurence of '\\' */
+    lpdir = wcschr(lpstr, '\\');        /* find the last occurence of '\\' */
 
     plength = wcslen(lpstr);
     flength = wcslen(lpdir);
@@ -247,12 +263,12 @@ SH_FileGeneralSetText(HWND hwndDlg, WCHAR * lpstr)
         SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
     }
 
-    if(flength > 1)
+    if (flength > 1)
     {
-         /* text filename field */
-         wcsncpy(buff, &lpdir[1], flength);
-         hDlgCtrl = GetDlgItem(hwndDlg, 14001);
-         SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
+        /* text filename field */
+        wcsncpy(buff, &lpdir[1], flength);
+        hDlgCtrl = GetDlgItem(hwndDlg, 14001);
+        SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
     }
 
     return TRUE;
@@ -267,7 +283,7 @@ SH_FileGeneralSetText(HWND hwndDlg, WCHAR * lpstr)
  */
 
 BOOL
-SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR * lpfilename, PULARGE_INTEGER lpfilesize)
+SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR *lpfilename, PULARGE_INTEGER lpfilesize)
 {
     BOOL result;
     HANDLE hFile;
@@ -283,7 +299,8 @@ SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR * lpfilename, PULARGE_INTEGER
 
     hFile = CreateFileW(lpfilename,
                         GENERIC_READ,
-                        FILE_SHARE_READ,NULL,
+                        FILE_SHARE_READ,
+                        NULL,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         NULL);
@@ -301,7 +318,8 @@ SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR * lpfilename, PULARGE_INTEGER
         WARN("GetFileTime failed\n");
         return FALSE;
     }
-    if (SHFileGeneralGetFileTimeString(&create_time,resultstr))
+
+    if (SHFileGeneralGetFileTimeString(&create_time, resultstr))
     {
         hDlgCtrl = GetDlgItem(hwndDlg, 14015);
         SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
@@ -325,15 +343,21 @@ SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR * lpfilename, PULARGE_INTEGER
         CloseHandle(hFile);
         return FALSE;
     }
+
     CloseHandle(hFile);
-    if (!StrFormatByteSizeW(file_size.QuadPart, resultstr, sizeof(resultstr) / sizeof(WCHAR)))
-       return FALSE;
+
+    if (!StrFormatByteSizeW(file_size.QuadPart,
+                            resultstr,
+                            sizeof(resultstr) / sizeof(WCHAR)))
+        return FALSE;
+
     hDlgCtrl = GetDlgItem(hwndDlg, 14011);
+
     TRACE("result size %u resultstr %s\n", file_size.QuadPart, debugstr_w(resultstr));
     SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
 
     if (lpfilesize)
-       lpfilesize->QuadPart = (ULONGLONG)file_size.QuadPart;
+        lpfilesize->QuadPart = (ULONGLONG)file_size.QuadPart;
 
     return TRUE;
 }
@@ -346,23 +370,24 @@ SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR * lpfilename, PULARGE_INTEGER
  */
 
 BOOL
-SH_FileVersionQuerySetText(HWND hwndDlg, DWORD dlgId, LPVOID pInfo, WCHAR * text, WCHAR ** resptr)
+SH_FileVersionQuerySetText(HWND hwndDlg, DWORD dlgId, LPVOID pInfo, WCHAR *text, WCHAR **resptr)
 {
-  UINT reslen;
-  HWND hDlgCtrl;
-
-  if(hwndDlg == NULL || resptr == NULL || text == NULL)
-   return FALSE;
-
-  if(VerQueryValueW(pInfo, text, (LPVOID *)resptr, &reslen))
-  {
-    /* file description property */
-   hDlgCtrl = GetDlgItem(hwndDlg, dlgId);
-   TRACE("%s :: %s\n",debugstr_w(text), debugstr_w(*resptr));
-   SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)0, (LPARAM)*resptr);
-   return TRUE;
-  }
-  return FALSE;
+    UINT reslen;
+    HWND hDlgCtrl;
+
+    if (hwndDlg == NULL || resptr == NULL || text == NULL)
+        return FALSE;
+
+    if (VerQueryValueW(pInfo, text, (LPVOID *)resptr, &reslen))
+    {
+        /* file description property */
+        hDlgCtrl = GetDlgItem(hwndDlg, dlgId);
+        TRACE("%s :: %s\n", debugstr_w(text), debugstr_w(*resptr));
+        SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)0, (LPARAM)*resptr);
+        return TRUE;
+    }
+
+    return FALSE;
 }
 
 /*************************************************************************
@@ -373,33 +398,35 @@ SH_FileVersionQuerySetText(HWND hwndDlg, DWORD dlgId, LPVOID pInfo, WCHAR * text
  *
  */
 
-
 BOOL
-SH_FileVersionQuerySetListText(HWND hwndDlg, LPVOID pInfo, const WCHAR * text, WCHAR **resptr, WORD lang, WORD code)
+SH_FileVersionQuerySetListText(HWND hwndDlg, LPVOID pInfo, const WCHAR *text, WCHAR **resptr, WORD lang, WORD code)
 {
-  UINT reslen;
-  HWND hDlgCtrl;
-  UINT index;
-  static const WCHAR wFormat[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n',
-         'f','o','\\','%','0','4','x','%','0','4','x','\\','%','s',0 };
-  WCHAR buff[256];
-
-  TRACE("text %s, resptr %p hwndDlg %p\n",debugstr_w(text), resptr, hwndDlg);
-
-  if(hwndDlg == NULL || resptr == NULL || text == NULL)
-   return FALSE;
-
-  swprintf(buff, wFormat, lang, code, text);
-  if(VerQueryValueW(pInfo, buff, (LPVOID *)resptr, &reslen))
-  {
-    /* listbox name property */
-   hDlgCtrl = GetDlgItem(hwndDlg, 14009);
-   TRACE("%s :: %s\n",debugstr_w(text), debugstr_w(*resptr));
-   index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)text);
-   SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)index, (LPARAM)(WCHAR*)*resptr);
-   return TRUE;
-  }
-  return FALSE;
+    UINT reslen;
+    HWND hDlgCtrl;
+    UINT index;
+    static const WCHAR wFormat[] = {
+        '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
+        '\\', '%', '0', '4', 'x', '%', '0', '4', 'x', '\\', '%', 's', 0 };
+    WCHAR buff[256];
+
+    TRACE("text %s, resptr %p hwndDlg %p\n", debugstr_w(text), resptr, hwndDlg);
+
+    if (hwndDlg == NULL || resptr == NULL || text == NULL)
+        return FALSE;
+
+    swprintf(buff, wFormat, lang, code, text);
+
+    if (VerQueryValueW(pInfo, buff, (LPVOID *)resptr, &reslen))
+    {
+        /* listbox name property */
+        hDlgCtrl = GetDlgItem(hwndDlg, 14009);
+        TRACE("%s :: %s\n", debugstr_w(text), debugstr_w(*resptr));
+        index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)text);
+        SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)index, (LPARAM)(WCHAR *)*resptr);
+        return TRUE;
+    }
+
+    return FALSE;
 }
 
 /*************************************************************************
@@ -408,102 +435,117 @@ SH_FileVersionQuerySetListText(HWND hwndDlg, LPVOID pInfo, const WCHAR * text, W
  *
  * sets all file version properties in dialog
  */
+
 BOOL
-SH_FileVersionInitialize(HWND hwndDlg, WCHAR * lpfilename)
+SH_FileVersionInitialize(HWND hwndDlg, WCHAR *lpfilename)
 {
-  LPVOID pBuf;
-  DWORD versize;
-  DWORD handle;
-  LPVOID info = NULL;
-  UINT infolen;
-  WCHAR buff[256];
-  HWND hDlgCtrl;
-  WORD lang = 0;
-  WORD code = 0;
-  LPLANGANDCODEPAGE lplangcode;
-  WCHAR * str;
-  static const WCHAR wVersionFormat[] = { '%','d','.','%','d','.','%','d','.','%','d',0 };
-  static const WCHAR wFileDescriptionFormat[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
-       '\\','%','0','4','x','%','0','4','x','\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0 };
-  static const WCHAR wLegalCopyrightFormat[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
-       '\\','%','0','4','x','%','0','4','x','\\','L','e','g','a','l','C','o','p','y','r','i','g','h','t',0 };
-  static const WCHAR wTranslation[] = { 'V','a','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n',0 };
-  static const WCHAR wCompanyName[] = { 'C','o','m','p','a','n','y','N','a','m','e',0 };
-  static const WCHAR wFileVersion[] = { 'F','i','l','e','V','e','r','s','i','o','n',0 };
-  static const WCHAR wInternalName[] = { 'I','n','t','e','r','n','a','l','N','a','m','e',0 };
-  static const WCHAR wOriginalFilename[] = { 'O','r','i','g','i','n','a','l','F','i','l','e','n','a','m','e',0 };
-  static const WCHAR wProductName[] = { 'P','r','o','d','u','c','t','N','a','m','e',0 };
-  static const WCHAR wProductVersion[] = { 'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0 };
-  static const WCHAR wSlash[] = { '\\',0 };
-
-
-  if(lpfilename == 0)
-    return FALSE;
+    LPVOID pBuf;
+    DWORD versize;
+    DWORD handle;
+    LPVOID info = NULL;
+    UINT infolen;
+    WCHAR buff[256];
+    HWND hDlgCtrl;
+    WORD lang = 0;
+    WORD code = 0;
+    LPLANGANDCODEPAGE lplangcode;
+    WCHAR *str;
+    static const WCHAR wVersionFormat[] = {
+        '%', 'd', '.', '%', 'd', '.', '%', 'd', '.', '%', 'd', 0 };
+    static const WCHAR wFileDescriptionFormat[] = {
+        '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
+        '\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
+        '\\', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 0 };
+    static const WCHAR wLegalCopyrightFormat[] = {
+        '\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
+        '\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
+        '\\', 'L', 'e', 'g', 'a', 'l', 'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', 0 };
+    static const WCHAR wTranslation[] = {
+        'V', 'a', 'r', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
+        '\\', 'T', 'r', 'a', 'n', 's', 'l', 'a', 't', 'i', 'o', 'n', 0 };
+    static const WCHAR wCompanyName[] = {
+        'C', 'o', 'm', 'p', 'a', 'n', 'y', 'N', 'a', 'm', 'e', 0 };
+    static const WCHAR wFileVersion[] = {
+        'F', 'i', 'l', 'e', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
+    static const WCHAR wInternalName[] = {
+        'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', 'N', 'a', 'm', 'e', 0 };
+    static const WCHAR wOriginalFilename[] = {
+        'O', 'r', 'i', 'g', 'i', 'n', 'a', 'l', 'F', 'i', 'l', 'e', 'n', 'a', 'm', 'e', 0 };
+    static const WCHAR wProductName[] = {
+        'P', 'r', 'o', 'd', 'u', 'c', 't', 'N', 'a', 'm', 'e', 0 };
+    static const WCHAR wProductVersion[] = {
+        'P', 'r', 'o', 'd', 'u', 'c', 't', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
+    static const WCHAR wSlash[] = { '\\', 0 };
+
+    if (lpfilename == 0)
+        return FALSE;
 
-  if(!(versize = GetFileVersionInfoSizeW(lpfilename, &handle)))
-  {
-       WARN("GetFileVersionInfoSize failed\n");
-    return FALSE;
-  }
+    if (!(versize = GetFileVersionInfoSizeW(lpfilename, &handle)))
+    {
+        WARN("GetFileVersionInfoSize failed\n");
+        return FALSE;
+    }
 
-  if(!(pBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, versize)))
-  {
-       WARN("HeapAlloc failed bytes %x\n",versize);
-    return FALSE;
-  }
+    if (!(pBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, versize)))
+    {
+        WARN("HeapAlloc failed bytes %x\n", versize);
+        return FALSE;
+    }
 
-  if(!GetFileVersionInfoW(lpfilename, handle, versize, pBuf))
-  {
-       HeapFree(GetProcessHeap(), 0, pBuf);
-    return FALSE;
-  }
-  if(VerQueryValueW(pBuf, wSlash, &info, &infolen))
-  {
-    VS_FIXEDFILEINFO * inf = (VS_FIXEDFILEINFO *)info;
-    swprintf(buff, wVersionFormat, HIWORD(inf->dwFileVersionMS),
-                                   LOWORD(inf->dwFileVersionMS),
-                                   HIWORD(inf->dwFileVersionLS),
-                                   LOWORD(inf->dwFileVersionLS));
-
-   hDlgCtrl = GetDlgItem(hwndDlg, 14001);
-   TRACE("MS %x LS %x res %s \n",inf->dwFileVersionMS, inf->dwFileVersionLS, debugstr_w(buff));
-   SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
-  }
-  if(VerQueryValueW(pBuf, wTranslation, (LPVOID *)&lplangcode, &infolen))
-  {
-    /* FIXME find language from current locale / if not available,
-        * default to english
-        * for now default to first available language
-     */
-    lang = lplangcode->lang;
-    code = lplangcode->code;
-  }
-
-  swprintf(buff, wFileDescriptionFormat, lang, code);
-  SH_FileVersionQuerySetText(hwndDlg, 14003, pBuf, buff, &str);
-
-  swprintf(buff, wLegalCopyrightFormat, lang, code);
-  SH_FileVersionQuerySetText(hwndDlg, 14005, pBuf, buff, &str);
-
-  /* listbox properties */
-  SH_FileVersionQuerySetListText(hwndDlg, pBuf, wCompanyName, &str, lang, code);
-  SH_FileVersionQuerySetListText(hwndDlg, pBuf, wFileVersion, &str, lang, code);
-  SH_FileVersionQuerySetListText(hwndDlg, pBuf, wInternalName, &str, lang, code);
-
-  /* FIXME insert language identifier */
-
-  SH_FileVersionQuerySetListText(hwndDlg, pBuf, wOriginalFilename, &str, lang, code);
-  SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductName, &str, lang, code);
-  SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductVersion, &str, lang, code);
-  SetWindowLong(hwndDlg, DWL_USER, (LONG)pBuf);
-
-  /* select first item */
-  hDlgCtrl = GetDlgItem(hwndDlg, 14009);
-  SendMessageW(hDlgCtrl, LB_SETCURSEL, 0, 0);
-  str = (WCHAR *)SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)0, (LPARAM)NULL);
-  hDlgCtrl = GetDlgItem(hwndDlg, 14010);
-  SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
-  return TRUE;
+    if (!GetFileVersionInfoW(lpfilename, handle, versize, pBuf))
+    {
+        HeapFree(GetProcessHeap(), 0, pBuf);
+        return FALSE;
+    }
+
+    if (VerQueryValueW(pBuf, wSlash, &info, &infolen))
+    {
+        VS_FIXEDFILEINFO *inf = (VS_FIXEDFILEINFO *)info;
+        swprintf(buff, wVersionFormat, HIWORD(inf->dwFileVersionMS),
+                                       LOWORD(inf->dwFileVersionMS),
+                                       HIWORD(inf->dwFileVersionLS),
+                                       LOWORD(inf->dwFileVersionLS));
+        hDlgCtrl = GetDlgItem(hwndDlg, 14001);
+        TRACE("MS %x LS %x res %s \n", inf->dwFileVersionMS, inf->dwFileVersionLS, debugstr_w(buff));
+        SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
+    }
+
+    if (VerQueryValueW(pBuf, wTranslation, (LPVOID *)&lplangcode, &infolen))
+    {
+        /* FIXME find language from current locale / if not available,
+         * default to english
+         * for now default to first available language
+         */
+        lang = lplangcode->lang;
+        code = lplangcode->code;
+    }
+
+    swprintf(buff, wFileDescriptionFormat, lang, code);
+    SH_FileVersionQuerySetText(hwndDlg, 14003, pBuf, buff, &str);
+
+    swprintf(buff, wLegalCopyrightFormat, lang, code);
+    SH_FileVersionQuerySetText(hwndDlg, 14005, pBuf, buff, &str);
+
+    /* listbox properties */
+    SH_FileVersionQuerySetListText(hwndDlg, pBuf, wCompanyName, &str, lang, code);
+    SH_FileVersionQuerySetListText(hwndDlg, pBuf, wFileVersion, &str, lang, code);
+    SH_FileVersionQuerySetListText(hwndDlg, pBuf, wInternalName, &str, lang, code);
+
+    /* FIXME insert language identifier */
+
+    SH_FileVersionQuerySetListText(hwndDlg, pBuf, wOriginalFilename, &str, lang, code);
+    SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductName, &str, lang, code);
+    SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductVersion, &str, lang, code);
+    SetWindowLong(hwndDlg, DWL_USER, (LONG)pBuf);
+
+    /* select first item */
+    hDlgCtrl = GetDlgItem(hwndDlg, 14009);
+    SendMessageW(hDlgCtrl, LB_SETCURSEL, 0, 0);
+    str = (WCHAR *) SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)0, (LPARAM)NULL);
+    hDlgCtrl = GetDlgItem(hwndDlg, 14010);
+    SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
+
+    return TRUE;
 }
 
 /*************************************************************************
@@ -512,70 +554,71 @@ SH_FileVersionInitialize(HWND hwndDlg, WCHAR * lpfilename)
  *
  * wnd proc of 'Version' property sheet page
  */
+
 INT_PTR
 CALLBACK
-SH_FileVersionDlgProc(
-    HWND hwndDlg,
-    UINT uMsg,
-    WPARAM wParam,
-    LPARAM lParam
-)
+SH_FileVersionDlgProc(HWND hwndDlg,
+                      UINT uMsg,
+                      WPARAM wParam,
+                      LPARAM lParam)
 {
-  LPPROPSHEETPAGE ppsp;
-  WCHAR * lpstr;
-  LPVOID * buf;
-  switch(uMsg)
-  {
-  case WM_INITDIALOG:
-        ppsp = (LPPROPSHEETPAGE)lParam;
-        if(ppsp == NULL)
-          break;
-
-        TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n",hwndDlg, lParam, ppsp->lParam);
-
-        lpstr = (WCHAR *)ppsp->lParam;
-
-        if(lpstr == NULL)
-          break;
-
-        return SH_FileVersionInitialize(hwndDlg, lpstr);
-
-
-  case WM_COMMAND:
-     if(LOWORD(wParam) == 14009 && HIWORD(wParam) == LBN_DBLCLK)
-        {
-       HWND hDlgCtrl;
-          LRESULT lresult;
-          WCHAR * str;
-
-          hDlgCtrl = GetDlgItem(hwndDlg, 14009);
-          lresult = SendMessageW(hDlgCtrl, LB_GETCURSEL, (WPARAM)NULL, (LPARAM)NULL);
-       if(lresult == LB_ERR)
-          {
-            break;
-          }
-       str = (WCHAR *)SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)lresult, (LPARAM)NULL);
-
-          if(str == NULL)
-          {
-                break;
-          }
-          hDlgCtrl = GetDlgItem(hwndDlg, 14010);
-       TRACE("hDlgCtrl %x string %s \n",hDlgCtrl, debugstr_w(str));
-          SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
-       return TRUE;
-        }
-     break;
-
-  case WM_DESTROY:
-       buf = (LPVOID)GetWindowLong(hwndDlg, DWL_USER);
-          HeapFree(GetProcessHeap(), 0, buf);
-       break;
-
-  default:
-         break;
-  }
-  return FALSE;
+    LPPROPSHEETPAGE ppsp;
+    WCHAR *lpstr;
+    LPVOID *buf;
+
+    switch (uMsg)
+    {
+        case WM_INITDIALOG:
+            ppsp = (LPPROPSHEETPAGE)lParam;
+
+            if (ppsp == NULL)
+                break;
+
+            TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n", hwndDlg, lParam, ppsp->lParam);
+
+            lpstr = (WCHAR *)ppsp->lParam;
+
+            if (lpstr == NULL)
+                break;
+
+            return SH_FileVersionInitialize(hwndDlg, lpstr);
+
+        case WM_COMMAND:
+            if (LOWORD(wParam) == 14009 && HIWORD(wParam) == LBN_DBLCLK)
+            {
+                HWND hDlgCtrl;
+                LRESULT lresult;
+                WCHAR *str;
+
+                hDlgCtrl = GetDlgItem(hwndDlg, 14009);
+                lresult = SendMessageW(hDlgCtrl, LB_GETCURSEL, (WPARAM)NULL, (LPARAM)NULL);
+
+                if (lresult == LB_ERR)
+                    break;
+
+                str = (WCHAR *) SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)lresult, (LPARAM)NULL);
+
+                if (str == NULL)
+                    break;
+
+                hDlgCtrl = GetDlgItem(hwndDlg, 14010);
+                TRACE("hDlgCtrl %x string %s \n", hDlgCtrl, debugstr_w(str));
+                SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
+
+                return TRUE;
+            }
+        break;
+
+        case WM_DESTROY:
+            buf = (LPVOID) GetWindowLong(hwndDlg, DWL_USER);
+            HeapFree(GetProcessHeap(), 0, buf);
+            break;
+
+        default:
+            break;
+    }
+
+    return FALSE;
 }
 
 /*************************************************************************
@@ -588,44 +631,54 @@ SH_FileVersionDlgProc(
 
 INT_PTR
 CALLBACK
-SH_FileGeneralDlgProc(
-    HWND hwndDlg,
-    UINT uMsg,
-    WPARAM wParam,
-    LPARAM lParam
-)
+SH_FileGeneralDlgProc(HWND hwndDlg,
+                      UINT uMsg,
+                      WPARAM wParam,
+                      LPARAM lParam)
 {
     LPPROPSHEETPAGEW ppsp;
-    WCHAR * lpstr;
-    switch(uMsg)
+    WCHAR *lpstr;
+
+    switch (uMsg)
     {
-    case WM_INITDIALOG:
-        ppsp = (LPPROPSHEETPAGEW)lParam;
-        if (ppsp == NULL)
-            break;
-        TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n",hwndDlg, lParam, ppsp->lParam);
+        case WM_INITDIALOG:
+            ppsp = (LPPROPSHEETPAGEW)lParam;
 
-        lpstr = (WCHAR *)ppsp->lParam;
+            if (ppsp == NULL)
+                break;
 
-        if ( lpstr == NULL)
-        {
-            ERR("no filename\n");
+            TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n", hwndDlg, lParam, ppsp->lParam);
+
+            lpstr = (WCHAR *)ppsp->lParam;
+
+            if (lpstr == NULL)
+            {
+                ERR("no filename\n");
+                break;
+            }
+
+            /* set general text properties filename filelocation and icon */
+            SH_FileGeneralSetText(hwndDlg, lpstr);
+
+            /* enumerate file extension from registry and application which opens it */
+            SH_FileGeneralSetFileType(hwndDlg, wcsrchr(lpstr, '.'));
+
+            /* set file time create/modfied/accessed */
+            SH_FileGeneralSetFileSizeTime(hwndDlg, lpstr, NULL);
+
+            return TRUE;
+
+        default:
             break;
-        }
-        /* set general text properties filename filelocation and icon */
-        SH_FileGeneralSetText(hwndDlg, lpstr);
-        /* enumerate file extension from registry and application which opens it*/
-        SH_FileGeneralSetFileType(hwndDlg, wcsrchr(lpstr, '.'));
-        /* set file time create/modfied/accessed */
-        SH_FileGeneralSetFileSizeTime(hwndDlg, lpstr, NULL);
-        return TRUE;
-  default:
-      break;
-  }
-  return FALSE;
+    }
+
+    return FALSE;
 }
 
-BOOL CALLBACK AddShellPropSheetExCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
+BOOL
+CALLBACK
+AddShellPropSheetExCallback(HPROPSHEETPAGE hPage,
+                            LPARAM lParam)
 {
     PROPSHEETHEADERW *pinfo = (PROPSHEETHEADERW *)lParam;
 
@@ -634,66 +687,73 @@ BOOL CALLBACK AddShellPropSheetExCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
         pinfo->u3.phpage[pinfo->nPages++] = hPage;
         return TRUE;
     }
+
     return FALSE;
 }
 
-
 int
-EnumPropSheetExt(LPWSTR wFileName, PROPSHEETHEADERW *pinfo, int NumPages, HPSXA * hpsxa, IDataObject *pDataObj)
+EnumPropSheetExt(LPWSTR wFileName, PROPSHEETHEADERW *pinfo, int NumPages, HPSXA *hpsxa, IDataObject *pDataObj)
 {
-    WCHAR szName[MAX_PATH] = {0};
-    WCHAR * pOffset;
+    WCHAR szName[MAX_PATH] = { 0 };
+    WCHAR *pOffset;
     UINT Length;
     DWORD dwName;
     int Pages;
     CLSID clsid;
 
     pOffset = wcsrchr(wFileName, L'.');
+
     if (!pOffset)
     {
         Length = wcslen(szName);
-        if (Length + 6 > sizeof(szName)/sizeof(szName[0]))
-           return 0;
+
+        if (Length + 6 > sizeof(szName) / sizeof(szName[0]))
+            return 0;
 
         if (CLSIDFromString(wFileName, &clsid) == NOERROR)
         {
-           wcscpy(szName, L"CLSID\\");
-           wcscpy(&szName[6], wFileName);
+            wcscpy(szName, L"CLSID\\");
+            wcscpy(&szName[6], wFileName);
         }
         else
         {
-           wcscpy(szName, wFileName);
+            wcscpy(szName, wFileName);
         }
     }
     else
     {
         Length = wcslen(pOffset);
-        if (Length  >= sizeof(szName)/sizeof(szName[0]))
+
+        if (Length >= sizeof(szName) / sizeof(szName[0]))
             return 0;
+
         wcscpy(szName, pOffset);
     }
+
     TRACE("EnumPropSheetExt szName %s\n", debugstr_w(szName));
+
     hpsxa[0] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, szName, NumPages, pDataObj);
-    Pages = SHAddFromPropSheetExtArray(hpsxa[0], AddShellPropSheetExCallback, (LPARAM)pinfo);
+    hpsxa[1] = NULL;
 
+    Pages = SHAddFromPropSheetExtArray(hpsxa[0], AddShellPropSheetExCallback, (LPARAM)pinfo);
 
     if (pOffset)
     {
         /* try to load property sheet handlers from prog id key */
         dwName = sizeof(szName);
+
         if (RegGetValueW(HKEY_CLASSES_ROOT, pOffset, NULL, RRF_RT_REG_SZ, NULL, szName, &dwName) == ERROR_SUCCESS)
         {
             TRACE("EnumPropSheetExt szName %s, pOffset %s\n", debugstr_w(szName), debugstr_w(pOffset));
-            szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0';
+            szName[(sizeof(szName) / sizeof(WCHAR)) - 1] = L'\0';
             hpsxa[1] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, szName, NumPages - Pages, pDataObj);
-            Pages +=SHAddFromPropSheetExtArray(hpsxa[1], AddShellPropSheetExCallback, (LPARAM)pinfo);
+            Pages += SHAddFromPropSheetExtArray(hpsxa[1], AddShellPropSheetExCallback, (LPARAM)pinfo);
         }
     }
+
     return Pages;
 }
 
-
-
 /*************************************************************************
  *
  * SH_ShowPropertiesDialog
@@ -703,38 +763,39 @@ EnumPropSheetExt(LPWSTR wFileName, PROPSHEETHEADERW *pinfo, int NumPages, HPSXA
  * lpf contains (quoted) path of folder/file
  *
  * TODO: provide button change application type if file has registered type
- *        make filename field editable and apply changes to filename on close
+ *       make filename field editable and apply changes to filename on close
  */
 
 BOOL
-SH_ShowPropertiesDialog(WCHAR * lpf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * apidl)
+SH_ShowPropertiesDialog(WCHAR *lpf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl)
 {
     PROPSHEETHEADERW pinfo;
     HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
     WCHAR wFileName[MAX_PATH];
     DWORD dwHandle = 0;
-    WCHAR * pFileName;
+    WCHAR *pFileName;
     HPSXA hpsxa[2];
     INT_PTR res;
-    IDataObjectpDataObj = NULL;
+    IDataObject *pDataObj = NULL;
     HRESULT hResult;
 
     TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(lpf));
 
-    if (lpf== NULL)
+    if (lpf == NULL)
         return FALSE;
 
-    if ( !wcslen(lpf) )
+    if (!wcslen(lpf))
         return FALSE;
 
     memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE);
+
     if (lpf[0] == '"')
     {
         /* remove quotes from lpf */
         LPCWSTR src = lpf + 1;
         LPWSTR dst = wFileName;
 
-        while(*src && *src!='"')
+        while (*src && *src != '"')
             *dst++ = *src++;
 
         *dst = '\0';
@@ -754,38 +815,46 @@ SH_ShowPropertiesDialog(WCHAR * lpf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * a
         return SH_ShowDriveProperties(wFileName, pidlFolder, apidl);
     }
 
-
     pFileName = wcsrchr(wFileName, '\\');
+
     if (!pFileName)
         pFileName = wFileName;
     else
         pFileName++;
 
-
     memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
     pinfo.dwSize = sizeof(PROPSHEETHEADERW);
     pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE;
     pinfo.u3.phpage = hppages;
     pinfo.pszCaption = pFileName;
 
-    hppages[pinfo.nPages] = SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG", SH_FileGeneralDlgProc, (LPARAM)wFileName, NULL);
+    hppages[pinfo.nPages] =
+        SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG",
+                                   SH_FileGeneralDlgProc,
+                                   (LPARAM)wFileName,
+                                   NULL);
+
     if (hppages[pinfo.nPages])
         pinfo.nPages++;
 
+    hResult = SHCreateDataObject(pidlFolder, 1, apidl, NULL, &IID_IDataObject, (LPVOID *)&pDataObj);
 
-    hResult = SHCreateDataObject(pidlFolder, 1, apidl, NULL, &IID_IDataObject, (LPVOID*)&pDataObj);
     if (hResult == S_OK)
     {
-        if (!EnumPropSheetExt(wFileName, &pinfo, MAX_PROPERTY_SHEET_PAGE-1, hpsxa, pDataObj))
+        if (!EnumPropSheetExt(wFileName, &pinfo, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj))
         {
             hpsxa[0] = NULL;
             hpsxa[1] = NULL;
         }
     }
 
-    if ( GetFileVersionInfoSizeW(lpf, &dwHandle))
+    if (GetFileVersionInfoSizeW(lpf, &dwHandle))
     {
-        hppages[pinfo.nPages] = SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",SH_FileVersionDlgProc, (LPARAM)wFileName, NULL);
+        hppages[pinfo.nPages] =
+            SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",
+                                       SH_FileVersionDlgProc,
+                                       (LPARAM)wFileName,
+                                       NULL);
         if (hppages[pinfo.nPages])
             pinfo.nPages++;
     }
@@ -794,11 +863,12 @@ SH_ShowPropertiesDialog(WCHAR * lpf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * a
 
     if (hResult == S_OK)
     {
-            SHDestroyPropSheetExtArray(hpsxa[0]);
-            SHDestroyPropSheetExtArray(hpsxa[1]);
+        SHDestroyPropSheetExtArray(hpsxa[0]);
+        SHDestroyPropSheetExtArray(hpsxa[1]);
         IDataObject_Release(pDataObj);
     }
 
     return (res != -1);
 }
+
 /*EOF */
index c5d0552..e27495f 100644 (file)
@@ -624,7 +624,7 @@ BEGIN
        IDS_MYCOMPUTER              "Ìîÿò êîìïþòúð"
        IDS_RECYCLEBIN_FOLDER_NAME  "Êîø÷å"
        IDS_CONTROLPANEL            "Êðèëî çà óïðàâëåíèå"
-       IDS_ADMINISTRATIVETOOLS     "Óïðàâëåíñêè ñðåäñòâà"
+       IDS_ADMINISTRATIVETOOLS     "Óïðàâíè÷åñêè ñðåäñòâà"
 
        // context menus 
        IDS_VIEW_LARGE              "&Ãîëåìè çíà÷åòà"
@@ -668,10 +668,10 @@ BEGIN
        IDS_SHUTDOWN_PROMPT         "Èñêàòå ëè äà èçêëþ÷èòå êîìïþòúðà?"
 
        // shell folder path default values 
-       IDS_PROGRAMS                "Ïóñêîâ èçáîðíèê\\Programs"
+       IDS_PROGRAMS                "Ïóñêîâ èçáîðíèê\\Ïðèëîæåíèÿ"
        IDS_PERSONAL                "Êíèæà"
        IDS_FAVORITES               "Ëþáèìêè"
-       IDS_STARTUP                 "Ïóñêîâ èçáîðíèê\\Programs\\StartUp"
+       IDS_STARTUP                 "Ïóñêîâ èçáîðíèê\\Ïðèëîæåíèÿ\\Ñàìîçàïóñêàùè"
        IDS_RECENT                  "Ñêîðîøíè"
        IDS_SENDTO                  "Èçïðàùàíå"
        IDS_STARTMENU               "Ïóñêîâ èçáîðíèê"
@@ -690,7 +690,7 @@ BEGIN
        IDS_MYPICTURES              "Ìîèòå èçîáðàæåíèÿ"
        IDS_PROGRAM_FILES_COMMON    "Program Files\\Common Files"
        IDS_COMMON_DOCUMENTS        "Äîêóìåíòè"
-       IDS_ADMINTOOLS              "Ïóñêîâ èçáîðíèê\\Programs\\Administrative Tools"
+       IDS_ADMINTOOLS              "Ïóñêîâ èçáîðíèê\\Ïðèëîæåíèÿ\\Óïðàâíè÷åñêè ñðåäñòâà"
        IDS_COMMON_MUSIC            "Äîêóìåíòè\\Ìóçèêàòà ìè"
        IDS_COMMON_PICTURES         "Äîêóìåíòè\\Ðèñóíêèòå ìè"
        IDS_COMMON_VIDEO            "Äîêóìåíòè\\Ëåíòèòå ìè"
@@ -718,7 +718,7 @@ BEGIN
        IDS_PICK_ICON_TITLE         "Èçáåðåòå çíà÷å"
        IDS_PICK_ICON_FILTER        "Ôàéëîâå ñúñ çíà÷åòà(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0"
        IDS_OPEN_WITH_FILTER        "Èçïúëíèìè ôàéëîâå\0*.exe\0"
-       IDS_DIRECTORY                "Ïàïêà"
+       IDS_DIRECTORY               "Ïàïêà"
        IDS_VIRTUAL_DRIVER          "Âîäà÷ íà ïðèâèäíî óñòðîéñòâî"
        IDS_BAT_FILE                "Ïàêåòåí ôàéë íà ÐåàêòÎÑ"
        IDS_CMD_FILE                "Ïèñàíèå çà óïðàâëåíèå íà ÐåàêòÎÑ"
diff --git a/reactos/dll/win32/shimgvw/lang/bg-BG.rc b/reactos/dll/win32/shimgvw/lang/bg-BG.rc
new file mode 100644 (file)
index 0000000..d429ddd
--- /dev/null
@@ -0,0 +1,17 @@
+LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_APPTITLE    "Ïðåãëåäúò çà ñíèìêè è ôàêñîâå íà ÐåàêòÎÑ"
+    IDS_SETASDESKBG "Ñëàãàíå êàòî ïîäêðàñêà"
+
+    /* Tooltips */
+    IDS_TOOLTIP_NEXT_PIC   "Ñëåäâàùî èçîáðàæåíèå"
+    IDS_TOOLTIP_PREV_PIC   "Ïðåäõîäíî èçîáðàæåíèå"
+    IDS_TOOLTIP_ZOOM_IN    "Óâåëè÷àâàíå (+)"
+    IDS_TOOLTIP_ZOOM_OUT   "Íàìàëÿâàíå (-)"
+    IDS_TOOLTIP_ROT_CLOCKW "Çàâúðòàíå ïî ÷àñîâíèêà (Ctrl+K)"
+    IDS_TOOLTIP_ROT_COUNCW "Çàâúðòàíå ñðåùó ÷àñîâíèêà (Ctrl+L)"
+    IDS_TOOLTIP_PRINT      "Ðàçïå÷àòâàíå (Ctrl+P)"
+    IDS_TOOLTIP_SAVEAS     "Çàïèñâàíå êàòî... (Ctrl+S)"
+END
index 83ce5c9..d94a216 100644 (file)
@@ -1,6 +1,7 @@
 #include <windows.h>
 #include "resource.h"
 
+#include "lang/bg-BG.rc"
 #include "lang/cs-CZ.rc"
 #include "lang/de-DE.rc"
 #include "lang/en-US.rc"
index 677d588..f7908a1 100644 (file)
@@ -58,7 +58,7 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS
 CAPTION "Íàñòðîéêà íà ÐåàêòÎÑ"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    LTEXT "Íàïèøåòå öÿëîòî ñè èìå è èìåòî íà ïðåäïðèÿòèåòî âè.",
+    LTEXT "Íàïèøåòå èìåíàòà ñè è èìåòî íà âàøåòî ïðåäïðèÿòèåòî.",
           IDC_STATIC, 54, 7, 242, 21
     LTEXT "&Èìå:", IDC_STATIC, 54, 37, 44, 8
     EDITTEXT IDC_OWNERNAME, 132, 35, 163, 14, WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL
index ca896ac..ec8c553 100644 (file)
@@ -4833,7 +4833,8 @@ static LRESULT EDIT_WM_LButtonDown(EDITSTATE *es, DWORD keys, INT x, INT y)
        EDIT_EM_SetSel(es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap);
        EDIT_EM_ScrollCaret(es);
        es->region_posx = es->region_posy = 0;
-       SetTimer(es->hwndSelf, 0, 100, NULL);
+       if (!(es->style & ES_MULTILINE))
+           SetTimer(es->hwndSelf, 0, 100, NULL);
 
        if (!(es->flags & EF_FOCUSED))
             SetFocus(es->hwndSelf);
index 8e59cdd..6ac37cb 100644 (file)
@@ -412,6 +412,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
    ULONG HeaderSize;
    ULONG ColorCount;
    PVOID Data;
+   BOOL Hit = FALSE;
 
    if (!(fuLoad & LR_LOADFROMFILE))
    {
@@ -470,8 +471,26 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
          UnmapViewOfFile(BitmapInfo);
       return NULL;
    }
+
+   _SEH2_TRY
+   {
    memcpy(PrivateInfo, BitmapInfo, HeaderSize);
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+      Hit = TRUE;
+   }
+   _SEH2_END;
 
+   if (Hit)
+   {
+      DbgPrint("We have a thread overrun, these are already freed! pi -> %d bi -> %d\n", PrivateInfo, BitmapInfo);
+      RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
+      if (fuLoad & LR_LOADFROMFILE)
+         UnmapViewOfFile(BitmapInfo);
+      return NULL;
+   }
+   
    /* FIXME: Handle color conversion and transparency. */
 
    hScreenDc = CreateCompatibleDC(NULL);
index eafaf66..dbeda42 100644 (file)
@@ -76,6 +76,9 @@
 <directory name="dciman32">
        <xi:include href="dciman32/dciman32.rbuild" />
 </directory>
+<directory name="dwmapi">
+       <xi:include href="dwmapi/dwmapi.rbuild" />
+</directory>
 <directory name="devmgr">
        <xi:include href="devmgr/devmgr.rbuild" />
 </directory>
index 2e7f642..0dcf5a2 100644 (file)
@@ -23,9 +23,6 @@
 #ifndef _WINE_INTERNET_H_
 #define _WINE_INTERNET_H_
 
-/* ReactOS-specific definitions */
-#define CP_UNIXCP   CP_THREAD_ACP
-
 #ifndef __WINE_CONFIG_H
 # error You must include config.h to use this header
 #endif
 #define ioctlsocket ioctl
 #endif /* __MINGW32__ */
 
+/* ReactOS-specific definitions */
+#undef CP_UNIXCP
+#define CP_UNIXCP   CP_THREAD_ACP
+
 /* used for netconnection.c stuff */
 typedef struct
 {
index 09285bc..4799a68 100644 (file)
@@ -49,7 +49,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
 
 #endif
 
+#define ASN_BOOL            (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x01)
 #define ASN_BITSTRING       (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x03)
+#define ASN_BMPSTRING       (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1e)
 
 static BOOL CRYPT_EncodeLen(DWORD len, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
@@ -290,7 +292,7 @@ struct AsnEncodeSequenceItem
     DWORD                 size; /* used during encoding, not for your use */
 };
 
-static BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType,
  struct AsnEncodeSequenceItem items[], DWORD cItem, BYTE *pbEncoded,
  DWORD *pcbEncoded)
 {
@@ -738,6 +740,362 @@ BOOL WINAPI WVTAsn1SpcIndirectDataContentEncode(DWORD dwCertEncodingType,
     return ret;
 }
 
+static BOOL WINAPI CRYPT_AsnEncodeBMPString(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret = TRUE;
+    LPCWSTR str = (LPCWSTR)pvStructInfo;
+    DWORD bytesNeeded, lenBytes, strLen;
+
+    if (str)
+        strLen = lstrlenW(str);
+    else
+        strLen = 0;
+    CRYPT_EncodeLen(strLen * 2, NULL, &lenBytes);
+    bytesNeeded = 1 + lenBytes + strLen * 2;
+    if (!pbEncoded)
+        *pcbEncoded = bytesNeeded;
+    else if (*pcbEncoded < bytesNeeded)
+    {
+        *pcbEncoded = bytesNeeded;
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        DWORD i;
+
+        *pcbEncoded = bytesNeeded;
+        *pbEncoded++ = ASN_BMPSTRING;
+        CRYPT_EncodeLen(strLen * 2, pbEncoded, &lenBytes);
+        pbEncoded += lenBytes;
+        for (i = 0; i < strLen; i++)
+        {
+            *pbEncoded++ = (str[i] & 0xff00) >> 8;
+            *pbEncoded++ = str[i] & 0x00ff;
+        }
+    }
+    return ret;
+}
+
+struct AsnEncodeTagSwappedItem
+{
+    BYTE                  tag;
+    const void           *pvStructInfo;
+    CryptEncodeObjectFunc encodeFunc;
+};
+
+/* Sort of a wacky hack, it encodes something using the struct
+ * AsnEncodeTagSwappedItem's encodeFunc, then replaces the tag byte with the tag
+ * given in the struct AsnEncodeTagSwappedItem.
+ */
+static BOOL WINAPI CRYPT_AsnEncodeSwapTag(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret;
+    const struct AsnEncodeTagSwappedItem *item = pvStructInfo;
+
+    ret = item->encodeFunc(dwCertEncodingType, lpszStructType,
+     item->pvStructInfo, pbEncoded, pcbEncoded);
+    if (ret && pbEncoded)
+        *pbEncoded = item->tag;
+    return ret;
+}
+
+BOOL WINAPI WVTAsn1SpcSpOpusInfoEncode(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret = FALSE;
+
+    TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType,
+     debugstr_a(lpszStructType), pvStructInfo, pbEncoded, pcbEncoded);
+
+    __TRY
+    {
+        const SPC_SP_OPUS_INFO *info = pvStructInfo;
+
+        if (info->pMoreInfo &&
+         info->pMoreInfo->dwLinkChoice != SPC_URL_LINK_CHOICE &&
+         info->pMoreInfo->dwLinkChoice != SPC_MONIKER_LINK_CHOICE &&
+         info->pMoreInfo->dwLinkChoice != SPC_FILE_LINK_CHOICE)
+            SetLastError(E_INVALIDARG);
+        else if (info->pPublisherInfo &&
+         info->pPublisherInfo->dwLinkChoice != SPC_URL_LINK_CHOICE &&
+         info->pPublisherInfo->dwLinkChoice != SPC_MONIKER_LINK_CHOICE &&
+         info->pPublisherInfo->dwLinkChoice != SPC_FILE_LINK_CHOICE)
+            SetLastError(E_INVALIDARG);
+        else
+        {
+            struct AsnEncodeSequenceItem items[3] = { { 0 } };
+            struct AsnConstructedItem constructed[3] = { { 0 } };
+            struct AsnEncodeTagSwappedItem swapped;
+            DWORD cItem = 0, cConstructed = 0;
+
+            if (info->pwszProgramName)
+            {
+                swapped.tag = ASN_CONTEXT;
+                swapped.pvStructInfo = info->pwszProgramName;
+                swapped.encodeFunc = CRYPT_AsnEncodeBMPString;
+                constructed[cConstructed].tag = 0;
+                constructed[cConstructed].pvStructInfo = &swapped;
+                constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeSwapTag;
+                items[cItem].pvStructInfo = &constructed[cConstructed];
+                items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
+                cConstructed++;
+                cItem++;
+            }
+            if (info->pMoreInfo)
+            {
+                constructed[cConstructed].tag = 1;
+                constructed[cConstructed].pvStructInfo = info->pMoreInfo;
+                constructed[cConstructed].encodeFunc = WVTAsn1SpcLinkEncode;
+                items[cItem].pvStructInfo = &constructed[cConstructed];
+                items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
+                cConstructed++;
+                cItem++;
+            }
+            if (info->pPublisherInfo)
+            {
+                constructed[cConstructed].tag = 2;
+                constructed[cConstructed].pvStructInfo = info->pPublisherInfo;
+                constructed[cConstructed].encodeFunc = WVTAsn1SpcLinkEncode;
+                items[cItem].pvStructInfo = &constructed[cConstructed];
+                items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
+                cConstructed++;
+                cItem++;
+            }
+            ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING,
+             items, cItem, pbEncoded, pcbEncoded);
+        }
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    return ret;
+}
+
+static BOOL CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret;
+
+    __TRY
+    {
+        DWORD significantBytes, lenBytes, bytesNeeded;
+        BYTE padByte = 0;
+        BOOL pad = FALSE;
+        const CRYPT_INTEGER_BLOB *blob =
+         (const CRYPT_INTEGER_BLOB *)pvStructInfo;
+
+        significantBytes = blob->cbData;
+        if (significantBytes)
+        {
+            if (blob->pbData[significantBytes - 1] & 0x80)
+            {
+                /* negative, lop off leading (little-endian) 0xffs */
+                for (; significantBytes > 0 &&
+                 blob->pbData[significantBytes - 1] == 0xff; significantBytes--)
+                    ;
+                if (blob->pbData[significantBytes - 1] < 0x80)
+                {
+                    padByte = 0xff;
+                    pad = TRUE;
+                }
+            }
+            else
+            {
+                /* positive, lop off leading (little-endian) zeroes */
+                for (; significantBytes > 0 &&
+                 !blob->pbData[significantBytes - 1]; significantBytes--)
+                    ;
+                if (significantBytes == 0)
+                    significantBytes = 1;
+                if (blob->pbData[significantBytes - 1] > 0x7f)
+                {
+                    padByte = 0;
+                    pad = TRUE;
+                }
+            }
+        }
+        if (pad)
+            CRYPT_EncodeLen(significantBytes + 1, NULL, &lenBytes);
+        else
+            CRYPT_EncodeLen(significantBytes, NULL, &lenBytes);
+        bytesNeeded = 1 + lenBytes + significantBytes;
+        if (pad)
+            bytesNeeded++;
+        if (!pbEncoded)
+        {
+            *pcbEncoded = bytesNeeded;
+            ret = TRUE;
+        }
+        else if (*pcbEncoded < bytesNeeded)
+        {
+            *pcbEncoded = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            *pcbEncoded = bytesNeeded;
+            *pbEncoded++ = ASN_INTEGER;
+            if (pad)
+            {
+                CRYPT_EncodeLen(significantBytes + 1, pbEncoded, &lenBytes);
+                pbEncoded += lenBytes;
+                *pbEncoded++ = padByte;
+            }
+            else
+            {
+                CRYPT_EncodeLen(significantBytes, pbEncoded, &lenBytes);
+                pbEncoded += lenBytes;
+            }
+            for (; significantBytes > 0; significantBytes--)
+                *(pbEncoded++) = blob->pbData[significantBytes - 1];
+            ret = TRUE;
+        }
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+        ret = FALSE;
+    }
+    __ENDTRY
+    return ret;
+}
+
+BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    CRYPT_INTEGER_BLOB blob = { sizeof(INT), (BYTE *)pvStructInfo };
+
+    return CRYPT_AsnEncodeInteger(dwCertEncodingType, X509_MULTI_BYTE_INTEGER,
+     &blob, pbEncoded, pcbEncoded);
+}
+
+BOOL WINAPI WVTAsn1CatMemberInfoEncode(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret = FALSE;
+
+    TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType,
+     debugstr_a(lpszStructType), pvStructInfo, pbEncoded, pcbEncoded);
+
+    __TRY
+    {
+        const CAT_MEMBERINFO *info = (const CAT_MEMBERINFO *)pvStructInfo;
+        struct AsnEncodeSequenceItem items[] = {
+         { info->pwszSubjGuid, CRYPT_AsnEncodeBMPString, 0 },
+         { &info->dwCertVersion, CRYPT_AsnEncodeInt, 0 },
+        };
+
+        ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING,
+         items, sizeof(items) / sizeof(items[0]), pbEncoded, pcbEncoded);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    return ret;
+}
+
+BOOL WINAPI WVTAsn1CatNameValueEncode(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret = FALSE;
+
+    TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType,
+     debugstr_a(lpszStructType), pvStructInfo, pbEncoded, pcbEncoded);
+
+    __TRY
+    {
+        const CAT_NAMEVALUE *value = (const CAT_NAMEVALUE *)pvStructInfo;
+        struct AsnEncodeSequenceItem items[] = {
+         { value->pwszTag,   CRYPT_AsnEncodeBMPString, 0 },
+         { &value->fdwFlags, CRYPT_AsnEncodeInt, 0 },
+         { &value->Value,    CRYPT_AsnEncodeOctets, 0 },
+        };
+
+        ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING,
+         items, sizeof(items) / sizeof(items[0]), pbEncoded, pcbEncoded);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnEncodeBool(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL val = *(const BOOL *)pvStructInfo, ret;
+
+    TRACE("%d\n", val);
+
+    if (!pbEncoded)
+    {
+        *pcbEncoded = 3;
+        ret = TRUE;
+    }
+    else if (*pcbEncoded < 3)
+    {
+        *pcbEncoded = 3;
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        *pcbEncoded = 3;
+        *pbEncoded++ = ASN_BOOL;
+        *pbEncoded++ = 1;
+        *pbEncoded++ = val ? 0xff : 0;
+        ret = TRUE;
+    }
+    TRACE("returning %d (%08x)\n", ret, GetLastError());
+    return ret;
+}
+
+BOOL WINAPI WVTAsn1SpcFinancialCriteriaInfoEncode(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+    BOOL ret = FALSE;
+
+    TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType,
+     debugstr_a(lpszStructType), pvStructInfo, pbEncoded, pcbEncoded);
+
+    __TRY
+    {
+        const SPC_FINANCIAL_CRITERIA *criteria = pvStructInfo;
+        struct AsnEncodeSequenceItem items[] = {
+         { &criteria->fFinancialInfoAvailable, CRYPT_AsnEncodeBool, 0 },
+         { &criteria->fMeetsCriteria,          CRYPT_AsnEncodeBool, 0 },
+        };
+
+        ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING,
+         items, sizeof(items) / sizeof(items[0]), pbEncoded, pcbEncoded);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    return ret;
+}
+
 /* Gets the number of length bytes from the given (leading) length byte */
 #define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
 
@@ -868,7 +1226,7 @@ static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
     return ret;
 }
 
-static BOOL WINAPI CRYPT_AsnDecodeSPCLinkInternal(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnDecodeSPCLinkInternal(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  void *pvStructInfo, DWORD *pcbStructInfo)
 {
@@ -1733,3 +2091,271 @@ BOOL WINAPI WVTAsn1SpcSpOpusInfoDecode(DWORD dwCertEncodingType,
      pvStructInfo, *pcbStructInfo);
     return FALSE;
 }
+
+static BOOL WINAPI CRYPT_AsnDecodeBMPString(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret;
+    DWORD bytesNeeded, dataLen;
+
+    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+    {
+        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+
+        bytesNeeded = dataLen + 2 + sizeof(LPWSTR);
+        if (!pvStructInfo)
+            *pcbStructInfo = bytesNeeded;
+        else if (*pcbStructInfo < bytesNeeded)
+        {
+            *pcbStructInfo = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            LPWSTR str;
+            DWORD i;
+
+            *pcbStructInfo = bytesNeeded;
+            assert(pvStructInfo);
+            str = *(LPWSTR *)pvStructInfo;
+            for (i = 0; i < dataLen / 2; i++)
+                str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
+                 pbEncoded[1 + lenBytes + 2 * i + 1];
+            /* Decoded string is always NULL-terminated */
+            str[i] = '\0';
+        }
+    }
+    return ret;
+}
+
+static BOOL CRYPT_AsnDecodeInteger(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret;
+    DWORD bytesNeeded, dataLen;
+
+    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+    {
+        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+
+        bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
+        if (!pvStructInfo)
+            *pcbStructInfo = bytesNeeded;
+        else if (*pcbStructInfo < bytesNeeded)
+        {
+            *pcbStructInfo = bytesNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
+
+            *pcbStructInfo = bytesNeeded;
+            blob->cbData = dataLen;
+            assert(blob->pbData);
+            if (blob->cbData)
+            {
+                DWORD i;
+
+                for (i = 0; i < blob->cbData; i++)
+                {
+                    blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
+                     dataLen - i - 1);
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+/* Ignores tag.  Only allows integers 4 bytes or smaller in size. */
+static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret;
+    BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
+    CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
+    DWORD size = sizeof(buf);
+
+    blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
+    ret = CRYPT_AsnDecodeInteger(pbEncoded, cbEncoded, 0, buf, &size);
+    if (ret)
+    {
+        if (!pvStructInfo)
+            *pcbStructInfo = sizeof(int);
+        else if (*pcbStructInfo < sizeof(int))
+        {
+            *pcbStructInfo = sizeof(int);
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+        {
+            int val;
+            DWORD i;
+
+            *pcbStructInfo = sizeof(int);
+            if (blob->pbData[blob->cbData - 1] & 0x80)
+            {
+                /* initialize to a negative value to sign-extend */
+                val = -1;
+            }
+            else
+                val = 0;
+            for (i = 0; i < blob->cbData; i++)
+            {
+                val <<= 8;
+                val |= blob->pbData[blob->cbData - i - 1];
+            }
+            memcpy(pvStructInfo, &val, sizeof(int));
+        }
+    }
+    else if (GetLastError() == ERROR_MORE_DATA)
+        SetLastError(CRYPT_E_ASN1_LARGE);
+    return ret;
+}
+
+BOOL WINAPI WVTAsn1CatMemberInfoDecode(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret = FALSE;
+
+    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, *pcbStructInfo);
+
+    __TRY
+    {
+        struct AsnDecodeSequenceItem items[] = {
+         { ASN_BMPSTRING, offsetof(CAT_MEMBERINFO, pwszSubjGuid),
+           CRYPT_AsnDecodeBMPString, sizeof(LPWSTR), FALSE, TRUE,
+           offsetof(CAT_MEMBERINFO, pwszSubjGuid), 0 },
+         { ASN_INTEGER, offsetof(CAT_MEMBERINFO, dwCertVersion),
+           CRYPT_AsnDecodeInt, sizeof(DWORD),
+           FALSE, FALSE, 0, 0 },
+        };
+
+        ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
+         sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
+         pvStructInfo, pcbStructInfo, NULL);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
+BOOL WINAPI WVTAsn1CatNameValueDecode(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret = FALSE;
+
+    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, *pcbStructInfo);
+
+    __TRY
+    {
+        struct AsnDecodeSequenceItem items[] = {
+         { ASN_BMPSTRING, offsetof(CAT_NAMEVALUE, pwszTag),
+           CRYPT_AsnDecodeBMPString, sizeof(LPWSTR), FALSE, TRUE,
+           offsetof(CAT_NAMEVALUE, pwszTag), 0 },
+         { ASN_INTEGER, offsetof(CAT_NAMEVALUE, fdwFlags),
+           CRYPT_AsnDecodeInt, sizeof(DWORD), FALSE, FALSE, 0, 0 },
+         { ASN_OCTETSTRING, offsetof(CAT_NAMEVALUE, Value),
+           CRYPT_AsnDecodeOctets, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
+           offsetof(CAT_NAMEVALUE, Value.pbData), 0 },
+        };
+
+        ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
+         sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
+         pvStructInfo, pcbStructInfo, NULL);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeBool(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret;
+
+    if (cbEncoded < 3)
+    {
+        SetLastError(CRYPT_E_ASN1_CORRUPT);
+        return FALSE;
+    }
+    if (GET_LEN_BYTES(pbEncoded[1]) > 1)
+    {
+        SetLastError(CRYPT_E_ASN1_CORRUPT);
+        return FALSE;
+    }
+    if (pbEncoded[1] > 1)
+    {
+        SetLastError(CRYPT_E_ASN1_CORRUPT);
+        return FALSE;
+    }
+    if (!pvStructInfo)
+    {
+        *pcbStructInfo = sizeof(BOOL);
+        ret = TRUE;
+    }
+    else if (*pcbStructInfo < sizeof(BOOL))
+    {
+        *pcbStructInfo = sizeof(BOOL);
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        *pcbStructInfo = sizeof(BOOL);
+        *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
+        ret = TRUE;
+    }
+    TRACE("returning %d (%08x)\n", ret, GetLastError());
+    return ret;
+}
+
+BOOL WINAPI WVTAsn1SpcFinancialCriteriaInfoDecode(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret = FALSE;
+
+    TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
+     pvStructInfo, *pcbStructInfo);
+
+    __TRY
+    {
+        struct AsnDecodeSequenceItem items[] = {
+         { ASN_BOOL, offsetof(SPC_FINANCIAL_CRITERIA, fFinancialInfoAvailable),
+           CRYPT_AsnDecodeBool, sizeof(BOOL), FALSE, FALSE, 0, 0 },
+         { ASN_BOOL, offsetof(SPC_FINANCIAL_CRITERIA, fMeetsCriteria),
+           CRYPT_AsnDecodeBool, sizeof(BOOL), FALSE, FALSE, 0, 0 },
+        };
+
+        ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
+         sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
+         pvStructInfo, pcbStructInfo, NULL);
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+    }
+    __ENDTRY
+    TRACE("returning %d\n", ret);
+    return ret;
+}
index e2129df..6337a85 100644 (file)
 #include "imagehlp.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
 
+#define CATADMIN_MAGIC 0x43415441 /* 'CATA' */
+#define CATINFO_MAGIC  0x43415449 /* 'CATI' */
+
+struct catadmin
+{
+    DWORD magic;
+    WCHAR path[MAX_PATH];
+};
+
+struct catinfo
+{
+    DWORD magic;
+    WCHAR file[MAX_PATH];
+};
+
 /***********************************************************************
  *      CryptCATAdminAcquireContext (WINTRUST.@)
  *
@@ -42,7 +58,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
  *
  * PARAMS
  *   catAdmin  [O] Pointer to the context handle.
- *   sysSystem [I] Pointer to a GUID for the needed subsystem.
+ *   sys       [I] Pointer to a GUID for the needed subsystem.
  *   dwFlags   [I] Reserved.
  *
  * RETURNS
@@ -50,31 +66,108 @@ WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
  *   Failure: FALSE.
  *
  */
-BOOL WINAPI CryptCATAdminAcquireContext(HCATADMINcatAdmin,
-                    const GUID *sysSystem, DWORD dwFlags )
+BOOL WINAPI CryptCATAdminAcquireContext(HCATADMIN *catAdmin,
+                                        const GUID *sys, DWORD dwFlags)
 {
-    FIXME("%p %s %x\n", catAdmin, debugstr_guid(sysSystem), dwFlags);
+    static const WCHAR catroot[] =
+        {'\\','c','a','t','r','o','o','t',0};
+    static const WCHAR fmt[] =
+        {'%','s','\\','{','%','0','8','x','-','%','0','4','x','-','%','0',
+         '4','x','-','%','0','2','x','%','0','2','x','-','%','0','2','x',
+         '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',
+         '%','0','2','x','}',0};
+    static const GUID defsys =
+        {0x127d0a1d,0x4ef2,0x11d1,{0x86,0x08,0x00,0xc0,0x4f,0xc2,0x95,0xee}};
+
+    WCHAR catroot_dir[MAX_PATH];
+    struct catadmin *ca;
+
+    TRACE("%p %s %x\n", catAdmin, debugstr_guid(sys), dwFlags);
 
     if (!catAdmin)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
+    if (!(ca = HeapAlloc(GetProcessHeap(), 0, sizeof(*ca))))
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        return FALSE;
+    }
+
+    GetSystemDirectoryW(catroot_dir, MAX_PATH);
+    strcatW(catroot_dir, catroot);
 
-    *catAdmin = (HCATADMIN)0xdeadbeef;
+    /* create the directory if it doesn't exist */
+    CreateDirectoryW(catroot_dir, NULL);
 
+    if (!sys) sys = &defsys;
+    sprintfW(ca->path, fmt, catroot_dir, sys->Data1, sys->Data2,
+             sys->Data3, sys->Data4[0], sys->Data4[1], sys->Data4[2],
+             sys->Data4[3], sys->Data4[4], sys->Data4[5], sys->Data4[6],
+             sys->Data4[7]);
+
+    /* create the directory if it doesn't exist */
+    CreateDirectoryW(ca->path, NULL);
+
+    ca->magic = CATADMIN_MAGIC;
+    *catAdmin = ca;
     return TRUE;
 }
 
 /***********************************************************************
  *             CryptCATAdminAddCatalog (WINTRUST.@)
  */
-BOOL WINAPI CryptCATAdminAddCatalog(HCATADMIN catAdmin, PWSTR catalogFile,
-                                    PWSTR selectBaseName, DWORD flags)
+HCATINFO WINAPI CryptCATAdminAddCatalog(HCATADMIN catAdmin, PWSTR catalogFile,
+                                        PWSTR selectBaseName, DWORD flags)
 {
-    FIXME("%p %s %s %d\n", catAdmin, debugstr_w(catalogFile),
+    static const WCHAR slashW[] = {'\\',0};
+    struct catadmin *ca = catAdmin;
+    struct catinfo *ci;
+    WCHAR *target;
+    DWORD len;
+
+    TRACE("%p %s %s %d\n", catAdmin, debugstr_w(catalogFile),
           debugstr_w(selectBaseName), flags);
-    return TRUE;
+
+    if (!selectBaseName)
+    {
+        FIXME("NULL basename not handled\n");
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    if (!ca || ca->magic != CATADMIN_MAGIC || !catalogFile || flags)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    len = strlenW(ca->path) + strlenW(selectBaseName) + 2;
+    if (!(target = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        return FALSE;
+    }
+    strcpyW(target, ca->path);
+    strcatW(target, slashW);
+    strcatW(target, selectBaseName);
+
+    if (!CopyFileW(catalogFile, target, FALSE))
+    {
+        HeapFree(GetProcessHeap(), 0, target);
+        return NULL;
+    }
+    if (!(ci = HeapAlloc(GetProcessHeap(), 0, sizeof(*ci))))
+    {
+        HeapFree(GetProcessHeap(), 0, target);
+        SetLastError(ERROR_OUTOFMEMORY);
+        return FALSE;
+    }
+    ci->magic = CATINFO_MAGIC;
+    strcpyW(ci->file, selectBaseName);
+
+    HeapFree(GetProcessHeap(), 0, target);
+    return ci;
 }
 
 /***********************************************************************
@@ -83,10 +176,59 @@ BOOL WINAPI CryptCATAdminAddCatalog(HCATADMIN catAdmin, PWSTR catalogFile,
 BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD* pcbHash,
                                                 BYTE* pbHash, DWORD dwFlags )
 {
-    FIXME("%p %p %p %x\n", hFile, pcbHash, pbHash, dwFlags);
+    BOOL ret = FALSE;
 
-    if (pbHash && pcbHash) memset(pbHash, 0, *pcbHash);
-    return TRUE;
+    TRACE("%p %p %p %x\n", hFile, pcbHash, pbHash, dwFlags);
+
+    if (!hFile || !pcbHash || dwFlags)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    if (*pcbHash < 20)
+    {
+        *pcbHash = 20;
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return TRUE;
+    }
+
+    *pcbHash = 20;
+    if (pbHash)
+    {
+        HCRYPTPROV prov;
+        HCRYPTHASH hash;
+        DWORD bytes_read;
+        BYTE *buffer;
+
+        if (!(buffer = HeapAlloc(GetProcessHeap(), 0, 4096)))
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+        if (!ret)
+        {
+            HeapFree(GetProcessHeap(), 0, buffer);
+            return FALSE;
+        }
+        ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash);
+        if (!ret)
+        {
+            HeapFree(GetProcessHeap(), 0, buffer);
+            CryptReleaseContext(prov, 0);
+            return FALSE;
+        }
+        while ((ret = ReadFile(hFile, buffer, 4096, &bytes_read, NULL)) && bytes_read)
+        {
+            CryptHashData(hash, buffer, bytes_read, 0);
+        }
+        if (ret) ret = CryptGetHashParam(hash, HP_HASHVAL, pbHash, pcbHash, 0);
+
+        HeapFree(GetProcessHeap(), 0, buffer);
+        CryptDestroyHash(hash);
+        CryptReleaseContext(prov, 0);
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -114,15 +256,25 @@ HCATINFO WINAPI CryptCATAdminEnumCatalogFromHash(HCATADMIN hCatAdmin,
  *
  * RETURNS
  *   Success: TRUE.
- *   Failure: FAIL.
+ *   Failure: FALSE.
  *
  */
 BOOL WINAPI CryptCATAdminReleaseCatalogContext(HCATADMIN hCatAdmin,
                                                HCATINFO hCatInfo,
                                                DWORD dwFlags)
 {
-    FIXME("%p %p %x\n", hCatAdmin, hCatInfo, dwFlags);
-    return TRUE;
+    struct catinfo *ci = hCatInfo;
+    struct catadmin *ca = hCatAdmin;
+
+    TRACE("%p %p %x\n", hCatAdmin, hCatInfo, dwFlags);
+
+    if (!ca || ca->magic != CATADMIN_MAGIC || !ci || ci->magic != CATINFO_MAGIC)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    ci->magic = 0;
+    return HeapFree(GetProcessHeap(), 0, ci);
 }
 
 /***********************************************************************
@@ -136,13 +288,22 @@ BOOL WINAPI CryptCATAdminReleaseCatalogContext(HCATADMIN hCatAdmin,
  *
  * RETURNS
  *   Success: TRUE.
- *   Failure: FAIL.
+ *   Failure: FALSE.
  *
  */
 BOOL WINAPI CryptCATAdminReleaseContext(HCATADMIN hCatAdmin, DWORD dwFlags )
 {
-    FIXME("%p %x\n", hCatAdmin, dwFlags);
-    return TRUE;
+    struct catadmin *ca = hCatAdmin;
+
+    TRACE("%p %x\n", hCatAdmin, dwFlags);
+
+    if (!ca || ca->magic != CATADMIN_MAGIC)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    ca->magic = 0;
+    return HeapFree(GetProcessHeap(), 0, ca);
 }
 
 /***********************************************************************
@@ -162,7 +323,15 @@ BOOL WINAPI CryptCATAdminReleaseContext(HCATADMIN hCatAdmin, DWORD dwFlags )
  */
 BOOL WINAPI CryptCATAdminRemoveCatalog(HCATADMIN hCatAdmin, LPCWSTR pwszCatalogFile, DWORD dwFlags)
 {
-    FIXME("%p %s %x\n", hCatAdmin, debugstr_w(pwszCatalogFile), dwFlags);
+    struct catadmin *ca = hCatAdmin;
+
+    TRACE("%p %s %x\n", hCatAdmin, debugstr_w(pwszCatalogFile), dwFlags);
+
+    if (!ca || ca->magic != CATADMIN_MAGIC)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
     return DeleteFileW(pwszCatalogFile);
 }
 
@@ -349,7 +518,7 @@ static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo,
     /* get basic offset & size info */
     base_offset = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR);
 
-    if (SetFilePointer(pSubjectInfo->hFile, 0, NULL, SEEK_END) == -1)
+    if (SetFilePointer(pSubjectInfo->hFile, 0, NULL, SEEK_END) == INVALID_SET_FILE_POINTER)
     {
         TRACE("seek error\n");
         return FALSE;
@@ -357,7 +526,7 @@ static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo,
 
     cabsize = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR);
     if ((cabsize == -1) || (base_offset == -1) ||
-     (SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET) == -1))
+     (SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER))
     {
         TRACE("seek error\n");
         return FALSE;
@@ -453,7 +622,7 @@ static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo,
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
         return FALSE;
     }
-    if (SetFilePointer(pSubjectInfo->hFile, cert_offset, NULL, SEEK_SET) == -1)
+    if (SetFilePointer(pSubjectInfo->hFile, cert_offset, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER)
     {
         ERR("couldn't seek to cert location\n");
         return FALSE;
@@ -472,6 +641,41 @@ static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo,
     return TRUE;
 }
 
+static BOOL WINTRUST_GetSignedMsgFromCatFile(SIP_SUBJECTINFO *pSubjectInfo,
+ DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg,
+ BYTE *pbSignedDataMsg)
+{
+    BOOL ret;
+
+    TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
+          pcbSignedDataMsg, pbSignedDataMsg);
+
+    if (!pbSignedDataMsg)
+    {
+        *pcbSignedDataMsg = GetFileSize(pSubjectInfo->hFile, NULL);
+         ret = TRUE;
+    }
+    else
+    {
+        DWORD len = GetFileSize(pSubjectInfo->hFile, NULL);
+
+        if (*pcbSignedDataMsg < len)
+        {
+            *pcbSignedDataMsg = len;
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            ret = FALSE;
+        }
+        else
+        {
+            ret = ReadFile(pSubjectInfo->hFile, pbSignedDataMsg, len,
+             pcbSignedDataMsg, NULL);
+            if (ret)
+                *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+        }
+    }
+    return ret;
+}
+
 /***********************************************************************
  *      CryptSIPGetSignedDataMsg  (WINTRUST.@)
  */
@@ -482,6 +686,8 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn
      0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
     static const GUID cabGUID = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,
      0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
+    static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,
+     0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
     BOOL ret;
 
     TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
@@ -493,6 +699,9 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn
     else if (!memcmp(pSubjectInfo->pgSubjectType, &cabGUID, sizeof(cabGUID)))
         ret = WINTRUST_GetSignedMsgFromCabFile(pSubjectInfo, pdwEncodingType,
          dwIndex, pcbSignedDataMsg, pbSignedDataMsg);
+    else if (!memcmp(pSubjectInfo->pgSubjectType, &catGUID, sizeof(catGUID)))
+        ret = WINTRUST_GetSignedMsgFromCatFile(pSubjectInfo, pdwEncodingType,
+         dwIndex, pcbSignedDataMsg, pbSignedDataMsg);
     else
     {
         FIXME("unimplemented for subject type %s\n",
index c2eb1eb..e0acf03 100644 (file)
@@ -128,7 +128,8 @@ static BOOL SOFTPUB_GetSIP(CRYPT_PROVIDER_DATA *data)
 /* Assumes data->u.pPDSip has been loaded, and data->u.pPDSip->pSip allocated.
  * Calls data->u.pPDSip->pSip->pfGet to construct data->hMsg.
  */
-static BOOL SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data)
+static BOOL SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data, HANDLE file,
+ LPCWSTR filePath)
 {
     BOOL ret;
     LPBYTE buf = NULL;
@@ -144,9 +145,8 @@ static BOOL SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data)
 
     data->u.pPDSip->psSipSubjectInfo->cbSize = sizeof(SIP_SUBJECTINFO);
     data->u.pPDSip->psSipSubjectInfo->pgSubjectType = &data->u.pPDSip->gSubject;
-    data->u.pPDSip->psSipSubjectInfo->hFile = data->pWintrustData->u.pFile->hFile;
-    data->u.pPDSip->psSipSubjectInfo->pwsFileName =
-     data->pWintrustData->u.pFile->pcwszFilePath;
+    data->u.pPDSip->psSipSubjectInfo->hFile = file;
+    data->u.pPDSip->psSipSubjectInfo->pwsFileName = filePath;
     data->u.pPDSip->psSipSubjectInfo->hProv = data->hProv;
     ret = data->u.pPDSip->pSip->pfGet(data->u.pPDSip->psSipSubjectInfo,
      &data->dwEncoding, 0, &size, 0);
@@ -198,146 +198,193 @@ static DWORD SOFTPUB_DecodeInnerContent(CRYPT_PROVIDER_DATA *data)
 {
     BOOL ret;
     DWORD size;
+    LPSTR oid = NULL;
     LPBYTE buf = NULL;
 
     ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL,
      &size);
     if (!ret)
         goto error;
-    buf = data->psPfns->pfnAlloc(size);
-    if (!buf)
+    oid = data->psPfns->pfnAlloc(size);
+    if (!oid)
     {
         SetLastError(ERROR_OUTOFMEMORY);
         ret = FALSE;
         goto error;
     }
-    ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, buf,
+    ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, oid,
      &size);
     if (!ret)
         goto error;
-    if (!strcmp((LPCSTR)buf, SPC_INDIRECT_DATA_OBJID))
-    {
-        data->psPfns->pfnFree(buf);
-        buf = NULL;
-        ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, NULL, &size);
-        if (!ret)
-            goto error;
-        buf = data->psPfns->pfnAlloc(size);
-        if (!buf)
-        {
-            SetLastError(ERROR_OUTOFMEMORY);
-            ret = FALSE;
-            goto error;
-        }
-        ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, buf, &size);
-        if (!ret)
-            goto error;
-        ret = CryptDecodeObject(data->dwEncoding,
-         SPC_INDIRECT_DATA_CONTENT_STRUCT, buf, size, 0, NULL, &size);
-        if (!ret)
-            goto error;
-        data->u.pPDSip->psIndirectData = data->psPfns->pfnAlloc(size);
-        if (!data->u.pPDSip->psIndirectData)
-        {
-            SetLastError(ERROR_OUTOFMEMORY);
-            ret = FALSE;
-            goto error;
-        }
-        ret = CryptDecodeObject(data->dwEncoding,
-         SPC_INDIRECT_DATA_CONTENT_STRUCT, buf, size, 0,
-         data->u.pPDSip->psIndirectData, &size);
+    ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, NULL, &size);
+    if (!ret)
+        goto error;
+    buf = data->psPfns->pfnAlloc(size);
+    if (!buf)
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        ret = FALSE;
+        goto error;
     }
-    else
+    ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, buf, &size);
+    if (!ret)
+        goto error;
+    ret = CryptDecodeObject(data->dwEncoding, oid, buf, size, 0, NULL, &size);
+    if (!ret)
+        goto error;
+    data->u.pPDSip->psIndirectData = data->psPfns->pfnAlloc(size);
+    if (!data->u.pPDSip->psIndirectData)
     {
-        FIXME("unimplemented for OID %s\n", (LPCSTR)buf);
-        SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
+        SetLastError(ERROR_OUTOFMEMORY);
         ret = FALSE;
+        goto error;
     }
+    ret = CryptDecodeObject(data->dwEncoding, oid, buf, size, 0,
+     data->u.pPDSip->psIndirectData, &size);
 
 error:
     TRACE("returning %d\n", ret);
+    data->psPfns->pfnFree(oid);
+    data->psPfns->pfnFree(buf);
     return ret;
 }
 
-HRESULT WINAPI SoftpubLoadMessage(CRYPT_PROVIDER_DATA *data)
+static BOOL SOFTPUB_LoadCertMessage(CRYPT_PROVIDER_DATA *data)
 {
     BOOL ret;
 
-    TRACE("(%p)\n", data);
-
-    if (!data->padwTrustStepErrors)
-        return S_FALSE;
-
-    switch (data->pWintrustData->dwUnionChoice)
+    if (data->pWintrustData->u.pCert &&
+     data->pWintrustData->u.pCert->cbStruct == sizeof(WINTRUST_CERT_INFO))
     {
-    case WTD_CHOICE_CERT:
-        if (data->pWintrustData->u.pCert &&
-         data->pWintrustData->u.pCert->cbStruct == sizeof(WINTRUST_CERT_INFO))
+        if (data->psPfns)
         {
-            if (data->psPfns)
+            CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
+            DWORD i;
+
+            /* Add a signer with nothing but the time to verify, so we can
+             * add a cert to it
+             */
+            if (data->pWintrustData->u.pCert->psftVerifyAsOf)
+                data->sftSystemTime = signer.sftVerifyAsOf;
+            else
             {
-                CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
-                DWORD i;
-
-                /* Add a signer with nothing but the time to verify, so we can
-                 * add a cert to it
-                 */
-                if (data->pWintrustData->u.pCert->psftVerifyAsOf)
-                    data->sftSystemTime = signer.sftVerifyAsOf;
-                else
-                {
-                    SYSTEMTIME sysTime;
+                SYSTEMTIME sysTime;
 
-                    GetSystemTime(&sysTime);
-                    SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
-                }
-                ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
-                if (!ret)
-                    goto error;
+                GetSystemTime(&sysTime);
+                SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
+            }
+            ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
+            if (ret)
+            {
                 ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
                  data->pWintrustData->u.pCert->psCertContext);
-                if (!ret)
-                    goto error;
                 for (i = 0; ret && i < data->pWintrustData->u.pCert->chStores;
                  i++)
                     ret = data->psPfns->pfnAddStore2Chain(data,
                      data->pWintrustData->u.pCert->pahStores[i]);
             }
-            else
-            {
-                /* Do nothing!?  See the tests */
-                ret = TRUE;
-            }
         }
         else
         {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            ret = FALSE;
+            /* Do nothing!?  See the tests */
+            ret = TRUE;
         }
+    }
+    else
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        ret = FALSE;
+    }
+    return ret;
+}
+
+static BOOL SOFTPUB_LoadFileMessage(CRYPT_PROVIDER_DATA *data)
+{
+    BOOL ret;
+
+    if (!data->pWintrustData->u.pFile)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        ret = FALSE;
+        goto error;
+    }
+    ret = SOFTPUB_OpenFile(data);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_GetFileSubject(data);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_GetSIP(data);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_GetMessageFromFile(data, data->pWintrustData->u.pFile->hFile,
+     data->pWintrustData->u.pFile->pcwszFilePath);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_CreateStoreFromMessage(data);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_DecodeInnerContent(data);
+error:
+    return ret;
+}
+
+static BOOL SOFTPUB_LoadCatalogMessage(CRYPT_PROVIDER_DATA *data)
+{
+    BOOL ret;
+    HANDLE catalog = INVALID_HANDLE_VALUE;
+
+    if (!data->pWintrustData->u.pCatalog)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    catalog = CreateFileW(data->pWintrustData->u.pCatalog->pcwszCatalogFilePath,
+     GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
+     NULL);
+    if (catalog == INVALID_HANDLE_VALUE)
+        return FALSE;
+    ret = CryptSIPRetrieveSubjectGuid(
+     data->pWintrustData->u.pCatalog->pcwszCatalogFilePath, catalog,
+     &data->u.pPDSip->gSubject);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_GetSIP(data);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_GetMessageFromFile(data, catalog,
+     data->pWintrustData->u.pCatalog->pcwszCatalogFilePath);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_CreateStoreFromMessage(data);
+    if (!ret)
+        goto error;
+    ret = SOFTPUB_DecodeInnerContent(data);
+    /* FIXME: this loads the catalog file, but doesn't validate the member. */
+error:
+    CloseHandle(catalog);
+    return ret;
+}
+
+HRESULT WINAPI SoftpubLoadMessage(CRYPT_PROVIDER_DATA *data)
+{
+    BOOL ret;
+
+    TRACE("(%p)\n", data);
+
+    if (!data->padwTrustStepErrors)
+        return S_FALSE;
+
+    switch (data->pWintrustData->dwUnionChoice)
+    {
+    case WTD_CHOICE_CERT:
+        ret = SOFTPUB_LoadCertMessage(data);
         break;
     case WTD_CHOICE_FILE:
-        if (!data->pWintrustData->u.pFile)
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            ret = FALSE;
-            goto error;
-        }
-        ret = SOFTPUB_OpenFile(data);
-        if (!ret)
-            goto error;
-        ret = SOFTPUB_GetFileSubject(data);
-        if (!ret)
-            goto error;
-        ret = SOFTPUB_GetSIP(data);
-        if (!ret)
-            goto error;
-        ret = SOFTPUB_GetMessageFromFile(data);
-        if (!ret)
-            goto error;
-        ret = SOFTPUB_CreateStoreFromMessage(data);
-        if (!ret)
-            goto error;
-        ret = SOFTPUB_DecodeInnerContent(data);
+        ret = SOFTPUB_LoadFileMessage(data);
+        break;
+    case WTD_CHOICE_CATALOG:
+        ret = SOFTPUB_LoadCatalogMessage(data);
         break;
     default:
         FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice);
@@ -345,7 +392,6 @@ HRESULT WINAPI SoftpubLoadMessage(CRYPT_PROVIDER_DATA *data)
         ret = FALSE;
     }
 
-error:
     if (!ret)
         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] =
          GetLastError();
@@ -501,6 +547,20 @@ HRESULT WINAPI SoftpubLoadSignature(CRYPT_PROVIDER_DATA *data)
     return ret ? S_OK : S_FALSE;
 }
 
+static DWORD WINTRUST_TrustStatusToConfidence(DWORD errorStatus)
+{
+    DWORD confidence = 0;
+
+    confidence = 0;
+    if (!(errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID))
+        confidence |= CERT_CONFIDENCE_SIG;
+    if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_VALID))
+        confidence |= CERT_CONFIDENCE_TIME;
+    if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED))
+        confidence |= CERT_CONFIDENCE_TIMENEST;
+    return confidence;
+}
+
 BOOL WINAPI SoftpubCheckCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
  BOOL fCounterSignerChain, DWORD idxCounterSigner)
 {
@@ -524,19 +584,9 @@ BOOL WINAPI SoftpubCheckCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
         for (i = 0; i < simpleChain->cElement; i++)
         {
             /* Set confidence */
-            data->pasSigners[idxSigner].pasCertChain[i].dwConfidence = 0;
-            if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
-             CERT_TRUST_IS_NOT_TIME_VALID))
-                data->pasSigners[idxSigner].pasCertChain[i].dwConfidence
-                 |= CERT_CONFIDENCE_TIME;
-            if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
-             CERT_TRUST_IS_NOT_TIME_NESTED))
-                data->pasSigners[idxSigner].pasCertChain[i].dwConfidence
-                 |= CERT_CONFIDENCE_TIMENEST;
-            if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
-             CERT_TRUST_IS_NOT_SIGNATURE_VALID))
-                data->pasSigners[idxSigner].pasCertChain[i].dwConfidence
-                 |= CERT_CONFIDENCE_SIG;
+            data->pasSigners[idxSigner].pasCertChain[i].dwConfidence =
+             WINTRUST_TrustStatusToConfidence(
+             simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus);
             /* Set additional flags */
             if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
              CERT_TRUST_IS_UNTRUSTED_ROOT))
@@ -552,6 +602,51 @@ BOOL WINAPI SoftpubCheckCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
     return ret;
 }
 
+static DWORD WINTRUST_TrustStatusToError(DWORD errorStatus)
+{
+    DWORD error;
+
+    if (errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID)
+        error = TRUST_E_CERT_SIGNATURE;
+    else if (errorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT)
+        error = CERT_E_UNTRUSTEDROOT;
+    else if (errorStatus & CERT_TRUST_IS_NOT_TIME_VALID)
+        error = CERT_E_EXPIRED;
+    else if (errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED)
+        error = CERT_E_VALIDITYPERIODNESTING;
+    else if (errorStatus & CERT_TRUST_IS_REVOKED)
+        error = CERT_E_REVOKED;
+    else if (errorStatus & CERT_TRUST_IS_OFFLINE_REVOCATION ||
+     errorStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
+        error = CERT_E_REVOCATION_FAILURE;
+    else if (errorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE)
+        error = CERT_E_WRONG_USAGE;
+    else if (errorStatus & CERT_TRUST_IS_CYCLIC)
+        error = CERT_E_CHAINING;
+    else if (errorStatus & CERT_TRUST_INVALID_EXTENSION)
+        error = CERT_E_CRITICAL;
+    else if (errorStatus & CERT_TRUST_INVALID_POLICY_CONSTRAINTS)
+        error = CERT_E_INVALID_POLICY;
+    else if (errorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS)
+        error = TRUST_E_BASIC_CONSTRAINTS;
+    else if (errorStatus & CERT_TRUST_INVALID_NAME_CONSTRAINTS ||
+     errorStatus & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT ||
+     errorStatus & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT ||
+     errorStatus & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT ||
+     errorStatus & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT)
+        error = CERT_E_INVALID_NAME;
+    else if (errorStatus & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY)
+        error = CERT_E_INVALID_POLICY;
+    else if (errorStatus)
+    {
+        FIXME("unknown error status %08x\n", errorStatus);
+        error = TRUST_E_SYSTEM_ERROR;
+    }
+    else
+        error = S_OK;
+    return error;
+}
+
 static BOOL WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
 {
     BOOL ret;
@@ -559,6 +654,9 @@ static BOOL WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
      data->pasSigners[signerIdx].pChainContext->rgpChain[0];
     DWORD i;
 
+    data->pasSigners[signerIdx].pasCertChain[0].dwConfidence =
+     WINTRUST_TrustStatusToConfidence(
+     simpleChain->rgpElement[0]->TrustStatus.dwErrorStatus);
     data->pasSigners[signerIdx].pasCertChain[0].pChainElement =
      simpleChain->rgpElement[0];
     ret = TRUE;
@@ -567,9 +665,18 @@ static BOOL WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
         ret = data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0,
          simpleChain->rgpElement[i]->pCertContext);
         if (ret)
+        {
             data->pasSigners[signerIdx].pasCertChain[i].pChainElement =
              simpleChain->rgpElement[i];
+            data->pasSigners[signerIdx].pasCertChain[i].dwConfidence =
+             WINTRUST_TrustStatusToConfidence(
+             simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus);
+        }
     }
+    data->pasSigners[signerIdx].pasCertChain[simpleChain->cElement - 1].dwError
+     = WINTRUST_TrustStatusToError(
+     simpleChain->rgpElement[simpleChain->cElement - 1]->
+     TrustStatus.dwErrorStatus);
     return ret;
 }
 
@@ -580,6 +687,11 @@ static void WINTRUST_CreateChainPolicyCreateInfo(
     chainPara->cbSize = sizeof(CERT_CHAIN_PARA);
     if (data->pRequestUsage)
         chainPara->RequestedUsage = *data->pRequestUsage;
+    else
+    {
+        chainPara->RequestedUsage.dwType = 0;
+        chainPara->RequestedUsage.Usage.cUsageIdentifier = 0;
+    }
     info->u.cbSize = sizeof(WTD_GENERIC_CHAIN_POLICY_CREATE_INFO);
     info->hChainEngine = NULL;
     info->pChainPara = chainPara;
@@ -599,7 +711,20 @@ static BOOL WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data,
  PCERT_CHAIN_PARA chainPara)
 {
     BOOL ret = TRUE;
+    HCERTSTORE store = NULL;
+
+    if (data->chStores)
+    {
+        store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
+         CERT_STORE_CREATE_NEW_FLAG, NULL);
+        if (store)
+        {
+            DWORD i;
 
+            for (i = 0; i < data->chStores; i++)
+                CertAddStoreToCollection(store, data->pahStores[i], 0, 0);
+        }
+    }
     /* Expect the end certificate for each signer to be the only cert in the
      * chain:
      */
@@ -608,8 +733,7 @@ static BOOL WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data,
         /* Create a certificate chain for each signer */
         ret = CertGetCertificateChain(createInfo->hChainEngine,
          data->pasSigners[signer].pasCertChain[0].pCert,
-         &data->pasSigners[signer].sftVerifyAsOf,
-         data->chStores ? data->pahStores[0] : NULL,
+         &data->pasSigners[signer].sftVerifyAsOf, store,
          chainPara, createInfo->dwFlags, createInfo->pvReserved,
          &data->pasSigners[signer].pChainContext);
         if (ret)
@@ -622,11 +746,17 @@ static BOOL WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data,
             else
             {
                 if ((ret = WINTRUST_CopyChain(data, signer)))
-                    ret = data->psPfns->pfnCertCheckPolicy(data, signer, FALSE,
-                     0);
+                {
+                    if (data->psPfns->pfnCertCheckPolicy)
+                        ret = data->psPfns->pfnCertCheckPolicy(data, signer,
+                         FALSE, 0);
+                    else
+                        TRACE("no cert check policy, skipping policy check\n");
+                }
             }
         }
     }
+    CertCloseStore(store, 0);
     return ret;
 }
 
@@ -735,27 +865,60 @@ HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *data)
         ret = TRUE;
         for (i = 0; ret && i < data->csSigners; i++)
         {
-            CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 };
-
-            if (data->dwRegPolicySettings & WTPF_TRUSTTEST)
-                policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG;
-            if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID)
-                policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG;
-            if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION)
-                policyPara.dwFlags |=
-                 CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
-                 CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG |
-                 CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG;
-            if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION)
-                policyPara.dwFlags |=
-                 CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG |
-                 CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG |
-                 CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG |
-                 CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG;
-            CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE,
-             data->pasSigners[i].pChainContext, &policyPara, &policyStatus);
-            if (policyStatus.dwError != NO_ERROR)
-                ret = FALSE;
+            BYTE hash[20];
+            DWORD size = sizeof(hash);
+
+            /* First make sure cert isn't disallowed */
+            if ((ret = CertGetCertificateContextProperty(
+             data->pasSigners[i].pasCertChain[0].pCert,
+             CERT_SIGNATURE_HASH_PROP_ID, hash, &size)))
+            {
+                static const WCHAR disallowedW[] =
+                 { 'D','i','s','a','l','l','o','w','e','d',0 };
+                HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
+                 X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER,
+                 disallowedW);
+
+                if (disallowed)
+                {
+                    PCCERT_CONTEXT found = CertFindCertificateInStore(
+                     disallowed, X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH,
+                     hash, NULL);
+
+                    if (found)
+                    {
+                        /* Disallowed!  Can't verify it. */
+                        policyStatus.dwError = TRUST_E_SUBJECT_NOT_TRUSTED;
+                        ret = FALSE;
+                        CertFreeCertificateContext(found);
+                    }
+                    CertCloseStore(disallowed, 0);
+                }
+            }
+            if (ret)
+            {
+                CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 };
+
+                if (data->dwRegPolicySettings & WTPF_TRUSTTEST)
+                    policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG;
+                if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID)
+                    policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG;
+                if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION)
+                    policyPara.dwFlags |=
+                     CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
+                     CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG |
+                     CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG;
+                if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION)
+                    policyPara.dwFlags |=
+                     CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG |
+                     CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG |
+                     CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG |
+                     CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG;
+                CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE,
+                 data->pasSigners[i].pChainContext, &policyPara, &policyStatus);
+                if (policyStatus.dwError != NO_ERROR)
+                    ret = FALSE;
+            }
         }
     }
     if (!ret)
@@ -849,14 +1012,14 @@ HRESULT WINAPI GenericChainFinalProv(CRYPT_PROVIDER_DATA *data)
             else
                 err = ERROR_OUTOFMEMORY;
         }
-        if (!err)
+        if (err == NO_ERROR)
             err = policyCallback(data, TRUSTERROR_STEP_FINAL_POLICYPROV,
              data->dwRegPolicySettings, data->csSigners, signers, policyArg);
         data->psPfns->pfnFree(signers);
     }
-    if (err)
+    if (err != NO_ERROR)
         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] = err;
-    TRACE("returning %d (%08x)\n", !err ? S_OK : S_FALSE,
+    TRACE("returning %d (%08x)\n", err == NO_ERROR ? S_OK : S_FALSE,
      data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]);
     return err == NO_ERROR ? S_OK : S_FALSE;
 }
index f0c6790..9dbb4f2 100644 (file)
@@ -6,6 +6,7 @@
        <define name="__WINESRC__" />
        <library>wine</library>
        <library>crypt32</library>
+       <library>cryptui</library>
        <library>user32</library>
        <library>advapi32</library>
        <library>kernel32</library>
index 191e3d1..6f83282 100644 (file)
@@ -55,7 +55,7 @@
 @ stub MsCatFreeHashTag
 @ stub OfficeCleanupPolicy
 @ stub OfficeInitializePolicy
-@ stub OpenPersonalTrustDBDialog
+@ stdcall OpenPersonalTrustDBDialog(ptr)
 @ stdcall SoftpubAuthenticode(ptr)
 @ stdcall SoftpubCheckCert(ptr long long long)
 @ stdcall SoftpubCleanup(ptr)
 @ stub WTHelperGetAgencyInfo
 @ stdcall WTHelperGetFileHandle(ptr)
 @ stdcall WTHelperGetFileName(ptr)
-@ stub WTHelperGetKnownUsages
+@ stdcall WTHelperGetKnownUsages(long ptr)
 @ stdcall WTHelperGetProvCertFromChain(ptr long)
 @ stdcall WTHelperGetProvPrivateDataFromChain(ptr ptr)
 @ stdcall WTHelperGetProvSignerFromChain(ptr long long long)
 @ stub WTHelperIsInRootStore
 @ stub WTHelperOpenKnownStores
 @ stdcall WTHelperProvDataFromStateData(ptr)
-@ stub WVTAsn1CatMemberInfoDecode
-@ stub WVTAsn1CatMemberInfoEncode
-@ stub WVTAsn1CatNameValueDecode
-@ stub WVTAsn1CatNameValueEncode
-@ stub WVTAsn1SpcFinancialCriteriaInfoDecode
-@ stub WVTAsn1SpcFinancialCriteriaInfoEncode
+@ stdcall WVTAsn1CatMemberInfoDecode(long str ptr long long ptr ptr)
+@ stdcall WVTAsn1CatMemberInfoEncode(long str ptr ptr ptr)
+@ stdcall WVTAsn1CatNameValueDecode(long str ptr long long ptr ptr)
+@ stdcall WVTAsn1CatNameValueEncode(long str ptr ptr ptr)
+@ stdcall WVTAsn1SpcFinancialCriteriaInfoDecode(long str ptr long long ptr ptr)
+@ stdcall WVTAsn1SpcFinancialCriteriaInfoEncode(long str ptr ptr ptr)
 @ stdcall WVTAsn1SpcIndirectDataContentDecode(long str ptr long long ptr ptr)
 @ stdcall WVTAsn1SpcIndirectDataContentEncode(long str ptr ptr ptr)
 @ stdcall WVTAsn1SpcLinkDecode(long str ptr long long ptr ptr)
 @ stub WVTAsn1SpcSpAgencyInfoDecode
 @ stub WVTAsn1SpcSpAgencyInfoEncode
 @ stdcall WVTAsn1SpcSpOpusInfoDecode(long str ptr long long ptr ptr)
-@ stub WVTAsn1SpcSpOpusInfoEncode
+@ stdcall WVTAsn1SpcSpOpusInfoEncode(long str ptr ptr ptr)
 @ stub WVTAsn1SpcStatementTypeDecode
 @ stub WVTAsn1SpcStatementTypeEncode
 @ stdcall WinVerifyTrust(long ptr ptr)
index ed6a8ed..f9d3329 100644 (file)
@@ -33,6 +33,8 @@
 #include "mscat.h"
 #include "objbase.h"
 #include "winuser.h"
+#include "cryptdlg.h"
+#include "cryptuiapi.h"
 #include "wintrust_priv.h"
 #include "wine/debug.h"
 
@@ -88,15 +90,9 @@ static DWORD WINTRUST_ExecuteSteps(const struct wintrust_step *steps,
     return err;
 }
 
-static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
- WINTRUST_DATA *data)
+static CRYPT_PROVIDER_DATA *WINTRUST_AllocateProviderData(void)
 {
-    DWORD err = ERROR_SUCCESS, numSteps = 0;
     CRYPT_PROVIDER_DATA *provData;
-    BOOL ret;
-    struct wintrust_step verifySteps[5];
-
-    TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
 
     provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA));
     if (!provData)
@@ -118,6 +114,69 @@ static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
     if (!provData->psPfns)
         goto oom;
     provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
+    return provData;
+
+oom:
+    if (provData)
+    {
+        WINTRUST_Free(provData->padwTrustStepErrors);
+        WINTRUST_Free(provData->u.pPDSip);
+        WINTRUST_Free(provData->psPfns);
+        WINTRUST_Free(provData);
+    }
+    return NULL;
+}
+
+/* Adds trust steps for each function in psPfns.  Assumes steps has at least
+ * 5 entries.  Returns the number of steps added.
+ */
+static DWORD WINTRUST_AddTrustStepsFromFunctions(struct wintrust_step *steps,
+ const CRYPT_PROVIDER_FUNCTIONS *psPfns)
+{
+    DWORD numSteps = 0;
+
+    if (psPfns->pfnInitialize)
+    {
+        steps[numSteps].func = psPfns->pfnInitialize;
+        steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT;
+    }
+    if (psPfns->pfnObjectTrust)
+    {
+        steps[numSteps].func = psPfns->pfnObjectTrust;
+        steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV;
+    }
+    if (psPfns->pfnSignatureTrust)
+    {
+        steps[numSteps].func = psPfns->pfnSignatureTrust;
+        steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV;
+    }
+    if (psPfns->pfnCertificateTrust)
+    {
+        steps[numSteps].func = psPfns->pfnCertificateTrust;
+        steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV;
+    }
+    if (psPfns->pfnFinalPolicy)
+    {
+        steps[numSteps].func = psPfns->pfnFinalPolicy;
+        steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV;
+    }
+    return numSteps;
+}
+
+static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
+ WINTRUST_DATA *data)
+{
+    DWORD err = ERROR_SUCCESS, numSteps = 0;
+    CRYPT_PROVIDER_DATA *provData;
+    BOOL ret;
+    struct wintrust_step verifySteps[5];
+
+    TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
+
+    provData = WINTRUST_AllocateProviderData();
+    if (!provData)
+        return ERROR_OUTOFMEMORY;
+
     ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
     if (!ret)
     {
@@ -134,36 +193,11 @@ static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
     provData->pgActionID = actionID;
     WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
 
-    if (provData->psPfns->pfnInitialize)
-    {
-        verifySteps[numSteps].func = provData->psPfns->pfnInitialize;
-        verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT;
-    }
-    if (provData->psPfns->pfnObjectTrust)
-    {
-        verifySteps[numSteps].func = provData->psPfns->pfnObjectTrust;
-        verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV;
-    }
-    if (provData->psPfns->pfnSignatureTrust)
-    {
-        verifySteps[numSteps].func = provData->psPfns->pfnSignatureTrust;
-        verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV;
-    }
-    if (provData->psPfns->pfnCertificateTrust)
-    {
-        verifySteps[numSteps].func = provData->psPfns->pfnCertificateTrust;
-        verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV;
-    }
-    if (provData->psPfns->pfnFinalPolicy)
-    {
-        verifySteps[numSteps].func = provData->psPfns->pfnFinalPolicy;
-        verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV;
-    }
+    numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps,
+     provData->psPfns);
     err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
     goto done;
 
-oom:
-    err = ERROR_OUTOFMEMORY;
 error:
     if (provData)
     {
@@ -235,6 +269,184 @@ static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
     return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
 }
 
+/* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY
+ * action is not stored in the registry and is located in wintrust, not in
+ * cryptdlg along with the rest of the implementation (verified by running the
+ * action with a native wintrust.dll.)
+ */
+static HRESULT WINAPI WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA *data)
+{
+    BOOL ret;
+
+    TRACE("(%p)\n", data);
+
+    if (!data->padwTrustStepErrors)
+        return S_FALSE;
+
+    switch (data->pWintrustData->dwUnionChoice)
+    {
+    case WTD_CHOICE_BLOB:
+        if (data->pWintrustData->u.pBlob &&
+         data->pWintrustData->u.pBlob->cbStruct == sizeof(WINTRUST_BLOB_INFO) &&
+         data->pWintrustData->u.pBlob->cbMemObject ==
+         sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
+         data->pWintrustData->u.pBlob->pbMemObject)
+        {
+            CERT_VERIFY_CERTIFICATE_TRUST *pCert =
+             (CERT_VERIFY_CERTIFICATE_TRUST *)
+             data->pWintrustData->u.pBlob->pbMemObject;
+
+            if (pCert->cbSize == sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
+             pCert->pccert)
+            {
+                CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
+                DWORD i;
+                SYSTEMTIME sysTime;
+
+                /* Add a signer with nothing but the time to verify, so we can
+                 * add a cert to it
+                 */
+                GetSystemTime(&sysTime);
+                SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
+                ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
+                if (!ret)
+                    goto error;
+                ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
+                 pCert->pccert);
+                if (!ret)
+                    goto error;
+                for (i = 0; ret && i < pCert->cRootStores; i++)
+                    ret = data->psPfns->pfnAddStore2Chain(data,
+                     pCert->rghstoreRoots[i]);
+                for (i = 0; ret && i < pCert->cStores; i++)
+                    ret = data->psPfns->pfnAddStore2Chain(data,
+                     pCert->rghstoreCAs[i]);
+                for (i = 0; ret && i < pCert->cTrustStores; i++)
+                    ret = data->psPfns->pfnAddStore2Chain(data,
+                     pCert->rghstoreTrust[i]);
+            }
+            else
+            {
+                SetLastError(ERROR_INVALID_PARAMETER);
+                ret = FALSE;
+            }
+        }
+        else
+        {
+            SetLastError(ERROR_INVALID_PARAMETER);
+            ret = FALSE;
+        }
+        break;
+    default:
+        FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice);
+        SetLastError(ERROR_INVALID_PARAMETER);
+        ret = FALSE;
+    }
+
+error:
+    if (!ret)
+        data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] =
+         GetLastError();
+    TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
+     data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
+    return ret ? S_OK : S_FALSE;
+}
+
+static LONG WINTRUST_CertVerify(HWND hwnd, GUID *actionID,
+ WINTRUST_DATA *data)
+{
+    DWORD err = ERROR_SUCCESS, numSteps = 0;
+    CRYPT_PROVIDER_DATA *provData;
+    BOOL ret;
+    struct wintrust_step verifySteps[5];
+
+    TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
+
+    provData = WINTRUST_AllocateProviderData();
+    if (!provData)
+        return ERROR_OUTOFMEMORY;
+
+    ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
+    if (!ret)
+    {
+        err = GetLastError();
+        goto error;
+    }
+    if (!provData->psPfns->pfnObjectTrust)
+        provData->psPfns->pfnObjectTrust = WINTRUST_CertVerifyObjTrust;
+    /* Not sure why, but native skips the policy check */
+    provData->psPfns->pfnCertCheckPolicy = NULL;
+
+    data->hWVTStateData = (HANDLE)provData;
+    provData->pWintrustData = data;
+    if (hwnd == INVALID_HANDLE_VALUE)
+        provData->hWndParent = GetDesktopWindow();
+    else
+        provData->hWndParent = hwnd;
+    provData->pgActionID = actionID;
+    WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
+
+    numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps,
+     provData->psPfns);
+    err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
+    goto done;
+
+error:
+    if (provData)
+    {
+        WINTRUST_Free(provData->padwTrustStepErrors);
+        WINTRUST_Free(provData->u.pPDSip);
+        WINTRUST_Free(provData->psPfns);
+        WINTRUST_Free(provData);
+    }
+done:
+    TRACE("returning %08x\n", err);
+    return err;
+}
+
+static LONG WINTRUST_CertVerifyAndClose(HWND hwnd, GUID *actionID,
+ WINTRUST_DATA *data)
+{
+    LONG err;
+
+    TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
+
+    err = WINTRUST_CertVerify(hwnd, actionID, data);
+    WINTRUST_DefaultClose(hwnd, actionID, data);
+    TRACE("returning %08x\n", err);
+    return err;
+}
+
+static LONG WINTRUST_CertActionVerify(HWND hwnd, GUID *actionID,
+ WINTRUST_DATA *data)
+{
+    DWORD stateAction;
+    LONG err = ERROR_SUCCESS;
+
+    if (WVT_ISINSTRUCT(WINTRUST_DATA, data->cbStruct, dwStateAction))
+        stateAction = data->dwStateAction;
+    else
+    {
+        TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
+        stateAction = WTD_STATEACTION_IGNORE;
+    }
+    switch (stateAction)
+    {
+    case WTD_STATEACTION_IGNORE:
+        err = WINTRUST_CertVerifyAndClose(hwnd, actionID, data);
+        break;
+    case WTD_STATEACTION_VERIFY:
+        err = WINTRUST_CertVerify(hwnd, actionID, data);
+        break;
+    case WTD_STATEACTION_CLOSE:
+        err = WINTRUST_DefaultClose(hwnd, actionID, data);
+        break;
+    default:
+        FIXME("unimplemented for %d\n", data->dwStateAction);
+    }
+    return err;
+}
+
 static void dump_file_info(WINTRUST_FILE_INFO *pFile)
 {
     TRACE("%p\n", pFile);
@@ -370,6 +582,7 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
     static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
     static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
     static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
+    static const GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY;
     LONG err = ERROR_SUCCESS;
     WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData;
 
@@ -379,8 +592,12 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
     /* Support for known old-style callers: */
     if (IsEqualGUID(ActionID, &published_software))
         err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
+    else if (IsEqualGUID(ActionID, &cert_action_verify))
+        err = WINTRUST_CertActionVerify(hwnd, ActionID, ActionData);
     else
     {
+        DWORD stateAction;
+
         /* Check known actions to warn of possible problems */
         if (!IsEqualGUID(ActionID, &unknown) &&
          !IsEqualGUID(ActionID, &generic_verify_v2) &&
@@ -388,7 +605,14 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
          !IsEqualGUID(ActionID, &generic_chain_verify))
             WARN("unknown action %s, default behavior may not be right\n",
              debugstr_guid(ActionID));
-        switch (actionData->dwStateAction)
+        if (WVT_ISINSTRUCT(WINTRUST_DATA, actionData->cbStruct, dwStateAction))
+            stateAction = actionData->dwStateAction;
+        else
+        {
+            TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
+            stateAction = WTD_STATEACTION_IGNORE;
+        }
+        switch (stateAction)
         {
         case WTD_STATEACTION_IGNORE:
             err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData);
@@ -512,6 +736,92 @@ HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *data)
         return INVALID_HANDLE_VALUE;
 }
 
+static BOOL WINAPI WINTRUST_enumUsages(PCCRYPT_OID_INFO pInfo, void *pvArg)
+{
+    PCCRYPT_OID_INFO **usages = (PCCRYPT_OID_INFO **)pvArg;
+    DWORD cUsages;
+    BOOL ret;
+
+    if (!*usages)
+    {
+        cUsages = 0;
+        *usages = WINTRUST_Alloc(2 * sizeof(PCCRYPT_OID_INFO));
+    }
+    else
+    {
+        PCCRYPT_OID_INFO *ptr;
+
+        /* Count the existing usages.
+         * FIXME: make sure the new usage doesn't duplicate any in the list?
+         */
+        for (cUsages = 0, ptr = *usages; *ptr; ptr++, cUsages++)
+            ;
+        *usages = WINTRUST_ReAlloc((CRYPT_OID_INFO *)*usages,
+         (cUsages + 2) * sizeof(PCCRYPT_OID_INFO));
+    }
+    if (*usages)
+    {
+        (*usages)[cUsages] = pInfo;
+        (*usages)[cUsages + 1] = NULL;
+        ret = TRUE;
+    }
+    else
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        ret = FALSE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *             WTHelperGetKnownUsages(WINTRUST.@)
+ *
+ * Enumerates the known enhanced key usages as an array of PCCRYPT_OID_INFOs.
+ *
+ * PARAMS
+ *  action      [In]     1 => allocate and return known usages, 2 => free previously
+ *                       allocated usages.
+ *  usages      [In/Out] If action == 1, *usages is set to an array of
+ *                       PCCRYPT_OID_INFO *.  The array is terminated with a NULL
+ *                       pointer.
+ *                       If action == 2, *usages is freed.
+ *
+ * RETURNS
+ *  TRUE on success, FALSE on failure.
+ */
+BOOL WINAPI WTHelperGetKnownUsages(DWORD action, PCCRYPT_OID_INFO **usages)
+{
+    BOOL ret;
+
+    TRACE("(%d, %p)\n", action, usages);
+
+    if (!usages)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (action == 1)
+    {
+        *usages = NULL;
+        ret = CryptEnumOIDInfo(CRYPT_ENHKEY_USAGE_OID_GROUP_ID, 0, usages,
+         WINTRUST_enumUsages);
+    }
+    else if (action == 2)
+    {
+        WINTRUST_Free((CRYPT_OID_INFO *)*usages);
+        *usages = NULL;
+        ret = TRUE;
+    }
+    else
+    {
+        WARN("unknown action %d\n", action);
+        SetLastError(ERROR_INVALID_PARAMETER);
+        ret = FALSE;
+    }
+    return ret;
+}
+
 static const WCHAR Software_Publishing[] = {
  'S','o','f','t','w','a','r','e','\\',
  'M','i','c','r','o','s','o','f','t','\\',
@@ -598,6 +908,8 @@ BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
 {
     BOOL ret = FALSE;
 
+    TRACE("(%p, %p)\n", data, store);
+
     if (data->chStores)
         data->pahStores = WINTRUST_ReAlloc(data->pahStores,
          (data->chStores + 1) * sizeof(HCERTSTORE));
@@ -621,6 +933,8 @@ BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
 {
     BOOL ret = FALSE;
 
+    TRACE("(%p, %d, %d, %p)\n", data, fCounterSigner, idxSigner, sgnr);
+
     if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
     {
         SetLastError(ERROR_INVALID_PARAMETER);
@@ -672,6 +986,9 @@ BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
 {
     BOOL ret = FALSE;
 
+    TRACE("(%p, %d, %d, %d, %p)\n", data, idxSigner, fCounterSigner,
+     idxSigner, pCert2Add);
+
     if (fCounterSigner)
     {
         FIXME("unimplemented for counter signers\n");
@@ -741,3 +1058,27 @@ BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data,
         SetLastError(ERROR_OUTOFMEMORY);
     return ret;
 }
+
+/***********************************************************************
+ *             OpenPersonalTrustDBDialog (WINTRUST.@)
+ *
+ * Opens the certificate manager dialog, showing only the stores that
+ * contain trusted software publishers.
+ *
+ * PARAMS
+ *  hwnd [I] handle of parent window
+ *
+ * RETURNS
+ *  TRUE if the dialog could be opened, FALSE if not.
+ */
+BOOL WINAPI OpenPersonalTrustDBDialog(HWND hwnd)
+{
+    CRYPTUI_CERT_MGR_STRUCT uiCertMgr;
+
+    uiCertMgr.dwSize = sizeof(uiCertMgr);
+    uiCertMgr.hwndParent = hwnd;
+    uiCertMgr.dwFlags = CRYPTUI_CERT_MGR_PUBLISHER_TAB;
+    uiCertMgr.pwszTitle = NULL;
+    uiCertMgr.pszInitUsageOID = NULL;
+    return CryptUIDlgCertMgr(&uiCertMgr);
+}
index c73f666..f55a1b2 100644 (file)
@@ -18,8 +18,8 @@
 #ifndef __WINTRUST_PRIV_H__
 #define __WINTRUST_PRIV_H__
 
-void * WINAPI WINTRUST_Alloc(DWORD cb);
-void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb);
+void * WINAPI WINTRUST_Alloc(DWORD cb) __WINE_ALLOC_SIZE(1);
+void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb) __WINE_ALLOC_SIZE(2);
 void WINAPI WINTRUST_Free(void *p);
 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store);
 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
index 1c77ef9..2402ae5 100644 (file)
@@ -163,6 +163,12 @@ setsockopt(IN  SOCKET s,
         return SOCKET_ERROR;
     }
 
+    if(IS_INTRESOURCE(optval))
+    {
+        SetLastError(WSAEFAULT);
+        return SOCKET_ERROR;
+    }
+
     if (!ReferenceProviderByHandle((HANDLE)s, &Provider))
     {
         WSASetLastError(WSAENOTSOCK);
index 6c5e755..20143c3 100644 (file)
@@ -548,7 +548,7 @@ IN PDEVICE_OBJECT                           DeviceObject);
 
 extern BOOLEAN NTAPI Ext2FastIoUnlockAllByKey(
 IN PFILE_OBJECT                                FileObject,
-PEPROCESS                                              ProcessId,
+PVOID                                          ProcessId,
 ULONG                                                          Key,
 OUT PIO_STATUS_BLOCK                   IoStatus,
 IN PDEVICE_OBJECT                              DeviceObject);
index 7524049..4a76c88 100644 (file)
@@ -35,6 +35,7 @@ typedef PVOID PBCB;
 #define except(x) if (0 && (x))
 #define finally if (1)
 #define GetExceptionInformation() 0
+#define GetExceptionCode() 0
 
 // we will use the LARGE_INTEGER structure as defined by NT
 
index 1d6c4a8..150db70 100644 (file)
@@ -168,7 +168,7 @@ NTSTATUS NTAPI Ext2ReadPhysicalBlocks (
                {
                        DebugTrace(DEBUG_TRACE_MISC,   " !!!! Unable to create an IRP", 0 );
                        Status = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return( Status );
+                       try_return();
                }
 
                //
index bacce9e..d5d33c5 100644 (file)
@@ -140,7 +140,7 @@ BOOLEAN                                             FirstAttempt )
                        {
                                DebugTrace( DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Cleanup]", PtrFileObject);
                        }
-                       try_return( RC );
+                       try_return();
                }
                
 
@@ -345,7 +345,7 @@ BOOLEAN                                             FirstAttempt )
                        CompleteIrp = TRUE;
                }
                
-               try_return( RC );
+               try_return();
 
                try_exit:       NOTHING;
 
index 32b9d00..9ef83b4 100644 (file)
@@ -142,7 +142,7 @@ BOOLEAN                                             FirstAttempt )
                        {
                                DebugTrace( DEBUG_TRACE_SPECIAL, "###### File Pointer 0x%LX [Close]", PtrFileObject);
                        }
-                       try_return( RC );
+                       try_return();
                }
 
                // Get the FCB and CCB pointers
@@ -400,7 +400,7 @@ BOOLEAN                                             FirstAttempt )
                        DebugTrace(DEBUG_TRACE_MISC,   "VCB Close Requested !!!", 0);
                        CompleteIrp = TRUE;
                }
-               try_return( RC );
+               try_return();
                
                try_exit:       NOTHING;
 
index c1de84c..13aeafd 100644 (file)
@@ -180,6 +180,9 @@ BOOLEAN                                             FirstAttempt)
        UNICODE_STRING                  AbsolutePathName;
        UNICODE_STRING                  RenameLinkTargetFileName;
 
+    /* Silence GCC warnings */
+    RtlZeroMemory(&RelatedObjectName, sizeof(UNICODE_STRING));
+
 
        ASSERT(PtrIrpContext);
        ASSERT(PtrIrp);
@@ -200,7 +203,7 @@ BOOLEAN                                             FirstAttempt)
                        //      Asynchronous processing required...
                        RC = Ext2PostRequest(PtrIrpContext, PtrIrp);
                        DeferredProcessing = TRUE;
-                       try_return(RC);
+                       try_return();
                }
 
                // Obtaining the parameters specified by the user.
@@ -259,7 +262,7 @@ BOOLEAN                                             FirstAttempt)
                if (PtrIrp->Overlay.AllocationSize.HighPart) 
                {
                        RC = STATUS_INVALID_PARAMETER;
-                       try_return(RC);
+                       try_return();
                }
 
                // Getting a pointer to the supplied security context
@@ -324,7 +327,7 @@ BOOLEAN                                             FirstAttempt)
                //      Verify Volume...
                //      if (!NT_SUCCESS(RC = Ext2VerifyVolume(PtrVCB))) 
                //      {
-               //              try_return(RC);
+               //              try_return();
                //      }
 
                // If the volume has been locked, fail the request
@@ -333,7 +336,7 @@ BOOLEAN                                             FirstAttempt)
                {
                        DebugTrace(DEBUG_TRACE_MISC,   "Volume locked. Failing Create", 0 );
                        RC = STATUS_ACCESS_DENIED;
-                       try_return(RC);
+                       try_return();
                }
 
 
@@ -348,34 +351,34 @@ BOOLEAN                                           FirstAttempt)
                        if ((OpenTargetDirectory) || (PtrExtAttrBuffer)) 
                        {
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                        }
 
                        if (DirectoryOnlyRequested) 
                        {
                                // a volume is not a directory
                                RC = STATUS_NOT_A_DIRECTORY;
-                               try_return(RC);
+                               try_return();
                        }
 
                        if ((RequestedDisposition != FILE_OPEN) && (RequestedDisposition != FILE_OPEN_IF)) 
                        {
                                // cannot create a new volume, I'm afraid ...
                                RC = STATUS_ACCESS_DENIED;
-                               try_return(RC);
+                               try_return();
                        }
                        DebugTrace(DEBUG_TRACE_MISC,   "Volume open requested", 0 );
                        RC = Ext2OpenVolume(PtrVCB, PtrIrpContext, PtrIrp, ShareAccess, PtrSecurityContext, PtrNewFileObject);
                        ReturnedInformation = PtrIrp->IoStatus.Information;
 
-                       try_return(RC);
+                       try_return();
                }
 
                if (OpenByFileId) 
                {
                        DebugTrace(DEBUG_TRACE_MISC, "Open by File Id requested", 0 );
                        RC = STATUS_ACCESS_DENIED;
-                       try_return(RC);
+                       try_return();
                }
 
                // Relative path name specified...
@@ -386,20 +389,20 @@ BOOLEAN                                           FirstAttempt)
                        {
                                // we must have a directory as the "related" object
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                        }
 
                        //      Performing validity checks...
                        if ((RelatedObjectName.Length == 0) || (RelatedObjectName.Buffer[0] != L'\\')) 
                        {
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                        }
 
                        if ((TargetObjectName.Length != 0) && (TargetObjectName.Buffer[0] == L'\\')) 
                        {
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                        }
 
                        // Creating an absolute path-name.
@@ -408,7 +411,7 @@ BOOLEAN                                             FirstAttempt)
                                if (!(AbsolutePathName.Buffer = Ext2AllocatePool(PagedPool, AbsolutePathName.MaximumLength ))) 
                                {
                                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                                       try_return(RC);
+                                       try_return();
                                }
 
                                RtlZeroMemory(AbsolutePathName.Buffer, AbsolutePathName.MaximumLength);
@@ -429,14 +432,14 @@ BOOLEAN                                           FirstAttempt)
                        if (TargetObjectName.Buffer[0] != L'\\') 
                        {
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                        }
 
                        {
                                AbsolutePathName.MaximumLength = TargetObjectName.Length;
                                if (!(AbsolutePathName.Buffer = Ext2AllocatePool(PagedPool, AbsolutePathName.MaximumLength ))) {
                                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                                       try_return(RC);
+                                       try_return();
                                }
 
                                RtlZeroMemory(AbsolutePathName.Buffer, AbsolutePathName.MaximumLength);
@@ -456,12 +459,12 @@ BOOLEAN                                           FirstAttempt)
                                 (RequestedDisposition == FILE_OVERWRITE_IF)) 
                        {
                                RC = STATUS_FILE_IS_A_DIRECTORY;
-                               try_return(RC);
+                               try_return();
                        }
 
                        RC = Ext2OpenRootDirectory(PtrVCB, PtrIrpContext, PtrIrp, ShareAccess, PtrSecurityContext, PtrNewFileObject);
                        DebugTrace(DEBUG_TRACE_MISC,   " === Root directory opened", 0 );
-                       try_return(RC);
+                       try_return();
                }
 
 
@@ -562,7 +565,7 @@ BOOLEAN                                             FirstAttempt)
                                                //      Can have only a directory in the middle of the path...
                                                //
                                                RC = STATUS_OBJECT_PATH_NOT_FOUND;
-                                               try_return( RC );
+                                               try_return();
                                        }
                                }
                                else    //      searching on the disk...
@@ -600,7 +603,7 @@ BOOLEAN                                             FirstAttempt)
                                                        if(     !CurrInodeNo )
                                                        {
                                                                RC = STATUS_OBJECT_PATH_NOT_FOUND;
-                                                               try_return( RC );
+                                                               try_return();
                                                        }
                                                        // Set the allocation size for the object is specified
                                                        //IoSetShareAccess(DesiredAccess, ShareAccess, PtrNewFileObject, &(PtrNewFCB->FCBShareAccess));
@@ -647,7 +650,7 @@ BOOLEAN                                             FirstAttempt)
                                                else
                                                {
                                                        RC = STATUS_OBJECT_PATH_NOT_FOUND;
-                                                       try_return( RC );
+                                                       try_return();
                                                }
                                        }
 
@@ -660,7 +663,7 @@ BOOLEAN                                             FirstAttempt)
                                                        //      Can have only a directory in the middle of the path...
                                                        //
                                                        RC = STATUS_OBJECT_PATH_NOT_FOUND;
-                                                       try_return( RC );
+                                                       try_return();
                                                }
 
                                                PtrCurrFileObject = NULL;
@@ -681,7 +684,7 @@ BOOLEAN                                             FirstAttempt)
                                                {
                                                        ReturnedInformation = FILE_EXISTS;
                                                        RC = STATUS_OBJECT_NAME_COLLISION;
-                                                       try_return(RC);
+                                                       try_return();
                                                }
                                                
                                                //      Is this the type of file I was looking for?
@@ -692,18 +695,18 @@ BOOLEAN                                           FirstAttempt)
                                                        //      Deny access!
                                                        //      Cannot open a special file...
                                                        RC = STATUS_ACCESS_DENIED;
-                                                       try_return( RC );
+                                                       try_return();
 
                                                }
                                                if( DirectoryOnlyRequested && Type != EXT2_FT_DIR )
                                                {
                                                        RC = STATUS_NOT_A_DIRECTORY;
-                                                       try_return( RC );
+                                                       try_return();
                                                }
                                                if( FileOnlyRequested && Type == EXT2_FT_DIR )
                                                {
                                                        RC = STATUS_FILE_IS_A_DIRECTORY;
-                                                       try_return(RC);
+                                                       try_return();
                                                }
 
                                                PtrCurrFileObject = PtrNewFileObject;
@@ -733,7 +736,7 @@ BOOLEAN                                             FirstAttempt)
                                                        PtrObjectName  )  )  )
                                                {
                                                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                                                       try_return(RC);
+                                                       try_return();
                                                }
 
                                                if( Type == EXT2_FT_DIR )
@@ -781,7 +784,7 @@ BOOLEAN                                             FirstAttempt)
                                  (RequestedDisposition == FILE_OVERWRITE) || (RequestedDisposition == FILE_OVERWRITE_IF ))) 
                        {
                                RC = STATUS_FILE_IS_A_DIRECTORY;
-                               try_return(RC);
+                               try_return();
                        }
                
                        
@@ -798,7 +801,7 @@ BOOLEAN                                             FirstAttempt)
                                                                                                &(PtrNewFCB->FCBShareAccess), TRUE))) 
                                {
                                        // Ext2CloseCCB(PtrNewCCB);
-                                       try_return(RC);
+                                       try_return();
                                }
                        } 
                        else 
@@ -1008,7 +1011,7 @@ PFILE_OBJECT                      PtrNewFileObject)               // I/O Mgr. created file object
                if (!(PtrCCB = Ext2AllocateCCB())) 
                {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return(RC);
+                       try_return();
                }
 
                // initialize the CCB
index 9fd9213..a3e3e16 100644 (file)
@@ -429,7 +429,7 @@ PtrExt2CCB                                  PtrCCB)
                {
                        //      Read Failure
                        DebugTrace(DEBUG_TRACE_MISC,   "Cache read failiure while reading in volume meta data", 0);
-                       try_return( STATUS_ACCESS_DENIED );
+                       try_return();
                }
                else
                {
@@ -579,7 +579,7 @@ PtrExt2CCB                                  PtrCCB)
                                        //      BothDirInformation->ShortName[ j ] = PtrDirEntry->name[j];
                                        BothDirInformation->FileName[ j ] = PtrDirEntry->name[j];
                                        //      if( j < 11 )
-                                       //              BothDirInformation->ShortName[j] = PtrDirEntry->name[j];;
+                                       //              BothDirInformation->ShortName[j] = PtrDirEntry->name[j];
                                }
 
                                /*
@@ -694,11 +694,11 @@ PtrExt2CCB                                        PtrCCB)
                        case FileFullDirectoryInformation:
                                //      FullDirInformation->
                                DebugTrace(DEBUG_TRACE_DIRINFO,   " === FileFullDirectoryInformation - Not handled", 0 );
-                               try_return( RC );
+                               try_return();
                        case FileNamesInformation:
                                //      NamesInformation->
                                DebugTrace(DEBUG_TRACE_DIRINFO,   " === FileNamesInformation - Not handled", 0 );
-                               try_return( RC );
+                               try_return();
                        default:
                                DebugTrace(DEBUG_TRACE_DIRINFO,   " === Invalid Dir Info class - Not handled", 0 );
                                try_return( RC = STATUS_INVALID_INFO_CLASS );
@@ -719,7 +719,7 @@ PtrExt2CCB                                  PtrCCB)
                                RC = STATUS_NO_SUCH_FILE;
                        else
                                RC = STATUS_NO_MORE_FILES;
-                       try_return( RC );
+                       try_return();
                }
                else if( BytesReturned )
                {
index 01a82aa..68e84f1 100644 (file)
@@ -85,7 +85,7 @@ PUNICODE_STRING       RegistryPath)           // path to the registry key
                                        // in your commercial driver implementation, it would be
                                        //      advisable for your driver to print an appropriate error
                                        //      message to the system error log before leaving
-                       //              try_return(RC);
+                       //              try_return();
                        //      }
 
                        // we should have the registry data (if any), allocate zone memory ...
@@ -98,7 +98,7 @@ PUNICODE_STRING       RegistryPath)           // path to the registry key
                        if (!NT_SUCCESS(RC = Ext2InitializeZones())) 
                        {
                                // we failed, print a message and leave ...
-                               try_return(RC);
+                               try_return();
                        }
 #endif
 
@@ -143,7 +143,7 @@ PUNICODE_STRING     RegistryPath)           // path to the registry key
                                        &(Ext2GlobalData.Ext2DeviceObject)))) 
                        {
                                // failed to create a device object, leave ...
-                               try_return(RC);
+                               try_return();
                        }
 
 
index b91b42c..5c61676 100644 (file)
@@ -593,7 +593,7 @@ IN PDEVICE_OBJECT                           DeviceObject)
 *************************************************************************/
 BOOLEAN NTAPI Ext2FastIoUnlockAllByKey(
 IN PFILE_OBJECT                                FileObject,
-PEPROCESS                                              ProcessId,
+PVOID                                          ProcessId,
 ULONG                                                          Key,
 OUT PIO_STATUS_BLOCK                   IoStatus,
 IN PDEVICE_OBJECT                              DeviceObject)
index eba4512..143c809 100644 (file)
@@ -144,7 +144,7 @@ PIRP                                                        PtrIrp)
                {
                        // This is not allowed. Caller must use get/set volume information instead.
                        RC = STATUS_INVALID_PARAMETER;
-                       try_return(RC);
+                       try_return();
                }
 
                //      ASSERT(PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB);
@@ -205,14 +205,14 @@ PIRP                                                      PtrIrp)
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "FileNetworkOpenInformation requested for %S", PtrFCB->FCBName->ObjectName.Buffer );
                                RC = Ext2GetNetworkOpenInformation(PtrFCB, (PFILE_NETWORK_OPEN_INFORMATION)PtrSystemBuffer, &BufferLength);
                                //      RC = STATUS_INVALID_PARAMETER;
-                               //      try_return(RC);
+                               //      try_return();
                                break;
 #endif // _WIN32_WINNT >= 0x0400
                        case FileInternalInformation:
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "FileInternalInformation requested for %S", PtrFCB->FCBName->ObjectName.Buffer );
                                // RC = Ext2GetInternalInformation(...);
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                                break;
                        case FileEaInformation:
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "FileEaInformation requested for %S", PtrFCB->FCBName->ObjectName.Buffer );
@@ -246,7 +246,7 @@ PIRP                                                        PtrIrp)
                                // RC = Ext2GetFileStreamInformation(...);
 
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                                
                                break;
                        case FileAllInformation:
@@ -274,11 +274,11 @@ PIRP                                                      PtrIrp)
                                        if (!NT_SUCCESS(RC = Ext2GetBasicInformation(PtrFCB, (PFILE_BASIC_INFORMATION)&(PtrAllInfo->BasicInformation),
                                                                                                                                                                        &BufferLength))) 
                                        {
-                                               try_return(RC);
+                                               try_return();
                                        }
                                        if (!NT_SUCCESS(RC = Ext2GetStandardInformation(PtrFCB, &(PtrAllInfo->StandardInformation), &BufferLength))) 
                                        {
-                                               try_return(RC);
+                                               try_return();
                                        }
                                        // Similarly, get all of the others ...
                                }
@@ -291,19 +291,19 @@ PIRP                                                      PtrIrp)
                        case FileAlternateNameInformation:
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "FileAlternateNameInformation requested for %S", PtrFCB->FCBName->ObjectName.Buffer );
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                                // RC = Ext2GetAltNameInformation(...);
                                break;
                        case FileCompressionInformation:
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "FileCompressionInformation requested for %S", PtrFCB->FCBName->ObjectName.Buffer );
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                                // RC = Ext2GetCompressionInformation(...);
                                break;
 
                        default:
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                        }
 
                        // If we completed successfully, the return the amount of information transferred.
@@ -409,7 +409,7 @@ PIRP                                                        PtrIrp)
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "Attempt to set FileEndOfFileInformation for %S", PtrFCB->FCBName->ObjectName.Buffer );
                                // RC = Ext2SetEOF(...);
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                                break;
 
                        case FilePositionInformation:
@@ -449,7 +449,7 @@ PIRP                                                        PtrIrp)
                        case FileLinkInformation:
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "Attempt to set FileLinkInformation for %S", PtrFCB->FCBName->ObjectName.Buffer );
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                                // When you implement your rename/link routine, be careful to
                                // check the following two arguments:
                                // TargetFileObject = PtrIoStackLocation->Parameters.SetFile.FileObject;
@@ -484,7 +484,7 @@ PIRP                                                        PtrIrp)
                        default:
                                DebugTrace(DEBUG_TRACE_FILEINFO,   "Unrecoganised SetFileInformation code for %S", PtrFCB->FCBName->ObjectName.Buffer );
                                RC = STATUS_INVALID_PARAMETER;
-                               try_return(RC);
+                               try_return();
                        }
                }
 
@@ -934,7 +934,7 @@ PFILE_DISPOSITION_INFORMATION       PtrBuffer)
                        // "un-delete" the file.
                        Ext2ClearFlag(PtrFCB->FCBFlags, EXT2_FCB_DELETE_ON_CLOSE);
                        PtrFileObject->DeletePending = FALSE;
-                       try_return(RC);
+                       try_return();
                }
 
                // Do some checking to see if the file can even be deleted.
@@ -942,7 +942,7 @@ PFILE_DISPOSITION_INFORMATION       PtrBuffer)
                if (PtrFCB->FCBFlags & EXT2_FCB_DELETE_ON_CLOSE) 
                {
                        // All done!
-                       try_return(RC);
+                       try_return();
                }
 
                if (PtrFCB->FCBFlags & EXT2_FCB_READ_ONLY) 
index ff61c56..9ca5294 100644 (file)
@@ -138,7 +138,7 @@ PIRP                                                        PtrIrp)
                // If we cannot wait, post the request immediately since a flush is inherently blocking/synchronous.
                if (!CanWait) {
                        PostRequest = TRUE;
-                       try_return(RC);
+                       try_return();
                }
 
                // Check the type of object passed-in. That will determine the course of
@@ -160,7 +160,7 @@ PIRP                                                        PtrIrp)
 
                        Ext2FlushLogicalVolume(PtrIrpContext, PtrIrp, PtrVCB);
 
-                       try_return(RC);
+                       try_return();
                }
 
                if (!(PtrFCB->FCBFlags & EXT2_FCB_DIRECTORY)) 
index dfd5459..472dfbf 100644 (file)
@@ -221,8 +221,6 @@ Ext2MountVolume (
        
        PEXT2_GROUP_DESCRIPTOR  PtrGroupDescriptor = NULL;
 
-       PEXT2_INODE                     PtrInode = NULL;
-
        // Inititalising variables
        
        PtrVPB = IrpSp->Parameters.MountVolume.Vpb;
@@ -257,7 +255,7 @@ Ext2MountVolume (
                DebugTrace(DEBUG_TRACE_MOUNT, "OEM[%s]", BootSector->Oem);
                if (BootSector->Oem[0])
                {
-                   try_return (STATUS_WRONG_VOLUME);
+                   try_return();
                }
 
                //      Allocating memory for reading in Super Block...
@@ -299,7 +297,7 @@ Ext2MountVolume (
                     (PDEVICE_OBJECT *)&PtrVolumeDeviceObject)) //      The Volume Device Object
                                        ) 
                        {
-                   try_return( Status );
+                   try_return();
                        }
 
                        //      
@@ -444,7 +442,7 @@ Ext2MountVolume (
                        PtrRootFileObject = IoCreateStreamFileObject(NULL, TargetDeviceObject );
                        if( !PtrRootFileObject )
                        {
-                               try_return( Status );
+                               try_return();
                        }
                        //
                        //      Associate the file stream with the Volume parameter block...
@@ -473,7 +471,7 @@ Ext2MountVolume (
                                                PtrVCB,
                                                PtrObjectName  )  )  )
                                {
-                                       try_return( Status );
+                                       try_return();
                                }
                                
 
index 14db465..a09b83d 100644 (file)
@@ -76,7 +76,7 @@ NTSTATUS NTAPI Ext2PassDownMultiReadWriteIRP(
                        if ( !PtrSyncEvent )
                        {
                                RC = STATUS_INSUFFICIENT_RESOURCES;
-                               try_return ( RC );
+                               try_return();
                        }
                        KeInitializeEvent( PtrSyncEvent, SynchronizationEvent, FALSE );
                }
@@ -87,7 +87,7 @@ NTSTATUS NTAPI Ext2PassDownMultiReadWriteIRP(
                if ( !PtrIoContext )
                {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return ( RC );
+                       try_return();
                }
 
                RtlZeroMemory( PtrIoContext, sizeof(EXT2_IO_CONTEXT) );
@@ -198,13 +198,13 @@ NTSTATUS NTAPI Ext2PassDownMultiReadWriteIRP(
                        KeWaitForSingleObject( PtrSyncEvent,
                                Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL );
                         DbgPrint("DEADLY WAIT DONE\n");
-                       try_return ( RC );
+                       try_return();
                }
                else
                {
                        //      Asynchronous IO...
                        RC = STATUS_PENDING;
-                       try_return ( RC );
+                       try_return();
                }
        
                try_exit:       NOTHING;
@@ -259,7 +259,7 @@ NTSTATUS NTAPI Ext2PassDownSingleReadWriteIRP(
                        if ( !PtrSyncEvent )
                        {
                                RC = STATUS_INSUFFICIENT_RESOURCES;
-                               try_return ( RC );
+                               try_return();
                        }
                        KeInitializeEvent( PtrSyncEvent, SynchronizationEvent, FALSE );
                }
@@ -271,7 +271,7 @@ NTSTATUS NTAPI Ext2PassDownSingleReadWriteIRP(
                if ( !PtrIoContext )
                {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return ( RC );
+                       try_return();
                }
 
                RtlZeroMemory( PtrIoContext, sizeof(EXT2_IO_CONTEXT) );
index 0b18a2f..468a1e4 100644 (file)
@@ -83,7 +83,7 @@ NTSTATUS NTAPI Ext2ReadInode (
                        DebugTrace(DEBUG_TRACE_MISC,   "&&&&&& Invalid Inode no. Group no %d - too big", GroupNo );
                        DebugTrace(DEBUG_TRACE_MISC,   "Only %d groups available on disk", PtrVcb->NoOfGroups );
                        RC = STATUS_UNSUCCESSFUL;
-                       try_return( RC );
+                       try_return();
                }
 
                //if( PtrVcb->InodeTableBlock[ GroupNo ] == 0 )
@@ -91,7 +91,7 @@ NTSTATUS NTAPI Ext2ReadInode (
                {
                        DebugTrace(DEBUG_TRACE_MISC,   "&&&&&& Inode Table Group Invalid - Group no %d ", GroupNo );
                        RC = STATUS_UNSUCCESSFUL;
-                       try_return( RC );
+                       try_return();
                }
 
                //      Inode numbers start at 1 and not from 0
@@ -135,7 +135,7 @@ NTSTATUS NTAPI Ext2ReadInode (
                        (PVOID*)&PtrPinnedReadBuffer )) 
                {
                        RC = STATUS_UNSUCCESSFUL;
-                       try_return( RC );
+                       try_return();
                }
                else
                {
@@ -736,14 +736,14 @@ NTSTATUS NTAPI Ext2WriteInode(
                        DebugTrace(DEBUG_TRACE_MISC,   "&&&&&& Invalid Inode no. Group no %d - too big", GroupNo );
                        DebugTrace(DEBUG_TRACE_MISC,   "Only %d groups available on disk", PtrVcb->NoOfGroups );
                        RC = STATUS_UNSUCCESSFUL;
-                       try_return( RC );
+                       try_return();
                }
 
                if( PtrVcb->PtrGroupDescriptors[ GroupNo ].InodeTablesBlock == 0 )
                {
                        DebugTrace(DEBUG_TRACE_MISC,   "&&&&&& Inode Table Group Invalid - Group no %d ", GroupNo );
                        RC = STATUS_UNSUCCESSFUL;
-                       try_return( RC );
+                       try_return();
                }
 
                Index = ( InodeNo - 1 ) - ( GroupNo * PtrVcb->InodesPerGroup );
@@ -781,7 +781,7 @@ NTSTATUS NTAPI Ext2WriteInode(
                                        (PVOID*)&PtrPinnedBuffer ) )
                {
                        RC = STATUS_UNSUCCESSFUL;
-                       try_return( RC );
+                       try_return();
                }
                else
                {
index 4863acc..dbf92e0 100644 (file)
@@ -92,27 +92,27 @@ void)
                // allocate memory for each of the zones and initialize the     zones ...
                if (!(Ext2GlobalData.ObjectNameZone = Ext2AllocatePool(NonPagedPool, SizeOfObjectNameZone ))) {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return(RC);
+                       try_return();
                }
 
                if (!(Ext2GlobalData.CCBZone = Ext2AllocatePool(NonPagedPool, SizeOfCCBZone ))) {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return(RC);
+                       try_return();
                }
 
                if (!(Ext2GlobalData.FCBZone = Ext2AllocatePool(NonPagedPool, SizeOfFCBZone ))) {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return(RC);
+                       try_return();
                }
 
                if (!(Ext2GlobalData.ByteLockZone = Ext2AllocatePool(NonPagedPool, SizeOfByteLockZone ))) {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return(RC);
+                       try_return();
                }
 
                if (!(Ext2GlobalData.IrpContextZone = Ext2AllocatePool(NonPagedPool, SizeOfIrpContextZone ))) {
                        RC = STATUS_INSUFFICIENT_RESOURCES;
-                       try_return(RC);
+                       try_return();
                }
 
                // initialize each of the zone headers ...
@@ -120,7 +120,7 @@ void)
                                        Ext2QuadAlign(sizeof(Ext2ObjectName)),
                                        Ext2GlobalData.ObjectNameZone, SizeOfObjectNameZone))) {
                        // failed the initialization, leave ...
-                       try_return(RC);
+                       try_return();
                }
 
                if (!NT_SUCCESS(RC = ExInitializeZone(&(Ext2GlobalData.CCBZoneHeader),
@@ -128,7 +128,7 @@ void)
                                        Ext2GlobalData.CCBZone,
                                        SizeOfCCBZone))) {
                        // failed the initialization, leave ...
-                       try_return(RC);
+                       try_return();
                }
 
                if (!NT_SUCCESS(RC = ExInitializeZone(&(Ext2GlobalData.FCBZoneHeader),
@@ -136,7 +136,7 @@ void)
                                        Ext2GlobalData.FCBZone,
                                        SizeOfFCBZone))) {
                        // failed the initialization, leave ...
-                       try_return(RC);
+                       try_return();
                }
 
                if (!NT_SUCCESS(RC = ExInitializeZone(&(Ext2GlobalData.ByteLockZoneHeader),
@@ -144,7 +144,7 @@ void)
                                        Ext2GlobalData.ByteLockZone,
                                        SizeOfByteLockZone))) {
                        // failed the initialization, leave ...
-                       try_return(RC);
+                       try_return();
                }
 
                if (!NT_SUCCESS(RC = ExInitializeZone(&(Ext2GlobalData.IrpContextZoneHeader),
@@ -152,7 +152,7 @@ void)
                                        Ext2GlobalData.IrpContextZone,
                                        SizeOfIrpContextZone))) {
                        // failed the initialization, leave ...
-                       try_return(RC);
+                       try_return();
                }
 
                try_exit:       NOTHING;
@@ -1411,7 +1411,7 @@ PLARGE_INTEGER                    AllocationSize )
        PtrVCB->CommonVCBHeader.IsFastIoPossible = FastIoIsNotPossible;
        
        PtrVCB->CommonVCBHeader.Resource = &(PtrVCB->VCBResource);
-       PtrVCB->CommonVCBHeader.PagingIoResource = &(PtrVCB->PagingIoResource);;
+       PtrVCB->CommonVCBHeader.PagingIoResource = &(PtrVCB->PagingIoResource);
 
        // Create a stream file object for this volume.
        PtrVCB->PtrStreamFileObject = IoCreateStreamFileObject(NULL,
index c8f41d3..3c7d70b 100644 (file)
@@ -255,7 +255,7 @@ BOOLEAN                                             FirstAttempt )
                if (ReadLength == 0) 
                {
                        // a 0 byte read can be immediately succeeded
-                       try_return(RC);
+                       try_return();
                }
 
                // Is this a read of the volume itself ?
@@ -320,7 +320,7 @@ BOOLEAN                                             FirstAttempt )
                                {
                                        RC = STATUS_END_OF_FILE;
                                        NumberBytesRead = 0;
-                                       try_return( RC );
+                                       try_return();
                                }
                        }
                        if( PagingIo || NonBufferedIo )
@@ -332,7 +332,7 @@ BOOLEAN                                             FirstAttempt )
                                        PtrIrpContext, PtrIrp, PtrVCB, 
                                        ByteOffset, ReadLength, SynchronousIo);
 
-                               try_return(RC);
+                               try_return();
                        }
                        else
                        {
@@ -357,7 +357,7 @@ BOOLEAN                                             FirstAttempt )
 
                                        RC = STATUS_UNSUCCESSFUL;
                                        NumberBytesRead = 0;
-                                       try_return( RC );
+                                       try_return();
                                }
                                else
                                {
@@ -367,7 +367,7 @@ BOOLEAN                                             FirstAttempt )
                                        PtrBCB = NULL;
                                        RC = STATUS_SUCCESS;
                                        NumberBytesRead = ReadLength;
-                                       try_return(RC);
+                                       try_return();
 
                                }
                        }
@@ -400,7 +400,7 @@ BOOLEAN                                             FirstAttempt )
                if ( ( PtrFCB->FCBFlags & EXT2_FCB_DIRECTORY ) &&  !PagingIo )
                {
                        RC = STATUS_INVALID_DEVICE_REQUEST;
-                       try_return(RC);
+                       try_return();
                }
 
                PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
@@ -448,7 +448,7 @@ BOOLEAN                                             FirstAttempt )
                                // If the flush failed, return error to the caller
                                if (!NT_SUCCESS(RC = PtrIrp->IoStatus.Status)) 
                                {
-                                       try_return(RC);
+                                       try_return();
                                }
                        }
                }
@@ -573,7 +573,7 @@ BOOLEAN                                             FirstAttempt )
                                NumberBytesRead = PtrIrp->IoStatus.Information;
                                RC = PtrIrp->IoStatus.Status;
 
-                               try_return(RC);
+                               try_return();
                        }
 
                        // This is a regular run-of-the-mill cached I/O request. Let the
@@ -593,13 +593,13 @@ BOOLEAN                                           FirstAttempt )
                                // Mark Irp Pending ...
                                IoMarkIrpPending( PtrIrp );
                                RC = STATUS_PENDING;
-                               try_return(RC);
+                               try_return();
                        }
 
                        // We have the data
                        RC = PtrIrp->IoStatus.Status;
                        NumberBytesRead = PtrIrp->IoStatus.Information;
-                       try_return(RC);
+                       try_return();
                }
                else // NonBuffered or Paged IO
                {
@@ -693,7 +693,7 @@ BOOLEAN                                             FirstAttempt )
                                        // Mark Irp Pending ...
                                        IoMarkIrpPending( PtrIrp );
                                        RC = STATUS_PENDING;
-                                       try_return(RC);
+                                       try_return();
                                        DebugTrace(DEBUG_TRACE_ASYNC,   "Cache read failiure while reading in volume meta data - Retrying", 0);
                                }
                        }
@@ -732,7 +732,7 @@ BOOLEAN                                             FirstAttempt )
                                        // Mark Irp Pending ...
                                        IoMarkIrpPending( PtrIrp );
                                        RC = STATUS_PENDING;
-                                       try_return(RC);
+                                       try_return();
                                        DebugTrace(DEBUG_TRACE_ASYNC,   "Cache read failiure while reading in volume meta data - Retrying", 0);
                                }
 
@@ -839,7 +839,7 @@ BOOLEAN                                             FirstAttempt )
                                        // Mark Irp Pending ...
                                        IoMarkIrpPending( PtrIrp );
                                        RC = STATUS_PENDING;
-                                       try_return(RC);
+                                       try_return();
                                        DebugTrace(DEBUG_TRACE_ASYNC,   "Cache read failiure while reading in volume meta data - Retrying", 0);
                                }
 
@@ -1045,7 +1045,7 @@ BOOLEAN                                           FirstAttempt )
                                                Ext2BreakPoint();
                                        }
 
-                                       PtrIoRuns[ Index ].LogicalBlock = PtrTIArray[ IBlockIndex ].PtrSIBlocks[ BlockIndex ];;
+                                       PtrIoRuns[ Index ].LogicalBlock = PtrTIArray[ IBlockIndex ].PtrSIBlocks[ BlockIndex ];
                                        DbgPrint( "LogicalBlock = 0x%lX", PtrIoRuns[ Index ].LogicalBlock );
                                }
 
@@ -1146,7 +1146,7 @@ BOOLEAN                                           FirstAttempt )
                        {
                                CompleteIrp = FALSE;    
                        }
-                       try_return( RC );
+                       try_return();
                
                }
                try_exit:       NOTHING;
@@ -1374,7 +1374,7 @@ uint32                    Length)
                        if (!(PtrMdl = IoAllocateMdl(PtrIrp->UserBuffer, Length, FALSE, FALSE, PtrIrp))) 
                        {
                                RC = STATUS_INSUFFICIENT_RESOURCES;
-                               try_return(RC);
+                               try_return();
                        }
 
                        // Probe and lock the pages described by the MDL
index 63b5ea9..f72c0ec 100644 (file)
@@ -241,7 +241,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                if (WriteLength == 0) 
                {
                        // a 0 byte write can be immediately succeeded
-                       try_return(RC);
+                       try_return();
                }
 
                // Is this a write of the volume itself ?
@@ -310,14 +310,14 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                        //
                                        RC = STATUS_END_OF_FILE;
                                        NumberBytesWritten = 0;
-                                       try_return( RC );
+                                       try_return();
                                }
                        }
 
                        // Lock the callers buffer
                        if (!NT_SUCCESS(RC = Ext2LockCallersBuffer(PtrIrp, TRUE, WriteLength))) 
                        {
-                               try_return(RC);
+                               try_return();
                        }
 
                        // Forward the request to the lower level driver
@@ -337,7 +337,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                                PtrIrpContext, PtrIrp, PtrVCB, 
                                                ByteOffset, WriteLength, SynchronousIo );
 
-                               try_return(RC);
+                               try_return();
                        }
                        else
                        {
@@ -375,7 +375,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
 
                                //      Go ahead and complete the IRP...
                        }
-                       try_return(RC);
+                       try_return();
                }
 
       
@@ -433,7 +433,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                //      Nope... User initiated directory writes are not allowed!
                                //      Fail this request...
                                RC = STATUS_INVALID_DEVICE_REQUEST;
-                               try_return(RC);
+                               try_return();
                        }
                }
 
@@ -496,7 +496,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                        // If the flush failed, return error to the caller
                        if (!NT_SUCCESS(RC = PtrIrp->IoStatus.Status)) 
                        {
-                               try_return(RC);
+                               try_return();
                        }
 
                        // Attempt the purge and ignore the return code
@@ -555,7 +555,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                                //      Page request for writing outside the file...
                                                //      No op this IRP by completing it...
                                                //
-                                               try_return(RC);
+                                               try_return();
                                        }
                                        if( ByteOffset.QuadPart + WriteLength
                                                > PtrReqdFCB->CommonFCBHeader.AllocationSize.QuadPart )
@@ -688,7 +688,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                NumberBytesWritten = PtrIrp->IoStatus.Information;
                                RC = PtrIrp->IoStatus.Status;
 
-                               try_return(RC);
+                               try_return();
                        }
 
                        // This is a regular run-of-the-mill cached I/O request. Let the
@@ -781,7 +781,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
 
                                Ext2DeallocateUnicodeString( &ErrorMessage );
                                RC = STATUS_INSUFFICIENT_RESOURCES;
-                               try_return ( RC );
+                               try_return();
                        }
                        
                        if( ( ByteOffset.QuadPart + WriteLength ) > DirectBlockSize &&
@@ -813,7 +813,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                        // Mark Irp Pending ...
                                        IoMarkIrpPending( PtrIrp );
                                        RC = STATUS_PENDING;
-                                       try_return(RC);
+                                       try_return();
                                        DebugTrace(DEBUG_TRACE_ASYNC,   "Cache read failiure while reading in volume meta data", 0);
                                }
                        }
@@ -852,7 +852,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                        // Mark Irp Pending ...
                                        IoMarkIrpPending( PtrIrp );
                                        RC = STATUS_PENDING;
-                                       try_return(RC);
+                                       try_return();
                                        DebugTrace(DEBUG_TRACE_ASYNC,   "Cache read failiure while reading in volume meta data - Retrying", 0);
                                }
 
@@ -944,7 +944,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                        // Mark Irp Pending ...
                                        IoMarkIrpPending( PtrIrp );
                                        RC = STATUS_PENDING;
-                                       try_return(RC);
+                                       try_return();
                                        DebugTrace(DEBUG_TRACE_ASYNC,   "Cache read failiure while reading in volume meta data - Retrying", 0);
                                }
 
@@ -1055,7 +1055,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                        // Mark Irp Pending ...
                                        IoMarkIrpPending( PtrIrp );
                                        RC = STATUS_PENDING;
-                                       try_return(RC);
+                                       try_return();
                                        DebugTrace(DEBUG_TRACE_ASYNC,   "Cache read failiure while reading in volume meta data - Retrying", 0);
                                }
 
@@ -1256,7 +1256,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                                                Ext2BreakPoint();
                                        }
 
-                                       PtrIoRuns[ Index ].LogicalBlock = PtrTIArray[ IBlockIndex ].PtrSIBlocks[ BlockIndex ];;
+                                       PtrIoRuns[ Index ].LogicalBlock = PtrTIArray[ IBlockIndex ].PtrSIBlocks[ BlockIndex ];
                                        DbgPrint( "LogicalBlock = 0x%lX", PtrIoRuns[ Index ].LogicalBlock );
                                }
 
@@ -1324,7 +1324,7 @@ NTSTATUS NTAPI Ext2CommonWrite(
                        {
                                CompleteIrp = FALSE;    
                        }
-                       try_return( RC );
+                       try_return();
                }
 
                try_exit:       NOTHING;
index 86032af..d6e9891 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<module name="ks" type="kernelmodedriver" installbase="system32/drivers" installname="ks.sys" allowwarnings="true">
+<module name="ks" type="kernelmodedriver" installbase="system32/drivers" installname="ks.sys">
        <include base="ks">.</include>
        <include base="ks">..</include>
        <include base="ks">../include</include>
index cbfb18f..6fb1292 100644 (file)
@@ -63,13 +63,14 @@ KsUnregisterWorker(
 {
     KS_WORKER * KsWorker;
     KIRQL OldIrql;
-    ULONG bWait = FALSE;
 
     if (!Worker)
         return;
 
     KsWorker = (KS_WORKER *)Worker;
 
+    KeAcquireSpinLock(&KsWorker->Lock, &OldIrql);
+
     KsWorker->DeleteInProgress = TRUE;
 
     if (KsWorker->WorkItemActive)
index 1b51a25..895b2eb 100644 (file)
@@ -1923,7 +1923,7 @@ Return Value:
             break;
         }
 
-        length += (sizeof(SENDCMDOUTPARAMS) > sizeof(SENDCMDINPARAMS)) ? sizeof(SENDCMDOUTPARAMS) : sizeof(SENDCMDINPARAMS);;
+        length += (sizeof(SENDCMDOUTPARAMS) > sizeof(SENDCMDINPARAMS)) ? sizeof(SENDCMDOUTPARAMS) : sizeof(SENDCMDINPARAMS);
         srbControl = ExAllocatePool(NonPagedPool,
                                     sizeof(SRB_IO_CONTROL) + length);
 
index bca43f8..5d25c60 100644 (file)
@@ -138,6 +138,10 @@ ScsiDebugPrint(
 
 #else // _DEBUG
 
+#ifdef KdPrint
+#undef KdPrint
+#endif
+
 #define PRINT_PREFIX "UniATA: "
 
 //#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
index e1fbe3b..58f8313 100644 (file)
@@ -1864,7 +1864,9 @@ AtapiResetController__(
     ULONG slotNumber = deviceExtension->slotNumber;
     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
+#ifdef _DEBUG
     ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
+#endif
     //ULONG RevID    =  deviceExtension->RevID;
     ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
     UCHAR tmp8;
index 48e96dc..b8c129b 100644 (file)
@@ -159,7 +159,11 @@ InitBadBlocks(
                                                 L"UniATA\\Parameters\\BadBlocks",
                                                 QueryTable, 0, 0);
 
+#ifdef _DEBUG
         KdPrint(( "InitBadBlocks returned: %#x\n", status));
+#else
+        UNREFERENCED_PARAMETER(status);
+#endif
     } else {
 
         KdPrint(( "InitBadBlocks local\n"));
index 0b1239f..6de1fa7 100644 (file)
@@ -219,7 +219,7 @@ AtapiDmaSetup(
     PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
     PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
     BOOLEAN use_DB_IO = FALSE;
-    BOOLEAN use_AHCI = FALSE;
+    //BOOLEAN use_AHCI = FALSE;
     ULONG orig_count = count;
     ULONG max_entries = (deviceExtension->HwFlags & UNIATA_AHCI) ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES;
 
@@ -281,7 +281,7 @@ retry_DB_IO:
     if(!dma_count || ((LONG)(dma_base) == -1)) {
         KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No 1st block\n" ));
         //AtaReq->dma_base = NULL;
-        AtaReq->ahci_base64 = NULL;
+        AtaReq->ahci_base64 = (ULONGLONG)NULL;
         return FALSE;
     }
 
@@ -303,7 +303,7 @@ retry_DB_IO:
         if (i >= max_entries) {
             KdPrint2((PRINT_PREFIX "too many segments in DMA table\n" ));
             //AtaReq->dma_base = NULL;
-            AtaReq->ahci_base64 = NULL;
+            AtaReq->ahci_base64 = (ULONGLONG)NULL;
             return FALSE;
         }
         KdPrint2((PRINT_PREFIX "  get Phys(data[n]=%x)\n", data ));
@@ -321,7 +321,7 @@ retry_DB_IO:
         } else
         if(!dma_count || !dma_base || ((LONG)(dma_base) == -1)) {
             //AtaReq->dma_base = NULL;
-            AtaReq->ahci_base64 = NULL;
+            AtaReq->ahci_base64 = (ULONGLONG)NULL;
             KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No NEXT block\n" ));
             return FALSE;
         }
@@ -612,7 +612,7 @@ AtapiDmaReinit(
     }
 
     if((deviceExtension->HbaCtrlFlags & HBAFLAGS_DMA_DISABLED_LBA48) &&
-       (AtaReq->lba >= ATA_MAX_LBA28) &&
+       (AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) &&
        (LunExt->TransferMode > ATA_PIO5) ) {
         KdPrint2((PRINT_PREFIX
                     "AtapiDmaReinit: FORCE_DOWNRATE on Device %d for LBA48\n", ldev & 1));
@@ -623,7 +623,7 @@ AtapiDmaReinit(
     if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
         KdPrint2((PRINT_PREFIX
                     "AtapiDmaReinit: FORCE_DOWNRATE on Device %d\n", ldev & 1));
-        if(AtaReq->lba >= ATA_MAX_LBA28) {
+        if(AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) {
 limit_lba48:
             LunExt->DeviceFlags |= REQ_FLAG_FORCE_DOWNRATE_LBA48;
 limit_pio:
@@ -1046,7 +1046,7 @@ set_new_acard:
         /* set PIO mode timings */
         AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
         if((apiomode >= 0) && (ChipType != VIA133)) {
-            SetPciConfig1(reg-0x08, via_pio[apiomode]);
+            SetPciConfig1(reg-0x08, via_pio[(UCHAR)apiomode]);
         }
         via82c_timing(deviceExtension, dev, ATA_PIO0 + apiomode);
         AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
@@ -1067,18 +1067,18 @@ set_new_acard:
             apiomode = 4;
         for(i=udmamode; i>=0; i--) {
             if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
-                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]);
+                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[(UCHAR)udmamode]);
                 return;
             }
         }
         for(i=wdmamode; i>=0; i--) {
             if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
-                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]);
+                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[(UCHAR)wdmamode]);
                 return;
             }
         }
         if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
-            AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]);
+            AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[(UCHAR)apiomode]);
             return;
         }
         return;
@@ -1113,7 +1113,7 @@ set_new_acard:
         }
         if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
             ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000);
-            SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]);
+            SetPciConfig4(0x40 + (dev * 8), nat_piotiming[(UCHAR)apiomode]);
             return;
         }
         /* Use GENERIC PIO */
@@ -1413,7 +1413,7 @@ set_new_acard:
                 // 44
                 GetPciConfig4(0x44, reg44);
                 reg44 = (reg44 & ~(0xff << bit_offset)) |
-                             (sw_dma_modes[wdmamode] << bit_offset);
+                             (sw_dma_modes[(UCHAR)wdmamode] << bit_offset);
                 SetPciConfig4(0x44, reg44);
                 // 40
                 GetPciConfig4(0x40, reg40);
@@ -1439,7 +1439,7 @@ set_new_acard:
         // 40
         GetPciConfig4(0x40, reg40);
         reg40 = (reg40 & ~(0xff << bit_offset)) |
-                       (sw_pio_modes[apiomode] << bit_offset);
+                       (sw_pio_modes[(UCHAR)apiomode] << bit_offset);
         SetPciConfig4(0x40, reg40);
         return;
         break; }
@@ -1527,7 +1527,7 @@ l_ATA_SILICON_IMAGE_ID:
             /* set PIO mode timings */
             AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
 
-            SetPciConfig1(treg, cmd_pio_modes[apiomode]);
+            SetPciConfig1(treg, cmd_pio_modes[(UCHAR)apiomode]);
             ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca));
             return;
 
@@ -1538,7 +1538,7 @@ l_ATA_SILICON_IMAGE_ID:
         /*******/
         /* SiS */
         /*******/
-        PULONG sis_modes;
+        PULONG sis_modes = NULL;
         static const ULONG sis_modes_new133[] =
                 { 0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008,
                   0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac,
@@ -1553,9 +1553,9 @@ l_ATA_SILICON_IMAGE_ID:
                 { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031,
                   0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 };
 
-        ULONG reg;
+        ULONG reg = 0;
         UCHAR reg57;
-        ULONG reg_size;
+        ULONG reg_size = 0;
         ULONG offs;
 
         switch(ChipType) {
@@ -1901,7 +1901,7 @@ hpt_timing(
     ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
     //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
 
-    ULONG timing;
+    ULONG timing = 0;
 
     if(mode == ATA_PIO5)
         mode = ATA_PIO4;
index a1e8bbe..214401c 100644 (file)
@@ -52,11 +52,11 @@ UniataChipDetectChannels(
     )
 {
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG slotNumber = deviceExtension->slotNumber;
-    ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
+    //ULONG slotNumber = deviceExtension->slotNumber;
+    //ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
-    ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
-    ULONG RevID    =  deviceExtension->RevID;
+    //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
+    //ULONG RevID    =  deviceExtension->RevID;
     ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
     ULONG ChipFlags= deviceExtension->HwFlags & CHIPFLAG_MASK;
 
@@ -216,7 +216,7 @@ UniataChipDetect(
         PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5, "SiS 730"  , SIS100OLD        ),
 
         PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6, "SiS 645DX", SIS133NEW        ),
-/*        PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645"  , SIS133NEW        ),
+/*        PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645"  , SIS133NEW        ),*/
 /*        PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640"  , SIS_SOUTH        ),*/
         PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5, "SiS 635"  , SIS100NEW        ),
         PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5, "SiS 633"  , SIS100NEW        ),
@@ -419,7 +419,7 @@ for_ugly_chips:
             BaseIoAddressBM = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
                                     4, 0, deviceExtension->NumberChannels*sizeof(IDE_BUSMASTER_REGISTERS));
             for(c=0; c<deviceExtension->NumberChannels; c++) {
-                ULONG unit01 = (c & 1);
+                //ULONG unit01 = (c & 1);
                 ULONG unit10 = (c & 2);
                 chan = &deviceExtension->chan[c];
 
@@ -987,7 +987,7 @@ AtapiRosbSouthBridgeFixup(
     IN ULONG  slotNumber
     )
 {
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+    //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     PCI_COMMON_CONFIG     pciData;
     ULONG                 funcNumber;
     ULONG                 busDataRead;
@@ -1039,7 +1039,7 @@ AtapiAliSouthBridgeFixup(
     IN ULONG  c
     )
 {
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+    //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     PCI_COMMON_CONFIG     pciData;
     ULONG                 funcNumber;
     ULONG                 busDataRead;
@@ -1174,7 +1174,7 @@ generic_cable80(
     ULONG slotNumber = deviceExtension->slotNumber;
     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
 
-    ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
+    //ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
     PHW_CHANNEL chan;
     ULONG  c; // logical channel (for Compatible Mode controllers)
     UCHAR tmp8;
@@ -1332,7 +1332,9 @@ AtapiChipInit(
     ULONG slotNumber = deviceExtension->slotNumber;
     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
+#ifdef _DEBUG
     ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
+#endif
     ULONG RevID    =  deviceExtension->RevID;
 //    ULONG i;
 //    BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
index cfbb887..51cd639 100644 (file)
@@ -76,7 +76,6 @@ UniataEnumBusMasterController__(
 VOID
 AtapiDoNothing(VOID)
 {
-    ULONG i = 0;
     return;
 } // end AtapiDoNothing()
 
@@ -504,8 +503,8 @@ UniataEnumBusMasterController__(
 /*                        if(known) {
                             RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION));
                         } else {*/
-                        sprintf((PCHAR)vendorStrPtr, "%4.4x", VendorID);
-                        sprintf((PCHAR)deviceStrPtr, "%4.4x", DeviceID);
+                        sprintf((PCHAR)vendorStrPtr, "%4.4x", (UINT32)VendorID);
+                        sprintf((PCHAR)deviceStrPtr, "%4.4x", (UINT32)DeviceID);
 
                         RtlCopyMemory(&(newBMListPtr->VendorIdStr), (PCHAR)vendorStrPtr, 4);
                         RtlCopyMemory(&(newBMListPtr->DeviceIdStr), (PCHAR)deviceStrPtr, 4);
@@ -874,7 +873,11 @@ UniataFindBusMasterController(
     BOOLEAN found = FALSE;
     BOOLEAN MasterDev;
     BOOLEAN simplexOnly = FALSE;
+#ifndef UNIATA_CORE
+#ifdef UNIATA_INIT_ON_PROBE
     BOOLEAN skip_find_dev = FALSE;
+#endif
+#endif
     BOOLEAN AltInit = FALSE;
 
     SCSI_PHYSICAL_ADDRESS IoBasePort1;
@@ -1712,7 +1715,7 @@ UniataFindFakeBusMasterController(
     )
 {
     PHW_DEVICE_EXTENSION  deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL           chan = NULL;
+    //PHW_CHANNEL           chan = NULL;
     // this buffer must be global for UNIATA_CORE build
     PCI_COMMON_CONFIG     pciData;
 
@@ -1743,8 +1746,8 @@ UniataFindFakeBusMasterController(
     BOOLEAN found = FALSE;
     BOOLEAN MasterDev;
     BOOLEAN simplexOnly = FALSE;
-    BOOLEAN skip_find_dev = FALSE;
-    BOOLEAN AltInit = FALSE;
+    //BOOLEAN skip_find_dev = FALSE;
+    //BOOLEAN AltInit = FALSE;
 
     PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL;
 
@@ -1797,7 +1800,7 @@ UniataFindFakeBusMasterController(
                                      &pciData,
                                      PCI_COMMON_HDR_LENGTH);
 
-    if (busDataRead < PCI_COMMON_HDR_LENGTH) {
+    if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
         KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
         goto exit_error;
     }
@@ -2207,7 +2210,7 @@ AtapiFindController(
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     PHW_CHANNEL          chan;
     PULONG               adapterCount    = (PULONG)Context;
-    PUCHAR               ioSpace;
+    PUCHAR               ioSpace = NULL;
     ULONG                i;
     ULONG                irq=0;
     ULONG                portBase;
@@ -2217,7 +2220,7 @@ AtapiFindController(
     BOOLEAN              preConfig = FALSE;
     //
     PIDE_REGISTERS_1 BaseIoAddress1;
-    PIDE_REGISTERS_2 BaseIoAddress2;
+    PIDE_REGISTERS_2 BaseIoAddress2 = NULL;
 
     // The following table specifies the ports to be checked when searching for
     // an IDE controller.  A zero entry terminates the search.
index 3ebd999..3cb8e51 100644 (file)
@@ -7,7 +7,7 @@ UniataSataConnect(
     )
 {
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG Channel = deviceExtension->Channel + lChannel;
+    //ULONG Channel = deviceExtension->Channel + lChannel;
     PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
     SATA_SSTATUS_REG SStatus;
     ULONG i;
@@ -126,7 +126,7 @@ UniataSataClearErr(
 {
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
-    ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
+    //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
     SATA_SSTATUS_REG SStatus;
     SATA_SERROR_REG  SError;
 
index 61f5267..3dc20fd 100644 (file)
@@ -6,7 +6,8 @@
 #define ASSERT
 #else
 #undef ASSERT
-#define ASSERT //(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
+//#define ASSERT //(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
+#define ASSERT(x) // FIXME: WTF!
 #endif //__REACTOS__
 
 
index 8dc4c63..6d231b4 100644 (file)
@@ -172,7 +172,7 @@ typedef union _CDB {
         } Byte2;
 
         UCHAR Reserved2[3];
-        UCHAR Start_TrackSes;;
+        UCHAR Start_TrackSes;
         UCHAR AllocationLength[2];
         UCHAR Control : 6;
         UCHAR Format : 2;
index 98aa814..cecef35 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
-<module name="uniata" type="kernelmodedriver" installbase="system32/drivers" allowwarnings="true" installname="uniata.sys">
+<module name="uniata" type="kernelmodedriver" installbase="system32/drivers" installname="uniata.sys">
        <bootstrap installbase="$(CDOUTPUT)" />
        <include base="uniata">.</include>
        <include base="uniata">inc</include>
diff --git a/reactos/drivers/storage/ide/uniata/warningfixes.diff b/reactos/drivers/storage/ide/uniata/warningfixes.diff
new file mode 100644 (file)
index 0000000..3760c51
--- /dev/null
@@ -0,0 +1,393 @@
+Index: atapi.h\r
+===================================================================\r
+--- atapi.h    (revision 38425)\r
++++ atapi.h    (working copy)\r
+@@ -138,6 +138,10 @@\r
+ #else // _DEBUG
++#ifdef KdPrint
++#undef KdPrint
++#endif
++
+ #define PRINT_PREFIX "UniATA: "
+ //#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
+Index: id_ata.cpp\r
+===================================================================\r
+--- id_ata.cpp (revision 38425)\r
++++ id_ata.cpp (working copy)\r
+@@ -1864,7 +1864,9 @@\r
+     ULONG slotNumber = deviceExtension->slotNumber;
+     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
+     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
++#ifdef _DEBUG
+     ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
++#endif
+     //ULONG RevID    =  deviceExtension->RevID;
+     ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
+     UCHAR tmp8;
+Index: id_badblock.cpp\r
+===================================================================\r
+--- id_badblock.cpp    (revision 38425)\r
++++ id_badblock.cpp    (working copy)\r
+@@ -159,7 +159,11 @@\r
+                                                 L"UniATA\\Parameters\\BadBlocks",
+                                                 QueryTable, 0, 0);
++#ifdef _DEBUG
+         KdPrint(( "InitBadBlocks returned: %#x\n", status));
++#else
++        UNREFERENCED_PARAMETER(status);
++#endif
+     } else {
+         KdPrint(( "InitBadBlocks local\n"));
+Index: id_dma.cpp\r
+===================================================================\r
+--- id_dma.cpp (revision 38425)\r
++++ id_dma.cpp (working copy)\r
+@@ -219,7 +219,7 @@\r
+     PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
+     PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
+     BOOLEAN use_DB_IO = FALSE;
+-    BOOLEAN use_AHCI = FALSE;
++    //BOOLEAN use_AHCI = FALSE;
+     ULONG orig_count = count;
+     ULONG max_entries = (deviceExtension->HwFlags & UNIATA_AHCI) ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES;
+@@ -281,7 +281,7 @@\r
+     if(!dma_count || ((LONG)(dma_base) == -1)) {
+         KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No 1st block\n" ));
+         //AtaReq->dma_base = NULL;
+-        AtaReq->ahci_base64 = NULL;
++        AtaReq->ahci_base64 = (ULONGLONG)NULL;
+         return FALSE;
+     }
+@@ -303,7 +303,7 @@\r
+         if (i >= max_entries) {
+             KdPrint2((PRINT_PREFIX "too many segments in DMA table\n" ));
+             //AtaReq->dma_base = NULL;
+-            AtaReq->ahci_base64 = NULL;
++            AtaReq->ahci_base64 = (ULONGLONG)NULL;
+             return FALSE;
+         }
+         KdPrint2((PRINT_PREFIX "  get Phys(data[n]=%x)\n", data ));
+@@ -321,7 +321,7 @@\r
+         } else
+         if(!dma_count || !dma_base || ((LONG)(dma_base) == -1)) {
+             //AtaReq->dma_base = NULL;
+-            AtaReq->ahci_base64 = NULL;
++            AtaReq->ahci_base64 = (ULONGLONG)NULL;
+             KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No NEXT block\n" ));
+             return FALSE;
+         }
+@@ -612,7 +612,7 @@\r
+     }
+     if((deviceExtension->HbaCtrlFlags & HBAFLAGS_DMA_DISABLED_LBA48) &&
+-       (AtaReq->lba >= ATA_MAX_LBA28) &&
++       (AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) &&
+        (LunExt->TransferMode > ATA_PIO5) ) {
+         KdPrint2((PRINT_PREFIX
+                     "AtapiDmaReinit: FORCE_DOWNRATE on Device %d for LBA48\n", ldev & 1));
+@@ -623,7 +623,7 @@\r
+     if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
+         KdPrint2((PRINT_PREFIX
+                     "AtapiDmaReinit: FORCE_DOWNRATE on Device %d\n", ldev & 1));
+-        if(AtaReq->lba >= ATA_MAX_LBA28) {
++        if(AtaReq->lba >= (LONGLONG)ATA_MAX_LBA28) {
+ limit_lba48:
+             LunExt->DeviceFlags |= REQ_FLAG_FORCE_DOWNRATE_LBA48;
+ limit_pio:
+@@ -1046,7 +1046,7 @@\r
+         /* set PIO mode timings */
+         AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
+         if((apiomode >= 0) && (ChipType != VIA133)) {
+-            SetPciConfig1(reg-0x08, via_pio[apiomode]);
++            SetPciConfig1(reg-0x08, via_pio[(UCHAR)apiomode]);
+         }
+         via82c_timing(deviceExtension, dev, ATA_PIO0 + apiomode);
+         AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
+@@ -1067,18 +1067,18 @@\r
+             apiomode = 4;
+         for(i=udmamode; i>=0; i--) {
+             if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+-                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]);
++                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[(UCHAR)udmamode]);
+                 return;
+             }
+         }
+         for(i=wdmamode; i>=0; i--) {
+             if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+-                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]);
++                AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[(UCHAR)wdmamode]);
+                 return;
+             }
+         }
+         if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+-            AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]);
++            AtapiWritePortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[(UCHAR)apiomode]);
+             return;
+         }
+         return;
+@@ -1113,7 +1113,7 @@\r
+         }
+         if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+             ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000);
+-            SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]);
++            SetPciConfig4(0x40 + (dev * 8), nat_piotiming[(UCHAR)apiomode]);
+             return;
+         }
+         /* Use GENERIC PIO */
+@@ -1413,7 +1413,7 @@\r
+                 // 44
+                 GetPciConfig4(0x44, reg44);
+                 reg44 = (reg44 & ~(0xff << bit_offset)) |
+-                             (sw_dma_modes[wdmamode] << bit_offset);
++                             (sw_dma_modes[(UCHAR)wdmamode] << bit_offset);
+                 SetPciConfig4(0x44, reg44);
+                 // 40
+                 GetPciConfig4(0x40, reg40);
+@@ -1439,7 +1439,7 @@\r
+         // 40
+         GetPciConfig4(0x40, reg40);
+         reg40 = (reg40 & ~(0xff << bit_offset)) |
+-                       (sw_pio_modes[apiomode] << bit_offset);
++                       (sw_pio_modes[(UCHAR)apiomode] << bit_offset);
+         SetPciConfig4(0x40, reg40);
+         return;
+         break; }
+@@ -1527,7 +1527,7 @@\r
+             /* set PIO mode timings */
+             AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
+-            SetPciConfig1(treg, cmd_pio_modes[apiomode]);
++            SetPciConfig1(treg, cmd_pio_modes[(UCHAR)apiomode]);
+             ChangePciConfig1(Channel ? 0x7b : 0x73, a & ~(!(DeviceNumber & 1) ? 0x35 : 0xca));
+             return;
+@@ -1538,7 +1538,7 @@\r
+         /*******/
+         /* SiS */
+         /*******/
+-        PULONG sis_modes;
++        PULONG sis_modes = NULL;
+         static const ULONG sis_modes_new133[] =
+                 { 0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008,
+                   0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac,
+@@ -1553,9 +1553,9 @@\r
+                 { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031,
+                   0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 };
+-        ULONG reg;
++        ULONG reg = 0;
+         UCHAR reg57;
+-        ULONG reg_size;
++        ULONG reg_size = 0;
+         ULONG offs;
+         switch(ChipType) {
+@@ -1901,7 +1901,7 @@\r
+     ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
+     //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
+-    ULONG timing;
++    ULONG timing = 0;
+     if(mode == ATA_PIO5)
+         mode = ATA_PIO4;
+Index: id_init.cpp\r
+===================================================================\r
+--- id_init.cpp        (revision 38425)\r
++++ id_init.cpp        (working copy)\r
+@@ -52,11 +52,11 @@\r
+     )
+ {
+     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+-    ULONG slotNumber = deviceExtension->slotNumber;
+-    ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
++    //ULONG slotNumber = deviceExtension->slotNumber;
++    //ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
+     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
+-    ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
+-    ULONG RevID    =  deviceExtension->RevID;
++    //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
++    //ULONG RevID    =  deviceExtension->RevID;
+     ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
+     ULONG ChipFlags= deviceExtension->HwFlags & CHIPFLAG_MASK;
+@@ -216,7 +216,7 @@\r
+         PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5, "SiS 730"  , SIS100OLD        ),
+         PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6, "SiS 645DX", SIS133NEW        ),
+-/*        PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645"  , SIS133NEW        ),
++/*        PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645"  , SIS133NEW        ),*/
+ /*        PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640"  , SIS_SOUTH        ),*/
+         PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5, "SiS 635"  , SIS100NEW        ),
+         PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5, "SiS 633"  , SIS100NEW        ),
+@@ -419,7 +419,7 @@\r
+             BaseIoAddressBM = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
+                                     4, 0, deviceExtension->NumberChannels*sizeof(IDE_BUSMASTER_REGISTERS));
+             for(c=0; c<deviceExtension->NumberChannels; c++) {
+-                ULONG unit01 = (c & 1);
++                //ULONG unit01 = (c & 1);
+                 ULONG unit10 = (c & 2);
+                 chan = &deviceExtension->chan[c];
+@@ -987,7 +987,7 @@\r
+     IN ULONG  slotNumber
+     )
+ {
+-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
++    //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+     PCI_COMMON_CONFIG     pciData;
+     ULONG                 funcNumber;
+     ULONG                 busDataRead;
+@@ -1039,7 +1039,7 @@\r
+     IN ULONG  c
+     )
+ {
+-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
++    //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+     PCI_COMMON_CONFIG     pciData;
+     ULONG                 funcNumber;
+     ULONG                 busDataRead;
+@@ -1174,7 +1174,7 @@\r
+     ULONG slotNumber = deviceExtension->slotNumber;
+     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
+-    ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
++    //ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
+     PHW_CHANNEL chan;
+     ULONG  c; // logical channel (for Compatible Mode controllers)
+     UCHAR tmp8;
+@@ -1332,7 +1332,9 @@\r
+     ULONG slotNumber = deviceExtension->slotNumber;
+     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
+     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
++#ifdef _DEBUG
+     ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
++#endif
+     ULONG RevID    =  deviceExtension->RevID;
+ //    ULONG i;
+ //    BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
+Index: id_probe.cpp\r
+===================================================================\r
+--- id_probe.cpp       (revision 38425)\r
++++ id_probe.cpp       (working copy)\r
+@@ -76,7 +76,6 @@\r
+ VOID
+ AtapiDoNothing(VOID)
+ {
+-    ULONG i = 0;
+     return;
+ } // end AtapiDoNothing()
+@@ -504,8 +503,8 @@\r
+ /*                        if(known) {
+                             RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION));
+                         } else {*/
+-                        sprintf((PCHAR)vendorStrPtr, "%4.4x", VendorID);
+-                        sprintf((PCHAR)deviceStrPtr, "%4.4x", DeviceID);
++                        sprintf((PCHAR)vendorStrPtr, "%4.4x", (UINT32)VendorID);
++                        sprintf((PCHAR)deviceStrPtr, "%4.4x", (UINT32)DeviceID);
+                         RtlCopyMemory(&(newBMListPtr->VendorIdStr), (PCHAR)vendorStrPtr, 4);
+                         RtlCopyMemory(&(newBMListPtr->DeviceIdStr), (PCHAR)deviceStrPtr, 4);
+@@ -874,7 +873,11 @@\r
+     BOOLEAN found = FALSE;
+     BOOLEAN MasterDev;
+     BOOLEAN simplexOnly = FALSE;
++#ifndef UNIATA_CORE
++#ifdef UNIATA_INIT_ON_PROBE
+     BOOLEAN skip_find_dev = FALSE;
++#endif
++#endif
+     BOOLEAN AltInit = FALSE;
+     SCSI_PHYSICAL_ADDRESS IoBasePort1;
+@@ -1712,7 +1715,7 @@\r
+     )
+ {
+     PHW_DEVICE_EXTENSION  deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+-    PHW_CHANNEL           chan = NULL;
++    //PHW_CHANNEL           chan = NULL;
+     // this buffer must be global for UNIATA_CORE build
+     PCI_COMMON_CONFIG     pciData;
+@@ -1743,8 +1746,8 @@\r
+     BOOLEAN found = FALSE;
+     BOOLEAN MasterDev;
+     BOOLEAN simplexOnly = FALSE;
+-    BOOLEAN skip_find_dev = FALSE;
+-    BOOLEAN AltInit = FALSE;
++    //BOOLEAN skip_find_dev = FALSE;
++    //BOOLEAN AltInit = FALSE;
+     PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL;
+@@ -1797,7 +1800,7 @@\r
+                                      &pciData,
+                                      PCI_COMMON_HDR_LENGTH);
+-    if (busDataRead < PCI_COMMON_HDR_LENGTH) {
++    if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
+         KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
+         goto exit_error;
+     }
+@@ -2207,7 +2210,7 @@\r
+     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+     PHW_CHANNEL          chan;
+     PULONG               adapterCount    = (PULONG)Context;
+-    PUCHAR               ioSpace;
++    PUCHAR               ioSpace = NULL;
+     ULONG                i;
+     ULONG                irq=0;
+     ULONG                portBase;
+@@ -2217,7 +2220,7 @@\r
+     BOOLEAN              preConfig = FALSE;
+     //
+     PIDE_REGISTERS_1 BaseIoAddress1;
+-    PIDE_REGISTERS_2 BaseIoAddress2;
++    PIDE_REGISTERS_2 BaseIoAddress2 = NULL;
+     // The following table specifies the ports to be checked when searching for
+     // an IDE controller.  A zero entry terminates the search.
+Index: id_sata.cpp\r
+===================================================================\r
+--- id_sata.cpp        (revision 38425)\r
++++ id_sata.cpp        (working copy)\r
+@@ -7,7 +7,7 @@\r
+     )
+ {
+     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+-    ULONG Channel = deviceExtension->Channel + lChannel;
++    //ULONG Channel = deviceExtension->Channel + lChannel;
+     PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
+     SATA_SSTATUS_REG SStatus;
+     ULONG i;
+@@ -126,7 +126,7 @@\r
+ {
+     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+     PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
+-    ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
++    //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
+     SATA_SSTATUS_REG SStatus;
+     SATA_SERROR_REG  SError;
+Index: ntddk_ex.h\r
+===================================================================\r
+--- ntddk_ex.h (revision 38425)\r
++++ ntddk_ex.h (working copy)\r
+@@ -6,7 +6,8 @@\r
+ #define ASSERT
+ #else
+ #undef ASSERT
+-#define ASSERT //(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
++//#define ASSERT //(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
++#define ASSERT(x) // FIXME: WTF!
+ #endif //__REACTOS__
index 7485c13..9f836f5 100644 (file)
@@ -2752,7 +2752,7 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
 {
     PIO_STACK_LOCATION Stack;
     PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
-    NTSTATUS Status = STATUS_SUCCESS;;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     DPRINT("ScsiPortDeviceControl()\n");
 
index 9bcefd4..222ca24 100644 (file)
@@ -300,7 +300,7 @@ elem_list_get_total_count(PEHCI_ELEM_LIST plist)
 {
     if (plist == NULL)
         return 0;
-    return plist->total_count;;
+    return plist->total_count;
 }
 
 LONG
index 370216b..d76b2da 100644 (file)
@@ -186,7 +186,7 @@ rh_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
 
         pif->endp_count = 1;
         pendp = &pif->endp[0];
-        pif->pusb_config = pconfig;;
+        pif->pusb_config = pconfig;
         pif->pusb_if_desc = pif_desc;
 
         pif->if_ext_size = 0;
index b548ff2..1e5f9eb 100644 (file)
@@ -2783,7 +2783,7 @@ uhci_insert_urb_schedule(PUHCI_DEV uhci, PURB urb)
             uhci->fsbr_cnt++;
             if (uhci->fsbr_cnt == 1)
             {
-                uhci->skel_term_qh->link = uhci->skel_hs_control_qh->phy_addr;;
+                uhci->skel_term_qh->link = uhci->skel_hs_control_qh->phy_addr;
             }
 
             return TRUE;
index d1c9392..1a05c15 100644 (file)
@@ -35,7 +35,7 @@ IntInt10AllocateBuffer(
 {
    PVOID MemoryAddress;
    NTSTATUS Status;
-   PKPROCESS CallingProcess;
+   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
    KAPC_STATE ApcState;
 
    TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");
@@ -82,7 +82,7 @@ IntInt10FreeBuffer(
 {
    PVOID MemoryAddress = (PVOID)((Seg << 4) | Off);
    NTSTATUS Status;
-   PKPROCESS CallingProcess;
+   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
    KAPC_STATE ApcState;
 
    TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n");
@@ -105,7 +105,7 @@ IntInt10ReadMemory(
    OUT PVOID Buffer,
    IN ULONG Length)
 {
-   PKPROCESS CallingProcess;
+   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
    KAPC_STATE ApcState;
 
    TRACE_(VIDEOPRT, "IntInt10ReadMemory\n");
@@ -129,7 +129,7 @@ IntInt10WriteMemory(
    IN PVOID Buffer,
    IN ULONG Length)
 {
-   PKPROCESS CallingProcess;
+   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
    KAPC_STATE ApcState;
 
    TRACE_(VIDEOPRT, "IntInt10WriteMemory\n");
@@ -153,7 +153,7 @@ IntInt10CallBios(
 {
     CONTEXT BiosContext;
     NTSTATUS Status;
-    PKPROCESS CallingProcess;
+    PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
     KAPC_STATE ApcState;
 
     /* Attach to CSRSS */
@@ -201,51 +201,51 @@ IntInt10CallBios(
 
 VP_STATUS NTAPI
 VideoPortInt10(
-   IN PVOID HwDeviceExtension,
-   IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
+    IN PVOID HwDeviceExtension,
+    IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
 {
 #if defined(_M_IX86)
-   KV86M_REGISTERS Regs;
-   NTSTATUS Status;
-   PKPROCESS CallingProcess;
-   KAPC_STATE ApcState;
+    CONTEXT BiosContext;
+    NTSTATUS Status;
+    PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+    KAPC_STATE ApcState;
 
-   TRACE_(VIDEOPRT, "VideoPortInt10\n");
+    if (!CsrssInitialized)
+    {
+       return ERROR_INVALID_PARAMETER;
+    }
 
-   if (!CsrssInitialized)
-   {
-      return ERROR_INVALID_PARAMETER;
-   }
+    /* Attach to CSRSS */
+    IntAttachToCSRSS(&CallingProcess, &ApcState);
 
-   IntAttachToCSRSS(&CallingProcess, &ApcState);
+    /* Clear the context */
+    RtlZeroMemory(&BiosContext, sizeof(CONTEXT));
+
+    /* Fill out the bios arguments */
+    BiosContext.Eax = BiosArguments->Eax;
+    BiosContext.Ebx = BiosArguments->Ebx;
+    BiosContext.Ecx = BiosArguments->Ecx;
+    BiosContext.Edx = BiosArguments->Edx;
+    BiosContext.Esi = BiosArguments->Esi;
+    BiosContext.Edi = BiosArguments->Edi;
+    BiosContext.Ebp = BiosArguments->Ebp;
 
-   memset(&Regs, 0, sizeof(Regs));
-   INFO_(VIDEOPRT, "- Input register Eax: %x\n", BiosArguments->Eax);
-   Regs.Eax = BiosArguments->Eax;
-   INFO_(VIDEOPRT, "- Input register Ebx: %x\n", BiosArguments->Ebx);
-   Regs.Ebx = BiosArguments->Ebx;
-   INFO_(VIDEOPRT, "- Input register Ecx: %x\n", BiosArguments->Ecx);
-   Regs.Ecx = BiosArguments->Ecx;
-   INFO_(VIDEOPRT, "- Input register Edx: %x\n", BiosArguments->Edx);
-   Regs.Edx = BiosArguments->Edx;
-   INFO_(VIDEOPRT, "- Input register Esi: %x\n", BiosArguments->Esi);
-   Regs.Esi = BiosArguments->Esi;
-   INFO_(VIDEOPRT, "- Input register Edi: %x\n", BiosArguments->Edi);
-   Regs.Edi = BiosArguments->Edi;
-   INFO_(VIDEOPRT, "- Input register Ebp: %x\n", BiosArguments->Ebp);
-   Regs.Ebp = BiosArguments->Ebp;
-   Status = Ke386CallBios(0x10, (PCONTEXT)&Regs);
-   BiosArguments->Eax = Regs.Eax;
-   BiosArguments->Ebx = Regs.Ebx;
-   BiosArguments->Ecx = Regs.Ecx;
-   BiosArguments->Edx = Regs.Edx;
-   BiosArguments->Esi = Regs.Esi;
-   BiosArguments->Edi = Regs.Edi;
-   BiosArguments->Ebp = Regs.Ebp;
+    /* Do the ROM BIOS call */
+    Status = Ke386CallBios(0x10, &BiosContext);
 
-   IntDetachFromCSRSS(&CallingProcess, &ApcState);
+    /* Return the arguments */
+    BiosArguments->Eax = BiosContext.Eax;
+    BiosArguments->Ebx = BiosContext.Ebx;
+    BiosArguments->Ecx = BiosContext.Ecx;
+    BiosArguments->Edx = BiosContext.Edx;
+    BiosArguments->Esi = BiosContext.Esi;
+    BiosArguments->Edi = BiosContext.Edi;
+    BiosArguments->Ebp = BiosContext.Ebp;
 
-   return Status;
+    /* Detach from CSRSS */
+    IntDetachFromCSRSS(&CallingProcess, &ApcState);
+
+    return Status;
 #else
     /* Not implemented for anything else than X86*/
     DPRINT1("Int10 not available on non-x86!\n");
index c6a6c0f..b3a2f28 100644 (file)
@@ -401,6 +401,7 @@ VideoPortGetAccessRanges(
    IN PULONG Slot)
 {
    PCI_SLOT_NUMBER PciSlotNumber;
+   ULONG DeviceNumber;
    ULONG FunctionNumber;
    PCI_COMMON_CONFIG Config;
    PCM_RESOURCE_LIST AllocatedResources;
@@ -413,6 +414,7 @@ VideoPortGetAccessRanges(
    USHORT DeviceIdToFind;
    ULONG SlotIdToFind;
    ULONG ReturnedLength;
+   BOOLEAN DeviceAndVendorFound = FALSE;
 
    TRACE_(VIDEOPRT, "VideoPortGetAccessRanges\n");
 
@@ -453,36 +455,40 @@ VideoPortGetAccessRanges(
             /*
              * Search for the device id and vendor id on this bus.
              */
-
-            for (FunctionNumber = 0; FunctionNumber < 8; FunctionNumber++)
+            for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
             {
-               INFO_(VIDEOPRT, "- Function number: %d\n", FunctionNumber);
-               PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
-               ReturnedLength = HalGetBusData(
-                  PCIConfiguration,
-                  DeviceExtension->SystemIoBusNumber,
-                  PciSlotNumber.u.AsULONG,
-                  &Config,
-                  sizeof(PCI_COMMON_CONFIG));
-               INFO_(VIDEOPRT, "- Length of data: %x\n", ReturnedLength);
-               if (ReturnedLength == sizeof(PCI_COMMON_CONFIG))
+               PciSlotNumber.u.bits.DeviceNumber = DeviceNumber;
+               for (FunctionNumber = 0; FunctionNumber < 8; FunctionNumber++)
                {
-                  INFO_(VIDEOPRT, "- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
-                         "DeviceId 0x%04x\n",
-                         PciSlotNumber.u.AsULONG,
-                         PciSlotNumber.u.bits.DeviceNumber,
-                         PciSlotNumber.u.bits.FunctionNumber,
-                         Config.VendorID,
-                         Config.DeviceID);
-
-                  if ((VendorIdToFind == 0 || Config.VendorID == VendorIdToFind) &&
-                      (DeviceIdToFind == 0 || Config.DeviceID == DeviceIdToFind))
+                  INFO_(VIDEOPRT, "- Function number: %d\n", FunctionNumber);
+                  PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
+                  ReturnedLength = HalGetBusData(
+                     PCIConfiguration,
+                     DeviceExtension->SystemIoBusNumber,
+                     PciSlotNumber.u.AsULONG,
+                     &Config,
+                     sizeof(PCI_COMMON_CONFIG));
+                  INFO_(VIDEOPRT, "- Length of data: %x\n", ReturnedLength);
+                  if (ReturnedLength == sizeof(PCI_COMMON_CONFIG))
                   {
-                     break;
+                     INFO_(VIDEOPRT, "- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
+                            "DeviceId 0x%04x\n",
+                            PciSlotNumber.u.AsULONG,
+                            PciSlotNumber.u.bits.DeviceNumber,
+                            PciSlotNumber.u.bits.FunctionNumber,
+                            Config.VendorID,
+                            Config.DeviceID);
+
+                     if ((VendorIdToFind == 0 || Config.VendorID == VendorIdToFind) &&
+                         (DeviceIdToFind == 0 || Config.DeviceID == DeviceIdToFind))
+                     {
+                        DeviceAndVendorFound = TRUE;
+                        break;
+                     }
                   }
                }
+               if (DeviceAndVendorFound) break;
             }
-
             if (FunctionNumber == 8)
             {
                WARN_(VIDEOPRT, "Didn't find device.\n");
@@ -491,7 +497,10 @@ VideoPortGetAccessRanges(
          }
 
          Status = HalAssignSlotResources(
-            NULL, NULL, NULL, NULL,
+            &DeviceExtension->RegistryPath,
+            NULL,
+            DeviceExtension->DriverObject,
+            DeviceExtension->DriverObject->DeviceObject,
             DeviceExtension->AdapterInterfaceType,
             DeviceExtension->SystemIoBusNumber,
             PciSlotNumber.u.AsULONG,
@@ -499,13 +508,13 @@ VideoPortGetAccessRanges(
 
          if (!NT_SUCCESS(Status))
          {
+            WARN_(VIDEOPRT, "HalAssignSlotResources failed with status %x.\n",Status);
             return Status;
          }
          DeviceExtension->AllocatedResources = AllocatedResources;
       }
       if (AllocatedResources == NULL)
          return ERROR_NOT_ENOUGH_MEMORY;
-
       AssignedCount = 0;
       for (FullList = AllocatedResources->List;
            FullList < AllocatedResources->List + AllocatedResources->Count;
@@ -515,7 +524,7 @@ VideoPortGetAccessRanges(
                 FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
                 1 == FullList->PartialResourceList.Version &&
                 1 == FullList->PartialResourceList.Revision);
-        for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
+         for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
               Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
               Descriptor++)
          {
index 51cb5a2..2fbce7a 100644 (file)
@@ -259,7 +259,7 @@ IDmaChannelSlave_fnWaitForTC(
 
 }
 
-static IDmaChannelSlaveVtbl vt_IDmaChannelSlaveVtbl =
+IDmaChannelSlaveVtbl vt_IDmaChannelSlaveVtbl =
 {
     /* IUnknown methods */
     IDmaChannelSlave_fnQueryInterface,
diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
new file mode 100644 (file)
index 0000000..e42eab0
--- /dev/null
@@ -0,0 +1,389 @@
+#ifndef INTERFACES_H__
+#define INTERFACES_H__
+
+DEFINE_GUID(IID_IIrpTarget,        0xB4C90A60, 0x5791, 0x11D0, 0x86, 0xF9, 0x00, 0xA0, 0xC9, 0x11, 0xB5, 0x44);
+DEFINE_GUID(IID_ISubdevice,        0xB4C90A61, 0x5791, 0x11D0, 0x86, 0xF9, 0x00, 0xA0, 0xC9, 0x11, 0xB5, 0x44);
+DEFINE_GUID(IID_IIrpTargetFactory, 0xB4C90A62, 0x5791, 0x11D0, 0x86, 0xF9, 0x00, 0xA0, 0xC9, 0x11, 0xB5, 0x44);
+
+
+/*****************************************************************************
+ * IIrpTarget
+ *****************************************************************************
+ */
+
+#define DEFINE_ABSTRACT_IRPTARGET()                        \
+    STDMETHOD_(NTSTATUS, NewIrpTarget)(THIS_               \
+        OUT struct IIrpTarget **OutTarget,                 \
+        IN WCHAR * Name,                                   \
+        IN PUNKNOWN Unknown,                               \
+        IN POOL_TYPE PoolType,                             \
+        IN PDEVICE_OBJECT * DeviceObject,                  \
+        IN PIRP Irp,                                       \
+        IN KSOBJECT_CREATE *CreateObject) PURE;            \
+                                                           \
+    STDMETHOD_(NTSTATUS, DeviceIoControl)(THIS_            \
+        IN PDEVICE_OBJECT DeviceObject,                    \
+        IN PIRP Irp)PURE;                                  \
+                                                           \
+    STDMETHOD_(NTSTATUS, Read)(THIS_                       \
+        IN PDEVICE_OBJECT DeviceObject,                    \
+        IN PIRP Irp)PURE;                                  \
+                                                           \
+    STDMETHOD_(NTSTATUS, Write)(THIS_                      \
+        IN PDEVICE_OBJECT DeviceObject,                    \
+        IN PIRP Irp)PURE;                                  \
+                                                           \
+    STDMETHOD_(NTSTATUS, Flush)(THIS_                      \
+        IN PDEVICE_OBJECT DeviceObject,                    \
+        IN PIRP Irp)PURE;                                  \
+                                                           \
+    STDMETHOD_(NTSTATUS, Close)(THIS_                      \
+        IN PDEVICE_OBJECT DeviceObject,                    \
+        IN PIRP Irp)PURE;                                  \
+                                                           \
+    STDMETHOD_(NTSTATUS, QuerySecurity)(THIS_              \
+        IN PDEVICE_OBJECT DeviceObject,                    \
+        IN PIRP Irp)PURE;                                  \
+                                                           \
+    STDMETHOD_(NTSTATUS, SetSecurity)(THIS_                \
+        IN PDEVICE_OBJECT DeviceObject,                    \
+        IN PIRP Irp)PURE;                                  \
+                                                           \
+    STDMETHOD_(NTSTATUS, FastDeviceIoControl)(THIS_        \
+        IN PFILE_OBJECT FileObject,                        \
+        IN BOOLEAN Wait,                                   \
+        IN PVOID InputBuffer,                              \
+        IN ULONG InputBufferLength,                        \
+        OUT PVOID OutputBuffer,                            \
+        IN ULONG OutputBufferLength,                       \
+        IN ULONG IoControlCode,                            \
+        OUT PIO_STATUS_BLOCK StatusBlock,                  \
+        IN PDEVICE_OBJECT DeviceObject)PURE;               \
+                                                           \
+    STDMETHOD_(NTSTATUS, FastRead)(THIS_                   \
+        IN PFILE_OBJECT FileObject,                        \
+        IN PLARGE_INTEGER FileOffset,                      \
+        IN ULONG Length,                                   \
+        IN BOOLEAN Wait,                                   \
+        IN ULONG LockKey,                                  \
+        IN PVOID Buffer,                                   \
+        OUT PIO_STATUS_BLOCK StatusBlock,                  \
+        IN PDEVICE_OBJECT DeviceObject)PURE;               \
+                                                           \
+    STDMETHOD_(NTSTATUS, FastWrite)(THIS_                  \
+        IN PFILE_OBJECT FileObject,                        \
+        IN PLARGE_INTEGER FileOffset,                      \
+        IN ULONG Length,                                   \
+        IN BOOLEAN Wait,                                   \
+        IN ULONG LockKey,                                  \
+        IN PVOID Buffer,                                   \
+        OUT PIO_STATUS_BLOCK StatusBlock,                  \
+        IN PDEVICE_OBJECT DeviceObject)PURE;
+
+#undef INTERFACE
+#define INTERFACE IIrpTarget
+
+DECLARE_INTERFACE_(IIrpTarget, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPTARGET()
+};
+
+/*****************************************************************************
+ * ISubdevice
+ *****************************************************************************
+ */
+
+struct IIrpTargetFactory;
+struct SUBDEVICE_DESCRIPTOR;
+
+
+#undef INTERFACE
+#define INTERFACE ISubdevice
+
+DECLARE_INTERFACE_(ISubdevice, IUnknown)
+{
+    STDMETHOD_(NTSTATUS, QueryInterface)(THIS_
+        REFIID InterfaceId,
+        PVOID* Interface
+        ) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+
+    STDMETHOD_(NTSTATUS, NewIrpTarget)(THIS_
+        OUT IIrpTarget **OutTarget,
+        IN WCHAR * Name,
+        IN PUNKNOWN Unknown,
+        IN POOL_TYPE PoolType,
+        IN PDEVICE_OBJECT * DeviceObject,
+        IN PIRP Irp, 
+        IN KSOBJECT_CREATE *CreateObject) PURE;
+
+    STDMETHOD_(NTSTATUS, ReleaseChildren)(THIS) PURE;
+
+    STDMETHOD_(NTSTATUS, GetDescriptor)(THIS_
+        IN struct SUBDEVICE_DESCRIPTOR **) PURE;
+
+    STDMETHOD_(NTSTATUS, DataRangeIntersection)(THIS_
+        IN  ULONG PinId,
+        IN  PKSDATARANGE DataRange,
+        IN  PKSDATARANGE MatchingDataRange,
+        IN  ULONG OutputBufferLength,
+        OUT PVOID ResultantFormat OPTIONAL,
+        OUT PULONG ResultantFormatLength) PURE;
+
+    STDMETHOD_(NTSTATUS, PowerChangeNotify)(THIS_
+        IN POWER_STATE PowerState) PURE;
+
+    STDMETHOD_(NTSTATUS, PinCount)(THIS_
+        IN ULONG  PinId,
+        IN OUT PULONG  FilterNecessary,
+        IN OUT PULONG  FilterCurrent,
+        IN OUT PULONG  FilterPossible,
+        IN OUT PULONG  GlobalCurrent,
+        IN OUT PULONG  GlobalPossible)PURE;
+
+};
+
+/*****************************************************************************
+ * IKsWorkSink
+ *****************************************************************************
+ */
+#undef INTERFACE
+#define INTERFACE IKsWorkSink
+
+DECLARE_INTERFACE_(IKsWorkSink, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    STDMETHOD_(NTSTATUS, Work)(THIS);
+};
+
+/*****************************************************************************
+ * IIrpStreamNotify
+ *****************************************************************************
+ */
+#undef INTERFACE
+#define INTERFACE IIrpStreamNotify
+
+struct IRPSTREAMPOSITION;
+
+DECLARE_INTERFACE_(IIrpStreamNotify, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    STDMETHOD_(NTSTATUS, IrpSubmitted)(THIS_
+        IN PIRP Irp,
+        IN BOOLEAN WAIT)PURE;
+
+    STDMETHOD_(NTSTATUS, GetPosition)(THIS_
+        OUT struct IRPSTREAMPOSITION * Position)PURE;
+};
+
+/*****************************************************************************
+ * IKsShellTransport
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IKsShellTransport
+
+#define DEFINE_ABSTRACT_IKSSHELLTRANSPORT()                     \
+    STDMETHOD_(NTSTATUS, TransferKsIrp)(THIS_                   \
+        IN PIRP Irp,                                            \
+        OUT IKsShellTransport ** Transport) PURE;               \
+                                                                \
+    STDMETHOD_(NTSTATUS, Connect)(THIS_                         \
+        IN IKsShellTransport * StartTransport,                  \
+        OUT IKsShellTransport ** EndTransport,                  \
+        IN KSPIN_DATAFLOW DataFlow)PURE;                        \
+                                                                \
+    STDMETHOD_(NTSTATUS, SetDeviceState)(THIS_                  \
+        IN KSSTATE State1,                                      \
+        IN KSSTATE State2,                                      \
+        OUT IKsShellTransport ** EndTransport)PURE;             \
+                                                                \
+    STDMETHOD_(NTSTATUS, SetResetState)(THIS_                   \
+        IN KSRESET State1,                                      \
+        OUT IKsShellTransport ** EndTransport)PURE;
+
+
+DECLARE_INTERFACE_(IKsShellTransport, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IKSSHELLTRANSPORT()
+};
+
+/*****************************************************************************
+ * IIrpStream
+ *****************************************************************************
+ */
+struct IRPSTREAM_POSITION;
+struct IRPSTREAMPACKETINFO;
+
+#define DEFINE_ABSTRACT_IRPSTREAM()                             \
+    STDMETHOD_(NTSTATUS, TransferKsIrp)(THIS_                   \
+        IN PIRP Irp,                                            \
+        OUT IKsShellTransport ** Transport) PURE;               \
+                                                                \
+    STDMETHOD_(NTSTATUS, Connect)(THIS_                         \
+        IN IKsShellTransport * StartTransport,                  \
+        OUT IKsShellTransport ** EndTransport,                  \
+        IN KSPIN_DATAFLOW DataFlow)PURE;                        \
+                                                                \
+    STDMETHOD_(NTSTATUS, SetDeviceState)(THIS_                  \
+        IN KSSTATE State1,                                      \
+        IN KSSTATE State2,                                      \
+        OUT IKsShellTransport ** EndTransport)PURE;             \
+                                                                \
+    STDMETHOD_(NTSTATUS, SetResetState)(THIS_                   \
+        IN KSRESET State1,                                      \
+        OUT IKsShellTransport ** EndTransport)PURE;             \
+                                                                \
+    STDMETHOD_(NTSTATUS, GetPosition)(THIS_                     \
+        IN OUT struct IRPSTREAM_POSITION * Position) PURE;      \
+                                                                \
+    STDMETHOD_(NTSTATUS, Init)(THIS_                            \
+        IN BOOLEAN Wait,                                        \
+        KSPIN_CONNECT *ConnectDetails,                          \
+        PDEVICE_OBJECT DeviceObject,                            \
+        PDMA_ADAPTER DmaAdapter) PURE;                          \
+                                                                \
+    STDMETHOD_(NTSTATUS, CancelAllIrps)(THIS_                   \
+        ULONG Wait)PURE;                                        \
+                                                                \
+    STDMETHOD_(VOID, TerminatePacket)(THIS);                    \
+                                                                \
+    STDMETHOD_(NTSTATUS, ChangeOptionsFlag)(THIS_               \
+       ULONG Unknown1,                                          \
+       ULONG Unknown2,                                          \
+       ULONG Unknown3,                                          \
+       ULONG Unknown4)PURE;                                     \
+                                                                \
+    STDMETHOD_(NTSTATUS, GetPacketInfo)(THIS_                   \
+       struct IRPSTREAMPACKETINFO * Info1,                      \
+       struct IRPSTREAMPACKETINFO * Info2)PURE;                 \
+                                                                \
+    STDMETHOD_(NTSTATUS, SetPacketOffsets)(THIS_                \
+       ULONG Unknown1,                                          \
+       ULONG Unknown2)PURE;                                     \
+                                                                \
+    STDMETHOD_(NTSTATUS, RegisterNotifySink)(THIS_              \
+       IN IIrpStreamNotify * NotifyStream)PURE;
+
+
+
+#undef INTERFACE
+#define INTERFACE IIrpStream
+
+DECLARE_INTERFACE_(IIrpStream, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPSTREAM()
+};
+
+
+/*****************************************************************************
+ * IIrpStreamPhysical
+ *****************************************************************************
+ */
+#undef INTERFACE
+#define INTERFACE IIrpStreamPhysical
+
+DECLARE_INTERFACE_(IIrpStreamPhysical, IIrpStream)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPSTREAM()
+
+    STDMETHOD_(NTSTATUS, GetMapping)(THIS_
+       IN PVOID Tag,
+       OUT PPHYSICAL_ADDRESS PhysicalAddress,
+       OUT PVOID * VirtualAddress,
+       OUT PULONG ByteCount,
+       OUT PULONG Flags)PURE;
+
+};
+
+/*****************************************************************************
+ * IIrpStreamVirtual
+ *****************************************************************************
+ */
+#undef INTERFACE
+#define INTERFACE IIrpStreamVirtual
+
+DECLARE_INTERFACE_(IIrpStreamVirtual, IIrpStream)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPSTREAM()
+
+    STDMETHOD_(NTSTATUS, GetLockedRegion)(THIS_
+       OUT PULONG OutSize,
+       OUT PVOID * OutBuffer)PURE;
+
+    STDMETHOD_(NTSTATUS, Copy)(THIS_
+       IN BOOLEAN Wait,
+       OUT ULONG Size,
+       IN PULONG Buffer,
+       OUT PVOID Result)PURE;
+
+    STDMETHOD_(NTSTATUS, Complete)(THIS_
+       IN ULONG Unknown1,
+       IN PULONG Data)PURE;
+
+    STDMETHOD_(ULONG, GetIrpStreamPositionLock)(THIS);
+};
+
+
+/*****************************************************************************
+ * IPortFilterWaveCyclic
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IPortFilterWaveCyclic
+
+DECLARE_INTERFACE_(IPortFilterWaveCyclic, IIrpTarget)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPTARGET()
+
+    STDMETHOD_(NTSTATUS, Init)(THIS_
+        IN PPORTWAVECYCLIC Port)PURE;
+};
+
+typedef IPortFilterWaveCyclic *PPORTFILTERWAVECYCLIC;
+
+/*****************************************************************************
+ * IPortPinWaveCyclic
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IPortPinWaveCyclic
+
+DECLARE_INTERFACE_(IPortPinWaveCyclic, IIrpTarget)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPTARGET()
+
+    STDMETHOD_(NTSTATUS, Init)(THIS_
+        IN PPORTWAVECYCLIC Port,
+        IN PPORTFILTERWAVECYCLIC Filter,
+        IN KSPIN_CONNECT * ConnectDetails,
+        IN KSPIN_DESCRIPTOR * PinDescriptor) PURE;
+
+    STDMETHOD_(ULONG, GetCompletedPosition)(THIS);
+    STDMETHOD_(ULONG, GetCycleCount)(THIS);
+    STDMETHOD_(ULONG, GetDeviceBufferSize)(THIS);
+    STDMETHOD_(PVOID, GetIrpStream)(THIS);
+    STDMETHOD_(PMINIPORT, GetMiniport)(THIS);
+};
+
+#endif
index 24c458d..c19d8d7 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
-<module name="portcls" type="kernelmodedriver" installbase="system32/drivers" installname="portcls.sys" allowwarnings="true">
+<module name="portcls" type="kernelmodedriver" installbase="system32/drivers" installname="portcls.sys">
        <importlibrary definition="portcls.spec" />
        <define name="_NTDDK_" />
        <define name="PC_NO_IMPORTS" />
index e664cf9..62eda18 100644 (file)
@@ -1487,7 +1487,7 @@ HalpCopyBufferMap(
        */
       /* FIXME: The correct bug check code isn't defined. */
       /* KEBUGCHECKEX(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0); */
-      ASSERT(FALSE);;
+      ASSERT(FALSE);
    }
 
    CurrentAddress = (ULONG_PTR)VirtualAddress +
index a338339..71b9a0b 100644 (file)
@@ -250,7 +250,7 @@ VOID APICDump(VOID)
 {
   ULONG v, ver, maxlvt;
   ULONG r1, r2, w1, w2;
-  ULONG CPU = ThisCPU();;
+  ULONG CPU = ThisCPU();
 
 
   r1 = lastregr[CPU];
@@ -774,12 +774,12 @@ VOID APICSetupLVTT(ULONG ClockTicks)
    tmp = GET_APIC_VERSION(APICRead(APIC_VER));
    if (!APIC_INTEGRATED(tmp))
    {
-      tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+      tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
    }
    else
    {
       /* Periodic timer */
-      tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+      tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
    }
    APICWrite(APIC_LVTT, tmp);
 
index 8ba3df7..6a0dabd 100644 (file)
@@ -36,4 +36,17 @@ typedef unsigned int dev_t;
 # endif
 #endif
 
+// HACK HACK HACK
+#ifndef _PID_T_
+#define        _PID_T_
+#ifndef _WIN64
+typedef int    _pid_t;
+#else
+typedef __int64        _pid_t;
+#endif
+#ifndef        NO_OLDNAMES
+typedef _pid_t pid_t;
+#endif
+#endif /* Not _PID_T_ */
+
 #endif /* !_INC_TYPES */
index 6d353ad..33a6500 100644 (file)
@@ -11,7 +11,7 @@
 
 // FIXME: Should we include these here?
 #include <stdarg.h>
-#include <string.h> 
+#include <string.h>
 
 
 typedef unsigned long POINTER_64; // FIXME! HACK!!!
@@ -226,6 +226,7 @@ typedef unsigned long POINTER_64; // FIXME! HACK!!!
 #endif
 #endif
 
+#ifndef DECLSPEC_NOINLINE
 #if (_MSC_VER >= 1300)
 #define DECLSPEC_NOINLINE  __declspec(noinline)
 #elif defined(__GNUC__)
@@ -233,6 +234,7 @@ typedef unsigned long POINTER_64; // FIXME! HACK!!!
 #else
 #define DECLSPEC_NOINLINE
 #endif
+#endif
 
 #if !defined(_M_CEE_PURE)
 #define NTAPI_INLINE    NTAPI
@@ -256,7 +258,7 @@ typedef unsigned long POINTER_64; // FIXME! HACK!!!
 
 
 //
-// Use to silence unused variable warnings when it is intentional 
+// Use to silence unused variable warnings when it is intentional
 //
 #define UNREFERENCED_PARAMETER(P) {(P)=(P);}
 #define UNREFERENCED_LOCAL_VARIABLE(L) {(L)=(L);}
@@ -291,7 +293,7 @@ typedef unsigned long POINTER_64; // FIXME! HACK!!!
 // Void Pointers
 //
 typedef void *PVOID;
-//typedef void * POINTER_64 PVOID64; 
+//typedef void * POINTER_64 PVOID64;
 typedef PVOID PVOID64; // FIXME!
 
 //
index df4275c..932dae8 100644 (file)
@@ -1544,9 +1544,50 @@ DECLARE_INTERFACE_(IAdapterPowerManagement, IUnknown)
     IPowerNotify Interface
 */
 
+#undef INTERFACE
+#define INTERFACE IPowerNotify
+
+DEFINE_GUID(IID_IPowerNotify, 0x3DD648B8L, 0x969F, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3);
+
+DECLARE_INTERFACE_(IPowerNotify, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    STDMETHOD_(void, PowerChangeNotify)(THIS_
+        IN POWER_STATE PowerState)PURE;
+};
+
+typedef IPowerNotify *PPOWERNOTIFY;
+
+#undef INTERFACE
+
 /* ===============================================================
     IPinCount Interface
 */
+#if (NTDDI_VERSION >= NTDDI_WINXP)
+
+#undef INTERFACE
+#define INTERFACE IPinCount
+
+DEFINE_GUID(IID_IPinCount, 0x5dadb7dcL, 0xa2cb, 0x4540, 0xa4, 0xa8, 0x42, 0x5e, 0xe4, 0xae, 0x90, 0x51);
+
+DECLARE_INTERFACE_(IPinCount, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    STDMETHOD_(void,PinCount)(THIS_
+        IN ULONG PinId,
+        IN OUT PULONG FilterNecessary,
+        IN OUT PULONG FilterCurrent,
+        IN OUT PULONG FilterPossible,
+        IN OUT PULONG GlobalCurrent,
+        IN OUT PULONG GlobalPossible) PURE;
+};
+typedef IPinCount *PPINCOUNT;
+
+#undef INTERFACE
+#endif
+
 
 /* ===============================================================
     IPortEvents Interface
index 99f68d0..5c7bfa4 100644 (file)
@@ -47,8 +47,8 @@
 /* Basic types
    Emulate a LLP64 memory model using a LP64 compiler */
 typedef void VOID, *PVOID;
-typedef char CHAR, *PCHAR, *PSTR;
-typedef const char CCHAR, *PCSTR, *LPCSTR;
+typedef char CHAR, CCHAR, *PCHAR, *PSTR;
+typedef const char *PCSTR, *LPCSTR;
 typedef unsigned char UCHAR, *PUCHAR, BYTE, *LPBYTE, BOOLEAN, *PBOOLEAN;
 typedef short SHORT, *PSHORT;
 typedef unsigned short USHORT, *PUSHORT, WORD, *PWORD, *LPWORD, WCHAR, *PWCHAR, *PWSTR, *LPWSTR;
diff --git a/reactos/include/psdk/cryptdlg.h b/reactos/include/psdk/cryptdlg.h
new file mode 100644 (file)
index 0000000..47bd984
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef __CRYPTDLG_H__
+#define __CRYPTDLG_H__
+
+#include <prsht.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CRYPTDLG_FLAGS_MASK         0xff000000
+#define CRYPTDLG_REVOCATION_DEFAULT 0x00000000
+#define CRYPTDLG_REVOCATION_ONLINE  0x80000000
+#define CRYPTDLG_REVOCATION_CACHE   0x40000000
+#define CRYPTDLG_REVOCATION_NONE    0x20000000
+
+#define CRYPTDLG_POLICY_MASK          0x0000ffff
+#define POLICY_IGNORE_NON_CRITICAL_BC 0x00000001
+
+#define CRYPTDLG_ACTION_MASK             0xffff0000
+#define ACTION_REVOCATION_DEFAULT_ONLINE 0x00010000
+#define ACTION_REVOCATION_DEFAULT_CACHE  0x00020000
+
+typedef BOOL (WINAPI *PFNCMFILTERPROC)(PCCERT_CONTEXT, DWORD, DWORD, DWORD);
+
+#define CERT_DISPWELL_SELECT                 1
+#define CERT_DISPWELL_TRUST_CA_CERT          2
+#define CERT_DISPWELL_TRUST_LEAF_CERT        3
+#define CERT_DISPWELL_TRUST_ADD_CA_CERT      4
+#define CERT_DISPWELL_TRUST_ADD_LEAF_CERT    5
+#define CERT_DISPWELL_DISTRUST_CA_CERT       6
+#define CERT_DISPWELL_DISTRUST_LEAF_CERT     7
+#define CERT_DISPWELL_DISTRUST_ADD_CA_CERT   8
+#define CERT_DISPWELL_DISTRUST_ADD_LEAF_CERT 9
+
+typedef UINT (WINAPI *PFNCMHOOKPROC)(HWND, UINT, WPARAM, LPARAM);
+
+#define CSS_SELECTCERT_MASK      0x00ffffff
+#define CSS_HIDE_PROPERTIES      0x00000001
+#define CSS_ENABLEHOOK           0x00000002
+#define CSS_ALLOWMULTISELECT     0x00000004
+#define CSS_SHOW_HELP            0x00000010
+#define CSS_ENABLETEMPLATE       0x00000020
+#define CSS_ENABLETEMPLATEHANDLE 0x00000040
+
+#define SELCERT_OK         IDOK
+#define SELCERT_CANCEL     IDCANCEL
+#define SELCERT_PROPERTIES 100
+#define SELCERT_FINEPRINT  101
+#define SELCERT_CERTLIST   102
+#define SELCERT_HELP       IDHELP
+#define SELCERT_ISSUED_TO  103
+#define SELCERT_VALIDITY   104
+#define SELCERT_ALGORITHM  105
+#define SELCERT_SERIAL_NUM 106
+#define SELCERT_THUMBPRINT 107
+
+typedef struct tagCSSA
+{
+    DWORD           dwSize;
+    HWND            hwndParent;
+    HINSTANCE       hInstance;
+    LPCSTR          pTemplateName;
+    DWORD           dwFlags;
+    LPCSTR          szTitle;
+    DWORD           cCertStore;
+    HCERTSTORE     *arrayCertStore;
+    LPCSTR          szPurposeOid;
+    DWORD           cCertContext;
+    PCCERT_CONTEXT *arrayCertContext;
+    DWORD           lCustData;
+    PFNCMHOOKPROC   pfnHook;
+    PFNCMFILTERPROC pfnFilter;
+    LPCSTR          szHelpFileName;
+    DWORD           dwHelpId;
+    HCRYPTPROV      hprov;
+} CERT_SELECT_STRUCT_A, *PCERT_SELECT_STRUCT_A;
+
+typedef struct tagCSSW
+{
+    DWORD           dwSize;
+    HWND            hwndParent;
+    HINSTANCE       hInstance;
+    LPCWSTR         pTemplateName;
+    DWORD           dwFlags;
+    LPCWSTR         szTitle;
+    DWORD           cCertStore;
+    HCERTSTORE     *arrayCertStore;
+    LPCSTR          szPurposeOid;
+    DWORD           cCertContext;
+    PCCERT_CONTEXT *arrayCertContext;
+    DWORD           lCustData;
+    PFNCMHOOKPROC   pfnHook;
+    PFNCMFILTERPROC pfnFilter;
+    LPCWSTR         szHelpFileName;
+    DWORD           dwHelpId;
+    HCRYPTPROV      hprov;
+} CERT_SELECT_STRUCT_W, *PCERT_SELECT_STRUCT_W;
+
+#define CERT_SELECT_STRUCT WINELIB_NAME_AW(CERT_SELECT_STRUCT_)
+
+BOOL WINAPI CertSelectCertificateA(PCERT_SELECT_STRUCT_A pCertSelectInfo);
+BOOL WINAPI CertSelectCertificateW(PCERT_SELECT_STRUCT_W pCertSelectInfo);
+#define CertSelectCertificate WINELIB_NAME_AW(CertSelectCertificate)
+
+#define CM_VIEWFLAGS_MASK       0x00ffffff
+#define CM_ENABLEHOOK           0x00000001
+#define CM_SHOW_HELP            0x00000002
+#define CM_SHOW_HELPICON        0x00000004
+#define CM_ENABLETEMPLATE       0x00000008
+#define CM_HIDE_ADVANCEPAGE     0x00000010
+#define CM_HIDE_TRUSTPAGE       0x00000020
+#define CM_NO_NAMECHANGE        0x00000040
+#define CM_NO_EDITTRUST         0x00000080
+#define CM_HIDE_DETAILPAGE      0x00000100
+#define CM_ADD_CERT_STORES      0x00000200
+#define CERTVIEW_CRYPTUI_LPARAM 0x00800000
+
+typedef struct tagCERT_VIEWPROPERTIES_STRUCT_A
+{
+    DWORD           dwSize;
+    HWND            hwndParent;
+    HINSTANCE       hInstance;
+    DWORD           dwFlags;
+    LPCSTR          szTitle;
+    PCCERT_CONTEXT  pCertContext;
+    LPSTR          *arrayPurposes;
+    DWORD           cArrayPurposes;
+    DWORD           cRootStores;
+    HCERTSTORE     *rghstoreRoots;
+    DWORD           cStores;
+    HCERTSTORE     *rghstoreCAs;
+    DWORD           cTrustStores;
+    HCERTSTORE     *rghstoreTrust;
+    HCRYPTPROV      hprov;
+    DWORD           lCustData;
+    DWORD           dwPad;
+    LPCSTR          szHelpFileName;
+    DWORD           dwHelpId;
+    DWORD           nStartPage;
+    DWORD           cArrayPropSheetPages;
+    /* FIXME: PSDK declares arrayPropSheetPages as a PROPSHEETPAGE *, which we
+     * don't allow in our own headers.  It's probably wrong, but we're not
+     * compatible.
+     */
+    PROPSHEETPAGEA *arrayPropSheetPages;
+} CERT_VIEWPROPERTIES_STRUCT_A, *PCERT_VIEWPROPERTIES_STRUCT_A;
+
+typedef struct tagCERT_VIEWPROPERTIES_STRUCT_W
+{
+    DWORD           dwSize;
+    HWND            hwndParent;
+    HINSTANCE       hInstance;
+    DWORD           dwFlags;
+    LPCWSTR         szTitle;
+    PCCERT_CONTEXT  pCertContext;
+    LPSTR          *arrayPurposes;
+    DWORD           cArrayPurposes;
+    DWORD           cRootStores;
+    HCERTSTORE     *rghstoreRoots;
+    DWORD           cStores;
+    HCERTSTORE     *rghstoreCAs;
+    DWORD           cTrustStores;
+    HCERTSTORE     *rghstoreTrust;
+    HCRYPTPROV      hprov;
+    DWORD           lCustData;
+    DWORD           dwPad;
+    LPCWSTR         szHelpFileName;
+    DWORD           dwHelpId;
+    DWORD           nStartPage;
+    DWORD           cArrayPropSheetPages;
+    /* FIXME: PSDK declares arrayPropSheetPages as a PROPSHEETPAGE *, which we
+     * don't allow in our own headers.  It's probably wrong, but we're not
+     * compatible.
+     */
+    PROPSHEETPAGEW *arrayPropSheetPages;
+} CERT_VIEWPROPERTIES_STRUCT_W, *PCERT_VIEWPROPERTIES_STRUCT_W;
+
+#define CERT_VIEWPROPERTIES_STRUCT WINELIB_NAME_AW(CERT_VIEWPROPERTIES_STRUCT_)
+#define PCERT_VIEWPROPERTIES_STRUCT \
+ WINELIB_NAME_AW(PCERT_VIEWPROPERTIES_STRUCT_)
+
+BOOL WINAPI CertViewPropertiesA(PCERT_VIEWPROPERTIES_STRUCT_A pCertViewInfo);
+BOOL WINAPI CertViewPropertiesW(PCERT_VIEWPROPERTIES_STRUCT_W pCertViewInfo);
+#define CertViewProperties WINELIB_NAME_AW(CertViewProperties)
+
+#define CERT_FILTER_OP_EXISTS     1
+#define CERT_FILTER_OP_NOT_EXISTS 2
+#define CERT_FILTER_OP_EQUALITY   3
+
+typedef struct tagCMOID
+{
+    LPCSTR szExtensionOID;
+    DWORD  dwTestOperation;
+    LPBYTE pbTestData;
+    DWORD  cbTestData;
+} CERT_FILTER_EXTENSION_MATCH;
+
+#define CERT_FILTER_INCLUDE_V1_CERTS  0x0001
+#define CERT_FILTER_VALID_TIME_RANGE  0x0002
+#define CERT_FILTER_VALID_SIGNATURE   0x0004
+#define CERT_FILTER_LEAF_CERTS_ONLY   0x0008
+#define CERT_FILTER_ISSUER_CERTS_ONLY 0x0010
+#define CERT_FILTER_KEY_EXISTS        0x0020
+
+typedef struct tagCMFLTR
+{
+    DWORD                        dwSize;
+    DWORD                        cExtensionChecks;
+    CERT_FILTER_EXTENSION_MATCH *arrayExtensionChecks;
+    DWORD                        dwCheckingFlags;
+} CERT_FILTER_DATA;
+
+DWORD WINAPI GetFriendlyNameOfCertA(PCCERT_CONTEXT pccert, LPSTR pchBuffer,
+ DWORD cchBuffer);
+DWORD WINAPI GetFriendlyNameOfCertW(PCCERT_CONTEXT pccert, LPWSTR pchBuffer,
+ DWORD cchBuffer);
+#define GetFriendlyNameOfCert WINELIB_NAME_AW(GetFriendlyNameOfCert)
+
+#define CERT_CERTIFICATE_ACTION_VERIFY \
+ { 0x7801ebd0, 0xcf4b, 0x11d0, { 0x85,0x1f,0x00,0x60,0x97,0x93,0x87,0xea }}
+#define szCERT_CERTIFICATE_ACTION_VERIFY \
+ "{7801ebd0-cf4b-11d0-851f-0060979387ea}"
+
+typedef HRESULT (WINAPI *PFNTRUSTHELPER)(PCCERT_CONTEXT, DWORD, BOOL, LPBYTE);
+
+#define CERT_VALIDITY_MASK_VALIDITY              0x0000ffff
+#define CERT_VALIDITY_BEFORE_START               0x00000001
+#define CERT_VALIDITY_AFTER_END                  0x00000002
+#define CERT_VALIDITY_SIGNATURE_FAILS            0x00000004
+#define CERT_VALIDITY_CERTIFICATE_REVOKED        0x00000008
+#define CERT_VALIDITY_KEY_USAGE_EXT_FAILURE      0x00000010
+#define CERT_VALIDITY_EXTENDED_USAGE_FAILURE     0x00000020
+#define CERT_VALIDITY_NAME_CONSTRAINTS_FAILURE   0x00000040
+#define CERT_VALIDITY_UNKNOWN_CRITICAL_EXTENSION 0x00000080
+#define CERT_VALIDITY_ISSUER_INVALID             0x00000100
+#define CERT_VALIDITY_OTHER_EXTENSION_FAILURE    0x00000200
+#define CERT_VALIDITY_PERIOD_NESTING_FAILURE     0x00000400
+#define CERT_VALIDITY_OTHER_ERROR                0x00000800
+
+#define CERT_VALIDITY_MASK_TRUST                 0xffff0000
+#define CERT_VALIDITY_EXPLICITLY_DISTRUSTED      0x01000000
+#define CERT_VALIDITY_ISSUER_DISTRUST            0x02000000
+#define CERT_VALIDITY_NO_ISSUER_CERT_FOUND       0x10000000
+#define CERT_VALIDITY_NO_CRL_FOUND               0x20000000
+#define CERT_VALIDITY_CRL_OUT_OF_DATE            0x40000000
+#define CERT_VALIDITY_NO_TRUST_DATA              0x80000000
+
+#define CERT_TRUST_MASK                0x00ffffff
+#define CERT_TRUST_DO_FULL_SEARCH      0x00000001
+#define CERT_TRUST_PERMIT_MISSING_CRLS 0x00000002
+#define CERT_TRUST_DO_FULL_TRUST       0x00000005
+#define CERT_TRUST_ADD_CERT_STORES     CM_ADD_CERT_STORES
+
+typedef struct _CERT_VERIFY_CERTIFICATE_TRUST
+{
+    DWORD            cbSize;
+    PCCERT_CONTEXT   pccert;
+    DWORD            dwFlags;
+    DWORD            dwIgnoreErr;
+    DWORD           *pdwErrors;
+    LPSTR            pszUsageOid;
+    HCRYPTPROV       hprov;
+    DWORD            cRootStores;
+    HCERTSTORE      *rghstoreRoots;
+    DWORD            cStores;
+    HCERTSTORE      *rghstoreCAs;
+    DWORD            cTrustStores;
+    HCERTSTORE      *rghstoreTrust;
+    DWORD            lCustData;
+    PFNTRUSTHELPER   pfnTrustHelper;
+    DWORD           *pcchain;
+    PCCERT_CONTEXT **prgChain;
+    DWORD          **prgdwErrors;
+    DATA_BLOB      **prgpbTrustInfo;
+} CERT_VERIFY_CERTIFICATE_TRUST, *PCERT_VERIFY_CERTIFICATE_TRUST;
+
+#define CTL_MODIFY_REQUEST_ADD_NOT_TRUSTED 1
+#define CTL_MODIFY_REQUEST_REMOVE          2
+#define CTL_MODIFY_REQUEST_ADD_TRUSTED     3
+
+typedef struct _CTL_MODIFY_REQUEST
+{
+    PCCERT_CONTEXT pccert;
+    DWORD          dwOperation;
+    DWORD          dwError;
+} CTL_MODIFY_REQUEST, *PCTL_MODIFY_REQUEST;
+
+HRESULT WINAPI CertModifyCertificatesToTrust(int cCertStore,
+ PCTL_MODIFY_REQUEST rgCerts, LPCSTR szPurpose, HWND hwnd,
+ HCERTSTORE hcertstoreTrust);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index c00134c..510c7d1 100644 (file)
+/*
+ * Copyright (C) 2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef __CRYPTUIAPI_H__
+#define __CRYPTUIAPI_H__
 
-typedef struct _CRYPTUI_CERT_MGR_STRUCT {
-  DWORD dwSize;
-  HWND hwndParent;
-  DWORD dwFlags;
-  LPCWSTR pwszTitle;
-  LPCSTR pszInitUsageOID;
-} CRYPTUI_CERT_MGR_STRUCT,
- *PCRYPTUI_CERT_MGR_STRUCT;
+#include <wintrust.h>
+#include <wincrypt.h>
+#include <prsht.h>
 
-typedef const CRYPTUI_CERT_MGR_STRUCT *PCCRYPTUI_CERT_MGR_STRUCT;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <pshpack8.h>
+
+BOOL WINAPI CryptUIDlgViewContext(DWORD dwContextType, LPVOID pvContext,
+ HWND hwnd, LPCWSTR pwszTitle, DWORD dwFlags, LPVOID pvReserved);
+
+/* Values for dwDontUseColumn */
+#define CRYPTUI_SELECT_ISSUEDTO_COLUMN     0x00000001
+#define CRYPTUI_SELECT_ISSUEDBY_COLUMN     0x00000002
+#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN  0x00000004
+#define CRYPTUI_SELECT_FRIENDLYNAME_COLUMN 0x00000008
+#define CRYPTUI_SELECT_LOCATION_COLUMN     0x00000010
+#define CRYPTUI_SELECT_EXPIRATION_COLUMN   0x00000020
+
+PCCERT_CONTEXT WINAPI CryptUIDlgSelectCertificateFromStore(
+ HCERTSTORE hCertStore, HWND hwnd, LPCWSTR pwszTitle, LPCWSTR pwszDisplayString,
+ DWORD dwDontUseColumn, DWORD dwFlags, LPVOID pvReserved);
+
+/* Values for CRYPTUI_CERT_MGR_STRUCT's dwFlags */
+#define CRYPTUI_CERT_MGR_PUBLISHER_TAB   0x00000004
+#define CRYPTUI_CERT_MGR_TAB_MASK        0x0000000f
+#define CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG 0x00008000
+
+typedef struct _CRYPTUI_CERT_MGR_STRUCT
+{
+    DWORD   dwSize;
+    HWND    hwndParent;
+    DWORD   dwFlags;
+    LPCWSTR pwszTitle;
+    LPCSTR  pszInitUsageOID;
+} CRYPTUI_CERT_MGR_STRUCT, *PCRYPTUI_CERT_MGR_STRUCT;
+typedef const struct _CRYPTUI_CERT_MGR_STRUCT *PCCRYPTUI_CERT_MGR_STRUCT;
 
 BOOL WINAPI CryptUIDlgCertMgr(PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr);
+
+typedef BOOL (WINAPI *PFNCFILTERPROC)(PCCERT_CONTEXT pCertContext,
+ BOOL *pfInitialSelectedCert, void *pvCallbackData);
+
+typedef struct tagCRYPTUI_INITDIALOG_STRUCT
+{
+    LPARAM         lParam;
+    PCCERT_CONTEXT pCertContext;
+} CRYPTUI_INITDIALOG_STRUCT, *PCRYPTUI_INITDIALOG_STRUCT;
+
+/* Values for CRYPTUI_VIEWCERTIFICATE_STRUCT's dwFlags */
+#define CRYPTUI_HIDE_HIERARCHYPAGE               0x00000001
+#define CRYPTUI_HIDE_DETAILPAGE                  0x00000002
+#define CRYPTUI_DISABLE_EDITPROPERTIES           0x00000004
+#define CRYPTUI_ENABLE_EDITPROPERTIES            0x00000008
+#define CRYPTUI_DISABLE_ADDTOSTORE               0x00000010
+#define CRYPTUI_ENABLE_ADDTOSTORE                0x00000020
+#define CRYPTUI_ACCEPT_DECLINE_STYLE             0x00000040
+#define CRYPTUI_IGNORE_UNTRUSTED_ROOT            0x00000080
+#define CRYPTUI_DONT_OPEN_STORES                 0x00000100
+#define CRYPTUI_ONLY_OPEN_ROOT_STORE             0x00000200
+#define CRYPTUI_WARN_UNTRUSTED_ROOT              0x00000400
+#define CRYPTUI_ENABLE_REVOCATION_CHECKING       0x00000800
+#define CRYPTUI_WARN_REMOTE_TRUST                0x00001000
+#define CRYPTUI_DISABLE_EXPORT                   0x00002000
+#define CRYPTUI_ENABLE_REVOCATION_CHECK_END_CERT 0x00004000
+#define CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN    0x00008000
+#define CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT CRYPTUI_ENABLE_REVOCATION_CHECKING
+#define CRYPTUI_DISABLE_HTMLLINK                 0x00010000
+#define CRYPTUI_DISABLE_ISSUERSTATEMENT          0x00020000
+
+typedef struct tagCRYPTUI_VIEWCERTIFICATE_STRUCTA
+{
+    DWORD             dwSize;
+    HWND              hwndParent;
+    DWORD             dwFlags;
+    LPCSTR            szTitle;
+    PCCERT_CONTEXT    pCertContext;
+    LPCSTR           *rgszPurposes;
+    DWORD             cPurposes;
+    union {
+        CRYPT_PROVIDER_DATA const *pCryptProviderData;
+        HANDLE                     hWVTStateData;
+    } DUMMYUNIONNAME;
+    BOOL              fpCryptProviderDataTrustedUsage;
+    DWORD             idxSigner;
+    DWORD             idxCert;
+    BOOL              fCounterSigner;
+    DWORD             idxCounterSigner;
+    DWORD             cStores;
+    HCERTSTORE       *rghStores;
+    DWORD             cPropSheetPages;
+    LPCPROPSHEETPAGEA rgPropSheetPages;
+    DWORD             nStartPage;
+} CRYPTUI_VIEWCERTIFICATE_STRUCTA, *PCRYPTUI_VIEWCERTIFICATE_STRUCTA;
+typedef const CRYPTUI_VIEWCERTIFICATE_STRUCTA *PCCRYPTUI_VIEWCERTIFICATE_STRUCTA;
+
+typedef struct tagCRYPTUI_VIEWCERTIFICATE_STRUCTW
+{
+    DWORD             dwSize;
+    HWND              hwndParent;
+    DWORD             dwFlags;
+    LPCWSTR           szTitle;
+    PCCERT_CONTEXT    pCertContext;
+    LPCSTR           *rgszPurposes;
+    DWORD             cPurposes;
+    union {
+        CRYPT_PROVIDER_DATA const *pCryptProviderData;
+        HANDLE                     hWVTStateData;
+    } DUMMYUNIONNAME;
+    BOOL              fpCryptProviderDataTrustedUsage;
+    DWORD             idxSigner;
+    DWORD             idxCert;
+    BOOL              fCounterSigner;
+    DWORD             idxCounterSigner;
+    DWORD             cStores;
+    HCERTSTORE       *rghStores;
+    DWORD             cPropSheetPages;
+    LPCPROPSHEETPAGEW rgPropSheetPages;
+    DWORD             nStartPage;
+} CRYPTUI_VIEWCERTIFICATE_STRUCTW, *PCRYPTUI_VIEWCERTIFICATE_STRUCTW;
+typedef const CRYPTUI_VIEWCERTIFICATE_STRUCTW *PCCRYPTUI_VIEWCERTIFICATE_STRUCTW;
+
+#define CRYPTUI_VIEWCERTIFICATE_STRUCT   WINELIB_NAME_AW(CRYPTUI_VIEWCERTIFICATE_STRUCT)
+#define PCCRYPTUI_VIEWCERTIFICATE_STRUCT WINELIB_NAME_AW(PCCRYPTUI_VIEWCERTIFICATE_STRUCT)
+
+BOOL WINAPI CryptUIDlgViewCertificateA(
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTA pCertViewInfo, BOOL *pfPropertiesChanged);
+BOOL WINAPI CryptUIDlgViewCertificateW(
+ PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo, BOOL *pfPropertiesChanged);
+#define CryptUIDlgViewCertificate WINELIB_NAME_AW(CryptUIDlgViewCertificate)
+
+typedef struct _CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO
+{
+    DWORD   dwSize;
+    GUID   *pGuidSubject;
+    DWORD   cbBlob;
+    BYTE   *pbBlob;
+    LPCWSTR pwszDisplayName;
+} CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO, *PCRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO;
+typedef const CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO *
+ PCCRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO;
+
+typedef struct _CRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO
+{
+    DWORD          dwSize;
+    DWORD          cCertStore;
+    HCERTSTORE    *rghCertStore;
+    PFNCFILTERPROC pFilterCallback;
+    void          *pvCallbackData;
+} CRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO, *PCRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO;
+typedef const CRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO *
+ PCCRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO;
+
+typedef struct _CRYPTUI_WIZ_DIGITAL_SIGN_PVK_FILE_INFO
+{
+    DWORD  dwSize;
+    LPWSTR pwszPvkFileName;
+    LPWSTR pwszProvName;
+    DWORD  dwProvType;
+} CRYPTUI_WIZ_DIGITAL_SIGN_PVK_FILE_INFO,
+ *PCRYPTUI_WIZ_DIGITAL_SIGN_PVK_FILE_INFO;
+typedef const CRYPTUI_WIZ_DIGITAL_SIGN_PVK_FILE_INFO *
+ PCCRYPTUI_WIZ_DIGITAL_SIGN_PVK_FILE_INFO;
+
+typedef struct _CRYPTUI_WIZ_DIGITAL_SIGN_CERT_PVK_INFO
+{
+    DWORD  dwSize;
+    LPWSTR pwszSigningCertFileName;
+    DWORD  dwPvkChoice;
+    union {
+        PCCRYPTUI_WIZ_DIGITAL_SIGN_PVK_FILE_INFO pPvkFileInfo;
+        PCRYPT_KEY_PROV_INFO                    pPvkProvInfo;
+    } DUMMYUNIONNAME;
+} CRYPTUI_WIZ_DIGITAL_SIGN_CERT_PVK_INFO,
+ *PCRYPTUI_WIZ_DIGITAL_SIGN_CERT_PVK_INFO;
+typedef const CRYPTUI_WIZ_DIGITAL_SIGN_CERT_PVK_INFO *
+ PCCRYPTUI_WIZ_DIGITAL_SIGN_CERT_PVK_INFO;
+
+typedef struct _CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO
+{
+    DWORD             dwSize;
+    DWORD             dwAttrFlags;
+    LPCWSTR           pwszDescription;
+    LPCWSTR           pwszMoreInfoLocation;
+    LPCSTR            pszHashAlg;
+    LPCWSTR           pwszSigningCertDisplayString;
+    HCERTSTORE        hAdditionalCertStore;
+    PCRYPT_ATTRIBUTES psAuthenticated;
+    PCRYPT_ATTRIBUTES psUnauthenticated;
+} CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO,
+ *PCRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO;
+typedef const CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO *
+ PCCRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO;
+
+typedef struct _CRYPTUI_WIZ_DIGITAL_SIGN_INFO
+{
+    DWORD   dwSize;
+    DWORD   dwSubjectChoice;
+    union {
+        LPCWSTR                              pwszFileName;
+        PCCRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO pSignBlobInfo;
+    } DUMMYUNIONNAME1;
+    DWORD   dwSigningCertChoice;
+    union {
+        PCCERT_CONTEXT                           pSigningCertContext;
+        PCCRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO    pSigningCertStore;
+        PCCRYPTUI_WIZ_DIGITAL_SIGN_CERT_PVK_INFO pSigningCertPvkInfo;
+    } DUMMYUNIONNAME2;
+    LPCWSTR pwszTimestampURL;
+    DWORD   dwAdditionalCertChoice;
+    PCCRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO pSignExtInfo;
+} CRYPTUI_WIZ_DIGITAL_SIGN_INFO, *PCRYPTUI_WIZ_DIGITAL_SIGN_INFO;
+typedef const CRYPTUI_WIZ_DIGITAL_SIGN_INFO *PCCRYPTUI_WIZ_DIGITAL_SIGN_INFO;
+
+typedef struct _CRYPTUI_WIZ_DIGITAL_SIGN_CONTEXT
+{
+    DWORD dwSize;
+    DWORD cbBlob;
+    BYTE *pbBlob;
+} CRYPTUI_WIZ_DIGITAL_SIGN_CONTEXT, *PCRYPTUI_WIZ_DIGITAL_SIGN_CONTEXT;
+
+/* Values for CryptUIWizDigitalSign's dwFlags */
+#define CRYPTUI_WIZ_NO_UI                            0x00000001
+#define CRYPTUI_WIZ_DIGITAL_SIGN_EXCLUDE_PAGE_HASHES 0x00000002
+#define CRYPTUI_WIZ_DIGITAL_SIGN_INCLUDE_PAGE_HASHES 0x00000004
+
+BOOL WINAPI CryptUIWizDigitalSign(DWORD dwFlags, HWND hwndParent,
+ LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_DIGITAL_SIGN_INFO pDigitalSignInfo,
+ PCRYPTUI_WIZ_DIGITAL_SIGN_CONTEXT *ppSignContext);
+
+BOOL WINAPI CryptUIWizFreeDigitalSignContext(
+ PCRYPTUI_WIZ_DIGITAL_SIGN_CONTEXT pSignContext);
+
+/* Values for CRYPTUI_WIZ_EXPORT_INFO's dwSubjectChoice */
+#define CRYPTUI_WIZ_EXPORT_CERT_CONTEXT                 1
+#define CRYPTUI_WIZ_EXPORT_CTL_CONTEXT                  2
+#define CRYPTUI_WIZ_EXPORT_CRL_CONTEXT                  3
+#define CRYPTUI_WIZ_EXPORT_CERT_STORE                   4
+#define CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY 5
+#define CRYPTUI_WIZ_EXPORT_FORMAT_CRL                   6
+#define CRYPTUI_WIZ_EXPORT_FORMAT_CTL                   7
+
+typedef struct _CRYPTUI_WIZ_EXPORT_INFO
+{
+    DWORD       dwSize;
+    LPCWSTR     pwszExportFileName;
+    DWORD       dwSubjectChoice;
+    union {
+        PCCERT_CONTEXT pCertContext;
+        PCCTL_CONTEXT  pCTLContext;
+        PCCRL_CONTEXT  pCRLContext;
+    } DUMMYUNIONNAME;
+    DWORD       cStores;
+    HCERTSTORE *rghStores;
+} CRYPTUI_WIZ_EXPORT_INFO, *PCRYPTUI_WIZ_EXPORT_INFO;
+typedef const CRYPTUI_WIZ_EXPORT_INFO *PCCRYPTUI_WIZ_EXPORT_INFO;
+
+/* Values for CRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO's dwExportFormat */
+#define CRYPTUI_WIZ_EXPORT_FORMAT_DER                   1
+#define CRYPTUI_WIZ_EXPORT_FORMAT_PFX                   2
+#define CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7                 3
+#define CRYPTUI_WIZ_EXPORT_FORMAT_BASE64                4
+#define CRYPTUI_WIZ_EXPORT_FORMAT_SERIALIZED_CERT_STORE 5
+
+typedef struct _CRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO
+{
+    DWORD   dwSize;
+    DWORD   dwExportFormat;
+    BOOL    fExportChain;
+    BOOL    fExportPrivateKeys;
+    LPCWSTR pwszPassword;
+    BOOL    fStrongEncryption;
+} CRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO, *PCRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO;
+typedef const CRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO *
+ PCCRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO;
+
+BOOL WINAPI CryptUIWizExport(DWORD dwFlags, HWND hwndParent,
+ LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo, void *pvoid);
+
+/* Values for CRYPTUI_WIZ_IMPORT_SRC_INFO's dwSubjectChoice */
+#define CRYPTUI_WIZ_IMPORT_SUBJECT_FILE         1
+#define CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT 2
+#define CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT  3
+#define CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT  4
+#define CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE   5
+
+typedef struct _CRYPTUI_WIZ_IMPORT_SUBJECT_INFO
+{
+    DWORD   dwSize;
+    DWORD   dwSubjectChoice;
+    union {
+        LPCWSTR        pwszFileName;
+        PCCERT_CONTEXT pCertContext;
+        PCCTL_CONTEXT  pCTLContext;
+        PCCRL_CONTEXT  pCRLContext;
+        HCERTSTORE     hCertStore;
+    } DUMMYUNIONNAME;
+    DWORD   dwFlags;
+    LPCWSTR pwszPassword;
+} CRYPTUI_WIZ_IMPORT_SRC_INFO, *PCRYPTUI_WIZ_IMPORT_SRC_INFO;
+typedef const CRYPTUI_WIZ_IMPORT_SRC_INFO *PCCRYPTUI_WIZ_IMPORT_SRC_INFO;
+
+/* Values for CryptUIWizImport's dwFlags */
+#define CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE 0x00010000
+#define CRYPTUI_WIZ_IMPORT_ALLOW_CERT           0x00020000
+#define CRYPTUI_WIZ_IMPORT_ALLOW_CRL            0x00040000
+#define CRYPTUI_WIZ_IMPORT_ALLOW_CTL            0x00080000
+#define CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE      0x00100000
+#define CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER       0x00200000
+#define CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE    0x00400000
+
+BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent,
+ LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc,
+ HCERTSTORE hDestCertStore);
+
+/* Definitions missing from PSDK's cryptuiapi.h, but documented on MSDN. */
+typedef BOOL (WINAPI *PFNCCERTDISPLAYPROC)(PCCERT_CONTEXT pCertContext,
+ HWND hWndSelCertDlg, void *pvCallbackData);
+
+/* Values for CRYPTUI_SELECTCERTIFICATE_STRUCT's dwFlags */
+#define CRYPTUI_SELECTCERT_MULTISELECT 0x00000001
+
+typedef struct _CRYPTUI_SELECTCERTIFICATE_STRUCTA
+{
+    DWORD               dwSize;
+    HWND                hwndParent;
+    DWORD               dwFlags;
+    LPCWSTR             szTitle;
+    DWORD               dwDontUseColumn;
+    LPCWSTR             szDisplayString;
+    PFNCFILTERPROC      pFilterCallback;
+    PFNCCERTDISPLAYPROC pDisplayCallback;
+    void               *pvCallbackData;
+    DWORD               cStores;
+    HCERTSTORE         *rghStores;
+    DWORD               cPropSheetPages;
+    LPCPROPSHEETPAGEW   rgPropSheetPages;
+    HCERTSTORE          hSelectedCertStore;
+} CRYPTUI_SELECTCERTIFICATE_STRUCTA, *PCRYPTUI_SELECTCERTIFICATE_STRUCTA;
+typedef const CRYPTUI_SELECTCERTIFICATE_STRUCTA *
+ PCCRYPTUI_SELECTCERTIFICATE_STRUCTA;
+
+typedef struct _CRYPTUI_SELECTCERTIFICATE_STRUCTW
+{
+    DWORD               dwSize;
+    HWND                hwndParent;
+    DWORD               dwFlags;
+    LPCWSTR             szTitle;
+    DWORD               dwDontUseColumn;
+    LPCWSTR             szDisplayString;
+    PFNCFILTERPROC      pFilterCallback;
+    PFNCCERTDISPLAYPROC pDisplayCallback;
+    void               *pvCallbackData;
+    DWORD               cStores;
+    HCERTSTORE         *rghStores;
+    DWORD               cPropSheetPages;
+    LPCPROPSHEETPAGEW   rgPropSheetPages;
+    HCERTSTORE          hSelectedCertStore;
+} CRYPTUI_SELECTCERTIFICATE_STRUCTW, *PCRYPTUI_SELECTCERTIFICATE_STRUCTW;
+typedef const CRYPTUI_SELECTCERTIFICATE_STRUCTW *
+ PCCRYPTUI_SELECTCERTIFICATE_STRUCTW;
+
+PCCERT_CONTEXT WINAPI CryptUIDlgSelectCertificateA(
+ PCCRYPTUI_SELECTCERTIFICATE_STRUCTA pcsc);
+PCCERT_CONTEXT WINAPI CryptUIDlgSelectCertificateW(
+ PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc);
+
+typedef struct tagCRYPTUI_VIEWSIGNERINFO_STRUCTA
+{
+    DWORD             dwSize;
+    HWND              hwndParent;
+    DWORD             dwFlags;
+    LPCSTR            szTitle;
+    CMSG_SIGNER_INFO *pSignerInfo;
+    HCRYPTMSG         hMsg;
+    LPCSTR            pszOID;
+    DWORD_PTR         dwReserved;
+    DWORD             cStores;
+    HCERTSTORE       *rghStores;
+    DWORD             cPropSheetPages;
+    LPCPROPSHEETPAGEA rgPropSheetPages;
+} CRYPTUI_VIEWSIGNERINFO_STRUCTA, *PCRYPTUI_VIEWSIGNERINFO_STRUCTA;
+
+typedef struct tagCRYPTUI_VIEWSIGNERINFO_STRUCTW
+{
+    DWORD             dwSize;
+    HWND              hwndParent;
+    DWORD             dwFlags;
+    LPCWSTR           szTitle;
+    CMSG_SIGNER_INFO *pSignerInfo;
+    HCRYPTMSG         hMsg;
+    LPCSTR            pszOID;
+    DWORD_PTR         dwReserved;
+    DWORD             cStores;
+    HCERTSTORE       *rghStores;
+    DWORD             cPropSheetPages;
+    LPCPROPSHEETPAGEW rgPropSheetPages;
+} CRYPTUI_VIEWSIGNERINFO_STRUCTW, *PCRYPTUI_VIEWSIGNERINFO_STRUCTW;
+
+BOOL WINAPI CryptUIDlgViewSignerInfoA(CRYPTUI_VIEWSIGNERINFO_STRUCTA *pcvsi);
+BOOL WINAPI CryptUIDlgViewSignerInfoW(CRYPTUI_VIEWSIGNERINFO_STRUCTW *pcvsi);
+
+#include <poppack.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reactos/include/psdk/dwmapi.h b/reactos/include/psdk/dwmapi.h
new file mode 100644 (file)
index 0000000..710e3f4
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_DWMAPI_H
+#define __WINE_DWMAPI_H
+
+#include "wtypes.h"
+#include "uxtheme.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef DWMAPI
+# define DWMAPI        STDAPI
+# define DWMAPI_(type) STDAPI_(type)
+#endif
+
+DECLARE_HANDLE(HTHUMBNAIL);
+
+DWMAPI DwmEnableComposition(UINT);
+DWMAPI DwmExtendFrameIntoClientArea(HWND,const MARGINS*);
+DWMAPI DwmGetColorizationColor(DWORD*,BOOL);
+DWMAPI DwmIsCompositionEnabled(BOOL*);
+DWMAPI DwmSetWindowAttribute(HWND, DWORD, LPCVOID, DWORD);
+DWMAPI DwmUnregisterThumbnail(HTHUMBNAIL);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __WINE_DWMAPI_H */
index 1fa5638..5e7e097 100644 (file)
@@ -71,7 +71,7 @@ typedef struct CATALOG_INFO_
 #include <poppack.h>
 
 BOOL      WINAPI CryptCATAdminAcquireContext(HCATADMIN*,const GUID*,DWORD);
-BOOL      WINAPI CryptCATAdminAddCatalog(HCATADMIN,PWSTR,PWSTR,DWORD);
+HCATINFO  WINAPI CryptCATAdminAddCatalog(HCATADMIN,PWSTR,PWSTR,DWORD);
 BOOL      WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE,DWORD*,BYTE*,DWORD);
 HCATINFO  WINAPI CryptCATAdminEnumCatalogFromHash(HCATADMIN,BYTE*,DWORD,DWORD,HCATINFO*);
 BOOL      WINAPI CryptCATAdminReleaseCatalogContext(HCATADMIN,HCATINFO,DWORD);
index 1ffce4e..5564fcd 100644 (file)
@@ -46,6 +46,17 @@ typedef enum tagINSTALLSTATE
     INSTALLSTATE_DEFAULT = 5
 } INSTALLSTATE;
 
+typedef enum tagMSIPATCHSTATE
+{
+    MSIPATCHSTATE_INVALID = 0,
+    MSIPATCHSTATE_APPLIED = 1,
+    MSIPATCHSTATE_SUPERSEDED = 2,
+    MSIPATCHSTATE_OBSOLETED = 4,
+    MSIPATCHSTATE_REGISTERED = 8,
+    MSIPATCHSTATE_ALL = (MSIPATCHSTATE_APPLIED | MSIPATCHSTATE_SUPERSEDED |
+                         MSIPATCHSTATE_OBSOLETED | MSIPATCHSTATE_REGISTERED)
+} MSIPATCHSTATE;
+
 typedef enum tagINSTALLUILEVEL
 {
     INSTALLUILEVEL_NOCHANGE = 0,
@@ -201,6 +212,29 @@ typedef struct _MSIFILEHASHINFO {
     ULONG dwData[4];
 } MSIFILEHASHINFO, *PMSIFILEHASHINFO;
 
+typedef enum tagMSIPATCHDATATYPE
+{
+    MSIPATCH_DATATYPE_PATCHFILE = 0,
+    MSIPATCH_DATATYPE_XMLPATH = 1,
+    MSIPATCH_DATATYPE_XMLBLOB = 2,
+} MSIPATCHDATATYPE, *PMSIPATCHDATATYPE;
+
+typedef struct tagMSIPATCHSEQUENCEINFOA
+{
+    LPCSTR szPatchData;
+    MSIPATCHDATATYPE ePatchDataType;
+    DWORD dwOrder;
+    UINT uStatus;
+} MSIPATCHSEQUENCEINFOA, *PMSIPATCHSEQUENCEINFOA;
+
+typedef struct tagMSIPATCHSEQUENCEINFOW
+{
+    LPCWSTR szPatchData;
+    MSIPATCHDATATYPE ePatchDataType;
+    DWORD dwOrder;
+    UINT uStatus;
+} MSIPATCHSEQUENCEINFOW, *PMSIPATCHSEQUENCEINFOW;
+
 #define MAX_FEATURE_CHARS 38
 
 /* Strings defined in msi.h */
@@ -364,6 +398,8 @@ static const WCHAR INSTALLPROPERTY_DISKPROMPTW[] = {'D','i','s','k','P','r','o',
 
 typedef INT (CALLBACK *INSTALLUI_HANDLERA)(LPVOID, UINT, LPCSTR);
 typedef INT (CALLBACK *INSTALLUI_HANDLERW)(LPVOID, UINT, LPCWSTR);
+typedef INT (CALLBACK *INSTALLUI_HANDLER_RECORD)(LPVOID, UINT, MSIHANDLE);
+typedef INSTALLUI_HANDLER_RECORD* PINSTALLUI_HANDLER_RECORD;
 
 UINT WINAPI MsiAdvertiseProductA(LPCSTR, LPCSTR, LPCSTR, LANGID);
 UINT WINAPI MsiAdvertiseProductW(LPCWSTR, LPCWSTR, LPCWSTR, LANGID);
@@ -461,6 +497,10 @@ UINT WINAPI MsiGetProductInfoExA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPST
 UINT WINAPI MsiGetProductInfoExW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, LPWSTR, LPDWORD);
 #define     MsiGetProductInfoEx WINELIB_NAME_AW(MsiGetProductInfoEx)
 
+UINT WINAPI MsiGetPatchInfoExA(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
+UINT WINAPI MsiGetPatchInfoExW(LPCWSTR, LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, LPWSTR, LPDWORD);
+#define     MsiGetPatchInfoEx WINELIB_NAME_AW(MsiGetPatchInfoEx)
+
 UINT WINAPI MsiEnableLogA(DWORD, LPCSTR, DWORD);
 UINT WINAPI MsiEnableLogW(DWORD, LPCWSTR, DWORD);
 #define     MsiEnableLog WINELIB_NAME_AW(MsiEnableLog)
@@ -579,6 +619,12 @@ UINT WINAPI MsiEnumPatchesA(LPCSTR, DWORD, LPSTR, LPSTR, LPDWORD);
 UINT WINAPI MsiEnumPatchesW(LPCWSTR, DWORD, LPWSTR, LPWSTR, LPDWORD);
 #define     MsiEnumPatches WINELIB_NAME_AW(MsiEnumPatches)
 
+UINT WINAPI MsiEnumPatchesExA(LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
+                              MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
+UINT WINAPI MsiEnumPatchesExW(LPCWSTR, LPCWSTR, DWORD, DWORD, DWORD, LPWSTR, LPWSTR,
+                              MSIINSTALLCONTEXT*, LPWSTR, LPDWORD);
+#define     MsiEnumPatchesEx WINELIB_NAME_AW(MsiEnumPatchesEx)
+
 UINT WINAPI MsiGetFileHashA(LPCSTR, DWORD, PMSIFILEHASHINFO);
 UINT WINAPI MsiGetFileHashW(LPCWSTR, DWORD, PMSIFILEHASHINFO);
 #define     MsiGetFileHash WINELIB_NAME_AW(MsiGetFileHash)
@@ -591,10 +637,23 @@ UINT WINAPI MsiIsProductElevatedA(LPCSTR, BOOL *);
 UINT WINAPI MsiIsProductElevatedW(LPCWSTR, BOOL *);
 #define     MsiIsProductElevated WINELIB_NAME_AW(MsiIsProductElevated)
 
+UINT WINAPI MsiDatabaseMergeA(MSIHANDLE, MSIHANDLE, LPCSTR);
+UINT WINAPI MsiDatabaseMergeW(MSIHANDLE, MSIHANDLE, LPCWSTR);
+#define     MsiDatabaseMerge WINELIB_NAME_AW(MsiDatabaseMerge)
+
+UINT WINAPI MsiInstallMissingComponentA(LPCSTR, LPCSTR, INSTALLSTATE);
+UINT WINAPI MsiInstallMissingComponentW(LPCWSTR, LPCWSTR, INSTALLSTATE);
+#define     MsiInstallMissingComponent WINELIB_NAME_AW(MsiInstallMissingComponent)
+
+UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR, DWORD, PMSIPATCHSEQUENCEINFOA);
+UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR, DWORD, PMSIPATCHSEQUENCEINFOW);
+#define     MsiDetermineApplicablePatches WINELIB_NAME_AW(MsiDetermineApplicablePatches)
+
 /* Non Unicode */
 UINT WINAPI MsiCloseHandle(MSIHANDLE);
 UINT WINAPI MsiCloseAllHandles(void);
 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL, HWND*);
+UINT WINAPI MsiSetExternalUIRecord(INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
 
 #ifdef __cplusplus
 }
index 141e203..d87569f 100644 (file)
@@ -215,6 +215,13 @@ enum msidbSumInfoSourceType
     msidbSumInfoSourceTypeLUAPackage = 0x00000008,
 };
 
+enum msidbRemoveFileInstallMode
+{
+    msidbRemoveFileInstallModeOnInstall = 0x00000001,
+    msidbRemoveFileInstallModeOnRemove = 0x00000002,
+    msidbRemoveFileInstallModeOnBoth = 0x00000003,
+};
+
 /*
  * Windows SDK braindamage alert
  *
diff --git a/reactos/include/psdk/oleacc.h b/reactos/include/psdk/oleacc.h
deleted file mode 100644 (file)
index 0a8108f..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef _OLEACC_H
-#define _OLEACC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define DISPID_ACC_PARENT                   (-5000)
-#define DISPID_ACC_CHILDCOUNT               (-5001)
-#define DISPID_ACC_CHILD                    (-5002)
-
-#define DISPID_ACC_NAME                     (-5003)
-#define DISPID_ACC_VALUE                    (-5004)
-#define DISPID_ACC_DESCRIPTION              (-5005)
-#define DISPID_ACC_ROLE                     (-5006)
-#define DISPID_ACC_STATE                    (-5007)
-#define DISPID_ACC_HELP                     (-5008)
-#define DISPID_ACC_HELPTOPIC                (-5009)
-#define DISPID_ACC_KEYBOARDSHORTCUT         (-5010)
-#define DISPID_ACC_FOCUS                    (-5011)
-#define DISPID_ACC_SELECTION                (-5012)
-#define DISPID_ACC_DEFAULTACTION            (-5013)
-
-#define DISPID_ACC_SELECT                   (-5014)
-#define DISPID_ACC_LOCATION                 (-5015)
-#define DISPID_ACC_NAVIGATE                 (-5016)
-#define DISPID_ACC_HITTEST                  (-5017)
-#define DISPID_ACC_DODEFAULTACTION          (-5018)
-
-#define NAVDIR_DOWN 2
-#define NAVDIR_FIRSTCHILD 7
-#define NAVDIR_LASTCHILD 8
-#define NAVDIR_LEFT 3
-#define NAVDIR_NEXT 5
-#define NAVDIR_PREVIOUS 6
-#define NAVDIR_RIGHT 4
-#define NAVDIR_UP 1
-
-#define ROLE_SYSTEM_ALERT 8
-#define ROLE_SYSTEM_ANIMATION 54
-#define ROLE_SYSTEM_APPLICATION 14
-#define ROLE_SYSTEM_BORDER 19
-#define ROLE_SYSTEM_BUTTONDROPDOWN  56
-#define ROLE_SYSTEM_BUTTONDROPDOWNGRID 58
-#define ROLE_SYSTEM_BUTTONMENU 57
-#define ROLE_SYSTEM_CARET 7
-#define ROLE_SYSTEM_CELL 29
-#define ROLE_SYSTEM_CHARACTER 32
-#define ROLE_SYSTEM_CHART 17
-#define ROLE_SYSTEM_CHECKBUTTON 44
-#define ROLE_SYSTEM_CLIENT 10
-#define ROLE_SYSTEM_CLOCK 61
-#define ROLE_SYSTEM_COLUMN 27
-#define ROLE_SYSTEM_COLUMNHEADER 25
-#define ROLE_SYSTEM_COMBOBOX 46
-#define ROLE_SYSTEM_CURSOR 6
-#define ROLE_SYSTEM_DIAGRAM 53
-#define ROLE_SYSTEM_DIAL 49
-#define ROLE_SYSTEM_DIALOG 18
-#define ROLE_SYSTEM_DOCUMENT 15
-#define ROLE_SYSTEM_DROPLIST 47
-#define ROLE_SYSTEM_EQUATION 55
-#define ROLE_SYSTEM_GRAPHIC 40
-#define ROLE_SYSTEM_GRIP 4
-#define ROLE_SYSTEM_GROUPING 20
-#define ROLE_SYSTEM_HELPBALLOON 31
-#define ROLE_SYSTEM_HOTKEYFIELD 50
-#define ROLE_SYSTEM_INDICATOR 39
-#define ROLE_SYSTEM_LINK 30
-#define ROLE_SYSTEM_LIST 33
-#define ROLE_SYSTEM_LISTITEM 34
-#define ROLE_SYSTEM_MENUBAR 2
-#define ROLE_SYSTEM_MENUITEM 12
-#define ROLE_SYSTEM_MENUPOPUP 11
-#define ROLE_SYSTEM_OUTLINE 35
-#define ROLE_SYSTEM_OUTLINEITEM 36
-#define ROLE_SYSTEM_PAGETAB 37
-#define ROLE_SYSTEM_PAGETABLIST 60
-#define ROLE_SYSTEM_PANE 16
-#define ROLE_SYSTEM_PROGRESSBAR 48
-#define ROLE_SYSTEM_PROPERTYPAGE 38
-#define ROLE_SYSTEM_PUSHBUTTON 43
-#define ROLE_SYSTEM_RADIOBUTTON 45
-#define ROLE_SYSTEM_ROW 28
-#define ROLE_SYSTEM_ROWHEADER 26
-#define ROLE_SYSTEM_SCROLLBAR 3
-#define ROLE_SYSTEM_SEPARATOR 21
-#define ROLE_SYSTEM_SLIDER 51
-#define ROLE_SYSTEM_SOUND 5
-#define ROLE_SYSTEM_SPINBUTTON 52
-#define ROLE_SYSTEM_STATICTEXT 41
-#define ROLE_SYSTEM_STATUSBAR 23
-#define ROLE_SYSTEM_TABLE 24
-#define ROLE_SYSTEM_TEXT 42
-#define ROLE_SYSTEM_TITLEBAR 1
-#define ROLE_SYSTEM_TOOLBAR 22
-#define ROLE_SYSTEM_TOOLTIP 13
-#define ROLE_SYSTEM_WHITESPACE 59
-#define ROLE_SYSTEM_WINDOW 9
-
-#ifndef STATE_SYSTEM_UNAVAILABLE
-#define STATE_SYSTEM_UNAVAILABLE 0x00000001
-#define STATE_SYSTEM_SELECTED 0x00000002
-#define STATE_SYSTEM_FOCUSED 0x00000004
-#define STATE_SYSTEM_PRESSED 0x00000008
-#define STATE_SYSTEM_CHECKED 0x00000010
-#define STATE_SYSTEM_MIXED 0x00000020
-#define STATE_SYSTEM_INDETERMINATE   STATE_SYSTEM_MIXED
-#define STATE_SYSTEM_READONLY 0x00000040
-#define STATE_SYSTEM_HOTTRACKED 0x00000080
-#define STATE_SYSTEM_DEFAULT 0x00000100
-#define STATE_SYSTEM_EXPANDED 0x00000200
-#define STATE_SYSTEM_COLLAPSED 0x00000400
-#define STATE_SYSTEM_BUSY 0x00000800
-#define STATE_SYSTEM_FLOATING 0x00001000
-#define STATE_SYSTEM_MARQUEED 0x00002000
-#define STATE_SYSTEM_ANIMATED 0x00004000
-#define STATE_SYSTEM_INVISIBLE 0x00008000
-#define STATE_SYSTEM_OFFSCREEN 0x00010000
-#define STATE_SYSTEM_SIZEABLE 0x00020000
-#define STATE_SYSTEM_MOVEABLE 0x00040000
-#define STATE_SYSTEM_SELFVOICING 0x00080000
-#define STATE_SYSTEM_FOCUSABLE 0x00100000
-#define STATE_SYSTEM_SELECTABLE 0x00200000
-#define STATE_SYSTEM_LINKED 0x00400000
-#define STATE_SYSTEM_TRAVERSED 0x00800000
-#define STATE_SYSTEM_MULTISELECTABLE 0x01000000
-#define STATE_SYSTEM_EXTSELECTABLE 0x02000000
-#define STATE_SYSTEM_ALERT_LOW 0x04000000
-#define STATE_SYSTEM_ALERT_MEDIUM 0x08000000
-#define STATE_SYSTEM_ALERT_HIGH 0x10000000
-#define STATE_SYSTEM_VALID 0x1fffffff
-#endif
-
-typedef enum tagSELFLAG
-{
-  SELFLAG_NONE = 0,
-  SELFLAG_TAKEFOCUS = 1,
-  SELFLAG_TAKESELECTION = 2,
-  SELFLAG_EXTENDSELECTION = 4,
-  SELFLAG_ADDSELECTION = 8,
-  SELFLAG_REMOVESELECTION = 16
-} SELFLAG;
-
-#define SELFLAG_VALID  0x0000001F
-
-/* DEFINE_GUID(LIBID_Accessibility, 0x1ea4dbf0, 0x3c3b,0x11cf, 0x81, 0x0c, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); */
-/* DEFINE_GUID(IID_IAccessible,     0x618736e0, 0x3c3d,0x11cf, 0x81, 0x0c, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); */
-EXTERN_C const IID LIBID_Accessibility;
-EXTERN_C const IID IID_IAccessible;
-
-#define INTERFACE IAccessible
-DECLARE_INTERFACE_(IAccessible, IDispatch)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG,Release)(THIS) PURE;
-    STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE;
-    STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,LPTYPEINFO*) PURE;
-    STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*) PURE;
-    STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*) PURE;
-
-    STDMETHOD(get_accParent)(THIS_ IDispatch**) PURE;
-    STDMETHOD(get_accChildCount)(THIS_ long*) PURE;
-    STDMETHOD(get_accChild)(THIS_ VARIANT, IDispatch **) PURE;
-    STDMETHOD(get_accName)(THIS_ VARIANT, BSTR*) PURE;
-    STDMETHOD(get_accValue)(THIS_ VARIANT, BSTR*) PURE;
-    STDMETHOD(get_accDescription)(THIS_ VARIANT, BSTR*) PURE;
-    STDMETHOD(get_accRole)(THIS_ VARIANT, VARIANT*) PURE;
-    STDMETHOD(get_accState)(THIS_ VARIANT, VARIANT*) PURE;
-    STDMETHOD(get_accHelp)(THIS_ VARIANT, BSTR*) PURE;
-    STDMETHOD(get_accHelpTopic)(THIS_ BSTR*, VARIANT, long*) PURE;
-    STDMETHOD(get_accKeyboardShortcut)(THIS_ VARIANT, BSTR*) PURE;
-    STDMETHOD(get_accFocus)(THIS_ VARIANT*) PURE;
-    STDMETHOD(get_accSelection)(THIS_ VARIANT*) PURE;
-    STDMETHOD(get_accDefaultAction)(THIS_ VARIANT, BSTR*) PURE;
-
-    STDMETHOD(accSelect)(THIS_ long, VARIANT) PURE;
-    STDMETHOD(accLocation)(THIS_ long*, long*, long*, long*, VARIANT) PURE;
-    STDMETHOD(accNavigate)(THIS_ long, VARIANT, VARIANT*) PURE;
-    STDMETHOD(accHitTest)(THIS_ long, long, VARIANT*) PURE;
-    STDMETHOD(accDoDefaultAction)(THIS_ VARIANT) PURE;
-
-    STDMETHOD(put_accName)(THIS_ VARIANT, BSTR) PURE;
-    STDMETHOD(put_accValue)(THIS_ VARIANT, BSTR) PURE;
-};
-#undef INTERFACE
-typedef IAccessible* LPACCESSIBLE;
-
-STDAPI AccessibleChildren(IAccessible*,LONG,LONG,VARIANT*,LONG*);
-STDAPI AccessibleObjectFromEvent(HWND,DWORD,DWORD,IAccessible*,VARIANT*);
-STDAPI AccessibleObjectFromPoint(POINT,IAccessible**,VARIANT*);
-STDAPI AccessibleObjectFromWindow(HWND,DWORD,REFIID,void**);
-STDAPI CreateStdAccessibleObject(HWND,LONG,REFIID,void**);
-STDAPI CreateStdAccessibleProxyA(HWND,LPCSTR,LONG,REFIID,void**);
-STDAPI CreateStdAccessibleProxyW(HWND,LPCWSTR,LONG,REFIID,void**);
-void WINAPI GetOleaccVersionInfo(DWORD*,DWORD*);
-UINT WINAPI GetRoleTextA(DWORD,LPSTR,UINT);
-UINT WINAPI GetRoleTextW(DWORD,LPWSTR,UINT);
-UINT WINAPI GetStateTextA(DWORD,LPSTR,UINT);
-UINT WINAPI GetStateTextW(DWORD,LPWSTR,UINT);
-LRESULT WINAPI LresultFromObject(REFIID,WPARAM,LPUNKNOWN);
-STDAPI ObjectFromLresult(LRESULT,REFIID,WPARAM,void**);
-STDAPI WindowFromAccessibleObject(IAccessible*,HWND*);
-
-#ifdef UNICODE
-#define CreateStdAccessibleProxy CreateStdAccessibleProxyW
-#define GetRoleText GetRoleTextW
-#define GetStateText GetStateTextW
-#else
-#define CreateStdAccessibleProxy CreateStdAccessibleProxyA
-#define GetRoleText GetRoleTextA
-#define GetStateText GetStateTextA
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _OLEACC_H */
diff --git a/reactos/include/psdk/scarderr.h b/reactos/include/psdk/scarderr.h
new file mode 100644 (file)
index 0000000..9ad60f8
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Winscard definitions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Note that if you included winerror.h directly or indirectly,
+ * none of these definitions will be used!
+ */
+#ifndef SCARD_S_SUCCESS
+
+#define FACILITY_SYSTEM                       0
+#define FACILITY_SCARD                       16
+
+#define STATUS_SEVERITY_INFORMATIONAL    ((NTSTATUS) 0x00000001)
+#define STATUS_SEVERITY_WARNING          ((NTSTATUS) 0x00000002)
+#define STATUS_SEVERITY_ERROR            ((NTSTATUS) 0x00000003)
+
+#define SCARD_S_SUCCESS                                    NO_ERROR
+#define SCARD_F_INTERNAL_ERROR                             ((DWORD)0x80100001)
+#define SCARD_E_CANCELLED                                  ((DWORD)0x80100002)
+#define SCARD_E_INVALID_HANDLE                             ((DWORD)0x80100003)
+#define SCARD_E_INVALID_PARAMETER                          ((DWORD)0x80100004)
+#define SCARD_E_INVALID_TARGET                             ((DWORD)0x80100005)
+#define SCARD_E_NO_MEMORY                                  ((DWORD)0x80100006)
+#define SCARD_F_WAITED_TOO_LONG                            ((DWORD)0x80100007)
+#define SCARD_E_INSUFFICIENT_BUFFER                        ((DWORD)0x80100008)
+#define SCARD_E_UNKNOWN_READER                             ((DWORD)0x80100009)
+#define SCARD_E_TIMEOUT                                    ((DWORD)0x8010000A)
+#define SCARD_E_SHARING_VIOLATION                          ((DWORD)0x8010000B)
+#define SCARD_E_NO_SMARTCARD                               ((DWORD)0x8010000C)
+#define SCARD_E_UNKNOWN_CARD                               ((DWORD)0x8010000D)
+#define SCARD_E_CANT_DISPOSE                               ((DWORD)0x8010000E)
+#define SCARD_E_PROTO_MISMATCH                             ((DWORD)0x8010000F)
+#define SCARD_E_NOT_READY                                  ((DWORD)0x80100010)
+#define SCARD_E_INVALID_VALUE                              ((DWORD)0x80100011)
+#define SCARD_E_SYSTEM_CANCELLED                           ((DWORD)0x80100012)
+#define SCARD_F_COMM_ERROR                                 ((DWORD)0x80100013)
+#define SCARD_F_UNKNOWN_ERROR                              ((DWORD)0x80100014)
+#define SCARD_E_INVALID_ATR                                ((DWORD)0x80100015)
+#define SCARD_E_NOT_TRANSACTED                             ((DWORD)0x80100016)
+#define SCARD_E_READER_UNAVAILABLE                         ((DWORD)0x80100017)
+#define SCARD_P_SHUTDOWN                                   ((DWORD)0x80100018)
+#define SCARD_E_PCI_TOO_SMALL                              ((DWORD)0x80100019)
+#define SCARD_E_READER_UNSUPPORTED                         ((DWORD)0x8010001A)
+#define SCARD_E_DUPLICATE_READER                           ((DWORD)0x8010001B)
+#define SCARD_E_CARD_UNSUPPORTED                           ((DWORD)0x8010001C)
+#define SCARD_E_NO_SERVICE                                 ((DWORD)0x8010001D)
+#define SCARD_E_SERVICE_STOPPED                            ((DWORD)0x8010001E)
+#define SCARD_E_UNEXPECTED                                 ((DWORD)0x8010001F)
+#define SCARD_E_ICC_INSTALLATION                           ((DWORD)0x80100020)
+#define SCARD_E_ICC_CREATEORDER                            ((DWORD)0x80100021)
+#define SCARD_E_UNSUPPORTED_FEATURE                        ((DWORD)0x80100022)
+#define SCARD_E_DIR_NOT_FOUND                              ((DWORD)0x80100023)
+#define SCARD_E_FILE_NOT_FOUND                             ((DWORD)0x80100024)
+#define SCARD_E_NO_DIR                                     ((DWORD)0x80100025)
+#define SCARD_E_NO_FILE                                    ((DWORD)0x80100026)
+#define SCARD_E_NO_ACCESS                                  ((DWORD)0x80100027)
+#define SCARD_E_WRITE_TOO_MANY                             ((DWORD)0x80100028)
+#define SCARD_E_BAD_SEEK                                   ((DWORD)0x80100029)
+#define SCARD_E_INVALID_CHV                                ((DWORD)0x8010002A)
+#define SCARD_E_UNKNOWN_RES_MNG                            ((DWORD)0x8010002B)
+#define SCARD_E_NO_SUCH_CERTIFICATE                        ((DWORD)0x8010002C)
+#define SCARD_E_CERTIFICATE_UNAVAILABLE                    ((DWORD)0x8010002D)
+#define SCARD_E_NO_READERS_AVAILABLE                       ((DWORD)0x8010002E)
+#define SCARD_E_COMM_DATA_LOST                             ((DWORD)0x8010002F)
+#define SCARD_E_NO_KEY_CONTAINER                           ((DWORD)0x80100030)
+#define SCARD_E_SERVER_TOO_BUSY                            ((DWORD)0x80100031)
+#define SCARD_W_UNSUPPORTED_CARD                           ((DWORD)0x80100065)
+#define SCARD_W_UNRESPONSIVE_CARD                          ((DWORD)0x80100066)
+#define SCARD_W_UNPOWERED_CARD                             ((DWORD)0x80100067)
+#define SCARD_W_RESET_CARD                                 ((DWORD)0x80100068)
+#define SCARD_W_REMOVED_CARD                               ((DWORD)0x80100069)
+#define SCARD_W_SECURITY_VIOLATION                         ((DWORD)0x8010006A)
+#define SCARD_W_WRONG_CHV                                  ((DWORD)0x8010006B)
+#define SCARD_W_CHV_BLOCKED                                ((DWORD)0x8010006C)
+#define SCARD_W_EOF                                        ((DWORD)0x8010006D)
+#define SCARD_W_CANCELLED_BY_USER                          ((DWORD)0x8010006E)
+#define SCARD_W_CARD_NOT_AUTHENTICATED                     ((DWORD)0x8010006F)
+#define SCARD_W_CACHE_ITEM_NOT_FOUND                       ((DWORD)0x80100070)
+#define SCARD_W_CACHE_ITEM_STALE                           ((DWORD)0x80100071)
+#define SCARD_W_CACHE_ITEM_TOO_BIG                         ((DWORD)0x80100072)
+
+#endif /* SCARD_S_SUCCESS */
index 9424216..bccabc5 100644 (file)
@@ -147,4 +147,13 @@ DEFINE_GUID(CLSID_CAnchorBrowsePropertyPage, 0x3050F3BB, 0x98B5, 0x11CF, 0xBB,0x
 DEFINE_GUID(CLSID_CDocBrowsePropertyPage, 0x3050F3B4, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
 DEFINE_GUID(CLSID_CImageBrowsePropertyPage, 0x3050F3B3, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
 
+DEFINE_GUID(VID_LargeIcons, 0x0057d0e0, 0x3573, 0x11cf, 0xae, 0x69, 0x08, 0x00, 0x2b, 0x2e, 0x12, 0x62);
+DEFINE_GUID(VID_SmallIcons, 0x089000c0, 0x3573, 0x11cf, 0xae, 0x69, 0x08, 0x00, 0x2b, 0x2e, 0x12, 0x62);
+DEFINE_GUID(VID_List,       0x0e1fa5e0, 0x3573, 0x11cf, 0xae, 0x69, 0x08, 0x00, 0x2b, 0x2e, 0x12, 0x62);
+DEFINE_GUID(VID_Details,    0x137e7700, 0x3573, 0x11cf, 0xae, 0x69, 0x08, 0x00, 0x2b, 0x2e, 0x12, 0x62);
+DEFINE_GUID(VID_Thumbnails, 0x8bebb290, 0x52d0, 0x11d0, 0xb7, 0xf4, 0x00, 0xc0, 0x4f, 0xd7, 0x06, 0xec);
+DEFINE_GUID(VID_Tile,       0x65f125e5, 0x7be1, 0x4810, 0xba, 0x9d, 0xd2, 0x71, 0xc8, 0x43, 0x2c, 0xe3);
+DEFINE_GUID(VID_ThumbStrip, 0x8eefa624, 0xd1e9, 0x445b, 0x94, 0xb7, 0x74, 0xfb, 0xce, 0x2e, 0xa1, 0x1a);
+
+
 #endif /* __WINE_SHLGUID_H */
index 456186c..844f0b9 100644 (file)
@@ -27,6 +27,13 @@ extern "C" {
 
 /* Defines */
 
+/* Event types */
+#define BEGIN_NESTED_SYSTEM_CHANGE 102
+#define END_NESTED_SYSTEM_CHANGE   103
+
+/* Restore point types */
+#define APPLICATION_INSTALL          0
+
 #define MAX_DESC    64
 #define MAX_DESC_W  256
 
index 83bc58b..a3dd39a 100644 (file)
@@ -22,6 +22,10 @@ import "oleidl.idl";
 import "servprov.idl";
 import "msxml.idl";
 
+cpp_quote("#ifdef WINE_NO_UNICODE_MACROS")
+cpp_quote("#undef GetUserName")
+cpp_quote("#endif")
+
 interface IInternetProtocolSink;
 
 /*****************************************************************************
@@ -1363,6 +1367,147 @@ typedef enum _tagINTERNETFEATURELIST
     FEATURE_ENTRY_COUNT
 } INTERNETFEATURELIST;
 
+/*****************************************************************************
+ * IUri interface
+ */
+[
+    local,
+    object,
+    uuid(a39ee748-6a27-4817-a6f2-13914bef5890),
+    pointer_default(unique)
+]
+interface IUri : IUnknown
+{
+    typedef enum
+    {
+        Uri_PROPERTY_ABSOLUTE_URI = 0,
+        Uri_PROPERTY_STRING_START = Uri_PROPERTY_ABSOLUTE_URI,
+        Uri_PROPERTY_AUTHORITY = 1,
+        Uri_PROPERTY_DISPLAY_URI = 2,
+        Uri_PROPERTY_DOMAIN = 3,
+        Uri_PROPERTY_EXTENSION = 4,
+        Uri_PROPERTY_FRAGMENT = 5,
+        Uri_PROPERTY_HOST = 6,
+        Uri_PROPERTY_PASSWORD = 7,
+        Uri_PROPERTY_PATH = 8,
+        Uri_PROPERTY_PATH_AND_QUERY = 9,
+        Uri_PROPERTY_QUERY = 10,
+        Uri_PROPERTY_RAW_URI = 11,
+        Uri_PROPERTY_SCHEME_NAME = 12,
+        Uri_PROPERTY_USER_INFO = 13,
+        Uri_PROPERTY_USER_NAME = 14,
+        Uri_PROPERTY_STRING_LAST = Uri_PROPERTY_USER_NAME,
+        Uri_PROPERTY_HOST_TYPE = 15,
+        Uri_PROPERTY_DWORD_START = Uri_PROPERTY_HOST_TYPE,
+        Uri_PROPERTY_PORT = 16,
+        Uri_PROPERTY_SCHEME = 17,
+        Uri_PROPERTY_ZONE = 18,
+        Uri_PROPERTY_DWORD_LAST = Uri_PROPERTY_ZONE
+    } Uri_PROPERTY;
+
+    HRESULT GetPropertyBSTR(
+        [in]  Uri_PROPERTY uriProp,
+        [out] BSTR *pbstrProperty,
+        [in]  DWORD dwFlags);
+
+    HRESULT GetPropertyLength(
+        [in]  Uri_PROPERTY uriProp,
+        [out] DWORD *pcchProperty,
+        [in]  DWORD dwFlags);
+
+    HRESULT GetPropertyDWORD(
+        [in]  Uri_PROPERTY uriProp,
+        [out] DWORD *pdwProperty,
+        [in]  DWORD dwFlags);
+
+    HRESULT HasProperty(
+        [in] Uri_PROPERTY uriProp,
+        [out] BOOL *pfHasProperty);
+
+    HRESULT GetAbsoluteUri(
+        [out] BSTR *pbstrAbsoluteUri);
+
+    HRESULT GetAuthority(
+        [out] BSTR *pbstrAuthority);
+
+    HRESULT GetDisplayUri(
+        [out] BSTR *pbstrDisplayString);
+
+    HRESULT GetDomain(
+        [out] BSTR *pbstrDomain);
+
+    HRESULT GetExtension(
+        [out] BSTR *pbstrExtension);
+
+    HRESULT GetFragment(
+        [out] BSTR *pbstrFragment);
+
+    HRESULT GetHost(
+        [out] BSTR *pbstrHost);
+
+    HRESULT GetPassword(
+        [out] BSTR *pbstrPassword);
+
+    HRESULT GetPath(
+        [out] BSTR *pbstrPath);
+
+    HRESULT GetPathAndQuery(
+        [out] BSTR *pbstrPathAndQuery);
+
+    HRESULT GetQuery(
+        [out] BSTR *pbstrQuery);
+
+    HRESULT GetRawUri(
+        [out] BSTR *pbstrRawUri);
+
+    HRESULT GetSchemeName(
+        [out] BSTR *pbstrSchemeName);
+
+    HRESULT GetUserInfo(
+        [out] BSTR *pbstrUserInfo);
+
+    HRESULT GetUserName(
+        [out] BSTR *pbstrUserName);
+
+    HRESULT GetHostType(
+        [out] DWORD *pdwHostType);
+
+    HRESULT GetPort(
+        [out] DWORD *pdwPort);
+
+    HRESULT GetScheme(
+        [out] DWORD *pdwScheme);
+
+    HRESULT GetZone(
+        [out] DWORD *pdwZone);
+
+    HRESULT GetProperties(
+        [out] LPDWORD pdwFlags);
+
+    HRESULT IsEqual(
+        [in]  IUri *pUri,
+        [out] BOOL *pfEqual);
+}
+
+/*****************************************************************************
+ * IInternetProtocolEx interface
+ */
+[
+    local,
+    object,
+    uuid(c7a98e66-1010-492c-a1c8-c809e1f75905),
+    pointer_default(unique)
+]
+interface IInternetProtocolEx : IInternetProtocol
+{
+    HRESULT StartEx(
+        [in] IUri *pUri,
+        [in] IInternetProtocolSink *pOIProtSink,
+        [in] IInternetBindInfo *pOIBindInfo,
+        [in] DWORD grfPI,
+        [in] HANDLE *dwReserved);
+}
+
 cpp_quote("DEFINE_GUID(CLSID_InternetSecurityManager, 0x7b8a2d94, 0x0ac9, 0x11d1, 0x89, 0x6c, 0x00, 0xc0, 0x4f, 0xB6, 0xbf, 0xc4);")
 cpp_quote("DEFINE_GUID(CLSID_InternetZoneManager, 0x7B8A2D95, 0x0AC9, 0x11D1, 0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4);")
 cpp_quote("DEFINE_GUID(IID_IAsyncMoniker, 0x79EAC9D3, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B);")
@@ -1381,32 +1526,32 @@ cpp_quote("#define URLMON_OPTION_USERAGENT          0x10000001")
 cpp_quote("#define URLMON_OPTION_USERAGENT_REFRESH  0x10000002")
 cpp_quote("#define URLMON_OPTION_URL_ENCODING       0x10000004")
 
-cpp_quote("#define MK_S_ASYNCHRONOUS                0x000401E8")
+cpp_quote("#define MK_S_ASYNCHRONOUS                _HRESULT_TYPEDEF_(0x000401E8)")
 cpp_quote("#ifndef S_ASYNCHRONOUS")
 cpp_quote("#define S_ASYNCHRONOUS                   MK_S_ASYNCHRONOUS")
 cpp_quote("#endif")
 
-cpp_quote("#define INET_E_ERROR_FIRST               0x800C0002")
-cpp_quote("#define INET_E_INVALID_URL               0x800C0002")
-cpp_quote("#define INET_E_NO_SESSION                0x800C0003")
-cpp_quote("#define INET_E_CANNOT_CONNECT            0x800C0004")
-cpp_quote("#define INET_E_RESOURCE_NOT_FOUND        0x800C0005")
-cpp_quote("#define INET_E_OBJECT_NOT_FOUND          0x800C0006")
-cpp_quote("#define INET_E_DATA_NOT_AVAILABLE        0x800C0007")
-cpp_quote("#define INET_E_DOWNLOAD_FAILURE          0x800C0008")
-cpp_quote("#define INET_E_AUTHENTICATION_REQUIRED   0x800C0009")
-cpp_quote("#define INET_E_NO_VALID_MEDIA            0x800C000A")
-cpp_quote("#define INET_E_CONNECTION_TIMEOUT        0x800C000B")
-cpp_quote("#define INET_E_INVALID_REQUEST           0x800C000C")
-cpp_quote("#define INET_E_UNKNOWN_PROTOCOL          0x800C000D")
-cpp_quote("#define INET_E_SECURITY_PROBLEM          0x800C000E")
-cpp_quote("#define INET_E_CANNOT_LOAD_DATA          0x800C000F")
-cpp_quote("#define INET_E_CANNOT_INSTANTIATE_OBJECT 0x800C0010")
-cpp_quote("#define INET_E_USE_DEFAULT_PROTOCOLHANDLER 0x800C0011")
-cpp_quote("#define INET_E_QUERYOPTION_UNKNOWN       0x800C0013")
-cpp_quote("#define INET_E_REDIRECT_FAILED           0x800C0014")
-cpp_quote("#define INET_E_REDIRECT_TO_DIR           0x800C0015")
-cpp_quote("#define INET_E_CANNOT_LOCK_REQUEST       0x800C0016")
+cpp_quote("#define INET_E_ERROR_FIRST               _HRESULT_TYPEDEF_(0x800C0002)")
+cpp_quote("#define INET_E_INVALID_URL               _HRESULT_TYPEDEF_(0x800C0002)")
+cpp_quote("#define INET_E_NO_SESSION                _HRESULT_TYPEDEF_(0x800C0003)")
+cpp_quote("#define INET_E_CANNOT_CONNECT            _HRESULT_TYPEDEF_(0x800C0004)")
+cpp_quote("#define INET_E_RESOURCE_NOT_FOUND        _HRESULT_TYPEDEF_(0x800C0005)")
+cpp_quote("#define INET_E_OBJECT_NOT_FOUND          _HRESULT_TYPEDEF_(0x800C0006)")
+cpp_quote("#define INET_E_DATA_NOT_AVAILABLE        _HRESULT_TYPEDEF_(0x800C0007)")
+cpp_quote("#define INET_E_DOWNLOAD_FAILURE          _HRESULT_TYPEDEF_(0x800C0008)")
+cpp_quote("#define INET_E_AUTHENTICATION_REQUIRED   _HRESULT_TYPEDEF_(0x800C0009)")
+cpp_quote("#define INET_E_NO_VALID_MEDIA            _HRESULT_TYPEDEF_(0x800C000A)")
+cpp_quote("#define INET_E_CONNECTION_TIMEOUT        _HRESULT_TYPEDEF_(0x800C000B)")
+cpp_quote("#define INET_E_INVALID_REQUEST           _HRESULT_TYPEDEF_(0x800C000C)")
+cpp_quote("#define INET_E_UNKNOWN_PROTOCOL          _HRESULT_TYPEDEF_(0x800C000D)")
+cpp_quote("#define INET_E_SECURITY_PROBLEM          _HRESULT_TYPEDEF_(0x800C000E)")
+cpp_quote("#define INET_E_CANNOT_LOAD_DATA          _HRESULT_TYPEDEF_(0x800C000F)")
+cpp_quote("#define INET_E_CANNOT_INSTANTIATE_OBJECT _HRESULT_TYPEDEF_(0x800C0010)")
+cpp_quote("#define INET_E_USE_DEFAULT_PROTOCOLHANDLER _HRESULT_TYPEDEF_(0x800C0011)")
+cpp_quote("#define INET_E_QUERYOPTION_UNKNOWN       _HRESULT_TYPEDEF_(0x800C0013)")
+cpp_quote("#define INET_E_REDIRECT_FAILED           _HRESULT_TYPEDEF_(0x800C0014)")
+cpp_quote("#define INET_E_REDIRECT_TO_DIR           _HRESULT_TYPEDEF_(0x800C0015)")
+cpp_quote("#define INET_E_CANNOT_LOCK_REQUEST       _HRESULT_TYPEDEF_(0x800C0016)")
 cpp_quote("#define INET_E_ERROR_LAST                INET_E_REDIRECT_TO_DIR")
 cpp_quote("#define INET_E_DEFAULT_ACTION            INET_E_USE_DEFAULT_PROTOCOLHANDLER")
 
@@ -1461,6 +1606,10 @@ cpp_quote("#define OInetCombineUrl CoInternetCombineUrl")
 cpp_quote("#define OInetCompareUrl CoInternetCompareUrl")
 cpp_quote("#define OInetGetSession CoInternetGetSession")
 
+cpp_quote("BOOL WINAPI IsLoggingEnabledA(LPCSTR);")
+cpp_quote("BOOL WINAPI IsLoggingEnabledW(LPCWSTR);")
+cpp_quote("#define IsLoggingEnabled WINELIB_NAME_AW(IsLoggingEnabled)")
+
 cpp_quote("#define MKSYS_URLMONIKER 6")
 cpp_quote("#define URL_MK_LEGACY            0")
 cpp_quote("#define URL_MK_UNIFORM           1")
index 2816dc2..638ae53 100644 (file)
@@ -3088,6 +3088,15 @@ typedef struct _CTL_FIND_SUBJECT_PARA
 #define szOID_NETSCAPE_SSL_SERVER_NAME       "2.16.840.1.113730.1.12"
 #define szOID_NETSCAPE_COMMENT               "2.16.840.1.113730.1.13"
 
+/* Bits for szOID_NETSCAPE_CERT_TYPE */
+#define NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE 0x80
+#define NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE 0x40
+#define NETSCAPE_SMIME_CERT_TYPE           0x20
+#define NETSCAPE_SIGN_CERT_TYPE            0x10
+#define NETSCAPE_SSL_CA_CERT_TYPE          0x04
+#define NETSCAPE_SMIME_CA_CERT_TYPE        0x02
+#define NETSCAPE_SIGN_CA_CERT_TYPE         0x01
+
 #define CRYPT_ENCODE_DECODE_NONE             0
 #define X509_CERT                            ((LPCSTR)1)
 #define X509_CERT_TO_BE_SIGNED               ((LPCSTR)2)
index db57802..5edb0ff 100644 (file)
@@ -141,6 +141,15 @@ extern "C" {
 
 #define DECLSPEC_IMPORT __declspec(dllimport)
 #define DECLSPEC_EXPORT __declspec(dllexport)
+#ifndef DECLSPEC_NOINLINE
+#if (_MSC_VER >= 1300)
+#define DECLSPEC_NOINLINE  __declspec(noinline)
+#elif defined(__GNUC__)
+#define DECLSPEC_NOINLINE __attribute__((noinline))
+#else
+#define DECLSPEC_NOINLINE
+#endif
+#endif
 #ifdef __GNUC__
 #define DECLSPEC_NORETURN __declspec(noreturn)
 #define DECLARE_STDCALL_P( type ) __stdcall type
index aee8ca5..873e2b4 100644 (file)
 #include <rpc.h>
 #include <shellapi.h>
 #include <winperf.h>
+#ifndef NOCRYPT
+#include <wincrypt.h>
+#include <winefs.h>
+#include <winscard.h>
+#endif
 #ifndef NOGDI
 #include <commdlg.h>
 #include <winspool.h>
index 7e09905..30ed039 100644 (file)
@@ -1745,7 +1745,7 @@ typedef struct tagPANOSE {
        BYTE bLetterform;
        BYTE bMidline;
        BYTE bXHeight;
-} PANOSE, *LPPANOSE;;
+} PANOSE, *LPPANOSE;
 typedef struct tagLOGFONTA {
        LONG    lfHeight;
        LONG    lfWidth;
index 3a77f51..825e26d 100644 (file)
 /*
- * WinSCard.h
+ * Winscard definitions
  *
- * SmartCard API
+ * 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 SOFTWARE IS NOT COPYRIGHTED
- *
- * This source code is offered for use in the public domain. You may
- * use, modify or distribute it freely.
- *
- * This code is distributed in the hope that it will be useful but
- * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
- * DISCLAIMED. This includes but is not limited to warranties of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#ifndef __WINSCARD_H
-#define __WINSCARD_H
+#ifndef __WINE_WINSCARD_H
+#define __WINE_WINSCARD_H
 
-#include <WinSmCrd.h>
+#include <wtypes.h>
+#include <winioctl.h>
+#include <winsmcrd.h>
+#include <scarderr.h>
 
-#ifdef __cplusplus
-extern "C" {
+#ifndef _LPCBYTE_DEFINED
+#define _LPCBYTE_DEFINED
+typedef const BYTE *LPCBYTE;
 #endif
 
-#define SCARD_S_SUCCESS                 NO_ERROR
-
-#define SCARD_F_INTERNAL_ERROR          ((DWORD)0x80100001)
-#define SCARD_E_CANCELLED               ((DWORD)0x80100002)
-#define SCARD_E_INVALID_HANDLE          ((DWORD)0x80100003)
-#define SCARD_E_INVALID_PARAMETER       ((DWORD)0x80100004)
-#define SCARD_E_INVALID_TARGET          ((DWORD)0x80100005)
-#define SCARD_E_NO_MEMORY               ((DWORD)0x80100006)
-#define SCARD_F_WAITED_TOO_LONG         ((DWORD)0x80100007)
-#define SCARD_E_INSUFFICIENT_BUFFER     ((DWORD)0x80100008)
-#define SCARD_E_UNKNOWN_READER          ((DWORD)0x80100009)
-#define SCARD_E_TIMEOUT                 ((DWORD)0x8010000A)
-#define SCARD_E_SHARING_VIOLATION       ((DWORD)0x8010000B)
-#define SCARD_E_NO_SMARTCARD            ((DWORD)0x8010000C)
-#define SCARD_E_UNKNOWN_CARD            ((DWORD)0x8010000D)
-#define SCARD_E_CANT_DISPOSE            ((DWORD)0x8010000E)
-#define SCARD_E_PROTO_MISMATCH          ((DWORD)0x8010000F)
-#define SCARD_E_NOT_READY               ((DWORD)0x80100010)
-#define SCARD_E_INVALID_VALUE           ((DWORD)0x80100011)
-#define SCARD_E_SYSTEM_CANCELLED        ((DWORD)0x80100012)
-#define SCARD_F_COMM_ERROR              ((DWORD)0x80100013)
-#define SCARD_F_UNKNOWN_ERROR           ((DWORD)0x80100014)
-#define SCARD_E_INVALID_ATR             ((DWORD)0x80100015)
-#define SCARD_E_NOT_TRANSACTED          ((DWORD)0x80100016)
-#define SCARD_E_READER_UNAVAILABLE      ((DWORD)0x80100017)
-#define SCARD_P_SHUTDOWN                ((DWORD)0x80100018)
-#define SCARD_E_PCI_TOO_SMALL           ((DWORD)0x80100019)
-#define SCARD_E_READER_UNSUPPORTED      ((DWORD)0x8010001A)
-#define SCARD_E_DUPLICATE_READER        ((DWORD)0x8010001B)
-#define SCARD_E_CARD_UNSUPPORTED        ((DWORD)0x8010001C)
-#define SCARD_E_NO_SERVICE              ((DWORD)0x8010001D)
-#define SCARD_E_SERVICE_STOPPED         ((DWORD)0x8010001E)
-#define SCARD_E_UNEXPECTED              ((DWORD)0x8010001F)
-#define SCARD_E_ICC_INSTALLATION        ((DWORD)0x80100020)
-#define SCARD_E_ICC_CREATEORDER         ((DWORD)0x80100021)
-#define SCARD_E_UNSUPPORTED_FEATURE     ((DWORD)0x80100022)
-#define SCARD_E_DIR_NOT_FOUND           ((DWORD)0x80100023)
-#define SCARD_E_FILE_NOT_FOUND          ((DWORD)0x80100024)
-#define SCARD_E_NO_DIR                  ((DWORD)0x80100025)
-#define SCARD_E_NO_FILE                 ((DWORD)0x80100026)
-#define SCARD_E_NO_ACCESS               ((DWORD)0x80100027)
-#define SCARD_E_WRITE_TOO_MANY          ((DWORD)0x80100028)
-#define SCARD_E_BAD_SEEK                ((DWORD)0x80100029)
-#define SCARD_E_INVALID_CHV             ((DWORD)0x8010002A)
-#define SCARD_E_UNKNOWN_RES_MNG         ((DWORD)0x8010002B)
-#define SCARD_E_NO_SUCH_CERTIFICATE     ((DWORD)0x8010002C)
-#define SCARD_E_CERTIFICATE_UNAVAILABLE ((DWORD)0x8010002D)
-#define SCARD_E_NO_READERS_AVAILABLE    ((DWORD)0x8010002E)
-#define SCARD_E_COMM_DATA_LOST          ((DWORD)0x8010002F)
-#define SCARD_E_NO_KEY_CONTAINER        ((DWORD)0x80100030)
-#define SCARD_W_UNSUPPORTED_CARD        ((DWORD)0x80100065)
-#define SCARD_W_UNRESPONSIVE_CARD       ((DWORD)0x80100066)
-#define SCARD_W_UNPOWERED_CARD          ((DWORD)0x80100067)
-#define SCARD_W_RESET_CARD              ((DWORD)0x80100068)
-#define SCARD_W_REMOVED_CARD            ((DWORD)0x80100069)
-#define SCARD_W_SECURITY_VIOLATION      ((DWORD)0x8010006A)
-#define SCARD_W_WRONG_CHV               ((DWORD)0x8010006B)
-#define SCARD_W_CHV_BLOCKED             ((DWORD)0x8010006C)
-#define SCARD_W_EOF                     ((DWORD)0x8010006D)
-#define SCARD_W_CANCELLED_BY_USER       ((DWORD)0x8010006E)
-#define SCARD_W_CARD_NOT_AUTHENTICATED  ((DWORD)0x8010006F)
-
-#define SCARD_SHARE_EXCLUSIVE (0x1)
-#define SCARD_SHARE_SHARED    (0x2)
-#define SCARD_SHARE_DIRECT    (0x3)
-
-#define SCARD_LEAVE_CARD   (0x0)
-#define SCARD_RESET_CARD   (0x1)
-#define SCARD_UNPOWER_CARD (0x2)
-#define SCARD_EJECT_CARD   (0x3)
-
-#define SCARD_AUTOALLOCATE   ((DWORD)-1)
-#define SCARD_SCOPE_USER     (0x0)
-#define SCARD_SCOPE_TERMINAL (0x1)
-#define SCARD_SCOPE_SYSTEM   (0x2)
-
-#define SCARD_PROVIDER_PRIMARY (0x1)
-#define SCARD_PROVIDER_CSP     (0x2)
-
 typedef ULONG_PTR SCARDCONTEXT, *PSCARDCONTEXT, *LPSCARDCONTEXT;
-typedef ULONG_PTR SCARDHANDLE, *PSCARDHANDLE, *LPSCARDHANDLE;
-typedef const BYTE *LPCBYTE;
-
-typedef struct _SCARD_READERSTATEA
-{
-  LPCSTR szReader;
-  LPVOID pvUserData;
-  DWORD dwCurrentState;
-  DWORD dwEventState;
-  DWORD cbAtr;
-  BYTE rgbAtr[36];
-} SCARD_READERSTATEA, *PSCARD_READERSTATEA, *LPSCARD_READERSTATEA;
-
-typedef struct _SCARD_READERSTATEW
-{
-  LPCWSTR szReader;
-  LPVOID pvUserData;
-  DWORD dwCurrentState;
-  DWORD dwEventState;
-  DWORD cbAtr;
-  BYTE rgbAtr[36];
-} SCARD_READERSTATEW, *PSCARD_READERSTATEW, *LPSCARD_READERSTATEW;
+typedef ULONG_PTR SCARDHANDLE,  *PSCARDHANDLE,  *LPSCARDHANDLE;
 
 typedef struct _SCARD_ATRMASK
 {
-  DWORD cbAtr;
-  BYTE rgbAtr[36];
-  BYTE rgbMask[36];
+    DWORD cbAtr;
+    BYTE  rgbAtr[36];
+    BYTE  rgbMask[36];
 } SCARD_ATRMASK, *PSCARD_ATRMASK, *LPSCARD_ATRMASK;
 
-HANDLE WINAPI SCardAccessStartedEvent(VOID);
-LONG WINAPI SCardAddReaderToGroupA(SCARDCONTEXT, LPCSTR, LPCSTR);
-LONG WINAPI SCardAddReaderToGroupW(SCARDCONTEXT, LPCWSTR, LPCWSTR);
-LONG WINAPI SCardBeginTransaction(SCARDHANDLE);
-LONG WINAPI SCardCancel(SCARDCONTEXT);
-LONG WINAPI SCardConnectA(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE, LPDWORD);
-LONG WINAPI SCardConnectW(SCARDCONTEXT, LPCWSTR, DWORD, DWORD, LPSCARDHANDLE, LPDWORD);
-LONG WINAPI SCardControl(SCARDHANDLE, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
-LONG WINAPI SCardDisconnect(SCARDHANDLE, DWORD);
-LONG WINAPI SCardEndTransaction(SCARDHANDLE, DWORD);
-LONG WINAPI SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
-LONG WINAPI SCardForgetCardTypeA(SCARDCONTEXT, LPCSTR);
-LONG WINAPI SCardForgetCardTypeW(SCARDCONTEXT, LPCWSTR);
-LONG WINAPI SCardForgetReaderA(SCARDCONTEXT, LPCSTR);
-LONG WINAPI SCardForgetReaderW(SCARDCONTEXT, LPCWSTR);
-LONG WINAPI SCardForgetReaderGroupA(SCARDCONTEXT, LPCSTR);
-LONG WINAPI SCardForgetReaderGroupW(SCARDCONTEXT, LPCWSTR);
-LONG WINAPI SCardFreeMemory(SCARDCONTEXT, LPCVOID);
-LONG WINAPI SCardGetAttrib(SCARDHANDLE, DWORD, LPBYTE, LPDWORD);
-LONG WINAPI SCardGetCardTypeProviderNameA(SCARDCONTEXT, LPCSTR, DWORD, LPSTR, LPDWORD);
-LONG WINAPI SCardGetCardTypeProviderNameW(SCARDCONTEXT, LPCWSTR, DWORD, LPWSTR, LPDWORD);
-LONG WINAPI SCardGetProviderIdA(SCARDCONTEXT, LPCSTR, LPGUID);
-LONG WINAPI SCardGetProviderIdW(SCARDCONTEXT, LPCWSTR, LPGUID);
-LONG WINAPI SCardGetStatusChangeA(SCARDCONTEXT, DWORD, LPSCARD_READERSTATEA, DWORD);
-LONG WINAPI SCardGetStatusChangeW(SCARDCONTEXT, DWORD, LPSCARD_READERSTATEW, DWORD);
-LONG WINAPI SCardIntroduceCardTypeA(SCARDCONTEXT, LPCSTR, LPCGUID, LPCGUID, DWORD, LPCBYTE, LPCBYTE, DWORD);
-LONG WINAPI SCardIntroduceCardTypeW(SCARDCONTEXT, LPCWSTR, LPCGUID, LPCGUID, DWORD, LPCBYTE, LPCBYTE, DWORD);
-LONG WINAPI SCardIntroduceReaderA(SCARDCONTEXT, LPCSTR, LPCSTR);
-LONG WINAPI SCardIntroduceReaderW(SCARDCONTEXT, LPCWSTR, LPCWSTR);
-LONG WINAPI SCardIntroduceReaderGroupA(SCARDCONTEXT, LPCSTR);
-LONG WINAPI SCardIntroduceReaderGroupW(SCARDCONTEXT, LPCWSTR);
-LONG WINAPI SCardIsValidContext(SCARDCONTEXT);
-LONG WINAPI SCardListCardsA(SCARDCONTEXT, LPCBYTE, LPCGUID, DWORD, LPCSTR, LPDWORD);
-LONG WINAPI SCardListCardsW(SCARDCONTEXT, LPCBYTE, LPCGUID, DWORD, LPCWSTR, LPDWORD);
-LONG WINAPI SCardListInterfacesA(SCARDCONTEXT, LPCSTR, LPGUID, LPDWORD);
-LONG WINAPI SCardListInterfacesW(SCARDCONTEXT, LPCWSTR, LPGUID, LPDWORD);
-LONG WINAPI SCardListReaderGroupsA(SCARDCONTEXT, LPSTR, LPDWORD);
-LONG WINAPI SCardListReaderGroupsW(SCARDCONTEXT, LPWSTR, LPDWORD);
-LONG WINAPI SCardListReadersA(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD);
-LONG WINAPI SCardListReadersW(SCARDCONTEXT, LPCWSTR, LPWSTR, LPDWORD);
-LONG WINAPI SCardLocateCardsA(SCARDCONTEXT, LPCSTR, LPSCARD_READERSTATEA, DWORD);
-LONG WINAPI SCardLocateCardsW(SCARDCONTEXT, LPCWSTR, LPSCARD_READERSTATEW, DWORD);
-LONG WINAPI SCardLocateCardsByATRA(SCARDCONTEXT, LPSCARD_ATRMASK, DWORD, LPSCARD_READERSTATEA, DWORD);
-LONG WINAPI SCardLocateCardsByATRW(SCARDCONTEXT, LPSCARD_ATRMASK, DWORD, LPSCARD_READERSTATEW, DWORD);
-LONG WINAPI SCardReconnect(SCARDHANDLE, DWORD, DWORD, DWORD, LPDWORD);
-LONG WINAPI SCardReleaseContext(SCARDCONTEXT);
-VOID WINAPI SCardReleaseStartedEvent(HANDLE);
-LONG WINAPI SCardRemoveReaderFromGroupA(SCARDCONTEXT, LPCSTR, LPCSTR);
-LONG WINAPI SCardRemoveReaderFromGroupW(SCARDCONTEXT, LPCWSTR, LPCWSTR);
-LONG WINAPI SCardSetAttrib(SCARDHANDLE, DWORD, LPCBYTE, DWORD);
-LONG WINAPI SCardSetCardTypeProviderNameA(SCARDCONTEXT, LPCSTR, DWORD, LPCSTR);
-LONG WINAPI SCardSetCardTypeProviderNameW(SCARDCONTEXT, LPCWSTR, DWORD, LPCWSTR);
-LONG WINAPI SCardState(SCARDHANDLE, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
-LONG WINAPI SCardStatusA(SCARDHANDLE, LPSTR, LPDWORD, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
-LONG WINAPI SCardStatusW(SCARDHANDLE, LPWSTR, LPDWORD, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
-LONG WINAPI SCardTransmit(SCARDHANDLE, LPCSCARD_IO_REQUEST, LPCBYTE, DWORD, LPSCARD_IO_REQUEST, LPBYTE, LPDWORD);
-
-#ifndef _DISABLE_TIDENTS
+typedef struct
+{
+    LPCSTR szReader;
+    LPVOID pvUserData;
+    DWORD  dwCurrentState;
+    DWORD  dwEventState;
+    DWORD  cbAtr;
+    BYTE   rgbAtr[36];
+} SCARD_READERSTATEA, *PSCARD_READERSTATEA, *LPSCARD_READERSTATEA;
+typedef struct
+{
+    LPCWSTR szReader;
+    LPVOID  pvUserData;
+    DWORD   dwCurrentState;
+    DWORD   dwEventState;
+    DWORD   cbAtr;
+    BYTE    rgbAtr[36];
+} SCARD_READERSTATEW, *PSCARD_READERSTATEW, *LPSCARD_READERSTATEW;
+DECL_WINELIB_TYPE_AW(SCARD_READERSTATE)
+DECL_WINELIB_TYPE_AW(PSCARD_READERSTATE)
+DECL_WINELIB_TYPE_AW(LPSCARD_READERSTATE)
 
-#ifdef UNICODE
-typedef struct SCARD_READERSTATEW SCARD_READERSTATE, *PSCARD_READERSTATE, *LPSCARD_READERSTATE;
-#define SCardAddReaderToGroup SCardAddReaderToGroupW
-#define SCardConnect SCardConnectW
-#define SCardForgetCardType SCardForgetCardTypeW
-#define SCardForgetReader SCardForgetReaderW
-#define SCardForgetReaderGroup SCardForgetReaderGroupW
-#define SCardGetCardTypeProviderName SCardGetCardTypeProviderNameW
-#define SCardGetProviderId SCardGetProviderIdW
-#define SCardGetStatusChange SCardGetStatusChangeW
-#define SCardIntroduceCardType SCardIntroduceCardTypeW
-#define SCardIntroduceReader SCardIntroduceReaderW
-#define SCardIntroduceReaderGroup SCardIntroduceReaderGroupW
-#define SCardListCards SCardListCardsW
-#define SCardListInterfaces SCardListInterfacesW
-#define SCardListReaderGroups SCardListReaderGroupsW
-#define SCardListReaders SCardListReadersW
-#define SCardLocateCards SCardLocateCardsW
-#define SCardLocateCardsByATR SCardLocateCardsByATRW
-#define SCardRemoveReaderFromGroup SCardRemoveReaderFromGroupW
-#define SCardSetCardTypeProviderName SCardSetCardTypeProviderNameW
-#define SCardStatus SCardStatusW
-#else /* !UNICODE */
-typedef struct SCARD_READERSTATEA SCARD_READERSTATE, *PSCARD_READERSTATE, *LPSCARD_READERSTATE;
-#define SCardAddReaderToGroup SCardAddReaderToGroupA
-#define SCardConnect SCardConnectA
-#define SCardForgetCardType SCardForgetCardTypeA
-#define SCardForgetReader SCardForgetReaderA
-#define SCardForgetReaderGroup SCardForgetReaderGroupA
-#define SCardGetCardTypeProviderName SCardGetCardTypeProviderNameA
-#define SCardGetProviderId SCardGetProviderIdA
-#define SCardGetStatusChange SCardGetStatusChangeA
-#define SCardIntroduceCardType SCardIntroduceCardTypeA
-#define SCardIntroduceReader SCardIntroduceReaderA
-#define SCardIntroduceReaderGroup SCardIntroduceReaderGroupA
-#define SCardListCards SCardListCardsA
-#define SCardListInterfaces SCardListInterfacesA
-#define SCardListReaderGroups SCardListReaderGroupsA
-#define SCardListReaders SCardListReadersA
-#define SCardLocateCards SCardLocateCardsA
-#define SCardLocateCardsByATR SCardLocateCardsByATRA
-#define SCardRemoveReaderFromGroup SCardRemoveReaderFromGroupA
-#define SCardSetCardTypeProviderName SCardSetCardTypeProviderNameA
-#define SCardStatus SCardStatusA
-#endif /* UNICODE */
 
-#endif /* _DISABLE_TIDENTS */
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-extern const SCARD_IO_REQUEST g_rgSCardT0Pci;
-extern const SCARD_IO_REQUEST g_rgSCardT1Pci;
-extern const SCARD_IO_REQUEST g_rgSCardRawPci;
+HANDLE      WINAPI SCardAccessStartedEvent(void);
+LONG        WINAPI SCardAddReaderToGroupA(SCARDCONTEXT,LPCSTR,LPCSTR);
+LONG        WINAPI SCardAddReaderToGroupW(SCARDCONTEXT,LPCWSTR,LPCWSTR);
+#define     SCardAddReaderToGroup WINELIB_NAME_AW(SCardAddReaderToGroup)
+LONG        WINAPI SCardBeginTransaction(SCARDHANDLE);
+LONG        WINAPI SCardCancel(SCARDCONTEXT);
+LONG        WINAPI SCardConnectA(SCARDCONTEXT,LPCSTR,DWORD,DWORD,LPSCARDHANDLE,LPDWORD);
+LONG        WINAPI SCardConnectW(SCARDCONTEXT,LPCWSTR,DWORD,DWORD,LPSCARDHANDLE,LPDWORD);
+#define     SCardConnect WINELIB_NAME_AW(SCardConnect)
+LONG        WINAPI SCardControl(SCARDHANDLE,DWORD,LPCVOID,DWORD,LPVOID,DWORD,LPDWORD);
+LONG        WINAPI SCardDisconnect(SCARDHANDLE,DWORD);
+LONG        WINAPI SCardEndTransaction(SCARDHANDLE,DWORD);
+LONG        WINAPI SCardEstablishContext(DWORD,LPCVOID,LPCVOID,LPSCARDCONTEXT);
+LONG        WINAPI SCardForgetCardTypeA(SCARDCONTEXT,LPCSTR);
+LONG        WINAPI SCardForgetCardTypeW(SCARDCONTEXT,LPCWSTR);
+#define     SCardForgetCardType WINELIB_NAME_AW(SCardForgetCardType)
+LONG        WINAPI SCardForgetReaderA(SCARDCONTEXT,LPCSTR);
+LONG        WINAPI SCardForgetReaderW(SCARDCONTEXT,LPCWSTR);
+#define     SCardForgetReader WINELIB_NAME_AW(SCardForgetReader)
+LONG        WINAPI SCardForgetReaderGroupA(SCARDCONTEXT,LPCSTR);
+LONG        WINAPI SCardForgetReaderGroupW(SCARDCONTEXT,LPCWSTR);
+#define     SCardForgetReaderGroup WINELIB_NAME_AW(SCardForgetReaderGroup)
+LONG        WINAPI SCardFreeMemory(SCARDCONTEXT,LPCVOID);
+LONG        WINAPI SCardGetAttrib(SCARDHANDLE,DWORD,LPBYTE,LPDWORD);
+LONG        WINAPI SCardGetCardTypeProviderNameA(SCARDCONTEXT,LPCSTR,DWORD,LPSTR,LPDWORD);
+LONG        WINAPI SCardGetCardTypeProviderNameW(SCARDCONTEXT,LPCWSTR,DWORD,LPWSTR,LPDWORD);
+#define     SCardGetCardTypeProviderName WINELIB_NAME_AW(SCardGetCardTypeProviderName)
+LONG        WINAPI SCardGetProviderIdA(SCARDCONTEXT,LPCSTR,LPGUID);
+LONG        WINAPI SCardGetProviderIdW(SCARDCONTEXT,LPCWSTR,LPGUID);
+#define     SCardGetProviderId WINELIB_NAME_AW(SCardGetProviderId)
+LONG        WINAPI SCardGetStatusChangeA(SCARDCONTEXT,DWORD,LPSCARD_READERSTATEA,DWORD);
+LONG        WINAPI SCardGetStatusChangeW(SCARDCONTEXT,DWORD,LPSCARD_READERSTATEW,DWORD);
+#define     SCardGetStatusChange WINELIB_NAME_AW(SCardGetStatusChange)
+LONG        WINAPI SCardIntroduceCardTypeA(SCARDCONTEXT,LPCSTR,LPCGUID,LPCGUID,DWORD,LPCBYTE,LPCBYTE,DWORD);
+LONG        WINAPI SCardIntroduceCardTypeW(SCARDCONTEXT,LPCWSTR,LPCGUID,LPCGUID,DWORD,LPCBYTE,LPCBYTE,DWORD);
+#define     SCardIntroduceCardType WINELIB_NAME_AW(SCardIntroduceCardType)
+LONG        WINAPI SCardIntroduceReaderA(SCARDCONTEXT,LPCSTR,LPCSTR);
+LONG        WINAPI SCardIntroduceReaderW(SCARDCONTEXT,LPCWSTR,LPCWSTR);
+#define     SCardIntroduceReader WINELIB_NAME_AW(SCardIntroduceReader)
+LONG        WINAPI SCardIntroduceReaderGroupA(SCARDCONTEXT,LPCSTR);
+LONG        WINAPI SCardIntroduceReaderGroupW(SCARDCONTEXT,LPCWSTR);
+#define     SCardIntroduceReaderGroup WINELIB_NAME_AW(SCardIntroduceReaderGroup)
+LONG        WINAPI SCardIsValidContext(SCARDCONTEXT);
+LONG        WINAPI SCardListCardsA(SCARDCONTEXT,LPCBYTE,LPCGUID,DWORD,LPSTR,LPDWORD);
+LONG        WINAPI SCardListCardsW(SCARDCONTEXT,LPCBYTE,LPCGUID,DWORD,LPWSTR,LPDWORD);
+#define     SCardListCards WINELIB_NAME_AW(SCardListCards)
+LONG        WINAPI SCardListInterfacesA(SCARDCONTEXT,LPCSTR,LPGUID,LPDWORD);
+LONG        WINAPI SCardListInterfacesW(SCARDCONTEXT,LPCWSTR,LPGUID,LPDWORD);
+#define     SCardListInterfaces WINELIB_NAME_AW(SCardListInterfaces)
+LONG        WINAPI SCardListReadersA(SCARDCONTEXT,LPCSTR,LPSTR,LPDWORD);
+LONG        WINAPI SCardListReadersW(SCARDCONTEXT,LPCWSTR,LPWSTR,LPDWORD);
+#define     SCardListReaders WINELIB_NAME_AW(SCardListReaders)
+LONG        WINAPI SCardListReaderGroupsA(SCARDCONTEXT,LPSTR,LPDWORD);
+LONG        WINAPI SCardListReaderGroupsW(SCARDCONTEXT,LPWSTR,LPDWORD);
+#define     SCardListReaderGroups WINELIB_NAME_AW(SCardListReaderGroups)
+LONG        WINAPI SCardLocateCardsA(SCARDCONTEXT,LPCSTR,LPSCARD_READERSTATEA,DWORD);
+LONG        WINAPI SCardLocateCardsW(SCARDCONTEXT,LPCWSTR,LPSCARD_READERSTATEW,DWORD);
+#define     SCardLocateCards WINELIB_NAME_AW(SCardLocateCards)
+LONG        WINAPI SCardLocateCardsByATRA(SCARDCONTEXT,LPSCARD_ATRMASK,DWORD,LPSCARD_READERSTATEA,DWORD);
+LONG        WINAPI SCardLocateCardsByATRW(SCARDCONTEXT,LPSCARD_ATRMASK,DWORD,LPSCARD_READERSTATEW,DWORD);
+#define     SCardLocateCardsByATR WINELIB_NAME_AW(SCardLocateCardsByATR)
+LONG        WINAPI SCardReconnect(SCARDHANDLE,DWORD,DWORD,DWORD,LPDWORD);
+LONG        WINAPI SCardReleaseContext(SCARDCONTEXT);
+void        WINAPI SCardReleaseStartedEvent(HANDLE);
+LONG        WINAPI SCardRemoveReaderFromGroupA(SCARDCONTEXT,LPCSTR,LPCSTR);
+LONG        WINAPI SCardRemoveReaderFromGroupW(SCARDCONTEXT,LPCWSTR,LPCWSTR);
+#define     SCardRemoveReaderFromGroup WINELIB_NAME_AW(SCardRemoveReaderFromGroup)
+LONG        WINAPI SCardSetAttrib(SCARDHANDLE,DWORD,LPCBYTE,DWORD);
+LONG        WINAPI SCardSetCardTypeProviderNameA(SCARDCONTEXT,LPCSTR,DWORD,LPCSTR);
+LONG        WINAPI SCardSetCardTypeProviderNameW(SCARDCONTEXT,LPCWSTR,DWORD,LPCWSTR);
+#define     SCardSetCardTypeProviderName WINELIB_NAME_AW(SCardSetCardTypeProviderName)
+LONG        WINAPI SCardState(SCARDHANDLE,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
+LONG        WINAPI SCardStatusA(SCARDHANDLE,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
+LONG        WINAPI SCardStatusW(SCARDHANDLE,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
+#define     SCardStatus WINELIB_NAME_AW(SCardStatus)
+LONG        WINAPI SCardTransmit(SCARDHANDLE,LPCSCARD_IO_REQUEST,LPCBYTE,DWORD,LPSCARD_IO_REQUEST,LPBYTE,LPDWORD);
 
 #ifdef __cplusplus
 }
 #endif
-#endif /* __WINSCARD_H */
 
-/* EOF */
+#endif  /* __WINE_WINSCARD_H */
index 3157063..e26c9a8 100644 (file)
@@ -35,7 +35,7 @@ typedef struct _SCARD_T0_COMMAND
   BYTE bIns;
   BYTE P1;
   BYTE P2;
-  BYTE P3
+  BYTE P3;
 } SCARD_T0_COMMAND, *PSCARD_T0_COMMAND, *LPSCARD_T0_COMMAND;
 
 typedef struct _SCARD_T0_REQUEST
@@ -55,7 +55,7 @@ typedef struct _SCARD_T1_REQUEST
   SCARD_IO_REQUEST ioRequest;
 } SCARD_T1_REQUEST, *PSCARD_T1_REQUEST, *LPSCARD_T1_REQUEST;
 
-#define FILE_DEVICE_SMARTCARD (0x00000031)
+#define FILE_DEVICE_SMARTCARD 49
 
 #define SCARD_ATR_LENGTH (0x21)
 
index 5408ad4..228d868 100644 (file)
@@ -260,7 +260,7 @@ struct _CRYPT_PROVIDER_DATA;
 
 #define TRUSTERROR_MAX_STEPS                   38
 
-typedef void * (WINAPI *PFN_CPD_MEM_ALLOC)(DWORD cbSize);
+typedef void * (__WINE_ALLOC_SIZE(1) WINAPI *PFN_CPD_MEM_ALLOC)(DWORD cbSize);
 typedef void (WINAPI *PFN_CPD_MEM_FREE)(void *pvMem2Free);
 typedef BOOL (WINAPI *PFN_CPD_ADD_STORE)(struct _CRYPT_PROVIDER_DATA *pProvData,
  HCERTSTORE hStore2Add);
@@ -385,6 +385,10 @@ typedef struct _CRYPT_PROVUI_FUNCS {
 
 #include <poppack.h>
 
+#define WVT_OFFSETOF(t,f)     ((ULONG)((ULONG_PTR)(&((t*)0)->f)))
+#define WVT_ISINSTRUCT(t,s,f) (WVT_OFFSETOF(t,f) + sizeof(((t*)0)->f) <= (s))
+#define WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(t,s,f) WVT_ISINSTRUCT(t,s,f)
+
 #define WTPF_TRUSTTEST            0x00000020
 #define WTPF_TESTCANBEVALID       0x00000080
 #define WTPF_IGNOREEXPIRATION     0x00000100
index 9cd411c..01f878c 100644 (file)
@@ -1849,6 +1849,7 @@ extern "C" {
 #define EM_CHARFROMPOS 215
 #define EM_EMPTYUNDOBUFFER 205
 #define EM_FMTLINES 200
+#define EM_GETIMESTATUS 217
 #define EM_GETFIRSTVISIBLELINE 206
 #define EM_GETHANDLE 189
 #define EM_GETLIMITTEXT 213
@@ -1871,6 +1872,7 @@ extern "C" {
 #define EM_SCROLL 181
 #define EM_SCROLLCARET 183
 #define EM_SETHANDLE 188
+#define EM_SETIMESTATUS 216
 #define EM_SETLIMITTEXT 197
 #define EM_SETMARGINS 211
 #define EM_SETMODIFY 185
index 1a45c2e..ab3d613 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef KJK_PSEH2_H_
 #define KJK_PSEH2_H_
 
+#if defined(__GNUC__)
 struct _EXCEPTION_RECORD;
 struct _EXCEPTION_POINTERS;
 struct _CONTEXT;
@@ -76,8 +77,6 @@ extern void __cdecl _SEH2Return(void);
 }
 #endif
 
-#if defined(__GNUC__)
-
 #if defined(__i386__)
 typedef struct __SEHTrampoline
 {
@@ -139,9 +138,6 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
 #define ___SEH_STRINGIFY(X_) # X_
 #define __SEH_STRINGIFY(X_) ___SEH_STRINGIFY(X_)
 
-#define __SEH_FORCE_NEST \
-       __asm__ __volatile__("#%0" : : "r" (&_SEHFrame))
-
 #define __SEH_EXCEPT_RET long
 #define __SEH_EXCEPT_ARGS __attribute__((unused)) _SEH2Frame_t * _SEH2FrameP, __attribute__((unused)) struct _EXCEPTION_POINTERS * _SEHExceptionInformation
 #define __SEH_EXCEPT_ARGS_ , __SEH_EXCEPT_ARGS
@@ -206,25 +202,28 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
                        __label__ _SEHDoTry; \
                        __label__ _SEHAfterTry; \
                        static const int _SEH2ScopeKind = 0; \
-                       _SEH2Frame_t _SEHFrame; \
                        volatile _SEH2TryLevel_t _SEHTryLevel; \
-                       _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? &_SEHFrame : _SEHCurFrameP; \
+                       void * _SEHStackPointer; \
                        volatile _SEH2TryLevel_t * const _SEH2TryLevelP = &_SEHTryLevel; \
+                       _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? \
+                               ({ __asm__ __volatile__("mov %%esp, %0" : "=g" (_SEHStackPointer)); __builtin_alloca(sizeof(_SEH2Frame_t)); }) : \
+                               _SEHCurFrameP; \
  \
                        (void)_SEH2ScopeKind; \
-                       (void)_SEHFrame; \
                        (void)_SEHTryLevel; \
+                       (void)_SEHStackPointer; \
                        (void)_SEH2FrameP; \
                        (void)_SEH2TryLevelP; \
+ \
+                       if(_SEHTopTryLevel) \
+                               _SEH2EnterFrame(_SEH2FrameP); \
  \
                        _SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \
                        goto _SEHBeforeTry; \
  \
                        _SEHDoTry:; \
-                       __SEH_ENTER_TRYLEVEL(); \
  \
-                       if(_SEHTopTryLevel) \
-                               _SEH2EnterFrame(&_SEHFrame); \
+                       __SEH_ENTER_TRYLEVEL();
 
 #define __SEH_END_SCOPE \
                } \
@@ -350,7 +349,10 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
  \
                _SEHAfterTry:; \
                if(_SEHTopTryLevel) \
+               { \
                        _SEH2LeaveFrame(); \
+                       __asm__ __volatile__("mov %0, %%esp" : : "g" (_SEHStackPointer)); \
+               } \
                else \
                { \
                        __SEH_LEAVE_TRYLEVEL(); \
index 69e1b7c..98eab10 100644 (file)
@@ -21,7 +21,7 @@
 #define KERNEL_VERSION_MINOR        4
 #define KERNEL_VERSION_PATCH_LEVEL  0
 
-#define COPYRIGHT_YEAR              "2008"
+#define COPYRIGHT_YEAR              "2009"
 
 /* KERNEL_VERSION_BUILD_TYPE is L"SVN", L"RC1", L"RC2" or L"" (for the release) */
 #define KERNEL_VERSION_BUILD_TYPE   L"SVN"
index d48b672..e4f02e7 100644 (file)
 
 /* Define to 1 if the system has the type `pid_t'. */
 #if !defined(_MSC_VER)
-//#define HAVE_PID_T 1
+#define HAVE_PID_T 1
 #endif
 
 /* Define to 1 if you have the <poll.h> header file. */
index 44f0988..2bff22e 100644 (file)
@@ -42,6 +42,7 @@
 #define vsprintfW vswprintf
 #define snprintfW _snwprintf
 #define vsnprintfW _vsnwprintf
+#define isprintW iswprint
 
 #ifndef WINE_UNICODE_API
 #define WINE_UNICODE_API __attribute__((dllimport))
index 22396f5..299405a 100644 (file)
@@ -104,7 +104,7 @@ static char              gMutexesInUse[MAX_MUTEXES];
  *
  *-------------------------------------------------------------*/
 static CRITICAL_SECTION  gMutexes[MAX_MUTEXES];
-static CRITICAL_SECTION  gGlobalWinMutex;
+/* static */ CRITICAL_SECTION  gGlobalWinMutex;
 
 
 /* On WIN32 mutexes are reentrant.  This makes it difficult to debug
index d8bea38..f2113b7 100644 (file)
@@ -1314,7 +1314,7 @@ UnicodeString::cloneArrayIfNeeded(int32_t newCapacity,
    */
   if(forceClone ||
      fFlags & kBufferIsReadonly ||
-     fFlags & kRefCounted && refCount() > 1 ||
+     (fFlags & kRefCounted && refCount() > 1) ||
      newCapacity > fCapacity
   ) {
     // save old values
@@ -1330,7 +1330,7 @@ UnicodeString::cloneArrayIfNeeded(int32_t newCapacity,
 
     // allocate a new array
     if(allocate(growCapacity) ||
-       newCapacity < growCapacity && allocate(newCapacity)
+       (newCapacity < growCapacity && allocate(newCapacity))
     ) {
       if(doCopyArray) {
         // copy the contents
@@ -1377,7 +1377,7 @@ The vector deleting destructor is already a part of UObject,
 but defining it here makes sure that it is included with this object file.
 This makes sure that static library dependencies are kept to a minimum.
 */
-static void uprv_UnicodeStringDummy(void) {
+/* static */ void uprv_UnicodeStringDummy(void) {
     U_NAMESPACE_USE
     delete [] (new UnicodeString[2]);
 }
index 24c85e8..aee0bc5 100644 (file)
@@ -98,10 +98,12 @@ struct name {                                                               \
        struct type *slh_first; /* first element */                     \
 }
 
+#if 0
 #define SLIST_ENTRY(type)                                              \
 struct {                                                               \
        struct type *sle_next;  /* next element */                      \
 }
+#endif
 
 /*
  * Singly-linked List functions.
index 1e6a817..98b73e4 100644 (file)
@@ -132,7 +132,7 @@ void        printf __P((const char *, ...));
 static __inline int bsd_log ( int blah, const char* fmt, ... )
 {
        va_list arg;
-       int i;
+       int i = 0;
        va_start(arg, fmt);
 #ifndef __NTDRIVER__
        i = vprintf ( fmt, arg );
@@ -238,10 +238,14 @@ struct execve_args {
        char    **envv;
 };
 int    execve __P((struct proc *, struct execve_args *, int *retval));
+
+#if 0
 struct fork_args {
        int     dummy;
 };
 int    fork __P((struct proc *, struct fork_args *, int retval[]));
+#endif
+
 struct sync_args {
        int     dummy;
 };
index f3bad2a..354e7e6 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef _OSKITFREEBSD_H
 #define _OSKITFREEBSD_H
 
+// Hacky? Yep
+#undef PAGE_SIZE
+#undef PAGE_SHIFT
 #include <ntddk.h>
 
 #ifdef linux
index cb66bd2..d90a964 100644 (file)
@@ -102,7 +102,7 @@ in_pcbbind(inp, nam)
 
        OS_DbgPrint(OSK_MID_TRACE,("Called\n"));
 
-       if( nam ) OskitDumpBuffer( nam->m_data, nam->m_len );
+       if( nam ) OskitDumpBuffer((OSK_PCHAR)nam->m_data, nam->m_len );
 
 #ifndef __REACTOS__
        if (in_ifaddr == 0) {
index fb44beb..33b2d93 100644 (file)
@@ -35,12 +35,12 @@ int _snprintf(char * buf, size_t cnt, const char *fmt, ...);
 void *fbsd_malloc( unsigned int bytes, char *file, unsigned line, ... ) {
     if( !OtcpEvent.TCPMalloc ) panic("no malloc");
     return OtcpEvent.TCPMalloc
-       ( OtcpEvent.ClientData, (OSK_UINT)bytes, file, line );
+       ( OtcpEvent.ClientData, (OSK_UINT)bytes, (OSK_PCHAR)file, line );
 }
 
 void fbsd_free( void *data, char *file, unsigned line, ... ) {
     if( !OtcpEvent.TCPFree ) panic("no free");
-    OtcpEvent.TCPFree( OtcpEvent.ClientData, data, file, line );
+    OtcpEvent.TCPFree( OtcpEvent.ClientData, data, (OSK_PCHAR)file, line );
 }
 
 void InitOskitTCP() {
@@ -155,7 +155,7 @@ int OskitTCPRecv( void *connection,
     uio.uio_rw = UIO_READ;
     uio.uio_iovcnt = 1;
     iov.iov_len = Len;
-    iov.iov_base = Data;
+    iov.iov_base = (char *)Data;
 
     OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
 
@@ -260,7 +260,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
     struct iovec iov;
 
     iov.iov_len = Len;
-    iov.iov_base = Data;
+    iov.iov_base = (char *)Data;
     uio.uio_iov = &iov;
     uio.uio_iovcnt = 1;
     uio.uio_offset = 0;
@@ -406,7 +406,7 @@ out:
 
 void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
                              OSK_UINT IpHeaderLen ) {
-    struct mbuf *Ip = m_devget( Data, Len, 0, NULL, NULL );
+    struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL );
     struct ip *iph;
 
     if( !Ip ) return; /* drop the segment */
index a43def5..709b6b1 100644 (file)
@@ -88,7 +88,7 @@ ip_output(m0, opt, ro, flags, imo)
 #endif
        register struct mbuf *m = m0;
        register int hlen = sizeof (struct ip);
-       int len, off, error = 0;
+       int len = 0, off, error = 0;
        /*
         * It might seem obvious at first glance that one could easily
         * make a one-behind cache out of this by simply making `iproute'
@@ -108,7 +108,7 @@ ip_output(m0, opt, ro, flags, imo)
         */
        struct route iproute;
        struct sockaddr_in *dst;
-       struct in_ifaddr *ia;
+       struct in_ifaddr *ia = NULL;
 
 #ifdef DIAGNOSTIC
        if ((m->m_flags & M_PKTHDR) == 0)
@@ -380,7 +380,7 @@ sendit:
                m_copydata( m, 0, htons(ip->ip_len), new_m->m_data );
                new_m->m_len = htons(ip->ip_len);
                error = OtcpEvent.PacketSend( OtcpEvent.ClientData,
-                                             new_m->m_data, new_m->m_len );
+                                             (OSK_PCHAR)new_m->m_data, new_m->m_len );
                m_free( new_m );
                goto done;
            }
@@ -520,7 +520,7 @@ sendorfree:
            m_copydata( m, 0, htons(ip->ip_len), new_m->m_data );
            new_m->m_len = htons(ip->ip_len);
            error = OtcpEvent.PacketSend( OtcpEvent.ClientData,
-                                         new_m->m_data, new_m->m_len );
+                                         (OSK_PCHAR)new_m->m_data, new_m->m_len );
            m_free( new_m );
            goto done;
        }
index f796f8a..248b8bc 100644 (file)
@@ -486,7 +486,7 @@ findpcb:
         * else do it below (after getting remote address).
         */
        if (tp->t_state != TCPS_LISTEN)
-               tcp_dooptions(tp, optp, optlen, ti, &to);
+               tcp_dooptions(tp, (u_char *)optp, optlen, ti, &to);
 
        /*
         * Header prediction: check for the two common cases
@@ -687,7 +687,7 @@ findpcb:
                        taop = &tao_noncached;
                        bzero(taop, sizeof(*taop));
                }
-               tcp_dooptions(tp, optp, optlen, ti, &to);
+               tcp_dooptions(tp, (u_char *)optp, optlen, ti, &to);
                if (iss)
                        tp->iss = iss;
                else
@@ -1974,7 +1974,7 @@ tcp_mss(tp, offer)
        int offer;
 {
        register struct rtentry *rt;
-       struct ifnet *ifp;
+       struct ifnet *ifp = NULL;
        register int rtt, mss;
        u_long bufsize;
        struct inpcb *inp;
index 8b022ca..b43af11 100644 (file)
@@ -142,6 +142,8 @@ bool zero_blocks(PEXT2_FILESYS fs, ULONG blk, ULONG num,
         if (!buf)
         {
             DPRINT1("Mke2fs: while allocating zeroizing buffer");
+            if (ret_blk)
+                *ret_blk = blk;
             return false;
         }
         memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
index d69f788..7dc7287 100644 (file)
@@ -40,7 +40,7 @@
 
 extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *);
 extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
-extern int __cdecl __SEH2NestedHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
+extern int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
 
 FORCEINLINE
 _SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void)
@@ -134,8 +134,18 @@ void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
        }
 }
 
+typedef struct __SEH2UnwindFrame
+{
+       _SEH2Registration_t SUF_Registration;
+       _SEH2Frame_t * SUF_Frame;
+       volatile _SEH2TryLevel_t * SUF_TargetTryLevel;
+}
+_SEH2UnwindFrame_t;
+
+static void _SEH2LocalUnwind(_SEH2Frame_t *, volatile _SEH2TryLevel_t *);
+
 extern
-int __cdecl _SEH2NestedHandler
+int __cdecl _SEH2UnwindHandler
 (
        struct _EXCEPTION_RECORD * ExceptionRecord,
        void * EstablisherFrame,
@@ -144,25 +154,33 @@ int __cdecl _SEH2NestedHandler
 )
 {
        if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING))
-               return ExceptionContinueSearch;
+       {
+               _SEH2UnwindFrame_t * unwindframe = CONTAINING_RECORD(EstablisherFrame, _SEH2UnwindFrame_t, SUF_Registration);
+               _SEH2LocalUnwind(unwindframe->SUF_Frame, unwindframe->SUF_TargetTryLevel);
+               *((void **)DispatcherContext) = EstablisherFrame;
+               return ExceptionCollidedUnwind;
+       }
 
-       *((void **)DispatcherContext) = EstablisherFrame;
-       return ExceptionCollidedUnwind;
+       return ExceptionContinueSearch;
 }
 
 static
 void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel)
 {
        volatile _SEH2TryLevel_t * trylevel;
-       _SEH2Registration_t nestedframe;
+       _SEH2UnwindFrame_t unwindframe;
+
+       unwindframe.SUF_Frame = frame;
+       unwindframe.SUF_TargetTryLevel = dsttrylevel;
 
-       nestedframe.SER_Handler = &__SEH2NestedHandler;
-       __SEH2EnterFrame(&nestedframe);
+       unwindframe.SUF_Registration.SER_Handler = &__SEH2UnwindHandler;
+       __SEH2EnterFrame(&unwindframe.SUF_Registration);
 
        for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel != dsttrylevel; trylevel = trylevel->ST_Next)
+       {
+               frame->SF_TopTryLevel = trylevel->ST_Next;
                _SEH2Finally(frame, trylevel);
-
-       frame->SF_TopTryLevel = dsttrylevel;
+       }
 
        __SEH2LeaveFrame();
 }
@@ -223,6 +241,7 @@ extern
 void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame)
 {
        frame->SF_Registration.SER_Handler = __SEH2FrameHandler;
+       frame->SF_TopTryLevel = 0;
        frame->SF_Code = 0;
        __SEH2EnterFrame(&frame->SF_Registration);
 }
index d60f6cf..f529b43 100644 (file)
@@ -40,14 +40,14 @@ ___SEH2FrameHandler:
        jmp __SEH2FrameHandler
 .endfunc
 
-.func __SEH2NestedHandler
-.globl ___SEH2NestedHandler
-___SEH2NestedHandler:
+.func __SEH2UnwindHandler
+.globl ___SEH2UnwindHandler
+___SEH2UnwindHandler:
 
-.extern __SEH2NestedHandler
+.extern __SEH2UnwindHandler
 
        cld
-       jmp __SEH2NestedHandler
+       jmp __SEH2UnwindHandler
 .endfunc
 
 // EOF
index 3601580..69f0687 100644 (file)
@@ -764,9 +764,12 @@ RtlNumberOfSetBits(PRTL_BITMAP BitMapHeader)
       lpOut++;
     }
 
-    bMasked = *lpOut & NTDLL_maskBits[ulRemainder];
-    ulSet += NTDLL_nibbleBitCount[bMasked >> 4];
-    ulSet += NTDLL_nibbleBitCount[bMasked & 0xf];
+    if (ulRemainder)
+    {
+      bMasked = *lpOut & NTDLL_maskBits[ulRemainder];
+      ulSet += NTDLL_nibbleBitCount[bMasked >> 4];
+      ulSet += NTDLL_nibbleBitCount[bMasked & 0xf];
+    }
   }
   return ulSet;
 }
@@ -848,7 +851,8 @@ RtlSetBits(PRTL_BITMAP BitMapHeader,
   }
 
   /* Set remaining bits, if any */
-  *lpOut |= NTDLL_maskBits[NumberToSet & 0x7];
+  if (NumberToSet & 0x7)
+    *lpOut |= NTDLL_maskBits[NumberToSet & 0x7];
 }
 
 
index ffb1339..c54a0ff 100644 (file)
@@ -23,7 +23,7 @@ PEPROCESS ExpDefaultErrorPortProcess = NULL;
 /* FUNCTIONS ****************************************************************/
 
 /*++
-* @name ExpRaiseHardError
+* @name ExpSystemErrorHandler
 *
 * For now it's a stub
 *
index 0fdeb30..65cef59 100644 (file)
@@ -220,7 +220,7 @@ NtCreateProfile(OUT PHANDLE ProfileHandle,
     if (!NT_SUCCESS(Status))
     {
         /* Dereference the process object if it was specified */
-        if (Process) ObDereferenceObject(Process);
+        if (pProcess) ObDereferenceObject(pProcess);
 
         /* Return Status */
         return Status;
index 10f04fa..39a1983 100644 (file)
@@ -1158,7 +1158,10 @@ QSI_DEF(SystemFileCacheInformation)
                MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE;
        Sci->PeakSize =
                MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE; /* FIXME */
-
+       /* Taskmgr multiplies this one by page size right away */
+       Sci->CurrentSizeIncludingTransitionInPages =
+               MiMemoryConsumers[MC_CACHE].PagesUsed; /* FIXME: Should be */
+       /* system working set and standby pages. */
        Sci->PageFaultCount = 0; /* FIXME */
        Sci->MinimumWorkingSet = 0; /* FIXME */
        Sci->MaximumWorkingSet = 0; /* FIXME */
@@ -1373,25 +1376,38 @@ SSI_DEF(SystemUnloadGdiDriverInformation)
 /* Class 28 - Time Adjustment Information */
 QSI_DEF(SystemTimeAdjustmentInformation)
 {
-       if (sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION) > Size)
-       {
-               * ReqSize = sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION);
-               return (STATUS_INFO_LENGTH_MISMATCH);
-       }
-       /* FIXME: */
-       DPRINT1("NtQuerySystemInformation - SystemTimeAdjustmentInformation not implemented\n");
-       return (STATUS_NOT_IMPLEMENTED);
+    PSYSTEM_QUERY_TIME_ADJUST_INFORMATION TimeInfo =
+        (PSYSTEM_QUERY_TIME_ADJUST_INFORMATION)Buffer;
+
+    /* Check if enough storage was provided */
+    if (sizeof(SYSTEM_QUERY_TIME_ADJUST_INFORMATION) > Size)
+    {
+        * ReqSize = sizeof(SYSTEM_SET_TIME_ADJUST_INFORMATION);
+        return STATUS_INFO_LENGTH_MISMATCH;
+    }
+
+    /* Give time values to our caller */
+    TimeInfo->TimeIncrement = KeMaximumIncrement;
+    TimeInfo->TimeAdjustment = KeTimeAdjustment;
+    TimeInfo->Enable = TRUE;
+
+    return STATUS_SUCCESS;
 }
 
 SSI_DEF(SystemTimeAdjustmentInformation)
 {
-       if (sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION) > Size)
-       {
-               return (STATUS_INFO_LENGTH_MISMATCH);
-       }
-       /* FIXME: */
-       DPRINT1("NtSetSystemInformation - SystemTimeAdjustmentInformation not implemented\n");
-       return (STATUS_NOT_IMPLEMENTED);
+    /*PSYSTEM_SET_TIME_ADJUST_INFORMATION TimeInfo =
+        (PSYSTEM_SET_TIME_ADJUST_INFORMATION)Buffer;*/
+
+    /* Check size of a buffer, it must match our expectations */
+    if (sizeof(SYSTEM_SET_TIME_ADJUST_INFORMATION) != Size)
+        return STATUS_INFO_LENGTH_MISMATCH;
+
+    /* TODO: Check privileges */
+
+    /* TODO: Set time adjustment information */
+    DPRINT1("Setting of SystemTimeAdjustmentInformation is not implemented yet!\n");
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 /* Class 29 - Summary Memory Information */
index cf60cd2..7ff8a4b 100644 (file)
@@ -153,6 +153,7 @@ extern PVOID KeRaiseUserExceptionDispatcher;
 extern UCHAR KiDebugRegisterTrapOffsets[9];
 extern UCHAR KiDebugRegisterContextOffsets[9];
 extern ULONG KeTimeIncrement;
+extern ULONG KeTimeAdjustment;
 extern ULONG_PTR KiBugCheckData[5];
 extern ULONG KiFreezeFlag;
 extern ULONG KiDPCTimeout;
index a5e81b9..86325a4 100644 (file)
@@ -390,10 +390,6 @@ typedef VOID
 
 /* marea.c *******************************************************************/
 
-NTSTATUS
-NTAPI
-MmInitMemoryAreas(VOID);
-
 NTSTATUS
 NTAPI
 MmCreateMemoryArea(
index 4d88d8c..0df8da8 100644 (file)
@@ -1501,7 +1501,7 @@ IoStartPacket(IN PDEVICE_OBJECT DeviceObject,
             }
 
             /* Release the cancel lock */
-            IoReleaseCancelSpinLock(OldIrql);
+            IoReleaseCancelSpinLock(CancelIrql);
         }
 
         /* Call the Start I/O function */
index 8ccb16d..a5fcf71 100644 (file)
@@ -98,6 +98,10 @@ IoBuildPartialMdl(IN PMDL SourceMdl,
     PPFN_NUMBER TargetPages = (PPFN_NUMBER)(TargetMdl + 1);
     PPFN_NUMBER SourcePages = (PPFN_NUMBER)(SourceMdl + 1);
     ULONG Offset;
+    ULONG FlagsMask = (MDL_IO_PAGE_READ |
+                       MDL_SOURCE_IS_NONPAGED_POOL |
+                       MDL_MAPPED_TO_SYSTEM_VA |
+                       MDL_IO_SPACE);
 
     /* Calculate the offset */
     Offset = (ULONG)((ULONG_PTR)VirtualAddress -
@@ -117,11 +121,8 @@ IoBuildPartialMdl(IN PMDL SourceMdl,
     Length = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);
 
     /* Set the MDL Flags */
-    TargetMdl->MdlFlags = (MDL_ALLOCATED_FIXED_SIZE | MDL_ALLOCATED_MUST_SUCCEED);
-    TargetMdl->MdlFlags |= (MDL_IO_PAGE_READ |
-                            MDL_SOURCE_IS_NONPAGED_POOL |
-                            MDL_MAPPED_TO_SYSTEM_VA |
-                            MDL_IO_SPACE);
+    TargetMdl->MdlFlags &= (MDL_ALLOCATED_FIXED_SIZE | MDL_ALLOCATED_MUST_SUCCEED);
+    TargetMdl->MdlFlags |= SourceMdl->MdlFlags & FlagsMask;
     TargetMdl->MdlFlags |= MDL_PARTIAL;
 
     /* Set the mapped VA */
index 093ae53..c2e190a 100644 (file)
@@ -169,6 +169,8 @@ IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer,
     ULONG NextEaBufferOffset;
     LONG IntEaLength;
 
+    PAGED_CODE();
+
     /* Lenght of the rest. Inital equal to EaLength */
     IntEaLength = EaLength;
 
@@ -209,7 +211,7 @@ IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer,
                      */
                     NextEaBufferOffset = ((NextEaBufferOffset + 3) & ~3);
                     if ((EaBufferEnd->NextEntryOffset == NextEaBufferOffset) &&
-                        (EaBufferEnd->NextEntryOffset>0))
+                        ((LONG)EaBufferEnd->NextEntryOffset > 0))
                     {
                         /* Rest of buffer must be greater then the
                            next offset */
index 6b306b2..cc0c68e 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/kd/kdinit.c
- * PURPOSE:         Kernel Debugger Initializtion
+ * PURPOSE:         Kernel Debugger Initialization
  *
  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
  */
index 3be5002..39a0541 100644 (file)
 KSPIN_LOCK KiFreezeExecutionLock;
 KSPIN_LOCK Ki486CompatibilityLock;
 
-/* BIOS Memory Map. Not NTLDR-compliant yet */
-extern ULONG KeMemoryMapRangeCount;
-extern ADDRESS_RANGE KeMemoryMap[64];
-
 /* FUNCTIONS *****************************************************************/
 
 VOID
index d88b5a1..852ee09 100644 (file)
@@ -181,7 +181,7 @@ KePPCInitThreadWithContext(IN PKTHREAD Thread,
     /* And set up the Context Switch Frame */
     CtxSwitchFrame->RetAddr = KiThreadStartup;
     CtxSwitchFrame->ApcBypassDisable = TRUE;
-    CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;;
+    CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;
 
     /* Save back the new value of the kernel stack. */
     Thread->KernelStack = (PVOID)CtxSwitchFrame;
index 6f0e8db..786eae7 100644 (file)
@@ -54,7 +54,7 @@ KeStartProfile(PKPROFILE Profile,
     KIRQL OldIrql;
     PKPROFILE_SOURCE_OBJECT SourceBuffer;
     PKPROFILE_SOURCE_OBJECT CurrentSource;
-    BOOLEAN FreeBuffer = TRUE, SourceFound = FALSE;;
+    BOOLEAN FreeBuffer = TRUE, SourceFound = FALSE;
     PKPROCESS ProfileProcess;
     PLIST_ENTRY NextEntry;
 
index 4fec011..eb31da8 100644 (file)
@@ -703,21 +703,6 @@ MmFindGapAtAddress(
    }
 }
 
-/**
- * @name MmInitMemoryAreas
- *
- * Initialize the memory area list implementation.
- */
-
-NTSTATUS
-INIT_FUNCTION
-NTAPI
-MmInitMemoryAreas(VOID)
-{
-   DPRINT("MmInitMemoryAreas()\n");
-   return(STATUS_SUCCESS);
-}
-
 
 /**
  * @name MmFreeMemoryArea
index e0b6306..8a8a565 100644 (file)
@@ -118,8 +118,6 @@ MmInitVirtualMemory()
 
    BoundaryAddressMultiple.QuadPart = 0;
 
-   MmInitMemoryAreas();
-
    DPRINT("NonPagedPool %x - %x, PagedPool %x - %x\n", MiNonPagedPoolStart, (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength - 1,
            MmPagedPoolBase, (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize - 1);
 
@@ -134,13 +132,14 @@ MmInitVirtualMemory()
    MmCreateMemoryArea(MmGetKernelAddressSpace(),
                       MEMORY_AREA_SYSTEM,
                       &BaseAddress,
-                      PAGE_SIZE * MAXIMUM_PROCESSORS,
+                      PAGE_SIZE * KeNumberProcessors,
                       PAGE_READWRITE,
                       &MArea,
                       TRUE,
                       0,
                       BoundaryAddressMultiple);
 
+#if defined(_M_IX86)
    /* Local APIC base */
    BaseAddress = (PVOID)0xFEE00000;
    MmCreateMemoryArea(MmGetKernelAddressSpace(),
@@ -164,17 +163,7 @@ MmInitVirtualMemory()
                       TRUE,
                       0,
                       BoundaryAddressMultiple);
-
-   BaseAddress = (PVOID)0xFF3A0000;
-   MmCreateMemoryArea(MmGetKernelAddressSpace(),
-                      MEMORY_AREA_SYSTEM,
-                      &BaseAddress,
-                      0x20000,
-                      PAGE_READWRITE,
-                      &MArea,
-                      TRUE,
-                      0,
-                      BoundaryAddressMultiple);
+#endif
 
    BaseAddress = MiNonPagedPoolStart;
    MmCreateMemoryArea(MmGetKernelAddressSpace(),
index 29fd9e9..2b3531f 100644 (file)
@@ -245,7 +245,7 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
    if (Type == MEMORY_AREA_SECTION_VIEW)
    {
       Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-             + MemoryArea->Data.SectionData.ViewOffset;;
+             + MemoryArea->Data.SectionData.ViewOffset;
 
       /*
        * Get or create a pageop
index 3ab55e0..e59489b 100644 (file)
@@ -126,9 +126,9 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
       return FALSE;
    }
   if (pgp->MovePointer)
-    pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
+    pgp->MovePointer(SurfObj, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude);
   else
-    EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
+    EngMovePointer(SurfObj, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude);
 
   ppdev->SafetyRemoveLevel = 0;
 
@@ -169,8 +169,8 @@ IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
   /*
    *  Hide the cours
    */
-   pt.x = pgp->Pos.x - pgp->HotSpot.x;
-   pt.y = pgp->Pos.y - pgp->HotSpot.y;
+   pt.x = gpsi->ptCursor.x - pgp->HotSpot.x;
+   pt.y = gpsi->ptCursor.y - pgp->HotSpot.y;
 
 
    if (pgp->SaveSurface != NULL)
@@ -233,8 +233,8 @@ IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
      return ;
    }
 
-   pt.x = pgp->Pos.x - pgp->HotSpot.x;
-   pt.y = pgp->Pos.y - pgp->HotSpot.y;
+   pt.x = gpsi->ptCursor.x - pgp->HotSpot.x;
+   pt.y = gpsi->ptCursor.y - pgp->HotSpot.y;
 
    /*
     * Copy the pixels under the cursor to temporary surface.
@@ -402,8 +402,8 @@ EngSetPointerShape(
     * done right after this. It helps IntShowMousePointer. */
    if (x != -1)
    {
-     pgp->Pos.x = x;
-     pgp->Pos.y = y;
+     gpsi->ptCursor.x = x;
+     gpsi->ptCursor.y = y;
    }
 
    pgp->Size.cx = abs(psoMask->lDelta) << 3;
@@ -552,8 +552,8 @@ EngMovePointer(
    {
      /* Actually this should be set by 'the other side', but it would be
       * done right after this. It helps IntShowMousePointer. */
-     pgp->Pos.x = x;
-     pgp->Pos.y = y;
+     gpsi->ptCursor.x = x;
+     gpsi->ptCursor.y = y;
      IntShowMousePointer(ppdev, pso);
      if (prcl != NULL)
      {
index 9e33cd5..cc0da09 100644 (file)
@@ -157,7 +157,6 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of GDIDEVICE
 {
   /* private GDI pointer handling information, required for software emulation */
   BOOL     Enabled;
-  POINTL   Pos;
   SIZEL    Size;
   POINTL   HotSpot;
   XLATEOBJ *XlateObject;
index 8e1638d..d7f57a1 100644 (file)
@@ -106,6 +106,7 @@ BOOL FASTCALL ftGdiRealizationInfo(PFONTGDI,PREALIZATION_INFO);
 DWORD FASTCALL ftGdiGetKerningPairs(PFONTGDI,DWORD,LPKERNINGPAIR);
 BOOL NTAPI GreExtTextOutW(IN HDC,IN INT,IN INT,IN UINT,IN OPTIONAL LPRECT,
     IN LPWSTR, IN INT, IN OPTIONAL LPINT, IN DWORD);
+DWORD FASTCALL IntGetCharDimensions(HDC, PTEXTMETRICW, PDWORD);
 
 #define IntLockProcessPrivateFonts(W32Process) \
   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&W32Process->PrivateFontListLock)
index 1d7b875..d0623a2 100644 (file)
@@ -585,7 +585,7 @@ BOOLEAN
 APIENTRY
 DxEngReferenceHdev(HDEV hDev)
 {
-    IntGdiReferencePdev((PGDIDEVICE) hDev);;
+    IntGdiReferencePdev((PGDIDEVICE) hDev);
     /* ALWAYS return true */
     return TRUE;
 }
index b19ba20..1662b59 100644 (file)
 static PAGED_LOOKASIDE_LIST gProcessLookasideList;
 static LIST_ENTRY gCurIconList;
 
-/* Look up the location of the cursor in the GDIDEVICE structure
- * when all we know is the window station object
- * Actually doesn't use the window station, but should... */
 BOOL FASTCALL
 IntGetCursorLocation(PWINSTATION_OBJECT WinSta, POINT *loc)
 {
-   HDC hDC;
-   PDC dc;
-   GDIDEVICE *GDIDevice;
-
-#if 1
-   /* FIXME - get the screen dc from the window station or desktop */
-   if (!(hDC = IntGetScreenDC()))
-      return FALSE;
-#endif
-
-   if (!(dc = DC_LockDc(hDC)))
-      return FALSE;
-   GDIDevice = (GDIDEVICE *)dc->pPDev;
-   DC_UnlockDc(dc);
-
-   loc->x = GDIDevice->Pointer.Pos.x;
-   loc->y = GDIDevice->Pointer.Pos.y;
+   loc->x = gpsi->ptCursor.x;
+   loc->y = gpsi->ptCursor.y;
 
    return TRUE;
 }
@@ -259,8 +241,8 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
             SurfObj, soMask, soColor, XlateObj,
             NewCursor->IconInfo.xHotspot,
             NewCursor->IconInfo.yHotspot,
-            GDIDEV(SurfObj)->Pointer.Pos.x,
-            GDIDEV(SurfObj)->Pointer.Pos.y,
+            gpsi->ptCursor.x,
+            gpsi->ptCursor.y,
             &(GDIDEV(SurfObj)->Pointer.Exclude),
             SPS_CHANGE);
       DPRINT("SetCursor: DrvSetPointerShape() returned %x\n",
@@ -277,8 +259,8 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
                                            SurfObj, soMask, soColor, XlateObj,
                                            NewCursor->IconInfo.xHotspot,
                                            NewCursor->IconInfo.yHotspot,
-                                           GDIDEV(SurfObj)->Pointer.Pos.x,
-                                           GDIDEV(SurfObj)->Pointer.Pos.y,
+                                           gpsi->ptCursor.x,
+                                           gpsi->ptCursor.y,
                                            &(GDIDEV(SurfObj)->Pointer.Exclude),
                                            SPS_CHANGE);
       GDIDEV(SurfObj)->Pointer.MovePointer = NULL;
@@ -796,39 +778,16 @@ NtUserGetCursorInfo(
    CURSORINFO SafeCi;
    PSYSTEM_CURSORINFO CurInfo;
    PWINSTATION_OBJECT WinSta;
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
    PCURICON_OBJECT CurIcon;
-   HDC hDC;
+   BOOL Ret = FALSE;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserGetCursorInfo\n");
    UserEnterExclusive();
 
-#if 1
-
-
-   /* FIXME - get the screen dc from the window station or desktop */
-   if (!(hDC = IntGetScreenDC()))
-   {
-      RETURN( FALSE);
-   }
-#endif
-
-   Status = MmCopyFromCaller(&SafeCi.cbSize, pci, sizeof(DWORD));
-   if(!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      RETURN( FALSE);
-   }
-
-   if(SafeCi.cbSize != sizeof(CURSORINFO))
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      RETURN( FALSE);
-   }
-
    WinSta = IntGetWinStaObj();
-   if(WinSta == NULL)
+   if (WinSta == NULL)
    {
       RETURN( FALSE);
    }
@@ -836,21 +795,37 @@ NtUserGetCursorInfo(
    CurInfo = IntGetSysCursorInfo(WinSta);
    CurIcon = (PCURICON_OBJECT)CurInfo->CurrentCursorObject;
 
+   SafeCi.cbSize = sizeof(CURSORINFO);
    SafeCi.flags = ((CurInfo->ShowingCursor && CurIcon) ? CURSOR_SHOWING : 0);
    SafeCi.hCursor = (CurIcon ? (HCURSOR)CurIcon->Self : (HCURSOR)0);
 
    IntGetCursorLocation(WinSta, &SafeCi.ptScreenPos);
 
-   Status = MmCopyToCaller(pci, &SafeCi, sizeof(CURSORINFO));
-   if(!NT_SUCCESS(Status))
+   _SEH2_TRY
+   {
+      if (pci->cbSize == sizeof(CURSORINFO))
+      {
+         ProbeForWrite(pci, sizeof(CURSORINFO), 1);
+         RtlCopyMemory(pci, &SafeCi, sizeof(CURSORINFO));
+         Ret = TRUE;
+      }
+      else
+      {
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      }
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+      Status = _SEH2_GetExceptionCode();
+   }
+   _SEH2_END;
+   if (!NT_SUCCESS(Status))
    {
-      ObDereferenceObject(WinSta);
       SetLastNtError(Status);
-      RETURN( FALSE);
    }
 
    ObDereferenceObject(WinSta);
-   RETURN( TRUE);
+   RETURN(Ret);
 
 CLEANUP:
    DPRINT("Leave NtUserGetCursorInfo, ret=%i\n",_ret_);
index 3dbb05d..4ecc6c1 100644 (file)
@@ -1094,8 +1094,8 @@ IntMouseInput(MOUSEINPUT *mi)
             }
             /* Only now, update the info in the GDIDEVICE, so EngMovePointer can
             * use the old values to move the pointer image */
-            GDIDEV(SurfObj)->Pointer.Pos.x = MousePos.x;
-            GDIDEV(SurfObj)->Pointer.Pos.y = MousePos.y;
+            gpsi->ptCursor.x = MousePos.x;
+            gpsi->ptCursor.y = MousePos.y;
 
             BITMAPOBJ_UnlockBitmap(BitmapObj);
          }
index 3d9e7a4..f0dc07b 100644 (file)
@@ -56,7 +56,7 @@ IntGdiGetLanguageID()
     }
     ZwClose(KeyHandle);
   }
-  DPRINT1("Language ID = %x\n",Ret);
+  DPRINT("Language ID = %x\n",Ret);
   return (SHORT) Ret;
 }
 
index f24620b..c3d14e1 100644 (file)
@@ -396,9 +396,28 @@ NtUserCallOneParam(
          /* FIXME: Should use UserEnterShared */
          RETURN(IntEnumClipboardFormats(Param));
 
-       case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
+      case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
           IntUserManualGuiCheck(Param);
           RETURN(TRUE);
+
+      case ONEPARAM_ROUTINE_GETCURSORPOS:
+      {
+          BOOL Ret = TRUE;
+          PPOINTL pptl;
+          PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+          if (pti->hDesktop != InputDesktopHandle) RETURN(FALSE);
+          _SEH2_TRY
+          {
+             pptl = (PPOINTL)Param;
+             *pptl = gpsi->ptCursor;
+          }
+          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+          {
+             Ret = FALSE;
+          }
+          _SEH2_END;
+          RETURN(Ret);
+      }      
    }
    DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
            Routine, Param);
index 12953c6..eaa89d4 100644 (file)
@@ -3133,7 +3133,7 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
    DECLARE_RETURN(BOOL);
    USER_REFERENCE_ENTRY Ref;
    NTSTATUS Status;
-   PW32THREADINFO ti;;
+   PW32THREADINFO ti;
 
    DPRINT("Enter NtUserSetShellWindowEx\n");
    UserEnterExclusive();
index 7ab878b..2804204 100644 (file)
@@ -1324,6 +1324,8 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
    ASSERT_REFS_CO(Window);
    Wnd = Window->Wnd;
 
+   if (!Wnd) return FALSE;
+   
    WasVisible = (Wnd->Style & WS_VISIBLE) != 0;
 
    switch (Cmd)
index 8925dd2..7cfe9b1 100644 (file)
@@ -294,6 +294,7 @@ IntGetWindowStationObject(PWINSTATION_OBJECT Object)
 BOOL FASTCALL
 co_IntInitializeDesktopGraphics(VOID)
 {
+   TEXTMETRICW tmw;
    UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
    if (! IntCreatePrimarySurface())
    {
@@ -316,9 +317,13 @@ co_IntInitializeDesktopGraphics(VOID)
    IntGdiSetDCOwnerEx( hSystemBM, GDI_OBJ_HMGR_PUBLIC, FALSE);
 
    // FIXME! Move these to a update routine.
-   gpsi->Planes    = NtGdiGetDeviceCaps(ScreenDeviceContext, PLANES);
-   gpsi->BitsPixel = NtGdiGetDeviceCaps(ScreenDeviceContext, BITSPIXEL);
-   gpsi->BitCount  = gpsi->Planes * gpsi->BitsPixel;
+   gpsi->Planes        = NtGdiGetDeviceCaps(ScreenDeviceContext, PLANES);
+   gpsi->BitsPixel     = NtGdiGetDeviceCaps(ScreenDeviceContext, BITSPIXEL);
+   gpsi->BitCount      = gpsi->Planes * gpsi->BitsPixel;
+   gpsi->dmLogPixels   = NtGdiGetDeviceCaps(ScreenDeviceContext, LOGPIXELSY);
+   // Font is realized and this dc was previously set to internal DC_ATTR.
+   gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, &gpsi->cySysFontChar);
+   gpsi->tmSysFont     = tmw;
 
    return TRUE;
 }
index 8a0d64b..626d085 100644 (file)
@@ -685,8 +685,8 @@ IntCreatePrimarySurface()
      EngEraseSurface(SurfObj, &SurfaceRect, 0); */
 
    /* Put the pointer in the center of the screen */
-   GDIDEV(SurfObj)->Pointer.Pos.x = (SurfaceRect.right - SurfaceRect.left) / 2;
-   GDIDEV(SurfObj)->Pointer.Pos.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+   gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2;
+   gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
 
    EngUnlockSurface(SurfObj);
    co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
index 1f49571..1d100b9 100644 (file)
@@ -54,6 +54,49 @@ FontGetObject(PTEXTOBJ TFont, INT Count, PVOID Buffer)
   return Count;
 }
 
+DWORD
+FASTCALL
+IntGetCharDimensions(HDC hdc, PTEXTMETRICW ptm, PDWORD height)
+{
+  PDC pdc;
+  PDC_ATTR pDc_Attr;
+  PTEXTOBJ TextObj;
+  SIZE sz;
+  TMW_INTERNAL tmwi;
+  BOOL Good;
+
+  static const WCHAR alphabet[] = {
+        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
+        'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
+        'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
+
+  if(!ftGdiGetTextMetricsW(hdc, &tmwi)) return 0;
+
+  pdc = DC_LockDc(hdc);
+
+  if (!pdc) return 0;
+
+  pDc_Attr = pdc->pDc_Attr;
+  if(!pDc_Attr) pDc_Attr = &pdc->Dc_Attr;
+
+  TextObj = RealizeFontInit(pDc_Attr->hlfntNew);
+  if ( !TextObj )
+  {
+     DC_UnlockDc(pdc);
+     return 0;
+  }
+  Good = TextIntGetTextExtentPoint(pdc, TextObj, alphabet, 52, 0, NULL, 0, &sz);
+  TEXTOBJ_UnlockText(TextObj);
+  DC_UnlockDc(pdc);
+
+  if (!Good) return 0;
+  if (ptm) *ptm = tmwi.TextMetric;
+  if (height) *height = tmwi.TextMetric.tmHeight;
+
+  return (sz.cx / 26 + 1) / 2;
+}
+
+
 DWORD
 FASTCALL
 IntGetFontLanguageInfo(PDC Dc)
index 9763661..1a34391 100644 (file)
@@ -3603,6 +3603,12 @@ GreExtTextOutW(
             TextLeft += Dx[i<<DxShift] << 6;
 //         DbgPrint("new TextLeft2: %d\n", TextLeft);
         }
+
+        if (DxShift)
+        {
+            TextTop -= Dx[2 * i + 1] << 6;
+        }
+
         previous = glyph_index;
 
         String++;
@@ -3651,7 +3657,7 @@ fail:
     return FALSE;
 }
 
-#define STACK_TEXT_BUFFER_SIZE 50
+#define STACK_TEXT_BUFFER_SIZE 100
 BOOL
 APIENTRY
 NtGdiExtTextOutW(
@@ -3706,17 +3712,19 @@ NtGdiExtTextOutW(
         /* Probe and copy user mode data to the buffer */
         _SEH2_TRY
         {
+            /* Put the Dx before the String to assure alignment of 4 */
+            SafeString = (LPWSTR)(((ULONG_PTR)Buffer) + DxSize);
+
             /* Probe and copy the string */
             ProbeForRead(UnsafeString, StringSize, 1);
-            SafeString = Buffer;
             memcpy((PVOID)SafeString, UnsafeString, StringSize);
 
             /* If we have Dx values... */
             if (UnsafeDx)
             {
                 /* ... probe and copy them */
+                SafeDx = Buffer;
                 ProbeForRead(UnsafeDx, DxSize, 1);
-                SafeDx = (LPINT)(((ULONG_PTR)Buffer) + StringSize);
                 memcpy(SafeDx, UnsafeDx, DxSize);
             }
         }
@@ -3768,7 +3776,7 @@ cleanup:
         ExFreePoolWithTag(Buffer, TAG_GDITEXT);
     }
 
-    return Result;;
+    return Result;
 }
 
 
index cd155bf..96bc4fe 100644 (file)
@@ -244,6 +244,6 @@ void DevCppBackend::OutputFileUnits()
                m_devFile << "Link=1"                           << endl;
                m_devFile << "Priority=1000"            << endl;
                m_devFile << "OverrideBuildCmd=0"       << endl;
-               m_devFile << "BuildCmd="                        << endl << endl;;
+               m_devFile << "BuildCmd="                        << endl << endl;
        }
 }
index ad25135..c4b1335 100644 (file)
@@ -541,6 +541,9 @@ MingwBackend::GenerateGlobalVariables () const
        fprintf ( fMakefile, "ifneq ($(OARCH),)\n" );
        fprintf ( fMakefile, "PROJECT_GCCOPTIONS += -march=$(OARCH)\n" );
        fprintf ( fMakefile, "endif\n" );
+       fprintf ( fMakefile, "ifneq ($(TUNE),)\n" );
+       fprintf ( fMakefile, "PROJECT_GCCOPTIONS += -mtune=$(TUNE)\n" );
+       fprintf ( fMakefile, "endif\n" );
        fprintf ( fMakefile, "PROJECT_CFLAGS = $(PROJECT_GCCOPTIONS) $(PROJECT_GCC_CFLAGS)\n" );
        fprintf ( fMakefile, "PROJECT_CXXFLAGS = $(PROJECT_GCCOPTIONS) $(PROJECT_GCC_CXXFLAGS)\n" );
        fprintf ( fMakefile, "\n" );
index 874cec5..77daeb5 100644 (file)
@@ -596,7 +596,7 @@ MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Includ
                Include& include = *includes[i];
                if ( parameters.length () > 0 )
                        parameters += " ";
-               parameters += "-I" + backend->GetFullPath ( *include.directory );;
+               parameters += "-I" + backend->GetFullPath ( *include.directory );
        }
        return parameters;
 }
index 573fc36..5cf3168 100644 (file)
@@ -21,6 +21,7 @@
  */
 #ifdef _MSC_VER
 #pragma warning ( disable : 4786 )
+#pragma warning ( disable : 4996 )
 #endif//_MSC_VER
 
 #include <iostream>
index ec7c211..7543cc0 100644 (file)
@@ -31,7 +31,7 @@ char cBadSep;
 void
 InitializeEnvironment ()
 {
-       char *SepValue, *ExePostfixValue, *ExePrefixValue;;
+       char *SepValue, *ExePostfixValue, *ExePrefixValue;
 
        SepValue = getenv ( "SEP" );
        if ( SepValue && ( 0 == strcmp ( SepValue, DEF_SSEP ) || 0 == strcmp ( SepValue, DEF_SBAD_SEP ) ) )
index 64823bb..62a0a1f 100644 (file)
@@ -24,6 +24,8 @@
 using std::string;
 using std::vector;
 
+static const Path defaultPath;
+
 string
 Right ( const string& s, size_t n )
 {
index 7b6e9a9..42b44d0 100644 (file)
@@ -20,6 +20,7 @@
 
 #ifdef _MSC_VER
 #pragma warning ( disable : 4786 ) // identifier was truncated to '255' characters in the debug information
+#pragma warning ( disable : 4996 ) // CRT deprecate
 #endif//_MSC_VER
 
 #include <string>