Commit 5891ce25 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Implement MsiQueryFeatureStateExA/W.

parent 6488a6a5
...@@ -2918,6 +2918,123 @@ end: ...@@ -2918,6 +2918,123 @@ end:
return r; return r;
} }
static UINT query_feature_state( const WCHAR *product, const WCHAR *squashed, const WCHAR *usersid,
MSIINSTALLCONTEXT ctx, const WCHAR *feature, INSTALLSTATE *state )
{
UINT r;
HKEY hkey;
WCHAR *parent, *components, *path;
const WCHAR *p;
BOOL missing = FALSE, source = FALSE;
WCHAR comp[GUID_SIZE];
GUID guid;
if (ctx != MSIINSTALLCONTEXT_MACHINE) SetLastError( ERROR_SUCCESS );
if (MSIREG_OpenFeaturesKey( product, usersid, ctx, &hkey, FALSE )) return ERROR_UNKNOWN_PRODUCT;
parent = msi_reg_get_val_str( hkey, feature );
RegCloseKey( hkey );
if (!parent) return ERROR_UNKNOWN_FEATURE;
*state = (parent[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
msi_free( parent );
if (*state == INSTALLSTATE_ABSENT)
return ERROR_SUCCESS;
r = MSIREG_OpenUserDataFeaturesKey( product, usersid, ctx, &hkey, FALSE );
if (r != ERROR_SUCCESS)
{
*state = INSTALLSTATE_ADVERTISED;
return ERROR_SUCCESS;
}
components = msi_reg_get_val_str( hkey, feature );
RegCloseKey( hkey );
TRACE("buffer = %s\n", debugstr_w(components));
if (!components)
{
*state = INSTALLSTATE_ADVERTISED;
return ERROR_SUCCESS;
}
for (p = components; *p && *p != 2 ; p += 20)
{
if (!decode_base85_guid( p, &guid ))
{
if (p != components) break;
msi_free( components );
*state = INSTALLSTATE_BADCONFIG;
return ERROR_BAD_CONFIGURATION;
}
StringFromGUID2( &guid, comp, GUID_SIZE );
if (ctx == MSIINSTALLCONTEXT_MACHINE)
r = MSIREG_OpenUserDataComponentKey( comp, szLocalSid, &hkey, FALSE );
else
r = MSIREG_OpenUserDataComponentKey( comp, usersid, &hkey, FALSE );
if (r != ERROR_SUCCESS)
{
msi_free( components );
*state = INSTALLSTATE_ADVERTISED;
return ERROR_SUCCESS;
}
path = msi_reg_get_val_str( hkey, squashed );
if (!path) missing = TRUE;
else if (strlenW( path ) > 2 &&
path[0] >= '0' && path[0] <= '9' &&
path[1] >= '0' && path[1] <= '9')
{
source = TRUE;
}
msi_free( path );
}
msi_free( components );
if (missing)
*state = INSTALLSTATE_ADVERTISED;
else if (source)
*state = INSTALLSTATE_SOURCE;
else
*state = INSTALLSTATE_LOCAL;
TRACE("returning state %d\n", *state);
return ERROR_SUCCESS;
}
UINT WINAPI MsiQueryFeatureStateExA( LPCSTR product, LPCSTR usersid, MSIINSTALLCONTEXT ctx,
LPCSTR feature, INSTALLSTATE *state )
{
UINT r;
WCHAR *productW = NULL, *usersidW = NULL, *featureW = NULL;
if (product && !(productW = strdupAtoW( product ))) return ERROR_OUTOFMEMORY;
if (usersid && !(usersidW = strdupAtoW( usersid )))
{
msi_free( productW );
return ERROR_OUTOFMEMORY;
}
if (feature && !(featureW = strdupAtoW( feature )))
{
msi_free( productW );
msi_free( usersidW );
return ERROR_OUTOFMEMORY;
}
r = MsiQueryFeatureStateExW( productW, usersidW, ctx, featureW, state );
msi_free( productW );
msi_free( usersidW );
msi_free( featureW );
return r;
}
UINT WINAPI MsiQueryFeatureStateExW( LPCWSTR product, LPCWSTR usersid, MSIINSTALLCONTEXT ctx,
LPCWSTR feature, INSTALLSTATE *state )
{
WCHAR squashed[33];
if (!squash_guid( product, squashed )) return ERROR_INVALID_PARAMETER;
return query_feature_state( product, squashed, usersid, ctx, feature, state );
}
/****************************************************************** /******************************************************************
* MsiQueryFeatureStateA [MSI.@] * MsiQueryFeatureStateA [MSI.@]
*/ */
...@@ -2962,117 +3079,25 @@ end: ...@@ -2962,117 +3079,25 @@ end:
*/ */
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
{ {
WCHAR squishProduct[33], comp[GUID_SIZE]; UINT r;
GUID guid; INSTALLSTATE state;
LPWSTR components, p, parent_feature, path; WCHAR squashed[33];
UINT rc;
HKEY hkey;
INSTALLSTATE r;
BOOL missing = FALSE;
BOOL machine = FALSE;
BOOL source = FALSE;
TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature)); TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
if (!szProduct || !szFeature) if (!szProduct || !szFeature || !squash_guid( szProduct, squashed ))
return INSTALLSTATE_INVALIDARG; return INSTALLSTATE_INVALIDARG;
if (!squash_guid( szProduct, squishProduct )) r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_USERMANAGED, szFeature, &state );
return INSTALLSTATE_INVALIDARG; if (r == ERROR_SUCCESS || r == ERROR_BAD_CONFIGURATION) return state;
SetLastError( ERROR_SUCCESS );
if (MSIREG_OpenFeaturesKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
&hkey, FALSE) != ERROR_SUCCESS &&
MSIREG_OpenFeaturesKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE) != ERROR_SUCCESS)
{
rc = MSIREG_OpenFeaturesKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE);
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_UNKNOWN;
machine = TRUE;
}
parent_feature = msi_reg_get_val_str( hkey, szFeature );
RegCloseKey(hkey);
if (!parent_feature)
return INSTALLSTATE_UNKNOWN;
r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
msi_free(parent_feature);
if (r == INSTALLSTATE_ABSENT)
return r;
if (machine)
rc = MSIREG_OpenUserDataFeaturesKey(szProduct, NULL,
MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE);
else
rc = MSIREG_OpenUserDataFeaturesKey(szProduct, NULL,
MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE);
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_ADVERTISED;
components = msi_reg_get_val_str( hkey, szFeature );
RegCloseKey(hkey);
TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
if (!components) r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, szFeature, &state );
return INSTALLSTATE_ADVERTISED; if (r == ERROR_SUCCESS || r == ERROR_BAD_CONFIGURATION) return state;
for( p = components; *p && *p != 2 ; p += 20) r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_MACHINE, szFeature, &state );
{ if (r == ERROR_SUCCESS || r == ERROR_BAD_CONFIGURATION) return state;
if (!decode_base85_guid( p, &guid ))
{
if (p != components)
break;
msi_free(components); return INSTALLSTATE_UNKNOWN;
return INSTALLSTATE_BADCONFIG;
}
StringFromGUID2(&guid, comp, GUID_SIZE);
if (machine)
rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
else
rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
if (rc != ERROR_SUCCESS)
{
msi_free(components);
return INSTALLSTATE_ADVERTISED;
}
path = msi_reg_get_val_str(hkey, squishProduct);
if (!path)
missing = TRUE;
else if (lstrlenW(path) > 2 &&
path[0] >= '0' && path[0] <= '9' &&
path[1] >= '0' && path[1] <= '9')
{
source = TRUE;
}
msi_free(path);
}
msi_free(components);
if (missing)
r = INSTALLSTATE_ADVERTISED;
else if (source)
r = INSTALLSTATE_SOURCE;
else
r = INSTALLSTATE_LOCAL;
TRACE("-> %d\n", r);
return r;
} }
/****************************************************************** /******************************************************************
......
...@@ -244,8 +244,8 @@ ...@@ -244,8 +244,8 @@
248 stdcall MsiGetProductInfoExW(wstr wstr long wstr ptr ptr) 248 stdcall MsiGetProductInfoExW(wstr wstr long wstr ptr ptr)
249 stdcall MsiQueryComponentStateA(str str long str ptr) 249 stdcall MsiQueryComponentStateA(str str long str ptr)
250 stdcall MsiQueryComponentStateW(wstr wstr long wstr ptr) 250 stdcall MsiQueryComponentStateW(wstr wstr long wstr ptr)
251 stub MsiQueryFeatureStateExA 251 stdcall MsiQueryFeatureStateExA(str str long str ptr)
252 stub MsiQueryFeatureStateExW 252 stdcall MsiQueryFeatureStateExW(wstr wstr long wstr ptr)
253 stdcall MsiDeterminePatchSequenceA(str str long long ptr) 253 stdcall MsiDeterminePatchSequenceA(str str long long ptr)
254 stdcall MsiDeterminePatchSequenceW(wstr wstr long long ptr) 254 stdcall MsiDeterminePatchSequenceW(wstr wstr long long ptr)
255 stdcall MsiSourceListAddSourceExA(str str long long str long) 255 stdcall MsiSourceListAddSourceExA(str str long long str long)
......
...@@ -39,6 +39,8 @@ static UINT (WINAPI *pMsiSourceListGetInfoA) ...@@ -39,6 +39,8 @@ static UINT (WINAPI *pMsiSourceListGetInfoA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD); (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA) static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD); (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
static UINT (WINAPI *pMsiQueryFeatureStateExA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR *); static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR *);
static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE); static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE);
...@@ -2101,6 +2103,7 @@ static void init_functionpointers(void) ...@@ -2101,6 +2103,7 @@ static void init_functionpointers(void)
GET_PROC(hmsi, MsiSourceListEnumSourcesA); GET_PROC(hmsi, MsiSourceListEnumSourcesA);
GET_PROC(hmsi, MsiSourceListGetInfoA); GET_PROC(hmsi, MsiSourceListGetInfoA);
GET_PROC(hmsi, MsiGetComponentPathExA); GET_PROC(hmsi, MsiGetComponentPathExA);
GET_PROC(hmsi, MsiQueryFeatureStateExA);
GET_PROC(hadvapi32, ConvertSidToStringSidA); GET_PROC(hadvapi32, ConvertSidToStringSidA);
GET_PROC(hadvapi32, OpenProcessToken); GET_PROC(hadvapi32, OpenProcessToken);
...@@ -3609,20 +3612,19 @@ error: ...@@ -3609,20 +3612,19 @@ error:
static void test_publish(void) static void test_publish(void)
{ {
static const char subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
static const char subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
UINT r; UINT r;
LONG res; LONG res;
HKEY uninstall, prodkey, uninstall_32node = NULL; HKEY uninstall, prodkey, uninstall_32node = NULL;
INSTALLSTATE state; INSTALLSTATE state;
CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; char date[MAX_PATH], temp[MAX_PATH], prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
char date[MAX_PATH], temp[MAX_PATH];
REGSAM access = KEY_ALL_ACCESS; REGSAM access = KEY_ALL_ACCESS;
DWORD error;
static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; if (!pMsiQueryFeatureStateExA)
static const CHAR subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
if (!pMsiQueryComponentStateA)
{ {
win_skip("MsiQueryComponentStateA is not available\n"); win_skip("MsiQueryFeatureStateExA is not available\n");
return; return;
} }
if (is_process_limited()) if (is_process_limited())
...@@ -3653,13 +3655,40 @@ static void test_publish(void) ...@@ -3653,13 +3655,40 @@ static void test_publish(void)
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
ok(error == 0xdeadbeef, "got %u\n", error);
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
ok(error == ERROR_SUCCESS, "got %u\n", error);
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
ok(error == ERROR_SUCCESS, "got %u\n", error);
state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3681,13 +3710,13 @@ static void test_publish(void) ...@@ -3681,13 +3710,13 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File not installed\n"); ok(pf_exists("msitest\\maximus"), "File not installed\n");
ok(pf_exists("msitest"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3704,13 +3733,13 @@ static void test_publish(void) ...@@ -3704,13 +3733,13 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File not installed\n"); ok(pf_exists("msitest\\maximus"), "File not installed\n");
ok(pf_exists("msitest"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3765,13 +3794,13 @@ static void test_publish(void) ...@@ -3765,13 +3794,13 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File deleted\n"); ok(pf_exists("msitest\\maximus"), "File deleted\n");
ok(pf_exists("msitest"), "File deleted\n"); ok(pf_exists("msitest"), "File deleted\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3788,13 +3817,37 @@ static void test_publish(void) ...@@ -3788,13 +3817,37 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File not installed\n"); ok(pf_exists("msitest\\maximus"), "File not installed\n");
ok(pf_exists("msitest"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
ok(error == 0xdeadbeef, "got %u\n", error);
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
ok(state == 0xdead, "got %d\n", state);
ok(error == ERROR_SUCCESS, "got %u\n", error);
state = 0xdead;
SetLastError(0xdeadbeef);
r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
error = GetLastError();
ok(r == ERROR_SUCCESS, "got %u\n", r);
ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
ok(error == ERROR_SUCCESS, "got %u\n", error);
state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3848,13 +3901,13 @@ static void test_publish(void) ...@@ -3848,13 +3901,13 @@ static void test_publish(void)
ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
ok(!pf_exists("msitest"), "Directory not deleted\n"); ok(!pf_exists("msitest"), "Directory not deleted\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3871,13 +3924,13 @@ static void test_publish(void) ...@@ -3871,13 +3924,13 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File not installed\n"); ok(pf_exists("msitest\\maximus"), "File not installed\n");
ok(pf_exists("msitest"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3931,13 +3984,13 @@ static void test_publish(void) ...@@ -3931,13 +3984,13 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File deleted\n"); ok(pf_exists("msitest\\maximus"), "File deleted\n");
ok(pf_exists("msitest"), "Directory deleted\n"); ok(pf_exists("msitest"), "Directory deleted\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -3991,13 +4044,13 @@ static void test_publish(void) ...@@ -3991,13 +4044,13 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File not installed\n"); ok(pf_exists("msitest\\maximus"), "File not installed\n");
ok(pf_exists("msitest"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -4051,13 +4104,13 @@ static void test_publish(void) ...@@ -4051,13 +4104,13 @@ static void test_publish(void)
ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
ok(!pf_exists("msitest"), "Directory not deleted\n"); ok(!pf_exists("msitest"), "Directory not deleted\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -4074,13 +4127,13 @@ static void test_publish(void) ...@@ -4074,13 +4127,13 @@ static void test_publish(void)
ok(pf_exists("msitest\\maximus"), "File not installed\n"); ok(pf_exists("msitest\\maximus"), "File not installed\n");
ok(pf_exists("msitest"), "File not installed\n"); ok(pf_exists("msitest"), "File not installed\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
...@@ -4134,13 +4187,13 @@ static void test_publish(void) ...@@ -4134,13 +4187,13 @@ static void test_publish(void)
ok(!pf_exists("msitest\\maximus"), "File not deleted\n"); ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
ok(!pf_exists("msitest"), "Directory not deleted\n"); ok(!pf_exists("msitest"), "Directory not deleted\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); state = MsiQueryProductState(prodcode);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); state = MsiQueryFeatureState(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); state = MsiQueryFeatureState(prodcode, "montecristo");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
......
...@@ -539,6 +539,10 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR, LPCSTR); ...@@ -539,6 +539,10 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR, LPCSTR);
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR); INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR);
#define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState) #define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState)
UINT WINAPI MsiQueryFeatureStateExA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
UINT WINAPI MsiQueryFeatureStateExW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, INSTALLSTATE*);
#define MsiQueryFeatureStateEx WINELIB_NAME_AW(MsiQueryFeatureStateEx)
UINT WINAPI MsiGetFeatureInfoA(MSIHANDLE, LPCSTR, LPDWORD, LPSTR, LPDWORD, LPSTR, LPDWORD); UINT WINAPI MsiGetFeatureInfoA(MSIHANDLE, LPCSTR, LPDWORD, LPSTR, LPDWORD, LPSTR, LPDWORD);
UINT WINAPI MsiGetFeatureInfoW(MSIHANDLE, LPCWSTR, LPDWORD, LPWSTR, LPDWORD, LPWSTR, LPDWORD); UINT WINAPI MsiGetFeatureInfoW(MSIHANDLE, LPCWSTR, LPDWORD, LPWSTR, LPDWORD, LPWSTR, LPDWORD);
#define MsiGetFeatureInfo WINELIB_NAME_AW(MsiGetFeatureInfo) #define MsiGetFeatureInfo WINELIB_NAME_AW(MsiGetFeatureInfo)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment