ReactOS  0.4.15-dev-1033-gd7d716a
install.c
Go to the documentation of this file.
1 /*
2  * Setupapi install routines
3  *
4  * Copyright 2002 Alexandre Julliard for CodeWeavers
5  * 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "setupapi_private.h"
23 
24 #include <winsvc.h>
25 #include <ndk/cmfuncs.h>
26 
27 /* Unicode constants */
28 static const WCHAR BackSlash[] = {'\\',0};
29 static const WCHAR GroupOrderListKey[] = {'S','Y','S','T','E','M','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','G','r','o','u','p','O','r','d','e','r','L','i','s','t',0};
30 static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
31 static const WCHAR OemFileMask[] = {'o','e','m','*','.','i','n','f',0};
32 static const WCHAR OemFileSpecification[] = {'o','e','m','%','l','u','.','i','n','f',0};
33 static const WCHAR DotLnk[] = {'.','l','n','k',0};
34 static const WCHAR DotServices[] = {'.','S','e','r','v','i','c','e','s',0};
35 
36 static const WCHAR DependenciesKey[] = {'D','e','p','e','n','d','e','n','c','i','e','s',0};
37 static const WCHAR DescriptionKey[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
38 static const WCHAR DisplayNameKey[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
39 static const WCHAR ErrorControlKey[] = {'E','r','r','o','r','C','o','n','t','r','o','l',0};
40 static const WCHAR LoadOrderGroupKey[] = {'L','o','a','d','O','r','d','e','r','G','r','o','u','p',0};
41 static const WCHAR SecurityKey[] = {'S','e','c','u','r','i','t','y',0};
42 static const WCHAR ServiceBinaryKey[] = {'S','e','r','v','i','c','e','B','i','n','a','r','y',0};
43 static const WCHAR ServiceTypeKey[] = {'S','e','r','v','i','c','e','T','y','p','e',0};
44 static const WCHAR StartTypeKey[] = {'S','t','a','r','t','T','y','p','e',0};
45 static const WCHAR StartNameKey[] = {'S','t','a','r','t','N','a','m','e',0};
46 
47 static const WCHAR Name[] = {'N','a','m','e',0};
48 static const WCHAR CmdLine[] = {'C','m','d','L','i','n','e',0};
49 static const WCHAR SubDir[] = {'S','u','b','D','i','r',0};
50 static const WCHAR WorkingDir[] = {'W','o','r','k','i','n','g','D','i','r',0};
51 static const WCHAR IconPath[] = {'I','c','o','n','P','a','t','h',0};
52 static const WCHAR IconIndex[] = {'I','c','o','n','I','n','d','e','x',0};
53 static const WCHAR HotKey[] = {'H','o','t','K','e','y',0};
54 static const WCHAR InfoTip[] = {'I','n','f','o','T','i','p',0};
55 static const WCHAR DisplayResource[] = {'D','i','s','p','l','a','y','R','e','s','o','u','r','c','e',0};
56 
57 /* info passed to callback functions dealing with files */
59 {
64 };
65 
66 /* info passed to callback functions dealing with the registry */
68 {
70  BOOL delete;
71 };
72 
73 /* info passed to callback functions dealing with registering dlls */
75 {
79 };
80 
81 /* info passed to callback functions dealing with Needs directives */
83 {
85 
97 };
98 
99 typedef BOOL (*iterate_fields_func)( HINF hinf, PCWSTR field, void *arg );
100 static BOOL GetLineText( HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value);
102 typedef HRESULT (WINAPI *COCREATEINSTANCE)(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID *ppv);
104 
105 /* Unicode constants */
106 static const WCHAR AddService[] = {'A','d','d','S','e','r','v','i','c','e',0};
107 static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0};
108 static const WCHAR DelFiles[] = {'D','e','l','F','i','l','e','s',0};
109 static const WCHAR RenFiles[] = {'R','e','n','F','i','l','e','s',0};
110 static const WCHAR Ini2Reg[] = {'I','n','i','2','R','e','g',0};
111 static const WCHAR LogConf[] = {'L','o','g','C','o','n','f',0};
112 static const WCHAR AddReg[] = {'A','d','d','R','e','g',0};
113 static const WCHAR DelReg[] = {'D','e','l','R','e','g',0};
114 static const WCHAR BitReg[] = {'B','i','t','R','e','g',0};
115 static const WCHAR UpdateInis[] = {'U','p','d','a','t','e','I','n','i','s',0};
116 static const WCHAR CopyINF[] = {'C','o','p','y','I','N','F',0};
117 static const WCHAR UpdateIniFields[] = {'U','p','d','a','t','e','I','n','i','F','i','e','l','d','s',0};
118 static const WCHAR RegisterDlls[] = {'R','e','g','i','s','t','e','r','D','l','l','s',0};
119 static const WCHAR UnregisterDlls[] = {'U','n','r','e','g','i','s','t','e','r','D','l','l','s',0};
120 static const WCHAR ProfileItems[] = {'P','r','o','f','i','l','e','I','t','e','m','s',0};
121 static const WCHAR Include[] = {'I','n','c','l','u','d','e',0};
122 static const WCHAR Needs[] = {'N','e','e','d','s',0};
123 static const WCHAR DotSecurity[] = {'.','S','e','c','u','r','i','t','y',0};
124 #ifdef __WINESRC__
125 static const WCHAR WineFakeDlls[] = {'W','i','n','e','F','a','k','e','D','l','l','s',0};
126 #endif
127 
128 
129 /***********************************************************************
130  * get_field_string
131  *
132  * Retrieve the contents of a field, dynamically growing the buffer if necessary.
133  */
135  WCHAR *static_buffer, DWORD *size )
136 {
137  DWORD required;
138 
139  if (SetupGetStringFieldW( context, index, buffer, *size, &required )) return buffer;
141  {
142  /* now grow the buffer */
143  if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
144  if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required*sizeof(WCHAR) ))) return NULL;
145  *size = required;
146  if (SetupGetStringFieldW( context, index, buffer, *size, &required )) return buffer;
147  }
148  if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
149  return NULL;
150 }
151 
152 
153 /***********************************************************************
154  * copy_files_callback
155  *
156  * Called once for each CopyFiles entry in a given section.
157  */
158 static BOOL copy_files_callback( HINF hinf, PCWSTR field, void *arg )
159 {
160  struct files_callback_info *info = arg;
161 
162  if (field[0] == '@') /* special case: copy single file */
163  SetupQueueDefaultCopyW( info->queue, info->layout ? info->layout : hinf, info->src_root, NULL, field+1, info->copy_flags );
164  else
165  SetupQueueCopySectionW( info->queue, info->src_root, info->layout ? info->layout : hinf, hinf, field, info->copy_flags );
166  return TRUE;
167 }
168 
169 
170 /***********************************************************************
171  * delete_files_callback
172  *
173  * Called once for each DelFiles entry in a given section.
174  */
176 {
177  struct files_callback_info *info = arg;
178  SetupQueueDeleteSectionW( info->queue, hinf, 0, field );
179  return TRUE;
180 }
181 
182 
183 /***********************************************************************
184  * rename_files_callback
185  *
186  * Called once for each RenFiles entry in a given section.
187  */
189 {
190  struct files_callback_info *info = arg;
191  SetupQueueRenameSectionW( info->queue, hinf, 0, field );
192  return TRUE;
193 }
194 
195 
196 /***********************************************************************
197  * get_root_key
198  *
199  * Retrieve the registry root key from its name.
200  */
201 static HKEY get_root_key( const WCHAR *name, HKEY def_root )
202 {
203  static const WCHAR HKCR[] = {'H','K','C','R',0};
204  static const WCHAR HKCU[] = {'H','K','C','U',0};
205  static const WCHAR HKLM[] = {'H','K','L','M',0};
206  static const WCHAR HKU[] = {'H','K','U',0};
207  static const WCHAR HKR[] = {'H','K','R',0};
208 
209  if (!strcmpiW( name, HKCR )) return HKEY_CLASSES_ROOT;
210  if (!strcmpiW( name, HKCU )) return HKEY_CURRENT_USER;
211  if (!strcmpiW( name, HKLM )) return HKEY_LOCAL_MACHINE;
212  if (!strcmpiW( name, HKU )) return HKEY_USERS;
213  if (!strcmpiW( name, HKR )) return def_root;
214  return 0;
215 }
216 
217 
218 /***********************************************************************
219  * append_multi_sz_value
220  *
221  * Append a multisz string to a multisz registry value.
222  */
223 static void append_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *strings,
224  DWORD str_size )
225 {
226  DWORD size, type, total;
227  WCHAR *buffer, *p;
228 
229  if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
230  if (type != REG_MULTI_SZ) return;
231 
232  size = size + str_size * sizeof(WCHAR) ;
233  if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size))) return;
234  if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
235 
236  /* compare each string against all the existing ones */
237  total = size;
238  while (*strings)
239  {
240  int len = strlenW(strings) + 1;
241 
242  for (p = buffer; *p; p += strlenW(p) + 1)
243  if (!strcmpiW( p, strings )) break;
244 
245  if (!*p) /* not found, need to append it */
246  {
247  memcpy( p, strings, len * sizeof(WCHAR) );
248  p[len] = 0;
249  total += len * sizeof(WCHAR);
250  }
251  strings += len;
252  }
253  if (total != size)
254  {
255  TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) );
256  RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total + sizeof(WCHAR) );
257  }
258  done:
259  HeapFree( GetProcessHeap(), 0, buffer );
260 }
261 
262 
263 /***********************************************************************
264  * delete_multi_sz_value
265  *
266  * Remove a string from a multisz registry value.
267  */
268 static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string )
269 {
270  DWORD size, type;
271  WCHAR *buffer, *src, *dst;
272 
273  if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
274  if (type != REG_MULTI_SZ) return;
275  /* allocate double the size, one for value before and one for after */
276  if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2))) return;
277  if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
278  src = buffer;
279  dst = buffer + size;
280  while (*src)
281  {
282  int len = strlenW(src) + 1;
283  if (strcmpiW( src, string ))
284  {
285  memcpy( dst, src, len * sizeof(WCHAR) );
286  dst += len;
287  }
288  src += len;
289  }
290  *dst++ = 0;
291  if (dst != buffer + 2*size) /* did we remove something? */
292  {
293  TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) );
294  RegSetValueExW( hkey, value, 0, REG_MULTI_SZ,
295  (BYTE *)(buffer + size), dst - (buffer + size) );
296  }
297  done:
298  HeapFree( GetProcessHeap(), 0, buffer );
299 }
300 
301 
302 /***********************************************************************
303  * do_reg_operation
304  *
305  * Perform an add/delete registry operation depending on the flags.
306  */
308 {
309  DWORD type, size;
310 
311  if (flags & (FLG_ADDREG_DELREG_BIT | FLG_ADDREG_DELVAL)) /* deletion */
312  {
314  {
315  if ((flags & FLG_DELREG_MULTI_SZ_DELSTRING) == FLG_DELREG_MULTI_SZ_DELSTRING)
316  {
317  WCHAR *str;
318 
319  if (!SetupGetStringFieldW( context, 5, NULL, 0, &size ) || !size) return TRUE;
320  if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;
322  delete_multi_sz_value( hkey, value, str );
323  HeapFree( GetProcessHeap(), 0, str );
324  }
325  else RegDeleteValueW( hkey, value );
326  }
327  else NtDeleteKey( hkey );
328  return TRUE;
329  }
330 
332 
334  {
335  BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL );
336  if (exists && (flags & FLG_ADDREG_NOCLOBBER)) return TRUE;
337  if (!exists && (flags & FLG_ADDREG_OVERWRITEONLY)) return TRUE;
338  }
339 
340  switch(flags & FLG_ADDREG_TYPE_MASK)
341  {
342  case FLG_ADDREG_TYPE_SZ: type = REG_SZ; break;
345  case FLG_ADDREG_TYPE_BINARY: type = REG_BINARY; break;
346  case FLG_ADDREG_TYPE_DWORD: type = REG_DWORD; break;
347  case FLG_ADDREG_TYPE_NONE: type = REG_NONE; break;
348  default: type = flags >> 16; break;
349  }
350 
351  if (!(flags & FLG_ADDREG_BINVALUETYPE) ||
353  {
354  static const WCHAR empty;
355  WCHAR *str = NULL;
356 
357  if (type == REG_MULTI_SZ)
358  {
359  if (!SetupGetMultiSzFieldW( context, 5, NULL, 0, &size )) size = 0;
360  if (size)
361  {
362  if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;
364  }
365  if (flags & FLG_ADDREG_APPEND)
366  {
367  if (!str) return TRUE;
368  append_multi_sz_value( hkey, value, str, size );
369  HeapFree( GetProcessHeap(), 0, str );
370  return TRUE;
371  }
372  /* else fall through to normal string handling */
373  }
374  else
375  {
376  if (!SetupGetStringFieldW( context, 5, NULL, 0, &size )) size = 0;
377  if (size)
378  {
379  if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;
381  }
382  }
383 
384  if (type == REG_DWORD)
385  {
386  DWORD dw = str ? strtoulW( str, NULL, 0 ) : 0;
387  TRACE( "setting dword %s to %x\n", debugstr_w(value), dw );
388  RegSetValueExW( hkey, value, 0, type, (BYTE *)&dw, sizeof(dw) );
389  }
390  else
391  {
392  TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(str) );
393  if (str) RegSetValueExW( hkey, value, 0, type, (BYTE *)str, size * sizeof(WCHAR) );
394  else RegSetValueExW( hkey, value, 0, type, (const BYTE *)&empty, sizeof(WCHAR) );
395  }
396  HeapFree( GetProcessHeap(), 0, str );
397  return TRUE;
398  }
399  else /* get the binary data */
400  {
401  BYTE *data = NULL;
402 
403  if (!SetupGetBinaryField( context, 5, NULL, 0, &size )) size = 0;
404  if (size)
405  {
406  if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
407  TRACE( "setting binary data %s len %d\n", debugstr_w(value), size );
409  }
410  RegSetValueExW( hkey, value, 0, type, data, size );
411  HeapFree( GetProcessHeap(), 0, data );
412  return TRUE;
413  }
414 }
415 
416 
417 /***********************************************************************
418  * registry_callback
419  *
420  * Called once for each AddReg and DelReg entry in a given section.
421  */
422 static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg )
423 {
424  struct registry_callback_info *info = arg;
425  LPWSTR security_key, security_descriptor;
426  INFCONTEXT context, security_context;
428  SECURITY_ATTRIBUTES security_attributes = { 0, };
429  HKEY root_key, hkey;
430  DWORD required;
431 
433  if (!ok)
434  return TRUE;
435 
436  /* Check for .Security section */
437  security_key = MyMalloc( (strlenW( field ) + strlenW( DotSecurity )) * sizeof(WCHAR) + sizeof(UNICODE_NULL) );
438  if (!security_key)
439  {
441  return FALSE;
442  }
443  strcpyW( security_key, field );
444  strcatW( security_key, DotSecurity );
445  ok = SetupFindFirstLineW( hinf, security_key, NULL, &security_context );
446  MyFree(security_key);
447  if (ok)
448  {
449  if (!SetupGetLineTextW( &security_context, NULL, NULL, NULL, NULL, 0, &required ))
450  return FALSE;
451  security_descriptor = MyMalloc( required * sizeof(WCHAR) );
452  if (!security_descriptor)
453  {
455  return FALSE;
456  }
457  if (!SetupGetLineTextW( &security_context, NULL, NULL, NULL, security_descriptor, required, NULL ))
458  return FALSE;
460  MyFree( security_descriptor );
461  if (!ok)
462  return FALSE;
463  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
464  security_attributes.lpSecurityDescriptor = sd;
465  }
466 
467  for (ok = TRUE; ok; ok = SetupFindNextLine( &context, &context ))
468  {
470  INT flags;
471 
472  /* get root */
473  if (!SetupGetStringFieldW( &context, 1, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
474  continue;
475  if (!(root_key = get_root_key( buffer, info->default_root )))
476  continue;
477 
478  /* get key */
479  if (!SetupGetStringFieldW( &context, 2, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
480  *buffer = 0;
481 
482  /* get flags */
483  if (!SetupGetIntField( &context, 4, &flags )) flags = 0;
484 
485  if (!info->delete)
486  {
487  if (flags & FLG_ADDREG_DELREG_BIT) continue; /* ignore this entry */
488  }
489  else
490  {
492  else if (!(flags & FLG_ADDREG_DELREG_BIT)) continue; /* ignore this entry */
493  }
494 
495  if (info->delete || (flags & FLG_ADDREG_OVERWRITEONLY))
496  {
497  if (RegOpenKeyW( root_key, buffer, &hkey )) continue; /* ignore if it doesn't exist */
498  }
500  sd ? &security_attributes : NULL, &hkey, NULL ))
501  {
502  ERR( "could not create key %p %s\n", root_key, debugstr_w(buffer) );
503  continue;
504  }
505  TRACE( "key %p %s\n", root_key, debugstr_w(buffer) );
506 
507  /* get value name */
508  if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
509  *buffer = 0;
510 
511  /* and now do it */
512  if (!do_reg_operation( hkey, buffer, &context, flags ))
513  {
514  if (hkey != root_key) RegCloseKey( hkey );
515  if (sd) LocalFree( sd );
516  return FALSE;
517  }
518  if (hkey != root_key) RegCloseKey( hkey );
519  }
520  if (sd) LocalFree( sd );
521  return TRUE;
522 }
523 
524 
525 /***********************************************************************
526  * do_register_dll
527  *
528  * Register or unregister a dll.
529  */
530 static BOOL do_register_dll( const struct register_dll_info *info, const WCHAR *path,
531  INT flags, INT timeout, const WCHAR *args )
532 {
533  HMODULE module;
534  HRESULT res;
536 #ifdef __WINESRC__
538 #endif
539 
540  status.cbSize = sizeof(status);
541  status.FileName = path;
542  status.FailureCode = SPREG_SUCCESS;
543  status.Win32Error = ERROR_SUCCESS;
544 
545  if (info->callback)
546  {
547  switch(info->callback( info->callback_context, SPFILENOTIFY_STARTREGISTRATION,
548  (UINT_PTR)&status, !info->unregister ))
549  {
550  case FILEOP_ABORT:
552  return FALSE;
553  case FILEOP_SKIP:
554  return TRUE;
555  case FILEOP_DOIT:
556  break;
557  }
558  }
559 
561  {
562  WARN( "could not load %s\n", debugstr_w(path) );
563  status.FailureCode = SPREG_LOADLIBRARY;
564  status.Win32Error = GetLastError();
565  goto done;
566  }
567 
568 #ifdef __WINESRC__
570  {
571  /* file is an executable, not a dll */
574  WCHAR *cmd_line;
575  BOOL res;
576  static const WCHAR format[] = {'"','%','s','"',' ','%','s',0};
577  static const WCHAR default_args[] = {'/','R','e','g','S','e','r','v','e','r',0};
578 
579  FreeLibrary( module );
580  module = NULL;
581  if (!args) args = default_args;
582  cmd_line = HeapAlloc( GetProcessHeap(), 0, (strlenW(path) + strlenW(args) + 4) * sizeof(WCHAR) );
583  sprintfW( cmd_line, format, path, args );
584  memset( &startup, 0, sizeof(startup) );
585  startup.cb = sizeof(startup);
586  TRACE( "executing %s\n", debugstr_w(cmd_line) );
587  res = CreateProcessW( NULL, cmd_line, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info );
588  HeapFree( GetProcessHeap(), 0, cmd_line );
589  if (!res)
590  {
591  status.FailureCode = SPREG_LOADLIBRARY;
592  status.Win32Error = GetLastError();
593  goto done;
594  }
595  CloseHandle( info.hThread );
596 
597  if (WaitForSingleObject( info.hProcess, timeout*1000 ) == WAIT_TIMEOUT)
598  {
599  /* timed out, kill the process */
600  TerminateProcess( info.hProcess, 1 );
601  status.FailureCode = SPREG_TIMEOUT;
602  status.Win32Error = ERROR_TIMEOUT;
603  }
604  CloseHandle( info.hProcess );
605  goto done;
606  }
607 #endif // __WINESRC__
608 
610  {
611  const char *entry_point = info->unregister ? "DllUnregisterServer" : "DllRegisterServer";
612  HRESULT (WINAPI *func)(void) = (void *)GetProcAddress( module, entry_point );
613 
614  if (!func)
615  {
616  status.FailureCode = SPREG_GETPROCADDR;
617  status.Win32Error = GetLastError();
618  goto done;
619  }
620 
621  TRACE( "calling %s in %s\n", entry_point, debugstr_w(path) );
622  res = func();
623 
624  if (FAILED(res))
625  {
626  WARN( "calling %s in %s returned error %x\n", entry_point, debugstr_w(path), res );
627  status.FailureCode = SPREG_REGSVR;
628  status.Win32Error = res;
629  goto done;
630  }
631  }
632 
634  {
635  HRESULT (WINAPI *func)(BOOL,LPCWSTR) = (void *)GetProcAddress( module, "DllInstall" );
636 
637  if (!func)
638  {
639  status.FailureCode = SPREG_GETPROCADDR;
640  status.Win32Error = GetLastError();
641  goto done;
642  }
643 
644  TRACE( "calling DllInstall(%d,%s) in %s\n",
645  !info->unregister, debugstr_w(args), debugstr_w(path) );
646  res = func( !info->unregister, args );
647 
648  if (FAILED(res))
649  {
650  WARN( "calling DllInstall in %s returned error %x\n", debugstr_w(path), res );
651  status.FailureCode = SPREG_REGSVR;
652  status.Win32Error = res;
653  goto done;
654  }
655  }
656 
657 done:
658  if (module) FreeLibrary( module );
659  if (info->callback) info->callback( info->callback_context, SPFILENOTIFY_ENDREGISTRATION,
660  (UINT_PTR)&status, !info->unregister );
661  return TRUE;
662 }
663 
664 
665 /***********************************************************************
666  * register_dlls_callback
667  *
668  * Called once for each RegisterDlls entry in a given section.
669  */
671 {
672  struct register_dll_info *info = arg;
674  BOOL ret = TRUE;
676 
677  for (; ok; ok = SetupFindNextLine( &context, &context ))
678  {
679  WCHAR *path, *args, *p;
681  INT flags, timeout;
682 
683  /* get directory */
684  if (!(path = PARSER_get_dest_dir( &context ))) continue;
685 
686  /* get dll name */
687  if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
688  goto done;
689  if (!(p = HeapReAlloc( GetProcessHeap(), 0, path,
690  (strlenW(path) + strlenW(buffer) + 2) * sizeof(WCHAR) ))) goto done;
691  path = p;
692  p += strlenW(p);
693  if (p == path || p[-1] != '\\') *p++ = '\\';
694  strcpyW( p, buffer );
695 
696  /* get flags */
697  if (!SetupGetIntField( &context, 4, &flags )) flags = 0;
698 
699  /* get timeout */
700  if (!SetupGetIntField( &context, 5, &timeout )) timeout = 60;
701 
702  /* get command line */
703  args = NULL;
704  if (SetupGetStringFieldW( &context, 6, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
705  args = buffer;
706 
708 
709  done:
710  HeapFree( GetProcessHeap(), 0, path );
711  if (!ret) break;
712  }
713  return ret;
714 }
715 
716 #ifdef __WINESRC__
717 /***********************************************************************
718  * fake_dlls_callback
719  *
720  * Called once for each WineFakeDlls entry in a given section.
721  */
722 static BOOL fake_dlls_callback( HINF hinf, PCWSTR field, void *arg )
723 {
725  BOOL ret = TRUE;
727 
728  for (; ok; ok = SetupFindNextLine( &context, &context ))
729  {
730  WCHAR *path, *p;
732 
733  /* get directory */
734  if (!(path = PARSER_get_dest_dir( &context ))) continue;
735 
736  /* get dll name */
737  if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
738  goto done;
739  if (!(p = HeapReAlloc( GetProcessHeap(), 0, path,
740  (strlenW(path) + strlenW(buffer) + 2) * sizeof(WCHAR) ))) goto done;
741  path = p;
742  p += strlenW(p);
743  if (p == path || p[-1] != '\\') *p++ = '\\';
744  strcpyW( p, buffer );
745 
746  /* get source dll */
747  if (SetupGetStringFieldW( &context, 4, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
748  p = buffer; /* otherwise use target base name as default source */
749 
750  create_fake_dll( path, p ); /* ignore errors */
751 
752  done:
753  HeapFree( GetProcessHeap(), 0, path );
754  if (!ret) break;
755  }
756  return ret;
757 }
758 #endif // __WINESRC__
759 
760 /***********************************************************************
761  * update_ini_callback
762  *
763  * Called once for each UpdateInis entry in a given section.
764  */
765 static BOOL update_ini_callback( HINF hinf, PCWSTR field, void *arg )
766 {
768 
770 
771  for (; ok; ok = SetupFindNextLine( &context, &context ))
772  {
778  LPWSTR divider;
779 
781  sizeof(filename)/sizeof(WCHAR), NULL ))
782  continue;
783 
785  sizeof(section)/sizeof(WCHAR), NULL ))
786  continue;
787 
789  sizeof(buffer)/sizeof(WCHAR), NULL ))
790  continue;
791 
792  divider = strchrW(buffer,'=');
793  if (divider)
794  {
795  *divider = 0;
797  divider++;
798  strcpyW(string,divider);
799  }
800  else
801  {
803  string[0]=0;
804  }
805 
806  TRACE("Writing %s = %s in %s of file %s\n",debugstr_w(entry),
809 
810  }
811  return TRUE;
812 }
813 
815 {
816  FIXME( "should update ini fields %s\n", debugstr_w(field) );
817  return TRUE;
818 }
819 
820 static BOOL ini2reg_callback( HINF hinf, PCWSTR field, void *arg )
821 {
822  FIXME( "should do ini2reg %s\n", debugstr_w(field) );
823  return TRUE;
824 }
825 
826 static BOOL logconf_callback( HINF hinf, PCWSTR field, void *arg )
827 {
828  FIXME( "should do logconf %s\n", debugstr_w(field) );
829  return TRUE;
830 }
831 
832 static BOOL bitreg_callback( HINF hinf, PCWSTR field, void *arg )
833 {
834  FIXME( "should do bitreg %s\n", debugstr_w(field) );
835  return TRUE;
836 }
837 
838 static BOOL Concatenate(int DirId, LPCWSTR SubDirPart, LPCWSTR NamePart, LPWSTR *pFullName)
839 {
840  DWORD dwRequired = 0;
841  LPCWSTR Dir;
843 
844  *pFullName = NULL;
845 
846  Dir = DIRID_get_string(DirId);
847  if (Dir)
848  dwRequired += wcslen(Dir) + 1;
849  if (SubDirPart)
850  dwRequired += wcslen(SubDirPart) + 1;
851  if (NamePart)
852  dwRequired += wcslen(NamePart);
853  dwRequired = dwRequired * sizeof(WCHAR) + sizeof(UNICODE_NULL);
854 
855  FullName = MyMalloc(dwRequired);
856  if (!FullName)
857  {
859  return FALSE;
860  }
861  FullName[0] = UNICODE_NULL;
862 
863  if (Dir)
864  {
865  wcscat(FullName, Dir);
866  if (FullName[wcslen(FullName) - 1] != '\\')
868  }
869  if (SubDirPart)
870  {
871  wcscat(FullName, SubDirPart);
872  if (FullName[wcslen(FullName) - 1] != '\\')
874  }
875  if (NamePart)
876  wcscat(FullName, NamePart);
877 
878  *pFullName = FullName;
879  return TRUE;
880 }
881 
882 /***********************************************************************
883  * profile_items_callback
884  *
885  * Called once for each ProfileItems entry in a given section.
886  */
887 static BOOL
889  IN HINF hInf,
890  IN PCWSTR SectionName,
891  IN PVOID Arg)
892 {
894  LPWSTR LinkSubDir = NULL, LinkName = NULL;
895  INT LinkAttributes = 0;
896  INT LinkFolder = 0;
897  INT FileDirId = 0;
898  INT CSIDL = CSIDL_COMMON_PROGRAMS;
899  LPWSTR FileSubDir = NULL;
900  INT DirId = 0;
901  LPWSTR SubDirPart = NULL, NamePart = NULL;
902  LPWSTR FullLinkName = NULL, FullFileName = NULL, FullWorkingDir = NULL, FullIconName = NULL;
903  INT IconIdx = 0;
904  LPWSTR lpHotKey = NULL, lpInfoTip = NULL;
905  LPWSTR DisplayName = NULL;
906  INT DisplayResId = 0;
907  BOOL ret = FALSE;
909 
910  IShellLinkW *psl;
911  IPersistFile *ppf;
912  HMODULE hOle32 = NULL;
913  COINITIALIZE pCoInitialize;
914  COCREATEINSTANCE pCoCreateInstance;
915  COUNINITIALIZE pCoUninitialize;
916  HRESULT hr;
917 
918  TRACE("hInf %p, SectionName %s, Arg %p\n",
919  hInf, debugstr_w(SectionName), Arg);
920 
921  /* Read 'Name' entry */
922  if (!SetupFindFirstLineW(hInf, SectionName, Name, &Context))
923  goto cleanup;
924  if (!GetStringField(&Context, 1, &LinkName))
925  goto cleanup;
926  if (SetupGetFieldCount(&Context) >= 2)
927  {
928  if (!SetupGetIntField(&Context, 2, &LinkAttributes))
929  goto cleanup;
930  }
931  if (SetupGetFieldCount(&Context) >= 3)
932  {
933  if (!SetupGetIntField(&Context, 3, &LinkFolder))
934  goto cleanup;
935  }
936 
937  /* Read 'CmdLine' entry */
938  if (!SetupFindFirstLineW(hInf, SectionName, CmdLine, &Context))
939  goto cleanup;
940  Index = 1;
941  if (!SetupGetIntField(&Context, Index++, &FileDirId))
942  goto cleanup;
943  if (SetupGetFieldCount(&Context) >= 3)
944  {
945  if (!GetStringField(&Context, Index++, &FileSubDir))
946  goto cleanup;
947  }
948  if (!GetStringField(&Context, Index++, &NamePart))
949  goto cleanup;
950  if (!Concatenate(FileDirId, FileSubDir, NamePart, &FullFileName))
951  goto cleanup;
952  MyFree(NamePart);
953  NamePart = NULL;
954 
955  /* Read 'SubDir' entry */
956  if ((LinkAttributes & FLG_PROFITEM_GROUP) == 0 && SetupFindFirstLineW(hInf, SectionName, SubDir, &Context))
957  {
958  if (!GetStringField(&Context, 1, &LinkSubDir))
959  goto cleanup;
960  }
961 
962  /* Read 'WorkingDir' entry */
963  if (SetupFindFirstLineW(hInf, SectionName, WorkingDir, &Context))
964  {
965  if (!SetupGetIntField(&Context, 1, &DirId))
966  goto cleanup;
967  if (SetupGetFieldCount(&Context) >= 2)
968  {
969  if (!GetStringField(&Context, 2, &SubDirPart))
970  goto cleanup;
971  }
972  if (!Concatenate(DirId, SubDirPart, NULL, &FullWorkingDir))
973  goto cleanup;
974  MyFree(SubDirPart);
975  SubDirPart = NULL;
976  }
977  else
978  {
979  if (!Concatenate(FileDirId, FileSubDir, NULL, &FullWorkingDir))
980  goto cleanup;
981  }
982 
983  /* Read 'IconPath' entry */
984  if (SetupFindFirstLineW(hInf, SectionName, IconPath, &Context))
985  {
986  Index = 1;
987  if (!SetupGetIntField(&Context, Index++, &DirId))
988  goto cleanup;
989  if (SetupGetFieldCount(&Context) >= 3)
990  {
991  if (!GetStringField(&Context, Index++, &SubDirPart))
992  goto cleanup;
993  }
994  if (!GetStringField(&Context, Index, &NamePart))
995  goto cleanup;
996  if (!Concatenate(DirId, SubDirPart, NamePart, &FullIconName))
997  goto cleanup;
998  MyFree(SubDirPart);
999  MyFree(NamePart);
1000  SubDirPart = NamePart = NULL;
1001  }
1002  else
1003  {
1004  FullIconName = pSetupDuplicateString(FullFileName);
1005  if (!FullIconName)
1006  goto cleanup;
1007  }
1008 
1009  /* Read 'IconIndex' entry */
1010  if (SetupFindFirstLineW(hInf, SectionName, IconIndex, &Context))
1011  {
1012  if (!SetupGetIntField(&Context, 1, &IconIdx))
1013  goto cleanup;
1014  }
1015 
1016  /* Read 'HotKey' and 'InfoTip' entries */
1017  GetLineText(hInf, SectionName, HotKey, &lpHotKey);
1018  GetLineText(hInf, SectionName, InfoTip, &lpInfoTip);
1019 
1020  /* Read 'DisplayResource' entry */
1021  if (SetupFindFirstLineW(hInf, SectionName, DisplayResource, &Context))
1022  {
1023  if (!GetStringField(&Context, 1, &DisplayName))
1024  goto cleanup;
1025  if (!SetupGetIntField(&Context, 2, &DisplayResId))
1026  goto cleanup;
1027  }
1028 
1029  /* Some debug */
1030  TRACE("Link is %s\\%s, attributes 0x%x\n", debugstr_w(LinkSubDir), debugstr_w(LinkName), LinkAttributes);
1031  TRACE("File is %s\n", debugstr_w(FullFileName));
1032  TRACE("Working dir %s\n", debugstr_w(FullWorkingDir));
1033  TRACE("Icon is %s, %d\n", debugstr_w(FullIconName), IconIdx);
1034  TRACE("Hotkey %s\n", debugstr_w(lpHotKey));
1035  TRACE("InfoTip %s\n", debugstr_w(lpInfoTip));
1036  TRACE("Display %s, %d\n", DisplayName, DisplayResId);
1037 
1038  /* Load ole32.dll */
1039  hOle32 = LoadLibraryA("ole32.dll");
1040  if (!hOle32)
1041  goto cleanup;
1042  pCoInitialize = (COINITIALIZE)GetProcAddress(hOle32, "CoInitialize");
1043  if (!pCoInitialize)
1044  goto cleanup;
1045  pCoCreateInstance = (COCREATEINSTANCE)GetProcAddress(hOle32, "CoCreateInstance");
1046  if (!pCoCreateInstance)
1047  goto cleanup;
1048  pCoUninitialize = (COUNINITIALIZE)GetProcAddress(hOle32, "CoUninitialize");
1049  if (!pCoUninitialize)
1050  goto cleanup;
1051 
1052  /* Create shortcut */
1053  hr = pCoInitialize(NULL);
1054  if (!SUCCEEDED(hr))
1055  {
1058  else
1060  goto cleanup;
1061  }
1062  hr = pCoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID*)&psl);
1063  if (SUCCEEDED(hr))
1064  {
1065  /* Fill link properties */
1066  hr = IShellLinkW_SetPath(psl, FullFileName);
1067  if (SUCCEEDED(hr))
1068  hr = IShellLinkW_SetArguments(psl, L"");
1069  if (SUCCEEDED(hr))
1070  hr = IShellLinkW_SetWorkingDirectory(psl, FullWorkingDir);
1071  if (SUCCEEDED(hr))
1072  hr = IShellLinkW_SetIconLocation(psl, FullIconName, IconIdx);
1073  if (SUCCEEDED(hr) && lpHotKey)
1074  FIXME("Need to store hotkey %s in shell link\n", debugstr_w(lpHotKey));
1075  if (SUCCEEDED(hr) && lpInfoTip)
1076  hr = IShellLinkW_SetDescription(psl, lpInfoTip);
1077  if (SUCCEEDED(hr) && DisplayName)
1078  FIXME("Need to store display name %s, %d in shell link\n", debugstr_w(DisplayName), DisplayResId);
1079  if (SUCCEEDED(hr))
1080  {
1081  hr = IShellLinkW_QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
1082  if (SUCCEEDED(hr))
1083  {
1084  Required = (MAX_PATH + 1 +
1085  ((LinkSubDir != NULL) ? wcslen(LinkSubDir) : 0) +
1086  ((LinkName != NULL) ? wcslen(LinkName) : 0)) * sizeof(WCHAR);
1087  FullLinkName = MyMalloc(Required);
1088  if (!FullLinkName)
1089  hr = E_OUTOFMEMORY;
1090  else
1091  {
1092  if (LinkAttributes & (FLG_PROFITEM_DELETE | FLG_PROFITEM_GROUP))
1093  FIXME("Need to handle FLG_PROFITEM_DELETE and FLG_PROFITEM_GROUP\n");
1094  if (LinkAttributes & FLG_PROFITEM_CSIDL)
1095  CSIDL = LinkFolder;
1096  else if (LinkAttributes & FLG_PROFITEM_CURRENTUSER)
1097  CSIDL = CSIDL_PROGRAMS;
1098 
1100  NULL,
1101  FullLinkName,
1102  CSIDL,
1103  TRUE))
1104  {
1105  if (FullLinkName[wcslen(FullLinkName) - 1] != '\\')
1106  wcscat(FullLinkName, BackSlash);
1107  if (LinkSubDir)
1108  {
1109  wcscat(FullLinkName, LinkSubDir);
1110  if (FullLinkName[wcslen(FullLinkName) - 1] != '\\')
1111  wcscat(FullLinkName, BackSlash);
1112  }
1113  if (LinkName)
1114  {
1115  wcscat(FullLinkName, LinkName);
1116  wcscat(FullLinkName, DotLnk);
1117  }
1118  hr = IPersistFile_Save(ppf, FullLinkName, TRUE);
1119  }
1120  else
1122  }
1123  IPersistFile_Release(ppf);
1124  }
1125  }
1126  IShellLinkW_Release(psl);
1127  }
1128  pCoUninitialize();
1129  if (SUCCEEDED(hr))
1130  ret = TRUE;
1131  else
1132  {
1135  else
1137  }
1138 
1139 cleanup:
1140  MyFree(LinkSubDir);
1141  MyFree(LinkName);
1142  MyFree(FileSubDir);
1143  MyFree(SubDirPart);
1144  MyFree(NamePart);
1145  MyFree(FullFileName);
1146  MyFree(FullWorkingDir);
1147  MyFree(FullIconName);
1148  MyFree(FullLinkName);
1149  MyFree(lpHotKey);
1150  MyFree(lpInfoTip);
1151  MyFree(DisplayName);
1152  if (hOle32)
1153  FreeLibrary(hOle32);
1154 
1155  TRACE("Returning %d\n", ret);
1156  return ret;
1157 }
1158 
1159 static BOOL copy_inf_callback( HINF hinf, PCWSTR field, void *arg )
1160 {
1161  FIXME( "should do copy inf %s\n", debugstr_w(field) );
1162  return TRUE;
1163 }
1164 
1165 
1166 /***********************************************************************
1167  * iterate_section_fields
1168  *
1169  * Iterate over all fields of a certain key of a certain section
1170  */
1173 {
1174  WCHAR static_buffer[200];
1175  WCHAR *buffer = static_buffer;
1176  DWORD size = sizeof(static_buffer)/sizeof(WCHAR);
1178  BOOL ret = FALSE;
1179 
1180  BOOL ok = SetupFindFirstLineW( hinf, section, key, &context );
1181  while (ok)
1182  {
1184  for (i = 1; i <= count; i++)
1185  {
1186  if (!(buffer = get_field_string( &context, i, buffer, static_buffer, &size )))
1187  goto done;
1188  if (!callback( hinf, buffer, arg ))
1189  {
1190  WARN("callback failed for %s %s err %d\n",
1192  goto done;
1193  }
1194  }
1196  }
1197  ret = TRUE;
1198  done:
1199  if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
1200  return ret;
1201 }
1202 
1203 
1204 /***********************************************************************
1205  * SetupInstallFilesFromInfSectionA (SETUPAPI.@)
1206  */
1208  PCSTR section, PCSTR src_root, UINT flags )
1209 {
1210  UNICODE_STRING sectionW;
1211  BOOL ret = FALSE;
1212 
1213  if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1214  {
1216  return FALSE;
1217  }
1218  if (!src_root)
1219  ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
1220  NULL, flags );
1221  else
1222  {
1223  UNICODE_STRING srcW;
1224  if (RtlCreateUnicodeStringFromAsciiz( &srcW, src_root ))
1225  {
1226  ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
1227  srcW.Buffer, flags );
1228  RtlFreeUnicodeString( &srcW );
1229  }
1231  }
1232  RtlFreeUnicodeString( &sectionW );
1233  return ret;
1234 }
1235 
1236 
1237 /***********************************************************************
1238  * SetupInstallFilesFromInfSectionW (SETUPAPI.@)
1239  */
1241  PCWSTR section, PCWSTR src_root, UINT flags )
1242 {
1243  struct files_callback_info info;
1244 
1245  info.queue = queue;
1246  info.src_root = src_root;
1247  info.copy_flags = flags;
1248  info.layout = hlayout;
1250 }
1251 
1252 
1253 /***********************************************************************
1254  * SetupInstallFromInfSectionA (SETUPAPI.@)
1255  */
1257  HKEY key_root, PCSTR src_root, UINT copy_flags,
1259  HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )
1260 {
1261  UNICODE_STRING sectionW, src_rootW;
1262  struct callback_WtoA_context ctx;
1263  BOOL ret = FALSE;
1264 
1265  src_rootW.Buffer = NULL;
1266  if (src_root && !RtlCreateUnicodeStringFromAsciiz( &src_rootW, src_root ))
1267  {
1269  return FALSE;
1270  }
1271 
1272  if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1273  {
1274  ctx.orig_context = context;
1275  ctx.orig_handler = callback;
1276  ret = SetupInstallFromInfSectionW( owner, hinf, sectionW.Buffer, flags, key_root,
1277  src_rootW.Buffer, copy_flags, QUEUE_callback_WtoA,
1278  &ctx, devinfo, devinfo_data );
1279  RtlFreeUnicodeString( &sectionW );
1280  }
1282 
1283  RtlFreeUnicodeString( &src_rootW );
1284  return ret;
1285 }
1286 
1287 
1288 /***********************************************************************
1289  * include_callback
1290  *
1291  * Called once for each Include entry in a given section.
1292  */
1293 static BOOL include_callback( HINF hinf, PCWSTR field, void *arg )
1294 {
1295  return SetupOpenAppendInfFileW( field, hinf, NULL );
1296 }
1297 
1298 
1299 /***********************************************************************
1300  * needs_callback
1301  *
1302  * Called once for each Needs entry in a given section.
1303  */
1304 static BOOL needs_callback( HINF hinf, PCWSTR field, void *arg )
1305 {
1306  struct needs_callback_info *info = arg;
1307 
1308  switch (info->type)
1309  {
1310  case 0:
1311  return SetupInstallFromInfSectionW(info->owner, *(HINF*)hinf, field, info->flags,
1312  info->key_root, info->src_root, info->copy_flags, info->callback,
1313  info->context, info->devinfo, info->devinfo_data);
1314  case 1:
1315  return SetupInstallServicesFromInfSectionExW(*(HINF*)hinf, field, info->flags,
1316  info->devinfo, info->devinfo_data, info->reserved1, info->reserved2);
1317  default:
1318  ERR("Unknown info type %u\n", info->type);
1319  return FALSE;
1320  }
1321 }
1322 
1323 
1324 /***********************************************************************
1325  * SetupInstallFromInfSectionW (SETUPAPI.@)
1326  */
1331 {
1332  struct needs_callback_info needs_info;
1333 
1334  /* Parse 'Include' and 'Needs' directives */
1336  needs_info.type = 0;
1337  needs_info.owner = owner;
1338  needs_info.flags = flags;
1339  needs_info.key_root = key_root;
1340  needs_info.src_root = src_root;
1341  needs_info.copy_flags = copy_flags;
1342  needs_info.callback = callback;
1343  needs_info.context = context;
1344  needs_info.devinfo = devinfo;
1345  needs_info.devinfo_data = devinfo_data;
1346  iterate_section_fields( hinf, section, Needs, needs_callback, &needs_info);
1347 
1348  if (flags & SPINST_FILES)
1349  {
1350  SP_DEVINSTALL_PARAMS_W install_params;
1351  struct files_callback_info info;
1352  HSPFILEQ queue = NULL;
1353  BOOL use_custom_queue;
1354  BOOL ret;
1355 
1356  install_params.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
1357  use_custom_queue = SetupDiGetDeviceInstallParamsW(devinfo, devinfo_data, &install_params) && (install_params.Flags & DI_NOVCP);
1358  if (!use_custom_queue && ((queue = SetupOpenFileQueue()) == (HSPFILEQ)INVALID_HANDLE_VALUE ))
1359  return FALSE;
1360  info.queue = use_custom_queue ? install_params.FileQueue : queue;
1361  info.src_root = src_root;
1362  info.copy_flags = copy_flags;
1363  info.layout = hinf;
1367  if (!use_custom_queue)
1368  {
1369  if (ret)
1372  }
1373  if (!ret) return FALSE;
1374  }
1375  if (flags & SPINST_INIFILES)
1376  {
1380  return FALSE;
1381  }
1382  if (flags & SPINST_INI2REG)
1383  {
1385  return FALSE;
1386  }
1387  if (flags & SPINST_LOGCONFIG)
1388  {
1390  return FALSE;
1391  }
1392  if (flags & SPINST_REGSVR)
1393  {
1394  struct register_dll_info info;
1395 
1396  info.unregister = FALSE;
1397  if (flags & SPINST_REGISTERCALLBACKAWARE)
1398  {
1399  info.callback = callback;
1400  info.callback_context = context;
1401  }
1402  else info.callback = NULL;
1403 
1405  return FALSE;
1406 
1407 #ifdef __WINESRC__
1408  if (!iterate_section_fields( hinf, section, WineFakeDlls, fake_dlls_callback, NULL ))
1409  return FALSE;
1410 #endif // __WINESRC__
1411  }
1412  if (flags & SPINST_UNREGSVR)
1413  {
1414  struct register_dll_info info;
1415 
1416  info.unregister = TRUE;
1417  if (flags & SPINST_REGISTERCALLBACKAWARE)
1418  {
1419  info.callback = callback;
1420  info.callback_context = context;
1421  }
1422  else info.callback = NULL;
1423 
1425  return FALSE;
1426  }
1427  if (flags & SPINST_REGISTRY)
1428  {
1430 
1431  info.default_root = key_root;
1432  info.delete = TRUE;
1434  return FALSE;
1435  info.delete = FALSE;
1437  return FALSE;
1438  }
1439  if (flags & SPINST_BITREG)
1440  {
1442  return FALSE;
1443  }
1444  if (flags & SPINST_PROFILEITEMS)
1445  {
1447  return FALSE;
1448  }
1449  if (flags & SPINST_COPYINF)
1450  {
1452  return FALSE;
1453  }
1454 
1455  return TRUE;
1456 }
1457 
1458 
1459 /***********************************************************************
1460  * InstallHinfSectionW (SETUPAPI.@)
1461  *
1462  * NOTE: 'cmdline' is <section> <mode> <path> from
1463  * RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection <section> <mode> <path>
1464  */
1466 {
1467  BOOL ret = FALSE;
1468  WCHAR *s, *path, section[MAX_PATH];
1469  void *callback_context = NULL;
1470  DWORD SectionNameLength;
1471  UINT mode;
1472  HINF hinf = INVALID_HANDLE_VALUE;
1473  BOOL bRebootRequired = FALSE;
1474 
1475  TRACE("hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_w(cmdline));
1476 
1478 
1479  if (!(s = strchrW( section, ' ' ))) goto cleanup;
1480  *s++ = 0;
1481  while (*s == ' ') s++;
1482  mode = atoiW( s );
1483 
1484  /* quoted paths are not allowed on native, the rest of the command line is taken as the path */
1485  if (!(s = strchrW( s, ' ' ))) goto cleanup;
1486  while (*s == ' ') s++;
1487  path = s;
1488 
1489  if (mode & 0x80)
1490  {
1491  FIXME("default path of the installation not changed\n");
1492  mode &= ~0x80;
1493  }
1494 
1496  if (hinf == INVALID_HANDLE_VALUE)
1497  {
1498  WARN("SetupOpenInfFileW(%s) failed (Error %u)\n", path, GetLastError());
1499  goto cleanup;
1500  }
1501 
1503  hinf, section, section, sizeof(section)/sizeof(section[0]), &SectionNameLength, NULL );
1504  if (!ret)
1505  {
1506  WARN("SetupDiGetActualSectionToInstallW() failed (Error %u)\n", GetLastError());
1507  goto cleanup;
1508  }
1509  if (SectionNameLength > MAX_PATH - strlenW(DotServices))
1510  {
1511  WARN("Section name '%s' too long\n", section);
1512  goto cleanup;
1513  }
1514 
1515  /* Copy files and add registry entries */
1520  NULL, NULL );
1521  if (!ret)
1522  {
1523  WARN("SetupInstallFromInfSectionW() failed (Error %u)\n", GetLastError());
1524  goto cleanup;
1525  }
1526  /* FIXME: need to check if some files were in use and need reboot
1527  * bReboot = ...;
1528  */
1529 
1530  /* Install services */
1534  ret = TRUE;
1535  if (!ret)
1536  {
1537  WARN("SetupInstallServicesFromInfSectionW() failed (Error %u)\n", GetLastError());
1538  goto cleanup;
1539  }
1541  {
1542  bRebootRequired = TRUE;
1543  }
1544 
1545  /* Check if we need to reboot */
1546  switch (mode)
1547  {
1548  case 0:
1549  /* Never reboot */
1550  break;
1551  case 1:
1552  /* Always reboot */
1553  ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
1554  SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
1555  break;
1556  case 2:
1557  /* Query user before rebooting */
1559  break;
1560  case 3:
1561  /* Reboot if necessary */
1562  if (bRebootRequired)
1563  {
1564  ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
1565  SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
1566  }
1567  break;
1568  case 4:
1569  /* If necessary, query user before rebooting */
1570  if (bRebootRequired)
1571  {
1573  }
1574  break;
1575  default:
1576  break;
1577  }
1578 
1579 cleanup:
1580  if ( callback_context )
1582  if ( hinf != INVALID_HANDLE_VALUE )
1583  SetupCloseInfFile( hinf );
1584 
1585 #ifdef CORE_11689_IS_FIXED
1586  // TODO: Localize the error string.
1588  {
1589  MessageBoxW(hwnd, section, L"setupapi.dll: An error happened...", MB_ICONERROR | MB_OK);
1590  }
1591 #endif
1592 }
1593 
1594 
1595 /***********************************************************************
1596  * InstallHinfSectionA (SETUPAPI.@)
1597  */
1599 {
1600  UNICODE_STRING cmdlineW;
1601 
1602  if (RtlCreateUnicodeStringFromAsciiz( &cmdlineW, cmdline ))
1603  {
1604  InstallHinfSectionW( hwnd, handle, cmdlineW.Buffer, show );
1605  RtlFreeUnicodeString( &cmdlineW );
1606  }
1607 }
1608 
1609 /***********************************************************************
1610  * SetupInstallServicesFromInfSectionW (SETUPAPI.@)
1611  */
1613 {
1614  return SetupInstallServicesFromInfSectionExW( Inf, SectionName, Flags,
1615  NULL, NULL, NULL, NULL );
1616 }
1617 
1618 /***********************************************************************
1619  * SetupInstallServicesFromInfSectionA (SETUPAPI.@)
1620  */
1622 {
1623  return SetupInstallServicesFromInfSectionExA( Inf, SectionName, Flags,
1624  NULL, NULL, NULL, NULL );
1625 }
1626 
1627 /***********************************************************************
1628  * SetupInstallServicesFromInfSectionExA (SETUPAPI.@)
1629  */
1631 {
1632  UNICODE_STRING sectionnameW;
1633  BOOL ret = FALSE;
1634 
1635  if (RtlCreateUnicodeStringFromAsciiz( &sectionnameW, sectionname ))
1636  {
1637  ret = SetupInstallServicesFromInfSectionExW( hinf, sectionnameW.Buffer, flags, devinfo, devinfo_data, reserved1, reserved2 );
1638  RtlFreeUnicodeString( &sectionnameW );
1639  }
1640  else
1642 
1643  return ret;
1644 }
1645 
1646 
1647 static BOOL GetLineText( HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
1648 {
1649  DWORD required;
1650  PWSTR buf = NULL;
1651 
1652  *value = NULL;
1653 
1654  if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, NULL, 0, &required )
1656  return FALSE;
1657 
1658  buf = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) );
1659  if ( ! buf )
1660  {
1662  return FALSE;
1663  }
1664 
1665  if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, buf, required, &required ) )
1666  {
1667  HeapFree( GetProcessHeap(), 0, buf );
1668  return FALSE;
1669  }
1670 
1671  *value = buf;
1672  return TRUE;
1673 }
1674 
1675 
1676 static BOOL GetIntField( HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
1677 {
1678  LPWSTR buffer, end;
1679  INT res;
1680 
1681  if (! GetLineText( hinf, section_name, key_name, &buffer ) )
1682  return FALSE;
1683 
1684  res = wcstol( buffer, &end, 0 );
1685  if (end != buffer && !*end)
1686  {
1688  *value = res;
1689  return TRUE;
1690  }
1691  else
1692  {
1695  return FALSE;
1696  }
1697 }
1698 
1699 
1701 {
1703  BOOL ret;
1704 
1706  context,
1707  index,
1708  NULL, 0,
1709  &RequiredSize);
1710  if (!ret)
1711  return FALSE;
1712  else if (RequiredSize == 0)
1713  {
1714  *value = NULL;
1715  return TRUE;
1716  }
1717 
1718  /* We got the needed size for the buffer */
1719  *value = MyMalloc(RequiredSize * sizeof(WCHAR));
1720  if (!*value)
1721  {
1723  return FALSE;
1724  }
1726  context,
1727  index,
1728  *value, RequiredSize, NULL);
1729  if (!ret)
1730  MyFree(*value);
1731 
1732  return ret;
1733 }
1734 
1736  IN DWORD ServiceType,
1737  IN OUT LPWSTR *ServiceBinary)
1738 {
1739  LPWSTR Buffer;
1740  WCHAR ReactOSDir[MAX_PATH];
1741  DWORD RosDirLength, ServiceLength, Win32Length;
1742 
1743  GetWindowsDirectoryW(ReactOSDir, MAX_PATH);
1744  RosDirLength = strlenW(ReactOSDir);
1745  ServiceLength = strlenW(*ServiceBinary);
1746 
1747  /* Check and fix two things:
1748  1. Get rid of C:\ReactOS and use relative
1749  path instead.
1750  2. Add %SystemRoot% for Win32 services */
1751 
1752  if (ServiceLength < RosDirLength)
1753  return;
1754 
1755  if (!wcsnicmp(*ServiceBinary, ReactOSDir, RosDirLength))
1756  {
1757  /* Yes, the first part is the C:\ReactOS\, just skip it */
1758  MoveMemory(*ServiceBinary, *ServiceBinary + RosDirLength + 1,
1759  (ServiceLength - RosDirLength) * sizeof(WCHAR));
1760 
1761  /* Handle Win32-services differently */
1762  if (ServiceType & SERVICE_WIN32)
1763  {
1764  Win32Length = (ServiceLength - RosDirLength) * sizeof(WCHAR)
1765  - sizeof(L'\\') + sizeof(L"%SystemRoot%\\");
1766  Buffer = MyMalloc(Win32Length);
1767 
1768  wcscpy(Buffer, L"%SystemRoot%\\");
1769  wcscat(Buffer, *ServiceBinary);
1770  MyFree(*ServiceBinary);
1771 
1772  *ServiceBinary = Buffer;
1773  }
1774  }
1775 }
1776 
1778  struct DeviceInfoSet *list,
1779  IN HINF hInf,
1780  IN LPCWSTR ServiceSection,
1782  IN UINT ServiceFlags)
1783 {
1784  SC_HANDLE hSCManager = NULL;
1785  SC_HANDLE hService = NULL;
1786  LPDWORD GroupOrder = NULL;
1787  LPQUERY_SERVICE_CONFIGW ServiceConfig = NULL;
1788  HKEY hServicesKey, hServiceKey;
1789  LONG rc;
1790  BOOL ret = FALSE;
1791 
1792  HKEY hGroupOrderListKey = NULL;
1793  LPWSTR ServiceBinary = NULL;
1794  LPWSTR LoadOrderGroup = NULL;
1795  LPWSTR DisplayName = NULL;
1797  LPWSTR Dependencies = NULL;
1798  LPWSTR StartName = NULL;
1801  INT ServiceType, StartType, ErrorControl;
1802  DWORD dwRegType;
1803  DWORD tagId = (DWORD)-1;
1804  BOOL useTag;
1805 
1806  if (!GetIntField(hInf, ServiceSection, ServiceTypeKey, &ServiceType))
1807  {
1809  goto cleanup;
1810  }
1811  if (!GetIntField(hInf, ServiceSection, StartTypeKey, &StartType))
1812  {
1814  goto cleanup;
1815  }
1816  if (!GetIntField(hInf, ServiceSection, ErrorControlKey, &ErrorControl))
1817  {
1819  goto cleanup;
1820  }
1821  useTag = (ServiceType == SERVICE_BOOT_START || ServiceType == SERVICE_SYSTEM_START);
1822 
1824  if (hSCManager == NULL)
1825  goto cleanup;
1826 
1827  if (!GetLineText(hInf, ServiceSection, ServiceBinaryKey, &ServiceBinary))
1828  {
1830  goto cleanup;
1831  }
1832 
1833  /* Adjust binary path according to the service type */
1834  FixupServiceBinaryPath(ServiceType, &ServiceBinary);
1835 
1836  /* Don't check return value, as these fields are optional and
1837  * GetLineText initialize output parameter even on failure */
1838  GetLineText(hInf, ServiceSection, LoadOrderGroupKey, &LoadOrderGroup);
1839  GetLineText(hInf, ServiceSection, DisplayNameKey, &DisplayName);
1840  GetLineText(hInf, ServiceSection, DescriptionKey, &Description);
1841  GetLineText(hInf, ServiceSection, DependenciesKey, &Dependencies);
1842  GetLineText(hInf, ServiceSection, StartNameKey, &StartName);
1843 
1844  /* If there is no group, we must not request a tag */
1845  if (!LoadOrderGroup || !*LoadOrderGroup)
1846  useTag = FALSE;
1847 
1848  hService = OpenServiceW(
1849  hSCManager,
1850  ServiceName,
1852  if (hService == NULL && GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
1853  goto cleanup;
1854 
1855  if (hService && (ServiceFlags & SPSVCINST_DELETEEVENTLOGENTRY))
1856  {
1857  ret = DeleteService(hService);
1859  goto cleanup;
1860  }
1861 
1862  if (hService == NULL)
1863  {
1864  /* Create new service */
1865  hService = CreateServiceW(
1866  hSCManager,
1867  ServiceName,
1868  DisplayName,
1869  WRITE_DAC,
1870  ServiceType,
1871  StartType,
1872  ErrorControl,
1873  ServiceBinary,
1874  LoadOrderGroup,
1875  useTag ? &tagId : NULL,
1876  Dependencies,
1877  StartName,
1878  NULL);
1879  if (hService == NULL)
1880  goto cleanup;
1881  }
1882  else
1883  {
1884  DWORD bufferSize;
1885  /* Read current configuration */
1886  if (!QueryServiceConfigW(hService, NULL, 0, &bufferSize))
1887  {
1889  goto cleanup;
1890  ServiceConfig = MyMalloc(bufferSize);
1891  if (!ServiceConfig)
1892  {
1894  goto cleanup;
1895  }
1896  if (!QueryServiceConfigW(hService, ServiceConfig, bufferSize, &bufferSize))
1897  goto cleanup;
1898  }
1899  tagId = ServiceConfig->dwTagId;
1900 
1901  /* Update configuration */
1903  hService,
1904  ServiceType,
1905  (ServiceFlags & SPSVCINST_NOCLOBBER_STARTTYPE) ? SERVICE_NO_CHANGE : StartType,
1906  (ServiceFlags & SPSVCINST_NOCLOBBER_ERRORCONTROL) ? SERVICE_NO_CHANGE : ErrorControl,
1907  ServiceBinary,
1908  (ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP && ServiceConfig->lpLoadOrderGroup) ? NULL : LoadOrderGroup,
1909  useTag ? &tagId : NULL,
1910  (ServiceFlags & SPSVCINST_NOCLOBBER_DEPENDENCIES && ServiceConfig->lpDependencies) ? NULL : Dependencies,
1911  StartName,
1912  NULL,
1913  (ServiceFlags & SPSVCINST_NOCLOBBER_DISPLAYNAME && ServiceConfig->lpDisplayName) ? NULL : DisplayName);
1914  if (!ret)
1915  goto cleanup;
1916  }
1917 
1918  /* Set security */
1919  if (GetLineText(hInf, ServiceSection, SecurityKey, &SecurityDescriptor))
1920  {
1922  if (!ret)
1923  goto cleanup;
1925  if (!ret)
1926  goto cleanup;
1927  }
1928 
1929  /* FIXME: use Description and SPSVCINST_NOCLOBBER_DESCRIPTION */
1930 
1931  if (useTag)
1932  {
1933  /* Add the tag to SYSTEM\CurrentControlSet\Control\GroupOrderList key */
1934  LPCWSTR lpLoadOrderGroup;
1935  DWORD bufferSize;
1936 
1937  lpLoadOrderGroup = LoadOrderGroup;
1938  if ((ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP) && ServiceConfig && ServiceConfig->lpLoadOrderGroup)
1939  lpLoadOrderGroup = ServiceConfig->lpLoadOrderGroup;
1940 
1941  rc = RegOpenKeyW(
1942  list ? list->HKLM : HKEY_LOCAL_MACHINE,
1944  &hGroupOrderListKey);
1945  if (rc != ERROR_SUCCESS)
1946  {
1947  SetLastError(rc);
1948  goto cleanup;
1949  }
1950  rc = RegQueryValueExW(hGroupOrderListKey, lpLoadOrderGroup, NULL, &dwRegType, NULL, &bufferSize);
1951  if (rc == ERROR_FILE_NOT_FOUND)
1952  bufferSize = sizeof(DWORD);
1953  else if (rc != ERROR_SUCCESS)
1954  {
1955  SetLastError(rc);
1956  goto cleanup;
1957  }
1958  else if (dwRegType != REG_BINARY || bufferSize == 0 || bufferSize % sizeof(DWORD) != 0)
1959  {
1961  goto cleanup;
1962  }
1963  /* Allocate buffer to store existing data + the new tag */
1964  GroupOrder = MyMalloc(bufferSize + sizeof(DWORD));
1965  if (!GroupOrder)
1966  {
1968  goto cleanup;
1969  }
1970  if (rc == ERROR_SUCCESS)
1971  {
1972  /* Read existing data */
1973  rc = RegQueryValueExW(
1974  hGroupOrderListKey,
1975  lpLoadOrderGroup,
1976  NULL,
1977  NULL,
1978  (BYTE*)GroupOrder,
1979  &bufferSize);
1980  if (rc != ERROR_SUCCESS)
1981  {
1982  SetLastError(rc);
1983  goto cleanup;
1984  }
1985  if (ServiceFlags & SPSVCINST_TAGTOFRONT)
1986  memmove(&GroupOrder[2], &GroupOrder[1], bufferSize - sizeof(DWORD));
1987  }
1988  else
1989  {
1990  GroupOrder[0] = 0;
1991  }
1992  GroupOrder[0]++;
1993  if (ServiceFlags & SPSVCINST_TAGTOFRONT)
1994  GroupOrder[1] = tagId;
1995  else
1996  GroupOrder[bufferSize / sizeof(DWORD)] = tagId;
1997 
1998  rc = RegSetValueExW(
1999  hGroupOrderListKey,
2000  lpLoadOrderGroup,
2001  0,
2002  REG_BINARY,
2003  (BYTE*)GroupOrder,
2004  bufferSize + sizeof(DWORD));
2005  if (rc != ERROR_SUCCESS)
2006  {
2007  SetLastError(rc);
2008  goto cleanup;
2009  }
2010  }
2011 
2012  /* Handle AddReg and DelReg */
2013  rc = RegOpenKeyExW(
2014  list ? list->HKLM : HKEY_LOCAL_MACHINE,
2016  0,
2017  READ_CONTROL,
2018  &hServicesKey);
2019  if (rc != ERROR_SUCCESS)
2020  {
2021  SetLastError(rc);
2022  goto cleanup;
2023  }
2024  rc = RegOpenKeyExW(
2025  hServicesKey,
2026  ServiceName,
2027  0,
2028  KEY_READ | KEY_WRITE,
2029  &hServiceKey);
2031  if (rc != ERROR_SUCCESS)
2032  {
2033  SetLastError(rc);
2034  goto cleanup;
2035  }
2036 
2038  NULL,
2039  hInf,
2040  ServiceSection,
2042  hServiceKey,
2043  NULL,
2044  0,
2045  NULL,
2046  NULL,
2047  NULL,
2048  NULL);
2049  RegCloseKey(hServiceKey);
2050 
2051 cleanup:
2052  if (hSCManager != NULL)
2054  if (hService != NULL)
2055  CloseServiceHandle(hService);
2056  if (hGroupOrderListKey != NULL)
2057  RegCloseKey(hGroupOrderListKey);
2058  if (sd != NULL)
2059  LocalFree(sd);
2060  MyFree(ServiceConfig);
2061  MyFree(ServiceBinary);
2062  MyFree(LoadOrderGroup);
2063  MyFree(DisplayName);
2065  MyFree(Dependencies);
2067  MyFree(GroupOrder);
2068  MyFree(StartName);
2069 
2070  TRACE("Returning %d\n", ret);
2071  return ret;
2072 }
2073 
2074 
2075 /***********************************************************************
2076  * SetupInstallServicesFromInfSectionExW (SETUPAPI.@)
2077  */
2079 {
2080  struct DeviceInfoSet *list = NULL;
2081  BOOL ret = FALSE;
2082 
2083  TRACE("%p, %s, 0x%lx, %p, %p, %p, %p\n", hinf, debugstr_w(sectionname),
2085 
2086  if (!sectionname)
2089  {
2092  }
2097  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
2099  else if (reserved1 != NULL || reserved2 != NULL)
2101  else
2102  {
2103  struct needs_callback_info needs_info;
2105  LPWSTR ServiceSection = NULL;
2106  INT ServiceFlags;
2107  INFCONTEXT ContextService;
2108  BOOL bNeedReboot = FALSE;
2109 
2110  /* Parse 'Include' and 'Needs' directives */
2111  iterate_section_fields( hinf, sectionname, Include, include_callback, NULL);
2112  needs_info.type = 1;
2113  needs_info.flags = flags;
2114  needs_info.devinfo = DeviceInfoSet;
2115  needs_info.devinfo_data = DeviceInfoData;
2116  needs_info.reserved1 = reserved1;
2117  needs_info.reserved2 = reserved2;
2118  iterate_section_fields( hinf, sectionname, Needs, needs_callback, &needs_info);
2119 
2121  {
2122  FIXME("Stopping the device not implemented\n");
2123  /* This may lead to require a reboot */
2124  /* bNeedReboot = TRUE; */
2125 #if 0
2129  goto done;
2131  {
2133  goto done;
2134  }
2135 #endif
2137  }
2138 
2139  if (!(ret = SetupFindFirstLineW( hinf, sectionname, NULL, &ContextService )))
2140  {
2142  goto done;
2143  }
2144 
2145  ret = SetupFindFirstLineW(hinf, sectionname, AddService, &ContextService);
2146  while (ret)
2147  {
2148  if (!GetStringField(&ContextService, 1, &ServiceName))
2149  goto done;
2150 
2152  &ContextService,
2153  2, /* Field index */
2154  &ServiceFlags);
2155  if (!ret)
2156  {
2157  /* The field may be empty. Ignore the error */
2158  ServiceFlags = 0;
2159  }
2160 
2161  if (!GetStringField(&ContextService, 3, &ServiceSection))
2162  goto done;
2163 
2164  ret = InstallOneService(list, hinf, ServiceSection, ServiceName, (ServiceFlags & ~SPSVCINST_ASSOCSERVICE) | flags);
2165  if (!ret)
2166  goto done;
2167 
2168  if (ServiceFlags & SPSVCINST_ASSOCSERVICE)
2169  {
2171  if (!ret)
2172  goto done;
2173  }
2174 
2176  HeapFree(GetProcessHeap(), 0, ServiceSection);
2177  ServiceName = ServiceSection = NULL;
2178  ret = SetupFindNextMatchLineW(&ContextService, AddService, &ContextService);
2179  }
2180 
2181  if (bNeedReboot)
2183  else
2185  ret = TRUE;
2186  }
2187 done:
2188  TRACE("Returning %d\n", ret);
2189  return ret;
2190 }
2191 
2192 
2193 /***********************************************************************
2194  * SetupCopyOEMInfA (SETUPAPI.@)
2195  */
2197  IN PCSTR SourceInfFileName,
2198  IN PCSTR OEMSourceMediaLocation,
2199  IN DWORD OEMSourceMediaType,
2200  IN DWORD CopyStyle,
2201  OUT PSTR DestinationInfFileName OPTIONAL,
2202  IN DWORD DestinationInfFileNameSize,
2204  OUT PSTR* DestinationInfFileNameComponent OPTIONAL)
2205 {
2206  PWSTR SourceInfFileNameW = NULL;
2207  PWSTR OEMSourceMediaLocationW = NULL;
2208  PWSTR DestinationInfFileNameW = NULL;
2209  PWSTR DestinationInfFileNameComponentW = NULL;
2210  BOOL ret = FALSE;
2211  DWORD size;
2212 
2213  TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2214  SourceInfFileName, OEMSourceMediaLocation, OEMSourceMediaType,
2215  CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2216  RequiredSize, DestinationInfFileNameComponent);
2217 
2218  if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2220  else if (!(SourceInfFileNameW = pSetupMultiByteToUnicode(SourceInfFileName, CP_ACP)))
2222  else if (OEMSourceMediaType != SPOST_NONE && !(OEMSourceMediaLocationW = pSetupMultiByteToUnicode(OEMSourceMediaLocation, CP_ACP)))
2224  else
2225  {
2226  if (DestinationInfFileNameSize != 0)
2227  {
2228  DestinationInfFileNameW = MyMalloc(DestinationInfFileNameSize * sizeof(WCHAR));
2229  if (!DestinationInfFileNameW)
2230  {
2232  goto cleanup;
2233  }
2234  }
2235 
2237  SourceInfFileNameW,
2238  OEMSourceMediaLocationW,
2239  OEMSourceMediaType,
2240  CopyStyle,
2241  DestinationInfFileNameW,
2242  DestinationInfFileNameSize,
2243  &size,
2244  DestinationInfFileNameComponent ? &DestinationInfFileNameComponentW : NULL);
2245  if (!ret)
2246  {
2247  if (RequiredSize) *RequiredSize = size;
2248  goto cleanup;
2249  }
2250 
2251  if (DestinationInfFileNameSize != 0)
2252  {
2253  if (WideCharToMultiByte(CP_ACP, 0, DestinationInfFileNameW, -1,
2254  DestinationInfFileName, DestinationInfFileNameSize, NULL, NULL) == 0)
2255  {
2256  DestinationInfFileName[0] = '\0';
2257  goto cleanup;
2258  }
2259  }
2260  if (DestinationInfFileNameComponent)
2261  {
2262  if (DestinationInfFileNameComponentW)
2263  *DestinationInfFileNameComponent = &DestinationInfFileName[DestinationInfFileNameComponentW - DestinationInfFileNameW];
2264  else
2265  *DestinationInfFileNameComponent = NULL;
2266  }
2267  ret = TRUE;
2268  }
2269 
2270 cleanup:
2271  MyFree(SourceInfFileNameW);
2272  MyFree(OEMSourceMediaLocationW);
2273  MyFree(DestinationInfFileNameW);
2274  TRACE("Returning %d\n", ret);
2276  return ret;
2277 }
2278 
2279 static int compare_files( HANDLE file1, HANDLE file2 )
2280 {
2281  char buffer1[2048];
2282  char buffer2[2048];
2283  DWORD size1;
2284  DWORD size2;
2285 
2286  while( ReadFile(file1, buffer1, sizeof(buffer1), &size1, NULL) &&
2287  ReadFile(file2, buffer2, sizeof(buffer2), &size2, NULL) )
2288  {
2289  int ret;
2290  if (size1 != size2)
2291  return size1 > size2 ? 1 : -1;
2292  if (!size1)
2293  return 0;
2294  ret = memcmp( buffer1, buffer2, size1 );
2295  if (ret)
2296  return ret;
2297  }
2298 
2299  return 0;
2300 }
2301 
2302 /***********************************************************************
2303  * SetupCopyOEMInfW (SETUPAPI.@)
2304  */
2306  IN PCWSTR SourceInfFileName,
2307  IN PCWSTR OEMSourceMediaLocation,
2308  IN DWORD OEMSourceMediaType,
2309  IN DWORD CopyStyle,
2310  OUT PWSTR DestinationInfFileName OPTIONAL,
2311  IN DWORD DestinationInfFileNameSize,
2313  OUT PWSTR* DestinationInfFileNameComponent OPTIONAL)
2314 {
2315  BOOL ret = FALSE;
2316 
2317  TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2318  debugstr_w(SourceInfFileName), debugstr_w(OEMSourceMediaLocation), OEMSourceMediaType,
2319  CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2320  RequiredSize, DestinationInfFileNameComponent);
2321 
2322  if (!SourceInfFileName)
2324  else if (OEMSourceMediaType != SPOST_NONE && OEMSourceMediaType != SPOST_PATH && OEMSourceMediaType != SPOST_URL)
2327  {
2328  TRACE("Unknown flags: 0x%08lx\n", CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY));
2330  }
2331  else if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2333  else if (CopyStyle & SP_COPY_OEMINF_CATALOG_ONLY)
2334  {
2335  FIXME("CopyStyle 0x%x not supported\n", SP_COPY_OEMINF_CATALOG_ONLY);
2337  }
2338  else
2339  {
2340  HANDLE hSearch = INVALID_HANDLE_VALUE;
2341  WIN32_FIND_DATAW FindFileData;
2342  BOOL AlreadyExists;
2343  DWORD NextFreeNumber = 0;
2344  SIZE_T len;
2345  LPWSTR pFullFileName = NULL;
2346  LPWSTR pFileName; /* Pointer into pFullFileName buffer */
2347  HANDLE hSourceFile = INVALID_HANDLE_VALUE;
2348 
2349  if (OEMSourceMediaType == SPOST_PATH || OEMSourceMediaType == SPOST_URL)
2350  FIXME("OEMSourceMediaType 0x%lx ignored\n", OEMSourceMediaType);
2351 
2352  /* Check if source file exists, and open it */
2353  if (strchrW(SourceInfFileName, '\\' ) || strchrW(SourceInfFileName, '/' ))
2354  {
2355  WCHAR *path;
2356 
2357  if (!(len = GetFullPathNameW(SourceInfFileName, 0, NULL, NULL)))
2358  return FALSE;
2359  if (!(path = MyMalloc(len * sizeof(WCHAR))))
2360  {
2362  return FALSE;
2363  }
2364  GetFullPathNameW(SourceInfFileName, len, path, NULL);
2365  hSourceFile = CreateFileW(
2368  NULL, OPEN_EXISTING, 0, NULL);
2369  MyFree(path);
2370  }
2371  else /* try Windows directory */
2372  {
2373  WCHAR *path, *p;
2374  static const WCHAR Inf[] = {'\\','i','n','f','\\',0};
2375  static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
2376 
2377  len = GetWindowsDirectoryW(NULL, 0) + strlenW(SourceInfFileName) + 12;
2378  if (!(path = MyMalloc(len * sizeof(WCHAR))))
2379  {
2381  return FALSE;
2382  }
2384  p = path + strlenW(path);
2385  strcpyW(p, Inf);
2386  strcatW(p, SourceInfFileName);
2387  hSourceFile = CreateFileW(
2390  NULL, OPEN_EXISTING, 0, NULL);
2391  if (hSourceFile == INVALID_HANDLE_VALUE)
2392  {
2393  strcpyW(p, System32);
2394  strcatW(p, SourceInfFileName);
2395  hSourceFile = CreateFileW(
2398  NULL, OPEN_EXISTING, 0, NULL);
2399  }
2400  MyFree(path);
2401  }
2402  if (hSourceFile == INVALID_HANDLE_VALUE)
2403  {
2405  goto cleanup;
2406  }
2407 
2408  /* Prepare .inf file specification */
2409  len = MAX_PATH + 1 + strlenW(InfDirectory) + 13;
2410  pFullFileName = MyMalloc(len * sizeof(WCHAR));
2411  if (!pFullFileName)
2412  {
2414  goto cleanup;
2415  }
2416  len = GetSystemWindowsDirectoryW(pFullFileName, MAX_PATH);
2417  if (len == 0 || len > MAX_PATH)
2418  goto cleanup;
2419  if (pFullFileName[strlenW(pFullFileName) - 1] != '\\')
2420  strcatW(pFullFileName, BackSlash);
2421  strcatW(pFullFileName, InfDirectory);
2422  pFileName = &pFullFileName[strlenW(pFullFileName)];
2423 
2424  /* Search if the specified .inf file already exists in %WINDIR%\Inf */
2425  AlreadyExists = FALSE;
2426  strcpyW(pFileName, OemFileMask);
2427  hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2428  if (hSearch != INVALID_HANDLE_VALUE)
2429  {
2430  LARGE_INTEGER SourceFileSize;
2431 
2432  if (GetFileSizeEx(hSourceFile, &SourceFileSize))
2433  {
2434  do
2435  {
2436  LARGE_INTEGER DestFileSize;
2437  HANDLE hDestFile;
2438 
2439  strcpyW(pFileName, FindFileData.cFileName);
2440  hDestFile = CreateFileW(
2441  pFullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
2443  NULL, OPEN_EXISTING, 0, NULL);
2444  if (hDestFile != INVALID_HANDLE_VALUE)
2445  {
2446  if (GetFileSizeEx(hDestFile, &DestFileSize)
2447  && DestFileSize.QuadPart == SourceFileSize.QuadPart
2448  && !compare_files(hSourceFile, hDestFile))
2449  {
2450  TRACE("%s already exists as %s\n",
2451  debugstr_w(SourceInfFileName), debugstr_w(pFileName));
2452  AlreadyExists = TRUE;
2453  }
2454  }
2455  } while (!AlreadyExists && FindNextFileW(hSearch, &FindFileData));
2456  }
2457  FindClose(hSearch);
2458  hSearch = INVALID_HANDLE_VALUE;
2459  }
2460 
2461  if (!AlreadyExists && CopyStyle & SP_COPY_REPLACEONLY)
2462  {
2463  /* FIXME: set DestinationInfFileName, RequiredSize, DestinationInfFileNameComponent */
2465  goto cleanup;
2466  }
2467  else if (AlreadyExists && (CopyStyle & SP_COPY_NOOVERWRITE))
2468  {
2469  DWORD Size = strlenW(pFileName) + 1;
2470 
2471  if (RequiredSize)
2472  *RequiredSize = Size;
2473  if (DestinationInfFileNameSize == 0)
2475  else if (DestinationInfFileNameSize < Size)
2477  else
2478  {
2480  strcpyW(DestinationInfFileName, pFileName);
2481  }
2482  goto cleanup;
2483  }
2484 
2485  /* Search the number to give to OEM??.INF */
2486  strcpyW(pFileName, OemFileMask);
2487  hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2488  if (hSearch == INVALID_HANDLE_VALUE)
2489  {
2491  goto cleanup;
2492  }
2493  else
2494  {
2495  do
2496  {
2497  DWORD CurrentNumber;
2498  if (swscanf(FindFileData.cFileName, OemFileSpecification, &CurrentNumber) == 1
2499  && CurrentNumber <= 99999)
2500  {
2501  if (CurrentNumber >= NextFreeNumber)
2502  NextFreeNumber = CurrentNumber + 1;
2503  }
2504  } while (FindNextFileW(hSearch, &FindFileData));
2505  }
2506 
2507  if (NextFreeNumber > 99999)
2508  {
2509  ERR("Too much custom .inf files\n");
2511  goto cleanup;
2512  }
2513 
2514  /* Create the full path: %WINDIR%\Inf\OEM{XXXXX}.inf */
2515  sprintfW(pFileName, OemFileSpecification, NextFreeNumber);
2516  TRACE("Next available file is %s\n", debugstr_w(pFileName));
2517 
2518  if (!CopyFileW(SourceInfFileName, pFullFileName, TRUE))
2519  {
2520  TRACE("CopyFileW() failed with error 0x%lx\n", GetLastError());
2521  goto cleanup;
2522  }
2523 
2524  len = strlenW(pFullFileName) + 1;
2525  if (RequiredSize)
2526  *RequiredSize = len;
2527  if (DestinationInfFileName)
2528  {
2529  if (DestinationInfFileNameSize >= len)
2530  {
2531  strcpyW(DestinationInfFileName, pFullFileName);
2532  if (DestinationInfFileNameComponent)
2533  *DestinationInfFileNameComponent = &DestinationInfFileName[pFileName - pFullFileName];
2534  }
2535  else
2536  {
2538  goto cleanup;
2539  }
2540  }
2541 
2542  if (CopyStyle & SP_COPY_DELETESOURCE)
2543  {
2544  if (!DeleteFileW(SourceInfFileName))
2545  {
2546  TRACE("DeleteFileW() failed with error 0x%lx\n", GetLastError());
2547  goto cleanup;
2548  }
2549  }
2550 
2551  ret = TRUE;
2552 
2553 cleanup:
2554  if (hSourceFile != INVALID_HANDLE_VALUE)
2555  CloseHandle(hSourceFile);
2556  if (hSearch != INVALID_HANDLE_VALUE)
2557  FindClose(hSearch);
2558  MyFree(pFullFileName);
2559  }
2560 
2561  TRACE("Returning %d\n", ret);
2563  return ret;
2564 }
#define HKEY_USERS
Definition: winreg.h:13
static HANDLE DWORD
Definition: install.c:28
static const WCHAR HKCR[]
Definition: reginf.c:56
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SPSVCINST_NOCLOBBER_DISPLAYNAME
Definition: setupapi.h:623
DWORD size
Definition: install.c:3631
GLenum func
Definition: glext.h:6028
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define FLG_ADDREG_APPEND
Definition: registry.c:46
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
static BOOL register_dlls_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:670
BOOL WINAPI SetupFindFirstLineW(IN HINF InfHandle, IN PCWSTR Section, IN PCWSTR Key, IN OUT PINFCONTEXT Context)
Definition: infsupp.c:54
#define FLG_PROFITEM_CURRENTUSER
Definition: setupapi.h:398
#define FLG_ADDREG_OVERWRITEONLY
Definition: registry.c:48
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
const uint16_t * PCWSTR
Definition: typedefs.h:57
static const WCHAR Include[]
Definition: install.c:121
static HKEY get_root_key(const WCHAR *name, HKEY def_root)
Definition: install.c:201
#define IN
Definition: typedefs.h:39
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2396
BOOL WINAPI SetupDiGetActualSectionToInstallW(HINF InfHandle, PCWSTR InfSectionName, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PWSTR *Extension)
Definition: devinst.c:1985
#define ERROR_SECTION_NOT_FOUND
Definition: setupapi.h:288
#define REFIID
Definition: guiddef.h:118
#define CloseHandle
Definition: compat.h:487
HMODULE module
Definition: main.cpp:47
#define SPSVCINST_DELETEEVENTLOGENTRY
Definition: setupapi.h:622
static BOOL update_ini_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:765
#define SPINST_INIFILES
Definition: setupapi.h:584
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define FLG_PROFITEM_CSIDL
Definition: setupapi.h:401
BOOL WINAPI SetupInstallFilesFromInfSectionA(HINF hinf, HINF hlayout, HSPFILEQ queue, PCSTR section, PCSTR src_root, UINT flags)
Definition: install.c:1207
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static const WCHAR OemFileSpecification[]
Definition: install.c:32
#define FLG_ADDREG_TYPE_SZ
Definition: registry.c:49
BOOL WINAPI SetupInstallFilesFromInfSectionW(HINF hinf, HINF hlayout, HSPFILEQ queue, PCWSTR section, PCWSTR src_root, UINT flags)
Definition: install.c:1240
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define FLG_REGSVR_DLLINSTALL
Definition: setupapi.h:403
BOOL WINAPI SetupQueueCopySectionW(HSPFILEQ queue, PCWSTR src_root, HINF hinf, HINF hlist, PCWSTR section, DWORD style)
Definition: queue.c:820
#define FLG_PROFITEM_GROUP
Definition: setupapi.h:400
#define INF_STYLE_WIN4
Definition: infsupp.h:41
#define ERROR_SUCCESS
Definition: deptool.c:10
static const WCHAR Ini2Reg[]
Definition: install.c:110
DWORD dwCurrentState
Definition: winsvc.h:100
#define WideCharToMultiByte
Definition: compat.h:111
static const WCHAR ServiceTypeKey[]
Definition: install.c:43
#define FLG_ADDREG_NOCLOBBER
Definition: registry.c:44
HRESULT hr
Definition: shlfolder.c:183
static const WCHAR UpdateInis[]
Definition: install.c:115
static BOOL include_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1293
#define SPINST_REGSVR
Definition: setupapi.h:589
static BOOL logconf_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:826
BOOL WINAPI SetupInstallServicesFromInfSectionExW(HINF hinf, PCWSTR sectionname, DWORD flags, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID reserved1, PVOID reserved2)
Definition: install.c:2078
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static const WCHAR UnregisterDlls[]
Definition: install.c:119
#define SERVICES_ACTIVE_DATABASE
Definition: winsvc.h:564
#define SPFILENOTIFY_STARTREGISTRATION
Definition: setupapi.h:565
static BOOL do_register_dll(const struct register_dll_info *info, const WCHAR *path, INT flags, INT timeout, const WCHAR *args)
Definition: install.c:530
Definition: http.c:7094
static const WCHAR DelFiles[]
Definition: install.c:108
#define SPINST_BITREG
Definition: setupapi.h:588
static int compare_files(HANDLE file1, HANDLE file2)
Definition: install.c:2279
static const WCHAR LogConf[]
Definition: install.c:111
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static const WCHAR Needs[]
Definition: install.c:122
#define REG_BINARY
Definition: nt_native.h:1496
SC_HANDLE WINAPI CreateServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword)
Definition: scm.c:808
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
static WCHAR * get_field_string(INFCONTEXT *context, DWORD index, WCHAR *buffer, WCHAR *static_buffer, DWORD *size)
Definition: install.c:134
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
GLsizei const GLchar ** path
Definition: glext.h:7234
REFIID riid
Definition: precomp.h:44
#define ERROR_TIMEOUT
Definition: winerror.h:941
uint16_t * PWSTR
Definition: typedefs.h:56
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
BOOL WINAPI QueryServiceConfigW(SC_HANDLE hService, LPQUERY_SERVICE_CONFIGW lpServiceConfig, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2234
#define REFCLSID
Definition: guiddef.h:117
#define CP_ACP
Definition: compat.h:109
BOOL WINAPI SetupQueueRenameSectionW(HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section)
Definition: queue.c:967
#define FLG_ADDREG_KEYONLY
Definition: registry.c:47
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define HKEY_CURRENT_USER
Definition: winreg.h:11
LPWSTR lpLoadOrderGroup
Definition: winsvc.h:160
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
static const WCHAR SecurityKey[]
Definition: install.c:41
#define WARN(fmt,...)
Definition: debug.h:112
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define ERROR_SUCCESS_REBOOT_REQUIRED
Definition: winerror.h:1215
static BOOL update_ini_fields_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:814
HSPFILEQ WINAPI SetupOpenFileQueue(VOID)
Definition: fileqsup.c:161
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define SP_COPY_OEMINF_CATALOG_ONLY
Definition: setupapi.h:489
u32_t magic(void)
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
#define FLG_ADDREG_DELVAL
Definition: registry.c:45
static BOOL registry_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:422
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
UINT(CALLBACK * PSP_FILE_CALLBACK_A)(PVOID, UINT, UINT_PTR, UINT_PTR)
Definition: setupapi.h:871
#define SPSVCINST_TAGTOFRONT
Definition: setupapi.h:620
HSPFILEQ queue
Definition: install.c:60
GLuint buffer
Definition: glext.h:5915
#define FLG_ADDREG_TYPE_MASK
Definition: registry.c:55
int startup(int argc, const char *argv[])
Definition: startup.c:430
#define SPREG_GETPROCADDR
Definition: setupapi.h:649
#define ERROR_INSTALL_SERVICE_FAILURE
Definition: winerror.h:959
void * arg
Definition: msvc.h:10
Definition: dhcpd.h:245
static BOOL needs_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1304
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
#define FLG_ADDREG_KEYONLY_COMMON
Definition: reginf.c:43
GLuint GLuint end
Definition: gl.h:1545
WCHAR * PARSER_get_dest_dir(INFCONTEXT *context)
Definition: parser.c:1116
TCHAR * cmdline
Definition: stretchblt.cpp:32
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
static const WCHAR Description[]
Definition: oid.c:1266
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:339
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
Definition: parser.c:55
#define EWX_REBOOT
Definition: winuser.h:633
#define MoveMemory
Definition: winbase.h:1645
BOOL WINAPI SetupCopyOEMInfA(IN PCSTR SourceInfFileName, IN PCSTR OEMSourceMediaLocation, IN DWORD OEMSourceMediaType, IN DWORD CopyStyle, OUT PSTR DestinationInfFileName OPTIONAL, IN DWORD DestinationInfFileNameSize, OUT PDWORD RequiredSize OPTIONAL, OUT PSTR *DestinationInfFileNameComponent OPTIONAL)
Definition: install.c:2196
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:916
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
static HRESULT(WINAPI *pRunSetupCommand)(HWND
const char * filename
Definition: ioapi.h:135
static const WCHAR DisplayNameKey[]
Definition: install.c:38
#define E_FAIL
Definition: ddrawi.h:102
static const WCHAR HKU[]
Definition: reginf.c:59
Definition: match.c:390
#define ERROR_SERVICE_NOT_ACTIVE
Definition: winerror.h:613
int32_t INT
Definition: typedefs.h:58
#define SETUP_DEVICE_INFO_SET_MAGIC
GLbitfield GLuint64 timeout
Definition: glext.h:7164
BOOL WINAPI SetupInstallServicesFromInfSectionA(HINF Inf, PCSTR SectionName, DWORD Flags)
Definition: install.c:1621
static const WCHAR CopyINF[]
Definition: install.c:116
IMAGE_NT_HEADERS nt
Definition: module.c:50
#define IMAGE_FILE_DLL
Definition: pedump.c:169
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define FILE_SHARE_READ
Definition: compat.h:136
VOID WINAPI SetupCloseInfFile(IN HINF InfHandle)
Definition: infsupp.c:43
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
#define lstrcpynW
Definition: compat.h:486
#define FILEOP_ABORT
Definition: fileqsup.h:47
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2034
#define ERROR_OPERATION_ABORTED
Definition: winerror.h:575
#define SERVICE_NO_CHANGE
Definition: winsvc.h:20
struct _test_info info[]
Definition: SetCursorPos.c:19
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define SP_COPY_IN_USE_NEEDS_REBOOT
Definition: setupapi.h:480
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static const WCHAR AddService[]
Definition: install.c:106
static const WCHAR CmdLine[]
Definition: install.c:48
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static BOOL rename_files_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:188
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SPSVCINST_STOPSERVICE
Definition: setupapi.h:629
#define FLG_DELREG_KEYONLY_COMMON
Definition: reginf.c:44
#define SERVICE_STOPPED
Definition: winsvc.h:21
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define PSPGF_NONINTERACTIVE
unsigned char * LPBYTE
Definition: typedefs.h:53
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
LPWSTR WINAPI pSetupDuplicateString(LPCWSTR lpSrc)
Definition: misc.c:198
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define FLG_ADDREG_TYPE_DWORD
Definition: registry.c:53
#define SP_COPY_NEWER
Definition: setupapi.h:473
LPWSTR WINAPI pSetupMultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
Definition: misc.c:281
static const WCHAR DelReg[]
Definition: install.c:113
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static BOOL(WINAPI *pCheckTokenMembership)(HANDLE
#define FLG_REGSVR_DLLREGISTER
Definition: setupapi.h:402
BOOL WINAPI SetupGetBinaryField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PUCHAR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:126
#define HRESULT_FACILITY(hr)
Definition: winerror.h:79
static LPUNKNOWN
Definition: ndr_ole.c:49
void WINAPI InstallHinfSectionW(HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show)
Definition: install.c:1465
static const WCHAR DotLnk[]
Definition: install.c:33
#define FILE_READ_DATA
Definition: nt_native.h:628
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3296
static const WCHAR WorkingDir[]
Definition: install.c:50
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define debugstr_w
Definition: kernel32.h:32
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
#define FLG_PROFITEM_DELETE
Definition: setupapi.h:399
#define FIXME(fmt,...)
Definition: debug.h:111
#define SPREG_REGSVR
Definition: setupapi.h:650
BOOL WINAPI ChangeServiceConfigW(SC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword, LPCWSTR lpDisplayName)
Definition: scm.c:480
static const WCHAR RegisterDlls[]
Definition: install.c:118
BOOL WINAPI SetupDiGetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4456
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2103
static const WCHAR CopyFiles[]
Definition: install.c:107
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
static BOOL copy_files_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:158
HRESULT(WINAPI * COCREATEINSTANCE)(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID *ppv)
Definition: install.c:102
const WCHAR * str
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:577
Definition: _queue.h:59
#define DI_NOVCP
Definition: setupapi.h:49
#define SPINST_REGISTRY
Definition: setupapi.h:585
static const WCHAR InfDirectory[]
Definition: install.c:30
BOOL WINAPI SetupQueueDeleteSectionW(HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section)
Definition: queue.c:918
struct reiserfs_key root_key
static BOOL GetIntField(HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
Definition: install.c:1676
INT WINAPI SetupPromptReboot(HSPFILEQ file_queue, HWND owner, BOOL scan_only)
Definition: stubs.c:35
smooth NULL
Definition: ftsmooth.c:416
#define REGSTR_PATH_SERVICES
Definition: regstr.h:47
static BOOL delete_files_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:175
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
Definition: bufpool.h:45
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define ERROR_SERVICE_MARKED_FOR_DELETE
Definition: winerror.h:623
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
HRESULT(WINAPI * COUNINITIALIZE)(VOID)
Definition: install.c:103
#define SPINST_FILES
Definition: setupapi.h:587
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
BOOL WINAPI SetupInstallFromInfSectionA(HWND owner, HINF hinf, PCSTR section, UINT flags, HKEY key_root, PCSTR src_root, UINT copy_flags, PSP_FILE_CALLBACK_A callback, PVOID context, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data)
Definition: install.c:1256
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static void append_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *strings, DWORD str_size)
Definition: install.c:223
#define OPEN_EXISTING
Definition: compat.h:523
static const WCHAR RenFiles[]
Definition: install.c:109
#define SP_COPY_NOOVERWRITE
Definition: setupapi.h:475
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4595
static const WCHAR HKLM[]
Definition: reginf.c:58
static const WCHAR HKR[]
Definition: reginf.c:60
PVOID callback_context
Definition: install.c:77
#define SPINST_UNREGSVR
Definition: setupapi.h:590
#define KEY_WRITE
Definition: nt_native.h:1031
static HANDLE hServicesKey
Definition: devinst.c:21
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
MmuTrapHandler callback[0x30]
Definition: mmuobject.c:44
#define FILEOP_DOIT
Definition: fileqsup.h:48
static const WCHAR HotKey[]
Definition: install.c:53
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:496
#define FLG_ADDREG_TYPE_BINARY
Definition: registry.c:52
GLsizeiptr size
Definition: glext.h:5919
uint8_t reserved2[12]
Definition: fsck.fat.h:58
#define ERROR_BAD_SERVICE_INSTALLSECT
Definition: setupapi.h:314
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:34
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
static const WCHAR DotServices[]
Definition: install.c:34
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SPOST_PATH
Definition: setupapi.h:605
Definition: parser.c:43
LONG HRESULT
Definition: typedefs.h:79
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
UINT(CALLBACK * PSP_FILE_CALLBACK_W)(IN PVOID Context, IN UINT Notification, IN UINT_PTR Param1, IN UINT_PTR Param2)
Definition: fileqsup.h:66
static const WCHAR DependenciesKey[]
Definition: install.c:36
static LPCSTR DWORD void * pvReserved
Definition: str.c:196
BOOL WINAPI SetupCopyOEMInfW(IN PCWSTR SourceInfFileName, IN PCWSTR OEMSourceMediaLocation, IN DWORD OEMSourceMediaType, IN DWORD CopyStyle, OUT PWSTR DestinationInfFileName OPTIONAL, IN DWORD DestinationInfFileNameSize, OUT PDWORD RequiredSize OPTIONAL, OUT PWSTR *DestinationInfFileNameComponent OPTIONAL)
Definition: install.c:2305
#define SERVICE_CHANGE_CONFIG
Definition: winsvc.h:54
static SERVICE_STATUS ServiceStatus
Definition: browser.c:22
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
static const UCHAR Index[8]
Definition: usbohci.c:18
#define SPSVCINST_ASSOCSERVICE
Definition: setupapi.h:621
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1523
static BOOL copy_inf_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1159
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ PSTRING FullName
Definition: rtlfuncs.h:1649
#define WRITE_DAC
Definition: nt_native.h:59
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
SP_DEVINSTALL_PARAMS_A SP_DEVINSTALL_PARAMS
Definition: setupapi.h:1150
static const WCHAR BitReg[]
Definition: install.c:114
#define SetLastError(x)
Definition: compat.h:500
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
static const WCHAR StartTypeKey[]
Definition: install.c:44
BOOL WINAPI SetupCommitFileQueueW(IN HWND Owner, IN HSPFILEQ QueueHandle, IN PSP_FILE_CALLBACK_W MsgHandler, IN PVOID Context OPTIONAL)
Definition: fileqsup.c:617
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define READ_CONTROL
Definition: nt_native.h:58
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static const WCHAR IconIndex[]
Definition: install.c:52
static const WCHAR DotSecurity[]
Definition: install.c:123
static const WCHAR sd[]
Definition: suminfo.c:287
BOOL WINAPI SetupInstallFromInfSectionW(HWND owner, HINF hinf, PCWSTR section, UINT flags, HKEY key_root, PCWSTR src_root, UINT copy_flags, PSP_FILE_CALLBACK_W callback, PVOID context, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data)
Definition: install.c:1327
#define GetFileSizeEx
Definition: compat.h:505
static const WCHAR BackSlash[]
Definition: install.c:28
int ret
ULONG WINAPI SetupGetFieldCount(IN PINFCONTEXT Context)
Definition: infsupp.c:91
#define wcsnicmp
Definition: compat.h:14
GLsizei const GLchar *const * strings
Definition: glext.h:7622
static BOOL GetLineText(HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
Definition: install.c:1647
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FLG_ADDREG_BINVALUETYPE
Definition: registry.c:43
void WINAPI InstallHinfSectionA(HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show)
Definition: install.c:1598
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR ErrorControlKey[]
Definition: install.c:39
static const WCHAR OemFileMask[]
Definition: install.c:31
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2011
UINT WINAPI SetupDefaultQueueCallbackW(PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:1777
#define MB_ICONERROR
Definition: winuser.h:781
#define VOID
Definition: acefi.h:82
uint32_t entry
Definition: isohybrid.c:63
#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
#define SPDRP_SERVICE
Definition: setupapi.h:506
GLdouble s
Definition: gl.h:2039
static const WCHAR InfoTip[]
Definition: install.c:54
#define SPINST_ALL
Definition: setupapi.h:596
Definition: _list.h:228
GLenum src
Definition: glext.h:6340
#define SP_COPY_REPLACEONLY
Definition: setupapi.h:472
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
GLenum mode
Definition: glext.h:6217
SC_HANDLE hSCManager
Definition: sc.c:12
BOOL WINAPI ExitWindowsEx(_In_ UINT, _In_ DWORD)
unsigned char BYTE
Definition: xxhash.c:193
const WCHAR * DIRID_get_string(int dirid)
Definition: dirid.c:159
UINT CALLBACK QUEUE_callback_WtoA(void *context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:187
BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR string, LPCWSTR filename)
Definition: profile.c:1453
static const WCHAR DisplayResource[]
Definition: install.c:55
BOOL WINAPI SetupOpenAppendInfFileW(PCWSTR name, HINF parent_hinf, UINT *error)
Definition: parser.c:1346
HRESULT(WINAPI * COINITIALIZE)(IN LPVOID pvReserved)
Definition: install.c:101
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
#define strcmpiW(s1, s2)
Definition: unicode.h:39
static const WCHAR LoadOrderGroupKey[]
Definition: install.c:40
#define ERROR_INVALID_DATA
Definition: winerror.h:116
static const WCHAR HKCU[]
Definition: reginf.c:57
#define ERR(fmt,...)
Definition: debug.h:110
static BOOL profile_items_callback(IN HINF hInf, IN PCWSTR SectionName, IN PVOID Arg)
Definition: install.c:888
#define FACILITY_WIN32
Definition: winerror.h:27
ULONG_PTR SIZE_T
Definition: typedefs.h:80
BOOL GetStringField(PINFCONTEXT context, DWORD index, PWSTR *value)
Definition: install.c:1700
static const WCHAR AddReg[]
Definition: install.c:112
#define SPFILENOTIFY_ENDREGISTRATION
Definition: setupapi.h:566
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define SPSVCINST_NOCLOBBER_ERRORCONTROL
Definition: setupapi.h:625
#define SPINST_PROFILEITEMS
Definition: setupapi.h:591
BOOL WINAPI SetupGetMultiSzFieldW(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PWSTR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:162
LPVOID lpSecurityDescriptor
Definition: compat.h:193
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2709
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
BOOL WINAPI SetupInstallServicesFromInfSectionW(HINF Inf, PCWSTR SectionName, DWORD Flags)
Definition: install.c:1612
static BOOL ini2reg_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:820
static const WCHAR DescriptionKey[]
Definition: install.c:37
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
HDEVINFO devinfo
Definition: install.c:93
PVOID WINAPI SetupInitDefaultQueueCallback(HWND owner)
Definition: queue.c:1677
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
#define FILEOP_SKIP
Definition: fileqsup.h:49
#define SP_COPY_DELETESOURCE
Definition: setupapi.h:471
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define ok(value,...)
Definition: atltest.h:57
#define HeapReAlloc
Definition: compat.h:482
#define SERVICE_WIN32
Definition: cmtypes.h:964
signed char * PSTR
Definition: retypes.h:7
GLenum GLenum dst
Definition: glext.h:6340
#define sprintfW
Definition: unicode.h:58
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
#define ReadFile(a, b, c, d, e)
Definition: compat.h:490
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
LPCWSTR src_root
Definition: install.c:89
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:619
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI SetServiceObjectSecurity(SC_HANDLE hService, SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR lpSecurityDescriptor)
Definition: scm.c:2717
PSP_DEVINFO_DATA devinfo_data
Definition: install.c:94
DWORD GlobalSetupFlags
Definition: misc.c:845
#define MB_OK
Definition: winuser.h:784
BOOL empty
Definition: button.c:170
#define SPINST_LOGCONFIG
Definition: setupapi.h:583
DWORD * PDWORD
Definition: pedump.c:68
BOOL WINAPI SetupFindNextLine(IN PINFCONTEXT ContextIn, OUT PINFCONTEXT ContextOut)
Definition: infsupp.c:80
#define SPOST_NONE
Definition: setupapi.h:604
static BOOL InstallOneService(struct DeviceInfoSet *list, IN HINF hInf, IN LPCWSTR ServiceSection, IN LPCWSTR ServiceName, IN UINT ServiceFlags)
Definition: install.c:1777
static const WCHAR IconPath[]
Definition: install.c:51
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
#define SPSVCINST_NOCLOBBER_DEPENDENCIES
Definition: setupapi.h:627
static BOOL iterate_section_fields(HINF hinf, PCWSTR section, PCWSTR key, iterate_fields_func callback, void *arg)
Definition: install.c:1171
#define RtlImageNtHeader
Definition: compat.h:554
#define CreateFileW
Definition: compat.h:489
static BOOL do_reg_operation(HKEY hkey, const WCHAR *value, INFCONTEXT *context, INT flags)
Definition: install.c:307
#define SPSVCINST_NOCLOBBER_STARTTYPE
Definition: setupapi.h:624
#define FLG_ADDREG_DELREG_BIT
Definition: reginf.c:45
const GUID IID_IPersistFile
#define HRESULT_CODE(hr)
Definition: winerror.h:76
Definition: name.c:38
BOOL WINAPI SetupGetIntField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT INT *IntegerValue)
Definition: infsupp.c:146
#define OUT
Definition: typedefs.h:40
GLuint res
Definition: glext.h:9613
BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, const BYTE *PropertyBuffer, DWORD PropertyBufferSize)
Definition: devinst.c:3457
static void delete_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *string)
Definition: install.c:268
uint32_t * LPDWORD
Definition: typedefs.h:59
struct tagContext Context
Definition: acpixf.h:1034
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define FLG_ADDREG_TYPE_EXPAND_SZ
Definition: registry.c:51
static const WCHAR StartNameKey[]
Definition: install.c:45
char * cleanup(char *str)
Definition: wpickclick.c:99
#define GetProcAddress(x, y)
Definition: compat.h:501
LPVOID WINAPI MyMalloc(DWORD dwSize)
Definition: misc.c:147
static const WCHAR SubDir[]
Definition: install.c:49
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_QUERY_CONFIG
Definition: winsvc.h:53
static BOOL create_fake_dll(LPCSTR filename)
Definition: file.c:2209
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
const char * PCSTR
Definition: typedefs.h:52
static const WCHAR ProfileItems[]
Definition: install.c:120
BOOL WINAPI SetupQueueDefaultCopyW(HSPFILEQ queue, HINF hinf, PCWSTR src_root, PCWSTR src_file, PCWSTR dst_file, DWORD style)
Definition: queue.c:671
#define strtoulW(s1, s2, b)
Definition: unicode.h:41
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
#define REG_NONE
Definition: nt_native.h:1492
static const WCHAR GroupOrderListKey[]
Definition: install.c:29
#define SPOST_URL
Definition: setupapi.h:606
static const WCHAR UpdateIniFields[]
Definition: install.c:117
struct _MEMORY_AREA struct _MM_REQUIRED_RESOURCES * Required
Definition: newmm.h:66
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define SPREG_TIMEOUT
Definition: setupapi.h:652
#define SPSVCINST_NOCLOBBER_LOADORDERGROUP
Definition: setupapi.h:626
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
static VOID FixupServiceBinaryPath(IN DWORD ServiceType, IN OUT LPWSTR *ServiceBinary)
Definition: install.c:1735
BOOL WINAPI SetupInstallServicesFromInfSectionExA(HINF hinf, PCSTR sectionname, DWORD flags, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data, PVOID reserved1, PVOID reserved2)
Definition: install.c:1630
#define CSIDL_PROGRAMS
Definition: shlobj.h:2014
#define SPREG_LOADLIBRARY
Definition: setupapi.h:648
#define memset(x, y, z)
Definition: compat.h:39
HRESULT(* iterate_fields_func)(HINF hinf, PCWSTR field, const void *arg)
Definition: install.c:60
#define REG_DWORD
Definition: sdbapi.c:596
_Check_return_ _CRTIMP int __cdecl swscanf(_In_z_ const wchar_t *_Src, _In_z_ _Scanf_format_string_ const wchar_t *_Format,...)
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI MyFree(LPVOID lpMem)
Definition: misc.c:128
#define args
Definition: format.c:66
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SPREG_SUCCESS
Definition: setupapi.h:647
BOOL WINAPI SetupCloseFileQueue(IN HSPFILEQ QueueHandle)
Definition: fileqsup.c:217
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:483
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
PSP_FILE_CALLBACK_W callback
Definition: install.c:76
BOOL WINAPI SetupFindNextMatchLineW(PINFCONTEXT context_in, PCWSTR key, PINFCONTEXT context_out)
Definition: parser.c:1694
static BOOL Concatenate(int DirId, LPCWSTR SubDirPart, LPCWSTR NamePart, LPWSTR *pFullName)
Definition: install.c:838
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define SDDL_REVISION_1
Definition: sddl.h:30
#define FLG_ADDREG_TYPE_NONE
Definition: registry.c:54
static BOOL bitreg_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:832
#define SUCCEEDED(hr)
Definition: intsafe.h:49
#define DELETE
Definition: nt_native.h:57
LONGLONG QuadPart
Definition: typedefs.h:114
#define SPINST_INI2REG
Definition: setupapi.h:586
static const WCHAR ServiceBinaryKey[]
Definition: install.c:42
WINE_UNICODE_INLINE int atoiW(const WCHAR *str)
Definition: unicode.h:315
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
Definition: path.c:41
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor, DWORD StringSDRevision, PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize)
Definition: security.c:2738
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define FLG_ADDREG_TYPE_MULTI_SZ
Definition: registry.c:50
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1756
#define REG_SZ
Definition: layer.c:22
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
Definition: ps.c:97
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOL WINAPI SetupGetStringFieldW(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PWSTR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:184