Sync to Wine-20050419:

Mike McCormack <[email protected]>
- Load and display bitmaps in the dialogs.
- Make sure there's only one place we allocate dialog controls.
- Rename dupstrW to strdupW, and remove duplicate definition.
- Move definition of string manipulation functions to msipriv.h.
- Split out database functions, remove dependence on wine/unicode.h.
- Fix loading of the summary information.
- test cases for summary information
- fix memory leaks
- Implement summary information loading and saving.
- Declare MsiExportDatabase* in the spec file, and fix a typo.
- Replace instances of HeapAlloc/MultiByteToWideChar with the internally
  defined strdupAtoW.
- Use strdup, implement MsiDatabaseImportA.
Francois Gouget <[email protected]>
- Assorted spelling fixes.
Peter Berg Larsen <[email protected]>
- Janitorial: Get rid of strncpy/strncpyW.
- Remove 2 identicals calls to strlenW.
Jose Manuel Ferrer Ortiz <[email protected]>
- Spanish translations updated.
Aric Stewart <[email protected]>
- Implement Publish Components in order for MsiGetQualifiedComponent
  apis to work. Also implement MsiGetQualifiedComponent, or at least some
  of the functionality as it is supposed to install stuff if it is
  absent, which it does not do yet.
- Make sure the GUID of the typelib we are registering matches the guid
  requested from MSI. If not search the given typelib file to find the
  typelib requested to register.
- If running in UI mode, then display the UI mode dialogs at the end of
  the installs.
Steven Edwards <[email protected]>
- Avoid using ver.h in favor of winver.h.
Jakob Eriksson <[email protected]>
- Get rid of HeapAlloc casts.
Hans Leidekker <[email protected]>
- Dutch resource translation.
Marcus Meissner <[email protected]>
- Fixed MsiDatabaseImportA, MsiDatabaseImportW, and
  MsiCreateAndVerifyInstallerDirectory stub parameter counts.
Juan Lang <[email protected]>
- Log missing environment vars for easier debugging.

svn path=/trunk/; revision=14823
This commit is contained in:
Gé van Geldorp
2005-04-26 20:39:02 +00:00
parent f668ceb14f
commit c5106fcc0a
25 changed files with 1672 additions and 938 deletions
+43
View File
@@ -103,6 +103,49 @@ enum msidbComponentAttributes
msidbComponentAttributes64bit = 0x00000100
};
/*
* Windows SDK braindamage alert
*
* PID_DICTIONARY and PID_CODEPAGE are defined by propidl.h too
* PID_SECURITY is defined in propidl.h with a different value!
* So these need to be undefined first.
*/
#ifdef PID_DICTIONARY
#undef PID_DICTIONARY
#endif
#ifdef PID_CODEPAGE
#undef PID_CODEPAGE
#endif
#ifdef PID_SECURITY
#undef PID_SECURITY
#endif
#define PID_DICTIONARY 0
#define PID_CODEPAGE 1
#define PID_TITLE 2
#define PID_SUBJECT 3
#define PID_AUTHOR 4
#define PID_KEYWORDS 5
#define PID_COMMENTS 6
#define PID_TEMPLATE 7
#define PID_LASTAUTHOR 8
#define PID_REVNUMBER 9
#define PID_EDITTINE 10
#define PID_LASTPRINTED 11
#define PID_CREATE_DTM 12
#define PID_LASTSAVE_DTM 13
#define PID_PAGECOUNT 14
#define PID_WORDCOUNT 15
#define PID_CHARCOUNT 16
#define PID_THUMBNAIL 17
#define PID_APPNAME 18
#define PID_SECURITY 19
#define PID_MSIVERSION PID_PAGECOUNT
#define PID_MSISOURCE PID_WORDCOUNT
#define PID_MSIRESTRICT PID_CHARCOUNT
#ifdef __cplusplus
}
#endif
+1
View File
@@ -11,6 +11,7 @@ C_SRCS = \
appsearch.c \
create.c \
custom.c \
database.c \
delete.c \
dialog.c \
distinct.c \
+142 -57
View File
@@ -61,7 +61,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
*/
static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran);
static UINT ACTION_ProcessUISequence(MSIPACKAGE *package);
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq);
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq, BOOL UI);
static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
LPWSTR *FilePath);
@@ -508,8 +508,8 @@ int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)
memset(&package->files[index],0,sizeof(MSIFILE));
package->files[index].File = dupstrW(name);
package->files[index].TargetPath = dupstrW(path);
package->files[index].File = strdupW(name);
package->files[index].TargetPath = strdupW(path);
package->files[index].Temporary = TRUE;
TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));
@@ -677,7 +677,7 @@ static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * recor
package->ActionFormat = load_dynamic_stringW(row,3);
HeapFree(GetProcessHeap(),0,package->LastAction);
package->LastAction = dupstrW(action);
package->LastAction = strdupW(action);
msiobj_release(&row->hdr);
MSI_ViewClose(view);
@@ -864,6 +864,7 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
DWORD sz;
WCHAR buffer[10];
UINT rc;
BOOL ui = FALSE;
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
@@ -875,8 +876,8 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
{
LPWSTR p, check, path;
package->PackagePath = dupstrW(szPackagePath);
path = dupstrW(szPackagePath);
package->PackagePath = strdupW(szPackagePath);
path = strdupW(szPackagePath);
p = strrchrW(path,'\\');
if (p)
{
@@ -921,7 +922,7 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
while (*ptr == ' ') ptr++;
len = ptr2-ptr;
prop = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
strncpyW(prop,ptr,len);
memcpy(prop,ptr,len*sizeof(WCHAR));
prop[len]=0;
ptr2++;
@@ -941,7 +942,7 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
len -= 2;
}
val = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
strncpyW(val,ptr2,len);
memcpy(val,ptr2,len*sizeof(WCHAR));
val[len] = 0;
if (strlenW(prop) > 0)
@@ -963,6 +964,7 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED)
{
rc = ACTION_ProcessUISequence(package);
ui = TRUE;
if (rc == ERROR_SUCCESS)
rc = ACTION_ProcessExecSequence(package,TRUE);
}
@@ -980,13 +982,13 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
/* process the ending type action */
if (rc == ERROR_SUCCESS)
ACTION_PerformActionSequence(package,-1);
ACTION_PerformActionSequence(package,-1,ui);
else if (rc == ERROR_INSTALL_USEREXIT)
ACTION_PerformActionSequence(package,-2);
ACTION_PerformActionSequence(package,-2,ui);
else if (rc == ERROR_FUNCTION_FAILED)
ACTION_PerformActionSequence(package,-3);
ACTION_PerformActionSequence(package,-3,ui);
else if (rc == ERROR_INSTALL_SUSPEND)
ACTION_PerformActionSequence(package,-4);
ACTION_PerformActionSequence(package,-4,ui);
/* finish up running custom actions */
ACTION_FinishCustomActions(package);
@@ -994,7 +996,7 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
return rc;
}
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq, BOOL UI)
{
MSIQUERY * view;
UINT rc;
@@ -1007,7 +1009,16 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
'S','e','q','u','e','n','c','e',' ', 'W','H','E','R','E',' ',
'S','e','q','u','e','n','c','e',' ', '=',' ','%','i',0};
rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
static const WCHAR UISeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e',
' ', 'W','H','E','R','E',' ', 'S','e','q','u','e','n','c','e',
' ', '=',' ','%','i',0};
if (UI)
rc = MSI_OpenQuery(package->db, &view, UISeqQuery, seq);
else
rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
if (rc == ERROR_SUCCESS)
{
@@ -1058,7 +1069,10 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
goto end;
}
rc = ACTION_PerformAction(package,buffer);
if (UI)
rc = ACTION_PerformUIAction(package,buffer);
else
rc = ACTION_PerformAction(package,buffer);
msiobj_release(&row->hdr);
end:
MSI_ViewClose(view);
@@ -1921,7 +1935,7 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
memset(&package->folders[index],0,sizeof(MSIFOLDER));
package->folders[index].Directory = dupstrW(dir);
package->folders[index].Directory = strdupW(dir);
rc = MSI_OpenQuery(package->db, &view, Query, dir);
if (rc != ERROR_SUCCESS)
@@ -1980,13 +1994,13 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
{
TRACE(" TargetDefault = %s\n",debugstr_w(targetdir));
HeapFree(GetProcessHeap(),0, package->folders[index].TargetDefault);
package->folders[index].TargetDefault = dupstrW(targetdir);
package->folders[index].TargetDefault = strdupW(targetdir);
}
if (srcdir)
package->folders[index].SourceDefault = dupstrW(srcdir);
package->folders[index].SourceDefault = strdupW(srcdir);
else if (targetdir)
package->folders[index].SourceDefault = dupstrW(targetdir);
package->folders[index].SourceDefault = strdupW(targetdir);
HeapFree(GetProcessHeap(), 0, ptargetdir);
parent = load_dynamic_stringW(row,2);
@@ -2084,13 +2098,13 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
if (!source && package->folders[i].ResolvedTarget)
{
path = dupstrW(package->folders[i].ResolvedTarget);
path = strdupW(package->folders[i].ResolvedTarget);
TRACE(" already resolved to %s\n",debugstr_w(path));
return path;
}
else if (source && package->folders[i].ResolvedSource)
{
path = dupstrW(package->folders[i].ResolvedSource);
path = strdupW(package->folders[i].ResolvedSource);
return path;
}
else if (!source && package->folders[i].Property)
@@ -2114,7 +2128,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
{
TRACE(" TargetDefault = %s\n",debugstr_w(package->folders[i].TargetDefault));
path = build_directory_name(3, p, package->folders[i].TargetDefault, NULL);
package->folders[i].ResolvedTarget = dupstrW(path);
package->folders[i].ResolvedTarget = strdupW(path);
TRACE(" resolved into %s\n",debugstr_w(path));
if (set_prop)
MSI_SetPropertyW(package,name,path);
@@ -2122,7 +2136,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
else
{
path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);
package->folders[i].ResolvedSource = dupstrW(path);
package->folders[i].ResolvedSource = strdupW(path);
}
HeapFree(GetProcessHeap(),0,p);
}
@@ -3119,7 +3133,7 @@ inline static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key,
{
if (package->files[index].State >= 2)
{
*file_source = dupstrW(package->files[index].TargetPath);
*file_source = strdupW(package->files[index].TargetPath);
return ERROR_SUCCESS;
}
else
@@ -3231,7 +3245,7 @@ static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
if (MSI_RecordIsNull(row,5))
{
LPWSTR p;
dest_path = dupstrW(file_source);
dest_path = strdupW(file_source);
p = strrchrW(dest_path,'\\');
if (p)
*p=0;
@@ -3523,7 +3537,8 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
value_data = parse_value(package, value, &type, &size);
else
{
value_data = NULL;
static const WCHAR szEmpty[] = {0};
value_data = (LPSTR)strdupW(szEmpty);
size = 0;
type = REG_SZ;
}
@@ -3759,7 +3774,7 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, INT
if (j>=0)
{
LPWSTR p = dupstrW(package->files[j].TargetPath);
LPWSTR p = strdupW(package->files[j].TargetPath);
return p;
}
}
@@ -4005,6 +4020,61 @@ end:
return rc;
}
typedef struct {
CLSID clsid;
LPWSTR source;
LPWSTR path;
ITypeLib *ptLib;
} typelib_struct;
BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType,
LPWSTR lpszName, LONG_PTR lParam)
{
TLIBATTR *attr;
typelib_struct *tl_struct = (typelib_struct*) lParam;
static const WCHAR fmt[] = {'%','s','\\','%','i',0};
int sz;
HRESULT res;
if (!IS_INTRESOURCE(lpszName))
{
ERR("Not Int Resource Name %s\n",debugstr_w(lpszName));
return TRUE;
}
sz = strlenW(tl_struct->source)+4;
sz *= sizeof(WCHAR);
tl_struct->path = HeapAlloc(GetProcessHeap(),0,sz);
sprintfW(tl_struct->path,fmt,tl_struct->source, lpszName);
TRACE("trying %s\n", debugstr_w(tl_struct->path));
res = LoadTypeLib(tl_struct->path,&tl_struct->ptLib);
if (!SUCCEEDED(res))
{
HeapFree(GetProcessHeap(),0,tl_struct->path);
tl_struct->path = NULL;
return TRUE;
}
ITypeLib_GetLibAttr(tl_struct->ptLib, &attr);
if (IsEqualGUID(&(tl_struct->clsid),&(attr->guid)))
{
ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr);
return FALSE;
}
HeapFree(GetProcessHeap(),0,tl_struct->path);
tl_struct->path = NULL;
ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr);
ITypeLib_Release(tl_struct->ptLib);
return TRUE;
}
static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
{
/*
@@ -4019,8 +4089,6 @@ static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
static const WCHAR Query[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'T','y','p','e','L','i','b',0};
ITypeLib *ptLib;
HRESULT res;
if (!package)
return ERROR_INVALID_HANDLE;
@@ -4042,6 +4110,10 @@ static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
WCHAR component[0x100];
DWORD sz;
INT index;
LPWSTR guid;
typelib_struct tl_struct;
HMODULE module;
static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
rc = MSI_ViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
@@ -4082,46 +4154,59 @@ static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
continue;
}
res = LoadTypeLib(package->files[index].TargetPath,&ptLib);
if (SUCCEEDED(res))
guid = load_dynamic_stringW(row,1);
module = LoadLibraryExW(package->files[index].TargetPath, NULL,
LOAD_LIBRARY_AS_DATAFILE);
if (module != NULL)
{
LPWSTR help;
WCHAR helpid[0x100];
CLSIDFromString(guid, &tl_struct.clsid);
tl_struct.source = strdupW(package->files[index].TargetPath);
tl_struct.path = NULL;
sz = 0x100;
MSI_RecordGetStringW(row,6,helpid,&sz);
EnumResourceNamesW(module, szTYPELIB, Typelib_EnumResNameProc,
(LONG_PTR)&tl_struct);
help = resolve_folder(package,helpid,FALSE,FALSE,NULL);
res = RegisterTypeLib(ptLib,package->files[index].TargetPath,help);
HeapFree(GetProcessHeap(),0,help);
if (!SUCCEEDED(res))
ERR("Failed to register type library %s\n",
debugstr_w(package->files[index].TargetPath));
else
if (tl_struct.path != NULL)
{
/* Yes the row has more fields than I need, but #1 is
correct and the only one I need. Why make a new row? */
LPWSTR help;
WCHAR helpid[0x100];
HRESULT res;
ui_actiondata(package,szRegisterTypeLibraries,row);
sz = 0x100;
MSI_RecordGetStringW(row,6,helpid,&sz);
help = resolve_folder(package,helpid,FALSE,FALSE,NULL);
res = RegisterTypeLib(tl_struct.ptLib,tl_struct.path,help);
HeapFree(GetProcessHeap(),0,help);
if (!SUCCEEDED(res))
ERR("Failed to register type library %s\n",
debugstr_w(tl_struct.path));
else
{
ui_actiondata(package,szRegisterTypeLibraries,row);
TRACE("Registered %s\n",
debugstr_w(package->files[index].TargetPath));
}
TRACE("Registered %s\n", debugstr_w(tl_struct.path));
}
if (ptLib)
ITypeLib_Release(ptLib);
ITypeLib_Release(tl_struct.ptLib);
HeapFree(GetProcessHeap(),0,tl_struct.path);
}
else
ERR("Failed to load type library %s\n",
debugstr_w(tl_struct.source));
FreeLibrary(module);
HeapFree(GetProcessHeap(),0,tl_struct.source);
}
else
ERR("Failed to load type library %s\n",
debugstr_w(package->files[index].TargetPath));
ERR("Could not load file! %s\n",
debugstr_w(package->files[index].TargetPath));
msiobj_release(&row->hdr);
}
MSI_ViewClose(view);
msiobj_release(&view->hdr);
return rc;
}
static UINT register_appid(MSIPACKAGE *package, LPCWSTR clsid, LPCWSTR app )
@@ -4362,7 +4447,7 @@ static UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
HeapFree(GetProcessHeap(),0,argument);
size += (strlenW(package->files[index].TargetPath))*sizeof(WCHAR);
argument = (LPWSTR)HeapAlloc(GetProcessHeap(),0,size+sizeof(WCHAR));
argument = HeapAlloc(GetProcessHeap(),0,size+sizeof(WCHAR));
strcpyW(argument,package->files[index].TargetPath);
if (deformated)
{
@@ -4882,7 +4967,7 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
{
LPWSTR keypath;
FIXME("poorly handled shortcut format, advertised shortcut\n");
keypath = dupstrW(package->components[index].FullKeypath);
keypath = strdupW(package->components[index].FullKeypath);
IShellLinkW_SetPath(sl,keypath);
HeapFree(GetProcessHeap(),0,keypath);
}
-36
View File
@@ -116,39 +116,3 @@ int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component );
int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature );
int get_loaded_file(MSIPACKAGE* package, LPCWSTR file);
int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
inline static char *strdupWtoA( const WCHAR *str )
{
char *ret = NULL;
if (str)
{
DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL
);
if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
}
return ret;
}
inline static WCHAR *strdupAtoW( const char *str )
{
WCHAR *ret = NULL;
if (str)
{
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
}
return ret;
}
inline static LPWSTR dupstrW(LPCWSTR src)
{
LPWSTR dest;
if (!src) return NULL;
dest = HeapAlloc(GetProcessHeap(), 0, (strlenW(src)+1)*sizeof(WCHAR));
strcpyW(dest, src);
return dest;
}
+4 -4
View File
@@ -406,7 +406,7 @@ static void ACTION_ExpandAnyPath(MSIPACKAGE *package, WCHAR *src, WCHAR *dst,
/* Sets *matches to whether the file (whose path is filePath) matches the
* versions set in sig.
* Return ERROR_SUCCESS in case of success (whether or not the file matches),
* something else if a install-halting error occurs.
* something else if an install-halting error occurs.
*/
static UINT ACTION_FileVersionMatches(MSISIGNATURE *sig, LPCWSTR filePath,
BOOL *matches)
@@ -481,7 +481,7 @@ static UINT ACTION_FileVersionMatches(MSISIGNATURE *sig, LPCWSTR filePath,
* fullFilePath is assumed to be the full path of the file specified in
* findData, which may be necessary to compare the version.
* Return ERROR_SUCCESS in case of success (whether or not the file matches),
* something else if a install-halting error occurs.
* something else if an install-halting error occurs.
*/
static UINT ACTION_FileMatchesSig(MSISIGNATURE *sig,
LPWIN32_FIND_DATAW findData, LPCWSTR fullFilePath, BOOL *matches)
@@ -672,8 +672,8 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
pathWithDrive[0] = 'A' + i;
if (GetDriveTypeW(pathWithDrive) == DRIVE_FIXED)
{
strncpyW(pathWithDrive + 3, expanded,
sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3);
lstrcpynW(pathWithDrive + 3, expanded,
sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3);
if (sig->File)
rc = ACTION_RecurseSearchDirectory(package, &found, sig,
pathWithDrive, depth);
+81 -55
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 1.875b. */
/* A Bison parser, made by GNU Bison 1.875c. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@@ -253,18 +253,25 @@ typedef union YYSTYPE {
#if ! defined (yyoverflow) || YYERROR_VERBOSE
# ifndef YYFREE
# define YYFREE free
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# endif
/* The parser invokes alloca or malloc; define the necessary symbols. */
# if YYSTACK_USE_ALLOCA
# define YYSTACK_ALLOC alloca
# ifdef YYSTACK_USE_ALLOCA
# if YYSTACK_USE_ALLOCA
# define YYSTACK_ALLOC alloca
# endif
# else
# ifndef YYSTACK_USE_ALLOCA
# if defined (alloca) || defined (_ALLOCA_H)
# define YYSTACK_ALLOC alloca
# else
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
# endif
# if defined (alloca) || defined (_ALLOCA_H)
# define YYSTACK_ALLOC alloca
# else
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
# endif
# endif
# endif
@@ -277,15 +284,15 @@ typedef union YYSTYPE {
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# endif
# define YYSTACK_ALLOC malloc
# define YYSTACK_FREE free
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
# endif
#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
#if (! defined (yyoverflow) \
&& (! defined (__cplusplus) \
|| (YYSTYPE_IS_TRIVIAL)))
|| (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
@@ -306,7 +313,7 @@ union yyalloc
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if 1 < __GNUC__
# if defined (__GNUC__) && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
@@ -454,14 +461,14 @@ static const unsigned short yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR",
"COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR",
"COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS",
"COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT",
"COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition",
"expression", "boolean_term", "boolean_factor", "term", "comp_op_i",
"comp_op_s", "comp_op_m1", "comp_op_m2", "value_i", "value_s",
"literal", "symbol_i", "symbol_s", "identifier", "integer", 0
"$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR",
"COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR",
"COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS",
"COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT",
"COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition",
"expression", "boolean_term", "boolean_factor", "term", "comp_op_i",
"comp_op_s", "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal",
"symbol_i", "symbol_s", "identifier", "integer", 0
};
#endif
@@ -624,7 +631,7 @@ static const unsigned char yystos[] =
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrlab1
#define YYERROR goto yyerrorlab
/* Like YYERROR except do call yyerror. This remains here temporarily
@@ -659,11 +666,11 @@ while (0)
are run). */
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
Current.first_line = Rhs[1].first_line; \
Current.first_column = Rhs[1].first_column; \
Current.last_line = Rhs[N].last_line; \
Current.last_column = Rhs[N].last_column;
# define YYLLOC_DEFAULT(Current, Rhs, N) \
((Current).first_line = (Rhs)[1].first_line, \
(Current).first_column = (Rhs)[1].first_column, \
(Current).last_line = (Rhs)[N].last_line, \
(Current).last_column = (Rhs)[N].last_column)
#endif
/* YYLEX -- calling `yylex' with the right arguments. */
@@ -707,7 +714,7 @@ do { \
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (cinluded). |
| TOP (included). |
`------------------------------------------------------------------*/
#if defined (__STDC__) || defined (__cplusplus)
@@ -786,7 +793,7 @@ int yydebug;
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
#if YYMAXDEPTH == 0
#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
# undef YYMAXDEPTH
#endif
@@ -1714,8 +1721,8 @@ yyreduce:
}
/* Line 999 of yacc.c. */
#line 1719 "cond.tab.c"
/* Line 1000 of yacc.c. */
#line 1726 "cond.tab.c"
yyvsp -= yylen;
yyssp -= yylen;
@@ -1818,25 +1825,27 @@ yyerrlab:
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
/* Return failure if at end of input. */
if (yychar == YYEOF)
if (yychar <= YYEOF)
{
/* Pop the error token. */
YYPOPSTACK;
/* Pop the rest of the stack. */
while (yyss < yyssp)
{
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
yydestruct (yystos[*yyssp], yyvsp);
YYPOPSTACK;
}
YYABORT;
/* If at end of input, pop the error token,
then the rest of the stack, then return failure. */
if (yychar == YYEOF)
for (;;)
{
YYPOPSTACK;
if (yyssp == yyss)
YYABORT;
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
yydestruct (yystos[*yyssp], yyvsp);
}
}
else
{
YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
yydestruct (yytoken, &yylval);
yychar = YYEMPTY;
YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
yydestruct (yytoken, &yylval);
yychar = YYEMPTY;
}
}
/* Else will try to reuse lookahead token after shifting the error
@@ -1844,9 +1853,27 @@ yyerrlab:
goto yyerrlab1;
/*----------------------------------------------------.
| yyerrlab1 -- error raised explicitly by an action. |
`----------------------------------------------------*/
/*---------------------------------------------------.
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
#ifdef __GNUC__
/* Pacify GCC when the user code never invokes YYERROR and the label
yyerrorlab therefore never appears in user code. */
if (0)
goto yyerrorlab;
#endif
yyvsp -= yylen;
yyssp -= yylen;
yystate = *yyssp;
goto yyerrlab1;
/*-------------------------------------------------------------.
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
@@ -1870,9 +1897,8 @@ yyerrlab1:
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
yydestruct (yystos[yystate], yyvsp);
yyvsp--;
yystate = *--yyssp;
YYPOPSTACK;
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
@@ -2123,7 +2149,7 @@ static LPWSTR COND_GetString( struct cond_str *str )
ret = HeapAlloc( GetProcessHeap(), 0, (str->len+1) * sizeof (WCHAR) );
if( ret )
{
strncpyW( ret, str->data, str->len );
memcpy( ret, str->data, str->len * sizeof(WCHAR));
ret[str->len]=0;
}
TRACE("Got identifier %s\n",debugstr_w(ret));
+2 -2
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 1.875b. */
/* A Bison parser, made by GNU Bison 1.875c. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@@ -86,7 +86,7 @@ typedef union YYSTYPE {
comp_m1 fn_comp_m1;
comp_m2 fn_comp_m2;
} YYSTYPE;
/* Line 1252 of yacc.c. */
/* Line 1275 of yacc.c. */
#line 91 "cond.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+1 -1
View File
@@ -701,7 +701,7 @@ static LPWSTR COND_GetString( struct cond_str *str )
ret = HeapAlloc( GetProcessHeap(), 0, (str->len+1) * sizeof (WCHAR) );
if( ret )
{
strncpyW( ret, str->data, str->len );
memcpy( ret, str->data, str->len * sizeof(WCHAR));
ret[str->len]=0;
}
TRACE("Got identifier %s\n",debugstr_w(ret));
+8 -8
View File
@@ -145,7 +145,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute)
else
newbuf = HeapAlloc(GetProcessHeap(),0, sizeof(LPWSTR));
newbuf[count] = dupstrW(action);
newbuf[count] = strdupW(action);
package->CommitAction = newbuf;
}
else
@@ -160,7 +160,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute)
else
newbuf = HeapAlloc(GetProcessHeap(),0, sizeof(LPWSTR));
newbuf[count] = dupstrW(action);
newbuf[count] = strdupW(action);
package->DeferredAction = newbuf;
}
@@ -326,7 +326,7 @@ static void file_running_action(MSIPACKAGE* package, HANDLE Handle,
newbuf[count].handle = Handle;
newbuf[count].process = process;
newbuf[count].name = dupstrW(name);
newbuf[count].name = strdupW(name);
package->RunningAction = newbuf;
}
@@ -508,8 +508,8 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) );
msiobj_addref( &package->hdr );
info->package = package;
info->target = dupstrW(target);
info->source = dupstrW(tmp_file);
info->target = strdupW(target);
info->source = strdupW(tmp_file);
ThreadHandle = CreateThread(NULL,0,DllThread,(LPVOID)info,0,&ThreadId);
@@ -542,7 +542,7 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
if (deformated)
len += strlenW(deformated);
cmd = (WCHAR*)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
cmd = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
strcpyW(cmd,tmp_file);
if (deformated)
@@ -595,7 +595,7 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source,
len += strlenW(deformated);
len += 2;
cmd = (WCHAR*)HeapAlloc(GetProcessHeap(),0,len * sizeof(WCHAR));
cmd = HeapAlloc(GetProcessHeap(),0,len * sizeof(WCHAR));
strcpyW(cmd, package->files[index].TargetPath);
if (deformated)
@@ -692,7 +692,7 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
if (deformated)
len += strlenW(deformated);
cmd = (WCHAR*)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
cmd = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
strcpyW(cmd,prop);
if (deformated)
+345
View File
@@ -0,0 +1,345 @@
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2002,2003,2004,2005 Mike McCormack for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#include "objidl.h"
#include "objbase.h"
#include "initguid.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
/*
* The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
* which is a problem because LPCTSTR isn't defined when compiling wine.
* To work around this problem, we need to define LPCTSTR as LPCWSTR here,
* and make sure to only use it in W functions.
*/
#define LPCTSTR LPCWSTR
DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000,
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
/*
* .MSI file format
*
* An .msi file is a structured storage file.
* It contains a number of streams.
* A stream for each table in the database.
* Two streams for the string table in the database.
* Any binary data in a table is a reference to a stream.
*/
VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
{
MSIDATABASE *db = (MSIDATABASE *) arg;
DWORD r;
free_cached_tables( db );
r = IStorage_Release( db->storage );
if( r )
ERR("database reference count was not zero (%ld)\n", r);
}
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
{
IStorage *stg = NULL;
HRESULT r;
MSIDATABASE *db = NULL;
UINT ret = ERROR_FUNCTION_FAILED;
LPWSTR szMode;
STATSTG stat;
TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
if( !pdb )
return ERROR_INVALID_PARAMETER;
szMode = (LPWSTR) szPersist;
if( HIWORD( szPersist ) )
{
/* UINT len = lstrlenW( szPerist ) + 1; */
FIXME("don't support persist files yet\b");
return ERROR_INVALID_PARAMETER;
/* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
}
else if( szPersist == MSIDBOPEN_READONLY )
{
r = StgOpenStorage( szDBPath, NULL,
STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
}
else if( szPersist == MSIDBOPEN_CREATE )
{
r = StgCreateDocfile( szDBPath,
STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
if( r == ERROR_SUCCESS )
{
IStorage_SetClass( stg, &CLSID_MsiDatabase );
r = init_string_table( stg );
}
}
else if( szPersist == MSIDBOPEN_TRANSACT )
{
r = StgOpenStorage( szDBPath, NULL,
STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
}
else
{
ERR("unknown flag %p\n",szPersist);
return ERROR_INVALID_PARAMETER;
}
if( FAILED( r ) )
{
FIXME("open failed r = %08lx!\n",r);
return ERROR_FUNCTION_FAILED;
}
r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
if( FAILED( r ) )
{
FIXME("Failed to stat storage\n");
goto end;
}
if( memcmp( &stat.clsid, &CLSID_MsiDatabase, sizeof (GUID) ) )
{
ERR("storage GUID is not a MSI database GUID %s\n",
debugstr_guid(&stat.clsid) );
goto end;
}
db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
MSI_CloseDatabase );
if( !db )
{
FIXME("Failed to allocate a handle\n");
goto end;
}
if( TRACE_ON( msi ) )
enum_stream_names( stg );
db->storage = stg;
db->mode = szMode;
ret = load_string_table( db );
if( ret != ERROR_SUCCESS )
goto end;
msiobj_addref( &db->hdr );
IStorage_AddRef( stg );
*pdb = db;
end:
if( db )
msiobj_release( &db->hdr );
if( stg )
IStorage_Release( stg );
return ret;
}
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
{
MSIDATABASE *db;
UINT ret;
TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
if( ret == ERROR_SUCCESS )
{
*phDB = alloc_msihandle( &db->hdr );
msiobj_release( &db->hdr );
}
return ret;
}
UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
{
HRESULT r = ERROR_FUNCTION_FAILED;
LPWSTR szwDBPath = NULL, szwPersist = NULL;
TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
if( szDBPath )
{
szwDBPath = strdupAtoW( szDBPath );
if( !szwDBPath )
goto end;
}
if( HIWORD(szPersist) )
{
szwPersist = strdupAtoW( szPersist );
if( !szwPersist )
goto end;
}
else
szwPersist = (LPWSTR) szPersist;
r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
end:
HeapFree( GetProcessHeap(), 0, szwPersist );
HeapFree( GetProcessHeap(), 0, szwDBPath );
return r;
}
UINT MSI_DatabaseImport( MSIDATABASE *db, LPCWSTR folder, LPCWSTR file )
{
FIXME("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) );
if( folder == NULL || file == NULL )
return ERROR_INVALID_PARAMETER;
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, LPCWSTR szFolder, LPCWSTR szFilename)
{
MSIDATABASE *db;
UINT r;
TRACE("%lx %s %s\n",handle,debugstr_w(szFolder), debugstr_w(szFilename));
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
r = MSI_DatabaseImport( db, szFolder, szFilename );
msiobj_release( &db->hdr );
return r;
}
UINT WINAPI MsiDatabaseImportA( MSIHANDLE handle,
LPCSTR szFolder, LPCSTR szFilename )
{
LPWSTR path = NULL, file = NULL;
UINT r = ERROR_OUTOFMEMORY;
TRACE("%lx %s %s\n", handle, debugstr_a(szFolder), debugstr_a(szFilename));
if( szFolder )
{
path = strdupAtoW( szFolder );
if( !path )
goto end;
}
if( szFilename )
{
file = strdupAtoW( szFilename );
if( !file )
goto end;
}
r = MsiDatabaseImportW( handle, path, file );
end:
HeapFree( GetProcessHeap(), 0, path );
HeapFree( GetProcessHeap(), 0, file );
return r;
}
UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table,
LPCWSTR folder, LPCWSTR file )
{
FIXME("%p %s %s %s\n", db, debugstr_w(table),
debugstr_w(folder), debugstr_w(file) );
if( folder == NULL || file == NULL )
return ERROR_INVALID_PARAMETER;
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiDatabaseExportW( MSIHANDLE handle, LPCWSTR szTable,
LPCWSTR szFolder, LPCWSTR szFilename )
{
MSIDATABASE *db;
UINT r;
TRACE("%lx %s %s %s\n", handle, debugstr_w(szTable),
debugstr_w(szFolder), debugstr_w(szFilename));
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
r = MSI_DatabaseExport( db, szTable, szFolder, szFilename );
msiobj_release( &db->hdr );
return r;
}
UINT WINAPI MsiDatabaseExportA( MSIHANDLE handle, LPCSTR szTable,
LPCSTR szFolder, LPCSTR szFilename )
{
LPWSTR path = NULL, file = NULL, table = NULL;
UINT r = ERROR_OUTOFMEMORY;
TRACE("%lx %s %s %s\n", handle, debugstr_a(szTable),
debugstr_a(szFolder), debugstr_a(szFilename));
if( szTable )
{
table = strdupAtoW( szTable );
if( !table )
goto end;
}
if( szFolder )
{
path = strdupAtoW( szFolder );
if( !path )
goto end;
}
if( szFilename )
{
file = strdupAtoW( szFilename );
if( !file )
goto end;
}
r = MsiDatabaseImportW( handle, path, file );
end:
HeapFree( GetProcessHeap(), 0, table );
HeapFree( GetProcessHeap(), 0, path );
HeapFree( GetProcessHeap(), 0, file );
return r;
}
+104 -60
View File
@@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define COBJMACROS
#include <stdarg.h>
#include "windef.h"
@@ -28,6 +30,8 @@
#include "msi.h"
#include "msipriv.h"
#include "msidefs.h"
#include "ocidl.h"
#include "olectl.h"
#include "wine/debug.h"
#include "wine/unicode.h"
@@ -55,6 +59,7 @@ struct msi_control_tag
HWND hwnd;
msi_handler handler;
LPWSTR property;
IPicture *pic;
WCHAR name[1];
};
@@ -131,7 +136,7 @@ static LPWSTR msi_dialog_get_style( LPCWSTR *text )
ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
if( !ret )
return ret;
strncpyW( ret, p, len );
memcpy( ret, p, len*sizeof(WCHAR) );
ret[len-1] = 0;
return ret;
}
@@ -226,17 +231,16 @@ static UINT msi_dialog_build_font_list( msi_dialog *dialog )
return r;
}
static msi_control *msi_dialog_add_control( msi_dialog *dialog,
MSIRECORD *rec, LPCWSTR szCls, DWORD style )
static msi_control *msi_dialog_create_window( msi_dialog *dialog,
MSIRECORD *rec, LPCWSTR szCls, LPCWSTR name, LPCWSTR text,
DWORD style, HWND parent )
{
DWORD x, y, width, height, attributes;
LPCWSTR text, name;
DWORD x, y, width, height;
LPWSTR font = NULL, title = NULL;
msi_control *control = NULL;
msi_control *control;
style |= WS_CHILD | WS_GROUP;
name = MSI_RecordGetString( rec, 2 );
control = HeapAlloc( GetProcessHeap(), 0,
sizeof *control + strlenW(name)*sizeof(WCHAR) );
strcpyW( control->name, name );
@@ -244,39 +248,57 @@ static msi_control *msi_dialog_add_control( msi_dialog *dialog,
dialog->control_list = control;
control->handler = NULL;
control->property = NULL;
control->pic = NULL;
x = MSI_RecordGetInteger( rec, 4 );
y = MSI_RecordGetInteger( rec, 5 );
width = MSI_RecordGetInteger( rec, 6 );
height = MSI_RecordGetInteger( rec, 7 );
attributes = MSI_RecordGetInteger( rec, 8 );
text = MSI_RecordGetString( rec, 10 );
TRACE("Dialog %s control %s\n", debugstr_w(dialog->name), debugstr_w(text));
x = msi_dialog_scale_unit( dialog, x );
y = msi_dialog_scale_unit( dialog, y );
width = msi_dialog_scale_unit( dialog, width );
height = msi_dialog_scale_unit( dialog, height );
if( attributes & 1 )
style |= WS_VISIBLE;
if( ~attributes & 2 )
style |= WS_DISABLED;
if( text )
{
font = msi_dialog_get_style( &text );
deformat_string( dialog->package, text, &title );
}
control->hwnd = CreateWindowW( szCls, title, style,
x, y, width, height, dialog->hwnd, NULL, NULL, NULL );
x, y, width, height, parent, NULL, NULL, NULL );
TRACE("Dialog %s control %s hwnd %p\n",
debugstr_w(dialog->name), debugstr_w(text), control->hwnd );
msi_dialog_set_font( dialog, control->hwnd,
font ? font : dialog->default_font );
HeapFree( GetProcessHeap(), 0, font );
HeapFree( GetProcessHeap(), 0, title );
return control;
}
/* everything except radio buttons */
static msi_control *msi_dialog_add_control( msi_dialog *dialog,
MSIRECORD *rec, LPCWSTR szCls, DWORD style )
{
DWORD attributes;
LPCWSTR text, name;
name = MSI_RecordGetString( rec, 2 );
attributes = MSI_RecordGetInteger( rec, 8 );
text = MSI_RecordGetString( rec, 10 );
if( attributes & 1 )
style |= WS_VISIBLE;
if( ~attributes & 2 )
style |= WS_DISABLED;
return msi_dialog_create_window( dialog, rec, szCls, name, text,
style, dialog->hwnd );
}
static UINT msi_dialog_text_control( msi_dialog *dialog, MSIRECORD *rec )
{
TRACE("%p %p\n", dialog, rec);
@@ -309,7 +331,7 @@ static UINT msi_dialog_checkbox_control( msi_dialog *dialog, MSIRECORD *rec )
control->handler = msi_dialog_checkbox_handler;
prop = MSI_RecordGetString( rec, 9 );
if( prop )
control->property = dupstrW( prop );
control->property = strdupW( prop );
msi_dialog_checkbox_sync_state( dialog, control );
return ERROR_SUCCESS;
@@ -327,7 +349,7 @@ static UINT msi_dialog_scrolltext_control( msi_dialog *dialog, MSIRECORD *rec )
{
const static WCHAR szEdit[] = { 'E','D','I','T',0 };
TRACE("%p %p\n", dialog, rec);
FIXME("%p %p\n", dialog, rec);
msi_dialog_add_control( dialog, rec, szEdit, WS_BORDER |
ES_MULTILINE | WS_VSCROLL | ES_READONLY | ES_AUTOVSCROLL );
@@ -335,12 +357,64 @@ static UINT msi_dialog_scrolltext_control( msi_dialog *dialog, MSIRECORD *rec )
return ERROR_SUCCESS;
}
static UINT msi_load_bitmap( MSIDATABASE *db, LPCWSTR name, IPicture **pic )
{
const static WCHAR query[] = {
's','e','l','e','c','t',' ','*',' ',
'f','r','o','m',' ','B','i','n','a','r','y',' ',
'w','h','e','r','e',' ',
'`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0
};
MSIQUERY *view = NULL;
MSIRECORD *rec = NULL;
IStream *stm = NULL;
UINT r;
r = MSI_OpenQuery( db, &view, query, name );
if( r != ERROR_SUCCESS )
return r;
MSI_ViewExecute( view, NULL );
MSI_ViewFetch( view, &rec );
MSI_ViewClose( view );
msiobj_release( &view->hdr );
if( !rec )
return ERROR_FUNCTION_FAILED;
r = MSI_RecordGetIStream( rec, 2, &stm );
msiobj_release( &rec->hdr );
if( r != ERROR_SUCCESS )
return r;
r = OleLoadPicture( stm, 0, TRUE, &IID_IPicture, (LPVOID*) pic );
IStream_Release( stm );
if( FAILED( r ) )
return ERROR_FUNCTION_FAILED;
return ERROR_SUCCESS;
}
static UINT msi_dialog_bitmap_control( msi_dialog *dialog, MSIRECORD *rec )
{
TRACE("%p %p\n", dialog, rec);
IPicture *pic = NULL;
msi_control *control;
OLE_HANDLE hBitmap = 0;
LPCWSTR text;
UINT r;
msi_dialog_add_control( dialog, rec, szStatic,
control = msi_dialog_add_control( dialog, rec, szStatic,
SS_BITMAP | SS_LEFT | SS_CENTERIMAGE );
text = MSI_RecordGetString( rec, 10 );
r = msi_load_bitmap( dialog->package->db, text, &pic );
if( r == ERROR_SUCCESS )
{
r = IPicture_get_Handle( pic, &hBitmap );
if( SUCCEEDED( r ) )
SendMessageW( control->hwnd, STM_SETIMAGE, IMAGE_BITMAP, hBitmap );
control->pic = pic;
}
return ERROR_SUCCESS;
}
@@ -364,7 +438,7 @@ static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec )
control->handler = msi_dialog_edit_handler;
prop = MSI_RecordGetString( rec, 9 );
if( prop )
control->property = dupstrW( prop );
control->property = strdupW( prop );
val = load_dynamic_property( dialog->package, control->property, NULL );
SetWindowTextW( control->hwnd, val );
HeapFree( GetProcessHeap(), 0, val );
@@ -377,63 +451,31 @@ static UINT msi_dialog_pathedit_control( msi_dialog *dialog, MSIRECORD *rec )
return msi_dialog_edit_control( dialog, rec );
}
/* radio buttons are a bit different from normal controls */
static UINT msi_dialog_create_radiobutton( MSIRECORD *rec, LPVOID param )
{
radio_button_group_descr *group = (radio_button_group_descr *)param;
msi_dialog *dialog = group->dialog;
msi_control *control;
LPCWSTR prop;
DWORD x, y, width, height, style;
LPCWSTR prop, text, name;
DWORD style;
DWORD attributes = group->attributes;
LPCWSTR text, name;
LPWSTR font = NULL, title = NULL;
style = WS_CHILD | BS_AUTORADIOBUTTON | BS_MULTILINE;
name = MSI_RecordGetString( rec, 3 );
control = HeapAlloc( GetProcessHeap(), 0,
sizeof *control + strlenW(name)*sizeof(WCHAR) );
strcpyW( control->name, name );
control->next = dialog->control_list;
dialog->control_list = control;
x = MSI_RecordGetInteger( rec, 4 );
y = MSI_RecordGetInteger( rec, 5 );
width = MSI_RecordGetInteger( rec, 6 );
height = MSI_RecordGetInteger( rec, 7 );
text = MSI_RecordGetString( rec, 8 );
x = msi_dialog_scale_unit( dialog, x );
y = msi_dialog_scale_unit( dialog, y );
width = msi_dialog_scale_unit( dialog, width );
height = msi_dialog_scale_unit( dialog, height );
if( attributes & 1 )
style |= WS_VISIBLE;
if( ~attributes & 2 )
style |= WS_DISABLED;
if( text )
{
font = msi_dialog_get_style( &text );
deformat_string( dialog->package, text, &title );
}
control->hwnd = CreateWindowW( szButton, title, style, x, y, width, height,
group->parent->hwnd, NULL, NULL, NULL );
TRACE("Dialog %s control %s hwnd %p\n", debugstr_w(dialog->name), debugstr_w(text), control->hwnd);
msi_dialog_set_font( dialog, control->hwnd,
font ? font : dialog->default_font );
HeapFree( GetProcessHeap(), 0, font );
HeapFree( GetProcessHeap(), 0, title );
control = msi_dialog_create_window( dialog, rec, szButton, name, text,
style, group->parent->hwnd );
control->handler = msi_dialog_radiogroup_handler;
prop = MSI_RecordGetString( rec, 1 );
if( prop )
control->property = dupstrW( prop );
control->property = strdupW( prop );
return ERROR_SUCCESS;
}
@@ -467,7 +509,7 @@ static UINT msi_dialog_radiogroup_control( msi_dialog *dialog, MSIRECORD *rec )
}
if( prop )
control->property = dupstrW( prop );
control->property = strdupW( prop );
/* query the Radio Button table for all control in this group */
r = MSI_OpenQuery( package->db, &view, query, prop );
@@ -1078,6 +1120,8 @@ void msi_dialog_destroy( msi_dialog *dialog )
dialog->control_list = t->next;
/* leave dialog->hwnd - destroying parent destroys child windows */
HeapFree( GetProcessHeap(), 0, t->property );
if( t->pic )
IPicture_Release( t->pic );
HeapFree( GetProcessHeap(), 0, t );
}
+7 -6
View File
@@ -114,7 +114,7 @@ static LPWSTR deformat_file(MSIPACKAGE* package, LPCWSTR key, DWORD* sz)
index = get_loaded_file(package,key);
if (index >=0)
{
value = dupstrW(package->files[index].TargetPath);
value = strdupW(package->files[index].TargetPath);
*sz = (strlenW(value)) * sizeof(WCHAR);
}
@@ -137,7 +137,7 @@ static LPWSTR deformat_environment(MSIPACKAGE* package, LPCWSTR key,
}
else
{
ERR("Unknown environment variable\n");
ERR("Unknown environment variable %s\n", debugstr_w(key));
*chunk = 0;
value = NULL;
}
@@ -252,7 +252,7 @@ static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining,
*key = HeapAlloc(GetProcessHeap(),0,i*sizeof(WCHAR));
/* do not have the [] in the key */
i -= 1;
strncpyW(*key,&(*mark)[1],i);
memcpy(*key,&(*mark)[1],i*sizeof(WCHAR));
(*key)[i] = 0;
TRACE("Found Key %s\n",debugstr_w(*key));
@@ -358,11 +358,12 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
value = deformat_index(record,key,&chunk);
else
{
chunk = (strlenW(key) + 2)*sizeof(WCHAR);
DWORD keylen = strlenW(key);
chunk = (keylen + 2)*sizeof(WCHAR);
value = HeapAlloc(GetProcessHeap(),0,chunk);
value[0] = '[';
memcpy(&value[1],key,strlenW(key)*sizeof(WCHAR));
value[strlenW(key)+1] = ']';
memcpy(&value[1],key,keylen*sizeof(WCHAR));
value[1+keylen] = ']';
}
}
else
+134 -376
View File
@@ -32,15 +32,10 @@
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#include "objidl.h"
#include "wincrypt.h"
#include "wine/unicode.h"
#include "objbase.h"
#include "winver.h"
#include "winuser.h"
#include "initguid.h"
UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf);
@@ -54,9 +49,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
*/
#define LPCTSTR LPCWSTR
DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000,
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
/* the UI level */
INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
HWND gUIhwnd = 0;
@@ -67,198 +59,25 @@ LPVOID gUIContext = NULL;
WCHAR gszLogFile[MAX_PATH];
HINSTANCE msi_hInstance;
/*
* .MSI file format
*
* A .msi file is a structured storage file.
* It should contain a number of streams.
*/
VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
{
MSIDATABASE *db = (MSIDATABASE *) arg;
DWORD r;
free_cached_tables( db );
r = IStorage_Release( db->storage );
if( r )
ERR("database reference count was not zero (%ld)\n", r);
}
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
{
IStorage *stg = NULL;
HRESULT r;
MSIDATABASE *db = NULL;
UINT ret = ERROR_FUNCTION_FAILED;
LPWSTR szMode;
STATSTG stat;
TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
if( !pdb )
return ERROR_INVALID_PARAMETER;
szMode = (LPWSTR) szPersist;
if( HIWORD( szPersist ) )
{
/* UINT len = lstrlenW( szPerist ) + 1; */
FIXME("don't support persist files yet\b");
return ERROR_INVALID_PARAMETER;
/* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
}
else if( szPersist == MSIDBOPEN_READONLY )
{
r = StgOpenStorage( szDBPath, NULL,
STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
}
else if( szPersist == MSIDBOPEN_CREATE )
{
r = StgCreateDocfile( szDBPath,
STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
if( r == ERROR_SUCCESS )
{
IStorage_SetClass( stg, &CLSID_MsiDatabase );
r = init_string_table( stg );
}
}
else if( szPersist == MSIDBOPEN_TRANSACT )
{
r = StgOpenStorage( szDBPath, NULL,
STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
}
else
{
ERR("unknown flag %p\n",szPersist);
return ERROR_INVALID_PARAMETER;
}
if( FAILED( r ) )
{
FIXME("open failed r = %08lx!\n",r);
return ERROR_FUNCTION_FAILED;
}
r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
if( FAILED( r ) )
{
FIXME("Failed to stat storage\n");
goto end;
}
if( memcmp( &stat.clsid, &CLSID_MsiDatabase, sizeof (GUID) ) )
{
ERR("storage GUID is not a MSI database GUID %s\n",
debugstr_guid(&stat.clsid) );
goto end;
}
db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
MSI_CloseDatabase );
if( !db )
{
FIXME("Failed to allocate a handle\n");
goto end;
}
if( TRACE_ON( msi ) )
enum_stream_names( stg );
db->storage = stg;
db->mode = szMode;
ret = load_string_table( db );
if( ret != ERROR_SUCCESS )
goto end;
msiobj_addref( &db->hdr );
IStorage_AddRef( stg );
*pdb = db;
end:
if( db )
msiobj_release( &db->hdr );
if( stg )
IStorage_Release( stg );
return ret;
}
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
{
MSIDATABASE *db;
UINT ret;
TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
if( ret == ERROR_SUCCESS )
{
*phDB = alloc_msihandle( &db->hdr );
msiobj_release( &db->hdr );
}
return ret;
}
UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
{
HRESULT r = ERROR_FUNCTION_FAILED;
LPWSTR szwDBPath = NULL, szwPersist = NULL;
UINT len;
TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
if( szDBPath )
{
len = MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, NULL, 0 );
szwDBPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwDBPath )
goto end;
MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, szwDBPath, len );
}
if( HIWORD(szPersist) )
{
len = MultiByteToWideChar( CP_ACP, 0, szPersist, -1, NULL, 0 );
szwPersist = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwPersist )
goto end;
MultiByteToWideChar( CP_ACP, 0, szPersist, -1, szwPersist, len );
}
else
szwPersist = (LPWSTR) szPersist;
r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
end:
HeapFree( GetProcessHeap(), 0, szwPersist );
HeapFree( GetProcessHeap(), 0, szwDBPath );
return r;
}
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
{
UINT len, ret;
UINT r;
LPWSTR szwProd = NULL;
TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
if( szProduct )
{
len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
szwProd = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
if( szwProd )
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProd, len );
szwProd = strdupAtoW( szProduct );
if( !szwProd )
return ERROR_OUTOFMEMORY;
}
ret = MsiOpenProductW( szwProd, phProduct );
r = MsiOpenProductW( szwProd, phProduct );
HeapFree( GetProcessHeap(), 0, szwProd );
return ret;
return r;
}
UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
@@ -350,28 +169,24 @@ UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfileP
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
{
LPWSTR szwPath = NULL, szwCommand = NULL;
UINT r = ERROR_FUNCTION_FAILED; /* FIXME: check return code */
UINT r = ERROR_OUTOFMEMORY;
TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
if( szPackagePath )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, NULL, 0 );
szwPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwPath = strdupAtoW( szPackagePath );
if( !szwPath )
goto end;
MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, szwPath, len );
}
if( szCommandLine )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
szwCommand = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwCommand = strdupAtoW( szCommandLine );
if( !szwCommand )
goto end;
MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommand, len );
}
r = MsiInstallProductW( szwPath, szwCommand );
end:
@@ -384,26 +199,26 @@ end:
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
MSIPACKAGE *package = NULL;
UINT rc = ERROR_SUCCESS;
UINT r;
MSIHANDLE handle;
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
rc = MsiVerifyPackageW(szPackagePath);
if (rc != ERROR_SUCCESS)
return rc;
r = MsiVerifyPackageW(szPackagePath);
if (r != ERROR_SUCCESS)
return r;
rc = MSI_OpenPackageW(szPackagePath,&package);
if (rc != ERROR_SUCCESS)
return rc;
r = MSI_OpenPackageW(szPackagePath,&package);
if (r != ERROR_SUCCESS)
return r;
handle = alloc_msihandle( &package->hdr );
rc = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
MsiCloseHandle(handle);
msiobj_release( &package->hdr );
return rc;
return r;
}
UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
@@ -437,7 +252,7 @@ UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
{
MSIHANDLE handle;
MSIHANDLE handle;
MSIPACKAGE* package;
UINT rc;
HKEY hkey=0,hkey1=0;
@@ -454,7 +269,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
debugstr_w(szCommandLine));
if (eInstallState != INSTALLSTATE_LOCAL &&
if (eInstallState != INSTALLSTATE_LOCAL &&
eInstallState != INSTALLSTATE_DEFAULT)
{
FIXME("Not implemented for anything other than local installs\n");
@@ -479,7 +294,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
* ok 1, we need to find the msi file for this product.
* 2, find the source dir for the files
* 3, do the configure/install.
* 4, cleanupany runonce entry.
* 4, cleanupany runonce entry.
*/
rc = MsiOpenProductW(szProduct,&handle);
@@ -492,21 +307,21 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
rc = ERROR_INVALID_HANDLE;
goto end;
}
sz = strlenW(szInstalled);
sz = lstrlenW(szInstalled);
if (szCommandLine)
sz += strlenW(szCommandLine);
sz += lstrlenW(szCommandLine);
commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
if (szCommandLine)
strcpyW(commandline,szCommandLine);
if (szCommandLine)
lstrcpyW(commandline,szCommandLine);
else
commandline[0] = 0;
if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
strcatW(commandline,szInstalled);
lstrcatW(commandline,szInstalled);
rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
@@ -524,102 +339,89 @@ UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
{
LPWSTR szwProduct = NULL;
LPWSTR szwCommandLine = NULL;
UINT hr = ERROR_FUNCTION_FAILED;
UINT r = ERROR_OUTOFMEMORY;
if( szProduct )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
goto end;
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
}
if( szCommandLine)
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
szwCommandLine= HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwCommandLine = strdupAtoW( szCommandLine );
if( !szwCommandLine)
goto end;
MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommandLine, len );
}
hr = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
szwCommandLine );
end:
HeapFree( GetProcessHeap(), 0, szwProduct );
HeapFree( GetProcessHeap(), 0, szwCommandLine);
return hr;
return r;
}
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState)
{
LPWSTR szwProduct = NULL;
UINT hr = ERROR_SUCCESS;
UINT r;
FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
if( szProduct )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
goto end;
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
return ERROR_OUTOFMEMORY;
}
hr = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
end:
r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
HeapFree( GetProcessHeap(), 0, szwProduct );
return hr;
return r;
}
UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState)
{
FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState,
NULL);
return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
}
UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
{
LPWSTR szwComponent = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
UINT r;
WCHAR szwBuffer[GUID_SIZE];
FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
if( szComponent )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwComponent = strdupAtoW( szComponent );
if( !szwComponent )
goto end;
MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
return ERROR_OUTOFMEMORY;
}
else
return ERROR_INVALID_PARAMETER;
hr = MsiGetProductCodeW( szwComponent, szwBuffer );
r = MsiGetProductCodeW( szwComponent, szwBuffer );
if( ERROR_SUCCESS == hr )
if( ERROR_SUCCESS == r )
WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
end:
HeapFree( GetProcessHeap(), 0, szwComponent );
return hr;
return r;
}
UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
{
FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
FIXME("%s %p\n",debugstr_w(szComponent), szBuffer);
if (NULL == szComponent)
return ERROR_INVALID_PARAMETER;
return ERROR_CALL_NOT_IMPLEMENTED;
@@ -629,36 +431,23 @@ UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
LPSTR szBuffer, DWORD *pcchValueBuf)
{
LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
UINT r = ERROR_OUTOFMEMORY;
FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute),
TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
szBuffer, pcchValueBuf);
if( NULL != szBuffer && NULL == pcchValueBuf )
return ERROR_INVALID_PARAMETER;
if( szProduct )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
goto end;
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
}
else
return ERROR_INVALID_PARAMETER;
if( szAttribute )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, NULL, 0 );
szwAttribute = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwAttribute = strdupAtoW( szAttribute );
if( !szwAttribute )
goto end;
MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, szwAttribute, len );
}
else
{
hr = ERROR_INVALID_PARAMETER;
goto end;
}
if( szBuffer )
@@ -668,9 +457,9 @@ UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
goto end;
}
hr = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
if( ERROR_SUCCESS == hr )
if( ERROR_SUCCESS == r )
WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);
end:
@@ -678,15 +467,15 @@ end:
HeapFree( GetProcessHeap(), 0, szwAttribute );
HeapFree( GetProcessHeap(), 0, szwBuffer );
return hr;
return r;
}
UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
LPWSTR szBuffer, DWORD *pcchValueBuf)
{
MSIHANDLE hProduct;
UINT hr;
UINT r;
FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
szBuffer, pcchValueBuf);
@@ -695,51 +484,31 @@ UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
if (NULL == szProduct || NULL == szAttribute)
return ERROR_INVALID_PARAMETER;
hr = MsiOpenProductW(szProduct, &hProduct);
if (ERROR_SUCCESS != hr)
return hr;
r = MsiOpenProductW(szProduct, &hProduct);
if (ERROR_SUCCESS != r)
return r;
hr = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
MsiCloseHandle(hProduct);
return hr;
}
UINT WINAPI MsiDatabaseImportA(LPCSTR szFolderPath, LPCSTR szFilename)
{
FIXME("%s %s\n",debugstr_a(szFolderPath), debugstr_a(szFilename));
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiDatabaseImportW(LPCWSTR szFolderPath, LPCWSTR szFilename)
{
FIXME("%s %s\n",debugstr_w(szFolderPath), debugstr_w(szFilename));
return ERROR_CALL_NOT_IMPLEMENTED;
return r;
}
UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
{
LPWSTR szwLogFile = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
UINT r;
FIXME("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
if( szLogFile )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, NULL, 0 );
szwLogFile = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
szwLogFile = strdupAtoW( szLogFile );
if( !szwLogFile )
goto end;
MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, szwLogFile, len );
return ERROR_OUTOFMEMORY;
}
else
return ERROR_INVALID_PARAMETER;
hr = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
end:
r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
HeapFree( GetProcessHeap(), 0, szwLogFile );
return hr;
return r;
}
UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
@@ -748,7 +517,7 @@ UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
strcpyW(gszLogFile,szLogFile);
lstrcpyW(gszLogFile,szLogFile);
if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
DeleteFileW(szLogFile);
file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
@@ -763,23 +532,25 @@ UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
{
LPWSTR szwProduct;
UINT len;
INSTALLSTATE rc;
LPWSTR szwProduct = NULL;
INSTALLSTATE r;
len = MultiByteToWideChar(CP_ACP,0,szProduct,-1,NULL,0);
szwProduct = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,0,szProduct,-1,szwProduct,len);
rc = MsiQueryProductStateW(szwProduct);
HeapFree(GetProcessHeap(),0,szwProduct);
return rc;
if( szProduct )
{
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
return ERROR_OUTOFMEMORY;
}
r = MsiQueryProductStateW( szwProduct );
HeapFree( GetProcessHeap(), 0, szwProduct );
return r;
}
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
{
UINT rc;
INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
HKEY hkey=0;
HKEY hkey = 0;
static const WCHAR szWindowsInstaller[] = {
'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
DWORD sz;
@@ -833,7 +604,7 @@ INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
return old;
}
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
DWORD dwMessageFilter, LPVOID pvContext)
{
INSTALLUI_HANDLERA prev = gUIHandlerA;
@@ -980,7 +751,7 @@ UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uT
UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
DWORD* pcchPathBuf )
DWORD* pcchPathBuf )
{
FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
@@ -992,7 +763,7 @@ UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
DWORD* pcchPathBuf )
{
FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
pcchPathBuf);
return ERROR_CALL_NOT_IMPLEMENTED;
@@ -1046,18 +817,16 @@ UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
{
UINT r, len;
UINT r;
LPWSTR szPack = NULL;
TRACE("%s\n", debugstr_a(szPackage) );
if( szPackage )
{
len = MultiByteToWideChar( CP_ACP, 0, szPackage, -1, NULL, 0 );
szPack = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
szPack = strdupAtoW( szPackage );
if( !szPack )
return ERROR_OUTOFMEMORY;
MultiByteToWideChar( CP_ACP, 0, szPackage, -1, szPack, len );
}
r = MsiVerifyPackageW( szPack );
@@ -1085,27 +854,23 @@ INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
{
LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
INSTALLSTATE rc;
UINT len, incoming_len;
UINT incoming_len;
if( szProduct )
{
len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
szwProduct= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
szwProduct = strdupAtoW( szProduct );
if( !szwProduct)
return ERROR_OUTOFMEMORY;
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
}
if( szComponent )
{
len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
szwComponent= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
szwComponent = strdupAtoW( szComponent );
if( !szwComponent )
{
HeapFree( GetProcessHeap(), 0, szwProduct);
return ERROR_OUTOFMEMORY;
}
MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
}
if( pcchBuf && *pcchBuf > 0 )
@@ -1180,7 +945,7 @@ INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
if (path[0]=='0')
{
FIXME("Registry entry.. check entry\n");
rrc = INSTALLSTATE_LOCAL;
rrc = INSTALLSTATE_LOCAL;
}
else
{
@@ -1195,7 +960,7 @@ INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
{
sz = sz / sizeof(WCHAR);
if( *pcchBuf >= sz )
strcpyW( lpPathBuf, path );
lstrcpyW( lpPathBuf, path );
*pcchBuf = sz;
}
@@ -1208,29 +973,24 @@ end:
INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
{
INSTALLSTATE rc;
UINT len;
LPWSTR szwProduct= NULL;
LPWSTR szwFeature= NULL;
if( szProduct )
{
len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
szwProduct= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
szwProduct = strdupAtoW( szProduct );
if( !szwProduct)
return ERROR_OUTOFMEMORY;
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
}
if( szFeature )
{
len = MultiByteToWideChar( CP_ACP, 0, szFeature, -1, NULL, 0 );
szwFeature= HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
szwFeature = strdupAtoW( szFeature );
if( !szwFeature)
{
HeapFree( GetProcessHeap(), 0, szwProduct);
return ERROR_OUTOFMEMORY;
}
MultiByteToWideChar( CP_ACP, 0, szFeature, -1, szwFeature, len );
}
rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
@@ -1254,17 +1014,15 @@ UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
{
LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
UINT len, ret = ERROR_OUTOFMEMORY;
UINT ret = ERROR_OUTOFMEMORY;
if( szFilePath )
{
len = MultiByteToWideChar( CP_ACP, 0, szFilePath, -1, NULL, 0 );
szwFilePath = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
szwFilePath = strdupAtoW( szFilePath );
if( !szwFilePath )
goto end;
MultiByteToWideChar( CP_ACP, 0, szFilePath, -1, szwFilePath, len );
}
if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
{
lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
@@ -1278,22 +1036,22 @@ UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
if( !lpwLangBuff )
goto end;
}
ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
lpwLangBuff, pcchLangBuf);
if( lpwVersionBuff )
WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
lpVersionBuf, *pcchVersionBuf, NULL, NULL);
if( lpwLangBuff )
WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
lpLangBuf, *pcchLangBuf, NULL, NULL);
end:
HeapFree(GetProcessHeap(), 0, szwFilePath);
HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
HeapFree(GetProcessHeap(), 0, lpwLangBuff);
return ret;
}
@@ -1340,7 +1098,7 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
*pcchVersionBuf = strlenW(lpVersionBuf);
*pcchVersionBuf = lstrlenW(lpVersionBuf);
}
else
{
@@ -1356,7 +1114,7 @@ UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
FIXME("Retrieve language from file\n");
wsprintfW(tmp, szLangFormat, lang);
lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
*pcchLangBuf = strlenW(lpLangBuf);
*pcchLangBuf = lstrlenW(lpLangBuf);
}
end:
@@ -1461,15 +1219,15 @@ HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
{
TRACE("%p\n",pdvi);
if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
return E_INVALIDARG;
pdvi->dwMajorVersion = MSI_MAJORVERSION;
pdvi->dwMinorVersion = MSI_MINORVERSION;
pdvi->dwBuildNumber = MSI_BUILDNUMBER;
pdvi->dwPlatformID = 1;
return S_OK;
}
@@ -1497,7 +1255,7 @@ UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
return ERROR_CALL_NOT_IMPLEMENTED;
}
INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
DWORD dwInstallMode, DWORD dwReserved)
{
FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
@@ -1509,37 +1267,37 @@ INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
* Software\\Microsoft\\Windows\\CurrentVersion\\
* Installer\\Products\\<squishguid>\\<feature>
* "Usage"=dword:........
*/
return INSTALLSTATE_LOCAL;
*/
return INSTALLSTATE_LOCAL;
}
INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
DWORD dwInstallMode, DWORD dwReserved)
{
FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
dwInstallMode, dwReserved);
return INSTALLSTATE_LOCAL;
return INSTALLSTATE_LOCAL;
}
INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
{
FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
return INSTALLSTATE_LOCAL;
return INSTALLSTATE_LOCAL;
}
INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
{
FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
return INSTALLSTATE_LOCAL;
return INSTALLSTATE_LOCAL;
}
UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
DWORD* pcchPathBuf)
{
FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
@@ -1549,26 +1307,26 @@ UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
return ERROR_INDEX_ABSENT;
}
USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
{
FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
pcchSerialBuf);
return USERINFOSTATE_UNKNOWN;
return USERINFOSTATE_UNKNOWN;
}
USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
{
FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
pcchSerialBuf);
return USERINFOSTATE_UNKNOWN;
return USERINFOSTATE_UNKNOWN;
}
UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
@@ -1583,9 +1341,9 @@ UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiCreateAndVerifyInstallerDirectory(void)
UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
{
FIXME("\n");
FIXME("%ld\n", dwReserved);
return ERROR_CALL_NOT_IMPLEMENTED;
}
@@ -1605,7 +1363,7 @@ UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
DWORD dwReinstallMode )
{
FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
@@ -1613,7 +1371,7 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
return ERROR_SUCCESS;
}
UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
DWORD dwReinstallMode )
{
FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
+1
View File
@@ -31,4 +31,5 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#include "msi_En.rc"
#include "msi_Es.rc"
#include "msi_Fr.rc"
#include "msi_Nl.rc"
#include "msi_Pt.rc"
+3 -3
View File
@@ -24,8 +24,8 @@
24 stdcall MsiDatabaseGenerateTransformW(long long wstr long long)
25 stdcall MsiDatabaseGetPrimaryKeysA(long str ptr)
26 stdcall MsiDatabaseGetPrimaryKeysW(long wstr ptr)
27 stdcall MsiDatabaseImportA(str str)
28 stdcall MsiDatabaseImportW(wstr wstr)
27 stdcall MsiDatabaseImportA(str str long)
28 stdcall MsiDatabaseImportW(wstr wstr long)
29 stub MsiDatabaseMergeA
30 stub MsiDatabaseMergeW
31 stdcall MsiDatabaseOpenViewA(long str ptr)
@@ -219,7 +219,7 @@
219 stub MsiGetFileHashW
220 stub MsiEnumComponentCostsA
221 stub MsiEnumComponentCostsW
222 stdcall MsiCreateAndVerifyInstallerDirectory()
222 stdcall MsiCreateAndVerifyInstallerDirectory(long)
223 stdcall MsiGetFileSignatureInformationA(str long ptr ptr ptr)
224 stdcall MsiGetFileSignatureInformationW(wstr long ptr ptr ptr)
225 stdcall MsiProvideAssemblyA(str str long long str ptr)
+1 -1
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{
+33
View File
@@ -0,0 +1,33 @@
/*
* Durch resources for MSI
*
* Copyright 2005 Hans Leidekker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
{
5 "Pad %s niet gevonden"
9 "Plaats disk %s"
10 "Ongeldige parameters"
11 "Voer de map in die %s bevat"
12 "De installatiebron van het feature ontbreekt"
13 "De netwerkschijf met het feature ontbreekt"
14 "Feature van:"
15 "Kies de map die %s bevat"
}
+36 -6
View File
@@ -29,6 +29,7 @@
#include "msiquery.h"
#include "objbase.h"
#include "objidl.h"
#include "wine/unicode.h"
#define MSI_DATASIZEMASK 0x00ff
#define MSITYPE_VALID 0x0100
@@ -170,12 +171,6 @@ typedef struct tagMSIVIEWOPS
} MSIVIEWOPS;
typedef struct tagMSISUMMARYINFO
{
MSIOBJECTHDR hdr;
IPropertyStorage *propstg;
} MSISUMMARYINFO;
struct tagMSIVIEW
{
MSIOBJECTHDR hdr;
@@ -307,6 +302,7 @@ extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR);
/* record internals */
extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
extern UINT MSI_RecordGetIStream( MSIRECORD *, unsigned int, IStream **);
extern const WCHAR *MSI_RecordGetString( MSIRECORD *, unsigned int );
extern MSIRECORD *MSI_CreateRecord( unsigned int );
extern UINT MSI_RecordSetInteger( MSIRECORD *, unsigned int, int );
@@ -386,4 +382,38 @@ extern DWORD gUIFilter;
extern LPVOID gUIContext;
extern WCHAR gszLogFile[MAX_PATH];
inline static char *strdupWtoA( LPCWSTR str )
{
LPSTR ret = NULL;
if (str)
{
DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL
);
if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
}
return ret;
}
inline static LPWSTR strdupAtoW( LPCSTR str )
{
LPWSTR ret = NULL;
if (str)
{
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
}
return ret;
}
inline static LPWSTR strdupW( LPCWSTR src )
{
LPWSTR dest;
if (!src) return NULL;
dest = HeapAlloc(GetProcessHeap(), 0, (strlenW(src)+1)*sizeof(WCHAR));
strcpyW(dest, src);
return dest;
}
#endif /* __WINE_MSI_PRIVATE__ */
+4 -7
View File
@@ -86,11 +86,9 @@ UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
if( szQuery )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szQuery, -1, NULL, 0 );
szwQuery = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
szwQuery = strdupAtoW( szQuery );
if( !szwQuery )
return ERROR_FUNCTION_FAILED;
MultiByteToWideChar( CP_ACP, 0, szQuery, -1, szwQuery, len );
}
else
szwQuery = NULL;
@@ -672,16 +670,15 @@ UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb,
LPCSTR table, MSIHANDLE* phRec)
{
LPWSTR szwTable = NULL;
DWORD len;
UINT r;
TRACE("%ld %s %p\n", hdb, debugstr_a(table), phRec);
if( table )
{
len = MultiByteToWideChar( CP_ACP, 0, table, -1, NULL, 0 );
szwTable = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, table, -1, szwTable, len );
szwTable = strdupAtoW( table );
if( !szwTable )
return ERROR_OUTOFMEMORY;
}
r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec );
HeapFree( GetProcessHeap(), 0, szwTable );
+30 -34
View File
@@ -469,14 +469,13 @@ UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
{
LPWSTR szwPack = NULL;
UINT len, ret;
UINT ret;
if( szPackage )
{
len = MultiByteToWideChar( CP_ACP, 0, szPackage, -1, NULL, 0 );
szwPack = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
if( szwPack )
MultiByteToWideChar( CP_ACP, 0, szPackage, -1, szwPack, len );
szwPack = strdupAtoW( szPackage );
if( !szwPack )
return ERROR_OUTOFMEMORY;
}
ret = MsiOpenPackageExW( szwPack, dwOptions, phPackage );
@@ -638,29 +637,20 @@ UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
{
LPWSTR szwName = NULL, szwValue = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
UINT len;
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
if (NULL == szValue) {
return ERROR_INVALID_PARAMETER;
if( szName )
{
szwName = strdupAtoW( szName );
if( !szwName )
goto end;
}
len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwName )
goto end;
MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
len = MultiByteToWideChar( CP_ACP, 0, szValue, -1, NULL, 0 );
szwValue = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwValue)
goto end;
MultiByteToWideChar( CP_ACP, 0, szValue , -1, szwValue, len );
if( szValue )
{
szwValue = strdupAtoW( szValue );
if( !szwValue)
goto end;
}
hr = MsiSetPropertyW( hInstall, szwName, szwValue);
@@ -703,7 +693,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
}
else
{
strcpyW(Query,Insert);
strcpyW(Query,Insert);
row = MSI_CreateRecord(2);
MSI_RecordSetStringW(row,1,szName);
@@ -732,8 +722,13 @@ 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)
if( !package )
return ERROR_INVALID_HANDLE;
ret = MSI_SetPropertyW( package, szName, szValue);
msiobj_release( &package->hdr );
@@ -808,17 +803,18 @@ UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName,
LPSTR szValueBuf, DWORD* pchValueBuf)
{
MSIRECORD *row;
UINT rc, len;
LPWSTR szwName;
UINT rc;
LPWSTR szwName = NULL;
if (*pchValueBuf > 0)
szValueBuf[0] = 0;
len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if (!szwName)
return ERROR_NOT_ENOUGH_MEMORY;
MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
if( szName )
{
szwName = strdupAtoW( szName );
if (!szwName)
return ERROR_NOT_ENOUGH_MEMORY;
}
rc = MSI_GetPropertyRow(package, szwName, &row);
if (rc == ERROR_SUCCESS)
+4 -4
View File
@@ -132,16 +132,16 @@ UINT WINAPI MsiPreviewDialogW( MSIHANDLE hPreview, LPCWSTR szDialogName )
UINT WINAPI MsiPreviewDialogA( MSIHANDLE hPreview, LPCSTR szDialogName )
{
UINT r, len;
UINT r;
LPWSTR strW = NULL;
TRACE("%ld %s\n", hPreview, debugstr_a(szDialogName));
if( szDialogName )
{
len = MultiByteToWideChar( CP_ACP, 0, szDialogName, -1, NULL, 0 );
strW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, szDialogName, -1, strW, len );
strW = strdupAtoW( szDialogName );
if( !strW )
return ERROR_OUTOFMEMORY;
}
r = MsiPreviewDialogW( hPreview, strW );
HeapFree( GetProcessHeap(), 0, strW );
+22 -13
View File
@@ -448,7 +448,6 @@ UINT WINAPI MsiRecordDataSize(MSIHANDLE handle, unsigned int iField)
UINT MSI_RecordSetStringA( MSIRECORD *rec, unsigned int iField, LPCSTR szValue )
{
LPWSTR str;
UINT len;
TRACE("%p %d %s\n", rec, iField, debugstr_a(szValue));
@@ -458,9 +457,7 @@ UINT MSI_RecordSetStringA( MSIRECORD *rec, unsigned int iField, LPCSTR szValue )
MSI_FreeField( &rec->fields[iField] );
if( szValue && szValue[0] )
{
len = MultiByteToWideChar( CP_ACP, 0, szValue, -1, NULL, 0 );
str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, szValue, -1, str, len );
str = strdupAtoW( szValue );
rec->fields[iField].type = MSIFIELD_WSTR;
rec->fields[iField].u.szwVal = str;
}
@@ -493,7 +490,6 @@ UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, unsigned int iField, LPCSTR s
UINT MSI_RecordSetStringW( MSIRECORD *rec, unsigned int iField, LPCWSTR szValue )
{
LPWSTR str;
UINT len;
TRACE("%p %d %s\n", rec, iField, debugstr_w(szValue));
@@ -504,10 +500,7 @@ UINT MSI_RecordSetStringW( MSIRECORD *rec, unsigned int iField, LPCWSTR szValue
if( szValue && szValue[0] )
{
len = lstrlenW(szValue) + 1;
str = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR));
lstrcpyW( str, szValue );
str = strdupW( szValue );
rec->fields[iField].type = MSIFIELD_WSTR;
rec->fields[iField].u.szwVal = str;
}
@@ -633,15 +626,15 @@ UINT MSI_RecordSetStreamW(MSIRECORD *rec, unsigned int iField, LPCWSTR szFilenam
UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, unsigned int iField, LPCSTR szFilename)
{
LPWSTR wstr = NULL;
UINT ret, len;
UINT ret;
TRACE("%ld %d %s\n", hRecord, iField, debugstr_a(szFilename));
if( szFilename )
{
len = MultiByteToWideChar(CP_ACP,0,szFilename,-1,NULL,0);
wstr = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,0,szFilename,-1,wstr,len);
wstr = strdupAtoW( szFilename );
if( !wstr )
return ERROR_OUTOFMEMORY;
}
ret = MsiRecordSetStreamW(hRecord, iField, wstr);
HeapFree(GetProcessHeap(),0,wstr);
@@ -751,3 +744,19 @@ UINT MSI_RecordSetIStream( MSIRECORD *rec, unsigned int iField, IStream *stm )
return ERROR_SUCCESS;
}
UINT MSI_RecordGetIStream( MSIRECORD *rec, unsigned int iField, IStream **pstm)
{
TRACE("%p %d %p\n", rec, iField, pstm);
if( iField > rec->count )
return ERROR_INVALID_FIELD;
if( rec->fields[iField].type != MSIFIELD_STREAM )
return ERROR_INVALID_FIELD;
*pstm = rec->fields[iField].u.stream;
IStream_AddRef( *pstm );
return ERROR_SUCCESS;
}
+59 -89
View File
@@ -134,6 +134,8 @@ static const WCHAR szInstaller_UpgradeCodes_fmt[] = {
'U','p','g','r','a','d','e','C','o','d','e','s','\\',
'%','s',0};
#define SQUISH_GUID_SIZE 33
BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
{
DWORD i,n=0;
@@ -496,16 +498,16 @@ UINT WINAPI MsiDecomposeDescriptorA( LPCSTR szDescriptor, LPSTR szProduct,
WCHAR feature[MAX_FEATURE_CHARS+1];
WCHAR component[MAX_FEATURE_CHARS+1];
LPWSTR str = NULL;
UINT r, len;
UINT r;
TRACE("%s %p %p %p %p\n", debugstr_a(szDescriptor), szProduct,
szFeature, szComponent, pUsed);
if( szDescriptor )
{
len = MultiByteToWideChar( CP_ACP, 0, szDescriptor, -1, NULL, 0 );
str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, szDescriptor, -1, str, len );
str = strdupAtoW( szDescriptor );
if( !str )
return ERROR_OUTOFMEMORY;
}
r = MsiDecomposeDescriptorW( str, product, feature, component, pUsed );
@@ -542,7 +544,7 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
{
HKEY hkeyFeatures = 0;
DWORD r;
WCHAR szKeyName[33];
WCHAR szKeyName[SQUISH_GUID_SIZE];
TRACE("%ld %p\n",index,lpguid);
@@ -551,16 +553,12 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
r = MSIREG_OpenFeatures(&hkeyFeatures);
if( r != ERROR_SUCCESS )
goto end;
return ERROR_NO_MORE_ITEMS;
r = RegEnumKeyW(hkeyFeatures, index, szKeyName, GUID_SIZE);
unsquash_guid(szKeyName, lpguid);
end:
if( hkeyFeatures )
RegCloseKey(hkeyFeatures);
r = RegEnumKeyW(hkeyFeatures, index, szKeyName, SQUISH_GUID_SIZE);
if( r == ERROR_SUCCESS )
unsquash_guid(szKeyName, lpguid);
RegCloseKey(hkeyFeatures);
return r;
}
@@ -576,12 +574,9 @@ UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index,
if( szProduct )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
if( szwProduct )
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
else
return ERROR_FUNCTION_FAILED;
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
return ERROR_OUTOFMEMORY;
}
r = MsiEnumFeaturesW(szwProduct, index, szwFeature, szwParent);
@@ -608,14 +603,11 @@ UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
r = MSIREG_OpenFeaturesKey(szProduct,&hkeyProduct,FALSE);
if( r != ERROR_SUCCESS )
goto end;
return ERROR_NO_MORE_ITEMS;
sz = GUID_SIZE;
r = RegEnumValueW(hkeyProduct, index, szFeature, &sz, NULL, NULL, NULL, NULL);
end:
if( hkeyProduct )
RegCloseKey(hkeyProduct);
RegCloseKey(hkeyProduct);
return r;
}
@@ -638,22 +630,18 @@ UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
{
HKEY hkeyComponents = 0;
DWORD r;
WCHAR szKeyName[33];
WCHAR szKeyName[SQUISH_GUID_SIZE];
TRACE("%ld %p\n",index,lpguid);
r = MSIREG_OpenComponents(&hkeyComponents);
if( r != ERROR_SUCCESS )
goto end;
return ERROR_NO_MORE_ITEMS;
r = RegEnumKeyW(hkeyComponents, index, szKeyName, GUID_SIZE);
unsquash_guid(szKeyName, lpguid);
end:
if( hkeyComponents )
RegCloseKey(hkeyComponents);
r = RegEnumKeyW(hkeyComponents, index, szKeyName, SQUISH_GUID_SIZE);
if( r == ERROR_SUCCESS )
unsquash_guid(szKeyName, lpguid);
RegCloseKey(hkeyComponents);
return r;
}
@@ -668,12 +656,9 @@ UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
if( szComponent )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
if( szwComponent )
MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
else
return ERROR_FUNCTION_FAILED;
szwComponent = strdupAtoW( szComponent );
if( !szwComponent )
return ERROR_OUTOFMEMORY;
}
r = MsiEnumClientsW(szComponent?szwComponent:NULL, index, szwProduct);
@@ -692,24 +677,20 @@ UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
{
HKEY hkeyComp = 0;
DWORD r, sz;
WCHAR szValName[GUID_SIZE];
WCHAR szValName[SQUISH_GUID_SIZE];
TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);
r = MSIREG_OpenComponentsKey(szComponent,&hkeyComp,FALSE);
if( r != ERROR_SUCCESS )
goto end;
return ERROR_NO_MORE_ITEMS;
sz = GUID_SIZE;
sz = SQUISH_GUID_SIZE;
r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);
if( r != ERROR_SUCCESS )
goto end;
if( r == ERROR_SUCCESS )
unsquash_guid(szValName, szProduct);
unsquash_guid(szValName, szProduct);
end:
if( hkeyComp )
RegCloseKey(hkeyComp);
RegCloseKey(hkeyComp);
return r;
}
@@ -737,9 +718,9 @@ UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex,
UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,
DWORD iProductIndex, LPWSTR lpProductBuf)
{
UINT rc;
UINT r;
HKEY hkey;
WCHAR szKeyName[33];
WCHAR szKeyName[SQUISH_GUID_SIZE];
TRACE("%s %lu %lu %p\n", debugstr_w(szUpgradeCode), dwReserved,
iProductIndex, lpProductBuf);
@@ -748,54 +729,43 @@ UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,
return ERROR_INVALID_PARAMETER;
if (NULL == lpProductBuf)
return ERROR_INVALID_PARAMETER;
rc = MSIREG_OpenUpgradeCodesKey(szUpgradeCode, &hkey, FALSE);
if (rc != ERROR_SUCCESS)
{
rc = ERROR_NO_MORE_ITEMS;
goto end;
}
rc = RegEnumKeyW(hkey, iProductIndex, szKeyName,
sizeof(szKeyName) / sizeof(szKeyName[0]));
r = MSIREG_OpenUpgradeCodesKey(szUpgradeCode, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_NO_MORE_ITEMS;
unsquash_guid(szKeyName, lpProductBuf);
r = RegEnumKeyW(hkey, iProductIndex, szKeyName, SQUISH_GUID_SIZE);
if( r == ERROR_SUCCESS )
unsquash_guid(szKeyName, lpProductBuf);
RegCloseKey(hkey);
end:
return rc;
return r;
}
UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved,
DWORD iProductIndex, LPSTR lpProductBuf)
{
UINT rc;
int len;
LPWSTR szUpgradeCodeW = NULL;
LPWSTR szwUpgradeCode = NULL;
WCHAR productW[GUID_SIZE];
UINT r;
TRACE("%s %lu %lu %p\n", debugstr_a(szUpgradeCode), dwReserved,
iProductIndex, lpProductBuf);
if (!szUpgradeCode)
return ERROR_INVALID_PARAMETER;
len = MultiByteToWideChar(CP_ACP, 0, szUpgradeCode, -1, NULL, 0);
szUpgradeCodeW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
len * sizeof(WCHAR));
if (szUpgradeCodeW)
if (szUpgradeCode)
{
WCHAR productW[39];
MultiByteToWideChar(CP_ACP, 0, szUpgradeCode, -1, szUpgradeCodeW, len);
rc = MsiEnumRelatedProductsW(szUpgradeCodeW, dwReserved,
iProductIndex, productW);
if (rc == ERROR_SUCCESS)
{
LPWSTR ptr;
for (ptr = productW; *ptr; )
*lpProductBuf++ = *ptr++;
}
HeapFree(GetProcessHeap(), 0, szUpgradeCodeW);
szwUpgradeCode = strdupAtoW( szUpgradeCode );
if( !szwUpgradeCode )
return ERROR_OUTOFMEMORY;
}
else
rc = ERROR_OUTOFMEMORY;
return rc;
r = MsiEnumRelatedProductsW( szwUpgradeCode, dwReserved,
iProductIndex, productW );
if (r == ERROR_SUCCESS)
{
WideCharToMultiByte( CP_ACP, 0, productW, GUID_SIZE,
lpProductBuf, GUID_SIZE, NULL, NULL );
}
HeapFree(GetProcessHeap(), 0, szwUpgradeCode);
return r;
}
+607 -167
View File
@@ -1,7 +1,7 @@
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2002 Mike McCormack for CodeWeavers
* Copyright 2002, 2005 Mike McCormack for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -33,61 +33,406 @@
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msidefs.h"
#include "msipriv.h"
#include "objidl.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
#define MSI_MAX_PROPS 19
#include "pshpack1.h"
typedef struct {
WORD wByteOrder;
WORD wFormat;
DWORD dwOSVer;
CLSID clsID;
DWORD reserved;
} PROPERTYSETHEADER;
typedef struct {
FMTID fmtid;
DWORD dwOffset;
} FORMATIDOFFSET;
typedef struct {
DWORD cbSection;
DWORD cProperties;
} PROPERTYSECTIONHEADER;
typedef struct {
DWORD propid;
DWORD dwOffset;
} PROPERTYIDOFFSET;
typedef struct {
DWORD type;
union {
INT i4;
SHORT i2;
FILETIME ft;
struct {
DWORD len;
BYTE str[1];
} str;
} u;
} PROPERTY_DATA;
#include "poppack.h"
typedef struct {
BOOL unicode;
union {
LPSTR a;
LPWSTR w;
} str;
} awstring;
typedef struct tagMSISUMMARYINFO
{
MSIOBJECTHDR hdr;
MSIDATABASE *db;
DWORD update_count;
PROPVARIANT property[MSI_MAX_PROPS];
} MSISUMMARYINFO;
static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
'I','n','f','o','r','m','a','t','i','o','n',0 };
static void MSI_CloseSummaryInfo( MSIOBJECTHDR *arg )
static void free_prop( PROPVARIANT *prop )
{
MSISUMMARYINFO *suminfo = (MSISUMMARYINFO *) arg;
IPropertyStorage_Release( suminfo->propstg );
if (prop->vt == VT_LPSTR )
HeapFree( GetProcessHeap(), 0, prop->u.pszVal );
prop->vt = VT_EMPTY;
}
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase,
LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
static void MSI_CloseSummaryInfo( MSIOBJECTHDR *arg )
{
LPWSTR szwDatabase = NULL;
UINT ret;
MSISUMMARYINFO *si = (MSISUMMARYINFO *) arg;
DWORD i;
TRACE("%ld %s %d %p\n", hDatabase, debugstr_a(szDatabase),
uiUpdateCount, phSummaryInfo);
for( i = 0; i < MSI_MAX_PROPS; i++ )
free_prop( &si->property[i] );
msiobj_release( &si->db->hdr );
}
if( szDatabase )
static UINT get_type( UINT uiProperty )
{
switch( uiProperty )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, NULL, 0 );
szwDatabase = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
if( !szwDatabase )
return ERROR_FUNCTION_FAILED;
MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, szwDatabase, len );
case PID_CODEPAGE:
return VT_I2;
case PID_SUBJECT:
case PID_AUTHOR:
case PID_KEYWORDS:
case PID_COMMENTS:
case PID_TEMPLATE:
case PID_LASTAUTHOR:
case PID_REVNUMBER:
case PID_APPNAME:
case PID_TITLE:
return VT_LPSTR;
case PID_LASTPRINTED:
case PID_CREATE_DTM:
case PID_LASTSAVE_DTM:
return VT_FILETIME;
case PID_WORDCOUNT:
case PID_CHARCOUNT:
case PID_SECURITY:
case PID_PAGECOUNT:
return VT_I4;
}
return VT_EMPTY;
}
static UINT get_property_count( PROPVARIANT *property )
{
UINT i, n = 0;
if( !property )
return n;
for( i = 0; i < MSI_MAX_PROPS; i++ )
if( property[i].vt != VT_EMPTY )
n++;
return n;
}
/* FIXME: doesn't deal with endian conversion */
static void read_properties_from_data( PROPVARIANT *prop,
PROPERTYIDOFFSET *idofs, DWORD count, LPBYTE data, DWORD sz )
{
UINT type;
DWORD i;
int size;
PROPERTY_DATA *propdata;
PROPVARIANT *property;
/* now set all the properties */
for( i = 0; i < count; i++ )
{
type = get_type( idofs[i].propid );
if( type == VT_EMPTY )
{
ERR("propid %ld has unknown type\n", idofs[i].propid);
break;
}
propdata = (PROPERTY_DATA*) &data[idofs[i].dwOffset];
/* check the type is the same as we expect */
if( type != propdata->type )
{
ERR("wrong type\n");
break;
}
/* check we don't run off the end of the data */
size = sz - idofs[i].dwOffset - sizeof(DWORD);
if( sizeof(DWORD) > size ||
( type == VT_FILETIME && sizeof(FILETIME) > size ) ||
( type == VT_LPSTR && (propdata->u.str.len + sizeof(DWORD)) > size ) )
{
ERR("not enough data\n");
break;
}
property = &prop[ idofs[i].propid ];
property->vt = type;
if( type == VT_LPSTR )
{
LPSTR str = HeapAlloc( GetProcessHeap(), 0, propdata->u.str.len );
memcpy( str, propdata->u.str.str, propdata->u.str.len );
str[ propdata->u.str.len - 1 ] = 0;
property->u.pszVal = str;
}
else if( type == VT_FILETIME )
property->u.filetime = propdata->u.ft;
else if( type == VT_I2 )
property->u.iVal = propdata->u.i2;
else if( type == VT_I4 )
property->u.lVal = propdata->u.i4;
}
}
static UINT load_summary_info( MSISUMMARYINFO *si, IStream *stm )
{
UINT ret = ERROR_FUNCTION_FAILED;
PROPERTYSETHEADER set_hdr;
FORMATIDOFFSET format_hdr;
PROPERTYSECTIONHEADER section_hdr;
PROPERTYIDOFFSET idofs[MSI_MAX_PROPS];
LPBYTE data = NULL;
LARGE_INTEGER ofs;
ULONG count, sz;
HRESULT r;
TRACE("%p %p\n", si, stm);
/* read the header */
sz = sizeof set_hdr;
r = IStream_Read( stm, &set_hdr, sz, &count );
if( FAILED(r) || count != sz )
return ret;
if( set_hdr.wByteOrder != 0xfffe )
{
ERR("property set not big-endian %04X\n", set_hdr.wByteOrder);
return ret;
}
ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, phSummaryInfo);
sz = sizeof format_hdr;
r = IStream_Read( stm, &format_hdr, sz, &count );
if( FAILED(r) || count != sz )
return ret;
HeapFree( GetProcessHeap(), 0, szwDatabase );
/* check the format id is correct */
if( !IsEqualGUID( &FMTID_SummaryInformation, &format_hdr.fmtid ) )
return ret;
/* seek to the location of the section */
ofs.QuadPart = format_hdr.dwOffset;
r = IStream_Seek( stm, ofs, STREAM_SEEK_SET, NULL );
if( FAILED(r) )
return ret;
/* read the section itself */
sz = sizeof section_hdr;
r = IStream_Read( stm, &section_hdr, sz, &count );
if( FAILED(r) || count != sz )
return ret;
if( section_hdr.cProperties > MSI_MAX_PROPS )
{
ERR("too many properties %ld\n", section_hdr.cProperties);
return ret;
}
/* read the offsets */
sz = sizeof idofs[0] * section_hdr.cProperties;
r = IStream_Read( stm, idofs, sz, &count );
if( FAILED(r) || count != sz )
return ret;
/* read all the data in one go */
sz = section_hdr.cbSection;
data = HeapAlloc( GetProcessHeap(), 0, sz );
if( !data )
return ret;
r = IStream_Read( stm, data, sz, &count );
if( SUCCEEDED(r) && count == sz )
{
read_properties_from_data( si->property, idofs,
section_hdr.cProperties, data, sz );
}
HeapFree( GetProcessHeap(), 0, data );
return ret;
}
UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
static DWORD write_dword( LPBYTE data, DWORD ofs, DWORD val )
{
if( data )
{
data[ofs++] = val&0xff;
data[ofs++] = (val>>8)&0xff;
data[ofs++] = (val>>16)&0xff;
data[ofs++] = (val>>24)&0xff;
}
return 4;
}
static DWORD write_filetime( LPBYTE data, DWORD ofs, LPFILETIME ft )
{
write_dword( data, ofs, ft->dwLowDateTime );
write_dword( data, ofs + 4, ft->dwHighDateTime );
return 8;
}
static DWORD write_string( LPBYTE data, DWORD ofs, LPCSTR str )
{
DWORD len = lstrlenA( str ) + 1;
write_dword( data, ofs, len );
if( data )
lstrcpyA( &data[ofs + 4], str );
return (7 + len) & ~3;
}
static UINT write_property_to_data( PROPVARIANT *prop, LPBYTE data )
{
DWORD sz = 0;
if( prop->vt == VT_EMPTY )
return sz;
/* add the type */
sz += write_dword( data, sz, prop->vt );
switch( prop->vt )
{
case VT_I2:
sz += write_dword( data, sz, prop->u.iVal );
break;
case VT_I4:
sz += write_dword( data, sz, prop->u.lVal );
break;
case VT_FILETIME:
sz += write_filetime( data, sz, &prop->u.filetime );
break;
case VT_LPSTR:
sz += write_string( data, sz, prop->u.pszVal );
break;
}
return sz;
}
static UINT save_summary_info( MSISUMMARYINFO * si, IStream *stm )
{
UINT ret = ERROR_FUNCTION_FAILED;
PROPERTYSETHEADER set_hdr;
FORMATIDOFFSET format_hdr;
PROPERTYSECTIONHEADER section_hdr;
PROPERTYIDOFFSET idofs[MSI_MAX_PROPS];
LPBYTE data = NULL;
ULONG count, sz;
HRESULT r;
MSIHANDLE handle;
MSISUMMARYINFO *suminfo;
MSIDATABASE *db;
int i, n;
/* write the header */
sz = sizeof set_hdr;
memset( &set_hdr, 0, sz );
set_hdr.wByteOrder = 0xfffe;
set_hdr.wFormat = 0;
set_hdr.dwOSVer = 0x00020005; /* build 5, platform id 2 */
/* set_hdr.clsID is {00000000-0000-0000-0000-000000000000} */
set_hdr.reserved = 1;
r = IStream_Write( stm, &set_hdr, sz, &count );
if( FAILED(r) || count != sz )
return ret;
/* write the format header */
sz = sizeof format_hdr;
memcpy( &format_hdr.fmtid, &FMTID_SummaryInformation, sizeof (FMTID) );
format_hdr.dwOffset = sizeof format_hdr + sizeof set_hdr;
r = IStream_Write( stm, &format_hdr, sz, &count );
if( FAILED(r) || count != sz )
return ret;
/* add up how much space the data will take and calculate the offsets */
section_hdr.cbSection = sizeof section_hdr;
section_hdr.cbSection += (get_property_count( si->property ) * sizeof idofs[0]);
section_hdr.cProperties = 0;
n = 0;
for( i = 0; i < MSI_MAX_PROPS; i++ )
{
sz = write_property_to_data( &si->property[i], NULL );
if( !sz )
continue;
idofs[ section_hdr.cProperties ].propid = i;
idofs[ section_hdr.cProperties ].dwOffset = section_hdr.cbSection;
section_hdr.cProperties++;
section_hdr.cbSection += sz;
}
data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, section_hdr.cbSection );
sz = 0;
memcpy( &data[sz], &section_hdr, sizeof section_hdr );
sz += sizeof section_hdr;
memcpy( &data[sz], idofs, section_hdr.cProperties * sizeof idofs[0] );
sz += section_hdr.cProperties * sizeof idofs[0];
/* write out the data */
for( i = 0; i < MSI_MAX_PROPS; i++ )
sz += write_property_to_data( &si->property[i], &data[sz] );
r = IStream_Write( stm, data, sz, &count );
HeapFree( GetProcessHeap(), 0, data );
if( FAILED(r) || count != sz )
return ret;
return ERROR_SUCCESS;
}
UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle )
{
UINT ret = ERROR_SUCCESS;
IPropertySetStorage *psstg = NULL;
IPropertyStorage *ps = NULL;
IStream *stm = NULL;
MSISUMMARYINFO *si;
MSIHANDLE handle;
MSIDATABASE *db;
DWORD grfMode;
HRESULT r;
TRACE("%ld %s %d %p\n", hDatabase, debugstr_w(szDatabase),
uiUpdateCount, phSummaryInfo);
uiUpdateCount, pHandle);
if( !phSummaryInfo )
if( !pHandle )
return ERROR_INVALID_PARAMETER;
if( szDatabase )
@@ -105,207 +450,302 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
return ERROR_INVALID_PARAMETER;
}
r = IStorage_QueryInterface( db->storage,
&IID_IPropertySetStorage, (LPVOID)&psstg);
if( FAILED( r ) )
{
ERR("IStorage -> IPropertySetStorage failed\n");
ret = ERROR_FUNCTION_FAILED;
goto end;
}
grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps );
if( FAILED( r ) )
{
ERR("failed to get IPropertyStorage r=%08lx\n",r);
ret = ERROR_FUNCTION_FAILED;
goto end;
}
suminfo = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO,
si = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO,
sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
if( !suminfo )
if( !si )
{
ret = ERROR_FUNCTION_FAILED;
goto end;
}
IPropertyStorage_AddRef(ps);
suminfo->propstg = ps;
handle = alloc_msihandle( &suminfo->hdr );
msiobj_addref( &db->hdr );
si->db = db;
memset( &si->property, 0, sizeof si->property );
si->update_count = uiUpdateCount;
/* read the stream... if we fail, we'll start with an empty property set */
grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
r = IStorage_OpenStream( si->db->storage, szSumInfo, 0, grfMode, 0, &stm );
if( SUCCEEDED(r) )
{
load_summary_info( si, stm );
IStream_Release( stm );
}
handle = alloc_msihandle( &si->hdr );
if( handle )
*phSummaryInfo = handle;
*pHandle = handle;
else
ret = ERROR_FUNCTION_FAILED;
msiobj_release( &suminfo->hdr );
msiobj_release( &si->hdr );
end:
if( ps )
IPropertyStorage_Release(ps);
if( psstg )
IPropertySetStorage_Release(psstg);
if( db )
msiobj_release(&db->hdr);
return ret;
}
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase,
LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
{
LPWSTR szwDatabase = NULL;
UINT ret;
TRACE("%ld %s %d %p\n", hDatabase, debugstr_a(szDatabase),
uiUpdateCount, pHandle);
if( szDatabase )
{
szwDatabase = strdupAtoW( szDatabase );
if( !szwDatabase )
return ERROR_FUNCTION_FAILED;
}
ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, pHandle);
HeapFree( GetProcessHeap(), 0, szwDatabase );
return ret;
}
UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount)
{
MSISUMMARYINFO *suminfo;
MSISUMMARYINFO *si;
FIXME("%ld %p\n",hSummaryInfo, pCount);
TRACE("%ld %p\n",hSummaryInfo, pCount);
suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
if( !suminfo )
si = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
if( !si )
return ERROR_INVALID_HANDLE;
msiobj_release( &suminfo->hdr );
return ERROR_CALL_NOT_IMPLEMENTED;
if( pCount )
*pCount = get_property_count( si->property );
msiobj_release( &si->hdr );
return ERROR_SUCCESS;
}
static UINT get_prop( MSIHANDLE handle, UINT uiProperty, UINT *puiDataType,
INT *piValue, FILETIME *pftValue, awstring *str, DWORD *pcchValueBuf)
{
MSISUMMARYINFO *si;
PROPVARIANT *prop;
UINT type;
TRACE("%ld %d %p %p %p %p %p\n", handle, uiProperty, puiDataType,
piValue, pftValue, str, pcchValueBuf);
type = get_type( uiProperty );
if( puiDataType )
*puiDataType = type;
si = msihandle2msiinfo( handle, MSIHANDLETYPE_SUMMARYINFO );
if( !si )
return ERROR_INVALID_HANDLE;
prop = &si->property[uiProperty];
if( prop->vt != type )
goto end;
switch( type )
{
case VT_I2:
if( piValue )
*piValue = prop->u.iVal;
break;
case VT_I4:
if( piValue )
*piValue = prop->u.lVal;
break;
case VT_LPSTR:
if( pcchValueBuf )
{
DWORD len = 0;
if( str->unicode )
{
len = MultiByteToWideChar( CP_ACP, 0, prop->u.pszVal, -1,
str->str.w, *pcchValueBuf );
}
else
{
len = lstrlenA( prop->u.pszVal );
if( str->str.a )
lstrcpynA(str->str.a, prop->u.pszVal, *pcchValueBuf );
}
*pcchValueBuf = len;
}
break;
case VT_FILETIME:
if( pftValue )
memcpy(pftValue, &prop->u.filetime, sizeof (FILETIME) );
break;
case VT_EMPTY:
break;
default:
FIXME("Unknown property variant type\n");
break;
}
end:
msiobj_release( &si->hdr );
return ERROR_SUCCESS;
}
UINT WINAPI MsiSummaryInfoGetPropertyA(
MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, INT *piValue,
FILETIME *pftValue, LPSTR szValueBuf, DWORD *pcchValueBuf)
{
MSISUMMARYINFO *suminfo;
HRESULT r;
PROPSPEC spec;
PROPVARIANT var;
UINT rc = ERROR_SUCCESS;
awstring str;
TRACE("%ld %d %p %p %p %p %p\n",
hSummaryInfo, uiProperty, puiDataType, piValue,
pftValue, szValueBuf, pcchValueBuf);
TRACE("%ld %d %p %p %p %p %p\n", handle, uiProperty, puiDataType,
piValue, pftValue, szValueBuf, pcchValueBuf );
suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
if( !suminfo )
return ERROR_INVALID_HANDLE;
str.unicode = FALSE;
str.str.a = szValueBuf;
spec.ulKind = PRSPEC_PROPID;
spec.u.propid = uiProperty;
r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);
if( FAILED(r) )
{
rc = ERROR_FUNCTION_FAILED;
goto end;
}
if( puiDataType )
*puiDataType = var.vt;
switch( var.vt )
{
case VT_I4:
if( piValue )
*piValue = var.u.lVal;
break;
case VT_LPSTR:
if( pcchValueBuf && szValueBuf )
{
lstrcpynA(szValueBuf, var.u.pszVal, *pcchValueBuf );
*pcchValueBuf = lstrlenA( var.u.pszVal );
}
break;
case VT_FILETIME:
if( pftValue )
memcpy(pftValue, &var.u.filetime, sizeof (FILETIME) );
break;
case VT_EMPTY:
break;
default:
FIXME("Unknown property variant type\n");
break;
}
end:
msiobj_release( &suminfo->hdr );
return rc;
return get_prop( handle, uiProperty, puiDataType, piValue,
pftValue, &str, pcchValueBuf );
}
UINT WINAPI MsiSummaryInfoGetPropertyW(
MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, INT *piValue,
FILETIME *pftValue, LPWSTR szValueBuf, DWORD *pcchValueBuf)
{
MSISUMMARYINFO *suminfo;
HRESULT r;
PROPSPEC spec;
PROPVARIANT var;
UINT rc = ERROR_SUCCESS;
awstring str;
TRACE("%ld %d %p %p %p %p %p\n",
hSummaryInfo, uiProperty, puiDataType, piValue,
pftValue, szValueBuf, pcchValueBuf);
TRACE("%ld %d %p %p %p %p %p\n", handle, uiProperty, puiDataType,
piValue, pftValue, szValueBuf, pcchValueBuf );
suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
if( !suminfo )
str.unicode = TRUE;
str.str.w = szValueBuf;
return get_prop( handle, uiProperty, puiDataType, piValue,
pftValue, &str, pcchValueBuf );
}
static UINT set_prop( MSIHANDLE handle, UINT uiProperty, UINT uiDataType,
INT iValue, FILETIME* pftValue, awstring *str )
{
MSISUMMARYINFO *si;
PROPVARIANT *prop;
UINT type, len, ret = ERROR_SUCCESS;
TRACE("%ld %u %u %i %p %p\n", handle, uiProperty, uiDataType,
iValue, pftValue, str );
type = get_type( uiProperty );
if( type == VT_EMPTY || type != uiDataType )
return ERROR_DATATYPE_MISMATCH;
if( uiDataType == VT_LPSTR && !str->str.w )
return ERROR_INVALID_PARAMETER;
if( uiDataType == VT_FILETIME && !pftValue )
return ERROR_INVALID_PARAMETER;
si = msihandle2msiinfo( handle, MSIHANDLETYPE_SUMMARYINFO );
if( !si )
return ERROR_INVALID_HANDLE;
spec.ulKind = PRSPEC_PROPID;
spec.u.propid = uiProperty;
prop = &si->property[uiProperty];
r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);
if( FAILED(r) )
if( prop->vt == VT_EMPTY )
{
rc = ERROR_FUNCTION_FAILED;
goto end;
if( !si->update_count )
{
ret = ERROR_FUNCTION_FAILED;
goto end;
}
si->update_count--;
}
else if( prop->vt != type )
goto end;
if( puiDataType )
*puiDataType = var.vt;
switch( var.vt )
free_prop( prop );
prop->vt = type;
switch( type )
{
case VT_I4:
if( piValue )
*piValue = var.u.lVal;
prop->u.lVal = iValue;
break;
case VT_LPSTR:
if( pcchValueBuf && szValueBuf )
{
MultiByteToWideChar(CP_ACP, 0, var.u.pszVal, -1, szValueBuf,
*pcchValueBuf );
*pcchValueBuf = lstrlenA( var.u.pszVal );
}
case VT_I2:
prop->u.iVal = iValue;
break;
case VT_FILETIME:
if( pftValue )
memcpy(pftValue, &var.u.filetime, sizeof (FILETIME) );
memcpy( &prop->u.filetime, pftValue, sizeof prop->u.filetime );
break;
case VT_EMPTY:
break;
default:
FIXME("Unknown property variant type\n");
case VT_LPSTR:
if( str->unicode )
{
len = WideCharToMultiByte( CP_ACP, 0, str->str.w, -1,
NULL, 0, NULL, NULL );
prop->u.pszVal = HeapAlloc( GetProcessHeap(), 0, len );
WideCharToMultiByte( CP_ACP, 0, str->str.w, -1,
prop->u.pszVal, len, NULL, NULL );
}
else
{
len = lstrlenA( str->str.a ) + 1;
prop->u.pszVal = HeapAlloc( GetProcessHeap(), 0, len );
lstrcpyA( prop->u.pszVal, str->str.a );
}
break;
}
end:
msiobj_release( &suminfo->hdr );
return rc;
msiobj_release( &si->hdr );
return ret;
}
UINT WINAPI MsiSummaryInfoSetPropertyA( MSIHANDLE hSummaryInfo, UINT uiProperty,
UINT uiDataType, INT iValue,
FILETIME* pftValue, LPSTR szValue )
UINT WINAPI MsiSummaryInfoSetPropertyW( MSIHANDLE handle, UINT uiProperty,
UINT uiDataType, INT iValue, FILETIME* pftValue, LPWSTR szValue )
{
FIXME("%ld %u %u %i %p %s\n", hSummaryInfo, uiProperty,
uiDataType, iValue, pftValue, debugstr_a(szValue) );
return ERROR_CALL_NOT_IMPLEMENTED;
awstring str;
TRACE("%ld %u %u %i %p %s\n", handle, uiProperty, uiDataType,
iValue, pftValue, debugstr_w(szValue) );
str.unicode = TRUE;
str.str.w = szValue;
return set_prop( handle, uiProperty, uiDataType, iValue, pftValue, &str );
}
UINT WINAPI MsiSummaryInfoSetPropertyW( MSIHANDLE hSummaryInfo, UINT uiProperty,
UINT uiDataType, INT iValue,
FILETIME* pftValue, LPWSTR szValue )
UINT WINAPI MsiSummaryInfoSetPropertyA( MSIHANDLE handle, UINT uiProperty,
UINT uiDataType, INT iValue, FILETIME* pftValue, LPSTR szValue )
{
FIXME("%ld %u %u %i %p %s\n", hSummaryInfo, uiProperty,
uiDataType, iValue, pftValue, debugstr_w(szValue) );
return ERROR_CALL_NOT_IMPLEMENTED;
awstring str;
TRACE("%ld %u %u %i %p %s\n", handle, uiProperty, uiDataType,
iValue, pftValue, debugstr_a(szValue) );
str.unicode = FALSE;
str.str.a = szValue;
return set_prop( handle, uiProperty, uiDataType, iValue, pftValue, &str );
}
UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE hSummaryInfo )
UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE handle )
{
FIXME("%ld\n", hSummaryInfo );
return ERROR_CALL_NOT_IMPLEMENTED;
IStream *stm = NULL;
MSISUMMARYINFO *si;
DWORD grfMode;
HRESULT r;
UINT ret = ERROR_FUNCTION_FAILED;
TRACE("%ld\n", handle );
si = msihandle2msiinfo( handle, MSIHANDLETYPE_SUMMARYINFO );
if( !si )
return ERROR_INVALID_HANDLE;
grfMode = STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
r = IStorage_CreateStream( si->db->storage, szSumInfo, grfMode, 0, 0, &stm );
if( SUCCEEDED(r) )
{
ret = save_summary_info( si, stm );
IStream_Release( stm );
}
msiobj_release( &si->hdr );
return ret;
}
-9
View File
@@ -834,15 +834,6 @@ err:
return ret;
}
static LPWSTR strdupW( LPCWSTR str )
{
UINT len = lstrlenW( str ) + 1;
LPWSTR ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
if( ret )
lstrcpyW( ret, str );
return ret;
}
/* information for default tables */
static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
static const WCHAR szTable[] = { 'T','a','b','l','e',0 };