Commit 49d67080 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

msi: Make MsiGetTargetPath() RPC-compatible.

parent 676376d1
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "wine/debug.h"
#include "msi.h" #include "msi.h"
#include "msidefs.h" #include "msidefs.h"
#include "objbase.h" #include "objbase.h"
...@@ -35,6 +34,8 @@ ...@@ -35,6 +34,8 @@
#include "msipriv.h" #include "msipriv.h"
#include "winemsi.h" #include "winemsi.h"
#include "wine/heap.h"
#include "wine/debug.h"
#include "wine/unicode.h" #include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi); WINE_DEFAULT_DEBUG_CHANNEL(msi);
...@@ -200,50 +201,19 @@ static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder, ...@@ -200,50 +201,19 @@ static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
if (!package) if (!package)
{ {
MSIHANDLE remote;
HRESULT hr;
LPWSTR value = NULL; LPWSTR value = NULL;
BSTR folder; MSIHANDLE remote;
DWORD len;
if (!(remote = msi_get_remote(hInstall))) if (!(remote = msi_get_remote(hInstall)))
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
folder = SysAllocString( szFolder ); r = remote_GetTargetPath(remote, szFolder, &value);
if (!folder) if (r != ERROR_SUCCESS)
return ERROR_OUTOFMEMORY; return r;
len = 0;
hr = remote_GetTargetPath(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_GetTargetPath(remote, folder, value, &len);
if (FAILED(hr))
goto done;
r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf );
done: r = msi_strcpy_to_awstring(value, -1, szPathBuf, pcchPathBuf);
SysFreeString( folder );
msi_free( value );
if (FAILED(hr))
{
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
return HRESULT_CODE(hr);
return ERROR_FUNCTION_FAILED;
}
midl_user_free(value);
return r; return r;
} }
......
...@@ -2474,10 +2474,21 @@ UINT __cdecl remote_Sequence(MSIHANDLE hinst, LPCWSTR table, int sequence) ...@@ -2474,10 +2474,21 @@ UINT __cdecl remote_Sequence(MSIHANDLE hinst, LPCWSTR table, int sequence)
return MsiSequenceW(hinst, table, sequence); return MsiSequenceW(hinst, table, sequence);
} }
HRESULT __cdecl remote_GetTargetPath(MSIHANDLE hinst, BSTR folder, BSTR value, DWORD *size) UINT __cdecl remote_GetTargetPath(MSIHANDLE hinst, LPCWSTR folder, LPWSTR *value)
{ {
UINT r = MsiGetTargetPathW(hinst, folder, value, size); WCHAR empty[1];
return HRESULT_FROM_WIN32(r); DWORD size = 0;
UINT r;
r = MsiGetTargetPathW(hinst, folder, empty, &size);
if (r == ERROR_MORE_DATA)
{
*value = midl_user_allocate(++size * sizeof(WCHAR));
if (!*value)
return ERROR_OUTOFMEMORY;
r = MsiGetTargetPathW(hinst, folder, *value, &size);
}
return r;
} }
HRESULT __cdecl remote_SetTargetPath(MSIHANDLE hinst, BSTR folder, BSTR value) HRESULT __cdecl remote_SetTargetPath(MSIHANDLE hinst, BSTR folder, BSTR value)
......
...@@ -453,6 +453,96 @@ UINT WINAPI nested(MSIHANDLE hinst) ...@@ -453,6 +453,96 @@ UINT WINAPI nested(MSIHANDLE hinst)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
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;
UINT r;
/* test invalid values */
r = MsiGetTargetPathA(hinst, NULL, NULL, NULL);
ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r);
r = MsiGetTargetPathA(hinst, "TARGETDIR", NULL, NULL );
ok(hinst, !r, "got %u\n", r);
r = MsiGetTargetPathA(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... */
sz = 0;
r = MsiGetTargetPathA(hinst, "TARGETDIR", NULL, &sz);
ok(hinst, !r, "got %u\n", r);
todo_wine_ok(hinst, sz == 6, "got size %u\n", sz);
sz = 0;
strcpy(buffer,"q");
r = MsiGetTargetPathA(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 == 6, "got size %u\n", sz);
sz = 1;
strcpy(buffer,"x");
r = MsiGetTargetPathA(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 == 6, "got size %u\n", sz);
sz = 3;
strcpy(buffer,"x");
r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz);
ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
ok(hinst, !strcmp(buffer, "C:"), "got \"%s\"\n", buffer);
todo_wine_ok(hinst, sz == 6, "got size %u\n", sz);
sz = 4;
strcpy(buffer,"x");
r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz);
ok(hinst, !r, "got %u\n", r);
ok(hinst, !strcmp(buffer, "C:\\"), "got \"%s\"\n", buffer);
ok(hinst, sz == 3, "got size %u\n", sz);
sz = 0;
r = MsiGetTargetPathW(hinst, targetdirW, NULL, &sz);
ok(hinst, !r, "got %u\n", r);
ok(hinst, sz == 3, "got size %u\n", sz);
sz = 0;
bufferW[0] = 'q';
r = MsiGetTargetPathW(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 == 3, "got size %u\n", sz);
sz = 1;
bufferW[0] = 'q';
r = MsiGetTargetPathW(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 == 3, "got size %u\n", sz);
sz = 3;
bufferW[0] = 'q';
r = MsiGetTargetPathW(hinst, targetdirW, bufferW, &sz);
ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
ok(hinst, !lstrcmpW(bufferW, xyW), "got %s\n", dbgstr_w(bufferW));
ok(hinst, sz == 3, "got size %u\n", sz);
sz = 4;
bufferW[0] = 'q';
r = MsiGetTargetPathW(hinst, targetdirW, bufferW, &sz);
ok(hinst, !r, "got %u\n", r);
ok(hinst, !lstrcmpW(bufferW, xyzW), "got %s\n", dbgstr_w(bufferW));
ok(hinst, sz == 3, "got size %u\n", sz);
}
/* Main test. Anything that doesn't depend on a specific install configuration /* Main test. Anything that doesn't depend on a specific install configuration
* or have undesired side effects should go here. */ * or have undesired side effects should go here. */
UINT WINAPI main_test(MSIHANDLE hinst) UINT WINAPI main_test(MSIHANDLE hinst)
...@@ -479,6 +569,7 @@ UINT WINAPI main_test(MSIHANDLE hinst) ...@@ -479,6 +569,7 @@ UINT WINAPI main_test(MSIHANDLE hinst)
test_props(hinst); test_props(hinst);
test_db(hinst); test_db(hinst);
test_doaction(hinst); test_doaction(hinst);
test_targetpath(hinst);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
......
...@@ -695,6 +695,9 @@ static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAtt ...@@ -695,6 +695,9 @@ static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAtt
static const CHAR ca1_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" static const CHAR ca1_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
"s72\tS255\tI2\n" "s72\tS255\tI2\n"
"InstallExecuteSequence\tAction\n" "InstallExecuteSequence\tAction\n"
"CostInitialize\t\t100\n"
"FileCost\t\t200\n"
"CostFinalize\t\t300\n"
"embednull\t\t600\n" "embednull\t\t600\n"
"maintest\tMAIN_TEST\t700\n" "maintest\tMAIN_TEST\t700\n"
"testretval\tTEST_RETVAL\t710\n"; "testretval\tTEST_RETVAL\t710\n";
...@@ -1709,7 +1712,13 @@ static const msi_table sf_tables[] = ...@@ -1709,7 +1712,13 @@ static const msi_table sf_tables[] =
static const msi_table ca1_tables[] = static const msi_table ca1_tables[] =
{ {
ADD_TABLE(component),
ADD_TABLE(directory),
ADD_TABLE(feature),
ADD_TABLE(feature_comp),
ADD_TABLE(file),
ADD_TABLE(property), ADD_TABLE(property),
ADD_TABLE(directory),
ADD_TABLE(ca1_install_exec_seq), ADD_TABLE(ca1_install_exec_seq),
ADD_TABLE(ca1_custom_action), ADD_TABLE(ca1_custom_action),
ADD_TABLE(ca1_test_seq), ADD_TABLE(ca1_test_seq),
...@@ -4120,6 +4129,7 @@ static void test_customaction1(void) ...@@ -4120,6 +4129,7 @@ static void test_customaction1(void)
MSIHANDLE hdb, record; MSIHANDLE hdb, record;
UINT r; UINT r;
create_test_files();
create_database(msifile, ca1_tables, sizeof(ca1_tables) / sizeof(msi_table)); create_database(msifile, ca1_tables, sizeof(ca1_tables) / sizeof(msi_table));
add_custom_dll(); add_custom_dll();
...@@ -4158,6 +4168,7 @@ static void test_customaction1(void) ...@@ -4158,6 +4168,7 @@ static void test_customaction1(void)
r = MsiInstallProductA(msifile, "TEST_RETVAL=1"); r = MsiInstallProductA(msifile, "TEST_RETVAL=1");
ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
delete_test_files();
DeleteFileA(msifile); DeleteFileA(msifile);
DeleteFileA("unus"); DeleteFileA("unus");
DeleteFileA("duo"); DeleteFileA("duo");
......
...@@ -76,7 +76,7 @@ interface IWineMsiRemote ...@@ -76,7 +76,7 @@ interface IWineMsiRemote
int remote_ProcessMessage( [in] MSIHANDLE hinst, [in] INSTALLMESSAGE message, [in] struct wire_record *record ); int remote_ProcessMessage( [in] MSIHANDLE hinst, [in] INSTALLMESSAGE message, [in] struct wire_record *record );
UINT remote_DoAction( [in] MSIHANDLE hinst, [in, string] LPCWSTR action ); UINT remote_DoAction( [in] MSIHANDLE hinst, [in, string] LPCWSTR action );
UINT remote_Sequence( [in] MSIHANDLE hinst, [in, string] LPCWSTR table, [in] int sequence ); UINT remote_Sequence( [in] MSIHANDLE hinst, [in, string] LPCWSTR table, [in] int sequence );
HRESULT remote_GetTargetPath( [in] MSIHANDLE hinst, [in] BSTR folder, [out, size_is(*size)] BSTR value, [in, out] DWORD *size ); UINT remote_GetTargetPath( [in] MSIHANDLE hinst, [in, string] LPCWSTR folder, [out, string] LPWSTR *value );
HRESULT remote_SetTargetPath( [in] MSIHANDLE hinst, [in] BSTR folder, [in] BSTR value ); HRESULT remote_SetTargetPath( [in] MSIHANDLE hinst, [in] BSTR folder, [in] BSTR value );
HRESULT remote_GetSourcePath( [in] MSIHANDLE hinst, [in] BSTR folder, [out, size_is(*size)] BSTR value, [in, out] DWORD *size ); HRESULT remote_GetSourcePath( [in] MSIHANDLE hinst, [in] BSTR folder, [out, size_is(*size)] BSTR value, [in, out] DWORD *size );
HRESULT remote_GetMode( [in] MSIHANDLE hinst, [in] MSIRUNMODE mode, [out] BOOL *ret ); HRESULT remote_GetMode( [in] MSIHANDLE hinst, [in] MSIRUNMODE mode, [out] BOOL *ret );
......
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