[MSIEXEC][MSI] Sync msiexec and msi to wine-9.8 (#6897)

* [MSIEXEC] Sync msiexec to wine-9.8

* [WINESYNC] msi: Disable FS redirection for temporary file in cabinet_copy_file().

wine commit id a58c6251870dfb7d214464e709bbbc9ca649b900 by Paul Gofman <pgofman@codeweavers.com>

* [WINESYNC] msi/tests: Correct a couple of failure messages in test_msirecord.

wine commit id 2fde0a3f5c233b0ea1637f409998ce4ee85d28a7 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Use the wcsdup function instead of reimplementing it.

wine commit id 7cc7a6defc08d4de7574b7a75d574c3ab1f32db8 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Use _O_* constants from fcntl.h instead of redefining them.

wine commit id b07c95e79cdf6ae26c5170daa481ad160e0ce76a by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Remove wrappers around CRT memory allocation functions.

wine commit id d920aa81ad0c4618c27ebd7e9863618e988328e0 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Initialize all members of WINTRUST_DATA.

The pSignatureSettings field was not unitilized so it got a random value from
the stack causing a later crash when it was dereferenced in Wintrust
(SoftPubloadSignature).

wine commit id 904bedb3e96bc68101652e151db102532399abe8 by Philip K. Gisslow <ripxorip@gmail.com>

* [WINESYNC] msi: Fix memory leak on realloc failure in create_diff_row_query (cppcheck).

wine commit id 3e231d0f36a56ce991c7edbb6ae7845094e8417e by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Fix memory leak on realloc failure in msi_get_window_text (cppcheck).

wine commit id 6c1dd0f2c5669e084eb1f84571c38761a97c0970 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Fix memory leak on realloc failure in search_directory (cppcheck).

wine commit id d394df4a30feb685927908fce2887bf5496b5d66 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] ntdll: Default to Windows 10.

wine commit id 69154f0329aec4fb64886a0689da198b5323dcde by Hans Leidekker <hans@codeweavers.com>

* [MSI] Fix build

* [WINESYNC] Update winesync file

* [WINESYNC] msi/tests: Avoid test failures when running with insufficient rights.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51040

wine commit id 79ec3d9fb8551e84e9ff71dcf18861430246278a by Hans Leidekker <hans@codeweavers.com>

* [WINESYNC] msi: Install and patch global assemblies in InstallFinalize.

Installing global assemblies requires assembly caches to be initialized and
this is no longer the case after the PE conversion (builtin fusion no longer
loads if the dll is not present on disk).

The next patch changes msi to perform late initialization of the assembly
caches so that native fusion can be loaded once it's installed by .NET
installers. However, there's no guarantee that all necessary files and
registry keys are installed before the InstallFiles and PatchFiles actions
are executed. Therefore this patch moves the parts of these actions handling
global assemblies to InstallFinalize.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51345

wine commit id 2c450fd6215c0da4685143f97ece8b6db0f54a0b by Hans Leidekker <hans@codeweavers.com>

* [WINESYNC] msi: Perform late initialization of the assembly caches.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51345

wine commit id d9d700f3328f00ec419571df0e02cef208fa1e7b by Hans Leidekker <hans@codeweavers.com>

* [WINESYNC] msi: Remove msi_ prefix from static functions.

wine commit id 3611398b7575177b91e8162a84ebca977c50c2f5 by Hans Leidekker <hans@codeweavers.com>

* [WINESYNC] msi: Get rid of unnecessary typedefs.

wine commit id 258012742512a4072265fcc47826c52319bd37ab by Hans Leidekker <hans@codeweavers.com>

* [WINESYNC] msi: Handle memory allocation failure in get_link_file (cppcheck).

wine commit id 687c4f5c8dc65def6fc066d5d802d7448db70d7f by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Annotate memory allocation functions with __WINE_(DEALLOC|MALLOC).

wine commit id 9df04bfdb03a3017f532e70a047ee83290dbc257 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi/tests: Fix the ok() formats so they match the size of their arguments.

wine commit id b6fb1b8983af7644b78bb0ba5fb9d18a1f0822f1 by Francois Gouget <fgouget@codeweavers.com>

* [WINESYNC] msi/tests: Ok_() takes printf-style arguments.

This lets the compiler check that the format and argument sizes match.

wine commit id a80b183af74194a06af3281ee272590a7134b7f1 by Francois Gouget <fgouget@codeweavers.com>

* [WINESYNC] msi: Return ERROR_OUTOFMEMORY if calloc fails in TransformView_Create (scan-build).

Instead of ERROR_SUCCESS.

wine commit id daa20d9d636057d7009ff3652a8577b423d23fcf by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Make TransformView_Create static.

wine commit id 1da5618cbac1214082bfb897dc81804d14fc6e9e by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Fix memory leak in ready_media (scan-build).

base_url was never freed, and can simply be enlarged instead of copying
it to a new buffer.

wine commit id c39f785b34692ee994b2449cc17a96815517e9bf by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Fix memory leak on error path in MSI_ProcessMessage (scan-build).

wine commit id d06b3fd5274b056c720e2fb42eb189052d99404d by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Release record instead of free.

../dlls/msi/dialog.c:4476:11: warning: attempt to call free on non-heap object 'hdr' [-Wfree-nonheap-object]
    free( &rec->hdr );
          ^

wine commit id 7b3690dd7399cd64123554c8a6fc7e35dcbebbe1 by Daniel Lehman <dlehman25@gmail.com>

* [WINESYNC] include: Remove redundant __WINE_USE_MSVCRT checks.

wine commit id 93630ce14ebf16333fda8481b5ede6f587eb32ca by Alexandre Julliard <julliard@winehq.org>

* [WINESYNC] msi: Fix memory leak on error path in MSI_OpenPackageW (scan-build).

wine commit id 4db2ffa60e16e06b4f6ef89fcc4c73229f4446b1 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Fix double free on error paths in TransformView_Create (scan-build).

If TransformView_Create returns an error, it should not return a pointer
that table_load_transform will try to free.

wine commit id 0653409e0631582d89edaab0ac516994710dae1a by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Fix memory leaks in HANDLE_CustomType23 (scan-build).

wine commit id 993f4d48d23477e70e92256890c77687a1c4ba08 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Reject shorter/longer lines in MsiDatabaseImportA.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54532
Signed-off-by: David Kahurani <k.kahurani@gmail.com>

wine commit id e1ddc58a259d80f16bf1e62f23428775e1b070a0 by David Kahurani <k.kahurani@gmail.com>

* [WINESYNC] msi: Convert newlines to alternate representation when exporting.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54532
Signed-off-by: David Kahurani <k.kahurani@gmail.com>

wine commit id 60e4f8a261ae9044aafa9c4eec2a3f2aec6481b5 by David Kahurani <k.kahurani@gmail.com>

* [WINESYNC] msi: Remove DECLSPEC_HIDDEN usage.

wine commit id 51049c95a242f1553562a442142e813e37cee233 by Alistair Leslie-Hughes <leslie_alistair@hotmail.com>

* [MSI] remove DECLSPEC_HIDDEN

* [WINESYNC] msi: Fully initialize the control structure in dialog_line_control().

Fixes: 76606eaea034c51a73190aac92e75d8b20e82164
Fixes: 174b7b51ac9e57c6cfa8f48e62bbf468ae3b1f24

wine commit id 735584076efafc29673e0c9418a64343634f9aa5 by Jinoh Kang <jinoh.kang.kr@gmail.com>

* [WINESYNC] msi: Make insertion order of line controls consistent with other controls.

Fixes: 2c5bd49297f79d9941a256d8ec61e0eb2bf9bf9c

wine commit id 3eceda2f2a77754f0bf93ea33018e8ef49e82669 by Jinoh Kang <jinoh.kang.kr@gmail.com>

* [WINESYNC] msi: Don't open code dialog_add_control() in dialog_line_control().

