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