At the risk of waxing off-topic…
I wouldn’t bother with using the tchar machinery at all for a new app today. That only ever existed to allow single source builds for win9x (ansi) and winnt (Unicode) binaries. Unless you are really going to do separate builds for win9x nowadays, save yourself the headache of remembering to use tchar/_T everywhere.
Also, be very careful about using the static initializers for GetProcAddress like that. If you then become tempted to also call LoadLibrary and not just GetModuleHandle from a static initializer, your code will violate the API contract for DllMain were it to be used within a dll (as calling LoadLibrary from DllMain is prohibited, and static initializers are invoked from DllMain in a dll).
While we’re dispensing with quasi-OT tidbits, a handy construct for resolving a large number of exports can be patterned thusly:
MyFuncProc MyFunc;
MyOtherFuncProc MyOtherFunc;
OhNoNotAnotherOneProc OhNoNotAnotherOne;
/* … */
struct
{
void * * Ptr; // Pointer to typedef’d function pointer
const char * Symbol; // Associated name of dllexport to resolve
} Symbols =
{
{ (void **) &MyFunc1 , “MyFunc” },
{ (void **) &MyOtherFunc , “MyOtherFunc” },
{ (void **) &OhNoNotAnotherOne, “OhNoNotAnotherOne” }
};
for (size_t i = 0; i < _countof( Symbols ); i += 1)
{
*Symbols[i].Ptr = GetProcAddress( ModuleHandle, Symbols[i].Symbol );
if (*Symbols[i].Ptr == NULL)
{
//
// TODO: Handle API resolution failure as appropriate.
//
}
}
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Joseph M. Newcomer
Sent: Thursday, July 29, 2010 3:51 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Identify Physical Boot Disk
Note that GetProcAddress is the only API call that wants an LPCSTR, that is, an 8-bit character string, even in a Unicode app. However, GetModuleHandle wants an LPCTSTR, that is, either a Unicode or ANSI string, because in Unicode it compiles to GetModuleHandleW and in ANSI it compiles to GetModuleHandleA. To be Unicode-aware, in application space you want to make sure tchar.h is included in your build (for most apps, this happens by default), and the call would be
typedef result_type (callingconvention * TYPENAMEHERE)(args…);
TYPENAMEHERE func;
func = (TYPENAMEHERE)GetProcAddress(GetModuleHandle(_T(“ntdll”)), “name”);
if the function is a WINAPI BOOL SomeName(int x, int y); you would say
typedef BOOL (WINAPI * SomeNameType)(int, int);
SomeNameType SomeName;
SomeName = (SomeNameType)(GetModuleHandle_(T(“ntdll”)), “SomeName”);
if(SomeName == NULL)
// … deal with the situation that the name was not found…
if(SomeName(3, 5))
…
Note that you would not write
if( (*SomeName)(3, 5) )
because that is the old, obsolete K&R syntax and has not been used since the first ANSI (later ISO) compliant C compiler was released. It is accepted only for backward compatibility with existing code and would not be used for new code.
I generally use the variable name as the same name as the function I’m using. With some clever #defines and the use of # and ## you can simplify a lot of the tedium, e.g.,
#define DECLARE_FUNC(name, module) static const name##Type =\
GetProcAddress(GetModuleFileName(_T(#module)), #name)
so I can write, at least in C++ (which is all I use in application space)
DECLARE_FUNC(SomeName, ntdll);
This is an example of what you can do; my own macro system is far more elaborate and reduces the whole thing to a couple lines of code per function. Since I’m usually working in C++ and MFC, I can test to see if the function variable is NULL and if so, I do a throw new CUndefinedFunctionException (class CUndefinedFunctionException : public CException {…stuff…} and put enough information into the constructor to identify the function and module when the catch occurs.
Some day I’m going to figure out how to get all this to work with C++ templates, but that is a project for some later date.
joe
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Maxim S. Shatskih
Sent: Thursday, July 29, 2010 12:25 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Identify Physical Boot Disk
living hell since I’m actually working in usermode on a normal
application
in Visual Studio and have to
create the definitions for and dynamically load all kernel functions.
The proper way is GetProcAddress(GetModuleHandle(“ntdll”), "Name)
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
–
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer