Due to some brain damage, (either in windows or in me), there appears to be no API to get the size of a windows resource produced by LoadResource. The return type is HANDLE, but it's not a real handle, and GlobalSize does not work on it.
So absent the API, I need to embed my blobs in some simple format that will
wrap them with their length. Surely there must be a utility somewhere that
rewrites a file as a length, followed by the contents of the file, or some
such trivial encoding.
Not an answer to your question as to a helper for the work-around, but the API is not missing.
When you called LoadResource, you passed in the module handle and a HRSRC handle.
If you call SizeOfResource with the same arguments, it returns the size of the resource.
Related
please consider the microsoft "AVI mux" directshow filter, it have CLSID: {E2510970-F137-11CE-8B67-00AA00A3F1A6}
suppose that, just for an experiment, I want to change this code. I opened the file qcap.dll with WinHex qcap.dll but I can not find this string inside it, then I wonder where is written, if it's written in qcap.dll. Thanks
It is there but it is not a string, it is hardcoded as a binary value. Then you are to consider registration of the DLL, which stands alone from file contents. Whatever you are trying to achieve patching a stock DLL, it is wrong and a no-go for a real task. Not to mention that the file is proceted by System Restore and reversing is likely to be an EULA violation.
I am currently studying the VersionInfo Resource(s) for Windows.
It is kind of confusing that you can have multiple VS_VERSIONINFO/VS_FIXEDFILEINFO structures within a VS_VERSION_INFO Resource.
As far as I get it, you can have multiple RT_VERSION->VS_VERSION_INFO Resources with different language ids. (Just as shown as in the picture)
These 2 language ids (0 and 1031) have actually 2 different VS_VERSIONINFO/VS_FIXEDFILEINFO in each.
0 is a neutral language and seems to be prioritized than your actual local language id (which is 1031).
To me this seems to be kind of a mess and confusing.
How is it possible to have multiple VS_VERSIONINFO structures within a VS_VERSION_INFO resource and what is the point? How does Windows interpret multiple Resources,Structures?
And how is it possible to get only one piece of buffer when you call GetFileVersionInfo?
It all makes little sense to me and I can't find much documentation about it.
You have to make a difference between the textual infos, and the bare VS_FIXEDFILEINFO block. The first block exist only once. The text Information is language dependent.
"Windows" does not prefers a specific one ;) What the explorer does is a different thing. It just shows the resource information. But in fact this is just the string information and not the information from the fixed version info.
When you call GetFileVersionInfo you get all language blocks! VerQueryValue is used to access he separate blocks.
The installer and other routines inside windows only use the VS_FIXEDFILEINFO block. They don't care about any text blocks. And this block only exists once.
I assume that the explorer just shows the first text block and also doesn't prefer a specific one. Just use a text editor and exchange the blocks in the resource file. But maybe the resource compiler reorders them.
To access the separate parts:
- VerQueryValue with "\" gives you the fixed version info block VS_FIXEDFILEINFO
- VerQueryValue with "\VarFileInfo\Translation" gives you a list of translations
- with "\StringFileInfo\langId_charset\keyname" you get the specific string parts
You find this information in the MSDN
Is the ReplaceFile Windows API a convenience function only, or does it achieve anything beyond what could be coded using multiple calls to MoveFileEx?
I'm currently in the situation where I need to
write a temporary file and then
rename this temporary file to the original filename, possibly replacing the original file.
I thought about using MoveFileEx with MOVEFILE_REPLACE_EXISTING (since I don't need a backup or anything) but there is also the ReplaceFile API and since it is mentioned under Alternatives to TxF.
This got me thinking: Does ReplaceFile actually do anything special, or is it just a convenience wrapper for MoveFile(Ex)?
I think the key to this can be found in this line from the documentation (my emphasis):
The replacement file assumes the name of the replaced file and its identity.
When you use MoveFileEx, the replacement file has a different identity. Its creation date is not preserved, the creator is not preserved, any ACLs are not preserved and so on. Using ReplaceFile allows you to make it look as though you opened the file, and modified its contents.
The documentation says it like this:
Another advantage is that ReplaceFile not only copies the new file data, but also preserves the following attributes of the original file:
Creation time
Short file name
Object identifier
DACLs
Security resource attributes
Encryption
Compression
Named streams not already in the replacement file
For example, if the replacement file is encrypted, but the
replaced file is not encrypted, the resulting file is not
encrypted.
Any app that wants to update a file by writing to a temp and doing the rename/rename/delete dance (handling all the various failure scenarios correctly), would have to change each time a new non-data attribute was added to the system. Rather than forcing all apps to change, they put in an API that is supposed to do this for you.
So you could "just do it yourself", but why? Do you correctly cover all the failure scenarios? Yes, MS may have a bug, but why try to invent the wheel?
NB, I have a number of issues with the programming model (better to do a "CreateUsingTemplate") but it's better than nothing.
I got some problem with using FindFirstFile/FindNextFile. As I know it returns a handle but I'm not capable to use it with CreateFileMapping/ReadFile because value of returned handle is different than returned from CreateFile. First question: What's the difference between these two handles and the second: is it possible to convert this handle? My only idea is to get the file name and than use CreateFile.
Regards
What's the difference between these two handles
The first one is search handle. Underneath, there's an iterator reading the directory entry in the file system.
The second one is an iterator reading the file content. The file may even be on another volume than the directory entry you've used to locate it. To learn more about that, google "B-Tree" and then "NTFS"
get the file name and than use CreateFile
Yes, but you need to combine directory + file name. I usually call PathAppend API (CPathT::Append, to be precise) to do that.
I'm working with visual studio 2003 on Windows 7.
I'm trying to embed a binary file into a windows console application (c++).
I added into the resource script (.rc file) the following line:
SampleFile RCDATA "c:\\sample.zip"
and also added the following code to access the file:
HRSRC hResource = FindResource(NULL, (LPCSTR)"SampleFile", RT_RCDATA);
LPVOID l = LockResource(hResource);
now, hResource is a valid handle and LockResource also succeeds but the pointer l points to some struct, probably a header, that is followed by the actual data of the zip file I was trying to embed.
I managed to spot that the second DWORD in the said header is the size of the file, and the name of the resource ("SampleFile") also appears in the header, but couldn't manage to find a description of the header or at least the header size.
As Luke said, You're missing a LoadResource() call in the middle.
FindResource() essentially gives you a pointer/handle to the resource header, LoadResource() reads that header and gives you a value that (on win32) points to the data itself, but used to be an HGlobal that could be moved in memory. You would then lock this location and get a pointer using LockResource().
The usage stays the same on Win32 though.
From MSDN
Do not try to lock a resource by using the handle returned by the FindResource or FindResourceEx function. Such a handle points to random data.
The resource header is described in MSDN as the fictional RESOURCEHEADER structure.
This reply is largely taken from Raymond Chen's article on 16-bit resource management
You have an Api function to get size of resource SizeofResource.
The pointer points to the beginning of the file added as resource (in your case "c:\sample.zip).
If you want you can pass that pointer to a uncompress library or simply write to disk.
thanks for the help.
Actually I did have LoadResource in my code, which got lost in the copy paste to the site.
However, that is related to the problem in my code.
The code looked like this: (Psuedo code this time)
HANDLE hFindHandle = FindResource(...);
LoadResource(hFindHandle and Module Handle);
and then
LPVOID l = LockResource(hFindHandle);
I didn't use the returned value from the LoadResource but kept using the one from the FindResource, so even though I did call LoadResource, I didn't get the correct pointer from LockResource.