summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2021-12-21 12:24:35 +0100
committerVladislav Vaintroub <wlad@mariadb.com>2022-01-05 10:46:54 +0100
commit2a6e08690223fd15bd5cb261efe9b997fa2d6026 (patch)
treef98aa721dd8762ba61c806aeafa3db84a53db290
parent3712808ad2933a7a866e36114fa3c63a8630137d (diff)
downloadmariadb-git-2a6e08690223fd15bd5cb261efe9b997fa2d6026.tar.gz
MDEV-27335 Windows, MSI - Bring the datadir location into the instance config UI
-rw-r--r--win/packaging/ca/CustomAction.cpp122
-rw-r--r--win/packaging/ca/CustomAction.def2
-rw-r--r--win/packaging/extra.wxs.in29
3 files changed, 93 insertions, 60 deletions
diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp
index ccb83c7b0c6..cbef4d2ee41 100644
--- a/win/packaging/ca/CustomAction.cpp
+++ b/win/packaging/ca/CustomAction.cpp
@@ -161,70 +161,100 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
}
out[pos++]= 0;
}
+
+bool IsDirectoryEmptyOrNonExisting(const wchar_t *dir) {
+ wchar_t wildcard[MAX_PATH+3];
+ WIN32_FIND_DATAW data;
+ HANDLE h;
+ wcscpy_s(wildcard, MAX_PATH, dir);
+ wcscat_s(wildcard, MAX_PATH, L"*.*");
+ bool empty= true;
+ h= FindFirstFile(wildcard, &data);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ for (;;)
+ {
+ if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L".."))
+ {
+ empty= false;
+ break;
+ }
+ if (!FindNextFile(h, &data))
+ break;
+ }
+ FindClose(h);
+ }
+ return empty;
+}
+
/*
- Check for if directory is empty during install,
- sets "<PROPERTY>_NOT_EMPTY" otherise
+ Check for valid data directory is empty during install
+ A valid data directory is non-existing, or empty.
+
+ In addition, it must be different from any directories that
+ are going to be installed. This is required. because the full
+ directory is removed on a feature uninstall, and we do not want
+ it to be lib or bin.
*/
-extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
- const wchar_t *PropertyName)
+extern "C" UINT __stdcall CheckDataDirectory(MSIHANDLE hInstall)
{
- HRESULT hr = S_OK;
- UINT er = ERROR_SUCCESS;
- wchar_t buf[MAX_PATH];
- DWORD len = MAX_PATH;
- WIN32_FIND_DATAW data;
- HANDLE h;
+ HRESULT hr= S_OK;
+ UINT er= ERROR_SUCCESS;
+ wchar_t datadir[MAX_PATH];
+ DWORD len= MAX_PATH;
bool empty;
+ wchar_t *path= 0;
- hr = WcaInitialize(hInstall, __FUNCTION__);
+ MsiGetPropertyW(hInstall, L"DATADIR", datadir, &len);
+ hr= WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
- MsiGetPropertyW(hInstall, PropertyName, buf, &len);
- wcscat_s(buf, MAX_PATH, L"*.*");
+ WcaLog(LOGMSG_STANDARD, "Checking files in %S", datadir);
+ empty= IsDirectoryEmptyOrNonExisting(datadir);
+ if (empty)
+ WcaLog(LOGMSG_STANDARD, "DATADIR is empty or non-existent");
+ else
+ WcaLog(LOGMSG_STANDARD, "DATADIR is NOT empty");
+
+ if (!empty)
+ {
+ WcaSetProperty(L"DATADIRERROR", L"data directory exist and not empty");
+ goto LExit;
+ }
+ WcaSetProperty(L"DATADIRERROR", L"");
- WcaLog(LOGMSG_STANDARD, "Checking files in %S", buf);
- h= FindFirstFile(buf, &data);
- if (h != INVALID_HANDLE_VALUE)
+ WcaGetFormattedString(L"[INSTALLDIR]",&path);
+ if (path && !wcsicmp(datadir, path))
{
- empty= true;
- for(;;)
- {
- if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L".."))
- {
- empty= false;
- break;
- }
- if (!FindNextFile(h, &data))
- break;
- }
- FindClose(h);
+ WcaSetProperty(L"DATADIRERROR", L"data directory can not be "
+ L"installation root directory");
+ ReleaseStr(path);
+ goto LExit;
}
- else
+ for (auto dir :
+ {L"[INSTALLDIR]bin\\", L"[INSTALLDIR]include\\",
+ L"[INSTALLDIR]lib\\", L"[INSTALLDIR]share\\"})
{
- /* Non-existent directory, we handle it as empty */
- empty = true;
+ WcaGetFormattedString(dir, &path);
+ if (path && !wcsnicmp(datadir, path, wcslen(path)))
+ {
+ const wchar_t *subdir= dir + sizeof("[INSTALLDIR]") - 1;
+ wchar_t msg[MAX_PATH]= L"data directory conflicts with '";
+ wcsncat_s(msg, subdir, wcslen(subdir) - 1);
+ wcscat_s(msg, L"' directory, which is part of this installation");
+ WcaSetProperty(L"DATADIRERROR", msg);
+ ReleaseStr(path);
+ goto LExit;
+ }
+ ReleaseStr(path);
+ path= 0;
}
-
- if(empty)
- WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent",
- PropertyName);
- else
- WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName);
-
- wcscpy_s(buf, MAX_PATH, PropertyName);
- wcscat_s(buf, L"NOTEMPTY");
- WcaSetProperty(buf, empty? L"":L"1");
-
LExit:
return WcaFinalize(er);
}
-extern "C" UINT __stdcall CheckDataDirectoryEmpty(MSIHANDLE hInstall)
-{
- return CheckDirectoryEmpty(hInstall, L"DATADIR");
-}
bool CheckServiceExists(const wchar_t *name)
{
diff --git a/win/packaging/ca/CustomAction.def b/win/packaging/ca/CustomAction.def
index 0be77a97a08..aed69cf7827 100644
--- a/win/packaging/ca/CustomAction.def
+++ b/win/packaging/ca/CustomAction.def
@@ -5,6 +5,6 @@ PresetDatabaseProperties
RemoveDataDirectory
CreateDatabaseRollback
CheckDatabaseProperties
-CheckDataDirectoryEmpty
+CheckDataDirectory
CheckDBInUse
CheckServiceUpgrades
diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in
index e886ed87d06..d003cea26d6 100644
--- a/win/packaging/extra.wxs.in
+++ b/win/packaging/extra.wxs.in
@@ -230,12 +230,22 @@
<Control Id="CheckBoxUTF8" Type="CheckBox" X="8" Y="154" Width="250" Height="18" Property="UTF8" CheckBoxValue="1" TabSkip="no">
<Text>{\Font1}Use UTF8 as default server's character set</Text>
</Control>
-
+ <Control Type="Text" Id="Text11" Width="67" Height="17" X="8" Y="190" Text="{\Font1}Data directory" />
+ <Control Type="PathEdit" Id="TxtDir" Width="175" Height="18" X="80" Y="190" Property="DATADIR">
+ </Control>
+ <Control Id="btnDirBrowse" Type="PushButton" Width="56" Height="17" X="278" Y="190" Text="Browse...">
+ <Publish Property="_BrowseProperty" Value="DATADIR" Order="1">1</Publish>
+ <Publish Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
+ </Control>
<!-- Navigation buttons-->
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&amp;Back">
<Publish Event="NewDialog" Value="CustomizeDlg">1</Publish>
</Control>
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&amp;Next">
+ <Publish Event="DoAction" Value="CheckDataDirectory">1</Publish>
+ <Publish Property="WarningText" Value="Invalid data directory, choose a different one. Error: [DATADIRERROR]">
+ DATADIRERROR
+ </Publish>
<Publish Property="WarningText" Value="Passwords do not match."><![CDATA[PASSWORD <> RootPasswordConfirm]]></Publish>
<Publish Event="SpawnDialog" Value="WarningDlg"><![CDATA[WarningText <>""]]></Publish>
<Publish Property="SERVICENAME" Value="MariaDB">NOT SERVICENAME AND NOT WarningText</Publish>
@@ -335,7 +345,7 @@
</UI>
<Property Id="CRLF" Value="&#xD;&#xA;" />
- <CustomAction Id="CheckDataDirectoryEmpty" BinaryKey="wixca.dll" DllEntry="CheckDataDirectoryEmpty" Execute="immediate" Impersonate="yes"/>
+ <CustomAction Id="CheckDataDirectory" BinaryKey="wixca.dll" DllEntry="CheckDataDirectory" Execute="immediate" Impersonate="yes"/>
<!-- What to do when navigation buttons are clicked -->
<UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_FeatureTree" />
@@ -355,13 +365,6 @@
<Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="NewOrUpgradeInstanceDlg" Order="999">
NOT Installed AND UpgradableServiceFound
</Publish>
- <Publish Dialog="CustomizeDlg" Control="Next" Event="DoAction" Value="CheckDataDirectoryEmpty" Order="1"><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
- <Publish Dialog="CustomizeDlg" Property="DATADIRNOTEMPTY" Control="Next" Order="1"><![CDATA[NOT(&DBInstance=3 AND NOT !DBInstance=3)]]></Publish>
- <Publish Dialog="CustomizeDlg" Control="Next" Property="WarningText" Order="2"
- Value="Selected data directory [DATADIR] is not empty. Either clean it, or choose another location for 'Database Instance' feature.">
- DATADIRNOTEMPTY
- </Publish>
- <Publish Dialog="CustomizeDlg" Control="Next" Event="SpawnDialog" Value="WarningDlg" Order="3">WarningText</Publish>
<Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="4">
<![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]>
</Publish>
@@ -634,13 +637,13 @@
Property="FailureProgram"
Execute="deferred" />
- <CustomAction Id='ErrorDataDirNotEmpty'
- Error='Chosen data directory [DATADIR] is not empty. It must be empty prior to installation.'/>
+ <CustomAction Id='ErrorDataDir'
+ Error='Invalid data directory, choose a different one. Error : [DATADIRERROR]'/>
<InstallExecuteSequence>
- <Custom Action="CheckDataDirectoryEmpty" After="CostFinalize">
+ <Custom Action="CheckDataDirectory" After="CostFinalize">
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
</Custom>
- <Custom Action="ErrorDataDirNotEmpty" After="CheckDataDirectoryEmpty" >DATADIRNOTEMPTY</Custom>
+ <Custom Action="ErrorDataDir" After="CheckDataDirectory">DATADIRERROR</Custom>
<Custom Action="CheckDatabaseProperties" Before="CreateDatabaseCommand">SERVICENAME</Custom>
<Custom Action="CreateDatabaseCommand" After="CostFinalize" >
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>