Fix and test MsiGetProperty and MsiSetProperty.
This commit is contained in:
parent
94caa05d07
commit
3e6f31bf0b
|
@ -116,7 +116,7 @@ UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode
|
|||
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;
|
||||
|
||||
|
@ -134,9 +134,12 @@ static UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
|
|||
}
|
||||
else
|
||||
{
|
||||
len = WideCharToMultiByte( CP_ACP, 0, str, -1,
|
||||
awbuf->str.a, *sz, NULL, NULL );
|
||||
len--;
|
||||
len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
|
||||
if (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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* handle unicode/ascii output in the Msi* API functions */
|
||||
typedef struct {
|
||||
BOOL unicode;
|
||||
union {
|
||||
|
@ -270,6 +271,8 @@ typedef struct {
|
|||
} str;
|
||||
} awcstring;
|
||||
|
||||
UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz );
|
||||
|
||||
/* handle functions */
|
||||
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
|
||||
extern MSIHANDLE alloc_msihandle( MSIOBJECTHDR * );
|
||||
|
|
|
@ -682,32 +682,26 @@ out:
|
|||
}
|
||||
|
||||
/* 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;
|
||||
UINT hr = ERROR_INSTALL_FAILURE;
|
||||
UINT r = ERROR_OUTOFMEMORY;
|
||||
|
||||
if( szName )
|
||||
{
|
||||
szwName = strdupAtoW( szName );
|
||||
if( !szwName )
|
||||
goto end;
|
||||
}
|
||||
szwName = strdupAtoW( szName );
|
||||
if( szName && !szwName )
|
||||
goto end;
|
||||
|
||||
if( szValue )
|
||||
{
|
||||
szwValue = strdupAtoW( szValue );
|
||||
if( !szwValue)
|
||||
goto end;
|
||||
}
|
||||
szwValue = strdupAtoW( szValue );
|
||||
if( szValue && !szwValue )
|
||||
goto end;
|
||||
|
||||
hr = MsiSetPropertyW( hInstall, szwName, szwValue);
|
||||
r = MsiSetPropertyW( hInstall, szwName, szwValue);
|
||||
|
||||
end:
|
||||
msi_free( szwName );
|
||||
msi_free( szwValue );
|
||||
|
||||
return hr;
|
||||
return r;
|
||||
}
|
||||
|
||||
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};
|
||||
WCHAR Query[1024];
|
||||
|
||||
TRACE("Setting property (%s %s)\n",debugstr_w(szName),
|
||||
debugstr_w(szValue));
|
||||
TRACE("%p %s %s\n", package, debugstr_w(szName), 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);
|
||||
if (rc==ERROR_MORE_DATA || rc == ERROR_SUCCESS)
|
||||
|
@ -767,11 +767,6 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue
|
|||
MSIPACKAGE *package;
|
||||
UINT ret;
|
||||
|
||||
if (NULL == szName)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if (NULL == szValue)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
|
||||
if( !package )
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
@ -780,51 +775,33 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue
|
|||
return ret;
|
||||
}
|
||||
|
||||
static UINT MSI_GetPropertyRow(MSIPACKAGE *package, LPCWSTR szName, MSIRECORD **row)
|
||||
static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name )
|
||||
{
|
||||
MSIQUERY *view;
|
||||
UINT rc, sz;
|
||||
static const WCHAR select[]=
|
||||
static const WCHAR query[]=
|
||||
{'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
|
||||
'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','`',
|
||||
'=','\'','%','s','\'',0};
|
||||
LPWSTR query;
|
||||
|
||||
if (!szName)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if (!name || !name[0])
|
||||
return NULL;
|
||||
|
||||
sz = sizeof select + strlenW(szName)*sizeof(WCHAR);
|
||||
query = msi_alloc( sz);
|
||||
sprintfW(query,select,szName);
|
||||
|
||||
rc = MSI_DatabaseOpenViewW(package->db, query, &view);
|
||||
msi_free(query);
|
||||
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,
|
||||
LPWSTR szValueBuf, DWORD* pchValueBuf)
|
||||
|
||||
/* internal function, not compatible with MsiGetPropertyW */
|
||||
UINT MSI_GetPropertyW( MSIPACKAGE *package, LPCWSTR szName,
|
||||
LPWSTR szValueBuf, DWORD* pchValueBuf )
|
||||
{
|
||||
MSIRECORD *row;
|
||||
UINT rc;
|
||||
UINT rc = ERROR_FUNCTION_FAILED;
|
||||
|
||||
rc = MSI_GetPropertyRow(package, szName, &row);
|
||||
row = MSI_GetPropertyRow( package, szName );
|
||||
|
||||
if (*pchValueBuf > 0)
|
||||
szValueBuf[0] = 0;
|
||||
|
||||
if (rc == ERROR_SUCCESS)
|
||||
if (row)
|
||||
{
|
||||
rc = MSI_RecordGetStringW(row,1,szValueBuf,pchValueBuf);
|
||||
msiobj_release(&row->hdr);
|
||||
|
@ -845,106 +822,67 @@ UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName,
|
|||
return rc;
|
||||
}
|
||||
|
||||
UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName,
|
||||
LPSTR 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 UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name,
|
||||
awstring *szValueBuf, DWORD* pchValueBuf )
|
||||
{
|
||||
static const WCHAR empty[] = {0};
|
||||
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)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
if (NULL == szName)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if (NULL != szValueBuf && NULL == pchValueBuf)
|
||||
if (!name)
|
||||
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)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
ret = MSI_GetPropertyA(package, szName, szValueBuf, pchValueBuf );
|
||||
|
||||
row = MSI_GetPropertyRow( package, name );
|
||||
if (row)
|
||||
val = MSI_RecordGetString( row, 1 );
|
||||
|
||||
if (!val)
|
||||
val = empty;
|
||||
|
||||
r = msi_strcpy_to_awstring( val, szValueBuf, pchValueBuf );
|
||||
|
||||
if (row)
|
||||
msiobj_release( &row->hdr );
|
||||
msiobj_release( &package->hdr );
|
||||
|
||||
/* MsiGetProperty does not return error codes on missing properties */
|
||||
if (ret != ERROR_MORE_DATA)
|
||||
ret = ERROR_SUCCESS;
|
||||
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
|
||||
UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName,
|
||||
LPSTR szValueBuf, DWORD* pchValueBuf )
|
||||
{
|
||||
awstring val;
|
||||
LPWSTR name;
|
||||
UINT r;
|
||||
|
||||
val.unicode = FALSE;
|
||||
val.str.a = szValueBuf;
|
||||
|
||||
name = strdupAtoW( szName );
|
||||
if (szName && !name)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
r = MSI_GetProperty( hInstall, name, &val, pchValueBuf );
|
||||
msi_free( name );
|
||||
return r;
|
||||
}
|
||||
|
||||
UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
|
||||
LPWSTR szValueBuf, DWORD* pchValueBuf)
|
||||
UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName,
|
||||
LPWSTR szValueBuf, DWORD* pchValueBuf )
|
||||
{
|
||||
MSIPACKAGE *package;
|
||||
UINT ret;
|
||||
awstring val;
|
||||
|
||||
TRACE("%lu %s %p\n", hInstall, debugstr_w(szName), pchValueBuf);
|
||||
val.unicode = TRUE;
|
||||
val.str.w = szValueBuf;
|
||||
|
||||
if (0 == hInstall)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
if (NULL == szName)
|
||||
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);
|
||||
if (!package)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
ret = MSI_GetPropertyW(package, szName, szValueBuf, pchValueBuf );
|
||||
msiobj_release( &package->hdr );
|
||||
|
||||
/* MsiGetProperty does not return error codes on missing properties */
|
||||
if (ret != ERROR_MORE_DATA)
|
||||
ret = ERROR_SUCCESS;
|
||||
|
||||
return ret;
|
||||
return MSI_GetProperty( hInstall, szName, &val, pchValueBuf );
|
||||
}
|
||||
|
|
|
@ -567,6 +567,128 @@ void test_condition(void)
|
|||
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)
|
||||
{
|
||||
test_createpackage();
|
||||
|
@ -574,4 +696,5 @@ START_TEST(package)
|
|||
test_getsourcepath();
|
||||
test_doaction();
|
||||
test_gettargetpath_bad();
|
||||
test_props();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue