advpack: Add install_init/release to perform install initialization.

This commit is contained in:
James Hawkins 2006-04-17 01:51:06 -05:00 committed by Alexandre Julliard
parent 3f784a7339
commit eb602fa8f0
1 changed files with 106 additions and 11 deletions

View File

@ -42,6 +42,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(advpack);
#define ADV_HRESULT(x) ((x & SPAPI_ERROR) ? HRESULT_FROM_SPAPI(x) : HRESULT_FROM_WIN32(x)) #define ADV_HRESULT(x) ((x & SPAPI_ERROR) ? HRESULT_FROM_SPAPI(x) : HRESULT_FROM_WIN32(x))
/* contains information about a specific install instance */
typedef struct _ADVInfo
{
HINF hinf;
LPWSTR inf_filename;
LPWSTR install_sec;
LPWSTR working_dir;
DWORD flags;
BOOL need_reboot;
} ADVInfo;
/* sequentially returns pointers to parameters in a parameter list /* sequentially returns pointers to parameters in a parameter list
* returns NULL if the parameter is empty, e.g. one,,three */ * returns NULL if the parameter is empty, e.g. one,,three */
LPWSTR get_parameter(LPWSTR *params, WCHAR separator) LPWSTR get_parameter(LPWSTR *params, WCHAR separator)
@ -75,7 +86,7 @@ static BOOL is_full_path(LPWSTR path)
} }
/* performs a setupapi-level install of the INF file */ /* performs a setupapi-level install of the INF file */
static HRESULT spapi_install(HINF hinf, LPCWSTR install_sec, LPCWSTR source_path) static HRESULT spapi_install(ADVInfo *info)
{ {
BOOL ret; BOOL ret;
HRESULT res; HRESULT res;
@ -85,9 +96,9 @@ static HRESULT spapi_install(HINF hinf, LPCWSTR install_sec, LPCWSTR source_path
if (!context) if (!context)
return ADV_HRESULT(GetLastError()); return ADV_HRESULT(GetLastError());
ret = SetupInstallFromInfSectionW(NULL, hinf, install_sec, SPINST_FILES, ret = SetupInstallFromInfSectionW(NULL, info->hinf, info->install_sec,
NULL, source_path, SP_COPY_NEWER, SPINST_FILES, NULL, info->working_dir,
SetupDefaultQueueCallbackW, SP_COPY_NEWER, SetupDefaultQueueCallbackW,
context, NULL, NULL); context, NULL, NULL);
if (!ret) if (!ret)
{ {
@ -99,7 +110,7 @@ static HRESULT spapi_install(HINF hinf, LPCWSTR install_sec, LPCWSTR source_path
SetupTermDefaultQueueCallback(context); SetupTermDefaultQueueCallback(context);
ret = SetupInstallFromInfSectionW(NULL, hinf, install_sec, ret = SetupInstallFromInfSectionW(NULL, info->hinf, info->install_sec,
SPINST_INIFILES | SPINST_REGISTRY, SPINST_INIFILES | SPINST_REGISTRY,
HKEY_LOCAL_MACHINE, NULL, 0, HKEY_LOCAL_MACHINE, NULL, 0,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
@ -109,6 +120,86 @@ static HRESULT spapi_install(HINF hinf, LPCWSTR install_sec, LPCWSTR source_path
return S_OK; return S_OK;
} }
/* loads the INF file and performs checks on it */
HRESULT install_init(LPCWSTR inf_filename, LPCWSTR install_sec,
LPCWSTR working_dir, DWORD flags, ADVInfo *info)
{
DWORD len;
LPCWSTR ptr;
static const WCHAR default_install[] = {
'D','e','f','a','u','l','t','I','n','s','t','a','l','l',0
};
len = lstrlenW(inf_filename);
info->inf_filename = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!info->inf_filename)
return E_OUTOFMEMORY;
lstrcpyW(info->inf_filename, inf_filename);
/* FIXME: determine the proper platform to install (NTx86, etc) */
if (!install_sec || !*install_sec)
{
len = sizeof(default_install) - 1;
ptr = default_install;
}
else
{
len = lstrlenW(install_sec);
ptr = install_sec;
}
info->install_sec = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!info->install_sec)
return E_OUTOFMEMORY;
lstrcpyW(info->install_sec, ptr);
/* FIXME: need to get the real working directory */
if (!working_dir || !*working_dir)
{
ptr = strrchrW(info->inf_filename, '\\');
len = ptr - info->inf_filename + 1;
ptr = info->inf_filename;
}
else
{
len = lstrlenW(working_dir);
ptr = working_dir;
}
info->working_dir = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!info->working_dir)
return E_OUTOFMEMORY;
lstrcpynW(info->working_dir, ptr, len);
info->hinf = SetupOpenInfFileW(info->inf_filename, NULL, INF_STYLE_WIN4, NULL);
if (info->hinf == INVALID_HANDLE_VALUE)
return ADV_HRESULT(GetLastError());
/* FIXME: set the ldids of the install section */
/* FIXME: check that the INF is advanced */
info->flags = flags;
info->need_reboot = FALSE;
return S_OK;
}
/* release the install instance information */
void install_release(ADVInfo *info)
{
if (info->hinf && info->hinf != INVALID_HANDLE_VALUE)
SetupCloseInfFile(info->hinf);
HeapFree(GetProcessHeap(), 0, info->inf_filename);
HeapFree(GetProcessHeap(), 0, info->install_sec);
HeapFree(GetProcessHeap(), 0, info->working_dir);
}
/* this structure very closely resembles parameters of RunSetupCommand() */ /* this structure very closely resembles parameters of RunSetupCommand() */
typedef struct typedef struct
{ {
@ -472,7 +563,7 @@ HRESULT WINAPI RunSetupCommandW(HWND hWnd, LPCWSTR szCmdName,
LPCWSTR lpszTitle, HANDLE *phEXE, LPCWSTR lpszTitle, HANDLE *phEXE,
DWORD dwFlags, LPVOID pvReserved) DWORD dwFlags, LPVOID pvReserved)
{ {
HINF hinf; ADVInfo info;
HRESULT hr; HRESULT hr;
TRACE("(%p, %s, %s, %s, %s, %p, %ld, %p)\n", TRACE("(%p, %s, %s, %s, %s, %p, %ld, %p)\n",
@ -489,12 +580,16 @@ HRESULT WINAPI RunSetupCommandW(HWND hWnd, LPCWSTR szCmdName,
if (!(dwFlags & RSC_FLAG_INF)) if (!(dwFlags & RSC_FLAG_INF))
return launch_exe(szCmdName, szDir, phEXE); return launch_exe(szCmdName, szDir, phEXE);
hinf = SetupOpenInfFileW(szCmdName, NULL, INF_STYLE_WIN4, NULL); ZeroMemory(&info, sizeof(ADVInfo));
if (hinf == INVALID_HANDLE_VALUE)
return ADV_HRESULT(GetLastError());
hr = spapi_install(hinf, szInfSection, szDir); hr = install_init(szCmdName, szInfSection, szDir, dwFlags, &info);
if (hr != S_OK)
goto done;
hr = spapi_install(&info);
done:
install_release(&info);
SetupCloseInfFile(hinf);
return hr; return hr;
} }