Commit b1cc87cb656 ("msi: The line control has a height of exactly 2
device units.", 2007-12-16) open-coded the body of
(msi_)dialog_add_control() inside dialog_line_control() modulo the
height override.

Except the fixed height, line controls have nothing special compared to
other controls.  Thus, there is little merit in open-coding it.

Also, dialog_line_control() has bit-rotted over time; it already missed
a few changes that were done to any other controls.

Fix this by just using dialog_add_control().  Also, add a special case
logic just for line controls.

wine commit id 1fca47b724b3835ac0267f58c5b3486fc222fc71 by Jinoh Kang <jinoh.kang.kr@gmail.com>

* [WINESYNC] msi: Use nameless unions/structs.

wine commit id 8de0a9dc740d3ed1e3cf9460852db7e609122f3b by Alexandre Julliard <julliard@winehq.org>

* [MSI] disable nameless structs

* [WINESYNC] msi/tests: Use nameless unions/structs.

wine commit id 490aee03e45222aa9d7e3e7fd6ff80064dc3778d by Alexandre Julliard <julliard@winehq.org>

* [WINESYNC] makedep: Use #pragma makedep testdll for TESTDLL resources.

wine commit id 81da9ff0f8dea4932a3afdc4c447c1c9242bb596 by Rémi Bernon <rbernon@codeweavers.com>

* [WINESYNC] msi: Use CreateFileW() for handling path from cabinet_open() instead.

wine commit id 085e95cd5eceb36c3e21cb7d42adab5a6af38a38 by Jactry Zeng <jzeng@codeweavers.com>

* [WINESYNC] msiexec: Use CRT allocation functions.

wine commit id 0f44b3bdcb3d91701a9a8ef1ad07f3e88c08a666 by Alex Henrie <alexhenrie24@gmail.com>

* [WINESYNC] msi: Remove DECLSPEC_HIDDEN usage.

wine commit id 91e81083458374706bbace11114f4ad5e473ac07 by Alistair Leslie-Hughes <leslie_alistair@hotmail.com>

* [WINESYNC] msi: Store Context as MSIINSTALLCONTEXT in MSIPACKAGE.

Avoids casting to enum pointer in msi_locate_product call.

wine commit id 2daa8c9f95b35983c885f5f7efe9e1b48e91f679 by Jacek Caban <jacek@codeweavers.com>

* [WINESYNC] msi/tests: Initialize pathkey in test_installprops.

It could be used uninitialized on early no access return.

wine commit id 93668319dd63add97036fbb79b5745c699117313 by Jacek Caban <jacek@codeweavers.com>

* [WINESYNC] regsvr32: Use message boxes by default for output.

regsvr32 is in GUI subsystem and shouldn't interact with console.
Keeping unix I/O output in silent mode.
Removing -c option as not existing in native.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>

wine commit id ac8da35b87005e45947b8164a4132f3bbb4ec2cc by Eric Pouech <epouech@codeweavers.com>

* [MSI]: Reduce diff

* [WINESYNC] msiexec: No longer use console/file output APIs.

Regular GUI apps don't.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>

wine commit id e048f71ecbb103ae7c1876092cb8244b24a73cb7 by Eric Pouech <epouech@codeweavers.com>

* [WINESYNC] msi: Fix a memory leak (Coverity).

wine commit id 4afca1787febb012d0cdd2c007dd32beba35178d by Zhiyi Zhang <zzhang@codeweavers.com>

* [WINESYNC] msi: Don't write past end of string when selecting parent directory.

wine commit id bbce5d014db7f023b133d6d09e6846e027586f7d by Fabian Maurer <dark.shadow4@web.de>

* [WINESYNC] msi: Avoid leaking stream on DB update.

MSI_RecordGetIStream adds a reference to the stream. This
reference should be negated as we are done setting the stream.

Signed-off-by: David Kahurani <k.kahurani@gmail.com>

wine commit id 386dbe1059ba08485696760c267ef06dbed95bad by David Kahurani <k.kahurani@gmail.com>

* [WINESYNC] msi/tests: Expand costing tests.

wine commit id 674efeb1f7445935cf4f49dd1285727055664ab9 by Zebediah Figura <zfigura@codeweavers.com>

* [WINESYNC] msi: Round costs up to 4096 bytes instead of clamping.

wine commit id 9725a2286acdb791de316295d9bcb11411a3fd56 by Zebediah Figura <zfigura@codeweavers.com>

* [WINESYNC] msi: Store component cost in 512-byte units.

This avoids overflow when component costs exceed 4 GB.

wine commit id d7bbe884ef29215f4db2027f450fb959314f5383 by Zebediah Figura <zfigura@codeweavers.com>

* [MSI] store component cost in 512-byte units

* [WINESYNC] msi: Multiply by 512 in dialog_vcl_add_drives().

The main motivation here is to avoid overflow, and multiplying in one place seems simpler.

wine commit id 4a227c62a59a55aff9bacf1473c7f478f5c83294 by Zebediah Figura <zfigura@codeweavers.com>

* [MSI] reduce diff

* [WINESYNC] msi: Create the custom action server as an elevated process.

Dragon Naturally Speaking 12.5 manually validates that the custom action server
is elevated.

One might imagine that the right approach here is to add a manifest to msiexec;
however, msiexec does not always trigger a UAC prompt on Windows.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51143

wine commit id 366398cc53c76028c8dfe8d8a16c78a6a10ce962 by Zebediah Figura <z.figura12@gmail.com>

* [WINESYNC] msi/tests: Delete the temp .msi file in all failure cases.

wine commit id 43fb0ecd0717ad1a6aa0702ed68368ee35d3ecda by Alexandre Julliard <julliard@winehq.org>

* [WINESYNC] msi/tests: Use the helpers from utils.h in more modules.

wine commit id b3f11ceb7a0ddcf5fe742377f99c947b0b56a051 by Hans Leidekker <hans@codeweavers.com>

* [MSITEST] include util header

* [WINESYNC] msi/tests: Try restarting tests elevated.

Wine starts processes non-elevated since e92ba2de43d7afbe0704b11b29f7c30f44dfaeca
which means that many tests are skipped now.

wine commit id a6eb51f0e595b2e5ddc521fb61b10d72849dd0f2 by Hans Leidekker <hans@codeweavers.com>

* [MSITEST] try restarting for tests elevated

* [WINESYNC] msi/tests: Get rid of workarounds for old Windows versions.

wine commit id 738ec8285583248a84349939734ed600a47ba73d by Hans Leidekker <hans@codeweavers.com>

* [MSI] fix patch failed

* [WINESYNC] msi: Install global assemblies before running deferred custom actions.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56493

wine commit id 7f0ca9c284d15d03f14a8fefefac834990d622cd by Hans Leidekker <hans@codeweavers.com>

* [WINESYNC] msi: Install global assemblies after install custom actions and before commit custom actions.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56609

wine commit id 27f5470ff4c20121b9eacd702c888400191c7d9e by Hans Leidekker <hans@codeweavers.com>

* [WINESYNC]: msi is now in sync with wine-staging wine-9.8

* [MSI] Fix build

* [WINESYNC] Update WINESYNC doc

* [MSI] Remove nonameless* defines

* [MSIEXEC] Fix build

* [MSIEXEC] Fix build

* [MSI] Fix vcl_get_cost
This commit is contained in:
Mikhail 2024-09-29 13:24:15 -04:00 committed by GitHub
parent 1176530663
commit f4be6dc36f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 6319 additions and 8536 deletions

View file

@ -29,7 +29,6 @@
#include <msidefs.h>
#include <msi.h>
#include <fci.h>
#include <srrestoreptapi.h>
#include <wtypes.h>
#include <shellapi.h>
#include <winsvc.h>
@ -43,23 +42,6 @@
#include "utils.h"
#include "typelib.h"
static UINT (WINAPI *pMsiQueryComponentStateA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
static UINT (WINAPI *pMsiSourceListEnumSourcesA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
static UINT (WINAPI *pMsiSourceListGetInfoA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
static UINT (WINAPI *pMsiQueryFeatureStateExA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA *, STATEMGRSTATUS *);
static BOOL is_wow64;
static const BOOL is_64bit = sizeof(void *) > sizeof(int);
@ -2375,33 +2357,6 @@ static const msi_table rep_tables[] =
/* make the max size large so there is only one cab file */
#define MEDIA_SIZE 0x7FFFFFFF
static void init_functionpointers(void)
{
HMODULE hmsi = GetModuleHandleA("msi.dll");
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
HMODULE hsrclient = LoadLibraryA("srclient.dll");
#define GET_PROC(mod, func) \
p ## func = (void*)GetProcAddress(mod, #func); \
if(!p ## func) \
trace("GetProcAddress(%s) failed\n", #func);
GET_PROC(hmsi, MsiQueryComponentStateA);
GET_PROC(hmsi, MsiSourceListEnumSourcesA);
GET_PROC(hmsi, MsiSourceListGetInfoA);
GET_PROC(hmsi, MsiGetComponentPathExA);
GET_PROC(hmsi, MsiQueryFeatureStateExA);
GET_PROC(hadvapi32, RegDeleteKeyExA)
GET_PROC(hkernel32, IsWow64Process)
GET_PROC(hsrclient, SRRemoveRestorePoint);
GET_PROC(hsrclient, SRSetRestorePointA);
#undef GET_PROC
}
static char *get_user_sid(void)
{
HANDLE token;
@ -2457,34 +2412,6 @@ static void delete_test_files(void)
RemoveDirectoryA("msitest");
}
static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
{
RESTOREPOINTINFOA spec;
spec.dwEventType = event_type;
spec.dwRestorePtType = APPLICATION_INSTALL;
spec.llSequenceNumber = status->llSequenceNumber;
lstrcpyA(spec.szDescription, "msitest restore point");
return pSRSetRestorePointA(&spec, status);
}
static void remove_restore_point(DWORD seq_number)
{
DWORD res;
res = pSRRemoveRestorePoint(seq_number);
if (res != ERROR_SUCCESS)
trace("Failed to remove the restore point : %#lx\n", res);
}
static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
{
if (pRegDeleteKeyExA)
return pRegDeleteKeyExA( key, subkey, access, 0 );
return RegDeleteKeyA( key, subkey );
}
static void delete_pfmsitest_files(void)
{
SHFILEOPSTRUCTA shfl;
@ -2672,7 +2599,7 @@ static void test_register_product(void)
static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
"\\51AAE0C44620A5E4788506E91F249BD2";
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3055,7 +2982,7 @@ static void test_publish_product(void)
BOOL old_installer = FALSE;
REGSAM access = KEY_ALL_ACCESS;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3118,9 +3045,9 @@ static void test_publish_product(void)
if (!res)
CHECK_DEL_REG_STR(patches, "AllPatches", "");
delete_key(patches, "", access);
RegDeleteKeyExA(patches, "", access, 0);
RegCloseKey(patches);
delete_key(hkey, "", access);
RegDeleteKeyExA(hkey, "", access, 0);
RegCloseKey(hkey);
currentuser:
@ -3197,9 +3124,9 @@ currentuser:
if (!res)
CHECK_DEL_REG_STR(patches, "AllPatches", "");
delete_key(patches, "", access);
RegDeleteKeyExA(patches, "", access, 0);
RegCloseKey(patches);
delete_key(hkey, "", access);
RegDeleteKeyExA(hkey, "", access, 0);
RegCloseKey(hkey);
machprod:
@ -3230,7 +3157,7 @@ machprod:
CHECK_DEL_REG_STR(net, "1", temp);
res = delete_key(net, "", access);
res = RegDeleteKeyExA(net, "", access, 0);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
RegCloseKey(net);
@ -3239,13 +3166,13 @@ machprod:
CHECK_DEL_REG_STR(media, "1", "DISK1;");
res = delete_key(media, "", access);
res = RegDeleteKeyExA(media, "", access, 0);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
RegCloseKey(media);
res = delete_key(sourcelist, "", access);
res = RegDeleteKeyExA(sourcelist, "", access, 0);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
RegCloseKey(sourcelist);
res = delete_key(hkey, "", access);
res = RegDeleteKeyExA(hkey, "", access, 0);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
RegCloseKey(hkey);
@ -3254,7 +3181,7 @@ machprod:
CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", "");
res = delete_key(hkey, "", access);
res = RegDeleteKeyExA(hkey, "", access, 0);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
RegCloseKey(hkey);
@ -3286,7 +3213,7 @@ static void test_publish_features(void)
CHAR keypath[MAX_PATH];
REGSAM access = KEY_ALL_ACCESS;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3330,7 +3257,7 @@ static void test_publish_features(void)
RegDeleteValueA(hkey, "feature");
RegDeleteValueA(hkey, "montecristo");
delete_key(hkey, "", access);
RegDeleteKeyExA(hkey, "", access, 0);
RegCloseKey(hkey);
sprintf(keypath, udfeatpath, usersid);
@ -3342,10 +3269,10 @@ static void test_publish_features(void)
RegDeleteValueA(hkey, "feature");
RegDeleteValueA(hkey, "montecristo");
delete_key(hkey, "", access);
RegDeleteKeyExA(hkey, "", access, 0);
RegCloseKey(hkey);
sprintf(keypath, udpridpath, usersid);
delete_key(HKEY_LOCAL_MACHINE, keypath, access);
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath, access, 0);
/* PublishFeatures, machine */
r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
@ -3366,7 +3293,7 @@ static void test_publish_features(void)
RegDeleteValueA(hkey, "feature");
RegDeleteValueA(hkey, "montecristo");
delete_key(hkey, "", access);
RegDeleteKeyExA(hkey, "", access, 0);
RegCloseKey(hkey);
sprintf(keypath, udfeatpath, "S-1-5-18");
@ -3378,10 +3305,10 @@ static void test_publish_features(void)
RegDeleteValueA(hkey, "feature");
RegDeleteValueA(hkey, "montecristo");
delete_key(hkey, "", access);
RegDeleteKeyExA(hkey, "", access, 0);
RegCloseKey(hkey);
sprintf(keypath, udpridpath, "S-1-5-18");
delete_key(HKEY_LOCAL_MACHINE, keypath, access);
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath, access, 0);
error:
DeleteFileA(msifile);
@ -3470,7 +3397,7 @@ static void test_register_user(void)
"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
"UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3513,10 +3440,10 @@ static void test_register_user(void)
RegDeleteValueA(props, "ProductID");
RegDeleteValueA(props, "RegCompany");
RegDeleteValueA(props, "RegOwner");
delete_key(props, "", access);
RegDeleteKeyExA(props, "", access, 0);
RegCloseKey(props);
sprintf(keypath, keypridfmt, usersid);
delete_key(HKEY_LOCAL_MACHINE, keypath, access);
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath, access, 0);
/* RegisterUser, machine */
r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
@ -3535,10 +3462,10 @@ static void test_register_user(void)
RegDeleteValueA(props, "ProductID");
RegDeleteValueA(props, "RegCompany");
RegDeleteValueA(props, "RegOwner");
delete_key(props, "", access);
RegDeleteKeyExA(props, "", access, 0);
RegCloseKey(props);
sprintf(keypath, keypridfmt, "S-1-5-18");
delete_key(HKEY_LOCAL_MACHINE, keypath, access);
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath, access, 0);
error:
free(company);
@ -3566,7 +3493,7 @@ static void test_process_components(void)
CHAR program_files_maximus[MAX_PATH];
REGSAM access = KEY_ALL_ACCESS;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3615,7 +3542,7 @@ static void test_process_components(void)
ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
delete_key(comp, "", access);
RegDeleteKeyExA(comp, "", access, 0);
RegCloseKey(comp);
sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
@ -3633,7 +3560,7 @@ static void test_process_components(void)
ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
delete_key(comp, "", access);
RegDeleteKeyExA(comp, "", access, 0);
RegCloseKey(comp);
/* ProcessComponents, machine */
@ -3657,7 +3584,7 @@ static void test_process_components(void)
ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
delete_key(comp, "", access);
RegDeleteKeyExA(comp, "", access, 0);
RegCloseKey(comp);
sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
@ -3675,7 +3602,7 @@ static void test_process_components(void)
ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
delete_key(comp, "", access);
RegDeleteKeyExA(comp, "", access, 0);
RegCloseKey(comp);
error:
@ -3693,16 +3620,12 @@ static void test_publish(void)
LONG res;
HKEY uninstall, prodkey, uninstall_32node = NULL;
INSTALLSTATE state;
char date[MAX_PATH], temp[MAX_PATH], prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
char date[MAX_PATH], date2[MAX_PATH], temp[MAX_PATH], buf[MAX_PATH];
const char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
REGSAM access = KEY_ALL_ACCESS;
DWORD error;
DWORD error, type, size;
if (!pMsiQueryFeatureStateExA)
{
win_skip("MsiQueryFeatureStateExA is not available\n");
return;
}
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3738,7 +3661,7 @@ static void test_publish(void)
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
r = MsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
@ -3746,7 +3669,7 @@ static void test_publish(void)
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
r = MsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
@ -3754,7 +3677,7 @@ static void test_publish(void)
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
r = MsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
@ -3766,7 +3689,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@ -3794,7 +3717,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@ -3817,7 +3740,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@ -3876,7 +3799,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@ -3898,7 +3821,7 @@ static void test_publish(void)
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
r = MsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
@ -3906,7 +3829,7 @@ static void test_publish(void)
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
r = MsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
@ -3914,7 +3837,7 @@ static void test_publish(void)
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
r = MsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_SUCCESS, "got %u\n", r);
ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
@ -3923,7 +3846,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
@ -3981,7 +3904,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@ -4004,7 +3927,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
@ -4062,7 +3985,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
@ -4120,7 +4043,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
@ -4178,7 +4101,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@ -4201,7 +4124,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
@ -4219,7 +4142,15 @@ static void test_publish(void)
CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
CHECK_REG_STR(prodkey, "InstallDate", date);
get_date_str(date2);
size = ARRAY_SIZE(buf);
buf[0] = '\0';
res = RegQueryValueExA(prodkey, "InstallDate", NULL, &type, (BYTE *)buf, &size);
ok(!res, "Failed to query value, error %ld\n", res);
ok(type == REG_SZ, "Got wrong type %lu\n", type);
ok(!strcmp(buf, date) || !strcmp(buf, date2), "got %s\n", debugstr_a(buf));
CHECK_REG_STR(prodkey, "InstallSource", temp);
CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /X{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
CHECK_REG_STR(prodkey, "Publisher", "Wine");
@ -4259,7 +4190,7 @@ static void test_publish(void)
state = MsiQueryFeatureStateA(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@ -4286,12 +4217,7 @@ static void test_publish_sourcelist(void)
CHAR path[MAX_PATH];
CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
{
win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
return;
}
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4317,16 +4243,16 @@ static void test_publish_sourcelist(void)
/* nothing published */
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
r = MsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
@ -4339,16 +4265,16 @@ static void test_publish_sourcelist(void)
/* after RegisterProduct */
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
r = MsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
@ -4361,16 +4287,16 @@ static void test_publish_sourcelist(void)
/* after ProcessComponents */
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
r = MsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
@ -4383,16 +4309,16 @@ static void test_publish_sourcelist(void)
/* after PublishFeatures */
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
r = MsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == MAX_PATH, "got %lu\n", size);
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
@ -4405,24 +4331,24 @@ static void test_publish_sourcelist(void)
/* after PublishProduct */
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
ok(size == 11, "Expected 11, got %lu\n", size);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATHA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATHA, value, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
ok(size == 0, "Expected 0, got %lu\n", size);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPTA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPTA, value, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
ok(size == 0, "Expected 0, got %lu\n", size);
@ -4432,40 +4358,40 @@ static void test_publish_sourcelist(void)
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
ok(size == lstrlenA(path), "Expected %d, got %lu\n", lstrlenA(path), size);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA, value, &size);
r = MsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA, value, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
ok(size == 1, "Expected 1, got %lu\n", size);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
r = MsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
r = MsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
ok(size == lstrlenA(path), "Expected %d, got %lu\n", lstrlenA(path), size);
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
r = MsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
@ -4489,7 +4415,7 @@ static void test_remove_files(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4624,7 +4550,7 @@ static void test_move_files(void)
UINT r;
char props[4 * MAX_PATH + 74];
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4770,7 +4696,7 @@ static void test_duplicate_files(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4813,7 +4739,7 @@ static void test_write_registry_values(void)
LONG res;
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4981,7 +4907,7 @@ static void test_envvar(void)
HKEY env, env2;
LONG res;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5096,7 +5022,7 @@ static void test_create_remove_folder(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5268,7 +5194,7 @@ static void test_delete_services(void)
SC_HANDLE manager, service;
DWORD error;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5342,7 +5268,7 @@ static void test_install_services(void)
HKEY hKey;
DWORD err_control, err_controlsize, err_controltype;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5418,7 +5344,7 @@ static void test_self_registration(void)
HKEY key;
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5466,7 +5392,7 @@ static void test_register_font(void)
UINT r;
REGSAM access = KEY_ALL_ACCESS;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5517,7 +5443,7 @@ static void test_validate_product_id(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5571,7 +5497,7 @@ static void test_install_remove_odbc(void)
WORD len;
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5654,7 +5580,7 @@ static void test_register_typelib(void)
HRESULT hr;
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5704,7 +5630,7 @@ static void test_create_remove_shortcut(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5753,7 +5679,7 @@ static void test_publish_components(void)
BYTE *data;
DWORD size;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5804,10 +5730,7 @@ static void test_publish_components(void)
"english.txt", INSTALLMODE_DEFAULT, NULL, &size);
ok(r == ERROR_SUCCESS, "MsiProvideQualifiedComponent returned %d\n", r);
if (pRegDeleteKeyExA)
res = pRegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath2, KEY_WOW64_64KEY, 0);
else
res = RegDeleteKeyA(HKEY_LOCAL_MACHINE, keypath2);
res = RegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath2, KEY_WOW64_64KEY, 0);
ok(res == ERROR_SUCCESS, "RegDeleteKey failed %ld\n", res);
res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &key);
@ -5837,7 +5760,7 @@ static void test_remove_duplicate_files(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5887,7 +5810,7 @@ static void test_find_related_products(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5931,7 +5854,7 @@ static void test_ini_values(void)
HANDLE file;
BOOL ret;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5992,7 +5915,7 @@ static void test_register_class_info(void)
LONG res;
HKEY hkey;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6057,7 +5980,7 @@ static void test_register_extension_info(void)
LONG res;
HKEY hkey;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6109,7 +6032,7 @@ static void test_register_progid_info(void)
LONG res;
HKEY hkey;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6235,7 +6158,7 @@ static void test_register_mime_info(void)
LONG res;
HKEY hkey;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6334,7 +6257,7 @@ static void test_publish_assemblies(void)
const char *path;
int access;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6498,7 +6421,7 @@ static void test_remove_existing_products(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6530,18 +6453,64 @@ error:
DeleteFileA(msifile);
}
static HANDLE get_admin_token(void)
{
TOKEN_ELEVATION_TYPE type;
TOKEN_LINKED_TOKEN linked;
DWORD size;
#ifdef __REACTOS__
#ifndef GetCurrentThreadEffectiveToken
#define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
#define GetCurrentThreadEffectiveToken() GetCurrentProcessToken()
#endif
#endif
if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenElevationType, &type, sizeof(type), &size)
|| type == TokenElevationTypeFull)
return NULL;
if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenLinkedToken, &linked, sizeof(linked), &size))
return NULL;
return linked.LinkedToken;
}
void restart_as_admin_elevated(void)
{
HANDLE token;
PROCESS_INFORMATION pi;
STARTUPINFOW si;
if (!(token = get_admin_token())) return;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
if (CreateProcessAsUserW(token, NULL, GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
DWORD exit_code;
trace("restarting\n");
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &exit_code);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
ExitProcess(exit_code);
}
else trace("failed to restart as admin %lu\n", GetLastError());
CloseHandle(token);
}
START_TEST(action)
{
DWORD len;
char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
STATEMGRSTATUS status;
BOOL ret = FALSE;
init_functionpointers();
if (!is_process_elevated()) restart_as_admin_elevated();
subtest("custom");
if (pIsWow64Process)
pIsWow64Process(GetCurrentProcess(), &is_wow64);
IsWow64Process(GetCurrentProcess(), &is_wow64);
GetCurrentDirectoryA(MAX_PATH, prev_path);
GetTempPathA(MAX_PATH, temp_path);
@ -6556,18 +6525,6 @@ START_TEST(action)
ok(get_system_dirs(), "failed to retrieve system dirs\n");
ok(get_user_dirs(), "failed to retrieve user dirs\n");
/* Create a restore point ourselves so we circumvent the multitude of restore points
* that would have been created by all the installation and removal tests.
*
* This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
* creation of restore points.
*/
if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
{
memset(&status, 0, sizeof(status));
ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
}
/* Create only one log file and don't append. We have to pass something
* for the log mode for this to work. The logfile needs to have an absolute
* path otherwise we still end up with some extra logfiles as some tests
@ -6611,13 +6568,5 @@ START_TEST(action)
test_remove_existing_products();
DeleteFileA(log_file);
if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
{
ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
if (ret)
remove_restore_point(status.llSequenceNumber);
}
SetCurrentDirectoryA(prev_path);
}

View file

@ -32,6 +32,7 @@
#include <oaidl.h>
#include "wine/test.h"
#include "utils.h"
#ifdef __REACTOS__
#include "ole2.h"
@ -39,14 +40,10 @@
static BOOL is_wow64;
static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
static const char *msifile = "winetest-automation.msi";
static FILETIME systemtime;
static CHAR CURR_DIR[MAX_PATH];
static EXCEPINFO excepinfo;
/*
@ -156,13 +153,6 @@ static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_
"regdata\t1\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
"OrderTest\t1\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent\n";
typedef struct _msi_table
{
const CHAR *filename;
const CHAR *data;
int size;
} msi_table;
#define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
static const msi_table tables[] =
@ -202,65 +192,6 @@ static const msi_summary_info summary_info[] =
ADD_INFO_FILETIME(PID_LASTPRINTED, &systemtime)
};
static void init_functionpointers(void)
{
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
#define GET_PROC(dll, func) \
p ## func = (void *)GetProcAddress(dll, #func); \
if(!p ## func) \
trace("GetProcAddress(%s) failed\n", #func);
GET_PROC(hadvapi32, RegDeleteKeyExA)
GET_PROC(hkernel32, IsWow64Process)
#undef GET_PROC
}
static BOOL is_process_limited(void)
{
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
PSID Group = NULL;
BOOL IsInGroup;
HANDLE token;
if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
!CheckTokenMembership(NULL, Group, &IsInGroup))
{
trace("Could not check if the current user is an administrator\n");
FreeSid(Group);
return FALSE;
}
FreeSid(Group);
if (!IsInGroup)
{
/* Only administrators have enough privileges for these tests */
return TRUE;
}
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
{
BOOL ret;
TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
DWORD size;
ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
CloseHandle(token);
return (ret && type == TokenElevationTypeLimited);
}
return FALSE;
}
static LONG delete_key_portable( HKEY key, LPCSTR subkey, REGSAM access )
{
if (pRegDeleteKeyExA)
return pRegDeleteKeyExA( key, subkey, access, 0 );
return RegDeleteKeyA( key, subkey );
}
/*
* Database Helpers
*/
@ -301,8 +232,8 @@ static void write_msi_summary_info(MSIHANDLE db, const msi_summary_info *info, i
MsiCloseHandle(summary);
}
static void create_database(const CHAR *name, const msi_table *tables, int num_tables,
const msi_summary_info *info, int num_info)
static void create_database_suminfo(const CHAR *name, const msi_table *tables, int num_tables,
const msi_summary_info *info, int num_info)
{
MSIHANDLE db;
UINT r;
@ -343,7 +274,7 @@ static BOOL create_package(LPWSTR path)
DWORD len;
/* Prepare package */
create_database(msifile, tables, ARRAY_SIZE(tables), summary_info, ARRAY_SIZE(summary_info));
create_database_suminfo(msifile, tables, ARRAY_SIZE(tables), summary_info, ARRAY_SIZE(summary_info));
len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
CURR_DIR, -1, path, MAX_PATH);
@ -359,8 +290,6 @@ static BOOL create_package(LPWSTR path)
* Installation helpers
*/
static char PROG_FILES_DIR[MAX_PATH];
static BOOL get_program_files_dir(LPSTR buf)
{
HKEY hkey;
@ -378,24 +307,6 @@ static BOOL get_program_files_dir(LPSTR buf)
return TRUE;
}
static void create_file(const CHAR *name, DWORD size)
{
HANDLE file;
DWORD written, left;
file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
WriteFile(file, name, strlen(name), &written, NULL);
WriteFile(file, "\n", strlen("\n"), &written, NULL);
left = size - lstrlenA(name) - 1;
SetFilePointer(file, left, NULL, FILE_CURRENT);
SetEndOfFile(file);
CloseHandle(file);
}
static void create_test_files(void)
{
CreateDirectoryA("msitest", NULL);
@ -411,23 +322,8 @@ static void create_test_files(void)
create_file("msitest\\filename", 100);
}
static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
{
CHAR path[MAX_PATH];
lstrcpyA(path, PROG_FILES_DIR);
lstrcatA(path, "\\");
lstrcatA(path, rel_path);
if (is_file)
return DeleteFileA(path);
else
return RemoveDirectoryA(path);
}
static void delete_test_files(void)
{
DeleteFileA(msifile);
DeleteFileA("msitest\\cabout\\new\\five.txt");
DeleteFileA("msitest\\cabout\\four.txt");
DeleteFileA("msitest\\second\\three.txt");
@ -2341,7 +2237,7 @@ static UINT delete_registry_key(HKEY hkeyParent, LPCSTR subkey, REGSAM access)
RegCloseKey(hkey);
free(string);
delete_key_portable(hkeyParent, subkey, access);
RegDeleteKeyExA(hkeyParent, subkey, access, 0);
return ERROR_SUCCESS;
}
@ -2391,7 +2287,7 @@ static void test_Installer_InstallProduct(void)
IDispatch *pStringList = NULL;
REGSAM access = KEY_ALL_ACCESS;
if (is_process_limited())
if (!is_process_elevated())
{
/* In fact InstallProduct would succeed but then Windows XP
* would not allow us to clean up the registry!
@ -2521,13 +2417,13 @@ static void test_Installer_InstallProduct(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
/* Remove registry keys written by RegisterProduct standard action */
res = delete_key_portable(HKEY_LOCAL_MACHINE,
res = RegDeleteKeyExA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{837450fa-a39b-4bc8-b321-08b393f784b3}",
KEY_WOW64_32KEY);
KEY_WOW64_32KEY, 0);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
res = delete_key_portable(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\D8E760ECA1E276347B43E42BDBDA5656", access);
res = RegDeleteKeyExA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\D8E760ECA1E276347B43E42BDBDA5656", access, 0);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
res = find_registry_key(HKEY_LOCAL_MACHINE,
@ -2538,8 +2434,8 @@ static void test_Installer_InstallProduct(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
RegCloseKey(hkey);
res = delete_key_portable(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products\\af054738b93a8cb43b12803b397f483b", access);
res = RegDeleteKeyExA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products\\af054738b93a8cb43b12803b397f483b", access, 0);
ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
/* Remove registry keys written by PublishProduct standard action */
@ -2695,6 +2591,7 @@ static void test_Installer(void)
/* Installer::InstallProduct and other tests that depend on our product being installed */
test_Installer_InstallProduct();
DeleteFileA(msifile);
}
START_TEST(automation)
@ -2705,10 +2602,9 @@ START_TEST(automation)
CLSID clsid;
IUnknown *pUnk;
init_functionpointers();
if (!is_process_elevated()) restart_as_admin_elevated();
if (pIsWow64Process)
pIsWow64Process(GetCurrentProcess(), &is_wow64);
IsWow64Process(GetCurrentProcess(), &is_wow64);
GetSystemTimeAsFileTime(&systemtime);
@ -2745,6 +2641,5 @@ START_TEST(automation)
}
OleUninitialize();
SetCurrentDirectoryA(prev_path);
}

File diff suppressed because it is too large Load diff

View file

@ -29,6 +29,7 @@
#include <msiquery.h>
#include "wine/test.h"
#include "utils.h"
static const char *msifile = "winetest-db.msi";
static const char *msifile2 = "winetst2-db.msi";
@ -212,22 +213,6 @@ static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
return ret;
}
static UINT run_query( MSIHANDLE hdb, MSIHANDLE hrec, const char *query )
{
MSIHANDLE hview = 0;
UINT r;
r = MsiDatabaseOpenViewA(hdb, query, &hview);
if( r != ERROR_SUCCESS )
return r;
r = MsiViewExecute(hview, hrec);
if( r == ERROR_SUCCESS )
r = MsiViewClose(hview);
MsiCloseHandle(hview);
return r;
}
static UINT run_queryW( MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query )
{
MSIHANDLE hview = 0;
@ -1502,29 +1487,6 @@ static void test_longstrings(void)
DeleteFileA(msifile);
}
static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
{
HANDLE file;
DWORD written;
file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
WriteFile(file, data, strlen(data), &written, NULL);
WriteFile(file, "\n", strlen("\n"), &written, NULL);
if (size)
{
SetFilePointer(file, size, NULL, FILE_BEGIN);
SetEndOfFile(file);
}
CloseHandle(file);
}
#define create_file(name) create_file_data(name, name, 0)
static void test_streamtable(void)
{
MSIHANDLE hdb = 0, rec, view, hsi;
@ -1607,7 +1569,7 @@ static void test_streamtable(void)
MsiCloseHandle( view );
/* insert a file into the _Streams table */
create_file( "test.txt" );
create_file( "test.txt", 0 );
rec = MsiCreateRecord( 2 );
MsiRecordSetStringA( rec, 1, "data" );
@ -1629,7 +1591,7 @@ static void test_streamtable(void)
MsiCloseHandle( view );
/* insert another one */
create_file( "test1.txt" );
create_file( "test1.txt", 0 );
rec = MsiCreateRecord( 2 );
MsiRecordSetStringA( rec, 1, "data1" );
@ -1651,7 +1613,7 @@ static void test_streamtable(void)
MsiCloseHandle( view );
/* try again */
create_file( "test1.txt" );
create_file( "test1.txt", 0 );
rec = MsiCreateRecord( 2 );
MsiRecordSetStringA( rec, 1, "data1" );
@ -1691,7 +1653,7 @@ static void test_streamtable(void)
memset(buf, 0, MAX_PATH);
r = MsiRecordReadStream( rec, 2, buf, &size );
ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf);
ok( !lstrcmpA(buf, "test.txt"), "Expected 'test.txt', got %s\n", buf);
MsiCloseHandle( rec );
MsiViewClose( view );
@ -1716,14 +1678,14 @@ static void test_streamtable(void)
memset(buf, 0, MAX_PATH);
r = MsiRecordReadStream( rec, 2, buf, &size );
ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
ok( !lstrcmpA(buf, "test1.txt\n"), "Expected 'test1.txt\\n', got %s\n", buf);
ok( !lstrcmpA(buf, "test1.txt"), "Expected 'test1.txt', got %s\n", buf);
MsiCloseHandle( rec );
MsiViewClose( view );
MsiCloseHandle( view );
/* perform an update */
create_file( "test2.txt" );
create_file( "test2.txt", 0 );
rec = MsiCreateRecord( 1 );
r = MsiRecordSetStreamA( rec, 1, "test2.txt" );
@ -1761,7 +1723,7 @@ static void test_streamtable(void)
memset(buf, 0, MAX_PATH);
r = MsiRecordReadStream( rec, 2, buf, &size );
ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
ok( !lstrcmpA(buf, "test2.txt\n"), "Expected 'test2.txt\\n', got %s\n", buf);
ok( !lstrcmpA(buf, "test2.txt"), "Expected 'test2.txt', got %s\n", buf);
MsiCloseHandle( rec );
MsiViewClose( view );
@ -1773,7 +1735,7 @@ static void test_streamtable(void)
r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb);
ok(r == ERROR_SUCCESS, "Failed to create database\n");
ok( hdb, "failed to create db\n");
create_file( "test.txt" );
create_file( "test.txt", 0 );
rec = MsiCreateRecord( 2 );
MsiRecordSetStringA( rec, 1, "data" );
r = MsiRecordSetStreamA( rec, 2, "test.txt" );
@ -1809,7 +1771,7 @@ static void test_streamtable(void)
memset(buf, 0, MAX_PATH);
r = MsiRecordReadStream( rec, 2, buf, &size );
ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got '%s' (%lu)\n", buf, size);
ok( !lstrcmpA(buf, "test.txt"), "Expected 'test.txt', got '%s' (%lu)\n", buf, size);
MsiCloseHandle( rec );
/* open a handle to the "data" stream (and keep it open during removal) */
@ -1865,7 +1827,7 @@ static void test_binary(void)
r = run_query( hdb, 0, query );
ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r );
create_file( "test.txt" );
create_file( "test.txt", 0 );
rec = MsiCreateRecord( 1 );
r = MsiRecordSetStreamA( rec, 1, "test.txt" );
ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
@ -1892,7 +1854,7 @@ static void test_binary(void)
r = run_query( hdb, 0, query );
ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r );
create_file( "test.txt" );
create_file( "test.txt", 0 );
rec = MsiCreateRecord( 1 );
r = MsiRecordSetStreamA( rec, 1, "test.txt" );
ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r );
@ -1932,7 +1894,7 @@ static void test_binary(void)
memset( buf, 0, MAX_PATH );
r = MsiRecordReadStream( rec, 2, buf, &size );
ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
ok( !lstrcmpA(buf, "test.txt"), "Expected 'test.txt', got %s\n", buf );
r = MsiCloseHandle( rec );
ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
@ -1951,7 +1913,7 @@ static void test_binary(void)
memset( buf, 0, MAX_PATH );
r = MsiRecordReadStream( rec, 3, buf, &size );
ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
ok( !lstrcmpA(buf, "test.txt"), "Expected 'test.txt', got %s\n", buf );
r = MsiCloseHandle( rec );
ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
@ -2178,8 +2140,6 @@ static void test_where(void)
DeleteFileA(msifile);
}
static CHAR CURR_DIR[MAX_PATH];
static const CHAR test_data[] = "FirstPrimaryColumn\tSecondPrimaryColumn\tShortInt\tShortIntNullable\tLongInt\tLongIntNullable\tString\tLocalizableString\tLocalizableStringNullable\n"
"s255\ti2\ti2\tI2\ti4\tI4\tS255\tS0\ts0\n"
"TestTable\tFirstPrimaryColumn\n"
@ -7992,7 +7952,7 @@ static void test_dbmerge(void)
r = run_query(href, 0, query);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
create_file("binary.dat");
create_file("binary.dat", 0);
hrec = MsiCreateRecord(1);
MsiRecordSetStreamA(hrec, 1, "binary.dat");
@ -8017,8 +7977,7 @@ static void test_dbmerge(void)
ZeroMemory(buf, MAX_PATH);
r = MsiRecordReadStream(hrec, 2, buf, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(buf, "binary.dat\n"),
"Expected \"binary.dat\\n\", got \"%s\"\n", buf);
ok(!lstrcmpA(buf, "binary.dat"), "Expected \"binary.dat\", got \"%s\"\n", buf);
MsiCloseHandle(hrec);
@ -8584,6 +8543,18 @@ static void test_embedded_nulls(void)
"s72\tL0\n"
"Control\tDialog\n"
"LicenseAgreementDlg\ttext\x11\x19text\0text";
static const char export_expected[] =
"Dialog\tText\r\n"
"s72\tL0\r\n"
"Control\tDialog\r\n"
"LicenseAgreementDlg\ttext\x11\x19text\x19text";
/* newlines have alternate representation in idt files */
static const char control_table2[] =
"Dialog\tText\n"
"s72\tL0\n"
"Control\tDialog\n"
"LicenseAgreementDlg\ttext\x11\x19te\nxt\0text";
char data[1024];
UINT r;
DWORD sz;
MSIHANDLE hdb, hrec;
@ -8607,9 +8578,27 @@ static void test_embedded_nulls(void)
ok( r == ERROR_SUCCESS, "failed to get string %u\n", r );
ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer );
r = MsiDatabaseExportA( hdb, "Control", CURR_DIR, "temp_file1");
ok( r == ERROR_SUCCESS, "failed to export table %u\n", r );
read_file_data( "temp_file1", data );
ok( !memcmp( data, export_expected, sizeof(export_expected) - 1), "expected: \"%s\" got: \"%s\"\n", export_expected, data );
DeleteFileA( "temp_file1" );
MsiCloseHandle( hrec );
MsiCloseHandle( hdb );
DeleteFileA( msifile );
r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_CREATE, &hdb );
ok( r == ERROR_SUCCESS, "failed to open database %u\n", r );
GetCurrentDirectoryA( MAX_PATH, CURR_DIR );
write_file( "temp_file", control_table2, sizeof(control_table2) );
r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" );
ok( r == ERROR_FUNCTION_FAILED, "failed to import table %u\n", r );
DeleteFileA( "temp_file" );
MsiCloseHandle( hdb );
DeleteFileA( msifile );
}
static void test_select_column_names(void)

View file

@ -29,7 +29,6 @@
#include <msi.h>
#include <fci.h>
#include <objidl.h>
#include <srrestoreptapi.h>
#include <shlobj.h>
#include <winsvc.h>
#include <shellapi.h>
@ -37,21 +36,6 @@
#include "wine/test.h"
#include "utils.h"
static UINT (WINAPI *pMsiQueryComponentStateA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
static UINT (WINAPI *pMsiSourceListEnumSourcesA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(void **);
static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(void *);
static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
static BOOL is_wow64;
static const BOOL is_64bit = sizeof(void *) > sizeof(int);
@ -2224,67 +2208,17 @@ static int CDECL fci_delete(char *pszFile, int *err, void *pv)
return 0;
}
static void init_functionpointers(void)
BOOL is_process_elevated(void)
{
HMODULE hmsi = GetModuleHandleA("msi.dll");
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
HMODULE hsrclient = LoadLibraryA("srclient.dll");
#define GET_PROC(mod, func) \
p ## func = (void*)GetProcAddress(mod, #func); \
if(!p ## func) \
trace("GetProcAddress(%s) failed\n", #func);
GET_PROC(hmsi, MsiQueryComponentStateA);
GET_PROC(hmsi, MsiSourceListEnumSourcesA);
GET_PROC(hmsi, MsiGetComponentPathExA);
GET_PROC(hadvapi32, RegDeleteKeyExA)
GET_PROC(hkernel32, IsWow64Process)
GET_PROC(hkernel32, Wow64DisableWow64FsRedirection);
GET_PROC(hkernel32, Wow64RevertWow64FsRedirection);
GET_PROC(hsrclient, SRRemoveRestorePoint);
GET_PROC(hsrclient, SRSetRestorePointA);
#undef GET_PROC
}
BOOL is_process_limited(void)
{
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
PSID Group = NULL;
BOOL IsInGroup;
HANDLE token;
TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
DWORD size;
BOOL ret;
if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
!CheckTokenMembership(NULL, Group, &IsInGroup))
{
trace("Could not check if the current user is an administrator\n");
FreeSid(Group);
return FALSE;
}
FreeSid(Group);
if (!IsInGroup)
{
/* Only administrators have enough privileges for these tests */
return TRUE;
}
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
{
BOOL ret;
TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
DWORD size;
ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
CloseHandle(token);
return (ret && type == TokenElevationTypeLimited);
}
return FALSE;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) return FALSE;
ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
CloseHandle(token);
return (ret && type == TokenElevationTypeFull);
}
static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
@ -2734,34 +2668,6 @@ void create_database_wordcount(const CHAR *name, const msi_table *tables, int nu
free( nameW );
}
static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
{
RESTOREPOINTINFOA spec;
spec.dwEventType = event_type;
spec.dwRestorePtType = APPLICATION_INSTALL;
spec.llSequenceNumber = status->llSequenceNumber;
lstrcpyA(spec.szDescription, "msitest restore point");
return pSRSetRestorePointA(&spec, status);
}
static void remove_restore_point(DWORD seq_number)
{
DWORD res;
res = pSRRemoveRestorePoint(seq_number);
if (res != ERROR_SUCCESS)
trace("Failed to remove the restore point: %#lx\n", res);
}
static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
{
if (pRegDeleteKeyExA)
return pRegDeleteKeyExA( key, subkey, access, 0 );
return RegDeleteKeyA( key, subkey );
}
static void test_MsiInstallProduct(void)
{
UINT r;
@ -2771,7 +2677,7 @@ static void test_MsiInstallProduct(void)
DWORD num, size, type;
REGSAM access = KEY_ALL_ACCESS;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -2836,7 +2742,7 @@ static void test_MsiInstallProduct(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
delete_key(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", access);
RegDeleteKeyExA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", access, 0);
/* not published, reinstall */
r = MsiInstallProductA(msifile, NULL);
@ -3116,7 +3022,7 @@ static void test_continuouscabs(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3309,7 +3215,7 @@ static void test_mixedmedia(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3429,7 +3335,7 @@ static void test_readonlyfile(void)
HANDLE file;
CHAR path[MAX_PATH];
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3478,7 +3384,7 @@ static void test_readonlyfile_cab(void)
CHAR path[MAX_PATH];
CHAR buf[16];
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3535,7 +3441,7 @@ static void test_setdirproperty(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3568,7 +3474,7 @@ static void test_cabisextracted(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3809,7 +3715,7 @@ static void test_transformprop(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3857,7 +3763,7 @@ static void test_currentworkingdir(void)
CHAR drive[MAX_PATH], path[MAX_PATH + 12];
LPSTR ptr;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4015,7 +3921,7 @@ static void test_adminprops(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4066,7 +3972,7 @@ static void test_missingcab(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4136,7 +4042,7 @@ static void test_sourcefolder(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4239,7 +4145,7 @@ static void test_customaction51(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4272,7 +4178,7 @@ static void test_installstate(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4758,7 +4664,7 @@ static void test_missingcomponent(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4814,7 +4720,7 @@ static void test_sourcedirprop(void)
UINT r;
CHAR props[MAX_PATH + 18];
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4865,7 +4771,7 @@ static void test_adminimage(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4936,7 +4842,7 @@ static void test_propcase(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5042,7 +4948,7 @@ static void test_shortcut(void)
UINT r;
HRESULT hr;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5089,7 +4995,7 @@ static void test_preselected(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5145,7 +5051,7 @@ static void test_installed_prop(void)
static const char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5184,7 +5090,7 @@ static void test_allusers_prop(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5305,7 +5211,7 @@ static void process_pending_renames(HKEY hkey)
else
{
fileret = DeleteFileA(src);
ok(fileret || broken(!fileret) /* win2k3 */, "Failed to delete file %s (%lu)\n", src, GetLastError());
ok(fileret, "Failed to delete file %s (%lu)\n", src, GetLastError());
}
}
@ -5345,7 +5251,7 @@ static void test_file_in_use(void)
HKEY hkey;
char path[MAX_PATH];
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5404,7 +5310,7 @@ static void test_file_in_use_cab(void)
HKEY hkey;
char path[MAX_PATH];
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5465,7 +5371,7 @@ static void test_feature_override(void)
UINT r;
REGSAM access = KEY_ALL_ACCESS;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5527,7 +5433,7 @@ static void test_feature_override(void)
ok(!delete_pf("msitest\\preselected.txt", TRUE), "file not removed\n");
ok(!delete_pf("msitest", FALSE), "directory not removed\n");
delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", access);
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", access, 0);
error:
DeleteFileA("msitest\\override.txt");
@ -5545,7 +5451,7 @@ static void test_icon_table(void)
CHAR path[MAX_PATH];
static const char prodcode[] = "{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}";
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5623,7 +5529,7 @@ static void test_package_validation(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5814,7 +5720,7 @@ static void test_upgrade_code(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5850,7 +5756,7 @@ static void test_mixed_package(void)
char value[MAX_PATH];
DWORD size;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -5913,7 +5819,7 @@ static void test_mixed_package(void)
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
ok(res == ERROR_FILE_NOT_FOUND || broken(!res), "32-bit component key not removed\n");
ok(res == ERROR_FILE_NOT_FOUND, "32-bit component key not removed\n");
res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
ok(res == ERROR_FILE_NOT_FOUND, "64-bit component key not removed\n");
@ -5976,7 +5882,7 @@ static void test_mixed_package(void)
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
ok(res == ERROR_FILE_NOT_FOUND || broken(!res), "32-bit component key not removed\n");
ok(res == ERROR_FILE_NOT_FOUND, "32-bit component key not removed\n");
res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
ok(res == ERROR_FILE_NOT_FOUND, "64-bit component key not removed\n");
@ -5999,7 +5905,7 @@ static void test_volume_props(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6025,7 +5931,7 @@ static void test_shared_component(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6074,7 +5980,7 @@ static void test_remove_upgrade_code(void)
DWORD type, size;
char buf[1];
if (is_process_limited())
if (!is_process_elevated())
{
skip( "process is limited\n" );
return;
@ -6120,7 +6026,7 @@ static void test_feature_tree(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip( "process is limited\n" );
return;
@ -6197,7 +6103,7 @@ static void test_wow64(void)
return;
}
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -6212,7 +6118,7 @@ static void test_wow64(void)
goto error;
}
pWow64DisableWow64FsRedirection(&cookie);
Wow64DisableWow64FsRedirection(&cookie);
ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
@ -6238,7 +6144,7 @@ static void test_wow64(void)
ok(delete_pf_native("msitest\\filename", TRUE), "File not installed\n");
ok(delete_pf_native("msitest", FALSE), "Directory not created\n");
pWow64RevertWow64FsRedirection(cookie);
Wow64RevertWow64FsRedirection(cookie);
error:
delete_test_files();
@ -6250,7 +6156,7 @@ static void test_source_resolution(void)
{
UINT r;
if (is_process_limited())
if (!is_process_elevated())
{
skip( "process is limited\n" );
return;
@ -6279,14 +6185,12 @@ START_TEST(install)
{
DWORD len;
char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
STATEMGRSTATUS status;
BOOL ret = FALSE;
init_functionpointers();
if (!is_process_elevated()) restart_as_admin_elevated();
subtest("custom");
if (pIsWow64Process)
pIsWow64Process(GetCurrentProcess(), &is_wow64);
IsWow64Process(GetCurrentProcess(), &is_wow64);
GetCurrentDirectoryA(MAX_PATH, prev_path);
GetTempPathA(MAX_PATH, temp_path);
@ -6301,18 +6205,6 @@ START_TEST(install)
ok(get_system_dirs(), "failed to retrieve system dirs\n");
ok(get_user_dirs(), "failed to retrieve user dirs\n");
/* Create a restore point ourselves so we circumvent the multitude of restore points
* that would have been created by all the installation and removal tests.
*
* This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
* creation of restore points.
*/
if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
{
memset(&status, 0, sizeof(status));
ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
}
/* Create only one log file and don't append. We have to pass something
* for the log mode for this to work. The logfile needs to have an absolute
* path otherwise we still end up with some extra logfiles as some tests
@ -6322,8 +6214,7 @@ START_TEST(install)
lstrcatA(log_file, "\\msitest.log");
MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
if (pSRSetRestorePointA) /* test has side-effects on win2k3 that cause failures in following tests */
test_MsiInstallProduct();
test_MsiInstallProduct();
test_MsiSetComponentState();
test_packagecoltypes();
test_continuouscabs();
@ -6370,15 +6261,6 @@ START_TEST(install)
test_source_resolution();
DeleteFileA(customdll);
DeleteFileA(log_file);
if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
{
ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
if (ret)
remove_restore_point(status.llSequenceNumber);
}
SetCurrentDirectoryA(prev_path);
}

File diff suppressed because it is too large Load diff

View file

@ -32,96 +32,11 @@
#include <sddl.h>
#include "wine/test.h"
#include "utils.h"
static BOOL is_wow64;
static const char msifile[] = "winetest-package.msi";
static const WCHAR msifileW[] = L"winetest-package.msi";
static char CURR_DIR[MAX_PATH];
static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
static void init_functionpointers(void)
{
HMODULE hmsi = GetModuleHandleA("msi.dll");
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
HMODULE hsrclient = LoadLibraryA("srclient.dll");
#define GET_PROC(mod, func) \
p ## func = (void*)GetProcAddress(mod, #func);
GET_PROC(hmsi, MsiGetComponentPathExA);
GET_PROC(hadvapi32, RegDeleteKeyExA)
GET_PROC(hadvapi32, RegDeleteKeyExW)
GET_PROC(hkernel32, IsWow64Process)
GET_PROC(hsrclient, SRRemoveRestorePoint);
GET_PROC(hsrclient, SRSetRestorePointA);
#undef GET_PROC
}
static BOOL is_process_limited(void)
{
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
PSID Group = NULL;
BOOL IsInGroup;
HANDLE token;
if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
!CheckTokenMembership(NULL, Group, &IsInGroup))
{
trace("Could not check if the current user is an administrator\n");
FreeSid(Group);
return FALSE;
}
FreeSid(Group);
if (!IsInGroup)
{
if (!AllocateAndInitializeSid(&NtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_POWER_USERS,
0, 0, 0, 0, 0, 0, &Group) ||
!CheckTokenMembership(NULL, Group, &IsInGroup))
{
trace("Could not check if the current user is a power user\n");
return FALSE;
}
if (!IsInGroup)
{
/* Only administrators and power users can be powerful */
return TRUE;
}
}
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
{
BOOL ret;
TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
DWORD size;
ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
CloseHandle(token);
return (ret && type == TokenElevationTypeLimited);
}
return FALSE;
}
static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
{
if (pRegDeleteKeyExA)
return pRegDeleteKeyExA( key, subkey, access, 0 );
return RegDeleteKeyA( key, subkey );
}
static char *get_user_sid(void)
{
@ -186,12 +101,7 @@ static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM acce
}
if (lpszSubKey)
{
if (pRegDeleteKeyExW)
ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0);
else
ret = RegDeleteKeyW(hKey, lpszSubKey);
}
ret = RegDeleteKeyExW(hKey, lpszSubKey, access, 0);
else
while (TRUE)
{
@ -402,25 +312,9 @@ static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
return ret;
}
static UINT run_query( MSIHANDLE hdb, const char *query )
{
MSIHANDLE hview = 0;
UINT r;
r = MsiDatabaseOpenViewA(hdb, query, &hview);
if( r != ERROR_SUCCESS )
return r;
r = MsiViewExecute(hview, 0);
if( r == ERROR_SUCCESS )
r = MsiViewClose(hview);
MsiCloseHandle(hview);
return r;
}
static UINT create_component_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `Component` ( "
"`Component` CHAR(72) NOT NULL, "
"`ComponentId` CHAR(38), "
@ -435,7 +329,7 @@ static UINT create_component_table( MSIHANDLE hdb )
static UINT create_feature_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `Feature` ( "
"`Feature` CHAR(38) NOT NULL, "
"`Feature_Parent` CHAR(38), "
@ -452,7 +346,7 @@ static UINT create_feature_table( MSIHANDLE hdb )
static UINT create_feature_components_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `FeatureComponents` ( "
"`Feature_` CHAR(38) NOT NULL, "
"`Component_` CHAR(72) NOT NULL "
@ -463,7 +357,7 @@ static UINT create_feature_components_table( MSIHANDLE hdb )
static UINT create_file_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `File` ("
"`File` CHAR(72) NOT NULL, "
"`Component_` CHAR(72) NOT NULL, "
@ -480,7 +374,7 @@ static UINT create_file_table( MSIHANDLE hdb )
static UINT create_remove_file_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `RemoveFile` ("
"`FileKey` CHAR(72) NOT NULL, "
"`Component_` CHAR(72) NOT NULL, "
@ -494,7 +388,7 @@ static UINT create_remove_file_table( MSIHANDLE hdb )
static UINT create_appsearch_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `AppSearch` ("
"`Property` CHAR(72) NOT NULL, "
"`Signature_` CHAR(72) NOT NULL "
@ -505,7 +399,7 @@ static UINT create_appsearch_table( MSIHANDLE hdb )
static UINT create_reglocator_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `RegLocator` ("
"`Signature_` CHAR(72) NOT NULL, "
"`Root` SHORT NOT NULL, "
@ -519,7 +413,7 @@ static UINT create_reglocator_table( MSIHANDLE hdb )
static UINT create_signature_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `Signature` ("
"`Signature` CHAR(72) NOT NULL, "
"`FileName` CHAR(255) NOT NULL, "
@ -537,7 +431,7 @@ static UINT create_signature_table( MSIHANDLE hdb )
static UINT create_launchcondition_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `LaunchCondition` ("
"`Condition` CHAR(255) NOT NULL, "
"`Description` CHAR(255) NOT NULL "
@ -548,7 +442,7 @@ static UINT create_launchcondition_table( MSIHANDLE hdb )
static UINT create_property_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `Property` ("
"`Property` CHAR(72) NOT NULL, "
"`Value` CHAR(0) "
@ -559,7 +453,7 @@ static UINT create_property_table( MSIHANDLE hdb )
static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `InstallExecuteSequence` ("
"`Action` CHAR(72) NOT NULL, "
"`Condition` CHAR(255), "
@ -571,7 +465,7 @@ static UINT create_install_execute_sequence_table( MSIHANDLE hdb )
static UINT create_install_ui_sequence_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `InstallUISequence` ("
"`Action` CHAR(72) NOT NULL, "
"`Condition` CHAR(255), "
@ -583,7 +477,7 @@ static UINT create_install_ui_sequence_table( MSIHANDLE hdb )
static UINT create_media_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `Media` ("
"`DiskId` SHORT NOT NULL, "
"`LastSequence` SHORT NOT NULL, "
@ -598,7 +492,7 @@ static UINT create_media_table( MSIHANDLE hdb )
static UINT create_ccpsearch_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `CCPSearch` ("
"`Signature_` CHAR(72) NOT NULL "
"PRIMARY KEY `Signature_`)" );
@ -608,7 +502,7 @@ static UINT create_ccpsearch_table( MSIHANDLE hdb )
static UINT create_drlocator_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `DrLocator` ("
"`Signature_` CHAR(72) NOT NULL, "
"`Parent` CHAR(72), "
@ -621,7 +515,7 @@ static UINT create_drlocator_table( MSIHANDLE hdb )
static UINT create_complocator_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `CompLocator` ("
"`Signature_` CHAR(72) NOT NULL, "
"`ComponentId` CHAR(38) NOT NULL, "
@ -633,7 +527,7 @@ static UINT create_complocator_table( MSIHANDLE hdb )
static UINT create_inilocator_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `IniLocator` ("
"`Signature_` CHAR(72) NOT NULL, "
"`FileName` CHAR(255) NOT NULL, "
@ -648,7 +542,7 @@ static UINT create_inilocator_table( MSIHANDLE hdb )
static UINT create_custom_action_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `CustomAction` ("
"`Action` CHAR(72) NOT NULL, "
"`Type` SHORT NOT NULL, "
@ -661,7 +555,7 @@ static UINT create_custom_action_table( MSIHANDLE hdb )
static UINT create_dialog_table( MSIHANDLE hdb )
{
UINT r = run_query(hdb,
UINT r = run_query(hdb, 0,
"CREATE TABLE `Dialog` ("
"`Dialog` CHAR(72) NOT NULL, "
"`HCentering` SHORT NOT NULL, "
@ -680,7 +574,7 @@ static UINT create_dialog_table( MSIHANDLE hdb )
static UINT create_control_table( MSIHANDLE hdb )
{
UINT r = run_query(hdb,
UINT r = run_query(hdb, 0,
"CREATE TABLE `Control` ("
"`Dialog_` CHAR(72) NOT NULL, "
"`Control` CHAR(50) NOT NULL, "
@ -701,7 +595,7 @@ static UINT create_control_table( MSIHANDLE hdb )
static UINT create_controlevent_table( MSIHANDLE hdb )
{
UINT r = run_query(hdb,
UINT r = run_query(hdb, 0,
"CREATE TABLE `ControlEvent` ("
"`Dialog_` CHAR(72) NOT NULL, "
"`Control_` CHAR(50) NOT NULL, "
@ -716,7 +610,7 @@ static UINT create_controlevent_table( MSIHANDLE hdb )
static UINT create_actiontext_table( MSIHANDLE hdb )
{
UINT r = run_query(hdb,
UINT r = run_query(hdb, 0,
"CREATE TABLE `ActionText` ("
"`Action` CHAR(72) NOT NULL, "
"`Description` CHAR(64) LOCALIZABLE, "
@ -728,7 +622,7 @@ static UINT create_actiontext_table( MSIHANDLE hdb )
static UINT create_upgrade_table( MSIHANDLE hdb )
{
UINT r = run_query( hdb,
UINT r = run_query( hdb, 0,
"CREATE TABLE `Upgrade` ("
"`UpgradeCode` CHAR(38) NOT NULL, "
"`VersionMin` CHAR(20), "
@ -750,7 +644,7 @@ static inline UINT add_entry(const char *file, int line, const char *type, MSIHA
sz = strlen(values) + strlen(insert) + 1;
query = malloc(sz);
sprintf(query, insert, values);
r = run_query(hdb, query);
r = run_query(hdb, 0, query);
free(query);
ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r);
return r;
@ -867,7 +761,7 @@ static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, con
sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
query = malloc( sz );
sprintf( query, insert, sig, root, path, name, type );
r = run_query( hdb, query );
r = run_query( hdb, 0, query );
free( query );
ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \
return r;
@ -937,7 +831,7 @@ static MSIHANDLE create_package_db(void)
res = set_summary_info(hdb);
ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
res = run_query( hdb,
res = run_query( hdb, 0,
"CREATE TABLE `Directory` ( "
"`Directory` CHAR(255) NOT NULL, "
"`Directory_Parent` CHAR(255), "
@ -973,25 +867,9 @@ static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
return ERROR_SUCCESS;
}
static void create_file_data(LPCSTR name, LPCSTR data)
{
HANDLE file;
DWORD written;
file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
if (file == INVALID_HANDLE_VALUE)
return;
WriteFile(file, data, strlen(data), &written, NULL);
WriteFile(file, "\n", strlen("\n"), &written, NULL);
CloseHandle(file);
}
static void create_test_file(const CHAR *name)
{
create_file_data(name, name);
create_file_data(name, name, strlen(name));
}
typedef struct _tagVS_VERSIONINFO
@ -1057,27 +935,6 @@ done:
return ret;
}
static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
{
RESTOREPOINTINFOA spec;
spec.dwEventType = event_type;
spec.dwRestorePtType = APPLICATION_INSTALL;
spec.llSequenceNumber = status->llSequenceNumber;
lstrcpyA(spec.szDescription, "msitest restore point");
return pSRSetRestorePointA(&spec, status);
}
static void remove_restore_point(DWORD seq_number)
{
DWORD res;
res = pSRRemoveRestorePoint(seq_number);
if (res != ERROR_SUCCESS)
trace("Failed to remove the restore point: %#lx\n", res);
}
static BOOL is_root(const char *path)
{
return (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && !path[3]);
@ -2118,26 +1975,22 @@ static void test_condition(void)
ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<\"\xe5\"");
ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
"wrong return val (%d)\n", r);
ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\">\"\xe5\"");
ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
"wrong return val (%d)\n", r);
ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"<>\"\xe5\"");
ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
"wrong return val (%d)\n", r);
ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r);
r = MsiEvaluateConditionW(hpkg, L"\"a\x30a\"=\"\xe5\"");
ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
"wrong return val (%d)\n", r);
ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
MsiCloseHandle( hpkg );
DeleteFileA(msifile);
}
static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case)
static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int match_case, int todo_value)
{
char buffer[MAX_PATH] = "x";
DWORD sz = sizeof(buffer);
@ -2145,9 +1998,9 @@ static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect, int
ok(!r, "'%s': got %u\n", prop, r);
ok(sz == lstrlenA(buffer), "'%s': expected %u, got %lu\n", prop, lstrlenA(buffer), sz);
if (match_case)
ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
todo_wine_if (todo_value) ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
else
ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
todo_wine_if (todo_value) ok(!_stricmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer);
}
static void test_props(void)
@ -2220,29 +2073,29 @@ static void test_props(void)
r = MsiSetPropertyA( hpkg, "=", "asdf" );
ok(!r, "got %u\n", r);
check_prop(hpkg, "=", "asdf", 1);
check_prop(hpkg, "=", "asdf", 1, 0);
r = MsiSetPropertyA( hpkg, " ", "asdf" );
ok(!r, "got %u\n", r);
check_prop(hpkg, " ", "asdf", 1);
check_prop(hpkg, " ", "asdf", 1, 0);
r = MsiSetPropertyA( hpkg, "'", "asdf" );
ok(!r, "got %u\n", r);
check_prop(hpkg, "'", "asdf", 1);
check_prop(hpkg, "'", "asdf", 1, 0);
/* set empty values */
r = MsiSetPropertyA( hpkg, "boo", NULL );
ok(!r, "got %u\n", r);
check_prop(hpkg, "boo", "", 1);
check_prop(hpkg, "boo", "", 1, 0);
r = MsiSetPropertyA( hpkg, "boo", "" );
ok(!r, "got %u\n", r);
check_prop(hpkg, "boo", "", 1);
check_prop(hpkg, "boo", "", 1, 0);
/* set a non-empty value */
r = MsiSetPropertyA( hpkg, "boo", "xyz" );
ok(!r, "got %u\n", r);
check_prop(hpkg, "boo", "xyz", 1);
check_prop(hpkg, "boo", "xyz", 1, 0);
r = MsiGetPropertyA(hpkg, "boo", NULL, NULL);
ok(!r, "got %u\n", r);
@ -2317,10 +2170,10 @@ static void test_props(void)
ok(sz == 3, "got size %lu\n", sz);
/* properties are case-sensitive */
check_prop(hpkg, "BOO", "", 1);
check_prop(hpkg, "BOO", "", 1, 0);
/* properties set in Property table should work */
check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1);
check_prop(hpkg, "MetadataCompName", "Photoshop.dll", 1, 0);
MsiCloseHandle( hpkg );
DeleteFileA(msifile);
@ -2393,7 +2246,7 @@ static void test_property_table(void)
query = "CREATE TABLE `_Property` ( "
"`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
r = run_query(hdb, query);
r = run_query(hdb, 0, query);
ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
MsiCloseHandle(hdb);
@ -2405,19 +2258,19 @@ static void test_property_table(void)
query = "CREATE TABLE `_Property` ( "
"`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
r = run_query(hdb, query);
r = run_query(hdb, 0, query);
ok(r == ERROR_SUCCESS, "failed to create table\n");
query = "ALTER `_Property` ADD `foo` INTEGER";
r = run_query(hdb, query);
r = run_query(hdb, 0, query);
ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
query = "ALTER TABLE `_Property` ADD `foo` INTEGER";
r = run_query(hdb, query);
r = run_query(hdb, 0, query);
ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add column\n");
query = "ALTER TABLE `_Property` ADD `extra` INTEGER";
r = run_query(hdb, query);
r = run_query(hdb, 0, query);
ok(r == ERROR_SUCCESS, "failed to add column\n");
sprintf(package, "#%lu", hdb);
@ -3071,11 +2924,10 @@ static void test_states(void)
MSIHANDLE hpkg, hprod;
UINT r;
MSIHANDLE hdb;
BOOL is_broken;
char value[MAX_PATH];
DWORD size;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -3608,8 +3460,7 @@ static void test_states(void)
/* reinstall the product */
r = MsiInstallProductA(msifile3, "REINSTALL=ALL");
is_broken = (r == ERROR_INSTALL_FAILURE);
ok(r == ERROR_SUCCESS || broken(is_broken) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five");
ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state);
@ -3781,8 +3632,7 @@ static void test_states(void)
MsiCloseHandle( hpkg );
r = MsiInstallProductA(msifile, "");
ok(r == ERROR_SUCCESS || (is_broken && r == ERROR_INSTALL_FAILURE) /* win2k3 */,
"Expected ERROR_SUCCESS, got %d\n", r);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one");
ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state);
state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two");
@ -4120,8 +3970,8 @@ done:
MsiCloseHandle( hpkg );
DeleteFileA(msifile);
RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Winetest_msi");
delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY);
delete_key(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY);
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_32KEY, 0);
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Winetest_msi", KEY_WOW64_64KEY, 0);
}
static void test_appsearch_complocator(void)
@ -4135,7 +3985,7 @@ static void test_appsearch_complocator(void)
if (!(usersid = get_user_sid()))
return;
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -4412,9 +4262,7 @@ static void test_appsearch_reglocator(void)
users = 0;
res = RegCreateKeyA(HKEY_USERS, "S-1-5-18\\Software\\Wine", &users);
ok(res == ERROR_SUCCESS ||
broken(res == ERROR_INVALID_PARAMETER),
"Expected ERROR_SUCCESS, got %ld\n", res);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
if (res == ERROR_SUCCESS)
{
@ -4717,7 +4565,7 @@ static void test_appsearch_reglocator(void)
memset(&si, 0, sizeof(si));
GetNativeSystemInfo(&si);
if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
pathvar = malloc(size);
@ -5066,6 +4914,7 @@ static void test_appsearch_inilocator(void)
}
ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
MsiCloseHandle( hdb );
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
r = MsiDoActionA(hpkg, "AppSearch");
@ -5074,6 +4923,12 @@ static void test_appsearch_inilocator(void)
size = MAX_PATH;
r = MsiGetPropertyA(hpkg, "SIGPROP1", prop, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
if (!prop[0])
{
win_skip("broken result\n");
MsiCloseHandle(hpkg);
goto error;
}
ok(!lstrcmpA(prop, "keydata"), "Expected \"keydata\", got \"%s\"\n", prop);
size = MAX_PATH;
@ -5576,7 +5431,7 @@ static void test_installprops(void)
CHAR path[MAX_PATH], buf[MAX_PATH];
DWORD size, type;
LANGID langid;
HKEY hkey1, hkey2, pathkey;
HKEY hkey1, hkey2, pathkey = NULL;
int res;
UINT r;
REGSAM access = KEY_ALL_ACCESS;
@ -5628,7 +5483,12 @@ static void test_installprops(void)
ok( !lstrcmpA(buf, path), "Expected %s, got %s\n", path, buf);
RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
if (res == ERROR_ACCESS_DENIED)
{
win_skip("no access\n");
goto done;
}
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey);
@ -5734,72 +5594,73 @@ static void test_installprops(void)
GetNativeSystemInfo(&si);
sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
check_prop(hpkg, "VersionNT", buf, 1);
check_prop(hpkg, "VersionNT", buf, 1, 1);
if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
{
sprintf(buf, "%d", si.wProcessorLevel);
check_prop(hpkg, "Intel", buf, 1);
check_prop(hpkg, "MsiAMD64", buf, 1);
check_prop(hpkg, "Msix64", buf, 1);
check_prop(hpkg, "Intel", buf, 1, 0);
check_prop(hpkg, "MsiAMD64", buf, 1, 0);
check_prop(hpkg, "Msix64", buf, 1, 0);
sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion())));
check_prop(hpkg, "VersionNT64", buf, 1);
check_prop(hpkg, "VersionNT64", buf, 1, 1);
GetSystemDirectoryA(path, MAX_PATH);
strcat(path, "\\");
check_prop(hpkg, "System64Folder", path, 0);
check_prop(hpkg, "System64Folder", path, 0, 0);
GetSystemWow64DirectoryA(path, MAX_PATH);
strcat(path, "\\");
check_prop(hpkg, "SystemFolder", path, 0);
check_prop(hpkg, "SystemFolder", path, 0, 0);
size = MAX_PATH;
r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size);
strcat(path, "\\");
check_prop(hpkg, "ProgramFilesFolder", path, 0);
check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
size = MAX_PATH;
RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
strcat(path, "\\");
check_prop(hpkg, "ProgramFiles64Folder", path, 0);
check_prop(hpkg, "ProgramFiles64Folder", path, 0, 0);
size = MAX_PATH;
RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size);
strcat(path, "\\");
check_prop(hpkg, "CommonFilesFolder", path, 0);
check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
size = MAX_PATH;
RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
strcat(path, "\\");
check_prop(hpkg, "CommonFiles64Folder", path, 0);
check_prop(hpkg, "CommonFiles64Folder", path, 0, 0);
}
else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
sprintf(buf, "%d", si.wProcessorLevel);
check_prop(hpkg, "Intel", buf, 1);
check_prop(hpkg, "Intel", buf, 1, 0);
GetSystemDirectoryA(path, MAX_PATH);
strcat(path, "\\");
check_prop(hpkg, "SystemFolder", path, 0);
check_prop(hpkg, "SystemFolder", path, 0, 0);
size = MAX_PATH;
RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size);
strcat(path, "\\");
check_prop(hpkg, "ProgramFilesFolder", path, 0);
check_prop(hpkg, "ProgramFilesFolder", path, 0, 0);
size = MAX_PATH;
RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size);
strcat(path, "\\");
check_prop(hpkg, "CommonFilesFolder", path, 0);
check_prop(hpkg, "CommonFilesFolder", path, 0, 0);
check_prop(hpkg, "MsiAMD64", "", 1);
check_prop(hpkg, "Msix64", "", 1);
check_prop(hpkg, "VersionNT64", "", 1);
check_prop(hpkg, "System64Folder", "", 0);
check_prop(hpkg, "ProgramFiles64Dir", "", 0);
check_prop(hpkg, "CommonFiles64Dir", "", 0);
check_prop(hpkg, "MsiAMD64", "", 1, 0);
check_prop(hpkg, "Msix64", "", 1, 0);
check_prop(hpkg, "VersionNT64", "", 1, 0);
check_prop(hpkg, "System64Folder", "", 0, 0);
check_prop(hpkg, "ProgramFiles64Dir", "", 0, 0);
check_prop(hpkg, "CommonFiles64Dir", "", 0, 0);
}
done:
CloseHandle(hkey1);
CloseHandle(hkey2);
RegCloseKey(pathkey);
@ -7982,7 +7843,7 @@ static void test_MsiGetProductProperty(void)
r = set_summary_info(hdb);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = run_query(hdb,
r = run_query(hdb, 0,
"CREATE TABLE `Directory` ( "
"`Directory` CHAR(255) NOT NULL, "
"`Directory_Parent` CHAR(255), "
@ -8022,6 +7883,7 @@ static void test_MsiGetProductProperty(void)
skip("Not enough rights to perform tests\n");
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
DeleteFileA(msifile);
return;
}
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
@ -8032,12 +7894,16 @@ static void test_MsiGetProductProperty(void)
lstrcpyA(val, path);
lstrcatA(val, "\\");
lstrcatA(val, msifile);
res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
(const BYTE *)val, lstrlenA(val) + 1);
res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, (const BYTE *)val, lstrlenA(val) + 1);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
hprod = 0xdeadbeef;
r = MsiOpenProductA(prodcode, &hprod);
if (r == ERROR_UNKNOWN_PRODUCT)
{
win_skip("broken result, skipping tests\n");
goto done;
}
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
@ -8258,13 +8124,13 @@ static void test_MsiGetProductProperty(void)
"Expected %d, got %lu\n", lstrlenW(prodcodeW), size);
MsiCloseHandle(hprod);
done:
RegDeleteValueA(props, "LocalPackage");
delete_key(props, "", access);
RegDeleteKeyExA(props, "", access, 0);
RegCloseKey(props);
delete_key(userkey, "", access);
RegDeleteKeyExA(userkey, "", access, 0);
RegCloseKey(userkey);
delete_key(prodkey, "", access);
RegDeleteKeyExA(prodkey, "", access, 0);
RegCloseKey(prodkey);
DeleteFileA(msifile);
}
@ -8459,10 +8325,14 @@ static void test_costs(void)
add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
create_file_table( hdb );
add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
add_file_entry( hdb, "'a.txt', 'one', 'a.txt', 2048000000, '', '', 8192, 1" );
add_file_entry( hdb, "'b.txt', 'one', 'b.txt', 2048000000, '', '', 8192, 1" );
add_file_entry( hdb, "'c.txt', 'one', 'c.txt', 2048000000, '', '', 8192, 1" );
add_file_entry( hdb, "'d.txt', 'one', 'd.txt', 4097, '', '', 8192, 1" );
add_file_entry( hdb, "'e.txt', 'one', 'e.txt', 1, '', '', 8192, 1" );
create_component_table( hdb );
add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'a.txt'" );
add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
create_feature_table( hdb );
@ -8590,7 +8460,7 @@ static void test_costs(void)
ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
ok( len == 2, "expected len == 2, got %lu\n", len );
ok( drive[0], "expected a drive\n" );
ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
ok( cost == 12000024, "got %d\n", cost );
ok( !temp, "expected temp == 0, got %d\n", temp );
len = sizeof(drive);
@ -8611,7 +8481,7 @@ static void test_costs(void)
ok( len == 2, "expected len == 2, got %lu\n", len );
ok( drive[0], "expected a drive\n" );
ok( !cost, "expected cost == 0, got %d\n", cost );
ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
todo_wine ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
/* increased index */
len = sizeof(drive);
@ -8634,7 +8504,7 @@ static void test_costs(void)
cost = 0xdead;
r = MsiGetFeatureCostA( hpkg, "one", MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &cost );
ok( !r, "got %u\n", r);
ok( cost == 8, "got %d\n", cost );
ok( cost == 12000024, "got %d\n", cost );
MsiCloseHandle( hpkg );
error:
@ -9108,13 +8978,13 @@ static void test_externalui_message(void)
hdb = create_package_db();
ok(hdb, "failed to create database\n");
create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = run_query(hdb, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
r = run_query(hdb, 0, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
r = run_query(hdb, 0, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
create_actiontext_table(hdb);
@ -9325,7 +9195,7 @@ static void test_controlevent(void)
hdb = create_package_db();
ok(hdb, "failed to create database\n");
create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") - 1);
r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@ -9548,7 +9418,7 @@ static void test_top_level_action(void)
hdb = create_package_db();
ok(hdb, "failed to create database\n");
create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n");
create_file_data("forcecodepage.idt", "\r\n\r\n1252\t_ForceCodepage\r\n", sizeof("\r\n\r\n1252\t_ForceCodepage\r\n") -1 );
r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@ -9623,14 +9493,11 @@ static void test_top_level_action(void)
START_TEST(package)
{
char temp_path[MAX_PATH], prev_path[MAX_PATH];
STATEMGRSTATUS status;
BOOL ret = FALSE;
DWORD len;
init_functionpointers();
if (!is_process_elevated()) restart_as_admin_elevated();
if (pIsWow64Process)
pIsWow64Process(GetCurrentProcess(), &is_wow64);
IsWow64Process(GetCurrentProcess(), &is_wow64);
GetCurrentDirectoryA(MAX_PATH, prev_path);
GetTempPathA(MAX_PATH, temp_path);
@ -9642,18 +9509,6 @@ START_TEST(package)
if (len && (CURR_DIR[len - 1] == '\\'))
CURR_DIR[len - 1] = 0;
/* Create a restore point ourselves so we circumvent the multitude of restore points
* that would have been created by all the installation and removal tests.
*
* This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
* creation of restore points.
*/
if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
{
memset(&status, 0, sizeof(status));
ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
}
test_createpackage();
test_doaction();
test_gettargetpath_bad();
@ -9692,12 +9547,5 @@ START_TEST(package)
test_controlevent();
test_top_level_action();
if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
{
ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
if (ret)
remove_restore_point(status.llSequenceNumber);
}
SetCurrentDirectoryA(prev_path);
}

View file

@ -30,22 +30,13 @@
#include <wtypes.h>
#include "wine/test.h"
static UINT (WINAPI *pMsiApplyPatchA)( LPCSTR, LPCSTR, INSTALLTYPE, LPCSTR );
static UINT (WINAPI *pMsiGetPatchInfoExA)( LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT,
LPCSTR, LPSTR, DWORD * );
static UINT (WINAPI *pMsiEnumPatchesExA)( LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR,
LPSTR, MSIINSTALLCONTEXT *, LPSTR, LPDWORD );
#include "utils.h"
static const char *msifile = "winetest-patch.msi";
static const char *mspfile = "winetest-patch.msp";
static const WCHAR msifileW[] = L"winetest-patch.msi";
static const WCHAR mspfileW[] = L"winetest-patch.msp";
static char CURR_DIR[MAX_PATH];
static char PROG_FILES_DIR[MAX_PATH];
static char COMMON_FILES_DIR[MAX_PATH];
/* msi database data */
static const char property_dat[] =
@ -136,8 +127,6 @@ struct msi_table
int size;
};
#define ADD_TABLE( x ) { #x".idt", x##_dat, sizeof(x##_dat) }
static const struct msi_table tables[] =
{
ADD_TABLE( directory ),
@ -151,39 +140,6 @@ static const struct msi_table tables[] =
ADD_TABLE( condition )
};
static void init_function_pointers( void )
{
HMODULE hmsi = GetModuleHandleA( "msi.dll" );
#define GET_PROC( mod, func ) \
p ## func = (void *)GetProcAddress( mod, #func ); \
if (!p ## func) \
trace( "GetProcAddress(%s) failed\n", #func );
GET_PROC( hmsi, MsiApplyPatchA );
GET_PROC( hmsi, MsiGetPatchInfoExA );
GET_PROC( hmsi, MsiEnumPatchesExA );
#undef GET_PROC
}
static BOOL is_process_limited(void)
{
HANDLE token;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
{
BOOL ret;
TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
DWORD size;
ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
CloseHandle(token);
return (ret && type == TokenElevationTypeLimited);
}
return FALSE;
}
static BOOL get_program_files_dir( char *buf, char *buf2 )
{
HKEY hkey;
@ -209,40 +165,6 @@ static BOOL get_program_files_dir( char *buf, char *buf2 )
return TRUE;
}
static void create_file_data( const char *filename, const char *data, DWORD size )
{
HANDLE file;
DWORD written;
file = CreateFileA( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL );
if (file == INVALID_HANDLE_VALUE)
return;
WriteFile( file, data, strlen( data ), &written, NULL );
if (size)
{
SetFilePointer( file, size, NULL, FILE_BEGIN );
SetEndOfFile( file );
}
CloseHandle( file );
}
#define create_file( name, size ) create_file_data( name, name, size )
static BOOL delete_pf( const char *rel_path, BOOL is_file )
{
char path[MAX_PATH];
strcpy( path, PROG_FILES_DIR );
strcat( path, "\\" );
strcat( path, rel_path );
if (is_file)
return DeleteFileA( path );
else
return RemoveDirectoryA( path );
}
static DWORD get_pf_file_size( const char *filename )
{
char path[MAX_PATH];
@ -313,7 +235,7 @@ static void set_suminfo( const WCHAR *filename )
ok( r == ERROR_SUCCESS, "failed to close database %u\n", r );
}
static void create_database( const char *filename, const struct msi_table *tables, UINT num_tables )
static void create_database_suminfo( const char *filename, const struct msi_table *tables, UINT num_tables )
{
MSIHANDLE hdb;
UINT r, i;
@ -747,12 +669,7 @@ static void test_simple_patch( void )
WCHAR pathW[MAX_PATH];
MSIHANDLE hpackage, hdb, hview, hrec;
if (!pMsiApplyPatchA)
{
win_skip("MsiApplyPatchA is not available\n");
return;
}
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -761,7 +678,7 @@ static void test_simple_patch( void )
CreateDirectoryA( "msitest", NULL );
create_file( "msitest\\patch.txt", 1000 );
create_database( msifile, tables, ARRAY_SIZE(tables) );
create_database_suminfo( msifile, tables, ARRAY_SIZE(tables) );
create_patch( mspfile );
MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
@ -830,14 +747,7 @@ static void test_simple_patch( void )
MsiCloseHandle( hpackage );
r = MsiApplyPatchA( mspfile, NULL, INSTALLTYPE_DEFAULT, NULL );
ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
"expected ERROR_SUCCESS, got %u\n", r );
if (r == ERROR_PATCH_PACKAGE_INVALID)
{
win_skip("Windows Installer < 3.0 detected\n");
goto uninstall;
}
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
size = get_pf_file_size( "msitest\\patch.txt" );
ok( size == 1002, "expected 1002, got %lu\n", size );
@ -913,7 +823,6 @@ static void test_simple_patch( void )
MsiCloseHandle( hview );
MsiCloseHandle( hdb );
uninstall:
size = sizeof(path);
r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
"InstallSource", path, &size );
@ -962,7 +871,7 @@ static void test_MsiOpenDatabase( void )
MsiCloseHandle( hdb );
DeleteFileA( mspfile );
create_database( msifile, tables, ARRAY_SIZE(tables) );
create_database_suminfo( msifile, tables, ARRAY_SIZE(tables) );
create_patch( mspfile );
r = MsiOpenDatabaseW( msifileW, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &hdb );
@ -1086,12 +995,7 @@ static void test_system_tables( void )
const char *query;
MSIHANDLE hproduct, hdb, hview, hrec;
if (!pMsiApplyPatchA)
{
win_skip("MsiApplyPatchA is not available\n");
return;
}
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -1100,7 +1004,7 @@ static void test_system_tables( void )
CreateDirectoryA( "msitest", NULL );
create_file( "msitest\\patch.txt", 1000 );
create_database( msifile, tables, ARRAY_SIZE(tables) );
create_database_suminfo( msifile, tables, ARRAY_SIZE(tables) );
create_patch( mspfile );
MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
@ -1168,14 +1072,7 @@ static void test_system_tables( void )
MsiCloseHandle( hproduct );
r = MsiApplyPatchA( mspfile, NULL, INSTALLTYPE_DEFAULT, NULL );
ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
"expected ERROR_SUCCESS, got %u\n", r );
if (r == ERROR_PATCH_PACKAGE_INVALID)
{
win_skip("Windows Installer < 3.0 detected\n");
goto uninstall;
}
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
r = MsiOpenProductA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", &hproduct );
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
@ -1259,7 +1156,6 @@ static void test_system_tables( void )
MsiCloseHandle( hdb );
MsiCloseHandle( hproduct );
uninstall:
r = MsiInstallProductA( msifile, "REMOVE=ALL" );
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
@ -1276,12 +1172,7 @@ static void test_patch_registration( void )
DWORD size;
char buffer[MAX_PATH], patch_code[39];
if (!pMsiApplyPatchA || !pMsiGetPatchInfoExA || !pMsiEnumPatchesExA)
{
win_skip("required functions not available\n");
return;
}
if (is_process_limited())
if (!is_process_elevated())
{
skip("process is limited\n");
return;
@ -1290,7 +1181,7 @@ static void test_patch_registration( void )
CreateDirectoryA( "msitest", NULL );
create_file( "msitest\\patch.txt", 1000 );
create_database( msifile, tables, ARRAY_SIZE(tables) );
create_database_suminfo( msifile, tables, ARRAY_SIZE(tables) );
create_patch( mspfile );
MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
@ -1303,67 +1194,59 @@ static void test_patch_registration( void )
}
r = MsiApplyPatchA( mspfile, NULL, INSTALLTYPE_DEFAULT, NULL );
ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
"expected ERROR_SUCCESS, got %u\n", r );
if (r == ERROR_PATCH_PACKAGE_INVALID)
{
win_skip("Windows Installer < 3.0 detected\n");
goto uninstall;
}
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
buffer[0] = 0;
size = sizeof(buffer);
r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
INSTALLPROPERTY_LOCALPACKAGEA, buffer, &size );
r = MsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
INSTALLPROPERTY_LOCALPACKAGEA, buffer, &size );
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
ok( buffer[0], "buffer empty\n" );
buffer[0] = 0;
size = sizeof(buffer);
r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_MACHINE,
INSTALLPROPERTY_LOCALPACKAGEA, buffer, &size );
r = MsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_MACHINE,
INSTALLPROPERTY_LOCALPACKAGEA, buffer, &size );
ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r );
buffer[0] = 0;
size = sizeof(buffer);
r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
r = MsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERMANAGED,
INSTALLPROPERTY_LOCALPACKAGEA, buffer, &size );
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
ok( !buffer[0], "got %s\n", buffer );
r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_APPLIED,
0, patch_code, NULL, NULL, NULL, NULL );
r = MsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_APPLIED,
0, patch_code, NULL, NULL, NULL, NULL );
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
ok( !strcmp( patch_code, "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}" ), "wrong patch code\n" );
r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_MACHINE, MSIPATCHSTATE_APPLIED,
0, patch_code, NULL, NULL, NULL, NULL );
r = MsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_MACHINE, MSIPATCHSTATE_APPLIED,
0, patch_code, NULL, NULL, NULL, NULL );
ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERMANAGED, MSIPATCHSTATE_APPLIED,
0, patch_code, NULL, NULL, NULL, NULL );
r = MsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERMANAGED, MSIPATCHSTATE_APPLIED,
0, patch_code, NULL, NULL, NULL, NULL );
ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
uninstall:
r = MsiInstallProductA( msifile, "REMOVE=ALL" );
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
buffer[0] = 0;
size = sizeof(buffer);
r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
INSTALLPROPERTY_LOCALPACKAGEA, buffer, &size );
r = MsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
"{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
INSTALLPROPERTY_LOCALPACKAGEA, buffer, &size );
ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r );
cleanup:
@ -1378,7 +1261,7 @@ START_TEST(patch)
DWORD len;
char temp_path[MAX_PATH], prev_path[MAX_PATH];
init_function_pointers();
if (!is_process_elevated()) restart_as_admin_elevated();
GetCurrentDirectoryA( MAX_PATH, prev_path );
GetTempPathA( MAX_PATH, temp_path );

View file

@ -244,11 +244,11 @@ static void test_msirecord(void)
i = MsiRecordSetStringA(h,0,"42");
ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
i = MsiRecordGetInteger(h, 0);
ok(i == 42, "should get invalid integer\n");
ok(i == 42, "should get 42\n");
i = MsiRecordSetStringA(h,0,"-42");
ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
i = MsiRecordGetInteger(h, 0);
ok(i == -42, "should get invalid integer\n");
ok(i == -42, "should get -42\n");
i = MsiRecordSetStringA(h,0," 42");
ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
i = MsiRecordGetInteger(h, 0);
@ -349,7 +349,7 @@ static void test_msirecord(void)
ok(r == ERROR_SUCCESS, "failed to add stream to record\n");
r = MsiRecordReadStream(h, 1, buf, NULL);
ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
DeleteFileA(filename); /* Windows 98 doesn't like this at all, so don't check return. */
DeleteFileA(filename);
r = MsiRecordReadStream(h, 1, NULL, NULL);
ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
sz = sizeof buf;

View file

@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep testdll
#endif
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>

File diff suppressed because it is too large Load diff

View file

@ -343,45 +343,45 @@ static void test_create_database_binary(void)
ok( r == S_OK, "failed to set class\n");
propspec[0].ulKind = PRSPEC_PROPID;
U(propspec[0]).propid = PID_TITLE;
propspec[0].propid = PID_TITLE;
propvar[0].vt = VT_LPSTR;
U(propvar[0]).pszVal = LOSE_CONST("test title");
propvar[0].pszVal = LOSE_CONST("test title");
propspec[1].ulKind = PRSPEC_PROPID;
U(propspec[1]).propid = PID_SUBJECT;
propspec[1].propid = PID_SUBJECT;
propvar[1].vt = VT_LPSTR;
U(propvar[1]).pszVal = LOSE_CONST("msi suminfo / property storage test");
propvar[1].pszVal = LOSE_CONST("msi suminfo / property storage test");
propspec[2].ulKind = PRSPEC_PROPID;
U(propspec[2]).propid = PID_AUTHOR;
propspec[2].propid = PID_AUTHOR;
propvar[2].vt = VT_LPSTR;
U(propvar[2]).pszVal = LOSE_CONST("mike_m");
propvar[2].pszVal = LOSE_CONST("mike_m");
propspec[3].ulKind = PRSPEC_PROPID;
U(propspec[3]).propid = PID_TEMPLATE;
propspec[3].propid = PID_TEMPLATE;
propvar[3].vt = VT_LPSTR;
U(propvar[3]).pszVal = LOSE_CONST(";1033"); /* actually the string table's codepage */
propvar[3].pszVal = LOSE_CONST(";1033"); /* actually the string table's codepage */
propspec[4].ulKind = PRSPEC_PROPID;
U(propspec[4]).propid = PID_REVNUMBER;
propspec[4].propid = PID_REVNUMBER;
propvar[4].vt = VT_LPSTR;
U(propvar[4]).pszVal = LOSE_CONST("{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
propvar[4].pszVal = LOSE_CONST("{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
propspec[5].ulKind = PRSPEC_PROPID;
U(propspec[5]).propid = PID_PAGECOUNT;
propspec[5].propid = PID_PAGECOUNT;
propvar[5].vt = VT_I4;
U(propvar[5]).lVal = 100;
propvar[5].lVal = 100;
propspec[6].ulKind = PRSPEC_PROPID;
U(propspec[6]).propid = PID_WORDCOUNT;
propspec[6].propid = PID_WORDCOUNT;
propvar[6].vt = VT_I4;
U(propvar[6]).lVal = 0;
propvar[6].lVal = 0;
/* MSDN says that PID_LASTPRINTED should be a VT_FILETIME... */
propspec[7].ulKind = PRSPEC_PROPID;
U(propspec[7]).propid = PID_LASTPRINTED;
propspec[7].propid = PID_LASTPRINTED;
propvar[7].vt = VT_LPSTR;
U(propvar[7]).pszVal = LOSE_CONST("7/1/1999 5:17");
propvar[7].pszVal = LOSE_CONST("7/1/1999 5:17");
r = IPropertyStorage_WriteMultiple( ps, 8, propspec, propvar, PID_FIRST_USABLE );
ok( r == S_OK, "failed to write properties\n");

View file

@ -56,5 +56,6 @@ void delete_cab_files(void);
BOOL delete_pf(const char *rel_path, BOOL is_file);
BOOL file_exists(const char *file);
BOOL pf_exists(const char *file);
BOOL is_process_limited(void);
BOOL is_process_elevated(void);
UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query);
void restart_as_admin_elevated(void);