1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
|
#include <wx/dir.h>
#include <wx/filefn.h>
#include <wx/sstream.h>
#include <wx/wfstream.h>
#include "generated/configure_launcher.h"
#include "apis/FlagListManager.h"
#include "global/Compatibility.h"
#include "global/ProfileKeys.h"
#if IS_WIN32
#include "RegistryKeys.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
extern HKEY GetRegistryKeyname(wxString& keyNameOut);
bool enumRegistryValue(HKEY parent, DWORD index, wxString& valueNameOut, wxString& valueOut) {
valueNameOut.Clear();
valueOut.Clear();
WCHAR valueNameBuffer[512];
DWORD valueNameBufferSize = static_cast<DWORD>(sizeof(valueNameBuffer));
BYTE valueBuffer[512];
DWORD valueBufferSize = static_cast<DWORD>(sizeof(valueBuffer));
DWORD type;
LONG ret = RegEnumValueW(parent, index, valueNameBuffer, &valueNameBufferSize, NULL, &type, valueBuffer, &valueBufferSize);
if (ret != ERROR_SUCCESS) {
return false;
}
valueNameOut = wxString(valueNameBuffer, valueNameBufferSize);
switch (type) {
case REG_BINARY:
valueOut = wxString::From8BitData(reinterpret_cast<char*>(valueBuffer), valueBufferSize);
break;
case REG_DWORD:
{
ULONG val = *reinterpret_cast<ULONG*>(valueBuffer); // I feel dirty...
valueOut << val;
break;
}
case REG_QWORD:
{
ULONGLONG val = *reinterpret_cast<ULONGLONG*>(valueBuffer); // I feel dirty...
valueOut << val;
break;
}
case REG_SZ:
valueOut = wxString(reinterpret_cast<wchar_t*>(valueBuffer), (valueBufferSize / sizeof(WCHAR)) - 1);
break;
default:
return false;
}
return true;
}
void copyValuesIntoConfig(HKEY key, wxFileConfig& config, const wxString& sectionName) {
config.SetPath(sectionName);
for (DWORD i = 0; ; ++i) {
wxString name;
wxString value;
if (!enumRegistryValue(key, i, name, value))
{
break;
}
config.Write(name, value);
}
}
#endif
#define FSO_CONFIG_FILENAME _T("fs2_open.ini")
extern wxFileName GetPlatformDefaultConfigFilePathNew();
extern wxFileName GetPlatformDefaultConfigFilePathOld();
namespace Compatibility
{
bool SynchronizeOldPilots(ProMan* profileManager)
{
if (!(FlagListManager::GetFlagListManager()->GetBuildCaps() & FlagListManager::BUILD_CAPS_SDL))
{
// Nothing to do, we have an old build
return true;
}
wxLogStatus(_T("Synchronizing old pilot files..."));
wxFileName oldConfigFolder;
#if IS_WIN32
wxString rootPath;
if (!profileManager->ProfileRead(PRO_CFG_TC_ROOT_FOLDER, &rootPath))
{
wxLogWarning(_T("No TC root folder in configuration!"));
return false;
}
oldConfigFolder.AssignDir(rootPath, wxPATH_NATIVE);
#else
oldConfigFolder.Assign(GetPlatformDefaultConfigFilePathOld());
#endif
oldConfigFolder.AppendDir(_T("data"));
oldConfigFolder.AppendDir(_T("players"));
wxFileName newConfigFolder(GetPlatformDefaultConfigFilePathNew());
newConfigFolder.AppendDir(_T("data"));
newConfigFolder.AppendDir(_T("players"));
if (!oldConfigFolder.DirExists())
{
// No old config folder so there are no pilot files to copy
wxLogStatus(_T(" Old pilot directory does not exist, nothing to be done."));
return true;
}
// Heuristic to determine if the files were copied before
if (newConfigFolder.DirExists())
{
// new players directory already exists so it was already used before
// Don't try to copy in this case
wxLogStatus(_T(" New pilot directory already exists, was probably copied before."));
return true;
}
if (!newConfigFolder.Mkdir(0777, wxPATH_MKDIR_FULL))
{
wxLogError(_T("Failed to create directory '%s'"), newConfigFolder.GetFullPath().c_str());
return false;
}
// If we are here we need to copy the old pilot files
wxDir oldDir(oldConfigFolder.GetFullPath());
wxString pilotFile;
bool cont = oldDir.GetFirst(&pilotFile, wxEmptyString, wxDIR_FILES);
wxLogStatus(_T("Copying pilot files from '%s' to '%s'."), oldConfigFolder.GetFullPath().c_str(), newConfigFolder.GetFullPath().c_str());
while (cont)
{
wxFileName pilotFileName;
pilotFileName.Assign(oldConfigFolder.GetFullPath(), pilotFile);
wxFileName newPilotFile;
newPilotFile.Assign(newConfigFolder.GetFullPath(), pilotFile);
wxLogStatus(_T(" Copying '%s' to '%s'"), pilotFileName.GetFullPath().c_str(), newPilotFile.GetFullPath().c_str());
if (!wxCopyFile(pilotFileName.GetFullPath(), newPilotFile.GetFullPath()))
{
wxLogError(_T("Failed to copy pilot file '%s'!"), pilotFileName.GetFullPath().c_str());
}
cont = oldDir.GetNext(&pilotFile);
}
wxLogStatus(_T(" Done copying pilot files."));
return true;
}
bool MigrateOldConfig()
{
if (!(FlagListManager::GetFlagListManager()->GetBuildCaps() & FlagListManager::BUILD_CAPS_SDL))
{
// Nothing to do, we have an old build
return true;
}
wxFileName newName = GetPlatformDefaultConfigFilePathNew();
newName.SetFullName(FSO_CONFIG_FILENAME);
if (wxFile::Exists(newName.GetFullPath())) {
// New file already exists, nothing to do here
return true;
}
wxLogStatus(_T("Migrating old configuration..."));
#if IS_WIN32
// On Windows this is implemented by iterating through the registry and copying the values to the config file
wxString keyName;
HKEY useKey = GetRegistryKeyname(keyName);
LONG ret = ERROR_SUCCESS;
HKEY regHandle = 0;
ret = RegOpenKeyExW(useKey,
keyName.wc_str(),
0,
KEY_READ,
®Handle
);
if (ret != ERROR_SUCCESS) {
// Key does not exists or some other error, assume it doesn't exist
return true; // No old config, nothing to do here
}
wxStringInputStream configBlankInputStream(_T(""));
wxFileConfig outConfig(configBlankInputStream, wxMBConvUTF8());
copyValuesIntoConfig(regHandle, outConfig, REG_KEY_DEFAULT_FOLDER_CFG);
for (DWORD i = 0;; ++i) {
WCHAR subkey[255];
DWORD subkeyLen = 255;
LONG res = RegEnumKeyExW(regHandle, i, subkey, &subkeyLen, NULL, NULL, NULL, NULL);
if (res != ERROR_SUCCESS)
break;
HKEY handle;
res = RegOpenKeyExW(regHandle, subkey, 0, KEY_READ, &handle);
if (res != ERROR_SUCCESS) {
continue;
}
wxString sectionName(subkey, subkeyLen);
sectionName = wxString::FromAscii("/") + sectionName;
copyValuesIntoConfig(handle, outConfig, sectionName);
RegCloseKey(handle);
}
RegCloseKey(regHandle);
wxLogStatus(_T("Writing fs2_open.ini to %s"), newName.GetFullPath().c_str());
wxFFileOutputStream outFileStream(newName.GetFullPath());
outConfig.Save(outFileStream, wxMBConvUTF8());
#else
wxFileName oldName = GetPlatformDefaultConfigFilePathOld();
oldName.SetFullName(FSO_CONFIG_FILENAME);
if (!wxCopyFile(oldName.GetFullPath(), newName.GetFullPath())) {
wxLogError(_T("Failed to copy old configuration file to new location!"));
return false;
}
#endif
wxLogStatus(_T("Migration finished."));
return true;
}
}
|