question

drjackool-3839 avatar image
0 Votes"
drjackool-3839 asked RLWA32-6355 commented

Check valid filename Win32 API

Hi
Is there a Win32 API to check filename validity (for illegal chars and names) or I have to implement it?

Thanks

vs-general
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Why do you need to validate a filename? An invalid filename would cause a Win32 API function to fail and an error code would be available using GetLastError().

Naming guidance is available here - Naming Files, Paths, and Namespaces


2 Votes 2 ·
drjackool-3839 avatar image
0 Votes"
drjackool-3839 answered RLWA32-6355 commented

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;
             }
         }
     }
 }
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

A filename whose length is 260 characters may not be valid. The components of a path, including the filename, have length limitations. See nf-fileapi-getvolumeinformationa


0 Votes 0 ·
metablaster avatar image
0 Votes"
metablaster answered metablaster edited

There is an API called PathCleanupSpec that will attempt to remove illegal characters,
You don't have to use resultant path, because your goal is to determine if anything was removed
which means you know the path was bad.

You know the path was bad trough return value of PCS_REMOVEDCHAR which means "Removed one or more invalid characters."
Other return values need to be handled as well to get correct result.

https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-pathcleanupspec

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SimpleSamples avatar image
0 Votes"
SimpleSamples answered

Unless someone knows of or finds something better, you can use a regular expression. You do not specify a language; the vs-general tag is neither a language nor an API. There are some possible regexes in Regular Expression Library. In C# you can use the Path.GetInvalidPathChars Method in a regex, something like:

 Regex containsABadCharacter = new Regex("[" + Regex.Escape(System.IO.Path.InvalidPathChars) + "]");



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.