ReactOS 0.4.15-dev-8419-g7f0e8a3
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 */
28static const WCHAR BackSlash[] = {'\\',0};
29static 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};
30static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
31static const WCHAR OemFileMask[] = {'o','e','m','*','.','i','n','f',0};
32static const WCHAR OemFileSpecification[] = {'o','e','m','%','l','u','.','i','n','f',0};
33static const WCHAR DotLnk[] = {'.','l','n','k',0};
34static const WCHAR DotServices[] = {'.','S','e','r','v','i','c','e','s',0};
35
36static const WCHAR DependenciesKey[] = {'D','e','p','e','n','d','e','n','c','i','e','s',0};
37static const WCHAR DescriptionKey[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
38static const WCHAR DisplayNameKey[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
39static const WCHAR ErrorControlKey[] = {'E','r','r','o','r','C','o','n','t','r','o','l',0};
40static const WCHAR LoadOrderGroupKey[] = {'L','o','a','d','O','r','d','e','r','G','r','o','u','p',0};
41static const WCHAR SecurityKey[] = {'S','e','c','u','r','i','t','y',0};
42static const WCHAR ServiceBinaryKey[] = {'S','e','r','v','i','c','e','B','i','n','a','r','y',0};
43static const WCHAR ServiceTypeKey[] = {'S','e','r','v','i','c','e','T','y','p','e',0};
44static const WCHAR StartTypeKey[] = {'S','t','a','r','t','T','y','p','e',0};
45static const WCHAR StartNameKey[] = {'S','t','a','r','t','N','a','m','e',0};
46
47static const WCHAR Name[] = {'N','a','m','e',0};
48static const WCHAR CmdLine[] = {'C','m','d','L','i','n','e',0};
49static const WCHAR SubDir[] = {'S','u','b','D','i','r',0};
50static const WCHAR WorkingDir[] = {'W','o','r','k','i','n','g','D','i','r',0};
51static const WCHAR IconPath[] = {'I','c','o','n','P','a','t','h',0};
52static const WCHAR IconIndex[] = {'I','c','o','n','I','n','d','e','x',0};
53static const WCHAR HotKey[] = {'H','o','t','K','e','y',0};
54static const WCHAR InfoTip[] = {'I','n','f','o','T','i','p',0};
55static 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
99typedef BOOL (*iterate_fields_func)( HINF hinf, PCWSTR field, void *arg );
100static BOOL GetLineText( HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value);
102typedef HRESULT (WINAPI *COCREATEINSTANCE)(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID *ppv);
104
105/* Unicode constants */
106static const WCHAR AddService[] = {'A','d','d','S','e','r','v','i','c','e',0};
107static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0};
108static const WCHAR DelFiles[] = {'D','e','l','F','i','l','e','s',0};
109static const WCHAR RenFiles[] = {'R','e','n','F','i','l','e','s',0};
110static const WCHAR Ini2Reg[] = {'I','n','i','2','R','e','g',0};
111static const WCHAR LogConf[] = {'L','o','g','C','o','n','f',0};
112static const WCHAR AddReg[] = {'A','d','d','R','e','g',0};
113static const WCHAR DelReg[] = {'D','e','l','R','e','g',0};
114static const WCHAR BitReg[] = {'B','i','t','R','e','g',0};
115static const WCHAR UpdateInis[] = {'U','p','d','a','t','e','I','n','i','s',0};
116static const WCHAR CopyINF[] = {'C','o','p','y','I','N','F',0};
117static const WCHAR UpdateIniFields[] = {'U','p','d','a','t','e','I','n','i','F','i','e','l','d','s',0};
118static const WCHAR RegisterDlls[] = {'R','e','g','i','s','t','e','r','D','l','l','s',0};
119static const WCHAR UnregisterDlls[] = {'U','n','r','e','g','i','s','t','e','r','D','l','l','s',0};
120static const WCHAR ProfileItems[] = {'P','r','o','f','i','l','e','I','t','e','m','s',0};
121static const WCHAR Include[] = {'I','n','c','l','u','d','e',0};
122static const WCHAR Needs[] = {'N','e','e','d','s',0};
123static const WCHAR DotSecurity[] = {'.','S','e','c','u','r','i','t','y',0};
124#ifdef __WINESRC__
125static 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 */
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 */
201static 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 */
223static void append_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *strings,
224 DWORD str_size )
225{
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:
260}
261
262
263/***********************************************************************
264 * delete_multi_sz_value
265 *
266 * Remove a string from a multisz registry value.
267 */
268static 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) );
295 (BYTE *)(buffer + size), dst - (buffer + size) );
296 }
297 done:
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;
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
341 {
342 case FLG_ADDREG_TYPE_SZ: type = REG_SZ; 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
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 }
366 {
367 if (!str) return TRUE;
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 );
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 */
423{
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 }
499 else if (RegCreateKeyExW( root_key, buffer, 0, NULL, 0, MAXIMUM_ALLOWED,
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 */
530static BOOL do_register_dll( const struct register_dll_info *info, const WCHAR *path,
531 INT flags, INT timeout, const WCHAR *args )
532{
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
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
657done:
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;
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:
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 */
722static 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:
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 */
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
820static 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
826static 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
832static 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
838static 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 && *Dir)
848 dwRequired += wcslen(Dir) + 1;
849 else
850 Dir = NULL; /* DIRID_get_string returns L"" for DIRID_ABSOLUTE */
851 if (SubDirPart)
852 dwRequired += wcslen(SubDirPart) + 1;
853 if (NamePart)
854 dwRequired += wcslen(NamePart);
855 dwRequired = dwRequired * sizeof(WCHAR) + sizeof(UNICODE_NULL);
856
857 FullName = MyMalloc(dwRequired);
858 if (!FullName)
859 {
861 return FALSE;
862 }
864
865 if (Dir)
866 {
867 wcscat(FullName, Dir);
868 if (FullName[wcslen(FullName) - 1] != '\\')
870 }
871 if (SubDirPart)
872 {
873 wcscat(FullName, SubDirPart);
874 if (FullName[wcslen(FullName) - 1] != '\\')
876 }
877 if (NamePart)
878 wcscat(FullName, NamePart);
879
880 *pFullName = FullName;
881 return TRUE;
882}
883
884/***********************************************************************
885 * profile_items_callback
886 *
887 * Called once for each ProfileItems entry in a given section.
888 */
889static BOOL
891 IN HINF hInf,
892 IN PCWSTR SectionName,
893 IN PVOID Arg)
894{
896 LPWSTR LinkSubDir = NULL, LinkName = NULL;
897 INT LinkAttributes = 0;
898 INT LinkFolder = 0;
899 INT FileDirId = 0;
901 LPWSTR FileSubDir = NULL;
902 INT DirId = 0;
903 LPWSTR SubDirPart = NULL, NamePart = NULL;
904 LPWSTR FullLinkName = NULL, FullFileName = NULL, FullWorkingDir = NULL, FullIconName = NULL;
905 INT IconIdx = 0;
906 LPWSTR lpHotKey = NULL, lpInfoTip = NULL;
907 LPWSTR DisplayName = NULL;
908 INT DisplayResId = 0;
909 BOOL ret = FALSE;
911
912 IShellLinkW *psl;
913 IPersistFile *ppf;
914 HMODULE hOle32 = NULL;
915 COINITIALIZE pCoInitialize;
916 COCREATEINSTANCE pCoCreateInstance;
917 COUNINITIALIZE pCoUninitialize;
918 HRESULT hr;
919
920 TRACE("hInf %p, SectionName %s, Arg %p\n",
921 hInf, debugstr_w(SectionName), Arg);
922
923 /* Read 'Name' entry */
924 if (!SetupFindFirstLineW(hInf, SectionName, Name, &Context))
925 goto cleanup;
926 if (!GetStringField(&Context, 1, &LinkName))
927 goto cleanup;
928 if (SetupGetFieldCount(&Context) >= 2)
929 {
930 if (!SetupGetIntField(&Context, 2, &LinkAttributes))
931 goto cleanup;
932 }
933 if (SetupGetFieldCount(&Context) >= 3)
934 {
935 if (!SetupGetIntField(&Context, 3, &LinkFolder))
936 goto cleanup;
937 }
938
939 /* Read 'CmdLine' entry */
940 if (!SetupFindFirstLineW(hInf, SectionName, CmdLine, &Context))
941 goto cleanup;
942 Index = 1;
943 if (!SetupGetIntField(&Context, Index++, &FileDirId))
944 goto cleanup;
945 if (SetupGetFieldCount(&Context) >= 3)
946 {
947 if (!GetStringField(&Context, Index++, &FileSubDir))
948 goto cleanup;
949 }
950 if (!GetStringField(&Context, Index++, &NamePart))
951 goto cleanup;
952 if (!Concatenate(FileDirId, FileSubDir, NamePart, &FullFileName))
953 goto cleanup;
954 MyFree(NamePart);
955 NamePart = NULL;
956
957 /* Read 'SubDir' entry */
958 if ((LinkAttributes & FLG_PROFITEM_GROUP) == 0 && SetupFindFirstLineW(hInf, SectionName, SubDir, &Context))
959 {
960 if (!GetStringField(&Context, 1, &LinkSubDir))
961 goto cleanup;
962 }
963
964 /* Read 'WorkingDir' entry */
965 if (SetupFindFirstLineW(hInf, SectionName, WorkingDir, &Context))
966 {
967 if (!SetupGetIntField(&Context, 1, &DirId))
968 goto cleanup;
969 if (SetupGetFieldCount(&Context) >= 2)
970 {
971 if (!GetStringField(&Context, 2, &SubDirPart))
972 goto cleanup;
973 }
974 if (!Concatenate(DirId, SubDirPart, NULL, &FullWorkingDir))
975 goto cleanup;
976 MyFree(SubDirPart);
977 SubDirPart = NULL;
978 }
979 else
980 {
981 if (!Concatenate(FileDirId, FileSubDir, NULL, &FullWorkingDir))
982 goto cleanup;
983 }
984
985 /* Read 'IconPath' entry */
986 if (SetupFindFirstLineW(hInf, SectionName, IconPath, &Context))
987 {
988 Index = 1;
989 if (!SetupGetIntField(&Context, Index++, &DirId))
990 goto cleanup;
991 if (SetupGetFieldCount(&Context) >= 3)
992 {
993 if (!GetStringField(&Context, Index++, &SubDirPart))
994 goto cleanup;
995 }
996 if (!GetStringField(&Context, Index, &NamePart))
997 goto cleanup;
998 if (!Concatenate(DirId, SubDirPart, NamePart, &FullIconName))
999 goto cleanup;
1000 MyFree(SubDirPart);
1001 MyFree(NamePart);
1002 SubDirPart = NamePart = NULL;
1003 }
1004 else
1005 {
1006 FullIconName = pSetupDuplicateString(FullFileName);
1007 if (!FullIconName)
1008 goto cleanup;
1009 }
1010
1011 /* Read 'IconIndex' entry */
1012 if (SetupFindFirstLineW(hInf, SectionName, IconIndex, &Context))
1013 {
1014 if (!SetupGetIntField(&Context, 1, &IconIdx))
1015 goto cleanup;
1016 }
1017
1018 /* Read 'HotKey' and 'InfoTip' entries */
1019 GetLineText(hInf, SectionName, HotKey, &lpHotKey);
1020 GetLineText(hInf, SectionName, InfoTip, &lpInfoTip);
1021
1022 /* Read 'DisplayResource' entry */
1023 if (SetupFindFirstLineW(hInf, SectionName, DisplayResource, &Context))
1024 {
1025 if (!GetStringField(&Context, 1, &DisplayName))
1026 goto cleanup;
1027 if (!SetupGetIntField(&Context, 2, &DisplayResId))
1028 goto cleanup;
1029 }
1030
1031 /* Some debug */
1032 TRACE("Link is %s\\%s, attributes 0x%x\n", debugstr_w(LinkSubDir), debugstr_w(LinkName), LinkAttributes);
1033 TRACE("File is %s\n", debugstr_w(FullFileName));
1034 TRACE("Working dir %s\n", debugstr_w(FullWorkingDir));
1035 TRACE("Icon is %s, %d\n", debugstr_w(FullIconName), IconIdx);
1036 TRACE("Hotkey %s\n", debugstr_w(lpHotKey));
1037 TRACE("InfoTip %s\n", debugstr_w(lpInfoTip));
1038 TRACE("Display %s, %d\n", DisplayName, DisplayResId);
1039
1040 /* Load ole32.dll */
1041 hOle32 = LoadLibraryA("ole32.dll");
1042 if (!hOle32)
1043 goto cleanup;
1044 pCoInitialize = (COINITIALIZE)GetProcAddress(hOle32, "CoInitialize");
1045 if (!pCoInitialize)
1046 goto cleanup;
1047 pCoCreateInstance = (COCREATEINSTANCE)GetProcAddress(hOle32, "CoCreateInstance");
1048 if (!pCoCreateInstance)
1049 goto cleanup;
1050 pCoUninitialize = (COUNINITIALIZE)GetProcAddress(hOle32, "CoUninitialize");
1051 if (!pCoUninitialize)
1052 goto cleanup;
1053
1054 /* Create shortcut */
1055 hr = pCoInitialize(NULL);
1056 if (!SUCCEEDED(hr))
1057 {
1060 else
1062 goto cleanup;
1063 }
1064 hr = pCoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID*)&psl);
1065 if (SUCCEEDED(hr))
1066 {
1067 /* Fill link properties */
1068 hr = IShellLinkW_SetPath(psl, FullFileName);
1069 if (SUCCEEDED(hr))
1070 hr = IShellLinkW_SetArguments(psl, L"");
1071 if (SUCCEEDED(hr))
1072 hr = IShellLinkW_SetWorkingDirectory(psl, FullWorkingDir);
1073 if (SUCCEEDED(hr))
1074 hr = IShellLinkW_SetIconLocation(psl, FullIconName, IconIdx);
1075 if (SUCCEEDED(hr) && lpHotKey)
1076 FIXME("Need to store hotkey %s in shell link\n", debugstr_w(lpHotKey));
1077 if (SUCCEEDED(hr) && lpInfoTip)
1078 hr = IShellLinkW_SetDescription(psl, lpInfoTip);
1079 if (SUCCEEDED(hr) && DisplayName)
1080 FIXME("Need to store display name %s, %d in shell link\n", debugstr_w(DisplayName), DisplayResId);
1081 if (SUCCEEDED(hr))
1082 {
1083 hr = IShellLinkW_QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
1084 if (SUCCEEDED(hr))
1085 {
1086 Required = (MAX_PATH + 1 +
1087 ((LinkSubDir != NULL) ? wcslen(LinkSubDir) : 0) +
1088 ((LinkName != NULL) ? wcslen(LinkName) : 0)) * sizeof(WCHAR);
1089 FullLinkName = MyMalloc(Required);
1090 if (!FullLinkName)
1091 hr = E_OUTOFMEMORY;
1092 else
1093 {
1094 if (LinkAttributes & (FLG_PROFITEM_DELETE | FLG_PROFITEM_GROUP))
1095 FIXME("Need to handle FLG_PROFITEM_DELETE and FLG_PROFITEM_GROUP\n");
1096 if (LinkAttributes & FLG_PROFITEM_CSIDL)
1097 CSIDL = LinkFolder;
1098 else if (LinkAttributes & FLG_PROFITEM_CURRENTUSER)
1099 CSIDL = CSIDL_PROGRAMS;
1100
1102 NULL,
1103 FullLinkName,
1104 CSIDL,
1105 TRUE))
1106 {
1107 if (FullLinkName[wcslen(FullLinkName) - 1] != '\\')
1108 wcscat(FullLinkName, BackSlash);
1109 if (LinkSubDir)
1110 {
1111 wcscat(FullLinkName, LinkSubDir);
1112 if (FullLinkName[wcslen(FullLinkName) - 1] != '\\')
1113 wcscat(FullLinkName, BackSlash);
1114 }
1115 if (LinkName)
1116 {
1117 wcscat(FullLinkName, LinkName);
1118 wcscat(FullLinkName, DotLnk);
1119 }
1120 hr = IPersistFile_Save(ppf, FullLinkName, TRUE);
1121 }
1122 else
1124 }
1125 IPersistFile_Release(ppf);
1126 }
1127 }
1128 IShellLinkW_Release(psl);
1129 }
1130 pCoUninitialize();
1131 if (SUCCEEDED(hr))
1132 ret = TRUE;
1133 else
1134 {
1137 else
1139 }
1140
1141cleanup:
1142 MyFree(LinkSubDir);
1143 MyFree(LinkName);
1144 MyFree(FileSubDir);
1145 MyFree(SubDirPart);
1146 MyFree(NamePart);
1147 MyFree(FullFileName);
1148 MyFree(FullWorkingDir);
1149 MyFree(FullIconName);
1150 MyFree(FullLinkName);
1151 MyFree(lpHotKey);
1152 MyFree(lpInfoTip);
1153 MyFree(DisplayName);
1154 if (hOle32)
1155 FreeLibrary(hOle32);
1156
1157 TRACE("Returning %d\n", ret);
1158 return ret;
1159}
1160
1162{
1163 FIXME( "should do copy inf %s\n", debugstr_w(field) );
1164 return TRUE;
1165}
1166
1167
1168/***********************************************************************
1169 * iterate_section_fields
1170 *
1171 * Iterate over all fields of a certain key of a certain section
1172 */
1175{
1176 WCHAR static_buffer[200];
1177 WCHAR *buffer = static_buffer;
1178 DWORD size = sizeof(static_buffer)/sizeof(WCHAR);
1180 BOOL ret = FALSE;
1181
1183 while (ok)
1184 {
1186 for (i = 1; i <= count; i++)
1187 {
1188 if (!(buffer = get_field_string( &context, i, buffer, static_buffer, &size )))
1189 goto done;
1190 if (!callback( hinf, buffer, arg ))
1191 {
1192 WARN("callback failed for %s %s err %d\n",
1194 goto done;
1195 }
1196 }
1198 }
1199 ret = TRUE;
1200 done:
1201 if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
1202 return ret;
1203}
1204
1205
1206/***********************************************************************
1207 * SetupInstallFilesFromInfSectionA (SETUPAPI.@)
1208 */
1210 PCSTR section, PCSTR src_root, UINT flags )
1211{
1212 UNICODE_STRING sectionW;
1213 BOOL ret = FALSE;
1214
1215 if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1216 {
1218 return FALSE;
1219 }
1220 if (!src_root)
1221 ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
1222 NULL, flags );
1223 else
1224 {
1225 UNICODE_STRING srcW;
1226 if (RtlCreateUnicodeStringFromAsciiz( &srcW, src_root ))
1227 {
1228 ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
1229 srcW.Buffer, flags );
1230 RtlFreeUnicodeString( &srcW );
1231 }
1233 }
1234 RtlFreeUnicodeString( &sectionW );
1235 return ret;
1236}
1237
1238
1239/***********************************************************************
1240 * SetupInstallFilesFromInfSectionW (SETUPAPI.@)
1241 */
1243 PCWSTR section, PCWSTR src_root, UINT flags )
1244{
1246
1247 info.queue = queue;
1248 info.src_root = src_root;
1249 info.copy_flags = flags;
1250 info.layout = hlayout;
1252}
1253
1254
1255/***********************************************************************
1256 * SetupInstallFromInfSectionA (SETUPAPI.@)
1257 */
1259 HKEY key_root, PCSTR src_root, UINT copy_flags,
1261 HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )
1262{
1263 UNICODE_STRING sectionW, src_rootW;
1265 BOOL ret = FALSE;
1266
1267 src_rootW.Buffer = NULL;
1268 if (src_root && !RtlCreateUnicodeStringFromAsciiz( &src_rootW, src_root ))
1269 {
1271 return FALSE;
1272 }
1273
1274 if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1275 {
1276 ctx.orig_context = context;
1277 ctx.orig_handler = callback;
1278 ret = SetupInstallFromInfSectionW( owner, hinf, sectionW.Buffer, flags, key_root,
1279 src_rootW.Buffer, copy_flags, QUEUE_callback_WtoA,
1280 &ctx, devinfo, devinfo_data );
1281 RtlFreeUnicodeString( &sectionW );
1282 }
1284
1285 RtlFreeUnicodeString( &src_rootW );
1286 return ret;
1287}
1288
1289
1290/***********************************************************************
1291 * include_callback
1292 *
1293 * Called once for each Include entry in a given section.
1294 */
1296{
1297 return SetupOpenAppendInfFileW( field, hinf, NULL );
1298}
1299
1300
1301/***********************************************************************
1302 * needs_callback
1303 *
1304 * Called once for each Needs entry in a given section.
1305 */
1306static BOOL needs_callback( HINF hinf, PCWSTR field, void *arg )
1307{
1308 struct needs_callback_info *info = arg;
1309
1310 switch (info->type)
1311 {
1312 case 0:
1313 return SetupInstallFromInfSectionW(info->owner, *(HINF*)hinf, field, info->flags,
1314 info->key_root, info->src_root, info->copy_flags, info->callback,
1315 info->context, info->devinfo, info->devinfo_data);
1316 case 1:
1317 return SetupInstallServicesFromInfSectionExW(*(HINF*)hinf, field, info->flags,
1318 info->devinfo, info->devinfo_data, info->reserved1, info->reserved2);
1319 default:
1320 ERR("Unknown info type %u\n", info->type);
1321 return FALSE;
1322 }
1323}
1324
1325
1326/***********************************************************************
1327 * SetupInstallFromInfSectionW (SETUPAPI.@)
1328 */
1333{
1334 struct needs_callback_info needs_info;
1335
1336 /* Parse 'Include' and 'Needs' directives */
1338 needs_info.type = 0;
1339 needs_info.owner = owner;
1340 needs_info.flags = flags;
1341 needs_info.key_root = key_root;
1342 needs_info.src_root = src_root;
1343 needs_info.copy_flags = copy_flags;
1344 needs_info.callback = callback;
1345 needs_info.context = context;
1346 needs_info.devinfo = devinfo;
1347 needs_info.devinfo_data = devinfo_data;
1348 iterate_section_fields( hinf, section, Needs, needs_callback, &needs_info);
1349
1350 if (flags & SPINST_FILES)
1351 {
1352 SP_DEVINSTALL_PARAMS_W install_params;
1355 BOOL use_custom_queue;
1356 BOOL ret;
1357
1358 install_params.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
1359 use_custom_queue = SetupDiGetDeviceInstallParamsW(devinfo, devinfo_data, &install_params) && (install_params.Flags & DI_NOVCP);
1360 if (!use_custom_queue && ((queue = SetupOpenFileQueue()) == (HSPFILEQ)INVALID_HANDLE_VALUE ))
1361 return FALSE;
1362 info.queue = use_custom_queue ? install_params.FileQueue : queue;
1363 info.src_root = src_root;
1364 info.copy_flags = copy_flags;
1365 info.layout = hinf;
1369 if (!use_custom_queue)
1370 {
1371 if (ret)
1374 }
1375 if (!ret) return FALSE;
1376 }
1377 if (flags & SPINST_INIFILES)
1378 {
1382 return FALSE;
1383 }
1384 if (flags & SPINST_INI2REG)
1385 {
1387 return FALSE;
1388 }
1389 if (flags & SPINST_LOGCONFIG)
1390 {
1392 return FALSE;
1393 }
1394 if (flags & SPINST_REGSVR)
1395 {
1396 struct register_dll_info info;
1397
1398 info.unregister = FALSE;
1399 if (flags & SPINST_REGISTERCALLBACKAWARE)
1400 {
1401 info.callback = callback;
1402 info.callback_context = context;
1403 }
1404 else info.callback = NULL;
1405
1407 return FALSE;
1408
1409#ifdef __WINESRC__
1410 if (!iterate_section_fields( hinf, section, WineFakeDlls, fake_dlls_callback, NULL ))
1411 return FALSE;
1412#endif // __WINESRC__
1413 }
1414 if (flags & SPINST_UNREGSVR)
1415 {
1416 struct register_dll_info info;
1417
1418 info.unregister = TRUE;
1419 if (flags & SPINST_REGISTERCALLBACKAWARE)
1420 {
1421 info.callback = callback;
1422 info.callback_context = context;
1423 }
1424 else info.callback = NULL;
1425
1427 return FALSE;
1428 }
1429 if (flags & SPINST_REGISTRY)
1430 {
1432
1433 info.default_root = key_root;
1434 info.delete = TRUE;
1436 return FALSE;
1437 info.delete = FALSE;
1439 return FALSE;
1440 }
1441 if (flags & SPINST_BITREG)
1442 {
1444 return FALSE;
1445 }
1447 {
1449 return FALSE;
1450 }
1451 if (flags & SPINST_COPYINF)
1452 {
1454 return FALSE;
1455 }
1456
1457 return TRUE;
1458}
1459
1460
1461/***********************************************************************
1462 * InstallHinfSectionW (SETUPAPI.@)
1463 *
1464 * NOTE: 'cmdline' is <section> <mode> <path> from
1465 * RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection <section> <mode> <path>
1466 */
1468{
1469 BOOL ret = FALSE;
1471 void *callback_context = NULL;
1472 DWORD SectionNameLength;
1473 UINT mode;
1475 BOOL bRebootRequired = FALSE;
1476
1477 TRACE("hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_w(cmdline));
1478
1480
1481 if (!(s = strchrW( section, ' ' ))) goto cleanup;
1482 *s++ = 0;
1483 while (*s == ' ') s++;
1484 mode = atoiW( s );
1485
1486 /* quoted paths are not allowed on native, the rest of the command line is taken as the path */
1487 if (!(s = strchrW( s, ' ' ))) goto cleanup;
1488 while (*s == ' ') s++;
1489 path = s;
1490
1491 if (mode & 0x80)
1492 {
1493 FIXME("default path of the installation not changed\n");
1494 mode &= ~0x80;
1495 }
1496
1498 if (hinf == INVALID_HANDLE_VALUE)
1499 {
1500 WARN("SetupOpenInfFileW(%s) failed (Error %u)\n", path, GetLastError());
1501 goto cleanup;
1502 }
1503
1505 hinf, section, section, sizeof(section)/sizeof(section[0]), &SectionNameLength, NULL );
1506 if (!ret)
1507 {
1508 WARN("SetupDiGetActualSectionToInstallW() failed (Error %u)\n", GetLastError());
1509 goto cleanup;
1510 }
1511 if (SectionNameLength > MAX_PATH - strlenW(DotServices))
1512 {
1513 WARN("Section name '%s' too long\n", section);
1514 goto cleanup;
1515 }
1516
1517 /* Copy files and add registry entries */
1522 NULL, NULL );
1523 if (!ret)
1524 {
1525 WARN("SetupInstallFromInfSectionW() failed (Error %u)\n", GetLastError());
1526 goto cleanup;
1527 }
1528 /* FIXME: need to check if some files were in use and need reboot
1529 * bReboot = ...;
1530 */
1531
1532 /* Install services */
1536 ret = TRUE;
1537 if (!ret)
1538 {
1539 WARN("SetupInstallServicesFromInfSectionW() failed (Error %u)\n", GetLastError());
1540 goto cleanup;
1541 }
1543 {
1544 bRebootRequired = TRUE;
1545 }
1546
1547 /* Check if we need to reboot */
1548 switch (mode)
1549 {
1550 case 0:
1551 /* Never reboot */
1552 break;
1553 case 1:
1554 /* Always reboot */
1555 ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
1556 SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
1557 break;
1558 case 2:
1559 /* Query user before rebooting */
1561 break;
1562 case 3:
1563 /* Reboot if necessary */
1564 if (bRebootRequired)
1565 {
1566 ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
1567 SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
1568 }
1569 break;
1570 case 4:
1571 /* If necessary, query user before rebooting */
1572 if (bRebootRequired)
1573 {
1575 }
1576 break;
1577 default:
1578 break;
1579 }
1580
1581cleanup:
1582 if ( callback_context )
1584 if ( hinf != INVALID_HANDLE_VALUE )
1585 SetupCloseInfFile( hinf );
1586
1587#ifdef CORE_11689_IS_FIXED
1588 // TODO: Localize the error string.
1590 {
1591 MessageBoxW(hwnd, section, L"setupapi.dll: An error happened...", MB_ICONERROR | MB_OK);
1592 }
1593#endif
1594}
1595
1596
1597/***********************************************************************
1598 * InstallHinfSectionA (SETUPAPI.@)
1599 */
1601{
1602 UNICODE_STRING cmdlineW;
1603
1604 if (RtlCreateUnicodeStringFromAsciiz( &cmdlineW, cmdline ))
1605 {
1606 InstallHinfSectionW( hwnd, handle, cmdlineW.Buffer, show );
1607 RtlFreeUnicodeString( &cmdlineW );
1608 }
1609}
1610
1611/***********************************************************************
1612 * SetupInstallServicesFromInfSectionW (SETUPAPI.@)
1613 */
1615{
1616 return SetupInstallServicesFromInfSectionExW( Inf, SectionName, Flags,
1617 NULL, NULL, NULL, NULL );
1618}
1619
1620/***********************************************************************
1621 * SetupInstallServicesFromInfSectionA (SETUPAPI.@)
1622 */
1624{
1625 return SetupInstallServicesFromInfSectionExA( Inf, SectionName, Flags,
1626 NULL, NULL, NULL, NULL );
1627}
1628
1629/***********************************************************************
1630 * SetupInstallServicesFromInfSectionExA (SETUPAPI.@)
1631 */
1633{
1634 UNICODE_STRING sectionnameW;
1635 BOOL ret = FALSE;
1636
1637 if (RtlCreateUnicodeStringFromAsciiz( &sectionnameW, sectionname ))
1638 {
1639 ret = SetupInstallServicesFromInfSectionExW( hinf, sectionnameW.Buffer, flags, devinfo, devinfo_data, reserved1, reserved2 );
1640 RtlFreeUnicodeString( &sectionnameW );
1641 }
1642 else
1644
1645 return ret;
1646}
1647
1648
1649static BOOL GetLineText( HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
1650{
1651 DWORD required;
1652 PWSTR buf = NULL;
1653
1654 *value = NULL;
1655
1656 if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, NULL, 0, &required )
1658 return FALSE;
1659
1660 buf = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) );
1661 if ( ! buf )
1662 {
1664 return FALSE;
1665 }
1666
1667 if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, buf, required, &required ) )
1668 {
1669 HeapFree( GetProcessHeap(), 0, buf );
1670 return FALSE;
1671 }
1672
1673 *value = buf;
1674 return TRUE;
1675}
1676
1677
1678static BOOL GetIntField( HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
1679{
1680 LPWSTR buffer, end;
1681 INT res;
1682
1683 if (! GetLineText( hinf, section_name, key_name, &buffer ) )
1684 return FALSE;
1685
1686 res = wcstol( buffer, &end, 0 );
1687 if (end != buffer && !*end)
1688 {
1690 *value = res;
1691 return TRUE;
1692 }
1693 else
1694 {
1697 return FALSE;
1698 }
1699}
1700
1701
1703{
1705 BOOL ret;
1706
1708 context,
1709 index,
1710 NULL, 0,
1711 &RequiredSize);
1712 if (!ret)
1713 return FALSE;
1714 else if (RequiredSize == 0)
1715 {
1716 *value = NULL;
1717 return TRUE;
1718 }
1719
1720 /* We got the needed size for the buffer */
1721 *value = MyMalloc(RequiredSize * sizeof(WCHAR));
1722 if (!*value)
1723 {
1725 return FALSE;
1726 }
1728 context,
1729 index,
1731 if (!ret)
1732 MyFree(*value);
1733
1734 return ret;
1735}
1736
1738 IN DWORD ServiceType,
1739 IN OUT LPWSTR *ServiceBinary)
1740{
1741 LPWSTR Buffer;
1742 WCHAR ReactOSDir[MAX_PATH];
1743 DWORD RosDirLength, ServiceLength, Win32Length;
1744
1745 GetWindowsDirectoryW(ReactOSDir, MAX_PATH);
1746 RosDirLength = strlenW(ReactOSDir);
1747 ServiceLength = strlenW(*ServiceBinary);
1748
1749 /* Check and fix two things:
1750 1. Get rid of C:\ReactOS and use relative
1751 path instead.
1752 2. Add %SystemRoot% for Win32 services */
1753
1754 if (ServiceLength < RosDirLength)
1755 return;
1756
1757 if (!wcsnicmp(*ServiceBinary, ReactOSDir, RosDirLength))
1758 {
1759 /* Yes, the first part is the C:\ReactOS\, just skip it */
1760 MoveMemory(*ServiceBinary, *ServiceBinary + RosDirLength + 1,
1761 (ServiceLength - RosDirLength) * sizeof(WCHAR));
1762
1763 /* Handle Win32-services differently */
1764 if (ServiceType & SERVICE_WIN32)
1765 {
1766 Win32Length = (ServiceLength - RosDirLength) * sizeof(WCHAR)
1767 - sizeof(L'\\') + sizeof(L"%SystemRoot%\\");
1768 Buffer = MyMalloc(Win32Length);
1769
1770 wcscpy(Buffer, L"%SystemRoot%\\");
1771 wcscat(Buffer, *ServiceBinary);
1772 MyFree(*ServiceBinary);
1773
1774 *ServiceBinary = Buffer;
1775 }
1776 }
1777}
1778
1780 struct DeviceInfoSet *list,
1781 IN HINF hInf,
1782 IN LPCWSTR ServiceSection,
1784 IN UINT ServiceFlags)
1785{
1786 SC_HANDLE hSCManager = NULL;
1787 SC_HANDLE hService = NULL;
1788 LPDWORD GroupOrder = NULL;
1789 LPQUERY_SERVICE_CONFIGW ServiceConfig = NULL;
1790 HKEY hServicesKey, hServiceKey;
1791 LONG rc;
1792 BOOL ret = FALSE;
1793
1794 HKEY hGroupOrderListKey = NULL;
1795 LPWSTR ServiceBinary = NULL;
1796 LPWSTR LoadOrderGroup = NULL;
1797 LPWSTR DisplayName = NULL;
1799 LPWSTR Dependencies = NULL;
1800 LPWSTR StartName = NULL;
1803 INT ServiceType, StartType, ErrorControl;
1804 DWORD dwRegType;
1805 DWORD tagId = (DWORD)-1;
1806 BOOL useTag;
1807
1808 if (!GetIntField(hInf, ServiceSection, ServiceTypeKey, &ServiceType))
1809 {
1811 goto cleanup;
1812 }
1813 if (!GetIntField(hInf, ServiceSection, StartTypeKey, &StartType))
1814 {
1816 goto cleanup;
1817 }
1818 if (!GetIntField(hInf, ServiceSection, ErrorControlKey, &ErrorControl))
1819 {
1821 goto cleanup;
1822 }
1823 useTag = (ServiceType == SERVICE_BOOT_START || ServiceType == SERVICE_SYSTEM_START);
1824
1826 if (hSCManager == NULL)
1827 goto cleanup;
1828
1829 if (!GetLineText(hInf, ServiceSection, ServiceBinaryKey, &ServiceBinary))
1830 {
1832 goto cleanup;
1833 }
1834
1835 /* Adjust binary path according to the service type */
1836 FixupServiceBinaryPath(ServiceType, &ServiceBinary);
1837
1838 /* Don't check return value, as these fields are optional and
1839 * GetLineText initialize output parameter even on failure */
1840 GetLineText(hInf, ServiceSection, LoadOrderGroupKey, &LoadOrderGroup);
1841 GetLineText(hInf, ServiceSection, DisplayNameKey, &DisplayName);
1842 GetLineText(hInf, ServiceSection, DescriptionKey, &Description);
1843 GetLineText(hInf, ServiceSection, DependenciesKey, &Dependencies);
1844 GetLineText(hInf, ServiceSection, StartNameKey, &StartName);
1845
1846 /* If there is no group, we must not request a tag */
1847 if (!LoadOrderGroup || !*LoadOrderGroup)
1848 useTag = FALSE;
1849
1850 hService = OpenServiceW(
1851 hSCManager,
1854 if (hService == NULL && GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
1855 goto cleanup;
1856
1857 if (hService && (ServiceFlags & SPSVCINST_DELETEEVENTLOGENTRY))
1858 {
1859 ret = DeleteService(hService);
1861 goto cleanup;
1862 }
1863
1864 if (hService == NULL)
1865 {
1866 /* Create new service */
1867 hService = CreateServiceW(
1868 hSCManager,
1870 DisplayName,
1871 WRITE_DAC,
1872 ServiceType,
1873 StartType,
1874 ErrorControl,
1875 ServiceBinary,
1876 LoadOrderGroup,
1877 useTag ? &tagId : NULL,
1878 Dependencies,
1879 StartName,
1880 NULL);
1881 if (hService == NULL)
1882 goto cleanup;
1883 }
1884 else
1885 {
1887 /* Read current configuration */
1888 if (!QueryServiceConfigW(hService, NULL, 0, &bufferSize))
1889 {
1891 goto cleanup;
1892 ServiceConfig = MyMalloc(bufferSize);
1893 if (!ServiceConfig)
1894 {
1896 goto cleanup;
1897 }
1898 if (!QueryServiceConfigW(hService, ServiceConfig, bufferSize, &bufferSize))
1899 goto cleanup;
1900 }
1901 tagId = ServiceConfig->dwTagId;
1902
1903 /* Update configuration */
1905 hService,
1906 ServiceType,
1907 (ServiceFlags & SPSVCINST_NOCLOBBER_STARTTYPE) ? SERVICE_NO_CHANGE : StartType,
1908 (ServiceFlags & SPSVCINST_NOCLOBBER_ERRORCONTROL) ? SERVICE_NO_CHANGE : ErrorControl,
1909 ServiceBinary,
1910 (ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP && ServiceConfig->lpLoadOrderGroup) ? NULL : LoadOrderGroup,
1911 useTag ? &tagId : NULL,
1912 (ServiceFlags & SPSVCINST_NOCLOBBER_DEPENDENCIES && ServiceConfig->lpDependencies) ? NULL : Dependencies,
1913 StartName,
1914 NULL,
1915 (ServiceFlags & SPSVCINST_NOCLOBBER_DISPLAYNAME && ServiceConfig->lpDisplayName) ? NULL : DisplayName);
1916 if (!ret)
1917 goto cleanup;
1918 }
1919
1920 /* Set security */
1921 if (GetLineText(hInf, ServiceSection, SecurityKey, &SecurityDescriptor))
1922 {
1924 if (!ret)
1925 goto cleanup;
1927 if (!ret)
1928 goto cleanup;
1929 }
1930
1931 /* FIXME: use Description and SPSVCINST_NOCLOBBER_DESCRIPTION */
1932
1933 if (useTag)
1934 {
1935 /* Add the tag to SYSTEM\CurrentControlSet\Control\GroupOrderList key */
1936 LPCWSTR lpLoadOrderGroup;
1938
1939 lpLoadOrderGroup = LoadOrderGroup;
1940 if ((ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP) && ServiceConfig && ServiceConfig->lpLoadOrderGroup)
1941 lpLoadOrderGroup = ServiceConfig->lpLoadOrderGroup;
1942
1943 rc = RegOpenKeyW(
1944 list ? list->HKLM : HKEY_LOCAL_MACHINE,
1946 &hGroupOrderListKey);
1947 if (rc != ERROR_SUCCESS)
1948 {
1949 SetLastError(rc);
1950 goto cleanup;
1951 }
1952 rc = RegQueryValueExW(hGroupOrderListKey, lpLoadOrderGroup, NULL, &dwRegType, NULL, &bufferSize);
1953 if (rc == ERROR_FILE_NOT_FOUND)
1954 bufferSize = sizeof(DWORD);
1955 else if (rc != ERROR_SUCCESS)
1956 {
1957 SetLastError(rc);
1958 goto cleanup;
1959 }
1960 else if (dwRegType != REG_BINARY || bufferSize == 0 || bufferSize % sizeof(DWORD) != 0)
1961 {
1963 goto cleanup;
1964 }
1965 /* Allocate buffer to store existing data + the new tag */
1966 GroupOrder = MyMalloc(bufferSize + sizeof(DWORD));
1967 if (!GroupOrder)
1968 {
1970 goto cleanup;
1971 }
1972 if (rc == ERROR_SUCCESS)
1973 {
1974 /* Read existing data */
1975 rc = RegQueryValueExW(
1976 hGroupOrderListKey,
1977 lpLoadOrderGroup,
1978 NULL,
1979 NULL,
1980 (BYTE*)GroupOrder,
1981 &bufferSize);
1982 if (rc != ERROR_SUCCESS)
1983 {
1984 SetLastError(rc);
1985 goto cleanup;
1986 }
1987 if (ServiceFlags & SPSVCINST_TAGTOFRONT)
1988 memmove(&GroupOrder[2], &GroupOrder[1], bufferSize - sizeof(DWORD));
1989 }
1990 else
1991 {
1992 GroupOrder[0] = 0;
1993 }
1994 GroupOrder[0]++;
1995 if (ServiceFlags & SPSVCINST_TAGTOFRONT)
1996 GroupOrder[1] = tagId;
1997 else
1998 GroupOrder[bufferSize / sizeof(DWORD)] = tagId;
1999
2000 rc = RegSetValueExW(
2001 hGroupOrderListKey,
2002 lpLoadOrderGroup,
2003 0,
2004 REG_BINARY,
2005 (BYTE*)GroupOrder,
2006 bufferSize + sizeof(DWORD));
2007 if (rc != ERROR_SUCCESS)
2008 {
2009 SetLastError(rc);
2010 goto cleanup;
2011 }
2012 }
2013
2014 /* Handle AddReg and DelReg */
2015 rc = RegOpenKeyExW(
2016 list ? list->HKLM : HKEY_LOCAL_MACHINE,
2018 0,
2020 &hServicesKey);
2021 if (rc != ERROR_SUCCESS)
2022 {
2023 SetLastError(rc);
2024 goto cleanup;
2025 }
2026 rc = RegOpenKeyExW(
2029 0,
2031 &hServiceKey);
2033 if (rc != ERROR_SUCCESS)
2034 {
2035 SetLastError(rc);
2036 goto cleanup;
2037 }
2038
2040 NULL,
2041 hInf,
2042 ServiceSection,
2044 hServiceKey,
2045 NULL,
2046 0,
2047 NULL,
2048 NULL,
2049 NULL,
2050 NULL);
2051 RegCloseKey(hServiceKey);
2052
2053cleanup:
2054 if (hSCManager != NULL)
2056 if (hService != NULL)
2057 CloseServiceHandle(hService);
2058 if (hGroupOrderListKey != NULL)
2059 RegCloseKey(hGroupOrderListKey);
2060 if (sd != NULL)
2061 LocalFree(sd);
2062 MyFree(ServiceConfig);
2063 MyFree(ServiceBinary);
2064 MyFree(LoadOrderGroup);
2065 MyFree(DisplayName);
2067 MyFree(Dependencies);
2069 MyFree(GroupOrder);
2070 MyFree(StartName);
2071
2072 TRACE("Returning %d\n", ret);
2073 return ret;
2074}
2075
2076
2077/***********************************************************************
2078 * SetupInstallServicesFromInfSectionExW (SETUPAPI.@)
2079 */
2081{
2082 struct DeviceInfoSet *list = NULL;
2083 BOOL ret = FALSE;
2084
2085 TRACE("%p, %s, 0x%lx, %p, %p, %p, %p\n", hinf, debugstr_w(sectionname),
2087
2088 if (!sectionname)
2091 {
2094 }
2099 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
2101 else if (reserved1 != NULL || reserved2 != NULL)
2103 else
2104 {
2105 struct needs_callback_info needs_info;
2107 LPWSTR ServiceSection = NULL;
2108 INT ServiceFlags;
2109 INFCONTEXT ContextService;
2110 BOOL bNeedReboot = FALSE;
2111
2112 /* Parse 'Include' and 'Needs' directives */
2113 iterate_section_fields( hinf, sectionname, Include, include_callback, NULL);
2114 needs_info.type = 1;
2115 needs_info.flags = flags;
2116 needs_info.devinfo = DeviceInfoSet;
2117 needs_info.devinfo_data = DeviceInfoData;
2118 needs_info.reserved1 = reserved1;
2119 needs_info.reserved2 = reserved2;
2120 iterate_section_fields( hinf, sectionname, Needs, needs_callback, &needs_info);
2121
2123 {
2124 FIXME("Stopping the device not implemented\n");
2125 /* This may lead to require a reboot */
2126 /* bNeedReboot = TRUE; */
2127#if 0
2131 goto done;
2133 {
2135 goto done;
2136 }
2137#endif
2138 flags &= ~SPSVCINST_STOPSERVICE;
2139 }
2140
2141 if (!(ret = SetupFindFirstLineW( hinf, sectionname, NULL, &ContextService )))
2142 {
2144 goto done;
2145 }
2146
2147 ret = SetupFindFirstLineW(hinf, sectionname, AddService, &ContextService);
2148 while (ret)
2149 {
2150 if (!GetStringField(&ContextService, 1, &ServiceName))
2151 goto done;
2152
2154 &ContextService,
2155 2, /* Field index */
2156 &ServiceFlags);
2157 if (!ret)
2158 {
2159 /* The field may be empty. Ignore the error */
2160 ServiceFlags = 0;
2161 }
2162
2163 if (!GetStringField(&ContextService, 3, &ServiceSection))
2164 goto done;
2165
2166 ret = InstallOneService(list, hinf, ServiceSection, ServiceName, (ServiceFlags & ~SPSVCINST_ASSOCSERVICE) | flags);
2167 if (!ret)
2168 goto done;
2169
2170 if (ServiceFlags & SPSVCINST_ASSOCSERVICE)
2171 {
2173 if (!ret)
2174 goto done;
2175 }
2176
2178 HeapFree(GetProcessHeap(), 0, ServiceSection);
2179 ServiceName = ServiceSection = NULL;
2180 ret = SetupFindNextMatchLineW(&ContextService, AddService, &ContextService);
2181 }
2182
2183 if (bNeedReboot)
2185 else
2187 ret = TRUE;
2188 }
2189done:
2190 TRACE("Returning %d\n", ret);
2191 return ret;
2192}
2193
2194
2195/***********************************************************************
2196 * SetupCopyOEMInfA (SETUPAPI.@)
2197 */
2199 IN PCSTR SourceInfFileName,
2200 IN PCSTR OEMSourceMediaLocation,
2201 IN DWORD OEMSourceMediaType,
2202 IN DWORD CopyStyle,
2203 OUT PSTR DestinationInfFileName OPTIONAL,
2204 IN DWORD DestinationInfFileNameSize,
2206 OUT PSTR* DestinationInfFileNameComponent OPTIONAL)
2207{
2208 PWSTR SourceInfFileNameW = NULL;
2209 PWSTR OEMSourceMediaLocationW = NULL;
2210 PWSTR DestinationInfFileNameW = NULL;
2211 PWSTR DestinationInfFileNameComponentW = NULL;
2212 BOOL ret = FALSE;
2213 DWORD size;
2214
2215 TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2216 SourceInfFileName, OEMSourceMediaLocation, OEMSourceMediaType,
2217 CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2218 RequiredSize, DestinationInfFileNameComponent);
2219
2220 if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2222 else if (!(SourceInfFileNameW = pSetupMultiByteToUnicode(SourceInfFileName, CP_ACP)))
2224 else if (OEMSourceMediaType != SPOST_NONE && !(OEMSourceMediaLocationW = pSetupMultiByteToUnicode(OEMSourceMediaLocation, CP_ACP)))
2226 else
2227 {
2228 if (DestinationInfFileNameSize != 0)
2229 {
2230 DestinationInfFileNameW = MyMalloc(DestinationInfFileNameSize * sizeof(WCHAR));
2231 if (!DestinationInfFileNameW)
2232 {
2234 goto cleanup;
2235 }
2236 }
2237
2239 SourceInfFileNameW,
2240 OEMSourceMediaLocationW,
2241 OEMSourceMediaType,
2242 CopyStyle,
2243 DestinationInfFileNameW,
2244 DestinationInfFileNameSize,
2245 &size,
2246 DestinationInfFileNameComponent ? &DestinationInfFileNameComponentW : NULL);
2247 if (!ret)
2248 {
2250 goto cleanup;
2251 }
2252
2253 if (DestinationInfFileNameSize != 0)
2254 {
2255 if (WideCharToMultiByte(CP_ACP, 0, DestinationInfFileNameW, -1,
2256 DestinationInfFileName, DestinationInfFileNameSize, NULL, NULL) == 0)
2257 {
2258 DestinationInfFileName[0] = '\0';
2259 goto cleanup;
2260 }
2261 }
2262 if (DestinationInfFileNameComponent)
2263 {
2264 if (DestinationInfFileNameComponentW)
2265 *DestinationInfFileNameComponent = &DestinationInfFileName[DestinationInfFileNameComponentW - DestinationInfFileNameW];
2266 else
2267 *DestinationInfFileNameComponent = NULL;
2268 }
2269 ret = TRUE;
2270 }
2271
2272cleanup:
2273 MyFree(SourceInfFileNameW);
2274 MyFree(OEMSourceMediaLocationW);
2275 MyFree(DestinationInfFileNameW);
2276 TRACE("Returning %d\n", ret);
2278 return ret;
2279}
2280
2281static int compare_files( HANDLE file1, HANDLE file2 )
2282{
2283 char buffer1[2048];
2284 char buffer2[2048];
2285 DWORD size1;
2286 DWORD size2;
2287
2288 while( ReadFile(file1, buffer1, sizeof(buffer1), &size1, NULL) &&
2289 ReadFile(file2, buffer2, sizeof(buffer2), &size2, NULL) )
2290 {
2291 int ret;
2292 if (size1 != size2)
2293 return size1 > size2 ? 1 : -1;
2294 if (!size1)
2295 return 0;
2296 ret = memcmp( buffer1, buffer2, size1 );
2297 if (ret)
2298 return ret;
2299 }
2300
2301 return 0;
2302}
2303
2304/***********************************************************************
2305 * SetupCopyOEMInfW (SETUPAPI.@)
2306 */
2308 IN PCWSTR SourceInfFileName,
2309 IN PCWSTR OEMSourceMediaLocation,
2310 IN DWORD OEMSourceMediaType,
2311 IN DWORD CopyStyle,
2312 OUT PWSTR DestinationInfFileName OPTIONAL,
2313 IN DWORD DestinationInfFileNameSize,
2315 OUT PWSTR* DestinationInfFileNameComponent OPTIONAL)
2316{
2317 BOOL ret = FALSE;
2318
2319 TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2320 debugstr_w(SourceInfFileName), debugstr_w(OEMSourceMediaLocation), OEMSourceMediaType,
2321 CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2322 RequiredSize, DestinationInfFileNameComponent);
2323
2324 if (!SourceInfFileName)
2326 else if (OEMSourceMediaType != SPOST_NONE && OEMSourceMediaType != SPOST_PATH && OEMSourceMediaType != SPOST_URL)
2329 {
2330 TRACE("Unknown flags: 0x%08lx\n", CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY));
2332 }
2333 else if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2335 else if (CopyStyle & SP_COPY_OEMINF_CATALOG_ONLY)
2336 {
2337 FIXME("CopyStyle 0x%x not supported\n", SP_COPY_OEMINF_CATALOG_ONLY);
2339 }
2340 else
2341 {
2342 HANDLE hSearch = INVALID_HANDLE_VALUE;
2343 WIN32_FIND_DATAW FindFileData;
2344 BOOL AlreadyExists;
2345 DWORD NextFreeNumber = 0;
2346 SIZE_T len;
2347 LPWSTR pFullFileName = NULL;
2348 LPWSTR pFileName; /* Pointer into pFullFileName buffer */
2349 HANDLE hSourceFile = INVALID_HANDLE_VALUE;
2350
2351 if (OEMSourceMediaType == SPOST_PATH || OEMSourceMediaType == SPOST_URL)
2352 FIXME("OEMSourceMediaType 0x%lx ignored\n", OEMSourceMediaType);
2353
2354 /* Check if source file exists, and open it */
2355 if (strchrW(SourceInfFileName, '\\' ) || strchrW(SourceInfFileName, '/' ))
2356 {
2357 WCHAR *path;
2358
2359 if (!(len = GetFullPathNameW(SourceInfFileName, 0, NULL, NULL)))
2360 return FALSE;
2361 if (!(path = MyMalloc(len * sizeof(WCHAR))))
2362 {
2364 return FALSE;
2365 }
2366 GetFullPathNameW(SourceInfFileName, len, path, NULL);
2367 hSourceFile = CreateFileW(
2370 NULL, OPEN_EXISTING, 0, NULL);
2371 MyFree(path);
2372 }
2373 else /* try Windows directory */
2374 {
2375 WCHAR *path, *p;
2376 static const WCHAR Inf[] = {'\\','i','n','f','\\',0};
2377 static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
2378
2379 len = GetWindowsDirectoryW(NULL, 0) + strlenW(SourceInfFileName) + 12;
2380 if (!(path = MyMalloc(len * sizeof(WCHAR))))
2381 {
2383 return FALSE;
2384 }
2386 p = path + strlenW(path);
2387 strcpyW(p, Inf);
2388 strcatW(p, SourceInfFileName);
2389 hSourceFile = CreateFileW(
2392 NULL, OPEN_EXISTING, 0, NULL);
2393 if (hSourceFile == INVALID_HANDLE_VALUE)
2394 {
2395 strcpyW(p, System32);
2396 strcatW(p, SourceInfFileName);
2397 hSourceFile = CreateFileW(
2400 NULL, OPEN_EXISTING, 0, NULL);
2401 }
2402 MyFree(path);
2403 }
2404 if (hSourceFile == INVALID_HANDLE_VALUE)
2405 {
2407 goto cleanup;
2408 }
2409
2410 /* Prepare .inf file specification */
2411 len = MAX_PATH + 1 + strlenW(InfDirectory) + 13;
2412 pFullFileName = MyMalloc(len * sizeof(WCHAR));
2413 if (!pFullFileName)
2414 {
2416 goto cleanup;
2417 }
2418 len = GetSystemWindowsDirectoryW(pFullFileName, MAX_PATH);
2419 if (len == 0 || len > MAX_PATH)
2420 goto cleanup;
2421 if (pFullFileName[strlenW(pFullFileName) - 1] != '\\')
2422 strcatW(pFullFileName, BackSlash);
2423 strcatW(pFullFileName, InfDirectory);
2424 pFileName = &pFullFileName[strlenW(pFullFileName)];
2425
2426 /* Search if the specified .inf file already exists in %WINDIR%\Inf */
2427 AlreadyExists = FALSE;
2428 strcpyW(pFileName, OemFileMask);
2429 hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2430 if (hSearch != INVALID_HANDLE_VALUE)
2431 {
2432 LARGE_INTEGER SourceFileSize;
2433
2434 if (GetFileSizeEx(hSourceFile, &SourceFileSize))
2435 {
2436 do
2437 {
2438 LARGE_INTEGER DestFileSize;
2439 HANDLE hDestFile;
2440
2441 strcpyW(pFileName, FindFileData.cFileName);
2442 hDestFile = CreateFileW(
2443 pFullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
2445 NULL, OPEN_EXISTING, 0, NULL);
2446 if (hDestFile != INVALID_HANDLE_VALUE)
2447 {
2448 if (GetFileSizeEx(hDestFile, &DestFileSize)
2449 && DestFileSize.QuadPart == SourceFileSize.QuadPart
2450 && !compare_files(hSourceFile, hDestFile))
2451 {
2452 TRACE("%s already exists as %s\n",
2453 debugstr_w(SourceInfFileName), debugstr_w(pFileName));
2454 AlreadyExists = TRUE;
2455 }
2456 }
2457 } while (!AlreadyExists && FindNextFileW(hSearch, &FindFileData));
2458 }
2459 FindClose(hSearch);
2460 hSearch = INVALID_HANDLE_VALUE;
2461 }
2462
2463 if (!AlreadyExists && CopyStyle & SP_COPY_REPLACEONLY)
2464 {
2465 /* FIXME: set DestinationInfFileName, RequiredSize, DestinationInfFileNameComponent */
2467 goto cleanup;
2468 }
2469 else if (AlreadyExists && (CopyStyle & SP_COPY_NOOVERWRITE))
2470 {
2471 DWORD Size = strlenW(pFileName) + 1;
2472
2473 if (RequiredSize)
2474 *RequiredSize = Size;
2475 if (DestinationInfFileNameSize == 0)
2477 else if (DestinationInfFileNameSize < Size)
2479 else
2480 {
2482 strcpyW(DestinationInfFileName, pFileName);
2483 }
2484 goto cleanup;
2485 }
2486
2487 /* Search the number to give to OEM??.INF */
2488 strcpyW(pFileName, OemFileMask);
2489 hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2490 if (hSearch == INVALID_HANDLE_VALUE)
2491 {
2493 goto cleanup;
2494 }
2495 else
2496 {
2497 do
2498 {
2499 DWORD CurrentNumber;
2500 if (swscanf(FindFileData.cFileName, OemFileSpecification, &CurrentNumber) == 1
2501 && CurrentNumber <= 99999)
2502 {
2503 if (CurrentNumber >= NextFreeNumber)
2504 NextFreeNumber = CurrentNumber + 1;
2505 }
2506 } while (FindNextFileW(hSearch, &FindFileData));
2507 }
2508
2509 if (NextFreeNumber > 99999)
2510 {
2511 ERR("Too much custom .inf files\n");
2513 goto cleanup;
2514 }
2515
2516 /* Create the full path: %WINDIR%\Inf\OEM{XXXXX}.inf */
2517 sprintfW(pFileName, OemFileSpecification, NextFreeNumber);
2518 TRACE("Next available file is %s\n", debugstr_w(pFileName));
2519
2520 if (!CopyFileW(SourceInfFileName, pFullFileName, TRUE))
2521 {
2522 TRACE("CopyFileW() failed with error 0x%lx\n", GetLastError());
2523 goto cleanup;
2524 }
2525
2526 len = strlenW(pFullFileName) + 1;
2527 if (RequiredSize)
2528 *RequiredSize = len;
2529 if (DestinationInfFileName)
2530 {
2531 if (DestinationInfFileNameSize >= len)
2532 {
2533 strcpyW(DestinationInfFileName, pFullFileName);
2534 if (DestinationInfFileNameComponent)
2535 *DestinationInfFileNameComponent = &DestinationInfFileName[pFileName - pFullFileName];
2536 }
2537 else
2538 {
2540 goto cleanup;
2541 }
2542 }
2543
2544 if (CopyStyle & SP_COPY_DELETESOURCE)
2545 {
2546 if (!DeleteFileW(SourceInfFileName))
2547 {
2548 TRACE("DeleteFileW() failed with error 0x%lx\n", GetLastError());
2549 goto cleanup;
2550 }
2551 }
2552
2553 ret = TRUE;
2554
2555cleanup:
2556 if (hSourceFile != INVALID_HANDLE_VALUE)
2557 CloseHandle(hSourceFile);
2558 if (hSearch != INVALID_HANDLE_VALUE)
2559 FindClose(hSearch);
2560 MyFree(pFullFileName);
2561 }
2562
2563 TRACE("Returning %d\n", ret);
2565 return ret;
2566}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define VOID
Definition: acefi.h:82
static void startup(void)
#define ok(value,...)
Definition: atltest.h:57
static WCHAR ServiceName[]
Definition: browser.c:19
static SERVICE_STATUS ServiceStatus
Definition: browser.c:22
#define FLG_ADDREG_OVERWRITEONLY
Definition: registry.c:48
#define FLG_ADDREG_TYPE_MASK
Definition: registry.c:55
#define FLG_ADDREG_TYPE_BINARY
Definition: registry.c:52
#define FLG_ADDREG_TYPE_SZ
Definition: registry.c:49
#define FLG_ADDREG_BINVALUETYPE
Definition: registry.c:43
#define FLG_ADDREG_APPEND
Definition: registry.c:46
#define FLG_ADDREG_TYPE_EXPAND_SZ
Definition: registry.c:51
#define FLG_ADDREG_DELVAL
Definition: registry.c:45
#define FLG_ADDREG_TYPE_MULTI_SZ
Definition: registry.c:50
#define FLG_ADDREG_TYPE_NONE
Definition: registry.c:54
#define FLG_ADDREG_KEYONLY
Definition: registry.c:47
#define FLG_ADDREG_NOCLOBBER
Definition: registry.c:44
#define FLG_ADDREG_TYPE_DWORD
Definition: registry.c:53
static HANDLE hServicesKey
Definition: devinst.c:21
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: bufpool.h:45
Definition: list.h:37
Definition: _queue.h:67
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * DIRID_get_string(int dirid)
Definition: dirid.c:159
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
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:4882
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor, DWORD StringSDRevision, PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize)
Definition: security.c:3062
HRESULT(* iterate_fields_func)(HINF hinf, PCWSTR field, const void *arg)
Definition: install.c:60
static HRESULT iterate_section_fields(HINF hinf, PCWSTR section, PCWSTR key, iterate_fields_func callback, void *arg)
Definition: install.c:263
static WCHAR * get_field_string(INFCONTEXT *context, DWORD index, WCHAR *buffer, const WCHAR *static_buffer, DWORD *size)
Definition: install.c:242
static const WCHAR Description[]
Definition: oid.c:1266
static const WCHAR empty[]
Definition: main.c:47
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define wcsnicmp
Definition: compat.h:14
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define FreeLibrary(x)
Definition: compat.h:748
#define RtlImageNtHeader
Definition: compat.h:806
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define GetFileSizeEx
Definition: compat.h:757
#define WideCharToMultiByte
Definition: compat.h:111
#define FILE_SHARE_READ
Definition: compat.h:136
#define lstrcpynW
Definition: compat.h:738
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2397
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
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:4592
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR string, LPCWSTR filename)
Definition: profile.c:1453
BOOL WINAPI SetupDiGetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4451
BOOL WINAPI SetupDiGetActualSectionToInstallW(HINF InfHandle, PCWSTR InfSectionName, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PWSTR *Extension)
Definition: devinst.c:1980
BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, const BYTE *PropertyBuffer, DWORD PropertyBufferSize)
Definition: devinst.c:3452
static const WCHAR WorkingDir[]
Definition: install.c:50
static BOOL profile_items_callback(IN HINF hInf, IN PCWSTR SectionName, IN PVOID Arg)
Definition: install.c:890
static BOOL copy_inf_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1161
HRESULT(WINAPI * COINITIALIZE)(IN LPVOID pvReserved)
Definition: install.c:101
static const WCHAR DependenciesKey[]
Definition: install.c:36
static const WCHAR DelFiles[]
Definition: install.c:108
static const WCHAR StartNameKey[]
Definition: install.c:45
static void append_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *strings, DWORD str_size)
Definition: install.c:223
static const WCHAR ServiceTypeKey[]
Definition: install.c:43
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:1258
static const WCHAR UpdateInis[]
Definition: install.c:115
static const WCHAR DotSecurity[]
Definition: install.c:123
static BOOL Concatenate(int DirId, LPCWSTR SubDirPart, LPCWSTR NamePart, LPWSTR *pFullName)
Definition: install.c:838
static const WCHAR ErrorControlKey[]
Definition: install.c:39
static const WCHAR InfoTip[]
Definition: install.c:54
static const WCHAR OemFileMask[]
Definition: install.c:31
static const WCHAR CmdLine[]
Definition: install.c:48
static const WCHAR DotServices[]
Definition: install.c:34
BOOL WINAPI SetupInstallServicesFromInfSectionW(HINF Inf, PCWSTR SectionName, DWORD Flags)
Definition: install.c:1614
static const WCHAR CopyFiles[]
Definition: install.c:107
static const WCHAR HotKey[]
Definition: install.c:53
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:1329
static BOOL GetIntField(HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
Definition: install.c:1678
static const WCHAR GroupOrderListKey[]
Definition: install.c:29
void WINAPI InstallHinfSectionW(HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show)
Definition: install.c:1467
static const WCHAR LoadOrderGroupKey[]
Definition: install.c:40
BOOL WINAPI SetupInstallFilesFromInfSectionA(HINF hinf, HINF hlayout, HSPFILEQ queue, PCSTR section, PCSTR src_root, UINT flags)
Definition: install.c:1209
BOOL WINAPI SetupInstallServicesFromInfSectionExA(HINF hinf, PCSTR sectionname, DWORD flags, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data, PVOID reserved1, PVOID reserved2)
Definition: install.c:1632
static BOOL needs_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1306
static const WCHAR RenFiles[]
Definition: install.c:109
static const WCHAR DescriptionKey[]
Definition: install.c:37
static BOOL logconf_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:826
static const WCHAR ServiceBinaryKey[]
Definition: install.c:42
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
static const WCHAR IconIndex[]
Definition: install.c:52
static BOOL update_ini_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:765
static const WCHAR Ini2Reg[]
Definition: install.c:110
static const WCHAR Needs[]
Definition: install.c:122
HRESULT(WINAPI * COCREATEINSTANCE)(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID *ppv)
Definition: install.c:102
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:2198
static BOOL registry_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:422
static const WCHAR BackSlash[]
Definition: install.c:28
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:2307
static const WCHAR Include[]
Definition: install.c:121
BOOL GetStringField(PINFCONTEXT context, DWORD index, PWSTR *value)
Definition: install.c:1702
static BOOL delete_files_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:175
static const WCHAR ProfileItems[]
Definition: install.c:120
static int compare_files(HANDLE file1, HANDLE file2)
Definition: install.c:2281
static VOID FixupServiceBinaryPath(IN DWORD ServiceType, IN OUT LPWSTR *ServiceBinary)
Definition: install.c:1737
static BOOL include_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1295
static HKEY get_root_key(const WCHAR *name, HKEY def_root)
Definition: install.c:201
static BOOL do_reg_operation(HKEY hkey, const WCHAR *value, INFCONTEXT *context, INT flags)
Definition: install.c:307
BOOL WINAPI SetupInstallFilesFromInfSectionW(HINF hinf, HINF hlayout, HSPFILEQ queue, PCWSTR section, PCWSTR src_root, UINT flags)
Definition: install.c:1242
static const WCHAR AddService[]
Definition: install.c:106
static const WCHAR OemFileSpecification[]
Definition: install.c:32
static BOOL register_dlls_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:670
static BOOL copy_files_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:158
static BOOL rename_files_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:188
static const WCHAR LogConf[]
Definition: install.c:111
static void delete_multi_sz_value(HKEY hkey, const WCHAR *value, const WCHAR *string)
Definition: install.c:268
static const WCHAR SecurityKey[]
Definition: install.c:41
static const WCHAR IconPath[]
Definition: install.c:51
static BOOL GetLineText(HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
Definition: install.c:1649
HRESULT(WINAPI * COUNINITIALIZE)(VOID)
Definition: install.c:103
static BOOL InstallOneService(struct DeviceInfoSet *list, IN HINF hInf, IN LPCWSTR ServiceSection, IN LPCWSTR ServiceName, IN UINT ServiceFlags)
Definition: install.c:1779
BOOL WINAPI SetupInstallServicesFromInfSectionA(HINF Inf, PCSTR SectionName, DWORD Flags)
Definition: install.c:1623
static const WCHAR SubDir[]
Definition: install.c:49
static const WCHAR StartTypeKey[]
Definition: install.c:44
static BOOL ini2reg_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:820
void WINAPI InstallHinfSectionA(HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show)
Definition: install.c:1600
static const WCHAR BitReg[]
Definition: install.c:114
static BOOL bitreg_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:832
static const WCHAR AddReg[]
Definition: install.c:112
static const WCHAR InfDirectory[]
Definition: install.c:30
static const WCHAR DisplayNameKey[]
Definition: install.c:38
static const WCHAR RegisterDlls[]
Definition: install.c:118
static BOOL update_ini_fields_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:814
static const WCHAR DelReg[]
Definition: install.c:113
static const WCHAR UnregisterDlls[]
Definition: install.c:119
BOOL WINAPI SetupInstallServicesFromInfSectionExW(HINF hinf, PCWSTR sectionname, DWORD flags, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID reserved1, PVOID reserved2)
Definition: install.c:2080
static const WCHAR UpdateIniFields[]
Definition: install.c:117
static const WCHAR DotLnk[]
Definition: install.c:33
static const WCHAR CopyINF[]
Definition: install.c:116
static const WCHAR DisplayResource[]
Definition: install.c:55
LPWSTR WINAPI pSetupMultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
Definition: misc.c:281
LPVOID WINAPI MyMalloc(DWORD dwSize)
Definition: misc.c:147
VOID WINAPI MyFree(LPVOID lpMem)
Definition: misc.c:128
LPWSTR WINAPI pSetupDuplicateString(LPCWSTR lpSrc)
Definition: misc.c:198
DWORD GlobalSetupFlags
Definition: misc.c:845
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
WCHAR * PARSER_get_dest_dir(INFCONTEXT *context)
Definition: parser.c:1116
BOOL WINAPI SetupOpenAppendInfFileW(PCWSTR name, HINF parent_hinf, UINT *error)
Definition: parser.c:1346
BOOL WINAPI SetupFindNextMatchLineW(PINFCONTEXT context_in, PCWSTR key, PINFCONTEXT context_out)
Definition: parser.c:1694
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1756
BOOL WINAPI SetupQueueRenameSectionW(HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section)
Definition: queue.c:919
BOOL WINAPI SetupQueueDefaultCopyW(HSPFILEQ queue, HINF hinf, PCWSTR src_root, PCWSTR src_file, PCWSTR dst_file, DWORD style)
Definition: queue.c:623
UINT CALLBACK QUEUE_callback_WtoA(void *context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:187
UINT WINAPI SetupDefaultQueueCallbackW(PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:1729
void WINAPI SetupTermDefaultQueueCallback(PVOID context)
Definition: queue.c:1656
PVOID WINAPI SetupInitDefaultQueueCallback(HWND owner)
Definition: queue.c:1629
BOOL WINAPI SetupQueueDeleteSectionW(HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section)
Definition: queue.c:870
BOOL WINAPI SetupQueueCopySectionW(HSPFILEQ queue, PCWSTR src_root, HINF hinf, HINF hlist, PCWSTR section, DWORD style)
Definition: queue.c:772
INT WINAPI SetupPromptReboot(HSPFILEQ file_queue, HWND owner, BOOL scan_only)
Definition: stubs.c:35
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3092
#define FILEOP_SKIP
Definition: fileqsup.h:49
UINT(CALLBACK * PSP_FILE_CALLBACK_W)(IN PVOID Context, IN UINT Notification, IN UINT_PTR Param1, IN UINT_PTR Param2)
Definition: fileqsup.h:66
#define FILEOP_DOIT
Definition: fileqsup.h:48
#define FILEOP_ABORT
Definition: fileqsup.h:47
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
uint8_t reserved2[12]
Definition: fsck.fat.h:23
size_t bufferSize
size_t total
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_Check_return_ _CRTIMP int __cdecl swscanf(_In_z_ const wchar_t *_Src, _In_z_ _Scanf_format_string_ const wchar_t *_Format,...)
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define INF_STYLE_WIN4
Definition: infsupp.h:41
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:34
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static IPrintDialogCallback callback
Definition: printdlg.c:326
static LPCSTR DWORD void * pvReserved
Definition: str.c:196
static BOOL create_fake_dll(LPCSTR filename)
Definition: file.c:2209
IMAGE_NT_HEADERS nt
Definition: module.c:50
static const WCHAR sd[]
Definition: suminfo.c:286
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
static LPUNKNOWN
Definition: ndr_ole.c:49
u32_t magic(void)
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN _Inout_ PMM_REQUIRED_RESOURCES Required
Definition: newmm.h:210
#define BOOL
Definition: nt_native.h:43
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define WRITE_DAC
Definition: nt_native.h:59
#define REG_BINARY
Definition: nt_native.h:1496
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define KEY_READ
Definition: nt_native.h:1023
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define DELETE
Definition: nt_native.h:57
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define KEY_WRITE
Definition: nt_native.h:1031
#define READ_CONTROL
Definition: nt_native.h:58
#define DWORD
Definition: nt_native.h:44
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
const GUID IID_IPersistFile
DWORD * PDWORD
Definition: pedump.c:68
#define IMAGE_FILE_DLL
Definition: pedump.c:169
long LONG
Definition: pedump.c:60
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define SetupOpenFileQueue
Definition: fileqsup.c:29
#define SetupCommitFileQueueW
Definition: fileqsup.c:33
#define SetupCloseFileQueue
Definition: fileqsup.c:30
#define atoiW(s)
Definition: unicode.h:60
#define strchrW(s, c)
Definition: unicode.h:40
#define strcmpiW(s1, s2)
Definition: unicode.h:45
#define strlenW(s)
Definition: unicode.h:34
#define strcatW(d, s)
Definition: unicode.h:36
#define strtoulW(s1, s2, b)
Definition: unicode.h:47
#define sprintfW
Definition: unicode.h:64
#define strcpyW(d, s)
Definition: unicode.h:35
#define FLG_ADDREG_DELREG_BIT
Definition: reginf.c:45
static const WCHAR HKLM[]
Definition: reginf.c:58
static const WCHAR HKCR[]
Definition: reginf.c:56
#define FLG_DELREG_KEYONLY_COMMON
Definition: reginf.c:44
#define FLG_ADDREG_KEYONLY_COMMON
Definition: reginf.c:43
static const WCHAR HKU[]
Definition: reginf.c:59
static const WCHAR HKR[]
Definition: reginf.c:60
static const WCHAR HKCU[]
Definition: reginf.c:57
#define REGSTR_PATH_SERVICES
Definition: regstr.h:47
const WCHAR * str
SC_HANDLE hSCManager
Definition: sc.c:12
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2068
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:622
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2160
BOOL WINAPI QueryServiceConfigW(SC_HANDLE hService, LPQUERY_SERVICE_CONFIGW lpServiceConfig, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2291
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:482
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:812
BOOL WINAPI SetServiceObjectSecurity(SC_HANDLE hService, SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR lpSecurityDescriptor)
Definition: scm.c:2774
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
#define REG_DWORD
Definition: sdbapi.c:596
#define SDDL_REVISION_1
Definition: sddl.h:30
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define SPINST_BITREG
Definition: setupapi.h:593
#define SP_COPY_OEMINF_CATALOG_ONLY
Definition: setupapi.h:494
#define SPSVCINST_NOCLOBBER_ERRORCONTROL
Definition: setupapi.h:630
#define SPREG_GETPROCADDR
Definition: setupapi.h:654
#define SPINST_UNREGSVR
Definition: setupapi.h:595
#define FLG_REGSVR_DLLREGISTER
Definition: setupapi.h:407
#define SPREG_REGSVR
Definition: setupapi.h:655
#define SP_COPY_NOOVERWRITE
Definition: setupapi.h:480
#define SP_COPY_DELETESOURCE
Definition: setupapi.h:476
#define SPSVCINST_DELETEEVENTLOGENTRY
Definition: setupapi.h:627
#define SPSVCINST_NOCLOBBER_DISPLAYNAME
Definition: setupapi.h:628
#define DI_NOVCP
Definition: setupapi.h:49
#define SPINST_PROFILEITEMS
Definition: setupapi.h:596
#define SPINST_INI2REG
Definition: setupapi.h:591
#define SP_COPY_REPLACEONLY
Definition: setupapi.h:477
#define SPSVCINST_NOCLOBBER_LOADORDERGROUP
Definition: setupapi.h:631
SP_DEVINSTALL_PARAMS_A SP_DEVINSTALL_PARAMS
Definition: setupapi.h:1155
#define SPFILENOTIFY_STARTREGISTRATION
Definition: setupapi.h:570
#define SPINST_REGSVR
Definition: setupapi.h:594
#define SPOST_NONE
Definition: setupapi.h:609
#define SPREG_SUCCESS
Definition: setupapi.h:652
#define ERROR_BAD_SERVICE_INSTALLSECT
Definition: setupapi.h:319
#define SPREG_TIMEOUT
Definition: setupapi.h:657
#define FLG_PROFITEM_CSIDL
Definition: setupapi.h:406
#define SPSVCINST_NOCLOBBER_STARTTYPE
Definition: setupapi.h:629
#define SPINST_INIFILES
Definition: setupapi.h:589
#define SPINST_REGISTRY
Definition: setupapi.h:590
#define ERROR_SECTION_NOT_FOUND
Definition: setupapi.h:293
#define SPSVCINST_TAGTOFRONT
Definition: setupapi.h:625
#define SPFILENOTIFY_ENDREGISTRATION
Definition: setupapi.h:571
#define SPSVCINST_NOCLOBBER_DEPENDENCIES
Definition: setupapi.h:632
UINT(CALLBACK * PSP_FILE_CALLBACK_A)(PVOID, UINT, UINT_PTR, UINT_PTR)
Definition: setupapi.h:876
#define SPSVCINST_ASSOCSERVICE
Definition: setupapi.h:626
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1528
#define SP_COPY_IN_USE_NEEDS_REBOOT
Definition: setupapi.h:485
#define SPINST_LOGCONFIG
Definition: setupapi.h:588
#define SPOST_URL
Definition: setupapi.h:611
#define SPOST_PATH
Definition: setupapi.h:610
#define FLG_PROFITEM_GROUP
Definition: setupapi.h:405
#define SPINST_ALL
Definition: setupapi.h:601
#define SPREG_LOADLIBRARY
Definition: setupapi.h:653
#define FLG_PROFITEM_DELETE
Definition: setupapi.h:404
#define FLG_REGSVR_DLLINSTALL
Definition: setupapi.h:408
#define SPDRP_SERVICE
Definition: setupapi.h:511
#define SPINST_FILES
Definition: setupapi.h:592
#define SPSVCINST_STOPSERVICE
Definition: setupapi.h:634
#define FLG_PROFITEM_CURRENTUSER
Definition: setupapi.h:403
#define SP_COPY_NEWER
Definition: setupapi.h:478
#define SETUP_DEVICE_INFO_SET_MAGIC
#define PSPGF_NONINTERACTIVE
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2194
#define CSIDL_PROGRAMS
Definition: shlobj.h:2174
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
TCHAR * cmdline
Definition: stretchblt.cpp:32
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
LPWSTR lpLoadOrderGroup
Definition: winsvc.h:160
LPVOID lpSecurityDescriptor
Definition: compat.h:193
DWORD dwCurrentState
Definition: winsvc.h:100
Definition: match.c:390
Definition: http.c:7252
Definition: parser.c:44
HSPFILEQ queue
Definition: install.c:60
Definition: copy.c:22
Definition: name.c:39
HDEVINFO devinfo
Definition: install.c:93
LPCWSTR src_root
Definition: install.c:89
PSP_DEVINFO_DATA devinfo_data
Definition: install.c:94
PSP_FILE_CALLBACK_W callback
Definition: install.c:76
PVOID callback_context
Definition: install.c:77
Definition: parser.c:56
Definition: ps.c:97
Definition: dhcpd.h:245
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: pdh_main.c:94
BOOL WINAPI SetupGetStringFieldW(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PWSTR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:186
BOOL WINAPI SetupFindFirstLineW(IN HINF InfHandle, IN PCWSTR Section, IN PCWSTR Key, IN OUT PINFCONTEXT Context)
Definition: infsupp.c:56
BOOL WINAPI SetupGetMultiSzFieldW(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PWSTR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:164
BOOL WINAPI SetupGetIntField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT INT *IntegerValue)
Definition: infsupp.c:148
ULONG WINAPI SetupGetFieldCount(IN PINFCONTEXT Context)
Definition: infsupp.c:93
BOOL WINAPI SetupFindNextLine(IN PINFCONTEXT ContextIn, OUT PINFCONTEXT ContextOut)
Definition: infsupp.c:82
VOID WINAPI SetupCloseInfFile(IN HINF InfHandle)
Definition: infsupp.c:45
BOOL WINAPI SetupGetBinaryField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PUCHAR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:128
int ret
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:344
#define MoveMemory
Definition: winbase.h:1709
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
void * arg
Definition: msvc.h:10
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define ERROR_SERVICE_MARKED_FOR_DELETE
Definition: winerror.h:623
#define HRESULT_FACILITY(hr)
Definition: winerror.h:79
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define ERROR_SERVICE_NOT_ACTIVE
Definition: winerror.h:613
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define ERROR_SUCCESS_REBOOT_REQUIRED
Definition: winerror.h:1215
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define FACILITY_WIN32
Definition: winerror.h:27
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define HRESULT_CODE(hr)
Definition: winerror.h:76
#define ERROR_TIMEOUT
Definition: winerror.h:941
#define ERROR_OPERATION_ABORTED
Definition: winerror.h:575
#define ERROR_INSTALL_SERVICE_FAILURE
Definition: winerror.h:959
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SERVICE_NO_CHANGE
Definition: winsvc.h:20
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CHANGE_CONFIG
Definition: winsvc.h:54
#define SERVICES_ACTIVE_DATABASE
Definition: winsvc.h:564
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_QUERY_CONFIG
Definition: winsvc.h:53
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:787
#define EWX_REBOOT
Definition: winuser.h:638
#define MB_OK
Definition: winuser.h:790
BOOL WINAPI ExitWindowsEx(_In_ UINT, _In_ DWORD)
_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:191
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976
#define SERVICE_WIN32
Definition: cmtypes.h:964
_In_ PSTRING FullName
Definition: rtlfuncs.h:1648
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193