Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
eb0e0df9
Commit
eb0e0df9
authored
Jun 30, 2004
by
Aric Stewart
Committed by
Alexandre Julliard
Jun 30, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Start implementing MsiOpenPackage.
parent
de8674ec
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
631 additions
and
474 deletions
+631
-474
Makefile.in
dlls/msi/Makefile.in
+1
-0
action.c
dlls/msi/action.c
+84
-296
cond.y
dlls/msi/cond.y
+1
-3
msi.c
dlls/msi/msi.c
+4
-175
msipriv.h
dlls/msi/msipriv.h
+1
-0
package.c
dlls/msi/package.c
+540
-0
No files found.
dlls/msi/Makefile.in
View file @
eb0e0df9
...
...
@@ -15,6 +15,7 @@ C_SRCS = \
msi.c
\
msiquery.c
\
order.c
\
package.c
\
record.c
\
regsvr.c
\
select
.c
\
...
...
dlls/msi/action.c
View file @
eb0e0df9
...
...
@@ -47,23 +47,6 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/stand
#define CUSTOM_ACTION_TYPE_MASK 0x3F
/*
* These are hacks to get around the inability to write
* to the database and the inability to select on string values
* once those values are done then it will be possible to do
* all this inside the database.
*/
#define MAX_PROP 1024
typedef
struct
{
WCHAR
*
prop_name
;
WCHAR
*
prop_value
;
}
internal_property
;
static
internal_property
PropTableHack
[
MAX_PROP
];
static
INT
PropCount
=
-
1
;
WINE_DEFAULT_DEBUG_CHANNEL
(
msi
);
/*
...
...
@@ -83,13 +66,6 @@ static UINT HANDLE_CustomType1(MSIHANDLE hPackage, const LPWSTR source,
static
UINT
HANDLE_CustomType2
(
MSIHANDLE
hPackage
,
const
LPWSTR
source
,
const
LPWSTR
target
,
const
INT
type
);
static
UINT
set_property
(
MSIHANDLE
hPackage
,
const
WCHAR
*
prop
,
const
WCHAR
*
value
);
UINT
get_property
(
MSIHANDLE
hPackage
,
const
WCHAR
*
prop
,
WCHAR
*
value
,
DWORD
*
size
);
static
VOID
blitz_propertytable
();
static
VOID
set_installer_properties
(
MSIHANDLE
hPackage
);
static
DWORD
deformat_string
(
MSIHANDLE
hPackage
,
WCHAR
*
ptr
,
WCHAR
**
data
);
/*
...
...
@@ -98,6 +74,7 @@ static DWORD deformat_string(MSIHANDLE hPackage, WCHAR* ptr,WCHAR** data);
static
const
WCHAR
cszSourceDir
[]
=
{
'S'
,
'o'
,
'u'
,
'r'
,
'c'
,
'e'
,
'D'
,
'i'
,
'r'
,
0
};
static
const
WCHAR
cszRootDrive
[]
=
{
'R'
,
'O'
,
'O'
,
'T'
,
'D'
,
'R'
,
'I'
,
'V'
,
'E'
,
0
};
static
const
WCHAR
cszTargetDir
[]
=
{
'T'
,
'A'
,
'R'
,
'G'
,
'E'
,
'T'
,
'D'
,
'I'
,
'R'
,
0
};
static
const
WCHAR
c_collen
[]
=
{
'C'
,
':'
,
'\\'
,
0
};
static
const
WCHAR
cszlsb
[]
=
{
'['
,
0
};
static
const
WCHAR
cszrsb
[]
=
{
']'
,
0
};
...
...
@@ -120,226 +97,6 @@ inline static char *strdupWtoA( const WCHAR *str )
return
ret
;
}
static
VOID
blitz_propertytable
()
{
if
(
PropCount
==
-
1
)
{
PropCount
=
0
;
memset
(
&
PropTableHack
,
0
,
sizeof
(
PropTableHack
));
}
else
if
(
PropCount
>
0
)
{
int
i
;
TRACE
(
"Clearing %i properties
\n
"
,
PropCount
);
for
(
i
=
0
;
i
<
PropCount
;
i
++
)
{
HeapFree
(
GetProcessHeap
(),
0
,
PropTableHack
[
i
].
prop_name
);
HeapFree
(
GetProcessHeap
(),
0
,
PropTableHack
[
i
].
prop_value
);
}
memset
(
&
PropTableHack
,
0
,
sizeof
(
PropTableHack
));
PropCount
=
0
;
}
}
UINT
get_property
(
MSIHANDLE
hPackage
,
const
WCHAR
*
prop
,
WCHAR
*
value
,
DWORD
*
size
)
{
UINT
rc
=
1
;
int
index
=
0
;
WCHAR
*
pName
=
PropTableHack
[
0
].
prop_name
;
TRACE
(
"Looking for property %s
\n
"
,
debugstr_w
(
prop
));
/* prop table hacks take presidence */
while
(
pName
&&
strcmpW
(
pName
,
prop
)
&&
index
<
PropCount
)
{
index
++
;
pName
=
PropTableHack
[
index
].
prop_name
;
}
if
(
pName
&&
index
<
PropCount
)
{
if
(
*
size
>
strlenW
(
PropTableHack
[
index
].
prop_value
))
{
*
size
=
strlenW
(
PropTableHack
[
index
].
prop_value
)
+
1
;
TRACE
(
" index %i
\n
"
,
index
);
strcpyW
(
value
,
PropTableHack
[
index
].
prop_value
);
TRACE
(
" found value %s
\n
"
,
debugstr_w
(
value
));
return
0
;
}
else
{
*
size
=
strlenW
(
PropTableHack
[
index
].
prop_value
);
return
ERROR_MORE_DATA
;
}
}
rc
=
MsiGetPropertyW
(
hPackage
,
prop
,
value
,
size
);
if
(
rc
==
ERROR_SUCCESS
)
TRACE
(
" found value %s
\n
"
,
debugstr_w
(
value
));
else
TRACE
(
" value not found
\n
"
);
return
rc
;
}
static
UINT
set_property
(
MSIHANDLE
hPackage
,
const
WCHAR
*
prop
,
const
WCHAR
*
value
)
{
/* prop table hacks take precedence */
UINT
rc
;
int
index
=
0
;
WCHAR
*
pName
;
if
(
PropCount
==
-
1
)
blitz_propertytable
();
pName
=
PropTableHack
[
0
].
prop_name
;
TRACE
(
"Setting property %s to %s
\n
"
,
debugstr_w
(
prop
),
debugstr_w
(
value
));
while
(
pName
&&
strcmpW
(
pName
,
prop
)
&&
index
<
MAX_PROP
)
{
index
++
;
pName
=
PropTableHack
[
index
].
prop_name
;
}
if
(
pName
&&
index
<
MAX_PROP
)
{
TRACE
(
"property index %i
\n
"
,
index
);
strcpyW
(
PropTableHack
[
index
].
prop_value
,
value
);
return
0
;
}
else
{
if
(
index
>=
MAX_PROP
)
{
ERR
(
"EXCEEDING MAX PROP!!!!
\n
"
);
return
ERROR_FUNCTION_FAILED
;
}
PropTableHack
[
index
].
prop_name
=
HeapAlloc
(
GetProcessHeap
(),
0
,
1024
);
PropTableHack
[
index
].
prop_value
=
HeapAlloc
(
GetProcessHeap
(),
0
,
1024
);
strcpyW
(
PropTableHack
[
index
].
prop_name
,
prop
);
strcpyW
(
PropTableHack
[
index
].
prop_value
,
value
);
PropCount
++
;
TRACE
(
"new property index %i (%i)
\n
"
,
index
,
PropCount
);
return
0
;
}
/* currently unreachable */
rc
=
MsiSetPropertyW
(
hPackage
,
prop
,
value
);
return
rc
;
}
/*
* There are a whole slew of these we need to set
*
*
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
*/
static
VOID
set_installer_properties
(
MSIHANDLE
hPackage
)
{
WCHAR
pth
[
MAX_PATH
];
static
const
WCHAR
c_col
[]
=
{
'C'
,
':'
,
'\\'
,
0
};
static
const
WCHAR
CFF
[]
=
{
'C'
,
'o'
,
'm'
,
'm'
,
'o'
,
'n'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
PFF
[]
=
{
'P'
,
'r'
,
'o'
,
'g'
,
'r'
,
'a'
,
'm'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
CADF
[]
=
{
'C'
,
'o'
,
'm'
,
'm'
,
'o'
,
'n'
,
'A'
,
'p'
,
'p'
,
'D'
,
'a'
,
't'
,
'a'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
ATF
[]
=
{
'A'
,
'd'
,
'm'
,
'i'
,
'n'
,
'T'
,
'o'
,
'o'
,
'l'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
ADF
[]
=
{
'A'
,
'p'
,
'p'
,
'D'
,
'a'
,
't'
,
'a'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
SF
[]
=
{
'S'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
LADF
[]
=
{
'L'
,
'o'
,
'c'
,
'a'
,
'l'
,
'A'
,
'p'
,
'p'
,
'D'
,
'a'
,
't'
,
'a'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
MPF
[]
=
{
'M'
,
'y'
,
'P'
,
'i'
,
'c'
,
't'
,
'u'
,
'r'
,
'e'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
PF
[]
=
{
'P'
,
'e'
,
'r'
,
's'
,
'o'
,
'n'
,
'a'
,
'l'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
WF
[]
=
{
'W'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
TF
[]
=
{
'T'
,
'e'
,
'm'
,
'p'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
/* Not yet set ... but needed by iTunes
*
static const WCHAR DF[] =
{'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
static const WCHAR FF[] =
{'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
static const WCHAR FoF[] =
{'F','o','n','t','s','F','o','l','d','e','r',0};
PrimaryVolumePath
ProgramFiles64Folder
ProgramMenuFolder
SendToFolder
StartMenuFolder
StartupFolder
System16Folder
System64Folder
TemplateFolder
*/
/* asked for by iTunes ... but are they installer set?
*
* GlobalAssemblyCache
*/
set_property
(
hPackage
,
cszRootDrive
,
c_col
);
SHGetFolderPathW
(
NULL
,
CSIDL_PROGRAM_FILES_COMMON
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
CFF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_PROGRAM_FILES
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
PFF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_COMMON_APPDATA
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
CADF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_ADMINTOOLS
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
ATF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_APPDATA
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
ADF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_SYSTEM
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
SF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_LOCAL_APPDATA
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
LADF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_MYPICTURES
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
MPF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_PERSONAL
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
PF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_WINDOWS
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
set_property
(
hPackage
,
WF
,
pth
);
GetTempPathW
(
MAX_PATH
,
pth
);
set_property
(
hPackage
,
TF
,
pth
);
}
/****************************************************
* TOP level entry points
*****************************************************/
...
...
@@ -351,23 +108,17 @@ UINT ACTION_DoTopLevelINSTALL(MSIHANDLE hPackage, LPCWSTR szPackagePath,
UINT
rc
;
static
const
CHAR
*
ExecSeqQuery
=
"select * from InstallExecuteSequence where Sequence > 0 order by Sequence"
;
MSIHANDLE
db
;
FIXME
(
"****We do not do any of the UI level stuff yet***
\n
"
);
/* reset our properties */
blitz_propertytable
();
if
(
szPackagePath
)
{
static
const
WCHAR
OriginalDatabase
[]
=
{
'O'
,
'r'
,
'i'
,
'g'
,
'i'
,
'n'
,
'a'
,
'l'
,
'D'
,
'a'
,
't'
,
'a'
,
'b'
,
'a'
,
's'
,
'e'
,
0
};
LPWSTR
p
;
WCHAR
check
[
MAX_PATH
];
WCHAR
pth
[
MAX_PATH
];
DWORD
size
;
set_property
(
hPackage
,
OriginalDatabase
,
szPackagePath
);
strcpyW
(
pth
,
szPackagePath
);
p
=
strrchrW
(
pth
,
'\\'
);
if
(
p
)
...
...
@@ -377,11 +128,13 @@ UINT ACTION_DoTopLevelINSTALL(MSIHANDLE hPackage, LPCWSTR szPackagePath,
}
size
=
MAX_PATH
;
if
(
get_property
(
hPackage
,
cszSourceDir
,
check
,
&
size
)
!=
ERROR_SUCCESS
)
set_property
(
hPackage
,
cszSourceDir
,
pth
);
if
(
MsiGetPropertyW
(
hPackage
,
cszSourceDir
,
check
,
&
size
)
!=
ERROR_SUCCESS
)
MsiSetPropertyW
(
hPackage
,
cszSourceDir
,
pth
);
}
rc
=
MsiDatabaseOpenViewA
(
hPackage
,
ExecSeqQuery
,
&
view
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewA
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
if
(
rc
==
ERROR_SUCCESS
)
{
...
...
@@ -456,7 +209,6 @@ UINT ACTION_DoTopLevelINSTALL(MSIHANDLE hPackage, LPCWSTR szPackagePath,
}
end:
blitz_propertytable
();
return
rc
;
}
...
...
@@ -588,10 +340,15 @@ static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action)
WCHAR
source
[
0x100
];
WCHAR
target
[
0x200
];
WCHAR
*
deformated
=
NULL
;
MSIHANDLE
db
;
strcatW
(
ExecSeqQuery
,
action
);
strcatW
(
ExecSeqQuery
,
end
);
rc
=
MsiDatabaseOpenViewW
(
hPackage
,
ExecSeqQuery
,
&
view
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewW
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -633,7 +390,7 @@ static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action)
case
35
:
/* Directory set with formatted text. */
case
51
:
/* Property set with formatted text. */
deformat_string
(
hPackage
,
target
,
&
deformated
);
set_property
(
hPackage
,
source
,
deformated
);
MsiSetPropertyW
(
hPackage
,
source
,
deformated
);
HeapFree
(
GetProcessHeap
(),
0
,
deformated
);
break
;
default:
...
...
@@ -654,7 +411,7 @@ static UINT store_binary_to_temp(MSIHANDLE hPackage, const LPWSTR source,
static
const
WCHAR
TF
[]
=
{
'T'
,
'e'
,
'm'
,
'p'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
DWORD
sz
=
MAX_PATH
;
if
(
get_property
(
hPackage
,
TF
,
tmp_file
,
&
sz
)
!=
ERROR_SUCCESS
)
if
(
MsiGetPropertyW
(
hPackage
,
TF
,
tmp_file
,
&
sz
)
!=
ERROR_SUCCESS
)
GetTempPathW
(
MAX_PATH
,
tmp_file
);
strcatW
(
tmp_file
,
source
);
...
...
@@ -676,6 +433,7 @@ static UINT store_binary_to_temp(MSIHANDLE hPackage, const LPWSTR source,
static
const
WCHAR
end
[]
=
{
'`'
,
0
};
HANDLE
the_file
;
CHAR
buffer
[
1024
];
MSIHANDLE
db
;
the_file
=
CreateFileW
(
tmp_file
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
...
...
@@ -685,7 +443,11 @@ static UINT store_binary_to_temp(MSIHANDLE hPackage, const LPWSTR source,
strcatW
(
Query
,
source
);
strcatW
(
Query
,
end
);
rc
=
MsiDatabaseOpenViewW
(
hPackage
,
Query
,
&
view
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewW
(
db
,
Query
,
&
view
);
MsiCloseHandle
(
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -782,7 +544,6 @@ static UINT HANDLE_CustomType2(MSIHANDLE hPackage, const LPWSTR source,
PROCESS_INFORMATION
info
;
BOOL
rc
;
WCHAR
*
deformated
;
static
const
WCHAR
c_collen
[]
=
{
'C'
,
':'
,
'\\'
,
0
};
static
const
WCHAR
spc
[]
=
{
' '
,
0
};
memset
(
&
si
,
0
,
sizeof
(
STARTUPINFOW
));
...
...
@@ -875,8 +636,12 @@ static UINT ACTION_CreateFolders(MSIHANDLE hPackage)
static
const
CHAR
*
ExecSeqQuery
=
"select * from CreateFolder"
;
UINT
rc
;
MSIHANDLE
view
;
MSIHANDLE
db
;
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewA
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
rc
=
MsiDatabaseOpenViewA
(
hPackage
,
ExecSeqQuery
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -913,7 +678,7 @@ static UINT ACTION_CreateFolders(MSIHANDLE hPackage)
}
sz
=
MAX_PATH
;
rc
=
get_property
(
hPackage
,
dir
,
full_path
,
&
sz
);
rc
=
MsiGetPropertyW
(
hPackage
,
dir
,
full_path
,
&
sz
);
if
(
rc
!=
ERROR_SUCCESS
)
{
...
...
@@ -961,9 +726,10 @@ static UINT resolve_directory(MSIHANDLE hPackage, const WCHAR* dir,
MSIHANDLE
row
=
0
;
WCHAR
full_path
[
MAX_PATH
];
WCHAR
name_source
[
0x100
];
MSIHANDLE
db
;
sz
=
MAX_PATH
;
if
(
get_property
(
hPackage
,
dir
,
path
,
&
sz
)
==
ERROR_SUCCESS
)
if
(
MsiGetPropertyW
(
hPackage
,
dir
,
path
,
&
sz
)
==
ERROR_SUCCESS
)
return
ERROR_SUCCESS
;
TRACE
(
"Working to resolve %s
\n
"
,
debugstr_w
(
dir
));
...
...
@@ -974,18 +740,14 @@ static UINT resolve_directory(MSIHANDLE hPackage, const WCHAR* dir,
if
(
!
source
)
{
sz
=
0x100
;
if
(
!
get_property
(
hPackage
,
cszRootDrive
,
buffer
,
&
sz
))
if
(
!
MsiGetPropertyW
(
hPackage
,
cszRootDrive
,
buffer
,
&
sz
))
{
set_property
(
hPackage
,
cszTargetDir
,
buffer
);
MsiSetPropertyW
(
hPackage
,
cszTargetDir
,
buffer
);
strcpyW
(
path
,
buffer
);
}
else
{
ERR
(
"No RootDrive property defined disaster!
\n
"
);
MsiCloseHandle
(
row
);
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
return
ERROR_FUNCTION_FAILED
;
strcpyW
(
path
,
c_collen
);
}
}
else
...
...
@@ -996,7 +758,11 @@ static UINT resolve_directory(MSIHANDLE hPackage, const WCHAR* dir,
strcatW
(
Query
,
dir
);
strcatW
(
Query
,
end
);
rc
=
MsiDatabaseOpenViewW
(
hPackage
,
Query
,
&
view
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewW
(
db
,
Query
,
&
view
);
MsiCloseHandle
(
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -1068,7 +834,7 @@ static UINT resolve_directory(MSIHANDLE hPackage, const WCHAR* dir,
strcatW
(
full_path
,
targetdir
);
strcatW
(
full_path
,
cszbs
);
}
set_property
(
hPackage
,
dir
,
full_path
);
MsiSetPropertyW
(
hPackage
,
dir
,
full_path
);
if
(
!
source
)
strcpyW
(
path
,
full_path
);
...
...
@@ -1087,7 +853,7 @@ static UINT resolve_directory(MSIHANDLE hPackage, const WCHAR* dir,
strcpyW
(
name_source
,
dir
);
strcatW
(
name_source
,
cszsrc
);
set_property
(
hPackage
,
name_source
,
full_path
);
MsiSetPropertyW
(
hPackage
,
name_source
,
full_path
);
if
(
source
)
strcpyW
(
path
,
full_path
);
}
...
...
@@ -1122,15 +888,14 @@ static UINT ACTION_CostFinalize(MSIHANDLE hPackage)
static
const
CHAR
*
ExecSeqQuery
=
"select * from Directory"
;
UINT
rc
;
MSIHANDLE
view
;
/* According to MSDN these properties are set when CostFinalize is run
* or MsiSetInstallLevel is called */
TRACE
(
"Setting installer properties
\n
"
);
set_installer_properties
(
hPackage
);
MSIHANDLE
db
;
TRACE
(
"Building Directory properties
\n
"
);
rc
=
MsiDatabaseOpenViewA
(
hPackage
,
ExecSeqQuery
,
&
view
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewA
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -1184,14 +949,17 @@ static UINT writeout_cabinet_stream(MSIHANDLE hPackage, WCHAR* stream_name,
UINT
size
;
DWORD
write
;
HANDLE
the_file
;
MSIHANDLE
db
;
rc
=
read_raw_stream_data
(
hPackage
,
stream_name
,
&
data
,
&
size
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
read_raw_stream_data
(
db
,
stream_name
,
&
data
,
&
size
);
MsiCloseHandle
(
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
write
=
0x100
;
if
(
get_property
(
hPackage
,
cszSourceDir
,
source
,
&
write
))
if
(
MsiGetPropertyW
(
hPackage
,
cszSourceDir
,
source
,
&
write
))
{
ERR
(
"No Source dir defined
\n
"
);
rc
=
ERROR_FUNCTION_FAILED
;
...
...
@@ -1271,6 +1039,7 @@ static UINT ready_media_for_file(MSIHANDLE hPackage, UINT sequence,
DWORD
sz
=
0x100
;
INT
seq
;
static
INT
last_sequence
=
0
;
MSIHANDLE
db
;
if
(
sequence
<=
last_sequence
)
{
...
...
@@ -1280,7 +1049,10 @@ static UINT ready_media_for_file(MSIHANDLE hPackage, UINT sequence,
sprintf
(
Query
,
ExecSeqQuery
,
sequence
);
rc
=
MsiDatabaseOpenViewA
(
hPackage
,
Query
,
&
view
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewA
(
db
,
Query
,
&
view
);
MsiCloseHandle
(
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -1316,7 +1088,7 @@ static UINT ready_media_for_file(MSIHANDLE hPackage, UINT sequence,
else
{
sz
=
0x100
;
if
(
get_property
(
hPackage
,
cszSourceDir
,
source
,
&
sz
))
if
(
MsiGetPropertyW
(
hPackage
,
cszSourceDir
,
source
,
&
sz
))
{
ERR
(
"No Source dir defined
\n
"
);
rc
=
ERROR_FUNCTION_FAILED
;
...
...
@@ -1358,11 +1130,14 @@ static UINT get_directory_for_component(MSIHANDLE hPackage,
static
const
WCHAR
end
[]
=
{
'`'
,
0
};
WCHAR
dir
[
0x100
];
DWORD
sz
=
0x100
;
MSIHANDLE
db
;
strcatW
(
ExecSeqQuery
,
component
);
strcatW
(
ExecSeqQuery
,
end
);
rc
=
MsiDatabaseOpenViewW
(
hPackage
,
ExecSeqQuery
,
&
view
);
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewW
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -1387,7 +1162,7 @@ static UINT get_directory_for_component(MSIHANDLE hPackage,
sz
=
0x100
;
MsiRecordGetStringW
(
row
,
3
,
dir
,
&
sz
);
sz
=
MAX_PATH
;
rc
=
get_property
(
hPackage
,
dir
,
install_path
,
&
sz
);
rc
=
MsiGetPropertyW
(
hPackage
,
dir
,
install_path
,
&
sz
);
MsiCloseHandle
(
row
);
MsiViewClose
(
view
);
...
...
@@ -1402,6 +1177,7 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
MSIHANDLE
row
=
0
;
static
const
CHAR
*
ExecSeqQuery
=
"select * from File order by Sequence"
;
MSIHANDLE
db
;
/* REALLY what we want to do is go through all the enabled
* features and check all the components of that feature and
...
...
@@ -1410,8 +1186,10 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
* but for sheer gratification I am going to just brute force
* install all the files
*/
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewA
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
rc
=
MsiDatabaseOpenViewA
(
hPackage
,
ExecSeqQuery
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -1497,7 +1275,7 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
}
/* for future use lets keep track of this file and where it went */
set_property
(
hPackage
,
sourcename
,
install_path
);
MsiSetPropertyW
(
hPackage
,
sourcename
,
install_path
);
MsiCloseHandle
(
row
);
}
...
...
@@ -1513,14 +1291,17 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
MSIHANDLE
view
;
MSIHANDLE
row
=
0
;
static
const
CHAR
*
ExecSeqQuery
=
"select * from DuplicateFile"
;
MSIHANDLE
db
;
/*
* Yes we should only do this for componenets that are installed
* but again I need to do that went I track components.
*/
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewA
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
rc
=
MsiDatabaseOpenViewA
(
hPackage
,
ExecSeqQuery
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -1558,7 +1339,7 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
}
sz
=
0x100
;
rc
=
get_property
(
hPackage
,
file_key
,
file_source
,
&
sz
);
rc
=
MsiGetPropertyW
(
hPackage
,
file_key
,
file_source
,
&
sz
);
if
(
rc
!=
ERROR_SUCCESS
)
{
ERR
(
"Original file unknown %s
\n
"
,
debugstr_w
(
file_key
));
...
...
@@ -1586,7 +1367,7 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
sz
=
0x100
;
MsiRecordGetStringW
(
row
,
5
,
destkey
,
&
sz
);
sz
=
0x100
;
rc
=
get_property
(
hPackage
,
destkey
,
dest_path
,
&
sz
);
rc
=
MsiGetPropertyW
(
hPackage
,
destkey
,
dest_path
,
&
sz
);
if
(
rc
!=
ERROR_SUCCESS
)
{
ERR
(
"Unable to get destination folder
\n
"
);
...
...
@@ -1700,12 +1481,15 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
MSIHANDLE
view
;
MSIHANDLE
row
=
0
;
static
const
CHAR
*
ExecSeqQuery
=
"select * from Registry"
;
MSIHANDLE
db
;
/* Again here we want to key off of the components being installed...
* oh well
*/
db
=
MsiGetActiveDatabase
(
hPackage
);
rc
=
MsiDatabaseOpenViewA
(
db
,
ExecSeqQuery
,
&
view
);
MsiCloseHandle
(
db
);
rc
=
MsiDatabaseOpenViewA
(
hPackage
,
ExecSeqQuery
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
...
...
@@ -1851,7 +1635,7 @@ static DWORD deformat_string(MSIHANDLE hPackage, WCHAR* ptr,WCHAR** data)
mark
++
;
TRACE
(
"Current %s .. %s
\n
"
,
debugstr_w
(
*
data
),
debugstr_w
(
mark
));
sz
=
0x100
;
if
(
get_property
(
hPackage
,
key
,
value
,
&
sz
)
==
ERROR_SUCCESS
)
if
(
MsiGetPropertyW
(
hPackage
,
key
,
value
,
&
sz
)
==
ERROR_SUCCESS
)
{
LPWSTR
newdata
;
chunk
=
(
strlenW
(
value
)
+
1
)
*
sizeof
(
WCHAR
);
...
...
@@ -1953,7 +1737,7 @@ UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
szPathBuf
,
DWORD
*
pcchPathBuf
)
{
TRACE
(
"(%s %p %li)
\n
"
,
debugstr_w
(
szFolder
),
szPathBuf
,
*
pcchPathBuf
);
return
get_property
(
hInstall
,
szFolder
,
szPathBuf
,
pcchPathBuf
);
return
MsiGetPropertyW
(
hInstall
,
szFolder
,
szPathBuf
,
pcchPathBuf
);
}
...
...
@@ -2007,11 +1791,11 @@ UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
(
strlenW
(
szFolder
)
+
8
)
*
sizeof
(
WCHAR
));
strcpyW
(
newfolder
,
szFolder
);
strcatW
(
newfolder
,
cszsrc
);
rc
=
get_property
(
hInstall
,
newfolder
,
szPathBuf
,
pcchPathBuf
);
rc
=
MsiGetPropertyW
(
hInstall
,
newfolder
,
szPathBuf
,
pcchPathBuf
);
HeapFree
(
GetProcessHeap
(),
0
,
newfolder
);
}
else
rc
=
get_property
(
hInstall
,
szFolder
,
szPathBuf
,
pcchPathBuf
);
rc
=
MsiGetPropertyW
(
hInstall
,
szFolder
,
szPathBuf
,
pcchPathBuf
);
return
rc
;
}
...
...
@@ -2028,8 +1812,12 @@ static UINT ACTION_Template(MSIHANDLE hPackage)
MSIHANDLE view;
MSIHANDLE row = 0;
static const CHAR *ExecSeqQuery;
MSIHANDLE db;
db = MsiGetActiveDatabase(hPackage);
rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
MsiCloseHandle(db);
rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS)
return rc;
...
...
dlls/msi/cond.y
View file @
eb0e0df9
...
...
@@ -449,11 +449,9 @@ symbol_s:
$$ = HeapAlloc( GetProcessHeap(), 0, 0x100*sizeof (WCHAR) );
/* Lookup the identifier */
/* This will not really work until we have write access to the table*/
/* HACK ALERT HACK ALERT... */
sz=0x100;
if (
get_property
(cond->hInstall,$1,$$,&sz) != ERROR_SUCCESS)
if (
MsiGetPropertyW
(cond->hInstall,$1,$$,&sz) != ERROR_SUCCESS)
{
$$[0]=0;
}
...
...
dlls/msi/msi.c
View file @
eb0e0df9
...
...
@@ -375,32 +375,6 @@ end:
return
r
;
}
UINT
WINAPI
MsiOpenPackageA
(
LPCSTR
szPackage
,
MSIHANDLE
*
phPackage
)
{
FIXME
(
"%s %p
\n
"
,
debugstr_a
(
szPackage
),
phPackage
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
UINT
WINAPI
MsiOpenPackageW
(
LPCWSTR
szPackage
,
MSIHANDLE
*
phPackage
)
{
UINT
rc
;
FIXME
(
"%s %p
\n
"
,
debugstr_w
(
szPackage
),
phPackage
);
rc
=
MsiOpenDatabaseW
(
szPackage
,
MSIDBOPEN_READONLY
,
phPackage
);
return
rc
;
}
UINT
WINAPI
MsiOpenPackageExA
(
LPCSTR
szPackage
,
DWORD
dwOptions
,
MSIHANDLE
*
phPackage
)
{
FIXME
(
"%s 0x%08lx %p
\n
"
,
debugstr_a
(
szPackage
),
dwOptions
,
phPackage
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
UINT
WINAPI
MsiOpenPackageExW
(
LPCWSTR
szPackage
,
DWORD
dwOptions
,
MSIHANDLE
*
phPackage
)
{
FIXME
(
"%s 0x%08lx %p
\n
"
,
debugstr_w
(
szPackage
),
dwOptions
,
phPackage
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
UINT
WINAPI
MsiAdvertiseProductA
(
LPCSTR
szPackagePath
,
LPCSTR
szScriptfilePath
,
LPCSTR
szTransforms
,
LANGID
lgidLanguage
)
{
FIXME
(
"%s %s %s 0x%08x
\n
"
,
debugstr_a
(
szPackagePath
),
debugstr_a
(
szScriptfilePath
),
debugstr_a
(
szTransforms
),
lgidLanguage
);
...
...
@@ -466,7 +440,7 @@ end:
UINT
WINAPI
MsiInstallProductW
(
LPCWSTR
szPackagePath
,
LPCWSTR
szCommandLine
)
{
MSIHANDLE
db
handle
;
MSIHANDLE
package
handle
;
UINT
rc
=
ERROR_SUCCESS
;
FIXME
(
"%s %s
\n
"
,
debugstr_w
(
szPackagePath
),
debugstr_w
(
szCommandLine
));
...
...
@@ -475,13 +449,13 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
rc
=
MsiOpen
DatabaseW
(
szPackagePath
,
MSIDBOPEN_READONLY
,
&
db
handle
);
rc
=
MsiOpen
PackageW
(
szPackagePath
,
&
package
handle
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
ACTION_DoTopLevelINSTALL
(
db
handle
,
szPackagePath
,
szCommandLine
);
ACTION_DoTopLevelINSTALL
(
package
handle
,
szPackagePath
,
szCommandLine
);
MsiCloseHandle
(
db
handle
);
MsiCloseHandle
(
package
handle
);
return
rc
;
}
...
...
@@ -1224,151 +1198,6 @@ BOOL WINAPI MSI_DllCanUnloadNow(void)
return
S_FALSE
;
}
/* property code */
UINT
WINAPI
MsiSetPropertyA
(
MSIHANDLE
hInstall
,
LPCSTR
szName
,
LPCSTR
szValue
)
{
FIXME
(
"STUB until write access is done: (%s %s)
\n
"
,
szName
,
szValue
);
if
(
!
hInstall
)
return
ERROR_INVALID_HANDLE
;
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiSetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
LPCWSTR
szValue
)
{
FIXME
(
"STUB until write access is done: (%s %s)
\n
"
,
debugstr_w
(
szName
),
debugstr_w
(
szValue
));
if
(
!
hInstall
)
return
ERROR_INVALID_HANDLE
;
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiGetPropertyA
(
MSIHANDLE
hInstall
,
LPCSTR
szName
,
LPSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
{
LPWSTR
szwName
=
NULL
,
szwValueBuf
=
NULL
;
UINT
hr
=
ERROR_INSTALL_FAILURE
;
if
(
0
==
hInstall
)
{
return
ERROR_INVALID_HANDLE
;
}
if
(
NULL
==
szName
)
{
return
ERROR_INVALID_PARAMETER
;
}
FIXME
(
"%lu %s %lu
\n
"
,
hInstall
,
debugstr_a
(
szName
),
*
pchValueBuf
);
if
(
NULL
!=
szValueBuf
&&
NULL
==
pchValueBuf
)
{
return
ERROR_INVALID_PARAMETER
;
}
if
(
szName
)
{
UINT
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
);
}
else
{
return
ERROR_INVALID_PARAMETER
;
}
if
(
szValueBuf
)
{
szwValueBuf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
*
pchValueBuf
)
*
sizeof
(
WCHAR
)
);
if
(
!
szwValueBuf
)
goto
end
;
}
hr
=
MsiGetPropertyW
(
hInstall
,
szwName
,
szwValueBuf
,
pchValueBuf
);
if
(
ERROR_SUCCESS
==
hr
)
{
WideCharToMultiByte
(
CP_ACP
,
0
,
szwValueBuf
,
-
1
,
szValueBuf
,
*
pchValueBuf
,
NULL
,
NULL
);
}
end:
if
(
szwName
)
HeapFree
(
GetProcessHeap
(),
0
,
szwName
);
if
(
szwValueBuf
)
HeapFree
(
GetProcessHeap
(),
0
,
szwValueBuf
);
return
hr
;
}
UINT
WINAPI
MsiGetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
LPWSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
{
MSIHANDLE
view
,
row
;
UINT
rc
;
WCHAR
Query
[
1024
]
=
{
's'
,
'e'
,
'l'
,
'e'
,
'c'
,
't'
,
' '
,
'*'
,
' '
,
'f'
,
'r'
,
'o'
,
'm'
,
' '
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
' '
,
'w'
,
'h'
,
'e'
,
'r'
,
'e'
,
' '
,
'`'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
'='
,
'`'
,
0
};
static
const
WCHAR
szEnd
[]
=
{
'`'
,
0
};
if
(
0
==
hInstall
)
{
return
ERROR_INVALID_HANDLE
;
}
if
(
NULL
==
szName
)
{
return
ERROR_INVALID_PARAMETER
;
}
strcatW
(
Query
,
szName
);
strcatW
(
Query
,
szEnd
);
rc
=
MsiDatabaseOpenViewW
(
hInstall
,
Query
,
&
view
);
if
(
rc
==
ERROR_SUCCESS
)
{
DWORD
sz
;
WCHAR
value
[
0x100
];
rc
=
MsiViewExecute
(
view
,
0
);
if
(
rc
!=
ERROR_SUCCESS
)
{
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
return
rc
;
}
rc
=
MsiViewFetch
(
view
,
&
row
);
if
(
rc
==
ERROR_SUCCESS
)
{
sz
=
0x100
;
rc
=
MsiRecordGetStringW
(
row
,
2
,
value
,
&
sz
);
strncpyW
(
szValueBuf
,
value
,
min
(
sz
+
1
,
*
pchValueBuf
));
*
pchValueBuf
=
sz
+
1
;
MsiCloseHandle
(
row
);
}
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
}
if
(
rc
==
ERROR_SUCCESS
)
TRACE
(
"returning %s for property %s
\n
"
,
debugstr_w
(
szValueBuf
),
debugstr_w
(
szName
));
return
rc
;
}
INT
WINAPI
MsiProcessMessage
(
MSIHANDLE
hInstall
,
INSTALLMESSAGE
eMessageType
,
MSIHANDLE
hRecord
)
{
FIXME
(
"STUB:
\n
"
);
return
ERROR_SUCCESS
;
}
MSIHANDLE
WINAPI
MsiGetActiveDatabase
(
MSIHANDLE
hInstall
)
{
FIXME
(
"Is this correct?
\n
"
);
msihandle_addref
(
hInstall
);
return
hInstall
;
}
UINT
WINAPI
MsiEnumRelatedProductsA
(
LPCSTR
lpUpgradeCode
,
DWORD
dwReserved
,
DWORD
iProductIndex
,
LPSTR
lpProductBuf
)
{
...
...
dlls/msi/msipriv.h
View file @
eb0e0df9
...
...
@@ -145,6 +145,7 @@ typedef struct tagMSIHANDLEINFO
#define MSIHANDLETYPE_SUMMARYINFO 2
#define MSIHANDLETYPE_VIEW 3
#define MSIHANDLETYPE_RECORD 4
#define MSIHANDLETYPE_PACKAGE 5
#define MSI_MAJORVERSION 1
#define MSI_MINORVERSION 10
...
...
dlls/msi/package.c
0 → 100644
View file @
eb0e0df9
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2004 Aric Stewart 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
*/
#define NONAMELESSUNION
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#include "objidl.h"
#include "wincrypt.h"
#include "winuser.h"
#include "shlobj.h"
#include "wine/unicode.h"
#include "objbase.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
void
MSI_FreePackage
(
VOID
*
arg
);
typedef
struct
tagMSIPACKAGE
{
MSIHANDLE
db
;
}
MSIPACKAGE
;
void
MSI_FreePackage
(
VOID
*
arg
)
{
MSIPACKAGE
*
package
=
arg
;
MsiCloseHandle
(
package
->
db
);
}
UINT
WINAPI
MsiOpenPackageA
(
LPCSTR
szPackage
,
MSIHANDLE
*
phPackage
)
{
LPWSTR
szwPack
=
NULL
;
UINT
len
,
ret
;
TRACE
(
"%s %p
\n
"
,
debugstr_a
(
szPackage
),
phPackage
);
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
);
}
ret
=
MsiOpenPackageW
(
szwPack
,
phPackage
);
if
(
szwPack
)
HeapFree
(
GetProcessHeap
(),
0
,
szwPack
);
return
ret
;
}
static
const
void
clone_properties
(
MSIHANDLE
db
)
{
MSIHANDLE
view
;
UINT
rc
;
static
const
CHAR
CreateSql
[]
=
"CREATE TABLE `_Property` ( `_Property` "
"CHAR(56) NOT NULL, `Value` CHAR(98) NOT NULL PRIMARY KEY `_Property`)"
;
static
const
CHAR
Query
[]
=
"SELECT * from Property"
;
static
const
CHAR
Insert
[]
=
"INSERT into `_Property` (`_Property`,`Value`) VALUES (?)"
;
/* create the temporary properties table */
MsiDatabaseOpenViewA
(
db
,
CreateSql
,
&
view
);
MsiViewExecute
(
view
,
0
);
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
/* clone the existing properties */
MsiDatabaseOpenViewA
(
db
,
Query
,
&
view
);
MsiViewExecute
(
view
,
0
);
while
(
1
)
{
MSIHANDLE
row
;
MSIHANDLE
view2
;
rc
=
MsiViewFetch
(
view
,
&
row
);
if
(
rc
!=
ERROR_SUCCESS
)
break
;
MsiDatabaseOpenViewA
(
db
,
Insert
,
&
view2
);
MsiViewExecute
(
view2
,
row
);
MsiViewClose
(
view2
);
MsiCloseHandle
(
view2
);
MsiCloseHandle
(
row
);
}
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
}
/*
* There are a whole slew of these we need to set
*
*
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
*/
static
VOID
set_installer_properties
(
MSIHANDLE
hPackage
)
{
WCHAR
pth
[
MAX_PATH
];
static
const
WCHAR
cszbs
[]
=
{
'\\'
,
0
};
static
const
WCHAR
CFF
[]
=
{
'C'
,
'o'
,
'm'
,
'm'
,
'o'
,
'n'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
PFF
[]
=
{
'P'
,
'r'
,
'o'
,
'g'
,
'r'
,
'a'
,
'm'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
CADF
[]
=
{
'C'
,
'o'
,
'm'
,
'm'
,
'o'
,
'n'
,
'A'
,
'p'
,
'p'
,
'D'
,
'a'
,
't'
,
'a'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
ATF
[]
=
{
'A'
,
'd'
,
'm'
,
'i'
,
'n'
,
'T'
,
'o'
,
'o'
,
'l'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
ADF
[]
=
{
'A'
,
'p'
,
'p'
,
'D'
,
'a'
,
't'
,
'a'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
SF
[]
=
{
'S'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
LADF
[]
=
{
'L'
,
'o'
,
'c'
,
'a'
,
'l'
,
'A'
,
'p'
,
'p'
,
'D'
,
'a'
,
't'
,
'a'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
MPF
[]
=
{
'M'
,
'y'
,
'P'
,
'i'
,
'c'
,
't'
,
'u'
,
'r'
,
'e'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
PF
[]
=
{
'P'
,
'e'
,
'r'
,
's'
,
'o'
,
'n'
,
'a'
,
'l'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
WF
[]
=
{
'W'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
TF
[]
=
{
'T'
,
'e'
,
'm'
,
'p'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
/* Not yet set ... but needed by iTunes
*
DesktopFolder
FavoritesFolder
FontsFolder
PrimaryVolumePath
ProgramFiles64Folder
ProgramMenuFolder
SendToFolder
StartMenuFolder
StartupFolder
System16Folder
System64Folder
TemplateFolder
*/
/* asked for by iTunes ... but are they installer set?
*
* GlobalAssemblyCache
*/
/*
* Other things i notice set
*
ScreenY
ScreenX
SystemLanguageID
ComputerName
UserLanguageID
LogonUser
VirtualMemory
PhysicalMemory
Intel
ShellAdvSupport
ServicePackLevel
WindowsBuild
Version9x
Version95
VersionNT
AdminUser
DefaultUIFont
VersionMsi
VersionDatabase
PackagecodeChanging
ProductState
CaptionHeight
BorderTop
BorderSide
TextHeight
ColorBits
RedirectedDllSupport
Time
Date
Privilaged
DATABASE
OriginalDatabase
UILevel
*/
SHGetFolderPathW
(
NULL
,
CSIDL_PROGRAM_FILES_COMMON
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
CFF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_PROGRAM_FILES
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
PFF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_COMMON_APPDATA
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
CADF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_ADMINTOOLS
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
ATF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_APPDATA
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
ADF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_SYSTEM
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
SF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_LOCAL_APPDATA
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
LADF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_MYPICTURES
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
MPF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_PERSONAL
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
PF
,
pth
);
SHGetFolderPathW
(
NULL
,
CSIDL_WINDOWS
,
NULL
,
0
,
pth
);
strcatW
(
pth
,
cszbs
);
MsiSetPropertyW
(
hPackage
,
WF
,
pth
);
GetTempPathW
(
MAX_PATH
,
pth
);
MsiSetPropertyW
(
hPackage
,
TF
,
pth
);
}
UINT
WINAPI
MsiOpenPackageW
(
LPCWSTR
szPackage
,
MSIHANDLE
*
phPackage
)
{
UINT
rc
;
MSIHANDLE
handle
;
MSIHANDLE
db
;
MSIPACKAGE
*
package
;
static
const
WCHAR
OriginalDatabase
[]
=
{
'O'
,
'r'
,
'i'
,
'g'
,
'i'
,
'n'
,
'a'
,
'l'
,
'D'
,
'a'
,
't'
,
'a'
,
'b'
,
'a'
,
's'
,
'e'
,
0
};
static
const
WCHAR
Database
[]
=
{
'D'
,
'A'
,
'T'
,
'A'
,
'B'
,
'A'
,
'S'
,
'E'
,
0
};
TRACE
(
"%s %p
\n
"
,
debugstr_w
(
szPackage
),
phPackage
);
rc
=
MsiOpenDatabaseW
(
szPackage
,
MSIDBOPEN_READONLY
,
&
db
);
if
(
rc
!=
ERROR_SUCCESS
)
return
ERROR_FUNCTION_FAILED
;
handle
=
alloc_msihandle
(
MSIHANDLETYPE_PACKAGE
,
sizeof
(
MSIPACKAGE
),
MSI_FreePackage
,
(
void
**
)
&
package
);
if
(
!
handle
)
{
MsiCloseHandle
(
db
);
return
ERROR_FUNCTION_FAILED
;
}
package
->
db
=
db
;
/* ok here is where we do a slew of things to the database to
* prep for all that is to come as a package */
clone_properties
(
db
);
set_installer_properties
(
handle
);
MsiSetPropertyW
(
handle
,
OriginalDatabase
,
szPackage
);
MsiSetPropertyW
(
handle
,
Database
,
szPackage
);
*
phPackage
=
handle
;
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiOpenPackageExA
(
LPCSTR
szPackage
,
DWORD
dwOptions
,
MSIHANDLE
*
phPackage
)
{
FIXME
(
"%s 0x%08lx %p
\n
"
,
debugstr_a
(
szPackage
),
dwOptions
,
phPackage
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
UINT
WINAPI
MsiOpenPackageExW
(
LPCWSTR
szPackage
,
DWORD
dwOptions
,
MSIHANDLE
*
phPackage
)
{
FIXME
(
"%s 0x%08lx %p
\n
"
,
debugstr_w
(
szPackage
),
dwOptions
,
phPackage
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
MSIHANDLE
WINAPI
MsiGetActiveDatabase
(
MSIHANDLE
hInstall
)
{
MSIPACKAGE
*
package
;
TRACE
(
"(%i)
\n
"
,(
INT
)
hInstall
);
package
=
msihandle2msiinfo
(
hInstall
,
MSIHANDLETYPE_PACKAGE
);
if
(
!
package
)
return
ERROR_INVALID_HANDLE
;
msihandle_addref
(
package
->
db
);
return
package
->
db
;
}
INT
WINAPI
MsiProcessMessage
(
MSIHANDLE
hInstall
,
INSTALLMESSAGE
eMessageType
,
MSIHANDLE
hRecord
)
{
FIXME
(
"STUB:
\n
"
);
return
ERROR_SUCCESS
;
}
/* property code */
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
;
}
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
);
hr
=
MsiSetPropertyW
(
hInstall
,
szwName
,
szwValue
);
end:
if
(
szwName
)
HeapFree
(
GetProcessHeap
(),
0
,
szwName
);
if
(
szwValue
)
HeapFree
(
GetProcessHeap
(),
0
,
szwValue
);
return
hr
;
}
UINT
WINAPI
MsiSetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
LPCWSTR
szValue
)
{
MSIPACKAGE
*
package
;
MSIHANDLE
view
,
row
;
UINT
rc
;
DWORD
sz
=
0
;
static
const
CHAR
Insert
[]
=
"INSERT into `_Property` (`_Property`,`Value`) VALUES (?)"
;
TRACE
(
"Setting property (%s %s)
\n
"
,
debugstr_w
(
szName
),
debugstr_w
(
szValue
));
if
(
!
hInstall
)
return
ERROR_INVALID_HANDLE
;
if
(
MsiGetPropertyW
(
hInstall
,
szName
,
0
,
&
sz
)
==
ERROR_MORE_DATA
)
{
FIXME
(
"Cannot set exising properties! FIXME MIKE!
\n
"
);
return
ERROR_FUNCTION_FAILED
;
}
package
=
msihandle2msiinfo
(
hInstall
,
MSIHANDLETYPE_PACKAGE
);
if
(
!
package
)
return
ERROR_INVALID_HANDLE
;
rc
=
MsiDatabaseOpenViewA
(
package
->
db
,
Insert
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
row
=
MsiCreateRecord
(
2
);
MsiRecordSetStringW
(
row
,
1
,
szName
);
MsiRecordSetStringW
(
row
,
2
,
szValue
);
rc
=
MsiViewExecute
(
view
,
row
);
MsiCloseHandle
(
row
);
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
return
rc
;
}
UINT
WINAPI
MsiGetPropertyA
(
MSIHANDLE
hInstall
,
LPCSTR
szName
,
LPSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
{
LPWSTR
szwName
=
NULL
,
szwValueBuf
=
NULL
;
UINT
hr
=
ERROR_INSTALL_FAILURE
;
if
(
0
==
hInstall
)
{
return
ERROR_INVALID_HANDLE
;
}
if
(
NULL
==
szName
)
{
return
ERROR_INVALID_PARAMETER
;
}
TRACE
(
"%lu %s %lu
\n
"
,
hInstall
,
debugstr_a
(
szName
),
*
pchValueBuf
);
if
(
NULL
!=
szValueBuf
&&
NULL
==
pchValueBuf
)
{
return
ERROR_INVALID_PARAMETER
;
}
if
(
szName
)
{
UINT
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
);
}
else
{
return
ERROR_INVALID_PARAMETER
;
}
if
(
szValueBuf
)
{
szwValueBuf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
*
pchValueBuf
)
*
sizeof
(
WCHAR
)
);
if
(
!
szwValueBuf
)
goto
end
;
}
hr
=
MsiGetPropertyW
(
hInstall
,
szwName
,
szwValueBuf
,
pchValueBuf
);
if
(
*
pchValueBuf
>
0
)
{
WideCharToMultiByte
(
CP_ACP
,
0
,
szwValueBuf
,
-
1
,
szValueBuf
,
*
pchValueBuf
,
NULL
,
NULL
);
}
end:
if
(
szwName
)
HeapFree
(
GetProcessHeap
(),
0
,
szwName
);
if
(
szwValueBuf
)
HeapFree
(
GetProcessHeap
(),
0
,
szwValueBuf
);
return
hr
;
}
UINT
WINAPI
MsiGetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
LPWSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
{
MSIHANDLE
view
,
row
;
UINT
rc
;
WCHAR
Query
[
1024
]
=
{
's'
,
'e'
,
'l'
,
'e'
,
'c'
,
't'
,
' '
,
'V'
,
'a'
,
'l'
,
'u'
,
'e'
,
' '
,
'f'
,
'r'
,
'o'
,
'm'
,
' '
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
' '
,
'w'
,
'h'
,
'e'
,
'r'
,
'e'
,
' '
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'='
,
'`'
,
0
};
static
const
WCHAR
szEnd
[]
=
{
'`'
,
0
};
MSIPACKAGE
*
package
;
if
(
0
==
hInstall
)
{
return
ERROR_INVALID_HANDLE
;
}
if
(
NULL
==
szName
)
{
return
ERROR_INVALID_PARAMETER
;
}
package
=
msihandle2msiinfo
(
hInstall
,
MSIHANDLETYPE_PACKAGE
);
if
(
!
package
)
return
ERROR_INVALID_HANDLE
;
strcatW
(
Query
,
szName
);
strcatW
(
Query
,
szEnd
);
rc
=
MsiDatabaseOpenViewW
(
package
->
db
,
Query
,
&
view
);
if
(
rc
==
ERROR_SUCCESS
)
{
DWORD
sz
;
WCHAR
value
[
0x100
];
rc
=
MsiViewExecute
(
view
,
0
);
if
(
rc
!=
ERROR_SUCCESS
)
{
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
return
rc
;
}
rc
=
MsiViewFetch
(
view
,
&
row
);
if
(
rc
==
ERROR_SUCCESS
)
{
sz
=
0x100
;
rc
=
MsiRecordGetStringW
(
row
,
1
,
value
,
&
sz
);
strncpyW
(
szValueBuf
,
value
,
min
(
sz
+
1
,
*
pchValueBuf
));
*
pchValueBuf
=
sz
+
1
;
MsiCloseHandle
(
row
);
}
MsiViewClose
(
view
);
MsiCloseHandle
(
view
);
}
if
(
rc
==
ERROR_SUCCESS
)
TRACE
(
"returning %s for property %s
\n
"
,
debugstr_w
(
szValueBuf
),
debugstr_w
(
szName
));
else
{
*
pchValueBuf
=
0
;
TRACE
(
"property not found
\n
"
);
}
return
rc
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment