windows-nt/Source/XPSP1/NT/shell/shdocvw/impexpwz.cpp
2020-09-26 16:20:57 +08:00

2701 lines
75 KiB
C++

/*
* Author: t-franks
*
* Last Modified On: Oct 16, 1998
* Last Modified By: t-joshp
*
*/
#include "priv.h"
#include "resource.h"
#include "impexp.h"
#include "mluisupp.h" // for MLLoadString
#include "apithk.h"
//
// Indices into our imagelist
// (used for the open and closed folder icons on the tree view)
//
#define FOLDER_CLOSED 0
#define FOLDER_OPEN 1
#define ImportCookieFile ImportCookieFileW
#define ExportCookieFile ExportCookieFileW
BOOL ImportCookieFileW(IN LPCWSTR szFilename);
BOOL ExportCookieFileW(IN LPCWSTR szFilename, BOOL fAppend);
extern void SetListViewToString (HWND hLV, LPCTSTR pszString);
//
// used to display "file already exists" and "file not found" messages
//
int WarningMessageBox(HWND hwnd, UINT idTitle, UINT idMessage, LPCTSTR szFile, DWORD dwFlags);
//
// Strings that don't need localizing
//
#define NS3_COOKIE_REG_PATH TEXT("Software\\Netscape\\Netscape Navigator\\Cookies")
#define NS3_COOKIE_REG_KEY TEXT("Cookie File")
#ifndef UNIX
#define NS3_BOOKMARK_REG_PATH TEXT("Software\\Netscape\\Netscape Navigator\\Bookmark List")
#else
#define NS3_BOOKMARK_REG_PATH TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\unix\\nsbookmarks")
#endif
#define NS3_BOOKMARK_REG_KEY TEXT("File Location")
#define NS4_USERS_REG_PATH TEXT("Software\\Netscape\\Netscape Navigator\\Users")
#define NS4_USERPATH_REG_KEY TEXT("DirRoot")
#define NS_FALLBACK_ROOT_REG_KEY TEXT("Software\\Netscape\\Netscape Navigator")
#define NS_FALLBACK_VERSION_REG_VAL TEXT("CurrentVersion")
#define NS_FALLBACK_MAIN_REG_VAL TEXT("Main")
#define NS_FALLBACK_INST_REG_VAL TEXT("Install Directory")
#ifndef UNIX
#define ALL_FILES_WILDCARD TEXT("\\*.*")
#else
#define ALL_FILES_WILDCARD TEXT("/*")
#endif
#define DOT_DIR TEXT(".")
#define DOT_DOT_DIR TEXT("..")
#ifdef UNIX
#define DIR_SEPARATOR_CHAR TEXT('/')
#else
#define DIR_SEPARATOR_CHAR TEXT('\\')
#endif
//*************************************************************
//
// class ListIterator
//
// Keeps hold on a position in a list. Allows basic access
//to a list. The list is set up to map a name to a value.
class NestedList;
class ListIterator
{
friend NestedList;
struct node
{
LPTSTR _sName;
LPTSTR _sValue;
DWORD _cNameSize, _cValueSize;
node* _pnNext;
node* _pnSublist;
};
// A position is held by pointing to the
//current node and the pointer that is directed
//to that node. The back pointer is kept so the
//list can be manipulated at the current element.
// when m_pnCurrent == NULL, the iterator is
//at the end of the list.
node** m_ppnPrev;
node* m_pnCurrent;
// The invariant could be broken if two iterators
//point to the same node, and one inserts or deletes
//an element. So only one iterator should exist in
//a branch of the list at a time.
BOOL invariant()
{
return *m_ppnPrev == m_pnCurrent;
}
public:
ListIterator( node** ppnPrev)
{
m_ppnPrev = ppnPrev;
m_pnCurrent = *m_ppnPrev;
}
BOOL Insert( LPCTSTR sName, DWORD cNameSize, LPCTSTR sValue, DWORD cValueSize);
BOOL Remove();
ListIterator GetSublist();
void DeleteSublist();
BOOL Next();
BOOL AtEndOfList();
LPCTSTR GetName();
DWORD GetNameSize();
LPCTSTR GetValue();
DWORD GetValueSize();
};
//*************************************************************
//
// class NestedList
// Keeps a pointer to a node which heads a list,
// and deletes that list on destruction.
class NestedList
{
ListIterator::node* m_pnRoot;
public:
NestedList();
~NestedList();
operator ListIterator();
};
NestedList::NestedList()
: m_pnRoot(NULL)
{
}
NestedList::~NestedList()
{
while( ((ListIterator)*this).Remove())
{
}
}
NestedList::operator ListIterator()
{
return ListIterator( &m_pnRoot);
}
//*************************************************************
//*************************************************************
//
// ListIterator functions
//
// Inserts an element before the current one,
//leaves iterator pointing at new node.
BOOL ListIterator::Insert(
LPCTSTR sName,
DWORD cNameSize,
LPCTSTR sValue,
DWORD cValueSize)
{
ASSERT( invariant());
node* pNewNode = (node*)(new BYTE[ sizeof(node)
+ (( cNameSize + cValueSize)
* sizeof(TCHAR))]);
if( pNewNode == NULL)
return FALSE;
// the name and value will be appended to the node.
pNewNode->_sName = (LPTSTR)((BYTE*)pNewNode + sizeof(node));
pNewNode->_sValue = pNewNode->_sName + cNameSize;
pNewNode->_cNameSize = cNameSize;
pNewNode->_cValueSize = cValueSize;
memcpy( pNewNode->_sName, sName, pNewNode->_cNameSize * sizeof(TCHAR));
memcpy( pNewNode->_sValue, sValue, pNewNode->_cValueSize * sizeof(TCHAR));
// insert new node in list
pNewNode->_pnNext = m_pnCurrent;
*m_ppnPrev = pNewNode;
// The iterator now points to the new element.
m_pnCurrent = *m_ppnPrev;
ASSERT( invariant());
return TRUE;
}
// Deletes the current node.
// Returns FALSE if at end of list.
BOOL ListIterator::Remove()
{
ASSERT( invariant());
// If this list is empty, or if the iterator
//points at the end of the list, there is nothing to
//delete.
if( m_pnCurrent == NULL)
return FALSE;
// remove sublist
DeleteSublist();
// Remember where target node is
//so it can be deleted once out of
//the list.
node* pOldNode = m_pnCurrent;
// take the target node out of the list.
//(iterator points to next node or end of list)
*m_ppnPrev = m_pnCurrent->_pnNext;
m_pnCurrent = *m_ppnPrev;
// Get rid of target node.
delete [] (BYTE*)pOldNode;
ASSERT( invariant());
return TRUE;
}
// Returns the sublist of the current node.
ListIterator ListIterator::GetSublist()
{
ASSERT( invariant());
return ListIterator( &(m_pnCurrent->_pnSublist));
}
// deletes the children of the current node.
void ListIterator::DeleteSublist()
{
ASSERT( invariant());
ListIterator sublist( &(m_pnCurrent->_pnSublist));
while( sublist.Remove())
{
}
ASSERT( invariant());
}
// Advances to the next node.
// Returns FALSE if already at end of list.
BOOL ListIterator::Next()
{
ASSERT( invariant());
if( m_pnCurrent == NULL)
return FALSE;
m_ppnPrev = &(m_pnCurrent->_pnNext);
m_pnCurrent = *m_ppnPrev;
ASSERT( invariant());
return m_pnCurrent != NULL;
}
//
BOOL ListIterator::AtEndOfList()
{
return ( m_pnCurrent == NULL) ? TRUE : FALSE;
};
//
LPCTSTR ListIterator::GetName()
{
ASSERT( invariant() && m_pnCurrent != NULL);
return m_pnCurrent->_sName;
}
//
DWORD ListIterator::GetNameSize()
{
ASSERT( invariant() && m_pnCurrent != NULL);
return m_pnCurrent->_cNameSize;
}
//
LPCTSTR ListIterator::GetValue()
{
ASSERT( invariant() && m_pnCurrent != NULL);
return m_pnCurrent->_sValue;
}
//
DWORD ListIterator::GetValueSize()
{
ASSERT( invariant() && m_pnCurrent != NULL);
return m_pnCurrent->_cValueSize;
}
//*************************************************************
//*************************************************************
//
// class ImpExpUserProcess
//
// maintains the description of an import/export process
// for an import/export wizard, and finally executes the
// the import/export.
enum ExternalType { INVALID_EXTERNAL = 0, COOKIES, BOOKMARKS};
enum TransferType { INVALID_TRANSFER = 0, IMPORT, EXPORT};
class ImpExpUserProcess
{
public:
ImpExpUserProcess();
~ImpExpUserProcess();
// the first step the wizard should do is identify the type of
//import/export process to be done.
void SelectExternalType( ExternalType selection) { m_ExternalType = selection; }
void SelectTransferType( TransferType selection) { m_TransferType = selection; }
ExternalType GetExternalType() { return m_ExternalType; }
TransferType GetTransferType() { return m_TransferType; }
BOOL PopulateComboBoxForExternalSelection( HWND hComboBox);
BOOL GetExternalManualDefault( LPTSTR sExternal, DWORD* pcSize);
//
// used to fill the listbox with names of netscape profiles
//
void purgeExternalList();
BOOL populateExternalList();
BOOL populateExternalListForCookiesOrBookmarks();
//
// for netscape 3.x
//
BOOL populateExternalListForCookiesOrBookmarksWithNS3Entry();
//
// for netscape 4.x
//
BOOL populateExternalListForCookiesOrBookmarksWithNS4Entries();
//
// fallback case for "funny" versions of netscape
//
BOOL populateExternalListFromFolders(LPTSTR pszPath);
BOOL populateExternalListWithNSEntriesFallBack();
// If the transfer is for favorites, the wizard needs to specify
//an internal folder to import to or export from.
LPCTSTR GetInternalSelection() { return m_pSelectedInternal; }
BOOL PopulateTreeViewForInternalSelection( HWND TreeView);
BOOL populateTreeViewWithInternalList( HWND hTreeView, ListIterator iterator, HTREEITEM hParent);
BOOL ExpandTreeViewRoot ( HWND hTreeView ) ;
BOOL SelectInternalSelection( HWND TreeView);
void purgeInternalList();
BOOL populateInternalList();
BOOL populateInternalListForBookmarks();
BOOL appendSubdirsToInternalList( LPTSTR sPath, ListIterator iterator);
// And then, the import/export can be completed.
void PerformImpExpProcess(HWND hwnd);
//
// The filename that we're exporting to or
// importing from.
//
TCHAR m_szFileName[MAX_PATH];
private:
ExternalType m_ExternalType;
TransferType m_TransferType;
// m_ExternalList is a flat list of names associated with files
//example: name = "Netscape 4.0 profile - Dr. Falken"
// value = "c:\netscapeprofiledir\DrFalken.chs"
NestedList m_ExternalList;
// m_InternalList is a nested list favorites' pathnames,
//associated with the complete path.
NestedList m_InternalList;
// Maintain synchronization between m_ExternalType/m_TransferType
//and m_InternalList
ExternalType m_InternalListExternalType;
TransferType m_InternalListTransferType;
// if ExternalType == BOOKMARKS,
//m_pSelectedInternal is the path of a Favorites folder,
//residing in m_InternalList somewhere, or NULL if a folder
//hasn't been selected yet.
LPTSTR m_pSelectedInternal;
};
ImpExpUserProcess::ImpExpUserProcess()
: m_ExternalType(INVALID_EXTERNAL), m_TransferType(INVALID_TRANSFER),
m_InternalListExternalType(INVALID_EXTERNAL), m_InternalListTransferType(INVALID_TRANSFER),
m_pSelectedInternal(0)
{
}
ImpExpUserProcess::~ImpExpUserProcess()
{
}
//*************************************************************
// PopulateComboBoxForExternal
//
// Loads content for list box into memory and into List Box,
//associating value of each element with the list element.
// returns FALSE if the list box is left empty
BOOL ImpExpUserProcess::PopulateComboBoxForExternalSelection( HWND hComboBox)
{
ASSERT ( m_ExternalType != INVALID_EXTERNAL ) ;
ComboBox_ResetContent(hComboBox);
// If ExternalList is invalid, the list box will be left empty.
if( !populateExternalList() )
return FALSE;
ListIterator iterator = m_ExternalList;
// Detect and notify if the list is empty.
if( iterator.AtEndOfList() )
return FALSE;
// add entries from the new ExternalList to the ComboBox.
do
{
int index = ComboBox_AddString( hComboBox, const_cast<LPTSTR>(iterator.GetName() ) );
ComboBox_SetItemData( hComboBox, index, const_cast<LPTSTR>(iterator.GetValue() ) );
} while( iterator.Next());
// set the first one as selected
ComboBox_SetCurSel( hComboBox, 0 );
return TRUE;
}
//*************************************************************
//
// GetExternalManualDefault
//
// Allows user interface to offer some sort of default
// filename/location.
//
BOOL ImpExpUserProcess::GetExternalManualDefault(LPTSTR sExternal, DWORD* pcSize)
{
ASSERT(NULL != pcSize);
//
// We only fill it in if it's blank
//
if (m_szFileName[0])
{
return FALSE;
}
ListIterator iterator = m_ExternalList;
TCHAR szFileName[MAX_PATH];
INT cchFileName;
if(m_ExternalType == BOOKMARKS)
MLLoadString(IDS_NETSCAPE_BOOKMARK_FILE,szFileName,ARRAYSIZE(szFileName));
else
MLLoadString(IDS_NETSCAPE_COOKIE_FILE,szFileName,ARRAYSIZE(szFileName));
cchFileName = lstrlen(szFileName) + 1;
// Grab the first item in the External List and use its value.
if( ((ListIterator)m_ExternalList).AtEndOfList() == FALSE
&& ((ListIterator)m_ExternalList).GetValue() != NULL
&& *pcSize >= ((ListIterator)m_ExternalList).GetValueSize())
{
StrCpyN( sExternal,
((ListIterator)m_ExternalList).GetValue(),
((ListIterator)m_ExternalList).GetValueSize());
*pcSize = ((ListIterator)m_ExternalList).GetValueSize();
return TRUE;
}
// If there is enough room, specify some file with the correct name
// in the "my documents" directory.
else
{
ASSERT(m_ExternalType == BOOKMARKS || m_ExternalType == COOKIES);
TCHAR szMyDocsPath[MAX_PATH];
SHGetSpecialFolderPath(NULL,szMyDocsPath,CSIDL_PERSONAL,TRUE);
*pcSize = wnsprintf(sExternal,MAX_PATH,TEXT("%s%c%s"),szMyDocsPath,DIR_SEPARATOR_CHAR,szFileName);
return *pcSize > 0;
}
}
//*************************************************************
//
//
// purgeExternalList
//
// Used to clear external target/source list loaded into memory
void ImpExpUserProcess::purgeExternalList()
{
// delete elements until they're all gone.
ListIterator iterator = m_ExternalList;
while( iterator.Remove())
{
}
}
//*************************************************************
//
// populeExternalList
//
// Used to load external target/source list into memory
BOOL ImpExpUserProcess::populateExternalList()
{
ASSERT(m_ExternalType != INVALID_EXTERNAL)
purgeExternalList();
if(!populateExternalListForCookiesOrBookmarks())
{
//
// If we didn't get any entries using the "standard"
// techniques, then (and only then) we try the "fallback"
//
if (!populateExternalListWithNSEntriesFallBack())
{
purgeExternalList();
return FALSE;
}
}
return TRUE;
}
//*************************************************************
//
// populateExternalListforCookiesOrBookmarks
//
// Used to lod external target/source list into memory
//in the case that the content to be transfered is cookies
//or bookmarks.
// returns TRUE if any elements have been added to the external list
BOOL ImpExpUserProcess::populateExternalListForCookiesOrBookmarks()
{
ASSERT( m_ExternalType == COOKIES || m_ExternalType == BOOKMARKS);
BOOL fHasAddedElements = FALSE;
if( populateExternalListForCookiesOrBookmarksWithNS3Entry())
fHasAddedElements = TRUE;
if( populateExternalListForCookiesOrBookmarksWithNS4Entries())
fHasAddedElements = TRUE;
return fHasAddedElements;
}
//*************************************************************
//
// populateExternalList..WithNS3Entry
//
// subfunc of populateExternalListForCookiesOrBookmarks.
// returns TRUE if any elements have been added to the external list
BOOL ImpExpUserProcess::populateExternalListForCookiesOrBookmarksWithNS3Entry()
{
BOOL retVal = FALSE;
// Determine where to look for reg key
LPTSTR sNS3RegPath;
LPTSTR sNS3RegKey;
if( m_ExternalType == BOOKMARKS)
{
sNS3RegPath = NS3_BOOKMARK_REG_PATH;
sNS3RegKey = NS3_BOOKMARK_REG_KEY;
}
else
{
sNS3RegPath = NS3_COOKIE_REG_PATH;
sNS3RegKey = NS3_COOKIE_REG_KEY;
}
// Get the file location and add it to the list
// The registry location has the complete path + filename.
TCHAR sFilePath[MAX_PATH];
DWORD cbFilePathSize = sizeof(sFilePath);
DWORD dwType;
if (ERROR_SUCCESS == SHGetValue(HKEY_CURRENT_USER, sNS3RegPath, sNS3RegKey,
&dwType, (BYTE*)sFilePath, &cbFilePathSize)
&& (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
{
TCHAR szBuffer[MAX_PATH];
MLLoadString(IDS_NS3_VERSION_CAPTION, szBuffer, MAX_PATH);
retVal = ((ListIterator)m_ExternalList).Insert(
szBuffer, lstrlen(szBuffer)+1,
sFilePath, cbFilePathSize / sizeof(TCHAR));
}
return retVal;
}
//*************************************************************
//
// populateExternalList..WithNS4Entries
//
// subfunc of populateExternalListForCookiesOrBookmarks.
// returns TRUE if any elements have been added to the external list
BOOL ImpExpUserProcess::populateExternalListForCookiesOrBookmarksWithNS4Entries()
{
BOOL retVal = FALSE;
// Get an iterator to advance position as items are inserted.
ListIterator iterator = (ListIterator)m_ExternalList;
// Get the filename to be attached and the associated string size.
TCHAR sFilename[MAX_PATH];
DWORD cFilenameLength;
if(m_ExternalType == BOOKMARKS)
MLLoadString(IDS_NETSCAPE_BOOKMARK_FILE,sFilename,ARRAYSIZE(sFilename));
else
MLLoadString(IDS_NETSCAPE_COOKIE_FILE,sFilename,ARRAYSIZE(sFilename));
cFilenameLength = lstrlen(sFilename);
// Get the reg key of the root of the NS profiles for enumeration.
HKEY hUserRootKey = NULL;
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, NS4_USERS_REG_PATH,
0, KEY_READ, &hUserRootKey)
!= ERROR_SUCCESS)
{
hUserRootKey = NULL;
goto donePopulateExternalListForCookiesOrBookmarksWithNS4Entries;
}
DWORD dwNumberOfProfiles;
if( RegQueryInfoKey( hUserRootKey, NULL, NULL, NULL, &dwNumberOfProfiles,
NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS
|| dwNumberOfProfiles == 0)
{
goto donePopulateExternalListForCookiesOrBookmarksWithNS4Entries;
}
// Enumerate over the NS profiles, getting their names and
//directory paths. Associated the profile name with the path
//of the desired files by appending the filename to the
//user's root.
TCHAR sProfileName[MAX_PATH];
DWORD cProfileNameSize;
cProfileNameSize = MAX_PATH;
DWORD iEnumIndex; iEnumIndex = 0;
while( RegEnumKeyEx( hUserRootKey, (iEnumIndex++), sProfileName,
&cProfileNameSize, NULL, NULL, NULL, NULL)
== ERROR_SUCCESS)
{
//RegEnumKeyEx gives us the ProfileNameSize w/out the '\0'.
cProfileNameSize = MAX_PATH;
HKEY hProfileKey = NULL;
if( RegOpenKeyEx( hUserRootKey, sProfileName, 0, KEY_READ, &hProfileKey)
!= ERROR_SUCCESS)
{
hProfileKey = NULL;
goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
}
DWORD dwType; // should be REG_SZ when returned from QueryValue
TCHAR sProfilePath[MAX_PATH];
DWORD cProfilePathSize; cProfilePathSize = sizeof(sProfilePath);
if( (RegQueryValueEx( hProfileKey, NS4_USERPATH_REG_KEY, NULL, &dwType,
(LPBYTE)sProfilePath, &cProfilePathSize)
!= ERROR_SUCCESS)
|| dwType != REG_SZ)
{
goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
}
cProfilePathSize /= sizeof(TCHAR);
if( (MAX_PATH - cProfilePathSize) < cFilenameLength)
{
goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
}
// append "\\sFilename\0" to the path.
sProfilePath[ cProfilePathSize - 1] = TCHAR(FILENAME_SEPARATOR);
memcpy( &sProfilePath[cProfilePathSize],
sFilename, cFilenameLength * sizeof(TCHAR));
cProfilePathSize += cFilenameLength;
sProfilePath[cProfilePathSize++] = TCHAR('\0');
// we can only import files if they exist!
if( m_TransferType == IMPORT
&& GetFileAttributes(sProfilePath) == 0xFFFFFFFF)
goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
//
// construct the string for the combo box
//
TCHAR sRawProfileName[MAX_PATH];
TCHAR sRealProfileName[MAX_PATH];
UINT cRealProfileName;
MLLoadString(IDS_NS4_FRIENDLY_PROFILE_NAME, sRawProfileName, MAX_PATH);
cRealProfileName =
wnsprintf(sRealProfileName, MAX_PATH,
sRawProfileName, sProfileName);
// Insert the profile into the list. If it inserts, thats
//enough to consider the whole functions call a success.
if( iterator.Insert(sRealProfileName, cRealProfileName + 1,
sProfilePath, cProfilePathSize))
retVal = TRUE;
doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries:
if( hProfileKey != NULL)
RegCloseKey(hProfileKey);
}
donePopulateExternalListForCookiesOrBookmarksWithNS4Entries:
if( hUserRootKey != NULL)
RegCloseKey( hUserRootKey);
return retVal;
}
BOOL ImpExpUserProcess::populateExternalListFromFolders(LPTSTR pszPath)
{
BOOL retval = FALSE;
TCHAR szFileName[MAX_PATH];
TCHAR szPathWithWildcards[MAX_PATH];
ListIterator iterator = (ListIterator)m_ExternalList;
HANDLE hFind = NULL;
WIN32_FIND_DATA wfd;
//
// what are we looking for?
//
if(m_ExternalType == BOOKMARKS)
MLLoadString(IDS_NETSCAPE_BOOKMARK_FILE,szFileName,ARRAYSIZE(szFileName));
else
MLLoadString(IDS_NETSCAPE_COOKIE_FILE,szFileName,ARRAYSIZE(szFileName));
//
// prepare the path variable
//
StrCpyN(szPathWithWildcards,pszPath,MAX_PATH);
StrCatBuff(szPathWithWildcards,ALL_FILES_WILDCARD,MAX_PATH);
//
// start the find file thing
//
hFind = FindFirstFile(szPathWithWildcards,&wfd);
if (hFind == INVALID_HANDLE_VALUE)
goto Cleanup;
do
{
//
// the actual bookmark or cookie file
//
TCHAR szFullPath[MAX_PATH];
int cchFullPath;
//
// a "friendly" name for the corresponding profile
//
TCHAR szProfileFormat[MAX_PATH];
TCHAR szProfileName[MAX_PATH];
int cchProfileName;
//
// skip over "." and ".."
//
if(!StrCmp(wfd.cFileName, DOT_DIR) ||
!StrCmp(wfd.cFileName, DOT_DOT_DIR))
continue;
//
// skip over any non-directories
//
if (!(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
continue;
//
// generate the path
//
#ifndef UNIX
cchFullPath = wnsprintf(szFullPath,MAX_PATH,TEXT("%s\\%s\\%s"),pszPath,wfd.cFileName,szFileName);
#else
cchFullPath = wnsprintf(szFullPath,MAX_PATH,TEXT("%s/%s/%s"),pszPath,wfd.cFileName,szFileName);
#endif
//
// see if the file actually exists
//
if (GetFileAttributes(szFullPath) == 0xFFFFFFFF)
continue;
//
// generate the profile name
//
MLLoadString(IDS_FB_FRIENDLY_PROFILE_NAME, szProfileFormat, MAX_PATH);
cchProfileName = wnsprintf(szProfileName, MAX_PATH, szProfileFormat, wfd.cFileName);
//
// add the entry to the list
//
iterator.Insert(
szProfileName,cchProfileName+1,
szFullPath,cchFullPath+1);
retval = TRUE;
} while(FindNextFile(hFind,&wfd));
Cleanup:
if (hFind)
FindClose(hFind);
return retval;
}
BOOL ImpExpUserProcess::populateExternalListWithNSEntriesFallBack()
{
BOOL retVal = FALSE;
HKEY hRoot = NULL;
HKEY hCurrentVersion = NULL;
HKEY hCurrentVersionMain = NULL;
TCHAR szUsersDir[64]; // will contain "..\\Users"
DWORD dwType;
TCHAR szVersion[64];
TCHAR szPath[MAX_PATH];
DWORD cbSize;
LONG result;
//
// Open the root of netscape's HKLM registry hierarchy
//
result = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
NS_FALLBACK_ROOT_REG_KEY,
0,
KEY_READ,
&hRoot);
if (result != ERROR_SUCCESS)
goto Cleanup;
//
// Retrieve the "CurrentVersion" value
//
cbSize = sizeof(szVersion);
result = RegQueryValueEx(
hRoot,
NS_FALLBACK_VERSION_REG_VAL,
NULL,
&dwType,
(LPBYTE)szVersion,
&cbSize);
if (result != ERROR_SUCCESS || dwType != REG_SZ)
goto Cleanup;
//
// Open the sub-hierarchy corresponding to the current version
//
result = RegOpenKeyEx(
hRoot,
szVersion,
0,
KEY_READ,
&hCurrentVersion);
if (result != ERROR_SUCCESS)
goto Cleanup;
//
// Open the "main" sub-hierarchy
//
result = RegOpenKeyEx(
hCurrentVersion,
NS_FALLBACK_MAIN_REG_VAL,
0,
KEY_READ,
&hCurrentVersionMain);
if (result != ERROR_SUCCESS)
goto Cleanup;
//
// Retrieve the "Install Directory" value
//
cbSize = sizeof(szPath);
result = RegQueryValueEx(
hCurrentVersionMain,
NS_FALLBACK_INST_REG_VAL,
NULL,
&dwType,
(LPBYTE)szPath,
&cbSize);
if (result != ERROR_SUCCESS || dwType != REG_SZ)
goto Cleanup;
//
// Take a wild guess at where the "Users" dir might be
//
MLLoadString(IDS_NETSCAPE_USERS_DIR,szUsersDir,ARRAYSIZE(szUsersDir));
StrCatBuff(szPath,szUsersDir,ARRAYSIZE(szPath));
//
// Fill in the list
//
if (populateExternalListFromFolders(szPath))
retVal = TRUE;
Cleanup:
if (hRoot)
RegCloseKey(hRoot);
if (hCurrentVersion)
RegCloseKey(hCurrentVersion);
if (hCurrentVersionMain)
RegCloseKey(hCurrentVersionMain);
return retVal;
}
//*************************************************************
//
// PopulateTreeViewForInternalSelection
//
// Load a nested list of the favorites folders into memory
//and then into a Tree View.
// returns FALSE if TreeView is left empty.
BOOL ImpExpUserProcess::PopulateTreeViewForInternalSelection( HWND hTreeView)
{
ASSERT( m_TransferType != INVALID_TRANSFER);
TreeView_DeleteAllItems( hTreeView);
if( !populateInternalList())
return FALSE;
return populateTreeViewWithInternalList
( hTreeView, (ListIterator)m_InternalList, TVI_ROOT);
}
//*************************************************************
//
// populateTreeViewWithInternalList
//
// Loads list entries at 'iterator' below tree view item 'hParent'
// into 'hTreeView'. Associates value of each list entry with
// the Param of the Tree View node.
//
BOOL ImpExpUserProcess::populateTreeViewWithInternalList
(
HWND hTreeView,
ListIterator iterator,
HTREEITEM hParent
)
{
BOOL retVal = FALSE;
if( iterator.AtEndOfList())
goto donePopulateTreeViewWithInternalList;
TVINSERTSTRUCT newTV;
HTREEITEM hNew;
// declare parent and intent to put at end of list.
newTV.hParent = hParent;
newTV.hInsertAfter = TVI_LAST;
// build info struct
newTV.itemex.mask = TVIF_TEXT
| TVIF_PARAM
| TVIF_CHILDREN
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE;
// give name
newTV.itemex.cchTextMax = lstrlen( iterator.GetName()) + 1;
newTV.itemex.pszText = const_cast<LPTSTR>(iterator.GetName());
// associate the necessary data
newTV.itemex.lParam = (LPARAM)iterator.GetValue();
// tell tree view if there are any children.
newTV.itemex.cChildren =
iterator.GetSublist().AtEndOfList() == TRUE ? FALSE : TRUE;
// use correct icons
newTV.itemex.iSelectedImage = FOLDER_OPEN ;
newTV.itemex.iImage = FOLDER_CLOSED ;
hNew = TreeView_InsertItem( hTreeView, &newTV );
if( hNew == NULL)
goto donePopulateTreeViewWithInternalList;
// an element has been added, so we should return TRUE.
retVal = TRUE;
// add children
populateTreeViewWithInternalList( hTreeView, iterator.GetSublist(), hNew );
// add siblings
if( iterator.Next())
populateTreeViewWithInternalList( hTreeView, iterator, hParent );
donePopulateTreeViewWithInternalList:
return retVal;
}
BOOL ImpExpUserProcess::ExpandTreeViewRoot ( HWND hTreeView )
{
HTREEITEM hRoot ;
hRoot = TreeView_GetRoot ( hTreeView ) ;
if ( hRoot != NULL )
TreeView_Expand ( hTreeView, hRoot, TVE_EXPAND ) ;
else
return FALSE ;
return TRUE ;
}
//*************************************************************
//
// SelectInternalSelection
//
// Gets the data associated with the current selection of
//'hTreeView'.
BOOL ImpExpUserProcess::SelectInternalSelection( HWND hTreeView)
{
HTREEITEM hSelection = TreeView_GetSelection( hTreeView);
if( hSelection == NULL)
return FALSE;
//TVITEM is built up to query the lParam
//(the lParam has been associated with a pointer to the path value)
TVITEM TV;
TV.mask = TVIF_PARAM;
TV.hItem = hSelection;
if( !TreeView_GetItem( hTreeView, &TV))
return FALSE;
m_pSelectedInternal = (LPTSTR)TV.lParam;
ASSERT( m_pSelectedInternal != NULL);
return TRUE;
}
//*************************************************************
//
// purgeInternalList
//
// Wipes out whatever has been loaded in the internal
//target/source list.
void ImpExpUserProcess::purgeInternalList()
{
// clear the list.
ListIterator iterator = (ListIterator)m_InternalList;
while( iterator.Remove())
{
}
m_pSelectedInternal = NULL;
m_InternalListExternalType = INVALID_EXTERNAL;
m_InternalListTransferType = INVALID_TRANSFER;
}
//*************************************************************
//
// populateInternalList
//
// Builds the internal list for potential internal target/sources.
// This currently only makes sense for bookmarks, where a favorites
//directory has to be picked.
// returns TRUE if any elements have been added to the internal list
BOOL ImpExpUserProcess::populateInternalList()
{
ASSERT( m_ExternalType != INVALID_EXTERNAL);
if( m_InternalListExternalType == m_ExternalType
&& m_InternalListTransferType == m_TransferType)
return TRUE;
purgeInternalList();
// (could switch on different m_ExternalTypes here)
if( !populateInternalListForBookmarks())
{
purgeInternalList();
return FALSE;
}
m_InternalListExternalType = m_ExternalType;
m_InternalListTransferType = m_TransferType;
return TRUE;
}
//*************************************************************
//
// populateInternalListForBookmarks
// returns TRUE if any elements have been added to the internal list
BOOL ImpExpUserProcess::populateInternalListForBookmarks()
{
TCHAR szFavoritesPath[MAX_PATH];
if( SHGetSpecialFolderPath( NULL, szFavoritesPath, CSIDL_FAVORITES, FALSE)
&& appendSubdirsToInternalList( szFavoritesPath, m_InternalList))
{
return TRUE;
}
else return FALSE;
}
//*************************************************************
//
// appendSubdirsToInternalList
//
// Takes 'sPath' as a specification for a file search. All
//directories that match that are added to the internal list
//at 'iterator'.
// Recursively adds subdirectories found.
//
//typical usage:
// szPath is "c:\Root\Favorites",
// finds "c:\Root\Favorites",
// recursively calls itself with
// szPath = "c:\Root\Favorites\*.*"
// finding and recursing into all subdirs
// returns TRUE if any directories have been added to the internal list
// Edits the contents of the buffer past the last '\\'.
BOOL ImpExpUserProcess::appendSubdirsToInternalList
(
LPTSTR sPath,
ListIterator iterator
)
{
BOOL fHaveAddedDirectories = FALSE;
DWORD cPathLength = lstrlen(sPath);
HANDLE hEnum;
WIN32_FIND_DATA currentFile;
hEnum = FindFirstFile( sPath, &currentFile);
//example:
//given: "c:\root\*.*" (will find all dirs in root)
//want: "c:\root\"
//given: "c:\favorites" (will find favorites in root)
//want: "c:\"
// left search to '\\' to find the path of the files to be found.
while( cPathLength > 0
&& sPath[ --cPathLength] != TCHAR(FILENAME_SEPARATOR))
{
}
cPathLength++;
if( hEnum == INVALID_HANDLE_VALUE)
return FALSE;
do
{
DWORD cFileNameLength;
// we only handle directories
if( !(currentFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
continue;
// we don't want '.' and '..' to show up.
if( !StrCmp( currentFile.cFileName, DOT_DIR)
|| !StrCmp( currentFile.cFileName, DOT_DOT_DIR))
continue;
cFileNameLength = lstrlen( currentFile.cFileName);
memcpy( sPath + cPathLength, currentFile.cFileName, cFileNameLength * sizeof(TCHAR));
sPath[ cPathLength + cFileNameLength] = TCHAR('\0');
if( iterator.Insert( currentFile.cFileName, cFileNameLength + 1,
sPath, cPathLength + cFileNameLength + 1))
{
memcpy( sPath + cPathLength + cFileNameLength,
ALL_FILES_WILDCARD, sizeof(ALL_FILES_WILDCARD));
appendSubdirsToInternalList( sPath, iterator.GetSublist());
// we know now that a directory has been added
fHaveAddedDirectories = TRUE;
}
} while( FindNextFile( hEnum, &currentFile));
ASSERT(ERROR_NO_MORE_FILES == GetLastError());
FindClose(hEnum);
return fHaveAddedDirectories;
}
//*************************************************************
//
// PerformImpExpProcess
//
// Once everything is set up right, this should do the trick.
void ImpExpUserProcess::PerformImpExpProcess(HWND hwnd)
{
ASSERT( GetExternalType() != INVALID_EXTERNAL);
ASSERT( GetTransferType() != INVALID_TRANSFER);
ASSERT( (GetExternalType() == BOOKMARKS) ? (GetInternalSelection() != NULL) : TRUE);
HCURSOR hOldCursor;
//
// This could take a while, so show an hourglass cursor
//
hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
switch( GetExternalType())
{
case COOKIES:
switch( GetTransferType())
{
case IMPORT:
if (ImportCookieFile(m_szFileName))
{
MLShellMessageBox(
hwnd,
MAKEINTRESOURCE(IDS_IMPORTSUCCESS_COOK),
MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_COOK),
MB_OK);
}
else
{
MLShellMessageBox(
hwnd,
MAKEINTRESOURCE(IDS_IMPORTFAILURE_COOK),
MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_COOK),
MB_OK);
}
break;
case EXPORT:
if (SUCCEEDED(SHPathPrepareForWriteWrap(hwnd, NULL, m_szFileName, FO_COPY, (SHPPFW_DEFAULT | SHPPFW_IGNOREFILENAME))))
{
// FALSE specifies that we will overwrite cookies
if (ExportCookieFile(m_szFileName, FALSE ))
{
MLShellMessageBox(
hwnd,
MAKEINTRESOURCE(IDS_EXPORTSUCCESS_COOK),
MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_COOK),
MB_OK);
}
else
{
MLShellMessageBox(
hwnd,
MAKEINTRESOURCE(IDS_EXPORTFAILURE_COOK),
MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_COOK),
MB_OK);
}
}
break;
default:
ASSERT(0);
}
break;
case BOOKMARKS:
DoImportOrExport(
GetTransferType()==IMPORT,
m_pSelectedInternal,
m_szFileName,
FALSE);
break;
default:
ASSERT(0);
}
//
// Put the old cursor back when finished
//
SetCursor(hOldCursor);
}
//*************************************************************
//*************************************************************
//
// ImpExpUserDlg
//
// Handles the user interface side of things, building
// up an ImpExpUserProcess then executing it.
// The dialog procedures below will all have a return value
// which can be set to something besides FALSE if used, or left
// as FALSE if not used. Since only one section of code should
// attempt to give the return value a value before returning,
// class RetVal is set up to throw an assertion if two pieces
// of code intended to pass back a return value at the same
// time.
class ReturnValue
{
private:
BOOL_PTR m_value;
public:
ReturnValue()
{
m_value = FALSE;
}
BOOL_PTR operator =(BOOL_PTR newVal)
{
ASSERT( m_value == FALSE);
m_value = newVal;
return m_value;
}
operator BOOL_PTR ()
{
return m_value;
}
};
class ImpExpUserDlg
{
private:
static HIMAGELIST m_himl ;
static BOOL InitImageList ( HWND hwndTree ) ;
static BOOL DestroyImageList ( HWND hwndTree ) ;
static HFONT m_hfont ;
static BOOL InitFont ( HWND hwndStatic ) ;
static BOOL DestroyFont ( HWND hwndStatic ) ;
// A sheet knows its resource ID and what process
//it contributes to.
struct SheetData
{
int _idPage;
ImpExpUserProcess* _pImpExp;
SheetData( int idPage, ImpExpUserProcess* pImpExp )
: _idPage( idPage ), _pImpExp( pImpExp )
{
}
};
//
// InitializePropertySheetPage() will associate a dialog
// with an allocated copy of SheetData, which will be
// found at PSN_SETACTIVE with and stored with SetWindowLong.
// The allocated SheetData will be cleaned up by callback
// procedure PropertySheetPageProc().
//
// Callback functions sure are a drag for maintaining identity.
// GetWindowLong and SetWindowLong will be used to keep tabs
// on who is who, setting 'ghost' member variables.
//
// 'ghost' SheetData* This;
// 'ghost' ImpExpUserProcess* m_pImpExp;
// 'ghost' DWORD m_idPage;
//
// CommonDialogProc retrieves the 'ghost' values and does other
// shared behavior.
//
static DWORD CommonDialogProc
(
IN HWND hwndDlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam,
OUT ImpExpUserProcess** ppImpExp, OUT DWORD* pPageId,
IN OUT ReturnValue& retVal
);
static void InitializePropertySheetPage( PROPSHEETPAGE* psp, DWORD idDialogTemplate, DWORD idTitle, DWORD idSubTitle,DLGPROC dlgProc, ImpExpUserProcess* lParam);
static UINT CALLBACK PropertySheetPageProc( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
// some dialog procedures
static BOOL_PTR CALLBACK Wizard97DlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL_PTR CALLBACK TransferTypeDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL_PTR CALLBACK InternalDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL_PTR CALLBACK ExternalDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
static void HandleTransferTypeChange ( HWND hwndDlg, ImpExpUserProcess* m_pImpExp, UINT iSelect ) ;
public:
static BOOL RunNewDialogProcess( HWND hParent ) ;
};
HIMAGELIST ImpExpUserDlg::m_himl = NULL ;
BOOL ImpExpUserDlg::InitImageList ( HWND hwndTree )
{
//
// Code to retrieve icons for open and closed folders
// was based on code in private/samples/sampview/utility.cpp.
//
TCHAR szFolder[MAX_PATH];
SHFILEINFO sfi;
HIMAGELIST himlOld ;
DWORD dwRet ;
// create the image list
m_himl = ImageList_Create ( GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLORDDB, 2, 2 ) ;
if ( m_himl == NULL )
return FALSE ;
ImageList_SetBkColor( m_himl, GetSysColor(COLOR_WINDOW) ) ;
// add the closed folder icon
GetWindowsDirectory(szFolder, MAX_PATH);
SHGetFileInfo( szFolder,
0,
&sfi,
sizeof(sfi),
SHGFI_ICON | SHGFI_SMALLICON);
dwRet = ImageList_AddIcon(m_himl, sfi.hIcon);
ASSERT ( dwRet == FOLDER_CLOSED ) ;
// add the open folder icon
SHGetFileInfo( szFolder,
0,
&sfi,
sizeof(sfi),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_OPENICON);
dwRet = ImageList_AddIcon(m_himl, sfi.hIcon);
ASSERT ( dwRet == FOLDER_OPEN ) ;
himlOld = TreeView_SetImageList( hwndTree, m_himl, TVSIL_NORMAL );
if ( himlOld != NULL )
{
BOOL fOk ;
fOk = ImageList_Destroy ( himlOld ) ;
ASSERT ( fOk ) ;
}
return TRUE ;
}
BOOL ImpExpUserDlg::DestroyImageList ( HWND hwndTree )
{
HIMAGELIST himlOld ;
himlOld = TreeView_SetImageList( hwndTree, NULL, TVSIL_NORMAL );
if ( himlOld != NULL )
{
BOOL fOk ;
fOk = ImageList_Destroy ( himlOld ) ;
ASSERT ( fOk ) ;
}
return TRUE ;
}
HFONT ImpExpUserDlg::m_hfont = NULL ;
BOOL ImpExpUserDlg::InitFont ( HWND hwndStatic )
{
HDC hdc = GetDC ( hwndStatic ) ;
if ( hdc == NULL )
return FALSE ;
LOGFONT lf;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH;
lf.lfItalic = 0;
lf.lfWeight = FW_BOLD;
lf.lfStrikeOut = 0;
lf.lfUnderline = 0;
lf.lfWidth = 0;
lf.lfHeight = -MulDiv(13, GetDeviceCaps(hdc, LOGPIXELSY), 72);
LOGFONT lfTmp;
HFONT hFontOrig = (HFONT)SendMessage(hwndStatic, WM_GETFONT, (WPARAM)0, (LPARAM)0);
if (hFontOrig && GetObject(hFontOrig, sizeof(lfTmp), &lfTmp))
{
lf.lfCharSet = lfTmp.lfCharSet;
StrCpyN(lf.lfFaceName, lfTmp.lfFaceName, LF_FACESIZE);
}
else
{
lf.lfCharSet = GetTextCharset(hdc);
StrCpyN(lf.lfFaceName, TEXT("MS Shell Dlg"), LF_FACESIZE);
}
m_hfont = CreateFontIndirect(&lf);
if ( m_hfont == NULL )
{
ReleaseDC(hwndStatic, hdc);
return FALSE ;
}
SendMessage ( hwndStatic, WM_SETFONT, (WPARAM)m_hfont, MAKELPARAM(FALSE, 0) ) ;
ReleaseDC ( hwndStatic,hdc ) ;
return TRUE ;
}
BOOL ImpExpUserDlg::DestroyFont ( HWND hwndDlg )
{
if ( m_hfont )
DeleteObject ( m_hfont ) ;
return TRUE ;
}
void ImpExpUserDlg::InitializePropertySheetPage
(
PROPSHEETPAGE* psp,
DWORD idDialogTemplate,
DWORD idTitle,
DWORD idSubTitle,
DLGPROC dlgProc,
ImpExpUserProcess* lParam
)
{
psp->dwFlags |= PSP_USECALLBACK | PSP_USETITLE;
psp->hInstance = MLGetHinst();
psp->pszTemplate = MAKEINTRESOURCE(idDialogTemplate);
psp->pfnDlgProc = dlgProc;
psp->lParam = (LPARAM)(new SheetData(idDialogTemplate,lParam));
psp->pfnCallback = PropertySheetPageProc;
psp->pszHeaderTitle = MAKEINTRESOURCE(idTitle);
psp->pszHeaderSubTitle = MAKEINTRESOURCE(idSubTitle);
psp->pszTitle = MAKEINTRESOURCE(IDS_IMPEXP_CAPTION);
if ( idDialogTemplate == IDD_IMPEXPWELCOME ||
idDialogTemplate == IDD_IMPEXPCOMPLETE )
{
psp->dwFlags |= PSP_HIDEHEADER;
}
else
{
psp->dwFlags |= (PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE);
}
}
UINT CALLBACK ImpExpUserDlg::PropertySheetPageProc
(
HWND hwnd,
UINT uMsg,
LPPROPSHEETPAGE ppsp
)
{
switch(uMsg)
{
case PSPCB_CREATE:
break;
case PSPCB_RELEASE:
delete (SheetData*)ppsp->lParam;
ppsp->lParam = NULL;
break;
default:
break;
}
return TRUE ;
}
//*************************************************************
//
// RunNewDialogProcess
//
// Runs the Import Export Wizard.
BOOL_PTR CALLBACK TEMP(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
return (uMsg==WM_INITDIALOG);
}
BOOL ImpExpUserDlg::RunNewDialogProcess(HWND hParent)
{
const int numPages = 9;
ImpExpUserProcess* pImpExp = new ImpExpUserProcess();
if( pImpExp == NULL)
return FALSE;
PROPSHEETPAGE pspOld[numPages];
PROPSHEETPAGE* psp = pspOld;
// dwSkip is set in Whistler_AllocatePropertySheetPage to whatever the size of Whistler's PROPSHEETPAGE
// is. 0x34 last I checked. (IE5 PROPSHEETPAGE is 0x30)
DWORD dwSkip = sizeof(PROPSHEETPAGE);
if (IsOS(OS_WHISTLERORGREATER))
{
PROPSHEETPAGE* psp2 = Whistler_AllocatePropertySheetPage(numPages, &dwSkip);
if (psp2)
{
psp = psp2;
}
}
if (psp==pspOld)
{
for (int i=0; i<numPages; i++)
{
memset(&psp[i], 0, sizeof(PROPSHEETPAGE));
psp[i].dwSize = sizeof(PROPSHEETPAGE);
}
}
PROPSHEETHEADER psh;
PBYTE pspNext = (PBYTE)psp;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPWELCOME, 0, 0, Wizard97DlgProc, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPTRANSFERTYPE, IDS_IMPEXPTRANSFERTYPE_TITLE, IDS_IMPEXPTRANSFERTYPE_SUBTITLE, TransferTypeDlg, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPIMPFAVSRC, IDS_IMPEXPIMPFAVSRC_TITLE, IDS_IMPEXPIMPFAVSRC_SUBTITLE, ExternalDlg, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPIMPFAVDES, IDS_IMPEXPIMPFAVDES_TITLE, IDS_IMPEXPIMPFAVDES_SUBTITLE, InternalDlg, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPEXPFAVSRC, IDS_IMPEXPEXPFAVSRC_TITLE, IDS_IMPEXPEXPFAVSRC_SUBTITLE, InternalDlg, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPEXPFAVDES, IDS_IMPEXPEXPFAVDES_TITLE, IDS_IMPEXPEXPFAVDES_SUBTITLE, ExternalDlg, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPIMPCKSRC, IDS_IMPEXPIMPCKSRC_TITLE, IDS_IMPEXPIMPCKSRC_SUBTITLE, ExternalDlg, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPEXPCKDES, IDS_IMPEXPEXPCKDES_TITLE, IDS_IMPEXPEXPCKDES_SUBTITLE, ExternalDlg, pImpExp );
pspNext += dwSkip;
InitializePropertySheetPage( (PROPSHEETPAGE*)pspNext, IDD_IMPEXPCOMPLETE, 0, 0, Wizard97DlgProc, pImpExp );
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_WIZARD97 | PSH_PROPSHEETPAGE | PSH_HEADER | PSH_WATERMARK ;
psh.hwndParent = hParent;
psh.hInstance = MLGetHinst();
psh.pszCaption = MAKEINTRESOURCE(IDS_IMPEXP_CAPTION);
psh.nPages = numPages;
psh.nStartPage = 0;
psh.ppsp = psp;
psh.pszbmWatermark = MAKEINTRESOURCE(IDB_IMPEXPWATERMARK);
psh.pszbmHeader = MAKEINTRESOURCE(IDB_IMPEXPHEADER);
ULONG_PTR uCookie = 0;
SHActivateContext(&uCookie);
int iResult = (int)PropertySheet(&psh) ;
if (uCookie)
{
SHDeactivateContext(uCookie);
}
delete pImpExp;
if (psp!=pspOld)
{
HeapFree(GetProcessHeap(), NULL, psp);
}
return iResult;
}
//*************************************************************
//
// CommonDialogProc
//
// Prepares 'ghost' member variables of the user dialog process,
// handles ordering details of wizard pages and initializes common
// dialog elements.
//
// retVal passes through CommonDialogProc so that it can be set
// if necessary. Clients of CommonDialogProc should not need
// to specify a new return value if CommonDialogProc has specified
// a non-FALSE return value.
//
// If CommonDialogProc returns FALSE dialog procedure should
// considered 'msg' handled and return retVal immediately.
//
// If this dialog has yet to receive WM_INITDIALOG, the 'ghost'
// values will be zero (and invalid).
//
DWORD ImpExpUserDlg::CommonDialogProc
(
IN HWND hwndDlg,
IN UINT msg,
IN WPARAM wParam,
IN LPARAM lParam,
OUT ImpExpUserProcess** ppImpExp,
OUT DWORD* pPageId,
ReturnValue& retVal
)
{
SheetData* sheetData;
ImpExpUserProcess* m_pImpExp = NULL;
DWORD m_idPage = 0;
//
// Do init-dialog stuff
//
if ( WM_INITDIALOG == msg )
{
sheetData = (SheetData*)(((PROPSHEETPAGE*)lParam)->lParam);
SetWindowLongPtr( hwndDlg, DWLP_USER, (LONG_PTR)sheetData);
}
//
// Initialize the sheetData field
//
sheetData = (SheetData*)GetWindowLongPtr( hwndDlg, DWLP_USER ) ;
if ( sheetData != NULL )
{
m_pImpExp = *ppImpExp = sheetData->_pImpExp;
m_idPage = *pPageId = sheetData->_idPage;
}
//
// Next, we check to make sure we're on the correct page. If not, simply
// return -1 and the wizard will automatically advance to the next page.
//
if( WM_NOTIFY == msg && PSN_SETACTIVE == ((LPNMHDR)lParam)->code )
{
BOOL fPageValidation = TRUE ;
switch( m_idPage )
{
case IDD_IMPEXPWELCOME:
case IDD_IMPEXPTRANSFERTYPE:
case IDD_IMPEXPCOMPLETE:
break;
case IDD_IMPEXPIMPFAVSRC:
case IDD_IMPEXPIMPFAVDES:
if(m_pImpExp->GetTransferType() != IMPORT || m_pImpExp->GetExternalType() != BOOKMARKS)
fPageValidation = FALSE;
break;
case IDD_IMPEXPEXPFAVSRC:
case IDD_IMPEXPEXPFAVDES:
if(m_pImpExp->GetTransferType() != EXPORT || m_pImpExp->GetExternalType() != BOOKMARKS)
fPageValidation = FALSE;
break;
case IDD_IMPEXPIMPCKSRC:
if(m_pImpExp->GetTransferType() != IMPORT || m_pImpExp->GetExternalType() != COOKIES)
fPageValidation = FALSE;
break;
case IDD_IMPEXPEXPCKDES:
if(m_pImpExp->GetTransferType() != EXPORT || m_pImpExp->GetExternalType() != COOKIES)
fPageValidation = FALSE;
break;
}
SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, fPageValidation ? 0 : -1 ) ;
retVal = TRUE ;
if ( ! fPageValidation )
return FALSE ;
}
//
// Initialize fonts and image lists (if needed)
//
if ( WM_NOTIFY == msg )
{
HWND hwndTitle = GetDlgItem ( hwndDlg, IDC_IMPEXPTITLETEXT ) ;
HWND hwndTree = GetDlgItem ( hwndDlg, IDC_IMPEXPFAVTREE ) ;
switch ( ((LPNMHDR)lParam)->code )
{
case PSN_SETACTIVE:
if ( hwndTitle )
InitFont ( hwndTitle ) ;
if ( hwndTree )
InitImageList( hwndTree ) ;
break ;
case PSN_KILLACTIVE:
case PSN_QUERYCANCEL:
if ( hwndTitle )
DestroyFont ( hwndTitle ) ;
if ( hwndTree )
DestroyImageList( hwndTree ) ;
break;
}
}
if( WM_NOTIFY == msg && PSN_SETACTIVE == ((LPNMHDR)lParam)->code )
{
HWND hwndParent = GetParent( hwndDlg);
switch( m_idPage )
{
case IDD_IMPEXPWELCOME:
PropSheet_SetWizButtons( hwndParent, PSWIZB_NEXT );
break;
case IDD_IMPEXPCOMPLETE:
{
UINT idText ;
const TCHAR *szInsert = m_pImpExp->m_szFileName ;
TCHAR szRawString[1024] ;
TCHAR szRealString[1024] ;
//
// First, we need to figure out which string should
// be used to describe what the wizard is going to
// do (for example "Import the cookies from...")
//
if ( m_pImpExp->GetTransferType() == IMPORT )
{
if ( m_pImpExp->GetExternalType() == COOKIES )
idText = IDS_IMPEXP_COMPLETE_IMPCK ;
else
idText = IDS_IMPEXP_COMPLETE_IMPFV ;
}
else
{
if ( m_pImpExp->GetExternalType() == COOKIES )
idText = IDS_IMPEXP_COMPLETE_EXPCK ;
else
idText = IDS_IMPEXP_COMPLETE_EXPFV ;
}
LoadString(MLGetHinst(), idText, szRawString, 1024);
wnsprintf(szRealString, 1024, szRawString, szInsert);
//
// Set the text in the listview, and do all the other magic to make
// the tooltips work, etc.
//
SetListViewToString(GetDlgItem(hwndDlg,IDC_IMPEXPCOMPLETECONFIRM), szRealString);
//
// The SetListViewToString function helpfully sets the background color to
// gray instead of the default (white). But we actually want it white, so
// let's reset it here.
//
ListView_SetBkColor(GetDlgItem(hwndDlg,IDC_IMPEXPCOMPLETECONFIRM), GetSysColor(COLOR_WINDOW));
ListView_SetTextBkColor(GetDlgItem(hwndDlg,IDC_IMPEXPCOMPLETECONFIRM), GetSysColor(COLOR_WINDOW));
PropSheet_SetWizButtons(hwndParent, PSWIZB_BACK|PSWIZB_FINISH);
}
break;
default:
PropSheet_SetWizButtons( hwndParent, PSWIZB_NEXT | PSWIZB_BACK );
break;
}
}
return TRUE ;
}
//*************************************************************
//
// Wizard97DlgProc
//
// Dialog proc for welcome and complete pages.
//
BOOL_PTR CALLBACK ImpExpUserDlg::Wizard97DlgProc
(
HWND hwndDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
ReturnValue retVal;
ImpExpUserProcess* m_pImpExp = NULL;
DWORD m_idPage = 0;
if( !CommonDialogProc( hwndDlg, msg, wParam, lParam,
&m_pImpExp, &m_idPage, retVal))
{
return retVal;
}
if( m_idPage == IDD_IMPEXPCOMPLETE
&& msg == WM_NOTIFY
&& PSN_WIZFINISH == ((LPNMHDR)lParam)->code)
m_pImpExp->PerformImpExpProcess(hwndDlg);
return retVal;;
}
//*************************************************************
//
// TransferTypeDlg
//
// Dialog proc for dialog where user picks transfer type
// (import vs. export), (cookies vs. bookmarks)
BOOL_PTR CALLBACK ImpExpUserDlg::TransferTypeDlg
(
HWND hwndDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
ReturnValue retVal;
ImpExpUserProcess* m_pImpExp = NULL;
DWORD m_idPage = 0;
if( !CommonDialogProc( hwndDlg, msg, wParam, lParam,
&m_pImpExp, &m_idPage, retVal))
{
return retVal;
}
HWND hwndDlgItem;
switch( msg)
{
case WM_INITDIALOG:
{
hwndDlgItem = GetDlgItem( hwndDlg, IDC_IMPEXPACTIONLISTBOX);
LRESULT index;
TCHAR szBuffer[MAX_PATH];
const DWORD cbSize = MAX_PATH;
if( MLLoadString( IDS_IMPFAVORITES, szBuffer, cbSize))
{
index = ListBox_AddString( hwndDlgItem, szBuffer);
ListBox_SetItemData( hwndDlgItem, index, IDS_IMPFAVORITES);
}
if( MLLoadString( IDS_EXPFAVORITES, szBuffer, cbSize))
{
index = ListBox_AddString( hwndDlgItem, szBuffer);
ListBox_SetItemData( hwndDlgItem, index, IDS_EXPFAVORITES);
}
if( MLLoadString( IDS_IMPCOOKIES, szBuffer, cbSize))
{
index = ListBox_AddString( hwndDlgItem, szBuffer);
ListBox_SetItemData( hwndDlgItem, index, IDS_IMPCOOKIES);
}
if( MLLoadString( IDS_EXPCOOKIES, szBuffer, cbSize))
{
index = ListBox_AddString( hwndDlgItem, szBuffer);
ListBox_SetItemData( hwndDlgItem, index, IDS_EXPCOOKIES);
}
// Select the first list item, by default
ListBox_SetCurSel(hwndDlgItem, 0);
HandleTransferTypeChange(hwndDlg, m_pImpExp, IDS_IMPFAVORITES);
} // end of WM_INITDIALOG
break;
case WM_COMMAND:
// when the user selects an option, choose it and
//and update the description box.
hwndDlgItem = GetDlgItem(hwndDlg, IDC_IMPEXPACTIONLISTBOX);
if(hwndDlgItem == (HWND)lParam
&& HIWORD(wParam) == LBN_SELCHANGE)
{
// find out which string resource was selected.
LRESULT index = ListBox_GetCurSel(hwndDlgItem);
LRESULT selection = ListBox_GetItemData(hwndDlgItem, index);
HandleTransferTypeChange ( hwndDlg, m_pImpExp, (UINT)selection ) ;
retVal = TRUE;
}
break;
case WM_NOTIFY:
//
// Prevent advancement until user has made valid choices
//
if( ((LPNMHDR)lParam)->code == PSN_WIZNEXT && m_pImpExp
&& (m_pImpExp->GetExternalType() == INVALID_EXTERNAL
|| m_pImpExp->GetTransferType() == INVALID_TRANSFER))
{
SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, -1);
retVal = TRUE;
}
//
// otherwise, set the filename to nul (so we get the default)
// and allow default navigation behavior
//
if (m_pImpExp)
m_pImpExp->m_szFileName[0] = TEXT('\0');
break;
}
return retVal;
}
void ImpExpUserDlg::HandleTransferTypeChange ( HWND hwndDlg, ImpExpUserProcess* pImpExp, UINT iSelect )
{
TCHAR szBuffer[MAX_PATH];
const DWORD cbSize = MAX_PATH;
if (pImpExp)
{
//
// Note: The description of each option has a resource id
// which is one higher than the resource id of the option name.
//
switch( iSelect )
{
case IDS_IMPFAVORITES:
if( MLLoadString( IDS_IMPFAVORITES + 1, szBuffer, cbSize ) )
SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC ),
szBuffer );
pImpExp->SelectExternalType( BOOKMARKS );
pImpExp->SelectTransferType( IMPORT );
break;
case IDS_EXPFAVORITES:
if( MLLoadString( IDS_EXPFAVORITES + 1, szBuffer, cbSize ) )
SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC ),
szBuffer );
pImpExp->SelectExternalType( BOOKMARKS );
pImpExp->SelectTransferType( EXPORT );
break;
case IDS_IMPCOOKIES:
if( MLLoadString( IDS_IMPCOOKIES + 1, szBuffer, cbSize))
SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC),
szBuffer);
pImpExp->SelectExternalType( COOKIES);
pImpExp->SelectTransferType( IMPORT);
break;
case IDS_EXPCOOKIES:
if( MLLoadString( IDS_EXPCOOKIES + 1, szBuffer, cbSize))
SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC),
szBuffer);
pImpExp->SelectExternalType( COOKIES);
pImpExp->SelectTransferType( EXPORT);
break;
}
}
}
//*************************************************************
//
// InternalDlg
//
// Allows user to pick internal target/source from tree view.
BOOL_PTR CALLBACK ImpExpUserDlg::InternalDlg
(
HWND hwndDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
ReturnValue retVal;
ImpExpUserProcess* m_pImpExp = NULL;
DWORD m_idPage = 0;
if( !CommonDialogProc( hwndDlg, msg, wParam, lParam,
&m_pImpExp, &m_idPage, retVal))
{
return retVal;
}
HWND hwndDlgItem;
switch( msg)
{
case WM_INITDIALOG:
//
// Populate the tree control
//
hwndDlgItem = GetDlgItem(hwndDlg, IDC_IMPEXPFAVTREE);
if ( hwndDlgItem )
{
if (m_pImpExp)
{
m_pImpExp->PopulateTreeViewForInternalSelection(hwndDlgItem);
m_pImpExp->ExpandTreeViewRoot ( hwndDlgItem ) ;
}
}
else
ASSERT(0);
return TRUE;
case WM_NOTIFY:
switch( ((LPNMHDR)lParam)->code)
{
case PSN_WIZNEXT:
// Only allow user to go to next if there is a valid selection.
if( !m_pImpExp->SelectInternalSelection(GetDlgItem(hwndDlg,IDC_IMPEXPFAVTREE)) )
{
SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, -1);
retVal = TRUE;
}
}
}
return retVal;
}
BOOL IsValidFileOrURL(LPTSTR szFileOrURL)
{
if (szFileOrURL == NULL)
return FALSE;
//
// any URL is ok
//
if (PathIsURL(szFileOrURL))
return TRUE;
//
// just a directory is no good, we need a filename too
//
if (PathIsDirectory(szFileOrURL))
return FALSE;
//
// just a filename is no good, we need a directory too
//
if (PathIsFileSpec(szFileOrURL))
return FALSE;
//
// relative paths are no good
//
if (PathIsRelative(szFileOrURL))
return FALSE;
//
// now make sure it parses correctly
//
if (PathFindFileName(szFileOrURL) == szFileOrURL)
return FALSE;
return TRUE;
}
//*************************************************************
//
// ExternalDlg
//
// Allows user to pick external target/source from list box
//or manual browse.
BOOL_PTR CALLBACK ImpExpUserDlg::ExternalDlg
(
HWND hwndDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
ReturnValue retVal;
ImpExpUserProcess* m_pImpExp = NULL;
DWORD m_idPage = 0;
if( !CommonDialogProc( hwndDlg, msg, wParam, lParam,
&m_pImpExp, &m_idPage, retVal))
{
return retVal;
}
HWND hwndDlgItem;
switch(msg)
{
case WM_COMMAND:
hwndDlgItem = (HWND) lParam;
if( HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_IMPEXPBROWSE)
{
OPENFILENAME ofn;
TCHAR szFile[MAX_PATH];
TCHAR szTitle[MAX_PATH];
TCHAR szFilter[MAX_PATH];
TCHAR szInitialPath[MAX_PATH];
int i;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwndDlg;
ofn.hInstance = MLGetHinst();
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 1;
ofn.lpstrCustomFilter = NULL;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = NULL;
ofn.lpstrInitialDir = szInitialPath;
ofn.lpstrTitle = szTitle;
ofn.lpstrDefExt = (m_pImpExp->GetExternalType()==COOKIES) ? TEXT("txt") : TEXT("htm");
GetDlgItemText(hwndDlg, IDC_IMPEXPMANUAL, szInitialPath, ARRAYSIZE(szFile));
szFile[0] = 0;
if (PathIsDirectory(szInitialPath))
{
ofn.lpstrInitialDir = szInitialPath;
szFile[0] = TEXT('\0');
}
else
{
TCHAR *pchFilePart;
pchFilePart = PathFindFileName(szInitialPath);
if (pchFilePart == szInitialPath || pchFilePart == NULL)
{
if (PathIsFileSpec(szInitialPath))
StrCpyN(szFile,szInitialPath,MAX_PATH);
else
szFile[0] = TEXT('\0');
ofn.lpstrInitialDir = szInitialPath;
SHGetSpecialFolderPath(NULL,szInitialPath,CSIDL_DESKTOP,FALSE);
}
else
{
pchFilePart[-1] = TEXT('\0');
ofn.lpstrInitialDir = szInitialPath;
StrCpyN(szFile,pchFilePart,MAX_PATH);
}
}
//
// Work out the title and the filter strings
//
if (m_pImpExp->GetExternalType() == BOOKMARKS)
{
MLLoadShellLangString(IDS_IMPEXP_CHOSEBOOKMARKFILE,szTitle,MAX_PATH);
MLLoadShellLangString(IDS_IMPEXP_BOOKMARKFILTER,szFilter,MAX_PATH);
}
else
{
MLLoadShellLangString(IDS_IMPEXP_CHOSECOOKIEFILE,szTitle,MAX_PATH);
MLLoadShellLangString(IDS_IMPEXP_COOKIEFILTER,szFilter,MAX_PATH);
}
//
// Search and replace '@' with nul in the filter string
//
for (i=0; szFilter[i]; i++)
if (szFilter[i]==TEXT('@'))
szFilter[i]=TEXT('\0');
//
// Set the flags for openfilename
//
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY ;
if (m_pImpExp->GetTransferType() == IMPORT)
ofn.Flags |= (OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST);
//
// Show the dialog
//
if(GetSaveFileName(&ofn))
if(SetWindowText(GetDlgItem(hwndDlg, IDC_IMPEXPMANUAL), ofn.lpstrFile))
{
Button_SetCheck(GetDlgItem( hwndDlg, IDC_IMPEXPRADIOFILE), BST_CHECKED);
Button_SetCheck(GetDlgItem( hwndDlg, IDC_IMPEXPRADIOAPP), BST_UNCHECKED);
}
retVal = TRUE;
}
break;
case WM_NOTIFY:
switch( ((LPNMHDR)lParam)->code )
{
case PSN_SETACTIVE:
{
TCHAR sBuffer[MAX_PATH];
DWORD cbSize = ARRAYSIZE(sBuffer);
hwndDlgItem = GetDlgItem( hwndDlg, IDC_IMPEXPEXTERNALCOMBO );
//
// Load the "application list" into the combo box.
// If the list is empty, then disable the combo box,
// disable the associated radio button, and select the
// "to/from file" option (the second radio button).
//
if( hwndDlgItem != NULL
&& m_pImpExp && m_pImpExp->PopulateComboBoxForExternalSelection( hwndDlgItem ) )
{
EnableWindow ( GetDlgItem(hwndDlg, IDC_IMPEXPRADIOAPP), TRUE ) ;
EnableWindow ( hwndDlgItem, TRUE ) ;
Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOAPP), BST_CHECKED);
Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOFILE), BST_UNCHECKED);
}
else if ( hwndDlgItem != NULL)
{
EnableWindow ( GetDlgItem(hwndDlg, IDC_IMPEXPRADIOAPP), FALSE ) ;
EnableWindow( hwndDlgItem, FALSE ) ;
Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOFILE), BST_CHECKED);
Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOAPP), BST_UNCHECKED);
}
// Put a default value in the browse option.
if(m_pImpExp->GetExternalManualDefault(sBuffer, &cbSize))
SetDlgItemText(hwndDlg, IDC_IMPEXPMANUAL, sBuffer);
SHAutoComplete(GetDlgItem(hwndDlg, IDC_IMPEXPMANUAL), SHACF_FILESYSTEM);
}
break;
case PSN_WIZNEXT:
// If the application radio button is checked,
// select the selection from the application combo box. If
// the manual button is checked, select the selection
// using the manual edit box.
retVal = TRUE;
if (Button_GetCheck(GetDlgItem(hwndDlg,IDC_IMPEXPRADIOAPP)) == BST_CHECKED)
{
HWND hwndComboBox = GetDlgItem(hwndDlg,IDC_IMPEXPEXTERNALCOMBO);
if (hwndComboBox != NULL)
{
// Find out the index of the selected item
INT nIndex = ComboBox_GetCurSel(hwndDlg);
if (nIndex != CB_ERR)
{
// Retrieve a pointer to the filename
LPTSTR pszFileName = (LPTSTR)ComboBox_GetItemData(hwndComboBox, nIndex);
if (pszFileName != NULL)
StrCpyN(m_pImpExp->m_szFileName,pszFileName,MAX_PATH);
}
}
}
else if (Button_GetCheck(GetDlgItem(hwndDlg,IDC_IMPEXPRADIOFILE)) == BST_CHECKED)
{
// just get the text from the edit box
GetDlgItemText(hwndDlg,IDC_IMPEXPMANUAL,m_pImpExp->m_szFileName,MAX_PATH);
//
// Don't allow "next" if the edit control contains a bogus filename
//
if (!IsValidFileOrURL(m_pImpExp->m_szFileName))
{
TCHAR szFmt[128];
TCHAR szMsg[INTERNET_MAX_URL_LENGTH+128];
MLLoadShellLangString(IDS_INVALIDURLFILE, szFmt, ARRAYSIZE(szFmt));
wnsprintf(szMsg, INTERNET_MAX_URL_LENGTH+40, szFmt, m_pImpExp->m_szFileName);
MLShellMessageBox(
hwndDlg,
szMsg,
(IMPORT == m_pImpExp->GetTransferType()) ?
MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV) :
MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_FAV),
MB_OK);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
return retVal;
}
//
// If the user doesn't type an extension, then we add ".htm"
// or ".txt" as appropriate. Otherwise, we don't touch it.
//
if (*PathFindExtension(m_pImpExp->m_szFileName) == TEXT('\0'))
{
PathRenameExtension(
m_pImpExp->m_szFileName,
(m_pImpExp->GetExternalType()==COOKIES) ? TEXT(".txt") : TEXT(".htm"));
}
}
else
{
ASSERT(0);
m_pImpExp->m_szFileName[0] = TEXT('\0');
}
//
// Finally, show an overwrite or file-not-found message
// (but supress it if importing or exporting to a web address)
//
if (m_pImpExp->GetExternalType() == COOKIES ||
!PathIsURL(m_pImpExp->m_szFileName))
{
if ( EXPORT == m_pImpExp->GetTransferType() &&
GetFileAttributes(m_pImpExp->m_szFileName) != 0xFFFFFFFF )
{
int answer ;
UINT idTitle ;
if ( m_pImpExp->GetExternalType() == COOKIES )
idTitle = IDS_EXPCOOKIES ;
else if ( m_pImpExp->GetExternalType() == BOOKMARKS )
idTitle = IDS_EXPFAVORITES ;
else
ASSERT(0);
answer = WarningMessageBox(
hwndDlg,
idTitle,
IDS_IMPEXP_FILEEXISTS,
m_pImpExp->m_szFileName,
MB_YESNO | MB_ICONEXCLAMATION);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (IDYES==answer)?0:-1);
}
else
{
if (IMPORT == m_pImpExp->GetTransferType())
{
BOOL fError;
fError = FALSE;
if (PathIsUNC(m_pImpExp->m_szFileName))
;
else
// Give the user a chance to insert the floppy if it's not already in.
fError = FAILED(SHPathPrepareForWriteWrap(hwndDlg,
NULL,
m_pImpExp->m_szFileName,
FO_COPY,
(SHPPFW_DEFAULT | SHPPFW_IGNOREFILENAME)));
if (!fError)
fError = (0xFFFFFFFF == GetFileAttributes(m_pImpExp->m_szFileName));
if (fError)
{
UINT idTitle ;
if ( m_pImpExp->GetExternalType() == COOKIES )
idTitle = IDS_IMPCOOKIES ;
else if ( m_pImpExp->GetExternalType() == BOOKMARKS )
idTitle = IDS_IMPFAVORITES ;
else
ASSERT(0);
WarningMessageBox(
hwndDlg,
idTitle,
IDS_IMPEXP_FILENOTFOUND,
m_pImpExp->m_szFileName,
MB_OK | MB_ICONEXCLAMATION);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
}
}
}
}
break; // PSN_WIZNEXT
} // WM_NOTIFY
break;
} // switch(msg)
return retVal;
}
BOOL WINAPI RunImportExportFavoritesWizard(HWND hDlg)
{
ImpExpUserDlg::RunNewDialogProcess(hDlg);
return TRUE;
}
int WarningMessageBox(HWND hwnd, UINT idTitle, UINT idMessage, LPCTSTR szFile, DWORD dwFlags)
{
TCHAR szBuffer[1024];
TCHAR szFormat[1024];
//
// load the string (must contain "%s")
//
MLLoadShellLangString(idMessage, szFormat, 1024);
//
// insert the filename
//
wnsprintf(szBuffer,1024,szFormat,szFile);
//
// display the messagebox
//
return MLShellMessageBox(
hwnd,
szBuffer,
MAKEINTRESOURCE(idTitle),
dwFlags);
}