Finally I implement it:
// This function replaces illegal chars in file name by _
// pstrOut must point to a buffer with MAX_PATH size
void MakeLegalFileName(LPCTSTR pstrIn, LPTSTR pstrOut)
{
ASSERT(pstrIn);
ASSERT(pstrOut);
LPCTSTR pIn = pstrIn;
LPTSTR pOut = pstrOut;
LPTSTR pRightTrimPos = pstrOut;
int nLen = 0;
*pstrOut = _T('\0');
while (*pIn != _T('\0') && nLen++ < MAX_PATH)
{
if (*pIn > 31)
{
switch (*pIn)
{
case _T('<'):
case _T('>'):
case _T(':'):
case _T('"'):
case _T('/'):
case _T('\\'):
case _T('|'):
case _T('?'):
case _T('*'):
*pOut = _T('_');
pOut++;
break;
default:
if (*pIn != _T(' ') || *pstrOut != _T('\0')) // trim left spaces
{
*pOut = *pIn;
if (*pOut != _T('.') && *pOut != _T(' ')) // trim right spaces & dots
pRightTrimPos = pOut + 1;
pOut++;
}
break;
}
}
else
{
*pOut = _T('_');
pOut++;
}
pIn++;
}
*pRightTrimPos = _T('\0');
static const TCHAR* szSpecialNames[22] = {
_T("CON"), _T("PRN"), _T("AUX"), _T("NUL"),
_T("COM1"), _T("COM2"), _T("COM3"), _T("COM4"), _T("COM5"), _T("COM6"), _T("COM7"), _T("COM8"), _T("COM9"),
_T("LPT1"), _T("LPT2"), _T("LPT3"), _T("LPT4"), _T("LPT5"), _T("LPT6"), _T("LPT7"), _T("LPT8"), _T("LPT9")
};
int nOutStrLen = pRightTrimPos - pstrOut;
if (nOutStrLen == 3)
{
for (int i = 0; i < 4; i++)
{
if (_tcsicmp(pstrOut, szSpecialNames[i]) == 0)
{
pstrOut[2] = _T('_');
return;
}
}
}
else if (nOutStrLen == 4)
{
for (int i = 4; i < 22; i++)
{
if (_tcsicmp(pstrOut, szSpecialNames[i]) == 0)
{
pstrOut[3] = _T('_');
return;
}
}
}
}