From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/oleutest/cfmex/cdir.cxx | 418 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 private/oleutest/cfmex/cdir.cxx (limited to 'private/oleutest/cfmex/cdir.cxx') diff --git a/private/oleutest/cfmex/cdir.cxx b/private/oleutest/cfmex/cdir.cxx new file mode 100644 index 000000000..250404676 --- /dev/null +++ b/private/oleutest/cfmex/cdir.cxx @@ -0,0 +1,418 @@ + +//+========================================================================== +// +// File: CDir.cxx +// +// Purpose: Define the CDirectory class. +// +// This class is used to represent a directory name. +// Along with maintaining the name, it can determine +// the type of FileSystem. +// +//+========================================================================== + + +// -------- +// Includes +// -------- + +#include +#include +#include +#include +#include + +#include "CFMEx.hxx" +#include "CDir.hxx" + + +//+------------------------------------------------------------------------------ +// +// Function: CDirectory::Initialize (no arguments) +// +// Synopsis: Generate a directory name, using the TEMP environment +// variable, and use it to initialize this object. +// +// Inputs: None. +// +// Outputs: TRUE if the function succeeds, FALSE otherwise. +// +//+------------------------------------------------------------------------------ + +BOOL CDirectory::Initialize() +{ + // --------------- + // Local Variables + // --------------- + + // Assume failure for now. + BOOL bSuccess = FALSE; + + // The TEMP environment variable. + WCHAR wszSystemTempPath[ MAX_PATH + sizeof( L'\0' )]; + + // Reset the error code. + m_lError = 0L; + + // ---------- + // Get %TEMP% + // ---------- + + if( !GetTempPath( MAX_PATH, + wszSystemTempPath ) + ) + { + m_lError = GetLastError(); + EXIT( L"GetTempPath() failed (%d)" ); + } + + // ---------------------- + // Initialize this object + // ---------------------- + + // Initialize using the temporary path. We must never pass a NULL here, + // or we'll cause an infinite recursion. + + if( wszSystemTempPath == NULL ) + EXIT( L"Invalid temporary path" ); + bSuccess = Initialize( wszSystemTempPath ); + + // ---- + // Exit + // ---- + +Exit: + + return( bSuccess ); + +} + +//+----------------------------------------------------------------------- +// +// Function: CDirectory::Initialize (with an ANSI string) +// +// Synopsis: This function converts the ANSI string to a Unicode +// string, then initializes the object with it. +// +// Inputs: A Unicode string. +// +// Outputs: TRUE if the function succeeds, FALSE otherwise. +// +//+----------------------------------------------------------------------- + +BOOL CDirectory::Initialize( LPCSTR szDirectory ) +{ + // --------------- + // Local Variables + // --------------- + + // Assume failure. + BOOL bSuccess = FALSE; + + // A buffer for the Unicode path + WCHAR wszDirectory[ MAX_UNICODE_PATH + sizeof( L'\0' )]; + + // ----- + // Begin + // ----- + + // Initialize the error code. + m_lError = 0L; + + + // If we were givin a NULL path, use the version of Initialize + // that requires no path. + + if( szDirectory == NULL ) + { + bSuccess = Initialize(); + goto Exit; + } + + // Convert the Ansi name to Unicode. + + if( m_lError = (long) AnsiToUnicode( szDirectory, + wszDirectory, + strlen( szDirectory ) + ) + ) + { + EXIT( L"Unable to convert directory to Unicode" ); + } + + // Initialize using the temporary path. We must never pass a NULL here, + // or we'll cause an infinite recursion. + + if( wszDirectory == NULL ) + EXIT( L"Invalid Directory (internal error)" ); + bSuccess = Initialize( wszDirectory ); + + // ---- + // Exit + // ---- + +Exit: + + return( bSuccess ); + +} + + +//+----------------------------------------------------------------------- +// +// Function: CDirectory::Initialize (with a Unicode string) +// +// Synopsis: This function is the only form of Initialize +// (there are several variations of the Initialize member) +// which really initializes the object. It stores the +// directory name, and determines the type of filesystem +// on which it resides. +// +// Inputs: A Unicode string. +// +// Outputs: TRUE if the function succeeds, FALSE otherwise. +// +//+----------------------------------------------------------------------- + +BOOL CDirectory::Initialize( LPCWSTR wszDirectory ) +{ + + // --------------- + // Local Variables + // --------------- + + // Assume failure. + BOOL bSuccess = FALSE; + + // Buffers for the root of the path and for the volume name. + WCHAR wszDirectoryRoot[ MAX_PATH + sizeof( L'\0' )]; + WCHAR wszVolumeName[ MAX_PATH + sizeof( L'\0' )]; + + // Parameters to GetVolumeInformation which we won't use. + DWORD dwMaxComponentLength = 0L; + DWORD dwFileSystemFlags = 0L; + + // ----- + // Begin + // ----- + + // Initialize the error code. + m_lError = 0L; + + // If we were given a NULL path, use the variation of Initialization() + // which does not require one. Note that we will then be called again, + // but this time with a path. + + if( wszDirectory == NULL ) + { + bSuccess = Initialize(); + goto Exit; + } + + // Validate the path. + + if( wcslen( wszDirectory ) > MAX_PATH ) + { + m_lError = wcslen( wszDirectory ); + EXIT( L"Input path is too long (%d)\n" ); + } + + // Save the path to our member buffer + + wcscpy( m_wszDirectory, wszDirectory ); + + + // ------------------------ + // Get the file system name + // ------------------------ + + // Get the root path to the directory. + + wcscpy( wszDirectoryRoot, wszDirectory ); + MakeRoot( wszDirectoryRoot ); + + // Get the volume information, which will include the filesystem name. + + if( !GetVolumeInformation( wszDirectoryRoot, // Root path name. + wszVolumeName, // Buffer for volume name + MAX_PATH, // Length of the above buffer + NULL, // Buffer for serial number + // Longest filename length. + &dwMaxComponentLength, + &dwFileSystemFlags, // Compression, etc. + m_wszFileSystemName,// Buffer for the FS name. + MAX_PATH ) // Length of above buffer + ) + { + m_lError = GetLastError(); + EXIT( L"GetVolumeInformation() failed" ); + } + + + // Determine the file system type from the name. + + if( !wcscmp( m_wszFileSystemName, L"FAT" )) + m_FileSystemType = fstFAT; + + else if( !wcscmp( m_wszFileSystemName, L"NTFS" )) + m_FileSystemType = fstNTFS; + + else if( !wcscmp( m_wszFileSystemName, L"OFS" )) + m_FileSystemType = fstOFS; + + else + m_FileSystemType = fstUnknown; + + bSuccess = TRUE; + + // ---- + // Exit + // ---- + +Exit: + + DisplayErrors( bSuccess, L"CDirectory::Initialize( wszDirectory )" ); + return( bSuccess ); + +} + + + +// +// GetRootLength +// +// This routine was simply copied from private\windows\shell\shelldll\tracker.cxx, +// and should not be modified here. +// + +unsigned +CDirectory::GetRootLength(const WCHAR *pwszPath) +{ + ULONG cwcRoot = 0; + m_lError = 0L; + + if (pwszPath == 0) + pwszPath = L""; + + if (*pwszPath == L'\\') + { + // If the first character is a path separator (backslash), this + // must be a UNC drive designator which must be of the form: + // (+) + // (+) + // + // This covers drives like these: \\worf\scratch\ and + // \\savik\win4dev\. + // + pwszPath++; + cwcRoot++; + + BOOL fMachine = FALSE; + BOOL fShare = FALSE; + + if (*pwszPath == L'\\') + { + cwcRoot++; + pwszPath++; + + while (*pwszPath != '\0' && *pwszPath != L'\\') + { + cwcRoot++; + pwszPath++; + + fMachine = TRUE; + } + + if (*pwszPath == L'\\') + { + cwcRoot++; + pwszPath++; + + while (*pwszPath != '\0' && *pwszPath != L'\\') + { + cwcRoot++; + pwszPath++; + + fShare = TRUE; + } + + // If there weren't any characters in the machine or + // share portions of the UNC name, then the drive + // designator is bogus. + // + if (!fMachine || !fShare) + { + cwcRoot = 0; + } + } + else + { + cwcRoot = 0; + } + } + else + { + cwcRoot = 0; + } + } + else + if (iswalpha(*pwszPath)) + { + // If the first character is an alphanumeric, we must have + // a drive designator of this form: + // ()+ + // + // This covers drives like these: a:\, c:\, etc + // + + pwszPath++; + cwcRoot++; + + if (*pwszPath == L':') + { + cwcRoot++; + pwszPath++; + } + else + { + cwcRoot = 0; + } + } + + // If we have counted one or more characters in the root and these + // are followed by a component separator, we need to add the separator + // to the root length. Otherwise this is not a valid root and we need + // to return a length of zero. + // + if ((cwcRoot > 0) && (*pwszPath == L'\\')) + { + cwcRoot++; + } + else + { + cwcRoot = 0; + } + + return (cwcRoot); +} + +// +// MakeRoot +// +// This routine was simply copied from private\windows\shell\shelldll\tracker.cxx, +// and should not be modified here. +// + + +VOID +CDirectory::MakeRoot(WCHAR *pwszPath) +{ + unsigned rootlength = GetRootLength(pwszPath); + m_lError = 0L; + + if (rootlength) + { + pwszPath[rootlength] = L'\0'; + } +} + -- cgit v1.2.3