From 1418b4fec23459aafec4b5a787e2c2b89f6af1f1 Mon Sep 17 00:00:00 2001 From: "Asanka C. Herath" Date: Mon, 18 Oct 2010 04:52:34 -0400 Subject: [PATCH] Windows: Backup and restore configuration across installs The MSI installer for OpenAFS does not preserve configuration data across installs. This patch creates a backup of specific configuration registry values when uninstalling OpenAFS and uses this backup when subsequently installing OpenAFS. Change-Id: Ie30f8f7f0eada3f0aeef2341b04aca55657ec864 Reviewed-on: http://gerrit.openafs.org/2977 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/install/wix/Binary/newconfig.ico | Bin 0 -> 766 bytes src/WINNT/install/wix/Binary/restore.ico | Bin 0 -> 766 bytes src/WINNT/install/wix/custom/NTMakefile | 5 +- src/WINNT/install/wix/custom/afscustom.cpp | 390 ++++++++++++++++++++++++++++- src/WINNT/install/wix/lang/en_US/ui.wxi | 93 +++++-- src/WINNT/install/wix/openafs.wxs | 27 ++ src/WINNT/install/wix/property.wxi | 4 + src/WINNT/install/wix/registry.wxi | 3 +- 8 files changed, 501 insertions(+), 21 deletions(-) create mode 100644 src/WINNT/install/wix/Binary/newconfig.ico create mode 100644 src/WINNT/install/wix/Binary/restore.ico diff --git a/src/WINNT/install/wix/Binary/newconfig.ico b/src/WINNT/install/wix/Binary/newconfig.ico new file mode 100644 index 0000000000000000000000000000000000000000..1da8cac10f1a04d70a6bd47cb5e5f3862cadf364 GIT binary patch literal 766 zcmcgqp>D%45WTFE?5bpFbb*7D0tQ0%Ns$T+3TCTdkpfm4)Q<>AB$IqfVPRn_O}V{u z(k`jAYG`La`|kOjUo3?v!ieJstoO9PBYGsFXCMaN0O4eoQ%JkMz1i{c~c3AtQ(-&DznSb4up0-?f1 z5SX4A{8xTi8z^3eTGeTqg2>L_XDWpGsdWKCYAE=Nr(Q!)OE!ckrcYZ}8I9ksbF`hV z-d}DfP4jIzsWqQAX9wBgUyf_!^Q-!1iGSeNa5%Yu6gwNSYw4YL^uz~J?nsgQ0y=;N YcIJ3DV?HY8PNDbn(m&i~v3DcKZ-N@buK)l5 literal 0 HcmV?d00001 diff --git a/src/WINNT/install/wix/Binary/restore.ico b/src/WINNT/install/wix/Binary/restore.ico new file mode 100644 index 0000000000000000000000000000000000000000..3204c58be3fa530e0309127ade001b8401dee5da GIT binary patch literal 766 zcmcgqp$@_@6g(ISof--~i6p@+so|4wvn4Ym80-`uF++mc=OAZiDA(6EY)gjZ+Uwr+ z`rd1k0Sk^i-*8>wwFI^Rc4ST-Nw@zS2H=D-{==0aY0$PU4J#AYx`^a(TW_cfi(a~?Pmj1em1%1Dw8Ebuw1%m$w7u<*YT?G~I z=leedysw9*T`?uA)Qr=K{wetn%;HSv h+##EAZ96z7+>cx^c9gU9GTSB0C0&gH4dXW%@d2wD*t!4! literal 0 HcmV?d00001 diff --git a/src/WINNT/install/wix/custom/NTMakefile b/src/WINNT/install/wix/custom/NTMakefile index ddd1c8b..01038bd 100644 --- a/src/WINNT/install/wix/custom/NTMakefile +++ b/src/WINNT/install/wix/custom/NTMakefile @@ -18,7 +18,10 @@ DLLEXPORTS=\ -EXPORT:AbortMsiImmediate \ -EXPORT:UninstallNsisInstallation \ -EXPORT:CreateAFSClientAdminGroup \ - -EXPORT:RemoveAFSClientAdminGroup + -EXPORT:RemoveAFSClientAdminGroup \ + -EXPORT:BackupAFSClientRegistryKeys \ + -EXPORT:RestoreAFSClientRegistryKeys \ + -EXPORT:DetectSavedConfiguration DLLLIBFILES=\ msi.lib advapi32.lib netapi32.lib diff --git a/src/WINNT/install/wix/custom/afscustom.cpp b/src/WINNT/install/wix/custom/afscustom.cpp index 08f1554..9e03670 100644 --- a/src/WINNT/install/wix/custom/afscustom.cpp +++ b/src/WINNT/install/wix/custom/afscustom.cpp @@ -38,9 +38,14 @@ SOFTWARE. // Only works for Win2k and above #define _WIN32_WINNT 0x0500 +#define UNICODE +#define _UNICODE #include "afscustom.h" -#include "tchar.h" +#include +#include +#include + void ShowMsiError( MSIHANDLE hInstall, DWORD errcode, DWORD param ){ MSIHANDLE hRecord; @@ -79,7 +84,7 @@ MSIDLLEXPORT AbortMsiImmediate( MSIHANDLE hInstall ) { dwSize = 0; - rv = MsiFormatRecord(hInstall, hRecord, "", &dwSize); + rv = MsiFormatRecord(hInstall, hRecord, _T(""), &dwSize); if(rv != ERROR_MORE_DATA) goto _cleanup; sFormatted = new TCHAR[ ++dwSize ]; @@ -485,3 +490,384 @@ UINT removeAfsAdminGroup(void) { return status; } +const TCHAR * reg_NP = _T("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider"); +const TCHAR * reg_NP_Backup = _T("SOFTWARE\\OpenAFS\\Client\\BackupSettings\\NetworkProvider"); + +const TCHAR * reg_NP_Domains = _T("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider\\Domain"); +const TCHAR * reg_NP_Domains_Backup = _T("SOFTWARE\\OpenAFS\\Client\\BackupSettings\\NetworkProvider\\Domain"); + +const TCHAR * reg_Param = _T("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"); +const TCHAR * reg_Param_Backup = _T("SOFTWARE\\OpenAFS\\Client\\BackupSettings\\Parameters"); + +const TCHAR * reg_Client = _T("SOFTWARE\\OpenAFS\\Client"); +const TCHAR * reg_Client_Backup = _T("SOFTWARE\\OpenAFS\\Client\\BackupSettings\\Client"); + +const TCHAR * reg_Backup = _T("SOFTWARE\\OpenAFS\\Client\\BackupSettings"); + +const TCHAR * reg_NP_values[] = { + _T("LogonOptions"), + _T("VerboseLogging"), + _T("LogonScript"), + _T("FailLoginsSilently"), + _T("LoginRetryInterval"), + _T("LoginSleepInterval"), + _T("Realm"), + _T("TheseCells"), + NULL +}; + +const TCHAR * reg_Everything[] = { + _T("*"), + NULL +}; + +const TCHAR * reg_Client_values[] = { + _T("CellServDBDir"), + _T("VerifyServiceSignature"), + _T("IoctlDebug"), + _T("MiniDumpType"), + _T("SMBAsyncStoreSize"), + _T("StoreAnsiFilenames"), + _T("StartAfscredsOnStartup"), + _T("AfscredsShortcutParams"), + NULL +}; + +struct registry_backup { + const TCHAR * key; + const TCHAR ** values; + const TCHAR * backup_key; +} registry_backups[] = { + + // Subkeys must be specified before parent keys. + + { reg_NP_Domains, reg_Everything, reg_NP_Domains_Backup }, + { reg_NP, reg_NP_values, reg_NP_Backup }, + { reg_Param, reg_Everything, reg_Param_Backup }, + { reg_Client, reg_Client_values, reg_Client_Backup }, + { NULL, NULL, NULL } +}; + +void +ShowMsiActionData(MSIHANDLE hInstall, const TCHAR * format, ...) +{ + va_list vl; + TCHAR buf[1024]; + MSIHANDLE hRec; + + va_start(vl, format); + StringCbVPrintf(buf, sizeof(buf), format, vl); + va_end(vl); + + hRec = MsiCreateRecord(2); + MsiRecordSetString(hRec, 1, buf); + MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRec); + MsiCloseHandle(hRec); +} + +void +do_reg_copy_value(MSIHANDLE hInstall, HKEY hk_src, HKEY hk_dest, const TCHAR * value) +{ + BYTE static_buffer[4096]; + BYTE * buffer = static_buffer; + DWORD cb = sizeof(static_buffer); + LONG rv; + DWORD type = 0; + + rv = RegQueryValueEx(hk_src, value, 0, &type, buffer, &cb); + if (rv == ERROR_MORE_DATA) { + buffer = new BYTE[cb]; + if (buffer == NULL) { + ShowMsiActionData(hInstall, _T("Out of memory")); + return; + } + + rv = RegQueryValueEx(hk_src, value, 0, &type, buffer, &cb); + } + + if (rv == ERROR_SUCCESS) { + rv = RegSetValueEx(hk_dest, value, 0, type, buffer, cb); + if (rv == ERROR_SUCCESS) { + ShowMsiActionData(hInstall, _T("Copied value [%s]"), value); + } else { + ShowMsiActionData(hInstall, _T("Can't write value [%s]. Return code =%d"), value, rv); + } + } else if (rv != ERROR_FILE_NOT_FOUND) { + ShowMsiActionData(hInstall, _T("Can't read registry value [%s]. Return code = %d"), value, rv); + } + + if (buffer != static_buffer) + delete[] buffer; +} + +//! Copy a registry key and optionally all its subkeys +// +// @return TRUE if the source was deleted +BOOL +do_reg_copy(MSIHANDLE hInstall, + HKEY hk_root_src, const TCHAR * src, + HKEY hk_root_dest, const TCHAR * dest, + const TCHAR ** values, BOOL delete_source) +{ + BOOL retval = FALSE; + HKEY hk_src = 0; + HKEY hk_dest = 0; + + LONG rv; + + rv = RegOpenKeyEx(hk_root_src, src, 0, KEY_READ, &hk_src); + if (rv != ERROR_SUCCESS) { + if (rv == ERROR_FILE_NOT_FOUND) { + ShowMsiActionData(hInstall, _T("Source key %s does not exist"), src); + } else { + ShowMsiActionData(hInstall, _T("Can't open source key while copying %s. Return value=%d"), src, rv); + } + goto cleanup; + } + + ShowMsiActionData(hInstall, _T("Copying registry key %s to %s"), src, dest); + + // If dest == NULL, then we are just being asked to cleanup src + if (dest == NULL) + goto del_source; + + rv = RegCreateKeyEx(hk_root_dest, dest, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &hk_dest, NULL); + if (rv != ERROR_SUCCESS) { + ShowMsiActionData(hInstall, _T("Can't create target key. Return value=%d"), rv); + goto cleanup; + } + + if (values[0][0] == _T('*')) { + BOOL retry; + + for (DWORD index = 0; ; index++) { + TCHAR name[16384]; + DWORD cch = 16384; + + rv = RegEnumValue(hk_src, index, name, &cch, NULL, NULL, NULL, NULL); + if (rv == ERROR_SUCCESS) { + do_reg_copy_value(hInstall, hk_src, hk_dest, name); + } else { + break; + } + } + + do { + retry = FALSE; + + for (DWORD index = 0; ; index++) { + TCHAR name[256]; + DWORD cch = 256; + + rv = RegEnumKeyEx(hk_src, index, name, &cch, NULL, NULL, NULL, NULL); + if (rv == ERROR_SUCCESS) { + if (do_reg_copy(hInstall, hk_src, name, hk_dest, name, + reg_Everything, delete_source)) { + index--; + retry = TRUE; + } + } else { + break; + } + } + + } while (retry); + + } else { + + for (const TCHAR ** pv = values; *pv; pv++) { + do_reg_copy_value(hInstall, hk_src, hk_dest, *pv); + } + } + +del_source: + if (delete_source) { + rv = RegDeleteKey(hk_root_src, src); + retval = (rv == ERROR_SUCCESS); + if (rv == ERROR_SUCCESS) { + ShowMsiActionData(hInstall, _T("Deleted source key")); + } else { + ShowMsiActionData(hInstall, _T("Unable to delete source key. Return code=%d"), rv); + } + } + +cleanup: + if (hk_dest != 0) + RegCloseKey(hk_dest); + if (hk_src != 0) + RegCloseKey(hk_src); + + return retval; +} + + +MSIDLLEXPORT BackupAFSClientRegistryKeys( MSIHANDLE hInstall ) +{ + registry_backup *b; + MSIHANDLE hRec; + + hRec = MsiCreateRecord(4); + MsiRecordSetString(hRec, 1, _T("BackupAFSClientRegistryKeys")); + MsiRecordSetString(hRec, 2, _T("Backing up AFS client configuration registry keys")); + MsiRecordSetString(hRec, 3, _T("[1]")); + MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONSTART, hRec); + MsiCloseHandle(hRec); + + for (b = registry_backups; b->key != NULL; b++) { + do_reg_copy(hInstall, HKEY_LOCAL_MACHINE, b->key, HKEY_LOCAL_MACHINE, b->backup_key, + b->values, FALSE); + } + + return ERROR_SUCCESS; +} + +MSIDLLEXPORT RestoreAFSClientRegistryKeys( MSIHANDLE hInstall ) +{ + registry_backup *b; + MSIHANDLE hRec; + + hRec = MsiCreateRecord(4); + MsiRecordSetString(hRec, 1, _T("RestoreAFSClientRegistryKeys")); + MsiRecordSetString(hRec, 2, _T("Restoring AFS client configuration registry keys")); + MsiRecordSetString(hRec, 3, _T("[1]")); + MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONSTART, hRec); + MsiCloseHandle(hRec); + + for (b = registry_backups; b->key != NULL; b++) { + do_reg_copy(hInstall, HKEY_LOCAL_MACHINE, b->backup_key, HKEY_LOCAL_MACHINE, b->key, + b->values, TRUE); + } + do_reg_copy(hInstall, HKEY_LOCAL_MACHINE, reg_Backup, NULL, NULL, NULL, TRUE); + + return ERROR_SUCCESS; +} + +LONG +SetMsiPropertyFromRegValue(MSIHANDLE hInstall, HKEY hk, + const TCHAR * property, const TCHAR * value_name) +{ + LONG rv; + BYTE static_buffer[4096]; + BYTE *buffer = static_buffer; + DWORD cb = sizeof(static_buffer); + DWORD type = 0; + + rv = RegQueryValueEx(hk, value_name, NULL, &type, buffer, &cb); + if (rv == ERROR_FILE_NOT_FOUND) + return rv; + + if (rv == ERROR_MORE_DATA || + ((type == REG_SZ || type == REG_EXPAND_SZ) && cb >= sizeof(static_buffer))) { + + if (type == REG_SZ || type == REG_EXPAND_SZ) + cb += sizeof(TCHAR); + + buffer = new BYTE[cb]; + rv = RegQueryValueEx(hk, value_name, NULL, &type, buffer, &cb); + } + + if (rv != ERROR_SUCCESS) + goto cleanup; + + switch (type) { + case REG_DWORD: + { + DWORD d = *((DWORD *) buffer); + StringCbPrintf((TCHAR *) static_buffer, sizeof(static_buffer), _T("%d"), (int) d); + rv = MsiSetProperty(hInstall, property, (const TCHAR *) static_buffer); + break; + } + + case REG_SZ: + case REG_EXPAND_SZ: + { + TCHAR * s = (TCHAR *) buffer; + + if (s[cb / sizeof(TCHAR) - 1] != _T('\0')) + s[cb / sizeof(TCHAR)] = _T('\0'); + rv = MsiSetProperty(hInstall, property, s); + break; + } + + default: + rv = ERROR_FILE_NOT_FOUND; + } + +cleanup: + if (buffer != static_buffer) + delete[] buffer; + + return rv; +} + +LONG +SetAfscredsOptionsFromRegValue(MSIHANDLE hInstall, HKEY hk) +{ + TCHAR buffer[16]; + DWORD cb = sizeof(buffer); + LONG rv; + DWORD type; + + rv = RegQueryValueEx(hk, _T("AfscredsShortcutParams"), NULL, &type, (LPBYTE) buffer, &cb); + if (rv != ERROR_SUCCESS || type != REG_SZ || cb == sizeof(buffer)) { + return ERROR_FILE_NOT_FOUND; + } + + MsiSetProperty(hInstall, _T("CREDSAUTOINIT"), (_tcsstr(buffer, _T("-a")) != NULL)? _T("-a"): NULL); + MsiSetProperty(hInstall, _T("CREDSIPCHDET"), (_tcsstr(buffer, _T("-n")) != NULL)? _T("-n"): NULL); + MsiSetProperty(hInstall, _T("CREDSQUIET"), (_tcsstr(buffer, _T("-q")) != NULL)? _T("-q"): NULL); + MsiSetProperty(hInstall, _T("CREDSRENEWDRMAP"), (_tcsstr(buffer, _T("-m")) != NULL)? _T("-m"): NULL); + MsiSetProperty(hInstall, _T("CREDSSHOW"), (_tcsstr(buffer, _T("-s")) != NULL)? _T("-s"): NULL); + + return rv; +} + +/// Pull in known configuration values for use during this installation +// +MSIDLLEXPORT DetectSavedConfiguration( MSIHANDLE hInstall ) +{ + { + MSIHANDLE hRec; + + hRec = MsiCreateRecord(4); + MsiRecordSetString(hRec, 1, _T("DetectSavedConfiguration")); + MsiRecordSetString(hRec, 2, _T("Detecting saved configuration")); + MsiRecordSetString(hRec, 3, _T("[1]")); + MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONSTART, hRec); + MsiCloseHandle(hRec); + } + + HKEY hk_client = 0, hk_param = 0, hk_np = 0; + LONG rv; + BOOL found = FALSE; + + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_Param_Backup, 0, KEY_READ, &hk_param); + if (rv == ERROR_SUCCESS) { + SetMsiPropertyFromRegValue(hInstall, hk_param, _T("AFSCELLNAME"), _T("Cell")); + SetMsiPropertyFromRegValue(hInstall, hk_param, _T("FREELANCEMODE"), _T("FreelanceClient")); + SetMsiPropertyFromRegValue(hInstall, hk_param, _T("USEDNS"), _T("UseDNS")); + SetMsiPropertyFromRegValue(hInstall, hk_param, _T("SECURITYLEVEL"), _T("SecurityLevel")); + RegCloseKey(hk_param); + found = TRUE; + } + + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_Client_Backup, 0, KEY_READ, &hk_client); + if (rv == ERROR_SUCCESS) { + SetMsiPropertyFromRegValue(hInstall, hk_client, _T("CREDSSTARTUP"), _T("StartAfscredsOnStartup")); + SetAfscredsOptionsFromRegValue(hInstall, hk_client); + RegCloseKey(hk_client); + found = TRUE; + } + + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_NP_Backup, 0, KEY_READ, &hk_np); + if (rv == ERROR_SUCCESS) { + SetMsiPropertyFromRegValue(hInstall, hk_np, _T("LOGONOPTIONS"), _T("LogonOptions")); + RegCloseKey(hk_np); + found = TRUE; + } + + MsiSetProperty(hInstall, _T("SAVED_CONFIG"), (found)?_T("1"):NULL); + + return 0; +} diff --git a/src/WINNT/install/wix/lang/en_US/ui.wxi b/src/WINNT/install/wix/lang/en_US/ui.wxi index cc351b5..cd12f7b 100644 --- a/src/WINNT/install/wix/lang/en_US/ui.wxi +++ b/src/WINNT/install/wix/lang/en_US/ui.wxi @@ -37,6 +37,8 @@ Setup 0 Setup Wizard + restore + newconfig @@ -229,7 +231,10 @@ - 3 AND !feaClient<>3) OR &feaControlCenter=2 OR (&feaControlCenter<>3 AND !feaControlCenter<>3) ))]]> + 3 AND !feaClient<>3) OR &feaControlCenter=2 OR (&feaControlCenter<>3 AND !feaControlCenter<>3) )) AND NOT SAVED_CONFIG ]]> + + + 3 AND !feaClient<>3) OR &feaControlCenter=2 OR (&feaControlCenter<>3 AND !feaControlCenter<>3) )) AND SAVED_CONFIG ]]> 3 AND NOT ((&feaServer=3 OR (!feaServer=3 AND &feaServer<1)) AND (&feaClient=2 OR (&feaClient<>3 AND !feaClient<>3) OR &feaControlCenter=2 OR (&feaControlCenter<>3 AND !feaControlCenter<>3) ))]]> @@ -287,7 +292,10 @@ 3 AND !feaClient<>3)]]> 3 AND !feaControlCenter<>3)]]> - + + + + 3 ]]> @@ -690,7 +698,8 @@ 1 1 - 1 + NOT SAVED_CONFIG + SAVED_CONFIG 1 @@ -709,7 +718,8 @@ 1 1 - 1 + NOT SAVED_CONFIG + SAVED_CONFIG 1 @@ -744,11 +754,53 @@ - + + + + [DlgTitleFont]&Restore + + + 1 + 1 + + + [DlgTitleFont]&New settings + + + 1 + 1 + InstallMode <> "Typical" AND InstallMode <> "Complete" InstallMode = "Typical" OR InstallMode = "Complete" + + + 1 + + + + Configuration settings from a prior OpenAFS installation is available. + + + + + [DlgTitleFont]Restore configuration? + + + Specify new settings. Basic settings can be set via this installer. All others will be reset to defaults. + + + Restore and use the saved configuration settings. + + + + + + InstallMode <> "Typical" AND InstallMode <> "Complete" AND NOT SAVED_CONFIG + ( InstallMode = "Typical" OR InstallMode = "Complete" ) AND NOT SAVED_CONFIG + SAVED_CONFIG + 1 @@ -764,16 +816,16 @@ [DlgTitleFont]Configure AFS Client - - - - - - - - - - + + + + + + + + + + @@ -888,8 +940,10 @@ InstallMode = "Server Image" (InstallMode = "Custom" OR InstallMode = "Change") AND &feaClient <> 3 - (InstallMode = "Custom" OR InstallMode = "Change") AND &feaClient = 3 - InstallMode = "Typical" OR InstallMode = "Complete" + (InstallMode = "Custom" OR InstallMode = "Change") AND &feaClient = 3 AND NOT RESTORE_CONFIG + (InstallMode = "Typical" OR InstallMode = "Complete") AND NOT RESTORE_CONFIG + (InstallMode = "Custom" OR InstallMode = "Change") AND &feaClient = 3 AND RESTORE_CONFIG + (InstallMode = "Typical" OR InstallMode = "Complete") AND RESTORE_CONFIG InstallMode = "Custom" OR InstallMode = "Change" InstallMode = "Typical" OR InstallMode = "Complete" @@ -1088,6 +1142,9 @@ Installed AND NOT RESUME AND NOT Preselected (NOT Installed) AND AFTERREBOOT + + + @@ -1101,6 +1158,8 @@ + + diff --git a/src/WINNT/install/wix/openafs.wxs b/src/WINNT/install/wix/openafs.wxs index 127af09..e955ea2 100644 --- a/src/WINNT/install/wix/openafs.wxs +++ b/src/WINNT/install/wix/openafs.wxs @@ -214,6 +214,29 @@ DllEntry="AbortMsiImmediate" Execute="immediate" /> + + + + @@ -242,10 +265,14 @@ !feaClient=2 And &feaClient=3 And (VersionNT=501 Or VersionNT=502) &feaClient=3 &feaServer=3 + !feaClient=2 And &feaClient=3 And RESTORE_CONFIG + !feaClient=2 And &feaClient=3 And RESTORE_CONFIG + !feaClient=3 And &feaClient=2 &feaClient=3 &feaClient=3 + &feaClient=3 OR &feaServer=3 OR &feaClient=2 OR &feaServer=2 diff --git a/src/WINNT/install/wix/property.wxi b/src/WINNT/install/wix/property.wxi index b8d7d9b..9446831 100644 --- a/src/WINNT/install/wix/property.wxi +++ b/src/WINNT/install/wix/property.wxi @@ -31,6 +31,10 @@ + + 1 diff --git a/src/WINNT/install/wix/registry.wxi b/src/WINNT/install/wix/registry.wxi index 210a974..cca7455 100644 --- a/src/WINNT/install/wix/registry.wxi +++ b/src/WINNT/install/wix/registry.wxi @@ -1,4 +1,4 @@ - +