Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Startool fails to extract data from standard install.exe file #26

Closed
Hypexed opened this issue Jan 20, 2017 · 5 comments
Closed

Startool fails to extract data from standard install.exe file #26

Hypexed opened this issue Jan 20, 2017 · 5 comments

Comments

@Hypexed
Copy link
Contributor

Hypexed commented Jan 20, 2017

I was testing the latest 2.4.1 build. I managed to compile it but it failed to extract data. So then I installed it using apt-get. And that also failed. I'm using Cinnamon Mint x64.

While it fails to extract data files it does manage to extract stardat.mpq but then after loops through looking for other archives before stopping.

I found it can work if I rename the install.exe to StarCraft.mpq and it then extracts files. I tested both an install.exe from a PC StarCraft CD as well as a Starcraft Archive from a Mac CD, which is actually just another install.exe. Both files give the same result as an install.exe or starcraft.mpq. PC install.exe does work with earlier version of Startool, such as 2.2.4.

Also it tries to find the mpqlist.txt where it extracts the data files instead of the current dir meaning it must be specified. This is different to previous behavior which was easier since it could find it.

Here are logs of install.exe and starcraft.mpq:
`damien@damien-Presario-V6500-Notebook-PC ~/Development/stargus-master/build $ startool /media/damien/USB\ Stick data ../mpqlist.txt
Extract from "/media/damien/USB Stick" to "data"
Using mpq list file "../mpqlist.txt"
Please be patient, the data may take a couple of minutes to extract...
Archive "/media/damien/USB Stick/install.exe"
extracted: files\stardat.mpq (578, 61009744 bytes)
Archive "/media/damien/USB Stick/Install.exe"
extracted: files\stardat.mpq (578, 61009744 bytes)
Archive "/media/damien/USB Stick/starcraft.mpq"
Can't open /media/damien/USB Stick/starcraft.mpq
Could not open archive "/media/damien/USB Stick/starcraft.mpq", skipping
Archive "/media/damien/USB Stick/Install.exe"
Archive "/media/damien/USB Stick/starcraft.mpq"
Can't open /media/damien/USB Stick/starcraft.mpq
Could not open archive "/media/damien/USB Stick/starcraft.mpq", skipping
Archive "/media/damien/USB Stick/starcraft.mpq"
Can't open /media/damien/USB Stick/starcraft.mpq
Could not open archive "/media/damien/USB Stick/starcraft.mpq", skipping
Archive "/media/damien/USB Stick/StarCraft.mpq"
Can't open /media/damien/USB Stick/StarCraft.mpq
Could not open archive "/media/damien/USB Stick/StarCraft.mpq", skipping
Archive "/media/damien/USB Stick/StarDat.mpq"
Can't open /media/damien/USB Stick/StarDat.mpq
Could not open archive "/media/damien/USB Stick/StarDat.mpq", skipping
Archive "/media/damien/USB Stick/StarDat.mpq"
Can't open /media/damien/USB Stick/StarDat.mpq
Could not open archive "/media/damien/USB Stick/StarDat.mpq", skipping
DONE!

damien@damien-Presario-V6500-Notebook-PC ~/Development/stargus-master/build $ startool /media/damien/USB\ Stick data ../mpqlist.txt
Extract from "/media/damien/USB Stick" to "data"
Using mpq list file "../mpqlist.txt"
Please be patient, the data may take a couple of minutes to extract...
Archive "/media/damien/USB Stick/install.exe"
Can't open /media/damien/USB Stick/install.exe
Could not open archive "/media/damien/USB Stick/install.exe", skipping
Archive "/media/damien/USB Stick/Install.exe"
Can't open /media/damien/USB Stick/Install.exe
Could not open archive "/media/damien/USB Stick/Install.exe", skipping
Archive "/media/damien/USB Stick/starcraft.mpq"
Archive "/media/damien/USB Stick/StarCraft.mpq"
extracted: files\font\font8.fnt (569, 6443 bytes)
...
extracted: multimaps(2)Challenger.scm (628, 55297 bytes)`

@Hypexed
Copy link
Contributor Author

Hypexed commented Jan 23, 2017

There's something seriously wrong with the code. Once it finds a file to extract the "stardat.mpq" from, it keeps searching. For example if it finds an "install.exe" it still looks for an "Install.exe". The same thing in this case.

But the main problem is with the Todo pointer. So it saves out a file called "remove-stardat.mpq" into the data folder. That;s fine. But, it never gets to it! It never looks in Todo or Todo[0] where that filename is stored. It always skips it and goes to the camel case version at Todo[1]! I've been playing with the code and I can't figure the damn thing out. It doesn't make sense.

When i = 4 c = Todo and that happens. But when it executes it never looks in Todo. It looks in Todo[1]! I think this code needs refactoring.

