ReactOS 0.4.17-dev-804-g023d8af
install.c
Go to the documentation of this file.
1/*
2 * Advpack install functions
3 *
4 * Copyright 2006 James Hawkins
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22#include <stdlib.h>
23
24#include "windef.h"
25#include "winbase.h"
26#include "winuser.h"
27#include "winreg.h"
28#include "winternl.h"
29#include "winnls.h"
30#include "setupapi.h"
31#include "advpub.h"
32#include "ole2.h"
33#include "wine/debug.h"
34#include "advpack_private.h"
35
37
38#define SPAPI_ERROR 0xE0000000L
39#define SPAPI_PREFIX 0x800F0000L
40#define SPAPI_MASK 0xFFFFL
41#define HRESULT_FROM_SPAPI(x) ((HRESULT)((x & SPAPI_MASK) | SPAPI_PREFIX))
42
43#define ADV_HRESULT(x) ((x & SPAPI_ERROR) ? HRESULT_FROM_SPAPI(x) : HRESULT_FROM_WIN32(x))
44
45#define ADV_SUCCESS 0
46#define ADV_FAILURE 1
47
48/* contains information about a specific install instance */
49typedef struct _ADVInfo
50{
59
60typedef HRESULT (*iterate_fields_func)(HINF hinf, PCWSTR field, const void *arg);
61
62/* Advanced INF callbacks */
63static HRESULT del_dirs_callback(HINF hinf, PCWSTR field, const void *arg)
64{
66 HRESULT hr = S_OK;
67 DWORD size;
68
70
72 {
74
77 continue;
78
80 hr = E_FAIL;
81 }
82
83 return hr;
84}
85
87{
88 PERUSERSECTIONW per_user;
90 DWORD size;
91
92 per_user.bRollback = FALSE;
93 per_user.dwIsInstalled = 0;
94
95 SetupGetLineTextW(NULL, hinf, field, L"DisplayName", per_user.szDispName, ARRAY_SIZE(per_user.szDispName), &size);
96
97 SetupGetLineTextW(NULL, hinf, field, L"Version", per_user.szVersion, ARRAY_SIZE(per_user.szVersion), &size);
98
99 if (SetupFindFirstLineW(hinf, field, L"IsInstalled", &context))
100 {
102 }
103
104 SetupGetLineTextW(NULL, hinf, field, L"ComponentID", per_user.szCompID, ARRAY_SIZE(per_user.szCompID), &size);
105
106 SetupGetLineTextW(NULL, hinf, field, L"GUID", per_user.szGUID, ARRAY_SIZE(per_user.szGUID), &size);
107
108 SetupGetLineTextW(NULL, hinf, field, L"Locale", per_user.szLocale, ARRAY_SIZE(per_user.szLocale), &size);
109
110 SetupGetLineTextW(NULL, hinf, field, L"StubPath", per_user.szStub, ARRAY_SIZE(per_user.szStub), &size);
111
112 return SetPerUserSecValuesW(&per_user);
113}
114
116{
117 HMODULE hm;
119 HRESULT hr = S_OK;
120
122
123 for (; ok; ok = SetupFindNextLine(&context, &context))
124 {
126
127 /* get OCX filename */
129 continue;
130
132 if (hm)
133 {
134 if (do_ocx_reg(hm, TRUE, NULL, NULL) != S_OK)
135 hr = E_FAIL;
136
137 FreeLibrary(hm);
138 }
139 else
140 hr = E_FAIL;
141
142 if (FAILED(hr))
143 {
144 /* FIXME: display a message box */
145 break;
146 }
147 }
148
149 return hr;
150}
151
153{
154 const ADVInfo *info = (const ADVInfo *)arg;
156 HRESULT hr = S_OK;
157 DWORD size;
158
160
161 for (; ok; ok = SetupFindNextLine(&context, &context))
162 {
164
167 continue;
168
169 if (launch_exe(buffer, info->working_dir, NULL) != S_OK)
170 hr = E_FAIL;
171 }
172
173 return hr;
174}
175
176/* sequentially returns pointers to parameters in a parameter list
177 * returns NULL if the parameter is empty, e.g. one,,three */
179{
181
182 if (!*params)
183 return NULL;
184
185 if (quoted && *token == '"')
186 {
187 WCHAR *end = wcschr(token + 1, '"');
188 if (end)
189 {
190 *end = 0;
191 *params = end + 1;
192 token = token + 1;
193 }
194 }
195
197 if (*params)
198 *(*params)++ = '\0';
199
200 if (!*token)
201 return NULL;
202
203 return token;
204}
205
207{
208 const int MIN_PATH_LEN = 3;
209
210 if (!path || lstrlenW(path) < MIN_PATH_LEN)
211 return FALSE;
212
213 if ((path[1] == ':' && path[2] == '\\') || (path[0] == '\\' && path[1] == '\\'))
214 return TRUE;
215
216 return FALSE;
217}
218
219/* retrieves the contents of a field, dynamically growing the buffer if necessary */
221 const WCHAR *static_buffer, DWORD *size)
222{
223 DWORD required;
224
225 if (SetupGetStringFieldW(context, index, buffer, *size, &required)) return buffer;
226
228 {
229 /* now grow the buffer */
230 if (buffer != static_buffer) free(buffer);
231 if (!(buffer = malloc(required*sizeof(WCHAR)))) return NULL;
232 *size = required;
233 if (SetupGetStringFieldW(context, index, buffer, *size, &required)) return buffer;
234 }
235
236 if (buffer != static_buffer) free(buffer);
237 return NULL;
238}
239
240/* iterates over all fields of a certain key of a certain section */
243{
244 WCHAR static_buffer[200];
245 WCHAR *buffer = static_buffer;
246 DWORD size = ARRAY_SIZE(static_buffer);
248 HRESULT hr = E_FAIL;
249
251 while (ok)
252 {
254
255 for (i = 1; i <= count; i++)
256 {
257 if (!(buffer = get_field_string(&context, i, buffer, static_buffer, &size)))
258 goto done;
259
260 if ((hr = callback(hinf, buffer, arg)) != S_OK)
261 goto done;
262 }
263
265 }
266
267 hr = S_OK;
268
269 done:
270 if (buffer != static_buffer) free(buffer);
271 return hr;
272}
273
275{
276 INT check;
278 HRESULT hr = S_OK;
279
280 if (!SetupFindFirstLineW(info->hinf, info->install_sec, L"CheckAdminRights", &context))
281 return S_OK;
282
283 if (!SetupGetIntField(&context, 1, &check))
284 return S_OK;
285
286 if (check == 1)
287 hr = IsNTAdmin(0, NULL) ? S_OK : E_FAIL;
288
289 return hr;
290}
291
292/* performs a setupapi-level install of the INF file */
294{
295 BOOL ret;
296 HRESULT res;
298
300 if (!context)
301 return ADV_HRESULT(GetLastError());
302
303 ret = SetupInstallFromInfSectionW(NULL, info->hinf, info->install_sec,
304 SPINST_FILES, NULL, info->working_dir,
306 context, NULL, NULL);
307 if (!ret)
308 {
311
312 return res;
313 }
314
316
317 ret = SetupInstallFromInfSectionW(NULL, info->hinf, info->install_sec,
320 NULL, NULL, NULL, NULL);
321 if (!ret)
322 return ADV_HRESULT(GetLastError());
323
324 return S_OK;
325}
326
327/* processes the Advanced INF commands */
329{
330 HRESULT hr;
331
333 if (hr != S_OK)
334 return hr;
335
336 hr = iterate_section_fields(info->hinf, info->install_sec, L"RunPreSetupCommands",
338 if (hr != S_OK)
339 return hr;
340
342 hr = iterate_section_fields(info->hinf, info->install_sec,
343 L"RegisterOCXs", register_ocxs_callback, NULL);
345 if (hr != S_OK)
346 return hr;
347
348 hr = iterate_section_fields(info->hinf, info->install_sec,
349 L"PerUserInstall", per_user_install_callback, info);
350 if (hr != S_OK)
351 return hr;
352
353 hr = iterate_section_fields(info->hinf, info->install_sec, L"RunPostSetupCommands",
355 if (hr != S_OK)
356 return hr;
357
358 hr = iterate_section_fields(info->hinf, info->install_sec, L"DelDirs", del_dirs_callback, info);
359 if (hr != S_OK)
360 return hr;
361
362 return hr;
363}
364
365/* determines the proper working directory for the INF file */
366static HRESULT get_working_dir(ADVInfo *info, LPCWSTR inf_filename, LPCWSTR working_dir)
367{
369 LPCWSTR ptr;
370 DWORD len;
371
372 if ((ptr = wcsrchr(inf_filename, '\\')))
373 {
374 len = ptr - inf_filename + 1;
375 ptr = inf_filename;
376 }
377 else if (working_dir && *working_dir)
378 {
379 len = lstrlenW(working_dir) + 1;
380 ptr = working_dir;
381 }
382 else
383 {
385 lstrcatW(path, L"\\");
386 lstrcatW(path, inf_filename);
387
388 /* check if the INF file is in the current directory */
390 {
392 }
393 else
394 {
395 /* default to the windows\inf directory if all else fails */
397 lstrcatW(path, L"\\INF");
398 }
399
400 len = lstrlenW(path) + 1;
401 ptr = path;
402 }
403
404 info->working_dir = malloc(len * sizeof(WCHAR));
405 if (!info->working_dir)
406 return E_OUTOFMEMORY;
407
408 lstrcpynW(info->working_dir, ptr, len);
409
410 return S_OK;
411}
412
413/* loads the INF file and performs checks on it */
414static HRESULT install_init(LPCWSTR inf_filename, LPCWSTR install_sec,
415 LPCWSTR working_dir, DWORD flags, ADVInfo *info)
416{
417 DWORD len;
418 HRESULT hr;
420
421 if (!(ptr = wcsrchr(inf_filename, '\\')))
422 ptr = inf_filename;
423
424 info->inf_filename = wcsdup(ptr);
425 if (!info->inf_filename)
426 return E_OUTOFMEMORY;
427
428 /* FIXME: determine the proper platform to install (NTx86, etc) */
429 info->install_sec = wcsdup(install_sec && *install_sec ? install_sec : L"DefaultInstall");
430 if (!info->install_sec)
431 return E_OUTOFMEMORY;
432
433 hr = get_working_dir(info, inf_filename, working_dir);
434 if (FAILED(hr))
435 return hr;
436
437 len = lstrlenW(info->working_dir) + lstrlenW(info->inf_filename) + 2;
438 info->inf_path = malloc(len * sizeof(WCHAR));
439 if (!info->inf_path)
440 return E_OUTOFMEMORY;
441
442 lstrcpyW(info->inf_path, info->working_dir);
443 lstrcatW(info->inf_path, L"\\");
444 lstrcatW(info->inf_path, info->inf_filename);
445
446 /* RunSetupCommand opens unmodified filename parameter */
447 if (flags & RSC_FLAG_INF)
448 path = inf_filename;
449 else
450 path = info->inf_path;
451
453 if (info->hinf == INVALID_HANDLE_VALUE)
454 return ADV_HRESULT(GetLastError());
455
456 set_ldids(info->hinf, info->install_sec, info->working_dir);
457
458 /* FIXME: check that the INF is advanced */
459
460 info->flags = flags;
461 info->need_reboot = FALSE;
462
463 return S_OK;
464}
465
466/* release the install instance information */
467static void install_release(const ADVInfo *info)
468{
469 SetupCloseInfFile(info->hinf);
470
471 free(info->inf_path);
472 free(info->inf_filename);
473 free(info->install_sec);
474 free(info->working_dir);
475}
476
477/* this structure very closely resembles parameters of RunSetupCommand() */
478typedef struct
479{
486
487typedef struct
488{
495
496/* internal: see DoInfInstall */
498{
500 HRESULT hr;
501
502 TRACE("(%p)\n", setup);
503
504 ZeroMemory(&info, sizeof(ADVInfo));
505
506 hr = install_init(setup->inf_name, setup->section_name, setup->dir, 0, &info);
507 if (hr != S_OK)
508 goto done;
509
511 if (hr != S_OK)
512 goto done;
513
514 hr = adv_install(&info);
515
516done:
518
519 return hr;
520}
521
522/***********************************************************************
523 * DoInfInstall (ADVPACK.@)
524 *
525 * Install an INF section.
526 *
527 * PARAMS
528 * setup [I] Structure containing install information.
529 *
530 * RETURNS
531 * S_OK Everything OK
532 * HRESULT_FROM_WIN32(GetLastError()) Some other error
533 */
535{
538 HRESULT hr;
539
540 if (!setup)
541 return E_INVALIDARG;
542
547
548 params.title = title.Buffer;
549 params.inf_name = inf.Buffer;
550 params.section_name = section.Buffer;
551 params.dir = dir.Buffer;
552 params.hwnd = setup->hwnd;
553
555
560
561 return hr;
562}
563
564/***********************************************************************
565 * ExecuteCabA (ADVPACK.@)
566 *
567 * See ExecuteCabW.
568 */
570{
571 UNICODE_STRING cab, inf, section;
572 CABINFOW cabinfo;
573 HRESULT hr;
574
575 TRACE("(%p, %p, %p)\n", hwnd, pCab, pReserved);
576
577 if (!pCab)
578 return E_INVALIDARG;
579
580 if (pCab->pszCab)
581 {
583 cabinfo.pszCab = cab.Buffer;
584 }
585 else
586 cabinfo.pszCab = NULL;
587
590
591 MultiByteToWideChar(CP_ACP, 0, pCab->szSrcPath, -1, cabinfo.szSrcPath, ARRAY_SIZE(cabinfo.szSrcPath));
592
593 cabinfo.pszInf = inf.Buffer;
594 cabinfo.pszSection = section.Buffer;
595 cabinfo.dwFlags = pCab->dwFlags;
596
597 hr = ExecuteCabW(hwnd, &cabinfo, pReserved);
598
599 if (pCab->pszCab)
601
604
605 return hr;
606}
607
608/***********************************************************************
609 * ExecuteCabW (ADVPACK.@)
610 *
611 * Installs the INF file extracted from a specified cabinet file.
612 *
613 * PARAMS
614 * hwnd [I] Handle to the window used for the display.
615 * pCab [I] Information about the cabinet file.
616 * pReserved [I] Reserved. Must be NULL.
617 *
618 * RETURNS
619 * Success: S_OK.
620 * Failure: E_FAIL.
621 */
623{
625 HRESULT hr;
626
627 TRACE("(%p, %p, %p)\n", hwnd, pCab, pReserved);
628
629 ZeroMemory(&info, sizeof(ADVInfo));
630
631 if ((pCab->pszCab && *pCab->pszCab) && (pCab->pszInf && *pCab->pszInf) && *pCab->szSrcPath)
632 {
633 TRACE("pszCab: %s, pszInf: %s, szSrcPath: %s\n", debugstr_w(pCab->pszCab), debugstr_w(pCab->pszInf),
634 debugstr_w(pCab->szSrcPath));
635
636 hr = ExtractFilesW(pCab->pszCab, pCab->szSrcPath, 0, pCab->pszInf, NULL, 0);
637 if (FAILED(hr))
638 ERR("Failed to extract .inf file!\n");
639 }
640
641 hr = install_init(pCab->pszInf, pCab->pszSection, pCab->szSrcPath, pCab->dwFlags, &info);
642 if (hr != S_OK)
643 goto done;
644
646 if (hr != S_OK)
647 goto done;
648
649 hr = adv_install(&info);
650
651done:
653
654 return hr;
655}
656
657/***********************************************************************
658 * LaunchINFSectionA (ADVPACK.@)
659 *
660 * See LaunchINFSectionW.
661 */
663{
665 HRESULT hr;
666
667 TRACE("(%p, %p, %s, %i)\n", hWnd, hInst, debugstr_a(cmdline), show);
668
669 if (!cmdline)
670 return ADV_FAILURE;
671
673
674 hr = LaunchINFSectionW(hWnd, hInst, cmd.Buffer, show);
675
677
678 return hr;
679}
680
681/***********************************************************************
682 * LaunchINFSectionW (ADVPACK.@)
683 *
684 * Installs an INF section without BACKUP/ROLLBACK capabilities.
685 *
686 * PARAMS
687 * hWnd [I] Handle to parent window, NULL for desktop.
688 * hInst [I] Instance of the process.
689 * cmdline [I] Contains parameters in the order INF,section,flags,reboot.
690 * show [I] How the window should be shown.
691 *
692 * RETURNS
693 * Success: ADV_SUCCESS.
694 * Failure: ADV_FAILURE.
695 *
696 * NOTES
697 * INF - Filename of the INF to launch.
698 * section - INF section to install.
699 * flags - see advpub.h.
700 * reboot - smart reboot behavior
701 * 'A' Always reboot.
702 * 'I' Reboot if needed (default).
703 * 'N' No reboot.
704 */
706{
708 LPWSTR cmdline_copy, cmdline_ptr;
709 LPWSTR inf_filename, install_sec;
710 LPWSTR str_flags;
711 DWORD flags = 0;
712 HRESULT hr = S_OK;
713
714 TRACE("(%p, %p, %s, %d)\n", hWnd, hInst, debugstr_w(cmdline), show);
715
716 if (!cmdline)
717 return ADV_FAILURE;
718
719 cmdline_copy = wcsdup(cmdline);
720 cmdline_ptr = cmdline_copy;
721
722 inf_filename = get_parameter(&cmdline_ptr, ',', TRUE);
723 install_sec = get_parameter(&cmdline_ptr, ',', TRUE);
724
725 str_flags = get_parameter(&cmdline_ptr, ',', TRUE);
726 if (str_flags)
727 {
728 DWORD inf_flags = wcstol(str_flags, NULL, 10);
729 if (inf_flags & LIS_QUIET) flags |= RSC_FLAG_QUIET;
730 if (inf_flags & LIS_NOGRPCONV) flags |= RSC_FLAG_NGCONV;
731 }
732
733 ZeroMemory(&info, sizeof(ADVInfo));
734
735 hr = install_init(inf_filename, install_sec, NULL, flags, &info);
736 if (hr != S_OK)
737 goto done;
738
740 if (hr != S_OK)
741 goto done;
742
743 hr = adv_install(&info);
744
745done:
747 free(cmdline_copy);
748
750}
751
752/***********************************************************************
753 * LaunchINFSectionExA (ADVPACK.@)
754 *
755 * See LaunchINFSectionExW.
756 */
758{
760 HRESULT hr;
761
762 TRACE("(%p, %p, %s, %i)\n", hWnd, hInst, debugstr_a(cmdline), show);
763
764 if (!cmdline)
765 return ADV_FAILURE;
766
768
769 hr = LaunchINFSectionExW(hWnd, hInst, cmd.Buffer, show);
770
772
773 return hr;
774}
775
776/***********************************************************************
777 * LaunchINFSectionExW (ADVPACK.@)
778 *
779 * Installs an INF section with BACKUP/ROLLBACK capabilities.
780 *
781 * PARAMS
782 * hWnd [I] Handle to parent window, NULL for desktop.
783 * hInst [I] Instance of the process.
784 * cmdline [I] Contains parameters in the order INF,section,CAB,flags,reboot.
785 * show [I] How the window should be shown.
786 *
787 * RETURNS
788 * Success: ADV_SUCCESS.
789 * Failure: ADV_FAILURE.
790 *
791 * NOTES
792 * INF - Filename of the INF to launch.
793 * section - INF section to install.
794 * flags - see advpub.h.
795 * reboot - smart reboot behavior
796 * 'A' Always reboot.
797 * 'I' Reboot if needed (default).
798 * 'N' No reboot.
799 *
800 * BUGS
801 * Doesn't handle the reboot flag.
802 */
804{
805 LPWSTR cmdline_copy, cmdline_ptr;
807 CABINFOW cabinfo;
808 HRESULT hr;
809
810 TRACE("(%p, %p, %s, %d)\n", hWnd, hInst, debugstr_w(cmdline), show);
811
812 if (!cmdline)
813 return ADV_FAILURE;
814
815 cmdline_copy = wcsdup(cmdline);
816 cmdline_ptr = cmdline_copy;
817
818 cabinfo.pszInf = get_parameter(&cmdline_ptr, ',', TRUE);
819 cabinfo.pszSection = get_parameter(&cmdline_ptr, ',', TRUE);
820 cabinfo.pszCab = get_parameter(&cmdline_ptr, ',', TRUE);
821 *cabinfo.szSrcPath = '\0';
822
823 flags = get_parameter(&cmdline_ptr, ',', TRUE);
824 if (flags)
825 cabinfo.dwFlags = wcstol(flags, NULL, 10);
826
827 if (!is_full_path(cabinfo.pszCab) && !is_full_path(cabinfo.pszInf))
828 {
829 free(cmdline_copy);
830 return E_INVALIDARG;
831 }
832
833 /* get the source path from the cab filename */
834 if (cabinfo.pszCab && *cabinfo.pszCab)
835 {
836 if (!is_full_path(cabinfo.pszCab))
837 lstrcpyW(cabinfo.szSrcPath, cabinfo.pszInf);
838 else
839 lstrcpyW(cabinfo.szSrcPath, cabinfo.pszCab);
840
841 ptr = wcsrchr(cabinfo.szSrcPath, '\\');
842 *(++ptr) = '\0';
843 }
844
845 hr = ExecuteCabW(hWnd, &cabinfo, NULL);
846 free(cmdline_copy);
848}
849
851{
854
855 if (phEXE) *phEXE = NULL;
856
857 ZeroMemory(&pi, sizeof(pi));
858 ZeroMemory(&si, sizeof(si));
859 si.cb = sizeof(si);
860
863 NULL, dir, &si, &pi))
864 {
866 }
867
869
870 if (phEXE)
871 {
872 *phEXE = pi.hProcess;
873 return S_ASYNCHRONOUS;
874 }
875
876 /* wait for the child process to finish */
879
880 return S_OK;
881}
882
883/***********************************************************************
884 * RunSetupCommandA (ADVPACK.@)
885 *
886 * See RunSetupCommandW.
887 */
889 LPCSTR szInfSection, LPCSTR szDir,
890 LPCSTR lpszTitle, HANDLE *phEXE,
892{
893 UNICODE_STRING cmdname, infsec;
895 HRESULT hr;
896
897 TRACE("(%p, %s, %s, %s, %s, %p, %ld, %p)\n",
898 hWnd, debugstr_a(szCmdName), debugstr_a(szInfSection),
899 debugstr_a(szDir), debugstr_a(lpszTitle),
900 phEXE, dwFlags, pvReserved);
901
902 if (!szCmdName || !szDir)
903 return E_INVALIDARG;
904
905 RtlCreateUnicodeStringFromAsciiz(&cmdname, szCmdName);
906 RtlCreateUnicodeStringFromAsciiz(&infsec, szInfSection);
909
910 hr = RunSetupCommandW(hWnd, cmdname.Buffer, infsec.Buffer, dir.Buffer,
911 title.Buffer, phEXE, dwFlags, pvReserved);
912
913 RtlFreeUnicodeString(&cmdname);
914 RtlFreeUnicodeString(&infsec);
917
918 return hr;
919}
920
921/***********************************************************************
922 * RunSetupCommandW (ADVPACK.@)
923 *
924 * Executes an install section in an INF file or a program.
925 *
926 * PARAMS
927 * hWnd [I] Handle to parent window, NULL for quiet mode
928 * szCmdName [I] Inf or EXE filename to execute
929 * szInfSection [I] Inf section to install, NULL for DefaultInstall
930 * szDir [I] Path to extracted files
931 * szTitle [I] Title of all dialogs
932 * phEXE [O] Handle of EXE to wait for
933 * dwFlags [I] Flags; see include/advpub.h
934 * pvReserved [I] Reserved
935 *
936 * RETURNS
937 * S_OK Everything OK
938 * S_ASYNCHRONOUS OK, required to wait on phEXE
939 * ERROR_SUCCESS_REBOOT_REQUIRED Reboot required
940 * E_INVALIDARG Invalid argument given
941 * HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION)
942 * Not supported on this Windows version
943 * E_UNEXPECTED Unexpected error
944 * HRESULT_FROM_WIN32(GetLastError()) Some other error
945 */
947 LPCWSTR szInfSection, LPCWSTR szDir,
948 LPCWSTR lpszTitle, HANDLE *phEXE,
950{
952 HRESULT hr;
953
954 TRACE("(%p, %s, %s, %s, %s, %p, %ld, %p)\n",
955 hWnd, debugstr_w(szCmdName), debugstr_w(szInfSection),
956 debugstr_w(szDir), debugstr_w(lpszTitle),
957 phEXE, dwFlags, pvReserved);
958
960 FIXME("Unhandled flag: RSC_FLAG_UPDHLPDLLS\n");
961
962 if (!szCmdName || !szDir)
963 return E_INVALIDARG;
964
965 if (!(dwFlags & RSC_FLAG_INF))
966 return launch_exe(szCmdName, szDir, phEXE);
967
968 ZeroMemory(&info, sizeof(ADVInfo));
969
970 hr = install_init(szCmdName, szInfSection, szDir, dwFlags, &info);
971 if (hr != S_OK)
972 goto done;
973
975 if (hr != S_OK)
976 goto done;
977
978 hr = adv_install(&info);
979
980done:
982
983 return hr;
984}
#define ADN_DEL_IF_EMPTY
Definition: DelNode.c:13
#define LIS_QUIET
Definition: advpub.h:139
#define RSC_FLAG_UPDHLPDLLS
Definition: advpub.h:134
#define RSC_FLAG_NGCONV
Definition: advpub.h:133
#define RSC_FLAG_INF
Definition: advpub.h:130
#define LIS_NOGRPCONV
Definition: advpub.h:140
#define RSC_FLAG_QUIET
Definition: advpub.h:132
#define S_ASYNCHRONOUS
Definition: urlmon.idl:2172
unsigned int dir
Definition: maze.c:112
#define ok(value,...)
Definition: atltest.h:57
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT do_ocx_reg(HMODULE hocx, BOOL do_reg, const WCHAR *flags, const WCHAR *param)
Definition: advpack.c:427
void set_ldids(HINF hInf, LPCWSTR pszInstallSection, LPCWSTR pszWorkingDir)
Definition: advpack.c:100
HRESULT WINAPI SetPerUserSecValuesW(PERUSERSECTIONW *pPerUser)
Definition: advpack.c:540
BOOL WINAPI IsNTAdmin(DWORD reserved, LPDWORD pReserved)
Definition: advpack.c:207
HRESULT WINAPI DelNodeW(LPCWSTR pszFileOrDirName, DWORD dwFlags)
Definition: files.c:425
HRESULT WINAPI ExtractFilesW(LPCWSTR CabName, LPCWSTR ExpandDir, DWORD Flags, LPCWSTR FileList, LPVOID LReserved, DWORD Reserved)
Definition: files.c:777
HRESULT WINAPI RunSetupCommandA(HWND hWnd, LPCSTR szCmdName, LPCSTR szInfSection, LPCSTR szDir, LPCSTR lpszTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved)
Definition: install.c:888
static HRESULT get_working_dir(ADVInfo *info, LPCWSTR inf_filename, LPCWSTR working_dir)
Definition: install.c:366
static HRESULT per_user_install_callback(HINF hinf, PCWSTR field, const void *arg)
Definition: install.c:86
static void install_release(const ADVInfo *info)
Definition: install.c:467
HRESULT(* iterate_fields_func)(HINF hinf, PCWSTR field, const void *arg)
Definition: install.c:60
HRESULT WINAPI ExecuteCabW(HWND hwnd, CABINFOW *pCab, LPVOID pReserved)
Definition: install.c:622
struct _ADVInfo ADVInfo
#define ADV_HRESULT(x)
Definition: install.c:43
static BOOL is_full_path(LPCWSTR path)
Definition: install.c:206
HRESULT WINAPI RunSetupCommandW(HWND hWnd, LPCWSTR szCmdName, LPCWSTR szInfSection, LPCWSTR szDir, LPCWSTR lpszTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved)
Definition: install.c:946
static HRESULT iterate_section_fields(HINF hinf, PCWSTR section, PCWSTR key, iterate_fields_func callback, void *arg)
Definition: install.c:241
static HRESULT del_dirs_callback(HINF hinf, PCWSTR field, const void *arg)
Definition: install.c:63
INT WINAPI LaunchINFSectionW(HWND hWnd, HINSTANCE hInst, LPWSTR cmdline, INT show)
Definition: install.c:705
static HRESULT spapi_install(const ADVInfo *info)
Definition: install.c:293
#define ADV_FAILURE
Definition: install.c:46
HRESULT WINAPI ExecuteCabA(HWND hwnd, CABINFOA *pCab, LPVOID pReserved)
Definition: install.c:569
static HRESULT run_setup_commands_callback(HINF hinf, PCWSTR field, const void *arg)
Definition: install.c:152
static HRESULT adv_install(ADVInfo *info)
Definition: install.c:328
static HRESULT install_init(LPCWSTR inf_filename, LPCWSTR install_sec, LPCWSTR working_dir, DWORD flags, ADVInfo *info)
Definition: install.c:414
LPWSTR get_parameter(LPWSTR *params, WCHAR separator, BOOL quoted)
Definition: install.c:178
#define ADV_SUCCESS
Definition: install.c:45
static HRESULT register_ocxs_callback(HINF hinf, PCWSTR field, const void *arg)
Definition: install.c:115
static WCHAR * get_field_string(INFCONTEXT *context, DWORD index, WCHAR *buffer, const WCHAR *static_buffer, DWORD *size)
Definition: install.c:220
HRESULT launch_exe(LPCWSTR cmd, LPCWSTR dir, HANDLE *phEXE)
Definition: install.c:850
static HRESULT DoInfInstallW(const SETUPCOMMAND_PARAMSW *setup)
Definition: install.c:497
HRESULT WINAPI DoInfInstall(const SETUPCOMMAND_PARAMS *setup)
Definition: install.c:534
HRESULT WINAPI LaunchINFSectionExA(HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show)
Definition: install.c:757
HRESULT WINAPI LaunchINFSectionExW(HWND hWnd, HINSTANCE hInst, LPWSTR cmdline, INT show)
Definition: install.c:803
INT WINAPI LaunchINFSectionA(HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show)
Definition: install.c:662
static HRESULT check_admin_rights(const ADVInfo *info)
Definition: install.c:274
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR separator[]
Definition: asmname.c:65
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2271
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:4491
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2752
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:162
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:218
BOOL WINAPI SetupInstallFromInfSectionW(HWND owner, HINF hinf, PCWSTR section, UINT flags, HKEY key_root, PCWSTR src_root, UINT copy_flags, PSP_FILE_CALLBACK_W callback, PVOID context, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data)
Definition: install.c:1330
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
BOOL WINAPI SetupFindNextMatchLineW(PINFCONTEXT context_in, PCWSTR key, PINFCONTEXT context_out)
Definition: parser.c:1701
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1763
PVOID WINAPI SetupInitDefaultQueueCallbackEx(HWND owner, HWND progress, UINT msg, DWORD reserved1, PVOID reserved2)
Definition: queue.c:1638
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
#define check(expected, result)
Definition: dplayx.c:32
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define INFINITE
Definition: serial.h:102
HINSTANCE hInst
Definition: dxdiag.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
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
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 token
Definition: glfuncs.h:210
unsigned int UINT
Definition: sysinfo.c:13
#define INF_STYLE_WIN4
Definition: infsupp.h:43
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:36
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define ZeroMemory
Definition: minwinbase.h:31
int * PINT
Definition: minwindef.h:150
static PVOID ptr
Definition: dispmode.c:27
static IPrintDialogCallback callback
Definition: printdlg.c:326
static LPCWSTR LPVOID pvReserved
Definition: asmcache.c:749
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static SYSTEM_INFO si
Definition: virtual.c:39
static BOOL setup(void)
Definition: enum_files.c:97
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
_Out_ PVOID pReserved
Definition: netsh.h:77
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
short WCHAR
Definition: pedump.c:58
static char title[]
Definition: ps.c:92
#define SPINST_REGSVR
Definition: setupapi.h:597
#define SPINST_INIFILES
Definition: setupapi.h:592
#define SPINST_REGISTRY
Definition: setupapi.h:593
#define SPINST_FILES
Definition: setupapi.h:595
#define SP_COPY_NEWER
Definition: setupapi.h:481
#define TRACE(s)
Definition: solgame.cpp:4
TCHAR * cmdline
Definition: stretchblt.cpp:32
LPCWSTR section_name
Definition: install.c:493
LPCSTR section_name
Definition: install.c:484
LPWSTR install_sec
Definition: install.c:54
LPWSTR working_dir
Definition: install.c:55
LPWSTR inf_path
Definition: install.c:52
BOOL need_reboot
Definition: install.c:57
HINF hinf
Definition: install.c:51
LPWSTR inf_filename
Definition: install.c:53
DWORD flags
Definition: install.c:56
LPSTR pszCab
Definition: advpub.h:34
DWORD dwFlags
Definition: advpub.h:38
LPSTR pszSection
Definition: advpub.h:36
LPSTR pszInf
Definition: advpub.h:35
CHAR szSrcPath[MAX_PATH]
Definition: advpub.h:37
LPWSTR pszSection
Definition: advpub.h:45
WCHAR szSrcPath[MAX_PATH]
Definition: advpub.h:46
LPWSTR pszCab
Definition: advpub.h:43
LPWSTR pszInf
Definition: advpub.h:44
DWORD dwFlags
Definition: advpub.h:47
WCHAR szStub[MAX_PATH *4]
Definition: advpub.h:70
BOOL bRollback
Definition: advpub.h:74
DWORD dwIsInstalled
Definition: advpub.h:73
WCHAR szLocale[10]
Definition: advpub.h:69
WCHAR szGUID[39+20]
Definition: advpub.h:67
WCHAR szVersion[32]
Definition: advpub.h:71
WCHAR szDispName[128]
Definition: advpub.h:68
WCHAR szCompID[128]
Definition: advpub.h:72
Definition: ftp_var.h:139
Definition: http.c:7252
Definition: parser.c:44
Definition: copy.c:22
Definition: parser.c:56
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
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 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
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:340
#define CREATE_DEFAULT_ERROR_MODE
Definition: winbase.h:216
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:190
_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
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12