改善しましたよ。不正コードは除去してからGetFullPathNameWに渡すことにしました。

#include<windows.h>
#include<io.h>
#include<stdio.h>
#include<string>

std::wstring fullpath( std::wstring fname){
unsigned int n;
std::wstring fn;
for( n=0; n<fname.size(); n++ ) if( fname[n] >= 32 ) fn+=fname[n];
fname=fn;
fn.resize(1<<15);
n=GetFullPathNameW( &fname[0], 1<<15, &fn[0], NULL);
fn.resize(n);
if( fn.substr(0,4) != L"\\\\?\\" ) fn=L"\\\\?\\" + fn;
return fn; }

FILE* wfopen (std::wstring fname, std::wstring opt) {
int flg, att;
std::wstring fn=fullpath( fname );
att = GetFileAttributesW(&fn[0]);
if(att==-1) { if( opt[0]==L'r' ) return NULL; else att=0; }
if(opt[0]==L'a' || opt[0]==L'r' ) flg=OPEN_ALWAYS; else flg=CREATE_ALWAYS;
HANDLE hd=CreateFileW( &fn[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL , flg , att , NULL);
return _wfdopen( _open_osfhandle ( (intptr_t)hd, 0 ), &opt[0] ); }

int main(){
FILE* fp = wfopen(L"c:/aaa/../test.txt", L"wb");
char ch[]="This is a pen.";
fwrite(ch,1,strlen(ch),fp);
fclose(fp); }