You should rewrite this by making two calls, otherwise this has a hidden limitation of an upper 32K bound. Call it once to get the size, allocate the string and call it again.

MSDN says: the return value specifies the number of characters copied to the buffer, not including the terminating null character. If the buffer is not large enough to contain all the key name and value pairs associated with the named section, the return value is equal to nSize minus two.