How can I tell that somebody used the MAKEINTRESOURCE macro to smuggle an integer inside a pointer?

Raymond Chen

Raymond

Many functions and interfaces provide the option of passing either a string or an integer. The parameter is formally declared as a string, and if you want to pass an integer, you smuggle the integer inside a pointer by using the MAKE­INT­RESOURCE macro. For example, the Find­Resource function lets you load an resource specified by integer identifier by passing the identifier in the form MAKE­INT­RESOURCE(ID). You can tell that it was the resource-loading functions who created the macro in the first place, since the name of the macro is “make integer resource.” But other functions use the MAKE­INT­RESOURCE convention, too. The Get­Proc­Address function lets you obtain a function exported by ordinal if you smuggle the ordinal inside a pointer: Get­Proc­Address(hModule, MAKE­INT­RESOURCEA(ordinal)). (You have to use MAKE­INT­RESOURCEA because Get­Proc­Address explicitly takes an ANSI string.) What if you’re implementing a function whose interface requires you to accept both strings and integers-smuggled-inside strings? For example, maybe you’re implementing IContext­Menu::Invoke­Command, which needs to look at the CM­INVOKE­COMMAND­INFO.lpVerb member and determine whether the invoker passed a string or a menu offset. You can use the IS_INT­RESOURCE macro. It will return non-FALSE if the pointer you passed is really an integer smuggled inside a pointer.

How does MAKE­INT­RESOURCE work? It just stashes the integer in the bottom 16 bits of a pointer, leaving the upper bits zero. This relies on the convention that the first 64KB of address space is never mapped to valid memory, a convention that is enforced starting in Windows 7.

0 comments

Comments are closed. Login to edit/delete your existing comments