/********************************************************************
 *                                                                  *
 *  MODULE    :  WVFILER.C                                          *
 *                                                                  *
 *  PURPOSE   :  This file high-level File and Path functions to    *
 *               allow WinVN to communicate with the file system.   *
 *                                                                  *
 *                Author - John S. Cooper                           *
 *                Date   - Sept 10, 1994                            *
 *                                                                  *
 *******************************************************************/

/* ------------------------------------------------------------------------
 * File handlers
 *
 *
 * $Id: wvfiler.c 1.12 1997/02/08 11:16:20 dumoulin Exp $
 */

#include <windows.h>
#include <windowsx.h>

#ifdef _WIN32
#include <shlobj.h> //shell file dialog

#ifndef BIF_NEWDIALOGSTYLE 
#define BIF_NEWDIALOGSTYLE 0x0040 
#endif 

#endif

#include "wvglob.h"
#include "winvn.h"
#pragma hdrstop
#include <io.h>         // for _access
#include <stdlib.h>       // itoa
#include <TCHAR.H>
#include <ctype.h>

#define MAXFILTERLEN 512

// Windows 2000 version of OPENFILENAME
struct OPENFILENAMEEX : public OPENFILENAME 
{ 
#if (_WIN32_WINNT < 0x0500)
#pragma message("_WIN32_WINNT is < 0x500" )
	void *        pvReserved;
	DWORD         dwReserved;
	DWORD         FlagsEx;
#endif
};


void GenerateFileFilters (HWND hParentWnd, char *filters)  /* Set up filters */

{
	register int i;
	int len;
	char chReplace;

	if ((len = LoadString (hInst, IDS_FILTERSTRING, filters, MAXFILTERLEN - 1)) == 0) 
	{
		WVMessageBox (hParentWnd, "No Filters Available", "String Load Failure", MB_OK | MB_ICONSTOP);
		*filters = '\0';
	}
	else 
	{
		chReplace = filters[len - 1]; /* grab separator */

		for (i = 0; filters[i] != '\0'; i++)
			if (filters[i] == chReplace)
				filters[i] = '\0';
	}
}

/* ------------------------------------------------------------------------
 *  Asks for a path
 *  jsc
 */

#ifdef _WIN32

typedef struct BROWSEDIRINFO
{
    short ver;
    LPCSTR  szPath;
} BROWSEDIRINFO;

//WIN32 use shell folder dlg
int CALLBACK BrowseCallbackProc(HWND hWnd,UINT uMsg,LPARAM lp, LPARAM pData) 
{
	TCHAR szDir[_MAX_PATH];
    static short shellVer = 0;
    BROWSEDIRINFO* lpDirInfo =NULL; 

	switch(uMsg) 
	{
		case BFFM_INITIALIZED: 
		{
            lpDirInfo = (BROWSEDIRINFO*) pData;
            if (lpDirInfo)
            {
                shellVer = lpDirInfo->ver;
            }
            else
            {
                shellVer = 0;
            }
            if (shellVer >= 0x0500)
            {
               //XP, 2K etc. support
               //turn on status static control at top of shell dialog
               //which is disabled with BIF_NEWDIALOGSTYLE style dialog
               HWND hWndStatus, hWndTitle = GetDlgItem(hWnd, 0x00003742);
		       RECT rc = {0};
		       if(hWndTitle)
		       {
			     GetWindowRect(hWndTitle, &rc);
			     MapWindowPoints(NULL,GetParent(hWndTitle),(LPPOINT)&rc, 2);
			     rc.bottom = rc.top + 20;
			     SetWindowPos(hWndTitle, NULL,
			       rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
			       (SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER|SWP_SHOWWINDOW));
		       }

		       hWndStatus = GetDlgItem(hWnd, 0x00003741);
		       if(hWndStatus)
		       {
			     DWORD dwNewStyle;
			     EnableWindow(hWndStatus, TRUE);
			     dwNewStyle = GetWindowLong(hWndStatus, GWL_STYLE) |
			       (SS_PATHELLIPSIS|SS_NOPREFIX);
			     SetWindowLong(hWndStatus, GWL_STYLE, dwNewStyle);
			     
			     OffsetRect(&rc, 0, 26);
			     SetWindowPos(hWndStatus, NULL,
			       rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
			       (SWP_NOACTIVATE|SWP_NOZORDER|SWP_SHOWWINDOW));
		       }
            }
			// WParam is TRUE since you are passing a path.
			// It would be FALSE if you were passing a pidl.
			if (lpDirInfo)
                SendMessage(hWnd,BFFM_SETSELECTION,TRUE,(LPARAM)lpDirInfo->szPath);

			break;
		}
		case BFFM_SELCHANGED: 
		{
			// Set the status window to the currently selected path.
			if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szDir)) 
			{
				 
                 if (shellVer < 0x0500)
                 {
                 
                    SendMessage(hWnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
                 }
                 else
                 {
				     HWND hWndStatus = GetDlgItem(hWnd, 0x00003741);
				     if(hWndStatus)
				     {
				       SetWindowText(hWndStatus, szDir);
				     }
                }

			}
			break;
		}
		default:
			break;
	}
	return 0;
}
#endif

