2 * Setupapi file queue routines
4 * Copyright 2002 Alexandre Julliard for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "setupapi_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(setupapi
);
25 /* context structure for the default queue callback */
26 struct default_callback_context
55 struct file_op_queue copy_queue
;
56 struct file_op_queue delete_queue
;
57 struct file_op_queue rename_queue
;
62 inline static WCHAR
*strdupW( const WCHAR
*str
)
67 int len
= (strlenW(str
) + 1) * sizeof(WCHAR
);
68 if ((ret
= HeapAlloc( GetProcessHeap(), 0, len
))) memcpy( ret
, str
, len
);
74 inline static WCHAR
*strdupAtoW( const char *str
)
79 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
80 if ((ret
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
81 MultiByteToWideChar( CP_ACP
, 0, str
, -1, ret
, len
);
86 inline static char *strdupWtoA( const WCHAR
*str
)
91 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1, NULL
, 0, NULL
, NULL
);
92 if ((ret
= HeapAlloc( GetProcessHeap(), 0, len
)))
93 WideCharToMultiByte( CP_ACP
, 0, str
, -1, ret
, len
, NULL
, NULL
);
98 /* append a file operation to a queue */
99 inline static void queue_file_op( struct file_op_queue
*queue
, struct file_op
*op
)
102 if (queue
->tail
) queue
->tail
->next
= op
;
103 else queue
->head
= op
;
108 /* free all the file operations on a given queue */
109 static void free_file_op_queue( struct file_op_queue
*queue
)
111 struct file_op
*t
, *op
= queue
->head
;
115 HeapFree( GetProcessHeap(), 0, op
->src_root
);
116 HeapFree( GetProcessHeap(), 0, op
->src_path
);
117 HeapFree( GetProcessHeap(), 0, op
->src_file
);
118 HeapFree( GetProcessHeap(), 0, op
->src_descr
);
119 HeapFree( GetProcessHeap(), 0, op
->src_tag
);
120 HeapFree( GetProcessHeap(), 0, op
->dst_path
);
121 if (op
->dst_file
!= op
->src_file
) HeapFree( GetProcessHeap(), 0, op
->dst_file
);
124 HeapFree( GetProcessHeap(), 0, t
);
128 /* concat 3 strings to make a path, handling separators correctly */
129 static void concat_W( WCHAR
*buffer
, const WCHAR
*src1
, const WCHAR
*src2
, const WCHAR
*src3
)
134 strcpyW( buffer
, src1
);
135 buffer
+= strlenW(buffer
);
136 if (buffer
[-1] != '\\') *buffer
++ = '\\';
137 if (src2
) while (*src2
== '\\') src2
++;
142 strcpyW( buffer
, src2
);
143 buffer
+= strlenW(buffer
);
144 if (buffer
[-1] != '\\') *buffer
++ = '\\';
145 if (src3
) while (*src3
== '\\') src3
++;
149 strcpyW( buffer
, src3
);
150 buffer
+= strlenW(buffer
);
155 /***********************************************************************
158 * Build a FILEPATHS_W structure for a given file operation.
160 static BOOL
build_filepathsW( const struct file_op
*op
, FILEPATHS_W
*paths
)
162 unsigned int src_len
= 1, dst_len
= 1;
163 WCHAR
*source
= (PWSTR
)paths
->Source
, *target
= (PWSTR
)paths
->Target
;
165 if (op
->src_root
) src_len
+= strlenW(op
->src_root
) + 1;
166 if (op
->src_path
) src_len
+= strlenW(op
->src_path
) + 1;
167 if (op
->src_file
) src_len
+= strlenW(op
->src_file
) + 1;
168 if (op
->dst_path
) dst_len
+= strlenW(op
->dst_path
) + 1;
169 if (op
->dst_file
) dst_len
+= strlenW(op
->dst_file
) + 1;
170 src_len
*= sizeof(WCHAR
);
171 dst_len
*= sizeof(WCHAR
);
173 if (!source
|| HeapSize( GetProcessHeap(), 0, source
) < src_len
)
175 HeapFree( GetProcessHeap(), 0, source
);
176 paths
->Source
= source
= HeapAlloc( GetProcessHeap(), 0, src_len
);
178 if (!target
|| HeapSize( GetProcessHeap(), 0, target
) < dst_len
)
180 HeapFree( GetProcessHeap(), 0, target
);
181 paths
->Target
= target
= HeapAlloc( GetProcessHeap(), 0, dst_len
);
183 if (!source
|| !target
) return FALSE
;
184 concat_W( source
, op
->src_root
, op
->src_path
, op
->src_file
);
185 concat_W( target
, NULL
, op
->dst_path
, op
->dst_file
);
186 paths
->Win32Error
= 0;
192 /***********************************************************************
193 * QUEUE_callback_WtoA
195 * Map a file callback parameters from W to A and call the A callback.
197 UINT CALLBACK
QUEUE_callback_WtoA( void *context
, UINT notification
,
198 UINT_PTR param1
, UINT_PTR param2
)
200 struct callback_WtoA_context
*callback_ctx
= context
;
201 char buffer
[MAX_PATH
];
203 UINT_PTR old_param2
= param2
;
207 case SPFILENOTIFY_COPYERROR
:
208 param2
= (UINT_PTR
)&buffer
;
210 case SPFILENOTIFY_STARTDELETE
:
211 case SPFILENOTIFY_ENDDELETE
:
212 case SPFILENOTIFY_DELETEERROR
:
213 case SPFILENOTIFY_STARTRENAME
:
214 case SPFILENOTIFY_ENDRENAME
:
215 case SPFILENOTIFY_RENAMEERROR
:
216 case SPFILENOTIFY_STARTCOPY
:
217 case SPFILENOTIFY_ENDCOPY
:
219 FILEPATHS_W
*pathsW
= (FILEPATHS_W
*)param1
;
222 pathsA
.Source
= strdupWtoA( pathsW
->Source
);
223 pathsA
.Target
= strdupWtoA( pathsW
->Target
);
224 pathsA
.Win32Error
= pathsW
->Win32Error
;
225 pathsA
.Flags
= pathsW
->Flags
;
226 ret
= callback_ctx
->orig_handler( callback_ctx
->orig_context
, notification
,
227 (UINT_PTR
)&pathsA
, param2
);
228 HeapFree( GetProcessHeap(), 0, (void *)pathsA
.Source
);
229 HeapFree( GetProcessHeap(), 0, (void *)pathsA
.Target
);
231 if (notification
== SPFILENOTIFY_COPYERROR
)
232 MultiByteToWideChar( CP_ACP
, 0, buffer
, -1, (WCHAR
*)old_param2
, MAX_PATH
);
235 case SPFILENOTIFY_STARTREGISTRATION
:
236 case SPFILENOTIFY_ENDREGISTRATION
:
238 SP_REGISTER_CONTROL_STATUSW
*statusW
= (SP_REGISTER_CONTROL_STATUSW
*)param1
;
239 SP_REGISTER_CONTROL_STATUSA statusA
;
241 statusA
.cbSize
= sizeof(statusA
);
242 statusA
.FileName
= strdupWtoA( statusW
->FileName
);
243 statusA
.Win32Error
= statusW
->Win32Error
;
244 statusA
.FailureCode
= statusW
->FailureCode
;
245 ret
= callback_ctx
->orig_handler( callback_ctx
->orig_context
, notification
,
246 (UINT_PTR
)&statusA
, param2
);
247 HeapFree( GetProcessHeap(), 0, (LPSTR
)statusA
.FileName
);
251 case SPFILENOTIFY_NEEDMEDIA
:
252 case SPFILENOTIFY_QUEUESCAN
:
253 FIXME("mapping for %d not implemented\n",notification
);
254 case SPFILENOTIFY_STARTQUEUE
:
255 case SPFILENOTIFY_ENDQUEUE
:
256 case SPFILENOTIFY_STARTSUBQUEUE
:
257 case SPFILENOTIFY_ENDSUBQUEUE
:
259 ret
= callback_ctx
->orig_handler( callback_ctx
->orig_context
, notification
, param1
, param2
);
266 /***********************************************************************
269 * Retrieve the source file information for a given file.
271 static void get_src_file_info( HINF hinf
, struct file_op
*op
)
273 static const WCHAR SourceDisksNames
[] =
274 {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
275 static const WCHAR SourceDisksFiles
[] =
276 {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
278 INFCONTEXT file_ctx
, disk_ctx
;
282 /* find the SourceDisksFiles entry */
283 if (!SetupFindFirstLineW( hinf
, SourceDisksFiles
, op
->src_file
, &file_ctx
))
285 if ((op
->style
& (SP_COPY_SOURCE_ABSOLUTE
|SP_COPY_SOURCEPATH_ABSOLUTE
))) return;
286 /* no specific info, use .inf file source directory */
287 if (!op
->src_root
) op
->src_root
= PARSER_get_src_root( hinf
);
290 if (!SetupGetIntField( &file_ctx
, 1, &diskid
)) return;
292 /* now find the diskid in the SourceDisksNames section */
293 if (!SetupFindFirstLineW( hinf
, SourceDisksNames
, NULL
, &disk_ctx
)) return;
296 if (SetupGetIntField( &disk_ctx
, 0, &id
) && (id
== diskid
)) break;
297 if (!SetupFindNextLine( &disk_ctx
, &disk_ctx
)) return;
300 /* and fill in the missing info */
304 if (SetupGetStringFieldW( &disk_ctx
, 1, NULL
, 0, &len
) &&
305 (op
->src_descr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) )))
306 SetupGetStringFieldW( &disk_ctx
, 1, op
->src_descr
, len
, NULL
);
310 if (SetupGetStringFieldW( &disk_ctx
, 2, NULL
, 0, &len
) &&
311 (op
->src_tag
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) )))
312 SetupGetStringFieldW( &disk_ctx
, 2, op
->src_tag
, len
, NULL
);
314 if (!op
->src_path
&& !(op
->style
& SP_COPY_SOURCE_ABSOLUTE
))
316 if (!(op
->style
& SP_COPY_SOURCEPATH_ABSOLUTE
))
318 /* retrieve relative path for this disk */
319 if (!SetupGetStringFieldW( &disk_ctx
, 4, NULL
, 0, &len
)) len
= 0;
321 /* retrieve relative path for this file */
322 if (!SetupGetStringFieldW( &file_ctx
, 2, NULL
, 0, &len2
)) len2
= 0;
325 (op
->src_path
= HeapAlloc( GetProcessHeap(), 0, (len
+len2
)*sizeof(WCHAR
) )))
327 WCHAR
*ptr
= op
->src_path
;
330 SetupGetStringFieldW( &disk_ctx
, 4, op
->src_path
, len
, NULL
);
331 ptr
= op
->src_path
+ strlenW(op
->src_path
);
332 if (len2
&& ptr
> op
->src_path
&& ptr
[-1] != '\\') *ptr
++ = '\\';
334 if (!SetupGetStringFieldW( &disk_ctx
, 4, ptr
, len2
, NULL
)) *ptr
= 0;
337 if (!op
->src_root
) op
->src_root
= PARSER_get_src_root(hinf
);
341 /***********************************************************************
342 * get_destination_dir
344 * Retrieve the destination dir for a given section.
346 static WCHAR
*get_destination_dir( HINF hinf
, const WCHAR
*section
)
348 static const WCHAR Dest
[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
349 static const WCHAR Def
[] = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};
352 if (!SetupFindFirstLineW( hinf
, Dest
, section
, &context
) &&
353 !SetupFindFirstLineW( hinf
, Dest
, Def
, &context
)) return NULL
;
354 return PARSER_get_dest_dir( &context
);
358 static void (WINAPI
*pExtractFiles
)( LPSTR
, LPSTR
, DWORD
, DWORD
, DWORD
, DWORD
);
360 /***********************************************************************
361 * extract_cabinet_file
363 * Extract a file from a .cab file.
365 static BOOL
extract_cabinet_file( const WCHAR
*cabinet
, const WCHAR
*root
,
366 const WCHAR
*src
, const WCHAR
*dst
)
368 static const WCHAR extW
[] = {'.','c','a','b',0};
369 static HMODULE advpack
;
371 char *cab_path
, *cab_file
;
372 int len
= strlenW( cabinet
);
374 /* make sure the cabinet file has a .cab extension */
375 if (len
<= 4 || strcmpiW( cabinet
+ len
- 4, extW
)) return FALSE
;
378 if (!advpack
&& !(advpack
= LoadLibraryA( "advpack.dll" )))
380 ERR( "could not load advpack.dll\n" );
383 if (!(pExtractFiles
= (void *)GetProcAddress( advpack
, "ExtractFiles" )))
385 ERR( "could not find ExtractFiles in advpack.dll\n" );
390 if (!(cab_path
= strdupWtoA( root
))) return FALSE
;
391 len
= WideCharToMultiByte( CP_ACP
, 0, cabinet
, -1, NULL
, 0, NULL
, NULL
);
392 if (!(cab_file
= HeapAlloc( GetProcessHeap(), 0, strlen(cab_path
) + len
+ 1 )))
394 HeapFree( GetProcessHeap(), 0, cab_path
);
397 strcpy( cab_file
, cab_path
);
398 if (cab_file
[0] && cab_file
[strlen(cab_file
)-1] != '\\') strcat( cab_file
, "\\" );
399 WideCharToMultiByte( CP_ACP
, 0, cabinet
, -1, cab_file
+ strlen(cab_file
), len
, NULL
, NULL
);
400 FIXME( "awful hack: extracting cabinet %s\n", debugstr_a(cab_file
) );
401 pExtractFiles( cab_file
, cab_path
, 0, 0, 0, 0 );
402 HeapFree( GetProcessHeap(), 0, cab_file
);
403 HeapFree( GetProcessHeap(), 0, cab_path
);
404 return CopyFileW( src
, dst
, FALSE
/*FIXME*/ );
408 /***********************************************************************
409 * SetupOpenFileQueue (SETUPAPI.@)
411 HSPFILEQ WINAPI
SetupOpenFileQueue(void)
413 struct file_queue
*queue
;
415 if (!(queue
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*queue
))))
416 return (HSPFILEQ
)INVALID_HANDLE_VALUE
;
421 /***********************************************************************
422 * SetupCloseFileQueue (SETUPAPI.@)
424 BOOL WINAPI
SetupCloseFileQueue( HSPFILEQ handle
)
426 struct file_queue
*queue
= handle
;
428 free_file_op_queue( &queue
->copy_queue
);
429 free_file_op_queue( &queue
->rename_queue
);
430 free_file_op_queue( &queue
->delete_queue
);
431 HeapFree( GetProcessHeap(), 0, queue
);
436 /***********************************************************************
437 * SetupQueueCopyIndirectA (SETUPAPI.@)
439 BOOL WINAPI
SetupQueueCopyIndirectA( PSP_FILE_COPY_PARAMS_A params
)
441 struct file_queue
*queue
= params
->QueueHandle
;
444 if (!(op
= HeapAlloc( GetProcessHeap(), 0, sizeof(*op
) ))) return FALSE
;
445 op
->style
= params
->CopyStyle
;
446 op
->src_root
= strdupAtoW( params
->SourceRootPath
);
447 op
->src_path
= strdupAtoW( params
->SourcePath
);
448 op
->src_file
= strdupAtoW( params
->SourceFilename
);
449 op
->src_descr
= strdupAtoW( params
->SourceDescription
);
450 op
->src_tag
= strdupAtoW( params
->SourceTagfile
);
451 op
->dst_path
= strdupAtoW( params
->TargetDirectory
);
452 op
->dst_file
= strdupAtoW( params
->TargetFilename
);
455 if (!op
->src_file
) op
->src_file
= op
->dst_file
;
456 if (params
->LayoutInf
)
458 get_src_file_info( params
->LayoutInf
, op
);
459 if (!op
->dst_path
) op
->dst_path
= get_destination_dir( params
->LayoutInf
, op
->dst_file
);
462 TRACE( "root=%s path=%s file=%s -> dir=%s file=%s descr=%s tag=%s\n",
463 debugstr_w(op
->src_root
), debugstr_w(op
->src_path
), debugstr_w(op
->src_file
),
464 debugstr_w(op
->dst_path
), debugstr_w(op
->dst_file
),
465 debugstr_w(op
->src_descr
), debugstr_w(op
->src_tag
) );
467 queue_file_op( &queue
->copy_queue
, op
);
472 /***********************************************************************
473 * SetupQueueCopyIndirectW (SETUPAPI.@)
475 BOOL WINAPI
SetupQueueCopyIndirectW( PSP_FILE_COPY_PARAMS_W params
)
477 struct file_queue
*queue
= params
->QueueHandle
;
480 if (!(op
= HeapAlloc( GetProcessHeap(), 0, sizeof(*op
) ))) return FALSE
;
481 op
->style
= params
->CopyStyle
;
482 op
->src_root
= strdupW( params
->SourceRootPath
);
483 op
->src_path
= strdupW( params
->SourcePath
);
484 op
->src_file
= strdupW( params
->SourceFilename
);
485 op
->src_descr
= strdupW( params
->SourceDescription
);
486 op
->src_tag
= strdupW( params
->SourceTagfile
);
487 op
->dst_path
= strdupW( params
->TargetDirectory
);
488 op
->dst_file
= strdupW( params
->TargetFilename
);
491 if (!op
->src_file
) op
->src_file
= op
->dst_file
;
492 if (params
->LayoutInf
)
494 get_src_file_info( params
->LayoutInf
, op
);
495 if (!op
->dst_path
) op
->dst_path
= get_destination_dir( params
->LayoutInf
, op
->dst_file
);
498 TRACE( "root=%s path=%s file=%s -> dir=%s file=%s descr=%s tag=%s\n",
499 debugstr_w(op
->src_root
), debugstr_w(op
->src_path
), debugstr_w(op
->src_file
),
500 debugstr_w(op
->dst_path
), debugstr_w(op
->dst_file
),
501 debugstr_w(op
->src_descr
), debugstr_w(op
->src_tag
) );
503 queue_file_op( &queue
->copy_queue
, op
);
508 /***********************************************************************
509 * SetupQueueCopyA (SETUPAPI.@)
511 BOOL WINAPI
SetupQueueCopyA( HSPFILEQ queue
, PCSTR src_root
, PCSTR src_path
, PCSTR src_file
,
512 PCSTR src_descr
, PCSTR src_tag
, PCSTR dst_dir
, PCSTR dst_file
,
515 SP_FILE_COPY_PARAMS_A params
;
517 params
.cbSize
= sizeof(params
);
518 params
.QueueHandle
= queue
;
519 params
.SourceRootPath
= src_root
;
520 params
.SourcePath
= src_path
;
521 params
.SourceFilename
= src_file
;
522 params
.SourceDescription
= src_descr
;
523 params
.SourceTagfile
= src_tag
;
524 params
.TargetDirectory
= dst_dir
;
525 params
.TargetFilename
= dst_file
;
526 params
.CopyStyle
= style
;
527 params
.LayoutInf
= 0;
528 params
.SecurityDescriptor
= NULL
;
529 return SetupQueueCopyIndirectA( ¶ms
);
533 /***********************************************************************
534 * SetupQueueCopyW (SETUPAPI.@)
536 BOOL WINAPI
SetupQueueCopyW( HSPFILEQ queue
, PCWSTR src_root
, PCWSTR src_path
, PCWSTR src_file
,
537 PCWSTR src_descr
, PCWSTR src_tag
, PCWSTR dst_dir
, PCWSTR dst_file
,
540 SP_FILE_COPY_PARAMS_W params
;
542 params
.cbSize
= sizeof(params
);
543 params
.QueueHandle
= queue
;
544 params
.SourceRootPath
= src_root
;
545 params
.SourcePath
= src_path
;
546 params
.SourceFilename
= src_file
;
547 params
.SourceDescription
= src_descr
;
548 params
.SourceTagfile
= src_tag
;
549 params
.TargetDirectory
= dst_dir
;
550 params
.TargetFilename
= dst_file
;
551 params
.CopyStyle
= style
;
552 params
.LayoutInf
= 0;
553 params
.SecurityDescriptor
= NULL
;
554 return SetupQueueCopyIndirectW( ¶ms
);
558 /***********************************************************************
559 * SetupQueueDefaultCopyA (SETUPAPI.@)
561 BOOL WINAPI
SetupQueueDefaultCopyA( HSPFILEQ queue
, HINF hinf
, PCSTR src_root
, PCSTR src_file
,
562 PCSTR dst_file
, DWORD style
)
564 SP_FILE_COPY_PARAMS_A params
;
566 params
.cbSize
= sizeof(params
);
567 params
.QueueHandle
= queue
;
568 params
.SourceRootPath
= src_root
;
569 params
.SourcePath
= NULL
;
570 params
.SourceFilename
= src_file
;
571 params
.SourceDescription
= NULL
;
572 params
.SourceTagfile
= NULL
;
573 params
.TargetDirectory
= NULL
;
574 params
.TargetFilename
= dst_file
;
575 params
.CopyStyle
= style
;
576 params
.LayoutInf
= hinf
;
577 params
.SecurityDescriptor
= NULL
;
578 return SetupQueueCopyIndirectA( ¶ms
);
582 /***********************************************************************
583 * SetupQueueDefaultCopyW (SETUPAPI.@)
585 BOOL WINAPI
SetupQueueDefaultCopyW( HSPFILEQ queue
, HINF hinf
, PCWSTR src_root
, PCWSTR src_file
,
586 PCWSTR dst_file
, DWORD style
)
588 SP_FILE_COPY_PARAMS_W params
;
590 params
.cbSize
= sizeof(params
);
591 params
.QueueHandle
= queue
;
592 params
.SourceRootPath
= src_root
;
593 params
.SourcePath
= NULL
;
594 params
.SourceFilename
= src_file
;
595 params
.SourceDescription
= NULL
;
596 params
.SourceTagfile
= NULL
;
597 params
.TargetDirectory
= NULL
;
598 params
.TargetFilename
= dst_file
;
599 params
.CopyStyle
= style
;
600 params
.LayoutInf
= hinf
;
601 params
.SecurityDescriptor
= NULL
;
602 return SetupQueueCopyIndirectW( ¶ms
);
606 /***********************************************************************
607 * SetupQueueDeleteA (SETUPAPI.@)
609 BOOL WINAPI
SetupQueueDeleteA( HSPFILEQ handle
, PCSTR part1
, PCSTR part2
)
611 struct file_queue
*queue
= handle
;
614 if (!(op
= HeapAlloc( GetProcessHeap(), 0, sizeof(*op
) ))) return FALSE
;
619 op
->src_descr
= NULL
;
621 op
->dst_path
= strdupAtoW( part1
);
622 op
->dst_file
= strdupAtoW( part2
);
623 queue_file_op( &queue
->delete_queue
, op
);
628 /***********************************************************************
629 * SetupQueueDeleteW (SETUPAPI.@)
631 BOOL WINAPI
SetupQueueDeleteW( HSPFILEQ handle
, PCWSTR part1
, PCWSTR part2
)
633 struct file_queue
*queue
= handle
;
636 if (!(op
= HeapAlloc( GetProcessHeap(), 0, sizeof(*op
) ))) return FALSE
;
641 op
->src_descr
= NULL
;
643 op
->dst_path
= strdupW( part1
);
644 op
->dst_file
= strdupW( part2
);
645 queue_file_op( &queue
->delete_queue
, op
);
650 /***********************************************************************
651 * SetupQueueRenameA (SETUPAPI.@)
653 BOOL WINAPI
SetupQueueRenameA( HSPFILEQ handle
, PCSTR SourcePath
, PCSTR SourceFilename
,
654 PCSTR TargetPath
, PCSTR TargetFilename
)
656 struct file_queue
*queue
= handle
;
659 if (!(op
= HeapAlloc( GetProcessHeap(), 0, sizeof(*op
) ))) return FALSE
;
662 op
->src_path
= strdupAtoW( SourcePath
);
663 op
->src_file
= strdupAtoW( SourceFilename
);
664 op
->src_descr
= NULL
;
666 op
->dst_path
= strdupAtoW( TargetPath
);
667 op
->dst_file
= strdupAtoW( TargetFilename
);
668 queue_file_op( &queue
->rename_queue
, op
);
673 /***********************************************************************
674 * SetupQueueRenameW (SETUPAPI.@)
676 BOOL WINAPI
SetupQueueRenameW( HSPFILEQ handle
, PCWSTR SourcePath
, PCWSTR SourceFilename
,
677 PCWSTR TargetPath
, PCWSTR TargetFilename
)
679 struct file_queue
*queue
= handle
;
682 if (!(op
= HeapAlloc( GetProcessHeap(), 0, sizeof(*op
) ))) return FALSE
;
685 op
->src_path
= strdupW( SourcePath
);
686 op
->src_file
= strdupW( SourceFilename
);
687 op
->src_descr
= NULL
;
689 op
->dst_path
= strdupW( TargetPath
);
690 op
->dst_file
= strdupW( TargetFilename
);
691 queue_file_op( &queue
->rename_queue
, op
);
696 /***********************************************************************
697 * SetupQueueCopySectionA (SETUPAPI.@)
699 BOOL WINAPI
SetupQueueCopySectionA( HSPFILEQ queue
, PCSTR src_root
, HINF hinf
, HINF hlist
,
700 PCSTR section
, DWORD style
)
702 UNICODE_STRING sectionW
;
705 if (!RtlCreateUnicodeStringFromAsciiz( §ionW
, section
))
707 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
711 ret
= SetupQueueCopySectionW( queue
, NULL
, hinf
, hlist
, sectionW
.Buffer
, style
);
715 if (RtlCreateUnicodeStringFromAsciiz( &srcW
, src_root
))
717 ret
= SetupQueueCopySectionW( queue
, srcW
.Buffer
, hinf
, hlist
, sectionW
.Buffer
, style
);
718 RtlFreeUnicodeString( &srcW
);
720 else SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
722 RtlFreeUnicodeString( §ionW
);
727 /***********************************************************************
728 * SetupQueueCopySectionW (SETUPAPI.@)
730 BOOL WINAPI
SetupQueueCopySectionW( HSPFILEQ queue
, PCWSTR src_root
, HINF hinf
, HINF hlist
,
731 PCWSTR section
, DWORD style
)
733 SP_FILE_COPY_PARAMS_W params
;
735 WCHAR dest
[MAX_PATH
], src
[MAX_PATH
];
738 TRACE( "hinf=%p/%p section=%s root=%s\n",
739 hinf
, hlist
, debugstr_w(section
), debugstr_w(src_root
) );
741 params
.cbSize
= sizeof(params
);
742 params
.QueueHandle
= queue
;
743 params
.SourceRootPath
= src_root
;
744 params
.SourcePath
= NULL
;
745 params
.SourceDescription
= NULL
;
746 params
.SourceTagfile
= NULL
;
747 params
.TargetFilename
= dest
;
748 params
.CopyStyle
= style
;
749 params
.LayoutInf
= hinf
;
750 params
.SecurityDescriptor
= NULL
;
752 if (!hlist
) hlist
= hinf
;
753 if (!hinf
) hinf
= hlist
;
754 if (!SetupFindFirstLineW( hlist
, section
, NULL
, &context
)) return FALSE
;
755 if (!(params
.TargetDirectory
= get_destination_dir( hinf
, section
))) return FALSE
;
758 if (!SetupGetStringFieldW( &context
, 1, dest
, sizeof(dest
)/sizeof(WCHAR
), NULL
))
760 if (!SetupGetStringFieldW( &context
, 2, src
, sizeof(src
)/sizeof(WCHAR
), NULL
)) *src
= 0;
761 if (!SetupGetIntField( &context
, 4, &flags
)) flags
= 0; /* FIXME */
763 params
.SourceFilename
= *src
? src
: NULL
;
764 if (!SetupQueueCopyIndirectW( ¶ms
)) return FALSE
;
765 } while (SetupFindNextLine( &context
, &context
));
770 /***********************************************************************
771 * SetupQueueDeleteSectionA (SETUPAPI.@)
773 BOOL WINAPI
SetupQueueDeleteSectionA( HSPFILEQ queue
, HINF hinf
, HINF hlist
, PCSTR section
)
775 UNICODE_STRING sectionW
;
778 if (RtlCreateUnicodeStringFromAsciiz( §ionW
, section
))
780 ret
= SetupQueueDeleteSectionW( queue
, hinf
, hlist
, sectionW
.Buffer
);
781 RtlFreeUnicodeString( §ionW
);
783 else SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
788 /***********************************************************************
789 * SetupQueueDeleteSectionW (SETUPAPI.@)
791 BOOL WINAPI
SetupQueueDeleteSectionW( HSPFILEQ queue
, HINF hinf
, HINF hlist
, PCWSTR section
)
795 WCHAR buffer
[MAX_PATH
];
799 TRACE( "hinf=%p/%p section=%s\n", hinf
, hlist
, debugstr_w(section
) );
801 if (!hlist
) hlist
= hinf
;
802 if (!SetupFindFirstLineW( hlist
, section
, NULL
, &context
)) return FALSE
;
803 if (!(dest_dir
= get_destination_dir( hinf
, section
))) return FALSE
;
806 if (!SetupGetStringFieldW( &context
, 1, buffer
, sizeof(buffer
)/sizeof(WCHAR
), NULL
))
808 if (!SetupGetIntField( &context
, 4, &flags
)) flags
= 0;
809 if (!SetupQueueDeleteW( queue
, dest_dir
, buffer
)) goto done
;
810 } while (SetupFindNextLine( &context
, &context
));
814 HeapFree( GetProcessHeap(), 0, dest_dir
);
819 /***********************************************************************
820 * SetupQueueRenameSectionA (SETUPAPI.@)
822 BOOL WINAPI
SetupQueueRenameSectionA( HSPFILEQ queue
, HINF hinf
, HINF hlist
, PCSTR section
)
824 UNICODE_STRING sectionW
;
827 if (RtlCreateUnicodeStringFromAsciiz( §ionW
, section
))
829 ret
= SetupQueueRenameSectionW( queue
, hinf
, hlist
, sectionW
.Buffer
);
830 RtlFreeUnicodeString( §ionW
);
832 else SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
837 /***********************************************************************
838 * SetupQueueRenameSectionW (SETUPAPI.@)
840 BOOL WINAPI
SetupQueueRenameSectionW( HSPFILEQ queue
, HINF hinf
, HINF hlist
, PCWSTR section
)
844 WCHAR src
[MAX_PATH
], dst
[MAX_PATH
];
847 TRACE( "hinf=%p/%p section=%s\n", hinf
, hlist
, debugstr_w(section
) );
849 if (!hlist
) hlist
= hinf
;
850 if (!SetupFindFirstLineW( hlist
, section
, NULL
, &context
)) return FALSE
;
851 if (!(dest_dir
= get_destination_dir( hinf
, section
))) return FALSE
;
854 if (!SetupGetStringFieldW( &context
, 1, dst
, sizeof(dst
)/sizeof(WCHAR
), NULL
))
856 if (!SetupGetStringFieldW( &context
, 2, src
, sizeof(src
)/sizeof(WCHAR
), NULL
))
858 if (!SetupQueueRenameW( queue
, dest_dir
, src
, NULL
, dst
)) goto done
;
859 } while (SetupFindNextLine( &context
, &context
));
863 HeapFree( GetProcessHeap(), 0, dest_dir
);
868 /***********************************************************************
869 * SetupCommitFileQueueA (SETUPAPI.@)
871 BOOL WINAPI
SetupCommitFileQueueA( HWND owner
, HSPFILEQ queue
, PSP_FILE_CALLBACK_A handler
,
874 struct callback_WtoA_context ctx
;
876 ctx
.orig_context
= context
;
877 ctx
.orig_handler
= handler
;
878 return SetupCommitFileQueueW( owner
, queue
, QUEUE_callback_WtoA
, &ctx
);
882 /***********************************************************************
885 * Recursively create all directories in the path.
887 static BOOL
create_full_pathW(const WCHAR
*path
)
893 new_path
= HeapAlloc(GetProcessHeap(), 0, (strlenW(path
) + 1) * sizeof(WCHAR
));
894 strcpyW(new_path
, path
);
896 while((len
= strlenW(new_path
)) && new_path
[len
- 1] == '\\')
897 new_path
[len
- 1] = 0;
899 while(!CreateDirectoryW(new_path
, NULL
))
902 DWORD last_error
= GetLastError();
904 if(last_error
== ERROR_ALREADY_EXISTS
)
907 if(last_error
!= ERROR_PATH_NOT_FOUND
)
913 if(!(slash
= strrchrW(new_path
, '\\')))
919 len
= slash
- new_path
;
921 if(!create_full_pathW(new_path
))
926 new_path
[len
] = '\\';
929 HeapFree(GetProcessHeap(), 0, new_path
);
933 static BOOL
do_file_copyW( LPCWSTR source
, LPCWSTR target
, DWORD style
)
938 TRACE("copy %s to %s style 0x%lx\n",debugstr_w(source
),debugstr_w(target
),style
);
940 /* before copy processing */
941 if (style
& SP_COPY_REPLACEONLY
)
943 if (GetFileAttributesW(target
) == INVALID_FILE_ATTRIBUTES
)
946 if (style
& (SP_COPY_NEWER_OR_SAME
| SP_COPY_NEWER_ONLY
| SP_COPY_FORCE_NEWER
))
948 DWORD VersionSizeSource
=0;
949 DWORD VersionSizeTarget
=0;
953 * This is sort of an interesting workaround. You see, calling
954 * GetVersionInfoSize on a builtin dll loads that dll into memory
955 * and we do not properly unload builtin dlls.. so we effectively
956 * lock into memory all the targets we are replacing. This leads
957 * to problems when we try to register the replaced dlls.
959 * So I will test for the existence of the files first so that
960 * we just basically unconditionally replace the builtin versions.
962 if ((GetFileAttributesW(target
) != INVALID_FILE_ATTRIBUTES
) &&
963 (GetFileAttributesW(source
) != INVALID_FILE_ATTRIBUTES
))
965 VersionSizeSource
= GetFileVersionInfoSizeW((LPWSTR
)source
,&zero
);
966 VersionSizeTarget
= GetFileVersionInfoSizeW((LPWSTR
)target
,&zero
);
969 TRACE("SizeTarget %li ... SizeSource %li\n",VersionSizeTarget
,
972 if (VersionSizeSource
&& VersionSizeTarget
)
974 LPVOID VersionSource
;
975 LPVOID VersionTarget
;
976 VS_FIXEDFILEINFO
*TargetInfo
;
977 VS_FIXEDFILEINFO
*SourceInfo
;
979 WCHAR SubBlock
[2]={'\\',0};
982 VersionSource
= HeapAlloc(GetProcessHeap(),0,VersionSizeSource
);
983 VersionTarget
= HeapAlloc(GetProcessHeap(),0,VersionSizeTarget
);
985 ret
= GetFileVersionInfoW((LPWSTR
)source
,0,VersionSizeSource
,VersionSource
);
987 ret
= GetFileVersionInfoW((LPWSTR
)target
, 0, VersionSizeTarget
,
992 ret
= VerQueryValueW(VersionSource
, SubBlock
,
993 (LPVOID
*)&SourceInfo
, &length
);
995 ret
= VerQueryValueW(VersionTarget
, SubBlock
,
996 (LPVOID
*)&TargetInfo
, &length
);
1000 TRACE("Versions: Source %li.%li target %li.%li\n",
1001 SourceInfo
->dwFileVersionMS
, SourceInfo
->dwFileVersionLS
,
1002 TargetInfo
->dwFileVersionMS
, TargetInfo
->dwFileVersionLS
);
1004 if (TargetInfo
->dwFileVersionMS
> SourceInfo
->dwFileVersionMS
)
1006 FIXME("Notify that target version is greater..\n");
1009 else if ((TargetInfo
->dwFileVersionMS
== SourceInfo
->dwFileVersionMS
)
1010 && (TargetInfo
->dwFileVersionLS
> SourceInfo
->dwFileVersionLS
))
1012 FIXME("Notify that target version is greater..\n");
1015 else if ((style
& SP_COPY_NEWER_ONLY
) &&
1016 (TargetInfo
->dwFileVersionMS
==
1017 SourceInfo
->dwFileVersionMS
)
1018 &&(TargetInfo
->dwFileVersionLS
==
1019 SourceInfo
->dwFileVersionLS
))
1021 FIXME("Notify that target version is greater..\n");
1026 HeapFree(GetProcessHeap(),0,VersionSource
);
1027 HeapFree(GetProcessHeap(),0,VersionTarget
);
1030 if (style
& (SP_COPY_NOOVERWRITE
| SP_COPY_FORCE_NOOVERWRITE
))
1032 if (GetFileAttributesW(target
) != INVALID_FILE_ATTRIBUTES
)
1034 FIXME("Notify user target file exists\n");
1038 if (style
& (SP_COPY_NODECOMP
| SP_COPY_LANGUAGEAWARE
| SP_COPY_FORCE_IN_USE
|
1039 SP_COPY_IN_USE_NEEDS_REBOOT
| SP_COPY_NOSKIP
| SP_COPY_WARNIFSKIP
))
1041 ERR("Unsupported style(s) 0x%lx\n",style
);
1046 rc
= CopyFileW(source
,target
,FALSE
);
1047 TRACE("Did copy... rc was %i\n",rc
);
1050 /* after copy processing */
1051 if (style
& SP_COPY_DELETESOURCE
)
1054 DeleteFileW(source
);
1060 /***********************************************************************
1061 * SetupCommitFileQueueW (SETUPAPI.@)
1063 BOOL WINAPI
SetupCommitFileQueueW( HWND owner
, HSPFILEQ handle
, PSP_FILE_CALLBACK_W handler
,
1066 struct file_queue
*queue
= handle
;
1068 BOOL result
= FALSE
;
1072 paths
.Source
= paths
.Target
= NULL
;
1074 if (!queue
->copy_queue
.count
&& !queue
->delete_queue
.count
&& !queue
->rename_queue
.count
)
1075 return TRUE
; /* nothing to do */
1077 if (!handler( context
, SPFILENOTIFY_STARTQUEUE
, (UINT
)owner
, 0 )) return FALSE
;
1079 /* perform deletes */
1081 if (queue
->delete_queue
.count
)
1083 if (!(handler( context
, SPFILENOTIFY_STARTSUBQUEUE
, FILEOP_DELETE
,
1084 queue
->delete_queue
.count
))) goto done
;
1085 for (op
= queue
->delete_queue
.head
; op
; op
= op
->next
)
1087 build_filepathsW( op
, &paths
);
1088 op_result
= handler( context
, SPFILENOTIFY_STARTDELETE
, (UINT_PTR
)&paths
, FILEOP_DELETE
);
1089 if (op_result
== FILEOP_ABORT
) goto done
;
1090 while (op_result
== FILEOP_DOIT
)
1092 TRACE( "deleting file %s\n", debugstr_w(paths
.Target
) );
1093 if (DeleteFileW( paths
.Target
)) break; /* success */
1094 paths
.Win32Error
= GetLastError();
1095 op_result
= handler( context
, SPFILENOTIFY_DELETEERROR
, (UINT_PTR
)&paths
, 0 );
1096 if (op_result
== FILEOP_ABORT
) goto done
;
1098 handler( context
, SPFILENOTIFY_ENDDELETE
, (UINT_PTR
)&paths
, 0 );
1100 handler( context
, SPFILENOTIFY_ENDSUBQUEUE
, FILEOP_DELETE
, 0 );
1103 /* perform renames */
1105 if (queue
->rename_queue
.count
)
1107 if (!(handler( context
, SPFILENOTIFY_STARTSUBQUEUE
, FILEOP_RENAME
,
1108 queue
->rename_queue
.count
))) goto done
;
1109 for (op
= queue
->rename_queue
.head
; op
; op
= op
->next
)
1111 build_filepathsW( op
, &paths
);
1112 op_result
= handler( context
, SPFILENOTIFY_STARTRENAME
, (UINT_PTR
)&paths
, FILEOP_RENAME
);
1113 if (op_result
== FILEOP_ABORT
) goto done
;
1114 while (op_result
== FILEOP_DOIT
)
1116 TRACE( "renaming file %s -> %s\n",
1117 debugstr_w(paths
.Source
), debugstr_w(paths
.Target
) );
1118 if (MoveFileW( paths
.Source
, paths
.Target
)) break; /* success */
1119 paths
.Win32Error
= GetLastError();
1120 op_result
= handler( context
, SPFILENOTIFY_RENAMEERROR
, (UINT_PTR
)&paths
, 0 );
1121 if (op_result
== FILEOP_ABORT
) goto done
;
1123 handler( context
, SPFILENOTIFY_ENDRENAME
, (UINT_PTR
)&paths
, 0 );
1125 handler( context
, SPFILENOTIFY_ENDSUBQUEUE
, FILEOP_RENAME
, 0 );
1128 /* perform copies */
1130 if (queue
->copy_queue
.count
)
1132 if (!(handler( context
, SPFILENOTIFY_STARTSUBQUEUE
, FILEOP_COPY
,
1133 queue
->copy_queue
.count
))) goto done
;
1134 for (op
= queue
->copy_queue
.head
; op
; op
= op
->next
)
1136 WCHAR newpath
[MAX_PATH
];
1138 build_filepathsW( op
, &paths
);
1139 op_result
= handler( context
, SPFILENOTIFY_STARTCOPY
, (UINT_PTR
)&paths
, FILEOP_COPY
);
1140 if (op_result
== FILEOP_ABORT
) goto done
;
1141 if (op_result
== FILEOP_NEWPATH
) op_result
= FILEOP_DOIT
;
1142 while (op_result
== FILEOP_DOIT
|| op_result
== FILEOP_NEWPATH
)
1144 TRACE( "copying file %s -> %s\n",
1145 debugstr_w( op_result
== FILEOP_NEWPATH
? newpath
: paths
.Source
),
1146 debugstr_w(paths
.Target
) );
1149 if (!create_full_pathW( op
->dst_path
))
1151 paths
.Win32Error
= GetLastError();
1152 op_result
= handler( context
, SPFILENOTIFY_COPYERROR
,
1153 (UINT_PTR
)&paths
, (UINT_PTR
)newpath
);
1154 if (op_result
== FILEOP_ABORT
) goto done
;
1157 if (do_file_copyW( op_result
== FILEOP_NEWPATH
? newpath
: paths
.Source
,
1158 paths
.Target
, op
->style
)) break; /* success */
1159 /* try to extract it from the cabinet file */
1162 if (extract_cabinet_file( op
->src_tag
, op
->src_root
,
1163 paths
.Source
, paths
.Target
)) break;
1165 paths
.Win32Error
= GetLastError();
1166 op_result
= handler( context
, SPFILENOTIFY_COPYERROR
,
1167 (UINT_PTR
)&paths
, (UINT_PTR
)newpath
);
1168 if (op_result
== FILEOP_ABORT
) goto done
;
1170 handler( context
, SPFILENOTIFY_ENDCOPY
, (UINT_PTR
)&paths
, 0 );
1172 handler( context
, SPFILENOTIFY_ENDSUBQUEUE
, FILEOP_COPY
, 0 );
1179 handler( context
, SPFILENOTIFY_ENDQUEUE
, result
, 0 );
1180 HeapFree( GetProcessHeap(), 0, (void *)paths
.Source
);
1181 HeapFree( GetProcessHeap(), 0, (void *)paths
.Target
);
1186 /***********************************************************************
1187 * SetupScanFileQueueA (SETUPAPI.@)
1189 BOOL WINAPI
SetupScanFileQueueA( HSPFILEQ queue
, DWORD flags
, HWND window
,
1190 PSP_FILE_CALLBACK_A callback
, PVOID context
, PDWORD result
)
1197 /***********************************************************************
1198 * SetupScanFileQueueW (SETUPAPI.@)
1200 BOOL WINAPI
SetupScanFileQueueW( HSPFILEQ handle
, DWORD flags
, HWND window
,
1201 PSP_FILE_CALLBACK_W callback
, PVOID context
, PDWORD result
)
1203 struct file_queue
*queue
= handle
;
1205 BOOL allnodesprocessed
= FALSE
;
1208 paths
.Source
= paths
.Target
= NULL
;
1211 if ( flags
& (SPQ_SCAN_FILE_PRESENCE
| SPQ_SCAN_FILE_VALIDITY
| SPQ_SCAN_USE_CALLBACKEX
| SPQ_SCAN_INFORM_USER
| SPQ_SCAN_PRUNE_COPY_QUEUE
/*| SPQ_SCAN_USE_CALLBACK_SIGNERINFO | SPQ_SCAN_PRUNE_DELREN*/) )
1213 FIXME( "flags ignored 0x%lx\n", flags
& (SPQ_SCAN_FILE_PRESENCE
| SPQ_SCAN_FILE_VALIDITY
| SPQ_SCAN_USE_CALLBACKEX
| SPQ_SCAN_INFORM_USER
| SPQ_SCAN_PRUNE_COPY_QUEUE
/*| SPQ_SCAN_USE_CALLBACK_SIGNERINFO | SPQ_SCAN_PRUNE_DELREN*/) );
1216 if (queue
->copy_queue
.count
)
1218 for (op
= queue
->copy_queue
.head
; op
; op
= op
->next
)
1220 build_filepathsW( op
, &paths
);
1221 if (flags
& SPQ_SCAN_USE_CALLBACK
)
1223 /* FIXME: sometimes set param 2 to SPQ_DELAYED_COPY */
1224 if (NO_ERROR
!= callback( context
, SPFILENOTIFY_QUEUESCAN
, (UINT
)paths
.Target
, 0 ))
1231 allnodesprocessed
= TRUE
;
1234 HeapFree( GetProcessHeap(), 0, (void *)paths
.Source
);
1235 HeapFree( GetProcessHeap(), 0, (void *)paths
.Target
);
1236 return allnodesprocessed
;
1240 /***********************************************************************
1241 * SetupGetFileQueueCount (SETUPAPI.@)
1243 BOOL WINAPI
SetupGetFileQueueCount( HSPFILEQ handle
, UINT op
, PUINT result
)
1245 struct file_queue
*queue
= handle
;
1250 *result
= queue
->copy_queue
.count
;
1253 *result
= queue
->rename_queue
.count
;
1256 *result
= queue
->delete_queue
.count
;
1263 /***********************************************************************
1264 * SetupGetFileQueueFlags (SETUPAPI.@)
1266 BOOL WINAPI
SetupGetFileQueueFlags( HSPFILEQ handle
, PDWORD flags
)
1268 struct file_queue
*queue
= handle
;
1269 *flags
= queue
->flags
;
1274 /***********************************************************************
1275 * SetupSetFileQueueFlags (SETUPAPI.@)
1277 BOOL WINAPI
SetupSetFileQueueFlags( HSPFILEQ handle
, DWORD mask
, DWORD flags
)
1279 struct file_queue
*queue
= handle
;
1280 queue
->flags
= (queue
->flags
& ~mask
) | flags
;
1285 /***********************************************************************
1286 * SetupSetFileQueueAlternatePlatformA (SETUPAPI.@)
1288 BOOL WINAPI
SetupSetFileQueueAlternatePlatformA(HSPFILEQ handle
, PSP_ALTPLATFORM_INFO platform
, PCSTR catalogfile
)
1290 FIXME("(%p, %p, %s) stub!\n", handle
, platform
, debugstr_a(catalogfile
));
1295 /***********************************************************************
1296 * SetupSetFileQueueAlternatePlatformW (SETUPAPI.@)
1298 BOOL WINAPI
SetupSetFileQueueAlternatePlatformW(HSPFILEQ handle
, PSP_ALTPLATFORM_INFO platform
, PCWSTR catalogfile
)
1300 FIXME("(%p, %p, %s) stub!\n", handle
, platform
, debugstr_w(catalogfile
));
1305 /***********************************************************************
1306 * SetupInitDefaultQueueCallback (SETUPAPI.@)
1308 PVOID WINAPI
SetupInitDefaultQueueCallback( HWND owner
)
1310 return SetupInitDefaultQueueCallbackEx( owner
, 0, 0, 0, NULL
);
1314 /***********************************************************************
1315 * SetupInitDefaultQueueCallbackEx (SETUPAPI.@)
1317 PVOID WINAPI
SetupInitDefaultQueueCallbackEx( HWND owner
, HWND progress
, UINT msg
,
1318 DWORD reserved1
, PVOID reserved2
)
1320 struct default_callback_context
*context
;
1322 if ((context
= HeapAlloc( GetProcessHeap(), 0, sizeof(*context
) )))
1324 context
->owner
= owner
;
1325 context
->progress
= progress
;
1326 context
->message
= msg
;
1332 /***********************************************************************
1333 * SetupTermDefaultQueueCallback (SETUPAPI.@)
1335 void WINAPI
SetupTermDefaultQueueCallback( PVOID context
)
1337 HeapFree( GetProcessHeap(), 0, context
);
1341 /***********************************************************************
1342 * SetupDefaultQueueCallbackA (SETUPAPI.@)
1344 UINT WINAPI
SetupDefaultQueueCallbackA( PVOID context
, UINT notification
,
1345 UINT_PTR param1
, UINT_PTR param2
)
1347 FILEPATHS_A
*paths
= (FILEPATHS_A
*)param1
;
1348 struct default_callback_context
*ctx
= (struct default_callback_context
*)context
;
1350 switch(notification
)
1352 case SPFILENOTIFY_STARTQUEUE
:
1353 TRACE( "start queue\n" );
1355 case SPFILENOTIFY_ENDQUEUE
:
1356 TRACE( "end queue\n" );
1358 case SPFILENOTIFY_STARTSUBQUEUE
:
1359 TRACE( "start subqueue %d count %d\n", param1
, param2
);
1361 case SPFILENOTIFY_ENDSUBQUEUE
:
1362 TRACE( "end subqueue %d\n", param1
);
1364 case SPFILENOTIFY_STARTDELETE
:
1365 TRACE( "start delete %s\n", debugstr_a(paths
->Target
) );
1367 case SPFILENOTIFY_ENDDELETE
:
1368 TRACE( "end delete %s\n", debugstr_a(paths
->Target
) );
1370 case SPFILENOTIFY_DELETEERROR
:
1371 /*Windows Ignores attempts to delete files / folders which do not exist*/
1372 if ((paths
->Win32Error
!= ERROR_FILE_NOT_FOUND
) && (paths
->Win32Error
!= ERROR_PATH_NOT_FOUND
))
1373 SetupDeleteErrorA(ctx
->owner
, NULL
, paths
->Target
, paths
->Win32Error
, 0);
1375 case SPFILENOTIFY_STARTRENAME
:
1376 TRACE( "start rename %s -> %s\n", debugstr_a(paths
->Source
), debugstr_a(paths
->Target
) );
1378 case SPFILENOTIFY_ENDRENAME
:
1379 TRACE( "end rename %s -> %s\n", debugstr_a(paths
->Source
), debugstr_a(paths
->Target
) );
1381 case SPFILENOTIFY_RENAMEERROR
:
1382 SetupRenameErrorA(ctx
->owner
, NULL
, paths
->Source
, paths
->Target
, paths
->Win32Error
, 0);
1384 case SPFILENOTIFY_STARTCOPY
:
1385 TRACE( "start copy %s -> %s\n", debugstr_a(paths
->Source
), debugstr_a(paths
->Target
) );
1387 case SPFILENOTIFY_ENDCOPY
:
1388 TRACE( "end copy %s -> %s\n", debugstr_a(paths
->Source
), debugstr_a(paths
->Target
) );
1390 case SPFILENOTIFY_COPYERROR
:
1391 ERR( "copy error %d %s -> %s\n", paths
->Win32Error
,
1392 debugstr_a(paths
->Source
), debugstr_a(paths
->Target
) );
1394 case SPFILENOTIFY_NEEDMEDIA
:
1395 TRACE( "need media\n" );
1398 FIXME( "notification %d params %x,%x\n", notification
, param1
, param2
);
1405 /***********************************************************************
1406 * SetupDefaultQueueCallbackW (SETUPAPI.@)
1408 UINT WINAPI
SetupDefaultQueueCallbackW( PVOID context
, UINT notification
,
1409 UINT_PTR param1
, UINT_PTR param2
)
1411 FILEPATHS_W
*paths
= (FILEPATHS_W
*)param1
;
1412 struct default_callback_context
*ctx
= (struct default_callback_context
*)context
;
1414 switch(notification
)
1416 case SPFILENOTIFY_STARTQUEUE
:
1417 TRACE( "start queue\n" );
1419 case SPFILENOTIFY_ENDQUEUE
:
1420 TRACE( "end queue\n" );
1422 case SPFILENOTIFY_STARTSUBQUEUE
:
1423 TRACE( "start subqueue %d count %d\n", param1
, param2
);
1425 case SPFILENOTIFY_ENDSUBQUEUE
:
1426 TRACE( "end subqueue %d\n", param1
);
1428 case SPFILENOTIFY_STARTDELETE
:
1429 TRACE( "start delete %s\n", debugstr_w(paths
->Target
) );
1431 case SPFILENOTIFY_ENDDELETE
:
1432 TRACE( "end delete %s\n", debugstr_w(paths
->Target
) );
1434 case SPFILENOTIFY_DELETEERROR
:
1435 /*Windows Ignores attempts to delete files / folders which do not exist*/
1436 if ((paths
->Win32Error
!= ERROR_FILE_NOT_FOUND
) && (paths
->Win32Error
!= ERROR_PATH_NOT_FOUND
))
1437 SetupDeleteErrorW(ctx
->owner
, NULL
, paths
->Target
, paths
->Win32Error
, 0);
1439 case SPFILENOTIFY_STARTRENAME
:
1440 SetupRenameErrorW(ctx
->owner
, NULL
, paths
->Source
, paths
->Target
, paths
->Win32Error
, 0);
1442 case SPFILENOTIFY_ENDRENAME
:
1443 TRACE( "end rename %s -> %s\n", debugstr_w(paths
->Source
), debugstr_w(paths
->Target
) );
1445 case SPFILENOTIFY_RENAMEERROR
:
1446 ERR( "rename error %d %s -> %s\n", paths
->Win32Error
,
1447 debugstr_w(paths
->Source
), debugstr_w(paths
->Target
) );
1449 case SPFILENOTIFY_STARTCOPY
:
1450 TRACE( "start copy %s -> %s\n", debugstr_w(paths
->Source
), debugstr_w(paths
->Target
) );
1452 case SPFILENOTIFY_ENDCOPY
:
1453 TRACE( "end copy %s -> %s\n", debugstr_w(paths
->Source
), debugstr_w(paths
->Target
) );
1455 case SPFILENOTIFY_COPYERROR
:
1456 ERR( "copy error %d %s -> %s\n", paths
->Win32Error
,
1457 debugstr_w(paths
->Source
), debugstr_w(paths
->Target
) );
1459 case SPFILENOTIFY_NEEDMEDIA
:
1460 TRACE( "need media\n" );
1463 FIXME( "notification %d params %x,%x\n", notification
, param1
, param2
);
1469 /***********************************************************************
1470 * SetupDeleteErrorA (SETUPAPI.@)
1473 UINT WINAPI
SetupDeleteErrorA( HWND parent
, PCSTR dialogTitle
, PCSTR file
,
1474 UINT w32error
, DWORD style
)
1476 FIXME( "stub: (Error Number %d when attempting to delete %s)\n",
1477 w32error
, debugstr_a(file
) );
1478 return DPROMPT_SKIPFILE
;
1481 /***********************************************************************
1482 * SetupDeleteErrorW (SETUPAPI.@)
1485 UINT WINAPI
SetupDeleteErrorW( HWND parent
, PCWSTR dialogTitle
, PCWSTR file
,
1486 UINT w32error
, DWORD style
)
1488 FIXME( "stub: (Error Number %d when attempting to delete %s)\n",
1489 w32error
, debugstr_w(file
) );
1490 return DPROMPT_SKIPFILE
;
1493 /***********************************************************************
1494 * SetupRenameErrorA (SETUPAPI.@)
1497 UINT WINAPI
SetupRenameErrorA( HWND parent
, PCSTR dialogTitle
, PCSTR source
,
1498 PCSTR target
, UINT w32error
, DWORD style
)
1500 FIXME( "stub: (Error Number %d when attempting to rename %s to %s)\n",
1501 w32error
, debugstr_a(source
), debugstr_a(target
));
1502 return DPROMPT_SKIPFILE
;
1505 /***********************************************************************
1506 * SetupRenameErrorW (SETUPAPI.@)
1509 UINT WINAPI
SetupRenameErrorW( HWND parent
, PCWSTR dialogTitle
, PCWSTR source
,
1510 PCWSTR target
, UINT w32error
, DWORD style
)
1512 FIXME( "stub: (Error Number %d when attempting to rename %s to %s)\n",
1513 w32error
, debugstr_w(source
), debugstr_w(target
));
1514 return DPROMPT_SKIPFILE
;
1518 /***********************************************************************
1519 * SetupCopyErrorA (SETUPAPI.@)
1522 UINT WINAPI
SetupCopyErrorA( HWND parent
, PCSTR dialogTitle
, PCSTR diskname
,
1523 PCSTR sourcepath
, PCSTR sourcefile
, PCSTR targetpath
,
1524 UINT w32error
, DWORD style
, PSTR pathbuffer
,
1525 DWORD buffersize
, PDWORD requiredsize
)
1527 FIXME( "stub: (Error Number %d when attempting to copy file %s from %s to %s)\n",
1528 w32error
, debugstr_a(sourcefile
), debugstr_a(sourcepath
) ,debugstr_a(targetpath
));
1529 return DPROMPT_SKIPFILE
;
1532 /***********************************************************************
1533 * SetupCopyErrorW (SETUPAPI.@)
1536 UINT WINAPI
SetupCopyErrorW( HWND parent
, PCWSTR dialogTitle
, PCWSTR diskname
,
1537 PCWSTR sourcepath
, PCWSTR sourcefile
, PCWSTR targetpath
,
1538 UINT w32error
, DWORD style
, PWSTR pathbuffer
,
1539 DWORD buffersize
, PDWORD requiredsize
)
1541 FIXME( "stub: (Error Number %d when attempting to copy file %s from %s to %s)\n",
1542 w32error
, debugstr_w(sourcefile
), debugstr_w(sourcepath
) ,debugstr_w(targetpath
));
1543 return DPROMPT_SKIPFILE
;