The Windows Registry 11

 

 

 

 

 

Determining the Registry Size Program Example

 

On Windows 2000, it is common for an installation utility to check the current and maximum size of the registry to determine whether there is enough available space for the new data it will be adding. The following program example demonstrates how to do this programmatically using the "% Registry Quota In Use" performance counter within the System object. The following sample uses performance data helper (PDH) to obtain the counter value; it must be linked with Pdh.lib. PDH is a high-level set of APIs used to obtain performance data.

Note that it is not necessary to implement this registry size-check on Windows Server 2003 or Windows XP because they do not have a registry quota limit.

Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.

Then, add the source file and give it a suitable name.

Next, add the following source code.

 

//***************************************************

//  Determines the current and maximum registry size.

//***************************************************

#include <windows.h>

#include <stdio.h>

// Don't forget to link to pdh.lib library

#include <pdh.h>

 

PDH_STATUS GetRegistrySize(LPTSTR szMachineName, LPDWORD lpdwCurrentSize, LPDWORD lpdwMaximumSize);

 

//*****************************************************************

//  Entry point for the program. This function demonstrates how to

//  use the GetRegistrySize() function implemented below.

//  It will use the first argument, if present, as the name of the

//  computer whose registry you wish to determine. If unspecified,

//  it will use the local computer.

//*****************************************************************

int wmain(int argc, WCHAR *argv[])

{

    LPTSTR      szMachineName  = NULL;

    PDH_STATUS  pdhStatus      = 0;

    DWORD       dwCurrent      = 0;

    DWORD       dwMaximum      = 0;

      LPTSTR szMessage;

 

      wprintf(L"Usage: %s <computer_name>\n", argv[0]);

      wprintf(L"Else, local computer will be used as default\n\n");

 

    // Allow a computer name to be specified on the command line

      // Else, just query the local machine

    if (argc > 1)

        szMachineName = argv[1];

 

    // Get the registry size.

    pdhStatus=GetRegistrySize(szMachineName, &dwCurrent, &dwMaximum);

 

    // Print the results.

    if (pdhStatus == ERROR_SUCCESS)

    {

        wprintf(L"\n");

        wprintf(L"Registry size: %ld bytes\n", dwCurrent);

        wprintf(L"Max registry size: %ld bytes\n", dwMaximum);

 

    }

    else

    {

        // If the operation failed, print the PDH error message

        szMessage = NULL;

 

            // A system (GetLastError()) or a PDH error code can be used/extracted

        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |

            FORMAT_MESSAGE_FROM_HMODULE,

            GetModuleHandle(L"PDH.DLL"), pdhStatus,

            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

            szMessage, 0, NULL);

 

        wprintf(L"GetRegistrySize() failed:  %s", szMessage);

 

        LocalFree(szMessage);

    }

 

    return 0;

}

 

//*******************************************************************

//  Retrieves the current and maximum registry size. It gets this

//  information from the raw counter values for the "% Registry Quota

//  In Use" performance counter within the System object.

//  PARAMETERS:  

//      szMachineName - Null-terminated string that specifies the

//          name of the computer whose registry you wish to query.

//          If this parameter is NULL, the local computer is used.

//      lpdwCurrentSize - Receives the current registry size.

//      lpdwMaximumSize - Receives the maximum registry size.

//  RETURN VALUE:

//      ERROR_SUCCESS if successful. Otherwise, the function

//      returns a PDH error code. These error codes can be

//      found in PDHMSG.H. A textual error message can be

//      retrieved from PDH.DLL using the FormatMessage function.

//******************************************************************

PDH_STATUS GetRegistrySize(LPTSTR szMachineName, LPDWORD lpdwCurrentSize, LPDWORD lpdwMaximumSize)

{

    PDH_STATUS  pdhResult   = 0;

    WCHAR       szCounterPath[1024];

    DWORD       dwPathSize  = 1024;

    PDH_COUNTER_PATH_ELEMENTS pe;

    PDH_RAW_COUNTER pdhRawValues;

    HQUERY      hQuery      = NULL;

    HCOUNTER    hCounter    = NULL;

    DWORD       dwType      = 0;

 

    // Open PDH query

    pdhResult = PdhOpenQuery(NULL, 0, &hQuery);

    if (pdhResult != ERROR_SUCCESS)

        return pdhResult;

      else

            wprintf(L"PdhOpenQuery() looks fine!\n");

 

      // Exception handling, __try-__finally

    __try

    {

        // Create counter path

        pe.szMachineName     = szMachineName;

        pe.szObjectName      = L"System";

        pe.szInstanceName    = NULL;

        pe.szParentInstance  = NULL;

        pe.dwInstanceIndex   = 1;

        pe.szCounterName     = L"% Registry Quota In Use";

 

        pdhResult = PdhMakeCounterPath(&pe, szCounterPath, &dwPathSize, 0);

        if (pdhResult != ERROR_SUCCESS)

            __leave;

            else

                  wprintf(L"PdhMakeCounterPath() is OK!\n");

 

        // Add the counter to the query

        pdhResult=PdhAddCounter(hQuery, szCounterPath, 0, &hCounter);

        if (pdhResult != ERROR_SUCCESS)

            __leave;

            else

                  wprintf(L"PdhAddCounter() is working!\n");

 

        // Run the query to collect the performance data

        pdhResult = PdhCollectQueryData(hQuery);

        if (pdhResult != ERROR_SUCCESS)

            __leave;

            else

                  wprintf(L"Well, PdhCollectQueryData() is also working!\n");

 

        // Retrieve the raw counter data:

        //    The dividend (FirstValue) is the current registry size

        //    The divisor (SecondValue) is the maximum registry size

        ZeroMemory(&pdhRawValues, sizeof(pdhRawValues));

        pdhResult = PdhGetRawCounterValue(hCounter, &dwType, &pdhRawValues);

        if (pdhResult != ERROR_SUCCESS)

            __leave;

            else

                  wprintf(L"PdhGetRawCounterValue() is OK!\n");

 

        // Store the sizes in variables.

        if (lpdwCurrentSize)

            *lpdwCurrentSize = (DWORD)pdhRawValues.FirstValue;

        

        if (lpdwMaximumSize)

            *lpdwMaximumSize = (DWORD)pdhRawValues.SecondValue;

 

    }

    __finally

    {

        // Close the query

        if(PdhCloseQuery(hQuery) == ERROR_SUCCESS)

                  wprintf(L"hQuery handle was closed successfully!\n");

    }

    return 0;

}

 

Build and run the project. The following screenshot is a sample output.

 

Determining the Registry Size Program Example: A sample console program output in action

 

 

 

 

< Windows Registry 10 | Windows Registry Index | Win32 Programming | Windows Registry 12 >