Click here to Skip to main content
15,881,819 members
Please Sign up or sign in to vote.
5.00/5 (7 votes)
See more:
It seems like I'm the only one on the plant (Earth) who is having this problem...

I wrote a very simple method which dynamically loads and executes RegCreateKeyExA and I get the following error from "GetProcAddress(Avapi32,RegCreateKeyExA)"
Error 1150. The specified program requires a newer version of Windows.


The same code works fine on Windows 7, so I went back to WINXP and opened advapi32.dll with notepad, and sure enough, RegCreateKeyExA was there.... what am I missing here :confused:

Here is the method:
UINT
regDyFunc::DyRegCreateKeyEx(HKEY hMainKey,
			   LPCTSTR lpSubKey,
			   PHKEY phkResult,
                           LPDWORD lpdwDisposition )
{
 // The type of the wanted function
 typedef UINT (CALLBACK* REGFUNCCreateKeyEx)( 	//LONG WINAPI RegCreateKeyEx(
  HKEY,	  //  __in        HKEY hKey,
  LPCTSTR,//  __in        LPCTSTR lpSubKey,
  DWORD,  //  __reserved  DWORD Reserved,
  LPTSTR, //  __in_opt    LPTSTR lpClass,
  DWORD,  //  __in        DWORD dwOptions,
  REGSAM, //  __in        REGSAM samDesired,
  LPSECURITY_ATTRIBUTES /*__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,*/,
  PHKEY,  //  __out       PHKEY phkResult,
  LPDWORD //  __out_opt   LPDWORD lpdwDisposition
 );

 REGFUNCCreateKeyEx regFuncCreateKeyEx; // Stores the wanted function
	
 long lResult = ERROR_SUCCESS; // Used to check for failure and return value

 // Verify parameters
 if (lpSubKey == NULL)
	lResult = ERROR_INVALID_ADDRESS;

 // Dynamically load the registry function
 if (lResult == ERROR_SUCCESS){
	regFuncCreateKeyEx =
              (REGFUNCCreateKeyEx)GetProcAddress(
                     hAvapi32,
                     (LPCSTR)"RegCreateKeyExA" );
        
	regDyFunc::csLastCall = "GetProcAddress(Avapi32,RegCreateKeyExA)";
	lResult = GetLastError();
 }
 
 // Execute the function
 if (lResult == ERROR_SUCCESS)
 {
	regDyFunc::csLastCall = "RegCreateKeyExA";
	lResult  = regFuncCreateKeyEx(
                                      hMainKey,
                                      lpSubKey,
                                      0,
                                      NULL,
                                      REG_OPTION_NON_VOLATILE,
                                      KEY_ALL_ACCESS,NULL,
                                      phkResult,
                                      lpdwDisposition);

 }
	
 return lResult;
}



And the function to load the library:
C#
bool
regDyFunc::openModules(void)
{
    bool bRet = true;
    regDyFunc::hAvapi32 = LoadLibrary("Advapi32");
    if (regDyFunc::hAvapi32 == NULL){
        _tprintf(_T("Unable to load Advapi32\n"));
        bRet = false;
    }
    if (bRet){
        // Always try to load all modules
        regDyFunc::hKtmW32 = LoadLibrary("KtmW32");
        //Give an error only if its Vista or later
        if ((regDyFunc::hKtmW32 == NULL) && (regDyFunc::Is_Vista_or_Later())) {
            _tprintf(_T("Unable to load KtmW32\n"));
            bRet = false;
        }
    }
    return bRet;
}


Thanks in advance
Posted
Updated 19-Jan-11 4:51am
v2
Comments
Henry Minute 19-Jan-11 10:52am    
Good question.
Regrettably I have no solution but a good question, nonetheless.
Ribhi Kamal 19-Jan-11 10:54am    
I take pride in asking good questions
fjdiewornncalwe 19-Jan-11 11:06am    
A great question. I'm going to have to look into this because I'm very curious about it. I don't have an answer now, but if I find something out I'll let you know.
HimanshuJoshi 19-Jan-11 11:08am    
http://msdn.microsoft.com/en-us/library/ms724844(v=vs.85).aspx tells me that minimum supported client is Windows 2000 Professional, so this should work on XP. I suggest better ask in MSDN support forum
Nish Nishant 19-Jan-11 11:09am    
How exactly do you get this error? When GetProcAddress is called, Windows pops up this messagebox with that text?

1 solution

Well, the fix was to use the Best Practices, which means:
1) Only call GetLastError for functions that actually SET it.
2) Only call GetLastError when the function RETURNS an error status.
3) Only call GetLastError immediately AFTER calling a function that returns an error status.


In my case I wasn't following #2 so the following fixed the problem:
C#
// Dynamically load the registry function
if (lResult == ERROR_SUCCESS){
   regFuncCreateKeyEx =
             (REGFUNCCreateKeyEx)GetProcAddress(
                    hAvapi32,
                    (LPCSTR)"RegCreateKeyExA" );
   regDyFunc::csLastCall = "GetProcAddress(Avapi32,RegCreateKeyExA)";
   if (!regFuncCreateKeyEx)
       lResult = GetLastError();
}



Thanks for you help, Codeproject rocks!
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 19-Jan-11 12:33pm    
All right, I just tried to obtain the function and it immediately worked, so I started to scratch my head...
Nish Nishant 19-Jan-11 12:35pm    
Ok, so the code was always working fine but since you checked the error code even when there was no error you assumed there was a problem?
Ribhi Kamal 19-Jan-11 12:45pm    
The function actually works just fine. It creates the key and its subkeys and opens the key if it already exists.. should I still be worried?
Nish Nishant 19-Jan-11 12:46pm    
No, there's nothing to worry at all.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900