Ok, here you have something that you can blindly compile:
Code:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream fs;
[b]fs.open("Gunz.exe", fstream::in | fstream::binary); // Line fixed after thread discussion, thanks.[/b]
char c = fs.get();
unsigned int fsize = 0;
unsigned int sum = 0;
while ((fs.good()) && (!fs.eof())) {
fs.putback(c);
unsigned int var1 = fs.get();
unsigned int var2 = fs.eof() ? 0 : fs.get();
unsigned int var3 = fs.eof() ? 0 : fs.get();
unsigned int var4 = fs.eof() ? 0 : fs.get();
var4 = var4 << 24; // shift
var3 = var3 << 16;
var2 = var2 << 8;
unsigned int dwVal = var4 | var3 | var2 | var1; // add'em all
sum += dwVal;
fsize += 4;
c = fs.get();
}
sum += fsize;
cout << "Checksum for Gunz.exe is " << sum << endl;
}
If i run it i get:
Checksum for Gunz.exe is 3421498287
With Indian Gunz.exe, which is the right checksum if you look into the patch.xml file that the launcher downloads:
Code:
<PATCHNODE file="./Gunz.exe">
<SIZE>2478080</SIZE>
<CHECKSUM>[b]3421498287[/b]</CHECKSUM>
</PATCHNODE>
I also tested it with fmod.dll and others, and it always returns the correct checksum.
Now you should put that code into a function that receives the file name as a parameter, and generate XML with the result, for each file, to have a patch.xml generator.
I may post my generator later, I didn't do it yet because didn't have the time to research how to walk directories in Windows, opendir() seems to be only for *nix, so my current implementation reads from a "filenames.txt".. which is not nice enough for a public release
If it's generating long numbers, check your file size. The gunz.exe for my server is about 25mb, so it generates a big number, but if you pack the exe with UPX or some exe compressor, you will get a nice, tiny number.
EDIT:
About the shifts:
1 unsigned int = 4 bytes = 32 bits
So if you have:
A1 2E F3 01
In the exe file, you need to reverse it (to 01 F3 2E A1)
The shifts work like this:
In this statment:
int var1 = 0;
var1's value is 00 00 00 00
I read the first byte into var1, which gets 00 00 00 A1, note that i do not shift var1.
Then i read the second byte into var2, gets 00 00 00 2E, and shift it 8 bits (1 byte) to the left, which results in 00 00 2E 00.
Now, var3 gets 00 00 00 F3, and i shift it 2 bytes to the left: 00 F3 00 00
Finally, var4 gets 00 00 00 01, and i shift it 3 bytes to the left: 01 00 00 00.
Ok, now dwVal is bitwise OR between 00 00 00 A1 | 00 00 2E 00 | 00 F3 00 00 | 01 00 00 00 = 01 F3 2E A1, the value i needed

.
So.. nothing wrong with the shift, and the code is working fine here. Just
pack your exe with UPX, make it smaller, and you will get a tiny number.