advpack: Open the INF file if the RSC_FLAG_INF flag is specified.
[wine/wine64.git] / dlls / advpack / install.c
blob042f761495f83e7fcb29a4bd2aafed3f0930480e
1 /*
2 * Advpack install functions
4 * Copyright 2006 James Hawkins
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
22 #include <stdlib.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "winver.h"
29 #include "winternl.h"
30 #include "setupapi.h"
31 #include "advpub.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(advpack);
36 #define SPAPI_ERROR 0xE0000000L
37 #define SPAPI_PREFIX 0x800F0000L
38 #define SPAPI_MASK 0xFFFFL
39 #define HRESULT_FROM_SPAPI(x) ((x & SPAPI_MASK) | SPAPI_PREFIX)
41 /* this structure very closely resembles parameters of RunSetupCommand() */
42 typedef struct
44 HWND hwnd;
45 LPCSTR title;
46 LPCSTR inf_name;
47 LPCSTR dir;
48 LPCSTR section_name;
49 } SETUPCOMMAND_PARAMS;
51 /***********************************************************************
52 * DoInfInstall (ADVPACK.@)
54 * Install an INF section.
56 * PARAMS
57 * setup [I] Structure containing install information.
59 * RETURNS
60 * S_OK Everything OK
61 * HRESULT_FROM_WIN32(GetLastError()) Some other error
63 HRESULT WINAPI DoInfInstall(const SETUPCOMMAND_PARAMS *setup)
65 BOOL ret;
66 HINF hinf;
67 void *callback_context;
69 TRACE("%p %s %s %s %s\n", setup->hwnd, debugstr_a(setup->title),
70 debugstr_a(setup->inf_name), debugstr_a(setup->dir),
71 debugstr_a(setup->section_name));
73 hinf = SetupOpenInfFileA(setup->inf_name, NULL, INF_STYLE_WIN4, NULL);
74 if (hinf == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError());
76 callback_context = SetupInitDefaultQueueCallback(setup->hwnd);
78 ret = SetupInstallFromInfSectionA(NULL, hinf, setup->section_name, SPINST_ALL,
79 NULL, NULL, 0, SetupDefaultQueueCallbackA,
80 callback_context, NULL, NULL);
81 SetupTermDefaultQueueCallback(callback_context);
82 SetupCloseInfFile(hinf);
84 return ret ? S_OK : HRESULT_FROM_WIN32(GetLastError());
87 /***********************************************************************
88 * ExecuteCabA (ADVPACK.@)
90 * Installs the INF file extracted from a specified cabinet file.
92 * PARAMS
93 * hwnd [I] Handle to the window used for the display.
94 * pCab [I] Information about the cabinet file.
95 * pReserved [I] Reserved. Must be NULL.
97 * RETURNS
98 * Success: S_OK.
99 * Failure: E_FAIL.
101 * BUGS
102 * Unimplemented
104 HRESULT WINAPI ExecuteCabA( HWND hwnd, CABINFOA* pCab, LPVOID pReserved )
106 FIXME("(%p %p %p): stub\n", hwnd, pCab, pReserved);
107 return E_FAIL;
110 /***********************************************************************
111 * LaunchINFSectionA (ADVPACK.@)
113 * Installs an INF section without BACKUP/ROLLBACK capabilities.
115 * PARAMS
116 * hWnd [I] Handle to parent window, NULL for desktop.
117 * hInst [I] Instance of the process.
118 * cmdline [I] Contains parameters in the order INF,section,flags,reboot.
119 * show [I] How the window should be shown.
121 * RETURNS
122 * Success: S_OK.
123 * Failure: S_FALSE
125 * NOTES
126 * INF - Filename of the INF to launch.
127 * section - INF section to install.
128 * flags - see advpub.h.
129 * reboot - smart reboot behavior
130 * 'A' Always reboot.
131 * 'I' Reboot if needed (default).
132 * 'N' No reboot.
134 * BUGS
135 * Unimplemented.
137 INT WINAPI LaunchINFSectionA( HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show )
139 FIXME("(%p %p %s %d): stub\n", hWnd, hInst, debugstr_a(cmdline), show );
140 return 0;
143 /***********************************************************************
144 * LaunchINFSectionExA (ADVPACK.@)
146 * See LaunchINFSectionExW.
148 HRESULT WINAPI LaunchINFSectionExA(HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show)
150 UNICODE_STRING cmd;
151 HRESULT hr;
153 TRACE("(%p, %p, %s, %d): stub\n", hWnd, hInst, debugstr_a(cmdline), show);
155 RtlCreateUnicodeStringFromAsciiz(&cmd, cmdline);
157 hr = LaunchINFSectionExW(hWnd, hInst, cmd.Buffer, show);
159 RtlFreeUnicodeString(&cmd);
161 return hr;
164 /***********************************************************************
165 * LaunchINFSectionExW (ADVPACK.@)
167 * Installs an INF section with BACKUP/ROLLBACK capabilities.
169 * PARAMS
170 * hWnd [I] Handle to parent window, NULL for desktop.
171 * hInst [I] Instance of the process.
172 * cmdline [I] Contains parameters in the order INF,section,CAB,flags,reboot.
173 * show [I] How the window should be shown.
175 * RETURNS
176 * Success: S_OK.
177 * Failure: E_FAIL.
179 * NOTES
180 * INF - Filename of the INF to launch.
181 * section - INF section to install.
182 * flags - see advpub.h.
183 * reboot - smart reboot behavior
184 * 'A' Always reboot.
185 * 'I' Reboot if needed (default).
186 * 'N' No reboot.
188 * BUGS
189 * Unimplemented.
191 HRESULT WINAPI LaunchINFSectionExW(HWND hWnd, HINSTANCE hInst, LPWSTR cmdline, INT show)
193 FIXME("(%p, %p, %s, %d): stub\n", hWnd, hInst, debugstr_w(cmdline), show );
194 return E_FAIL;
197 static HRESULT launch_exe(LPCWSTR cmd, LPCWSTR dir, HANDLE *phEXE)
199 STARTUPINFOW si;
200 PROCESS_INFORMATION pi;
202 if (phEXE) *phEXE = NULL;
204 ZeroMemory(&pi, sizeof(pi));
205 ZeroMemory(&si, sizeof(si));
206 si.cb = sizeof(si);
208 if (!CreateProcessW(NULL, (LPWSTR)cmd, NULL, NULL, FALSE,
209 CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP,
210 NULL, dir, &si, &pi))
212 return HRESULT_FROM_WIN32(GetLastError());
215 CloseHandle(pi.hThread);
217 if (phEXE)
219 *phEXE = pi.hProcess;
220 return S_ASYNCHRONOUS;
223 /* wait for the child process to finish */
224 WaitForSingleObject(pi.hProcess, INFINITE);
225 CloseHandle(pi.hProcess);
227 return S_OK;
230 /***********************************************************************
231 * RunSetupCommandA (ADVPACK.@)
233 * See RunSetupCommandW.
235 HRESULT WINAPI RunSetupCommandA(HWND hWnd, LPCSTR szCmdName,
236 LPCSTR szInfSection, LPCSTR szDir,
237 LPCSTR lpszTitle, HANDLE *phEXE,
238 DWORD dwFlags, LPVOID pvReserved )
240 UNICODE_STRING cmdname, infsec;
241 UNICODE_STRING dir, title;
242 HRESULT hr;
244 TRACE("(%p, %s, %s, %s, %s, %p, 0x%08lx, %p)\n",
245 hWnd, debugstr_a(szCmdName), debugstr_a(szInfSection),
246 debugstr_a(szDir), debugstr_a(lpszTitle),
247 phEXE, dwFlags, pvReserved);
249 if (!szCmdName || !szDir)
250 return E_INVALIDARG;
252 RtlCreateUnicodeStringFromAsciiz(&cmdname, szCmdName);
253 RtlCreateUnicodeStringFromAsciiz(&infsec, szInfSection);
254 RtlCreateUnicodeStringFromAsciiz(&dir, szDir);
255 RtlCreateUnicodeStringFromAsciiz(&title, lpszTitle);
257 hr = RunSetupCommandW(hWnd, cmdname.Buffer, infsec.Buffer, dir.Buffer,
258 title.Buffer, phEXE, dwFlags, pvReserved);
260 RtlFreeUnicodeString(&cmdname);
261 RtlFreeUnicodeString(&infsec);
262 RtlFreeUnicodeString(&dir);
263 RtlFreeUnicodeString(&title);
265 return hr;
268 /***********************************************************************
269 * RunSetupCommandW (ADVPACK.@)
271 * Executes an install section in an INF file or a program.
273 * PARAMS
274 * hWnd [I] Handle to parent window, NULL for quiet mode
275 * szCmdName [I] Inf or EXE filename to execute
276 * szInfSection [I] Inf section to install, NULL for DefaultInstall
277 * szDir [I] Path to extracted files
278 * szTitle [I] Title of all dialogs
279 * phEXE [O] Handle of EXE to wait for
280 * dwFlags [I] Flags; see include/advpub.h
281 * pvReserved [I] Reserved
283 * RETURNS
284 * S_OK Everything OK
285 * S_ASYNCHRONOUS OK, required to wait on phEXE
286 * ERROR_SUCCESS_REBOOT_REQUIRED Reboot required
287 * E_INVALIDARG Invalid argument given
288 * HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION)
289 * Not supported on this Windows version
290 * E_UNEXPECTED Unexpected error
291 * HRESULT_FROM_WIN32(GetLastError()) Some other error
293 * BUGS
294 * INF install unimplemented.
296 HRESULT WINAPI RunSetupCommandW(HWND hWnd, LPCWSTR szCmdName,
297 LPCWSTR szInfSection, LPCWSTR szDir,
298 LPCWSTR lpszTitle, HANDLE *phEXE,
299 DWORD dwFlags, LPVOID pvReserved )
301 HINF hinf;
302 DWORD err;
304 TRACE("(%p, %s, %s, %s, %s, %p, 0x%08lx, %p)\n",
305 hWnd, debugstr_w(szCmdName), debugstr_w(szInfSection),
306 debugstr_w(szDir), debugstr_w(lpszTitle),
307 phEXE, dwFlags, pvReserved);
309 if (dwFlags)
310 FIXME("Unhandled flags: 0x%08lx\n", dwFlags);
312 if (!szCmdName || !szDir)
313 return E_INVALIDARG;
315 if (!(dwFlags & RSC_FLAG_INF))
316 return launch_exe(szCmdName, szDir, phEXE);
318 hinf = SetupOpenInfFileW(szCmdName, NULL, INF_STYLE_WIN4, NULL);
319 if (hinf == INVALID_HANDLE_VALUE)
321 err = GetLastError();
322 if (err & SPAPI_ERROR)
323 return HRESULT_FROM_SPAPI(err);
324 else
325 return HRESULT_FROM_WIN32(err);
328 SetupCloseInfFile(hinf);
329 return E_UNEXPECTED;