I'm writing a library function that does some file i/o (using the Windows API).

Granted, such a function will have to open files, create files, read files, and allocate memory for buffers, all of which have the distinct possibility of failing for one reason or another. I want to write proper code that anticipates and can deal with any problems, but I'm not sure which way to do this.

The really simple, cumbersome way I started was something like (pseudocode)
Code:
bool FileFunc ( string infilename, string outfilename, ... )
{
    bool result = false;

    <open input file for reading>

    if ( input file is open )
    {
        <open output file for writing>

        if ( output file is open )
        {
           <allocate buffer>

            if ( buffer is allocated )
            {
                <other code, etc.>

                if ( function succeeds )
                    result = true;

               <free buffer memory>
            }
           <close output file>
        }
        <close input file>
    } 
    return result;
}
But somehow having up to a dozen nested if statements seemed wrong...

I also considered
Code:
int FileFunc ( ... )
{
    if ( input file is NOT open)
        return COULD_NOT_OPEN;
    
    ...

    if ( buffer is NOT allocated )
        return ALLOCATION_ERROR;

    ...

    return SUCCESS;
}

(or setting a global error variable to such values and just returning true/false, like errno...)
But then how would I close files and free memory unless I included the same cleanup function calls in every "if" block?

(In addition, I know the WinAPI supports exception raising / handling...)

So my question is, how would you recommend I handle numerous possible error conditions in a single function?