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
253a7fa7
Commit
253a7fa7
authored
Feb 23, 2010
by
Hans Leidekker
Committed by
Alexandre Julliard
Feb 23, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Implement the RemoveDuplicateFiles standard action.
parent
f3696e48
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
144 additions
and
82 deletions
+144
-82
action.c
dlls/msi/action.c
+0
-8
files.c
dlls/msi/files.c
+142
-74
msipriv.h
dlls/msi/msipriv.h
+2
-0
No files found.
dlls/msi/action.c
View file @
253a7fa7
...
...
@@ -134,8 +134,6 @@ static const WCHAR szRegisterFonts[] =
{
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'e'
,
'r'
,
'F'
,
'o'
,
'n'
,
't'
,
's'
,
0
};
static
const
WCHAR
szRegisterUser
[]
=
{
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'e'
,
'r'
,
'U'
,
's'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
szRemoveDuplicateFiles
[]
=
{
'R'
,
'e'
,
'm'
,
'o'
,
'v'
,
'e'
,
'D'
,
'u'
,
'p'
,
'l'
,
'i'
,
'c'
,
'a'
,
't'
,
'e'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
0
};
static
const
WCHAR
szRemoveEnvironmentStrings
[]
=
{
'R'
,
'e'
,
'm'
,
'o'
,
'v'
,
'e'
,
'E'
,
'n'
,
'v'
,
'i'
,
'r'
,
'o'
,
'n'
,
'm'
,
'e'
,
'n'
,
't'
,
'S'
,
't'
,
'r'
,
'i'
,
'n'
,
'g'
,
's'
,
0
};
static
const
WCHAR
szRemoveExistingProducts
[]
=
...
...
@@ -6600,12 +6598,6 @@ static UINT ACTION_InstallSFPCatalogFile( MSIPACKAGE *package )
return
msi_unimplemented_action_stub
(
package
,
"InstallSFPCatalogFile"
,
table
);
}
static
UINT
ACTION_RemoveDuplicateFiles
(
MSIPACKAGE
*
package
)
{
static
const
WCHAR
table
[]
=
{
'D'
,
'u'
,
'p'
,
'l'
,
'i'
,
'c'
,
'a'
,
't'
,
'e'
,
'F'
,
'i'
,
'l'
,
'e'
,
0
};
return
msi_unimplemented_action_stub
(
package
,
"RemoveDuplicateFiles"
,
table
);
}
static
UINT
ACTION_RemoveExistingProducts
(
MSIPACKAGE
*
package
)
{
static
const
WCHAR
table
[]
=
{
'U'
,
'p'
,
'g'
,
'r'
,
'a'
,
'd'
,
'e'
,
0
};
...
...
dlls/msi/files.c
View file @
253a7fa7
...
...
@@ -24,10 +24,10 @@
*
* InstallFiles
* DuplicateFiles
* MoveFiles
(TODO)
* MoveFiles
* PatchFiles (TODO)
* RemoveDuplicateFiles
(TODO)
* RemoveFiles
(TODO)
* RemoveDuplicateFiles
* RemoveFiles
*/
#include <stdarg.h>
...
...
@@ -85,23 +85,6 @@ static int msi_compare_file_version(MSIFILE *file)
return
lstrcmpW
(
version
,
file
->
Version
);
}
static
UINT
get_file_target
(
MSIPACKAGE
*
package
,
LPCWSTR
file_key
,
MSIFILE
**
file
)
{
LIST_FOR_EACH_ENTRY
(
*
file
,
&
package
->
files
,
MSIFILE
,
entry
)
{
if
(
lstrcmpW
(
file_key
,
(
*
file
)
->
File
)
==
0
)
{
if
((
*
file
)
->
state
>=
msifs_overwrite
)
return
ERROR_SUCCESS
;
else
return
ERROR_FILE_NOT_FOUND
;
}
}
return
ERROR_FUNCTION_FAILED
;
}
static
void
schedule_install_files
(
MSIPACKAGE
*
package
)
{
MSIFILE
*
file
;
...
...
@@ -345,14 +328,63 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
return
rc
;
}
static
WCHAR
*
get_duplicate_filename
(
MSIPACKAGE
*
package
,
MSIRECORD
*
row
,
const
WCHAR
*
file_key
,
const
WCHAR
*
src
)
{
DWORD
len
;
WCHAR
*
dst_name
,
*
dst_path
,
*
dst
;
if
(
MSI_RecordIsNull
(
row
,
4
))
{
len
=
strlenW
(
src
)
+
1
;
if
(
!
(
dst_name
=
msi_alloc
(
len
*
sizeof
(
WCHAR
))))
return
NULL
;
strcpyW
(
dst_name
,
strrchrW
(
src
,
'\\'
)
+
1
);
}
else
{
MSI_RecordGetStringW
(
row
,
4
,
NULL
,
&
len
);
if
(
!
(
dst_name
=
msi_alloc
(
++
len
*
sizeof
(
WCHAR
)
)))
return
NULL
;
MSI_RecordGetStringW
(
row
,
4
,
dst_name
,
&
len
);
reduce_to_longfilename
(
dst_name
);
}
if
(
MSI_RecordIsNull
(
row
,
5
))
{
WCHAR
*
p
;
dst_path
=
strdupW
(
src
);
p
=
strrchrW
(
dst_path
,
'\\'
);
if
(
p
)
*
p
=
0
;
}
else
{
const
WCHAR
*
dst_key
=
MSI_RecordGetString
(
row
,
5
);
dst_path
=
resolve_folder
(
package
,
dst_key
,
FALSE
,
FALSE
,
TRUE
,
NULL
);
if
(
!
dst_path
)
{
/* try a property */
dst_path
=
msi_dup_property
(
package
,
dst_key
);
if
(
!
dst_path
)
{
FIXME
(
"Unable to get destination folder, try AppSearch properties
\n
"
);
msi_free
(
dst_name
);
return
NULL
;
}
}
}
dst
=
build_directory_name
(
2
,
dst_path
,
dst_name
);
create_full_pathW
(
dst_path
);
msi_free
(
dst_name
);
msi_free
(
dst_path
);
return
dst
;
}
static
UINT
ITERATE_DuplicateFiles
(
MSIRECORD
*
row
,
LPVOID
param
)
{
MSIPACKAGE
*
package
=
param
;
WCHAR
dest_name
[
0x100
];
LPWSTR
dest_path
,
dest
;
LPWSTR
dest
;
LPCWSTR
file_key
,
component
;
DWORD
sz
;
DWORD
rc
;
MSICOMPONENT
*
comp
;
MSIFILE
*
file
;
...
...
@@ -376,70 +408,33 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param)
return
ERROR_FUNCTION_FAILED
;
}
rc
=
get_file_target
(
package
,
file_key
,
&
file
);
if
(
rc
!=
ERROR_SUCCESS
)
file
=
get_loaded_file
(
package
,
file_key
);
if
(
!
file
)
{
ERR
(
"Original file unknown %s
\n
"
,
debugstr_w
(
file_key
));
ERR
(
"Original file unknown %s
\n
"
,
debugstr_w
(
file_key
));
return
ERROR_SUCCESS
;
}
if
(
MSI_RecordIsNull
(
row
,
4
))
strcpyW
(
dest_name
,
strrchrW
(
file
->
TargetPath
,
'\\'
)
+
1
);
else
dest
=
get_duplicate_filename
(
package
,
row
,
file_key
,
file
->
TargetPath
);
if
(
!
dest
)
{
sz
=
0x100
;
MSI_RecordGetStringW
(
row
,
4
,
dest_name
,
&
sz
);
reduce_to_longfilename
(
dest_name
);
WARN
(
"Unable to get duplicate filename
\n
"
);
return
ERROR_SUCCESS
;
}
if
(
MSI_RecordIsNull
(
row
,
5
))
{
LPWSTR
p
;
dest_path
=
strdupW
(
file
->
TargetPath
);
p
=
strrchrW
(
dest_path
,
'\\'
);
if
(
p
)
*
p
=
0
;
}
else
TRACE
(
"Duplicating file %s to %s
\n
"
,
debugstr_w
(
file
->
TargetPath
),
debugstr_w
(
dest
));
if
(
!
CopyFileW
(
file
->
TargetPath
,
dest
,
TRUE
))
{
LPCWSTR
destkey
;
destkey
=
MSI_RecordGetString
(
row
,
5
);
dest_path
=
resolve_folder
(
package
,
destkey
,
FALSE
,
FALSE
,
TRUE
,
NULL
);
if
(
!
dest_path
)
{
/* try a Property */
dest_path
=
msi_dup_property
(
package
,
destkey
);
if
(
!
dest_path
)
{
FIXME
(
"Unable to get destination folder, try AppSearch properties
\n
"
);
return
ERROR_SUCCESS
;
}
}
WARN
(
"Failed to copy file %s -> %s (%u)
\n
"
,
debugstr_w
(
file
->
TargetPath
),
debugstr_w
(
dest
),
GetLastError
());
}
dest
=
build_directory_name
(
2
,
dest_path
,
dest_name
);
create_full_pathW
(
dest_path
);
TRACE
(
"Duplicating file %s to %s
\n
"
,
debugstr_w
(
file
->
TargetPath
),
debugstr_w
(
dest
));
if
(
strcmpW
(
file
->
TargetPath
,
dest
))
rc
=
!
CopyFileW
(
file
->
TargetPath
,
dest
,
TRUE
);
else
rc
=
ERROR_SUCCESS
;
if
(
rc
!=
ERROR_SUCCESS
)
ERR
(
"Failed to copy file %s -> %s, last error %d
\n
"
,
debugstr_w
(
file
->
TargetPath
),
debugstr_w
(
dest_path
),
GetLastError
());
FIXME
(
"We should track these duplicate files as well
\n
"
);
msi_free
(
dest_path
);
msi_free
(
dest
);
msi_file_update_ui
(
package
,
file
,
szDuplicateFiles
);
msi_free
(
dest
);
return
ERROR_SUCCESS
;
}
...
...
@@ -461,6 +456,79 @@ UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
return
rc
;
}
static
UINT
ITERATE_RemoveDuplicateFiles
(
MSIRECORD
*
row
,
LPVOID
param
)
{
MSIPACKAGE
*
package
=
param
;
LPWSTR
dest
;
LPCWSTR
file_key
,
component
;
MSICOMPONENT
*
comp
;
MSIFILE
*
file
;
component
=
MSI_RecordGetString
(
row
,
2
);
comp
=
get_loaded_component
(
package
,
component
);
if
(
!
comp
)
return
ERROR_SUCCESS
;
if
(
comp
->
ActionRequest
!=
INSTALLSTATE_ABSENT
)
{
TRACE
(
"Component not scheduled for removal %s
\n
"
,
debugstr_w
(
component
));
comp
->
Action
=
comp
->
Installed
;
return
ERROR_SUCCESS
;
}
comp
->
Action
=
INSTALLSTATE_ABSENT
;
file_key
=
MSI_RecordGetString
(
row
,
3
);
if
(
!
file_key
)
{
ERR
(
"Unable to get file key
\n
"
);
return
ERROR_FUNCTION_FAILED
;
}
file
=
get_loaded_file
(
package
,
file_key
);
if
(
!
file
)
{
ERR
(
"Original file unknown %s
\n
"
,
debugstr_w
(
file_key
));
return
ERROR_SUCCESS
;
}
dest
=
get_duplicate_filename
(
package
,
row
,
file_key
,
file
->
TargetPath
);
if
(
!
dest
)
{
WARN
(
"Unable to get duplicate filename
\n
"
);
return
ERROR_SUCCESS
;
}
TRACE
(
"Removing duplicate %s of %s
\n
"
,
debugstr_w
(
dest
),
debugstr_w
(
file
->
TargetPath
));
if
(
!
DeleteFileW
(
dest
))
{
WARN
(
"Failed to delete duplicate file %s (%u)
\n
"
,
debugstr_w
(
dest
),
GetLastError
());
}
msi_file_update_ui
(
package
,
file
,
szRemoveDuplicateFiles
);
msi_free
(
dest
);
return
ERROR_SUCCESS
;
}
UINT
ACTION_RemoveDuplicateFiles
(
MSIPACKAGE
*
package
)
{
UINT
rc
;
MSIQUERY
*
view
;
static
const
WCHAR
query
[]
=
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'`'
,
'D'
,
'u'
,
'p'
,
'l'
,
'i'
,
'c'
,
'a'
,
't'
,
'e'
,
'F'
,
'i'
,
'l'
,
'e'
,
'`'
,
0
};
rc
=
MSI_DatabaseOpenViewW
(
package
->
db
,
query
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
ERROR_SUCCESS
;
rc
=
MSI_IterateRecords
(
view
,
NULL
,
ITERATE_RemoveDuplicateFiles
,
package
);
msiobj_release
(
&
view
->
hdr
);
return
rc
;
}
static
BOOL
verify_comp_for_removal
(
MSICOMPONENT
*
comp
,
UINT
install_mode
)
{
INSTALLSTATE
request
=
comp
->
ActionRequest
;
...
...
dlls/msi/msipriv.h
View file @
253a7fa7
...
...
@@ -956,6 +956,7 @@ extern UINT ACTION_FindRelatedProducts(MSIPACKAGE *package);
extern
UINT
ACTION_InstallFiles
(
MSIPACKAGE
*
package
);
extern
UINT
ACTION_RemoveFiles
(
MSIPACKAGE
*
package
);
extern
UINT
ACTION_DuplicateFiles
(
MSIPACKAGE
*
package
);
extern
UINT
ACTION_RemoveDuplicateFiles
(
MSIPACKAGE
*
package
);
extern
UINT
ACTION_RegisterClassInfo
(
MSIPACKAGE
*
package
);
extern
UINT
ACTION_RegisterProgIdInfo
(
MSIPACKAGE
*
package
);
extern
UINT
ACTION_RegisterExtensionInfo
(
MSIPACKAGE
*
package
);
...
...
@@ -1063,6 +1064,7 @@ static const WCHAR szRegisterProgIdInfo[] = {'R','e','g','i','s','t','e','r','P'
static
const
WCHAR
szRegisterExtensionInfo
[]
=
{
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'e'
,
'r'
,
'E'
,
'x'
,
't'
,
'e'
,
'n'
,
's'
,
'i'
,
'o'
,
'n'
,
'I'
,
'n'
,
'f'
,
'o'
,
0
};
static
const
WCHAR
szRegisterMIMEInfo
[]
=
{
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'e'
,
'r'
,
'M'
,
'I'
,
'M'
,
'E'
,
'I'
,
'n'
,
'f'
,
'o'
,
0
};
static
const
WCHAR
szDuplicateFiles
[]
=
{
'D'
,
'u'
,
'p'
,
'l'
,
'i'
,
'c'
,
'a'
,
't'
,
'e'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
0
};
static
const
WCHAR
szRemoveDuplicateFiles
[]
=
{
'R'
,
'e'
,
'm'
,
'o'
,
'v'
,
'e'
,
'D'
,
'u'
,
'p'
,
'l'
,
'i'
,
'c'
,
'a'
,
't'
,
'e'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
0
};
static
const
WCHAR
szInstallFiles
[]
=
{
'I'
,
'n'
,
's'
,
't'
,
'a'
,
'l'
,
'l'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
0
};
static
const
WCHAR
szRemoveFiles
[]
=
{
'R'
,
'e'
,
'm'
,
'o'
,
'v'
,
'e'
,
'F'
,
'i'
,
'l'
,
'e'
,
's'
,
0
};
static
const
WCHAR
szFindRelatedProducts
[]
=
{
'F'
,
'i'
,
'n'
,
'd'
,
'R'
,
'e'
,
'l'
,
'a'
,
't'
,
'e'
,
'd'
,
'P'
,
'r'
,
'o'
,
'd'
,
'u'
,
'c'
,
't'
,
's'
,
0
};
...
...
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