int AskForFilePath (HWND hParentWnd, char *pathName, char *title)
{

#ifdef _WIN32

	DWORD dwVer = GetDllVersion("SHELL32.DLL") >> 16;

    if (dwVer >= 0x0400)
    {
	    TCHAR szDir[_MAX_PATH];
	    LPITEMIDLIST pidl;
	    LPMALLOC pMalloc;

	    if (SUCCEEDED(SHGetMalloc(&pMalloc))) 
	    {
		    BROWSEDIRINFO dirInfo;
            BROWSEINFO bi;

            dirInfo.ver = (short) dwVer;
            dirInfo.szPath = pathName;
            
            ZeroMemory(&bi,sizeof(bi));
		    bi.hwndOwner = hParentWnd;
		    bi.pszDisplayName = 0;
		    bi.pidlRoot = 0;
		    bi.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS |BIF_VALIDATE;
		    
            //version 5 of shell.dll supports new style browse dialog, unfortunately
            //it's not compatible with BIF_EDITBOX param. We take care of this in the
            //callback
            if (dwVer >= 0x0500)
                bi.ulFlags |= BIF_NEWDIALOGSTYLE;
            else
                bi.ulFlags |= BIF_EDITBOX;
        
        
            bi.lpfn = BrowseCallbackProc;
		    bi.lpszTitle = title;
            bi.lParam = (LPARAM) &dirInfo;

		    pidl = SHBrowseForFolder(&bi);
		    if (pidl) 
		    {
			    if (SHGetPathFromIDList(pidl,szDir)) 
			    {
				    strcpy(pathName, szDir);

			    }

			    //CoTaskMemFree(pidl);
                //pMalloc->lpVtbl->Free(pMalloc, pidl);
                //pMalloc->lpVtbl->Release(pMalloc);
				  pMalloc->Free(pidl);
				  pMalloc->Release();
			    return(SUCCESS);


		    }
		    //pMalloc->lpVtbl->Release(pMalloc);
			pMalloc->Release();

		    return (FAIL);
	    
	    }

	    return(FAIL);
    }
#endif

    //use old method on NT3.51, Win3.x

	if (!DialogBoxParam (hInst, MAKEINTRESOURCE(IDD_WINVNSELECTPATH), hParentWnd, (DLGPROC) lpfnWinVnSelectPathDlg, (LPARAM) pathName))
		return (FAIL);
	strcpy (pathName, AnsiLower (DialogString));

	return (SUCCESS);

}


/* ------------------------------------------------------------------------
 * Asks for a filename which must exist
 */
BOOL AskForExistingFileName (HWND hParentWnd, char *fileName, char *title)
{
	OPENFILENAME ofn;
	char szFile[MAXFILENAME];
	char filters[MAXFILTERLEN];

	GenerateFileFilters (hParentWnd, filters);

	memset (&ofn, 0, sizeof (OPENFILENAME));
	szFile[0] = '\0';
	ofn.lpstrTitle = title;
	ofn.lStructSize = sizeof (OPENFILENAME);
	ofn.hwndOwner = hParentWnd;
	ofn.lpstrFilter = filters;
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = szFile;
	ofn.nMaxFile = sizeof (szFile);
	ofn.lpstrFileTitle = NULL;
	ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
	ofn.lpstrInitialDir = *fileName ? NULL : AttachPath;

	strntcpy(AttachPath, fileName, MAXFILENAME);


	if (GetOpenFileName (&ofn) == 0)
		return (FAIL);
	/*  strcpy (fileName, AnsiLower (szFile)); */
	strcpy (fileName, szFile);   //DLS Preserve capitals in filename for encode
	PathWithoutName(AttachPath, szFile);
	return (SUCCESS);
}

