[WINESYNC] setupapi: Add an extension to support file copies from module resources.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 5696c3c23d5be9f5ce57ef7e361d88722120da09 by Alexandre Julliard <julliard@winehq.org>

NOTE: This commit is a Wine-specific feature, that does not exist in
Windows, thus should not exist in ReactOS: surrounded in __WINESRC__.
This commit is contained in:
winesync 2023-10-02 22:02:08 +02:00 committed by Hermès Bélusca-Maïto
parent 554be12b9f
commit e1e06fef84
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 78 additions and 7 deletions

View file

@ -21,6 +21,10 @@
#include "setupapi_private.h"
#include "wine/heap.h"
#ifdef __WINESRC__
#include <stdlib.h>
#endif
#ifdef __REACTOS__
#include <aclapi.h>
#endif
@ -146,8 +150,13 @@ static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
unsigned int src_len = 1, dst_len = 1;
WCHAR *source = (PWSTR)paths->Source, *target = (PWSTR)paths->Target;
if (op->media) src_len += lstrlenW(op->media->root) + 1;
if (op->src_path) src_len += lstrlenW(op->src_path) + 1;
#ifdef __WINESRC__
if (op->src_file[0] != '@')
#endif
{
if (op->media) src_len += lstrlenW(op->media->root) + 1;
if (op->src_path) src_len += lstrlenW(op->src_path) + 1;
}
if (op->src_file) src_len += lstrlenW(op->src_file) + 1;
if (op->dst_path) dst_len += lstrlenW(op->dst_path) + 1;
if (op->dst_file) dst_len += lstrlenW(op->dst_file) + 1;
@ -165,7 +174,14 @@ static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
paths->Target = target = HeapAlloc( GetProcessHeap(), 0, dst_len );
}
if (!source || !target) return FALSE;
concat_W( source, op->media ? op->media->root : NULL, op->src_path, op->src_file );
#ifdef __WINESRC__
if (op->src_file[0] != '@')
#endif
concat_W( source, op->media ? op->media->root : NULL, op->src_path, op->src_file );
#ifdef __WINESRC__
else
lstrcpyW( source, op->src_file );
#endif
concat_W( target, NULL, op->dst_path, op->dst_file );
paths->Win32Error = 0;
paths->Flags = 0;
@ -1159,6 +1175,61 @@ static BOOL create_full_pathW(const WCHAR *path)
return ret;
}
#ifdef __WINESRC__
static BOOL copy_file( LPCWSTR source, LPCWSTR target )
{
WCHAR module[MAX_PATH];
HMODULE mod = NULL;
HRSRC res;
HGLOBAL data;
HANDLE handle;
DWORD size, written;
BOOL ret = FALSE;
int id = 0;
const WCHAR *p;
TRACE( "%s -> %s\n", debugstr_w(source), debugstr_w(target) );
if (source[0] != '@') return CopyFileW( source, target, FALSE );
/* Wine extension: when the source of a file copy is in the format "@file.dll,-123"
* the source data is extracted from the corresponding file.dll resource */
source++; /* skip '@' */
p = wcschr( source, ',' );
if (!p || p - source >= MAX_PATH)
{
SetLastError( ERROR_RESOURCE_DATA_NOT_FOUND );
return FALSE;
}
memcpy( module, source, (p - source) * sizeof(WCHAR) );
module[p - source] = 0;
id = -wcstol( p + 1, NULL, 10 );
if (id <= 0 || id > 0xffff ||
!(mod = LoadLibraryExW( module, 0, LOAD_LIBRARY_AS_DATAFILE )) ||
!(res = FindResourceW( mod, MAKEINTRESOURCEW(id), L"WINE_DATA_FILE" )) ||
!(data = LoadResource( mod, res )))
{
WARN( "failed to save %s #%d to %s\n", debugstr_w(module), -id, debugstr_w(target) );
if (mod) FreeLibrary( mod );
SetLastError( ERROR_RESOURCE_DATA_NOT_FOUND );
return FALSE;
}
size = SizeofResource( mod, res );
if ((handle = CreateFileW( target, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, 0, 0 )) == INVALID_HANDLE_VALUE)
{
WARN( "failed to save %s #%d to %s\n", debugstr_w(module), -id, debugstr_w(target) );
if (mod) FreeLibrary( mod );
return FALSE;
}
ret = WriteFile( handle, LockResource(data), size, &written, NULL ) && written == size;
CloseHandle( handle );
if (!ret) DeleteFileW( target );
return ret;
}
#endif // __WINESRC__
static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
PSP_FILE_CALLBACK_W handler, PVOID context )
{
@ -1363,8 +1434,8 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
{
#ifdef __REACTOS__
rc = MoveFileExW(TempFile,target,MOVEFILE_REPLACE_EXISTING);
#else
rc = CopyFileW(source,target,FALSE);
#else // __WINESRC__
rc = copy_file( source, target );
#endif
if (!rc && GetLastError() == ERROR_SHARING_VIOLATION &&
(style & SP_COPY_IN_USE_NEEDS_REBOOT))
@ -1376,7 +1447,7 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
if (GetTempPathW(MAX_PATH, temp) &&
GetTempFileNameW(temp, L"SET", 0, temp_file))
{
rc = CopyFileW(source, temp_file, FALSE);
rc = copy_file( source, temp_file );
if (rc)
rc = MoveFileExW(temp_file, target, MOVEFILE_DELAY_UNTIL_REBOOT);
else

View file

@ -10,4 +10,4 @@ files:
dlls/setupapi/setupcab.c: dll/win32/setupapi/setupcab.c
dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable_wine.c
tags:
wine: 354aabd77e4ff3747446b2402de89d804001bd3f
wine: 5696c3c23d5be9f5ce57ef7e361d88722120da09