570 lines
11 KiB
C++
570 lines
11 KiB
C++
/*++
|
||
|
||
Copyright (c) 1990 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
path.hxx
|
||
|
||
Abstract:
|
||
|
||
The PATH class provides an interface to the complete
|
||
Win32 name space. Complete means that it will correctly
|
||
handle long, drive or UNC based, blank embedded, mixed case
|
||
names. It should eliminate the need for everyone to code
|
||
statements such as "is the second char a ':'" or "search for
|
||
the first '\' from the end of the name". That is, access to and
|
||
manipulation of path and file names should be performed soley
|
||
through the PATH member functions. This will eliminate
|
||
the recoding of standard name manipulation code and ensure
|
||
complete support of Win32 functionality, such as codepage and
|
||
DBCS support.
|
||
|
||
Author:
|
||
|
||
Steve Rowe 13-Dec-90
|
||
|
||
Environment:
|
||
|
||
ULIB, user
|
||
|
||
Notes:
|
||
|
||
|
||
To clarify terminology used here, the following describes a
|
||
canonicalized path (in butchered BNF/reg exp):
|
||
|
||
{Canon} ::= {Prefix}"\"{Name}
|
||
{Prefix} ::= {Device}{Dirs}
|
||
{Dirs} ::= {"\"{Component}}*
|
||
{Device} ::= {Drive}|{Machine}
|
||
{Drive} ::= {Letter}":"
|
||
{Machine} ::= "\\"{Char}+
|
||
{Letter} ::= valid drive letter [a-zA-Z]
|
||
{Char} ::= valid filename/directory char [~:\]
|
||
{Component} ::= {Char}+
|
||
{Name} ::= {Base - excluding "."} | { {Base}"."{Ext} }
|
||
{Base} ::= {Char}+
|
||
{Ext} ::= {Char - excluding "."}+
|
||
|
||
Legend:
|
||
-------
|
||
{x}* - 0 or more x
|
||
{x}+ - 1 or more x
|
||
"x" - just x (not the quotes)
|
||
{x}|{y} - x or y (not both or none)
|
||
|
||
|
||
Examples:
|
||
---------
|
||
# Canon
|
||
--- -----
|
||
(1) x:\abc\def.ghi\jkl.mnop
|
||
(2) \\x\abc\def.ghi\jkl.mnop
|
||
(3) c:\config.sys
|
||
|
||
(1) (2) (3)
|
||
|
||
Prefix x:\abc\def.ghi \\x\abc\def.ghi c:
|
||
Device x: \\x c:
|
||
Dirs \abc \abc\def.ghi
|
||
Name jkl.mnop jkl.mnop config.sys
|
||
Base jkl jkl config
|
||
Ext mnop mnop sys
|
||
|
||
Component numbers are 0-based.
|
||
|
||
|
||
--*/
|
||
|
||
#if !defined( _PATH_)
|
||
|
||
#define _PATH_
|
||
|
||
#include "wstring.hxx"
|
||
#include "array.hxx"
|
||
|
||
//
|
||
// Forward references & declarations
|
||
//
|
||
|
||
DECLARE_CLASS( PATH );
|
||
|
||
|
||
|
||
//
|
||
// PATHSTATE maintains the number of characters within each component that
|
||
// makes up a PATH
|
||
//
|
||
struct _PATHSTATE {
|
||
|
||
//
|
||
// Prefix
|
||
//
|
||
CHNUM PrefixLen;
|
||
CHNUM DeviceLen;
|
||
CHNUM DirsLen;
|
||
CHNUM SeparatorLen;
|
||
|
||
//
|
||
// Name
|
||
//
|
||
CHNUM NameLen;
|
||
CHNUM BaseLen;
|
||
CHNUM ExtLen;
|
||
|
||
};
|
||
|
||
DEFINE_TYPE( struct _PATHSTATE, PATHSTATE );
|
||
|
||
typedef enum PATH_ANALYZE_CODE {
|
||
PATH_OK,
|
||
PATH_COULD_BE_FLOPPY,
|
||
PATH_OUT_OF_MEMORY,
|
||
PATH_INVALID_DRIVE_SPEC,
|
||
PATH_NO_MOUNT_POINT_FOR_VOLUME_NAME_PATH
|
||
};
|
||
|
||
class PATH : public OBJECT {
|
||
|
||
public:
|
||
|
||
ULIB_EXPORT
|
||
DECLARE_CONSTRUCTOR( PATH );
|
||
|
||
DECLARE_CAST_MEMBER_FUNCTION( PATH );
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
Initialize (
|
||
IN PCWSTR InitialPath,
|
||
IN BOOLEAN Canonicalize DEFAULT FALSE
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
Initialize (
|
||
IN PCWSTRING InitialPath,
|
||
IN BOOLEAN Canonicalize DEFAULT FALSE
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
Initialize (
|
||
IN PCPATH InitialPath,
|
||
IN BOOLEAN Canonicalize DEFAULT FALSE
|
||
);
|
||
|
||
VIRTUAL
|
||
ULIB_EXPORT
|
||
~PATH (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
AppendBase (
|
||
IN PCWSTRING Base,
|
||
IN BOOLEAN Absolute DEFAULT FALSE
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
EndsWithDelimiter (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
PCWSTRING
|
||
GetPathString (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
HasWildCard (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
IsDrive (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
IsRoot (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
ModifyName (
|
||
IN PCWSTRING Pattern
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PWSTRING
|
||
QueryBase (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PARRAY
|
||
QueryComponentArray (
|
||
OUT PARRAY Array DEFAULT NULL
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
PWSTRING
|
||
QueryDevice (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PWSTRING
|
||
QueryDirs (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PWSTRING
|
||
QueryDirsAndName (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PWSTRING
|
||
QueryExt (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PPATH
|
||
QueryFullPath (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PWSTRING
|
||
QueryFullPathString (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
PWSTRING
|
||
QueryName (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PPATH
|
||
QueryPath (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
PWSTRING
|
||
QueryPrefix (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PWSTRING
|
||
QueryRoot (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PPATH
|
||
QueryWCExpansion(
|
||
IN PPATH BasePath
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
SetBase (
|
||
IN PCWSTRING NewBase
|
||
);
|
||
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
SetDevice (
|
||
IN PCWSTRING NewDevice
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
SetExt (
|
||
IN PCWSTRING NewExt
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
SetName (
|
||
IN PCWSTRING NewName
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
SetPrefix (
|
||
IN PCWSTRING NewPrefix
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
TruncateBase (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
VOID
|
||
TruncateNameAtColon (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
VOID
|
||
TruncateDelimiter (
|
||
);
|
||
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
AppendDelimiter (
|
||
);
|
||
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
AppendString (
|
||
IN PCWSTRING String
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
BOOLEAN
|
||
IsGuidVolName(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PPATH
|
||
QueryMountPointPath(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PWSTRING
|
||
QueryGuidString(
|
||
OUT PWSTRING LongestMountPointPath,
|
||
OUT PBOOLEAN IsLongestMountPointADriveLetter,
|
||
OUT PWSTRING DrivePath
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULIB_EXPORT
|
||
PATH_ANALYZE_CODE
|
||
AnalyzePath(
|
||
OUT PWSTRING VolumeName,
|
||
OUT PPATH VolumePath,
|
||
OUT PWSTRING RemainingPath
|
||
);
|
||
|
||
private:
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
Construct (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
ExpandWildCards(
|
||
IN OUT PWSTRING pStr1,
|
||
IN OUT PWSTRING pStr2
|
||
);
|
||
|
||
BOOLEAN
|
||
Initialize (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
CHNUM
|
||
QueryBaseStart (
|
||
) CONST;
|
||
|
||
CHNUM
|
||
QueryDeviceLen(
|
||
IN PWSTRING pString
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
CHNUM
|
||
QueryDeviceStart (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
CHNUM
|
||
QueryExtStart (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
CHNUM
|
||
QueryNameStart (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
CHNUM
|
||
QueryPrefixStart (
|
||
) CONST;
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
SetPathState (
|
||
);
|
||
|
||
STATIC
|
||
BOOLEAN
|
||
BuildMountPoint(
|
||
IN PWSTR Name,
|
||
IN PCWSTR GuidNameToMatch,
|
||
OUT PWSTR MountPointPath
|
||
);
|
||
|
||
#if DBG==1
|
||
|
||
ULONG _Signature;
|
||
BOOLEAN _Initialized;
|
||
|
||
#endif
|
||
//
|
||
// path data
|
||
//
|
||
WCHAR _PathBuffer[MAX_PATH];
|
||
FSTRING _PathString;
|
||
PATHSTATE _PathState;
|
||
|
||
};
|
||
|
||
INLINE
|
||
CHNUM
|
||
PATH::QueryPrefixStart (
|
||
) CONST
|
||
|
||
{
|
||
return( 0 );
|
||
}
|
||
|
||
INLINE
|
||
CHNUM
|
||
PATH::QueryNameStart (
|
||
) CONST
|
||
|
||
{
|
||
//
|
||
// Increment past the '\'
|
||
//
|
||
return( QueryPrefixStart() + _PathState.PrefixLen + _PathState.SeparatorLen );
|
||
}
|
||
|
||
INLINE
|
||
CHNUM
|
||
PATH::QueryBaseStart (
|
||
) CONST
|
||
|
||
{
|
||
return( QueryNameStart() );
|
||
}
|
||
|
||
INLINE
|
||
CHNUM
|
||
PATH::QueryDeviceStart (
|
||
) CONST
|
||
|
||
{
|
||
return( 0 );
|
||
}
|
||
|
||
INLINE
|
||
CHNUM
|
||
PATH::QueryExtStart (
|
||
) CONST
|
||
{
|
||
return( QueryNameStart() + _PathState.BaseLen + 1 );
|
||
}
|
||
|
||
INLINE
|
||
PCWSTRING
|
||
PATH::GetPathString (
|
||
) CONST
|
||
|
||
{
|
||
return( &_PathString );
|
||
}
|
||
|
||
INLINE
|
||
PWSTRING
|
||
PATH::QueryBase (
|
||
)
|
||
|
||
{
|
||
return( _PathState.BaseLen ? _PathString.QueryString( QueryBaseStart(), _PathState.BaseLen ) : NULL );
|
||
}
|
||
|
||
INLINE
|
||
PWSTRING
|
||
PATH::QueryDirs (
|
||
)
|
||
|
||
{
|
||
return( _PathState.DirsLen ? _PathString.QueryString( QueryDeviceStart() + _PathState.DeviceLen, _PathState.DirsLen ) : NULL );
|
||
}
|
||
|
||
INLINE
|
||
PWSTRING
|
||
PATH::QueryDirsAndName (
|
||
)
|
||
|
||
{
|
||
return( ( _PathState.DirsLen || _PathState.NameLen ) ? _PathString.QueryString( QueryDeviceStart() + _PathState.DeviceLen ) : NULL );
|
||
}
|
||
|
||
INLINE
|
||
PWSTRING
|
||
PATH::QueryDevice (
|
||
)
|
||
|
||
{
|
||
return( _PathState.DeviceLen ? _PathString.QueryString( QueryDeviceStart(), _PathState.DeviceLen ) : NULL );
|
||
}
|
||
|
||
INLINE
|
||
PWSTRING
|
||
PATH::QueryExt (
|
||
)
|
||
|
||
{
|
||
return( _PathState.ExtLen ? _PathString.QueryString( QueryExtStart(), _PathState.ExtLen ) : NULL );
|
||
}
|
||
|
||
INLINE
|
||
PWSTRING
|
||
PATH::QueryName (
|
||
) CONST
|
||
|
||
{
|
||
return( _PathState.NameLen ? _PathString.QueryString( QueryNameStart(), _PathState.NameLen ) : NULL );
|
||
}
|
||
|
||
INLINE
|
||
PWSTRING
|
||
PATH::QueryPrefix (
|
||
)
|
||
|
||
{
|
||
return( _PathState.PrefixLen ? _PathString.QueryString( QueryPrefixStart(), _PathState.PrefixLen ) : NULL );
|
||
}
|
||
|
||
|
||
|
||
#endif // _PATH_
|