//Ask for multiple filenames which must exist
BOOL AskForExistingFileNames (HWND hParentWnd, TCHAR *fileName, TCHAR *title, TCHAR **files)
{

	OPENFILENAMEEX ofn;
	bool bMoldy = false;
	ZeroMemory(&ofn,sizeof(OPENFILENAMEEX));
	ofn.lStructSize     = sizeof(OPENFILENAME);
	BOOL bAlloc = FALSE;

	if (!files)
		return FAIL;
	if (!*files)
	{
		*files = new TCHAR[32768];
		_tcscpy(*files, fileName);
		bAlloc = TRUE;
	}

	//does windows support explorer OF?
	//check comdlg32.dll version >= 5.0
	DWORD dwVer = GetVersion();
	if (((dwVer & 0x80000000) == 0) && ((dwVer & 0xFF) > 4) )
#if (_WIN32_WINNT >= 0x0500)
		ofn.lStructSize = sizeof OPENFILENAME; //ofn is already large
	else
	{
		ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; //no it doesn't
		bMoldy = true;
	}
#else
		ofn.lStructSize = sizeof OPENFILENAMEEX; //if WIN32_WINNT >= 0x0500 this is too large
	else
	{
		ofn.lStructSize = sizeof OPENFILENAME;
		bMoldy = true;
	}
#endif	
	
	char filters[MAXFILTERLEN];
	GenerateFileFilters (hParentWnd, filters);

	ofn.lpstrTitle = title;
	ofn.hwndOwner = hParentWnd;
	ofn.lpstrFilter = filters;
	ofn.lpstrInitialDir = AttachPath;
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = *files;
	ofn.nMaxFile = 32768;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | (bMoldy ? 0 : OFN_EXPLORER);

	if (GetOpenFileName (&ofn) == 0)
	{
		if (bAlloc)
		{
			if (*files)
				delete [] *files;
			*files = NULL;
		}
		return (FAIL);
	}
	//For Explorer-style dialog boxes, the directory and file name strings are NULL separated, 
	//with an extra NULL character after the last file name. This format enables the Explorer-style 
	//dialog boxes to return long file names that include spaces. For old-style dialog boxes, 
	//the directory and file name strings are separated by spaces and the function uses short 
	//file names for file names with spaces.
	if (bMoldy)
	{
		TCHAR *pEnd = _tcschr(*files, ' ');
		if (pEnd)
		{
			_tcsncpy(fileName, *files, (pEnd- (*files)));
		}
		else
		{
			_tcsncpy(fileName, *files, MAXFILENAME);
		}
		strntcpy(AttachPath, fileName, MAXFILENAME);

		(*files)[ofn.nFileOffset-1] = 0;
		while (pEnd)
		{
			*pEnd++ = NULL;
			pEnd = _tcschr(pEnd, ' ');
		}

	} 
	else
	{
		TCHAR *pEnd = *files + _tcslen(*files)+1;
		_tcscpy(fileName, *files);

		if (!*pEnd)
		{
			//single file
			TCHAR *p = _tcsrchr(*files, '\\');
			if (p)
				*p = _T('\0');
		}
		_tcscat(fileName, _T("\\"));
		strntcpy(AttachPath, fileName, MAXFILENAME); 

		if (*pEnd)
			_tcscat(fileName, pEnd);
	}
	return (SUCCESS);
}

/* ------------------------------------------------------------------------
 * Check if file name is OK based on SmartFiler settings.  If not, prompt user new name
 * Check if file already exists.  If so, prompt user OK to overwrite
 * If fileName contains a name on entry, check if it's OK, if yes-done
 */
