ReactOS 0.4.16-dev-852-gcfcc8d8
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 */
1615BOOL
1616WINAPI
1618 _In_ HINF InfHandle,
1619 _In_ PCWSTR SectionName,
1621{
1623 SectionName,
1624 Flags,
1626 NULL,
1627 NULL,
1628 NULL);
1629}
1630
1631/***********************************************************************
1632 * SetupInstallServicesFromInfSectionA (SETUPAPI.@)
1633 */
1634BOOL
1635WINAPI
1637 _In_ HINF InfHandle,
1638 _In_ PCSTR SectionName,
1640{
1642 SectionName,
1643 Flags,
1645 NULL,
1646 NULL,
1647 NULL);
1648}
1649
1650/***********************************************************************
1651 * SetupInstallServicesFromInfSectionExA (SETUPAPI.@)
1652 */
1653BOOL
1654WINAPI
1656 _In_ HINF InfHandle,
1657 _In_ PCSTR SectionName,
1663{
1664 UNICODE_STRING SectionNameW;
1665 BOOL ret;
1666
1667 if (!RtlCreateUnicodeStringFromAsciiz(&SectionNameW, SectionName))
1668 {
1670 return FALSE;
1671 }
1672
1674 SectionNameW.Buffer,
1675 Flags,
1678 Reserved1,
1679 Reserved2);
1680 RtlFreeUnicodeString(&SectionNameW);
1681 return ret;
1682}
1683
1684
1685static BOOL GetLineText( HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
1686{
1687 DWORD required;
1688 PWSTR buf = NULL;
1689
1690 *value = NULL;
1691
1692 if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, NULL, 0, &required )
1694 return FALSE;
1695
1696 buf = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) );
1697 if ( ! buf )
1698 {
1700 return FALSE;
1701 }
1702
1703 if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, buf, required, &required ) )
1704 {
1705 HeapFree( GetProcessHeap(), 0, buf );
1706 return FALSE;
1707 }
1708
1709 *value = buf;
1710 return TRUE;
1711}
1712
1713
1714static BOOL GetIntField( HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
1715{
1716 LPWSTR buffer, end;
1717 INT res;
1718
1719 if (! GetLineText( hinf, section_name, key_name, &buffer ) )
1720 return FALSE;
1721
1722 res = wcstol( buffer, &end, 0 );
1723 if (end != buffer && !*end)
1724 {
1726 *value = res;
1727 return TRUE;
1728 }
1729 else
1730 {
1733 return FALSE;
1734 }
1735}
1736
1737
1739{
1741 BOOL ret;
1742
1744 context,
1745 index,
1746 NULL, 0,
1747 &RequiredSize);
1748 if (!ret)
1749 return FALSE;
1750 else if (RequiredSize == 0)
1751 {
1752 *value = NULL;
1753 return TRUE;
1754 }
1755
1756 /* We got the needed size for the buffer */
1757 *value = MyMalloc(RequiredSize * sizeof(WCHAR));
1758 if (!*value)
1759 {
1761 return FALSE;
1762 }
1764 context,
1765 index,
1767 if (!ret)
1768 MyFree(*value);
1769
1770 return ret;
1771}
1772
1774 IN DWORD ServiceType,
1775 IN OUT LPWSTR *ServiceBinary)
1776{
1777 LPWSTR Buffer;
1778 WCHAR ReactOSDir[MAX_PATH];
1779 DWORD RosDirLength, ServiceLength, Win32Length;
1780
1781 GetWindowsDirectoryW(ReactOSDir, MAX_PATH);
1782 RosDirLength = strlenW(ReactOSDir);
1783 ServiceLength = strlenW(*ServiceBinary);
1784
1785 /* Check and fix two things:
1786 1. Get rid of C:\ReactOS and use relative
1787 path instead.
1788 2. Add %SystemRoot% for Win32 services */
1789
1790 if (ServiceLength < RosDirLength)
1791 return;
1792
1793 if (!wcsnicmp(*ServiceBinary, ReactOSDir, RosDirLength))
1794 {
1795 /* Yes, the first part is the C:\ReactOS\, just skip it */
1796 MoveMemory(*ServiceBinary, *ServiceBinary + RosDirLength + 1,
1797 (ServiceLength - RosDirLength) * sizeof(WCHAR));
1798
1799 /* Handle Win32-services differently */
1800 if (ServiceType & SERVICE_WIN32)
1801 {
1802 Win32Length = (ServiceLength - RosDirLength) * sizeof(WCHAR)
1803 - sizeof(L'\\') + sizeof(L"%SystemRoot%\\");
1804 Buffer = MyMalloc(Win32Length);
1805
1806 wcscpy(Buffer, L"%SystemRoot%\\");
1807 wcscat(Buffer, *ServiceBinary);
1808 MyFree(*ServiceBinary);
1809
1810 *ServiceBinary = Buffer;
1811 }
1812 }
1813}
1814
1816 struct DeviceInfoSet *list,
1817 IN HINF hInf,
1818 IN LPCWSTR ServiceSection,
1820 IN UINT ServiceFlags)
1821{
1822 SC_HANDLE hSCManager = NULL;
1823 SC_HANDLE hService = NULL;
1824 LPDWORD GroupOrder = NULL;
1825 LPQUERY_SERVICE_CONFIGW ServiceConfig = NULL;
1826 HKEY hServicesKey, hServiceKey;
1827 LONG rc;
1828 BOOL ret = FALSE;
1829
1830 HKEY hGroupOrderListKey = NULL;
1831 LPWSTR ServiceBinary = NULL;
1832 LPWSTR LoadOrderGroup = NULL;
1833 LPWSTR DisplayName = NULL;
1835 LPWSTR Dependencies = NULL;
1836 LPWSTR StartName = NULL;
1839 INT ServiceType, StartType, ErrorControl;
1840 DWORD dwRegType;
1841 DWORD tagId = (DWORD)-1;
1842 BOOL useTag;
1843
1844 if (!GetIntField(hInf, ServiceSection, ServiceTypeKey, &ServiceType))
1845 {
1847 goto cleanup;
1848 }
1849 if (!GetIntField(hInf, ServiceSection, StartTypeKey, &StartType))
1850 {
1852 goto cleanup;
1853 }
1854 if (!GetIntField(hInf, ServiceSection, ErrorControlKey, &ErrorControl))
1855 {
1857 goto cleanup;
1858 }
1859 useTag = (ServiceType == SERVICE_BOOT_START || ServiceType == SERVICE_SYSTEM_START);
1860
1862 if (hSCManager == NULL)
1863 goto cleanup;
1864
1865 if (!GetLineText(hInf, ServiceSection, ServiceBinaryKey, &ServiceBinary))
1866 {
1868 goto cleanup;
1869 }
1870
1871 /* Adjust binary path according to the service type */
1872 FixupServiceBinaryPath(ServiceType, &ServiceBinary);
1873
1874 /* Don't check return value, as these fields are optional and
1875 * GetLineText initialize output parameter even on failure */
1876 GetLineText(hInf, ServiceSection, LoadOrderGroupKey, &LoadOrderGroup);
1877 GetLineText(hInf, ServiceSection, DisplayNameKey, &DisplayName);
1878 GetLineText(hInf, ServiceSection, DescriptionKey, &Description);
1879 GetLineText(hInf, ServiceSection, DependenciesKey, &Dependencies);
1880 GetLineText(hInf, ServiceSection, StartNameKey, &StartName);
1881
1882 /* If there is no group, we must not request a tag */
1883 if (!LoadOrderGroup || !*LoadOrderGroup)
1884 useTag = FALSE;
1885
1886 hService = OpenServiceW(
1887 hSCManager,
1890 if (hService == NULL && GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
1891 goto cleanup;
1892
1893 if (hService && (ServiceFlags & SPSVCINST_DELETEEVENTLOGENTRY))
1894 {
1895 ret = DeleteService(hService);
1897 goto cleanup;
1898 }
1899
1900 if (hService == NULL)
1901 {
1902 /* Create new service */
1903 hService = CreateServiceW(
1904 hSCManager,
1906 DisplayName,
1907 WRITE_DAC,
1908 ServiceType,
1909 StartType,
1910 ErrorControl,
1911 ServiceBinary,
1912 LoadOrderGroup,
1913 useTag ? &tagId : NULL,
1914 Dependencies,
1915 StartName,
1916 NULL);
1917 if (hService == NULL)
1918 goto cleanup;
1919 }
1920 else
1921 {
1923 /* Read current configuration */
1924 if (!QueryServiceConfigW(hService, NULL, 0, &bufferSize))
1925 {
1927 goto cleanup;
1928 ServiceConfig = MyMalloc(bufferSize);
1929 if (!ServiceConfig)
1930 {
1932 goto cleanup;
1933 }
1934 if (!QueryServiceConfigW(hService, ServiceConfig, bufferSize, &bufferSize))
1935 goto cleanup;
1936 }
1937 tagId = ServiceConfig->dwTagId;
1938
1939 /* Update configuration */
1941 hService,
1942 ServiceType,
1943 (ServiceFlags & SPSVCINST_NOCLOBBER_STARTTYPE) ? SERVICE_NO_CHANGE : StartType,
1944 (ServiceFlags & SPSVCINST_NOCLOBBER_ERRORCONTROL) ? SERVICE_NO_CHANGE : ErrorControl,
1945 ServiceBinary,
1946 (ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP && ServiceConfig->lpLoadOrderGroup) ? NULL : LoadOrderGroup,
1947 useTag ? &tagId : NULL,
1948 (ServiceFlags & SPSVCINST_NOCLOBBER_DEPENDENCIES && ServiceConfig->lpDependencies) ? NULL : Dependencies,
1949 StartName,
1950 NULL,
1951 (ServiceFlags & SPSVCINST_NOCLOBBER_DISPLAYNAME && ServiceConfig->lpDisplayName) ? NULL : DisplayName);
1952 if (!ret)
1953 goto cleanup;
1954 }
1955
1956 /* Set security */
1957 if (GetLineText(hInf, ServiceSection, SecurityKey, &SecurityDescriptor))
1958 {
1960 if (!ret)
1961 goto cleanup;
1963 if (!ret)
1964 goto cleanup;
1965 }
1966
1967 /* FIXME: use Description and SPSVCINST_NOCLOBBER_DESCRIPTION */
1968
1969 if (useTag)
1970 {
1971 /* Add the tag to SYSTEM\CurrentControlSet\Control\GroupOrderList key */
1972 LPCWSTR lpLoadOrderGroup;
1974
1975 lpLoadOrderGroup = LoadOrderGroup;
1976 if ((ServiceFlags & SPSVCINST_NOCLOBBER_LOADORDERGROUP) && ServiceConfig && ServiceConfig->lpLoadOrderGroup)
1977 lpLoadOrderGroup = ServiceConfig->lpLoadOrderGroup;
1978
1979 rc = RegOpenKeyW(
1980 list ? list->HKLM : HKEY_LOCAL_MACHINE,
1982 &hGroupOrderListKey);
1983 if (rc != ERROR_SUCCESS)
1984 {
1985 SetLastError(rc);
1986 goto cleanup;
1987 }
1988 rc = RegQueryValueExW(hGroupOrderListKey, lpLoadOrderGroup, NULL, &dwRegType, NULL, &bufferSize);
1989 if (rc == ERROR_FILE_NOT_FOUND)
1990 bufferSize = sizeof(DWORD);
1991 else if (rc != ERROR_SUCCESS)
1992 {
1993 SetLastError(rc);
1994 goto cleanup;
1995 }
1996 else if (dwRegType != REG_BINARY || bufferSize == 0 || bufferSize % sizeof(DWORD) != 0)
1997 {
1999 goto cleanup;
2000 }
2001 /* Allocate buffer to store existing data + the new tag */
2002 GroupOrder = MyMalloc(bufferSize + sizeof(DWORD));
2003 if (!GroupOrder)
2004 {
2006 goto cleanup;
2007 }
2008 if (rc == ERROR_SUCCESS)
2009 {
2010 /* Read existing data */
2011 rc = RegQueryValueExW(
2012 hGroupOrderListKey,
2013 lpLoadOrderGroup,
2014 NULL,
2015 NULL,
2016 (BYTE*)GroupOrder,
2017 &bufferSize);
2018 if (rc != ERROR_SUCCESS)
2019 {
2020 SetLastError(rc);
2021 goto cleanup;
2022 }
2023 if (ServiceFlags & SPSVCINST_TAGTOFRONT)
2024 memmove(&GroupOrder[2], &GroupOrder[1], bufferSize - sizeof(DWORD));
2025 }
2026 else
2027 {
2028 GroupOrder[0] = 0;
2029 }
2030 GroupOrder[0]++;
2031 if (ServiceFlags & SPSVCINST_TAGTOFRONT)
2032 GroupOrder[1] = tagId;
2033 else
2034 GroupOrder[bufferSize / sizeof(DWORD)] = tagId;
2035
2036 rc = RegSetValueExW(
2037 hGroupOrderListKey,
2038 lpLoadOrderGroup,
2039 0,
2040 REG_BINARY,
2041 (BYTE*)GroupOrder,
2042 bufferSize + sizeof(DWORD));
2043 if (rc != ERROR_SUCCESS)
2044 {
2045 SetLastError(rc);
2046 goto cleanup;
2047 }
2048 }
2049
2050 /* Handle AddReg and DelReg */
2051 rc = RegOpenKeyExW(
2052 list ? list->HKLM : HKEY_LOCAL_MACHINE,
2054 0,
2056 &hServicesKey);
2057 if (rc != ERROR_SUCCESS)
2058 {
2059 SetLastError(rc);
2060 goto cleanup;
2061 }
2062 rc = RegOpenKeyExW(
2065 0,
2067 &hServiceKey);
2069 if (rc != ERROR_SUCCESS)
2070 {
2071 SetLastError(rc);
2072 goto cleanup;
2073 }
2074
2076 NULL,
2077 hInf,
2078 ServiceSection,
2080 hServiceKey,
2081 NULL,
2082 0,
2083 NULL,
2084 NULL,
2085 NULL,
2086 NULL);
2087 RegCloseKey(hServiceKey);
2088
2089cleanup:
2090 if (hSCManager != NULL)
2092 if (hService != NULL)
2093 CloseServiceHandle(hService);
2094 if (hGroupOrderListKey != NULL)
2095 RegCloseKey(hGroupOrderListKey);
2096 if (sd != NULL)
2097 LocalFree(sd);
2098 MyFree(ServiceConfig);
2099 MyFree(ServiceBinary);
2100 MyFree(LoadOrderGroup);
2101 MyFree(DisplayName);
2103 MyFree(Dependencies);
2105 MyFree(GroupOrder);
2106 MyFree(StartName);
2107
2108 TRACE("Returning %d\n", ret);
2109 return ret;
2110}
2111
2112
2113/***********************************************************************
2114 * SetupInstallServicesFromInfSectionExW (SETUPAPI.@)
2115 */
2116BOOL
2117WINAPI
2119 _In_ HINF InfHandle,
2120 _In_ PCWSTR SectionName,
2126{
2127 struct DeviceInfoSet *list;
2128 BOOL ret = FALSE;
2129
2130 /* FIXME: SPSVCINST_ASSOCSERVICE is not fully supported */
2131 static const DWORD SupportedFlags =
2136
2137 TRACE("%p, %s, 0x%lx, %p, %p, %p, %p\n",
2138 InfHandle,
2139 debugstr_w(SectionName),
2140 Flags,
2143 Reserved1,
2144 Reserved2);
2145
2147 {
2148 list = NULL;
2149 } else
2150 {
2151 list = (struct DeviceInfoSet*)DeviceInfoSet;
2152 }
2153
2154 if (Flags & ~(SupportedFlags))
2155 {
2156 TRACE("Unknown flags: 0x%08lx\n", Flags & ~(SupportedFlags));
2158 }
2159 else if (!SectionName || Reserved1 || Reserved2)
2160 {
2162 }
2163 else if (list && list->magic != SETUP_DEVICE_INFO_SET_MAGIC)
2164 {
2166 }
2167 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
2168 {
2170 }
2171 else
2172 {
2173 struct needs_callback_info needs_info;
2175 LPWSTR ServiceSection = NULL;
2176 INT ServiceFlags;
2177 INFCONTEXT ContextService;
2178 BOOL bNeedReboot = FALSE;
2179
2180 /* Parse 'Include' and 'Needs' directives */
2181 iterate_section_fields(InfHandle, SectionName, Include, include_callback, NULL);
2182 needs_info.type = 1;
2183 needs_info.flags = Flags;
2184 needs_info.devinfo = DeviceInfoSet;
2185 needs_info.devinfo_data = DeviceInfoData;
2186 needs_info.reserved1 = Reserved1;
2187 needs_info.reserved2 = Reserved2;
2188 iterate_section_fields(InfHandle, SectionName, Needs, needs_callback, &needs_info);
2189
2191 {
2192 FIXME("Stopping the device not implemented\n");
2193 /* This may lead to require a reboot */
2194 /* bNeedReboot = TRUE; */
2195#if 0
2199 goto done;
2201 {
2203 goto done;
2204 }
2205#endif
2206 Flags &= ~SPSVCINST_STOPSERVICE;
2207 }
2208
2209 if (!(ret = SetupFindFirstLineW(InfHandle, SectionName, NULL, &ContextService)))
2210 {
2212 goto done;
2213 }
2214
2215 ret = SetupFindFirstLineW(InfHandle, SectionName, AddService, &ContextService);
2216 while (ret)
2217 {
2218 if (!GetStringField(&ContextService, 1, &ServiceName))
2219 goto done;
2220
2222 &ContextService,
2223 2, /* Field index */
2224 &ServiceFlags);
2225 if (!ret)
2226 {
2227 /* The field may be empty. Ignore the error */
2228 ServiceFlags = 0;
2229 }
2230
2231 if (!GetStringField(&ContextService, 3, &ServiceSection))
2232 goto done;
2233
2234 ret = InstallOneService(list, InfHandle, ServiceSection, ServiceName, (ServiceFlags & ~SPSVCINST_ASSOCSERVICE) | Flags);
2235 if (!ret)
2236 goto done;
2237
2238 if (list && (ServiceFlags & SPSVCINST_ASSOCSERVICE))
2239 {
2241 if (!ret)
2242 goto done;
2243 }
2244
2246 HeapFree(GetProcessHeap(), 0, ServiceSection);
2247 ServiceName = ServiceSection = NULL;
2248 ret = SetupFindNextMatchLineW(&ContextService, AddService, &ContextService);
2249 }
2250
2251 if (bNeedReboot)
2253 else
2255 ret = TRUE;
2256 }
2257done:
2258 TRACE("Returning %d\n", ret);
2259 return ret;
2260}
2261
2262
2263/***********************************************************************
2264 * SetupCopyOEMInfA (SETUPAPI.@)
2265 */
2267 IN PCSTR SourceInfFileName,
2268 IN PCSTR OEMSourceMediaLocation,
2269 IN DWORD OEMSourceMediaType,
2270 IN DWORD CopyStyle,
2271 OUT PSTR DestinationInfFileName OPTIONAL,
2272 IN DWORD DestinationInfFileNameSize,
2274 OUT PSTR* DestinationInfFileNameComponent OPTIONAL)
2275{
2276 PWSTR SourceInfFileNameW = NULL;
2277 PWSTR OEMSourceMediaLocationW = NULL;
2278 PWSTR DestinationInfFileNameW = NULL;
2279 PWSTR DestinationInfFileNameComponentW = NULL;
2280 BOOL ret = FALSE;
2281 DWORD size;
2282
2283 TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2284 SourceInfFileName, OEMSourceMediaLocation, OEMSourceMediaType,
2285 CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2286 RequiredSize, DestinationInfFileNameComponent);
2287
2288 if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2290 else if (!(SourceInfFileNameW = pSetupMultiByteToUnicode(SourceInfFileName, CP_ACP)))
2292 else if (OEMSourceMediaType != SPOST_NONE && !(OEMSourceMediaLocationW = pSetupMultiByteToUnicode(OEMSourceMediaLocation, CP_ACP)))
2294 else
2295 {
2296 if (DestinationInfFileNameSize != 0)
2297 {
2298 DestinationInfFileNameW = MyMalloc(DestinationInfFileNameSize * sizeof(WCHAR));
2299 if (!DestinationInfFileNameW)
2300 {
2302 goto cleanup;
2303 }
2304 }
2305
2307 SourceInfFileNameW,
2308 OEMSourceMediaLocationW,
2309 OEMSourceMediaType,
2310 CopyStyle,
2311 DestinationInfFileNameW,
2312 DestinationInfFileNameSize,
2313 &size,
2314 DestinationInfFileNameComponent ? &DestinationInfFileNameComponentW : NULL);
2315 if (!ret)
2316 {
2318 goto cleanup;
2319 }
2320
2321 if (DestinationInfFileNameSize != 0)
2322 {
2323 if (WideCharToMultiByte(CP_ACP, 0, DestinationInfFileNameW, -1,
2324 DestinationInfFileName, DestinationInfFileNameSize, NULL, NULL) == 0)
2325 {
2326 DestinationInfFileName[0] = '\0';
2327 goto cleanup;
2328 }
2329 }
2330 if (DestinationInfFileNameComponent)
2331 {
2332 if (DestinationInfFileNameComponentW)
2333 *DestinationInfFileNameComponent = &DestinationInfFileName[DestinationInfFileNameComponentW - DestinationInfFileNameW];
2334 else
2335 *DestinationInfFileNameComponent = NULL;
2336 }
2337 ret = TRUE;
2338 }
2339
2340cleanup:
2341 MyFree(SourceInfFileNameW);
2342 MyFree(OEMSourceMediaLocationW);
2343 MyFree(DestinationInfFileNameW);
2344 TRACE("Returning %d\n", ret);
2346 return ret;
2347}
2348
2349static int compare_files( HANDLE file1, HANDLE file2 )
2350{
2351 char buffer1[2048];
2352 char buffer2[2048];
2353 DWORD size1;
2354 DWORD size2;
2355
2356 while( ReadFile(file1, buffer1, sizeof(buffer1), &size1, NULL) &&
2357 ReadFile(file2, buffer2, sizeof(buffer2), &size2, NULL) )
2358 {
2359 int ret;
2360 if (size1 != size2)
2361 return size1 > size2 ? 1 : -1;
2362 if (!size1)
2363 return 0;
2364 ret = memcmp( buffer1, buffer2, size1 );
2365 if (ret)
2366 return ret;
2367 }
2368
2369 return 0;
2370}
2371
2372/***********************************************************************
2373 * SetupCopyOEMInfW (SETUPAPI.@)
2374 */
2376 IN PCWSTR SourceInfFileName,
2377 IN PCWSTR OEMSourceMediaLocation,
2378 IN DWORD OEMSourceMediaType,
2379 IN DWORD CopyStyle,
2380 OUT PWSTR DestinationInfFileName OPTIONAL,
2381 IN DWORD DestinationInfFileNameSize,
2383 OUT PWSTR* DestinationInfFileNameComponent OPTIONAL)
2384{
2385 BOOL ret = FALSE;
2386
2387 TRACE("%s %s 0x%lx 0x%lx %p 0%lu %p %p\n",
2388 debugstr_w(SourceInfFileName), debugstr_w(OEMSourceMediaLocation), OEMSourceMediaType,
2389 CopyStyle, DestinationInfFileName, DestinationInfFileNameSize,
2390 RequiredSize, DestinationInfFileNameComponent);
2391
2392 if (!SourceInfFileName)
2394 else if (OEMSourceMediaType != SPOST_NONE && OEMSourceMediaType != SPOST_PATH && OEMSourceMediaType != SPOST_URL)
2397 {
2398 TRACE("Unknown flags: 0x%08lx\n", CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY));
2400 }
2401 else if (!DestinationInfFileName && DestinationInfFileNameSize > 0)
2403 else if (CopyStyle & SP_COPY_OEMINF_CATALOG_ONLY)
2404 {
2405 FIXME("CopyStyle 0x%x not supported\n", SP_COPY_OEMINF_CATALOG_ONLY);
2407 }
2408 else
2409 {
2410 HANDLE hSearch = INVALID_HANDLE_VALUE;
2411 WIN32_FIND_DATAW FindFileData;
2412 BOOL AlreadyExists;
2413 DWORD NextFreeNumber = 0;
2414 SIZE_T len;
2415 LPWSTR pFullFileName = NULL;
2416 LPWSTR pFileName; /* Pointer into pFullFileName buffer */
2417 HANDLE hSourceFile = INVALID_HANDLE_VALUE;
2418
2419 if (OEMSourceMediaType == SPOST_PATH || OEMSourceMediaType == SPOST_URL)
2420 FIXME("OEMSourceMediaType 0x%lx ignored\n", OEMSourceMediaType);
2421
2422 /* Check if source file exists, and open it */
2423 if (strchrW(SourceInfFileName, '\\' ) || strchrW(SourceInfFileName, '/' ))
2424 {
2425 WCHAR *path;
2426
2427 if (!(len = GetFullPathNameW(SourceInfFileName, 0, NULL, NULL)))
2428 return FALSE;
2429 if (!(path = MyMalloc(len * sizeof(WCHAR))))
2430 {
2432 return FALSE;
2433 }
2434 GetFullPathNameW(SourceInfFileName, len, path, NULL);
2435 hSourceFile = CreateFileW(
2438 NULL, OPEN_EXISTING, 0, NULL);
2439 MyFree(path);
2440 }
2441 else /* try Windows directory */
2442 {
2443 WCHAR *path, *p;
2444 static const WCHAR Inf[] = {'\\','i','n','f','\\',0};
2445 static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
2446
2447 len = GetWindowsDirectoryW(NULL, 0) + strlenW(SourceInfFileName) + 12;
2448 if (!(path = MyMalloc(len * sizeof(WCHAR))))
2449 {
2451 return FALSE;
2452 }
2454 p = path + strlenW(path);
2455 strcpyW(p, Inf);
2456 strcatW(p, SourceInfFileName);
2457 hSourceFile = CreateFileW(
2460 NULL, OPEN_EXISTING, 0, NULL);
2461 if (hSourceFile == INVALID_HANDLE_VALUE)
2462 {
2463 strcpyW(p, System32);
2464 strcatW(p, SourceInfFileName);
2465 hSourceFile = CreateFileW(
2468 NULL, OPEN_EXISTING, 0, NULL);
2469 }
2470 MyFree(path);
2471 }
2472 if (hSourceFile == INVALID_HANDLE_VALUE)
2473 {
2475 goto cleanup;
2476 }
2477
2478 /* Prepare .inf file specification */
2479 len = MAX_PATH + 1 + strlenW(InfDirectory) + 13;
2480 pFullFileName = MyMalloc(len * sizeof(WCHAR));
2481 if (!pFullFileName)
2482 {
2484 goto cleanup;
2485 }
2486 len = GetSystemWindowsDirectoryW(pFullFileName, MAX_PATH);
2487 if (len == 0 || len > MAX_PATH)
2488 goto cleanup;
2489 if (pFullFileName[strlenW(pFullFileName) - 1] != '\\')
2490 strcatW(pFullFileName, BackSlash);
2491 strcatW(pFullFileName, InfDirectory);
2492 pFileName = &pFullFileName[strlenW(pFullFileName)];
2493
2494 /* Search if the specified .inf file already exists in %WINDIR%\Inf */
2495 AlreadyExists = FALSE;
2496 strcpyW(pFileName, OemFileMask);
2497 hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2498 if (hSearch != INVALID_HANDLE_VALUE)
2499 {
2500 LARGE_INTEGER SourceFileSize;
2501
2502 if (GetFileSizeEx(hSourceFile, &SourceFileSize))
2503 {
2504 do
2505 {
2506 LARGE_INTEGER DestFileSize;
2507 HANDLE hDestFile;
2508
2509 strcpyW(pFileName, FindFileData.cFileName);
2510 hDestFile = CreateFileW(
2511 pFullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
2513 NULL, OPEN_EXISTING, 0, NULL);
2514 if (hDestFile != INVALID_HANDLE_VALUE)
2515 {
2516 if (GetFileSizeEx(hDestFile, &DestFileSize)
2517 && DestFileSize.QuadPart == SourceFileSize.QuadPart
2518 && !compare_files(hSourceFile, hDestFile))
2519 {
2520 TRACE("%s already exists as %s\n",
2521 debugstr_w(SourceInfFileName), debugstr_w(pFileName));
2522 AlreadyExists = TRUE;
2523 }
2524 }
2525 } while (!AlreadyExists && FindNextFileW(hSearch, &FindFileData));
2526 }
2527 FindClose(hSearch);
2528 hSearch = INVALID_HANDLE_VALUE;
2529 }
2530
2531 if (!AlreadyExists && CopyStyle & SP_COPY_REPLACEONLY)
2532 {
2533 /* FIXME: set DestinationInfFileName, RequiredSize, DestinationInfFileNameComponent */
2535 goto cleanup;
2536 }
2537 else if (AlreadyExists && (CopyStyle & SP_COPY_NOOVERWRITE))
2538 {
2539 DWORD Size = strlenW(pFileName) + 1;
2540
2541 if (RequiredSize)
2542 *RequiredSize = Size;
2543 if (DestinationInfFileNameSize == 0)
2545 else if (DestinationInfFileNameSize < Size)
2547 else
2548 {
2550 strcpyW(DestinationInfFileName, pFileName);
2551 }
2552 goto cleanup;
2553 }
2554
2555 /* Search the number to give to OEM??.INF */
2556 strcpyW(pFileName, OemFileMask);
2557 hSearch = FindFirstFileW(pFullFileName, &FindFileData);
2558 if (hSearch == INVALID_HANDLE_VALUE)
2559 {
2561 goto cleanup;
2562 }
2563 else
2564 {
2565 do
2566 {
2567 DWORD CurrentNumber;
2568 if (swscanf(FindFileData.cFileName, OemFileSpecification, &CurrentNumber) == 1
2569 && CurrentNumber <= 99999)
2570 {
2571 if (CurrentNumber >= NextFreeNumber)
2572 NextFreeNumber = CurrentNumber + 1;
2573 }
2574 } while (FindNextFileW(hSearch, &FindFileData));
2575 }
2576
2577 if (NextFreeNumber > 99999)
2578 {
2579 ERR("Too much custom .inf files\n");
2581 goto cleanup;
2582 }
2583
2584 /* Create the full path: %WINDIR%\Inf\OEM{XXXXX}.inf */
2585 sprintfW(pFileName, OemFileSpecification, NextFreeNumber);
2586 TRACE("Next available file is %s\n", debugstr_w(pFileName));
2587
2588 if (!CopyFileW(SourceInfFileName, pFullFileName, TRUE))
2589 {
2590 TRACE("CopyFileW() failed with error 0x%lx\n", GetLastError());
2591 goto cleanup;
2592 }
2593
2594 len = strlenW(pFullFileName) + 1;
2595 if (RequiredSize)
2596 *RequiredSize = len;
2597 if (DestinationInfFileName)
2598 {
2599 if (DestinationInfFileNameSize >= len)
2600 {
2601 strcpyW(DestinationInfFileName, pFullFileName);
2602 if (DestinationInfFileNameComponent)
2603 *DestinationInfFileNameComponent = &DestinationInfFileName[pFileName - pFullFileName];
2604 }
2605 else
2606 {
2608 goto cleanup;
2609 }
2610 }
2611
2612 if (CopyStyle & SP_COPY_DELETESOURCE)
2613 {
2614 if (!DeleteFileW(SourceInfFileName))
2615 {
2616 TRACE("DeleteFileW() failed with error 0x%lx\n", GetLastError());
2617 goto cleanup;
2618 }
2619 }
2620
2621 ret = TRUE;
2622
2623cleanup:
2624 if (hSourceFile != INVALID_HANDLE_VALUE)
2625 CloseHandle(hSourceFile);
2626 if (hSearch != INVALID_HANDLE_VALUE)
2627 FindClose(hSearch);
2628 MyFree(pFullFileName);
2629 }
2630
2631 TRACE("Returning %d\n", ret);
2633 return ret;
2634}
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
@ Reserved2
Definition: bcd.h:202
@ Reserved1
Definition: bcd.h:201
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: bufpool.h:45
Definition: list.h:37
Definition: _queue.h:67
wcscat
wcscpy
#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
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
BOOL WINAPI SetupInstallServicesFromInfSectionExA(_In_ HINF InfHandle, _In_ PCSTR SectionName, _In_ DWORD Flags, _In_opt_ HDEVINFO DeviceInfoSet, _In_opt_ PSP_DEVINFO_DATA DeviceInfoData, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2)
Definition: install.c:1655
BOOL WINAPI SetupInstallServicesFromInfSectionA(_In_ HINF InfHandle, _In_ PCSTR SectionName, _In_ DWORD Flags)
Definition: install.c:1636
static BOOL GetIntField(HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
Definition: install.c:1714
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
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:2266
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:2375
static const WCHAR Include[]
Definition: install.c:121
BOOL GetStringField(PINFCONTEXT context, DWORD index, PWSTR *value)
Definition: install.c:1738
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:2349
static VOID FixupServiceBinaryPath(IN DWORD ServiceType, IN OUT LPWSTR *ServiceBinary)
Definition: install.c:1773
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
BOOL WINAPI SetupInstallServicesFromInfSectionExW(_In_ HINF InfHandle, _In_ PCWSTR SectionName, _In_ DWORD Flags, _In_opt_ HDEVINFO DeviceInfoSet, _In_opt_ PSP_DEVINFO_DATA DeviceInfoData, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2)
Definition: install.c:2118
static const WCHAR IconPath[]
Definition: install.c:51
static BOOL GetLineText(HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
Definition: install.c:1685
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:1815
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
BOOL WINAPI SetupInstallServicesFromInfSectionW(_In_ HINF InfHandle, _In_ PCWSTR SectionName, _In_ DWORD Flags)
Definition: install.c:1617
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
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:3271
#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
size_t bufferSize
size_t total
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
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
GLsizeiptr size
Definition: glext.h:5919
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 _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Reserved_
Definition: no_sal2.h:504
#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
#define list
Definition: rosglue.h:35
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
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define SPINST_BITREG
Definition: setupapi.h:594
#define SP_COPY_OEMINF_CATALOG_ONLY
Definition: setupapi.h:495
#define SPSVCINST_NOCLOBBER_ERRORCONTROL
Definition: setupapi.h:631
#define SPREG_GETPROCADDR
Definition: setupapi.h:655
#define SPINST_UNREGSVR
Definition: setupapi.h:596
#define FLG_REGSVR_DLLREGISTER
Definition: setupapi.h:408
#define SPREG_REGSVR
Definition: setupapi.h:656
#define SP_COPY_NOOVERWRITE
Definition: setupapi.h:481
#define SP_COPY_DELETESOURCE
Definition: setupapi.h:477
#define SPSVCINST_DELETEEVENTLOGENTRY
Definition: setupapi.h:628
#define SPSVCINST_NOCLOBBER_DISPLAYNAME
Definition: setupapi.h:629
#define DI_NOVCP
Definition: setupapi.h:49
#define SPINST_PROFILEITEMS
Definition: setupapi.h:597
#define SPINST_INI2REG
Definition: setupapi.h:592
#define SP_COPY_REPLACEONLY
Definition: setupapi.h:478
#define SPSVCINST_NOCLOBBER_LOADORDERGROUP
Definition: setupapi.h:632
SP_DEVINSTALL_PARAMS_A SP_DEVINSTALL_PARAMS
Definition: setupapi.h:1156
#define SPFILENOTIFY_STARTREGISTRATION
Definition: setupapi.h:571
#define SPINST_REGSVR
Definition: setupapi.h:595
#define SPOST_NONE
Definition: setupapi.h:610
#define SPREG_SUCCESS
Definition: setupapi.h:653
#define ERROR_BAD_SERVICE_INSTALLSECT
Definition: setupapi.h:320
#define SPREG_TIMEOUT
Definition: setupapi.h:658
#define FLG_PROFITEM_CSIDL
Definition: setupapi.h:407
#define SPSVCINST_NOCLOBBER_STARTTYPE
Definition: setupapi.h:630
#define SPINST_INIFILES
Definition: setupapi.h:590
#define SPINST_REGISTRY
Definition: setupapi.h:591
#define ERROR_SECTION_NOT_FOUND
Definition: setupapi.h:294
#define SPSVCINST_TAGTOFRONT
Definition: setupapi.h:626
#define SPFILENOTIFY_ENDREGISTRATION
Definition: setupapi.h:572
#define SPSVCINST_NOCLOBBER_DEPENDENCIES
Definition: setupapi.h:633
UINT(CALLBACK * PSP_FILE_CALLBACK_A)(PVOID, UINT, UINT_PTR, UINT_PTR)
Definition: setupapi.h:877
#define SPSVCINST_ASSOCSERVICE
Definition: setupapi.h:627
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1529
#define SP_COPY_IN_USE_NEEDS_REBOOT
Definition: setupapi.h:486
#define SPINST_LOGCONFIG
Definition: setupapi.h:589
#define SPOST_URL
Definition: setupapi.h:612
#define SPOST_PATH
Definition: setupapi.h:611
#define FLG_PROFITEM_GROUP
Definition: setupapi.h:406
#define SPINST_ALL
Definition: setupapi.h:602
#define SPREG_LOADLIBRARY
Definition: setupapi.h:654
#define FLG_PROFITEM_DELETE
Definition: setupapi.h:405
#define FLG_REGSVR_DLLINSTALL
Definition: setupapi.h:409
#define SPDRP_SERVICE
Definition: setupapi.h:512
#define SPINST_FILES
Definition: setupapi.h:593
#define SPSVCINST_STOPSERVICE
Definition: setupapi.h:635
#define FLG_PROFITEM_CURRENTUSER
Definition: setupapi.h:404
#define SP_COPY_NEWER
Definition: setupapi.h:479
#define SETUP_DEVICE_INFO_SET_MAGIC
#define PSPGF_NONINTERACTIVE
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2203
#define CSIDL_PROGRAMS
Definition: shlobj.h:2183
#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:96
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