by_library/windows_registry/registry_functions/registry_functions.cpp

[C++ only] Illustrates use of the Windows Registry library function reg_get_string_value() component.

/* /////////////////////////////////////////////////////////////////////////
 * File:        by_library/windows_registry/registry_functions/registry_functions.cpp
 *
 * Purpose:     C++ example program demonstrating use of the Windows Registry
 *              library.
 *
 * Created:     22nd May 2006
 * Updated:     11th April 2007
 *
 * www:         http://www.stlsoft.org/
 *
 * License:     Copyright (c) 2006-2007, Synesis Software Pty Ltd.
 *              All rights reserved.
 *
 *              (Licensed under the Synesis Software Open License)
 *
 *              This source code is placed into the public domain 2006
 *              by Synesis Software Pty Ltd. There are no restrictions
 *              whatsoever to your use of the software.
 *
 * ////////////////////////////////////////////////////////////////////// */


/* WinSTL Header Files */
#include <winstl/registry/functions.hpp>
#include <winstl/error/error_desc.hpp>


/* Standard C++ Header Files */
#include <exception>
#include <iostream>

using std::cerr;
using std::cin;
using std::cout;
using std::endl;

/* Standard C Header Files */
#include <stdlib.h> // for EXIT_FAILURE, EXIT_SUCCESS

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

int main()
{
    try
    {
        // 1. Pass NULL and 0 to elicit the required size.
        size_t  cchBuffer   =   0;
        LONG    res;

        res = winstl::reg_get_string_value(HKEY_CURRENT_USER, "Environment", static_cast<char*>(0), cchBuffer);

        // 2. Now create an instance of stlsoft::auto_buffer to
        // hold the value, based on the size elicited by the
        // previous call.
        stlsoft::auto_buffer<TCHAR>     buff(cchBuffer);

        // 3. Now call again, this time checking the return code
        cchBuffer   =   buff.size();
        res         =   winstl::reg_get_string_value(HKEY_CURRENT_USER, "Environment", &buff[0], cchBuffer);

        if(ERROR_SUCCESS == res)
        {
            // 3.a Print out the value, which will be nul-terminated
            cout << "The value is: " << buff.data() << endl;
        }
        else
        {
            // 3.b Display the error. (error_desc is a class that converts a
            // Win32 error code into the corresponding string, and for which
            // a stream insertion operator is defined, making it rather
            // convenient, as you can see.)
            cerr << "Failed to elicit value: " << winstl::error_desc(res) << endl;
        }

#if 0
        // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

        // NOTE: In a real system, the size of the value can change at any time,
        // including between the first call (which elicits the size) and the
        // second (which elicits the contents). (Yes, you may wonder at the sense
        // of a global information database that engenders race conditions!) Hence,
        // the return value of the second call should be checked for
        // ERROR_MORE_DATA, in which circumstance the buffer should be expanded
        // and the call repeated. The following #ifdef'd out code shows how this
        // could be implemented. It has a goto in it, which is why I've #ifdef'd
        // it out. (Too many people have a cow when they see a goto, which is a
        // fair enough response ...)

        // 3. Now call again, this time checking the return code
retry:
        cchBuffer   =   buff.size();
        res         =   winstl::reg_get_string_value(HKEY_CURRENT_USER, "Environment", &buff[0], cchBuffer);

        if(ERROR_SUCCESS == res)
        {
            // 3.a Print out the value, which will be nul-terminated
            cout << "The value is: " << buff.data() << endl;
        }
        else if(ERROR_MORE_DATA == res)
        {
            // 3.b Need to resize the buffer according to the latest (failed)
            // retrieval attempt.
            buff.resize(cchBuffer);
            goto retry;
        }
        else
        {
            // 3.c Display the error. (error_desc is a class that converts a
            // Win32 error code into the corresponding string, and for which
            // a stream insertion operator is defined, making it rather
            // convenient, as you can see.)
            cerr << "Failed to elicit value: " << winstl::error_desc(res) << endl;
        }

        // Of course, a for or a while loop would be best. As an exercise for
        // the reader, perhaps you might work out the minimum amount of code
        // that takes into account all the above behaviour, with only one call
        // site of reg_get_string_value(). ;-)

        // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
#endif

        return EXIT_SUCCESS;
    }
    catch(std::exception &x)
    {
        fprintf(stderr, "Error: %s\n", x.what());

        return EXIT_FAILURE;
    }
    catch(...)
    {
        fprintf(stderr, "Unknown error\n");

        return EXIT_FAILURE;
    }
}

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

Generated on Thu Jun 10 08:55:05 2010 for STLSoft by  doxygen 1.5.6