int AskForNewFileName (HWND hParentWnd, char *fileName, char *startDir, BOOL appendOk)
{
	char mybuf[MAXINTERNALLINE];
	char szDirName[_MAX_DIR];
	char szFile[_MAX_PATH];
	BOOL valid = FALSE;
	char filters[MAXFILTERLEN];


	OPENFILENAMEEX ofn;
	ZeroMemory(&ofn,sizeof(OPENFILENAMEEX));
	ofn.lStructSize     = sizeof(OPENFILENAME);

	//does windows support explorer OF?
	//check comdlg32.dll version >= 5.0
	DWORD dwVer = GetVersion();
	if (((dwVer & 0x80000000) == 0) && ((dwVer & 0xFF) > 4) )
#if (_WIN32_WINNT >= 0x0500)
		ofn.lStructSize = sizeof OPENFILENAME; //ofn is already large
	else
		ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#else
		ofn.lStructSize = sizeof OPENFILENAMEEX; //if WIN32_WINNT >= 0x0500 this is too large
	else
		ofn.lStructSize = sizeof OPENFILENAME;
#endif



	*szDirName = '\0';  //MDS initialize!
	GenerateFileFilters (hParentWnd, filters);

	/* loop while no filename, invalid filename, or file exists */
	while (fileName[0] == '\0' ||
		  (valid = VerifyFileName (fileName)) == FAIL ||
		  (!appendOk && _access (fileName, 0) == 0)) 
	{

		/* filename valid, but file exists - ask if want to overwrite it */
		if (fileName[0] != '\0' && valid == SUCCESS) 
		{
			_snprintf (mybuf, MAXINTERNALLINE, "File %s exists.  OK to overwrite it?", fileName);
			if (WVMessageBox (hParentWnd, mybuf, "File exists",
   				MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION | MB_TOPMOST) == IDYES)
				break;
		}

		/* Open dialog to ask user for a new file name */
		if (fileName[0] != '\0')
			_snprintf (mybuf, MAXINTERNALLINE, "SmartFiler: Invalid file name. Select new name");
		else 
		{
			if (appendOk)
				strcpy (mybuf, "Select new file name to create/append");
			else
				strcpy (mybuf, "Select new file name to create/overwrite");
		}
		ofn.lpstrTitle = mybuf;
		if ((startDir) && (*startDir)) 
		{
			strcpy(szDirName, startDir);
			ofn.lpstrInitialDir = szDirName;
		}
		else
			ofn.lpstrInitialDir = NULL;

		strncpy(szFile, fileName, _MAX_PATH);

		ofn.hwndOwner = hParentWnd;
		ofn.lpstrFilter = filters;
		ofn.nFilterIndex = 1;
		ofn.lpstrFile = szFile;
		ofn.nMaxFile = sizeof (szFile);
		ofn.lpstrFileTitle = NULL;
		ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER;

		if (GetOpenFileName (&ofn) == 0)
			return (FAIL);

		strcpy (fileName,  (ofn.lpstrFile));
	}
	return (SUCCESS);
}
/* ------------------------------------------------------------------------
 * Test file name is OK using SmartFiler settings
 */
int VerifyFileName (char *fileName)
{
	char *beg, *ptr;

	if ((beg = strrchr (fileName, '\\')) == NULL)
		beg = fileName;
	else
		beg++;            /* skip to after path slash */

	if ((ptr = strrchr (beg, '.')) == NULL)
		if (strlen (beg) <= MaxFileNameLen)   /* no extension */
			return (SUCCESS);

	if ((unsigned int) (ptr - beg) > MaxFileNameLen)
		return (FAIL);

	beg = ptr + 1;
#ifndef _WIN32         /* multiple extensions (ok in NTFS) */
	if ((ptr = strchr (beg, '.')) != NULL)
		return (FAIL);
#endif

	if (strlen (beg) > MaxFileExtLen)   /* extension too long */
		return (FAIL);

	return (SUCCESS);
}

/* ------------------------------------------------------------------------
 * SplitFileName into path, name, ext, fullName
 * i.e. c:\windows\system\xyz.txt returns xyz.txt
 * path     --> c:\windows\system  (note no final slash)
 * name     --> xyz
 * ext      --> txt
 * fullName --> xyz.txt
 *
 * args must be pointers to buffers large enough to hold strings
 * any of args can be NULL, in which case that fileName portion is ignored
 */
void SplitFileName (char *path, char *name, char *ext, char *fullName, char *fileName)
{
	char *start, *slash, *dot, *end, saveSlash= 0;
	BOOL restoreSlash;
#ifndef _WIN32
	char * ptr;
#endif

	start = fileName;
	end = start + strlen (fileName);

	if ((slash = strrchr (start, '\\')) == NULL && (slash = strrchr (start, '/')) == NULL) 
	{
		//MDS not all filesystems use '\', we split paths from filenames embedded in downloads too
		/* handle case like c:abc.def (no slash) */
		restoreSlash = FALSE;
		if (start[1] == ':' && tolower (*start) >= 'a' && tolower (*start) <= 'z') 
		{
			slash = &start[2];
		}
		else 
		{
			slash = start;      /* there is no path */
		}
	}
	else 
	{
		saveSlash = *slash;
		*slash = '\0';        /* replace last slash with null */
		restoreSlash = TRUE;
		slash++;
	}
	if (path) 
	{
		if (slash == start)
			*path = '\0';
		else
			strncpy (path, start, MAXFILENAME-1);   /* from start to slash is the path */
	}

	if (fullName)
		strncpy (fullName, slash, MAXFILENAME-1);

	if ((dot = strrchr (slash, '.')) == NULL) 
	{
		dot = end;
	}
	else 
	{
		*dot = '\0';        /* replace last dot with null */

#ifndef _WIN32         /* replace multiple dots with dashes in non-NTFS */
		for (ptr = slash; *ptr; ptr++) 
		{
			if (*ptr == '.') 
			{
				*ptr = '-';
			}
		}
#endif

		dot++;
	}
	if (name) 
	{
		strncpy (name, slash, MAXFILENAME-1);   /* from after the slash to dot is the name */
	}

	if (ext) 
	{
		strncpy (ext, dot, _MAX_EXT -1);      /* from after the dot to the end is the extension */
	}
	if (slash != start && restoreSlash)
		*(slash - 1) = saveSlash;    /* restore the slash */
	if (dot != end)
		*(dot - 1) = '.';     /* restore the dot */
}

/* useful front ends to SplitFileName */
char * GetFileExtension (char *ext, char *fileName)
{
	SplitFileName (NULL, NULL, ext, NULL, fileName);
	return ext;
}

char * NameWithoutPath (char *name, char *fileName)
{
	SplitFileName (NULL, NULL, NULL, name, fileName);
	return name;
}

char * PathWithoutName (char *path, char *fileName)
{
	SplitFileName (path, NULL, NULL, NULL, fileName);
	return path;
}

BOOL StripNonDosChars(unsigned char *path)
{
	const char szDosChars[] = 
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_^$~!#%&-{}@`'()";
	int len, i, j;

	if (!path || !*path)
		return FALSE;

	len = strlen((char *)path);
	j = 0;

	for (i = 0; i < len; i++) 
	{
		if (strchr(szDosChars, path[i]))
			path[j++] = path[i];
	}
	path[j] = '\0';
	return TRUE;
}

BOOL StripSpecialChars(unsigned char *path)
{
  size_t i = 0, j = 0;

  if (!path || !*path)
    return FALSE;
  
  //Win95+ Fat32 disallows \/:*?"<>|

  while(i < strlen((char*)path)) 
  {

    if (SpaceProcessing && path[i] == 0x20)
		path[i] = 0x5F;

	if (path[i] >= 0x20 && // reserved
        path[i] != 0x22 && // "
        path[i] != 0x2F && // /
        path[i] != 0x5C && // '\'
        path[i] != 0x3A && // ':'
        path[i] != 0x2A && // *
        path[i] != 0x3F && // ?
        path[i] != 0x3C && // <
        path[i] != 0x3E && // >
        path[i] != 0x7C && // |
        path[i] != 0x7F )  // del
          path[j++] = path[i];
     i++;
  }
  path[j] = '\0';
  return TRUE;
}

/* ------------------------------------------------------------------------
 * Smartfiler: HandleDupeName 
 * check if dupe file name, and if there is, deal with it 
 * return SUCCESS if dupe and handled (fixed name in newName),or if no dupe
 * return FAIL on serious failure
 */
int HandleDupeName (HWND hParentWnd, char *fileName)
{
	char path[MAXFILENAME], name[MAXFILENAME], ext[MAXFILENAME], numStr[4];
	char newName[MAXFILENAME], namecat[MAXFILENAME];
	int i =0, len;

	if (_access (fileName, 0) < 0)
		return SUCCESS;

	/* we have a dupe */
	
	SplitFileName (path, name, ext, newName, fileName);
	switch (OnDupeName) 
	{
		case DUPE_AVOID_NONE:
		return AskForNewFileName (hParentWnd, fileName, path, FALSE);
		break;

		case DUPE_AVOID_NUMBER_EXT:
		for (i = 0; i < 999; i++) 
		{
			_snprintf (newName, MAXFILENAME, "%s\\%s.%03d", path, name, i);
			if (_access (newName, 0) < 0)
				break;
		}
		break;

		case DUPE_AVOID_PREPEND_NUM:
		for (i = 0; i < 999; i++) 
		{
			_snprintf (namecat, MAXFILENAME, "%d%s", i, name);
			namecat[MaxFileNameLen] = '\0';
			_snprintf (newName, MAXFILENAME, "%s\\%s.%s", path, namecat, ext);
			if (_access (newName, 0) < 0)
				break;
		}
		break;

		case DUPE_AVOID_APPEND_NUM:
		for (i = 0; i < 999; i++) 
		{
			_itoa (i, numStr, 10);
			len = MaxFileNameLen - strlen (numStr);
			if (len <= 0) 
			{
				i = 1000;
				break;
			}
			name[len] = '\0';
			_snprintf (namecat, MAXFILENAME, "%s%d", name, i);
			namecat[MaxFileNameLen] = '\0';
			_snprintf (newName, MAXFILENAME, "%s\\%s.%s", path, namecat, ext);
			if (_access (newName, 0) < 0)
				break;
		}
		break;
	}
	if (i == 1000)        /* we failed to get an alternative, so ask user for help */
		return AskForNewFileName (hParentWnd, fileName, path, FALSE);
	else
		strcpy (fileName, newName);

	return SUCCESS;
}

