ReactOS 0.4.16-dev-329-g9223134
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;
537
538 status.cbSize = sizeof(status);
539 status.FileName = path;
540 status.FailureCode = SPREG_SUCCESS;
541 status.Win32Error = ERROR_SUCCESS;
542
543 if (info->callback)
544 {
545 switch(info->callback( info->callback_context, SPFILENOTIFY_STARTREGISTRATION,
546 (UINT_PTR)&status, !info->unregister ))
547 {
548 case FILEOP_ABORT:
550 return FALSE;
551 case FILEOP_SKIP:
552 return TRUE;
553 case FILEOP_DOIT:
554 break;
555 }
556 }
557
559 {
560 WARN( "could not load %s\n", debugstr_w(path) );
561 status.FailureCode = SPREG_LOADLIBRARY;
562 status.Win32Error = GetLastError();
563 goto done;
564 }
565
567 {
568 /* file is an executable, not a dll */
571 WCHAR *cmd_line;
572 BOOL res;
573 static const WCHAR format[] = {'"','%','s','"',' ','%','s',0};
574 static const WCHAR default_args[] = {'/','R','e','g','S','e','r','v','e','r',0};
575
577 module = NULL;
578 if (!args) args = default_args;
579 cmd_line = HeapAlloc( GetProcessHeap(), 0, (strlenW(path) + strlenW(args) + 4) * sizeof(WCHAR) );
580 sprintfW( cmd_line, format, path, args );
581 memset( &startup, 0, sizeof(startup) );
582 startup.cb = sizeof(startup);
583 TRACE( "executing %s\n", debugstr_w(cmd_line) );
584 res = CreateProcessW( NULL, cmd_line, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info );
585 HeapFree( GetProcessHeap(), 0, cmd_line );
586 if (!res)
587 {
588 status.FailureCode = SPREG_LOADLIBRARY;
589 status.Win32Error = GetLastError();
590 goto done;
591 }
592 CloseHandle( info.hThread );
593
594 if (WaitForSingleObject( info.hProcess, timeout*1000 ) == WAIT_TIMEOUT)
595 {
596 /* timed out, kill the process */
597 TerminateProcess( info.hProcess, 1 );
598 status.FailureCode = SPREG_TIMEOUT;
599 status.Win32Error = ERROR_TIMEOUT;
600 }
601 CloseHandle( info.hProcess );
602 goto done;
603 }
604
606 {
607 const char *entry_point = info->unregister ? "DllUnregisterServer" : "DllRegisterServer";
608 HRESULT (WINAPI *func)(void) = (void *)GetProcAddress( module, entry_point );
609
610 if (!func)
611 {
612 status.FailureCode = SPREG_GETPROCADDR;
613 status.Win32Error = GetLastError();
614 goto done;
615 }
616
617 TRACE( "calling %s in %s\n", entry_point, debugstr_w(path) );
618 res = func();
619
620 if (FAILED(res))
621 {
622 WARN( "calling %s in %s returned error %x\n", entry_point, debugstr_w(path), res );
623 status.FailureCode = SPREG_REGSVR;
624 status.Win32Error = res;
625 goto done;
626 }
627 }
628
630 {
631 HRESULT (WINAPI *func)(BOOL,LPCWSTR) = (void *)GetProcAddress( module, "DllInstall" );
632
633 if (!func)
634 {
635 status.FailureCode = SPREG_GETPROCADDR;
636 status.Win32Error = GetLastError();
637 goto done;
638 }
639
640 TRACE( "calling DllInstall(%d,%s) in %s\n",
641 !info->unregister, debugstr_w(args), debugstr_w(path) );
642 res = func( !info->unregister, args );
643
644 if (FAILED(res))
645 {
646 WARN( "calling DllInstall in %s returned error %x\n", debugstr_w(path), res );
647 status.FailureCode = SPREG_REGSVR;
648 status.Win32Error = res;
649 goto done;
650 }
651 }
652
653done:
654 if (module) FreeLibrary( module );
655 if (info->callback) info->callback( info->callback_context, SPFILENOTIFY_ENDREGISTRATION,
656 (UINT_PTR)&status, !info->unregister );
657 return TRUE;
658}
659
660
661/***********************************************************************
662 * register_dlls_callback
663 *
664 * Called once for each RegisterDlls entry in a given section.
665 */
667{
668 struct register_dll_info *info = arg;
670 BOOL ret = TRUE;
672
673 for (; ok; ok = SetupFindNextLine( &context, &context ))
674 {
675 WCHAR *path, *args, *p;
678
679 /* get directory */
680 if (!(path = PARSER_get_dest_dir( &context ))) continue;
681
682 /* get dll name */
683 if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
684 goto done;
685 if (!(p = HeapReAlloc( GetProcessHeap(), 0, path,
686 (strlenW(path) + strlenW(buffer) + 2) * sizeof(WCHAR) ))) goto done;
687 path = p;
688 p += strlenW(p);
689 if (p == path || p[-1] != '\\') *p++ = '\\';
690 strcpyW( p, buffer );
691
692 /* get flags */
693 if (!SetupGetIntField( &context, 4, &flags )) flags = 0;
694
695 /* get timeout */
696#ifdef __REACTOS__
697 /* "11,,cmd.exe,,,/K dir" means default timeout, not a timeout of zero */
698 if (!SetupGetIntField( &context, 5, &timeout ) || timeout == 0) timeout = 60;
699#else
700 if (!SetupGetIntField( &context, 5, &timeout )) timeout = 60;
701#endif
702
703 /* get command line */
704 args = NULL;
705 if (SetupGetStringFieldW( &context, 6, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
706 args = buffer;
707
709
710 done:
712 if (!ret) break;
713 }
714 return ret;
715}
716
717#ifdef __WINESRC__
718/***********************************************************************
719 * fake_dlls_callback
720 *
721 * Called once for each WineFakeDlls entry in a given section.
722 */
723static BOOL fake_dlls_callback( HINF hinf, PCWSTR field, void *arg )
724{
726 BOOL ret = TRUE;
728
729 for (; ok; ok = SetupFindNextLine( &context, &context ))
730 {
731 WCHAR *path, *p;
733
734 /* get directory */
735 if (!(path = PARSER_get_dest_dir( &context ))) continue;
736
737 /* get dll name */
738 if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
739 goto done;
740 if (!(p = HeapReAlloc( GetProcessHeap(), 0, path,
741 (strlenW(path) + strlenW(buffer) + 2) * sizeof(WCHAR) ))) goto done;
742 path = p;
743 p += strlenW(p);
744 if (p == path || p[-1] != '\\') *p++ = '\\';
745 strcpyW( p, buffer );
746
747 /* get source dll */
748 if (SetupGetStringFieldW( &context, 4, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
749 p = buffer; /* otherwise use target base name as default source */
750
751 create_fake_dll( path, p ); /* ignore errors */
752
753 done:
755 if (!ret) break;
756 }
757 return ret;
758}
759#endif // __WINESRC__
760
761/***********************************************************************
762 * update_ini_callback
763 *
764 * Called once for each UpdateInis entry in a given section.
765 */
767{
769
771
772 for (; ok; ok = SetupFindNextLine( &context, &context ))
773 {
779 LPWSTR divider;
780
782 sizeof(filename)/sizeof(WCHAR), NULL ))
783 continue;
784
786 sizeof(section)/sizeof(WCHAR), NULL ))
787 continue;
788
790 sizeof(buffer)/sizeof(WCHAR), NULL ))
791 continue;
792
793 divider = strchrW(buffer,'=');
794 if (divider)
795 {
796 *divider = 0;
798 divider++;
799 strcpyW(string,divider);
800 }
801 else
802 {
804 string[0]=0;
805 }
806
807 TRACE("Writing %s = %s in %s of file %s\n",debugstr_w(entry),
810
811 }
812 return TRUE;
813}
814
816{
817 FIXME( "should update ini fields %s\n", debugstr_w(field) );
818 return TRUE;
819}
820
821static BOOL ini2reg_callback( HINF hinf, PCWSTR field, void *arg )
822{
823 FIXME( "should do ini2reg %s\n", debugstr_w(field) );
824 return TRUE;
825}
826
827static BOOL logconf_callback( HINF hinf, PCWSTR field, void *arg )
828{
829 FIXME( "should do logconf %s\n", debugstr_w(field) );
830 return TRUE;
831}
832
833static BOOL bitreg_callback( HINF hinf, PCWSTR field, void *arg )
834{
835 FIXME( "should do bitreg %s\n", debugstr_w(field) );
836 return TRUE;
837}
838
839static BOOL Concatenate(int DirId, LPCWSTR SubDirPart, LPCWSTR NamePart, LPWSTR *pFullName)
840{
841 DWORD dwRequired = 0;
842 LPCWSTR Dir;
844
845 *pFullName = NULL;
846
847 Dir = DIRID_get_string(DirId);
848 if (Dir && *Dir)
849 dwRequired += wcslen(Dir) + 1;
850 else
851 Dir = NULL; /* DIRID_get_string returns L"" for DIRID_ABSOLUTE */
852 if (SubDirPart)
853 dwRequired += wcslen(SubDirPart) + 1;
854 if (NamePart)
855 dwRequired += wcslen(NamePart);
856 dwRequired = dwRequired * sizeof(WCHAR) + sizeof(UNICODE_NULL);
857
858 FullName = MyMalloc(dwRequired);
859 if (!FullName)
860 {
862 return FALSE;
863 }
865
866 if (Dir)
867 {
868 wcscat(FullName, Dir);
869 if (FullName[wcslen(FullName) - 1] != '\\')
871 }
872 if (SubDirPart)
873 {
874 wcscat(FullName, SubDirPart);
875 if (FullName[wcslen(FullName) - 1] != '\\')
877 }
878 if (NamePart)
879 wcscat(FullName, NamePart);
880
881 *pFullName = FullName;
882 return TRUE;
883}
884
885/***********************************************************************
886 * profile_items_callback
887 *
888 * Called once for each ProfileItems entry in a given section.
889 */
890static BOOL
892 IN HINF hInf,
893 IN PCWSTR SectionName,
894 IN PVOID Arg)
895{
897 LPWSTR LinkSubDir = NULL, LinkName = NULL;
898 INT LinkAttributes = 0;
899 INT LinkFolder = 0;
900 INT FileDirId = 0;
902 LPWSTR FileSubDir = NULL;
903 INT DirId = 0;
904 LPWSTR SubDirPart = NULL, NamePart = NULL;
905 LPWSTR FullLinkName = NULL, FullFileName = NULL, FullWorkingDir = NULL, FullIconName = NULL;
906 INT IconIdx = 0;
907 LPWSTR lpHotKey = NULL, lpInfoTip = NULL;
908 LPWSTR DisplayName = NULL;
909 INT DisplayResId = 0;
910 BOOL ret = FALSE;
912
913 IShellLinkW *psl;
914 IPersistFile *ppf;
915 HMODULE hOle32 = NULL;
916 COINITIALIZE pCoInitialize;
917 COCREATEINSTANCE pCoCreateInstance;
918 COUNINITIALIZE pCoUninitialize;
919 HRESULT hr;
920
921 TRACE("hInf %p, SectionName %s, Arg %p\n",
922 hInf, debugstr_w(SectionName), Arg);
923
924 /* Read 'Name' entry */
925 if (!SetupFindFirstLineW(hInf, SectionName, Name, &Context))
926 goto cleanup;
927 if (!GetStringField(&Context, 1, &LinkName))
928 goto cleanup;
929 if (SetupGetFieldCount(&Context) >= 2)
930 {
931 if (!SetupGetIntField(&Context, 2, &LinkAttributes))
932 goto cleanup;
933 }
934 if (SetupGetFieldCount(&Context) >= 3)
935 {
936 if (!SetupGetIntField(&Context, 3, &LinkFolder))
937 goto cleanup;
938 }
939
940 /* Read 'CmdLine' entry */
941 if (!SetupFindFirstLineW(hInf, SectionName, CmdLine, &Context))
942 goto cleanup;
943 Index = 1;
944 if (!SetupGetIntField(&Context, Index++, &FileDirId))
945 goto cleanup;
946 if (SetupGetFieldCount(&Context) >= 3)
947 {
948 if (!GetStringField(&Context, Index++, &FileSubDir))
949 goto cleanup;
950 }
951 if (!GetStringField(&Context, Index++, &NamePart))
952 goto cleanup;
953 if (!Concatenate(FileDirId, FileSubDir, NamePart, &FullFileName))
954 goto cleanup;
955 MyFree(NamePart);
956 NamePart = NULL;
957
958 /* Read 'SubDir' entry */
959 if ((LinkAttributes & FLG_PROFITEM_GROUP) == 0 && SetupFindFirstLineW(hInf, SectionName, SubDir, &Context))
960 {
961 if (!GetStringField(&Context, 1, &LinkSubDir))
962 goto cleanup;
963 }
964
965 /* Read 'WorkingDir' entry */
966 if (SetupFindFirstLineW(hInf, SectionName, WorkingDir, &Context))
967 {
968 if (!SetupGetIntField(&Context, 1, &DirId))
969 goto cleanup;
970 if (SetupGetFieldCount(&Context) >= 2)
971 {
972 if (!GetStringField(&Context, 2, &SubDirPart))
973 goto cleanup;
974 }
975 if (!Concatenate(DirId, SubDirPart, NULL, &FullWorkingDir))
976 goto cleanup;
977 MyFree(SubDirPart);
978 SubDirPart = NULL;
979 }
980 else
981 {
982 if (!Concatenate(FileDirId, FileSubDir, NULL, &FullWorkingDir))
983 goto cleanup;
984 }
985
986 /* Read 'IconPath' entry */
987 if (SetupFindFirstLineW(hInf, SectionName, IconPath, &Context))
988 {
989 Index = 1;
990 if (!SetupGetIntField(&Context, Index++, &DirId))
991 goto cleanup;
992 if (SetupGetFieldCount(&Context) >= 3)
993 {
994 if (!GetStringField(&Context, Index++, &SubDirPart))
995 goto cleanup;
996 }
997 if (!GetStringField(&Context, Index, &NamePart))
998 goto cleanup;
999 if (!Concatenate(DirId, SubDirPart, NamePart, &FullIconName))
1000 goto cleanup;
1001 MyFree(SubDirPart);
1002 MyFree(NamePart);
1003 SubDirPart = NamePart = NULL;
1004 }
1005 else
1006 {
1007 FullIconName = pSetupDuplicateString(FullFileName);
1008 if (!FullIconName)
1009 goto cleanup;
1010 }
1011
1012 /* Read 'IconIndex' entry */
1013 if (SetupFindFirstLineW(hInf, SectionName, IconIndex, &Context))
1014 {
1015 if (!SetupGetIntField(&Context, 1, &IconIdx))
1016 goto cleanup;
1017 }
1018
1019 /* Read 'HotKey' and 'InfoTip' entries */
1020 GetLineText(hInf, SectionName, HotKey, &lpHotKey);
1021 GetLineText(hInf, SectionName, InfoTip, &lpInfoTip);
1022
1023 /* Read 'DisplayResource' entry */
1024 if (SetupFindFirstLineW(hInf, SectionName, DisplayResource, &Context))
1025 {
1026 if (!GetStringField(&Context, 1, &DisplayName))
1027 goto cleanup;
1028 if (!SetupGetIntField(&Context, 2, &DisplayResId))
1029 goto cleanup;
1030 }
1031
1032 /* Some debug */
1033 TRACE("Link is %s\\%s, attributes 0x%x\n", debugstr_w(LinkSubDir), debugstr_w(LinkName), LinkAttributes);
1034 TRACE("File is %s\n", debugstr_w(FullFileName));
1035 TRACE("Working dir %s\n", debugstr_w(FullWorkingDir));
1036 TRACE("Icon is %s, %d\n", debugstr_w(FullIconName), IconIdx);
1037 TRACE("Hotkey %s\n", debugstr_w(lpHotKey));
1038 TRACE("InfoTip %s\n", debugstr_w(lpInfoTip));
1039 TRACE("Display %s, %d\n", DisplayName, DisplayResId);
1040
1041 /* Load ole32.dll */
1042 hOle32 = LoadLibraryA("ole32.dll");
1043 if (!hOle32)
1044 goto cleanup;
1045 pCoInitialize = (COINITIALIZE)GetProcAddress(hOle32, "CoInitialize");
1046 if (!pCoInitialize)
1047 goto cleanup;
1048 pCoCreateInstance = (COCREATEINSTANCE)GetProcAddress(hOle32, "CoCreateInstance");
1049 if (!pCoCreateInstance)
1050 goto cleanup;
1051 pCoUninitialize = (COUNINITIALIZE)GetProcAddress(hOle32, "CoUninitialize");
1052 if (!pCoUninitialize)
1053 goto cleanup;
1054
1055 /* Create shortcut */
1056 hr = pCoInitialize(NULL);
1057 if (!SUCCEEDED(hr))
1058 {
1061 else
1063 goto cleanup;
1064 }
1065 hr = pCoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID*)&psl);
1066 if (SUCCEEDED(hr))
1067 {
1068 /* Fill link properties */
1069 hr = IShellLinkW_SetPath(psl, FullFileName);
1070 if (SUCCEEDED(hr))
1071 hr = IShellLinkW_SetArguments(psl, L"");
1072 if (SUCCEEDED(hr))
1073 hr = IShellLinkW_SetWorkingDirectory(psl, FullWorkingDir);
1074 if (SUCCEEDED(hr))
1075 hr = IShellLinkW_SetIconLocation(psl, FullIconName, IconIdx);
1076 if (SUCCEEDED(hr) && lpHotKey)
1077 FIXME("Need to store hotkey %s in shell link\n", debugstr_w(lpHotKey));
1078 if (SUCCEEDED(hr) && lpInfoTip)
1079 hr = IShellLinkW_SetDescription(psl, lpInfoTip);
1080 if (SUCCEEDED(hr) && DisplayName)
1081 FIXME("Need to store display name %s, %d in shell link\n", debugstr_w(DisplayName), DisplayResId);
1082 if (SUCCEEDED(hr))
1083 {
1084 hr = IShellLinkW_QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
1085 if (SUCCEEDED(hr))
1086 {
1087 Required = (MAX_PATH + 1 +
1088 ((LinkSubDir != NULL) ? wcslen(LinkSubDir) : 0) +
1089 ((LinkName != NULL) ? wcslen(LinkName) : 0)) * sizeof(WCHAR);
1090 FullLinkName = MyMalloc(Required);
1091 if (!FullLinkName)
1092 hr = E_OUTOFMEMORY;
1093 else
1094 {
1095 if (LinkAttributes & (FLG_PROFITEM_DELETE | FLG_PROFITEM_GROUP))
1096 FIXME("Need to handle FLG_PROFITEM_DELETE and FLG_PROFITEM_GROUP\n");
1097 if (LinkAttributes & FLG_PROFITEM_CSIDL)
1098 CSIDL = LinkFolder;
1099 else if (LinkAttributes & FLG_PROFITEM_CURRENTUSER)
1100 CSIDL = CSIDL_PROGRAMS;
1101
1103 NULL,
1104 FullLinkName,
1105 CSIDL,
1106 TRUE))
1107 {
1108 if (FullLinkName[wcslen(FullLinkName) - 1] != '\\')
1109 wcscat(FullLinkName, BackSlash);
1110 if (LinkSubDir)
1111 {
1112 wcscat(FullLinkName, LinkSubDir);
1113 if (FullLinkName[wcslen(FullLinkName) - 1] != '\\')
1114 wcscat(FullLinkName, BackSlash);
1115 }
1116 if (LinkName)
1117 {
1118 wcscat(FullLinkName, LinkName);
1119 wcscat(FullLinkName, DotLnk);
1120 }
1121 hr = IPersistFile_Save(ppf, FullLinkName, TRUE);
1122 }
1123 else
1125 }
1126 IPersistFile_Release(ppf);
1127 }
1128 }
1129 IShellLinkW_Release(psl);
1130 }
1131 pCoUninitialize();
1132 if (SUCCEEDED(hr))
1133 ret = TRUE;
1134 else
1135 {
1138 else
1140 }
1141
1142cleanup:
1143 MyFree(LinkSubDir);
1144 MyFree(LinkName);
1145 MyFree(FileSubDir);
1146 MyFree(SubDirPart);
1147 MyFree(NamePart);
1148 MyFree(FullFileName);
1149 MyFree(FullWorkingDir);
1150 MyFree(FullIconName);
1151 MyFree(FullLinkName);
1152 MyFree(lpHotKey);
1153 MyFree(lpInfoTip);
1154 MyFree(DisplayName);
1155 if (hOle32)
1156 FreeLibrary(hOle32);
1157
1158 TRACE("Returning %d\n", ret);
1159 return ret;
1160}
1161
1163{
1164 FIXME( "should do copy inf %s\n", debugstr_w(field) );
1165 return TRUE;
1166}
1167
1168
1169/***********************************************************************
1170 * iterate_section_fields
1171 *
1172 * Iterate over all fields of a certain key of a certain section
1173 */
1176{
1177 WCHAR static_buffer[200];
1178 WCHAR *buffer = static_buffer;
1179 DWORD size = sizeof(static_buffer)/sizeof(WCHAR);
1181 BOOL ret = FALSE;
1182
1184 while (ok)
1185 {
1187 for (i = 1; i <= count; i++)
1188 {
1189 if (!(buffer = get_field_string( &context, i, buffer, static_buffer, &size )))
1190 goto done;
1191 if (!callback( hinf, buffer, arg ))
1192 {
1193 WARN("callback failed for %s %s err %d\n",
1195 goto done;
1196 }
1197 }
1199 }
1200 ret = TRUE;
1201 done:
1202 if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
1203 return ret;
1204}
1205
1206
1207/***********************************************************************
1208 * SetupInstallFilesFromInfSectionA (SETUPAPI.@)
1209 */
1211 PCSTR section, PCSTR src_root, UINT flags )
1212{
1213 UNICODE_STRING sectionW;
1214 BOOL ret = FALSE;
1215
1216 if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1217 {
1219 return FALSE;
1220 }
1221 if (!src_root)
1222 ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
1223 NULL, flags );
1224 else
1225 {
1226 UNICODE_STRING srcW;
1227 if (RtlCreateUnicodeStringFromAsciiz( &srcW, src_root ))
1228 {
1229 ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
1230 srcW.Buffer, flags );
1231 RtlFreeUnicodeString( &srcW );
1232 }
1234 }
1235 RtlFreeUnicodeString( &sectionW );
1236 return ret;
1237}
1238
1239
1240/***********************************************************************
1241 * SetupInstallFilesFromInfSectionW (SETUPAPI.@)
1242 */
1244 PCWSTR section, PCWSTR src_root, UINT flags )
1245{
1247
1248 info.queue = queue;
1249 info.src_root = src_root;
1250 info.copy_flags = flags;
1251 info.layout = hlayout;
1253}
1254
1255
1256/***********************************************************************
1257 * SetupInstallFromInfSectionA (SETUPAPI.@)
1258 */
1260 HKEY key_root, PCSTR src_root, UINT copy_flags,
1262 HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )
1263{
1264 UNICODE_STRING sectionW, src_rootW;
1266 BOOL ret = FALSE;
1267
1268 src_rootW.Buffer = NULL;
1269 if (src_root && !RtlCreateUnicodeStringFromAsciiz( &src_rootW, src_root ))
1270 {
1272 return FALSE;
1273 }
1274
1275 if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1276 {
1277 ctx.orig_context = context;
1278 ctx.orig_handler = callback;
1279 ret = SetupInstallFromInfSectionW( owner, hinf, sectionW.Buffer, flags, key_root,
1280 src_rootW.Buffer, copy_flags, QUEUE_callback_WtoA,
1281 &ctx, devinfo, devinfo_data );
1282 RtlFreeUnicodeString( &sectionW );
1283 }
1285
1286 RtlFreeUnicodeString( &src_rootW );
1287 return ret;
1288}
1289
1290
1291/***********************************************************************
1292 * include_callback
1293 *
1294 * Called once for each Include entry in a given section.
1295 */
1297{
1298 return SetupOpenAppendInfFileW( field, hinf, NULL );
1299}
1300
1301
1302/***********************************************************************
1303 * needs_callback
1304 *
1305 * Called once for each Needs entry in a given section.
1306 */
1307static BOOL needs_callback( HINF hinf, PCWSTR field, void *arg )
1308{
1309 struct needs_callback_info *info = arg;
1310
1311 switch (info->type)
1312 {
1313 case 0:
1314 return SetupInstallFromInfSectionW(info->owner, *(HINF*)hinf, field, info->flags,
1315 info->key_root, info->src_root, info->copy_flags, info->callback,
1316 info->context, info->devinfo, info->devinfo_data);
1317 case 1:
1318 return SetupInstallServicesFromInfSectionExW(*(HINF*)hinf, field, info->flags,
1319 info->devinfo, info->devinfo_data, info->reserved1, info->reserved2);
1320 default:
1321 ERR("Unknown info type %u\n", info->type);
1322 return FALSE;
1323 }
1324}
1325
1326
1327/***********************************************************************
1328 * SetupInstallFromInfSectionW (SETUPAPI.@)
1329 */
1334{
1335 struct needs_callback_info needs_info;
1336
1337 /* Parse 'Include' and 'Needs' directives */
1339 needs_info.type = 0;
1340 needs_info.owner = owner;
1341 needs_info.flags = flags;
1342 needs_info.key_root = key_root;
1343 needs_info.src_root = src_root;
1344 needs_info.copy_flags = copy_flags;
1345 needs_info.callback = callback;
1346 needs_info.context = context;
1347 needs_info.devinfo = devinfo;
1348 needs_info.devinfo_data = devinfo_data;
1349 iterate_section_fields( hinf, section, Needs, needs_callback, &needs_info);
1350
1351 if (flags & SPINST_FILES)
1352 {
1353 SP_DEVINSTALL_PARAMS_W install_params;
1356 BOOL use_custom_queue;
1357 BOOL ret;
1358
1359 install_params.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
1360 use_custom_queue = SetupDiGetDeviceInstallParamsW(devinfo, devinfo_data, &install_params) && (install_params.Flags & DI_NOVCP);
1361 if (!use_custom_queue && ((queue = SetupOpenFileQueue()) == (HSPFILEQ)INVALID_HANDLE_VALUE ))
1362 return FALSE;
1363 info.queue = use_custom_queue ? install_params.FileQueue : queue;
1364 info.src_root = src_root;
1365 info.copy_flags = copy_flags;
1366 info.layout = hinf;
1370 if (!use_custom_queue)
1371 {
1372 if (ret)
1375 }
1376 if (!ret) return FALSE;
1377 }
1378 if (flags & SPINST_INIFILES)
1379 {
1383 return FALSE;
1384 }
1385 if (flags & SPINST_INI2REG)
1386 {
1388 return FALSE;
1389 }
1390 if (flags & SPINST_LOGCONFIG)
1391 {
1393 return FALSE;
1394 }
1395 if (flags & SPINST_REGSVR)
1396 {
1397 struct register_dll_info info;
1398
1399 info.unregister = FALSE;
1400 if (flags & SPINST_REGISTERCALLBACKAWARE)
1401 {
1402 info.callback = callback;
1403 info.callback_context = context;
1404 }
1405 else info.callback = NULL;
1406
1408 return FALSE;
1409
1410#ifdef __WINESRC__
1411 if (!iterate_section_fields( hinf, section, WineFakeDlls, fake_dlls_callback, NULL ))
1412 return FALSE;
1413#endif // __WINESRC__
1414 }
1415 if (flags & SPINST_UNREGSVR)
1416 {
1417 struct register_dll_info info;
1418
1419 info.unregister = TRUE;
1420 if (flags & SPINST_REGISTERCALLBACKAWARE)
1421 {
1422 info.callback = callback;
1423 info.callback_context = context;
1424 }
1425 else info.callback = NULL;
1426
1428 return FALSE;
1429 }
1430 if (flags & SPINST_REGISTRY)
1431 {
1433
1434 info.default_root = key_root;
1435 info.delete = TRUE;
1437 return FALSE;
1438 info.delete = FALSE;
1440 return FALSE;
1441 }
1442 if (flags & SPINST_BITREG)
1443 {
1445 return FALSE;
1446 }
1448 {
1450 return FALSE;
1451 }
1452 if (flags & SPINST_COPYINF)
1453 {
1455 return FALSE;
1456 }
1457
1458 return TRUE;
1459}
1460
1461
1462/***********************************************************************
1463 * InstallHinfSectionW (SETUPAPI.@)
1464 *
1465 * NOTE: 'cmdline' is <section> <mode> <path> from
1466 * RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection <section> <mode> <path>
1467 */
1469{
1470 BOOL ret = FALSE;
1472 void *callback_context = NULL;
1473 DWORD SectionNameLength;
1474 UINT mode;
1476 BOOL bRebootRequired = FALSE;
1477
1478 TRACE("hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_w(cmdline));
1479
1481
1482 if (!(s = strchrW( section, ' ' ))) goto cleanup;
1483 *s++ = 0;
1484 while (*s == ' ') s++;
1485 mode = atoiW( s );
1486
1487 /* quoted paths are not allowed on native, the rest of the command line is taken as the path */
1488 if (!(s = strchrW( s, ' ' ))) goto cleanup;
1489 while (*s == ' ') s++;
1490 path = s;
1491
1492 if (mode & 0x80)
1493 {
1494 FIXME("default path of the installation not changed\n");
1495 mode &= ~0x80;
1496 }
1497
1499 if (hinf == INVALID_HANDLE_VALUE)
1500 {
1501 WARN("SetupOpenInfFileW(%s) failed (Error %u)\n", path, GetLastError());
1502 goto cleanup;
1503 }
1504
1506 hinf, section, section, sizeof(section)/sizeof(section[0]), &SectionNameLength, NULL );
1507 if (!ret)
1508 {
1509 WARN("SetupDiGetActualSectionToInstallW() failed (Error %u)\n", GetLastError());
1510 goto cleanup;
1511 }
1512 if (SectionNameLength > MAX_PATH - strlenW(DotServices))
1513 {
1514 WARN("Section name '%s' too long\n", section);
1515 goto cleanup;
1516 }
1517
1518 /* Copy files and add registry entries */
1523 NULL, NULL );
1524 if (!ret)
1525 {
1526 WARN("SetupInstallFromInfSectionW() failed (Error %u)\n", GetLastError());
1527 goto cleanup;
1528 }
1529 /* FIXME: need to check if some files were in use and need reboot
1530 * bReboot = ...;
1531 */
1532
1533 /* Install services */
1537 ret = TRUE;
1538 if (!ret)
1539 {
1540 WARN("SetupInstallServicesFromInfSectionW() failed (Error %u)\n", GetLastError());
1541 goto cleanup;
1542 }
1544 {
1545 bRebootRequired = TRUE;
1546 }
1547
1548 /* Check if we need to reboot */
1549 switch (mode)
1550 {
1551 case 0:
1552 /* Never reboot */
1553 break;
1554 case 1:
1555 /* Always reboot */
1556 ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
1557 SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
1558 break;
1559 case 2:
1560 /* Query user before rebooting */
1562 break;
1563 case 3:
1564 /* Reboot if necessary */
1565 if (bRebootRequired)
1566 {
1567 ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_APPLICATION |
1568 SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED);
1569 }
1570 break;
1571 case 4:
1572 /* If necessary, query user before rebooting */
1573 if (bRebootRequired)
1574 {
1576 }
1577 break;
1578 default:
1579 break;
1580 }
1581
1582cleanup:
1583 if ( callback_context )
1585 if ( hinf != INVALID_HANDLE_VALUE )
1586 SetupCloseInfFile( hinf );
1587
1588#ifdef CORE_11689_IS_FIXED
1589 // TODO: Localize the error string.
1591 {
1592 MessageBoxW(hwnd, section, L"setupapi.dll: An error happened...", MB_ICONERROR | MB_OK);
1593 }
1594#endif
1595}
1596
1597
1598/***********************************************************************
1599 * InstallHinfSectionA (SETUPAPI.@)
1600 */
1602{
1603 UNICODE_STRING cmdlineW;
1604
1605 if (RtlCreateUnicodeStringFromAsciiz( &cmdlineW, cmdline ))
1606 {
1607 InstallHinfSectionW( hwnd, handle, cmdlineW.Buffer, show );
1608 RtlFreeUnicodeString( &cmdlineW );
1609 }
1610}
1611
1612/***********************************************************************
1613 * SetupInstallServicesFromInfSectionW (SETUPAPI.@)
1614 */
1616{
1617 return SetupInstallServicesFromInfSectionExW( Inf, SectionName, Flags,
1618 NULL, NULL, NULL, NULL );
1619}
1620
1621/***********************************************************************
1622 * SetupInstallServicesFromInfSectionA (SETUPAPI.@)
1623 */
1625{
1626 return SetupInstallServicesFromInfSectionExA( Inf, SectionName, Flags,
1627 NULL, NULL, NULL, NULL );
1628}
1629
1630/***********************************************************************
1631 * SetupInstallServicesFromInfSectionExA (SETUPAPI.@)
1632 */
1634{
1635 UNICODE_STRING sectionnameW;
1636 BOOL ret = FALSE;
1637
1638 if (RtlCreateUnicodeStringFromAsciiz( &sectionnameW, sectionname ))
1639 {
1640 ret = SetupInstallServicesFromInfSectionExW( hinf, sectionnameW.Buffer, flags, devinfo, devinfo_data, reserved1, reserved2 );
1641 RtlFreeUnicodeString( &sectionnameW );
1642 }
1643 else
1645
1646 return ret;
1647}
1648
1649
1650static BOOL GetLineText( HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
1651{
1652 DWORD required;
1653 PWSTR buf = NULL;
1654
1655 *value = NULL;
1656
1657 if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, NULL, 0, &required )
1659 return FALSE;
1660
1661 buf = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) );
1662 if ( ! buf )
1663 {
1665 return FALSE;
1666 }
1667
1668 if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, buf, required, &required ) )
1669 {
1670 HeapFree( GetProcessHeap(), 0, buf );
1671 return FALSE;
1672 }
1673
1674 *value = buf;
1675 return TRUE;
1676}
1677
1678
1679static BOOL GetIntField( HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
1680{
1681 LPWSTR buffer, end;
1682 INT res;
1683
1684 if (! GetLineText( hinf, section_name, key_name, &buffer ) )
1685 return FALSE;
1686
1687 res = wcstol( buffer, &end, 0 );
1688 if (end != buffer && !*end)
1689 {
1691 *value = res;
1692 return TRUE;
1693 }
1694 else
1695 {
1698 return FALSE;
1699 }
1700}
1701
1702
1704{
1706 BOOL ret;
1707
1709 context,
1710 index,
1711 NULL, 0,
1712 &RequiredSize);
1713 if (!ret)
1714 return FALSE;
1715 else if (RequiredSize == 0)
1716 {
1717 *value = NULL;
1718 return TRUE;
1719 }
1720
1721 /* We got the needed size for the buffer */
1722 *value = MyMalloc(RequiredSize * sizeof(WCHAR));
1723 if (!*value)
1724 {
1726 return FALSE;
1727 }
1729 context,
1730 index,
1732 if (!ret)
1733 MyFree(*value);
1734
1735 return ret;
1736}
1737
1739 IN DWORD ServiceType,
1740 IN OUT LPWSTR *ServiceBinary)
1741{
1742 LPWSTR Buffer;
1743 WCHAR ReactOSDir[MAX_PATH];
1744 DWORD RosDirLength, ServiceLength, Win32Length;
1745
1746 GetWindowsDirectoryW(ReactOSDir, MAX_PATH);
1747 RosDirLength = strlenW(ReactOSDir);
1748 ServiceLength = strlenW(*ServiceBinary);
1749
1750 /* Check and fix two things:
1751 1. Get rid of C:\ReactOS and use relative
1752 path instead.
1753 2. Add %SystemRoot% for Win32 services */
1754
1755 if (ServiceLength < RosDirLength)
1756 return;
1757
1758 if (!wcsnicmp(*ServiceBinary, ReactOSDir, RosDirLength))
1759 {
1760 /* Yes, the first part is the C:\ReactOS\, just skip it */
1761 MoveMemory(*ServiceBinary, *ServiceBinary + RosDirLength + 1,
1762 (ServiceLength - RosDirLength) * sizeof(WCHAR));
1763
1764 /* Handle Win32-services differently */
1765 if (ServiceType & SERVICE_WIN32)
1766 {
1767 Win32Length = (ServiceLength - RosDirLength) * sizeof(WCHAR)
1768 - sizeof(L'\\') + sizeof(L"%SystemRoot%\\");
1769 Buffer = MyMalloc(Win32Length);
1770
1771 wcscpy(Buffer, L"%SystemRoot%\\");
1772 wcscat(Buffer, *ServiceBinary);
1773 MyFree(*ServiceBinary);
1774
1775 *ServiceBinary = Buffer;
1776 }
1777 }
1778}
1779
1781 struct DeviceInfoSet *list,
1782 IN HINF hInf,
1783 IN LPCWSTR ServiceSection,
1785 IN UINT ServiceFlags)
1786{
1787 SC_HANDLE hSCManager = NULL;
1788 SC_HANDLE hService = NULL;
1789 LPDWORD GroupOrder = NULL;
1790 LPQUERY_SERVICE_CONFIGW ServiceConfig = NULL;
1791 HKEY hServicesKey, hServiceKey;
1792 LONG rc;
1793 BOOL ret = FALSE;
1794
1795 HKEY hGroupOrderListKey = NULL;
1796 LPWSTR ServiceBinary = NULL;
1797 LPWSTR LoadOrderGroup = NULL;
1798 LPWSTR DisplayName = NULL;
1800 LPWSTR Dependencies = NULL;
1801 LPWSTR StartName = NULL;
1804 INT ServiceType, StartType, ErrorControl;
1805 DWORD dwRegType;
1806 DWORD tagId = (DWORD)-1;
1807 BOOL useTag;
1808
1809 if (!GetIntField(hInf, ServiceSection, ServiceTypeKey, &ServiceType))
1810 {
1812 goto cleanup;
1813 }
1814 if (!GetIntField(hInf, ServiceSection, StartTypeKey, &StartType))
1815 {
1817 goto cleanup;
1818 }
1819 if (!GetIntField(hInf, ServiceSection, ErrorControlKey, &ErrorControl))
1820 {
1822 goto cleanup;
1823 }
1824 useTag = (ServiceType == SERVICE_BOOT_START || ServiceType == SERVICE_SYSTEM_START);
1825
1827 if (hSCManager == NULL)
1828 goto cleanup;
1829
1830 if (!GetLineText(hInf, ServiceSection, ServiceBinaryKey, &ServiceBinary))
1831 {
1833 goto cleanup;
1834 }
1835
1836 /* Adjust binary path according to the service type */
1837 FixupServiceBinaryPath(ServiceType, &ServiceBinary);
1838
1839 /* Don't check return value, as these fields are optional and
1840 * GetLineText initialize output parameter even on failure */
1841 GetLineText(hInf, ServiceSection, LoadOrderGroupKey, &LoadOrderGroup);
1842 GetLineText(hInf, ServiceSection, DisplayNameKey, &DisplayName);
1843 GetLineText(hInf, ServiceSection, DescriptionKey, &Description);
1844 GetLineText(hInf, ServiceSection, DependenciesKey, &Dependencies);
1845 GetLineText(hInf, ServiceSection, StartNameKey, &StartName);
1846
1847 /* If there is no group, we must not request a tag */
1848 if (!LoadOrderGroup || !*LoadOrderGroup)
1849 useTag = FALSE;
1850
1851 hService = OpenServiceW(
1852 hSCManager,
1855 if (hService == NULL && GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
1856 goto cleanup;
1857
1858 if (hService && (ServiceFlags & SPSVCINST_DELETEEVENTLOGENTRY))
1859 {
1860 ret = DeleteService(hService);
1862 goto cleanup;
1863 }
1864
1865 if (hService == NULL)
1866 {
1867 /* Create new service */
1868 hService = CreateServiceW(
1869 hSCManager,
1871 DisplayName,
1872 WRITE_DAC,
1873 ServiceType,
1874 StartType,
1875 ErrorControl,
1876 ServiceBinary,
1877 LoadOrderGroup,
1878 useTag ? &tagId : NULL,
1879 Dependencies,
1880 StartName,
1881 NULL);
1882 if (hService == NULL)
1883 goto cleanup;
1884 }
1885 else
1886 {
1888 /* Read current configuration */
1889 if (!QueryServiceConfigW(hService, NULL, 0, &bufferSize))
1890 {
1892 goto cleanup;
1893 ServiceConfig = MyMalloc(bufferSize);
1894 if (!ServiceConfig)
1895 {
1897 goto cleanup;
1898 }
1899 if (!QueryServiceConfigW(hService, ServiceConfig, bufferSize, &bufferSize))
1900 goto cleanup;
1901 }
1902 tagId = ServiceConfig->dwTagId;
1903
1904 /* Update configuration */
1906 hService,
1907 ServiceType,
1908 (ServiceFlags & SPSVCINST_NOCLOBBER_STARTTYPE) ? SERVICE_NO_CHANGE : StartType,
1909 (ServiceFlags & SPSVCINST_NOCLOBBER_ERRORCONTROL) ? SERVICE_NO_CHANGE : ErrorControl,
1910 ServiceBinary,
1911 (ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP && ServiceConfig->lpLoadOrderGroup) ? NULL : LoadOrderGroup,
1912 useTag ? &tagId : NULL,
1913 (ServiceFlags & SPSVCINST_NOCLOBBER_DEPENDENCIES && ServiceConfig->lpDependencies) ? NULL : Dependencies,
1914 StartName,
1915 NULL,
1916 (ServiceFlags & SPSVCINST_NOCLOBBER_DISPLAYNAME && ServiceConfig->lpDisplayName) ? NULL : DisplayName);
1917 if (!ret)
1918 goto cleanup;
1919 }
1920
1921 /* Set security */
1922 if (GetLineText(hInf, ServiceSection, SecurityKey, &SecurityDescriptor))
1923 {
1925 if (!ret)
1926 goto cleanup;
1928 if (!ret)
1929 goto cleanup;
1930 }
1931
1932 /* FIXME: use Description and SPSVCINST_NOCLOBBER_DESCRIPTION */
1933
1934 if (useTag)
1935 {
1936 /* Add the tag to SYSTEM\CurrentControlSet\Control\GroupOrderList key */
1937 LPCWSTR lpLoadOrderGroup;
1939
1940 lpLoadOrderGroup = LoadOrderGroup;
1941 if ((ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP) && ServiceConfig && ServiceConfig->lpLoadOrderGroup)
1942 lpLoadOrderGroup = ServiceConfig->lpLoadOrderGroup;
1943
1944 rc = RegOpenKeyW(
1945 list ? list->HKLM : HKEY_LOCAL_MACHINE,
1947 &hGroupOrderListKey);
1948 if (rc != ERROR_SUCCESS)
1949 {
1950 SetLastError(rc);
1951 goto cleanup;
1952 }
1953 rc = RegQueryValueExW(hGroupOrderListKey, lpLoadOrderGroup, NULL, &dwRegType, NULL, &bufferSize);
1954 if (rc == ERROR_FILE_NOT_FOUND)
1955 bufferSize = sizeof(DWORD);
1956 else if (rc != ERROR_SUCCESS)
1957 {
1958 SetLastError(rc);
1959 goto cleanup;
1960 }
1961 else if (dwRegType != REG_BINARY || bufferSize == 0 || bufferSize % sizeof(DWORD) != 0)
1962 {
1964 goto cleanup;
1965 }
1966 /* Allocate buffer to store existing data + the new tag */
1967 GroupOrder = MyMalloc(bufferSize + sizeof(DWORD));
1968 if (!GroupOrder)
1969 {
1971 goto cleanup;
1972 }
1973 if (rc == ERROR_SUCCESS)
1974 {
1975 /* Read existing data */
1976 rc = RegQueryValueExW(
1977 hGroupOrderListKey,
1978 lpLoadOrderGroup,
1979 NULL,
1980 NULL,
1981 (BYTE*)GroupOrder,
1982 &bufferSize);
1983 if (rc != ERROR_SUCCESS)
1984 {
1985 SetLastError(rc);
1986 goto cleanup;
1987 }
1988 if (ServiceFlags & SPSVCINST_TAGTOFRONT)
1989 memmove(&GroupOrder[2], &GroupOrder[1], bufferSize - sizeof(DWORD));
1990 }
1991 else
1992 {
1993 GroupOrder[0] = 0;
1994 }
1995 GroupOrder[0]++;
1996 if (ServiceFlags & SPSVCINST_TAGTOFRONT)
1997 GroupOrder[1] = tagId;
1998 else
1999 GroupOrder[bufferSize / sizeof(DWORD)] = tagId;
2000
2001 rc = RegSetValueExW(
2002 hGroupOrderListKey,
2003 lpLoadOrderGroup,
2004 0,
2005 REG_BINARY,
2006 (BYTE*)GroupOrder,
2007 bufferSize + sizeof(DWORD));
2008 if (rc != ERROR_SUCCESS)
2009 {
2010 SetLastError(rc);
2011 goto cleanup;
2012 }
2013 }
2014
2015 /* Handle AddReg and DelReg */
2016 rc = RegOpenKeyExW(
2017 list ? list->HKLM : HKEY_LOCAL_MACHINE,
2019 0,
2021 &hServicesKey);
2022 if (rc != ERROR_SUCCESS)
2023 {
2024 SetLastError(rc);
2025 goto cleanup;
2026 }
2027 rc = RegOpenKeyExW(
2030 0,
2032 &hServiceKey);
2034 if (rc != ERROR_SUCCESS)
2035 {
2036 SetLastError(rc);
2037 goto cleanup;
2038 }
2039
2041 NULL,
2042 hInf,
2043 ServiceSection,
2045 hServiceKey,
2046 NULL,
2047 0,
2048 NULL,
2049 NULL,
2050 NULL,
2051 NULL);
2052 RegCloseKey(hServiceKey);
2053
2054cleanup:
2055 if (hSCManager != NULL)
2057 if (hService != NULL)
2058 CloseServiceHandle(hService);
2059 if (hGroupOrderListKey != NULL)
2060 RegCloseKey(hGroupOrderListKey);
2061 if (sd != NULL)
2062 LocalFree(sd);
2063 MyFree(ServiceConfig);
2064 MyFree(ServiceBinary);
2065 MyFree(LoadOrderGroup);
2066 MyFree(DisplayName);
2068 MyFree(Dependencies);
2070 MyFree(GroupOrder);
2071 MyFree(StartName);
2072
2073 TRACE("Returning %d\n", ret);
2074 return ret;
2075}
2076
2077
2078/***********************************************************************
2079 * SetupInstallServicesFromInfSectionExW (SETUPAPI.@)
2080 */
2082{
2083 struct DeviceInfoSet *list = NULL;
2084 BOOL ret = FALSE;
2085
2086 TRACE("%p, %s, 0x%lx, %p, %p, %p, %p\n", hinf, debugstr_w(sectionname),
2088
2089 if (!sectionname)
2092 {
2095 }
2100 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
2102 else if (reserved1 != NULL || reserved2 != NULL)
2104 else
2105 {
2106 struct needs_callback_info needs_info;
2108 LPWSTR ServiceSection = NULL;
2109 INT ServiceFlags;
2110 INFCONTEXT ContextService;
2111 BOOL bNeedReboot = FALSE;
2112
2113 /* Parse 'Include' and 'Needs' directives */
2114 iterate_section_fields( hinf, sectionname, Include, include_callback, NULL);
2115 needs_info.type = 1;
2116 needs_info.flags = flags;
2117 needs_info.devinfo = DeviceInfoSet;
2118 needs_info.devinfo_data = DeviceInfoData;
2119 needs_info.reserved1 = reserved1;
2120 needs_info.reserved2 = reserved2;
2121 iterate_section_fields( hinf, sectionname, Needs, needs_callback, &needs_info);
2122
2124 {
2125 FIXME("Stopping the device not implemented\n");
2126 /* This may lead to require a reboot */
2127 /* bNeedReboot = TRUE; */
2128#if 0
2132 goto done;
2134 {
2136 goto done;
2137 }
2138#endif
2139 flags &= ~SPSVCINST_STOPSERVICE;
2140 }
2141
2142 if (!(ret = SetupFindFirstLineW( hinf, sectionname, NULL, &ContextService )))
2143 {
2145 goto done;
2146 }
2147
2148 ret = SetupFindFirstLineW(hinf, sectionname, AddService, &ContextService);
2149 while (ret)
2150 {
2151 if (!GetStringField(&ContextService, 1, &ServiceName))
2152 goto done;
2153
2155 &ContextService,
2156 2, /* Field index */
2157 &ServiceFlags);
2158 if (!ret)
2159 {
2160 /* The field may be empty. Ignore the error */
2161 ServiceFlags = 0;
2162 }
2163
2164 if (!GetStringField(&ContextService, 3, &ServiceSection))
2165 goto done;
2166
2167 ret = InstallOneService(list, hinf, ServiceSection, ServiceName, (ServiceFlags & ~SPSVCINST_ASSOCSERVICE) | flags);
2168 if (!ret)
2169 goto done;
2170
2171 if (ServiceFlags & SPSVCINST_ASSOCSERVICE)
2172 {
2174 if (!ret)
2175 goto done;
2176 }
2177
2179 HeapFree(GetProcessHeap(), 0, ServiceSection);
2180 ServiceName = ServiceSection = NULL;
2181 ret = SetupFindNextMatchLineW(&ContextService, AddService, &ContextService);
2182 }
2183
2184 if (bNeedReboot)
2186 else
2188 ret = TRUE;
2189 }
2190done:
2191 TRACE("Returning %d\n", ret);
2192 return ret;
2193}
2194
2195
2196/***********************************************************************
2197 * SetupCopyOEMInfA (SETUPAPI.@)
2198 */
2200 IN PCSTR SourceInfFileName,
2201 IN PCSTR OEMSourceMediaLocation,
2202 IN DWORD OEMSourceMediaType,
2203 IN DWORD CopyStyle,
2204 OUT PSTR DestinationInfFileName OPTIONAL,
2205 IN DWORD DestinationInfFileNameSize,
2207 OUT PSTR* DestinationInfFileNameComponent OPTIONAL)
2208{
2209 PWSTR SourceInfFileNameW = NULL;
2210 PWSTR OEMSourceMediaLocationW = NULL;
2211 PWSTR DestinationInfFileNameW = NULL;
2212 PWSTR DestinationInfFileNameComponentW = NULL;
2213 BOOL ret = FALSE;
2214 DWORD size;
2215
2216 TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2217 SourceInfFileName, OEMSourceMediaLocation, OEMSourceMediaType,
2218 CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2219 RequiredSize, DestinationInfFileNameComponent);
2220
2221 if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2223 else if (!(SourceInfFileNameW = pSetupMultiByteToUnicode(SourceInfFileName, CP_ACP)))
2225 else if (OEMSourceMediaType != SPOST_NONE && !(OEMSourceMediaLocationW = pSetupMultiByteToUnicode(OEMSourceMediaLocation, CP_ACP)))
2227 else
2228 {
2229 if (DestinationInfFileNameSize != 0)
2230 {
2231 DestinationInfFileNameW = MyMalloc(DestinationInfFileNameSize * sizeof(WCHAR));
2232 if (!DestinationInfFileNameW)
2233 {
2235 goto cleanup;
2236 }
2237 }
2238
2240 SourceInfFileNameW,
2241 OEMSourceMediaLocationW,
2242 OEMSourceMediaType,
2243 CopyStyle,
2244 DestinationInfFileNameW,
2245 DestinationInfFileNameSize,
2246 &size,
2247 DestinationInfFileNameComponent ? &DestinationInfFileNameComponentW : NULL);
2248 if (!ret)
2249 {
2251 goto cleanup;
2252 }
2253
2254 if (DestinationInfFileNameSize != 0)
2255 {
2256 if (WideCharToMultiByte(CP_ACP, 0, DestinationInfFileNameW, -1,
2257 DestinationInfFileName, DestinationInfFileNameSize, NULL, NULL) == 0)
2258 {
2259 DestinationInfFileName[0] = '\0';
2260 goto cleanup;
2261 }
2262 }
2263 if (DestinationInfFileNameComponent)
2264 {
2265 if (DestinationInfFileNameComponentW)
2266 *DestinationInfFileNameComponent = &DestinationInfFileName[DestinationInfFileNameComponentW - DestinationInfFileNameW];
2267 else
2268 *DestinationInfFileNameComponent = NULL;
2269 }
2270 ret = TRUE;
2271 }
2272
2273cleanup:
2274 MyFree(SourceInfFileNameW);
2275 MyFree(OEMSourceMediaLocationW);
2276 MyFree(DestinationInfFileNameW);
2277 TRACE("Returning %d\n", ret);
2279 return ret;
2280}
2281
2282static int compare_files( HANDLE file1, HANDLE file2 )
2283{
2284 char buffer1[2048];
2285 char buffer2[2048];
2286 DWORD size1;
2287 DWORD size2;
2288
2289 while( ReadFile(file1, buffer1, sizeof(buffer1), &size1, NULL) &&
2290 ReadFile(file2, buffer2, sizeof(buffer2), &size2, NULL) )
2291 {
2292 int ret;
2293 if (size1 != size2)
2294 return size1 > size2 ? 1 : -1;
2295 if (!size1)
2296 return 0;
2297 ret = memcmp( buffer1, buffer2, size1 );
2298 if (ret)
2299 return ret;
2300 }
2301
2302 return 0;
2303}
2304
2305/***********************************************************************
2306 * SetupCopyOEMInfW (SETUPAPI.@)
2307 */
2309 IN PCWSTR SourceInfFileName,
2310 IN PCWSTR OEMSourceMediaLocation,
2311 IN DWORD OEMSourceMediaType,
2312 IN DWORD CopyStyle,
2313 OUT PWSTR DestinationInfFileName OPTIONAL,
2314 IN DWORD DestinationInfFileNameSize,
2316 OUT PWSTR* DestinationInfFileNameComponent OPTIONAL)
2317{
2318 BOOL ret = FALSE;
2319
2320 TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2321 debugstr_w(SourceInfFileName), debugstr_w(OEMSourceMediaLocation), OEMSourceMediaType,
2322 CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2323 RequiredSize, DestinationInfFileNameComponent);
2324
2325 if (!SourceInfFileName)
2327 else if (OEMSourceMediaType != SPOST_NONE && OEMSourceMediaType != SPOST_PATH && OEMSourceMediaType != SPOST_URL)
2330 {
2331 TRACE("Unknown flags: 0x%08lx\n", CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY));
2333 }
2334 else if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2336 else if (CopyStyle & SP_COPY_OEMINF_CATALOG_ONLY)
2337 {
2338 FIXME("CopyStyle 0x%x not supported\n", SP_COPY_OEMINF_CATALOG_ONLY);
2340 }
2341 else
2342 {
2343 HANDLE hSearch = INVALID_HANDLE_VALUE;
2344 WIN32_FIND_DATAW FindFileData;
2345 BOOL AlreadyExists;
2346 DWORD NextFreeNumber = 0;
2347 SIZE_T len;
2348 LPWSTR pFullFileName = NULL;
2349 LPWSTR pFileName; /* Pointer into pFullFileName buffer */
2350 HANDLE hSourceFile = INVALID_HANDLE_VALUE;
2351
2352 if (OEMSourceMediaType == SPOST_PATH || OEMSourceMediaType == SPOST_URL)
2353 FIXME("OEMSourceMediaType 0x%lx ignored\n", OEMSourceMediaType);
2354
2355 /* Check if source file exists, and open it */
2356 if (strchrW(SourceInfFileName, '\\' ) || strchrW(SourceInfFileName, '/' ))
2357 {
2358 WCHAR *path;
2359
2360 if (!(len = GetFullPathNameW(SourceInfFileName, 0, NULL, NULL)))
2361 return FALSE;
2362 if (!(path = MyMalloc(len * sizeof(WCHAR))))
2363 {
2365 return FALSE;
2366 }
2367 GetFullPathNameW(SourceInfFileName, len, path, NULL);
2368 hSourceFile = CreateFileW(
2371 NULL, OPEN_EXISTING, 0, NULL);
2372 MyFree(path);
2373 }
2374 else /* try Windows directory */
2375 {
2376 WCHAR *path, *p;
2377 static const WCHAR Inf[] = {'\\','i','n','f','\\',0};
2378 static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
2379
2380 len = GetWindowsDirectoryW(NULL, 0) + strlenW(SourceInfFileName) + 12;
2381 if (!(path = MyMalloc(len * sizeof(WCHAR))))
2382 {
2384 return FALSE;
2385 }
2387 p = path + strlenW(path);
2388 strcpyW(p, Inf);
2389 strcatW(p, SourceInfFileName);
2390 hSourceFile = CreateFileW(
2393 NULL, OPEN_EXISTING, 0, NULL);
2394 if (hSourceFile == INVALID_HANDLE_VALUE)
2395 {
2396 strcpyW(p, System32);
2397 strcatW(p, SourceInfFileName);
2398 hSourceFile = CreateFileW(
2401 NULL, OPEN_EXISTING, 0, NULL);
2402 }
2403 MyFree(path);
2404 }
2405 if (hSourceFile == INVALID_HANDLE_VALUE)
2406 {
2408 goto cleanup;
2409 }
2410
2411 /* Prepare .inf file specification */
2412 len = MAX_PATH + 1 + strlenW(InfDirectory) + 13;
2413 pFullFileName = MyMalloc(len * sizeof(WCHAR));
2414 if (!pFullFileName)
2415 {
2417 goto cleanup;
2418 }
2419 len = GetSystemWindowsDirectoryW(pFullFileName, MAX_PATH);
2420 if (len == 0 || len > MAX_PATH)
2421 goto cleanup;
2422 if (pFullFileName[strlenW(pFullFileName) - 1] != '\\')
2423 strcatW(pFullFileName, BackSlash);
2424 strcatW(pFullFileName, InfDirectory);
2425 pFileName = &pFullFileName[strlenW(pFullFileName)];
2426
2427 /* Search if the specified .inf file already exists in %WINDIR%\Inf */
2428 AlreadyExists = FALSE;
2429 strcpyW(pFileName, OemFileMask);
2430 hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2431 if (hSearch != INVALID_HANDLE_VALUE)
2432 {
2433 LARGE_INTEGER SourceFileSize;
2434
2435 if (GetFileSizeEx(hSourceFile, &SourceFileSize))
2436 {
2437 do
2438 {
2439 LARGE_INTEGER DestFileSize;
2440 HANDLE hDestFile;
2441
2442 strcpyW(pFileName, FindFileData.cFileName);
2443 hDestFile = CreateFileW(
2444 pFullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
2446 NULL, OPEN_EXISTING, 0, NULL);
2447 if (hDestFile != INVALID_HANDLE_VALUE)
2448 {
2449 if (GetFileSizeEx(hDestFile, &DestFileSize)
2450 && DestFileSize.QuadPart == SourceFileSize.QuadPart
2451 && !compare_files(hSourceFile, hDestFile))
2452 {
2453 TRACE("%s already exists as %s\n",
2454 debugstr_w(SourceInfFileName), debugstr_w(pFileName));
2455 AlreadyExists = TRUE;
2456 }
2457 }
2458 } while (!AlreadyExists && FindNextFileW(hSearch, &FindFileData));
2459 }
2460 FindClose(hSearch);
2461 hSearch = INVALID_HANDLE_VALUE;
2462 }
2463
2464 if (!AlreadyExists && CopyStyle & SP_COPY_REPLACEONLY)
2465 {
2466 /* FIXME: set DestinationInfFileName, RequiredSize, DestinationInfFileNameComponent */
2468 goto cleanup;
2469 }
2470 else if (AlreadyExists && (CopyStyle & SP_COPY_NOOVERWRITE))
2471 {
2472 DWORD Size = strlenW(pFileName) + 1;
2473
2474 if (RequiredSize)
2475 *RequiredSize = Size;
2476 if (DestinationInfFileNameSize == 0)
2478 else if (DestinationInfFileNameSize < Size)
2480 else
2481 {
2483 strcpyW(DestinationInfFileName, pFileName);
2484 }
2485 goto cleanup;
2486 }
2487
2488 /* Search the number to give to OEM??.INF */
2489 strcpyW(pFileName, OemFileMask);
2490 hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2491 if (hSearch == INVALID_HANDLE_VALUE)
2492 {
2494 goto cleanup;
2495 }
2496 else
2497 {
2498 do
2499 {
2500 DWORD CurrentNumber;
2501 if (swscanf(FindFileData.cFileName, OemFileSpecification, &CurrentNumber) == 1
2502 && CurrentNumber <= 99999)
2503 {
2504 if (CurrentNumber >= NextFreeNumber)
2505 NextFreeNumber = CurrentNumber + 1;
2506 }
2507 } while (FindNextFileW(hSearch, &FindFileData));
2508 }
2509
2510 if (NextFreeNumber > 99999)
2511 {
2512 ERR("Too much custom .inf files\n");
2514 goto cleanup;
2515 }
2516
2517 /* Create the full path: %WINDIR%\Inf\OEM{XXXXX}.inf */
2518 sprintfW(pFileName, OemFileSpecification, NextFreeNumber);
2519 TRACE("Next available file is %s\n", debugstr_w(pFileName));
2520
2521 if (!CopyFileW(SourceInfFileName, pFullFileName, TRUE))
2522 {
2523 TRACE("CopyFileW() failed with error 0x%lx\n", GetLastError());
2524 goto cleanup;
2525 }
2526
2527 len = strlenW(pFullFileName) + 1;
2528 if (RequiredSize)
2529 *RequiredSize = len;
2530 if (DestinationInfFileName)
2531 {
2532 if (DestinationInfFileNameSize >= len)
2533 {
2534 strcpyW(DestinationInfFileName, pFullFileName);
2535 if (DestinationInfFileNameComponent)
2536 *DestinationInfFileNameComponent = &DestinationInfFileName[pFileName - pFullFileName];
2537 }
2538 else
2539 {
2541 goto cleanup;
2542 }
2543 }
2544
2545 if (CopyStyle & SP_COPY_DELETESOURCE)
2546 {
2547 if (!DeleteFileW(SourceInfFileName))
2548 {
2549 TRACE("DeleteFileW() failed with error 0x%lx\n", GetLastError());
2550 goto cleanup;
2551 }
2552 }
2553
2554 ret = TRUE;
2555
2556cleanup:
2557 if (hSourceFile != INVALID_HANDLE_VALUE)
2558 CloseHandle(hSourceFile);
2559 if (hSearch != INVALID_HANDLE_VALUE)
2560 FindClose(hSearch);
2561 MyFree(pFullFileName);
2562 }
2563
2564 TRACE("Returning %d\n", ret);
2566 return ret;
2567}
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:4598
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:891
static BOOL copy_inf_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1162
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:1259
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:839
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:1615
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:1330
static BOOL GetIntField(HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
Definition: install.c:1679
static const WCHAR GroupOrderListKey[]
Definition: install.c:29
void WINAPI InstallHinfSectionW(HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show)
Definition: install.c:1468
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:1210
BOOL WINAPI SetupInstallServicesFromInfSectionExA(HINF hinf, PCSTR sectionname, DWORD flags, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data, PVOID reserved1, PVOID reserved2)
Definition: install.c:1633
static BOOL needs_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1307
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:827
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:766
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:2199
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:2308
static const WCHAR Include[]
Definition: install.c:121
BOOL GetStringField(PINFCONTEXT context, DWORD index, PWSTR *value)
Definition: install.c:1703
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:2282
static VOID FixupServiceBinaryPath(IN DWORD ServiceType, IN OUT LPWSTR *ServiceBinary)
Definition: install.c:1738
static BOOL include_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:1296
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:1243
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:666
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:1650
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:1780
BOOL WINAPI SetupInstallServicesFromInfSectionA(HINF Inf, PCSTR SectionName, DWORD Flags)
Definition: install.c:1624
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:821
void WINAPI InstallHinfSectionA(HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show)
Definition: install.c:1601
static const WCHAR BitReg[]
Definition: install.c:114
static BOOL bitreg_callback(HINF hinf, PCWSTR field, void *arg)
Definition: install.c:833
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:815
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:2081
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
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:43
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:36
#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
_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:2195
#define CSIDL_PROGRAMS
Definition: shlobj.h:2175
#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: format.c:58
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:370
#define MoveMemory
Definition: winbase.h:1734
_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:790
#define EWX_REBOOT
Definition: winuser.h:638
#define MB_OK
Definition: winuser.h:793
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:1665
#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