Difference between unsigned char and char pointers
I'm a bit confused with differences between `unsigned char` (which is also `BYTE` in WinAPI) and `char` pointers.

*Currently I'm working with some ATL-based legacy code and I see a lot of expressions like the following:*

    CAtlArray<BYTE> rawContent;
    CALL_THE_FUNCTION_WHICH_FILLS_RAW_CONTENT(rawContent);
    return ArrayToUnicodeString(rawContent);
    // or return ArrayToAnsiString(rawContent);

Now, the implementations of `ArrayToXXString` look the following way:

    CStringA ArrayToAnsiString(const CAtlArray<BYTE>& array)
    {
        CAtlArray<BYTE> copiedArray;
        copiedArray.Copy(array);
        copiedArray.Add('\0');
        
        // Casting from BYTE* -> LPCSTR (const char*).
        return CStringA((LPCSTR)copiedArray.GetData());
    }
    
    CStringW ArrayToUnicodeString(const CAtlArray<BYTE>& array)
    {
        CAtlArray<BYTE> copiedArray;
        copiedArray.Copy(array);
       
        copiedArray.Add('\0');
        copiedArray.Add('\0');

        // Same here.        
        return CStringW((LPCWSTR)copiedArray.GetData());
    }

------

**So, the questions:**

- Is the C-style case from `BYTE*` to `LPCSTR` (`const char*`) safe for all possible cases?

- Is it really necessary to add **double** null-termination when converting the ANSI string to Unicode or is it a typo?

- *Any way to make all this code easier to understand and to maintain?*


Difference between unsigned char and char pointers
===

I'm a bit confused with differences between `unsigned char` (which is also `BYTE` in WinAPI) and `char` pointers.

*Currently I'm working with some ATL-based legacy code and I see a lot of expressions like the following:*

    CAtlArray<BYTE> rawContent;
    CALL_THE_FUNCTION_WHICH_FILLS_RAW_CONTENT(rawContent);
    return ArrayToUnicodeString(rawContent);
    // or return ArrayToAnsiString(rawContent);

Now, the implementations of `ArrayToXXString` look the following way:

    CStringA ArrayToAnsiString(const CAtlArray<BYTE>& array)
    {
        CAtlArray<BYTE> copiedArray;
        copiedArray.Copy(array);
        copiedArray.Add('\0');
        
        // Casting from BYTE* -> LPCSTR (const char*).
        return CStringA((LPCSTR)copiedArray.GetData());
    }
    
    CStringW ArrayToUnicodeString(const CAtlArray<BYTE>& array)
    {
        CAtlArray<BYTE> copiedArray;
        copiedArray.Copy(array);
       
        copiedArray.Add('\0');
        copiedArray.Add('\0');

        // Same here.        
        return CStringW((LPCWSTR)copiedArray.GetData());
    }

------

**So, the questions:**

- Is the C-style case from `BYTE*` to `LPCSTR` (`const char*`) safe for all possible cases?

- Is it really necessary to add **double** null-termination when converting the ANSI string to Unicode or is it a typo?

- *Any way to make all this code easier to understand and to maintain?*