/* ------------------------------------------------------------------------
 * SmartFiler: HandleLongName
 * check if given name is longer than given maxLen, and if it is, deal with it 
 * return SUCCESS if too long and handled (fixed name in newName), 
 * or if name is not too long
 * return FAIL if not handled
 */
int HandleLongName (char *name, unsigned int maxLen)
{
	char newName[MAXFILENAME];
	unsigned int skipped, len, src, dest;
	BOOL result = FAIL;

	len = strlen (name);
	if (len <= maxLen)
	return SUCCESS;

	/* name too long */
	switch (OnNameTooLong) 
	{
		case SHORTEN_NONE:
		result = FAIL;
		break;

		case SHORTEN_TRUNCATE:
		name[maxLen] = '\0';
		result = SUCCESS;
		break;

		case SHORTEN_SKIP_VOWELS:
		src = dest = skipped = 0;
		while (dest < maxLen && src < len) 
		{
			if (len - skipped > maxLen && strchr ("aeiou-_*!@:#$%^&*{}[]<>,()+.", name[src])) 
			{
				skipped++;
			}
			else 
			{
				newName[dest] = name[src];
				dest++;
			}
			src++;
		}
		newName[dest] = '\0';
		strcpy (name, newName);
		result = SUCCESS;
		break;
	}
	return result;
}

/* ------------------------------------------------------------------------
 * SmartFiler: HandleExtensionConversion
 * check if ext is in the extension mapping list, and if so,
 * replace it with the mapped ext
 */
void HandleExtensionConversion (char *ext)
{
	register unsigned long i;
	for (i = 0L; i < ExtMapSourceList->numLines; i++) 
	{
		if (!_stricmp (TextBlockLine (ExtMapSourceList, i), ext)) 
		{
			strcpy (ext, TextBlockLine (ExtMapDosList, i));
			break;
		}
	}
}

/* ------------------------------------------------------------------------
 * SmartFiler
 * processes fileName for dupe, too long, extension conversion
 * returns SUCCESS if everything works, else FAIL
 */
int SmartFile (HWND hParentWnd, char *fileName)
{
	char newName[MAXFILENAME];
	char path[MAXFILENAME], name[MAXFILENAME], ext[MAXFILENAME];
	BOOL result, result2;

	strcpy (newName, fileName);
	strcpy(ext, ".");
	SplitFileName (path, name, &ext[1], NULL, fileName);

	if (EnableExtensionConversion)
		HandleExtensionConversion (ext);

	//remove illegal win32 filename characters   20000401
	StripSpecialChars((unsigned char *) name);
	StripSpecialChars((unsigned char *)&ext[1]);

	if (MaxFileNameLen <= 8 && MaxFileExtLen <= 4)
	{
		//MDS remove illegal win16 chars 20000401
		StripNonDosChars((unsigned char *)name);
		StripNonDosChars((unsigned char *)&ext[1]);
	}
	_snprintf (newName, MAXFILENAME, "%s\\%s%s", path, name, ext);

	if (VerifyFileName (newName) == FAIL) 
	{
		result = HandleLongName (name, MaxFileNameLen);
		result2 = HandleLongName (&ext[1], MaxFileExtLen);
		_snprintf (newName, MAXFILENAME, "%s\\%s%s", path, name, ext);  //MDS - actually use changes!

		if (result == FAIL || result2 == FAIL) 
		{
			if (AskForNewFileName (hParentWnd, newName, path, FALSE) == FAIL)
				return FAIL; /* user has click'd cancel */
		}
	}
	result = HandleDupeName (hParentWnd, newName);
	strcpy (fileName, newName);
	return result;
}

/*
 * Local Variables:
 * tab-width: 2
 * end:
 */
