Commit 3e6f31bf authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Fix and test MsiGetProperty and MsiSetProperty.

parent 94caa05d
...@@ -116,7 +116,7 @@ UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode ...@@ -116,7 +116,7 @@ UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode
return ret; return ret;
} }
static UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz ) UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
{ {
UINT len, r = ERROR_SUCCESS; UINT len, r = ERROR_SUCCESS;
...@@ -134,9 +134,12 @@ static UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz ) ...@@ -134,9 +134,12 @@ static UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
} }
else else
{ {
len = WideCharToMultiByte( CP_ACP, 0, str, -1, len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
awbuf->str.a, *sz, NULL, NULL ); if (len)
len--; len--;
WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL );
if ( *sz && (len >= *sz) )
awbuf->str.a[*sz - 1] = 0;
} }
if (len >= *sz) if (len >= *sz)
......
...@@ -254,6 +254,7 @@ DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x0 ...@@ -254,6 +254,7 @@ DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x0
DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
/* handle unicode/ascii output in the Msi* API functions */
typedef struct { typedef struct {
BOOL unicode; BOOL unicode;
union { union {
...@@ -270,6 +271,8 @@ typedef struct { ...@@ -270,6 +271,8 @@ typedef struct {
} str; } str;
} awcstring; } awcstring;
UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz );
/* handle functions */ /* handle functions */
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type); extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
extern MSIHANDLE alloc_msihandle( MSIOBJECTHDR * ); extern MSIHANDLE alloc_msihandle( MSIOBJECTHDR * );
......
...@@ -682,32 +682,26 @@ out: ...@@ -682,32 +682,26 @@ out:
} }
/* property code */ /* property code */
UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue) UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue )
{ {
LPWSTR szwName = NULL, szwValue = NULL; LPWSTR szwName = NULL, szwValue = NULL;
UINT hr = ERROR_INSTALL_FAILURE; UINT r = ERROR_OUTOFMEMORY;
if( szName ) szwName = strdupAtoW( szName );
{ if( szName && !szwName )
szwName = strdupAtoW( szName ); goto end;
if( !szwName )
goto end;
}
if( szValue ) szwValue = strdupAtoW( szValue );
{ if( szValue && !szwValue )
szwValue = strdupAtoW( szValue ); goto end;
if( !szwValue)
goto end;
}
hr = MsiSetPropertyW( hInstall, szwName, szwValue); r = MsiSetPropertyW( hInstall, szwName, szwValue);
end: end:
msi_free( szwName ); msi_free( szwName );
msi_free( szwValue ); msi_free( szwValue );
return hr; return r;
} }
UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
...@@ -728,8 +722,14 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) ...@@ -728,8 +722,14 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
,'e','r','t','y','`',' ','=',' ','\'','%','s','\'',0}; ,'e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
WCHAR Query[1024]; WCHAR Query[1024];
TRACE("Setting property (%s %s)\n",debugstr_w(szName), TRACE("%p %s %s\n", package, debugstr_w(szName), debugstr_w(szValue));
debugstr_w(szValue));
if (!szName)
return ERROR_INVALID_PARAMETER;
/* this one is wierd... */
if (!szName[0])
return szValue ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS;
rc = MSI_GetPropertyW(package,szName,0,&sz); rc = MSI_GetPropertyW(package,szName,0,&sz);
if (rc==ERROR_MORE_DATA || rc == ERROR_SUCCESS) if (rc==ERROR_MORE_DATA || rc == ERROR_SUCCESS)
...@@ -767,11 +767,6 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue ...@@ -767,11 +767,6 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue
MSIPACKAGE *package; MSIPACKAGE *package;
UINT ret; UINT ret;
if (NULL == szName)
return ERROR_INVALID_PARAMETER;
if (NULL == szValue)
return ERROR_INVALID_PARAMETER;
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
if( !package ) if( !package )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
...@@ -780,51 +775,33 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue ...@@ -780,51 +775,33 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue
return ret; return ret;
} }
static UINT MSI_GetPropertyRow(MSIPACKAGE *package, LPCWSTR szName, MSIRECORD **row) static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name )
{ {
MSIQUERY *view; static const WCHAR query[]=
UINT rc, sz;
static const WCHAR select[]=
{'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ', {'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
'F','R','O','M',' ' ,'`','_','P','r','o','p','e','r','t','y','`', 'F','R','O','M',' ' ,'`','_','P','r','o','p','e','r','t','y','`',
' ','W','H','E','R','E',' ' ,'`','_','P','r','o','p','e','r','t','y','`', ' ','W','H','E','R','E',' ' ,'`','_','P','r','o','p','e','r','t','y','`',
'=','\'','%','s','\'',0}; '=','\'','%','s','\'',0};
LPWSTR query;
if (!szName)
return ERROR_INVALID_PARAMETER;
sz = sizeof select + strlenW(szName)*sizeof(WCHAR);
query = msi_alloc( sz);
sprintfW(query,select,szName);
rc = MSI_DatabaseOpenViewW(package->db, query, &view); if (!name || !name[0])
msi_free(query); return NULL;
if (rc == ERROR_SUCCESS)
{
rc = MSI_ViewExecute(view, 0);
if (rc == ERROR_SUCCESS)
rc = MSI_ViewFetch(view,row);
MSI_ViewClose(view);
msiobj_release(&view->hdr);
}
return rc; return MSI_QueryGetRecord( package->db, query, name );
} }
UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName, /* internal function, not compatible with MsiGetPropertyW */
LPWSTR szValueBuf, DWORD* pchValueBuf) UINT MSI_GetPropertyW( MSIPACKAGE *package, LPCWSTR szName,
LPWSTR szValueBuf, DWORD* pchValueBuf )
{ {
MSIRECORD *row; MSIRECORD *row;
UINT rc; UINT rc = ERROR_FUNCTION_FAILED;
rc = MSI_GetPropertyRow(package, szName, &row); row = MSI_GetPropertyRow( package, szName );
if (*pchValueBuf > 0) if (*pchValueBuf > 0)
szValueBuf[0] = 0; szValueBuf[0] = 0;
if (rc == ERROR_SUCCESS) if (row)
{ {
rc = MSI_RecordGetStringW(row,1,szValueBuf,pchValueBuf); rc = MSI_RecordGetStringW(row,1,szValueBuf,pchValueBuf);
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
...@@ -845,106 +822,67 @@ UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName, ...@@ -845,106 +822,67 @@ UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName,
return rc; return rc;
} }
UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName, static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name,
LPSTR szValueBuf, DWORD* pchValueBuf) awstring *szValueBuf, DWORD* pchValueBuf )
{
MSIRECORD *row;
UINT rc;
LPWSTR szwName = NULL;
if (*pchValueBuf > 0)
szValueBuf[0] = 0;
if( szName )
{
szwName = strdupAtoW( szName );
if (!szwName)
return ERROR_NOT_ENOUGH_MEMORY;
}
rc = MSI_GetPropertyRow(package, szwName, &row);
if (rc == ERROR_SUCCESS)
{
rc = MSI_RecordGetStringA(row,1,szValueBuf,pchValueBuf);
msiobj_release(&row->hdr);
}
if (rc == ERROR_SUCCESS)
TRACE("returning %s for property %s\n", debugstr_a(szValueBuf),
debugstr_a(szName));
else if (rc == ERROR_MORE_DATA)
TRACE("need %ld sized buffer for %s\n", *pchValueBuf,
debugstr_a(szName));
else
{
*pchValueBuf = 0;
TRACE("property not found\n");
}
msi_free( szwName );
return rc;
}
UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
{ {
static const WCHAR empty[] = {0};
MSIPACKAGE *package; MSIPACKAGE *package;
UINT ret; MSIRECORD *row = NULL;
UINT r;
LPCWSTR val = NULL;
TRACE("%lu %s %p\n", hInstall, debugstr_a(szName), pchValueBuf); TRACE("%lu %s %p %p\n", handle, debugstr_w(name),
szValueBuf->str.w, pchValueBuf );
if (0 == hInstall) if (!name)
return ERROR_INVALID_HANDLE;
if (NULL == szName)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
if (NULL != szValueBuf && NULL == pchValueBuf)
return ERROR_INVALID_PARAMETER;
/* This was tested against native msi */
if (NULL == szValueBuf && NULL != pchValueBuf)
*pchValueBuf = 0;
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE );
if (!package) if (!package)
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
ret = MSI_GetPropertyA(package, szName, szValueBuf, pchValueBuf );
msiobj_release( &package->hdr );
/* MsiGetProperty does not return error codes on missing properties */ row = MSI_GetPropertyRow( package, name );
if (ret != ERROR_MORE_DATA) if (row)
ret = ERROR_SUCCESS; val = MSI_RecordGetString( row, 1 );
return ret; if (!val)
val = empty;
r = msi_strcpy_to_awstring( val, szValueBuf, pchValueBuf );
if (row)
msiobj_release( &row->hdr );
msiobj_release( &package->hdr );
return r;
} }
UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName,
UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf )
LPWSTR szValueBuf, DWORD* pchValueBuf)
{ {
MSIPACKAGE *package; awstring val;
UINT ret; LPWSTR name;
UINT r;
TRACE("%lu %s %p\n", hInstall, debugstr_w(szName), pchValueBuf);
if (0 == hInstall) val.unicode = FALSE;
return ERROR_INVALID_HANDLE; val.str.a = szValueBuf;
if (NULL == szName)
return ERROR_INVALID_PARAMETER;
if (NULL != szValueBuf && NULL == pchValueBuf)
return ERROR_INVALID_PARAMETER;
/* This was tested against native msi */ name = strdupAtoW( szName );
if (NULL == szValueBuf && NULL != pchValueBuf) if (szName && !name)
*pchValueBuf = 0; return ERROR_OUTOFMEMORY;
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); r = MSI_GetProperty( hInstall, name, &val, pchValueBuf );
if (!package) msi_free( name );
return ERROR_INVALID_HANDLE; return r;
ret = MSI_GetPropertyW(package, szName, szValueBuf, pchValueBuf ); }
msiobj_release( &package->hdr );
UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName,
LPWSTR szValueBuf, DWORD* pchValueBuf )
{
awstring val;
/* MsiGetProperty does not return error codes on missing properties */ val.unicode = TRUE;
if (ret != ERROR_MORE_DATA) val.str.w = szValueBuf;
ret = ERROR_SUCCESS;
return ret; return MSI_GetProperty( hInstall, szName, &val, pchValueBuf );
} }
...@@ -567,6 +567,128 @@ void test_condition(void) ...@@ -567,6 +567,128 @@ void test_condition(void)
MsiCloseHandle( hpkg ); MsiCloseHandle( hpkg );
} }
static BOOL check_prop_empty( MSIHANDLE hpkg, char * prop)
{
UINT r;
DWORD sz;
char buffer[2];
sz = sizeof buffer;
strcpy(buffer,"x");
r = MsiGetProperty( hpkg, prop, buffer, &sz );
return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
}
static void test_props(void)
{
MSIHANDLE hpkg;
UINT r;
DWORD sz;
char buffer[0x100];
hpkg = package_from_db(create_package_db());
ok( hpkg, "failed to create package\n");
/* test invalid values */
r = MsiGetProperty( 0, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
r = MsiGetProperty( hpkg, NULL, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
r = MsiGetProperty( hpkg, "boo", NULL, NULL );
ok( r == ERROR_SUCCESS, "wrong return val\n");
r = MsiGetProperty( hpkg, "boo", buffer, NULL );
ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
/* test retrieving an empty/non-existant property */
sz = sizeof buffer;
r = MsiGetProperty( hpkg, "boo", NULL, &sz );
ok( r == ERROR_SUCCESS, "wrong return val\n");
ok( sz == 0, "wrong size returned\n");
check_prop_empty( hpkg, "boo");
sz = 0;
strcpy(buffer,"x");
r = MsiGetProperty( hpkg, "boo", buffer, &sz );
ok( r == ERROR_MORE_DATA, "wrong return val\n");
ok( !strcmp(buffer,"x"), "buffer was changed\n");
ok( sz == 0, "wrong size returned\n");
sz = 1;
strcpy(buffer,"x");
r = MsiGetProperty( hpkg, "boo", buffer, &sz );
ok( r == ERROR_SUCCESS, "wrong return val\n");
ok( buffer[0] == 0, "buffer was not changed\n");
ok( sz == 0, "wrong size returned\n");
/* set the property to something */
r = MsiSetProperty( 0, NULL, NULL );
ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
r = MsiSetProperty( hpkg, NULL, NULL );
ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
r = MsiSetProperty( hpkg, "", NULL );
ok( r == ERROR_SUCCESS, "wrong return val\n");
/* try set and get some illegal property identifiers */
r = MsiSetProperty( hpkg, "", "asdf" );
ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
r = MsiSetProperty( hpkg, "=", "asdf" );
ok( r == ERROR_SUCCESS, "wrong return val\n");
r = MsiSetProperty( hpkg, " ", "asdf" );
ok( r == ERROR_SUCCESS, "wrong return val\n");
r = MsiSetProperty( hpkg, "'", "asdf" );
ok( r == ERROR_SUCCESS, "wrong return val\n");
sz = sizeof buffer;
buffer[0]=0;
r = MsiGetProperty( hpkg, "'", buffer, &sz );
ok( r == ERROR_SUCCESS, "wrong return val\n");
ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
/* set empty values */
r = MsiSetProperty( hpkg, "boo", NULL );
ok( r == ERROR_SUCCESS, "wrong return val\n");
ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
r = MsiSetProperty( hpkg, "boo", "" );
ok( r == ERROR_SUCCESS, "wrong return val\n");
ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
/* set a non-empty value */
r = MsiSetProperty( hpkg, "boo", "xyz" );
ok( r == ERROR_SUCCESS, "wrong return val\n");
sz = 1;
strcpy(buffer,"x");
r = MsiGetProperty( hpkg, "boo", buffer, &sz );
ok( r == ERROR_MORE_DATA, "wrong return val\n");
ok( buffer[0] == 0, "buffer was not changed\n");
ok( sz == 3, "wrong size returned\n");
sz = 4;
strcpy(buffer,"x");
r = MsiGetProperty( hpkg, "boo", buffer, &sz );
ok( r == ERROR_SUCCESS, "wrong return val\n");
ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
ok( sz == 3, "wrong size returned\n");
sz = 3;
strcpy(buffer,"x");
r = MsiGetProperty( hpkg, "boo", buffer, &sz );
ok( r == ERROR_MORE_DATA, "wrong return val\n");
ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
ok( sz == 3, "wrong size returned\n");
MsiCloseHandle( hpkg );
}
START_TEST(package) START_TEST(package)
{ {
test_createpackage(); test_createpackage();
...@@ -574,4 +696,5 @@ START_TEST(package) ...@@ -574,4 +696,5 @@ START_TEST(package)
test_getsourcepath(); test_getsourcepath();
test_doaction(); test_doaction();
test_gettargetpath_bad(); test_gettargetpath_bad();
test_props();
} }
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