Wine-devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2020
- 82 participants
- 799 discussions
[PATCH v2 3/5] mfreadwrite: Abort ReadSample when unable to request any samples.
by Derek Lesho 27 Oct '20
by Derek Lesho 27 Oct '20
27 Oct '20
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2: Add tests, results here: https://testbot.winehq.org/JobDetails.pl?Key=81074
---
dlls/mfreadwrite/reader.c | 14 +++++++++++---
dlls/mfreadwrite/tests/mfplat.c | 26 ++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c
index 96a82b798ab..7dcae5a1cfa 100644
--- a/dlls/mfreadwrite/reader.c
+++ b/dlls/mfreadwrite/reader.c
@@ -439,7 +439,8 @@ static HRESULT source_reader_new_stream_handler(struct source_reader *reader, IM
}
if (reader->streams[i].requests)
- source_reader_request_sample(reader, &reader->streams[i]);
+ if (FAILED(source_reader_request_sample(reader, &reader->streams[i])))
+ WakeAllConditionVariable(&reader->sample_event);
}
break;
}
@@ -1780,10 +1781,17 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind
stream->requests++;
if (FAILED(hr = source_reader_request_sample(reader, stream)))
WARN("Failed to request a sample, hr %#x.\n", hr);
+ if (stream->stream && !(stream->flags & STREAM_FLAG_SAMPLE_REQUESTED))
+ {
+ *actual_index = index;
+ *stream_flags = MF_SOURCE_READERF_ERROR;
+ *timestamp = 0;
+ break;
+ }
SleepConditionVariableCS(&reader->sample_event, &reader->cs, INFINITE);
}
-
- source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags,
+ if (SUCCEEDED(hr))
+ source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags,
timestamp, sample);
}
}
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c
index cfe68cb6736..0e5053f905f 100644
--- a/dlls/mfreadwrite/tests/mfplat.c
+++ b/dlls/mfreadwrite/tests/mfplat.c
@@ -158,6 +158,8 @@ static HRESULT WINAPI test_media_stream_GetStreamDescriptor(IMFMediaStream *ifac
return S_OK;
}
+static BOOL fail_request_sample;
+
static HRESULT WINAPI test_media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token)
{
struct test_media_stream *stream = impl_from_IMFMediaStream(iface);
@@ -165,6 +167,9 @@ static HRESULT WINAPI test_media_stream_RequestSample(IMFMediaStream *iface, IUn
IMFSample *sample;
HRESULT hr;
+ if (fail_request_sample)
+ return E_NOTIMPL;
+
hr = MFCreateSample(&sample);
ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
hr = IMFSample_SetSampleTime(sample, 123);
@@ -977,6 +982,27 @@ static void test_source_reader_from_media_source(void)
ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
IMFSourceReader_Release(reader);
+ IMFMediaSource_Release(source);
+
+ /* RequestSample failure. */
+ source = create_test_source();
+ ok(!!source, "Failed to create test source.\n");
+
+ fail_request_sample = TRUE;
+
+ hr = MFCreateSourceReaderFromMediaSource(source, NULL, &reader);
+ ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr);
+
+ hr = IMFSourceReader_SetStreamSelection(reader, 0, TRUE);
+ ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
+
+ hr = IMFSourceReader_ReadSample(reader, 0, 0, &actual_index, &stream_flags, ×tamp, &sample);
+ ok(hr == E_NOTIMPL, "Unexpected ReadSample result, hr %#x.\n", hr);
+
+ IMFSourceReader_Release(reader);
+ IMFMediaSource_Release(source);
+
+ fail_request_sample = FALSE;
}
START_TEST(mfplat)
--
2.28.0
1
0
27 Oct '20
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/mfplat/buffer.c | 44 ++++++++++++++++++++++++++++++++++++++
dlls/mfplat/tests/mfplat.c | 13 +++++++++++
2 files changed, 57 insertions(+)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c
index a3311bc10f1..5e969e14ec9 100644
--- a/dlls/mfplat/buffer.c
+++ b/dlls/mfplat/buffer.c
@@ -31,6 +31,7 @@ struct memory_buffer
{
IMFMediaBuffer IMFMediaBuffer_iface;
IMF2DBuffer2 IMF2DBuffer2_iface;
+ IMFGetService IMFGetService_iface;
LONG refcount;
BYTE *data;
@@ -88,6 +89,11 @@ static struct memory_buffer *impl_from_IMF2DBuffer2(IMF2DBuffer2 *iface)
return CONTAINING_RECORD(iface, struct memory_buffer, IMF2DBuffer2_iface);
}
+static struct memory_buffer *impl_from_IMFGetService(IMFGetService *iface)
+{
+ return CONTAINING_RECORD(iface, struct memory_buffer, IMFGetService_iface);
+}
+
static inline struct sample *impl_from_IMFSample(IMFSample *iface)
{
return CONTAINING_RECORD(iface, struct sample, IMFSample_iface);
@@ -240,6 +246,10 @@ static HRESULT WINAPI memory_1d_2d_buffer_QueryInterface(IMFMediaBuffer *iface,
{
*out = &buffer->IMF2DBuffer2_iface;
}
+ else if (IsEqualIID(riid, &IID_IMFGetService))
+ {
+ *out = &buffer->IMFGetService_iface;
+ }
else
{
WARN("Unsupported interface %s.\n", debugstr_guid(riid));
@@ -511,6 +521,39 @@ static const IMF2DBuffer2Vtbl memory_2d_buffer_vtbl =
memory_2d_buffer_Copy2DTo,
};
+static HRESULT WINAPI memory_2d_buffer_gs_QueryInterface(IMFGetService *iface, REFIID riid, void **obj)
+{
+ struct memory_buffer *buffer = impl_from_IMFGetService(iface);
+ return IMFMediaBuffer_QueryInterface(&buffer->IMFMediaBuffer_iface, riid, obj);
+}
+
+static ULONG WINAPI memory_2d_buffer_gs_AddRef(IMFGetService *iface)
+{
+ struct memory_buffer *buffer = impl_from_IMFGetService(iface);
+ return IMFMediaBuffer_AddRef(&buffer->IMFMediaBuffer_iface);
+}
+
+static ULONG WINAPI memory_2d_buffer_gs_Release(IMFGetService *iface)
+{
+ struct memory_buffer *buffer = impl_from_IMFGetService(iface);
+ return IMFMediaBuffer_Release(&buffer->IMFMediaBuffer_iface);
+}
+
+static HRESULT WINAPI memory_2d_buffer_gs_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
+
+ return E_NOTIMPL;
+}
+
+static const IMFGetServiceVtbl memory_2d_buffer_gs_vtbl =
+{
+ memory_2d_buffer_gs_QueryInterface,
+ memory_2d_buffer_gs_AddRef,
+ memory_2d_buffer_gs_Release,
+ memory_2d_buffer_gs_GetService,
+};
+
static HRESULT memory_buffer_init(struct memory_buffer *buffer, DWORD max_length, DWORD alignment,
const IMFMediaBufferVtbl *vtbl)
{
@@ -620,6 +663,7 @@ static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, BOOL bo
}
object->IMF2DBuffer2_iface.lpVtbl = &memory_2d_buffer_vtbl;
+ object->IMFGetService_iface.lpVtbl = &memory_2d_buffer_gs_vtbl;
object->_2d.plane_size = plane_size;
object->_2d.width = stride;
object->_2d.height = height;
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 971469ec574..906454851a8 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -1818,6 +1818,7 @@ static void test_system_memory_buffer(void)
HRESULT hr;
DWORD length, max;
BYTE *data, *data2;
+ IUnknown *unk;
hr = MFCreateMemoryBuffer(1024, NULL);
ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
@@ -1836,6 +1837,9 @@ static void test_system_memory_buffer(void)
hr = MFCreateMemoryBuffer(1024, &buffer);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
+
hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
@@ -5155,6 +5159,7 @@ static void test_MFCreate2DMediaBuffer(void)
IMF2DBuffer *_2dbuffer;
IMFMediaBuffer *buffer;
int i, pitch, pitch2;
+ IUnknown *unk;
HRESULT hr;
BOOL ret;
@@ -5177,6 +5182,10 @@ static void test_MFCreate2DMediaBuffer(void)
hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&unk);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ IUnknown_Release(unk);
+
/* Full backing buffer size, with 64 bytes per row alignment. */
hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
@@ -5405,6 +5414,7 @@ static void test_MFCreateMediaBufferFromMediaType(void)
HRESULT hr;
IMFMediaType *media_type;
unsigned int i;
+ IUnknown *unk;
if (!pMFCreateMediaBufferFromMediaType)
{
@@ -5437,6 +5447,9 @@ static void test_MFCreateMediaBufferFromMediaType(void)
if (FAILED(hr))
break;
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
+
hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length);
--
2.28.0
2
2
Signed-off-by: Esme Povirk <esme(a)codeweavers.com>
---
dlls/windowscodecs/Makefile.in | 1 +
dlls/windowscodecs/decoder.c | 76 +-
dlls/windowscodecs/libtiff.c | 1187 ++++++++++++++++++++
dlls/windowscodecs/main.c | 32 +-
dlls/windowscodecs/tiffformat.c | 1428 +-----------------------
dlls/windowscodecs/unix_iface.c | 1 +
dlls/windowscodecs/unix_lib.c | 8 +
dlls/windowscodecs/wincodecs_common.h | 19 +
dlls/windowscodecs/wincodecs_private.h | 7 +
9 files changed, 1312 insertions(+), 1447 deletions(-)
create mode 100644 dlls/windowscodecs/libtiff.c
diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in
index 2472ef57d63..2dd6a78e147 100644
--- a/dlls/windowscodecs/Makefile.in
+++ b/dlls/windowscodecs/Makefile.in
@@ -23,6 +23,7 @@ C_SRCS = \
info.c \
jpegformat.c \
libpng.c \
+ libtiff.c \
main.c \
metadatahandler.c \
metadataquery.c \
diff --git a/dlls/windowscodecs/decoder.c b/dlls/windowscodecs/decoder.c
index 106aad4b92b..b51ca0a8def 100644
--- a/dlls/windowscodecs/decoder.c
+++ b/dlls/windowscodecs/decoder.c
@@ -216,9 +216,11 @@ static HRESULT WINAPI CommonDecoder_GetFrameCount(IWICBitmapDecoder *iface,
CommonDecoder *This = impl_from_IWICBitmapDecoder(iface);
if (!pCount) return E_INVALIDARG;
- if (!This->stream) return WINCODEC_ERR_WRONGSTATE;
+ if (This->stream)
+ *pCount = This->file_info.frame_count;
+ else
+ *pCount = 0;
- *pCount = This->file_info.frame_count;
return S_OK;
}
@@ -606,23 +608,69 @@ static HRESULT WINAPI CommonDecoderFrame_Block_GetReaderByIndex(IWICMetadataBloc
if (SUCCEEDED(hr))
{
- ULARGE_INTEGER offset, length;
+ if (This->metadata_blocks[nIndex].options & DECODER_BLOCK_FULL_STREAM)
+ {
+ LARGE_INTEGER offset;
+ offset.QuadPart = This->metadata_blocks[nIndex].offset;
- offset.QuadPart = This->metadata_blocks[nIndex].offset;
- length.QuadPart = This->metadata_blocks[nIndex].length;
- hr = IWICStream_InitializeFromIStreamRegion(stream, This->parent->stream,
- offset, length);
+ hr = IWICStream_InitializeFromIStream(stream, This->parent->stream);
- if (SUCCEEDED(hr))
- hr = ImagingFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory);
+ if (SUCCEEDED(hr))
+ hr = IWICStream_Seek(stream, offset, STREAM_SEEK_SET, NULL);
+ }
+ else
+ {
+ ULARGE_INTEGER offset, length;
- if (SUCCEEDED(hr))
+ offset.QuadPart = This->metadata_blocks[nIndex].offset;
+ length.QuadPart = This->metadata_blocks[nIndex].length;
+
+ hr = IWICStream_InitializeFromIStreamRegion(stream, This->parent->stream,
+ offset, length);
+ }
+
+ if (This->metadata_blocks[nIndex].options & DECODER_BLOCK_READER_CLSID)
{
- hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
- &This->parent->decoder_info.block_format, NULL, This->metadata_blocks[nIndex].options,
- (IStream*)stream, ppIMetadataReader);
+ IWICMetadataReader *reader;
+ IWICPersistStream *persist;
+ if (SUCCEEDED(hr))
+ {
+ hr = create_instance(&This->metadata_blocks[nIndex].reader_clsid,
+ &IID_IWICMetadataReader, (void**)&reader);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist);
- IWICComponentFactory_Release(factory);
+ if (SUCCEEDED(hr))
+ {
+ hr = IWICPersistStream_LoadEx(persist, (IStream*)stream, NULL,
+ This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK);
+
+ IWICPersistStream_Release(persist);
+ }
+
+ if (SUCCEEDED(hr))
+ *ppIMetadataReader = reader;
+ else
+ IWICMetadataReader_Release(reader);
+ }
+ }
+ else
+ {
+ if (SUCCEEDED(hr))
+ hr = ImagingFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
+ &This->parent->decoder_info.block_format, NULL,
+ This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK,
+ (IStream*)stream, ppIMetadataReader);
+
+ IWICComponentFactory_Release(factory);
+ }
}
IWICStream_Release(stream);
diff --git a/dlls/windowscodecs/libtiff.c b/dlls/windowscodecs/libtiff.c
new file mode 100644
index 00000000000..27f89679766
--- /dev/null
+++ b/dlls/windowscodecs/libtiff.c
@@ -0,0 +1,1187 @@
+/*
+ * Copyright 2010 Vincent Povirk for CodeWeavers
+ * Copyright 2016 Dmitry Timoshkov
+ *
+ * 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
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_TIFFIO_H
+#include <tiffio.h>
+#endif
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+#include "winbase.h"
+#include "objbase.h"
+
+#include "wincodecs_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+
+#ifdef SONAME_LIBTIFF
+
+/* Workaround for broken libtiff 4.x headers on some 64-bit hosts which
+ * define TIFF_UINT64_T/toff_t as 32-bit for 32-bit builds, while they
+ * are supposed to be always 64-bit.
+ * TIFF_UINT64_T doesn't exist in libtiff 3.x, it was introduced in 4.x.
+ */
+#ifdef TIFF_UINT64_T
+# undef toff_t
+# define toff_t UINT64
+#endif
+
+static CRITICAL_SECTION init_tiff_cs;
+static CRITICAL_SECTION_DEBUG init_tiff_cs_debug =
+{
+ 0, 0, &init_tiff_cs,
+ { &init_tiff_cs_debug.ProcessLocksList,
+ &init_tiff_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": init_tiff_cs") }
+};
+static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 };
+
+static void *libtiff_handle;
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(TIFFClientOpen);
+MAKE_FUNCPTR(TIFFClose);
+MAKE_FUNCPTR(TIFFCurrentDirOffset);
+MAKE_FUNCPTR(TIFFGetField);
+MAKE_FUNCPTR(TIFFIsByteSwapped);
+MAKE_FUNCPTR(TIFFNumberOfDirectories);
+MAKE_FUNCPTR(TIFFReadDirectory);
+MAKE_FUNCPTR(TIFFReadEncodedStrip);
+MAKE_FUNCPTR(TIFFReadEncodedTile);
+MAKE_FUNCPTR(TIFFSetDirectory);
+MAKE_FUNCPTR(TIFFSetField);
+MAKE_FUNCPTR(TIFFWriteDirectory);
+MAKE_FUNCPTR(TIFFWriteScanline);
+#undef MAKE_FUNCPTR
+
+static void *load_libtiff(void)
+{
+ void *result;
+
+ RtlEnterCriticalSection(&init_tiff_cs);
+
+ if (!libtiff_handle &&
+ (libtiff_handle = dlopen(SONAME_LIBTIFF, RTLD_NOW)) != NULL)
+ {
+ void * (*pTIFFSetWarningHandler)(void *);
+ void * (*pTIFFSetWarningHandlerExt)(void *);
+
+#define LOAD_FUNCPTR(f) \
+ if((p##f = dlsym(libtiff_handle, #f)) == NULL) { \
+ ERR("failed to load symbol %s\n", #f); \
+ libtiff_handle = NULL; \
+ RtlLeaveCriticalSection(&init_tiff_cs); \
+ return NULL; \
+ }
+ LOAD_FUNCPTR(TIFFClientOpen);
+ LOAD_FUNCPTR(TIFFClose);
+ LOAD_FUNCPTR(TIFFCurrentDirOffset);
+ LOAD_FUNCPTR(TIFFGetField);
+ LOAD_FUNCPTR(TIFFIsByteSwapped);
+ LOAD_FUNCPTR(TIFFNumberOfDirectories);
+ LOAD_FUNCPTR(TIFFReadDirectory);
+ LOAD_FUNCPTR(TIFFReadEncodedStrip);
+ LOAD_FUNCPTR(TIFFReadEncodedTile);
+ LOAD_FUNCPTR(TIFFSetDirectory);
+ LOAD_FUNCPTR(TIFFSetField);
+ LOAD_FUNCPTR(TIFFWriteDirectory);
+ LOAD_FUNCPTR(TIFFWriteScanline);
+#undef LOAD_FUNCPTR
+
+ if ((pTIFFSetWarningHandler = dlsym(libtiff_handle, "TIFFSetWarningHandler")))
+ pTIFFSetWarningHandler(NULL);
+ if ((pTIFFSetWarningHandlerExt = dlsym(libtiff_handle, "TIFFSetWarningHandlerExt")))
+ pTIFFSetWarningHandlerExt(NULL);
+ }
+
+ result = libtiff_handle;
+
+ RtlLeaveCriticalSection(&init_tiff_cs);
+ return result;
+}
+
+static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size)
+{
+ IStream *stream = (IStream*)client_data;
+ ULONG bytes_read;
+ HRESULT hr;
+
+ hr = stream_read(stream, data, size, &bytes_read);
+ if (FAILED(hr)) bytes_read = 0;
+ return bytes_read;
+}
+
+static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size)
+{
+ FIXME("stub\n");
+ return 0;
+}
+
+static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
+{
+ IStream *stream = (IStream*)client_data;
+ DWORD origin;
+ ULONGLONG new_position;
+ HRESULT hr;
+
+ switch (whence)
+ {
+ case SEEK_SET:
+ origin = STREAM_SEEK_SET;
+ break;
+ case SEEK_CUR:
+ origin = STREAM_SEEK_CUR;
+ break;
+ case SEEK_END:
+ origin = STREAM_SEEK_END;
+ break;
+ default:
+ ERR("unknown whence value %i\n", whence);
+ return -1;
+ }
+
+ hr = stream_seek(stream, offset, origin, &new_position);
+ if (SUCCEEDED(hr)) return new_position;
+ else return -1;
+}
+
+static int tiff_stream_close(thandle_t client_data)
+{
+ /* Caller is responsible for releasing the stream object. */
+ return 0;
+}
+
+static toff_t tiff_stream_size(thandle_t client_data)
+{
+ IStream *stream = (IStream*)client_data;
+ ULONGLONG size;
+ HRESULT hr;
+
+ hr = stream_getsize(stream, &size);
+
+ if (SUCCEEDED(hr)) return size;
+ else return -1;
+}
+
+static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
+{
+ /* Cannot mmap streams */
+ return 0;
+}
+
+static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
+{
+ /* No need to ever do this, since we can't map things. */
+}
+
+static TIFF* tiff_open_stream(IStream *stream, const char *mode)
+{
+ stream_seek(stream, 0, STREAM_SEEK_SET, NULL);
+
+ return pTIFFClientOpen("<IStream object>", mode, stream, tiff_stream_read,
+ tiff_stream_write, (void *)tiff_stream_seek, tiff_stream_close,
+ (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap);
+}
+
+typedef struct {
+ struct decoder_frame frame;
+ int bps;
+ int samples;
+ int source_bpp;
+ int planar;
+ int indexed;
+ int reverse_bgr;
+ int invert_grayscale;
+ UINT tile_width, tile_height;
+ UINT tile_stride;
+ UINT tile_size;
+ int tiled;
+ UINT tiles_across;
+} tiff_decode_info;
+
+struct tiff_decoder
+{
+ struct decoder decoder;
+ IStream *stream;
+ TIFF *tiff;
+ DWORD frame_count;
+ DWORD cached_frame;
+ tiff_decode_info cached_decode_info;
+ INT cached_tile_x, cached_tile_y;
+ BYTE *cached_tile;
+};
+
+static inline struct tiff_decoder *impl_from_decoder(struct decoder* iface)
+{
+ return CONTAINING_RECORD(iface, struct tiff_decoder, decoder);
+}
+
+static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
+{
+ uint16 photometric, bps, samples, planar;
+ uint16 extra_sample_count, extra_sample, *extra_samples;
+ uint16 *red, *green, *blue;
+ UINT resolution_unit;
+ float xres=0.0, yres=0.0;
+ int ret, i;
+ const BYTE *profile;
+ UINT len;
+
+ decode_info->indexed = 0;
+ decode_info->reverse_bgr = 0;
+ decode_info->invert_grayscale = 0;
+ decode_info->tiled = 0;
+ decode_info->source_bpp = 0;
+
+ ret = pTIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
+ if (!ret)
+ {
+ WARN("missing PhotometricInterpretation tag\n");
+ return E_FAIL;
+ }
+
+ ret = pTIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps);
+ if (!ret) bps = 1;
+ decode_info->bps = bps;
+
+ ret = pTIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples);
+ if (!ret) samples = 1;
+ decode_info->samples = samples;
+
+ if (samples == 1)
+ planar = 1;
+ else
+ {
+ ret = pTIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar);
+ if (!ret) planar = 1;
+ if (planar != 1)
+ {
+ FIXME("unhandled planar configuration %u\n", planar);
+ return E_FAIL;
+ }
+ }
+ decode_info->planar = planar;
+
+ TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps);
+
+ switch(photometric)
+ {
+ case 0: /* WhiteIsZero */
+ decode_info->invert_grayscale = 1;
+ /* fall through */
+ case 1: /* BlackIsZero */
+ if (samples == 2)
+ {
+ ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
+ if (!ret)
+ {
+ extra_sample_count = 1;
+ extra_sample = 0;
+ extra_samples = &extra_sample;
+ }
+ }
+ else if (samples != 1)
+ {
+ FIXME("unhandled %dbpp sample count %u\n", bps, samples);
+ return E_FAIL;
+ }
+
+ decode_info->frame.bpp = bps * samples;
+ decode_info->source_bpp = decode_info->frame.bpp;
+ switch (bps)
+ {
+ case 1:
+ if (samples != 1)
+ {
+ FIXME("unhandled 1bpp sample count %u\n", samples);
+ return E_FAIL;
+ }
+ decode_info->frame.pixel_format = GUID_WICPixelFormatBlackWhite;
+ break;
+ case 4:
+ if (samples != 1)
+ {
+ FIXME("unhandled 4bpp grayscale sample count %u\n", samples);
+ return E_FAIL;
+ }
+ decode_info->frame.pixel_format = GUID_WICPixelFormat4bppGray;
+ break;
+ case 8:
+ if (samples == 1)
+ decode_info->frame.pixel_format = GUID_WICPixelFormat8bppGray;
+ else
+ {
+ decode_info->frame.bpp = 32;
+
+ switch(extra_samples[0])
+ {
+ case 1: /* Associated (pre-multiplied) alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA;
+ break;
+ case 0: /* Unspecified data */
+ case 2: /* Unassociated alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA;
+ break;
+ default:
+ FIXME("unhandled extra sample type %u\n", extra_samples[0]);
+ return E_FAIL;
+ }
+ }
+ break;
+ case 16:
+ if (samples != 1)
+ {
+ FIXME("unhandled 16bpp grayscale sample count %u\n", samples);
+ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+ }
+ decode_info->frame.pixel_format = GUID_WICPixelFormat16bppGray;
+ break;
+ case 32:
+ if (samples != 1)
+ {
+ FIXME("unhandled 32bpp grayscale sample count %u\n", samples);
+ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+ }
+ decode_info->frame.pixel_format = GUID_WICPixelFormat32bppGrayFloat;
+ break;
+ default:
+ WARN("unhandled greyscale bit count %u\n", bps);
+ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+ }
+ break;
+ case 2: /* RGB */
+ if (samples == 4)
+ {
+ ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
+ if (!ret)
+ {
+ extra_sample_count = 1;
+ extra_sample = 0;
+ extra_samples = &extra_sample;
+ }
+ }
+ else if (samples != 3)
+ {
+ FIXME("unhandled RGB sample count %u\n", samples);
+ return E_FAIL;
+ }
+
+ decode_info->frame.bpp = max(bps, 8) * samples;
+ decode_info->source_bpp = bps * samples;
+ switch(bps)
+ {
+ case 1:
+ case 4:
+ case 8:
+ decode_info->reverse_bgr = 1;
+ if (samples == 3)
+ decode_info->frame.pixel_format = GUID_WICPixelFormat24bppBGR;
+ else
+ switch(extra_samples[0])
+ {
+ case 1: /* Associated (pre-multiplied) alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA;
+ break;
+ case 0: /* Unspecified data */
+ case 2: /* Unassociated alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA;
+ break;
+ default:
+ FIXME("unhandled extra sample type %i\n", extra_samples[0]);
+ return E_FAIL;
+ }
+ break;
+ case 16:
+ if (samples == 3)
+ decode_info->frame.pixel_format = GUID_WICPixelFormat48bppRGB;
+ else
+ switch(extra_samples[0])
+ {
+ case 1: /* Associated (pre-multiplied) alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat64bppPRGBA;
+ break;
+ case 0: /* Unspecified data */
+ case 2: /* Unassociated alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat64bppRGBA;
+ break;
+ default:
+ FIXME("unhandled extra sample type %i\n", extra_samples[0]);
+ return E_FAIL;
+ }
+ break;
+ case 32:
+ if (samples == 3)
+ decode_info->frame.pixel_format = GUID_WICPixelFormat96bppRGBFloat;
+ else
+ switch(extra_samples[0])
+ {
+ case 1: /* Associated (pre-multiplied) alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat128bppPRGBAFloat;
+ break;
+ case 0: /* Unspecified data */
+ case 2: /* Unassociated alpha data */
+ decode_info->frame.pixel_format = GUID_WICPixelFormat128bppRGBAFloat;
+ break;
+ default:
+ FIXME("unhandled extra sample type %i\n", extra_samples[0]);
+ return E_FAIL;
+ }
+ break;
+ default:
+ WARN("unhandled RGB bit count %u\n", bps);
+ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+ }
+ break;
+ case 3: /* RGB Palette */
+ if (samples != 1)
+ {
+ FIXME("unhandled indexed sample count %u\n", samples);
+ return E_FAIL;
+ }
+
+ decode_info->indexed = 1;
+ decode_info->frame.bpp = bps;
+ switch (bps)
+ {
+ case 1:
+ decode_info->frame.pixel_format = GUID_WICPixelFormat1bppIndexed;
+ break;
+ case 2:
+ decode_info->frame.pixel_format = GUID_WICPixelFormat2bppIndexed;
+ break;
+ case 4:
+ decode_info->frame.pixel_format = GUID_WICPixelFormat4bppIndexed;
+ break;
+ case 8:
+ decode_info->frame.pixel_format = GUID_WICPixelFormat8bppIndexed;
+ break;
+ default:
+ FIXME("unhandled indexed bit count %u\n", bps);
+ return E_NOTIMPL;
+ }
+ break;
+
+ case 5: /* Separated */
+ if (samples != 4)
+ {
+ FIXME("unhandled Separated sample count %u\n", samples);
+ return E_FAIL;
+ }
+
+ decode_info->frame.bpp = bps * samples;
+ switch(bps)
+ {
+ case 8:
+ decode_info->frame.pixel_format = GUID_WICPixelFormat32bppCMYK;
+ break;
+ case 16:
+ decode_info->frame.pixel_format = GUID_WICPixelFormat64bppCMYK;
+ break;
+
+ default:
+ WARN("unhandled Separated bit count %u\n", bps);
+ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+ }
+ break;
+
+ case 4: /* Transparency mask */
+ case 6: /* YCbCr */
+ case 8: /* CIELab */
+ default:
+ FIXME("unhandled PhotometricInterpretation %u\n", photometric);
+ return E_FAIL;
+ }
+
+ ret = pTIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->frame.width);
+ if (!ret)
+ {
+ WARN("missing image width\n");
+ return E_FAIL;
+ }
+
+ ret = pTIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->frame.height);
+ if (!ret)
+ {
+ WARN("missing image length\n");
+ return E_FAIL;
+ }
+
+ if ((ret = pTIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width)))
+ {
+ decode_info->tiled = 1;
+
+ ret = pTIFFGetField(tiff, TIFFTAG_TILELENGTH, &decode_info->tile_height);
+ if (!ret)
+ {
+ WARN("missing tile height\n");
+ return E_FAIL;
+ }
+
+ decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
+ decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
+ decode_info->tiles_across = (decode_info->frame.width + decode_info->tile_width - 1) / decode_info->tile_width;
+ }
+ else if ((ret = pTIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height)))
+ {
+ if (decode_info->tile_height > decode_info->frame.height)
+ decode_info->tile_height = decode_info->frame.height;
+ decode_info->tile_width = decode_info->frame.width;
+ decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
+ decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
+ }
+ else
+ {
+ /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */
+ decode_info->tile_height = decode_info->frame.height;
+ decode_info->tile_width = decode_info->frame.width;
+ decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8);
+ decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
+ }
+
+ resolution_unit = 0;
+ pTIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resolution_unit);
+
+ ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &xres);
+ if (!ret)
+ {
+ WARN("missing X resolution\n");
+ }
+ /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131)
+ * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */
+ if (!isfinite(xres))
+ {
+ xres = 0.0;
+ }
+
+ ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &yres);
+ if (!ret)
+ {
+ WARN("missing Y resolution\n");
+ }
+ if (!isfinite(yres))
+ {
+ yres = 0.0;
+ }
+
+ if (xres == 0.0 || yres == 0.0)
+ {
+ decode_info->frame.dpix = decode_info->frame.dpiy = 96.0;
+ }
+ else
+ {
+ switch (resolution_unit)
+ {
+ default:
+ FIXME("unknown resolution unit %i\n", resolution_unit);
+ /* fall through */
+ case 0: /* Not set */
+ case 1: /* Relative measurements */
+ case 2: /* Inch */
+ decode_info->frame.dpix = xres;
+ decode_info->frame.dpiy = yres;
+ break;
+ case 3: /* Centimeter */
+ decode_info->frame.dpix = xres * 2.54;
+ decode_info->frame.dpiy = yres * 2.54;
+ break;
+ }
+ }
+
+ if (decode_info->indexed &&
+ pTIFFGetField(tiff, TIFFTAG_COLORMAP, &red, &green, &blue))
+ {
+ decode_info->frame.num_colors = 1 << decode_info->bps;
+ for (i=0; i<decode_info->frame.num_colors; i++)
+ {
+ decode_info->frame.palette[i] = 0xff000000 |
+ ((red[i]<<8) & 0xff0000) |
+ (green[i] & 0xff00) |
+ ((blue[i]>>8) & 0xff);
+ }
+ }
+ else
+ {
+ decode_info->frame.num_colors = 0;
+ }
+
+ if (pTIFFGetField(tiff, TIFFTAG_ICCPROFILE, &len, &profile))
+ decode_info->frame.num_color_contexts = 1;
+ else
+ decode_info->frame.num_color_contexts = 0;
+
+ return S_OK;
+}
+
+static HRESULT CDECL tiff_decoder_initialize(struct decoder* iface, IStream *stream, struct decoder_stat *st)
+{
+ struct tiff_decoder *This = impl_from_decoder(iface);
+ HRESULT hr;
+
+ This->tiff = tiff_open_stream(stream, "r");
+ if (!This->tiff)
+ return E_FAIL;
+
+ This->frame_count = pTIFFNumberOfDirectories(This->tiff);
+ This->cached_frame = 0;
+ hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info);
+ if (FAILED(hr))
+ goto fail;
+
+ st->frame_count = This->frame_count;
+ st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages |
+ WICBitmapDecoderCapabilityCanDecodeSomeImages |
+ WICBitmapDecoderCapabilityCanEnumerateMetadata;
+ return S_OK;
+
+fail:
+ pTIFFClose(This->tiff);
+ This->tiff = NULL;
+ return hr;
+}
+
+static HRESULT tiff_decoder_select_frame(struct tiff_decoder* This, DWORD frame)
+{
+ HRESULT hr;
+ UINT prev_tile_size;
+ int res;
+
+ if (frame >= This->frame_count)
+ return E_INVALIDARG;
+
+ if (This->cached_frame == frame)
+ return S_OK;
+
+ prev_tile_size = This->cached_tile ? This->cached_decode_info.tile_size : 0;
+
+ res = pTIFFSetDirectory(This->tiff, frame);
+ if (!res)
+ return E_INVALIDARG;
+
+ hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info);
+
+ This->cached_tile_x = -1;
+
+ if (SUCCEEDED(hr))
+ {
+ This->cached_frame = frame;
+ if (This->cached_decode_info.tile_size > prev_tile_size)
+ {
+ free(This->cached_tile);
+ This->cached_tile = NULL;
+ }
+ }
+ else
+ {
+ /* Set an invalid value to ensure we'll refresh cached_decode_info before using it. */
+ This->cached_frame = This->frame_count;
+ free(This->cached_tile);
+ This->cached_tile = NULL;
+ }
+
+ return hr;
+}
+
+static HRESULT CDECL tiff_decoder_get_frame_info(struct decoder* iface, UINT frame, struct decoder_frame *info)
+{
+ struct tiff_decoder *This = impl_from_decoder(iface);
+ HRESULT hr;
+
+ hr = tiff_decoder_select_frame(This, frame);
+ if (SUCCEEDED(hr))
+ {
+ *info = This->cached_decode_info.frame;
+ }
+
+ return hr;
+}
+
+static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UINT tile_y)
+{
+ tsize_t ret;
+ int swap_bytes;
+ tiff_decode_info *info = &This->cached_decode_info;
+
+ swap_bytes = pTIFFIsByteSwapped(This->tiff);
+
+ if (info->tiled)
+ ret = pTIFFReadEncodedTile(This->tiff, tile_x + tile_y * info->tiles_across, This->cached_tile, info->tile_size);
+ else
+ ret = pTIFFReadEncodedStrip(This->tiff, tile_y, This->cached_tile, info->tile_size);
+
+ if (ret == -1)
+ return E_FAIL;
+
+ /* 3bps RGB */
+ if (info->source_bpp == 3 && info->samples == 3 && info->frame.bpp == 24)
+ {
+ BYTE *srcdata, *src, *dst;
+ DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8;
+
+ count = width_bytes * info->tile_height;
+
+ srcdata = malloc(count);
+ if (!srcdata) return E_OUTOFMEMORY;
+ memcpy(srcdata, This->cached_tile, count);
+
+ for (y = 0; y < info->tile_height; y++)
+ {
+ src = srcdata + y * width_bytes;
+ dst = This->cached_tile + y * info->tile_width * 3;
+
+ for (x = 0; x < info->tile_width; x += 8)
+ {
+ dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
+ dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
+ dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
+ if (x + 1 < info->tile_width)
+ {
+ dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */
+ dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */
+ dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */
+ }
+ if (x + 2 < info->tile_width)
+ {
+ dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */
+ dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */
+ dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */
+ }
+ if (x + 3 < info->tile_width)
+ {
+ dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */
+ dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */
+ dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */
+ }
+ if (x + 4 < info->tile_width)
+ {
+ dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */
+ dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */
+ dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */
+ }
+ if (x + 5 < info->tile_width)
+ {
+ dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */
+ dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */
+ dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */
+ }
+ if (x + 6 < info->tile_width)
+ {
+ dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */
+ dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */
+ dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */
+ }
+ if (x + 7 < info->tile_width)
+ {
+ dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */
+ dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */
+ dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */
+ }
+ src += 3;
+ dst += 24;
+ }
+ }
+
+ free(srcdata);
+ }
+ /* 12bps RGB */
+ else if (info->source_bpp == 12 && info->samples == 3 && info->frame.bpp == 24)
+ {
+ BYTE *srcdata, *src, *dst;
+ DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8;
+
+ count = width_bytes * info->tile_height;
+
+ srcdata = malloc(count);
+ if (!srcdata) return E_OUTOFMEMORY;
+ memcpy(srcdata, This->cached_tile, count);
+
+ for (y = 0; y < info->tile_height; y++)
+ {
+ src = srcdata + y * width_bytes;
+ dst = This->cached_tile + y * info->tile_width * 3;
+
+ for (x = 0; x < info->tile_width; x += 2)
+ {
+ dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
+ dst[1] = (src[0] & 0x0f) * 17; /* G */
+ dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
+ if (x + 1 < info->tile_width)
+ {
+ dst[5] = (src[1] & 0x0f) * 17; /* B */
+ dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */
+ dst[3] = (src[2] & 0x0f) * 17; /* R */
+ }
+ src += 3;
+ dst += 6;
+ }
+ }
+
+ free(srcdata);
+ }
+ /* 4bps RGBA */
+ else if (info->source_bpp == 4 && info->samples == 4 && info->frame.bpp == 32)
+ {
+ BYTE *srcdata, *src, *dst;
+ DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8;
+
+ count = width_bytes * info->tile_height;
+
+ srcdata = malloc(count);
+ if (!srcdata) return E_OUTOFMEMORY;
+ memcpy(srcdata, This->cached_tile, count);
+
+ for (y = 0; y < info->tile_height; y++)
+ {
+ src = srcdata + y * width_bytes;
+ dst = This->cached_tile + y * info->tile_width * 4;
+
+ /* 1 source byte expands to 2 BGRA samples */
+
+ for (x = 0; x < info->tile_width; x += 2)
+ {
+ dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
+ dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
+ dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
+ dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */
+ if (x + 1 < info->tile_width)
+ {
+ dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */
+ dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */
+ dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */
+ dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */
+ }
+ src++;
+ dst += 8;
+ }
+ }
+
+ free(srcdata);
+ }
+ /* 16bps RGBA */
+ else if (info->source_bpp == 16 && info->samples == 4 && info->frame.bpp == 32)
+ {
+ BYTE *srcdata, *src, *dst;
+ DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8;
+
+ count = width_bytes * info->tile_height;
+
+ srcdata = malloc(count);
+ if (!srcdata) return E_OUTOFMEMORY;
+ memcpy(srcdata, This->cached_tile, count);
+
+ for (y = 0; y < info->tile_height; y++)
+ {
+ src = srcdata + y * width_bytes;
+ dst = This->cached_tile + y * info->tile_width * 4;
+
+ for (x = 0; x < info->tile_width; x++)
+ {
+ dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
+ dst[1] = (src[0] & 0x0f) * 17; /* G */
+ dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
+ dst[3] = (src[1] & 0x0f) * 17; /* A */
+ src += 2;
+ dst += 4;
+ }
+ }
+
+ free(srcdata);
+ }
+ /* 8bpp grayscale with extra alpha */
+ else if (info->source_bpp == 16 && info->samples == 2 && info->frame.bpp == 32)
+ {
+ BYTE *src;
+ DWORD *dst, count = info->tile_width * info->tile_height;
+
+ src = This->cached_tile + info->tile_width * info->tile_height * 2 - 2;
+ dst = (DWORD *)(This->cached_tile + info->tile_size - 4);
+
+ while (count--)
+ {
+ *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24);
+ src -= 2;
+ }
+ }
+
+ if (info->reverse_bgr)
+ {
+ if (info->bps == 8)
+ {
+ UINT sample_count = info->samples;
+
+ reverse_bgr8(sample_count, This->cached_tile, info->tile_width,
+ info->tile_height, info->tile_width * sample_count);
+ }
+ }
+
+ if (swap_bytes && info->bps > 8)
+ {
+ UINT row, i, samples_per_row;
+ BYTE *sample, temp;
+
+ samples_per_row = info->tile_width * info->samples;
+
+ switch(info->bps)
+ {
+ case 16:
+ for (row=0; row<info->tile_height; row++)
+ {
+ sample = This->cached_tile + row * info->tile_stride;
+ for (i=0; i<samples_per_row; i++)
+ {
+ temp = sample[1];
+ sample[1] = sample[0];
+ sample[0] = temp;
+ sample += 2;
+ }
+ }
+ break;
+ default:
+ ERR("unhandled bps for byte swap %u\n", info->bps);
+ return E_FAIL;
+ }
+ }
+
+ if (info->invert_grayscale)
+ {
+ BYTE *byte, *end;
+
+ if (info->samples != 1)
+ {
+ ERR("cannot invert grayscale image with %u samples\n", info->samples);
+ return E_FAIL;
+ }
+
+ end = This->cached_tile+info->tile_size;
+
+ for (byte = This->cached_tile; byte != end; byte++)
+ *byte = ~(*byte);
+ }
+
+ This->cached_tile_x = tile_x;
+ This->cached_tile_y = tile_y;
+
+ return S_OK;
+}
+
+static HRESULT CDECL tiff_decoder_copy_pixels(struct decoder* iface, UINT frame,
+ const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
+{
+ struct tiff_decoder *This = impl_from_decoder(iface);
+ HRESULT hr;
+ UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y;
+ UINT tile_x, tile_y;
+ BYTE *dst_tilepos;
+ WICRect rc;
+ tiff_decode_info *info = &This->cached_decode_info;
+
+ hr = tiff_decoder_select_frame(This, frame);
+ if (FAILED(hr))
+ return hr;
+
+ if (!This->cached_tile)
+ {
+ This->cached_tile = malloc(info->tile_size);
+ if (!This->cached_tile)
+ return E_OUTOFMEMORY;
+ }
+
+ min_tile_x = prc->X / info->tile_width;
+ min_tile_y = prc->Y / info->tile_height;
+ max_tile_x = (prc->X+prc->Width-1) / info->tile_width;
+ max_tile_y = (prc->Y+prc->Height-1) / info->tile_height;
+
+ for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++)
+ {
+ for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++)
+ {
+ if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y)
+ {
+ hr = tiff_decoder_read_tile(This, tile_x, tile_y);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ if (prc->X < tile_x * info->tile_width)
+ rc.X = 0;
+ else
+ rc.X = prc->X - tile_x * info->tile_width;
+
+ if (prc->Y < tile_y * info->tile_height)
+ rc.Y = 0;
+ else
+ rc.Y = prc->Y - tile_y * info->tile_height;
+
+ if (prc->X+prc->Width > (tile_x+1) * info->tile_width)
+ rc.Width = info->tile_width - rc.X;
+ else if (prc->X < tile_x * info->tile_width)
+ rc.Width = prc->Width + prc->X - tile_x * info->tile_width;
+ else
+ rc.Width = prc->Width;
+
+ if (prc->Y+prc->Height > (tile_y+1) * info->tile_height)
+ rc.Height = info->tile_height - rc.Y;
+ else if (prc->Y < tile_y * info->tile_height)
+ rc.Height = prc->Height + prc->Y - tile_y * info->tile_height;
+ else
+ rc.Height = prc->Height;
+
+ dst_tilepos = buffer + (stride * ((rc.Y + tile_y * info->tile_height) - prc->Y)) +
+ ((info->frame.bpp * ((rc.X + tile_x * info->tile_width) - prc->X) + 7) / 8);
+
+ hr = copy_pixels(info->frame.bpp, This->cached_tile,
+ info->tile_width, info->tile_height, info->tile_stride,
+ &rc, stride, buffersize, dst_tilepos);
+ }
+
+ if (FAILED(hr))
+ {
+ TRACE("<-- 0x%x\n", hr);
+ return hr;
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+static HRESULT CDECL tiff_decoder_get_color_context(struct decoder *iface,
+ UINT frame, UINT num, BYTE **data, DWORD *datasize)
+{
+ struct tiff_decoder *This = impl_from_decoder(iface);
+ const BYTE *profile;
+ UINT len;
+ HRESULT hr;
+
+ hr = tiff_decoder_select_frame(This, frame);
+ if (FAILED(hr))
+ return hr;
+
+ if (!pTIFFGetField(This->tiff, TIFFTAG_ICCPROFILE, &len, &profile))
+ {
+ return E_UNEXPECTED;
+ }
+
+ *datasize = len;
+ *data = RtlAllocateHeap(GetProcessHeap(), 0, len);
+ if (!*data)
+ return E_OUTOFMEMORY;
+
+ memcpy(*data, profile, len);
+
+ return S_OK;
+}
+
+static HRESULT CDECL tiff_decoder_get_metadata_blocks(struct decoder *iface,
+ UINT frame, UINT *count, struct decoder_block **blocks)
+{
+ struct tiff_decoder *This = impl_from_decoder(iface);
+ HRESULT hr;
+ BOOL byte_swapped;
+ struct decoder_block result;
+
+ hr = tiff_decoder_select_frame(This, frame);
+ if (FAILED(hr))
+ return hr;
+
+ *count = 1;
+
+ result.offset = pTIFFCurrentDirOffset(This->tiff);
+ result.length = 0;
+
+ byte_swapped = pTIFFIsByteSwapped(This->tiff);
+#ifdef WORDS_BIGENDIAN
+ result.options = byte_swapped ? WICPersistOptionLittleEndian : WICPersistOptionBigEndian;
+#else
+ result.options = byte_swapped ? WICPersistOptionBigEndian : WICPersistOptionLittleEndian;
+#endif
+ result.options |= WICPersistOptionNoCacheStream|DECODER_BLOCK_FULL_STREAM|DECODER_BLOCK_READER_CLSID;
+ result.reader_clsid = CLSID_WICIfdMetadataReader;
+
+ *blocks = malloc(sizeof(**blocks));
+ **blocks = result;
+
+ return S_OK;
+}
+
+static void CDECL tiff_decoder_destroy(struct decoder* iface)
+{
+ struct tiff_decoder *This = impl_from_decoder(iface);
+ if (This->tiff) pTIFFClose(This->tiff);
+ free(This->cached_tile);
+ RtlFreeHeap(GetProcessHeap(), 0, This);
+}
+
+static const struct decoder_funcs tiff_decoder_vtable = {
+ tiff_decoder_initialize,
+ tiff_decoder_get_frame_info,
+ tiff_decoder_copy_pixels,
+ tiff_decoder_get_metadata_blocks,
+ tiff_decoder_get_color_context,
+ tiff_decoder_destroy
+};
+
+HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result)
+{
+ struct tiff_decoder *This;
+
+ if (!load_libtiff())
+ {
+ ERR("Failed reading TIFF because unable to load %s\n",SONAME_LIBTIFF);
+ return E_FAIL;
+ }
+
+ This = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*This));
+ if (!This) return E_OUTOFMEMORY;
+
+ This->decoder.vtable = &tiff_decoder_vtable;
+ This->tiff = NULL;
+ This->cached_tile = NULL;
+ This->cached_tile_x = -1;
+ *result = &This->decoder;
+
+ info->container_format = GUID_ContainerFormatTiff;
+ info->block_format = GUID_ContainerFormatTiff;
+ info->clsid = CLSID_WICTiffDecoder;
+
+ return S_OK;
+}
+
+#else /* !SONAME_LIBTIFF */
+
+HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result)
+{
+ ERR("Trying to load TIFF picture, but Wine was compiled without TIFF support.\n");
+ return E_FAIL;
+}
+
+#endif
diff --git a/dlls/windowscodecs/main.c b/dlls/windowscodecs/main.c
index 1b5057b1b95..7976b96a393 100644
--- a/dlls/windowscodecs/main.c
+++ b/dlls/windowscodecs/main.c
@@ -191,6 +191,19 @@ HRESULT write_source(IWICBitmapFrameEncode *iface,
return hr;
}
+HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size)
+{
+ STATSTG statstg;
+ HRESULT hr;
+
+ hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME);
+
+ if (SUCCEEDED(hr))
+ *size = statstg.cbSize.QuadPart;
+
+ return hr;
+}
+
HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read)
{
return IStream_Read(stream, buffer, read, bytes_read);
@@ -210,25 +223,6 @@ HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG
return hr;
}
-void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
-{
- UINT x, y;
- BYTE *pixel, temp;
-
- for (y=0; y<height; y++)
- {
- pixel = bits + stride * y;
-
- for (x=0; x<width; x++)
- {
- temp = pixel[2];
- pixel[2] = pixel[0];
- pixel[0] = temp;
- pixel += bytesperpixel;
- }
- }
-}
-
HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp)
{
HRESULT hr;
diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c
index 19cb0cf9286..b2478380334 100644
--- a/dlls/windowscodecs/tiffformat.c
+++ b/dlls/windowscodecs/tiffformat.c
@@ -221,1414 +221,6 @@ static TIFF* tiff_open_stream(IStream *stream, const char *mode)
(void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap);
}
-typedef struct {
- IWICBitmapDecoder IWICBitmapDecoder_iface;
- LONG ref;
- IStream *stream;
- CRITICAL_SECTION lock; /* Must be held when tiff is used or initialized is set */
- TIFF *tiff;
- BOOL initialized;
-} TiffDecoder;
-
-typedef struct {
- const WICPixelFormatGUID *format;
- int bps;
- int samples;
- int bpp, source_bpp;
- int planar;
- int indexed;
- int reverse_bgr;
- int invert_grayscale;
- UINT width, height;
- UINT tile_width, tile_height;
- UINT tile_stride;
- UINT tile_size;
- int tiled;
- UINT tiles_across;
- UINT resolution_unit;
- float xres, yres;
-} tiff_decode_info;
-
-typedef struct {
- IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
- IWICMetadataBlockReader IWICMetadataBlockReader_iface;
- LONG ref;
- TiffDecoder *parent;
- UINT index;
- tiff_decode_info decode_info;
- INT cached_tile_x, cached_tile_y;
- BYTE *cached_tile;
-} TiffFrameDecode;
-
-static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl;
-static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl;
-
-static inline TiffDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
-{
- return CONTAINING_RECORD(iface, TiffDecoder, IWICBitmapDecoder_iface);
-}
-
-static inline TiffFrameDecode *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
-{
- return CONTAINING_RECORD(iface, TiffFrameDecode, IWICBitmapFrameDecode_iface);
-}
-
-static inline TiffFrameDecode *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface)
-{
- return CONTAINING_RECORD(iface, TiffFrameDecode, IWICMetadataBlockReader_iface);
-}
-
-static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
-{
- uint16 photometric, bps, samples, planar;
- uint16 extra_sample_count, extra_sample, *extra_samples;
- int ret;
-
- decode_info->indexed = 0;
- decode_info->reverse_bgr = 0;
- decode_info->invert_grayscale = 0;
- decode_info->tiled = 0;
- decode_info->source_bpp = 0;
-
- ret = pTIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
- if (!ret)
- {
- WARN("missing PhotometricInterpretation tag\n");
- return E_FAIL;
- }
-
- ret = pTIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps);
- if (!ret) bps = 1;
- decode_info->bps = bps;
-
- ret = pTIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples);
- if (!ret) samples = 1;
- decode_info->samples = samples;
-
- if (samples == 1)
- planar = 1;
- else
- {
- ret = pTIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar);
- if (!ret) planar = 1;
- if (planar != 1)
- {
- FIXME("unhandled planar configuration %u\n", planar);
- return E_FAIL;
- }
- }
- decode_info->planar = planar;
-
- TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps);
-
- switch(photometric)
- {
- case 0: /* WhiteIsZero */
- decode_info->invert_grayscale = 1;
- /* fall through */
- case 1: /* BlackIsZero */
- if (samples == 2)
- {
- ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
- if (!ret)
- {
- extra_sample_count = 1;
- extra_sample = 0;
- extra_samples = &extra_sample;
- }
- }
- else if (samples != 1)
- {
- FIXME("unhandled %dbpp sample count %u\n", bps, samples);
- return E_FAIL;
- }
-
- decode_info->bpp = bps * samples;
- decode_info->source_bpp = decode_info->bpp;
- switch (bps)
- {
- case 1:
- if (samples != 1)
- {
- FIXME("unhandled 1bpp sample count %u\n", samples);
- return E_FAIL;
- }
- decode_info->format = &GUID_WICPixelFormatBlackWhite;
- break;
- case 4:
- if (samples != 1)
- {
- FIXME("unhandled 4bpp grayscale sample count %u\n", samples);
- return E_FAIL;
- }
- decode_info->format = &GUID_WICPixelFormat4bppGray;
- break;
- case 8:
- if (samples == 1)
- decode_info->format = &GUID_WICPixelFormat8bppGray;
- else
- {
- decode_info->bpp = 32;
-
- switch(extra_samples[0])
- {
- case 1: /* Associated (pre-multiplied) alpha data */
- decode_info->format = &GUID_WICPixelFormat32bppPBGRA;
- break;
- case 0: /* Unspecified data */
- case 2: /* Unassociated alpha data */
- decode_info->format = &GUID_WICPixelFormat32bppBGRA;
- break;
- default:
- FIXME("unhandled extra sample type %u\n", extra_samples[0]);
- return E_FAIL;
- }
- }
- break;
- case 16:
- if (samples != 1)
- {
- FIXME("unhandled 16bpp grayscale sample count %u\n", samples);
- return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
- }
- decode_info->format = &GUID_WICPixelFormat16bppGray;
- break;
- case 32:
- if (samples != 1)
- {
- FIXME("unhandled 32bpp grayscale sample count %u\n", samples);
- return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
- }
- decode_info->format = &GUID_WICPixelFormat32bppGrayFloat;
- break;
- default:
- WARN("unhandled greyscale bit count %u\n", bps);
- return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
- }
- break;
- case 2: /* RGB */
- if (samples == 4)
- {
- ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
- if (!ret)
- {
- extra_sample_count = 1;
- extra_sample = 0;
- extra_samples = &extra_sample;
- }
- }
- else if (samples != 3)
- {
- FIXME("unhandled RGB sample count %u\n", samples);
- return E_FAIL;
- }
-
- decode_info->bpp = max(bps, 8) * samples;
- decode_info->source_bpp = bps * samples;
- switch(bps)
- {
- case 1:
- case 4:
- case 8:
- decode_info->reverse_bgr = 1;
- if (samples == 3)
- decode_info->format = &GUID_WICPixelFormat24bppBGR;
- else
- switch(extra_samples[0])
- {
- case 1: /* Associated (pre-multiplied) alpha data */
- decode_info->format = &GUID_WICPixelFormat32bppPBGRA;
- break;
- case 0: /* Unspecified data */
- case 2: /* Unassociated alpha data */
- decode_info->format = &GUID_WICPixelFormat32bppBGRA;
- break;
- default:
- FIXME("unhandled extra sample type %i\n", extra_samples[0]);
- return E_FAIL;
- }
- break;
- case 16:
- if (samples == 3)
- decode_info->format = &GUID_WICPixelFormat48bppRGB;
- else
- switch(extra_samples[0])
- {
- case 1: /* Associated (pre-multiplied) alpha data */
- decode_info->format = &GUID_WICPixelFormat64bppPRGBA;
- break;
- case 0: /* Unspecified data */
- case 2: /* Unassociated alpha data */
- decode_info->format = &GUID_WICPixelFormat64bppRGBA;
- break;
- default:
- FIXME("unhandled extra sample type %i\n", extra_samples[0]);
- return E_FAIL;
- }
- break;
- case 32:
- if (samples == 3)
- decode_info->format = &GUID_WICPixelFormat96bppRGBFloat;
- else
- switch(extra_samples[0])
- {
- case 1: /* Associated (pre-multiplied) alpha data */
- decode_info->format = &GUID_WICPixelFormat128bppPRGBAFloat;
- break;
- case 0: /* Unspecified data */
- case 2: /* Unassociated alpha data */
- decode_info->format = &GUID_WICPixelFormat128bppRGBAFloat;
- break;
- default:
- FIXME("unhandled extra sample type %i\n", extra_samples[0]);
- return E_FAIL;
- }
- break;
- default:
- WARN("unhandled RGB bit count %u\n", bps);
- return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
- }
- break;
- case 3: /* RGB Palette */
- if (samples != 1)
- {
- FIXME("unhandled indexed sample count %u\n", samples);
- return E_FAIL;
- }
-
- decode_info->indexed = 1;
- decode_info->bpp = bps;
- switch (bps)
- {
- case 1:
- decode_info->format = &GUID_WICPixelFormat1bppIndexed;
- break;
- case 2:
- decode_info->format = &GUID_WICPixelFormat2bppIndexed;
- break;
- case 4:
- decode_info->format = &GUID_WICPixelFormat4bppIndexed;
- break;
- case 8:
- decode_info->format = &GUID_WICPixelFormat8bppIndexed;
- break;
- default:
- FIXME("unhandled indexed bit count %u\n", bps);
- return E_NOTIMPL;
- }
- break;
-
- case 5: /* Separated */
- if (samples != 4)
- {
- FIXME("unhandled Separated sample count %u\n", samples);
- return E_FAIL;
- }
-
- decode_info->bpp = bps * samples;
- switch(bps)
- {
- case 8:
- decode_info->format = &GUID_WICPixelFormat32bppCMYK;
- break;
- case 16:
- decode_info->format = &GUID_WICPixelFormat64bppCMYK;
- break;
-
- default:
- WARN("unhandled Separated bit count %u\n", bps);
- return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
- }
- break;
-
- case 4: /* Transparency mask */
- case 6: /* YCbCr */
- case 8: /* CIELab */
- default:
- FIXME("unhandled PhotometricInterpretation %u\n", photometric);
- return E_FAIL;
- }
-
- ret = pTIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->width);
- if (!ret)
- {
- WARN("missing image width\n");
- return E_FAIL;
- }
-
- ret = pTIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->height);
- if (!ret)
- {
- WARN("missing image length\n");
- return E_FAIL;
- }
-
- if ((ret = pTIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width)))
- {
- decode_info->tiled = 1;
-
- ret = pTIFFGetField(tiff, TIFFTAG_TILELENGTH, &decode_info->tile_height);
- if (!ret)
- {
- WARN("missing tile height\n");
- return E_FAIL;
- }
-
- decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
- decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
- decode_info->tiles_across = (decode_info->width + decode_info->tile_width - 1) / decode_info->tile_width;
- }
- else if ((ret = pTIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height)))
- {
- if (decode_info->tile_height > decode_info->height)
- decode_info->tile_height = decode_info->height;
- decode_info->tile_width = decode_info->width;
- decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
- decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
- }
- else
- {
- /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */
- decode_info->tile_height = decode_info->height;
- decode_info->tile_width = decode_info->width;
- decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
- decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
- }
-
- decode_info->resolution_unit = 0;
- pTIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &decode_info->resolution_unit);
-
- ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres);
- if (!ret)
- {
- WARN("missing X resolution\n");
- }
- /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131)
- * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */
- if (!isfinite(decode_info->xres))
- {
- decode_info->xres = 0.0;
- }
-
- ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &decode_info->yres);
- if (!ret)
- {
- WARN("missing Y resolution\n");
- }
- if (!isfinite(decode_info->yres))
- {
- decode_info->yres = 0.0;
- }
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
- void **ppv)
-{
- TiffDecoder *This = impl_from_IWICBitmapDecoder(iface);
- TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
-
- if (!ppv) return E_INVALIDARG;
-
- if (IsEqualIID(&IID_IUnknown, iid) ||
- IsEqualIID(&IID_IWICBitmapDecoder, iid))
- {
- *ppv = &This->IWICBitmapDecoder_iface;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
-static ULONG WINAPI TiffDecoder_AddRef(IWICBitmapDecoder *iface)
-{
- TiffDecoder *This = impl_from_IWICBitmapDecoder(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
-
- return ref;
-}
-
-static ULONG WINAPI TiffDecoder_Release(IWICBitmapDecoder *iface)
-{
- TiffDecoder *This = impl_from_IWICBitmapDecoder(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
-
- if (ref == 0)
- {
- if (This->tiff) pTIFFClose(This->tiff);
- if (This->stream) IStream_Release(This->stream);
- This->lock.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&This->lock);
- HeapFree(GetProcessHeap(), 0, This);
- }
-
- return ref;
-}
-
-static HRESULT WINAPI TiffDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream,
- DWORD *capability)
-{
- HRESULT hr;
-
- TRACE("(%p,%p,%p)\n", iface, stream, capability);
-
- if (!stream || !capability) return E_INVALIDARG;
-
- hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
- if (hr != S_OK) return hr;
-
- *capability = WICBitmapDecoderCapabilityCanDecodeAllImages |
- WICBitmapDecoderCapabilityCanDecodeSomeImages |
- WICBitmapDecoderCapabilityCanEnumerateMetadata;
- return S_OK;
-}
-
-static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
- WICDecodeOptions cacheOptions)
-{
- TiffDecoder *This = impl_from_IWICBitmapDecoder(iface);
- TIFF *tiff;
- tiff_decode_info decode_info;
- HRESULT hr=S_OK;
-
- TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
-
- EnterCriticalSection(&This->lock);
-
- if (This->initialized)
- {
- hr = WINCODEC_ERR_WRONGSTATE;
- goto exit;
- }
-
- tiff = tiff_open_stream(pIStream, "r");
- if (!tiff)
- {
- hr = E_FAIL;
- goto exit;
- }
-
- /* make sure that TIFF format is supported */
- hr = tiff_get_decode_info(tiff, &decode_info);
- if (hr != S_OK)
- {
- pTIFFClose(tiff);
- goto exit;
- }
-
- This->tiff = tiff;
- This->stream = pIStream;
- IStream_AddRef(pIStream);
- This->initialized = TRUE;
-
-exit:
- LeaveCriticalSection(&This->lock);
- return hr;
-}
-
-static HRESULT WINAPI TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
- GUID *pguidContainerFormat)
-{
- if (!pguidContainerFormat) return E_INVALIDARG;
-
- memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff, sizeof(GUID));
- return S_OK;
-}
-
-static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
- IWICBitmapDecoderInfo **ppIDecoderInfo)
-{
- TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
-
- return get_decoder_info(&CLSID_WICTiffDecoder, ppIDecoderInfo);
-}
-
-static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface,
- IWICPalette *palette)
-{
- TRACE("(%p,%p)\n", iface, palette);
- return WINCODEC_ERR_PALETTEUNAVAILABLE;
-}
-
-static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
- IWICMetadataQueryReader **ppIMetadataQueryReader)
-{
- TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
-
- if (!ppIMetadataQueryReader) return E_INVALIDARG;
-
- *ppIMetadataQueryReader = NULL;
- return WINCODEC_ERR_UNSUPPORTEDOPERATION;
-}
-
-static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface,
- IWICBitmapSource **ppIBitmapSource)
-{
- TRACE("(%p,%p)\n", iface, ppIBitmapSource);
-
- if (!ppIBitmapSource) return E_INVALIDARG;
-
- *ppIBitmapSource = NULL;
- return WINCODEC_ERR_UNSUPPORTEDOPERATION;
-}
-
-static HRESULT WINAPI TiffDecoder_GetColorContexts(IWICBitmapDecoder *iface,
- UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
-{
- FIXME("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
- return WINCODEC_ERR_UNSUPPORTEDOPERATION;
-}
-
-static HRESULT WINAPI TiffDecoder_GetThumbnail(IWICBitmapDecoder *iface,
- IWICBitmapSource **ppIThumbnail)
-{
- TRACE("(%p,%p)\n", iface, ppIThumbnail);
-
- if (!ppIThumbnail) return E_INVALIDARG;
-
- *ppIThumbnail = NULL;
- return WINCODEC_ERR_CODECNOTHUMBNAIL;
-}
-
-static HRESULT WINAPI TiffDecoder_GetFrameCount(IWICBitmapDecoder *iface,
- UINT *pCount)
-{
- TiffDecoder *This = impl_from_IWICBitmapDecoder(iface);
-
- if (!pCount) return E_INVALIDARG;
-
- EnterCriticalSection(&This->lock);
- *pCount = This->tiff ? pTIFFNumberOfDirectories(This->tiff) : 0;
- LeaveCriticalSection(&This->lock);
-
- TRACE("(%p) <-- %i\n", iface, *pCount);
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffDecoder_GetFrame(IWICBitmapDecoder *iface,
- UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
-{
- TiffDecoder *This = impl_from_IWICBitmapDecoder(iface);
- TiffFrameDecode *result;
- int res;
- tiff_decode_info decode_info;
- HRESULT hr;
-
- TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
-
- if (!This->tiff)
- return WINCODEC_ERR_FRAMEMISSING;
-
- EnterCriticalSection(&This->lock);
- res = pTIFFSetDirectory(This->tiff, index);
- if (!res) hr = E_INVALIDARG;
- else hr = tiff_get_decode_info(This->tiff, &decode_info);
- LeaveCriticalSection(&This->lock);
-
- if (SUCCEEDED(hr))
- {
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffFrameDecode));
-
- if (result)
- {
- result->IWICBitmapFrameDecode_iface.lpVtbl = &TiffFrameDecode_Vtbl;
- result->IWICMetadataBlockReader_iface.lpVtbl = &TiffFrameDecode_BlockVtbl;
- result->ref = 1;
- result->parent = This;
- IWICBitmapDecoder_AddRef(iface);
- result->index = index;
- result->decode_info = decode_info;
- result->cached_tile_x = -1;
- result->cached_tile = HeapAlloc(GetProcessHeap(), 0, decode_info.tile_size);
-
- if (result->cached_tile)
- *ppIBitmapFrame = &result->IWICBitmapFrameDecode_iface;
- else
- {
- hr = E_OUTOFMEMORY;
- IWICBitmapFrameDecode_Release(&result->IWICBitmapFrameDecode_iface);
- }
- }
- else hr = E_OUTOFMEMORY;
- }
-
- if (FAILED(hr)) *ppIBitmapFrame = NULL;
-
- return hr;
-}
-
-static const IWICBitmapDecoderVtbl TiffDecoder_Vtbl = {
- TiffDecoder_QueryInterface,
- TiffDecoder_AddRef,
- TiffDecoder_Release,
- TiffDecoder_QueryCapability,
- TiffDecoder_Initialize,
- TiffDecoder_GetContainerFormat,
- TiffDecoder_GetDecoderInfo,
- TiffDecoder_CopyPalette,
- TiffDecoder_GetMetadataQueryReader,
- TiffDecoder_GetPreview,
- TiffDecoder_GetColorContexts,
- TiffDecoder_GetThumbnail,
- TiffDecoder_GetFrameCount,
- TiffDecoder_GetFrame
-};
-
-static HRESULT WINAPI TiffFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
- void **ppv)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
- TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
-
- if (!ppv) return E_INVALIDARG;
-
- if (IsEqualIID(&IID_IUnknown, iid) ||
- IsEqualIID(&IID_IWICBitmapSource, iid) ||
- IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
- {
- *ppv = &This->IWICBitmapFrameDecode_iface;
- }
- else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid))
- {
- *ppv = &This->IWICMetadataBlockReader_iface;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
-static ULONG WINAPI TiffFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
-
- return ref;
-}
-
-static ULONG WINAPI TiffFrameDecode_Release(IWICBitmapFrameDecode *iface)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
-
- if (ref == 0)
- {
- IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface);
- HeapFree(GetProcessHeap(), 0, This->cached_tile);
- HeapFree(GetProcessHeap(), 0, This);
- }
-
- return ref;
-}
-
-static HRESULT WINAPI TiffFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
- UINT *puiWidth, UINT *puiHeight)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
-
- *puiWidth = This->decode_info.width;
- *puiHeight = This->decode_info.height;
-
- TRACE("(%p) <-- %ux%u\n", iface, *puiWidth, *puiHeight);
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
- WICPixelFormatGUID *pPixelFormat)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
-
- memcpy(pPixelFormat, This->decode_info.format, sizeof(GUID));
-
- TRACE("(%p) <-- %s\n", This, debugstr_guid(This->decode_info.format));
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
- double *pDpiX, double *pDpiY)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
-
- if (This->decode_info.xres == 0 || This->decode_info.yres == 0)
- {
- *pDpiX = *pDpiY = 96.0;
- }
- else
- {
- switch (This->decode_info.resolution_unit)
- {
- default:
- FIXME("unknown resolution unit %i\n", This->decode_info.resolution_unit);
- /* fall through */
- case 0: /* Not set */
- case 1: /* Relative measurements */
- case 2: /* Inch */
- *pDpiX = This->decode_info.xres;
- *pDpiY = This->decode_info.yres;
- break;
- case 3: /* Centimeter */
- *pDpiX = This->decode_info.xres * 2.54;
- *pDpiY = This->decode_info.yres * 2.54;
- break;
- }
- }
-
- TRACE("(%p) <-- %f,%f unit=%i\n", iface, *pDpiX, *pDpiY, This->decode_info.resolution_unit);
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
- IWICPalette *pIPalette)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
- uint16 *red, *green, *blue;
- WICColor colors[256];
- int color_count, ret, i;
-
- TRACE("(%p,%p)\n", iface, pIPalette);
-
- color_count = 1<<This->decode_info.bps;
-
- EnterCriticalSection(&This->parent->lock);
- ret = pTIFFGetField(This->parent->tiff, TIFFTAG_COLORMAP, &red, &green, &blue);
- LeaveCriticalSection(&This->parent->lock);
-
- if (!ret)
- {
- WARN("Couldn't read color map\n");
- return WINCODEC_ERR_PALETTEUNAVAILABLE;
- }
-
- for (i=0; i<color_count; i++)
- {
- colors[i] = 0xff000000 |
- ((red[i]<<8) & 0xff0000) |
- (green[i] & 0xff00) |
- ((blue[i]>>8) & 0xff);
- }
-
- return IWICPalette_InitializeCustom(pIPalette, colors, color_count);
-}
-
-static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y)
-{
- tsize_t ret;
- int swap_bytes;
-
- swap_bytes = pTIFFIsByteSwapped(This->parent->tiff);
-
- ret = pTIFFSetDirectory(This->parent->tiff, This->index);
- if (ret == -1)
- return E_FAIL;
-
- if (This->decode_info.tiled)
- ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size);
- else
- ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size);
-
- if (ret == -1)
- return E_FAIL;
-
- /* 3bps RGB */
- if (This->decode_info.source_bpp == 3 && This->decode_info.samples == 3 && This->decode_info.bpp == 24)
- {
- BYTE *srcdata, *src, *dst;
- DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8;
-
- count = width_bytes * This->decode_info.tile_height;
-
- srcdata = HeapAlloc(GetProcessHeap(), 0, count);
- if (!srcdata) return E_OUTOFMEMORY;
- memcpy(srcdata, This->cached_tile, count);
-
- for (y = 0; y < This->decode_info.tile_height; y++)
- {
- src = srcdata + y * width_bytes;
- dst = This->cached_tile + y * This->decode_info.tile_width * 3;
-
- for (x = 0; x < This->decode_info.tile_width; x += 8)
- {
- dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
- dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
- dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
- if (x + 1 < This->decode_info.tile_width)
- {
- dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */
- dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */
- dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */
- }
- if (x + 2 < This->decode_info.tile_width)
- {
- dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */
- dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */
- dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */
- }
- if (x + 3 < This->decode_info.tile_width)
- {
- dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */
- dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */
- dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */
- }
- if (x + 4 < This->decode_info.tile_width)
- {
- dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */
- dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */
- dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */
- }
- if (x + 5 < This->decode_info.tile_width)
- {
- dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */
- dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */
- dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */
- }
- if (x + 6 < This->decode_info.tile_width)
- {
- dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */
- dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */
- dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */
- }
- if (x + 7 < This->decode_info.tile_width)
- {
- dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */
- dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */
- dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */
- }
- src += 3;
- dst += 24;
- }
- }
-
- HeapFree(GetProcessHeap(), 0, srcdata);
- }
- /* 12bps RGB */
- else if (This->decode_info.source_bpp == 12 && This->decode_info.samples == 3 && This->decode_info.bpp == 24)
- {
- BYTE *srcdata, *src, *dst;
- DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 12 + 7) / 8;
-
- count = width_bytes * This->decode_info.tile_height;
-
- srcdata = HeapAlloc(GetProcessHeap(), 0, count);
- if (!srcdata) return E_OUTOFMEMORY;
- memcpy(srcdata, This->cached_tile, count);
-
- for (y = 0; y < This->decode_info.tile_height; y++)
- {
- src = srcdata + y * width_bytes;
- dst = This->cached_tile + y * This->decode_info.tile_width * 3;
-
- for (x = 0; x < This->decode_info.tile_width; x += 2)
- {
- dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
- dst[1] = (src[0] & 0x0f) * 17; /* G */
- dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
- if (x + 1 < This->decode_info.tile_width)
- {
- dst[5] = (src[1] & 0x0f) * 17; /* B */
- dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */
- dst[3] = (src[2] & 0x0f) * 17; /* R */
- }
- src += 3;
- dst += 6;
- }
- }
-
- HeapFree(GetProcessHeap(), 0, srcdata);
- }
- /* 4bps RGBA */
- else if (This->decode_info.source_bpp == 4 && This->decode_info.samples == 4 && This->decode_info.bpp == 32)
- {
- BYTE *srcdata, *src, *dst;
- DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8;
-
- count = width_bytes * This->decode_info.tile_height;
-
- srcdata = HeapAlloc(GetProcessHeap(), 0, count);
- if (!srcdata) return E_OUTOFMEMORY;
- memcpy(srcdata, This->cached_tile, count);
-
- for (y = 0; y < This->decode_info.tile_height; y++)
- {
- src = srcdata + y * width_bytes;
- dst = This->cached_tile + y * This->decode_info.tile_width * 4;
-
- /* 1 source byte expands to 2 BGRA samples */
-
- for (x = 0; x < This->decode_info.tile_width; x += 2)
- {
- dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
- dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
- dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
- dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */
- if (x + 1 < This->decode_info.tile_width)
- {
- dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */
- dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */
- dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */
- dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */
- }
- src++;
- dst += 8;
- }
- }
-
- HeapFree(GetProcessHeap(), 0, srcdata);
- }
- /* 16bps RGBA */
- else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 4 && This->decode_info.bpp == 32)
- {
- BYTE *srcdata, *src, *dst;
- DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 12 + 7) / 8;
-
- count = width_bytes * This->decode_info.tile_height;
-
- srcdata = HeapAlloc(GetProcessHeap(), 0, count);
- if (!srcdata) return E_OUTOFMEMORY;
- memcpy(srcdata, This->cached_tile, count);
-
- for (y = 0; y < This->decode_info.tile_height; y++)
- {
- src = srcdata + y * width_bytes;
- dst = This->cached_tile + y * This->decode_info.tile_width * 4;
-
- for (x = 0; x < This->decode_info.tile_width; x++)
- {
- dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
- dst[1] = (src[0] & 0x0f) * 17; /* G */
- dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
- dst[3] = (src[1] & 0x0f) * 17; /* A */
- src += 2;
- dst += 4;
- }
- }
-
- HeapFree(GetProcessHeap(), 0, srcdata);
- }
- /* 8bpp grayscale with extra alpha */
- else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32)
- {
- BYTE *src;
- DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height;
-
- src = This->cached_tile + This->decode_info.tile_width * This->decode_info.tile_height * 2 - 2;
- dst = (DWORD *)(This->cached_tile + This->decode_info.tile_size - 4);
-
- while (count--)
- {
- *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24);
- src -= 2;
- }
- }
-
- if (This->decode_info.reverse_bgr)
- {
- if (This->decode_info.bps == 8)
- {
- UINT sample_count = This->decode_info.samples;
-
- reverse_bgr8(sample_count, This->cached_tile, This->decode_info.tile_width,
- This->decode_info.tile_height, This->decode_info.tile_width * sample_count);
- }
- }
-
- if (swap_bytes && This->decode_info.bps > 8)
- {
- UINT row, i, samples_per_row;
- BYTE *sample, temp;
-
- samples_per_row = This->decode_info.tile_width * This->decode_info.samples;
-
- switch(This->decode_info.bps)
- {
- case 16:
- for (row=0; row<This->decode_info.tile_height; row++)
- {
- sample = This->cached_tile + row * This->decode_info.tile_stride;
- for (i=0; i<samples_per_row; i++)
- {
- temp = sample[1];
- sample[1] = sample[0];
- sample[0] = temp;
- sample += 2;
- }
- }
- break;
- default:
- ERR("unhandled bps for byte swap %u\n", This->decode_info.bps);
- return E_FAIL;
- }
- }
-
- if (This->decode_info.invert_grayscale)
- {
- BYTE *byte, *end;
-
- if (This->decode_info.samples != 1)
- {
- ERR("cannot invert grayscale image with %u samples\n", This->decode_info.samples);
- return E_FAIL;
- }
-
- end = This->cached_tile+This->decode_info.tile_size;
-
- for (byte = This->cached_tile; byte != end; byte++)
- *byte = ~(*byte);
- }
-
- This->cached_tile_x = tile_x;
- This->cached_tile_y = tile_y;
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
- const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
- UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y;
- UINT tile_x, tile_y;
- WICRect rc;
- HRESULT hr=S_OK;
- BYTE *dst_tilepos;
- UINT bytesperrow;
- WICRect rect;
-
- TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer);
-
- if (!prc)
- {
- rect.X = 0;
- rect.Y = 0;
- rect.Width = This->decode_info.width;
- rect.Height = This->decode_info.height;
- prc = ▭
- }
- else
- {
- if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->decode_info.width ||
- prc->Y+prc->Height > This->decode_info.height)
- return E_INVALIDARG;
- }
-
- bytesperrow = ((This->decode_info.bpp * prc->Width)+7)/8;
-
- if (cbStride < bytesperrow)
- return E_INVALIDARG;
-
- if ((cbStride * (prc->Height-1)) + bytesperrow > cbBufferSize)
- return E_INVALIDARG;
-
- min_tile_x = prc->X / This->decode_info.tile_width;
- min_tile_y = prc->Y / This->decode_info.tile_height;
- max_tile_x = (prc->X+prc->Width-1) / This->decode_info.tile_width;
- max_tile_y = (prc->Y+prc->Height-1) / This->decode_info.tile_height;
-
- EnterCriticalSection(&This->parent->lock);
-
- for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++)
- {
- for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++)
- {
- if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y)
- {
- hr = TiffFrameDecode_ReadTile(This, tile_x, tile_y);
- }
-
- if (SUCCEEDED(hr))
- {
- if (prc->X < tile_x * This->decode_info.tile_width)
- rc.X = 0;
- else
- rc.X = prc->X - tile_x * This->decode_info.tile_width;
-
- if (prc->Y < tile_y * This->decode_info.tile_height)
- rc.Y = 0;
- else
- rc.Y = prc->Y - tile_y * This->decode_info.tile_height;
-
- if (prc->X+prc->Width > (tile_x+1) * This->decode_info.tile_width)
- rc.Width = This->decode_info.tile_width - rc.X;
- else if (prc->X < tile_x * This->decode_info.tile_width)
- rc.Width = prc->Width + prc->X - tile_x * This->decode_info.tile_width;
- else
- rc.Width = prc->Width;
-
- if (prc->Y+prc->Height > (tile_y+1) * This->decode_info.tile_height)
- rc.Height = This->decode_info.tile_height - rc.Y;
- else if (prc->Y < tile_y * This->decode_info.tile_height)
- rc.Height = prc->Height + prc->Y - tile_y * This->decode_info.tile_height;
- else
- rc.Height = prc->Height;
-
- dst_tilepos = pbBuffer + (cbStride * ((rc.Y + tile_y * This->decode_info.tile_height) - prc->Y)) +
- ((This->decode_info.bpp * ((rc.X + tile_x * This->decode_info.tile_width) - prc->X) + 7) / 8);
-
- hr = copy_pixels(This->decode_info.bpp, This->cached_tile,
- This->decode_info.tile_width, This->decode_info.tile_height, This->decode_info.tile_stride,
- &rc, cbStride, cbBufferSize, dst_tilepos);
- }
-
- if (FAILED(hr))
- {
- LeaveCriticalSection(&This->parent->lock);
- TRACE("<-- 0x%x\n", hr);
- return hr;
- }
- }
- }
-
- LeaveCriticalSection(&This->parent->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
- IWICMetadataQueryReader **ppIMetadataQueryReader)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
-
- TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
-
- if (!ppIMetadataQueryReader)
- return E_INVALIDARG;
-
- return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader);
-}
-
-static HRESULT WINAPI TiffFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface,
- UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
-{
- TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
- const BYTE *profile;
- UINT len;
- HRESULT hr;
-
- TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
-
- EnterCriticalSection(&This->parent->lock);
-
- if (pTIFFGetField(This->parent->tiff, TIFFTAG_ICCPROFILE, &len, &profile))
- {
- if (cCount && ppIColorContexts)
- {
- hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len);
- if (FAILED(hr))
- {
- LeaveCriticalSection(&This->parent->lock);
- return hr;
- }
- }
- *pcActualCount = 1;
- }
- else
- *pcActualCount = 0;
-
- LeaveCriticalSection(&This->parent->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
- IWICBitmapSource **ppIThumbnail)
-{
- TRACE("(%p,%p)\n", iface, ppIThumbnail);
-
- if (!ppIThumbnail) return E_INVALIDARG;
-
- *ppIThumbnail = NULL;
- return WINCODEC_ERR_CODECNOTHUMBNAIL;
-}
-
-static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl = {
- TiffFrameDecode_QueryInterface,
- TiffFrameDecode_AddRef,
- TiffFrameDecode_Release,
- TiffFrameDecode_GetSize,
- TiffFrameDecode_GetPixelFormat,
- TiffFrameDecode_GetResolution,
- TiffFrameDecode_CopyPalette,
- TiffFrameDecode_CopyPixels,
- TiffFrameDecode_GetMetadataQueryReader,
- TiffFrameDecode_GetColorContexts,
- TiffFrameDecode_GetThumbnail
-};
-
-static HRESULT WINAPI TiffFrameDecode_Block_QueryInterface(IWICMetadataBlockReader *iface,
- REFIID iid, void **ppv)
-{
- TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface);
- return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv);
-}
-
-static ULONG WINAPI TiffFrameDecode_Block_AddRef(IWICMetadataBlockReader *iface)
-{
- TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface);
- return IWICBitmapFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface);
-}
-
-static ULONG WINAPI TiffFrameDecode_Block_Release(IWICMetadataBlockReader *iface)
-{
- TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface);
- return IWICBitmapFrameDecode_Release(&This->IWICBitmapFrameDecode_iface);
-}
-
-static HRESULT WINAPI TiffFrameDecode_Block_GetContainerFormat(IWICMetadataBlockReader *iface,
- GUID *guid)
-{
- TRACE("(%p,%p)\n", iface, guid);
-
- if (!guid) return E_INVALIDARG;
-
- *guid = GUID_ContainerFormatTiff;
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface,
- UINT *count)
-{
- TRACE("%p,%p\n", iface, count);
-
- if (!count) return E_INVALIDARG;
-
- *count = 1;
- return S_OK;
-}
-
-static HRESULT create_metadata_reader(TiffFrameDecode *This, IWICMetadataReader **reader)
-{
- HRESULT hr;
- LARGE_INTEGER dir_offset;
- IWICMetadataReader *metadata_reader;
- IWICPersistStream *persist;
-
- /* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
-
- hr = IfdMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void **)&metadata_reader);
- if (FAILED(hr)) return hr;
-
- hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist);
- if (FAILED(hr))
- {
- IWICMetadataReader_Release(metadata_reader);
- return hr;
- }
-
- EnterCriticalSection(&This->parent->lock);
-
- dir_offset.QuadPart = pTIFFCurrentDirOffset(This->parent->tiff);
- hr = IStream_Seek(This->parent->stream, dir_offset, STREAM_SEEK_SET, NULL);
- if (SUCCEEDED(hr))
- {
- BOOL byte_swapped = pTIFFIsByteSwapped(This->parent->tiff);
-#ifdef WORDS_BIGENDIAN
- DWORD persist_options = byte_swapped ? WICPersistOptionLittleEndian : WICPersistOptionBigEndian;
-#else
- DWORD persist_options = byte_swapped ? WICPersistOptionBigEndian : WICPersistOptionLittleEndian;
-#endif
- persist_options |= WICPersistOptionNoCacheStream;
- hr = IWICPersistStream_LoadEx(persist, This->parent->stream, NULL, persist_options);
- if (FAILED(hr))
- ERR("IWICPersistStream_LoadEx error %#x\n", hr);
- }
-
- LeaveCriticalSection(&This->parent->lock);
-
- IWICPersistStream_Release(persist);
-
- if (FAILED(hr))
- {
- IWICMetadataReader_Release(metadata_reader);
- return hr;
- }
-
- *reader = metadata_reader;
- return S_OK;
-}
-
-static HRESULT WINAPI TiffFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface,
- UINT index, IWICMetadataReader **reader)
-{
- TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface);
-
- TRACE("(%p,%u,%p)\n", iface, index, reader);
-
- if (!reader || index != 0) return E_INVALIDARG;
-
- return create_metadata_reader(This, reader);
-}
-
-static HRESULT WINAPI TiffFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface,
- IEnumUnknown **enum_metadata)
-{
- FIXME("(%p,%p): stub\n", iface, enum_metadata);
- return E_NOTIMPL;
-}
-
-static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl =
-{
- TiffFrameDecode_Block_QueryInterface,
- TiffFrameDecode_Block_AddRef,
- TiffFrameDecode_Block_Release,
- TiffFrameDecode_Block_GetContainerFormat,
- TiffFrameDecode_Block_GetCount,
- TiffFrameDecode_Block_GetReaderByIndex,
- TiffFrameDecode_Block_GetEnumerator
-};
-
-HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv)
-{
- HRESULT ret;
- TiffDecoder *This;
-
- TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
-
- *ppv = NULL;
-
- if (!load_libtiff())
- {
- ERR("Failed reading TIFF because unable to load %s\n",SONAME_LIBTIFF);
- return E_FAIL;
- }
-
- This = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffDecoder));
- if (!This) return E_OUTOFMEMORY;
-
- This->IWICBitmapDecoder_iface.lpVtbl = &TiffDecoder_Vtbl;
- This->ref = 1;
- This->stream = NULL;
- InitializeCriticalSection(&This->lock);
- This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffDecoder.lock");
- This->tiff = NULL;
- This->initialized = FALSE;
-
- ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
- IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
-
- return ret;
-}
-
struct tiff_encode_format {
const WICPixelFormatGUID *guid;
int photometric;
@@ -2386,12 +978,6 @@ HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv)
#else /* !SONAME_LIBTIFF */
-HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv)
-{
- ERR("Trying to load TIFF picture, but Wine was compiled without TIFF support.\n");
- return E_FAIL;
-}
-
HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv)
{
ERR("Trying to save TIFF picture, but Wine was compiled without TIFF support.\n");
@@ -2399,3 +985,17 @@ HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv)
}
#endif
+
+HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv)
+{
+ HRESULT hr;
+ struct decoder *decoder;
+ struct decoder_info decoder_info;
+
+ hr = get_unix_decoder(&CLSID_WICTiffDecoder, &decoder_info, &decoder);
+
+ if (SUCCEEDED(hr))
+ hr = CommonDecoder_CreateInstance(decoder, &decoder_info, iid, ppv);
+
+ return hr;
+}
diff --git a/dlls/windowscodecs/unix_iface.c b/dlls/windowscodecs/unix_iface.c
index e376ea45841..5ed995e7642 100644
--- a/dlls/windowscodecs/unix_iface.c
+++ b/dlls/windowscodecs/unix_iface.c
@@ -40,6 +40,7 @@ static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
static const struct unix_funcs *unix_funcs;
static const struct win32_funcs win32_funcs = {
+ stream_getsize,
stream_read,
stream_seek
};
diff --git a/dlls/windowscodecs/unix_lib.c b/dlls/windowscodecs/unix_lib.c
index 04cbe053a0e..ca2b38ef990 100644
--- a/dlls/windowscodecs/unix_lib.c
+++ b/dlls/windowscodecs/unix_lib.c
@@ -47,6 +47,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
static const struct win32_funcs *win32_funcs;
+HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size)
+{
+ return win32_funcs->stream_getsize(stream, size);
+}
+
HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read)
{
return win32_funcs->stream_read(stream, buffer, read, bytes_read);
@@ -62,6 +67,9 @@ HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *in
if (IsEqualGUID(decoder_clsid, &CLSID_WICPngDecoder))
return png_decoder_create(info, result);
+ if (IsEqualGUID(decoder_clsid, &CLSID_WICTiffDecoder))
+ return tiff_decoder_create(info, result);
+
return E_NOTIMPL;
}
diff --git a/dlls/windowscodecs/wincodecs_common.h b/dlls/windowscodecs/wincodecs_common.h
index 07e6dcaf44a..b7572d69df4 100644
--- a/dlls/windowscodecs/wincodecs_common.h
+++ b/dlls/windowscodecs/wincodecs_common.h
@@ -158,3 +158,22 @@ HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_siz
return S_OK;
}
+
+void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
+{
+ UINT x, y;
+ BYTE *pixel, temp;
+
+ for (y=0; y<height; y++)
+ {
+ pixel = bits + stride * y;
+
+ for (x=0; x<width; x++)
+ {
+ temp = pixel[2];
+ pixel[2] = pixel[0];
+ pixel[0] = temp;
+ pixel += bytesperpixel;
+ }
+ }
+}
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 64c813329cf..3d7a46f0f59 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -280,11 +280,15 @@ struct decoder_frame
WICColor palette[256];
};
+#define DECODER_BLOCK_OPTION_MASK 0x0001000F
+#define DECODER_BLOCK_FULL_STREAM 0x80000000
+#define DECODER_BLOCK_READER_CLSID 0x40000000
struct decoder_block
{
ULONGLONG offset;
ULONGLONG length;
DWORD options;
+ GUID reader_clsid;
};
struct decoder
@@ -305,11 +309,13 @@ struct decoder_funcs
void (CDECL *destroy)(struct decoder* This);
};
+HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size);
HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read);
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position);
struct win32_funcs
{
+ HRESULT (CDECL *stream_getsize)(IStream *stream, ULONGLONG *size);
HRESULT (CDECL *stream_read)(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read);
HRESULT (CDECL *stream_seek)(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position);
};
@@ -326,6 +332,7 @@ HRESULT CDECL decoder_get_color_context(struct decoder* This, UINT frame, UINT n
void CDECL decoder_destroy(struct decoder *This);
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
+HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result);
struct unix_funcs
{
--
2.17.1
1
0
[PATCH 1/7] qedit/tests: Add initial tests for bitmap grab mode with a custom filter.
by Gabriel Ivăncescu 27 Oct '20
by Gabriel Ivăncescu 27 Oct '20
27 Oct '20
We fill the video pattern with something that varies between lines and
columns, to test it properly later (including the scaling algorithm).
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/qedit/tests/mediadet.c | 337 +++++++++++++++++++++++++++++++++++-
1 file changed, 333 insertions(+), 4 deletions(-)
diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c
index dc83bb9..010b746 100644
--- a/dlls/qedit/tests/mediadet.c
+++ b/dlls/qedit/tests/mediadet.c
@@ -136,6 +136,11 @@ struct testfilter
struct strmbase_filter filter;
struct strmbase_source source;
IMediaSeeking IMediaSeeking_iface;
+
+ BOOL bitmap_grab_mode;
+ const GUID *time_format;
+ LONGLONG cur_pos;
+ HANDLE thread;
};
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
@@ -158,10 +163,103 @@ static void testfilter_destroy(struct strmbase_filter *iface)
strmbase_filter_cleanup(&filter->filter);
}
+static DWORD WINAPI testfilter_frame_thread(void *arg)
+{
+ REFERENCE_TIME start_time, end_time;
+ struct testfilter *filter = arg;
+ IMemAllocator *allocator;
+ IMediaSample *sample;
+ unsigned i;
+ HRESULT hr;
+ DWORD fill;
+ BYTE *data;
+
+ hr = IMemInputPin_GetAllocator(filter->source.pMemInputPin, &allocator);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ start_time = (filter->cur_pos == 0xdeadbeef) ? 0 : filter->cur_pos;
+ while (hr == S_OK)
+ {
+ hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
+ if (hr == VFW_E_NOT_COMMITTED)
+ {
+ IMemAllocator_Commit(allocator);
+ hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
+ }
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IMediaSample_GetPointer(sample, &data);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ fill = (start_time / 10000 & 0xffffff) ^ 0xccaabb;
+ for (i = 0; i < 640 * 480 * 3; i += 3)
+ {
+ data[i] = fill ^ i;
+ data[i + 1] = fill >> 8 ^ i;
+ data[i + 2] = fill >> 16 ^ i;
+ }
+
+ hr = IMediaSample_SetActualDataLength(sample, 640 * 480 * 3);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ end_time = start_time + 400000;
+ hr = IMediaSample_SetTime(sample, &start_time, &end_time);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ start_time = end_time;
+
+ if (winetest_debug > 1) trace("%04x: Sending frame.\n", GetCurrentThreadId());
+ hr = IMemInputPin_Receive(filter->source.pMemInputPin, sample);
+ if (winetest_debug > 1) trace("%04x: Returned %#x.\n", GetCurrentThreadId(), hr);
+
+ IMediaSample_Release(sample);
+ }
+
+ IMemAllocator_Release(allocator);
+ return hr;
+}
+
+static HRESULT testfilter_init_stream(struct strmbase_filter *iface)
+{
+ struct testfilter *filter = impl_from_strmbase_filter(iface);
+ HRESULT hr;
+
+ if (!filter->bitmap_grab_mode) return S_OK;
+
+ hr = BaseOutputPinImpl_Active(&filter->source);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ filter->thread = CreateThread(NULL, 0, testfilter_frame_thread, filter, 0, NULL);
+ ok(filter->thread != NULL, "Failed to create thread: %#x.\n", GetLastError());
+
+ return S_OK;
+}
+
+static HRESULT testfilter_cleanup_stream(struct strmbase_filter *iface)
+{
+ struct testfilter *filter = impl_from_strmbase_filter(iface);
+ HRESULT hr;
+
+ if (filter->thread)
+ {
+ WaitForSingleObject(filter->thread, INFINITE);
+ CloseHandle(filter->thread);
+ filter->thread = NULL;
+ }
+ if (!filter->bitmap_grab_mode)
+ return S_OK;
+
+ hr = BaseOutputPinImpl_Inactive(&filter->source);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ return S_OK;
+}
+
static const struct strmbase_filter_ops testfilter_ops =
{
.filter_get_pin = testfilter_get_pin,
.filter_destroy = testfilter_destroy,
+ .filter_init_stream = testfilter_init_stream,
+ .filter_cleanup_stream = testfilter_cleanup_stream
};
static inline struct testfilter *impl_from_strmbase_pin(struct strmbase_pin *iface)
@@ -175,7 +273,7 @@ static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned in
{
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
.bmiHeader.biWidth = 640,
- .bmiHeader.biHeight = 480,
+ .bmiHeader.biHeight = -480,
.bmiHeader.biPlanes = 1,
.bmiHeader.biBitCount = 24,
.bmiHeader.biCompression = BI_RGB,
@@ -211,10 +309,37 @@ static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid
return S_OK;
}
+static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface,
+ IMemAllocator *allocator, ALLOCATOR_PROPERTIES *requested)
+{
+ ALLOCATOR_PROPERTIES actual;
+
+ if (!requested->cbAlign)
+ requested->cbAlign = 1;
+
+ if (requested->cbBuffer < 640 * 480 * 3)
+ requested->cbBuffer = 640 * 480 * 3;
+
+ if (!requested->cBuffers)
+ requested->cBuffers = 1;
+
+ return IMemAllocator_SetProperties(allocator, requested, &actual);
+}
+
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface,
IMemInputPin *peer, IMemAllocator **allocator)
{
- return S_OK;
+ ALLOCATOR_PROPERTIES props = {0};
+ HRESULT hr;
+
+ hr = BaseOutputPinImpl_InitAllocator(iface, allocator);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ IMemInputPin_GetAllocatorRequirements(peer, &props);
+ hr = testsource_DecideBufferSize(iface, *allocator, &props);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ return IMemInputPin_NotifyAllocator(peer, *allocator, FALSE);
}
static const struct strmbase_source_ops testsource_ops =
@@ -222,6 +347,7 @@ static const struct strmbase_source_ops testsource_ops =
.base.pin_get_media_type = testsource_get_media_type,
.base.pin_query_interface = testsource_query_interface,
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
+ .pfnDecideBufferSize = testsource_DecideBufferSize,
.pfnDecideAllocator = testsource_DecideAllocator,
};
@@ -250,6 +376,15 @@ static ULONG WINAPI testseek_Release(IMediaSeeking *iface)
static HRESULT WINAPI testseek_GetCapabilities(IMediaSeeking *iface, DWORD *caps)
{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+
+ if (filter->bitmap_grab_mode)
+ {
+ if (winetest_debug > 1) trace("IMediaSeeking_GetCapabilities()\n");
+ *caps = 0; /* Doesn't seem to have any effect, despite being called */
+ return S_OK;
+ }
+
ok(0, "Unexpected call.\n");
return E_NOTIMPL;
}
@@ -262,6 +397,15 @@ static HRESULT WINAPI testseek_CheckCapabilities(IMediaSeeking *iface, DWORD *ca
static HRESULT WINAPI testseek_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+
+ if (filter->bitmap_grab_mode)
+ {
+ if (winetest_debug > 1) trace("IMediaSeeking_IsFormatSupported(%s)\n", wine_dbgstr_guid(format));
+ ok(IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME), "Unexpected format %s.\n", wine_dbgstr_guid(format));
+ return S_OK;
+ }
+
ok(0, "Unexpected call.\n");
return E_NOTIMPL;
}
@@ -274,12 +418,29 @@ static HRESULT WINAPI testseek_QueryPreferredFormat(IMediaSeeking *iface, GUID *
static HRESULT WINAPI testseek_GetTimeFormat(IMediaSeeking *iface, GUID *format)
{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+
+ if (filter->bitmap_grab_mode)
+ {
+ if (winetest_debug > 1) trace("IMediaSeeking_GetTimeFormat()\n");
+ *format = *filter->time_format;
+ return S_OK;
+ }
+
ok(0, "Unexpected call.\n");
return E_NOTIMPL;
}
static HRESULT WINAPI testseek_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+
+ if (filter->bitmap_grab_mode)
+ {
+ if (winetest_debug > 1) trace("IMediaSeeking_IsUsingTimeFormat(%s)\n", wine_dbgstr_guid(format));
+ return IsEqualGUID(format, filter->time_format) ? S_OK : S_FALSE;
+ }
+
ok(0, "Unexpected call.\n");
return E_NOTIMPL;
}
@@ -320,8 +481,35 @@ static HRESULT WINAPI testseek_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG
static HRESULT WINAPI testseek_SetPositions(IMediaSeeking *iface, LONGLONG *current,
DWORD current_flags, LONGLONG *stop, DWORD stop_flags)
{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+
+ if (winetest_debug > 1)
+ trace("IMediaSeeking_SetPositions(0x%s, 0x%08x, 0x%s, 0x%08x)\n",
+ wine_dbgstr_longlong(*current), current_flags, wine_dbgstr_longlong(*stop), stop_flags);
+
+ if (filter->bitmap_grab_mode)
+ {
+ ok(*stop == *current || !*stop, "Unexpected stop position: 0x%s.\n", wine_dbgstr_longlong(*stop));
+ ok(current_flags == (AM_SEEKING_AbsolutePositioning | AM_SEEKING_ReturnTime),
+ "Unexpected current_flags 0x%08x.\n", current_flags);
+ ok(stop_flags == AM_SEEKING_AbsolutePositioning || !stop_flags, "Unexpected stop_flags 0x%08x.\n", stop_flags);
+
+ if (filter->thread)
+ {
+ IPin_BeginFlush(filter->source.pin.peer);
+ WaitForSingleObject(filter->thread, INFINITE);
+ CloseHandle(filter->thread);
+ filter->cur_pos = *current;
+ IPin_EndFlush(filter->source.pin.peer);
+
+ filter->thread = CreateThread(NULL, 0, testfilter_frame_thread, filter, 0, NULL);
+ ok(filter->thread != NULL, "Failed to create thread: %#x.\n", GetLastError());
+ }
+ else
+ filter->cur_pos = *current;
+ }
+
+ return S_OK;
}
static HRESULT WINAPI testseek_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
@@ -386,6 +574,8 @@ static void testfilter_init(struct testfilter *filter)
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
filter->IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
+ filter->cur_pos = 0xdeadbeef;
+ filter->time_format = &TIME_FORMAT_MEDIA_TIME;
}
static WCHAR test_avi_filename[MAX_PATH];
@@ -1117,6 +1307,144 @@ static void test_COM_sg_enumpins(void)
IBaseFilter_Release(bf);
}
+static void test_bitmap_grab_mode(void)
+{
+ static const GUID *time_formats[] =
+ {
+ &TIME_FORMAT_NONE,
+ &TIME_FORMAT_FRAME,
+ &TIME_FORMAT_SAMPLE,
+ &TIME_FORMAT_FIELD,
+ &TIME_FORMAT_BYTE,
+ &TIME_FORMAT_MEDIA_TIME
+ };
+ struct testfilter testfilter;
+ IMediaDet *detector;
+ AM_MEDIA_TYPE mt;
+ double duration;
+ IUnknown *unk;
+ unsigned i;
+ HRESULT hr;
+ LONG count;
+ ULONG ref;
+ GUID guid;
+ BSTR str;
+
+ hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMediaDet, (void **)&detector);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IMediaDet_EnterBitmapGrabMode(detector, 0.0);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+ /* EnterBitmapGrabMode only seeks once, and if SeekTime is non-negative */
+ testfilter_init(&testfilter);
+ testfilter.bitmap_grab_mode = TRUE;
+ hr = IMediaDet_put_Filter(detector, &testfilter.filter.IUnknown_inner);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IMediaDet_EnterBitmapGrabMode(detector, -1.0);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(testfilter.cur_pos == 0xdeadbeef, "Current position was set to 0x%s.\n", wine_dbgstr_longlong(testfilter.cur_pos));
+ hr = IMediaDet_EnterBitmapGrabMode(detector, 1.0);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(testfilter.cur_pos == 0xdeadbeef, "Current position was set to 0x%s.\n", wine_dbgstr_longlong(testfilter.cur_pos));
+
+ ref = IMediaDet_Release(detector);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+ ref = IBaseFilter_Release(&testfilter.filter.IBaseFilter_iface);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+
+ /* Time formats other than TIME_FORMAT_MEDIA_TIME return E_NOTIMPL */
+ for (i = 0; i < ARRAY_SIZE(time_formats); i++)
+ {
+ hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMediaDet, (void **)&detector);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ testfilter_init(&testfilter);
+ testfilter.bitmap_grab_mode = TRUE;
+ testfilter.time_format = time_formats[i];
+ hr = IMediaDet_put_Filter(detector, &testfilter.filter.IUnknown_inner);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IMediaDet_EnterBitmapGrabMode(detector, 1337.0);
+ if (time_formats[i] == &TIME_FORMAT_MEDIA_TIME)
+ {
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(testfilter.cur_pos == 13370000000LL, "Current position was set to 0x%s.\n", wine_dbgstr_longlong(testfilter.cur_pos));
+ hr = IMediaDet_EnterBitmapGrabMode(detector, 1.0);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(testfilter.cur_pos == 13370000000LL, "Current position was set to 0x%s.\n", wine_dbgstr_longlong(testfilter.cur_pos));
+ }
+ else
+ ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
+
+ ref = IMediaDet_Release(detector);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+ ref = IBaseFilter_Release(&testfilter.filter.IBaseFilter_iface);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+ }
+
+ hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMediaDet, (void **)&detector);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ testfilter_init(&testfilter);
+ testfilter.bitmap_grab_mode = TRUE;
+ hr = IMediaDet_put_Filter(detector, &testfilter.filter.IUnknown_inner);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IMediaDet_EnterBitmapGrabMode(detector, 0.0);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(testfilter.cur_pos == 0, "Current position was set to 0x%s.\n", wine_dbgstr_longlong(testfilter.cur_pos));
+ hr = IMediaDet_EnterBitmapGrabMode(detector, 1.0);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(testfilter.cur_pos == 0, "Current position was set to 0x%s.\n", wine_dbgstr_longlong(testfilter.cur_pos));
+
+ /* These still work */
+ hr = IMediaDet_get_Filter(detector, &unk);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ IUnknown_Release(unk);
+ hr = IMediaDet_get_Filename(detector, &str);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ SysFreeString(str);
+ hr = IMediaDet_get_CurrentStream(detector, &count);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(count == 0, "Got stream %d.\n", count);
+
+ /* These don't work anymore */
+ hr = IMediaDet_get_OutputStreams(detector, &count);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = IMediaDet_get_FrameRate(detector, &duration);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = IMediaDet_get_StreamLength(detector, &duration);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = IMediaDet_get_StreamMediaType(detector, &mt);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ if (SUCCEEDED(hr)) FreeMediaType(&mt);
+ hr = IMediaDet_get_StreamType(detector, &guid);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = IMediaDet_get_StreamTypeB(detector, &str);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ if (SUCCEEDED(hr)) SysFreeString(str);
+ hr = IMediaDet_put_CurrentStream(detector, 0);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+ /* Changing filter resets bitmap grab mode */
+ testfilter.bitmap_grab_mode = FALSE;
+ hr = IMediaDet_put_Filter(detector, &testfilter.filter.IUnknown_inner);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = IMediaDet_get_OutputStreams(detector, &count);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(count == 1, "Got %d streams.\n", count);
+
+ ref = IMediaDet_Release(detector);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+ ref = IBaseFilter_Release(&testfilter.filter.IBaseFilter_iface);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
+
START_TEST(mediadet)
{
IMediaDet *detector;
@@ -1145,6 +1473,7 @@ START_TEST(mediadet)
test_put_filter();
test_samplegrabber();
test_COM_sg_enumpins();
+ test_bitmap_grab_mode();
ret = DeleteFileW(test_avi_filename);
ok(ret, "Failed to delete file, error %u.\n", GetLastError());
--
2.21.0
2
23
27 Oct '20
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/mfplat/buffer.c | 44 ++++++++++++++++++++++++++++++++++++++
dlls/mfplat/tests/mfplat.c | 13 +++++++++++
2 files changed, 57 insertions(+)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c
index a3311bc10f1..5e969e14ec9 100644
--- a/dlls/mfplat/buffer.c
+++ b/dlls/mfplat/buffer.c
@@ -31,6 +31,7 @@ struct memory_buffer
{
IMFMediaBuffer IMFMediaBuffer_iface;
IMF2DBuffer2 IMF2DBuffer2_iface;
+ IMFGetService IMFGetService_iface;
LONG refcount;
BYTE *data;
@@ -88,6 +89,11 @@ static struct memory_buffer *impl_from_IMF2DBuffer2(IMF2DBuffer2 *iface)
return CONTAINING_RECORD(iface, struct memory_buffer, IMF2DBuffer2_iface);
}
+static struct memory_buffer *impl_from_IMFGetService(IMFGetService *iface)
+{
+ return CONTAINING_RECORD(iface, struct memory_buffer, IMFGetService_iface);
+}
+
static inline struct sample *impl_from_IMFSample(IMFSample *iface)
{
return CONTAINING_RECORD(iface, struct sample, IMFSample_iface);
@@ -240,6 +246,10 @@ static HRESULT WINAPI memory_1d_2d_buffer_QueryInterface(IMFMediaBuffer *iface,
{
*out = &buffer->IMF2DBuffer2_iface;
}
+ else if (IsEqualIID(riid, &IID_IMFGetService))
+ {
+ *out = &buffer->IMFGetService_iface;
+ }
else
{
WARN("Unsupported interface %s.\n", debugstr_guid(riid));
@@ -511,6 +521,39 @@ static const IMF2DBuffer2Vtbl memory_2d_buffer_vtbl =
memory_2d_buffer_Copy2DTo,
};
+static HRESULT WINAPI memory_2d_buffer_gs_QueryInterface(IMFGetService *iface, REFIID riid, void **obj)
+{
+ struct memory_buffer *buffer = impl_from_IMFGetService(iface);
+ return IMFMediaBuffer_QueryInterface(&buffer->IMFMediaBuffer_iface, riid, obj);
+}
+
+static ULONG WINAPI memory_2d_buffer_gs_AddRef(IMFGetService *iface)
+{
+ struct memory_buffer *buffer = impl_from_IMFGetService(iface);
+ return IMFMediaBuffer_AddRef(&buffer->IMFMediaBuffer_iface);
+}
+
+static ULONG WINAPI memory_2d_buffer_gs_Release(IMFGetService *iface)
+{
+ struct memory_buffer *buffer = impl_from_IMFGetService(iface);
+ return IMFMediaBuffer_Release(&buffer->IMFMediaBuffer_iface);
+}
+
+static HRESULT WINAPI memory_2d_buffer_gs_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
+
+ return E_NOTIMPL;
+}
+
+static const IMFGetServiceVtbl memory_2d_buffer_gs_vtbl =
+{
+ memory_2d_buffer_gs_QueryInterface,
+ memory_2d_buffer_gs_AddRef,
+ memory_2d_buffer_gs_Release,
+ memory_2d_buffer_gs_GetService,
+};
+
static HRESULT memory_buffer_init(struct memory_buffer *buffer, DWORD max_length, DWORD alignment,
const IMFMediaBufferVtbl *vtbl)
{
@@ -620,6 +663,7 @@ static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, BOOL bo
}
object->IMF2DBuffer2_iface.lpVtbl = &memory_2d_buffer_vtbl;
+ object->IMFGetService_iface.lpVtbl = &memory_2d_buffer_gs_vtbl;
object->_2d.plane_size = plane_size;
object->_2d.width = stride;
object->_2d.height = height;
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 971469ec574..906454851a8 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -1818,6 +1818,7 @@ static void test_system_memory_buffer(void)
HRESULT hr;
DWORD length, max;
BYTE *data, *data2;
+ IUnknown *unk;
hr = MFCreateMemoryBuffer(1024, NULL);
ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
@@ -1836,6 +1837,9 @@ static void test_system_memory_buffer(void)
hr = MFCreateMemoryBuffer(1024, &buffer);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
+
hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
@@ -5155,6 +5159,7 @@ static void test_MFCreate2DMediaBuffer(void)
IMF2DBuffer *_2dbuffer;
IMFMediaBuffer *buffer;
int i, pitch, pitch2;
+ IUnknown *unk;
HRESULT hr;
BOOL ret;
@@ -5177,6 +5182,10 @@ static void test_MFCreate2DMediaBuffer(void)
hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&unk);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ IUnknown_Release(unk);
+
/* Full backing buffer size, with 64 bytes per row alignment. */
hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
@@ -5405,6 +5414,7 @@ static void test_MFCreateMediaBufferFromMediaType(void)
HRESULT hr;
IMFMediaType *media_type;
unsigned int i;
+ IUnknown *unk;
if (!pMFCreateMediaBufferFromMediaType)
{
@@ -5437,6 +5447,9 @@ static void test_MFCreateMediaBufferFromMediaType(void)
if (FAILED(hr))
break;
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
+
hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length);
--
2.28.0
2
3
27 Oct '20
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msi/action.c | 1340 ++++++++++++++-------------------------------
1 file changed, 407 insertions(+), 933 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index d02860e4d71..ed1d0c8ffcc 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -46,126 +46,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi);
-static const WCHAR szCreateFolders[] =
- {'C','r','e','a','t','e','F','o','l','d','e','r','s',0};
-static const WCHAR szCostFinalize[] =
- {'C','o','s','t','F','i','n','a','l','i','z','e',0};
-static const WCHAR szWriteRegistryValues[] =
- {'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
-static const WCHAR szFileCost[] =
- {'F','i','l','e','C','o','s','t',0};
-static const WCHAR szInstallInitialize[] =
- {'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0};
-static const WCHAR szInstallValidate[] =
- {'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
-static const WCHAR szLaunchConditions[] =
- {'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
-static const WCHAR szProcessComponents[] =
- {'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0};
-static const WCHAR szRegisterTypeLibraries[] =
- {'R','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r','i','e','s',0};
-static const WCHAR szCreateShortcuts[] =
- {'C','r','e','a','t','e','S','h','o','r','t','c','u','t','s',0};
-static const WCHAR szPublishProduct[] =
- {'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0};
-static const WCHAR szWriteIniValues[] =
- {'W','r','i','t','e','I','n','i','V','a','l','u','e','s',0};
-static const WCHAR szSelfRegModules[] =
- {'S','e','l','f','R','e','g','M','o','d','u','l','e','s',0};
-static const WCHAR szPublishFeatures[] =
- {'P','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
-static const WCHAR szRegisterProduct[] =
- {'R','e','g','i','s','t','e','r','P','r','o','d','u','c','t',0};
-static const WCHAR szInstallExecute[] =
- {'I','n','s','t','a','l','l','E','x','e','c','u','t','e',0};
-static const WCHAR szInstallExecuteAgain[] =
- {'I','n','s','t','a','l','l','E','x','e','c','u','t','e','A','g','a','i','n',0};
-static const WCHAR szInstallFinalize[] =
- {'I','n','s','t','a','l','l','F','i','n','a','l','i','z','e',0};
-static const WCHAR szForceReboot[] =
- {'F','o','r','c','e','R','e','b','o','o','t',0};
-static const WCHAR szResolveSource[] =
- {'R','e','s','o','l','v','e','S','o','u','r','c','e',0};
-static const WCHAR szAllocateRegistrySpace[] =
- {'A','l','l','o','c','a','t','e','R','e','g','i','s','t','r','y','S','p','a','c','e',0};
-static const WCHAR szBindImage[] =
- {'B','i','n','d','I','m','a','g','e',0};
-static const WCHAR szDeleteServices[] =
- {'D','e','l','e','t','e','S','e','r','v','i','c','e','s',0};
-static const WCHAR szDisableRollback[] =
- {'D','i','s','a','b','l','e','R','o','l','l','b','a','c','k',0};
-static const WCHAR szExecuteAction[] =
- {'E','x','e','c','u','t','e','A','c','t','i','o','n',0};
-static const WCHAR szInstallAdminPackage[] =
- {'I','n','s','t','a','l','l','A','d','m','i','n','P','a','c','k','a','g','e',0};
-static const WCHAR szInstallSFPCatalogFile[] =
- {'I','n','s','t','a','l','l','S','F','P','C','a','t','a','l','o','g','F','i','l','e',0};
-static const WCHAR szIsolateComponents[] =
- {'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0};
-static const WCHAR szMigrateFeatureStates[] =
- {'M','i','g','r','a','t','e','F','e','a','t','u','r','e','S','t','a','t','e','s',0};
-static const WCHAR szInstallODBC[] =
- {'I','n','s','t','a','l','l','O','D','B','C',0};
-static const WCHAR szInstallServices[] =
- {'I','n','s','t','a','l','l','S','e','r','v','i','c','e','s',0};
-static const WCHAR szPublishComponents[] =
- {'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0};
-static const WCHAR szRegisterComPlus[] =
- {'R','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
-static const WCHAR szRegisterUser[] =
- {'R','e','g','i','s','t','e','r','U','s','e','r',0};
-static const WCHAR szRemoveEnvironmentStrings[] =
- {'R','e','m','o','v','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};
-static const WCHAR szRemoveExistingProducts[] =
- {'R','e','m','o','v','e','E','x','i','s','t','i','n','g','P','r','o','d','u','c','t','s',0};
-static const WCHAR szRemoveFolders[] =
- {'R','e','m','o','v','e','F','o','l','d','e','r','s',0};
-static const WCHAR szRemoveIniValues[] =
- {'R','e','m','o','v','e','I','n','i','V','a','l','u','e','s',0};
-static const WCHAR szRemoveODBC[] =
- {'R','e','m','o','v','e','O','D','B','C',0};
-static const WCHAR szRemoveRegistryValues[] =
- {'R','e','m','o','v','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
-static const WCHAR szRemoveShortcuts[] =
- {'R','e','m','o','v','e','S','h','o','r','t','c','u','t','s',0};
-static const WCHAR szRMCCPSearch[] =
- {'R','M','C','C','P','S','e','a','r','c','h',0};
-static const WCHAR szScheduleReboot[] =
- {'S','c','h','e','d','u','l','e','R','e','b','o','o','t',0};
-static const WCHAR szSelfUnregModules[] =
- {'S','e','l','f','U','n','r','e','g','M','o','d','u','l','e','s',0};
-static const WCHAR szSetODBCFolders[] =
- {'S','e','t','O','D','B','C','F','o','l','d','e','r','s',0};
-static const WCHAR szStartServices[] =
- {'S','t','a','r','t','S','e','r','v','i','c','e','s',0};
-static const WCHAR szStopServices[] =
- {'S','t','o','p','S','e','r','v','i','c','e','s',0};
-static const WCHAR szUnpublishComponents[] =
- {'U','n','p','u','b','l','i','s','h', 'C','o','m','p','o','n','e','n','t','s',0};
-static const WCHAR szUnpublishFeatures[] =
- {'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
-static const WCHAR szUnpublishProduct[] =
- {'U','n','p','u','b','l','i','s','h','P','r','o','d','u','c','t',0};
-static const WCHAR szUnregisterComPlus[] =
- {'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
-static const WCHAR szUnregisterTypeLibraries[] =
- {'U','n','r','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r','i','e','s',0};
-static const WCHAR szValidateProductID[] =
- {'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};
-static const WCHAR szWriteEnvironmentStrings[] =
- {'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};
-static const WCHAR szINSTALL[] =
- {'I','N','S','T','A','L','L',0};
-
static INT ui_actionstart(MSIPACKAGE *package, LPCWSTR action, LPCWSTR description, LPCWSTR template)
{
- static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','A','c','t','i','o','n','T','e','x','t','`',' ','W','H','E','R','E',' ',
- '`','A','c','t','i','o','n','`',' ','=',' ','\'','%','s','\'',0};
MSIRECORD *row, *textrow;
INT rc;
- textrow = MSI_QueryGetRecord(package->db, query, action);
+ textrow = MSI_QueryGetRecord(package->db, L"SELECT * FROM `ActionText` WHERE `Action` = '%s'", action);
if (textrow)
{
description = MSI_RecordGetString(textrow, 2);
@@ -366,7 +252,7 @@ UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine,
TRACE("Found commandline property %s = %s\n", debugstr_w(prop), debugstr_w(val));
r = msi_set_property( package->db, prop, val, -1 );
- if (r == ERROR_SUCCESS && !wcscmp( prop, szSourceDir ))
+ if (r == ERROR_SUCCESS && !wcscmp( prop, L"SourceDir" ))
msi_reset_source_folders( package );
msi_free( val );
@@ -447,14 +333,10 @@ WCHAR **msi_split_string( const WCHAR *str, WCHAR sep )
static BOOL ui_sequence_exists( MSIPACKAGE *package )
{
- static const WCHAR query [] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e','`',' ',
- 'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',' ','>',' ','0',0};
MSIQUERY *view;
DWORD count = 0;
- if (!(MSI_DatabaseOpenViewW( package->db, query, &view )))
+ if (!(MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `InstallUISequence` WHERE `Sequence` > 0", &view )))
{
MSI_IterateRecords( view, &count, NULL, package );
msiobj_release( &view->hdr );
@@ -467,7 +349,7 @@ UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
WCHAR *source, *check, *p, *db;
DWORD len;
- if (!(db = msi_dup_property( package->db, szOriginalDatabase )))
+ if (!(db = msi_dup_property( package->db, L"OriginalDatabase" )))
return ERROR_OUTOFMEMORY;
if (!(p = wcsrchr( db, '\\' )) && !(p = wcsrchr( db, '/' )))
@@ -480,18 +362,18 @@ UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
lstrcpynW( source, db, len );
msi_free( db );
- check = msi_dup_property( package->db, szSourceDir );
+ check = msi_dup_property( package->db, L"SourceDir" );
if (!check || replace)
{
- UINT r = msi_set_property( package->db, szSourceDir, source, -1 );
+ UINT r = msi_set_property( package->db, L"SourceDir", source, -1 );
if (r == ERROR_SUCCESS)
msi_reset_source_folders( package );
}
msi_free( check );
- check = msi_dup_property( package->db, szSOURCEDIR );
+ check = msi_dup_property( package->db, L"SOURCEDIR" );
if (!check || replace)
- msi_set_property( package->db, szSOURCEDIR, source, -1 );
+ msi_set_property( package->db, L"SOURCEDIR", source, -1 );
msi_free( check );
msi_free( source );
@@ -509,7 +391,7 @@ UINT msi_set_context(MSIPACKAGE *package)
UINT r = msi_locate_product( package->ProductCode, &package->Context );
if (r != ERROR_SUCCESS)
{
- int num = msi_get_property_int( package->db, szAllUsers, 0 );
+ int num = msi_get_property_int( package->db, L"ALLUSERS", 0 );
if (num == 1 || num == 2)
package->Context = MSIINSTALLCONTEXT_MACHINE;
else
@@ -562,17 +444,12 @@ static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param)
UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR table )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','%','s','`',
- ' ','W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',' ',
- '>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ',
- '`','S','e','q','u','e','n','c','e','`',0};
MSIQUERY *view;
UINT r;
TRACE("%p %s\n", package, debugstr_w(table));
- r = MSI_OpenQuery( package->db, &view, query, table );
+ r = MSI_OpenQuery( package->db, &view, L"SELECT * FROM `%s` WHERE `Sequence` > 0 ORDER BY `Sequence`", table );
if (r == ERROR_SUCCESS)
{
r = MSI_IterateRecords( view, NULL, ITERATE_Actions, package );
@@ -583,12 +460,6 @@ UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR table )
static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- '`','I','n','s','t','a','l','l','E','x','e','c','u','t','e',
- 'S','e','q','u','e','n','c','e','`',' ', 'W','H','E','R','E',' ',
- '`','S','e','q','u','e','n','c','e','`',' ', '>',' ','0',' ',
- 'O','R','D','E','R',' ', 'B','Y',' ','`','S','e','q','u','e','n','c','e','`',0};
MSIQUERY *view;
UINT rc;
@@ -600,12 +471,13 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package)
package->ExecuteSequenceRun = TRUE;
- rc = MSI_OpenQuery(package->db, &view, query);
+ rc = MSI_OpenQuery(package->db, &view,
+ L"SELECT * FROM `InstallExecuteSequence` WHERE `Sequence` > 0 ORDER BY `Sequence`");
if (rc == ERROR_SUCCESS)
{
TRACE("Running the actions\n");
- msi_set_property( package->db, szSourceDir, NULL, -1 );
+ msi_set_property( package->db, L"SourceDir", NULL, -1 );
rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package);
msiobj_release(&view->hdr);
}
@@ -614,18 +486,15 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package)
static UINT ACTION_ProcessUISequence(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e','`',' ',
- 'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',' ','>',' ','0',' ',
- 'O','R','D','E','R',' ','B','Y',' ','`','S','e','q','u','e','n','c','e','`',0};
MSIQUERY *view;
UINT rc;
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db,
+ L"SELECT * FROM `InstallUISequence` WHERE `Sequence` > 0 ORDER BY `Sequence`",
+ &view);
if (rc == ERROR_SUCCESS)
{
- TRACE("Running the actions\n");
+ TRACE("Running the actions\n");
rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package);
msiobj_release(&view->hdr);
}
@@ -806,16 +675,13 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
static UINT ACTION_CreateFolders(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szCreateFolders);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"CreateFolders");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `CreateFolder`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -888,16 +754,13 @@ static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param )
static UINT ACTION_RemoveFolders( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveFolders);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveFolders");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `CreateFolder`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -938,16 +801,13 @@ static UINT load_component( MSIRECORD *row, LPVOID param )
UINT msi_load_all_components( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','o','m','p','o','n','e','n','t','`',0};
MSIQUERY *view;
UINT r;
if (!list_empty(&package->components))
return ERROR_SUCCESS;
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Component`", &view );
if (r != ERROR_SUCCESS)
return r;
@@ -1008,13 +868,8 @@ static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
return ERROR_SUCCESS;
}
-static UINT load_feature(MSIRECORD * row, LPVOID param)
+static UINT load_feature(MSIRECORD *row, LPVOID param)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','`','C','o','m','p','o','n','e','n','t','_','`',
- ' ','F','R','O','M',' ','`','F','e','a','t','u','r','e',
- 'C','o','m','p','o','n','e','n','t','s','`',' ','W','H','E','R','E',' ',
- '`','F','e', 'a','t','u','r','e','_','`',' ','=','\'','%','s','\'',0};
MSIPACKAGE *package = param;
MSIFEATURE *feature;
MSIQUERY *view;
@@ -1029,7 +884,7 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
list_init( &feature->Children );
list_init( &feature->Components );
-
+
feature->Feature = msi_dup_record_field( row, 1 );
TRACE("Loading feature %s\n",debugstr_w(feature->Feature));
@@ -1040,7 +895,7 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
if (!MSI_RecordIsNull(row,5))
feature->Display = MSI_RecordGetInteger(row,5);
-
+
feature->Level= MSI_RecordGetInteger(row,6);
feature->Directory = msi_dup_record_field( row, 7 );
feature->Attributes = MSI_RecordGetInteger(row,8);
@@ -1053,7 +908,8 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
/* load feature components */
- rc = MSI_OpenQuery( package->db, &view, query, feature->Feature );
+ rc = MSI_OpenQuery( package->db, &view, L"SELECT `Component_` FROM `FeatureComponents` WHERE `Feature_` = '%s'",
+ feature->Feature );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -1087,17 +943,13 @@ static UINT find_feature_children(MSIRECORD * row, LPVOID param)
UINT msi_load_all_features( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','F','e','a','t','u','r','e','`',' ','O','R','D','E','R',' ','B','Y',' ',
- '`','D','i','s','p','l','a','y','`',0};
MSIQUERY *view;
UINT r;
if (!list_empty(&package->features))
return ERROR_SUCCESS;
-
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Feature` ORDER BY `Display`", &view );
if (r != ERROR_SUCCESS)
return r;
@@ -1125,17 +977,13 @@ static LPWSTR folder_split_path(LPWSTR p, WCHAR ch)
static UINT load_file_hash(MSIPACKAGE *package, MSIFILE *file)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- '`','M','s','i','F','i','l','e','H','a','s','h','`',' ',
- 'W','H','E','R','E',' ','`','F','i','l','e','_','`',' ','=',' ','\'','%','s','\'',0};
MSIQUERY *view = NULL;
MSIRECORD *row = NULL;
UINT r;
TRACE("%s\n", debugstr_w(file->File));
- r = MSI_OpenQuery(package->db, &view, query, file->File);
+ r = MSI_OpenQuery(package->db, &view, L"SELECT * FROM `MsiFileHash` WHERE `File_` = '%s'", file->File);
if (r != ERROR_SUCCESS)
goto done;
@@ -1161,13 +1009,8 @@ done:
static UINT load_file_disk_id( MSIPACKAGE *package, MSIFILE *file )
{
- MSIRECORD *row;
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','`','D','i','s','k','I','d','`',' ', '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',0};
-
- row = MSI_QueryGetRecord( package->db, query, file->Sequence );
+ MSIRECORD *row = MSI_QueryGetRecord( package->db, L"SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= %d",
+ file->Sequence );
if (!row)
{
WARN("query failed\n");
@@ -1190,7 +1033,7 @@ static UINT load_file(MSIRECORD *row, LPVOID param)
file = msi_alloc_zero( sizeof (MSIFILE) );
if (!file)
return ERROR_NOT_ENOUGH_MEMORY;
-
+
file->File = msi_dup_record_field( row, 1 );
component = MSI_RecordGetString( row, 2 );
@@ -1209,7 +1052,7 @@ static UINT load_file(MSIRECORD *row, LPVOID param)
file->ShortName = msi_dup_record_field( row, 3 );
file->LongName = strdupW( folder_split_path(file->ShortName, '|'));
-
+
file->FileSize = MSI_RecordGetInteger( row, 4 );
file->Version = msi_dup_record_field( row, 5 );
file->Language = msi_dup_record_field( row, 6 );
@@ -1241,23 +1084,18 @@ static UINT load_file(MSIRECORD *row, LPVOID param)
TRACE("File loaded (file %s sequence %u)\n", debugstr_w(file->File), file->Sequence);
list_add_tail( &package->files, &file->entry );
-
return ERROR_SUCCESS;
}
static UINT load_all_files(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- '`','F','i','l','e','`',' ', 'O','R','D','E','R',' ','B','Y',' ',
- '`','S','e','q','u','e','n','c','e','`', 0};
MSIQUERY *view;
UINT rc;
if (!list_empty(&package->files))
return ERROR_SUCCESS;
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `File` ORDER BY `Sequence`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -1281,14 +1119,10 @@ static UINT load_media( MSIRECORD *row, LPVOID param )
static UINT load_all_media( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`',
- 'M','e','d','i','a','`',' ','O','R','D','E','R',' ','B','Y',' ',
- '`','D','i','s','k','I','d','`',0};
MSIQUERY *view;
UINT r;
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Media` ORDER BY `DiskId`", &view );
if (r != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -1299,13 +1133,9 @@ static UINT load_all_media( MSIPACKAGE *package )
static UINT load_patch_disk_id( MSIPACKAGE *package, MSIFILEPATCH *patch )
{
- static const WCHAR query[] =
- {'S','E','L','E','C','T',' ','`','D','i','s','k','I','d','`',' ', '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','`',' ','>','=',' ','%','u',0};
- MSIRECORD *rec;
-
- if (!(rec = MSI_QueryGetRecord( package->db, query, patch->Sequence )))
+ MSIRECORD *rec = MSI_QueryGetRecord( package->db, L"SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= %u",
+ patch->Sequence );
+ if (!rec)
{
WARN("query failed\n");
return ERROR_FUNCTION_FAILED;
@@ -1355,17 +1185,13 @@ static UINT load_patch(MSIRECORD *row, LPVOID param)
static UINT load_all_patches(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','P','a','t','c','h','`',' ','O','R','D','E','R',' ','B','Y',' ',
- '`','S','e','q','u','e','n','c','e','`',0};
MSIQUERY *view;
UINT rc;
if (!list_empty(&package->filepatches))
return ERROR_SUCCESS;
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Patch` ORDER BY `Sequence`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -1419,14 +1245,11 @@ static void mark_patched_components( MSIPACKAGE *package )
static UINT load_folder_persistence( MSIPACKAGE *package, MSIFOLDER *folder )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','r','e','a','t','e','F','o','l','d','e','r','`',' ','W','H','E','R','E',' ',
- '`','D','i','r','e','c','t','o','r','y','_','`',' ','=','\'','%','s','\'',0};
MSIQUERY *view;
folder->persistent = FALSE;
- if (!MSI_OpenQuery( package->db, &view, query, folder->Directory ))
+ if (!MSI_OpenQuery( package->db, &view, L"SELECT * FROM `CreateFolder` WHERE `Directory_` = '%s'",
+ folder->Directory ))
{
if (!MSI_ViewExecute( view, NULL ))
{
@@ -1446,7 +1269,7 @@ static UINT load_folder_persistence( MSIPACKAGE *package, MSIFOLDER *folder )
static UINT load_folder( MSIRECORD *row, LPVOID param )
{
MSIPACKAGE *package = param;
- static WCHAR szEmpty[] = { 0 };
+ static WCHAR szEmpty[] = {0};
LPWSTR p, tgt_short, tgt_long, src_short, src_long;
MSIFOLDER *folder;
@@ -1467,9 +1290,9 @@ static UINT load_folder( MSIRECORD *row, LPVOID param )
src_long = folder_split_path( src_short, '|' );
/* check for no-op dirs */
- if (tgt_short && !wcscmp( szDot, tgt_short ))
+ if (tgt_short && !wcscmp( L".", tgt_short ))
tgt_short = szEmpty;
- if (src_short && !wcscmp( szDot, src_short ))
+ if (src_short && !wcscmp( L".", src_short ))
src_short = szEmpty;
if (!tgt_long)
@@ -1527,16 +1350,13 @@ static UINT find_folder_children( MSIRECORD *row, LPVOID param )
static UINT load_all_folders( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','D','i','r','e','c','t','o','r','y','`',0};
MSIQUERY *view;
UINT r;
if (!list_empty(&package->folders))
return ERROR_SUCCESS;
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Directory`", &view );
if (r != ERROR_SUCCESS)
return r;
@@ -1553,8 +1373,8 @@ static UINT load_all_folders( MSIPACKAGE *package )
static UINT ACTION_CostInitialize(MSIPACKAGE *package)
{
- msi_set_property( package->db, szCostingComplete, szZero, -1 );
- msi_set_property( package->db, szRootDrive, szCRoot, -1 );
+ msi_set_property( package->db, L"CostingComplete", L"0", -1 );
+ msi_set_property( package->db, L"ROOTDRIVE", L"C:\\", -1 );
load_all_folders( package );
msi_load_all_components( package );
@@ -1622,7 +1442,7 @@ static void get_client_counts( MSIPACKAGE *package )
{
if (!comp->ComponentId) continue;
- if (MSIREG_OpenUserDataComponentKey( comp->ComponentId, szLocalSid, &hkey, FALSE ) &&
+ if (MSIREG_OpenUserDataComponentKey( comp->ComponentId, L"S-1-5-18", &hkey, FALSE ) &&
MSIREG_OpenUserDataComponentKey( comp->ComponentId, NULL, &hkey, FALSE ))
{
comp->num_clients = 0;
@@ -1687,8 +1507,8 @@ static BOOL process_state_property(MSIPACKAGE* package, int level,
{
LPWSTR override;
MSIFEATURE *feature;
- BOOL remove = !wcscmp(property, szRemove);
- BOOL reinstall = !wcscmp(property, szReinstall);
+ BOOL remove = !wcscmp(property, L"REMOVE");
+ BOOL reinstall = !wcscmp(property, L"REINSTALL");
override = msi_dup_property( package->db, property );
if (!override)
@@ -1704,7 +1524,7 @@ static BOOL process_state_property(MSIPACKAGE* package, int level,
else if (remove)
state = (feature->Installed == INSTALLSTATE_ABSENT ? INSTALLSTATE_UNKNOWN : INSTALLSTATE_ABSENT);
- if (!wcsicmp( override, szAll ))
+ if (!wcsicmp( override, L"ALL" ))
{
feature->Action = state;
feature->ActionRequest = state;
@@ -1741,12 +1561,6 @@ static BOOL process_state_property(MSIPACKAGE* package, int level,
static BOOL process_overrides( MSIPACKAGE *package, int level )
{
- static const WCHAR szAddLocal[] =
- {'A','D','D','L','O','C','A','L',0};
- static const WCHAR szAddSource[] =
- {'A','D','D','S','O','U','R','C','E',0};
- static const WCHAR szAdvertise[] =
- {'A','D','V','E','R','T','I','S','E',0};
BOOL ret = FALSE;
/* all these activation/deactivation things happen in order and things
@@ -1765,14 +1579,14 @@ static BOOL process_overrides( MSIPACKAGE *package, int level )
* 10 FILEADDSOURCE
* 11 FILEADDDEFAULT
*/
- ret |= process_state_property( package, level, szAddLocal, INSTALLSTATE_LOCAL );
- ret |= process_state_property( package, level, szRemove, INSTALLSTATE_ABSENT );
- ret |= process_state_property( package, level, szAddSource, INSTALLSTATE_SOURCE );
- ret |= process_state_property( package, level, szReinstall, INSTALLSTATE_UNKNOWN );
- ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED );
+ ret |= process_state_property( package, level, L"ADDLOCAL", INSTALLSTATE_LOCAL );
+ ret |= process_state_property( package, level, L"REMOVE", INSTALLSTATE_ABSENT );
+ ret |= process_state_property( package, level, L"ADDSOURCE", INSTALLSTATE_SOURCE );
+ ret |= process_state_property( package, level, L"REINSTALL", INSTALLSTATE_UNKNOWN );
+ ret |= process_state_property( package, level, L"ADVERTISE", INSTALLSTATE_ADVERTISED );
if (ret)
- msi_set_property( package->db, szPreselected, szOne, -1 );
+ msi_set_property( package->db, L"Preselected", L"1", -1 );
return ret;
}
@@ -1824,9 +1638,9 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
TRACE("Checking Install Level\n");
- level = msi_get_property_int(package->db, szInstallLevel, 1);
+ level = msi_get_property_int(package->db, L"INSTALLLEVEL", 1);
- if (msi_get_property_int( package->db, szPreselected, 0 ))
+ if (msi_get_property_int( package->db, L"Preselected", 0 ))
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
@@ -1847,7 +1661,7 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
}
}
}
- else if (!msi_get_property_int( package->db, szInstalled, 0 ))
+ else if (!msi_get_property_int( package->db, L"Installed", 0 ))
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
@@ -2141,7 +1955,7 @@ static WCHAR *create_temp_dir( MSIDATABASE *db )
WCHAR tmp[MAX_PATH];
UINT len = ARRAY_SIZE( tmp );
- if (msi_get_property( db, szTempFolder, tmp, &len ) ||
+ if (msi_get_property( db, L"TempFolder", tmp, &len ) ||
GetFileAttributesW( tmp ) != FILE_ATTRIBUTE_DIRECTORY)
{
GetTempPathW( MAX_PATH, tmp );
@@ -2153,7 +1967,7 @@ static WCHAR *create_temp_dir( MSIDATABASE *db )
{
for (;;)
{
- if (!GetTempFileNameW( db->tempfolder, szMsi, ++id, ret ))
+ if (!GetTempFileNameW( db->tempfolder, L"msi", ++id, ret ))
{
msi_free( ret );
return NULL;
@@ -2207,7 +2021,7 @@ WCHAR *msi_build_directory_name( DWORD count, ... )
const WCHAR *str = va_arg( va, const WCHAR * );
if (!str) continue;
lstrcatW( dir, str );
- if ( i + 1 != count && dir[0] && dir[lstrlenW( dir ) - 1] != '\\') lstrcatW( dir, szBackSlash );
+ if ( i + 1 != count && dir[0] && dir[lstrlenW( dir ) - 1] != '\\') lstrcatW( dir, L"\\" );
}
va_end( va );
return dir;
@@ -2345,7 +2159,7 @@ static WCHAR *get_install_location( MSIPACKAGE *package )
if (!package->ProductCode) return NULL;
if (MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE )) return NULL;
- if ((path = msi_reg_get_val_str( hkey, szInstallLocation )) && !path[0])
+ if ((path = msi_reg_get_val_str( hkey, L"InstallLocation" )) && !path[0])
{
msi_free( path );
path = NULL;
@@ -2364,12 +2178,12 @@ void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL loa
if (!(folder = msi_get_loaded_folder( package, name ))) return;
- if (!wcscmp( folder->Directory, szTargetDir )) /* special resolving for target root dir */
+ if (!wcscmp( folder->Directory, L"TARGETDIR" )) /* special resolving for target root dir */
{
if (!(path = get_install_location( package )) &&
- (!load_prop || !(path = msi_dup_property( package->db, szTargetDir ))))
+ (!load_prop || !(path = msi_dup_property( package->db, L"TARGETDIR" ))))
{
- path = msi_dup_property( package->db, szRootDrive );
+ path = msi_dup_property( package->db, L"ROOTDRIVE" );
}
}
else if (!load_prop || !(path = msi_dup_property( package->db, folder->Directory )))
@@ -2412,33 +2226,13 @@ static ULONGLONG get_volume_space_required( MSIPACKAGE *package )
static UINT ACTION_CostFinalize(MSIPACKAGE *package)
{
- static const WCHAR query[] =
- {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','o','n','d','i','t','i','o','n','`',0};
- static const WCHAR szOutOfDiskSpace[] =
- {'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0};
- static const WCHAR szPrimaryFolder[] =
- {'P','R','I','M','A','R','Y','F','O','L','D','E','R',0};
- static const WCHAR szPrimaryVolumePath[] =
- {'P','r','i','m','a','r','y','V','o','l','u','m','e','P','a','t','h',0};
- static const WCHAR szPrimaryVolumeSpaceAvailable[] =
- {'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e',
- 'A','v','a','i','l','a','b','l','e',0};
- static const WCHAR szPrimaryVolumeSpaceRequired[] =
- {'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e',
- 'R','e','q','u','i','r','e','d',0};
- static const WCHAR szPrimaryVolumeSpaceRemaining[] =
- {'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e',
- 'R','e','m','a','i','n','i','n','g',0};
- static const WCHAR szOutOfNoRbDiskSpace[] =
- {'O','u','t','O','f','N','o','R','b','D','i','s','k','S','p','a','c','e',0};
MSICOMPONENT *comp;
MSIQUERY *view;
WCHAR *level, *primary_key, *primary_folder;
UINT rc;
TRACE("Building directory properties\n");
- msi_resolve_target_folder( package, szTargetDir, TRUE );
+ msi_resolve_target_folder( package, L"TARGETDIR", TRUE );
TRACE("Evaluating component conditions\n");
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
@@ -2457,11 +2251,11 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
ACTION_GetComponentInstallStates(package);
ACTION_GetFeatureInstallStates(package);
- if (!process_overrides( package, msi_get_property_int( package->db, szInstallLevel, 1 ) ))
+ if (!process_overrides( package, msi_get_property_int( package->db, L"INSTALLLEVEL", 1 ) ))
{
TRACE("Evaluating feature conditions\n");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Condition`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_CostFinalizeConditions, package );
@@ -2474,22 +2268,21 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
TRACE("Calculating file cost\n");
calculate_file_cost( package );
- msi_set_property( package->db, szCostingComplete, szOne, -1 );
+ msi_set_property( package->db, L"CostingComplete", L"1", -1 );
/* set default run level if not set */
- level = msi_dup_property( package->db, szInstallLevel );
- if (!level) msi_set_property( package->db, szInstallLevel, szOne, -1 );
+ level = msi_dup_property( package->db, L"INSTALLLEVEL" );
+ if (!level) msi_set_property( package->db, L"INSTALLLEVEL", L"1", -1 );
msi_free(level);
if ((rc = MSI_SetFeatureStates( package ))) return rc;
- if ((primary_key = msi_dup_property( package->db, szPrimaryFolder )))
+ if ((primary_key = msi_dup_property( package->db, L"PRIMARYFOLDER" )))
{
if ((primary_folder = msi_dup_property( package->db, primary_key )))
{
if (((primary_folder[0] >= 'A' && primary_folder[0] <= 'Z') ||
(primary_folder[0] >= 'a' && primary_folder[0] <= 'z')) && primary_folder[1] == ':')
{
- static const WCHAR fmtW[] = {'%','l','u',0};
ULARGE_INTEGER free;
ULONGLONG required;
WCHAR buf[21];
@@ -2497,16 +2290,16 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
primary_folder[2] = 0;
if (GetDiskFreeSpaceExW( primary_folder, &free, NULL, NULL ))
{
- swprintf( buf, ARRAY_SIZE(buf), fmtW, free.QuadPart / 512 );
- msi_set_property( package->db, szPrimaryVolumeSpaceAvailable, buf, -1 );
+ swprintf( buf, ARRAY_SIZE(buf), L"%lu", free.QuadPart / 512 );
+ msi_set_property( package->db, L"PrimaryVolumeSpaceAvailable", buf, -1 );
}
required = get_volume_space_required( package );
- swprintf( buf, ARRAY_SIZE(buf), fmtW, required / 512 );
- msi_set_property( package->db, szPrimaryVolumeSpaceRequired, buf, -1 );
+ swprintf( buf, ARRAY_SIZE(buf), L"%lu", required / 512 );
+ msi_set_property( package->db, L"PrimaryVolumeSpaceRequired", buf, -1 );
- swprintf( buf, ARRAY_SIZE(buf), fmtW, (free.QuadPart - required) / 512 );
- msi_set_property( package->db, szPrimaryVolumeSpaceRemaining, buf, -1 );
- msi_set_property( package->db, szPrimaryVolumePath, primary_folder, 2 );
+ swprintf( buf, ARRAY_SIZE(buf), L"%lu", (free.QuadPart - required) / 512 );
+ msi_set_property( package->db, L"PrimaryVolumeSpaceRemaining", buf, -1 );
+ msi_set_property( package->db, L"PrimaryVolumePath", primary_folder, 2 );
}
msi_free( primary_folder );
}
@@ -2514,8 +2307,8 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
}
/* FIXME: check volume disk space */
- msi_set_property( package->db, szOutOfDiskSpace, szZero, -1 );
- msi_set_property( package->db, szOutOfNoRbDiskSpace, szZero, -1 );
+ msi_set_property( package->db, L"OutOfDiskSpace", L"0", -1 );
+ msi_set_property( package->db, L"OutOfNoRbDiskSpace", L"0", -1 );
return ERROR_SUCCESS;
}
@@ -2636,32 +2429,32 @@ static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key
switch (root)
{
case -1:
- if (msi_get_property_int( package->db, szAllUsers, 0 ))
+ if (msi_get_property_int( package->db, L"ALLUSERS", 0 ))
{
*root_key = HKEY_LOCAL_MACHINE;
- ret = szHLM;
+ ret = L"HKEY_LOCAL_MACHINE\\";
}
else
{
*root_key = HKEY_CURRENT_USER;
- ret = szHCU;
+ ret = L"HKEY_CURRENT_USER\\";
}
break;
case 0:
*root_key = HKEY_CLASSES_ROOT;
- ret = szHCR;
+ ret = L"HKEY_CLASSES_ROOT\\";
break;
case 1:
*root_key = HKEY_CURRENT_USER;
- ret = szHCU;
+ ret = L"HKEY_CURRENT_USER\\";
break;
case 2:
*root_key = HKEY_LOCAL_MACHINE;
- ret = szHLM;
+ ret = L"HKEY_LOCAL_MACHINE\\";
break;
case 3:
*root_key = HKEY_USERS;
- ret = szHU;
+ ret = L"HKEY_USERS\\";
break;
default:
ERR("Unknown root %i\n", root);
@@ -2993,16 +2786,13 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','R','e','g','i','s','t','r','y','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szWriteRegistryValues);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"WriteRegistryValues");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Registry`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -3225,19 +3015,13 @@ static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param
static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package )
{
- static const WCHAR registry_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','R','e','g','i','s','t','r','y','`',0};
- static const WCHAR remove_registry_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','R','e','m','o','v','e','R','e','g','i','s','t','r','y','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveRegistryValues);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveRegistryValues");
- rc = MSI_DatabaseOpenViewW( package->db, registry_query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Registry`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveRegistryValuesOnUninstall, package );
@@ -3245,7 +3029,7 @@ static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package )
if (rc != ERROR_SUCCESS)
return rc;
}
- rc = MSI_DatabaseOpenViewW( package->db, remove_registry_query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `RemoveRegistry`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveRegistryValuesOnInstall, package );
@@ -3264,9 +3048,6 @@ static UINT ACTION_InstallInitialize(MSIPACKAGE *package)
static UINT ACTION_InstallValidate(MSIPACKAGE *package)
{
- static const WCHAR query[]= {
- 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- '`','R','e','g','i','s','t','r','y','`',0};
MSICOMPONENT *comp;
DWORD total = 0, count = 0;
MSIQUERY *view;
@@ -3276,7 +3057,7 @@ static UINT ACTION_InstallValidate(MSIPACKAGE *package)
TRACE("InstallValidate\n");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Registry`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, &count, NULL, package );
@@ -3305,24 +3086,19 @@ static UINT ACTION_InstallValidate(MSIPACKAGE *package)
static UINT ITERATE_LaunchConditions(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE* package = param;
- LPCWSTR cond = NULL;
- LPCWSTR message = NULL;
+ const WCHAR *cond, *message;
UINT r;
- static const WCHAR title[]=
- {'I','n','s','t','a','l','l',' ','F','a', 'i','l','e','d',0};
-
- cond = MSI_RecordGetString(row,1);
-
- r = MSI_EvaluateConditionW(package,cond);
+ cond = MSI_RecordGetString(row, 1);
+ r = MSI_EvaluateConditionW(package, cond);
if (r == MSICONDITION_FALSE)
{
if ((package->ui_level & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
{
- LPWSTR deformated;
- message = MSI_RecordGetString(row,2);
- deformat_string(package,message,&deformated);
- MessageBoxW(NULL,deformated,title,MB_OK);
+ WCHAR *deformated;
+ message = MSI_RecordGetString(row, 2);
+ deformat_string(package, message, &deformated);
+ MessageBoxW(NULL, deformated, L"Install Failed", MB_OK);
msi_free(deformated);
}
@@ -3334,15 +3110,12 @@ static UINT ITERATE_LaunchConditions(MSIRECORD *row, LPVOID param)
static UINT ACTION_LaunchConditions(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','`',0};
MSIQUERY *view;
UINT rc;
TRACE("Checking launch conditions\n");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `LaunchCondition`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -3359,18 +3132,12 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp )
if (cmp->Attributes & msidbComponentAttributesRegistryKeyPath)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','R','e','g','i','s','t','r','y','`',' ','W','H','E','R','E',' ',
- '`','R','e','g','i','s','t','r','y','`',' ','=',' ' ,'\'','%','s','\'',0};
- static const WCHAR fmt[] = {'%','0','2','i',':','\\','%','s','\\',0};
- static const WCHAR fmt2[]= {'%','0','2','i',':','\\','%','s','\\','%','s',0};
MSIRECORD *row;
UINT root, len;
LPWSTR deformated, buffer, deformated_name;
LPCWSTR key, name;
- row = MSI_QueryGetRecord(package->db, query, cmp->KeyPath);
+ row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Registry` WHERE `Registry` = '%s'", cmp->KeyPath);
if (!row)
return NULL;
@@ -3387,9 +3154,9 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp )
buffer = msi_alloc( len *sizeof(WCHAR));
if (deformated_name)
- swprintf(buffer,len,fmt2,root,deformated,deformated_name);
+ swprintf(buffer, len, L"%02d:\\%s\\%s", root, deformated, deformated_name);
else
- swprintf(buffer,len,fmt,root,deformated);
+ swprintf(buffer, len, L"%02d:\\%s\\", root, deformated);
msi_free(deformated);
msi_free(deformated_name);
@@ -3414,11 +3181,8 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp )
static HKEY open_shared_dlls_key( MSICOMPONENT *comp, BOOL create, REGSAM access )
{
- static const WCHAR path[] =
- {'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','\\',
- 'S','h','a','r','e','d','D','L','L','s',0};
- return open_key( comp, HKEY_LOCAL_MACHINE, path, create, access );
+ return open_key( comp, HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs",
+ create, access );
}
static UINT get_shared_dlls_count( MSICOMPONENT *comp )
@@ -3514,13 +3278,12 @@ static WCHAR *build_full_keypath( MSIPACKAGE *package, MSICOMPONENT *comp )
{
if (comp->assembly)
{
- static const WCHAR prefixW[] = {'<','\\',0};
- DWORD len = lstrlenW( prefixW ) + lstrlenW( comp->assembly->display_name );
+ DWORD len = lstrlenW( L"<\\" ) + lstrlenW( comp->assembly->display_name );
WCHAR *keypath = msi_alloc( (len + 1) * sizeof(WCHAR) );
if (keypath)
{
- lstrcpyW( keypath, prefixW );
+ lstrcpyW( keypath, L"<\\" );
lstrcatW( keypath, comp->assembly->display_name );
}
return keypath;
@@ -3540,7 +3303,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
msi_set_sourcedir_props(package, FALSE);
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szProcessComponents);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"ProcessComponents");
squash_guid( package->ProductCode, squashed_pc );
@@ -3569,7 +3332,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (action == INSTALLSTATE_LOCAL || action == INSTALLSTATE_SOURCE)
{
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
- rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, szLocalSid, &hkey, TRUE);
+ rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, L"S-1-5-18", &hkey, TRUE);
else
rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, NULL, &hkey, TRUE);
@@ -3578,12 +3341,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (comp->Attributes & msidbComponentAttributesPermanent)
{
- static const WCHAR szPermKey[] =
- { '0','0','0','0','0','0','0','0','0','0','0','0',
- '0','0','0','0','0','0','0','0','0','0','0','0',
- '0','0','0','0','0','0','0','0',0 };
-
- msi_reg_set_val_str(hkey, szPermKey, comp->FullKeypath);
+ msi_reg_set_val_str(hkey, L"00000000000000000000000000000000", comp->FullKeypath);
}
if (action == INSTALLSTATE_LOCAL)
msi_reg_set_val_str( hkey, squashed_pc, comp->FullKeypath );
@@ -3596,21 +3354,14 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
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};
-
if (!comp->KeyPath || !(file = msi_get_loaded_file(package, comp->KeyPath)))
continue;
- if (!(row = MSI_QueryGetRecord(package->db, query, file->Sequence)))
+ if (!(row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `LastSequence` >= %d "
+ "ORDER BY `DiskId`", file->Sequence)))
return ERROR_FUNCTION_FAILED;
- swprintf(source, ARRAY_SIZE(source), fmt, MSI_RecordGetInteger(row, 1));
+ swprintf(source, ARRAY_SIZE(source), L"%02d\\", MSI_RecordGetInteger(row, 1));
ptr2 = wcsrchr(source, '\\') + 1;
msiobj_release(&row->hdr);
@@ -3632,7 +3383,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (comp->num_clients <= 0)
{
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
- rc = MSIREG_DeleteUserDataComponentKey( comp->ComponentId, szLocalSid );
+ rc = MSIREG_DeleteUserDataComponentKey( comp->ComponentId, L"S-1-5-18" );
else
rc = MSIREG_DeleteUserDataComponentKey( comp->ComponentId, NULL );
@@ -3643,7 +3394,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
LONG res;
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
- rc = MSIREG_OpenUserDataComponentKey( comp->ComponentId, szLocalSid, &hkey, FALSE );
+ rc = MSIREG_OpenUserDataComponentKey( comp->ComponentId, L"S-1-5-18", &hkey, FALSE );
else
rc = MSIREG_OpenUserDataComponentKey( comp->ComponentId, NULL, &hkey, FALSE );
@@ -3682,8 +3433,7 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType,
{
TLIBATTR *attr;
typelib_struct *tl_struct = (typelib_struct*) lParam;
- static const WCHAR fmt[] = {'%','s','\\','%','i',0};
- int sz;
+ int sz;
HRESULT res;
if (!IS_INTRESOURCE(lpszName))
@@ -3699,7 +3449,7 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType,
else
{
tl_struct->path = msi_alloc(sz * sizeof(WCHAR));
- swprintf(tl_struct->path,sz,fmt,tl_struct->source, lpszName);
+ swprintf(tl_struct->path, sz, L"%s\\%d", tl_struct->source, lpszName);
}
TRACE("trying %s\n", debugstr_w(tl_struct->path));
@@ -3785,7 +3535,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
tl_struct.source = strdupW( file->TargetPath );
tl_struct.path = NULL;
- EnumResourceNamesW(module, szTYPELIB, Typelib_EnumResNameProc,
+ EnumResourceNamesW(module, L"TYPELIB", Typelib_EnumResNameProc,
(LONG_PTR)&tl_struct);
if (tl_struct.path)
@@ -3828,16 +3578,13 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','T','y','p','e','L','i','b','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterTypeLibraries);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterTypeLibraries");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `TypeLib`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -3892,16 +3639,13 @@ static UINT ITERATE_UnregisterTypeLibraries( MSIRECORD *row, LPVOID param )
static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','T','y','p','e','L','i','b','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterTypeLibraries);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"UnregisterTypeLibraries");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `TypeLib`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -3912,7 +3656,6 @@ static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row )
{
- static const WCHAR szlnk[] = {'.','l','n','k',0};
LPCWSTR directory, extension, link_folder;
LPWSTR link_file, filename;
@@ -3930,11 +3673,11 @@ static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row )
msi_reduce_to_long_filename( filename );
extension = wcsrchr( filename, '.' );
- if (!extension || wcsicmp( extension, szlnk ))
+ if (!extension || wcsicmp( extension, L".lnk" ))
{
int len = lstrlenW( filename );
- filename = msi_realloc( filename, len * sizeof(WCHAR) + sizeof(szlnk) );
- memcpy( filename + len, szlnk, sizeof(szlnk) );
+ filename = msi_realloc( filename, len * sizeof(WCHAR) + sizeof(L".lnk") );
+ memcpy( filename + len, L".lnk", sizeof(L".lnk") );
}
link_file = msi_build_directory_name( 2, link_folder, filename );
msi_free( filename );
@@ -3944,19 +3687,17 @@ static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row )
WCHAR *msi_build_icon_path( MSIPACKAGE *package, const WCHAR *icon_name )
{
- static const WCHAR szMicrosoft[] = {'M','i','c','r','o','s','o','f','t','\\',0};
- static const WCHAR szInstaller[] = {'I','n','s','t','a','l','l','e','r','\\',0};
WCHAR *folder, *dest, *path;
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
- folder = msi_dup_property( package->db, szWindowsFolder );
+ folder = msi_dup_property( package->db, L"WindowsFolder" );
else
{
- WCHAR *appdata = msi_dup_property( package->db, szAppDataFolder );
- folder = msi_build_directory_name( 2, appdata, szMicrosoft );
+ WCHAR *appdata = msi_dup_property( package->db, L"AppDataFolder" );
+ folder = msi_build_directory_name( 2, appdata, L"Microsoft\\" );
msi_free( appdata );
}
- dest = msi_build_directory_name( 3, folder, szInstaller, package->ProductCode );
+ dest = msi_build_directory_name( 3, folder, L"Installer\\", package->ProductCode );
msi_create_full_path( package, dest );
path = msi_build_directory_name( 2, dest, icon_name );
msi_free( folder );
@@ -4082,17 +3823,14 @@ err:
static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','S','h','o','r','t','c','u','t','`',0};
MSIQUERY *view;
HRESULT res;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szCreateShortcuts);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"CreateShortcuts");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Shortcut`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -4135,16 +3873,13 @@ static UINT ITERATE_RemoveShortcuts( MSIRECORD *row, LPVOID param )
static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','S','h','o','r','t','c','u','t','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveShortcuts);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveShortcuts");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Shortcut`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -4204,13 +3939,10 @@ static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
static UINT msi_publish_icons(MSIPACKAGE *package)
{
- static const WCHAR query[]= {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','I','c','o','n','`',0};
MSIQUERY *view;
UINT r;
- r = MSI_DatabaseOpenViewW(package->db, query, &view);
+ r = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Icon`", &view);
if (r == ERROR_SUCCESS)
{
r = MSI_IterateRecords(view, NULL, ITERATE_PublishIcon, package);
@@ -4229,7 +3961,7 @@ static UINT msi_publish_sourcelist(MSIPACKAGE *package, HKEY hkey)
MSIMEDIADISK *disk;
MSISOURCELISTINFO *info;
- r = RegCreateKeyW(hkey, szSourceList, &source);
+ r = RegCreateKeyW(hkey, L"SourceList", &source);
if (r != ERROR_SUCCESS)
return r;
@@ -4244,13 +3976,13 @@ static UINT msi_publish_sourcelist(MSIPACKAGE *package, HKEY hkey)
r = MsiSourceListSetInfoW(package->ProductCode, NULL,
package->Context, MSICODE_PRODUCT,
- INSTALLPROPERTY_MEDIAPACKAGEPATHW, szEmpty);
+ INSTALLPROPERTY_MEDIAPACKAGEPATHW, L"");
if (r != ERROR_SUCCESS)
return r;
r = MsiSourceListSetInfoW(package->ProductCode, NULL,
package->Context, MSICODE_PRODUCT,
- INSTALLPROPERTY_DISKPROMPTW, szEmpty);
+ INSTALLPROPERTY_DISKPROMPTW, L"");
if (r != ERROR_SUCCESS)
return r;
@@ -4277,15 +4009,6 @@ static UINT msi_publish_sourcelist(MSIPACKAGE *package, HKEY hkey)
static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey)
{
- static const WCHAR szARPProductIcon[] =
- {'A','R','P','P','R','O','D','U','C','T','I','C','O','N',0};
- static const WCHAR szAssignment[] =
- {'A','s','s','i','g','n','m','e','n','t',0};
- static const WCHAR szAdvertiseFlags[] =
- {'A','d','v','e','r','t','i','s','e','F','l','a','g','s',0};
- static const WCHAR szClients[] =
- {'C','l','i','e','n','t','s',0};
- static const WCHAR szColon[] = {':',0};
WCHAR *buffer, *ptr, *guids, packcode[SQUASHED_GUID_SIZE];
DWORD langid;
@@ -4293,13 +4016,13 @@ static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey)
msi_reg_set_val_str(hkey, INSTALLPROPERTY_PRODUCTNAMEW, buffer);
msi_free(buffer);
- langid = msi_get_property_int(package->db, szProductLanguage, 0);
+ langid = msi_get_property_int(package->db, L"ProductLanguage", 0);
msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid);
/* FIXME */
msi_reg_set_val_dword(hkey, INSTALLPROPERTY_AUTHORIZED_LUA_APPW, 0);
- buffer = msi_dup_property(package->db, szARPProductIcon);
+ buffer = msi_dup_property(package->db, L"ARPPRODUCTICON");
if (buffer)
{
LPWSTR path = msi_build_icon_path(package, buffer);
@@ -4308,7 +4031,7 @@ static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey)
msi_free(buffer);
}
- buffer = msi_dup_property(package->db, szProductVersion);
+ buffer = msi_dup_property(package->db, L"ProductVersion");
if (buffer)
{
DWORD verdword = msi_version_str_to_dword(buffer);
@@ -4316,10 +4039,10 @@ static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey)
msi_free(buffer);
}
- msi_reg_set_val_dword(hkey, szAssignment, 0);
- msi_reg_set_val_dword(hkey, szAdvertiseFlags, 0x184);
+ msi_reg_set_val_dword(hkey, L"Assignment", 0);
+ msi_reg_set_val_dword(hkey, L"AdvertiseFlags", 0x184);
msi_reg_set_val_dword(hkey, INSTALLPROPERTY_INSTANCETYPEW, 0);
- msi_reg_set_val_str(hkey, szClients, szColon);
+ msi_reg_set_val_str(hkey, L"Clients", L":");
if (!(guids = msi_get_package_code(package->db))) return ERROR_OUTOFMEMORY;
if ((ptr = wcschr(guids, ';'))) *ptr = 0;
@@ -4336,7 +4059,7 @@ static UINT msi_publish_upgrade_code(MSIPACKAGE *package)
HKEY hkey;
WCHAR *upgrade, squashed_pc[SQUASHED_GUID_SIZE];
- upgrade = msi_dup_property(package->db, szUpgradeCode);
+ upgrade = msi_dup_property(package->db, L"UpgradeCode");
if (!upgrade)
return ERROR_SUCCESS;
@@ -4388,7 +4111,6 @@ static BOOL msi_check_unpublish(MSIPACKAGE *package)
static UINT msi_publish_patches( MSIPACKAGE *package )
{
- static const WCHAR szAllPatches[] = {'A','l','l','P','a','t','c','h','e','s',0};
WCHAR patch_squashed[GUID_SIZE];
HKEY patches_key = NULL, product_patches_key = NULL, product_key;
LONG res;
@@ -4401,7 +4123,7 @@ static UINT msi_publish_patches( MSIPACKAGE *package )
if (r != ERROR_SUCCESS)
return ERROR_FUNCTION_FAILED;
- res = RegCreateKeyExW( product_key, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL );
+ res = RegCreateKeyExW( product_key, L"Patches", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL );
if (res != ERROR_SUCCESS)
{
r = ERROR_FUNCTION_FAILED;
@@ -4439,7 +4161,7 @@ static UINT msi_publish_patches( MSIPACKAGE *package )
if (r != ERROR_SUCCESS)
goto done;
- res = RegSetValueExW( patch_key, szLocalPackage, 0, REG_SZ, (const BYTE *)patch->localfile,
+ res = RegSetValueExW( patch_key, L"LocalPackage", 0, REG_SZ, (const BYTE *)patch->localfile,
(lstrlenW( patch->localfile ) + 1) * sizeof(WCHAR) );
RegCloseKey( patch_key );
if (res != ERROR_SUCCESS)
@@ -4455,7 +4177,7 @@ static UINT msi_publish_patches( MSIPACKAGE *package )
if (res != ERROR_SUCCESS)
goto done;
- res = RegSetValueExW( patch_key, szState, 0, REG_DWORD, (const BYTE *)&patch->state,
+ res = RegSetValueExW( patch_key, L"State", 0, REG_DWORD, (const BYTE *)&patch->state,
sizeof(patch->state) );
if (res != ERROR_SUCCESS)
{
@@ -4463,7 +4185,7 @@ static UINT msi_publish_patches( MSIPACKAGE *package )
goto done;
}
- res = RegSetValueExW( patch_key, szUninstallable, 0, REG_DWORD, (const BYTE *)&patch->uninstallable,
+ res = RegSetValueExW( patch_key, L"Uninstallable", 0, REG_DWORD, (const BYTE *)&patch->uninstallable,
sizeof(patch->uninstallable) );
RegCloseKey( patch_key );
if (res != ERROR_SUCCESS)
@@ -4471,12 +4193,12 @@ static UINT msi_publish_patches( MSIPACKAGE *package )
}
all_patches[len] = 0;
- res = RegSetValueExW( patches_key, szPatches, 0, REG_MULTI_SZ,
+ res = RegSetValueExW( patches_key, L"Patches", 0, REG_MULTI_SZ,
(const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) );
if (res != ERROR_SUCCESS)
goto done;
- res = RegSetValueExW( product_patches_key, szAllPatches, 0, REG_MULTI_SZ,
+ res = RegSetValueExW( product_patches_key, L"AllPatches", 0, REG_MULTI_SZ,
(const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) );
if (res != ERROR_SUCCESS)
r = ERROR_FUNCTION_FAILED;
@@ -4497,7 +4219,7 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
BOOL republish = FALSE;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szPublishProduct);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"PublishProduct");
if (!list_empty(&package->patches))
{
@@ -4598,7 +4320,7 @@ static WCHAR *get_ini_file_name( MSIPACKAGE *package, MSIRECORD *row )
if (!folder) folder = msi_dup_property( package->db, dirprop );
}
else
- folder = msi_dup_property( package->db, szWindowsFolder );
+ folder = msi_dup_property( package->db, L"WindowsFolder" );
if (!folder)
{
@@ -4690,16 +4412,13 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
static UINT ACTION_WriteIniValues(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','I','n','i','F','i','l','e','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szWriteIniValues);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"WriteIniValues");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `IniFile`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -4833,19 +4552,13 @@ static UINT ITERATE_RemoveIniValuesOnInstall( MSIRECORD *row, LPVOID param )
static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','I','n','i','F','i','l','e','`',0};
- static const WCHAR remove_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','R','e','m','o','v','e','I','n','i','F','i','l','e','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveIniValues);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveIniValues");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `IniFile`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveIniValuesOnUninstall, package );
@@ -4853,7 +4566,7 @@ static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
if (rc != ERROR_SUCCESS)
return rc;
}
- rc = MSI_DatabaseOpenViewW( package->db, remove_query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `RemoveIniFile`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveIniValuesOnInstall, package );
@@ -4866,10 +4579,8 @@ static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
static void register_dll( const WCHAR *dll, BOOL unregister )
{
- static const WCHAR regW[] =
- {'r','e','g','s','v','r','3','2','.','e','x','e',' ','\"','%','s','\"',0};
- static const WCHAR unregW[] =
- {'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','u',' ','\"','%','s','\"',0};
+ static const WCHAR regW[] = L"regsvr32.exe \"%s\"";
+ static const WCHAR unregW[] = L"regsvr32.exe /u \"%s\"";
PROCESS_INFORMATION pi;
STARTUPINFOW si;
WCHAR *cmd;
@@ -4924,16 +4635,13 @@ static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','S','e','l','f','R','e','g','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szSelfRegModules);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"SelfRegModules");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `SelfReg`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -4977,16 +4685,13 @@ static UINT ITERATE_SelfUnregModules( MSIRECORD *row, LPVOID param )
static UINT ACTION_SelfUnregModules( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','S','e','l','f','R','e','g','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szSelfUnregModules);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"SelfUnregModules");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `SelfReg`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -5002,7 +4707,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
HKEY hkey = NULL, userdata = NULL;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szPublishFeatures);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"PublishFeatures");
if (!msi_check_publish(package))
return ERROR_SUCCESS;
@@ -5064,9 +4769,8 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
if (feature->Feature_Parent)
{
- static const WCHAR sep[] = {'\2',0};
- lstrcatW(data,sep);
- lstrcatW(data,feature->Feature_Parent);
+ lstrcatW(data, L"\2");
+ lstrcatW(data, feature->Feature_Parent);
}
msi_reg_set_val_str( userdata, feature->Feature, data );
@@ -5078,8 +4782,8 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
if (!absent)
{
size += sizeof(WCHAR);
- RegSetValueExW(hkey,feature->Feature,0,REG_SZ,
- (const BYTE*)(feature->Feature_Parent ? feature->Feature_Parent : szEmpty),size);
+ RegSetValueExW(hkey, feature->Feature, 0 ,REG_SZ,
+ (const BYTE*)(feature->Feature_Parent ? feature->Feature_Parent : L""), size);
}
else
{
@@ -5145,7 +4849,7 @@ static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package)
MSIFEATURE *feature;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szUnpublishFeatures);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"UnpublishFeatures");
if (!msi_check_unpublish(package))
return ERROR_SUCCESS;
@@ -5160,91 +4864,21 @@ static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package)
static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey)
{
- static const WCHAR date_fmt[] =
- {'%','i','%','0','2','i','%','0','2','i',0};
- static const WCHAR szEstimatedSize[] =
- {'E','s','t','i','m','a','t','e','d','S','i','z','e',0};
- static const WCHAR szDisplayVersion[] =
- {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
- static const WCHAR szInstallSource[] =
- {'I','n','s','t','a','l','l','S','o','u','r','c','e',0};
- static const WCHAR szARPAUTHORIZEDCDFPREFIX[] =
- {'A','R','P','A','U','T','H','O','R','I','Z','E','D','C','D','F','P','R','E','F','I','X',0};
- static const WCHAR szAuthorizedCDFPrefix[] =
- {'A','u','t','h','o','r','i','z','e','d','C','D','F','P','r','e','f','i','x',0};
- static const WCHAR szARPCONTACT[] =
- {'A','R','P','C','O','N','T','A','C','T',0};
- static const WCHAR szContact[] =
- {'C','o','n','t','a','c','t',0};
- static const WCHAR szARPCOMMENTS[] =
- {'A','R','P','C','O','M','M','E','N','T','S',0};
- static const WCHAR szComments[] =
- {'C','o','m','m','e','n','t','s',0};
- static const WCHAR szProductName[] =
- {'P','r','o','d','u','c','t','N','a','m','e',0};
- static const WCHAR szDisplayName[] =
- {'D','i','s','p','l','a','y','N','a','m','e',0};
- static const WCHAR szARPHELPLINK[] =
- {'A','R','P','H','E','L','P','L','I','N','K',0};
- static const WCHAR szHelpLink[] =
- {'H','e','l','p','L','i','n','k',0};
- static const WCHAR szARPHELPTELEPHONE[] =
- {'A','R','P','H','E','L','P','T','E','L','E','P','H','O','N','E',0};
- static const WCHAR szHelpTelephone[] =
- {'H','e','l','p','T','e','l','e','p','h','o','n','e',0};
- static const WCHAR szARPINSTALLLOCATION[] =
- {'A','R','P','I','N','S','T','A','L','L','L','O','C','A','T','I','O','N',0};
- static const WCHAR szManufacturer[] =
- {'M','a','n','u','f','a','c','t','u','r','e','r',0};
- static const WCHAR szPublisher[] =
- {'P','u','b','l','i','s','h','e','r',0};
- static const WCHAR szARPREADME[] =
- {'A','R','P','R','E','A','D','M','E',0};
- static const WCHAR szReadme[] =
- {'R','e','a','d','M','e',0};
- static const WCHAR szARPSIZE[] =
- {'A','R','P','S','I','Z','E',0};
- static const WCHAR szSize[] =
- {'S','i','z','e',0};
- static const WCHAR szARPURLINFOABOUT[] =
- {'A','R','P','U','R','L','I','N','F','O','A','B','O','U','T',0};
- static const WCHAR szURLInfoAbout[] =
- {'U','R','L','I','n','f','o','A','b','o','u','t',0};
- static const WCHAR szARPURLUPDATEINFO[] =
- {'A','R','P','U','R','L','U','P','D','A','T','E','I','N','F','O',0};
- static const WCHAR szURLUpdateInfo[] =
- {'U','R','L','U','p','d','a','t','e','I','n','f','o',0};
- static const WCHAR szARPSYSTEMCOMPONENT[] =
- {'A','R','P','S','Y','S','T','E','M','C','O','M','P','O','N','E','N','T',0};
- static const WCHAR szSystemComponent[] =
- {'S','y','s','t','e','m','C','o','m','p','o','n','e','n','t',0};
- static const WCHAR szARPNOMODIFY[] =
- {'A','R','P','N','O','M','O','D','I','F','Y',0};
- static const WCHAR szNoModify[] =
- {'N','o','M','o','d','i','f','y',0};
- static const WCHAR szARPNOREMOVE[] =
- {'A','R','P','N','O','R','E','M','O','V','E',0};
- static const WCHAR szNoRemove[] =
- {'N','o','R','e','m','o','v','e',0};
- static const WCHAR szARPNOREPAIR[] =
- {'A','R','P','N','O','R','E','P','A','I','R',0};
- static const WCHAR szNoRepair[] =
- {'N','o','R','e','p','a','i','r',0};
-
- static const WCHAR *propval[] = {
- szARPAUTHORIZEDCDFPREFIX, szAuthorizedCDFPrefix,
- szARPCONTACT, szContact,
- szARPCOMMENTS, szComments,
- szProductName, szDisplayName,
- szARPHELPLINK, szHelpLink,
- szARPHELPTELEPHONE, szHelpTelephone,
- szARPINSTALLLOCATION, szInstallLocation,
- szSourceDir, szInstallSource,
- szManufacturer, szPublisher,
- szARPREADME, szReadme,
- szARPSIZE, szSize,
- szARPURLINFOABOUT, szURLInfoAbout,
- szARPURLUPDATEINFO, szURLUpdateInfo,
+ static const WCHAR *propval[] =
+ {
+ L"ARPAUTHORIZEDCDFPREFIX", L"AuthorizedCDFPrefix",
+ L"ARPCONTACT", L"Contact",
+ L"ARPCOMMENTS", L"Comments",
+ L"ProductName", L"DisplayName",
+ L"ARPHELPLINK", L"HelpLink",
+ L"ARPHELPTELEPHONE", L"HelpTelephone",
+ L"ARPINSTALLLOCATION", L"InstallLocation",
+ L"SourceDir", L"InstallSource",
+ L"Manufacturer", L"Publisher",
+ L"ARPREADME", L"ReadMe",
+ L"ARPSIZE", L"Size",
+ L"ARPURLINFOABOUT", L"URLInfoAbout",
+ L"ARPURLUPDATEINFO", L"URLUpdateInfo",
NULL
};
const WCHAR **p = propval;
@@ -5262,55 +4896,47 @@ static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey)
msi_free(val);
}
- msi_reg_set_val_dword(hkey, szWindowsInstaller, 1);
- if (msi_get_property_int( package->db, szARPSYSTEMCOMPONENT, 0 ))
+ msi_reg_set_val_dword(hkey, L"WindowsInstaller", 1);
+ if (msi_get_property_int( package->db, L"ARPSYSTEMCOMPONENT", 0 ))
{
- msi_reg_set_val_dword( hkey, szSystemComponent, 1 );
+ msi_reg_set_val_dword( hkey, L"SystemComponent", 1 );
}
- if (msi_get_property_int( package->db, szARPNOREMOVE, 0 ))
- msi_reg_set_val_dword( hkey, szNoRemove, 1 );
+ if (msi_get_property_int( package->db, L"ARPNOREMOVE", 0 ))
+ msi_reg_set_val_dword( hkey, L"NoRemove", 1 );
else
{
- static const WCHAR fmt_install[] =
- {'M','s','i','E','x','e','c','.','e','x','e',' ',
- '/','I','[','P','r','o','d','u','c','t','C','o','d','e',']',0};
- static const WCHAR fmt_uninstall[] =
- {'M','s','i','E','x','e','c','.','e','x','e',' ',
- '/','X','[','P','r','o','d','u','c','t','C','o','d','e',']',0};
- static const WCHAR szModifyPath[] =
- {'M','o','d','i','f','y','P','a','t','h',0};
- static const WCHAR szUninstallString[] =
- {'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0};
+ static const WCHAR fmt_install[] = L"MsiExec.exe /I[ProductCode]";
+ static const WCHAR fmt_uninstall[] = L"MsiExec.exe /X[ProductCode]";
const WCHAR *fmt = fmt_install;
- if (msi_get_property_int( package->db, szARPNOREPAIR, 0 ))
- msi_reg_set_val_dword( hkey, szNoRepair, 1 );
+ if (msi_get_property_int( package->db, L"ARPNOREPAIR", 0 ))
+ msi_reg_set_val_dword( hkey, L"NoRepair", 1 );
- if (msi_get_property_int( package->db, szARPNOMODIFY, 0 ))
+ if (msi_get_property_int( package->db, L"ARPNOMODIFY", 0 ))
{
- msi_reg_set_val_dword( hkey, szNoModify, 1 );
+ msi_reg_set_val_dword( hkey, L"NoModify", 1 );
fmt = fmt_uninstall;
}
size = deformat_string(package, fmt, &buffer) * sizeof(WCHAR);
- RegSetValueExW(hkey, szModifyPath, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
- RegSetValueExW(hkey, szUninstallString, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
+ RegSetValueExW(hkey, L"ModifyPath", 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
+ RegSetValueExW(hkey, L"UninstallString", 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
msi_free(buffer);
}
/* FIXME: Write real Estimated Size when we have it */
- msi_reg_set_val_dword(hkey, szEstimatedSize, 0);
+ msi_reg_set_val_dword(hkey, L"EstimatedSize", 0);
GetLocalTime(&systime);
- swprintf(date, ARRAY_SIZE(date), date_fmt, systime.wYear, systime.wMonth, systime.wDay);
+ swprintf(date, ARRAY_SIZE(date), L"%d%02d%02d", systime.wYear, systime.wMonth, systime.wDay);
msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLDATEW, date);
- langid = msi_get_property_int(package->db, szProductLanguage, 0);
+ langid = msi_get_property_int(package->db, L"ProductLanguage", 0);
msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid);
- buffer = msi_dup_property(package->db, szProductVersion);
- msi_reg_set_val_str(hkey, szDisplayVersion, buffer);
+ buffer = msi_dup_property(package->db, L"ProductVersion");
+ msi_reg_set_val_str(hkey, L"DisplayVersion", buffer);
if (buffer)
{
DWORD verdword = msi_version_str_to_dword(buffer);
@@ -5332,10 +4958,10 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterProduct);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterProduct");
/* FIXME: also need to publish if the product is in advertise mode */
- if (!msi_get_property_int( package->db, szProductToBeRegistered, 0 )
+ if (!msi_get_property_int( package->db, L"ProductToBeRegistered", 0 )
&& !msi_check_publish(package))
return ERROR_SUCCESS;
@@ -5355,7 +4981,7 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS)
goto done;
- upgrade_code = msi_dup_property(package->db, szUpgradeCode);
+ upgrade_code = msi_dup_property(package->db, L"UpgradeCode");
if (upgrade_code)
{
rc = MSIREG_OpenUpgradeCodesKey( upgrade_code, &upgrade_key, TRUE );
@@ -5408,12 +5034,10 @@ static UINT ITERATE_UnpublishIcon( MSIRECORD *row, LPVOID param )
static UINT msi_unpublish_icons( MSIPACKAGE *package )
{
- static const WCHAR query[]= {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','I','c','o','n','`',0};
MSIQUERY *view;
UINT r;
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Icon`", &view );
if (r == ERROR_SUCCESS)
{
r = MSI_IterateRecords( view, NULL, ITERATE_UnpublishIcon, package );
@@ -5432,7 +5056,7 @@ static void remove_product_upgrade_code( MSIPACKAGE *package )
DWORD count;
squash_guid( package->ProductCode, product );
- if (!(code = msi_dup_property( package->db, szUpgradeCode )))
+ if (!(code = msi_dup_property( package->db, L"UpgradeCode" )))
{
WARN( "upgrade code not found\n" );
return;
@@ -5530,44 +5154,24 @@ static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
UINT ACTION_ForceReboot(MSIPACKAGE *package)
{
- static const WCHAR RunOnce[] = {
- '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','\\',
- 'R','u','n','O','n','c','e',0};
- static const WCHAR InstallRunOnce[] = {
- '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','\\',
- 'R','u','n','O','n','c','e','E','n','t','r','i','e','s',0};
-
- static const WCHAR msiexec_fmt[] = {
- '%','s',
- '\\','M','s','i','E','x','e','c','.','e','x','e',' ','/','@',' ',
- '\"','%','s','\"',0};
- static const WCHAR install_fmt[] = {
- '/','I',' ','\"','%','s','\"',' ',
- 'A','F','T','E','R','R','E','B','O','O','T','=','1',' ',
- 'R','U','N','O','N','C','E','E','N','T','R','Y','=','\"','%','s','\"',0};
WCHAR buffer[256], sysdir[MAX_PATH], squashed_pc[SQUASHED_GUID_SIZE];
HKEY hkey;
squash_guid( package->ProductCode, squashed_pc );
GetSystemDirectoryW(sysdir, ARRAY_SIZE(sysdir));
- RegCreateKeyW(HKEY_LOCAL_MACHINE,RunOnce,&hkey);
- swprintf(buffer, ARRAY_SIZE(buffer), msiexec_fmt, sysdir, squashed_pc);
+ RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", &hkey);
+ swprintf(buffer, ARRAY_SIZE(buffer), L"%s\\MsiExec.exe /@ \"%s\"", sysdir, squashed_pc);
msi_reg_set_val_str( hkey, squashed_pc, buffer );
RegCloseKey(hkey);
TRACE("Reboot command %s\n",debugstr_w(buffer));
- RegCreateKeyW(HKEY_LOCAL_MACHINE,InstallRunOnce,&hkey);
- swprintf( buffer, ARRAY_SIZE(buffer), install_fmt, package->ProductCode, squashed_pc );
+ RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\RunOnceEntries",
+ &hkey);
+ swprintf( buffer, ARRAY_SIZE(buffer), L"/I \"%s\" AFTERREBOOT=1 RUNONCEENTRY=\"%s\"", package->ProductCode,
+ squashed_pc );
msi_reg_set_val_str( hkey, squashed_pc, buffer );
RegCloseKey(hkey);
@@ -5631,29 +5235,27 @@ static UINT ACTION_ResolveSource(MSIPACKAGE* package)
static UINT ACTION_RegisterUser(MSIPACKAGE *package)
{
- HKEY hkey = 0;
- LPWSTR buffer, productid = NULL;
- UINT i, rc = ERROR_SUCCESS;
- MSIRECORD *uirow;
-
- static const WCHAR szPropKeys[][80] =
+ static const WCHAR szPropKeys[][80] =
{
- {'P','r','o','d','u','c','t','I','D',0},
- {'U','S','E','R','N','A','M','E',0},
- {'C','O','M','P','A','N','Y','N','A','M','E',0},
+ L"ProductID",
+ L"USERNAME",
+ L"COMPANYNAME",
{0},
};
-
- static const WCHAR szRegKeys[][80] =
+ static const WCHAR szRegKeys[][80] =
{
- {'P','r','o','d','u','c','t','I','D',0},
- {'R','e','g','O','w','n','e','r',0},
- {'R','e','g','C','o','m','p','a','n','y',0},
+ L"ProductID",
+ L"RegOwner",
+ L"RegCompany",
{0},
};
+ HKEY hkey = 0;
+ LPWSTR buffer, productid = NULL;
+ UINT i, rc = ERROR_SUCCESS;
+ MSIRECORD *uirow;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterUser);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterUser");
if (msi_check_unpublish(package))
{
@@ -5690,13 +5292,11 @@ end:
static UINT iterate_properties(MSIRECORD *record, void *param)
{
- static const WCHAR prop_template[] =
- {'P','r','o','p','e','r','t','y','(','S',')',':',' ','[','1',']',' ','=',' ','[','2',']',0};
MSIRECORD *uirow;
uirow = MSI_CloneRecord(record);
if (!uirow) return ERROR_OUTOFMEMORY;
- MSI_RecordSetStringW(uirow, 0, prop_template);
+ MSI_RecordSetStringW(uirow, 0, L"Property(S): [1] = [2]");
MSI_ProcessMessage(param, INSTALLMESSAGE_INFO|MB_ICONHAND, uirow);
msiobj_release(&uirow->hdr);
@@ -5706,8 +5306,6 @@ static UINT iterate_properties(MSIRECORD *record, void *param)
static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
{
- static const WCHAR prop_query[] =
- {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','_','P','r','o','p','e','r','t','y','`',0};
WCHAR *productname;
WCHAR *action;
WCHAR *info_template;
@@ -5753,15 +5351,15 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
package->LastActionResult = MSI_NULL_INTEGER;
- action = msi_dup_property(package->db, szEXECUTEACTION);
- if (!action) action = msi_strdupW(szINSTALL, lstrlenW(szINSTALL));
+ action = msi_dup_property(package->db, L"EXECUTEACTION");
+ if (!action) action = msi_strdupW(L"INSTALL", ARRAY_SIZE(L"INSTALL") - 1);
/* Perform the action. Top-level actions trigger a sequence. */
- if (!wcscmp(action, szINSTALL))
+ if (!wcscmp(action, L"INSTALL"))
{
/* Send ACTIONSTART/INFO and INSTALLSTART. */
- ui_actionstart(package, szINSTALL, NULL, NULL);
- ui_actioninfo(package, szINSTALL, TRUE, 0);
+ ui_actionstart(package, L"INSTALL", NULL, NULL);
+ ui_actioninfo(package, L"INSTALL", TRUE, 0);
uirow = MSI_CreateRecord(2);
if (!uirow)
{
@@ -5779,7 +5377,7 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
rc = ACTION_ProcessExecSequence(package);
/* Send return value and INSTALLEND. */
- ui_actioninfo(package, szINSTALL, FALSE, !rc);
+ ui_actioninfo(package, L"INSTALL", FALSE, !rc);
uirow = MSI_CreateRecord(3);
if (!uirow)
{
@@ -5797,7 +5395,7 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
rc = ACTION_PerformAction(package, action);
/* Send all set properties. */
- if (!MSI_OpenQuery(package->db, &view, prop_query))
+ if (!MSI_OpenQuery(package->db, &view, L"SELECT * FROM `_Property`"))
{
MSI_IterateRecords(view, NULL, iterate_properties, package);
msiobj_release(&view->hdr);
@@ -5826,7 +5424,7 @@ end:
static UINT ACTION_INSTALL(MSIPACKAGE *package)
{
- msi_set_property(package->db, szEXECUTEACTION, szINSTALL, -1);
+ msi_set_property(package->db, L"EXECUTEACTION", L"INSTALL", -1);
if (needs_ui_sequence(package) && ui_sequence_exists(package))
{
package->InWhatSequence |= SEQUENCE_UI;
@@ -5838,7 +5436,6 @@ static UINT ACTION_INSTALL(MSIPACKAGE *package)
WCHAR *msi_create_component_advertise_string( MSIPACKAGE *package, MSICOMPONENT *component, const WCHAR *feature )
{
- static const WCHAR fmt[] = {'%','s','%','s','%','c','%','s',0};
WCHAR productid_85[21], component_85[21], *ret;
GUID clsid;
DWORD sz;
@@ -5861,7 +5458,7 @@ WCHAR *msi_create_component_advertise_string( MSIPACKAGE *package, MSICOMPONENT
sz = 20 + lstrlenW( feature ) + 20 + 3;
ret = msi_alloc_zero( sz * sizeof(WCHAR) );
- if (ret) swprintf( ret, sz, fmt, productid_85, feature, component ? '>' : '<', component_85 );
+ if (ret) swprintf( ret, sz, L"%s%s%c%s", productid_85, feature, component ? '>' : '<', component_85 );
return ret;
}
@@ -5971,16 +5568,13 @@ end:
*/
static UINT ACTION_PublishComponents(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','`',0};
MSIQUERY *view;
UINT rc;
-
+
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szPublishComponents);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"PublishComponents");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `PublishComponent`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -5991,12 +5585,6 @@ static UINT ACTION_PublishComponents(MSIPACKAGE *package)
static UINT ITERATE_UnpublishComponent( MSIRECORD *rec, LPVOID param )
{
- static const WCHAR szInstallerComponents[] = {
- 'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\',
- 'C','o','m','p','o','n','e','n','t','s','\\',0};
-
MSIPACKAGE *package = param;
LPCWSTR compgroupid, component, feature, qualifier;
MSICOMPONENT *comp;
@@ -6026,7 +5614,7 @@ static UINT ITERATE_UnpublishComponent( MSIRECORD *rec, LPVOID param )
qualifier = MSI_RecordGetString( rec, 2 );
squash_guid( compgroupid, squashed );
- lstrcpyW( keypath, szInstallerComponents );
+ lstrcpyW( keypath, L"Software\\Microsoft\\Installer\\Components\\" );
lstrcatW( keypath, squashed );
res = RegDeleteKeyW( HKEY_CURRENT_USER, keypath );
@@ -6046,16 +5634,13 @@ static UINT ITERATE_UnpublishComponent( MSIRECORD *rec, LPVOID param )
static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szUnpublishComponents);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"UnpublishComponents");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `PublishComponent`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -6066,10 +5651,6 @@ static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
{
- static const WCHAR query[] =
- {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','o','m','p','o','n','e','n','t','`',' ','W','H','E','R','E',' ',
- '`','C','o','m','p','o','n','e','n','t','`',' ','=','\'','%','s','\'',0};
MSIPACKAGE *package = param;
MSICOMPONENT *component;
MSIRECORD *row;
@@ -6126,7 +5707,7 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
err_control &= ~msidbServiceInstallErrorControlVital;
/* fetch the service path */
- row = MSI_QueryGetRecord(package->db, query, comp);
+ row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Component` WHERE `Component` = '%s'", comp);
if (!row)
{
ERR("Query failed\n");
@@ -6156,7 +5737,7 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
}
lstrcpyW(image_path, file->TargetPath);
- lstrcatW(image_path, szSpace);
+ lstrcatW(image_path, L" ");
lstrcatW(image_path, args);
}
service = CreateServiceW(hscm, name, disp, GENERIC_ALL, serv_type,
@@ -6197,16 +5778,13 @@ done:
static UINT ACTION_InstallServices( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'S','e','r','v','i','c','e','I','n','s','t','a','l','l',0};
MSIQUERY *view;
UINT rc;
-
+
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szInstallServices);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"InstallServices");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ServiceInstall`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -6222,10 +5800,8 @@ static LPCWSTR *msi_service_args_to_vector(LPWSTR args, DWORD *numargs)
LPWSTR p, q;
DWORD sep_len;
- static const WCHAR separator[] = {'[','~',']',0};
-
*numargs = 0;
- sep_len = ARRAY_SIZE(separator) - 1;
+ sep_len = ARRAY_SIZE(L"[~]") - 1;
if (!args)
return NULL;
@@ -6240,7 +5816,7 @@ static LPCWSTR *msi_service_args_to_vector(LPWSTR args, DWORD *numargs)
(*numargs)++;
vector[*numargs - 1] = p;
- if ((q = wcsstr(p, separator)))
+ if ((q = wcsstr(p, L"[~]")))
{
*q = '\0';
@@ -6371,16 +5947,13 @@ done:
static UINT ACTION_StartServices( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szStartServices);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"StartServices");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ServiceControl`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -6537,16 +6110,13 @@ done:
static UINT ACTION_StopServices( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szStopServices);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"StopServices");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ServiceControl`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -6623,16 +6193,13 @@ done:
static UINT ACTION_DeleteServices( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szDeleteServices);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"DeleteServices");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ServiceControl`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -6653,13 +6220,6 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
DWORD len, usage;
UINT r = ERROR_SUCCESS;
- static const WCHAR driver_fmt[] = {
- 'D','r','i','v','e','r','=','%','s',0};
- static const WCHAR setup_fmt[] = {
- 'S','e','t','u','p','=','%','s',0};
- static const WCHAR usage_fmt[] = {
- 'F','i','l','e','U','s','a','g','e','=','1',0};
-
component = MSI_RecordGetString( rec, 2 );
comp = msi_get_loaded_component( package, component );
if (!comp)
@@ -6685,10 +6245,10 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
return ERROR_FUNCTION_FAILED;
}
- len = lstrlenW(desc) + lstrlenW(driver_fmt) + lstrlenW(driver_file->FileName);
+ len = lstrlenW(desc) + lstrlenW(L"Driver=%s") + lstrlenW(driver_file->FileName);
if (setup_file)
- len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);
- len += lstrlenW(usage_fmt) + 2; /* \0\0 */
+ len += lstrlenW(L"Setup=%s") + lstrlenW(setup_file->FileName);
+ len += lstrlenW(L"FileUsage=1") + 2; /* \0\0 */
driver = msi_alloc(len * sizeof(WCHAR));
if (!driver)
@@ -6698,16 +6258,16 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
lstrcpyW(ptr, desc);
ptr += lstrlenW(ptr) + 1;
- len = swprintf(ptr, len - (ptr - driver), driver_fmt, driver_file->FileName);
+ len = swprintf(ptr, len - (ptr - driver), L"Driver=%s", driver_file->FileName);
ptr += len + 1;
if (setup_file)
{
- len = swprintf(ptr, len - (ptr - driver), setup_fmt, setup_file->FileName);
+ len = swprintf(ptr, len - (ptr - driver), L"Setup=%s", setup_file->FileName);
ptr += len + 1;
}
- lstrcpyW(ptr, usage_fmt);
+ lstrcpyW(ptr, L"FileUsage=1");
ptr += lstrlenW(ptr) + 1;
*ptr = '\0';
@@ -6752,11 +6312,6 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
DWORD len, usage;
UINT r = ERROR_SUCCESS;
- static const WCHAR translator_fmt[] = {
- 'T','r','a','n','s','l','a','t','o','r','=','%','s',0};
- static const WCHAR setup_fmt[] = {
- 'S','e','t','u','p','=','%','s',0};
-
component = MSI_RecordGetString( rec, 2 );
comp = msi_get_loaded_component( package, component );
if (!comp)
@@ -6782,9 +6337,9 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
return ERROR_FUNCTION_FAILED;
}
- len = lstrlenW(desc) + lstrlenW(translator_fmt) + lstrlenW(translator_file->FileName) + 2; /* \0\0 */
+ len = lstrlenW(desc) + lstrlenW(L"Translator=%s") + lstrlenW(translator_file->FileName) + 2; /* \0\0 */
if (setup_file)
- len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);
+ len += lstrlenW(L"Setup=%s") + lstrlenW(setup_file->FileName);
translator = msi_alloc(len * sizeof(WCHAR));
if (!translator)
@@ -6794,12 +6349,12 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
lstrcpyW(ptr, desc);
ptr += lstrlenW(ptr) + 1;
- len = swprintf(ptr, len - (ptr - translator), translator_fmt, translator_file->FileName);
+ len = swprintf(ptr, len - (ptr - translator), L"Translator=%s", translator_file->FileName);
ptr += len + 1;
if (setup_file)
{
- len = swprintf(ptr, len - (ptr - translator), setup_fmt, setup_file->FileName);
+ len = swprintf(ptr, len - (ptr - translator), L"Setup=%s", setup_file->FileName);
ptr += len + 1;
}
*ptr = '\0';
@@ -6840,9 +6395,6 @@ static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param )
UINT r = ERROR_SUCCESS;
MSIRECORD *uirow;
- static const WCHAR attrs_fmt[] = {
- 'D','S','N','=','%','s',0 };
-
component = MSI_RecordGetString( rec, 2 );
comp = msi_get_loaded_component( package, component );
if (!comp)
@@ -6862,12 +6414,12 @@ static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param )
if (registration == msidbODBCDataSourceRegistrationPerMachine) request = ODBC_ADD_SYS_DSN;
else if (registration == msidbODBCDataSourceRegistrationPerUser) request = ODBC_ADD_DSN;
- len = lstrlenW(attrs_fmt) + lstrlenW(desc) + 2; /* \0\0 */
+ len = lstrlenW(L"DSN=%s") + lstrlenW(desc) + 2; /* \0\0 */
attrs = msi_alloc(len * sizeof(WCHAR));
if (!attrs)
return ERROR_OUTOFMEMORY;
- len = swprintf(attrs, len, attrs_fmt, desc);
+ len = swprintf(attrs, len, L"DSN=%s", desc);
attrs[len + 1] = 0;
if (!SQLConfigDataSourceW(NULL, request, driver, attrs))
@@ -6887,22 +6439,13 @@ static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param )
static UINT ACTION_InstallODBC( MSIPACKAGE *package )
{
- static const WCHAR driver_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','D','r','i','v','e','r',0};
- static const WCHAR translator_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0};
- static const WCHAR source_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','D','a','t','a','S','o','u','r','c','e',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szInstallODBC);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"InstallODBC");
- rc = MSI_DatabaseOpenViewW(package->db, driver_query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ODBCDriver`", &view);
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCDriver, package);
@@ -6910,7 +6453,7 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package )
if (rc != ERROR_SUCCESS)
return rc;
}
- rc = MSI_DatabaseOpenViewW(package->db, translator_query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ODBCTranslator`", &view);
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCTranslator, package);
@@ -6918,7 +6461,7 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package )
if (rc != ERROR_SUCCESS)
return rc;
}
- rc = MSI_DatabaseOpenViewW(package->db, source_query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ODBCDataSource`", &view);
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCDataSource, package);
@@ -7018,9 +6561,6 @@ static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param )
INT registration;
DWORD len;
- static const WCHAR attrs_fmt[] = {
- 'D','S','N','=','%','s',0 };
-
component = MSI_RecordGetString( rec, 2 );
comp = msi_get_loaded_component( package, component );
if (!comp)
@@ -7040,14 +6580,14 @@ static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param )
if (registration == msidbODBCDataSourceRegistrationPerMachine) request = ODBC_REMOVE_SYS_DSN;
else if (registration == msidbODBCDataSourceRegistrationPerUser) request = ODBC_REMOVE_DSN;
- len = lstrlenW( attrs_fmt ) + lstrlenW( desc ) + 2; /* \0\0 */
+ len = lstrlenW( L"DSN=%s" ) + lstrlenW( desc ) + 2; /* \0\0 */
attrs = msi_alloc( len * sizeof(WCHAR) );
if (!attrs)
return ERROR_OUTOFMEMORY;
FIXME("Use ODBCSourceAttribute table\n");
- len = swprintf( attrs, len, attrs_fmt, desc );
+ len = swprintf( attrs, len, L"DSN=%s", desc );
attrs[len + 1] = 0;
if (!SQLConfigDataSourceW( NULL, request, driver, attrs ))
@@ -7068,22 +6608,13 @@ static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param )
static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
{
- static const WCHAR driver_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','D','r','i','v','e','r',0};
- static const WCHAR translator_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0};
- static const WCHAR source_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','D','a','t','a','S','o','u','r','c','e',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveODBC);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveODBC");
- rc = MSI_DatabaseOpenViewW( package->db, driver_query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCDriver`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDriver, package );
@@ -7091,7 +6622,7 @@ static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
if (rc != ERROR_SUCCESS)
return rc;
}
- rc = MSI_DatabaseOpenViewW( package->db, translator_query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCTranslator`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCTranslator, package );
@@ -7099,7 +6630,7 @@ static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
if (rc != ERROR_SUCCESS)
return rc;
}
- rc = MSI_DatabaseOpenViewW( package->db, source_query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCDataSource`", &view );
if (rc == ERROR_SUCCESS)
{
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDataSource, package );
@@ -7124,10 +6655,7 @@ static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
static UINT env_parse_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
{
- LPCWSTR cptr = *name;
-
- static const WCHAR prefix[] = {'[','~',']',0};
- static const int prefix_len = 3;
+ const WCHAR *cptr = *name;
*flags = 0;
while (*cptr)
@@ -7158,24 +6686,24 @@ static UINT env_parse_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
if (*value)
{
LPCWSTR ptr = *value;
- if (!wcsncmp(ptr, prefix, prefix_len))
+ if (!wcsncmp(ptr, L"[~]", 3))
{
- if (ptr[prefix_len] == szSemiColon[0])
+ if (ptr[3] == ';')
{
*flags |= ENV_MOD_APPEND;
- *value += lstrlenW(prefix);
+ *value += 3;
}
else
{
*value = NULL;
}
}
- else if (lstrlenW(*value) >= prefix_len)
+ else if (lstrlenW(*value) >= 3)
{
- ptr += lstrlenW(ptr) - prefix_len;
- if (!wcscmp( ptr, prefix ))
+ ptr += lstrlenW(ptr) - 3;
+ if (!wcscmp( ptr, L"[~]" ))
{
- if ((ptr-1) > *value && *(ptr-1) == szSemiColon[0])
+ if ((ptr-1) > *value && *(ptr-1) == ';')
{
*flags |= ENV_MOD_PREFIX;
/* the "[~]" will be removed by deformat_string */;
@@ -7205,26 +6733,18 @@ static UINT env_parse_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
static UINT open_env_key( DWORD flags, HKEY *key )
{
- static const WCHAR user_env[] =
- {'E','n','v','i','r','o','n','m','e','n','t',0};
- static const WCHAR machine_env[] =
- {'S','y','s','t','e','m','\\',
- 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'C','o','n','t','r','o','l','\\',
- 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
- 'E','n','v','i','r','o','n','m','e','n','t',0};
const WCHAR *env;
HKEY root;
LONG res;
if (flags & ENV_MOD_MACHINE)
{
- env = machine_env;
+ env = L"System\\CurrentControlSet\\Control\\Session Manager\\Environment";
root = HKEY_LOCAL_MACHINE;
}
else
{
- env = user_env;
+ env = L"Environment";
root = HKEY_CURRENT_USER;
}
@@ -7423,16 +6943,13 @@ done:
static UINT ACTION_WriteEnvironmentStrings( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','E','n','v','i','r','o','n','m','e','n','t','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szWriteEnvironmentStrings);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"WriteEnvironmentStrings");
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Environment`", &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -7568,16 +7085,13 @@ done:
static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','E','n','v','i','r','o','n','m','e','n','t','`',0};
MSIQUERY *view;
UINT rc;
if (package->script == SCRIPT_NONE)
- return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveEnvironmentStrings);
+ return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveEnvironmentStrings");
- rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Environment`", &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
@@ -7591,18 +7105,18 @@ UINT msi_validate_product_id( MSIPACKAGE *package )
LPWSTR key, template, id;
UINT r = ERROR_SUCCESS;
- id = msi_dup_property( package->db, szProductID );
+ id = msi_dup_property( package->db, L"ProductID" );
if (id)
{
msi_free( id );
return ERROR_SUCCESS;
}
- template = msi_dup_property( package->db, szPIDTemplate );
- key = msi_dup_property( package->db, szPIDKEY );
+ template = msi_dup_property( package->db, L"PIDTemplate" );
+ key = msi_dup_property( package->db, L"PIDKEY" );
if (key && template)
{
FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) );
- r = msi_set_property( package->db, szProductID, key, -1 );
+ r = msi_set_property( package->db, L"ProductID", key, -1 );
}
msi_free( template );
msi_free( key );
@@ -7623,10 +7137,8 @@ static UINT ACTION_ScheduleReboot( MSIPACKAGE *package )
static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package )
{
- static const WCHAR szAvailableFreeReg[] =
- {'A','V','A','I','L','A','B','L','E','F','R','E','E','R','E','G',0};
MSIRECORD *uirow;
- int space = msi_get_property_int( package->db, szAvailableFreeReg, 0 );
+ int space = msi_get_property_int( package->db, L"AVAILABLEFREEREG", 0 );
TRACE("%p %d kilobytes\n", package, space);
@@ -7642,7 +7154,7 @@ static UINT ACTION_DisableRollback( MSIPACKAGE *package )
{
TRACE("%p\n", package);
- msi_set_property( package->db, szRollbackDisabled, szOne, -1 );
+ msi_set_property( package->db, L"RollbackDisabled", L"1", -1 );
return ERROR_SUCCESS;
}
@@ -7654,16 +7166,10 @@ static UINT ACTION_InstallAdminPackage( MSIPACKAGE *package )
static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
{
- static const WCHAR driver_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','D','r','i','v','e','r',0};
- static const WCHAR translator_query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0};
MSIQUERY *view;
UINT r, count;
- r = MSI_DatabaseOpenViewW( package->db, driver_query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCDriver`", &view );
if (r == ERROR_SUCCESS)
{
count = 0;
@@ -7673,7 +7179,7 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
return r;
if (count) FIXME("ignored %u rows in ODBCDriver table\n", count);
}
- r = MSI_DatabaseOpenViewW( package->db, translator_query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCTranslator`", &view );
if (r == ERROR_SUCCESS)
{
count = 0;
@@ -7688,13 +7194,10 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param )
{
- static const WCHAR fmtW[] =
- {'m','s','i','e','x','e','c',' ','/','q','n',' ','/','i',' ','%','s',' ',
- 'R','E','M','O','V','E','=','%','s',0};
MSIPACKAGE *package = param;
const WCHAR *property = MSI_RecordGetString( rec, 7 );
int attrs = MSI_RecordGetInteger( rec, 5 );
- UINT len = ARRAY_SIZE( fmtW );
+ UINT len = ARRAY_SIZE( L"msiexec /qn /i %s REMOVE=%s" );
WCHAR *product, *features, *cmd;
STARTUPINFOW si;
PROCESS_INFORMATION info;
@@ -7709,7 +7212,7 @@ static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param )
if (features)
len += lstrlenW( features );
else
- len += ARRAY_SIZE( szAll );
+ len += ARRAY_SIZE( L"ALL" );
if (!(cmd = msi_alloc( len * sizeof(WCHAR) )))
{
@@ -7717,7 +7220,7 @@ static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param )
msi_free( features );
return ERROR_OUTOFMEMORY;
}
- swprintf( cmd, len, fmtW, product, features ? features : szAll );
+ swprintf( cmd, len, L"msiexec /qn /i %s REMOVE=%s", product, features ? features : L"ALL" );
msi_free( product );
msi_free( features );
@@ -7734,12 +7237,10 @@ static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param )
static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','U','p','g','r','a','d','e',0};
MSIQUERY *view;
UINT r;
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Upgrade`", &view );
if (r == ERROR_SUCCESS)
{
r = MSI_IterateRecords( view, NULL, ITERATE_RemoveExistingProducts, package );
@@ -7787,23 +7288,20 @@ static UINT ITERATE_MigrateFeatureStates( MSIRECORD *rec, LPVOID param )
static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'U','p','g','r','a','d','e',0};
MSIQUERY *view;
UINT r;
- if (msi_get_property_int( package->db, szInstalled, 0 ))
+ if (msi_get_property_int( package->db, L"Installed", 0 ))
{
TRACE("product is installed, skipping action\n");
return ERROR_SUCCESS;
}
- if (msi_get_property_int( package->db, szPreselected, 0 ))
+ if (msi_get_property_int( package->db, L"Preselected", 0 ))
{
TRACE("Preselected property is set, not migrating feature states\n");
return ERROR_SUCCESS;
}
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Upgrade`", &view );
if (r == ERROR_SUCCESS)
{
r = MSI_IterateRecords( view, NULL, ITERATE_MigrateFeatureStates, package );
@@ -7871,13 +7369,10 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param )
static UINT ACTION_BindImage( MSIPACKAGE *package )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'B','i','n','d','I','m','a','g','e',0};
MSIQUERY *view;
UINT r;
- r = MSI_DatabaseOpenViewW( package->db, query, &view );
+ r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `BindImage`", &view );
if (r == ERROR_SUCCESS)
{
MSI_IterateRecords( view, NULL, ITERATE_BindImage, package );
@@ -7888,13 +7383,11 @@ static UINT ACTION_BindImage( MSIPACKAGE *package )
static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table )
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','%','s','`',0};
MSIQUERY *view;
DWORD count = 0;
UINT r;
-
- r = MSI_OpenQuery( package->db, &view, query, table );
+
+ r = MSI_OpenQuery( package->db, &view, L"SELECT * FROM `%s`", table );
if (r == ERROR_SUCCESS)
{
r = MSI_IterateRecords(view, &count, NULL, package);
@@ -7908,33 +7401,27 @@ static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, L
static UINT ACTION_IsolateComponents( MSIPACKAGE *package )
{
- static const WCHAR table[] = {
- 'I','s','o','l','a','t','e','d','C','o','m','p','o','n','e','n','t',0 };
- return msi_unimplemented_action_stub( package, "IsolateComponents", table );
+ return msi_unimplemented_action_stub( package, "IsolateComponents", L"IsolateComponent" );
}
static UINT ACTION_RMCCPSearch( MSIPACKAGE *package )
{
- static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 };
- return msi_unimplemented_action_stub( package, "RMCCPSearch", table );
+ return msi_unimplemented_action_stub( package, "RMCCPSearch", L"CCPSearch" );
}
static UINT ACTION_RegisterComPlus( MSIPACKAGE *package )
{
- static const WCHAR table[] = { 'C','o','m','p','l','u','s',0 };
- return msi_unimplemented_action_stub( package, "RegisterComPlus", table );
+ return msi_unimplemented_action_stub( package, "RegisterComPlus", L"Complus" );
}
static UINT ACTION_UnregisterComPlus( MSIPACKAGE *package )
{
- static const WCHAR table[] = { 'C','o','m','p','l','u','s',0 };
- return msi_unimplemented_action_stub( package, "UnregisterComPlus", table );
+ return msi_unimplemented_action_stub( package, "UnregisterComPlus", L"Complus" );
}
static UINT ACTION_InstallSFPCatalogFile( MSIPACKAGE *package )
{
- static const WCHAR table[] = { 'S','F','P','C','a','t','a','l','o','g',0 };
- return msi_unimplemented_action_stub( package, "InstallSFPCatalogFile", table );
+ return msi_unimplemented_action_stub( package, "InstallSFPCatalogFile", L"SFPCatalog" );
}
static const struct
@@ -7947,83 +7434,83 @@ static const struct
}
StandardActions[] =
{
- { szAllocateRegistrySpace, IDS_DESC_ALLOCATEREGISTRYSPACE, IDS_TEMP_ALLOCATEREGISTRYSPACE, ACTION_AllocateRegistrySpace, NULL },
- { szAppSearch, IDS_DESC_APPSEARCH, IDS_TEMP_APPSEARCH, ACTION_AppSearch, NULL },
- { szBindImage, IDS_DESC_BINDIMAGE, IDS_TEMP_BINDIMAGE, ACTION_BindImage, NULL },
- { szCCPSearch, IDS_DESC_CCPSEARCH, 0, ACTION_CCPSearch, NULL },
- { szCostFinalize, IDS_DESC_COSTFINALIZE, 0, ACTION_CostFinalize, NULL },
- { szCostInitialize, IDS_DESC_COSTINITIALIZE, 0, ACTION_CostInitialize, NULL },
- { szCreateFolders, IDS_DESC_CREATEFOLDERS, IDS_TEMP_CREATEFOLDERS, ACTION_CreateFolders, szRemoveFolders },
- { szCreateShortcuts, IDS_DESC_CREATESHORTCUTS, IDS_TEMP_CREATESHORTCUTS, ACTION_CreateShortcuts, szRemoveShortcuts },
- { szDeleteServices, IDS_DESC_DELETESERVICES, IDS_TEMP_DELETESERVICES, ACTION_DeleteServices, szInstallServices },
- { szDisableRollback, 0, 0, ACTION_DisableRollback, NULL },
- { szDuplicateFiles, IDS_DESC_DUPLICATEFILES, IDS_TEMP_DUPLICATEFILES, ACTION_DuplicateFiles, szRemoveDuplicateFiles },
- { szExecuteAction, 0, 0, ACTION_ExecuteAction, NULL },
- { szFileCost, IDS_DESC_FILECOST, 0, ACTION_FileCost, NULL },
- { szFindRelatedProducts, IDS_DESC_FINDRELATEDPRODUCTS, IDS_TEMP_FINDRELATEDPRODUCTS, ACTION_FindRelatedProducts, NULL },
- { szForceReboot, 0, 0, ACTION_ForceReboot, NULL },
- { szInstallAdminPackage, IDS_DESC_INSTALLADMINPACKAGE, IDS_TEMP_INSTALLADMINPACKAGE, ACTION_InstallAdminPackage, NULL },
- { szInstallExecute, 0, 0, ACTION_InstallExecute, NULL },
- { szInstallExecuteAgain, 0, 0, ACTION_InstallExecute, NULL },
- { szInstallFiles, IDS_DESC_INSTALLFILES, IDS_TEMP_INSTALLFILES, ACTION_InstallFiles, szRemoveFiles },
- { szInstallFinalize, 0, 0, ACTION_InstallFinalize, NULL },
- { szInstallInitialize, 0, 0, ACTION_InstallInitialize, NULL },
- { szInstallODBC, IDS_DESC_INSTALLODBC, 0, ACTION_InstallODBC, szRemoveODBC },
- { szInstallServices, IDS_DESC_INSTALLSERVICES, IDS_TEMP_INSTALLSERVICES, ACTION_InstallServices, szDeleteServices },
- { szInstallSFPCatalogFile, IDS_DESC_INSTALLSFPCATALOGFILE, IDS_TEMP_INSTALLSFPCATALOGFILE, ACTION_InstallSFPCatalogFile, NULL },
- { szInstallValidate, IDS_DESC_INSTALLVALIDATE, 0, ACTION_InstallValidate, NULL },
- { szIsolateComponents, 0, 0, ACTION_IsolateComponents, NULL },
- { szLaunchConditions, IDS_DESC_LAUNCHCONDITIONS, 0, ACTION_LaunchConditions, NULL },
- { szMigrateFeatureStates, IDS_DESC_MIGRATEFEATURESTATES, IDS_TEMP_MIGRATEFEATURESTATES, ACTION_MigrateFeatureStates, NULL },
- { szMoveFiles, IDS_DESC_MOVEFILES, IDS_TEMP_MOVEFILES, ACTION_MoveFiles, NULL },
- { szMsiPublishAssemblies, IDS_DESC_MSIPUBLISHASSEMBLIES, IDS_TEMP_MSIPUBLISHASSEMBLIES, ACTION_MsiPublishAssemblies, szMsiUnpublishAssemblies },
- { szMsiUnpublishAssemblies, IDS_DESC_MSIUNPUBLISHASSEMBLIES, IDS_TEMP_MSIUNPUBLISHASSEMBLIES, ACTION_MsiUnpublishAssemblies, szMsiPublishAssemblies },
- { szPatchFiles, IDS_DESC_PATCHFILES, IDS_TEMP_PATCHFILES, ACTION_PatchFiles, NULL },
- { szProcessComponents, IDS_DESC_PROCESSCOMPONENTS, 0, ACTION_ProcessComponents, szProcessComponents },
- { szPublishComponents, IDS_DESC_PUBLISHCOMPONENTS, IDS_TEMP_PUBLISHCOMPONENTS, ACTION_PublishComponents, szUnpublishComponents },
- { szPublishFeatures, IDS_DESC_PUBLISHFEATURES, IDS_TEMP_PUBLISHFEATURES, ACTION_PublishFeatures, szUnpublishFeatures },
- { szPublishProduct, IDS_DESC_PUBLISHPRODUCT, 0, ACTION_PublishProduct, szUnpublishProduct },
- { szRegisterClassInfo, IDS_DESC_REGISTERCLASSINFO, IDS_TEMP_REGISTERCLASSINFO, ACTION_RegisterClassInfo, szUnregisterClassInfo },
- { szRegisterComPlus, IDS_DESC_REGISTERCOMPLUS, IDS_TEMP_REGISTERCOMPLUS, ACTION_RegisterComPlus, szUnregisterComPlus },
- { szRegisterExtensionInfo, IDS_DESC_REGISTEREXTENSIONINFO, 0, ACTION_RegisterExtensionInfo, szUnregisterExtensionInfo },
- { szRegisterFonts, IDS_DESC_REGISTERFONTS, IDS_TEMP_REGISTERFONTS, ACTION_RegisterFonts, szUnregisterFonts },
- { szRegisterMIMEInfo, IDS_DESC_REGISTERMIMEINFO, IDS_TEMP_REGISTERMIMEINFO, ACTION_RegisterMIMEInfo, szUnregisterMIMEInfo },
- { szRegisterProduct, IDS_DESC_REGISTERPRODUCT, 0, ACTION_RegisterProduct, NULL },
- { szRegisterProgIdInfo, IDS_DESC_REGISTERPROGIDINFO, IDS_TEMP_REGISTERPROGIDINFO, ACTION_RegisterProgIdInfo, szUnregisterProgIdInfo },
- { szRegisterTypeLibraries, IDS_DESC_REGISTERTYPELIBRARIES, IDS_TEMP_REGISTERTYPELIBRARIES, ACTION_RegisterTypeLibraries, szUnregisterTypeLibraries },
- { szRegisterUser, IDS_DESC_REGISTERUSER, 0, ACTION_RegisterUser, NULL },
- { szRemoveDuplicateFiles, IDS_DESC_REMOVEDUPLICATEFILES, IDS_TEMP_REMOVEDUPLICATEFILES, ACTION_RemoveDuplicateFiles, szDuplicateFiles },
- { szRemoveEnvironmentStrings, IDS_DESC_REMOVEENVIRONMENTSTRINGS, IDS_TEMP_REMOVEENVIRONMENTSTRINGS, ACTION_RemoveEnvironmentStrings, szWriteEnvironmentStrings },
- { szRemoveExistingProducts, IDS_DESC_REMOVEEXISTINGPRODUCTS, IDS_TEMP_REMOVEEXISTINGPRODUCTS, ACTION_RemoveExistingProducts, NULL },
- { szRemoveFiles, IDS_DESC_REMOVEFILES, IDS_TEMP_REMOVEFILES, ACTION_RemoveFiles, szInstallFiles },
- { szRemoveFolders, IDS_DESC_REMOVEFOLDERS, IDS_TEMP_REMOVEFOLDERS, ACTION_RemoveFolders, szCreateFolders },
- { szRemoveIniValues, IDS_DESC_REMOVEINIVALUES, IDS_TEMP_REMOVEINIVALUES, ACTION_RemoveIniValues, szWriteIniValues },
- { szRemoveODBC, IDS_DESC_REMOVEODBC, 0, ACTION_RemoveODBC, szInstallODBC },
- { szRemoveRegistryValues, IDS_DESC_REMOVEREGISTRYVALUES, IDS_TEMP_REMOVEREGISTRYVALUES, ACTION_RemoveRegistryValues, szWriteRegistryValues },
- { szRemoveShortcuts, IDS_DESC_REMOVESHORTCUTS, IDS_TEMP_REMOVESHORTCUTS, ACTION_RemoveShortcuts, szCreateShortcuts },
- { szResolveSource, 0, 0, ACTION_ResolveSource, NULL },
- { szRMCCPSearch, IDS_DESC_RMCCPSEARCH, 0, ACTION_RMCCPSearch, NULL },
- { szScheduleReboot, 0, 0, ACTION_ScheduleReboot, NULL },
- { szSelfRegModules, IDS_DESC_SELFREGMODULES, IDS_TEMP_SELFREGMODULES, ACTION_SelfRegModules, szSelfUnregModules },
- { szSelfUnregModules, IDS_DESC_SELFUNREGMODULES, IDS_TEMP_SELFUNREGMODULES, ACTION_SelfUnregModules, szSelfRegModules },
- { szSetODBCFolders, IDS_DESC_SETODBCFOLDERS, 0, ACTION_SetODBCFolders, NULL },
- { szStartServices, IDS_DESC_STARTSERVICES, IDS_TEMP_STARTSERVICES, ACTION_StartServices, szStopServices },
- { szStopServices, IDS_DESC_STOPSERVICES, IDS_TEMP_STOPSERVICES, ACTION_StopServices, szStartServices },
- { szUnpublishComponents, IDS_DESC_UNPUBLISHCOMPONENTS, IDS_TEMP_UNPUBLISHCOMPONENTS, ACTION_UnpublishComponents, szPublishComponents },
- { szUnpublishFeatures, IDS_DESC_UNPUBLISHFEATURES, IDS_TEMP_UNPUBLISHFEATURES, ACTION_UnpublishFeatures, szPublishFeatures },
- { szUnpublishProduct, IDS_DESC_UNPUBLISHPRODUCT, 0, ACTION_UnpublishProduct, NULL }, /* for rollback only */
- { szUnregisterClassInfo, IDS_DESC_UNREGISTERCLASSINFO, IDS_TEMP_UNREGISTERCLASSINFO, ACTION_UnregisterClassInfo, szRegisterClassInfo },
- { szUnregisterComPlus, IDS_DESC_UNREGISTERCOMPLUS, IDS_TEMP_UNREGISTERCOMPLUS, ACTION_UnregisterComPlus, szRegisterComPlus },
- { szUnregisterExtensionInfo, IDS_DESC_UNREGISTEREXTENSIONINFO, IDS_TEMP_UNREGISTEREXTENSIONINFO, ACTION_UnregisterExtensionInfo, szRegisterExtensionInfo },
- { szUnregisterFonts, IDS_DESC_UNREGISTERFONTS, IDS_TEMP_UNREGISTERFONTS, ACTION_UnregisterFonts, szRegisterFonts },
- { szUnregisterMIMEInfo, IDS_DESC_UNREGISTERMIMEINFO, IDS_TEMP_UNREGISTERMIMEINFO, ACTION_UnregisterMIMEInfo, szRegisterMIMEInfo },
- { szUnregisterProgIdInfo, IDS_DESC_UNREGISTERPROGIDINFO, IDS_TEMP_UNREGISTERPROGIDINFO, ACTION_UnregisterProgIdInfo, szRegisterProgIdInfo },
- { szUnregisterTypeLibraries, IDS_DESC_UNREGISTERTYPELIBRARIES, IDS_TEMP_UNREGISTERTYPELIBRARIES, ACTION_UnregisterTypeLibraries, szRegisterTypeLibraries },
- { szValidateProductID, 0, 0, ACTION_ValidateProductID, NULL },
- { szWriteEnvironmentStrings, IDS_DESC_WRITEENVIRONMENTSTRINGS, IDS_TEMP_WRITEENVIRONMENTSTRINGS, ACTION_WriteEnvironmentStrings, szRemoveEnvironmentStrings },
- { szWriteIniValues, IDS_DESC_WRITEINIVALUES, IDS_TEMP_WRITEINIVALUES, ACTION_WriteIniValues, szRemoveIniValues },
- { szWriteRegistryValues, IDS_DESC_WRITEREGISTRYVALUES, IDS_TEMP_WRITEREGISTRYVALUES, ACTION_WriteRegistryValues, szRemoveRegistryValues },
- { szINSTALL, 0, 0, ACTION_INSTALL, NULL },
+ { L"AllocateRegistrySpace", IDS_DESC_ALLOCATEREGISTRYSPACE, IDS_TEMP_ALLOCATEREGISTRYSPACE, ACTION_AllocateRegistrySpace, NULL },
+ { L"AppSearch", IDS_DESC_APPSEARCH, IDS_TEMP_APPSEARCH, ACTION_AppSearch, NULL },
+ { L"BindImage", IDS_DESC_BINDIMAGE, IDS_TEMP_BINDIMAGE, ACTION_BindImage, NULL },
+ { L"CCPSearch", IDS_DESC_CCPSEARCH, 0, ACTION_CCPSearch, NULL },
+ { L"CostFinalize", IDS_DESC_COSTFINALIZE, 0, ACTION_CostFinalize, NULL },
+ { L"CostInitialize", IDS_DESC_COSTINITIALIZE, 0, ACTION_CostInitialize, NULL },
+ { L"CreateFolders", IDS_DESC_CREATEFOLDERS, IDS_TEMP_CREATEFOLDERS, ACTION_CreateFolders, L"RemoveFolders" },
+ { L"CreateShortcuts", IDS_DESC_CREATESHORTCUTS, IDS_TEMP_CREATESHORTCUTS, ACTION_CreateShortcuts, L"RemoveShortcuts" },
+ { L"DeleteServices", IDS_DESC_DELETESERVICES, IDS_TEMP_DELETESERVICES, ACTION_DeleteServices, L"InstallServices" },
+ { L"DisableRollback", 0, 0, ACTION_DisableRollback, NULL },
+ { L"DuplicateFiles", IDS_DESC_DUPLICATEFILES, IDS_TEMP_DUPLICATEFILES, ACTION_DuplicateFiles, L"RemoveDuplicateFiles" },
+ { L"ExecuteAction", 0, 0, ACTION_ExecuteAction, NULL },
+ { L"FileCost", IDS_DESC_FILECOST, 0, ACTION_FileCost, NULL },
+ { L"FindRelatedProducts", IDS_DESC_FINDRELATEDPRODUCTS, IDS_TEMP_FINDRELATEDPRODUCTS, ACTION_FindRelatedProducts, NULL },
+ { L"ForceReboot", 0, 0, ACTION_ForceReboot, NULL },
+ { L"InstallAdminPackage", IDS_DESC_INSTALLADMINPACKAGE, IDS_TEMP_INSTALLADMINPACKAGE, ACTION_InstallAdminPackage, NULL },
+ { L"InstallExecute", 0, 0, ACTION_InstallExecute, NULL },
+ { L"InstallExecuteAgain", 0, 0, ACTION_InstallExecute, NULL },
+ { L"InstallFiles", IDS_DESC_INSTALLFILES, IDS_TEMP_INSTALLFILES, ACTION_InstallFiles, L"RemoveFiles" },
+ { L"InstallFinalize", 0, 0, ACTION_InstallFinalize, NULL },
+ { L"InstallInitialize", 0, 0, ACTION_InstallInitialize, NULL },
+ { L"InstallODBC", IDS_DESC_INSTALLODBC, 0, ACTION_InstallODBC, L"RemoveODBC" },
+ { L"InstallServices", IDS_DESC_INSTALLSERVICES, IDS_TEMP_INSTALLSERVICES, ACTION_InstallServices, L"DeleteServices" },
+ { L"InstallSFPCatalogFile", IDS_DESC_INSTALLSFPCATALOGFILE, IDS_TEMP_INSTALLSFPCATALOGFILE, ACTION_InstallSFPCatalogFile, NULL },
+ { L"InstallValidate", IDS_DESC_INSTALLVALIDATE, 0, ACTION_InstallValidate, NULL },
+ { L"IsolateComponents", 0, 0, ACTION_IsolateComponents, NULL },
+ { L"LaunchConditions", IDS_DESC_LAUNCHCONDITIONS, 0, ACTION_LaunchConditions, NULL },
+ { L"MigrateFeutureStates", IDS_DESC_MIGRATEFEATURESTATES, IDS_TEMP_MIGRATEFEATURESTATES, ACTION_MigrateFeatureStates, NULL },
+ { L"MoveFiles", IDS_DESC_MOVEFILES, IDS_TEMP_MOVEFILES, ACTION_MoveFiles, NULL },
+ { L"MsiPublishAssemblies", IDS_DESC_MSIPUBLISHASSEMBLIES, IDS_TEMP_MSIPUBLISHASSEMBLIES, ACTION_MsiPublishAssemblies, L"MsiUnpublishAssemblies" },
+ { L"MsiUnpublishAssemblies", IDS_DESC_MSIUNPUBLISHASSEMBLIES, IDS_TEMP_MSIUNPUBLISHASSEMBLIES, ACTION_MsiUnpublishAssemblies, L"MsiPublishAssemblies" },
+ { L"PatchFiles", IDS_DESC_PATCHFILES, IDS_TEMP_PATCHFILES, ACTION_PatchFiles, NULL },
+ { L"ProcessComponents", IDS_DESC_PROCESSCOMPONENTS, 0, ACTION_ProcessComponents, L"ProcessComponents" },
+ { L"PublishComponents", IDS_DESC_PUBLISHCOMPONENTS, IDS_TEMP_PUBLISHCOMPONENTS, ACTION_PublishComponents, L"UnpublishComponents" },
+ { L"PublishFeatures", IDS_DESC_PUBLISHFEATURES, IDS_TEMP_PUBLISHFEATURES, ACTION_PublishFeatures, L"UnpublishFeatures" },
+ { L"PublishProduct", IDS_DESC_PUBLISHPRODUCT, 0, ACTION_PublishProduct, L"UnpublishProduct" },
+ { L"RegisterClassInfo", IDS_DESC_REGISTERCLASSINFO, IDS_TEMP_REGISTERCLASSINFO, ACTION_RegisterClassInfo, L"UnregisterClassInfo" },
+ { L"RegisterComPlus", IDS_DESC_REGISTERCOMPLUS, IDS_TEMP_REGISTERCOMPLUS, ACTION_RegisterComPlus, L"UnregisterComPlus" },
+ { L"RegisterExtensionInfo", IDS_DESC_REGISTEREXTENSIONINFO, 0, ACTION_RegisterExtensionInfo, L"UnregisterExtensionInfo" },
+ { L"RegisterFonts", IDS_DESC_REGISTERFONTS, IDS_TEMP_REGISTERFONTS, ACTION_RegisterFonts, L"UnregisterFonts" },
+ { L"RegisterMIMEInfo", IDS_DESC_REGISTERMIMEINFO, IDS_TEMP_REGISTERMIMEINFO, ACTION_RegisterMIMEInfo, L"UnregisterMIMEInfo" },
+ { L"RegisterProduct", IDS_DESC_REGISTERPRODUCT, 0, ACTION_RegisterProduct, NULL },
+ { L"RegisterProgIdInfo", IDS_DESC_REGISTERPROGIDINFO, IDS_TEMP_REGISTERPROGIDINFO, ACTION_RegisterProgIdInfo, L"UnregisterProgIdInfo" },
+ { L"RegisterTypeLibraries", IDS_DESC_REGISTERTYPELIBRARIES, IDS_TEMP_REGISTERTYPELIBRARIES, ACTION_RegisterTypeLibraries, L"UnregisterTypeLibraries" },
+ { L"RegisterUser", IDS_DESC_REGISTERUSER, 0, ACTION_RegisterUser, NULL },
+ { L"RemoveDuplicateFiles", IDS_DESC_REMOVEDUPLICATEFILES, IDS_TEMP_REMOVEDUPLICATEFILES, ACTION_RemoveDuplicateFiles, L"DuplicateFiles" },
+ { L"RemoveEnvironmentStrings", IDS_DESC_REMOVEENVIRONMENTSTRINGS, IDS_TEMP_REMOVEENVIRONMENTSTRINGS, ACTION_RemoveEnvironmentStrings, L"WriteEnvironmentStrings" },
+ { L"RemoveExistingProducts", IDS_DESC_REMOVEEXISTINGPRODUCTS, IDS_TEMP_REMOVEEXISTINGPRODUCTS, ACTION_RemoveExistingProducts, NULL },
+ { L"RemoveFiles", IDS_DESC_REMOVEFILES, IDS_TEMP_REMOVEFILES, ACTION_RemoveFiles, L"InstallFiles" },
+ { L"RemoveFolders", IDS_DESC_REMOVEFOLDERS, IDS_TEMP_REMOVEFOLDERS, ACTION_RemoveFolders, L"CreateFolders" },
+ { L"RemoveIniValues", IDS_DESC_REMOVEINIVALUES, IDS_TEMP_REMOVEINIVALUES, ACTION_RemoveIniValues, L"WriteIniValues" },
+ { L"RemoveODBC", IDS_DESC_REMOVEODBC, 0, ACTION_RemoveODBC, L"InstallODBC" },
+ { L"RemoveRegistryValues", IDS_DESC_REMOVEREGISTRYVALUES, IDS_TEMP_REMOVEREGISTRYVALUES, ACTION_RemoveRegistryValues, L"WriteRegistryValues" },
+ { L"RemoveShortcuts", IDS_DESC_REMOVESHORTCUTS, IDS_TEMP_REMOVESHORTCUTS, ACTION_RemoveShortcuts, L"CreateShortcuts" },
+ { L"ResolveSource", 0, 0, ACTION_ResolveSource, NULL },
+ { L"RMCCPSearch", IDS_DESC_RMCCPSEARCH, 0, ACTION_RMCCPSearch, NULL },
+ { L"ScheduleReboot", 0, 0, ACTION_ScheduleReboot, NULL },
+ { L"SelfRegModules", IDS_DESC_SELFREGMODULES, IDS_TEMP_SELFREGMODULES, ACTION_SelfRegModules, L"SelfUnregModules" },
+ { L"SelfUnregModules", IDS_DESC_SELFUNREGMODULES, IDS_TEMP_SELFUNREGMODULES, ACTION_SelfUnregModules, L"SelfRegModules" },
+ { L"SetODBCFolders", IDS_DESC_SETODBCFOLDERS, 0, ACTION_SetODBCFolders, NULL },
+ { L"StartServices", IDS_DESC_STARTSERVICES, IDS_TEMP_STARTSERVICES, ACTION_StartServices, L"StopServices" },
+ { L"StopServices", IDS_DESC_STOPSERVICES, IDS_TEMP_STOPSERVICES, ACTION_StopServices, L"StartServices" },
+ { L"UnpublishComponents", IDS_DESC_UNPUBLISHCOMPONENTS, IDS_TEMP_UNPUBLISHCOMPONENTS, ACTION_UnpublishComponents, L"PublishComponents" },
+ { L"UnpublishFeatures", IDS_DESC_UNPUBLISHFEATURES, IDS_TEMP_UNPUBLISHFEATURES, ACTION_UnpublishFeatures, L"PublishFeatures" },
+ { L"UnpublishProduct", IDS_DESC_UNPUBLISHPRODUCT, 0, ACTION_UnpublishProduct, NULL }, /* for rollback only */
+ { L"UnregisterClassInfo", IDS_DESC_UNREGISTERCLASSINFO, IDS_TEMP_UNREGISTERCLASSINFO, ACTION_UnregisterClassInfo, L"RegisterClassInfo" },
+ { L"UnregisterComPlus", IDS_DESC_UNREGISTERCOMPLUS, IDS_TEMP_UNREGISTERCOMPLUS, ACTION_UnregisterComPlus, L"RegisterComPlus" },
+ { L"UnregisterExtensionInfo", IDS_DESC_UNREGISTEREXTENSIONINFO, IDS_TEMP_UNREGISTEREXTENSIONINFO, ACTION_UnregisterExtensionInfo, L"RegisterExtensionInfo" },
+ { L"UnregisterFonts", IDS_DESC_UNREGISTERFONTS, IDS_TEMP_UNREGISTERFONTS, ACTION_UnregisterFonts, L"RegisterFonts" },
+ { L"UnregisterMIMEInfo", IDS_DESC_UNREGISTERMIMEINFO, IDS_TEMP_UNREGISTERMIMEINFO, ACTION_UnregisterMIMEInfo, L"RegisterMIMEInfo" },
+ { L"UnregisterProgIdInfo", IDS_DESC_UNREGISTERPROGIDINFO, IDS_TEMP_UNREGISTERPROGIDINFO, ACTION_UnregisterProgIdInfo, L"RegisterProgIdInfo" },
+ { L"UnregisterTypeLibraries", IDS_DESC_UNREGISTERTYPELIBRARIES, IDS_TEMP_UNREGISTERTYPELIBRARIES, ACTION_UnregisterTypeLibraries, L"RegisterTypeLibraries" },
+ { L"ValidateProductID", 0, 0, ACTION_ValidateProductID, NULL },
+ { L"WriteEnvironmentStrings", IDS_DESC_WRITEENVIRONMENTSTRINGS, IDS_TEMP_WRITEENVIRONMENTSTRINGS, ACTION_WriteEnvironmentStrings, L"RemoveEnvironmentStrings" },
+ { L"WriteIniValues", IDS_DESC_WRITEINIVALUES, IDS_TEMP_WRITEINIVALUES, ACTION_WriteIniValues, L"RemoveIniValues" },
+ { L"WriteRegistryValues", IDS_DESC_WRITEREGISTRYVALUES, IDS_TEMP_WRITEREGISTRYVALUES, ACTION_WriteRegistryValues, L"RemoveRegistryValues" },
+ { L"INSTALL", 0, 0, ACTION_INSTALL, NULL },
{ 0 }
};
@@ -8093,21 +7580,10 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
UINT rc = ERROR_SUCCESS;
MSIRECORD *row;
- static const WCHAR query[] =
- {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','I','n','s','t','a','l','l','E','x','e','c','u','t','e',
- 'S','e','q','u','e','n','c','e','`',' ', 'W','H','E','R','E',' ',
- '`','S','e','q','u','e','n','c','e','`',' ', '=',' ','%','i',0};
- static const WCHAR ui_query[] =
- {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e',
- '`', ' ', 'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',
- ' ', '=',' ','%','i',0};
-
if (needs_ui_sequence(package))
- row = MSI_QueryGetRecord(package->db, ui_query, seq);
+ row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `InstallUISequence` WHERE `Sequence` = %d", seq);
else
- row = MSI_QueryGetRecord(package->db, query, seq);
+ row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `InstallExecuteSequence` WHERE `Sequence` = %d", seq);
if (row)
{
@@ -8148,8 +7624,6 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
LPCWSTR szCommandLine )
{
- static const WCHAR szDisableRollback[] = {'D','I','S','A','B','L','E','R','O','L','L','B','A','C','K',0};
- static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
WCHAR *reinstall = NULL, *productcode, *action;
UINT rc;
DWORD len = 0;
@@ -8171,7 +7645,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
msi_free(dir);
dir = msi_alloc(MAX_PATH * sizeof(WCHAR));
GetCurrentDirectoryW(MAX_PATH, dir);
- lstrcatW(dir, szBackSlash);
+ lstrcatW(dir, L"\\");
file = szPackagePath;
}
@@ -8197,9 +7671,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
msi_apply_transforms( package );
msi_apply_patches( package );
- if (msi_get_property( package->db, szAction, NULL, &len ))
- msi_set_property( package->db, szAction, szINSTALL, -1 );
- action = msi_dup_property( package->db, szAction );
+ if (msi_get_property( package->db, L"ACTION", NULL, &len ))
+ msi_set_property( package->db, L"ACTION", L"INSTALL", -1 );
+ action = msi_dup_property( package->db, L"ACTION" );
CharUpperW(action);
msi_set_original_database_property( package->db, szPackagePath );
@@ -8207,7 +7681,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
msi_adjust_privilege_properties( package );
msi_set_context( package );
- productcode = msi_dup_property( package->db, szProductCode );
+ productcode = msi_dup_property( package->db, L"ProductCode" );
if (wcsicmp( productcode, package->ProductCode ))
{
TRACE( "product code changed %s -> %s\n", debugstr_w(package->ProductCode), debugstr_w(productcode) );
@@ -8216,10 +7690,10 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
}
else msi_free( productcode );
- if (msi_get_property_int( package->db, szDisableRollback, 0 ))
+ if (msi_get_property_int( package->db, L"DISABLEROLLBACK", 0 ))
{
TRACE("disabling rollback\n");
- msi_set_property( package->db, szRollbackDisabled, szOne, -1 );
+ msi_set_property( package->db, L"RollbackDisabled", L"1", -1 );
}
rc = ACTION_PerformAction(package, action);
@@ -8234,7 +7708,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
else /* failed */
{
ACTION_PerformActionSequence(package, -3);
- if (!msi_get_property_int( package->db, szRollbackDisabled, 0 ))
+ if (!msi_get_property_int( package->db, L"RollbackDisabled", 0 ))
{
package->need_rollback = TRUE;
}
@@ -8243,7 +7717,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
/* finish up running custom actions */
ACTION_FinishCustomActions(package);
- if (package->need_rollback && !(reinstall = msi_dup_property( package->db, szReinstall )))
+ if (package->need_rollback && !(reinstall = msi_dup_property( package->db, L"REINSTALL" )))
{
WARN("installation failed, running rollback script\n");
execute_script( package, SCRIPT_ROLLBACK );
--
2.28.0
1
0
From: Giovanni Mascellani <wine(a)mascellani.eu>
Signed-off-by: Giovanni Mascellani <wine(a)mascellani.eu>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
Minor style fixes.
dlls/d2d1/d2d1.spec | 2 +-
dlls/d2d1/factory.c | 7 +++++++
dlls/d2d1/tests/d2d1.c | 23 ++++++++++++++++++++++-
include/d2d1_1.idl | 1 +
4 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/d2d1.spec b/dlls/d2d1/d2d1.spec
index 410abfa5de6..7b624c7096e 100644
--- a/dlls/d2d1/d2d1.spec
+++ b/dlls/d2d1/d2d1.spec
@@ -7,5 +7,5 @@
@ stdcall D2D1CreateDevice(ptr ptr ptr)
@ stub D2D1CreateDeviceContext
@ stdcall D2D1SinCos(float ptr ptr)
-@ stub D2D1Tan
+@ stdcall D2D1Tan(float)
@ stub D2D1Vec3Length
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c
index 943347d7884..9c5337590cd 100644
--- a/dlls/d2d1/factory.c
+++ b/dlls/d2d1/factory.c
@@ -721,6 +721,13 @@ void WINAPI D2D1SinCos(float angle, float *s, float *c)
*c = cosf(angle);
}
+float WINAPI D2D1Tan(float angle)
+{
+ TRACE("angle %.8e.\n", angle);
+
+ return tanf(angle);
+}
+
static BOOL get_config_key_dword(HKEY default_key, HKEY application_key, const char *name, DWORD *value)
{
DWORD type, data, size;
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index df1df01c051..b269770365f 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -9428,7 +9428,7 @@ static void test_wic_bitmap_format(void)
static void test_math(void)
{
unsigned int i;
- float s, c;
+ float s, c, t;
static const struct
{
@@ -9445,6 +9445,20 @@ static void test_math(void)
{M_PI, -8.74227766e-008f, -1.0f},
};
+ static const struct
+ {
+ float x;
+ float t;
+ }
+ t_data[] =
+ {
+ {0.0f, 0.0f},
+ {1.0f, 1.55740774f},
+ {2.0f, -2.18503976f},
+ {M_PI / 2.0f, -2.28773320e+007f},
+ {M_PI, 8.74227766e-008f},
+ };
+
for (i = 0; i < ARRAY_SIZE(sc_data); ++i)
{
D2D1SinCos(sc_data[i].x, &s, &c);
@@ -9453,6 +9467,13 @@ static void test_math(void)
ok(compare_float(c, sc_data[i].c, 0),
"Test %u: Got unexpected cos %.8e, expected %.8e.\n", i, c, sc_data[i].c);
}
+
+ for (i = 0; i < ARRAY_SIZE(t_data); ++i)
+ {
+ t = D2D1Tan(t_data[i].x);
+ ok(compare_float(t, t_data[i].t, 1),
+ "Test %u: Got unexpected tan %.8e, expected %.8e.\n", i, t, t_data[i].t);
+ }
}
START_TEST(d2d1)
diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl
index 6fa893edbda..bd111bd6628 100644
--- a/include/d2d1_1.idl
+++ b/include/d2d1_1.idl
@@ -795,3 +795,4 @@ interface ID2D1Factory1 : ID2D1Factory
[local] HRESULT __stdcall D2D1CreateDevice(IDXGIDevice *dxgi_device,
const D2D1_CREATION_PROPERTIES *creation_properties, ID2D1Device **device);
[local] void __stdcall D2D1SinCos(float angle, float *s, float *c);
+[local] float __stdcall D2D1Tan(float angle);
--
2.20.1
4
3
[PATCH 5/5] riched20: Fix the struct size check in the para fmt retrieval function.
by Huw Davies 27 Oct '20
by Huw Davies 27 Oct '20
27 Oct '20
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/para.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c
index e1b848cf8f9..c7a0e271510 100644
--- a/dlls/riched20/para.c
+++ b/dlls/riched20/para.c
@@ -928,7 +928,8 @@ void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
ME_DisplayItem *para, *para_end;
PARAFORMAT2 *curFmt;
- if (pFmt->cbSize < sizeof(PARAFORMAT)) {
+ if (pFmt->cbSize < sizeof(PARAFORMAT))
+ {
pFmt->dwMask = 0;
return;
}
@@ -951,13 +952,14 @@ void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
CHECK_FIELD(PFM_RIGHTINDENT, dxRightIndent);
CHECK_FIELD(PFM_OFFSET, dxOffset);
CHECK_FIELD(PFM_ALIGNMENT, wAlignment);
- if (pFmt->dwMask & PFM_TABSTOPS) {
+ if (pFmt->dwMask & PFM_TABSTOPS)
+ {
if (pFmt->cTabCount != para->member.para.fmt.cTabCount ||
memcmp(pFmt->rgxTabs, curFmt->rgxTabs, curFmt->cTabCount*sizeof(int)))
pFmt->dwMask &= ~PFM_TABSTOPS;
}
- if (pFmt->dwMask >= sizeof(PARAFORMAT2))
+ if (pFmt->cbSize >= sizeof(PARAFORMAT2))
{
pFmt->dwMask &= ~((pFmt->wEffects ^ curFmt->wEffects) << 16);
CHECK_FIELD(PFM_SPACEBEFORE, dySpaceBefore);
--
2.23.0
1
0
[PATCH 4/5] riched20: Use row and para ptrs in the ensure visible function.
by Huw Davies 27 Oct '20
by Huw Davies 27 Oct '20
27 Oct '20
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/caret.c | 10 ++++------
dlls/riched20/editor.c | 2 +-
dlls/riched20/editor.h | 2 +-
dlls/riched20/paint.c | 25 ++++++++++++-------------
4 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 6a8f1e1cd71..47fe77df922 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -1176,13 +1176,11 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
if (editor->nSelectionType != stPosition &&
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_EnsureVisible(editor, &editor->pCursors[1]);
- } else {
- ME_EnsureVisible(editor, &editor->pCursors[0]);
- }
+ editor_ensure_visible( editor, &editor->pCursors[1] );
+ else
+ editor_ensure_visible( editor, &editor->pCursors[0] );
ME_InvalidateSelection(editor);
update_caret(editor);
@@ -1520,7 +1518,7 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
ME_InvalidateSelection(editor);
ME_Repaint(editor);
hide_caret(editor);
- ME_EnsureVisible(editor, &tmp_curs);
+ editor_ensure_visible( editor, &tmp_curs );
update_caret(editor);
ME_SendSelChange(editor);
return success;
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 6a2e96a3c7c..462245db233 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -4095,7 +4095,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return len;
}
case EM_SCROLLCARET:
- ME_EnsureVisible(editor, &editor->pCursors[0]);
+ editor_ensure_visible( editor, &editor->pCursors[0] );
return 0;
case WM_SETFONT:
{
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index ba1e5c169ff..1a2346854e7 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -242,7 +242,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLS
void ME_Repaint(ME_TextEditor *editor) DECLSPEC_HIDDEN;
void ME_RewrapRepaint(ME_TextEditor *editor) DECLSPEC_HIDDEN;
void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now) DECLSPEC_HIDDEN;
-void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor) DECLSPEC_HIDDEN;
+void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN;
void ME_InvalidateSelection(ME_TextEditor *editor) DECLSPEC_HIDDEN;
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator) DECLSPEC_HIDDEN;
int ME_twips2pointsX(const ME_Context *c, int x) DECLSPEC_HIDDEN;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index 0c37fc7c707..180307ae01b 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -117,7 +117,7 @@ void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now)
ME_UpdateScrollBar(editor);
/* Ensure that the cursor is visible */
- ME_EnsureVisible(editor, &editor->pCursors[0]);
+ editor_ensure_visible( editor, &editor->pCursors[0] );
ITextHost_TxViewChange(editor->texthost, update_now);
@@ -1269,19 +1269,17 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
}
}
-void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
+void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
{
- ME_Run *pRun = &pCursor->pRun->member.run;
- ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
- ME_DisplayItem *pPara = pCursor->pPara;
+ ME_Run *run = &cursor->pRun->member.run;
+ ME_Row *row = row_from_cursor( cursor );
+ ME_Paragraph *para = &cursor->pPara->member.para;
int x, y, yheight;
- assert(pRow);
- assert(pPara);
if (editor->styleFlags & ES_AUTOHSCROLL)
{
- x = pRun->pt.x + ME_PointFromChar(editor, pRun, pCursor->nOffset, TRUE);
+ x = run->pt.x + ME_PointFromChar( editor, run, cursor->nOffset, TRUE );
if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
x = x + 1 - editor->sizeWindow.cx;
else if (x > editor->horz_si.nPos)
@@ -1292,14 +1290,15 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
ME_HScrollAbs(editor, x);
return;
}
- } else {
- if (~editor->styleFlags & ES_AUTOVSCROLL)
- return;
+ }
+ else
+ {
+ if (~editor->styleFlags & ES_AUTOVSCROLL) return;
x = editor->horz_si.nPos;
}
- y = pPara->member.para.pt.y + pRow->member.row.pt.y;
- yheight = pRow->member.row.nHeight;
+ y = para->pt.y + row->pt.y;
+ yheight = row->nHeight;
if (y < editor->vert_si.nPos)
ME_ScrollAbs(editor, x, y);
--
2.23.0
1
0
27 Oct '20
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/editor.h | 2 +-
dlls/riched20/paint.c | 41 +++++++++++++++++++++--------------------
dlls/riched20/richole.c | 2 +-
3 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index f4484f57d39..ba1e5c169ff 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -264,7 +264,7 @@ int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN;
/* richole.c */
LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN;
-void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, BOOL selected) DECLSPEC_HIDDEN;
+void draw_ole( ME_Context *c, int x, int y, ME_Run* run, BOOL selected ) DECLSPEC_HIDDEN;
void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN;
void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) DECLSPEC_HIDDEN;
void ME_DeleteReObject(struct re_object *re_object) DECLSPEC_HIDDEN;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index 42f370c857c..0c37fc7c707 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -359,8 +359,8 @@ static void draw_text( ME_Context *c, ME_Run *run, int x, int y, BOOL selected,
}
-static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
- int nSelFrom, int nSelTo, int ymin, int cy)
+static void draw_text_with_style( ME_Context *c, ME_Run *run, int x, int y,
+ int nSelFrom, int nSelTo, int ymin, int cy )
{
HDC hDC = c->hDC;
int yOffset = 0;
@@ -434,16 +434,16 @@ static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) {
SetTextColor(hDC, color);
}
-static void ME_DrawRun( ME_Context *c, int x, int y, ME_Run *run, ME_Paragraph *para )
+static void draw_run( ME_Context *c, int x, int y, ME_Cursor *cursor )
{
- ME_DisplayItem *start;
- int runofs = run->nCharOfs+para->nCharOfs;
+ ME_Row *row;
+ ME_Run *run = &cursor->pRun->member.run;
+ int runofs = run_char_ofs( run, cursor->nOffset );
int nSelFrom, nSelTo;
- if (run->nFlags & MERF_HIDDEN)
- return;
+ if (run->nFlags & MERF_HIDDEN) return;
- start = ME_FindItemBack( run_get_di( run ), diStartRow );
+ row = row_from_cursor( cursor );
ME_GetSelectionOfs(c->editor, &nSelFrom, &nSelTo);
/* Draw selected end-of-paragraph mark */
@@ -452,8 +452,7 @@ static void ME_DrawRun( ME_Context *c, int x, int y, ME_Run *run, ME_Paragraph *
if (runofs >= nSelFrom && runofs < nSelTo)
{
draw_space( c, run, x, y, TRUE, FALSE,
- c->pt.y + para->pt.y + start->member.row.pt.y,
- start->member.row.nHeight );
+ c->pt.y + run->para->pt.y + row->pt.y, row->nHeight );
}
return;
}
@@ -463,19 +462,15 @@ static void ME_DrawRun( ME_Context *c, int x, int y, ME_Run *run, ME_Paragraph *
BOOL selected = runofs >= nSelFrom && runofs < nSelTo;
draw_space( c, run, x, y, selected, TRUE,
- c->pt.y + para->pt.y + start->member.row.pt.y,
- start->member.row.nHeight );
+ c->pt.y + run->para->pt.y + row->pt.y, row->nHeight );
return;
}
if (run->nFlags & MERF_GRAPHICS)
- ME_DrawOLE(c, x, y, run, (runofs >= nSelFrom) && (runofs < nSelTo));
+ draw_ole( c, x, y, run, (runofs >= nSelFrom) && (runofs < nSelTo) );
else
- {
- ME_DrawTextWithStyle(c, run, x, y, nSelFrom - runofs, nSelTo - runofs,
- c->pt.y + para->pt.y + start->member.row.pt.y,
- start->member.row.nHeight);
- }
+ draw_text_with_style( c, run, x, y, nSelFrom - runofs, nSelTo - runofs,
+ c->pt.y + run->para->pt.y + row->pt.y, row->nHeight );
}
/* The documented widths are in points (72 dpi), but converting them to
@@ -1001,8 +996,14 @@ static void draw_paragraph( ME_Context *c, ME_Paragraph *para )
FrameRect(c->hDC, &rc, GetSysColorBrush(COLOR_GRAYTEXT));
}
if (visible)
- ME_DrawRun( c, c->pt.x + run->pt.x,
- c->pt.y + para->pt.y + run->pt.y + baseline, run, para );
+ {
+ ME_Cursor cursor;
+
+ cursor.pRun = run_get_di( run );
+ cursor.pPara = para_get_di( para );
+ cursor.nOffset = 0;
+ draw_run( c, c->pt.x + run->pt.x, c->pt.y + para->pt.y + run->pt.y + baseline, &cursor );
+ }
if (me_debug)
{
static const WCHAR wszRunDebug[] = {'[','%','d',':','%','x',']',' ','%','l','s',0};
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index 21b63911954..015326c5abc 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -5846,7 +5846,7 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize)
}
}
-void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected)
+void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected )
{
IDataObject* ido;
FORMATETC fmt;
--
2.23.0
1
0