mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-10-30 21:35:06 +00:00
72 lines
2.6 KiB
C
72 lines
2.6 KiB
C
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <msi.h>
|
|
|
|
/* A package whose DLL custom actions run in the installer's custom action server: the immediate one reads a package property and
|
|
records it in the registry; the deferred one, on request, fails the installation, and the installer rolls back the file it had put in
|
|
place and leaves the product unregistered. */
|
|
|
|
/* An action library of the other width writes through that width's view of the registry, as a 32-bit one does on 64-bit Windows. */
|
|
#ifndef ACTION_VIEW
|
|
#define ACTION_VIEW 0
|
|
#endif
|
|
|
|
static const WCHAR product[] = L"{3F6A2B1C-8D4E-4A7B-9C1D-2E3F4A5B6C7D}";
|
|
static const WCHAR component[] = L"{6B5A4C3D-2E1F-4A0B-9C8D-7E6F5A4B3C2D}";
|
|
|
|
static BOOL same(const WCHAR *a, const WCHAR *b)
|
|
{
|
|
while (*a && *a == *b)
|
|
++a, ++b;
|
|
return *a == *b;
|
|
}
|
|
|
|
static void remove_marker(void)
|
|
{
|
|
HKEY key;
|
|
if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\RavenSample", 0, KEY_SET_VALUE | ACTION_VIEW, &key)) {
|
|
RegDeleteValueW(key, L"FromCustomAction");
|
|
RegCloseKey(key);
|
|
}
|
|
}
|
|
|
|
int raven_entry(void)
|
|
{
|
|
WCHAR package[MAX_PATH], path[MAX_PATH], value[64];
|
|
unsigned cut = GetModuleFileNameW(NULL, package, MAX_PATH);
|
|
while (cut && package[cut - 1] != L'\\')
|
|
--cut;
|
|
const WCHAR name[] = L"custom.msi";
|
|
for (unsigned i = 0; name[i]; ++i)
|
|
package[cut++] = name[i];
|
|
package[cut] = 0;
|
|
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
if (MsiQueryProductStateW(product) == INSTALLSTATE_DEFAULT)
|
|
MsiConfigureProductW(product, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT);
|
|
remove_marker();
|
|
|
|
UINT result = MsiInstallProductW(package, L"CA_VALUE=from-the-command-line");
|
|
if (result != ERROR_SUCCESS)
|
|
return 100 + (int)(result % 100);
|
|
HKEY key;
|
|
DWORD size = sizeof value, type = 0;
|
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\RavenSample", 0, KEY_READ | ACTION_VIEW, &key) ||
|
|
RegQueryValueExW(key, L"FromCustomAction", NULL, &type, (BYTE *)value, &size) || type != REG_SZ || !same(value, L"from-the-command-line"))
|
|
return 2;
|
|
RegCloseKey(key);
|
|
size = MAX_PATH;
|
|
if (MsiGetComponentPathW(product, component, path, &size) != INSTALLSTATE_LOCAL)
|
|
return 3;
|
|
if (MsiConfigureProductW(product, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT) != ERROR_SUCCESS || MsiQueryProductStateW(product) != INSTALLSTATE_UNKNOWN)
|
|
return 4;
|
|
remove_marker();
|
|
|
|
/* The deferred action fails after the file was installed: the whole installation is undone. */
|
|
result = MsiInstallProductW(package, L"FAIL=1");
|
|
if (result != ERROR_INSTALL_FAILURE)
|
|
return 200 + (int)(result % 100);
|
|
if (MsiQueryProductStateW(product) != INSTALLSTATE_UNKNOWN || GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
|
|
return 5;
|
|
return 0;
|
|
}
|