Reputation: 35
Our InnoSetup uses an external dll to grab and check an xml file for the paths to data files. This works fine in most cases, Windows XP, 7, 10 (32/64bit). But for some few users this fails and for me it fails in Crossover 19 for macOS 10.15. So first I added a delayload to the inno script to get past the "cannot import dll" runtime error.
But then I get "could not call proc" runtime error.
The InnoSetup debugger pointed me at procedure GetExultGamePaths
of our script.
Code in our dll:
extern "C" {
__declspec(dllexport) void __stdcall GetExultGamePaths(char *ExultDir, char *BGPath, char *SIPath, int MaxPath) {
MessageBoxDebug(nullptr, ExultDir, "ExultDir", MB_OK);
MessageBoxDebug(nullptr, BGPath, "BGPath", MB_OK);
MessageBoxDebug(nullptr, SIPath, "SIPath", MB_OK);
int p_size = strlen(ExultDir) + strlen("/exult.cfg") + MAX_STRLEN;
char *p = new char[p_size];
// Get the complete path for the config file
Path config_path(ExultDir);
config_path.AddString("exult.cfg");
config_path.GetString(p, p_size);
setup_program_paths();
const static char *si_pathdef = CFG_SI_NAME;
const static char *bg_pathdef = CFG_BG_NAME;
MessageBoxDebug(nullptr, ExultDir, p, MB_OK);
try {
// Open config file
Configuration config;
if (get_system_path("<CONFIG>") == ".")
config.read_config_file(p);
else
config.read_config_file("exult.cfg");
std::string dir;
// SI Path
config.value("config/disk/game/serpentisle/path", dir, si_pathdef);
if (dir != si_pathdef) {
Path si(ExultDir);
si.AddString(dir.c_str());
si.GetString(SIPath, MaxPath);
} else {
std::strncpy(SIPath, si_pathdef, MaxPath);
}
// BG Path
config.value("config/disk/game/blackgate/path", dir, bg_pathdef);
if (dir != bg_pathdef) {
Path bg(ExultDir);
bg.AddString(dir.c_str());
bg.GetString(BGPath, MaxPath);
} else {
std::strncpy(BGPath, bg_pathdef, MaxPath);
}
} catch (...) {
std::strncpy(BGPath, bg_pathdef, MaxPath);
std::strncpy(SIPath, si_pathdef, MaxPath);
}
delete [] p;
}
The part of the InnoSetup Script
procedure GetExultGamePaths(sExultDir, sBGPath, sSIPath: String; iMaxPath: Integer);
external 'GetExultGamePaths@files:exconfig.dll stdcall delayload';
procedure CurPageChanged(CurPageID: Integer);
var
sBGPath: String;
sSIPath: String;
begin
if CurPageID = DataDirPage.ID then begin
if bSetPaths = False then begin
setlength(sBGPath, 1024);
setlength(sSIPath, 1024);
GetExultGamePaths(ExpandConstant('{app}'), sBGPath, sSIPath, 1023 );
BGEdit.Text := sBGPath;
SIEdit.Text := sSIPath;
end;
end;
end;
The GetExultGamePaths(ExpandConstant('{app}'), sBGPath, sSIPath, 1023 );
is what is producing the "could not call proc" runtime error.
I have no idea why that fails on only a few systems. The full code for our dll and the script is at https://github.com/exult/exult/blob/master/win32/ The dll's code is in exconfig.* and the InnoSetup script is in exult_installer.iss
Upvotes: 1
Views: 1580
Reputation: 35
Through the help of Piotr in our Wine bug report https://bugs.winehq.org/show_bug.cgi?id=49033 it was discovered that using the mingw tool "dllwrap" is broken and added invalid relocation data.
NOT using dllwrap was the solution and fixed it for my Wine/Crossover install. Still waiting for the last user to report back who had this problem on a real Windows 10 installation.
Thanks for your help
Upvotes: 1