Skip to content
Snippets Groups Projects
Commit b5d31846 authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard
Browse files

Respect the version SP_COPY flags when installing files.

Make GenInstall16 only copy files if the version is new or same.
parent 1048ebb3
No related branches found
No related tags found
No related merge requests found
......@@ -4,7 +4,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = setupapi.dll
IMPORTS = user32 advapi32 kernel32 ntdll
IMPORTS = user32 version advapi32 kernel32 ntdll
ALTNAMES = setupx.dll
EXTRALIBS = $(LIBUNICODE)
......
......@@ -183,8 +183,9 @@ RETERR16 WINAPI GenInstall16( HINF16 hinf16, LPCSTR section, WORD genflags )
if (genflags & GENINSTALL_DO_PERUSER) FIXME( "unsupported flag: GENINSTALL_DO_PERUSER\n" );
context = SetupInitDefaultQueueCallback( 0 );
if (!SetupInstallFromInfSectionA( 0, hinf, section, flags, 0, NULL, 0,
SetupDefaultQueueCallbackA, context, 0, 0 ))
if (!SetupInstallFromInfSectionA( 0, hinf, section, flags, 0, NULL,
SP_COPY_NEWER_OR_SAME, SetupDefaultQueueCallbackA,
context, 0, 0 ))
ret = get_last_error();
SetupTermDefaultQueueCallback( context );
......
......@@ -25,6 +25,7 @@
#include "setupapi.h"
#include "wine/unicode.h"
#include "setupapi_private.h"
#include "ver.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
......@@ -937,6 +938,132 @@ static BOOL create_full_pathW(const WCHAR *path)
return ret;
}
BOOL static do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style)
{
BOOL rc = FALSE;
BOOL docopy = TRUE;
TRACE("copy %s to %s style 0x%lx\n",debugstr_w(source),debugstr_w(target),style);
/* before copy processing */
if (style & SP_COPY_REPLACEONLY)
{
if (GetFileAttributesW(target) == INVALID_FILE_ATTRIBUTES)
docopy = FALSE;
}
if (style & (SP_COPY_NEWER_OR_SAME | SP_COPY_NEWER_ONLY | SP_COPY_FORCE_NEWER))
{
DWORD VersionSizeSource=0;
DWORD VersionSizeTarget=0;
DWORD zero=0;
/*
* This is sort of an interesting workaround. You see, calling
* GetVersionInfoSize on a builtin dll loads that dll into memory.
* and we do not properly unload builtin dlls.. so we effectively
* lock into memory all the targets we are replacing. This leads
* to problems when we try to register the replaced dlls.
*
* So I will test for the existance of the files first so that
* we just basically unconditionally replace the builtin versions
*/
if ((GetFileAttributesW(target) != INVALID_FILE_ATTRIBUTES) &&
(GetFileAttributesW(source) != INVALID_FILE_ATTRIBUTES))
{
VersionSizeSource = GetFileVersionInfoSizeW(source,&zero);
VersionSizeTarget = GetFileVersionInfoSizeW(target,&zero);
}
TRACE("SizeTarget %li ... SizeSource %li\n",VersionSizeTarget,
VersionSizeSource);
if (VersionSizeSource && VersionSizeTarget)
{
LPVOID VersionSource;
LPVOID VersionTarget;
VS_FIXEDFILEINFO *TargetInfo;
VS_FIXEDFILEINFO *SourceInfo;
INT length;
WCHAR SubBlock[2]={'\\',0};
DWORD ret;
VersionSource = HeapAlloc(GetProcessHeap(),0,VersionSizeSource);
VersionTarget = HeapAlloc(GetProcessHeap(),0,VersionSizeTarget);
ret = GetFileVersionInfoW(source,0,VersionSizeSource,VersionSource);
if (ret)
ret = GetFileVersionInfoW(target, 0, VersionSizeTarget,
VersionTarget);
if (ret)
{
ret = VerQueryValueW(VersionSource, SubBlock,
(LPVOID*)&SourceInfo, &length);
if (ret)
ret = VerQueryValueW(VersionTarget, SubBlock,
(LPVOID*)&TargetInfo, &length);
if (ret)
{
TRACE("Versions: Source %li.%li target %li.%li\n",
SourceInfo->dwFileVersionMS, SourceInfo->dwFileVersionLS,
TargetInfo->dwFileVersionMS, TargetInfo->dwFileVersionLS);
if (TargetInfo->dwFileVersionMS > SourceInfo->dwFileVersionMS)
{
FIXME("Notify that target version is greater..\n");
docopy = FALSE;
}
else if ((TargetInfo->dwFileVersionMS == SourceInfo->dwFileVersionMS)
&& (TargetInfo->dwFileVersionLS > SourceInfo->dwFileVersionLS))
{
FIXME("Notify that target version is greater..\n");
docopy = FALSE;
}
else if ((style & SP_COPY_NEWER_ONLY) &&
(TargetInfo->dwFileVersionMS ==
SourceInfo->dwFileVersionMS)
&&(TargetInfo->dwFileVersionLS ==
SourceInfo->dwFileVersionLS))
{
FIXME("Notify that target version is greater..\n");
docopy = FALSE;
}
}
HeapFree(GetProcessHeap(),0,VersionSource);
HeapFree(GetProcessHeap(),0,VersionTarget);
}
}
}
if (style & (SP_COPY_NOOVERWRITE | SP_COPY_FORCE_NOOVERWRITE))
{
if (GetFileAttributesW(target) != INVALID_FILE_ATTRIBUTES)
{
FIXME("Notify user target file exists\n");
docopy = FALSE;
}
}
if (style & (SP_COPY_NODECOMP | SP_COPY_LANGUAGEAWARE | SP_COPY_FORCE_IN_USE |
SP_COPY_IN_USE_NEEDS_REBOOT | SP_COPY_NOSKIP | SP_COPY_WARNIFSKIP))
{
ERR("Unsupported style(s) 0x%lx\n",style);
}
if (docopy)
{
rc = CopyFileW(source,target,FALSE);
TRACE("Did copy... rc was %i\n",rc);
}
/* after copy processing */
if (style & SP_COPY_DELETESOURCE)
{
if (rc)
DeleteFileW(source);
}
return rc;
}
/***********************************************************************
* SetupCommitFileQueueW (SETUPAPI.@)
......@@ -1035,8 +1162,8 @@ BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBAC
if (op_result == FILEOP_ABORT) goto done;
}
}
if (CopyFileW( op_result == FILEOP_NEWPATH ? newpath : paths.Source,
paths.Target, FALSE /*FIXME*/ )) break; /* success */
if (do_file_copyW( op_result == FILEOP_NEWPATH ? newpath : paths.Source,
paths.Target, op->style )) break; /* success */
/* try to extract it from the cabinet file */
if (op->src_tag)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment