Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
f180de40
Commit
f180de40
authored
Jul 31, 2012
by
Hans Leidekker
Committed by
Alexandre Julliard
Jul 31, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Implement the RemoveExistingProducts standard action.
parent
3298a302
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
155 additions
and
7 deletions
+155
-7
action.c
dlls/msi/action.c
+35
-7
action.c
dlls/msi/tests/action.c
+120
-0
No files found.
dlls/msi/action.c
View file @
f180de40
...
...
@@ -7045,23 +7045,51 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
static
UINT
ITERATE_RemoveExistingProducts
(
MSIRECORD
*
rec
,
LPVOID
param
)
{
static
const
WCHAR
fmtW
[]
=
{
'm'
,
's'
,
'i'
,
'e'
,
'x'
,
'e'
,
'c'
,
' '
,
'/'
,
'i'
,
' '
,
'%'
,
's'
,
' '
,
'R'
,
'E'
,
'M'
,
'O'
,
'V'
,
'E'
,
'='
,
'%'
,
's'
,
0
};
MSIPACKAGE
*
package
=
param
;
const
WCHAR
*
property
=
MSI_RecordGetString
(
rec
,
1
);
WCHAR
*
value
;
const
WCHAR
*
property
=
MSI_RecordGetString
(
rec
,
7
);
UINT
len
=
sizeof
(
fmtW
)
/
sizeof
(
fmtW
[
0
]);
WCHAR
*
product
,
*
features
,
*
cmd
;
STARTUPINFOW
si
;
PROCESS_INFORMATION
info
;
BOOL
ret
;
if
((
value
=
msi_dup_property
(
package
->
db
,
property
)))
if
(
!
(
product
=
msi_dup_property
(
package
->
db
,
property
)))
return
ERROR_SUCCESS
;
deformat_string
(
package
,
MSI_RecordGetString
(
rec
,
6
),
&
features
);
len
+=
strlenW
(
product
);
if
(
features
)
len
+=
strlenW
(
features
);
else
len
+=
sizeof
(
szAll
)
/
sizeof
(
szAll
[
0
]);
if
(
!
(
cmd
=
msi_alloc
(
len
*
sizeof
(
WCHAR
)
)))
{
FIXME
(
"remove %s
\n
"
,
debugstr_w
(
value
));
msi_free
(
value
);
msi_free
(
product
);
msi_free
(
features
);
return
ERROR_OUTOFMEMORY
;
}
sprintfW
(
cmd
,
fmtW
,
product
,
features
?
features
:
szAll
);
msi_free
(
product
);
msi_free
(
features
);
memset
(
&
si
,
0
,
sizeof
(
STARTUPINFOW
)
);
ret
=
CreateProcessW
(
NULL
,
cmd
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
info
);
msi_free
(
cmd
);
if
(
!
ret
)
return
GetLastError
();
CloseHandle
(
info
.
hThread
);
WaitForSingleObject
(
info
.
hProcess
,
INFINITE
);
CloseHandle
(
info
.
hProcess
);
return
ERROR_SUCCESS
;
}
static
UINT
ACTION_RemoveExistingProducts
(
MSIPACKAGE
*
package
)
{
static
const
WCHAR
query
[]
=
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'A'
,
'c'
,
't'
,
'i'
,
'o'
,
'n'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'U'
,
'p'
,
'g'
,
'r'
,
'a'
,
'd'
,
'e'
,
0
};
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'U'
,
'p'
,
'g'
,
'r'
,
'a'
,
'd'
,
'e'
,
0
};
MSIQUERY
*
view
;
UINT
r
;
...
...
dlls/msi/tests/action.c
View file @
f180de40
...
...
@@ -1461,6 +1461,76 @@ static const char pa_install_exec_seq_dat[] =
"PublishProduct
\t\t
5200
\n
"
"InstallFinalize
\t\t
6000
\n
"
;
static
const
char
rep_file_dat
[]
=
"File
\t
Component_
\t
FileName
\t
FileSize
\t
Version
\t
Language
\t
Attributes
\t
Sequence
\n
"
"s72
\t
s72
\t
l255
\t
i4
\t
S72
\t
S20
\t
I2
\t
i2
\n
"
"File
\t
File
\n
"
"rep.txt
\t
rep
\t
rep.txt
\t
1000
\t\t\t
8192
\t
1
\n
"
;
static
const
char
rep_feature_dat
[]
=
"Feature
\t
Feature_Parent
\t
Title
\t
Description
\t
Display
\t
Level
\t
Directory_
\t
Attributes
\n
"
"s38
\t
S38
\t
L64
\t
L255
\t
I2
\t
i2
\t
S72
\t
i2
\n
"
"Feature
\t
Feature
\n
"
"rep
\t\t\t
rep feature
\t
1
\t
2
\t
MSITESTDIR
\t
0
\n
"
;
static
const
char
rep_feature_comp_dat
[]
=
"Feature_
\t
Component_
\n
"
"s38
\t
s72
\n
"
"FeatureComponents
\t
Feature_
\t
Component_
\n
"
"rep
\t
rep
\n
"
;
static
const
char
rep_component_dat
[]
=
"Component
\t
ComponentId
\t
Directory_
\t
Attributes
\t
Condition
\t
KeyPath
\n
"
"s72
\t
S38
\t
s72
\t
i2
\t
S255
\t
S72
\n
"
"Component
\t
Component
\n
"
"rep
\t
{A24FAF2A-3B2E-41EF-AA78-331542E1A29D}
\t
MSITESTDIR
\t
0
\t\t
rep.txt
\n
"
;
static
const
char
rep_upgrade_dat
[]
=
"UpgradeCode
\t
VersionMin
\t
VersionMax
\t
Language
\t
Attributes
\t
Remove
\t
ActionProperty
\n
"
"s38
\t
S20
\t
S20
\t
S255
\t
i4
\t
S255
\t
s72
\n
"
"Upgrade
\t
UpgradeCode
\t
VersionMin
\t
VersionMax
\t
Language
\t
Attributes
\n
"
"{2967C1CC-34D4-42EE-8D96-CD6836F192BF}
\t\t\t\t
256
\t\t
PRODUCT
\n
"
;
static
const
char
rep_property_dat
[]
=
"Property
\t
Value
\n
"
"s72
\t
l0
\n
"
"Property
\t
Property
\n
"
"HASUIRUN
\t
0
\n
"
"INSTALLLEVEL
\t
3
\n
"
"InstallMode
\t
Typical
\n
"
"Manufacturer
\t
Wine
\n
"
"PIDTemplate
\t
###-#######
\n
"
"ProductCode
\t
{1699F0BB-0B61-4A89-AFE4-CFD60DFD76F3}
\n
"
"ProductLanguage
\t
1033
\n
"
"ProductName
\t
MSITEST
\n
"
"ProductVersion
\t
1.1.1
\n
"
"UpgradeCode
\t
{2967C1CC-34D4-42EE-8D96-CD6836F192BF}
\n
"
"PRODUCT
\t
2F41860D-7B4C-4DA7-BED9-B64F26594C56
\n
"
"MSIFASTINSTALL
\t
1
\n
"
;
static
const
char
rep_install_exec_seq_dat
[]
=
"Action
\t
Condition
\t
Sequence
\n
"
"s72
\t
S255
\t
I2
\n
"
"InstallExecuteSequence
\t
Action
\n
"
"FindRelatedProducts
\t\t
100
\n
"
"CostInitialize
\t\t
800
\n
"
"FileCost
\t\t
900
\n
"
"CostFinalize
\t\t
1000
\n
"
"InstallValidate
\t\t
1400
\n
"
"RemoveExistingProducts
\t\t
1499
\n
"
"InstallInitialize
\t\t
1500
\n
"
"ProcessComponents
\t\t
1600
\n
"
"RemoveFiles
\t\t
1700
\n
"
"InstallFiles
\t\t
2000
\n
"
"UnregisterExtensionInfo
\t\t
3000
\n
"
"UnregisterMIMEInfo
\t\t
3500
\n
"
"RegisterExtensionInfo
\t\t
4000
\n
"
"RegisterMIMEInfo
\t\t
4500
\n
"
"RegisterProduct
\t\t
5000
\n
"
"PublishFeatures
\t\t
5100
\n
"
"PublishProduct
\t\t
5200
\n
"
"InstallFinalize
\t\t
6000
\n
"
;
typedef
struct
_msi_table
{
const
char
*
filename
;
...
...
@@ -1818,6 +1888,19 @@ static const msi_table pa_tables[] =
ADD_TABLE
(
property
)
};
static
const
msi_table
rep_tables
[]
=
{
ADD_TABLE
(
directory
),
ADD_TABLE
(
rep_component
),
ADD_TABLE
(
rep_feature
),
ADD_TABLE
(
rep_feature_comp
),
ADD_TABLE
(
rep_file
),
ADD_TABLE
(
rep_upgrade
),
ADD_TABLE
(
rep_property
),
ADD_TABLE
(
rep_install_exec_seq
),
ADD_TABLE
(
media
)
};
/* based on RegDeleteTreeW from dlls/advapi32/registry.c */
static
LSTATUS
action_RegDeleteTreeA
(
HKEY
hKey
,
LPCSTR
lpszSubKey
,
REGSAM
access
)
{
...
...
@@ -6125,6 +6208,42 @@ done:
DeleteFile
(
msifile
);
}
static
void
test_remove_existing_products
(
void
)
{
UINT
r
;
if
(
is_process_limited
())
{
skip
(
"process is limited
\n
"
);
return
;
}
create_test_files
();
create_file
(
"msitest
\\
rep.txt"
,
1000
);
create_database
(
msifile
,
rep_tables
,
sizeof
(
rep_tables
)
/
sizeof
(
msi_table
));
MsiSetInternalUI
(
INSTALLUILEVEL_NONE
,
NULL
);
r
=
MsiInstallProductA
(
msifile
,
NULL
);
if
(
r
==
ERROR_INSTALL_PACKAGE_REJECTED
)
{
skip
(
"Not enough rights to perform tests
\n
"
);
goto
error
;
}
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %u
\n
"
,
r
);
r
=
MsiInstallProductA
(
msifile
,
"REMOVE=ALL"
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %u
\n
"
,
r
);
ok
(
!
delete_pf
(
"msitest
\\
rep.txt"
,
TRUE
),
"file not removed
\n
"
);
ok
(
!
delete_pf
(
"msitest"
,
FALSE
),
"directory not removed
\n
"
);
error:
DeleteFileA
(
"msitest
\\
rep.txt"
);
delete_test_files
();
DeleteFile
(
msifile
);
}
START_TEST
(
action
)
{
DWORD
len
;
...
...
@@ -6202,6 +6321,7 @@ START_TEST(action)
test_register_extension_info
();
test_register_mime_info
();
test_publish_assemblies
();
test_remove_existing_products
();
DeleteFileA
(
log_file
);
...
...
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