Click here to Skip to main content
Click here to Skip to main content

Automatic release of Win32 objects

, 9 Nov 2006
Rate this:
Please Sign up or sign in to vote.
An article on safe and sound release of Win32 objects.

Introduction

I like to use auto_ptr whenever is possible. It handles a lot of work for me, and saves a lot of debugging time. But couldn't I use the mechanism for other things than pointers? Of course: Win32 objects.

Background

There are some cases where I have to write a large initialization function that creates some handles. It is expected that I check the error code and, if something goes wrong somewhere, I close the created handles and exit the function, just like in the example below.

BOOL Start()
{
    HANDLE hEvt = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (NULL == hEvt)
    {
        printf("Failed to create stop event\n");
        return FALSE;
    }

    HKEY hRegKey;
    if (RegCreateKey(HKEY_LOCAL_MACHINE, "File", &hkey)) 
    {
        printf("Failed to create registry key");

        CloseHandle(hEvt);
        return FALSE;
    }

    HANDLE hFile = CreateFile("registryfile.txt", ...);
    if (NULL == hFile)
    {
        printf("Failed to create file\n");

        RegCloseKey(hRegKey);
        CloseHandle(hEvt);
        return FALSE;
    }

    // .. read something from file

    CloseHandle(hFile);
    RegCloseKey(m_resVal.regKey);
    CloseHandle(hEvt);
    return TRUE;
}

I really don't like this style, because there are a lot of ways this can go wrong:

  • I forget to add code for closing handles.
  • Later in the development stage, I forget to add code for closing handles.
  • Other programmers change my function and doesn't add code to close the handles.
  • An unhandled exception is thrown.
Therefore, I developed a class that can dispose resources in the destructor, just like auto_ptr works. For the moment, there are only a few objects supported, but I intend to expand the class whenever I feel the need to add a new Win32 object.

Using the code

It's as simple as declaring an AutoRes variable whose constructor receives the handle you want to forget about. This is how the function would look like now:

BOOL Start()
{
    HANDLE hEvt = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (NULL == hEvt)
    {
        printf("Failed to create stop event\n");
        return FALSE;
    }
    AutoRes evtRes(hEvt);

    HKEY hRegKey;
    if (RegCreateKey(HKEY_LOCAL_MACHINE, "File", &hkey)) 
    {
        printf("Failed to create registry key");

        return FALSE;
    }
    AutoRes regRes(hRegKey);

    HANDLE hFile = CreateFile("registryfile.txt", ...);
    if (NULL == hFile)
    {
        printf("Failed to create file\n");

        return FALSE;
    }
    AutoRes fileRes(hFile);

    // .. read something from file

    return true;
    // automatic resource release
}

Points of Interest

The class is designed to work as fast as possible and be very small, and some flexibility was sacrificed in the name of speed and simplicity.

Since an instance can only hold a type of handle at a time, a union is used to hold the resource that is to be deleted. An instance can be initialized with specialized constructors, as well as with some specialized functions.

To add a new Win32 object, you'll have to:

  1. If the object is of type HANDLE and is closed with CloseHandle(), use the existing constructor.
  2. If the object is of type HANDLE and is not closed with CloseHandle(), add a new entry in the ResType enumeration, add to the specialized constructor that receives a HANDLE and an enum, then add to the Release() function code for releasing the HANDLE.
  3. If it's not a HANDLE object, add a new entry in the ResType enum and in the ResVal union, add a specialized constructor, and edit the Release() function.
  4. That's all.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Andrei Muraru
Web Developer
Romania Romania
After I finished the university, I worked for two years in gaming industry, as a programmer in DirectX environment.
After that, I switched to computer security, which is a fascinating domain, where a lot of stuffs can be learn and experimented.

Comments and Discussions

 
QuestionCode? PinmemberShawn Poulson9-Nov-06 5:25 
AnswerRe: Code? Pinmemberandrei50089-Nov-06 5:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 9 Nov 2006
Article Copyright 2006 by Andrei Muraru
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid