[WINESYNC] setupapi: Separate the entire copy operation into a helper function.

So as to centralize SPFILENOTIFY_COPYERROR callbacks into one place.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 3cb621e6ca78064adeb2415bf3467e476e9eba6a by Zebediah Figura <z.figura12@gmail.com>

[WINESYNC] setupapi: Keep track of source media in a separate list.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 31bb0097ad85090b1e006ade020c68aa5582dc0c by Zebediah Figura <z.figura12@gmail.com>
This commit is contained in:
winesync 2023-09-28 22:28:50 +02:00 committed by Hermès Bélusca-Maïto
parent 90e557fd4e
commit 0413993a2c
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 93 additions and 84 deletions

View file

@ -44,20 +44,24 @@ struct default_callback_context
DWORD_PTR unk3[5];
};
struct source_media
{
WCHAR root[MAX_PATH];
WCHAR *desc, *tag;
};
struct file_op
{
struct file_op *next;
UINT style;
WCHAR *src_root;
WCHAR *src_path;
WCHAR *src_file;
WCHAR *src_descr;
WCHAR *src_tag;
WCHAR *dst_path;
WCHAR *dst_file;
#ifdef __REACTOS__
PSECURITY_DESCRIPTOR dst_sd;
#endif
struct source_media *media;
};
struct file_op_queue
@ -72,7 +76,9 @@ struct file_queue
struct file_op_queue copy_queue;
struct file_op_queue delete_queue;
struct file_op_queue rename_queue;
DWORD flags;
DWORD flags;
struct source_media **sources;
unsigned int source_count;
};
@ -93,11 +99,8 @@ static void free_file_op_queue( struct file_op_queue *queue )
while( op )
{
HeapFree( GetProcessHeap(), 0, op->src_root );
HeapFree( GetProcessHeap(), 0, op->src_path );
HeapFree( GetProcessHeap(), 0, op->src_file );
HeapFree( GetProcessHeap(), 0, op->src_descr );
HeapFree( GetProcessHeap(), 0, op->src_tag );
HeapFree( GetProcessHeap(), 0, op->dst_path );
#ifdef __REACTOS__
if (op->dst_sd) LocalFree(op->dst_sd);
@ -144,7 +147,7 @@ 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->src_root) src_len += strlenW(op->src_root) + 1;
if (op->media) src_len += strlenW(op->media->root) + 1;
if (op->src_path) src_len += strlenW(op->src_path) + 1;
if (op->src_file) src_len += strlenW(op->src_file) + 1;
if (op->dst_path) dst_len += strlenW(op->dst_path) + 1;
@ -163,7 +166,7 @@ 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->src_root, op->src_path, op->src_file );
concat_W( source, op->media ? op->media->root : NULL, op->src_path, op->src_file );
concat_W( target, NULL, op->dst_path, op->dst_file );
paths->Win32Error = 0;
paths->Flags = 0;
@ -504,10 +507,18 @@ HSPFILEQ WINAPI SetupOpenFileQueue(void)
BOOL WINAPI SetupCloseFileQueue( HSPFILEQ handle )
{
struct file_queue *queue = handle;
unsigned int i;
free_file_op_queue( &queue->copy_queue );
free_file_op_queue( &queue->rename_queue );
free_file_op_queue( &queue->delete_queue );
for (i = 0; i < queue->source_count; ++i)
{
heap_free( queue->sources[i]->desc );
heap_free( queue->sources[i]->tag );
heap_free( queue->sources[i] );
}
heap_free( queue->sources );
HeapFree( GetProcessHeap(), 0, queue );
return TRUE;
}
@ -547,22 +558,48 @@ BOOL WINAPI SetupQueueCopyIndirectA( SP_FILE_COPY_PARAMS_A *paramsA )
return ret;
}
static BOOL equal_str(const WCHAR *a, const WCHAR *b)
{
return (!a && !b) || (a && b && !strcmpW(a, b));
}
static struct source_media *get_source_media(struct file_queue *queue,
const WCHAR *root, const WCHAR *desc, const WCHAR *tag)
{
unsigned int i;
for (i = 0; i < queue->source_count; ++i)
{
if (!strcmpW(root, queue->sources[i]->root)
&& equal_str(desc, queue->sources[i]->desc)
&& equal_str(tag, queue->sources[i]->tag))
{
return queue->sources[i];
}
}
queue->sources = heap_realloc( queue->sources, ++queue->source_count * sizeof(*queue->sources) );
queue->sources[i] = heap_alloc( sizeof(*queue->sources[i]) );
strcpyW(queue->sources[i]->root, root);
queue->sources[i]->desc = strdupW(desc);
queue->sources[i]->tag = strdupW(tag);
return queue->sources[i];
}
/***********************************************************************
* SetupQueueCopyIndirectW (SETUPAPI.@)
*/
BOOL WINAPI SetupQueueCopyIndirectW( PSP_FILE_COPY_PARAMS_W params )
{
static const WCHAR emptyW[] = {0};
struct file_queue *queue = params->QueueHandle;
struct file_op *op;
if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
op->style = params->CopyStyle;
op->src_root = strdupW( params->SourceRootPath );
op->src_path = strdupW( params->SourcePath );
op->src_file = strdupW( params->SourceFilename );
op->src_descr = strdupW( params->SourceDescription );
op->src_tag = strdupW( params->SourceTagfile );
op->dst_path = strdupW( params->TargetDirectory );
op->dst_file = strdupW( params->TargetFilename );
#ifdef __REACTOS__
@ -583,10 +620,13 @@ BOOL WINAPI SetupQueueCopyIndirectW( PSP_FILE_COPY_PARAMS_W params )
FIXME("Unhandled LayoutInf %p.\n", params->LayoutInf);
#endif
op->media = get_source_media( queue, params->SourceRootPath ? params->SourceRootPath : emptyW,
params->SourceDescription, params->SourceTagfile );
TRACE( "root=%s path=%s file=%s -> dir=%s file=%s descr=%s tag=%s\n",
debugstr_w(op->src_root), debugstr_w(op->src_path), debugstr_w(op->src_file),
debugstr_w(op->media->root), debugstr_w(op->src_path), debugstr_w(op->src_file),
debugstr_w(op->dst_path), debugstr_w(op->dst_file),
debugstr_w(op->src_descr), debugstr_w(op->src_tag) );
debugstr_w(op->media->desc), debugstr_w(op->media->tag) );
queue_file_op( &queue->copy_queue, op );
return TRUE;
@ -718,18 +758,9 @@ BOOL WINAPI SetupQueueDeleteA( HSPFILEQ handle, PCSTR part1, PCSTR part2 )
struct file_queue *queue = handle;
struct file_op *op;
if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
op->style = 0;
op->src_root = NULL;
op->src_path = NULL;
op->src_file = NULL;
op->src_descr = NULL;
op->src_tag = NULL;
op->dst_path = strdupAtoW( part1 );
op->dst_file = strdupAtoW( part2 );
#ifdef __REACTOS__
op->dst_sd = NULL;
#endif
if (!(op = heap_alloc_zero( sizeof(*op) ))) return FALSE;
op->dst_path = strdupAtoW( part1 );
op->dst_file = strdupAtoW( part2 );
queue_file_op( &queue->delete_queue, op );
return TRUE;
}
@ -743,18 +774,9 @@ BOOL WINAPI SetupQueueDeleteW( HSPFILEQ handle, PCWSTR part1, PCWSTR part2 )
struct file_queue *queue = handle;
struct file_op *op;
if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
op->style = 0;
op->src_root = NULL;
op->src_path = NULL;
op->src_file = NULL;
op->src_descr = NULL;
op->src_tag = NULL;
op->dst_path = strdupW( part1 );
op->dst_file = strdupW( part2 );
#ifdef __REACTOS__
op->dst_sd = NULL;
#endif
if (!(op = heap_alloc_zero( sizeof(*op) ))) return FALSE;
op->dst_path = strdupW( part1 );
op->dst_file = strdupW( part2 );
queue_file_op( &queue->delete_queue, op );
return TRUE;
}
@ -769,18 +791,11 @@ BOOL WINAPI SetupQueueRenameA( HSPFILEQ handle, PCSTR SourcePath, PCSTR SourceFi
struct file_queue *queue = handle;
struct file_op *op;
if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
op->style = 0;
op->src_root = NULL;
op->src_path = strdupAtoW( SourcePath );
op->src_file = strdupAtoW( SourceFilename );
op->src_descr = NULL;
op->src_tag = NULL;
op->dst_path = strdupAtoW( TargetPath );
op->dst_file = strdupAtoW( TargetFilename );
#ifdef __REACTOS__
op->dst_sd = NULL;
#endif
if (!(op = heap_alloc_zero( sizeof(*op) ))) return FALSE;
op->src_path = strdupAtoW( SourcePath );
op->src_file = strdupAtoW( SourceFilename );
op->dst_path = strdupAtoW( TargetPath );
op->dst_file = strdupAtoW( TargetFilename );
queue_file_op( &queue->rename_queue, op );
return TRUE;
}
@ -795,18 +810,11 @@ BOOL WINAPI SetupQueueRenameW( HSPFILEQ handle, PCWSTR SourcePath, PCWSTR Source
struct file_queue *queue = handle;
struct file_op *op;
if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
op->style = 0;
op->src_root = NULL;
op->src_path = strdupW( SourcePath );
op->src_file = strdupW( SourceFilename );
op->src_descr = NULL;
op->src_tag = NULL;
op->dst_path = strdupW( TargetPath );
op->dst_file = strdupW( TargetFilename );
#ifdef __REACTOS__
op->dst_sd = NULL;
#endif
if (!(op = heap_alloc_zero( sizeof(*op) ))) return FALSE;
op->src_path = strdupW( SourcePath );
op->src_file = strdupW( SourceFilename );
op->dst_path = strdupW( TargetPath );
op->dst_file = strdupW( TargetFilename );
queue_file_op( &queue->rename_queue, op );
return TRUE;
}
@ -1473,6 +1481,24 @@ BOOL WINAPI SetupInstallFileW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source
return SetupInstallFileExW( hinf, inf_context, source, root, dest, style, handler, context, NULL );
}
static BOOL queue_copy_file( const WCHAR *source, const WCHAR *dest,
const struct file_op *op, PSP_FILE_CALLBACK_W handler, void *context )
{
TRACE("copying file %s -> %s\n", debugstr_w(source), debugstr_w(dest));
if (op->dst_path && !create_full_pathW(op->dst_path))
return FALSE;
if (do_file_copyW(source, dest, op->style, handler, context))
return TRUE;
/* try to extract it from the cabinet file */
if (op->media->tag && extract_cabinet_file(op->media->tag, op->media->root, op->src_file, dest))
return TRUE;
return FALSE;
}
/***********************************************************************
* SetupCommitFileQueueW (SETUPAPI.@)
*/
@ -1557,27 +1583,10 @@ BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBAC
if (op_result == FILEOP_NEWPATH) op_result = FILEOP_DOIT;
while (op_result == FILEOP_DOIT || op_result == FILEOP_NEWPATH)
{
TRACE( "copying file %s -> %s\n",
debugstr_w( op_result == FILEOP_NEWPATH ? newpath : paths.Source ),
debugstr_w(paths.Target) );
if (op->dst_path)
{
if (!create_full_pathW( op->dst_path ))
{
paths.Win32Error = GetLastError();
op_result = handler( context, SPFILENOTIFY_COPYERROR,
(UINT_PTR)&paths, (UINT_PTR)newpath );
if (op_result == FILEOP_ABORT) goto done;
}
}
if (do_file_copyW( op_result == FILEOP_NEWPATH ? newpath : paths.Source,
paths.Target, op->style, handler, context )) break; /* success */
/* try to extract it from the cabinet file */
if (op->src_tag)
{
if (extract_cabinet_file( op->src_tag, op->src_root,
op->src_file, paths.Target )) break;
}
if (queue_copy_file( op_result == FILEOP_NEWPATH ? newpath : paths.Source,
paths.Target, op, handler, context ))
break;
paths.Win32Error = GetLastError();
op_result = handler( context, SPFILENOTIFY_COPYERROR,
(UINT_PTR)&paths, (UINT_PTR)newpath );

View file

@ -8,4 +8,4 @@ files:
dlls/setupapi/setupcab.c: dll/win32/setupapi/setupcab.c
dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable_wine.c
tags:
wine: ee36f923c59d9ba51b429247df90e0ed30592e62
wine: 31bb0097ad85090b1e006ade020c68aa5582dc0c