(SST) ShlWAPI.pas Version 1.08

Developer Reference
(SST)ShlWAPI PathIsLFNFileSpec Function
Tests the folder or file name component of a path for compliance with the Windows, long, file name format.
Scope
Global (i.e. this function can be called/accessed from code in any unit that includes/uses (SST)ShlWAPI.pas).
Syntax
function PathIsLFNFileSpec(lpName : LPCSTR) : BOOL;
Parameters
lpName [in] Pointer to null terminated ANSI or Unicode string, that is the folder or file name to test. This string, including the terminating null character, should not exceed MAX_PATH (= 260) characters in length.
Return Values
If the length of the name portion of the input string is longer than 8 characters and/or the extension/suffix portion is longer than 3 characters, the function returns TRUE (= 1), otherwise FALSE (= 0).
Remarks
The function name is slightly misleading in that it suggests that the funcion processes an entire path string, from drive letter to (and including) the file suffix. Unfortunately, this is not the case (at all). Instead, the function only processes individual components (i.e. file/folder names) correctly.
If the function is called with a parameter that consists of more than a single name (in- or excluding an extension), and/or it exceeds the DOS 8 + 3 restrictions, it seems to always return TRUE, irrespective of whether the string represents a path and file name in the DOS or LFN format.
Apparently, the function treats characters that are invalid in DOS/Windows file/folder names as valid characters (i.e it does not perform a syntax check).
Example
PROCEDURE TForm4.TestShlWAPIPathIsLFNFileSpec(Sender : TObject);

VAR pathtotest : STRING;
VAR apiretval : BOOL;
VAR newinfoline : STRING;

BEGIN
pathtotest := '';
apiretval := FALSE;
newinfoline := '';

//Could be either; a DOS or LFN path (and file name)
pathtotest := 'C:\Windows\System32\Kernel32.dll';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);
//LFN path
pathtotest := 'C:\Program Files\Common Files';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);
//DOS path
pathtotest := 'C:\PROGRA~1\COMMON~1';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);
//LFN path and file name
pathtotest := 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Paint.lnk';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);
//DOS path and file name
pathtotest := 'C:\PROGRA~2\MICROS~1\Windows\STARTM~1\Programs\Paint.lnk';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'C:\';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'PROGRA~2';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'ProgramData';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'DOS?Name'; //Invalid DOS name, no suffix
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'DOSName.LFNExt'; //Valid DOS name, invalid, DOS suffix, overall length > 8 + 3
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'DOS.Suffx'; //Valid DOS name, invalid DOS suffix, overall length <= 8 + 3
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'DOSName.Ext'; //Valid DOS name and suffix
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'InvalidLFNFileName_>';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'ValidLFNFileNamePlusShortExt.txt';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);

pathtotest := 'ValidLFNFileNamePlus.Extension';
newinfoline := 'PathIsLFNFileSpec called with ' + pathtotest;
Memo1.Lines.Add(newinfoline);
apiretval := PathIsLFNFileSpec(PChar(pathtotest));
IF apiretval THEN
newinfoline := 'TRUE'
ELSE
newinfoline := 'FALSE';
Memo1.Lines.Add(newinfoline);
Memo1.Lines.Add('');
//... and, Yeees, we do know what loops are
END;
The above code produces the following output:
PathIsLFNFileSpec called with C:\Windows\System32\Kernel32.dll //Could be either; a DOS or LFN path (and file name)
TRUE
PathIsLFNFileSpec called with C:\Program Files\Common Files //LFN path
TRUE
PathIsLFNFileSpec called with C:\PROGRA~1\COMMON~1 //DOS path
TRUE
PathIsLFNFileSpec called with C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Paint.lnk //LFN path and file name
TRUE
PathIsLFNFileSpec called with C:\PROGRA~2\MICROS~1\Windows\STARTM~1\Programs\Paint.lnk //DOS path and file name
TRUE

PathIsLFNFileSpec called with C:\
FALSE
PathIsLFNFileSpec called with PROGRA~2
FALSE
PathIsLFNFileSpec called with ProgramData
TRUE
PathIsLFNFileSpec called with DOS?Name //Note the invalid character in the middle of the string
FALSE
PathIsLFNFileSpec called with DOSName.LFNExt
TRUE
PathIsLFNFileSpec called with DOS.Suffx
TRUE
PathIsLFNFileSpec called with DOSName.Ext
FALSE
PathIsLFNFileSpec called with InvalidLFNFileName_> //Note the invalid character that terminates the name
TRUE
PathIsLFNFileSpec called with ValidLFNFileNamePlusShortExt.txt
TRUE
PathIsLFNFileSpec called with ValidLFNFileNamePlus.Extension
TRUE
Requirements
Unit: Declared and imported in (SST)ShlWAPI.pas
Library: (SST)ShlWAPI.dcu/(SST)ShlWAPI.obj
Unicode: Implemented as ANSI (PathIsLFNFileSpec and PathIsLFNFileSpecA) and Unicode (PathIsLFNFileSpecW) function.
Min. ShlWAPI.dll version according to MS SDK doc.: 5.0
Min. ShlWAPI.dll version based on SST research: 5.0
Min. OS version(s) according to Microsoft SDK doc.: Windows 2000, Windows NT 4.0 with Internet Explorer 5, Windows 98, Windows 95 with Internet Explorer 5
Min. OS version(s) according to SST research.: Windows NT 4.0 with IE 5, Windows 98, Windows 95 with IE 5, Windows 2000
See Also
PathFindNextComponent.
 
Windows APIs: PathFindNextComponent, PathIsLFNFileSpec, PathIsFileSpec, PathIsPrefix, PathIsRelative, PathIsUNC, PathIsURL, PathMatchSpec, PathMatchSpecEx, PathRemoveFileSpec.


Document/Contents version 1.00
Page/URI last updated on May 04, 2022
 
Copyright © Stoelzel Software Technologie (SST) 2010 - 2015
Suggestions and comments mail to:
webmaster@stoelzelsoftwaretech.com