@Hypexed
Copy link
Contributor Author

Hypexed commented Jan 23, 2017

Okay I found the problem. I knew it would be something simple. I needed a debugger to see it. The Todo case statements are missing breaks! I hate those case statements.

That leaves the issue with the archives. As soon as it finds one it opens it up. But then it keeps looking for other archives. When it fails it skips the rest of the file list and closes the open archive. It then continues along until it reaches the end.

The end result is that it can open an archive and extract a file out but then does nothing else. So it needs to check if an archive is open before attempting to open another and if so skip trying.

On top of this, the specific checks for CDTodo or Todo are a problem also, since the file may not be in that exact location but at another index. Checking "i" for a range would be better than checking a pointer. :-)

@johndh johndh mentioned this issue May 12, 2017
@Hypexed
Copy link
Contributor Author

Hypexed commented May 13, 2017

Suggest fixing it like so. As it stands the code it not manageable. It needs to account for different filenames. And there should be a filename table such as a null terminated string pointer array. Even so it may be best to just scan the folder and match it without case with C functions. Since the list here is now outdated. Accounting for all cases (pun intended ;-) is getting redundant or rather out of control. :-)

Edit: It keeps messing up the code codes for some reason. Not going to try and fix again. What sort of code is a single quote for code? :-?

CDTodo[]:
Control CDTodo[] = { {F,0,"","install.exe" __4}, {F,0,"","Install.exe" __4}, {F,0,"","starcraft.mpq" __4 }, {F,0,"","StarCraft.mpq" __4 }, {F,0,"","installer tome.mpq" __4 }, {F,0,"","Installer Tome.mpq" __4 }, {F,0,"","starcraft archive" __4 }, {F,0,"","StarCraft Archive" __4 }

File extraction loop:
` for (i = 0; i <= 9; ++i) {
Control *c;
unsigned len;

if (i <= 7) {	// CD install.exe or other MPQ file
c = &(CDTodo[i]);
len=sizeof(CDTodo) / sizeof(*CDTodo) - i;
} else {	// stardat.mpq from cd or hard drive
c = &(Todo[i-8]);
len = sizeof(Todo) / sizeof(*Todo) - (i-8);
}

for (u = 0; u < len; ++u) {
switch (c[u].Type) {
case F:
if (MpqFD) break;
if(! (strncmp(c[u].ListFile,"remove-",7)) ) {

// printf("remove\n");
psprintf(buf, c[u].ListFile, Dir);
} else {
psprintf(buf, c[u].ListFile, archivedir);
}
printf("Archive "%s"\n", buf);
if (OpenArchive(buf) == -1) {
printf("Could not open archive "%s", skipping\n", buf);
u=len;
if ((i == 9) && (arcs <2)) {
fprintf(stderr, "Fatal error: Cannot extract data\n");
return 1;
}
} else {
arcs++;
if (i <= 7) {
#ifdef DEBUG
printf("%s:\n", "remove-stardat.mpq");
#endif
RawExtract("files\stardat.mpq", "remove-stardat.mpq");
Todo[0].ListFile = "remove-stardat.mpq";
// printf("R %s:\n", Todo[0].ListFile);
}
}
break;
case M:
ConvertMap(c[u].ListFile, c[u].File);
break;
case R:
ConvertRgb(c[u].ListFile, c[u].File);
break;
case T:
ConvertTileset(c[u].ListFile, c[u].File);
break;
case G:
ConvertGfx(c[u].ListFile, c[u].File, c[u].Arg1);
break;
case U:
ConvertGfu(c[u].ListFile, c[u].File, c[u].Arg1);
break;
case I:
ConvertWidgets(c[u].ListFile, c[u].File, c[u].Arg1);
break;
case N:
ConvertFont(c[u].ListFile, c[u].File, 2, c[u].Arg1);
break;
case W:
ConvertWav(c[u].ListFile, c[u].File, c[u].Arg1);
break;
case H:
ConvertPcx(c[u].ListFile, c[u].File);
break;
case E:
RawExtract(c[u].ListFile, c[u].File);
break;
default:
break;
}
}

if( MpqFD ) {
CloseArchive();
}

if( !strncmp(c[0].ListFile,"remove-",7) ) {
psprintf(buf,c[0].ListFile,Dir);
printf("removing \"%s\"\n",buf);
unlink(buf);
}
}`

@timfel
Copy link
Member

timfel commented May 13, 2017 via email

@Hypexed
Copy link
Contributor Author

Hypexed commented May 13, 2017

I could but I'm not used to GF. In fact my coding is done on my computer and it stays there. Only binaries come out in public. :-)

Yes I hadn't yet added changes to my pull. Still need to figure that one out. Still reading Git docs...

@timfel timfel closed this as completed Sep 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants