Jump to content
Tuts 4 You

[Need help]c++ EndUpdateResource fail on vs build, why?


Harlock

Recommended Posts

Posted (edited)

Ok so I have coded a program that add resources to an exe and the problem is that I can't use it on an exe build with visual studio if the resource size are <8000 bytes but I can use it on other exe with any resource size..


It's the EndUpdateResource that returns false. I got the error it's ERROR_INVALID_DATA 13 (0xDThe data is invalid


 



HANDLE hResources = BeginUpdateResource(TEXT("file.exe"),FALSE);
if (hResources == NULL)
puts("couldn't not open"); size_t totIt = (size_t)lSize/1000, a;
for (a=1; a <= totIt; ++a){
UpdateResourceA(hResources,"RES",MAKEINTRESOURCE(a),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),&text[(a-1)*1000],1000); }
if (lSize%1000 != 0){
UpdateResourceA(hResources,"RES",MAKEINTRESOURCE(a),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),&text[(a-1)*1000],(lSize%1000)); } EndUpdateResource(hResources,FALSE);// It fails here
free(txt);

Here's my code but I'd guess it's some option in the target file build..


 


Thank you


 


 


Edited by Harlock
Posted

Not sure what your compiler settings are but perhaps you are mix-matching Ansi and Unicode calls. Try changing:


EndUpdateResource to EndUpdateResourceA


and


BeginUpdateResource to BeginUpdateResourceA


 


To make sure that the Ansi versions of those are being called too. Adjust the other params as needed.


Posted

BeginUpdateResource(TEXT("file.exe"),FALSE);//file.exe is not are txt is are string

like this:

//this is c#

string path = "c:\\users\\sean\\desktop\\resourcer.exe";IntPtr hResource = BeginUpdateResource(path, false);
if (hResource.ToInt32() == 0)
throw new Exception("File Not Found");

Posted

I've tried but it changes nothing. I think EndUpdateResource and BeginUpdateResource already call the ANSI version because I don't have to adjust the parameters but I have If I want to use W. Both project are set to use multicode. I've tried in a simple hello world build with vs and it fails but with a code blocks build it works...


 


@accede I don't understand.. But there's no problem opening the file


Posted

[sTAThread]

[DllImport("kernel32.dll", SetLastError = true)]

static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources);

[DllImport("kernel32.dll", SetLastError = true)]

static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);

[DllImport("kernel32.dll", SetLastError = true)]

static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);

static unsafe void Main()

{

string path = "c:\\users\\sean\\desktop\\resourcer.exe";

IntPtr hResource = BeginUpdateResource(path, false);

if (hResource.ToInt32() == 0)

throw new Exception("File Not Found");

string newMessage = File.ReadAllText("c:\\users\\sean\\desktop\\newMessage.txt");

Byte[] bytes = new ASCIIEncoding().GetBytes(newMessage);

GCHandle bHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);

IntPtr ptr = bHandle.AddrOfPinnedObject();

ushort id = (ushort)Language.MakeLanguageID();

if (UpdateResource(hResource, "FILE", "message.txt", id, ptr, (uint)bytes.Length))

EndUpdateResource(hResource, false);

else

MessageBox.Show("Did not update", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

public static class Language

{

public static int MakeLanguageID()

{

CultureInfo currentCulture = CultureInfo.CurrentCulture;

int pid = GetPid(currentCulture.LCID);

int sid = GetSid(currentCulture.LCID);

return (((ushort)pid) << 10) | ((ushort)sid);

}

public static int GetPid(int lcid)

{ return ((ushort)lcid) & 0x3ff; }

public static int GetSid(int lcid)

{ return ((ushort)lcid) >> 10; }

}

}

her is are samble on c# i found this her :http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/d2b07963-8722-4da7-9317-87c0f1d29a93/

Posted

Thanks but that doesn't help me x)


Posted

I once had the same problem.


Try  to remove the relocations and the .reloc section, if there are any. I suggest you use CFF explorer for this.


 


If that doesnt work, i'd like a copy of the vs .exe file you have there..


Posted

@deepzero thank you it worked! Can you explain why?


Posted

If i remember correctly, it's because the Resource handling APIs dont look at the complete section table, but only the resource section (and thus implicitly assume the resource section is the last section of the file).


You should try to somehow enlarge the resource section, either by moving the .reloc section further "down" or by making .rsrc the last section of the file.


Posted

Thank you it's very usefull information. But I still don't understand why It's working with large ressource and not small with the .reloc section. Why should I enlarge the ressource section?


Posted

Sorry, didnt notice the "<" and wrongly (?) assumed the space used stretches into the .reloc section.


So you are saying that you cannot add a resource of "<8000" bytes, but you can add one that is "<8000" b.?


 


To be perfectly honest: i dont know.


 


Since reloc-data is fully position independent (as opposed to resources), i recommend temporarily removing the .reloc section, saving the file, adding your resources, then re-appending the reloc section (adjusting the respective field in the header). This is an easy thing to do and also dodges the problem of limited space due to the .rsrc section not being the last section.


 


As for the original issue, maybe an alignment problem or some oddity of the Resource-APIs?


You could, of course, debug the APIs to see where it goes wrong... ;)


Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...