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
bfe07d1d
Commit
bfe07d1d
authored
Apr 30, 2008
by
James Hawkins
Committed by
Alexandre Julliard
Apr 30, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Add initial implementation of MsiPublishAssemblies.
parent
e487b1e2
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
325 additions
and
41 deletions
+325
-41
action.c
dlls/msi/action.c
+155
-7
files.c
dlls/msi/files.c
+24
-34
helpers.c
dlls/msi/helpers.c
+121
-0
msipriv.h
dlls/msi/msipriv.h
+19
-0
msidefs.h
include/msidefs.h
+6
-0
No files found.
dlls/msi/action.c
View file @
bfe07d1d
...
...
@@ -33,6 +33,10 @@
#include "msipriv.h"
#include "winuser.h"
#include "shlobj.h"
#include "objbase.h"
#include "mscoree.h"
#include "fusion.h"
#include "shlwapi.h"
#include "wine/unicode.h"
#include "winver.h"
...
...
@@ -1246,6 +1250,9 @@ static MSIFEATURE *find_feature_by_name( MSIPACKAGE *package, LPCWSTR name )
{
MSIFEATURE
*
feature
;
if
(
!
name
)
return
NULL
;
LIST_FOR_EACH_ENTRY
(
feature
,
&
package
->
features
,
MSIFEATURE
,
entry
)
{
if
(
!
lstrcmpW
(
feature
->
Feature
,
name
)
)
...
...
@@ -5542,6 +5549,154 @@ static UINT ACTION_MoveFiles( MSIPACKAGE *package )
return
rc
;
}
static
HRESULT
(
WINAPI
*
pCreateAssemblyCache
)(
IAssemblyCache
**
ppAsmCache
,
DWORD
dwReserved
);
static
HRESULT
(
WINAPI
*
pLoadLibraryShim
)(
LPCWSTR
szDllName
,
LPCWSTR
szVersion
,
LPVOID
pvReserved
,
HMODULE
*
phModDll
);
static
BOOL
init_functionpointers
(
void
)
{
HRESULT
hr
;
HMODULE
hfusion
;
HMODULE
hmscoree
;
static
const
WCHAR
szFusion
[]
=
{
'f'
,
'u'
,
's'
,
'i'
,
'o'
,
'n'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
};
hmscoree
=
LoadLibraryA
(
"mscoree.dll"
);
if
(
!
hmscoree
)
{
WARN
(
"mscoree.dll not available
\n
"
);
return
FALSE
;
}
pLoadLibraryShim
=
(
void
*
)
GetProcAddress
(
hmscoree
,
"LoadLibraryShim"
);
if
(
!
pLoadLibraryShim
)
{
WARN
(
"LoadLibraryShim not available
\n
"
);
FreeLibrary
(
hmscoree
);
return
FALSE
;
}
hr
=
pLoadLibraryShim
(
szFusion
,
NULL
,
NULL
,
&
hfusion
);
if
(
FAILED
(
hr
))
{
WARN
(
"fusion.dll not available
\n
"
);
FreeLibrary
(
hmscoree
);
return
FALSE
;
}
pCreateAssemblyCache
=
(
void
*
)
GetProcAddress
(
hfusion
,
"CreateAssemblyCache"
);
FreeLibrary
(
hmscoree
);
return
TRUE
;
}
static
UINT
install_assembly
(
LPWSTR
path
)
{
IAssemblyCache
*
cache
;
HRESULT
hr
;
UINT
r
=
ERROR_FUNCTION_FAILED
;
if
(
!
init_functionpointers
()
||
!
pCreateAssemblyCache
)
return
ERROR_FUNCTION_FAILED
;
hr
=
pCreateAssemblyCache
(
&
cache
,
0
);
if
(
FAILED
(
hr
))
goto
done
;
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
path
,
NULL
);
if
(
FAILED
(
hr
))
ERR
(
"Failed to install assembly: %s %08x
\n
"
,
debugstr_w
(
path
),
hr
);
r
=
ERROR_SUCCESS
;
done:
IAssemblyCache_Release
(
cache
);
return
r
;
}
static
UINT
ITERATE_PublishAssembly
(
MSIRECORD
*
rec
,
LPVOID
param
)
{
MSIPACKAGE
*
package
=
param
;
MSICOMPONENT
*
comp
;
MSIFEATURE
*
feature
;
MSIFILE
*
file
;
WCHAR
path
[
MAX_PATH
];
LPCWSTR
app
;
DWORD
attr
;
UINT
r
;
comp
=
get_loaded_component
(
package
,
MSI_RecordGetString
(
rec
,
1
));
if
(
!
comp
||
!
comp
->
Enabled
||
!
(
comp
->
Action
&
(
INSTALLSTATE_LOCAL
|
INSTALLSTATE_SOURCE
)))
{
ERR
(
"Component not set for install, not publishing assembly
\n
"
);
return
ERROR_SUCCESS
;
}
feature
=
find_feature_by_name
(
package
,
MSI_RecordGetString
(
rec
,
2
));
if
(
feature
)
msi_feature_set_state
(
feature
,
INSTALLSTATE_LOCAL
);
if
(
MSI_RecordGetString
(
rec
,
3
))
FIXME
(
"Manifest unhandled
\n
"
);
app
=
MSI_RecordGetString
(
rec
,
4
);
if
(
app
)
{
FIXME
(
"Assembly should be privately installed
\n
"
);
return
ERROR_SUCCESS
;
}
attr
=
MSI_RecordGetInteger
(
rec
,
5
);
if
(
attr
==
msidbAssemblyAttributesWin32
)
{
FIXME
(
"Win32 assemblies not handled
\n
"
);
return
ERROR_SUCCESS
;
}
/* FIXME: extract all files belonging to this component */
file
=
msi_find_file
(
package
,
comp
->
KeyPath
);
GetTempPathW
(
MAX_PATH
,
path
);
r
=
msi_extract_file
(
package
,
file
,
path
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"Failed to extract temporary assembly
\n
"
);
return
r
;
}
PathAddBackslashW
(
path
);
lstrcatW
(
path
,
file
->
FileName
);
r
=
install_assembly
(
path
);
if
(
r
!=
ERROR_SUCCESS
)
ERR
(
"Failed to install assembly
\n
"
);
/* FIXME: write Installer assembly reg values */
return
r
;
}
static
UINT
ACTION_MsiPublishAssemblies
(
MSIPACKAGE
*
package
)
{
UINT
rc
;
MSIQUERY
*
view
;
static
const
WCHAR
ExecSeqQuery
[]
=
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'`'
,
'M'
,
's'
,
'i'
,
'A'
,
's'
,
's'
,
'e'
,
'm'
,
'b'
,
'l'
,
'y'
,
'`'
,
0
};
rc
=
MSI_DatabaseOpenViewW
(
package
->
db
,
ExecSeqQuery
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
ERROR_SUCCESS
;
rc
=
MSI_IterateRecords
(
view
,
NULL
,
ITERATE_PublishAssembly
,
package
);
msiobj_release
(
&
view
->
hdr
);
return
rc
;
}
static
UINT
msi_unimplemented_action_stub
(
MSIPACKAGE
*
package
,
LPCSTR
action
,
LPCWSTR
table
)
{
...
...
@@ -5630,13 +5785,6 @@ static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
return
msi_unimplemented_action_stub
(
package
,
"RemoveEnvironmentStrings"
,
table
);
}
static
UINT
ACTION_MsiPublishAssemblies
(
MSIPACKAGE
*
package
)
{
static
const
WCHAR
table
[]
=
{
'M'
,
's'
,
'i'
,
'A'
,
's'
,
's'
,
'e'
,
'm'
,
'b'
,
'l'
,
'y'
,
0
};
return
msi_unimplemented_action_stub
(
package
,
"MsiPublishAssemblies"
,
table
);
}
static
UINT
ACTION_MsiUnpublishAssemblies
(
MSIPACKAGE
*
package
)
{
static
const
WCHAR
table
[]
=
{
...
...
dlls/msi/files.c
View file @
bfe07d1d
...
...
@@ -57,20 +57,7 @@ extern const WCHAR szRemoveFiles[];
static
const
WCHAR
cszTempFolder
[]
=
{
'T'
,
'e'
,
'm'
,
'p'
,
'F'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
0
};
struct
media_info
{
UINT
disk_id
;
UINT
type
;
UINT
last_sequence
;
LPWSTR
disk_prompt
;
LPWSTR
cabinet
;
LPWSTR
first_volume
;
LPWSTR
volume_label
;
BOOL
is_continuous
;
BOOL
is_extracted
;
WCHAR
source
[
MAX_PATH
];
};
static
BOOL
source_matches_volume
(
struct
media_info
*
mi
,
LPWSTR
source_root
)
static
BOOL
source_matches_volume
(
MSIMEDIAINFO
*
mi
,
LPWSTR
source_root
)
{
WCHAR
volume_name
[
MAX_PATH
+
1
];
...
...
@@ -84,7 +71,7 @@ static BOOL source_matches_volume(struct media_info *mi, LPWSTR source_root)
return
!
lstrcmpW
(
mi
->
volume_label
,
volume_name
);
}
static
UINT
msi_change_media
(
MSIPACKAGE
*
package
,
struct
media_info
*
mi
)
static
UINT
msi_change_media
(
MSIPACKAGE
*
package
,
MSIMEDIAINFO
*
mi
)
{
LPSTR
msg
;
LPWSTR
error
,
error_dialog
;
...
...
@@ -169,7 +156,7 @@ end:
typedef
struct
{
MSIPACKAGE
*
package
;
struct
media_info
*
mi
;
MSIMEDIAINFO
*
mi
;
}
CabData
;
static
void
*
cabinet_alloc
(
ULONG
cb
)
...
...
@@ -265,7 +252,7 @@ static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *ac
ui_progress
(
package
,
2
,
f
->
FileSize
,
0
,
0
);
}
static
UINT
msi_media_get_disk_info
(
MSIPACKAGE
*
package
,
struct
media_info
*
mi
)
static
UINT
msi_media_get_disk_info
(
MSIPACKAGE
*
package
,
MSIMEDIAINFO
*
mi
)
{
MSIRECORD
*
row
;
LPWSTR
ptr
;
...
...
@@ -311,7 +298,7 @@ static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
case
fdintNEXT_CABINET
:
{
CabData
*
data
=
(
CabData
*
)
pfdin
->
pv
;
struct
media_info
*
mi
=
data
->
mi
;
MSIMEDIAINFO
*
mi
=
data
->
mi
;
LPWSTR
cab
=
strdupAtoW
(
pfdin
->
psz1
);
UINT
rc
;
...
...
@@ -423,18 +410,18 @@ static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
}
/***********************************************************************
*
extract_cabinet_file
*
msi_cabextract
*
* Extract files from a cab file.
*/
static
BOOL
extract_cabinet_file
(
MSIPACKAGE
*
package
,
struct
media_info
*
mi
)
BOOL
msi_cabextract
(
MSIPACKAGE
*
package
,
MSIMEDIAINFO
*
mi
,
PFNFDINOTIFY
notify
,
LPVOID
data
)
{
LPSTR
cabinet
,
cab_path
=
NULL
;
LPWSTR
ptr
;
HFDI
hfdi
;
ERF
erf
;
BOOL
ret
=
FALSE
;
CabData
data
;
TRACE
(
"Extracting %s
\n
"
,
debugstr_w
(
mi
->
source
));
...
...
@@ -457,10 +444,7 @@ static BOOL extract_cabinet_file(MSIPACKAGE* package, struct media_info *mi)
cab_path
[
ptr
-
mi
->
source
]
=
'\0'
;
data
.
package
=
package
;
data
.
mi
=
mi
;
ret
=
FDICopy
(
hfdi
,
cabinet
,
cab_path
,
0
,
cabinet_notify
,
NULL
,
&
data
);
ret
=
FDICopy
(
hfdi
,
cabinet
,
cab_path
,
0
,
notify
,
NULL
,
data
);
if
(
!
ret
)
ERR
(
"FDICopy failed
\n
"
);
...
...
@@ -495,7 +479,7 @@ static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, LPCWSTR path)
file
->
SourcePath
=
build_directory_name
(
2
,
path
,
file
->
File
);
}
static
void
free_media_info
(
struct
media_info
*
mi
)
void
msi_free_media_info
(
MSIMEDIAINFO
*
mi
)
{
msi_free
(
mi
->
disk_prompt
);
msi_free
(
mi
->
cabinet
);
...
...
@@ -504,7 +488,7 @@ static void free_media_info( struct media_info *mi )
msi_free
(
mi
);
}
static
UINT
load_media_info
(
MSIPACKAGE
*
package
,
MSIFILE
*
file
,
struct
media_info
*
mi
)
UINT
msi_load_media_info
(
MSIPACKAGE
*
package
,
MSIFILE
*
file
,
MSIMEDIAINFO
*
mi
)
{
MSIRECORD
*
row
;
LPWSTR
source_dir
;
...
...
@@ -593,7 +577,7 @@ static UINT load_media_info(MSIPACKAGE *package, MSIFILE *file, struct media_inf
}
/* FIXME: search NETWORK and URL sources as well */
static
UINT
find_published_source
(
MSIPACKAGE
*
package
,
struct
media_info
*
mi
)
static
UINT
find_published_source
(
MSIPACKAGE
*
package
,
MSIMEDIAINFO
*
mi
)
{
WCHAR
source
[
MAX_PATH
];
WCHAR
volume
[
MAX_PATH
];
...
...
@@ -634,7 +618,7 @@ static UINT find_published_source(MSIPACKAGE *package, struct media_info *mi)
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
ready_media
(
MSIPACKAGE
*
package
,
MSIFILE
*
file
,
struct
media_info
*
mi
)
static
UINT
ready_media
(
MSIPACKAGE
*
package
,
MSIFILE
*
file
,
MSIMEDIAINFO
*
mi
)
{
UINT
rc
=
ERROR_SUCCESS
;
...
...
@@ -642,7 +626,7 @@ static UINT ready_media(MSIPACKAGE *package, MSIFILE *file, struct media_info *m
if
(
mi
->
is_continuous
)
return
ERROR_SUCCESS
;
rc
=
load_media_info
(
package
,
file
,
mi
);
rc
=
msi_
load_media_info
(
package
,
file
,
mi
);
if
(
rc
!=
ERROR_SUCCESS
)
{
ERR
(
"Unable to load media info
\n
"
);
...
...
@@ -808,7 +792,7 @@ static BOOL check_dest_hash_matches(MSIFILE *file)
*/
UINT
ACTION_InstallFiles
(
MSIPACKAGE
*
package
)
{
struct
media_info
*
mi
;
MSIMEDIAINFO
*
mi
;
UINT
rc
=
ERROR_SUCCESS
;
MSIFILE
*
file
;
...
...
@@ -825,7 +809,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
*/
msi_create_component_directories
(
package
);
mi
=
msi_alloc_zero
(
sizeof
(
struct
media_info
)
);
mi
=
msi_alloc_zero
(
sizeof
(
MSIMEDIAINFO
)
);
LIST_FOR_EACH_ENTRY
(
file
,
&
package
->
files
,
MSIFILE
,
entry
)
{
...
...
@@ -841,6 +825,8 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
if
(
file
->
Sequence
>
mi
->
last_sequence
||
mi
->
is_continuous
||
(
file
->
IsCompressed
&&
!
mi
->
is_extracted
))
{
CabData
data
;
rc
=
ready_media
(
package
,
file
,
mi
);
if
(
rc
!=
ERROR_SUCCESS
)
{
...
...
@@ -848,7 +834,11 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
break
;
}
if
(
file
->
IsCompressed
&&
!
extract_cabinet_file
(
package
,
mi
))
data
.
mi
=
mi
;
data
.
package
=
package
;
if
(
file
->
IsCompressed
&&
!
msi_cabextract
(
package
,
mi
,
cabinet_notify
,
&
data
))
{
ERR
(
"Failed to extract cabinet: %s
\n
"
,
debugstr_w
(
mi
->
cabinet
));
rc
=
ERROR_FUNCTION_FAILED
;
...
...
@@ -881,7 +871,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
}
}
free_media_info
(
mi
);
msi_
free_media_info
(
mi
);
return
rc
;
}
...
...
dlls/msi/helpers.c
View file @
bfe07d1d
...
...
@@ -31,6 +31,8 @@
#include "wine/debug.h"
#include "msipriv.h"
#include "winuser.h"
#include "winreg.h"
#include "shlwapi.h"
#include "wine/unicode.h"
#include "msidefs.h"
...
...
@@ -1054,3 +1056,122 @@ void msi_ui_error( DWORD msg_id, DWORD type )
MessageBoxW
(
NULL
,
text
,
title
,
type
);
}
typedef
struct
{
MSIPACKAGE
*
package
;
MSIMEDIAINFO
*
mi
;
MSIFILE
*
file
;
LPWSTR
destination
;
}
CabData
;
static
INT_PTR
cabinet_notify
(
FDINOTIFICATIONTYPE
fdint
,
PFDINOTIFICATION
pfdin
)
{
TRACE
(
"(%d)
\n
"
,
fdint
);
switch
(
fdint
)
{
case
fdintNEXT_CABINET
:
{
ERR
(
"continuous cabinets not handled
\n
"
);
return
0
;
}
case
fdintCOPY_FILE
:
{
CabData
*
data
=
(
CabData
*
)
pfdin
->
pv
;
LPWSTR
file
,
path
;
DWORD
attrs
,
size
;
HANDLE
handle
;
MSIFILE
*
f
;
file
=
strdupAtoW
(
pfdin
->
psz1
);
f
=
get_loaded_file
(
data
->
package
,
file
);
msi_free
(
file
);
if
(
!
f
)
{
WARN
(
"unknown file in cabinet (%s)
\n
"
,
debugstr_a
(
pfdin
->
psz1
));
return
0
;
}
if
(
lstrcmpW
(
f
->
File
,
data
->
file
->
File
))
return
0
;
size
=
lstrlenW
(
data
->
destination
)
+
lstrlenW
(
file
)
+
2
;
path
=
msi_alloc
(
size
*
sizeof
(
WCHAR
));
lstrcpyW
(
path
,
data
->
destination
);
PathAddBackslashW
(
path
);
lstrcatW
(
path
,
data
->
file
->
FileName
);
TRACE
(
"extracting %s
\n
"
,
debugstr_w
(
path
));
attrs
=
f
->
Attributes
&
(
FILE_ATTRIBUTE_READONLY
|
FILE_ATTRIBUTE_HIDDEN
|
FILE_ATTRIBUTE_SYSTEM
);
if
(
!
attrs
)
attrs
=
FILE_ATTRIBUTE_NORMAL
;
handle
=
CreateFileW
(
path
,
GENERIC_READ
|
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
attrs
,
NULL
);
if
(
handle
==
INVALID_HANDLE_VALUE
)
{
if
(
GetFileAttributesW
(
path
)
==
INVALID_FILE_ATTRIBUTES
)
ERR
(
"failed to create %s (error %d)
\n
"
,
debugstr_w
(
path
),
GetLastError
());
msi_free
(
path
);
return
0
;
}
msi_free
(
path
);
return
(
INT_PTR
)
handle
;
}
case
fdintCLOSE_FILE_INFO
:
{
FILETIME
ft
;
FILETIME
ftLocal
;
HANDLE
handle
=
(
HANDLE
)
pfdin
->
hf
;
if
(
!
DosDateTimeToFileTime
(
pfdin
->
date
,
pfdin
->
time
,
&
ft
))
return
-
1
;
if
(
!
LocalFileTimeToFileTime
(
&
ft
,
&
ftLocal
))
return
-
1
;
if
(
!
SetFileTime
(
handle
,
&
ftLocal
,
0
,
&
ftLocal
))
return
-
1
;
CloseHandle
(
handle
);
return
1
;
}
default:
return
0
;
}
}
UINT
msi_extract_file
(
MSIPACKAGE
*
package
,
MSIFILE
*
file
,
LPWSTR
destdir
)
{
MSIMEDIAINFO
*
mi
;
CabData
data
;
UINT
r
;
mi
=
msi_alloc_zero
(
sizeof
(
MSIMEDIAINFO
));
if
(
!
mi
)
return
ERROR_OUTOFMEMORY
;
r
=
msi_load_media_info
(
package
,
file
,
mi
);
if
(
r
!=
ERROR_SUCCESS
)
goto
done
;
data
.
package
=
package
;
data
.
mi
=
mi
;
data
.
file
=
file
;
data
.
destination
=
destdir
;
if
(
!
msi_cabextract
(
package
,
mi
,
cabinet_notify
,
&
data
))
{
ERR
(
"Failed to extract cabinet file
\n
"
);
r
=
ERROR_FUNCTION_FAILED
;
}
done:
msi_free_media_info
(
mi
);
return
r
;
}
dlls/msi/msipriv.h
View file @
bfe07d1d
...
...
@@ -26,6 +26,7 @@
#include "windef.h"
#include "winbase.h"
#include "fdi.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
...
...
@@ -133,6 +134,20 @@ typedef struct tagMSIMEDIADISK
LPWSTR
disk_prompt
;
}
MSIMEDIADISK
;
typedef
struct
tagMSIMEDIAINFO
{
UINT
disk_id
;
UINT
type
;
UINT
last_sequence
;
LPWSTR
disk_prompt
;
LPWSTR
cabinet
;
LPWSTR
first_volume
;
LPWSTR
volume_label
;
BOOL
is_continuous
;
BOOL
is_extracted
;
WCHAR
source
[
MAX_PATH
];
}
MSIMEDIAINFO
;
typedef
struct
_column_info
{
LPCWSTR
table
;
...
...
@@ -889,6 +904,10 @@ extern UINT msi_create_component_directories( MSIPACKAGE *package );
extern
void
msi_ui_error
(
DWORD
msg_id
,
DWORD
type
);
extern
UINT
msi_set_last_used_source
(
LPCWSTR
product
,
LPCWSTR
usersid
,
MSIINSTALLCONTEXT
context
,
DWORD
options
,
LPCWSTR
value
);
extern
UINT
msi_load_media_info
(
MSIPACKAGE
*
package
,
MSIFILE
*
file
,
MSIMEDIAINFO
*
mi
);
extern
void
msi_free_media_info
(
MSIMEDIAINFO
*
mi
);
extern
BOOL
msi_cabextract
(
MSIPACKAGE
*
package
,
MSIMEDIAINFO
*
mi
,
PFNFDINOTIFY
notify
,
LPVOID
data
);
extern
UINT
msi_extract_file
(
MSIPACKAGE
*
package
,
MSIFILE
*
file
,
LPWSTR
destdir
);
/* control event stuff */
extern
VOID
ControlEvent_FireSubscribedEvent
(
MSIPACKAGE
*
package
,
LPCWSTR
event
,
...
...
include/msidefs.h
View file @
bfe07d1d
...
...
@@ -201,6 +201,12 @@ enum msidbMoveFileOptions
msidbMoveFileOptionsMove
=
0x00000001
,
};
enum
msidbAssemblyAttributes
{
msidbAssemblyAttributesURT
=
0x00000000
,
msidbAssemblyAttributesWin32
=
0x00000001
,
};
/*
* Windows SDK braindamage alert
*
...
...
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