Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/install.c | 41 +++-------------------- dlls/msi/package.c | 17 ++++++++-- dlls/msi/tests/custom.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++-- dlls/msi/winemsi.idl | 2 +- 4 files changed, 106 insertions(+), 43 deletions(-)
diff --git a/dlls/msi/install.c b/dlls/msi/install.c index ba329eb..88b3ff5 100644 --- a/dlls/msi/install.c +++ b/dlls/msi/install.c @@ -334,50 +334,19 @@ static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder, package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); if (!package) { - HRESULT hr; LPWSTR value = NULL; MSIHANDLE remote; - BSTR folder; - DWORD len;
if (!(remote = msi_get_remote(hInstall))) return ERROR_INVALID_HANDLE;
- folder = SysAllocString( szFolder ); - if (!folder) - return ERROR_OUTOFMEMORY; + r = remote_GetSourcePath(remote, szFolder, &value); + if (r != ERROR_SUCCESS) + return r;
- len = 0; - hr = remote_GetSourcePath(remote, folder, NULL, &len); - if (FAILED(hr)) - goto done; - - len++; - value = msi_alloc(len * sizeof(WCHAR)); - if (!value) - { - r = ERROR_OUTOFMEMORY; - goto done; - } - - hr = remote_GetSourcePath(remote, folder, value, &len); - if (FAILED(hr)) - goto done; - - r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf ); - -done: - SysFreeString( folder ); - msi_free( value ); - - if (FAILED(hr)) - { - if (HRESULT_FACILITY(hr) == FACILITY_WIN32) - return HRESULT_CODE(hr); - - return ERROR_FUNCTION_FAILED; - } + r = msi_strcpy_to_awstring(value, -1, szPathBuf, pcchPathBuf);
+ midl_user_free(value); return r; }
diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 220692b..1790918 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -2496,10 +2496,21 @@ UINT __cdecl remote_SetTargetPath(MSIHANDLE hinst, LPCWSTR folder, LPCWSTR value return MsiSetTargetPathW(hinst, folder, value); }
-HRESULT __cdecl remote_GetSourcePath(MSIHANDLE hinst, BSTR folder, BSTR value, DWORD *size) +UINT __cdecl remote_GetSourcePath(MSIHANDLE hinst, LPCWSTR folder, LPWSTR *value) { - UINT r = MsiGetSourcePathW(hinst, folder, value, size); - return HRESULT_FROM_WIN32(r); + WCHAR empty[1]; + DWORD size = 1; + UINT r; + + r = MsiGetSourcePathW(hinst, folder, empty, &size); + if (r == ERROR_MORE_DATA) + { + *value = midl_user_allocate(++size * sizeof(WCHAR)); + if (!*value) + return ERROR_OUTOFMEMORY; + r = MsiGetSourcePathW(hinst, folder, *value, &size); + } + return r; }
HRESULT __cdecl remote_GetMode(MSIHANDLE hinst, MSIRUNMODE mode, BOOL *ret) diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index 111032c..d596f1e 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/custom.c @@ -458,9 +458,9 @@ static void test_targetpath(MSIHANDLE hinst) static const WCHAR targetdirW[] = {'T','A','R','G','E','T','D','I','R',0}; static const WCHAR xyzW[] = {'C',':','\',0}; static const WCHAR xyW[] = {'C',':',0}; - char buffer[20]; - WCHAR bufferW[20]; - DWORD sz; + WCHAR bufferW[100]; + char buffer[100]; + DWORD sz, srcsz; UINT r;
/* test invalid values */ @@ -557,6 +557,89 @@ static void test_targetpath(MSIHANDLE hinst) ok(hinst, !strcmp(buffer, "C:\subdir\"), "got "%s"\n", buffer);
r = MsiSetTargetPathA(hinst, "TARGETDIR", "C:\"); + + /* test GetSourcePath() */ + + r = MsiGetSourcePathA(hinst, NULL, NULL, NULL); + ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); + + r = MsiGetSourcePathA(hinst, "TARGETDIR", NULL, NULL ); + ok(hinst, !r, "got %u\n", r); + + r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, NULL ); + ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); + + /* Returned size is in bytes, not chars, but only for custom actions. + * Seems to be a casualty of RPC... */ + + srcsz = 0; + MsiGetSourcePathW(hinst, targetdirW, NULL, &srcsz); + + sz = 0; + r = MsiGetSourcePathA(hinst, "TARGETDIR", NULL, &sz); + ok(hinst, !r, "got %u\n", r); + todo_wine_ok(hinst, sz == srcsz * 2, "got size %u\n", sz); + + sz = 0; + strcpy(buffer,"q"); + r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); + ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); + ok(hinst, !strcmp(buffer, "q"), "got "%s"\n", buffer); + todo_wine_ok(hinst, sz == srcsz * 2, "got size %u\n", sz); + + sz = 1; + strcpy(buffer,"x"); + r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); + ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); + ok(hinst, !buffer[0], "got "%s"\n", buffer); + todo_wine_ok(hinst, sz == srcsz * 2, "got size %u\n", sz); + + sz = srcsz; + strcpy(buffer,"x"); + r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); + ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); + ok(hinst, strlen(buffer) == srcsz - 1, "wrong buffer length %d\n", strlen(buffer)); + todo_wine_ok(hinst, sz == srcsz * 2, "got size %u\n", sz); + + sz = srcsz + 1; + strcpy(buffer,"x"); + r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); + ok(hinst, !r, "got %u\n", r); + ok(hinst, strlen(buffer) == srcsz, "wrong buffer length %d\n", strlen(buffer)); + ok(hinst, sz == srcsz, "got size %u\n", sz); + + sz = 0; + r = MsiGetSourcePathW(hinst, targetdirW, NULL, &sz); + ok(hinst, !r, "got %u\n", r); + ok(hinst, sz == srcsz, "got size %u\n", sz); + + sz = 0; + bufferW[0] = 'q'; + r = MsiGetSourcePathW(hinst, targetdirW, bufferW, &sz); + ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); + ok(hinst, bufferW[0] == 'q', "got %s\n", dbgstr_w(bufferW)); + ok(hinst, sz == srcsz, "got size %u\n", sz); + + sz = 1; + bufferW[0] = 'q'; + r = MsiGetSourcePathW(hinst, targetdirW, bufferW, &sz); + ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); + ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW)); + ok(hinst, sz == srcsz, "got size %u\n", sz); + + sz = srcsz; + bufferW[0] = 'q'; + r = MsiGetSourcePathW(hinst, targetdirW, bufferW, &sz); + ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); + ok(hinst, lstrlenW(bufferW) == srcsz - 1, "wrong buffer length %d\n", lstrlenW(bufferW)); + ok(hinst, sz == srcsz, "got size %u\n", sz); + + sz = srcsz + 1; + bufferW[0] = 'q'; + r = MsiGetSourcePathW(hinst, targetdirW, bufferW, &sz); + ok(hinst, !r, "got %u\n", r); + ok(hinst, lstrlenW(bufferW) == srcsz, "wrong buffer length %d\n", lstrlenW(bufferW)); + ok(hinst, sz == srcsz, "got size %u\n", sz); }
/* Main test. Anything that doesn't depend on a specific install configuration diff --git a/dlls/msi/winemsi.idl b/dlls/msi/winemsi.idl index a0e1ddb..06db52e 100644 --- a/dlls/msi/winemsi.idl +++ b/dlls/msi/winemsi.idl @@ -78,7 +78,7 @@ interface IWineMsiRemote UINT remote_Sequence( [in] MSIHANDLE hinst, [in, string] LPCWSTR table, [in] int sequence ); UINT remote_GetTargetPath( [in] MSIHANDLE hinst, [in, string] LPCWSTR folder, [out, string] LPWSTR *value ); UINT remote_SetTargetPath( [in] MSIHANDLE hinst, [in, string] LPCWSTR folder, [in, string] LPCWSTR value ); - HRESULT remote_GetSourcePath( [in] MSIHANDLE hinst, [in] BSTR folder, [out, size_is(*size)] BSTR value, [in, out] DWORD *size ); + UINT remote_GetSourcePath( [in] MSIHANDLE hinst, [in, string] LPCWSTR folder, [out, string] LPWSTR *value ); HRESULT remote_GetMode( [in] MSIHANDLE hinst, [in] MSIRUNMODE mode, [out] BOOL *ret ); HRESULT remote_SetMode( [in] MSIHANDLE hinst, [in] MSIRUNMODE mode, [in] BOOL state ); HRESULT remote_GetFeatureState( [in] MSIHANDLE hinst, [in] BSTR feature, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action );