ReactOS  0.4.14-dev-599-g2d4d3f5
queue.c
Go to the documentation of this file.
1 /*
2  * Setupapi file queue routines
3  *
4  * Copyright 2002 Alexandre Julliard for CodeWeavers
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include "setupapi_private.h"
22 
23 #include <aclapi.h>
24 
25 /* Unicode constants */
26 static const WCHAR DotSecurity[] = {'.','S','e','c','u','r','i','t','y',0};
27 
28 /* context structure for the default queue callback */
30 {
34 };
35 
36 struct file_op
37 {
38  struct file_op *next;
48 };
49 
51 {
52  struct file_op *head;
53  struct file_op *tail;
54  unsigned int count;
55 };
56 
57 struct file_queue
58 {
63 };
64 
65 
66 static inline WCHAR *strdupW( const WCHAR *str )
67 {
68  WCHAR *ret = NULL;
69  if (str)
70  {
71  int len = (strlenW(str) + 1) * sizeof(WCHAR);
72  if ((ret = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( ret, str, len );
73  }
74  return ret;
75 }
76 
77 static inline char *strdupWtoA( const WCHAR *str )
78 {
79  char *ret = NULL;
80  if (str)
81  {
82  DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
83  if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
84  WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
85  }
86  return ret;
87 }
88 
89 /* append a file operation to a queue */
90 static inline void queue_file_op( struct file_op_queue *queue, struct file_op *op )
91 {
92  op->next = NULL;
93  if (queue->tail) queue->tail->next = op;
94  else queue->head = op;
95  queue->tail = op;
96  queue->count++;
97 }
98 
99 /* free all the file operations on a given queue */
100 static void free_file_op_queue( struct file_op_queue *queue )
101 {
102  struct file_op *t, *op = queue->head;
103 
104  while( op )
105  {
106  HeapFree( GetProcessHeap(), 0, op->src_root );
107  HeapFree( GetProcessHeap(), 0, op->src_path );
108  HeapFree( GetProcessHeap(), 0, op->src_file );
109  HeapFree( GetProcessHeap(), 0, op->src_descr );
110  HeapFree( GetProcessHeap(), 0, op->src_tag );
111  HeapFree( GetProcessHeap(), 0, op->dst_path );
112  if (op->dst_sd) LocalFree( op->dst_sd);
113  if (op->dst_file != op->src_file) HeapFree( GetProcessHeap(), 0, op->dst_file );
114  t = op;
115  op = op->next;
116  HeapFree( GetProcessHeap(), 0, t );
117  }
118 }
119 
120 /* concat 3 strings to make a path, handling separators correctly */
121 static void concat_W( WCHAR *buffer, const WCHAR *src1, const WCHAR *src2, const WCHAR *src3 )
122 {
123  *buffer = 0;
124  if (src1 && *src1)
125  {
126  strcpyW( buffer, src1 );
127  buffer += strlenW(buffer );
128  if (buffer[-1] != '\\') *buffer++ = '\\';
129  if (src2) while (*src2 == '\\') src2++;
130  }
131 
132  if (src2)
133  {
134  strcpyW( buffer, src2 );
135  buffer += strlenW(buffer );
136  if (buffer[-1] != '\\') *buffer++ = '\\';
137  if (src3) while (*src3 == '\\') src3++;
138  }
139 
140  if (src3)
141  strcpyW( buffer, src3 );
142 }
143 
144 
145 /***********************************************************************
146  * build_filepathsW
147  *
148  * Build a FILEPATHS_W structure for a given file operation.
149  */
150 static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
151 {
152  unsigned int src_len = 1, dst_len = 1;
153  WCHAR *source = (PWSTR)paths->Source, *target = (PWSTR)paths->Target;
154 
155  if (op->src_root) src_len += strlenW(op->src_root) + 1;
156  if (op->src_path) src_len += strlenW(op->src_path) + 1;
157  if (op->src_file) src_len += strlenW(op->src_file) + 1;
158  if (op->dst_path) dst_len += strlenW(op->dst_path) + 1;
159  if (op->dst_file) dst_len += strlenW(op->dst_file) + 1;
160  src_len *= sizeof(WCHAR);
161  dst_len *= sizeof(WCHAR);
162 
163  if (!source || HeapSize( GetProcessHeap(), 0, source ) < src_len )
164  {
165  HeapFree( GetProcessHeap(), 0, source );
166  paths->Source = source = HeapAlloc( GetProcessHeap(), 0, src_len );
167  }
168  if (!target || HeapSize( GetProcessHeap(), 0, target ) < dst_len )
169  {
170  HeapFree( GetProcessHeap(), 0, target );
171  paths->Target = target = HeapAlloc( GetProcessHeap(), 0, dst_len );
172  }
173  if (!source || !target) return FALSE;
174  concat_W( source, op->src_root, op->src_path, op->src_file );
175  concat_W( target, NULL, op->dst_path, op->dst_file );
176  paths->Win32Error = 0;
177  paths->Flags = 0;
178  return TRUE;
179 }
180 
181 
182 /***********************************************************************
183  * QUEUE_callback_WtoA
184  *
185  * Map a file callback parameters from W to A and call the A callback.
186  */
188  UINT_PTR param1, UINT_PTR param2 )
189 {
190  struct callback_WtoA_context *callback_ctx = context;
191  char buffer[MAX_PATH];
192  UINT ret;
193  UINT_PTR old_param2 = param2;
194 
195  switch(notification)
196  {
198  param2 = (UINT_PTR)&buffer;
199  /* fall through */
209  {
210  FILEPATHS_W *pathsW = (FILEPATHS_W *)param1;
211  FILEPATHS_A pathsA;
212 
213  pathsA.Source = strdupWtoA( pathsW->Source );
214  pathsA.Target = strdupWtoA( pathsW->Target );
215  pathsA.Win32Error = pathsW->Win32Error;
216  pathsA.Flags = pathsW->Flags;
217  ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification,
218  (UINT_PTR)&pathsA, param2 );
219  HeapFree( GetProcessHeap(), 0, (void *)pathsA.Source );
220  HeapFree( GetProcessHeap(), 0, (void *)pathsA.Target );
221  }
223  MultiByteToWideChar( CP_ACP, 0, buffer, -1, (WCHAR *)old_param2, MAX_PATH );
224  break;
225 
228  {
231 
232  statusA.cbSize = sizeof(statusA);
233  statusA.FileName = strdupWtoA( statusW->FileName );
234  statusA.Win32Error = statusW->Win32Error;
235  statusA.FailureCode = statusW->FailureCode;
236  ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification,
237  (UINT_PTR)&statusA, param2 );
238  HeapFree( GetProcessHeap(), 0, (LPSTR)statusA.FileName );
239  }
240  break;
241 
243  {
244  LPWSTR targetW = (LPWSTR)param1;
245  LPSTR target = strdupWtoA( targetW );
246 
247  ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification,
248  (UINT_PTR)target, param2 );
249  HeapFree( GetProcessHeap(), 0, target );
250  }
251  break;
252 
254  FIXME("mapping for %d not implemented\n",notification);
259  default:
260  ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification, param1, param2 );
261  break;
262  }
263  return ret;
264 }
265 
266 
267 /***********************************************************************
268  * get_src_file_info
269  *
270  * Retrieve the source file information for a given file.
271  */
272 static void get_src_file_info( HINF hinf, struct file_op *op )
273 {
274  static const WCHAR SourceDisksNames[] =
275  {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
276  static const WCHAR SourceDisksFiles[] =
277  {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
278 
279  INFCONTEXT file_ctx, disk_ctx;
280  INT id, diskid;
281  DWORD len, len2;
282  WCHAR SectionName[MAX_PATH];
283 
284  /* find the SourceDisksFiles entry */
285  if(!SetupDiGetActualSectionToInstallW(hinf, SourceDisksFiles, SectionName, MAX_PATH, NULL, NULL))
286  return;
287  if (!SetupFindFirstLineW( hinf, SectionName, op->src_file, &file_ctx ))
288  {
289  if ((op->style & (SP_COPY_SOURCE_ABSOLUTE|SP_COPY_SOURCEPATH_ABSOLUTE))) return;
290  /* no specific info, use .inf file source directory */
291  if (!op->src_root) op->src_root = PARSER_get_src_root( hinf );
292  return;
293  }
294  if (!SetupGetIntField( &file_ctx, 1, &diskid )) return;
295 
296  /* now find the diskid in the SourceDisksNames section */
297  if(!SetupDiGetActualSectionToInstallW(hinf, SourceDisksNames, SectionName, MAX_PATH, NULL, NULL))
298  return;
299  if (!SetupFindFirstLineW( hinf, SectionName, NULL, &disk_ctx )) return;
300  for (;;)
301  {
302  if (SetupGetIntField( &disk_ctx, 0, &id ) && (id == diskid)) break;
303  if (!SetupFindNextLine( &disk_ctx, &disk_ctx )) return;
304  }
305 
306  /* and fill in the missing info */
307 
308  if (!op->src_descr)
309  {
310  if (SetupGetStringFieldW( &disk_ctx, 1, NULL, 0, &len ) &&
311  (op->src_descr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) )))
312  SetupGetStringFieldW( &disk_ctx, 1, op->src_descr, len, NULL );
313  }
314  if (!op->src_tag)
315  {
316  if (SetupGetStringFieldW( &disk_ctx, 2, NULL, 0, &len ) &&
317  (op->src_tag = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) )))
318  SetupGetStringFieldW( &disk_ctx, 2, op->src_tag, len, NULL );
319  }
320  if (!op->src_path && !(op->style & SP_COPY_SOURCE_ABSOLUTE))
321  {
322  len = len2 = 0;
323  if (!(op->style & SP_COPY_SOURCEPATH_ABSOLUTE))
324  {
325  /* retrieve relative path for this disk */
326  if (!SetupGetStringFieldW( &disk_ctx, 4, NULL, 0, &len )) len = 0;
327  }
328  /* retrieve relative path for this file */
329  if (!SetupGetStringFieldW( &file_ctx, 2, NULL, 0, &len2 )) len2 = 0;
330 
331  if ((len || len2) &&
332  (op->src_path = HeapAlloc( GetProcessHeap(), 0, (len+len2)*sizeof(WCHAR) )))
333  {
334  WCHAR *ptr = op->src_path;
335  if (len)
336  {
337  SetupGetStringFieldW( &disk_ctx, 4, op->src_path, len, NULL );
338  ptr = op->src_path + strlenW(op->src_path);
339  if (len2 && ptr > op->src_path && ptr[-1] != '\\') *ptr++ = '\\';
340  }
341  if (!SetupGetStringFieldW( &file_ctx, 2, ptr, len2, NULL )) *ptr = 0;
342  }
343  }
344  if (!op->src_root) op->src_root = PARSER_get_src_root(hinf);
345 }
346 
347 
348 /***********************************************************************
349  * get_destination_dir
350  *
351  * Retrieve the destination dir for a given section.
352  */
353 static WCHAR *get_destination_dir( HINF hinf, const WCHAR *section )
354 {
355  static const WCHAR Dest[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
356  static const WCHAR Def[] = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};
358 
359  if (!SetupFindFirstLineW( hinf, Dest, section, &context ) &&
360  !SetupFindFirstLineW( hinf, Dest, Def, &context )) return NULL;
361  return PARSER_get_dest_dir( &context );
362 }
363 
364 
365 #ifndef __REACTOS__
366 static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, DWORD, DWORD, DWORD );
367 #else
368 static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, LPSTR, LPVOID, DWORD );
369 #endif
370 
371 /***********************************************************************
372  * extract_cabinet_file
373  *
374  * Extract a file from a .cab file.
375  */
377  const WCHAR *src, const WCHAR *dst )
378 {
379 #ifndef __REACTOS__
380  static const WCHAR extW[] = {'.','c','a','b',0};
381 #endif
382  static HMODULE advpack;
383 
384  char *cab_path, *cab_file;
385  int len = strlenW( cabinet );
386 
387 #ifdef __REACTOS__
388  TRACE("extract_cabinet_file(cab = '%s' ; root = '%s' ; src = '%s' ; dst = '%s')\n",
390 #else
391  /* make sure the cabinet file has a .cab extension */
392  if (len <= 4 || strcmpiW( cabinet + len - 4, extW )) return FALSE;
393 #endif
394  if (!pExtractFiles)
395  {
396  if (!advpack && !(advpack = LoadLibraryA( "advpack.dll" )))
397  {
398  ERR( "could not load advpack.dll\n" );
399  return FALSE;
400  }
401  if (!(pExtractFiles = (void *)GetProcAddress( advpack, "ExtractFiles" )))
402  {
403  ERR( "could not find ExtractFiles in advpack.dll\n" );
404  return FALSE;
405  }
406  }
407 
408  if (!(cab_path = strdupWtoA( root ))) return FALSE;
409  len = WideCharToMultiByte( CP_ACP, 0, cabinet, -1, NULL, 0, NULL, NULL );
410  if (!(cab_file = HeapAlloc( GetProcessHeap(), 0, strlen(cab_path) + len + 1 )))
411  {
412  HeapFree( GetProcessHeap(), 0, cab_path );
413  return FALSE;
414  }
415  strcpy( cab_file, cab_path );
416  if (cab_file[0] && cab_file[strlen(cab_file)-1] != '\\') strcat( cab_file, "\\" );
418  FIXME( "awful hack: extracting cabinet %s\n", debugstr_a(cab_file) );
419 
420 #ifdef __REACTOS__
421  {
422  BOOL Success;
423  char *src_file;
424  const WCHAR *src_fileW;
425  WCHAR TempPath[MAX_PATH];
426 
427  /* Retrieve the temporary path */
428  if (!GetTempPathW(ARRAYSIZE(TempPath), TempPath))
429  {
430  ERR("GetTempPathW error\n");
432  return FALSE;
433  }
434 
435  /* Build the real path to where the file will be extracted */
436  HeapFree( GetProcessHeap(), 0, cab_path );
437  if (!(cab_path = strdupWtoA( TempPath )))
438  {
440  return FALSE;
441  }
442 
443  /* Build the file list */
444  src_fileW = strrchrW(src, '\\'); // Find where the filename starts.
445  if (src_fileW) ++src_fileW;
446  else src_fileW = src;
447  /* Convert to ANSI */
448  if (!(src_file = strdupWtoA( src_fileW )))
449  {
451  HeapFree( GetProcessHeap(), 0, cab_path );
452  return FALSE;
453  }
454 
455  /* Prepare for the move operation */
456  /* Build the full path to the extracted file, that will be renamed */
457  if (!(src = HeapAlloc( GetProcessHeap(), 0, (strlenW(TempPath) + 1 + strlenW(src_fileW) + 1) * sizeof(WCHAR) )))
458  {
459  HeapFree( GetProcessHeap(), 0, src_file );
461  HeapFree( GetProcessHeap(), 0, cab_path );
462  return FALSE;
463  }
464  concat_W( (WCHAR*)src, NULL, TempPath, src_fileW );
465 
466  TRACE("pExtractFiles(cab_file = '%s' ; cab_path = '%s', src_file = '%s')\n",
467  debugstr_a(cab_file), debugstr_a(cab_path), debugstr_a(src_file));
468 
469  /* Extract to temporary folder */
470  pExtractFiles( cab_file, cab_path, 0, src_file, NULL, 0 );
471  HeapFree( GetProcessHeap(), 0, src_file );
473  HeapFree( GetProcessHeap(), 0, cab_path );
474 
475  /* Move to destination, overwriting the original file if needed */
476  TRACE("Renaming src = '%s' to dst = '%s')\n", debugstr_w(src), debugstr_w(dst));
478  HeapFree( GetProcessHeap(), 0, (WCHAR*)src );
479  return Success;
480  }
481 #else
482  pExtractFiles( cab_file, cab_path, 0, 0, 0, 0 );
484  HeapFree( GetProcessHeap(), 0, cab_path );
485  return CopyFileW( src, dst, FALSE /*FIXME*/ );
486 #endif
487 }
488 
489 
490 /***********************************************************************
491  * SetupOpenFileQueue (SETUPAPI.@)
492  */
494 {
495  struct file_queue *queue;
496 
497  if (!(queue = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*queue))))
498  return INVALID_HANDLE_VALUE;
499  return queue;
500 }
501 
502 
503 /***********************************************************************
504  * SetupCloseFileQueue (SETUPAPI.@)
505  */
507 {
508  struct file_queue *queue = handle;
509 
510  free_file_op_queue( &queue->copy_queue );
511  free_file_op_queue( &queue->rename_queue );
512  free_file_op_queue( &queue->delete_queue );
513  HeapFree( GetProcessHeap(), 0, queue );
514  return TRUE;
515 }
516 
517 
518 /***********************************************************************
519  * SetupQueueCopyIndirectA (SETUPAPI.@)
520  */
522 {
523  struct file_queue *queue = params->QueueHandle;
524  struct file_op *op;
525 
526  if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
527  op->style = params->CopyStyle;
528  op->src_root = strdupAtoW( params->SourceRootPath );
529  op->src_path = strdupAtoW( params->SourcePath );
530  op->src_file = strdupAtoW( params->SourceFilename );
531  op->src_descr = strdupAtoW( params->SourceDescription );
532  op->src_tag = strdupAtoW( params->SourceTagfile );
533  op->dst_path = strdupAtoW( params->TargetDirectory );
534  op->dst_file = strdupAtoW( params->TargetFilename );
535  op->dst_sd = NULL;
536 
537  /* some defaults */
538  if (!op->src_file) op->src_file = op->dst_file;
539  if (params->LayoutInf)
540  {
541  get_src_file_info( params->LayoutInf, op );
542  if (!op->dst_path) op->dst_path = get_destination_dir( params->LayoutInf, op->dst_file );
543  }
544 
545  TRACE( "root=%s path=%s file=%s -> dir=%s file=%s descr=%s tag=%s\n",
546  debugstr_w(op->src_root), debugstr_w(op->src_path), debugstr_w(op->src_file),
547  debugstr_w(op->dst_path), debugstr_w(op->dst_file),
548  debugstr_w(op->src_descr), debugstr_w(op->src_tag) );
549 
550  queue_file_op( &queue->copy_queue, op );
551  return TRUE;
552 }
553 
554 
555 /***********************************************************************
556  * SetupQueueCopyIndirectW (SETUPAPI.@)
557  */
559 {
560  struct file_queue *queue = params->QueueHandle;
561  struct file_op *op;
562 
563  if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
564  op->style = params->CopyStyle;
565  op->src_root = strdupW( params->SourceRootPath );
566  op->src_path = strdupW( params->SourcePath );
567  op->src_file = strdupW( params->SourceFilename );
568  op->src_descr = strdupW( params->SourceDescription );
569  op->src_tag = strdupW( params->SourceTagfile );
570  op->dst_path = strdupW( params->TargetDirectory );
571  op->dst_file = strdupW( params->TargetFilename );
572  op->dst_sd = NULL;
573  if (params->SecurityDescriptor)
575 
576  /* some defaults */
577  if (!op->src_file) op->src_file = op->dst_file;
578  if (params->LayoutInf)
579  {
580  get_src_file_info( params->LayoutInf, op );
581  if (!op->dst_path) op->dst_path = get_destination_dir( params->LayoutInf, op->dst_file );
582  }
583 
584  TRACE( "root=%s path=%s file=%s -> dir=%s file=%s descr=%s tag=%s\n",
585  debugstr_w(op->src_root), debugstr_w(op->src_path), debugstr_w(op->src_file),
586  debugstr_w(op->dst_path), debugstr_w(op->dst_file),
587  debugstr_w(op->src_descr), debugstr_w(op->src_tag) );
588 
589  queue_file_op( &queue->copy_queue, op );
590  return TRUE;
591 }
592 
593 
594 /***********************************************************************
595  * SetupQueueCopyA (SETUPAPI.@)
596  */
599  DWORD style )
600 {
602 
603  params.cbSize = sizeof(params);
604  params.QueueHandle = queue;
605  params.SourceRootPath = src_root;
606  params.SourcePath = src_path;
607  params.SourceFilename = src_file;
608  params.SourceDescription = src_descr;
609  params.SourceTagfile = src_tag;
610  params.TargetDirectory = dst_dir;
611  params.TargetFilename = dst_file;
612  params.CopyStyle = style;
613  params.LayoutInf = 0;
614  params.SecurityDescriptor = NULL;
615  return SetupQueueCopyIndirectA( &params );
616 }
617 
618 
619 /***********************************************************************
620  * SetupQueueCopyW (SETUPAPI.@)
621  */
624  DWORD style )
625 {
627 
628  params.cbSize = sizeof(params);
629  params.QueueHandle = queue;
630  params.SourceRootPath = src_root;
631  params.SourcePath = src_path;
632  params.SourceFilename = src_file;
633  params.SourceDescription = src_descr;
634  params.SourceTagfile = src_tag;
635  params.TargetDirectory = dst_dir;
636  params.TargetFilename = dst_file;
637  params.CopyStyle = style;
638  params.LayoutInf = 0;
639  params.SecurityDescriptor = NULL;
640  return SetupQueueCopyIndirectW( &params );
641 }
642 
643 
644 /***********************************************************************
645  * SetupQueueDefaultCopyA (SETUPAPI.@)
646  */
649 {
651 
652  params.cbSize = sizeof(params);
653  params.QueueHandle = queue;
654  params.SourceRootPath = src_root;
655  params.SourcePath = NULL;
656  params.SourceFilename = src_file;
657  params.SourceDescription = NULL;
658  params.SourceTagfile = NULL;
659  params.TargetDirectory = NULL;
660  params.TargetFilename = dst_file;
661  params.CopyStyle = style;
662  params.LayoutInf = hinf;
663  params.SecurityDescriptor = NULL;
664  return SetupQueueCopyIndirectA( &params );
665 }
666 
667 
668 /***********************************************************************
669  * SetupQueueDefaultCopyW (SETUPAPI.@)
670  */
673 {
675 
676  params.cbSize = sizeof(params);
677  params.QueueHandle = queue;
678  params.SourceRootPath = src_root;
679  params.SourcePath = NULL;
680  params.SourceFilename = src_file;
681  params.SourceDescription = NULL;
682  params.SourceTagfile = NULL;
683  params.TargetDirectory = NULL;
684  params.TargetFilename = dst_file;
685  params.CopyStyle = style;
686  params.LayoutInf = hinf;
687  params.SecurityDescriptor = NULL;
688  return SetupQueueCopyIndirectW( &params );
689 }
690 
691 
692 /***********************************************************************
693  * SetupQueueDeleteA (SETUPAPI.@)
694  */
696 {
697  struct file_queue *queue = handle;
698  struct file_op *op;
699 
700  if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
701  op->style = 0;
702  op->src_root = NULL;
703  op->src_path = NULL;
704  op->src_file = NULL;
705  op->src_descr = NULL;
706  op->src_tag = NULL;
707  op->dst_path = strdupAtoW( part1 );
708  op->dst_file = strdupAtoW( part2 );
709  op->dst_sd = NULL;
710  queue_file_op( &queue->delete_queue, op );
711  return TRUE;
712 }
713 
714 
715 /***********************************************************************
716  * SetupQueueDeleteW (SETUPAPI.@)
717  */
719 {
720  struct file_queue *queue = handle;
721  struct file_op *op;
722 
723  if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
724  op->style = 0;
725  op->src_root = NULL;
726  op->src_path = NULL;
727  op->src_file = NULL;
728  op->src_descr = NULL;
729  op->src_tag = NULL;
730  op->dst_path = strdupW( part1 );
731  op->dst_file = strdupW( part2 );
732  op->dst_sd = NULL;
733  queue_file_op( &queue->delete_queue, op );
734  return TRUE;
735 }
736 
737 
738 /***********************************************************************
739  * SetupQueueRenameA (SETUPAPI.@)
740  */
741 BOOL WINAPI SetupQueueRenameA( HSPFILEQ handle, PCSTR SourcePath, PCSTR SourceFilename,
742  PCSTR TargetPath, PCSTR TargetFilename )
743 {
744  struct file_queue *queue = handle;
745  struct file_op *op;
746 
747  if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
748  op->style = 0;
749  op->src_root = NULL;
750  op->src_path = strdupAtoW( SourcePath );
751  op->src_file = strdupAtoW( SourceFilename );
752  op->src_descr = NULL;
753  op->src_tag = NULL;
754  op->dst_path = strdupAtoW( TargetPath );
755  op->dst_file = strdupAtoW( TargetFilename );
756  op->dst_sd = NULL;
757  queue_file_op( &queue->rename_queue, op );
758  return TRUE;
759 }
760 
761 
762 /***********************************************************************
763  * SetupQueueRenameW (SETUPAPI.@)
764  */
765 BOOL WINAPI SetupQueueRenameW( HSPFILEQ handle, PCWSTR SourcePath, PCWSTR SourceFilename,
766  PCWSTR TargetPath, PCWSTR TargetFilename )
767 {
768  struct file_queue *queue = handle;
769  struct file_op *op;
770 
771  if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
772  op->style = 0;
773  op->src_root = NULL;
774  op->src_path = strdupW( SourcePath );
775  op->src_file = strdupW( SourceFilename );
776  op->src_descr = NULL;
777  op->src_tag = NULL;
778  op->dst_path = strdupW( TargetPath );
779  op->dst_file = strdupW( TargetFilename );
780  op->dst_sd = NULL;
781  queue_file_op( &queue->rename_queue, op );
782  return TRUE;
783 }
784 
785 
786 /***********************************************************************
787  * SetupQueueCopySectionA (SETUPAPI.@)
788  */
791 {
792  UNICODE_STRING sectionW;
793  BOOL ret = FALSE;
794 
795  if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
796  {
798  return FALSE;
799  }
800  if (!src_root)
801  ret = SetupQueueCopySectionW( queue, NULL, hinf, hlist, sectionW.Buffer, style );
802  else
803  {
804  UNICODE_STRING srcW;
806  {
807  ret = SetupQueueCopySectionW( queue, srcW.Buffer, hinf, hlist, sectionW.Buffer, style );
808  RtlFreeUnicodeString( &srcW );
809  }
811  }
812  RtlFreeUnicodeString( &sectionW );
813  return ret;
814 }
815 
816 
817 /***********************************************************************
818  * SetupQueueCopySectionW (SETUPAPI.@)
819  */
822 {
824  LPWSTR security_key, security_descriptor = NULL;
825  INFCONTEXT context, security_context;
827  INT flags;
828  DWORD required;
829  BOOL ret;
830 
831  TRACE( "hinf=%p/%p section=%s root=%s\n",
832  hinf, hlist, debugstr_w(section), debugstr_w(src_root) );
833 
834  /* Check for .Security section */
835  security_key = MyMalloc( (strlenW( section ) + strlenW( DotSecurity )) * sizeof(WCHAR) + sizeof(UNICODE_NULL) );
836  if (!security_key)
837  {
839  return FALSE;
840  }
841  strcpyW( security_key, section );
842  strcatW( security_key, DotSecurity );
843  ret = SetupFindFirstLineW( hinf, security_key, NULL, &security_context );
844  MyFree(security_key);
845  if (ret)
846  {
847  if (!SetupGetLineTextW( &security_context, NULL, NULL, NULL, NULL, 0, &required ))
848  return FALSE;
849  security_descriptor = MyMalloc( required * sizeof(WCHAR) );
850  if (!security_descriptor)
851  {
853  return FALSE;
854  }
855  if (!SetupGetLineTextW( &security_context, NULL, NULL, NULL, security_descriptor, required, NULL ))
856  {
857  MyFree( security_descriptor );
858  return FALSE;
859  }
860  }
861 
862  params.cbSize = sizeof(params);
863  params.QueueHandle = queue;
864  params.SourceRootPath = src_root;
865  params.SourcePath = NULL;
866  params.SourceDescription = NULL;
867  params.SourceTagfile = NULL;
868  params.TargetFilename = dest;
869  params.CopyStyle = style;
870  params.LayoutInf = hinf;
871  params.SecurityDescriptor = security_descriptor;
872 
873  ret = FALSE;
874  if (!hlist) hlist = hinf;
875  if (!hinf) hinf = hlist;
876  if (!SetupFindFirstLineW( hlist, section, NULL, &context )) goto done;
877  if (!(params.TargetDirectory = get_destination_dir( hinf, section ))) goto done;
878  do
879  {
880  if (!SetupGetStringFieldW( &context, 1, dest, sizeof(dest)/sizeof(WCHAR), NULL ))
881  goto done;
882  if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL )) *src = 0;
883  if (!SetupGetIntField( &context, 4, &flags )) flags = 0; /* FIXME */
884 
885  params.SourceFilename = *src ? src : NULL;
886  if (!SetupQueueCopyIndirectW( &params )) goto done;
887  } while (SetupFindNextLine( &context, &context ));
888  ret = TRUE;
889 
890 done:
891  if (security_descriptor)
892  MyFree( security_descriptor );
893  return ret;
894 }
895 
896 
897 /***********************************************************************
898  * SetupQueueDeleteSectionA (SETUPAPI.@)
899  */
901 {
902  UNICODE_STRING sectionW;
903  BOOL ret = FALSE;
904 
905  if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
906  {
907  ret = SetupQueueDeleteSectionW( queue, hinf, hlist, sectionW.Buffer );
908  RtlFreeUnicodeString( &sectionW );
909  }
911  return ret;
912 }
913 
914 
915 /***********************************************************************
916  * SetupQueueDeleteSectionW (SETUPAPI.@)
917  */
919 {
921  WCHAR *dest_dir;
923  BOOL ret = FALSE;
924  INT flags;
925 
926  TRACE( "hinf=%p/%p section=%s\n", hinf, hlist, debugstr_w(section) );
927 
928  if (!hlist) hlist = hinf;
929  if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;
930  if (!(dest_dir = get_destination_dir( hinf, section ))) return FALSE;
931  do
932  {
933  if (!SetupGetStringFieldW( &context, 1, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
934  goto done;
935  if (!SetupGetIntField( &context, 4, &flags )) flags = 0;
936  if (!SetupQueueDeleteW( queue, dest_dir, buffer )) goto done;
937  } while (SetupFindNextLine( &context, &context ));
938 
939  ret = TRUE;
940  done:
941  HeapFree( GetProcessHeap(), 0, dest_dir );
942  return ret;
943 }
944 
945 
946 /***********************************************************************
947  * SetupQueueRenameSectionA (SETUPAPI.@)
948  */
950 {
951  UNICODE_STRING sectionW;
952  BOOL ret = FALSE;
953 
954  if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
955  {
956  ret = SetupQueueRenameSectionW( queue, hinf, hlist, sectionW.Buffer );
957  RtlFreeUnicodeString( &sectionW );
958  }
960  return ret;
961 }
962 
963 
964 /***********************************************************************
965  * SetupQueueRenameSectionW (SETUPAPI.@)
966  */
968 {
970  WCHAR *dest_dir;
972  BOOL ret = FALSE;
973 
974  TRACE( "hinf=%p/%p section=%s\n", hinf, hlist, debugstr_w(section) );
975 
976  if (!hlist) hlist = hinf;
977  if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;
978  if (!(dest_dir = get_destination_dir( hinf, section ))) return FALSE;
979  do
980  {
981  if (!SetupGetStringFieldW( &context, 1, dst, sizeof(dst)/sizeof(WCHAR), NULL ))
982  goto done;
983  if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL ))
984  goto done;
985  if (!SetupQueueRenameW( queue, dest_dir, src, NULL, dst )) goto done;
986  } while (SetupFindNextLine( &context, &context ));
987 
988  ret = TRUE;
989  done:
990  HeapFree( GetProcessHeap(), 0, dest_dir );
991  return ret;
992 }
993 
994 
995 /***********************************************************************
996  * SetupCommitFileQueueA (SETUPAPI.@)
997  */
999  PVOID context )
1000 {
1001  struct callback_WtoA_context ctx;
1002 
1003  ctx.orig_context = context;
1004  ctx.orig_handler = handler;
1005  return SetupCommitFileQueueW( owner, queue, QUEUE_callback_WtoA, &ctx );
1006 }
1007 
1008 
1009 /***********************************************************************
1010  * create_full_pathW
1011  *
1012  * Recursively create all directories in the path.
1013  */
1015 {
1016  BOOL ret = TRUE;
1017  int len;
1018  WCHAR *new_path;
1019 
1020  new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) * sizeof(WCHAR));
1021  strcpyW(new_path, path);
1022 
1023  while((len = strlenW(new_path)) && new_path[len - 1] == '\\')
1024  new_path[len - 1] = 0;
1025 
1026  while(!CreateDirectoryW(new_path, NULL))
1027  {
1028  WCHAR *slash;
1030 
1032  break;
1033 
1035  {
1036  ret = FALSE;
1037  break;
1038  }
1039 
1040  if(!(slash = strrchrW(new_path, '\\')))
1041  {
1042  ret = FALSE;
1043  break;
1044  }
1045 
1046  len = slash - new_path;
1047  new_path[len] = 0;
1048  if(!create_full_pathW(new_path))
1049  {
1050  ret = FALSE;
1051  break;
1052  }
1053  new_path[len] = '\\';
1054  }
1055 
1056  HeapFree(GetProcessHeap(), 0, new_path);
1057  return ret;
1058 }
1059 
1062 {
1063  BOOL rc = FALSE;
1064  BOOL docopy = TRUE;
1065 #ifdef __REACTOS__
1066  INT hSource, hTemp;
1067  OFSTRUCT OfStruct;
1068  WCHAR TempPath[MAX_PATH];
1069  WCHAR TempFile[MAX_PATH];
1070  LONG lRes;
1071  DWORD dwLastError;
1072 #endif
1073 
1074  TRACE("copy %s to %s style 0x%x\n",debugstr_w(source),debugstr_w(target),style);
1075 
1076 #ifdef __REACTOS__
1077  /* Get a temp file name */
1078  if (!GetTempPathW(ARRAYSIZE(TempPath), TempPath))
1079  {
1080  ERR("GetTempPathW error\n");
1081  return FALSE;
1082  }
1083 
1084  /* Try to open the source file */
1085  hSource = LZOpenFileW((LPWSTR)source, &OfStruct, OF_READ);
1086  if (hSource < 0)
1087  {
1088  TRACE("LZOpenFileW(1) error %d %s\n", (int)hSource, debugstr_w(source));
1089  return FALSE;
1090  }
1091 
1092  if (!GetTempFileNameW(TempPath, L"", 0, TempFile))
1093  {
1094  dwLastError = GetLastError();
1095 
1096  ERR("GetTempFileNameW(%s) error\n", debugstr_w(TempPath));
1097 
1098  /* Close the source handle */
1099  LZClose(hSource);
1100 
1101  /* Restore error condition triggered by GetTempFileNameW */
1102  SetLastError(dwLastError);
1103 
1104  return FALSE;
1105  }
1106 
1107  /* Extract the compressed file to a temp location */
1108  hTemp = LZOpenFileW(TempFile, &OfStruct, OF_CREATE);
1109  if (hTemp < 0)
1110  {
1111  dwLastError = GetLastError();
1112 
1113  ERR("LZOpenFileW(2) error %d %s\n", (int)hTemp, debugstr_w(TempFile));
1114 
1115  /* Close the source handle */
1116  LZClose(hSource);
1117 
1118  /* Delete temp file if an error is signaled */
1119  DeleteFileW(TempFile);
1120 
1121  /* Restore error condition triggered by LZOpenFileW */
1122  SetLastError(dwLastError);
1123 
1124  return FALSE;
1125  }
1126 
1127  lRes = LZCopy(hSource, hTemp);
1128 
1129  dwLastError = GetLastError();
1130 
1131  LZClose(hSource);
1132  LZClose(hTemp);
1133 
1134  if (lRes < 0)
1135  {
1136  ERR("LZCopy error %d (%s, %s)\n", (int)lRes, debugstr_w(source), debugstr_w(TempFile));
1137 
1138  /* Delete temp file if copy was not successful */
1139  DeleteFileW(TempFile);
1140 
1141  /* Restore error condition triggered by LZCopy */
1142  SetLastError(dwLastError);
1143 
1144  return FALSE;
1145  }
1146 #endif
1147 
1148  /* before copy processing */
1149  if (style & SP_COPY_REPLACEONLY)
1150  {
1152  docopy = FALSE;
1153  }
1155  {
1156  DWORD VersionSizeSource=0;
1157  DWORD VersionSizeTarget=0;
1158  DWORD zero=0;
1159 
1160  /*
1161  * This is sort of an interesting workaround. You see, calling
1162  * GetVersionInfoSize on a builtin dll loads that dll into memory
1163  * and we do not properly unload builtin dlls.. so we effectively
1164  * lock into memory all the targets we are replacing. This leads
1165  * to problems when we try to register the replaced dlls.
1166  *
1167  * So I will test for the existence of the files first so that
1168  * we just basically unconditionally replace the builtin versions.
1169  */
1172  {
1173  VersionSizeSource = GetFileVersionInfoSizeW(TempFile,&zero);
1174  VersionSizeTarget = GetFileVersionInfoSizeW((LPWSTR)target,&zero);
1175  }
1176 
1177  TRACE("SizeTarget %i ... SizeSource %i\n",VersionSizeTarget,
1178  VersionSizeSource);
1179 
1180  if (VersionSizeSource && VersionSizeTarget)
1181  {
1182  LPVOID VersionSource;
1183  LPVOID VersionTarget;
1184  VS_FIXEDFILEINFO *TargetInfo;
1185  VS_FIXEDFILEINFO *SourceInfo;
1186  UINT length;
1187  WCHAR SubBlock[2]={'\\',0};
1188  DWORD ret;
1189 
1190  VersionSource = HeapAlloc(GetProcessHeap(),0,VersionSizeSource);
1191  VersionTarget = HeapAlloc(GetProcessHeap(),0,VersionSizeTarget);
1192 
1193  ret = GetFileVersionInfoW(TempFile,0,VersionSizeSource,VersionSource);
1194  if (ret)
1195  ret = GetFileVersionInfoW((LPWSTR)target, 0, VersionSizeTarget,
1196  VersionTarget);
1197 
1198  if (ret)
1199  {
1200  ret = VerQueryValueW(VersionSource, SubBlock,
1201  (LPVOID*)&SourceInfo, &length);
1202  if (ret)
1203  ret = VerQueryValueW(VersionTarget, SubBlock,
1204  (LPVOID*)&TargetInfo, &length);
1205 
1206  if (ret)
1207  {
1208  FILEPATHS_W filepaths;
1209 
1210  TRACE("Versions: Source %i.%i target %i.%i\n",
1211  SourceInfo->dwFileVersionMS, SourceInfo->dwFileVersionLS,
1212  TargetInfo->dwFileVersionMS, TargetInfo->dwFileVersionLS);
1213 
1214  /* used in case of notification */
1215  filepaths.Target = target;
1216  filepaths.Source = source;
1217  filepaths.Win32Error = 0;
1218  filepaths.Flags = 0;
1219 
1220  if (TargetInfo->dwFileVersionMS > SourceInfo->dwFileVersionMS)
1221  {
1222  if (handler)
1223  docopy = handler (context, SPFILENOTIFY_TARGETNEWER, (UINT_PTR)&filepaths, 0);
1224  else
1225  docopy = FALSE;
1226  }
1227  else if ((TargetInfo->dwFileVersionMS == SourceInfo->dwFileVersionMS)
1228  && (TargetInfo->dwFileVersionLS > SourceInfo->dwFileVersionLS))
1229  {
1230  if (handler)
1231  docopy = handler (context, SPFILENOTIFY_TARGETNEWER, (UINT_PTR)&filepaths, 0);
1232  else
1233  docopy = FALSE;
1234  }
1235  else if ((style & SP_COPY_NEWER_ONLY) &&
1236  (TargetInfo->dwFileVersionMS ==
1237  SourceInfo->dwFileVersionMS)
1238  &&(TargetInfo->dwFileVersionLS ==
1239  SourceInfo->dwFileVersionLS))
1240  {
1241  if (handler)
1242  docopy = handler (context, SPFILENOTIFY_TARGETNEWER, (UINT_PTR)&filepaths, 0);
1243  else
1244  docopy = FALSE;
1245  }
1246  }
1247  }
1248  HeapFree(GetProcessHeap(),0,VersionSource);
1249  HeapFree(GetProcessHeap(),0,VersionTarget);
1250  }
1251  }
1253  {
1255  {
1256  FIXME("Notify user target file exists\n");
1257  docopy = FALSE;
1258  }
1259  }
1262  {
1263  ERR("Unsupported style(s) 0x%x\n",style);
1264  }
1265 
1266  if (docopy)
1267  {
1269  TRACE("Did copy... rc was %i\n",rc);
1270  }
1271 
1272  /* after copy processing */
1274  {
1275  if (rc)
1277  }
1278 
1279  return rc;
1280 }
1281 
1282 /***********************************************************************
1283  * SetupInstallFileA (SETUPAPI.@)
1284  */
1287 {
1288  BOOL ret = FALSE;
1289  struct callback_WtoA_context ctx;
1290  UNICODE_STRING sourceW, rootW, destW;
1291 
1292  TRACE("%p %p %s %s %s %x %p %p\n", hinf, inf_context, debugstr_a(source), debugstr_a(root),
1294 
1295  sourceW.Buffer = rootW.Buffer = destW.Buffer = NULL;
1297  {
1299  return FALSE;
1300  }
1302  {
1304  goto exit;
1305  }
1306  if (dest && !RtlCreateUnicodeStringFromAsciiz( &destW, dest ))
1307  {
1309  goto exit;
1310  }
1311 
1312  ctx.orig_context = context;
1313  ctx.orig_handler = handler;
1314 
1315  ret = SetupInstallFileW( hinf, inf_context, sourceW.Buffer, rootW.Buffer, destW.Buffer, style, QUEUE_callback_WtoA, &ctx );
1316 
1317 exit:
1320  RtlFreeUnicodeString( &destW );
1321  return ret;
1322 }
1323 
1324 /***********************************************************************
1325  * SetupInstallFileW (SETUPAPI.@)
1326  */
1329 {
1330  static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0};
1331 
1332  BOOL ret, absolute = (root && *root && !(style & SP_COPY_SOURCE_ABSOLUTE));
1333  WCHAR *buffer, *p, *inf_source = NULL;
1334  unsigned int len;
1335 
1336  TRACE("%p %p %s %s %s %x %p %p\n", hinf, inf_context, debugstr_w(source), debugstr_w(root),
1338 
1339  if (hinf)
1340  {
1341  INFCONTEXT ctx;
1342 
1343  if (!inf_context)
1344  {
1345  inf_context = &ctx;
1346  if (!SetupFindFirstLineW( hinf, CopyFiles, NULL, inf_context )) return FALSE;
1347  }
1348  if (!SetupGetStringFieldW( inf_context, 1, NULL, 0, (PDWORD) &len )) return FALSE;
1349  if (!(inf_source = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
1350  {
1352  return FALSE;
1353  }
1354  if (!SetupGetStringFieldW( inf_context, 1, inf_source, len, NULL ))
1355  {
1356  HeapFree( GetProcessHeap(), 0, inf_source );
1357  return FALSE;
1358  }
1359  source = inf_source;
1360  }
1361  else if (!source)
1362  {
1364  return FALSE;
1365  }
1366 
1367  len = strlenW( source ) + 1;
1368  if (absolute) len += strlenW( root ) + 1;
1369 
1370  if (!(p = buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
1371  {
1372  HeapFree( GetProcessHeap(), 0, inf_source );
1374  return FALSE;
1375  }
1376 
1377  if (absolute)
1378  {
1379  strcpyW( buffer, root );
1380  p += strlenW( buffer );
1381  if (p[-1] != '\\') *p++ = '\\';
1382  }
1383  while (*source == '\\') source++;
1384  strcpyW( p, source );
1385 
1387 
1388  HeapFree( GetProcessHeap(), 0, inf_source );
1389  HeapFree( GetProcessHeap(), 0, buffer );
1390  return ret;
1391 }
1392 
1393 /***********************************************************************
1394  * SetupCommitFileQueueW (SETUPAPI.@)
1395  */
1397  PVOID context )
1398 {
1399  struct file_queue *queue = handle;
1400  struct file_op *op;
1401  BOOL result = FALSE;
1403  UINT op_result;
1404 
1405  paths.Source = paths.Target = NULL;
1406 
1407  if (!queue->copy_queue.count && !queue->delete_queue.count && !queue->rename_queue.count)
1408  return TRUE; /* nothing to do */
1409 
1410  if (!handler( context, SPFILENOTIFY_STARTQUEUE, (UINT_PTR)owner, 0 )) return FALSE;
1411 
1412  /* perform deletes */
1413 
1414  if (queue->delete_queue.count)
1415  {
1417  queue->delete_queue.count ))) goto done;
1418  for (op = queue->delete_queue.head; op; op = op->next)
1419  {
1420  build_filepathsW( op, &paths );
1422  if (op_result == FILEOP_ABORT) goto done;
1423  while (op_result == FILEOP_DOIT)
1424  {
1425  TRACE( "deleting file %s\n", debugstr_w(paths.Target) );
1426  if (DeleteFileW( paths.Target )) break; /* success */
1427  paths.Win32Error = GetLastError();
1428  op_result = handler( context, SPFILENOTIFY_DELETEERROR, (UINT_PTR)&paths, 0 );
1429  if (op_result == FILEOP_ABORT) goto done;
1430  }
1432  }
1434  }
1435 
1436  /* perform renames */
1437 
1438  if (queue->rename_queue.count)
1439  {
1441  queue->rename_queue.count ))) goto done;
1442  for (op = queue->rename_queue.head; op; op = op->next)
1443  {
1444  build_filepathsW( op, &paths );
1446  if (op_result == FILEOP_ABORT) goto done;
1447  while (op_result == FILEOP_DOIT)
1448  {
1449  TRACE( "renaming file %s -> %s\n",
1450  debugstr_w(paths.Source), debugstr_w(paths.Target) );
1451  if (MoveFileW( paths.Source, paths.Target )) break; /* success */
1452  paths.Win32Error = GetLastError();
1453  op_result = handler( context, SPFILENOTIFY_RENAMEERROR, (UINT_PTR)&paths, 0 );
1454  if (op_result == FILEOP_ABORT) goto done;
1455  }
1457  }
1459  }
1460 
1461  /* perform copies */
1462 
1463  if (queue->copy_queue.count)
1464  {
1466  queue->copy_queue.count ))) goto done;
1467  for (op = queue->copy_queue.head; op; op = op->next)
1468  {
1469  WCHAR newpath[MAX_PATH];
1470 
1471  build_filepathsW( op, &paths );
1473  if (op_result == FILEOP_ABORT) goto done;
1474  if (op_result == FILEOP_NEWPATH) op_result = FILEOP_DOIT;
1475  while (op_result == FILEOP_DOIT || op_result == FILEOP_NEWPATH)
1476  {
1477  TRACE( "copying file %s -> %s\n",
1478  debugstr_w( op_result == FILEOP_NEWPATH ? newpath : paths.Source ),
1479  debugstr_w(paths.Target) );
1480  if (op->dst_path)
1481  {
1482  if (!create_full_pathW( op->dst_path ))
1483  {
1484  paths.Win32Error = GetLastError();
1485  op_result = handler( context, SPFILENOTIFY_COPYERROR,
1486  (UINT_PTR)&paths, (UINT_PTR)newpath );
1487  if (op_result == FILEOP_ABORT) goto done;
1488  }
1489  }
1490  if (do_file_copyW( op_result == FILEOP_NEWPATH ? newpath : paths.Source,
1491  paths.Target, op->style, handler, context )) break; /* success */
1492  /* try to extract it from the cabinet file */
1493  if (op->src_tag)
1494  {
1495  if (extract_cabinet_file( op->src_tag, op->src_root,
1496  paths.Source, paths.Target )) break;
1497  }
1498  paths.Win32Error = GetLastError();
1499  op_result = handler( context, SPFILENOTIFY_COPYERROR,
1500  (UINT_PTR)&paths, (UINT_PTR)newpath );
1501  if (op_result == FILEOP_ABORT) goto done;
1502  }
1503  if (op->dst_sd)
1504  {
1505  PSID psidOwner = NULL, psidGroup = NULL;
1506  PACL pDacl = NULL, pSacl = NULL;
1507  SECURITY_INFORMATION security_info = 0;
1508  BOOL present, dummy;
1509 
1510  if (GetSecurityDescriptorOwner( op->dst_sd, &psidOwner, &dummy ) && psidOwner)
1511  security_info |= OWNER_SECURITY_INFORMATION;
1512  if (GetSecurityDescriptorGroup( op->dst_sd, &psidGroup, &dummy ) && psidGroup)
1513  security_info |= GROUP_SECURITY_INFORMATION;
1514  if (GetSecurityDescriptorDacl( op->dst_sd, &present, &pDacl, &dummy ))
1515  security_info |= DACL_SECURITY_INFORMATION;
1516  if (GetSecurityDescriptorSacl( op->dst_sd, &present, &pSacl, &dummy ))
1517  security_info |= DACL_SECURITY_INFORMATION;
1518  SetNamedSecurityInfoW( (LPWSTR)paths.Target, SE_FILE_OBJECT, security_info,
1519  psidOwner, psidGroup, pDacl, pSacl );
1520  /* Yes, ignore the return code... */
1521  }
1523  }
1525  }
1526 
1527 
1528  result = TRUE;
1529 
1530  done:
1532  HeapFree( GetProcessHeap(), 0, (void *)paths.Source );
1533  HeapFree( GetProcessHeap(), 0, (void *)paths.Target );
1534  return result;
1535 }
1536 
1537 
1538 /***********************************************************************
1539  * SetupScanFileQueueA (SETUPAPI.@)
1540  */
1543 {
1544  struct callback_WtoA_context ctx;
1545 
1546  TRACE("%p %x %p %p %p %p\n", handle, flags, window, handler, context, result);
1547 
1548  ctx.orig_context = context;
1549  ctx.orig_handler = handler;
1550 
1552 }
1553 
1554 
1555 /***********************************************************************
1556  * SetupScanFileQueueW (SETUPAPI.@)
1557  */
1560 {
1561  struct file_queue *queue = handle;
1562  struct file_op *op;
1564  UINT notification = 0;
1565  BOOL ret = FALSE;
1566 
1567  TRACE("%p %x %p %p %p %p\n", handle, flags, window, handler, context, result);
1568 
1569  *result = FALSE;
1570 
1571  if (!queue->copy_queue.count) return TRUE;
1572 
1575 
1577  {
1578  FIXME("flags %x not fully implemented\n", flags);
1579  }
1580 
1581  paths.Source = paths.Target = NULL;
1582 
1583  for (op = queue->copy_queue.head; op; op = op->next)
1584  {
1585  build_filepathsW( op, &paths );
1586  switch (notification)
1587  {
1589  /* FIXME: handle delay flag */
1590  if (handler( context, notification, (UINT_PTR)paths.Target, 0 )) goto done;
1591  break;
1593  if (handler( context, notification, (UINT_PTR)&paths, 0 )) goto done;
1594  break;
1595  default:
1596  ret = TRUE; goto done;
1597  }
1598  }
1599 
1600  *result = TRUE;
1601 
1602  done:
1603  HeapFree( GetProcessHeap(), 0, (void *)paths.Source );
1604  HeapFree( GetProcessHeap(), 0, (void *)paths.Target );
1605  return ret;
1606 }
1607 
1608 
1609 /***********************************************************************
1610  * SetupGetFileQueueCount (SETUPAPI.@)
1611  */
1613 {
1614  struct file_queue *queue = handle;
1615 
1616  switch(op)
1617  {
1618  case FILEOP_COPY:
1619  *result = queue->copy_queue.count;
1620  return TRUE;
1621  case FILEOP_RENAME:
1622  *result = queue->rename_queue.count;
1623  return TRUE;
1624  case FILEOP_DELETE:
1625  *result = queue->delete_queue.count;
1626  return TRUE;
1627  }
1628  return FALSE;
1629 }
1630 
1631 
1632 /***********************************************************************
1633  * SetupGetFileQueueFlags (SETUPAPI.@)
1634  */
1636 {
1637  struct file_queue *queue = handle;
1638  *flags = queue->flags;
1639  return TRUE;
1640 }
1641 
1642 
1643 /***********************************************************************
1644  * SetupSetFileQueueFlags (SETUPAPI.@)
1645  */
1647 {
1648  struct file_queue *queue = handle;
1649  queue->flags = (queue->flags & ~mask) | flags;
1650  return TRUE;
1651 }
1652 
1653 
1654 /***********************************************************************
1655  * SetupSetFileQueueAlternatePlatformA (SETUPAPI.@)
1656  */
1658 {
1659  FIXME("(%p, %p, %s) stub!\n", handle, platform, debugstr_a(catalogfile));
1660  return FALSE;
1661 }
1662 
1663 
1664 /***********************************************************************
1665  * SetupSetFileQueueAlternatePlatformW (SETUPAPI.@)
1666  */
1668 {
1669  FIXME("(%p, %p, %s) stub!\n", handle, platform, debugstr_w(catalogfile));
1670  return FALSE;
1671 }
1672 
1673 
1674 /***********************************************************************
1675  * SetupInitDefaultQueueCallback (SETUPAPI.@)
1676  */
1678 {
1679  return SetupInitDefaultQueueCallbackEx( owner, 0, 0, 0, NULL );
1680 }
1681 
1682 
1683 /***********************************************************************
1684  * SetupInitDefaultQueueCallbackEx (SETUPAPI.@)
1685  */
1687  DWORD reserved1, PVOID reserved2 )
1688 {
1690 
1691  if ((context = HeapAlloc( GetProcessHeap(), 0, sizeof(*context) )))
1692  {
1693  context->owner = owner;
1694  context->progress = progress;
1695  context->message = msg;
1696  }
1697  return context;
1698 }
1699 
1700 
1701 /***********************************************************************
1702  * SetupTermDefaultQueueCallback (SETUPAPI.@)
1703  */
1705 {
1706  HeapFree( GetProcessHeap(), 0, context );
1707 }
1708 
1709 
1710 /***********************************************************************
1711  * SetupDefaultQueueCallbackA (SETUPAPI.@)
1712  */
1714  UINT_PTR param1, UINT_PTR param2 )
1715 {
1716  FILEPATHS_A *paths = (FILEPATHS_A *)param1;
1718 
1719  switch(notification)
1720  {
1722  TRACE( "start queue\n" );
1723  return TRUE;
1724  case SPFILENOTIFY_ENDQUEUE:
1725  TRACE( "end queue\n" );
1726  return 0;
1728  TRACE( "start subqueue %ld count %ld\n", param1, param2 );
1729  return TRUE;
1731  TRACE( "end subqueue %ld\n", param1 );
1732  return 0;
1734  TRACE( "start delete %s\n", debugstr_a(paths->Target) );
1735  return FILEOP_DOIT;
1737  TRACE( "end delete %s\n", debugstr_a(paths->Target) );
1738  return 0;
1740  /*Windows Ignores attempts to delete files / folders which do not exist*/
1741  if ((paths->Win32Error != ERROR_FILE_NOT_FOUND) && (paths->Win32Error != ERROR_PATH_NOT_FOUND))
1742  SetupDeleteErrorA(ctx->owner, NULL, paths->Target, paths->Win32Error, 0);
1743  return FILEOP_SKIP;
1745  TRACE( "start rename %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
1746  return FILEOP_DOIT;
1748  TRACE( "end rename %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
1749  return 0;
1751  SetupRenameErrorA(ctx->owner, NULL, paths->Source, paths->Target, paths->Win32Error, 0);
1752  return FILEOP_SKIP;
1754  TRACE( "start copy %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
1755  return FILEOP_DOIT;
1756  case SPFILENOTIFY_ENDCOPY:
1757  TRACE( "end copy %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
1758  return 0;
1760  ERR( "copy error %d %s -> %s\n", paths->Win32Error,
1761  debugstr_a(paths->Source), debugstr_a(paths->Target) );
1762  return FILEOP_SKIP;
1764  TRACE( "need media\n" );
1765  return FILEOP_SKIP;
1766  default:
1767  FIXME( "notification %d params %lx,%lx\n", notification, param1, param2 );
1768  break;
1769  }
1770  return 0;
1771 }
1772 
1773 
1774 /***********************************************************************
1775  * SetupDefaultQueueCallbackW (SETUPAPI.@)
1776  */
1778  UINT_PTR param1, UINT_PTR param2 )
1779 {
1780  FILEPATHS_W *paths = (FILEPATHS_W *)param1;
1782 
1783  switch(notification)
1784  {
1786  TRACE( "start queue\n" );
1787  return TRUE;
1788  case SPFILENOTIFY_ENDQUEUE:
1789  TRACE( "end queue\n" );
1790  return 0;
1792  TRACE( "start subqueue %ld count %ld\n", param1, param2 );
1793  return TRUE;
1795  TRACE( "end subqueue %ld\n", param1 );
1796  return 0;
1798  TRACE( "start delete %s\n", debugstr_w(paths->Target) );
1799  return FILEOP_DOIT;
1801  TRACE( "end delete %s\n", debugstr_w(paths->Target) );
1802  return 0;
1804  /*Windows Ignores attempts to delete files / folders which do not exist*/
1805  if ((paths->Win32Error != ERROR_FILE_NOT_FOUND) && (paths->Win32Error != ERROR_PATH_NOT_FOUND))
1806  SetupDeleteErrorW(ctx->owner, NULL, paths->Target, paths->Win32Error, 0);
1807  return FILEOP_SKIP;
1809  SetupRenameErrorW(ctx->owner, NULL, paths->Source, paths->Target, paths->Win32Error, 0);
1810  return FILEOP_DOIT;
1812  TRACE( "end rename %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );
1813  return 0;
1815  ERR( "rename error %d %s -> %s\n", paths->Win32Error,
1816  debugstr_w(paths->Source), debugstr_w(paths->Target) );
1817  return FILEOP_SKIP;
1819  TRACE( "start copy %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );
1820  return FILEOP_DOIT;
1821  case SPFILENOTIFY_ENDCOPY:
1822  TRACE( "end copy %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );
1823  return 0;
1825  TRACE( "copy error %d %s -> %s\n", paths->Win32Error,
1826  debugstr_w(paths->Source), debugstr_w(paths->Target) );
1827  return FILEOP_SKIP;
1829  TRACE( "need media\n" );
1830  return FILEOP_SKIP;
1831  default:
1832  FIXME( "notification %d params %lx,%lx\n", notification, param1, param2 );
1833  break;
1834  }
1835  return 0;
1836 }
1837 
1838 /***********************************************************************
1839  * SetupDeleteErrorA (SETUPAPI.@)
1840  */
1841 
1843  UINT w32error, DWORD style)
1844 {
1845  FIXME( "stub: (Error Number %d when attempting to delete %s)\n",
1846  w32error, debugstr_a(file) );
1847  return DPROMPT_SKIPFILE;
1848 }
1849 
1850 /***********************************************************************
1851  * SetupDeleteErrorW (SETUPAPI.@)
1852  */
1853 
1855  UINT w32error, DWORD style)
1856 {
1857  FIXME( "stub: (Error Number %d when attempting to delete %s)\n",
1858  w32error, debugstr_w(file) );
1859  return DPROMPT_SKIPFILE;
1860 }
1861 
1862 /***********************************************************************
1863  * SetupRenameErrorA (SETUPAPI.@)
1864  */
1865 
1867  PCSTR target, UINT w32error, DWORD style)
1868 {
1869  FIXME( "stub: (Error Number %d when attempting to rename %s to %s)\n",
1870  w32error, debugstr_a(source), debugstr_a(target));
1871  return DPROMPT_SKIPFILE;
1872 }
1873 
1874 /***********************************************************************
1875  * SetupRenameErrorW (SETUPAPI.@)
1876  */
1877 
1879  PCWSTR target, UINT w32error, DWORD style)
1880 {
1881  FIXME( "stub: (Error Number %d when attempting to rename %s to %s)\n",
1882  w32error, debugstr_w(source), debugstr_w(target));
1883  return DPROMPT_SKIPFILE;
1884 }
1885 
1886 
1887 /***********************************************************************
1888  * SetupCopyErrorA (SETUPAPI.@)
1889  */
1890 
1892  PCSTR sourcepath, PCSTR sourcefile, PCSTR targetpath,
1893  UINT w32error, DWORD style, PSTR pathbuffer,
1894  DWORD buffersize, PDWORD requiredsize)
1895 {
1896  FIXME( "stub: (Error Number %d when attempting to copy file %s from %s to %s)\n",
1897  w32error, debugstr_a(sourcefile), debugstr_a(sourcepath) ,debugstr_a(targetpath));
1898  return DPROMPT_SKIPFILE;
1899 }
1900 
1901 /***********************************************************************
1902  * SetupCopyErrorW (SETUPAPI.@)
1903  */
1904 
1906  PCWSTR sourcepath, PCWSTR sourcefile, PCWSTR targetpath,
1907  UINT w32error, DWORD style, PWSTR pathbuffer,
1908  DWORD buffersize, PDWORD requiredsize)
1909 {
1910  FIXME( "stub: (Error Number %d when attempting to copy file %s from %s to %s)\n",
1911  w32error, debugstr_w(sourcefile), debugstr_w(sourcepath) ,debugstr_w(targetpath));
1912  return DPROMPT_SKIPFILE;
1913 }
1914 
1915 /***********************************************************************
1916  * pSetupGetQueueFlags (SETUPAPI.@)
1917  */
1919 {
1920  struct file_queue *queue = handle;
1921  return queue->flags;
1922 }
1923 
1924 /***********************************************************************
1925  * pSetupSetQueueFlags (SETUPAPI.@)
1926  */
1928 {
1929  struct file_queue *queue = handle;
1930  queue->flags = flags;
1931  return TRUE;
1932 }
struct file_op * head
Definition: queue.c:52
#define SPQ_SCAN_USE_CALLBACKEX
Definition: setupapi.h:615
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
unsigned __int3264 UINT_PTR
Definition: activex.cpp:275
BOOL WINAPI SetupFindFirstLineW(IN HINF InfHandle, IN PCWSTR Section, IN PCWSTR Key, IN OUT PINFCONTEXT Context)
Definition: infsupp.c:54
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define SP_COPY_NEWER_ONLY
Definition: setupapi.h:487
static BOOL build_filepathsW(const struct file_op *op, FILEPATHS_W *paths)
Definition: queue.c:150
PSP_FILE_CALLBACK_A orig_handler
BOOL WINAPI SetupDiGetActualSectionToInstallW(HINF InfHandle, PCWSTR InfSectionName, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PWSTR *Extension)
Definition: devinst.c:1985
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
BOOL WINAPI SetupQueueRenameA(HSPFILEQ handle, PCSTR SourcePath, PCSTR SourceFilename, PCSTR TargetPath, PCSTR TargetFilename)
Definition: queue.c:741
#define SPFILENOTIFY_QUEUESCAN
Definition: fileqsup.h:40
static WCHAR * get_destination_dir(HINF hinf, const WCHAR *section)
Definition: queue.c:353
#define OF_READ
Definition: winbase.h:116
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
BOOL WINAPI SetupQueueCopySectionW(HSPFILEQ queue, PCWSTR src_root, HINF hinf, HINF hlist, PCWSTR section, DWORD style)
Definition: queue.c:820
#define FILEOP_RENAME
Definition: fileqsup.h:43
#define WideCharToMultiByte
Definition: compat.h:101
BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL *pDacl, LPBOOL lpbDaclDefaulted)
Definition: sec.c:45
DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
Definition: misc.c:1197
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define SPFILENOTIFY_STARTREGISTRATION
Definition: setupapi.h:565
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
BOOL WINAPI SetupScanFileQueueA(HSPFILEQ handle, DWORD flags, HWND window, PSP_FILE_CALLBACK_A handler, PVOID context, PDWORD result)
Definition: queue.c:1541
Definition: http.c:7098
BOOL WINAPI SetupCommitFileQueueA(HWND owner, HSPFILEQ queue, PSP_FILE_CALLBACK_A handler, PVOID context)
Definition: queue.c:998
#define SPFILENOTIFY_STARTQUEUE
Definition: fileqsup.h:22
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
uint16_t * PWSTR
Definition: typedefs.h:54
PCSTR Target
Definition: setupapi.h:742
BOOL WINAPI SetupScanFileQueueW(HSPFILEQ handle, DWORD flags, HWND window, PSP_FILE_CALLBACK_W handler, PVOID context, PDWORD result)
Definition: queue.c:1558
static const WCHAR rootW[]
Definition: chain.c:69
static const WCHAR DotSecurity[]
Definition: queue.c:26
#define CP_ACP
Definition: compat.h:99
BOOL WINAPI SetupQueueRenameSectionW(HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section)
Definition: queue.c:967
static char * strdupWtoA(const WCHAR *str)
Definition: queue.c:77
BOOL WINAPI SetupGetFileQueueCount(HSPFILEQ handle, UINT op, PUINT result)
Definition: queue.c:1612
HSPFILEQ WINAPI SetupOpenFileQueue(void)
Definition: queue.c:493
#define SPFILENOTIFY_ENDCOPY
Definition: fileqsup.h:36
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
BOOL WINAPI pSetupSetQueueFlags(HSPFILEQ handle, DWORD flags)
Definition: queue.c:1927
UINT Win32Error
Definition: fileqsup.h:62
#define SPFILENOTIFY_QUEUESCAN_EX
Definition: setupapi.h:564
#define CALLBACK
Definition: compat.h:27
GLdouble GLdouble t
Definition: gl.h:2047
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define SPFILENOTIFY_STARTRENAME
Definition: fileqsup.h:31
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
UINT(CALLBACK * PSP_FILE_CALLBACK_A)(PVOID, UINT, UINT_PTR, UINT_PTR)
Definition: setupapi.h:871
GLuint buffer
Definition: glext.h:5915
WCHAR * dst_file
Definition: queue.c:46
BOOL WINAPI SetupQueueCopyW(HSPFILEQ queue, PCWSTR src_root, PCWSTR src_path, PCWSTR src_file, PCWSTR src_descr, PCWSTR src_tag, PCWSTR dst_dir, PCWSTR dst_file, DWORD style)
Definition: queue.c:622
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
BOOL WINAPI SetupQueueCopySectionA(HSPFILEQ queue, PCSTR src_root, HINF hinf, HINF hlist, PCSTR section, DWORD style)
Definition: queue.c:789
WCHAR * PARSER_get_dest_dir(INFCONTEXT *context)
Definition: parser.c:1116
Definition: parser.c:55
HFILE WINAPI LZOpenFileW(LPWSTR fn, LPOFSTRUCT ofs, WORD mode)
Definition: lzexpand.c:585
UINT WINAPI SetupDeleteErrorW(HWND parent, PCWSTR dialogTitle, PCWSTR file, UINT w32error, DWORD style)
Definition: queue.c:1854
BOOL WINAPI SetupQueueDeleteA(HSPFILEQ handle, PCSTR part1, PCSTR part2)
Definition: queue.c:695
DWORD WINAPI pSetupGetQueueFlags(HSPFILEQ handle)
Definition: queue.c:1918
char * LPSTR
Definition: xmlstorage.h:182
#define SPFILENOTIFY_ENDRENAME
Definition: fileqsup.h:32
#define SPFILENOTIFY_TARGETNEWER
Definition: setupapi.h:569
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
BOOL WINAPI SetupSetFileQueueAlternatePlatformW(HSPFILEQ handle, PSP_ALTPLATFORM_INFO platform, PCWSTR catalogfile)
Definition: queue.c:1667
int32_t INT
Definition: typedefs.h:56
static void free_file_op_queue(struct file_op_queue *queue)
Definition: queue.c:100
BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pGroup, LPBOOL lpbGroupDefaulted)
Definition: sec.c:76
#define FILEOP_ABORT
Definition: fileqsup.h:47
#define SP_COPY_LANGUAGEAWARE
Definition: setupapi.h:477
void WINAPI LZClose(HFILE fd)
Definition: lzexpand.c:600
#define SPQ_SCAN_USE_CALLBACK
Definition: setupapi.h:614
#define SP_COPY_IN_USE_NEEDS_REBOOT
Definition: setupapi.h:480
#define SPFILENOTIFY_STARTSUBQUEUE
Definition: fileqsup.h:24
BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner, LPBOOL lpbOwnerDefaulted)
Definition: sec.c:103
#define SPFILENOTIFY_ENDSUBQUEUE
Definition: fileqsup.h:25
BOOL WINAPI SetupQueueDeleteW(HSPFILEQ handle, PCWSTR part1, PCWSTR part2)
Definition: queue.c:718
static DWORD
Definition: queue.c:366
#define SPFILENOTIFY_RENAMEERROR
Definition: fileqsup.h:33
GLenum GLint GLuint mask
Definition: glext.h:6028
static BOOL extract_cabinet_file(const WCHAR *cabinet, const WCHAR *root, const WCHAR *src, const WCHAR *dst)
Definition: queue.c:376
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2079
#define UNICODE_NULL
BOOL WINAPI SetupInstallFileA(HINF hinf, PINFCONTEXT inf_context, PCSTR source, PCSTR root, PCSTR dest, DWORD style, PSP_FILE_CALLBACK_A handler, PVOID context)
Definition: queue.c:1285
GLenum const GLfloat * params
Definition: glext.h:5645
#define DPROMPT_SKIPFILE
Definition: setupapi.h:271
#define FILEOP_COPY
Definition: fileqsup.h:42
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
UINT WINAPI SetupDeleteErrorA(HWND parent, PCSTR dialogTitle, PCSTR file, UINT w32error, DWORD style)
Definition: queue.c:1842
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
#define SPFILENOTIFY_ENDDELETE
Definition: fileqsup.h:28
struct file_op_queue rename_queue
Definition: queue.c:61
#define debugstr_w
Definition: kernel32.h:32
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1044
static PVOID ptr
Definition: dispmode.c:27
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
static const WCHAR CopyFiles[]
Definition: install.c:107
const WCHAR * str
Definition: _queue.h:59
BOOL WINAPI SetupSetFileQueueFlags(HSPFILEQ handle, DWORD mask, DWORD flags)
Definition: queue.c:1646
static BOOL do_file_copyW(LPCWSTR source, LPCWSTR target, DWORD style, PSP_FILE_CALLBACK_W handler, PVOID context)
Definition: queue.c:1060
BOOL WINAPI SetupQueueDeleteSectionW(HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section)
Definition: queue.c:918
smooth NULL
Definition: ftsmooth.c:416
#define SP_COPY_FORCE_NEWER
Definition: setupapi.h:484
BOOL WINAPI SetupQueueCopyA(HSPFILEQ queue, PCSTR src_root, PCSTR src_path, PCSTR src_file, PCSTR src_descr, PCSTR src_tag, PCSTR dst_dir, PCSTR dst_file, DWORD style)
Definition: queue.c:597
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
#define SPFILENOTIFY_STARTCOPY
Definition: fileqsup.h:35
BOOL WINAPI SetupQueueDefaultCopyA(HSPFILEQ queue, HINF hinf, PCSTR src_root, PCSTR src_file, PCSTR dst_file, DWORD style)
Definition: queue.c:647
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static void get_src_file_info(HINF hinf, struct file_op *op)
Definition: queue.c:272
#define SP_COPY_NOOVERWRITE
Definition: setupapi.h:475
#define SPFILENOTIFY_STARTDELETE
Definition: fileqsup.h:27
platform
Definition: msipriv.h:356
struct file_op * tail
Definition: queue.c:53
static void queue_file_op(struct file_op_queue *queue, struct file_op *op)
Definition: queue.c:90
#define SP_COPY_NODECOMP
Definition: setupapi.h:476
#define FILEOP_DOIT
Definition: fileqsup.h:48
#define TRACE(s)
Definition: solgame.cpp:4
uint8_t reserved2[12]
Definition: fsck.fat.h:58
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
r parent
Definition: btrfs.c:2869
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned int count
Definition: queue.c:54
#define debugstr_a
Definition: kernel32.h:31
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
UINT(CALLBACK * PSP_FILE_CALLBACK_W)(IN PVOID Context, IN UINT Notification, IN UINT_PTR Param1, IN UINT_PTR Param2)
Definition: fileqsup.h:66
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned long DWORD
Definition: ntddk_ex.h:95
WCHAR * PARSER_get_src_root(HINF hinf)
Definition: parser.c:1096
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:417
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define SP_COPY_NEWER_OR_SAME
Definition: setupapi.h:474
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
UINT WINAPI SetupDefaultQueueCallbackA(PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:1713
#define SPFILENOTIFY_COPYERROR
Definition: fileqsup.h:37
#define LPVOID
Definition: nt_native.h:45
GLbitfield flags
Definition: glext.h:7161
WCHAR * src_root
Definition: queue.c:40
WCHAR * src_path
Definition: queue.c:41
#define SP_COPY_FORCE_NOOVERWRITE
Definition: setupapi.h:483
static double zero
Definition: j0_y0.c:96
int ret
static const WCHAR L[]
Definition: oid.c:1250
static BOOL create_full_pathW(const WCHAR *path)
Definition: queue.c:1014
UINT WINAPI SetupDefaultQueueCallbackW(PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:1777
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:611
static void concat_W(WCHAR *buffer, const WCHAR *src1, const WCHAR *src2, const WCHAR *src3)
Definition: queue.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
void WINAPI SetupTermDefaultQueueCallback(PVOID context)
Definition: queue.c:1704
BOOL WINAPI SetupCommitFileQueueW(HWND owner, HSPFILEQ handle, PSP_FILE_CALLBACK_W handler, PVOID context)
Definition: queue.c:1396
GLenum src
Definition: glext.h:6340
BOOL WINAPI SetupSetFileQueueAlternatePlatformA(HSPFILEQ handle, PSP_ALTPLATFORM_INFO platform, PCSTR catalogfile)
Definition: queue.c:1657
#define SP_COPY_REPLACEONLY
Definition: setupapi.h:472
static IHTMLWindow2 * window
Definition: events.c:77
#define SP_COPY_SOURCE_ABSOLUTE
Definition: setupapi.h:478
PCWSTR Source
Definition: fileqsup.h:61
UINT CALLBACK QUEUE_callback_WtoA(void *context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:187
PVOID WINAPI SetupInitDefaultQueueCallbackEx(HWND owner, HWND progress, UINT msg, DWORD reserved1, PVOID reserved2)
Definition: queue.c:1686
DWORD Flags
Definition: setupapi.h:745
#define SP_COPY_FORCE_IN_USE
Definition: setupapi.h:481
GLsizei const GLuint * paths
Definition: glext.h:11717
BOOL WINAPI SetupQueueCopyIndirectW(PSP_FILE_COPY_PARAMS_W params)
Definition: queue.c:558
#define strcmpiW(s1, s2)
Definition: unicode.h:39
WINE_UNICODE_INLINE WCHAR * strrchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:254
WCHAR * src_descr
Definition: queue.c:43
LONG WINAPI LZCopy(HFILE src, HFILE dest)
Definition: lzexpand.c:472
UINT WINAPI SetupRenameErrorA(HWND parent, PCSTR dialogTitle, PCSTR source, PCSTR target, UINT w32error, DWORD style)
Definition: queue.c:1866
#define ERR(fmt,...)
Definition: debug.h:109
UINT WINAPI SetupCopyErrorA(HWND parent, PCSTR dialogTitle, PCSTR diskname, PCSTR sourcepath, PCSTR sourcefile, PCSTR targetpath, UINT w32error, DWORD style, PSTR pathbuffer, DWORD buffersize, PDWORD requiredsize)
Definition: queue.c:1891
WCHAR * src_tag
Definition: queue.c:44
struct file_op_queue delete_queue
Definition: queue.c:60
PCSTR Source
Definition: setupapi.h:743
#define SPFILENOTIFY_ENDREGISTRATION
Definition: setupapi.h:566
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
PSECURITY_DESCRIPTOR dst_sd
Definition: queue.c:47
BOOL WINAPI SetupQueueRenameSectionA(HSPFILEQ queue, HINF hinf, HINF hlist, PCSTR section)
Definition: queue.c:949
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
unsigned char dummy
Definition: maze.c:118
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
PVOID WINAPI SetupInitDefaultQueueCallback(HWND owner)
Definition: queue.c:1677
#define FILEOP_SKIP
Definition: fileqsup.h:49
#define SP_COPY_DELETESOURCE
Definition: setupapi.h:471
static LPSTR
Definition: queue.c:366
static WCHAR * strdupW(const WCHAR *str)
Definition: queue.c:66
WCHAR * src_file
Definition: queue.c:42
signed char * PSTR
Definition: retypes.h:7
GLenum GLenum dst
Definition: glext.h:6340
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
static const WCHAR sourceW[]
Definition: jsregexp.c:37
BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbSaclPresent, PACL *pSacl, LPBOOL lpbSaclDefaulted)
Definition: sec.c:146
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
unsigned int UINT
Definition: ndis.h:50
UINT WINAPI SetupRenameErrorW(HWND parent, PCWSTR dialogTitle, PCWSTR source, PCWSTR target, UINT w32error, DWORD style)
Definition: queue.c:1878
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
UINT Win32Error
Definition: setupapi.h:744
DWORD * PDWORD
Definition: pedump.c:68
cd_progress_ptr progress
Definition: cdjpeg.h:150
BOOL WINAPI SetupFindNextLine(IN PINFCONTEXT ContextIn, OUT PINFCONTEXT ContextOut)
Definition: infsupp.c:80
#define MultiByteToWideChar
Definition: compat.h:100
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:845
struct file_op_queue copy_queue
Definition: queue.c:59
PCWSTR Target
Definition: fileqsup.h:60
#define msg(x)
Definition: auth_time.c:54
#define SP_COPY_WARNIFSKIP
Definition: setupapi.h:485
#define SPFILENOTIFY_DELETEERROR
Definition: fileqsup.h:29
#define SPFILENOTIFY_ENDQUEUE
Definition: fileqsup.h:23
BOOL WINAPI SetupGetIntField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT INT *IntegerValue)
Definition: infsupp.c:146
ULONG Flags
Definition: fileqsup.h:63
#define OF_CREATE
Definition: winbase.h:125
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
GLenum GLuint id
Definition: glext.h:5579
GLenum target
Definition: glext.h:7315
#define SP_COPY_SOURCEPATH_ABSOLUTE
Definition: setupapi.h:479
struct file_op * next
Definition: queue.c:38
BOOL WINAPI MoveFileExW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName OPTIONAL, IN DWORD dwFlags)
Definition: move.c:1060
#define GetProcAddress(x, y)
Definition: compat.h:418
LPVOID WINAPI MyMalloc(DWORD dwSize)
Definition: misc.c:147
BOOL WINAPI SetupQueueCopyIndirectA(PSP_FILE_COPY_PARAMS_A params)
Definition: queue.c:521
UINT op
Definition: effect.c:223
static char * dest
Definition: rtl.c:135
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
const char * PCSTR
Definition: typedefs.h:51
BOOL WINAPI SetupQueueDefaultCopyW(HSPFILEQ queue, HINF hinf, PCWSTR src_root, PCWSTR src_file, PCWSTR dst_file, DWORD style)
Definition: queue.c:671
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
WCHAR * dst_path
Definition: queue.c:45
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
Arabic default style
Definition: afstyles.h:93
GLuint64EXT * result
Definition: glext.h:11304
DWORD flags
Definition: queue.c:62
BOOL WINAPI SetupQueueRenameW(HSPFILEQ handle, PCWSTR SourcePath, PCWSTR SourceFilename, PCWSTR TargetPath, PCWSTR TargetFilename)
Definition: queue.c:765
VOID WINAPI MyFree(LPVOID lpMem)
Definition: misc.c:128
BOOL WINAPI SetupQueueDeleteSectionA(HSPFILEQ queue, HINF hinf, HINF hlist, PCSTR section)
Definition: queue.c:900
UINT style
Definition: queue.c:39
BOOL WINAPI SetupCloseFileQueue(HSPFILEQ handle)
Definition: queue.c:506
#define FILEOP_NEWPATH
Definition: fileqsup.h:51
#define HeapFree(x, y, z)
Definition: compat.h:402
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:65
#define SPFILENOTIFY_NEEDMEDIA
Definition: fileqsup.h:39
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
Definition: queue.c:36
UINT WINAPI SetupCopyErrorW(HWND parent, PCWSTR dialogTitle, PCWSTR diskname, PCWSTR sourcepath, PCWSTR sourcefile, PCWSTR targetpath, UINT w32error, DWORD style, PWSTR pathbuffer, DWORD buffersize, PDWORD requiredsize)
Definition: queue.c:1905
unsigned int * PUINT
Definition: ndis.h:50
#define SDDL_REVISION_1
Definition: sddl.h:30
#define SP_COPY_NOSKIP
Definition: setupapi.h:482
#define FILEOP_DELETE
Definition: fileqsup.h:44
static void(WINAPI *pExtractFiles)(LPSTR
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1049
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor, DWORD StringSDRevision, PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize)
Definition: security.c:2738
Definition: fci.c:126
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1756
BOOL WINAPI SetupGetFileQueueFlags(HSPFILEQ handle, PDWORD flags)
Definition: queue.c:1635
BOOL WINAPI SetupInstallFileW(HINF hinf, PINFCONTEXT inf_context, PCWSTR source, PCWSTR root, PCWSTR dest, DWORD style, PSP_FILE_CALLBACK_W handler, PVOID context)
Definition: queue.c:1327
BOOL WINAPI SetupGetStringFieldW(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PWSTR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:184