views:

1228

answers:

3

I need to remove a subtree in the Windows registry under Windows Mobile 6. The RegDeleteTree function is not available, and SHDeleteKey is (apparently) not available in any static library under the WM6 SDK, though the declaration is available in shlwapi.h.
I tried to get it from shlwapi.dll, like

    typedef DWORD (__stdcall *SHDeleteKey_Proc) (HKEY, LPCWSTR);
    SHDeleteKey_Proc procSHDeleteKey; 
    HINSTANCE shlwapidll = ::LoadLibrary(_T("shlwapi.dll"));
    if(shlwapidll) {
 procSHDeleteKey = 
            (SHDeleteKey_Proc)GetProcAddress(shlwapidll,_T("SHDeleteKeyW"));
        ASSERT(procSHDeleteKey);
    }

But I hit the assert.
Is there a nice way to delete, recursively, a Registry key (empty or not) under Windows Mobile?

A: 

The second argument of GetProcAddress is a LPCSTR (that is, it is not a LPCTSTR). So remove the _T() and try this:

GetProcAddress(shlwapidll, "SHDeleteKeyW");

Does that help solve the problem?

Ashutosh Mehra
Nope: 'GetProcAddressW' : cannot convert parameter 2 from 'const char [13]' to 'LPCWSTR'.
E Dominique
Your're absolutely right -- on Windows CS, there are indeed A and W versions of <code>GetProcAddress</a>, but not so on "regular" Windows. Wonder why...
Ashutosh Mehra
Nearly *every* API in Windows CE is the unicode version. CE has no ASCII version of GetProcAddress.
ctacke
+1  A: 

I guess I found the answer myself in MSDN. It puzzles me that the functionality is not available through the SDK, though...
I put the code from MSDN here as well, just for the record:

//*************************************************************
//
//  RegDelnodeRecurse()
//
//  Purpose:    Deletes a registry key and all it's subkeys / values.
//
//  Parameters: hKeyRoot    -   Root key
//              lpSubKey    -   SubKey to delete
//
//  Return:     TRUE if successful.
//              FALSE if an error occurs.
//
//*************************************************************

BOOL RegDelnodeRecurse (HKEY hKeyRoot, LPTSTR lpSubKey)
{
    LPTSTR lpEnd;
    LONG lResult;
    DWORD dwSize;
    TCHAR szName[MAX_PATH];
    HKEY hKey;
    FILETIME ftWrite;

    // First, see if we can delete the key without having
    // to recurse.

    lResult = RegDeleteKey(hKeyRoot, lpSubKey);

    if (lResult == ERROR_SUCCESS) 
        return TRUE;

    lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey);

    if (lResult != ERROR_SUCCESS) 
    {
        if (lResult == ERROR_FILE_NOT_FOUND) {
            printf("Key not found.\n");
            return TRUE;
        } 
        else {
            printf("Error opening key.\n");
            return FALSE;
        }
    }

    // Check for an ending slash and add one if it is missing.

    lpEnd = lpSubKey + lstrlen(lpSubKey);

    if (*(lpEnd - 1) != TEXT('\\')) 
    {
        *lpEnd =  TEXT('\\');
        lpEnd++;
        *lpEnd =  TEXT('\0');
    }

    // Enumerate the keys

    dwSize = MAX_PATH;
    lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
                           NULL, NULL, &ftWrite);

    if (lResult == ERROR_SUCCESS) 
    {
        do {

            StringCchCopy (lpEnd, MAX_PATH*2, szName);

            if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
                break;
            }

            dwSize = MAX_PATH;

            lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
                                   NULL, NULL, &ftWrite);

        } while (lResult == ERROR_SUCCESS);
    }

    lpEnd--;
    *lpEnd = TEXT('\0');

    RegCloseKey (hKey);

    // Try again to delete the key.

    lResult = RegDeleteKey(hKeyRoot, lpSubKey);

    if (lResult == ERROR_SUCCESS) 
        return TRUE;

    return FALSE;
}

//*************************************************************
//
//  RegDelnode()
//
//  Purpose:    Deletes a registry key and all it's subkeys / values.
//
//  Parameters: hKeyRoot    -   Root key
//              lpSubKey    -   SubKey to delete
//
//  Return:     TRUE if successful.
//              FALSE if an error occurs.
//
//*************************************************************

BOOL RegDelnode (HKEY hKeyRoot, LPTSTR lpSubKey)
{
    TCHAR szDelKey[MAX_PATH*2];

    StringCchCopy (szDelKey, MAX_PATH*2, lpSubKey);
    return RegDelnodeRecurse(hKeyRoot, szDelKey);
}
E Dominique
A: 

You're looking for the RegDeleteTree() function. Just replace RegDeleteKey with it.

Apparently, it took them a while to figure it out, so if you want to support XP or older, you need to have your own implementation of it.

slicedlime
Well, the question was explicitly on Windows Mobile, where RegDeleteTree is not available (as I stated in the question...)
E Dominique