917 lines
23 KiB
C
917 lines
23 KiB
C
/*++
|
|
|
|
Copyright (c) 1990-1998, Microsoft Corporation All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
parse.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the parse routines for the Win32 common dialogs.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
// precompiled headers
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include "fileopen.h"
|
|
|
|
//
|
|
// Global Variables.
|
|
//
|
|
extern TCHAR szCaption[];
|
|
extern TCHAR szWarning[];
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ParseFileNew
|
|
//
|
|
// On the return, pnExtOffset is the offset to the dot.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int ParseFileNew(
|
|
LPTSTR pszPath,
|
|
int *pnExtOffset,
|
|
BOOL bWowApp,
|
|
BOOL bNewStyle)
|
|
{
|
|
int lRet = ParseFile(pszPath, TRUE, bWowApp, bNewStyle);
|
|
|
|
if (pnExtOffset)
|
|
{
|
|
int nExt;
|
|
|
|
nExt = (int)(SHORT)HIWORD(lRet);
|
|
*pnExtOffset = ((nExt) && *(pszPath + nExt)) ? nExt : 0;
|
|
}
|
|
|
|
return ((int)(SHORT)LOWORD(lRet));
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ParseFileOld
|
|
//
|
|
// On return, pnExtOffset is the offset to the the dot and
|
|
// pnOldExt is the offset to the character following the dot.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int ParseFileOld(
|
|
LPTSTR pszPath,
|
|
int *pnExtOffset,
|
|
int *pnOldExt,
|
|
BOOL bWowApp,
|
|
BOOL bNewStyle)
|
|
{
|
|
int lRet = ParseFile(pszPath, TRUE, bWowApp, bNewStyle);
|
|
|
|
int nExt = (int)(SHORT)HIWORD(lRet);
|
|
*pnExtOffset = nExt;
|
|
*pnOldExt = ((nExt) && *(pszPath + nExt)) ? nExt + 1 : 0;
|
|
|
|
return ((int)(SHORT)LOWORD(lRet));
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ParseFile
|
|
//
|
|
// Determines if the filename is a legal dos name.
|
|
//
|
|
// Circumstances checked:
|
|
// 1) Valid as directory name, but not as file name
|
|
// 2) Empty String
|
|
// 3) Illegal Drive label
|
|
// 4) Period in invalid location (in extension, 1st in file name)
|
|
// 5) Missing directory character
|
|
// 6) Illegal character
|
|
// 7) Wildcard in directory name
|
|
// 8) Double slash beyond 1st 2 characters
|
|
// 9) Space character in the middle of the name (trailing spaces OK)
|
|
// -->> no longer applies : spaces are allowed in LFN
|
|
// 10) Filename greater than 8 characters : NOT APPLICABLE TO LONG FILE NAMES
|
|
// 11) Extension greater than 3 characters: NOT APPLICABLE TO LONG FILE NAMES
|
|
//
|
|
// lpstrFileName - ptr to a single file name
|
|
//
|
|
// Returns:
|
|
// LONG - LOWORD = char offset to filename,
|
|
// HIWORD = char offset to extension (dot),
|
|
// LONG - LOWORD is error code (<0), HIWORD is approx. place of problem
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
DWORD ParseFile(
|
|
LPTSTR lpstrFileName,
|
|
BOOL bLFNFileSystem,
|
|
BOOL bWowApp,
|
|
BOOL bNewStyle)
|
|
{
|
|
SHORT nFile, nExt, nFileOffset, nExtOffset = 0;
|
|
BOOL bExt;
|
|
BOOL bWildcard;
|
|
SHORT nNetwork = 0;
|
|
BOOL bUNCPath = FALSE;
|
|
LPTSTR lpstr = lpstrFileName;
|
|
|
|
//Check if the string is empty
|
|
if (!*lpstr)
|
|
{
|
|
nFileOffset = PARSE_EMPTYSTRING;
|
|
goto ParseFile_Failure;
|
|
}
|
|
|
|
//Check if the string is of form c:\foo1\foo2
|
|
if (*(lpstr + 1) == CHAR_COLON)
|
|
{
|
|
//Yes. Get the drive letter
|
|
TCHAR cDrive = CharLowerChar(*lpstr);
|
|
|
|
//
|
|
// Test to see if the drive is legal.
|
|
//
|
|
// Note: Does not test that drive exists.
|
|
//
|
|
if ((cDrive < CHAR_A) || (cDrive > CHAR_Z))
|
|
{
|
|
nFileOffset = PARSE_INVALIDDRIVE;
|
|
goto ParseFile_Failure;
|
|
}
|
|
|
|
//Move string past drive letter and ':'
|
|
lpstr = CharNext(CharNext(lpstr));
|
|
}
|
|
|
|
if ((*lpstr == CHAR_BSLASH) || (*lpstr == CHAR_SLASH && !bNewStyle))
|
|
{
|
|
//
|
|
// Cannot have "c:\."
|
|
//
|
|
if (*++lpstr == CHAR_DOT)
|
|
{
|
|
//
|
|
// Except that "c:\.\" is allowed.
|
|
//
|
|
if ((*++lpstr != CHAR_BSLASH) && (*lpstr != CHAR_SLASH || bNewStyle))
|
|
{
|
|
//
|
|
// It's the root directory.
|
|
//
|
|
if (!*lpstr)
|
|
{
|
|
goto MustBeDir;
|
|
}
|
|
else
|
|
{
|
|
lpstr--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// It's saying top dir (once again), thus allowed.
|
|
//
|
|
++lpstr;
|
|
}
|
|
}
|
|
else if ((*lpstr == CHAR_BSLASH) && (*(lpstr - 1) == CHAR_BSLASH))
|
|
{
|
|
//
|
|
// It seems that for a full network path, whether a drive is
|
|
// declared or not is insignificant, though if a drive is given,
|
|
// it must be valid (hence the code above should remain there).
|
|
//
|
|
|
|
//
|
|
// ...since it's the first slash, 2 are allowed.
|
|
//
|
|
++lpstr;
|
|
|
|
//
|
|
// Must receive server and share to be real.
|
|
//
|
|
nNetwork = -1;
|
|
|
|
//
|
|
// No wildcards allowed if UNC name.
|
|
//
|
|
bUNCPath = TRUE;
|
|
}
|
|
else if (*lpstr == CHAR_SLASH && !bNewStyle)
|
|
{
|
|
nFileOffset = PARSE_INVALIDDIRCHAR;
|
|
goto ParseFile_Failure;
|
|
}
|
|
}
|
|
else if (*lpstr == CHAR_DOT)
|
|
{
|
|
//
|
|
// Up one directory.
|
|
//
|
|
if (*++lpstr == CHAR_DOT)
|
|
{
|
|
++lpstr;
|
|
}
|
|
|
|
if (!*lpstr)
|
|
{
|
|
goto MustBeDir;
|
|
}
|
|
if ((*lpstr != CHAR_BSLASH) && (*lpstr != CHAR_SLASH || bNewStyle))
|
|
{
|
|
//
|
|
// Jumping to Failure here will skip the parsing that causes
|
|
// ".xxx.txt" to return with nFileOffset = 2.
|
|
//
|
|
nFileOffset = 0;
|
|
goto ParseFile_Failure;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Allow directory.
|
|
//
|
|
++lpstr;
|
|
}
|
|
}
|
|
|
|
if (!*lpstr)
|
|
{
|
|
goto MustBeDir;
|
|
}
|
|
|
|
//
|
|
// Should point to first char in filename by now.
|
|
//
|
|
nFileOffset = nExtOffset = nFile = nExt = 0;
|
|
bWildcard = bExt = FALSE;
|
|
while (*lpstr)
|
|
{
|
|
//
|
|
// Anything below the "Space" character is invalid.
|
|
//
|
|
#ifdef UNICODE
|
|
if (*lpstr < CHAR_SPACE)
|
|
#else
|
|
if (((UCHAR)*lpstr) < CHAR_SPACE)
|
|
#endif
|
|
{
|
|
nFileOffset = PARSE_INVALIDCHAR;
|
|
goto ParseFile_Failure;
|
|
}
|
|
switch (*lpstr)
|
|
{
|
|
case ( CHAR_COLON ) :
|
|
case ( CHAR_BAR ) :
|
|
case ( CHAR_LTHAN ) :
|
|
case ( CHAR_QUOTE ) :
|
|
{
|
|
//
|
|
// Invalid characters for all file systems.
|
|
//
|
|
nFileOffset = PARSE_INVALIDCHAR;
|
|
goto ParseFile_Failure;
|
|
}
|
|
case ( CHAR_SEMICOLON ) :
|
|
case ( CHAR_COMMA ) :
|
|
case ( CHAR_PLUS ) :
|
|
case ( CHAR_LBRACKET ) :
|
|
case ( CHAR_RBRACKET ) :
|
|
case ( CHAR_EQUAL ) :
|
|
{
|
|
if (!bLFNFileSystem)
|
|
{
|
|
nFileOffset = PARSE_INVALIDCHAR;
|
|
goto ParseFile_Failure;
|
|
}
|
|
else
|
|
{
|
|
goto RegularCharacter;
|
|
}
|
|
}
|
|
case ( CHAR_SLASH ) :
|
|
{
|
|
if (bNewStyle)
|
|
{
|
|
nFileOffset = PARSE_INVALIDCHAR;
|
|
goto ParseFile_Failure;
|
|
}
|
|
|
|
// fall thru...
|
|
}
|
|
case ( CHAR_BSLASH ) :
|
|
{
|
|
//
|
|
// Subdir indicators.
|
|
//
|
|
nNetwork++;
|
|
if (bWildcard)
|
|
{
|
|
nFileOffset = PARSE_WILDCARDINDIR;
|
|
goto ParseFile_Failure;
|
|
}
|
|
|
|
//
|
|
// if nFile==0 means that we are seeing this backslash right next to a backslash
|
|
// which is not allowed.
|
|
if (nFile == 0)
|
|
{
|
|
nFileOffset = PARSE_INVALIDDIRCHAR;
|
|
goto ParseFile_Failure;
|
|
}
|
|
else
|
|
{
|
|
//Move over the BSLASH/SLASH character.
|
|
++lpstr;
|
|
|
|
//Check if the path is valid network path name
|
|
if (!nNetwork && !*lpstr)
|
|
{
|
|
nFileOffset = PARSE_INVALIDNETPATH;
|
|
goto ParseFile_Failure;
|
|
}
|
|
|
|
|
|
//We assume that the characters we are seeing are filename characters. This BSLASH/SLASH
|
|
//character tells that characters we have seen so far specifies the name of a directory in the
|
|
//path. Reset flags so that we can start looking for filename again.
|
|
nFile = nExt = 0;
|
|
nExtOffset = 0;
|
|
bExt = FALSE;
|
|
}
|
|
break;
|
|
}
|
|
case ( CHAR_SPACE ) :
|
|
{
|
|
LPTSTR lpSpace = lpstr;
|
|
|
|
if (bLFNFileSystem)
|
|
{
|
|
// In Long file name file system space characters are O.K
|
|
goto RegularCharacter;
|
|
}
|
|
|
|
|
|
|
|
//We are not interested in the trailing spaces so null terminate it.
|
|
*lpSpace = CHAR_NULL;
|
|
|
|
|
|
// In non long file name file systems, space characters are OK at the end of file
|
|
// name. Check to see if all the characters that follows are spaces. if thats the case
|
|
// then its valid. if we have any non space character after the first space then its a
|
|
// invalid file name.
|
|
|
|
while (*++lpSpace)
|
|
{
|
|
if (*lpSpace != CHAR_SPACE)
|
|
{
|
|
*lpstr = CHAR_SPACE;
|
|
nFileOffset = PARSE_INVALIDSPACE;
|
|
goto ParseFile_Failure;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case ( CHAR_DOT ) :
|
|
{
|
|
|
|
// In newstyle nExtOffset points to the dot and not to the first character of extension.
|
|
if (bNewStyle)
|
|
{
|
|
nExtOffset = (SHORT)(lpstr - lpstrFileName);
|
|
goto RegularCharacter;
|
|
}
|
|
|
|
if (nFile == 0)
|
|
{
|
|
nFileOffset = (SHORT)(lpstr - lpstrFileName);
|
|
if (*++lpstr == CHAR_DOT)
|
|
{
|
|
++lpstr;
|
|
}
|
|
if (!*lpstr)
|
|
{
|
|
goto MustBeDir;
|
|
}
|
|
|
|
//
|
|
// Flags already set.
|
|
//
|
|
nFile++;
|
|
++lpstr;
|
|
}
|
|
else
|
|
{
|
|
nExtOffset = 0;
|
|
++lpstr;
|
|
bExt = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
case ( CHAR_STAR ) :
|
|
case ( CHAR_QMARK ) :
|
|
{
|
|
bWildcard = TRUE;
|
|
|
|
// Fall thru...
|
|
}
|
|
default :
|
|
{
|
|
RegularCharacter:
|
|
|
|
//Are we in extension part ?
|
|
if (bExt)
|
|
{
|
|
//Is this first character in extension part
|
|
if (++nExt == 1)
|
|
{
|
|
//Yes, then get the Extension offset
|
|
nExtOffset = (SHORT)(lpstr - lpstrFileName);
|
|
}
|
|
}
|
|
|
|
//We are still in file name part.
|
|
//Is this the first character in filename part ?
|
|
else if (++nFile == 1)
|
|
{
|
|
//Yes. Get the filename offset
|
|
nFileOffset = (SHORT)(lpstr - lpstrFileName);
|
|
}
|
|
|
|
//Move to the next character
|
|
lpstr = CharNext(lpstr);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nNetwork == -1)
|
|
{
|
|
nFileOffset = PARSE_INVALIDNETPATH;
|
|
goto ParseFile_Failure;
|
|
}
|
|
else if (bUNCPath)
|
|
{
|
|
if (!nNetwork)
|
|
{
|
|
//
|
|
// Server and share only.(e.g \\server\foo)
|
|
//
|
|
*lpstr = CHAR_NULL;
|
|
nFileOffset = PARSE_DIRECTORYNAME;
|
|
goto ParseFile_Failure;
|
|
}
|
|
else if ((nNetwork == 1) && !nFile)
|
|
{
|
|
//
|
|
// Server and share root.(e.g \\server\foo\)
|
|
//
|
|
*lpstr = CHAR_NULL;
|
|
nFileOffset = PARSE_DIRECTORYNAME;
|
|
goto ParseFile_Failure;
|
|
}
|
|
}
|
|
|
|
if (!nFile)
|
|
{
|
|
MustBeDir:
|
|
nFileOffset = PARSE_DIRECTORYNAME;
|
|
goto ParseFile_Failure;
|
|
}
|
|
|
|
//
|
|
// If bNewStyle is true, no ext. wanted.
|
|
//
|
|
if (!bNewStyle)
|
|
{
|
|
if ((bWowApp) &&
|
|
(*(lpstr - 1) == CHAR_DOT) &&
|
|
(*CharNext(lpstr - 2) == CHAR_DOT))
|
|
{
|
|
//
|
|
// Remove terminating period.
|
|
//
|
|
*(lpstr - 1) = CHAR_NULL;
|
|
}
|
|
else if (!nExt)
|
|
{
|
|
ParseFile_Failure:
|
|
//
|
|
// Need to recheck bNewStyle since we can jump here.
|
|
//
|
|
if (!bNewStyle)
|
|
{
|
|
nExtOffset = (SHORT)(lpstr - lpstrFileName);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (MAKELONG(nFileOffset, nExtOffset));
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PathRemoveBslash
|
|
//
|
|
// Removes a trailing backslash from the given path.
|
|
//
|
|
// Returns:
|
|
// Pointer to NULL that replaced the backslash OR
|
|
// Pointer to the last character if it isn't a backslash
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
LPTSTR PathRemoveBslash(
|
|
LPTSTR lpszPath)
|
|
{
|
|
int len = lstrlen(lpszPath) - 1;
|
|
|
|
#ifndef UNICODE
|
|
if (IsDBCSLeadByte(*CharPrev(lpszPath, lpszPath + len + 1)))
|
|
{
|
|
len--;
|
|
}
|
|
#endif
|
|
|
|
if (!PathIsRoot(lpszPath) && (lpszPath[len] == CHAR_BSLASH))
|
|
{
|
|
lpszPath[len] = CHAR_NULL;
|
|
}
|
|
|
|
return (lpszPath + len);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IsWild
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL IsWild(
|
|
LPCTSTR lpsz)
|
|
{
|
|
return (StrChr(lpsz, CHAR_STAR) || StrChr(lpsz, CHAR_QMARK));
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AppendExt
|
|
//
|
|
// Appends default extension onto path name.
|
|
// It assumes the current path name doesn't already have an extension.
|
|
// lpExtension does not need to be null terminated.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
VOID AppendExt(
|
|
LPTSTR lpszPath,
|
|
LPCTSTR lpExtension,
|
|
BOOL bWildcard)
|
|
{
|
|
WORD wOffset;
|
|
SHORT i;
|
|
TCHAR szExt[MAX_PATH + 1];
|
|
|
|
if (lpExtension && *lpExtension)
|
|
{
|
|
wOffset = (WORD)lstrlen(lpszPath);
|
|
if (bWildcard)
|
|
{
|
|
*(lpszPath + wOffset++) = CHAR_STAR;
|
|
}
|
|
|
|
//
|
|
// Add a period.
|
|
//
|
|
*(lpszPath + wOffset++) = CHAR_DOT;
|
|
for (i = 0; *(lpExtension + i) && i < MAX_PATH; i++)
|
|
{
|
|
szExt[i] = *(lpExtension + i);
|
|
}
|
|
szExt[i] = 0;
|
|
|
|
//
|
|
// Remove leading / trailing blanks in the extension.
|
|
//
|
|
PathRemoveBlanks(szExt);
|
|
|
|
//
|
|
// Add the rest.
|
|
//
|
|
lstrcpy(lpszPath + wOffset, szExt);
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IsUNC
|
|
//
|
|
// Determines if the given path is a UNC path.
|
|
//
|
|
// Returns:
|
|
// TRUE if path starts with "\\" or "X:\\"
|
|
// FALSE otherwise
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL IsUNC(
|
|
LPCTSTR lpszPath)
|
|
{
|
|
return ( DBL_BSLASH(lpszPath) ||
|
|
((lpszPath[1] == CHAR_COLON) && DBL_BSLASH(lpszPath + 2)) );
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PortName
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define PORTARRAY 14
|
|
|
|
BOOL PortName(
|
|
LPTSTR lpszFileName)
|
|
{
|
|
static TCHAR *szPorts[PORTARRAY] = { TEXT("LPT1"),
|
|
TEXT("LPT2"),
|
|
TEXT("LPT3"),
|
|
TEXT("LPT4"),
|
|
TEXT("COM1"),
|
|
TEXT("COM2"),
|
|
TEXT("COM3"),
|
|
TEXT("COM4"),
|
|
TEXT("EPT"),
|
|
TEXT("NUL"),
|
|
TEXT("PRN"),
|
|
TEXT("CLOCK$"),
|
|
TEXT("CON"),
|
|
TEXT("AUX"),
|
|
};
|
|
short i;
|
|
TCHAR cSave, cSave2;
|
|
|
|
|
|
cSave = *(lpszFileName + 4);
|
|
if (cSave == CHAR_DOT)
|
|
{
|
|
*(lpszFileName + 4) = CHAR_NULL;
|
|
}
|
|
|
|
//
|
|
// For "EPT".
|
|
//
|
|
cSave2 = *(lpszFileName + 3);
|
|
if (cSave2 == CHAR_DOT)
|
|
{
|
|
*(lpszFileName + 3) = CHAR_NULL;
|
|
}
|
|
|
|
for (i = 0; i < PORTARRAY; i++)
|
|
{
|
|
if (!lstrcmpi(szPorts[i], lpszFileName))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
*(lpszFileName + 4) = cSave;
|
|
*(lpszFileName + 3) = cSave2;
|
|
|
|
return (i != PORTARRAY);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IsDirectory
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL IsDirectory(
|
|
LPTSTR pszPath)
|
|
{
|
|
DWORD dwAttributes;
|
|
|
|
//
|
|
// Clean up for GetFileAttributes.
|
|
//
|
|
PathRemoveBslash(pszPath);
|
|
|
|
dwAttributes = GetFileAttributes(pszPath);
|
|
return ( (dwAttributes != (DWORD)(-1)) &&
|
|
(dwAttributes & FILE_ATTRIBUTE_DIRECTORY) );
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// WriteProtectedDirCheck
|
|
//
|
|
// This function takes a full filename, strips the path, and creates
|
|
// a temp file in that directory. If it can't, the directory is probably
|
|
// write protected.
|
|
//
|
|
// Returns:
|
|
// error code if writeprotected
|
|
// 0 if successful creation of file.
|
|
//
|
|
// Assumptions:
|
|
// Full Path name on input with space for full filename appended.
|
|
//
|
|
// Note: Do NOT use this on a floppy, it's too slow!
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int WriteProtectedDirCheck(
|
|
LPCTSTR lpszFile)
|
|
{
|
|
SHORT nFileOffset;
|
|
TCHAR szFile[MAX_PATH + 1];
|
|
TCHAR szBuf[MAX_PATH + 1];
|
|
|
|
lstrcpyn(szFile, lpszFile, MAX_PATH + 1);
|
|
nFileOffset = (SHORT)(int)LOWORD(ParseFile(szFile, TRUE, FALSE, TRUE));
|
|
|
|
szFile[nFileOffset - 1] = CHAR_NULL;
|
|
if (!GetTempFileName(szFile, TEXT("TMP"), 0, szBuf))
|
|
{
|
|
return (GetLastError());
|
|
}
|
|
else
|
|
{
|
|
DeleteFile(szBuf);
|
|
return (0); // success
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FOkToWriteOver
|
|
//
|
|
// Verifies that the user really does want to destroy the file,
|
|
// replacing its contents with new stuff.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL FOkToWriteOver(
|
|
HWND hDlg,
|
|
LPTSTR szFileName)
|
|
{
|
|
if (!CDLoadString( g_hinst,
|
|
iszOverwriteQuestion,
|
|
szCaption,
|
|
WARNINGMSGLENGTH - 1 ))
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
//
|
|
// Since we're passed in a valid filename, if the 3rd & 4th characters
|
|
// are both slashes, weve got a dummy drive as the 1st two characters.
|
|
//
|
|
if (DBL_BSLASH(szFileName + 2))
|
|
{
|
|
szFileName = szFileName + 2;
|
|
}
|
|
|
|
wsprintf(szWarning, szCaption, szFileName);
|
|
|
|
GetWindowText(hDlg, szCaption, cbCaption);
|
|
return (MessageBox( hDlg,
|
|
szWarning,
|
|
szCaption,
|
|
MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION ) == IDYES);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CreateFileDlg
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int CreateFileDlg(
|
|
HWND hDlg,
|
|
LPTSTR szPath)
|
|
{
|
|
//
|
|
// Since we're passed in a valid filename, if the 3rd & 4th
|
|
// characters are both slashes, we've got a dummy drive as the
|
|
// 1st two characters.
|
|
//
|
|
if (DBL_BSLASH(szPath + 2))
|
|
{
|
|
szPath = szPath + 2;
|
|
}
|
|
|
|
if (!CDLoadString(g_hinst, iszCreatePrompt, szCaption, TOOLONGLIMIT))
|
|
{
|
|
return (IDNO);
|
|
}
|
|
if (lstrlen(szPath) > TOOLONGLIMIT)
|
|
{
|
|
*(szPath + TOOLONGLIMIT) = CHAR_NULL;
|
|
}
|
|
|
|
wsprintf(szWarning, szCaption, szPath);
|
|
|
|
GetWindowText(hDlg, szCaption, TOOLONGLIMIT);
|
|
|
|
return (MessageBox( hDlg,
|
|
szWarning,
|
|
szCaption,
|
|
MB_YESNO | MB_ICONQUESTION ));
|
|
}
|
|
|
|
|
|
#ifndef UNICODE
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// EliminateString
|
|
//
|
|
// Chops the string by the specified length. If a DBCS lead byte is
|
|
// left as the last char, then it is removed as well.
|
|
//
|
|
// NOTE: For non-Unicode strings only.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
VOID EliminateString(
|
|
LPSTR lpStr,
|
|
int nLen)
|
|
{
|
|
LPSTR lpChar;
|
|
BOOL bFix = FALSE;
|
|
|
|
*(lpStr + nLen) = CHAR_NULL;
|
|
for (lpChar = lpStr + nLen - 1; lpChar >= lpStr; lpChar--)
|
|
{
|
|
if (!IsDBCSLeadByte(*lpChar))
|
|
{
|
|
break;
|
|
}
|
|
bFix = !bFix;
|
|
}
|
|
if (bFix)
|
|
{
|
|
*(lpStr + nLen - 1) = CHAR_NULL;
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IsBackSlash
|
|
//
|
|
// Decides whether a character is a '\' or a DBCS trail byte with the same
|
|
// code point value.
|
|
//
|
|
// NOTE: For non-Unicode strings only.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL IsBackSlash(
|
|
LPSTR lpStart,
|
|
LPSTR lpChar)
|
|
{
|
|
if (*lpChar == CHAR_BSLASH)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
|
|
while (--lpChar >= lpStart)
|
|
{
|
|
if (!IsDBCSLeadByte(*lpChar))
|
|
{
|
|
break;
|
|
}
|
|
bRet = !bRet;
|
|
}
|
|
return (bRet);
|
|
}
|
|
return (FALSE);
|
|
}
|
|
|
|
#endif
|
|
|