diff --git a/dlls/msi/source.c b/dlls/msi/source.c index 9ae4a65fe62..16e247cca33 100644 --- a/dlls/msi/source.c +++ b/dlls/msi/source.c @@ -353,6 +353,8 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, { WCHAR squished_pc[GUID_SIZE]; HKEY sourcekey, media; + LPWSTR source, ptr; + DWORD size; UINT rc; static const WCHAR mediapack[] = { @@ -400,39 +402,43 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, RegQueryValueExW(media, szProperty, 0, 0, (LPBYTE)szValue, pcchValue); RegCloseKey(media); } - else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0) + else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)) { - LPWSTR buffer; - DWORD size = 0; - - RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0, - NULL, &size); - if (size == 0) - rc = ERROR_UNKNOWN_PROPERTY; - else + rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, + 0, 0, NULL, &size); + if (rc != ERROR_SUCCESS) { - LPWSTR ptr; - buffer = msi_alloc(size); - rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, - 0, 0, (LPBYTE)buffer,&size); - ptr = strchrW(buffer,';'); - if (ptr) ptr = strchrW(ptr+1,';'); - if (!ptr) - rc = ERROR_UNKNOWN_PROPERTY; - else - { - ptr ++; - lstrcpynW(szValue, ptr, *pcchValue); - if (lstrlenW(ptr) > *pcchValue) - { - *pcchValue = lstrlenW(ptr)+1; - rc = ERROR_MORE_DATA; - } - else - rc = ERROR_SUCCESS; - } - msi_free(buffer); + RegCloseKey(sourcekey); + return ERROR_SUCCESS; } + + source = msi_alloc(size); + RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, + 0, 0, (LPBYTE)source, &size); + + if (!*source) + { + msi_free(source); + RegCloseKey(sourcekey); + return ERROR_SUCCESS; + } + + ptr = strrchrW(source, ';'); + if (!ptr) + ptr = source; + else + ptr++; + + if (szValue) + { + if (lstrlenW(ptr) < *pcchValue) + lstrcpyW(szValue, ptr); + else + rc = ERROR_MORE_DATA; + } + + *pcchValue = lstrlenW(ptr); + msi_free(source); } else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0) { diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 963d3d89ad3..b62e625a89c 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -3017,12 +3017,9 @@ static void test_publishsourcelist(void) lstrcpyA(value, "aaa"); r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size); - todo_wine - { - 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 %d\n", lstrlenA(path), 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 %d\n", lstrlenA(path), size); size = MAX_PATH; lstrcpyA(value, "aaa"); diff --git a/dlls/msi/tests/source.c b/dlls/msi/tests/source.c index 00a869a27aa..76720dab9dd 100644 --- a/dlls/msi/tests/source.c +++ b/dlls/msi/tests/source.c @@ -373,6 +373,20 @@ static void test_MsiSourceListGetInfo(void) ok(!lstrcmpA(value, "prompt"), "Expected \"prompt\", got \"%s\"\n", value); ok(size == 6, "Expected 6, got %d\n", size); + data = ""; + res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ, + (const BYTE *)data, lstrlenA(data) + 1); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + /* INSTALLPROPERTY_LASTUSEDSOURCE, source is empty */ + size = MAX_PATH; + r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, + 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 %d\n", size); + data = "source"; res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1); @@ -383,12 +397,57 @@ static void test_MsiSourceListGetInfo(void) r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value); - ok(size == 6, "Expected 6, got %d\n", size); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value); + ok(size == 6, "Expected 6, got %d\n", size); + + /* INSTALLPROPERTY_LASTUSEDSOURCE, size is too short */ + size = 4; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, + value, &size); + ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); + ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value); + ok(size == 6, "Expected 6, got %d\n", size); + + /* INSTALLPROPERTY_LASTUSEDSOURCE, size is exactly 6 */ + size = 6; + lstrcpyA(value, "aaa"); + r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, + value, &size); + ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); + ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value); + ok(size == 6, "Expected 6, got %d\n", size); + + data = "a;source"; + res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ, + (const BYTE *)data, lstrlenA(data) + 1); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + /* INSTALLPROPERTY_LASTUSEDSOURCE, one semi-colon */ + size = MAX_PATH; + r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, + value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value); + ok(size == 6, "Expected 6, got %d\n", size); + + data = "a:source"; + res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ, + (const BYTE *)data, lstrlenA(data) + 1); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + /* INSTALLPROPERTY_LASTUSEDSOURCE, one colon */ + size = MAX_PATH; + r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, + MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, + value, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(value, "a:source"), "Expected \"a:source\", got \"%s\"\n", value); + ok(size == 8, "Expected 8, got %d\n", size); /* INSTALLPROPERTY_LASTUSEDTYPE, invalid source format */ size = MAX_PATH;