/* * Tests for MSI Source functions * * Copyright (C) 2006 James Hawkins * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include "wine/test.h" /* copied from dlls/msi/registry.c */ static BOOL squash_guid(LPCWSTR in, LPWSTR out) { DWORD i,n=1; GUID guid; if (FAILED(CLSIDFromString((LPOLESTR)in, &guid))) return FALSE; for(i=0; i<8; i++) out[7-i] = in[n++]; n++; for(i=0; i<4; i++) out[11-i] = in[n++]; n++; for(i=0; i<4; i++) out[15-i] = in[n++]; n++; for(i=0; i<2; i++) { out[17+i*2] = in[n++]; out[16+i*2] = in[n++]; } n++; for( ; i<8; i++) { out[17+i*2] = in[n++]; out[16+i*2] = in[n++]; } out[32]=0; return TRUE; } static void create_test_guid(LPSTR prodcode, LPSTR squashed) { WCHAR guidW[MAX_PATH]; WCHAR squashedW[MAX_PATH]; GUID guid; HRESULT hr; int size; hr = CoCreateGuid(&guid); ok(hr == S_OK, "Expected S_OK, got %d\n", hr); size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH); ok(size == 39, "Expected 39, got %d\n", hr); WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL); squash_guid(guidW, squashedW); WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL); } static void get_user_sid(LPSTR *usersid) { HANDLE token; BYTE buf[1024]; DWORD size; PTOKEN_USER user; OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); size = sizeof(buf); GetTokenInformation(token, TokenUser, (void *)buf, size, &size); user = (PTOKEN_USER)buf; ConvertSidToStringSid(user->User.Sid, usersid); } static void test_MsiSourceListGetInfo(void) { CHAR prodcode[MAX_PATH]; CHAR prod_squashed[MAX_PATH]; CHAR keypath[MAX_PATH*2]; CHAR value[MAX_PATH]; LPSTR usersid; LPCSTR data; LONG res; UINT r; HKEY userkey, hkey; DWORD size; create_test_guid(prodcode, prod_squashed); get_user_sid(&usersid); /* NULL szProductCodeOrPatchCode */ r = MsiSourceListGetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* empty szProductCodeOrPatchCode */ r = MsiSourceListGetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* garbage szProductCodeOrPatchCode */ r = MsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* szProductCodeOrPatchCode */ r = MsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* guid without brackets */ r = MsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* guid with brackets */ r = MsiSourceListGetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); /* same length as guid, but random */ r = MsiSourceListGetInfoA("ADKD-2KSDFF2-DKK1KNFJASD9GLKWME-1I3KAD", usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* invalid context */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_NONE, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* another invalid context */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALLUSERMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* yet another invalid context */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALL, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* mix two valid contexts */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* invalid option */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 4, INSTALLPROPERTY_PACKAGENAME, NULL, NULL); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); /* NULL property */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, NULL, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* empty property */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, "", NULL, NULL); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); /* value is non-NULL while size is NULL */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, NULL); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); /* size is non-NULL while value is NULL */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\"); lstrcatA(keypath, prod_squashed); res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* user product key exists */ r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); res = RegCreateKeyA(userkey, "SourceList", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(size == 0, "Expected 0, got %d\n", size); data = "msitest.msi"; res = RegSetValueExA(hkey, "PackageName", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* PackageName value exists */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(size == 11, "Expected 11, got %d\n", size); /* read the value, don't change size */ lstrcpyA(value, "aaa"); r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size); ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); ok(!lstrcmpA(value, "aaa"), "Expected 'aaa', got %s\n", value); ok(size == 11, "Expected 11, got %d\n", size); /* read the value, fix size */ size++; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, 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 %d\n", size); /* empty property now that product key exists */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, "", NULL, &size); ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r); ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size); /* nonexistent property now that product key exists */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, "nonexistent", NULL, &size); ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r); ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size); data = "tester"; res = RegSetValueExA(hkey, "nonexistent", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* nonexistent property now that nonexistent value exists */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, "nonexistent", NULL, &size); ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r); ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size); /* invalid option now that product key exists */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 4, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(size == 11, "Expected 11, got %d\n", size); RegDeleteValueA(hkey, "nonexistent"); RegDeleteValueA(hkey, "PackageName"); RegDeleteKeyA(hkey, ""); RegDeleteKeyA(userkey, ""); RegCloseKey(hkey); RegCloseKey(userkey); /* try a patch */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r); ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size); lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\"); lstrcatA(keypath, prod_squashed); res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* patch key exists * NOTE: using prodcode guid, but it really doesn't matter */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r); ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size); res = RegCreateKeyA(userkey, "SourceList", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); /* SourceList key exists */ size = 0xdeadbeef; r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(size == 0, "Expected 0, got %d\n", size); RegDeleteKeyA(hkey, ""); RegDeleteKeyA(userkey, ""); RegCloseKey(hkey); RegCloseKey(userkey); } START_TEST(source) { test_MsiSourceListGetInfo(); }