impexpwz.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 75k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * Author: t-franks
  3.  *
  4.  * Last Modified On: Oct 16, 1998
  5.  * Last Modified By: t-joshp
  6.  *
  7.  */
  8. #include "priv.h"
  9. #include "resource.h"
  10. #include "impexp.h"
  11. #include "mluisupp.h"  // for MLLoadString
  12. //
  13. // Indices into our imagelist
  14. // (used for the open and closed folder icons on the tree view)
  15. //
  16. #define FOLDER_CLOSED 0
  17. #define FOLDER_OPEN   1
  18. #define ImportCookieFile ImportCookieFileW
  19. #define ExportCookieFile ExportCookieFileW
  20. BOOL ImportCookieFileW(IN LPCWSTR szFilename);
  21. BOOL ExportCookieFileW(IN LPCWSTR szFilename, BOOL fAppend);
  22. extern void SetListViewToString (HWND hLV, LPCTSTR pszString);
  23. //
  24. // used to display "file already exists" and "file not found" messages
  25. //
  26. int WarningMessageBox(HWND hwnd, UINT idTitle, UINT idMessage, LPCTSTR szFile, DWORD dwFlags);
  27. //
  28. // Strings that don't need localizing
  29. //
  30. #define NS3_COOKIE_REG_PATH         TEXT("Software\Netscape\Netscape Navigator\Cookies")
  31. #define NS3_COOKIE_REG_KEY          TEXT("Cookie File")
  32. #ifndef UNIX
  33. #define NS3_BOOKMARK_REG_PATH       TEXT("Software\Netscape\Netscape Navigator\Bookmark List")
  34. #else
  35. #define NS3_BOOKMARK_REG_PATH       TEXT("SOFTWARE\Microsoft\Internet Explorer\unix\nsbookmarks")
  36. #endif
  37. #define NS3_BOOKMARK_REG_KEY        TEXT("File Location")
  38. #define NS4_USERS_REG_PATH          TEXT("Software\Netscape\Netscape Navigator\Users")
  39. #define NS4_USERPATH_REG_KEY        TEXT("DirRoot")
  40. #define NS_FALLBACK_ROOT_REG_KEY    TEXT("Software\Netscape\Netscape Navigator")
  41. #define NS_FALLBACK_VERSION_REG_VAL TEXT("CurrentVersion")
  42. #define NS_FALLBACK_MAIN_REG_VAL    TEXT("Main")
  43. #define NS_FALLBACK_INST_REG_VAL    TEXT("Install Directory")
  44. #ifndef UNIX
  45. #define ALL_FILES_WILDCARD          TEXT("\*.*")
  46. #else
  47. #define ALL_FILES_WILDCARD          TEXT("/*")
  48. #endif
  49. #define DOT_DIR                     TEXT(".")
  50. #define DOT_DOT_DIR                 TEXT("..")
  51. #ifdef UNIX
  52. #define DIR_SEPARATOR_CHAR  TEXT('/')
  53. #else
  54. #define DIR_SEPARATOR_CHAR  TEXT('\')
  55. #endif
  56. //*************************************************************
  57. //
  58. //      class ListIterator
  59. //
  60. //  Keeps hold on a position in a list.  Allows basic access
  61. //to a list.  The list is set up to map a name to a value.
  62. class NestedList;
  63. class ListIterator
  64. {
  65.     friend NestedList;
  66.     
  67.     struct node
  68.     {
  69.         LPTSTR _sName;
  70.         LPTSTR _sValue;
  71.         DWORD _cNameSize, _cValueSize;
  72.         node* _pnNext;
  73.         node* _pnSublist;
  74.     };
  75.     //  A position is held by pointing to the
  76.     //current node and the pointer that is directed
  77.     //to that node.  The back pointer is kept so the 
  78.     //list can be manipulated at the current element.
  79.     //  when m_pnCurrent == NULL, the iterator is
  80.     //at the end of the list.
  81.     node** m_ppnPrev;
  82.     node* m_pnCurrent;
  83.     //  The invariant could be broken if two iterators
  84.     //point to the same node, and one inserts or deletes
  85.     //an element.  So only one iterator should exist in 
  86.     //a branch of the list at a time.
  87.     BOOL invariant()
  88.     {
  89.         return *m_ppnPrev == m_pnCurrent;
  90.     }
  91. public:
  92.     ListIterator( node** ppnPrev)
  93.     {
  94.         m_ppnPrev = ppnPrev;
  95.         m_pnCurrent = *m_ppnPrev;
  96.     }
  97.     BOOL Insert( LPCTSTR sName, DWORD cNameSize, LPCTSTR sValue, DWORD cValueSize);
  98.     BOOL Remove();
  99.     ListIterator GetSublist();
  100.     void DeleteSublist();
  101.     BOOL Next();
  102.     BOOL AtEndOfList();
  103.     LPCTSTR GetName();
  104.     DWORD GetNameSize();
  105.     LPCTSTR GetValue();
  106.     DWORD GetValueSize();
  107. };
  108. //*************************************************************
  109. //
  110. //  class NestedList
  111. //      Keeps a pointer to a node which heads a list,
  112. //  and deletes that list on destruction.
  113. class NestedList
  114. {
  115.     ListIterator::node* m_pnRoot;
  116.     
  117. public:
  118.     NestedList();
  119.     ~NestedList();
  120.     operator ListIterator();
  121. };
  122. NestedList::NestedList()
  123. : m_pnRoot(NULL)
  124. {
  125. }
  126. NestedList::~NestedList()
  127. {
  128.     while( ((ListIterator)*this).Remove())
  129.     {
  130.     }
  131. }
  132. NestedList::operator ListIterator()
  133. {
  134.     return ListIterator( &m_pnRoot);
  135. }
  136. //*************************************************************
  137. //*************************************************************
  138. //
  139. //  ListIterator functions
  140. //
  141. //  Inserts an element before the current one,
  142. //leaves iterator pointing at new node.
  143. BOOL ListIterator::Insert( 
  144.     LPCTSTR sName, 
  145.     DWORD cNameSize, 
  146.     LPCTSTR sValue, 
  147.     DWORD cValueSize)
  148. {
  149.     ASSERT( invariant());
  150.     node* pNewNode = (node*)(new BYTE[ sizeof(node) 
  151.                                        + (( cNameSize + cValueSize)
  152.                                           * sizeof(TCHAR))]);
  153.     if( pNewNode == NULL)
  154.         return FALSE;
  155.     //  the name and value will be appended to the node.
  156.     pNewNode->_sName = (LPTSTR)((BYTE*)pNewNode + sizeof(node));
  157.     pNewNode->_sValue = pNewNode->_sName + cNameSize;
  158.     pNewNode->_cNameSize = cNameSize;
  159.     pNewNode->_cValueSize = cValueSize;
  160.     memcpy( pNewNode->_sName, sName, pNewNode->_cNameSize * sizeof(TCHAR));
  161.     memcpy( pNewNode->_sValue, sValue, pNewNode->_cValueSize * sizeof(TCHAR));
  162.     // insert new node in list
  163.     pNewNode->_pnNext = m_pnCurrent;
  164.     *m_ppnPrev = pNewNode;
  165.     //  The iterator now points to the new element.
  166.     m_pnCurrent = *m_ppnPrev;
  167.     
  168.     ASSERT( invariant());
  169.     return TRUE;
  170. }
  171. //  Deletes the current node.
  172. //  Returns FALSE if at end of list.
  173. BOOL ListIterator::Remove()
  174. {
  175.     ASSERT( invariant());
  176.     
  177.     //  If this list is empty, or if the iterator 
  178.     //points at the end of the list, there is nothing to
  179.     //delete.
  180.     if( m_pnCurrent == NULL)
  181.         return FALSE;
  182.     // remove sublist
  183.     DeleteSublist();
  184.     
  185.     //  Remember where target node is
  186.     //so it can be deleted once out of
  187.     //the list.
  188.     node* pOldNode = m_pnCurrent;
  189.     // take the target node out of the list.
  190.     //(iterator points to next node or end of list)
  191.     *m_ppnPrev = m_pnCurrent->_pnNext;
  192.     m_pnCurrent = *m_ppnPrev;
  193.     //  Get rid of target node.
  194.     delete [] (BYTE*)pOldNode;
  195.     ASSERT( invariant());
  196.     return TRUE;    
  197. }
  198. //  Returns the sublist of the current node.
  199. ListIterator ListIterator::GetSublist()
  200. {
  201.     ASSERT( invariant());
  202.     
  203.     return ListIterator( &(m_pnCurrent->_pnSublist));
  204. }
  205. //  deletes the children of the current node.
  206. void ListIterator::DeleteSublist()
  207. {
  208.     ASSERT( invariant());
  209.     
  210.     ListIterator sublist( &(m_pnCurrent->_pnSublist));
  211.     
  212.     while( sublist.Remove())
  213.     {
  214.     }
  215.     ASSERT( invariant());
  216. }
  217. //  Advances to the next node.
  218. //  Returns FALSE if already at end of list.
  219. BOOL ListIterator::Next()
  220. {
  221.     ASSERT( invariant());
  222.     if( m_pnCurrent == NULL)
  223.         return FALSE;
  224.     m_ppnPrev = &(m_pnCurrent->_pnNext);
  225.     m_pnCurrent = *m_ppnPrev;
  226.     ASSERT( invariant());
  227.     return m_pnCurrent != NULL;
  228. }
  229. //  
  230. BOOL ListIterator::AtEndOfList()
  231. {
  232.     return ( m_pnCurrent == NULL) ? TRUE : FALSE;
  233. };
  234. //
  235. LPCTSTR ListIterator::GetName()
  236. {
  237.     ASSERT( invariant() && m_pnCurrent != NULL);
  238.     return m_pnCurrent->_sName;
  239. }
  240. //
  241. DWORD ListIterator::GetNameSize()
  242. {
  243.     ASSERT( invariant() && m_pnCurrent != NULL);
  244.     return m_pnCurrent->_cNameSize;
  245. }
  246. //
  247. LPCTSTR ListIterator::GetValue()
  248. {
  249.     ASSERT( invariant() && m_pnCurrent != NULL);
  250.     return m_pnCurrent->_sValue;
  251. }
  252. //
  253. DWORD ListIterator::GetValueSize()
  254. {
  255.     ASSERT( invariant() && m_pnCurrent != NULL);
  256.     return m_pnCurrent->_cValueSize;
  257. }
  258. //*************************************************************
  259. //*************************************************************
  260. //
  261. //  class ImpExpUserProcess
  262. //
  263. //      maintains the description of an import/export process
  264. //  for an import/export wizard, and finally executes the
  265. //  the import/export.
  266. enum ExternalType { INVALID_EXTERNAL = 0, COOKIES, BOOKMARKS};
  267. enum TransferType { INVALID_TRANSFER = 0, IMPORT, EXPORT};
  268. class ImpExpUserProcess
  269. {
  270. public:
  271.     ImpExpUserProcess();
  272.     ~ImpExpUserProcess();
  273.     
  274.     //  the first step the wizard should do is identify the type of
  275.     //import/export process to be done.
  276.     void SelectExternalType( ExternalType selection)    { m_ExternalType = selection; }
  277.     void SelectTransferType( TransferType selection)    { m_TransferType = selection; }
  278.     ExternalType GetExternalType()                      { return m_ExternalType; }
  279.     TransferType GetTransferType()                      { return m_TransferType; }
  280.     BOOL PopulateComboBoxForExternalSelection( HWND hComboBox);
  281.     BOOL GetExternalManualDefault( LPTSTR sExternal, DWORD* pcSize);
  282.     //
  283.     // used to fill the listbox with names of netscape profiles
  284.     //
  285.     void purgeExternalList();
  286.     BOOL populateExternalList();
  287.     BOOL populateExternalListForCookiesOrBookmarks();
  288.     //
  289.     // for netscape 3.x
  290.     //
  291.     BOOL populateExternalListForCookiesOrBookmarksWithNS3Entry();
  292.     //
  293.     // for netscape 4.x
  294.     //
  295.     BOOL populateExternalListForCookiesOrBookmarksWithNS4Entries();
  296.     //
  297.     // fallback case for "funny" versions of netscape
  298.     //
  299.     BOOL populateExternalListFromFolders(LPTSTR pszPath);
  300.     BOOL populateExternalListWithNSEntriesFallBack();
  301.     //  If the transfer is for favorites, the wizard needs to specify
  302.     //an internal folder to import to or export from.
  303.     LPCTSTR GetInternalSelection()       { return m_pSelectedInternal; }
  304.     BOOL PopulateTreeViewForInternalSelection( HWND TreeView);
  305.     BOOL populateTreeViewWithInternalList( HWND hTreeView, ListIterator iterator, HTREEITEM hParent);
  306.     BOOL ExpandTreeViewRoot ( HWND hTreeView ) ;
  307.     BOOL SelectInternalSelection( HWND TreeView);
  308.     void purgeInternalList();
  309.     BOOL populateInternalList();
  310.     BOOL populateInternalListForBookmarks();
  311.     BOOL appendSubdirsToInternalList( LPTSTR sPath, ListIterator iterator);
  312.     
  313.     //  And then, the import/export can be completed.
  314.     void PerformImpExpProcess(HWND hwnd);
  315.     //
  316.     // The filename that we're exporting to or 
  317.     // importing from.
  318.     //
  319.     TCHAR m_szFileName[MAX_PATH];
  320. private:
  321.     ExternalType m_ExternalType;
  322.     TransferType m_TransferType;
  323.     //  m_ExternalList is a flat list of names associated with files
  324.     //example: name =  "Netscape 4.0 profile - Dr. Falken"
  325.     //         value =  "c:netscapeprofiledirDrFalken.chs"
  326.     NestedList m_ExternalList;
  327.     //  m_InternalList is a nested list favorites' pathnames,
  328.     //associated with the complete path.
  329.     NestedList m_InternalList;
  330.     //  Maintain synchronization between m_ExternalType/m_TransferType 
  331.     //and m_InternalList
  332.     ExternalType m_InternalListExternalType;
  333.     TransferType m_InternalListTransferType;
  334.     // if ExternalType == BOOKMARKS,
  335.     //m_pSelectedInternal is the path of a Favorites folder,
  336.     //residing in m_InternalList somewhere, or NULL if a folder
  337.     //hasn't been selected yet.
  338.     LPTSTR m_pSelectedInternal;
  339. };
  340. ImpExpUserProcess::ImpExpUserProcess()
  341. :   m_ExternalType(INVALID_EXTERNAL), m_TransferType(INVALID_TRANSFER),
  342.     m_InternalListExternalType(INVALID_EXTERNAL), m_InternalListTransferType(INVALID_TRANSFER),
  343.     m_pSelectedInternal(0)
  344. {
  345. }
  346. ImpExpUserProcess::~ImpExpUserProcess()
  347. {
  348. }
  349. //*************************************************************
  350. //   PopulateComboBoxForExternal
  351. //
  352. //  Loads content for list box into memory and into List Box,
  353. //associating value of each element with the list element.
  354. //  returns FALSE if the list box is left empty
  355. BOOL ImpExpUserProcess::PopulateComboBoxForExternalSelection( HWND hComboBox)
  356. {
  357.     ASSERT ( m_ExternalType != INVALID_EXTERNAL ) ;
  358.     ComboBox_ResetContent(hComboBox);
  359.    
  360.     //  If ExternalList is invalid, the list box will be left empty.
  361.     if( !populateExternalList() )
  362.         return FALSE;
  363.     ListIterator iterator = m_ExternalList;
  364.     //  Detect and notify if the list is empty.
  365.     if( iterator.AtEndOfList() )
  366.         return FALSE;
  367.     //  add entries from the new ExternalList to the ComboBox.
  368.     do
  369.     {
  370.         int index = ComboBox_AddString( hComboBox, const_cast<LPTSTR>(iterator.GetName() ) );
  371.         ComboBox_SetItemData( hComboBox, index, const_cast<LPTSTR>(iterator.GetValue() ) );
  372.     } while( iterator.Next());
  373.     // set the first one as selected
  374.     ComboBox_SetCurSel( hComboBox, 0 );
  375.     return TRUE;
  376. }
  377. //*************************************************************
  378. //
  379. //  GetExternalManualDefault
  380. //
  381. //  Allows user interface to offer some sort of default
  382. //  filename/location.
  383. //
  384. BOOL ImpExpUserProcess::GetExternalManualDefault(LPTSTR sExternal, DWORD* pcSize)
  385. {
  386.     ASSERT(NULL != pcSize);
  387.     //
  388.     // We only fill it in if it's blank
  389.     //
  390.     if (m_szFileName[0])
  391.     {
  392.         return FALSE;
  393.     }
  394.     ListIterator iterator = m_ExternalList;
  395.     TCHAR szFileName[MAX_PATH];
  396.     INT cchFileName;
  397.     if(m_ExternalType == BOOKMARKS)
  398.         MLLoadString(IDS_NETSCAPE_BOOKMARK_FILE,szFileName,ARRAYSIZE(szFileName));
  399.     else
  400.         MLLoadString(IDS_NETSCAPE_COOKIE_FILE,szFileName,ARRAYSIZE(szFileName));
  401.     cchFileName = lstrlen(szFileName) + 1;
  402.     //  Grab the first item in the External List and use its value.
  403.     if( ((ListIterator)m_ExternalList).AtEndOfList() == FALSE
  404.         && ((ListIterator)m_ExternalList).GetValue() != NULL
  405.         && *pcSize >= ((ListIterator)m_ExternalList).GetValueSize())
  406.     {
  407.         StrCpyN( sExternal,
  408.                  ((ListIterator)m_ExternalList).GetValue(),
  409.                  ((ListIterator)m_ExternalList).GetValueSize());
  410.         *pcSize = ((ListIterator)m_ExternalList).GetValueSize();
  411.         return TRUE;
  412.     }
  413.     //  If there is enough room, specify some file with the correct name
  414.     //  in the "my documents" directory.
  415.     else 
  416.     {
  417.         ASSERT(m_ExternalType == BOOKMARKS || m_ExternalType == COOKIES);
  418.         
  419.         TCHAR szMyDocsPath[MAX_PATH];
  420.         SHGetSpecialFolderPath(NULL,szMyDocsPath,CSIDL_PERSONAL,TRUE);
  421.         *pcSize = wnsprintf(sExternal,MAX_PATH,TEXT("%s%c%s"),szMyDocsPath,DIR_SEPARATOR_CHAR,szFileName);
  422.         return *pcSize > 0;
  423.     }
  424. }
  425. //*************************************************************
  426. //
  427. //
  428. //  purgeExternalList
  429. //
  430. //  Used to clear external target/source list loaded into memory
  431. void ImpExpUserProcess::purgeExternalList()
  432. {
  433.     // delete elements until they're all gone.
  434.     ListIterator iterator = m_ExternalList;
  435.     while( iterator.Remove())
  436.     {
  437.     }
  438. }
  439. //*************************************************************
  440. //
  441. //  populeExternalList
  442. //
  443. //  Used to load external target/source list into memory
  444. BOOL ImpExpUserProcess::populateExternalList()
  445. {
  446.     ASSERT(m_ExternalType != INVALID_EXTERNAL)
  447.     purgeExternalList();
  448.     if(!populateExternalListForCookiesOrBookmarks())
  449.     {
  450.         //
  451.         // If we didn't get any entries using the "standard"
  452.         // techniques, then (and only then) we try the "fallback"
  453.         //
  454.         if (!populateExternalListWithNSEntriesFallBack())
  455.         {
  456.             purgeExternalList();
  457.             return FALSE;
  458.         }
  459.     }
  460.     return TRUE;
  461. }
  462. //*************************************************************
  463. //
  464. //  populateExternalListforCookiesOrBookmarks
  465. //
  466. //  Used to lod external target/source list into memory
  467. //in the case that the content to be transfered is cookies
  468. //or bookmarks.
  469. //  returns TRUE if any elements have been added to the external list
  470. BOOL ImpExpUserProcess::populateExternalListForCookiesOrBookmarks()
  471. {
  472.     ASSERT( m_ExternalType == COOKIES || m_ExternalType == BOOKMARKS);
  473.     BOOL fHasAddedElements = FALSE;
  474.     if( populateExternalListForCookiesOrBookmarksWithNS3Entry())
  475.         fHasAddedElements = TRUE;
  476.     if( populateExternalListForCookiesOrBookmarksWithNS4Entries())
  477.         fHasAddedElements = TRUE;
  478.  
  479.     return fHasAddedElements;
  480. }
  481. //*************************************************************
  482. //
  483. //  populateExternalList..WithNS3Entry
  484. //
  485. //  subfunc of populateExternalListForCookiesOrBookmarks.
  486. //  returns TRUE if any elements have been added to the external list
  487. BOOL ImpExpUserProcess::populateExternalListForCookiesOrBookmarksWithNS3Entry()
  488. {
  489.     BOOL retVal = FALSE;
  490.     //  Determine where to look for reg key
  491.     LPTSTR sNS3RegPath;
  492.     LPTSTR sNS3RegKey;
  493.     if( m_ExternalType == BOOKMARKS)
  494.     {
  495.         sNS3RegPath = NS3_BOOKMARK_REG_PATH;
  496.         sNS3RegKey = NS3_BOOKMARK_REG_KEY;
  497.     }
  498.     else
  499.     {
  500.         sNS3RegPath = NS3_COOKIE_REG_PATH;
  501.         sNS3RegKey = NS3_COOKIE_REG_KEY;
  502.     }
  503.     //  Get the file location and add it to the list
  504.     //  The registry location has the complete path + filename.
  505.     TCHAR sFilePath[MAX_PATH];
  506.     DWORD cbFilePathSize = sizeof(sFilePath);
  507.     DWORD dwType;
  508.     if (ERROR_SUCCESS == SHGetValue(HKEY_CURRENT_USER, sNS3RegPath, sNS3RegKey,
  509.                                     &dwType, (BYTE*)sFilePath, &cbFilePathSize)
  510.         && (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
  511.     {
  512.         TCHAR szBuffer[MAX_PATH];
  513.         MLLoadString(IDS_NS3_VERSION_CAPTION, szBuffer, MAX_PATH);
  514.         
  515.         retVal = ((ListIterator)m_ExternalList).Insert( 
  516.                    szBuffer, lstrlen(szBuffer)+1,
  517.                    sFilePath, cbFilePathSize / sizeof(TCHAR));
  518.     }
  519.     return retVal;
  520. }
  521. //*************************************************************
  522. //
  523. //  populateExternalList..WithNS4Entries
  524. //
  525. //  subfunc of populateExternalListForCookiesOrBookmarks.
  526. //  returns TRUE if any elements have been added to the external list
  527. BOOL ImpExpUserProcess::populateExternalListForCookiesOrBookmarksWithNS4Entries()
  528. {
  529.     BOOL retVal = FALSE;
  530.     //  Get an iterator to advance position as items are inserted.
  531.     ListIterator iterator = (ListIterator)m_ExternalList;
  532.     //  Get the filename to be attached and the associated string size.
  533.     TCHAR sFilename[MAX_PATH];
  534.     DWORD cFilenameLength;
  535.     if(m_ExternalType == BOOKMARKS)
  536.         MLLoadString(IDS_NETSCAPE_BOOKMARK_FILE,sFilename,ARRAYSIZE(sFilename));
  537.     else
  538.         MLLoadString(IDS_NETSCAPE_COOKIE_FILE,sFilename,ARRAYSIZE(sFilename));
  539.     cFilenameLength = lstrlen(sFilename);
  540.     //  Get the reg key of the root of the NS profiles for enumeration.
  541.     HKEY hUserRootKey = NULL;
  542.     if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, NS4_USERS_REG_PATH, 
  543.                       0, KEY_READ, &hUserRootKey) 
  544.         != ERROR_SUCCESS)
  545.     {
  546.         hUserRootKey = NULL;
  547.         goto donePopulateExternalListForCookiesOrBookmarksWithNS4Entries;
  548.     }
  549.     DWORD dwNumberOfProfiles;
  550.     if( RegQueryInfoKey( hUserRootKey, NULL, NULL, NULL, &dwNumberOfProfiles,
  551.         NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS
  552.         || dwNumberOfProfiles == 0)
  553.     {
  554.         goto donePopulateExternalListForCookiesOrBookmarksWithNS4Entries;
  555.     }
  556.     //  Enumerate over the NS profiles, getting their names and
  557.     //directory paths.  Associated the profile name with the path
  558.     //of the desired files by appending the filename to the
  559.     //user's root.
  560.     TCHAR sProfileName[MAX_PATH];
  561.     DWORD cProfileNameSize;  
  562.     cProfileNameSize = MAX_PATH;
  563.     DWORD iEnumIndex;  iEnumIndex = 0;
  564.     while( RegEnumKeyEx( hUserRootKey, (iEnumIndex++), sProfileName, 
  565.                          &cProfileNameSize, NULL, NULL, NULL, NULL) 
  566.            == ERROR_SUCCESS)
  567.     {
  568.         //RegEnumKeyEx gives us the ProfileNameSize w/out the ''.
  569.         cProfileNameSize = MAX_PATH;
  570.         HKEY hProfileKey = NULL;
  571.         if( RegOpenKeyEx( hUserRootKey, sProfileName, 0, KEY_READ, &hProfileKey) 
  572.             != ERROR_SUCCESS)
  573.         {
  574.             hProfileKey = NULL;
  575.             goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
  576.         }
  577.         DWORD dwType;  //  should be REG_SZ when returned from QueryValue
  578.         TCHAR sProfilePath[MAX_PATH];
  579.         DWORD cProfilePathSize;  cProfilePathSize = sizeof(sProfilePath);
  580.         if( (RegQueryValueEx( hProfileKey, NS4_USERPATH_REG_KEY, NULL, &dwType, 
  581.                              (LPBYTE)sProfilePath, &cProfilePathSize) 
  582.                 != ERROR_SUCCESS)
  583.             || dwType != REG_SZ)
  584.         {
  585.             goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
  586.         }
  587.         cProfilePathSize /= sizeof(TCHAR);
  588.         
  589.         if( (MAX_PATH - cProfilePathSize) < cFilenameLength)
  590.         {
  591.             goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
  592.         }
  593.         //  append "\sFilename" to the path.
  594.         sProfilePath[ cProfilePathSize - 1] = TCHAR(FILENAME_SEPARATOR);
  595.         memcpy( &sProfilePath[cProfilePathSize], 
  596.                 sFilename, cFilenameLength * sizeof(TCHAR));
  597.         cProfilePathSize += cFilenameLength;
  598.         sProfilePath[cProfilePathSize++] = TCHAR('');
  599.         // we can only import files if they exist!
  600.         if( m_TransferType == IMPORT
  601.             && GetFileAttributes(sProfilePath) == 0xFFFFFFFF)
  602.                 goto doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries;
  603.         //
  604.         // construct the string for the combo box
  605.         //
  606.         TCHAR sRawProfileName[MAX_PATH];
  607.         TCHAR sRealProfileName[MAX_PATH];
  608.         UINT cRealProfileName;
  609.         MLLoadString(IDS_NS4_FRIENDLY_PROFILE_NAME, sRawProfileName, MAX_PATH);
  610.         cRealProfileName = 
  611.             wnsprintf(sRealProfileName, MAX_PATH, 
  612.                       sRawProfileName, sProfileName);
  613.         //  Insert the profile into the list.  If it inserts, thats
  614.         //enough to consider the whole functions call a success.
  615.         if( iterator.Insert(sRealProfileName, cRealProfileName + 1,
  616.                             sProfilePath, cProfilePathSize))
  617.             retVal = TRUE;
  618.     doneWithEntryInPopulateExternalListForCookiesOrBookmarksWithNS4Entries:
  619.         if( hProfileKey != NULL)
  620.             RegCloseKey(hProfileKey);
  621.     }
  622. donePopulateExternalListForCookiesOrBookmarksWithNS4Entries:
  623.     if( hUserRootKey != NULL)
  624.         RegCloseKey( hUserRootKey);
  625.     return retVal;
  626. }
  627. BOOL ImpExpUserProcess::populateExternalListFromFolders(LPTSTR pszPath)
  628. {
  629.     BOOL retval = FALSE;
  630.     TCHAR szFileName[MAX_PATH];
  631.     TCHAR szPathWithWildcards[MAX_PATH];
  632.     ListIterator iterator = (ListIterator)m_ExternalList;
  633.     HANDLE hFind = NULL;
  634.     WIN32_FIND_DATA wfd;
  635.     //
  636.     // what are we looking for?
  637.     //
  638.     if(m_ExternalType == BOOKMARKS)
  639.         MLLoadString(IDS_NETSCAPE_BOOKMARK_FILE,szFileName,ARRAYSIZE(szFileName));
  640.     else
  641.         MLLoadString(IDS_NETSCAPE_COOKIE_FILE,szFileName,ARRAYSIZE(szFileName));
  642.     //
  643.     // prepare the path variable
  644.     //
  645.     StrCpyN(szPathWithWildcards,pszPath,MAX_PATH);
  646.     StrCatBuff(szPathWithWildcards,ALL_FILES_WILDCARD,MAX_PATH);
  647.     //
  648.     // start the find file thing
  649.     //
  650.     hFind = FindFirstFile(szPathWithWildcards,&wfd);
  651.     if (hFind == INVALID_HANDLE_VALUE)
  652.         goto Cleanup;
  653.     do
  654.     {
  655.         //
  656.         // the actual bookmark or cookie file
  657.         //
  658.         TCHAR szFullPath[MAX_PATH];
  659.         int cchFullPath;
  660.         //
  661.         // a "friendly" name for the corresponding profile
  662.         //
  663.         TCHAR szProfileFormat[MAX_PATH];
  664.         TCHAR szProfileName[MAX_PATH];
  665.         int cchProfileName;
  666.         //
  667.         // skip over "." and ".."
  668.         //
  669.         if(!StrCmp(wfd.cFileName, DOT_DIR) ||
  670.            !StrCmp(wfd.cFileName, DOT_DOT_DIR))
  671.             continue;
  672.         //
  673.         // skip over any non-directories
  674.         //
  675.         if (!(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
  676.             continue;
  677.         //
  678.         // generate the path
  679.         //
  680. #ifndef UNIX
  681.         cchFullPath = wnsprintf(szFullPath,MAX_PATH,TEXT("%s\%s\%s"),pszPath,wfd.cFileName,szFileName);
  682. #else
  683.         cchFullPath = wnsprintf(szFullPath,MAX_PATH,TEXT("%s/%s/%s"),pszPath,wfd.cFileName,szFileName);
  684. #endif
  685.         //
  686.         // see if the file actually exists
  687.         //
  688.         if (GetFileAttributes(szFullPath) == 0xFFFFFFFF)
  689.             continue;
  690.         //
  691.         // generate the profile name
  692.         //
  693.         MLLoadString(IDS_FB_FRIENDLY_PROFILE_NAME, szProfileFormat, MAX_PATH);
  694.         cchProfileName = wnsprintf(szProfileName, MAX_PATH, szProfileFormat, wfd.cFileName);
  695.         //
  696.         // add the entry to the list
  697.         //
  698.         iterator.Insert(
  699.             szProfileName,cchProfileName+1,
  700.             szFullPath,cchFullPath+1);
  701.         retval = TRUE;
  702.     } while(FindNextFile(hFind,&wfd));
  703. Cleanup:
  704.     if (hFind)
  705.         FindClose(hFind);
  706.     return retval;
  707. }
  708. BOOL ImpExpUserProcess::populateExternalListWithNSEntriesFallBack()
  709. {
  710.     BOOL retVal = FALSE;
  711.     HKEY hRoot = NULL;
  712.     HKEY hCurrentVersion = NULL;
  713.     HKEY hCurrentVersionMain = NULL;
  714.     TCHAR szUsersDir[64]; // will contain "..\Users"
  715.     DWORD dwType;
  716.     TCHAR szVersion[64];
  717.     TCHAR szPath[MAX_PATH];
  718.     DWORD cbSize;
  719.     LONG result;
  720.     //
  721.     // Open the root of netscape's HKLM registry hierarchy
  722.     //
  723.     result = RegOpenKeyEx(
  724.          HKEY_LOCAL_MACHINE, 
  725.          NS_FALLBACK_ROOT_REG_KEY,
  726.          0, 
  727.          KEY_READ, 
  728.          &hRoot);
  729.     
  730.     if (result != ERROR_SUCCESS)
  731.         goto Cleanup;
  732.     //
  733.     // Retrieve the "CurrentVersion" value
  734.     //
  735.     cbSize = sizeof(szVersion);
  736.     result = RegQueryValueEx(
  737.         hRoot, 
  738.         NS_FALLBACK_VERSION_REG_VAL, 
  739.         NULL, 
  740.         &dwType, 
  741.         (LPBYTE)szVersion, 
  742.         &cbSize);
  743.     if (result != ERROR_SUCCESS || dwType != REG_SZ)
  744.         goto Cleanup;
  745.     //
  746.     // Open the sub-hierarchy corresponding to the current version
  747.     //
  748.     result = RegOpenKeyEx(
  749.          hRoot, 
  750.          szVersion, 
  751.          0, 
  752.          KEY_READ, 
  753.          &hCurrentVersion);
  754.     if (result != ERROR_SUCCESS)
  755.         goto Cleanup;
  756.     //
  757.     // Open the "main" sub-hierarchy
  758.     //
  759.     result = RegOpenKeyEx(
  760.          hCurrentVersion, 
  761.          NS_FALLBACK_MAIN_REG_VAL, 
  762.          0, 
  763.          KEY_READ, 
  764.          &hCurrentVersionMain);
  765.     if (result != ERROR_SUCCESS)
  766.         goto Cleanup;
  767.     //
  768.     // Retrieve the "Install Directory" value
  769.     //
  770.     cbSize = sizeof(szPath);
  771.     result = RegQueryValueEx(
  772.         hCurrentVersionMain, 
  773.         NS_FALLBACK_INST_REG_VAL, 
  774.         NULL, 
  775.         &dwType, 
  776.         (LPBYTE)szPath, 
  777.         &cbSize);
  778.     if (result != ERROR_SUCCESS || dwType != REG_SZ)
  779.         goto Cleanup;
  780.     //
  781.     // Take a wild guess at where the "Users" dir might be
  782.     //
  783.     MLLoadString(IDS_NETSCAPE_USERS_DIR,szUsersDir,ARRAYSIZE(szUsersDir));
  784.     StrCatBuff(szPath,szUsersDir,ARRAYSIZE(szPath));
  785.     //
  786.     // Fill in the list
  787.     //
  788.     if (populateExternalListFromFolders(szPath))
  789.         retVal = TRUE;
  790. Cleanup:
  791.     if (hRoot)
  792.         RegCloseKey(hRoot);
  793.     if (hCurrentVersion)
  794.         RegCloseKey(hCurrentVersion);
  795.     if (hCurrentVersionMain)
  796.         RegCloseKey(hCurrentVersionMain);
  797.     return retVal;
  798. }
  799. //*************************************************************
  800. //
  801. //  PopulateTreeViewForInternalSelection
  802. //
  803. //  Load a nested list of the favorites folders into memory
  804. //and then into a Tree View.
  805. //  returns FALSE if TreeView is left empty.
  806. BOOL ImpExpUserProcess::PopulateTreeViewForInternalSelection( HWND hTreeView)
  807. {
  808.     ASSERT( m_TransferType != INVALID_TRANSFER);
  809.     TreeView_DeleteAllItems( hTreeView);
  810.     if( !populateInternalList())
  811.         return FALSE;
  812.     return populateTreeViewWithInternalList
  813.             ( hTreeView, (ListIterator)m_InternalList, TVI_ROOT);
  814. }
  815. //*************************************************************
  816. //
  817. //  populateTreeViewWithInternalList
  818. //
  819. //  Loads list entries at 'iterator' below tree view item 'hParent'
  820. //  into 'hTreeView'.  Associates value of each list entry with 
  821. //  the Param of the Tree View node.
  822. //
  823. BOOL ImpExpUserProcess::populateTreeViewWithInternalList
  824. (
  825.     HWND hTreeView,
  826.     ListIterator iterator,
  827.     HTREEITEM hParent
  828. )
  829. {
  830.     BOOL retVal = FALSE;
  831.     
  832.     if( iterator.AtEndOfList())
  833.         goto donePopulateTreeViewWithInternalList;
  834.     TVINSERTSTRUCT newTV;
  835.     HTREEITEM hNew;
  836.     
  837.     //  declare parent and intent to put at end of list.
  838.     newTV.hParent = hParent;
  839.     newTV.hInsertAfter = TVI_LAST;
  840.     // build info struct
  841.     newTV.itemex.mask = TVIF_TEXT
  842.                         | TVIF_PARAM
  843.                         | TVIF_CHILDREN
  844.                         | TVIF_IMAGE
  845.                         | TVIF_SELECTEDIMAGE;
  846.     // give name
  847.     newTV.itemex.cchTextMax = lstrlen( iterator.GetName()) + 1;
  848.     newTV.itemex.pszText = const_cast<LPTSTR>(iterator.GetName());
  849.     
  850.     // associate the necessary data
  851.     newTV.itemex.lParam = (LPARAM)iterator.GetValue();
  852.     // tell tree view if there are any children.
  853.     newTV.itemex.cChildren = 
  854.         iterator.GetSublist().AtEndOfList() == TRUE ? FALSE : TRUE;
  855.     //  use correct icons
  856.     newTV.itemex.iSelectedImage = FOLDER_OPEN ;
  857.     newTV.itemex.iImage = FOLDER_CLOSED ;
  858.     hNew = TreeView_InsertItem( hTreeView, &newTV );
  859.     if( hNew == NULL)
  860.         goto donePopulateTreeViewWithInternalList;
  861.     //  an element has been added, so we should return TRUE.
  862.     retVal = TRUE;
  863.     //  add children
  864.     populateTreeViewWithInternalList( hTreeView, iterator.GetSublist(), hNew );
  865.     //  add siblings
  866.     if( iterator.Next())
  867.         populateTreeViewWithInternalList( hTreeView, iterator, hParent );
  868. donePopulateTreeViewWithInternalList:
  869.     return retVal;
  870. }
  871. BOOL ImpExpUserProcess::ExpandTreeViewRoot ( HWND hTreeView ) 
  872. {
  873.     HTREEITEM hRoot ;
  874.     hRoot = TreeView_GetRoot ( hTreeView ) ;
  875.     if ( hRoot != NULL )
  876.         TreeView_Expand ( hTreeView, hRoot, TVE_EXPAND ) ;
  877.     else
  878.         return FALSE ;
  879.     return TRUE ;
  880. }
  881. //*************************************************************
  882. //
  883. //  SelectInternalSelection
  884. //
  885. //  Gets the data associated with the current selection of
  886. //'hTreeView'.
  887. BOOL ImpExpUserProcess::SelectInternalSelection( HWND hTreeView)
  888. {
  889.     HTREEITEM hSelection = TreeView_GetSelection( hTreeView);
  890.     
  891.     if( hSelection == NULL)
  892.         return FALSE;
  893.     //TVITEM is built up to query the lParam
  894.     //(the lParam has been associated with a pointer to the path value)
  895.     TVITEM TV;
  896.     TV.mask = TVIF_PARAM;
  897.     TV.hItem = hSelection;
  898.     
  899.     if( !TreeView_GetItem( hTreeView, &TV))
  900.         return FALSE;
  901.     m_pSelectedInternal = (LPTSTR)TV.lParam;
  902.     ASSERT( m_pSelectedInternal != NULL);
  903.     
  904.     return TRUE;
  905. }
  906. //*************************************************************
  907. //
  908. //  purgeInternalList
  909. //
  910. //  Wipes out whatever has been loaded in the internal
  911. //target/source list.
  912. void ImpExpUserProcess::purgeInternalList()
  913. {
  914.     // clear the list.
  915.     ListIterator iterator = (ListIterator)m_InternalList;
  916.     while( iterator.Remove())
  917.     {
  918.     }
  919.     m_pSelectedInternal = NULL;
  920.     m_InternalListExternalType = INVALID_EXTERNAL;
  921.     m_InternalListTransferType = INVALID_TRANSFER;
  922. }
  923. //*************************************************************
  924. //
  925. //  populateInternalList
  926. //
  927. //  Builds the internal list for potential internal target/sources.
  928. //  This currently only makes sense for bookmarks, where a favorites
  929. //directory has to be picked.
  930. //  returns TRUE if any elements have been added to the internal list
  931. BOOL ImpExpUserProcess::populateInternalList()
  932. {
  933.     ASSERT( m_ExternalType != INVALID_EXTERNAL);
  934.     if( m_InternalListExternalType == m_ExternalType
  935.         && m_InternalListTransferType == m_TransferType)
  936.         return TRUE;
  937.     purgeInternalList();
  938.     // (could switch on different m_ExternalTypes here)
  939.     if( !populateInternalListForBookmarks())
  940.     {
  941.         purgeInternalList();
  942.         return FALSE;
  943.     }
  944.     m_InternalListExternalType = m_ExternalType;
  945.     m_InternalListTransferType = m_TransferType;
  946.     return TRUE;
  947. }
  948. //*************************************************************
  949. //
  950. //  populateInternalListForBookmarks
  951. //  returns TRUE if any elements have been added to the internal list
  952. BOOL ImpExpUserProcess::populateInternalListForBookmarks()
  953. {
  954.     ASSERT( m_ExternalType == BOOKMARKS);
  955.     TCHAR szFavoritesPath[MAX_PATH];
  956.     if( SHGetSpecialFolderPath( NULL, szFavoritesPath, CSIDL_FAVORITES, FALSE)
  957.         && appendSubdirsToInternalList( szFavoritesPath, m_InternalList))
  958.     {
  959.         return TRUE;
  960.     }
  961.     else return FALSE;
  962. }
  963. //*************************************************************
  964. //
  965. //  appendSubdirsToInternalList
  966. //
  967. //  Takes 'sPath' as a specification for a file search.  All
  968. //directories that match that are added to the internal list 
  969. //at 'iterator'.
  970. //  Recursively adds subdirectories found.
  971. //
  972. //typical usage:
  973. //     szPath is "c:RootFavorites",
  974. //       finds "c:RootFavorites",
  975. //   recursively calls itself with
  976. //     szPath = "c:RootFavorites*.*"
  977. //       finding and recursing into all subdirs
  978. //  returns TRUE if any directories have been added to the internal list
  979. //  Edits the contents of the buffer past the last '\'.
  980. BOOL ImpExpUserProcess::appendSubdirsToInternalList
  981. (
  982.     LPTSTR sPath, 
  983.     ListIterator iterator
  984. )
  985. {
  986.     BOOL fHaveAddedDirectories = FALSE;
  987.     DWORD cPathLength = lstrlen(sPath);
  988.     HANDLE hEnum;
  989.     WIN32_FIND_DATA currentFile;
  990.     hEnum = FindFirstFile( sPath, &currentFile);
  991.     //example:
  992.     //given: "c:root*.*"  (will find all dirs in root)
  993.     //want: "c:root"
  994.     //given: "c:favorites" (will find favorites in root)
  995.     //want: "c:"
  996.     //  left search to '\' to find the path of the files to be found.
  997.     while( cPathLength > 0
  998.            && sPath[ --cPathLength] != TCHAR(FILENAME_SEPARATOR))
  999.     {
  1000.     }
  1001.     cPathLength++;
  1002.     if( hEnum == INVALID_HANDLE_VALUE)
  1003.         return FALSE;
  1004.     do
  1005.     {
  1006.         DWORD cFileNameLength;
  1007.         
  1008.         // we only handle directories
  1009.         if( !(currentFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1010.             continue;
  1011.         // we don't want '.' and '..' to show up.
  1012.         if( !StrCmp( currentFile.cFileName, DOT_DIR)
  1013.             || !StrCmp( currentFile.cFileName, DOT_DOT_DIR))
  1014.             continue;
  1015.         cFileNameLength = lstrlen( currentFile.cFileName);
  1016.         memcpy( sPath + cPathLength, currentFile.cFileName, cFileNameLength * sizeof(TCHAR));
  1017.         sPath[ cPathLength + cFileNameLength] = TCHAR('');
  1018.         if( iterator.Insert( currentFile.cFileName, cFileNameLength + 1,
  1019.                              sPath, cPathLength + cFileNameLength + 1))
  1020.         {
  1021.             memcpy( sPath + cPathLength + cFileNameLength,
  1022.                     ALL_FILES_WILDCARD, sizeof(ALL_FILES_WILDCARD));
  1023.             appendSubdirsToInternalList( sPath, iterator.GetSublist());
  1024.             // we know now that a directory has been added
  1025.             fHaveAddedDirectories = TRUE;
  1026.         }
  1027.     } while( FindNextFile( hEnum, &currentFile));
  1028.     ASSERT( GetLastError() == ERROR_NO_MORE_FILES);
  1029.     FindClose( hEnum);
  1030.     return fHaveAddedDirectories;
  1031. }
  1032. //*************************************************************
  1033. //
  1034. //  PerformImpExpProcess
  1035. //
  1036. //  Once everything is set up right, this should do the trick.
  1037. void ImpExpUserProcess::PerformImpExpProcess(HWND hwnd)
  1038. {
  1039.     ASSERT( GetExternalType() != INVALID_EXTERNAL);
  1040.     ASSERT( GetTransferType() != INVALID_TRANSFER);
  1041.     ASSERT( (GetExternalType() == BOOKMARKS) ? (GetInternalSelection() != NULL) : TRUE);
  1042.     HCURSOR hOldCursor;
  1043.     //
  1044.     // This could take a while, so show an hourglass cursor
  1045.     //
  1046.     hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1047.     switch( GetExternalType())
  1048.     {
  1049.     case COOKIES:
  1050.         switch( GetTransferType())
  1051.         {
  1052.         case IMPORT:
  1053.             if (ImportCookieFile(m_szFileName))
  1054.             {
  1055.                 MLShellMessageBox(
  1056.                     hwnd, 
  1057.                     MAKEINTRESOURCE(IDS_IMPORTSUCCESS_COOK), 
  1058.                     MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_COOK),
  1059.                     MB_OK);
  1060.             }
  1061.             else
  1062.             {
  1063.                 MLShellMessageBox(
  1064.                     hwnd, 
  1065.                     MAKEINTRESOURCE(IDS_IMPORTFAILURE_COOK), 
  1066.                     MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_COOK),
  1067.                     MB_OK);
  1068.             }
  1069.             break;
  1070.         case EXPORT:
  1071.             if (SUCCEEDED(SHPathPrepareForWriteWrap(hwnd, NULL, m_szFileName, FO_COPY, (SHPPFW_DEFAULT | SHPPFW_IGNOREFILENAME))))
  1072.             {
  1073.                 //  FALSE specifies that we will overwrite cookies
  1074.                 if (ExportCookieFile(m_szFileName, FALSE ))
  1075.                 {
  1076.                     MLShellMessageBox(
  1077.                         hwnd, 
  1078.                         MAKEINTRESOURCE(IDS_EXPORTSUCCESS_COOK), 
  1079.                         MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_COOK),
  1080.                         MB_OK);
  1081.                 }
  1082.                 else
  1083.                 {
  1084.                     MLShellMessageBox(
  1085.                         hwnd, 
  1086.                         MAKEINTRESOURCE(IDS_EXPORTFAILURE_COOK), 
  1087.                         MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_COOK),
  1088.                         MB_OK);
  1089.                 }
  1090.             }
  1091.             break;
  1092.         default:
  1093.             ASSERT(0);
  1094.             
  1095.         }
  1096.         break;
  1097.         
  1098.     case BOOKMARKS:
  1099.         DoImportOrExport(
  1100.             GetTransferType()==IMPORT,
  1101.             m_pSelectedInternal,
  1102.             m_szFileName,
  1103.             FALSE);
  1104.         break;
  1105.     default:
  1106.         ASSERT(0);
  1107.     }
  1108.     //
  1109.     // Put the old cursor back when finished
  1110.     //
  1111.     SetCursor(hOldCursor);
  1112. }
  1113. //*************************************************************
  1114. //*************************************************************
  1115. //
  1116. //   ImpExpUserDlg
  1117. //
  1118. //  Handles the user interface side of things, building
  1119. //  up an ImpExpUserProcess then executing it.
  1120. //  The dialog procedures below will all have a return value
  1121. //  which can be set to something besides FALSE if used, or left
  1122. //  as FALSE if not used.  Since only one section of code should
  1123. //  attempt to give the return value a value before returning,
  1124. //  class RetVal is set up to throw an assertion if two pieces
  1125. //  of code intended to pass back a return value at the same
  1126. //  time.
  1127. class ReturnValue
  1128. {
  1129. private:
  1130.     BOOL_PTR m_value;
  1131. public:
  1132.     ReturnValue()
  1133.     { 
  1134.         m_value = FALSE;
  1135.     }
  1136.     
  1137.     BOOL_PTR operator =(BOOL_PTR newVal)
  1138.     {
  1139.         ASSERT( m_value == FALSE);
  1140.         m_value = newVal;
  1141.         return m_value;
  1142.     }
  1143.     
  1144.     operator BOOL_PTR ()
  1145.     {
  1146.         return m_value;
  1147.     }
  1148. };
  1149. class ImpExpUserDlg
  1150. {
  1151. private:
  1152.     static HIMAGELIST m_himl ;
  1153.     static BOOL InitImageList ( HWND hwndTree ) ;   
  1154.     static BOOL DestroyImageList ( HWND hwndTree ) ;    
  1155.     static HFONT m_hfont ;
  1156.     static BOOL InitFont ( HWND hwndStatic ) ;
  1157.     static BOOL DestroyFont ( HWND hwndStatic ) ;
  1158.     //  A sheet knows its resource ID and what process
  1159.     //it contributes to.
  1160.     struct SheetData
  1161.     {
  1162.         int _idPage;
  1163.         ImpExpUserProcess* _pImpExp;
  1164.         SheetData( int idPage, ImpExpUserProcess* pImpExp )
  1165.         : _idPage( idPage ), _pImpExp( pImpExp )
  1166.         {
  1167.         }
  1168.     };
  1169.     //
  1170.     //  InitializePropertySheetPage() will associate a dialog 
  1171.     //  with an allocated copy of SheetData, which will be
  1172.     //  found at PSN_SETACTIVE with and stored with SetWindowLong.
  1173.     //  The allocated SheetData will be cleaned up by callback
  1174.     //  procedure PropertySheetPageProc().
  1175.     //
  1176.     //  Callback functions sure are a drag for maintaining identity.
  1177.     //  GetWindowLong and SetWindowLong will be used to keep tabs
  1178.     //  on who is who, setting 'ghost' member variables.
  1179.     //
  1180.     // 'ghost' SheetData*         This;
  1181.     // 'ghost' ImpExpUserProcess* m_pImpExp;
  1182.     // 'ghost' DWORD              m_idPage;
  1183.     //
  1184.     //  CommonDialogProc retrieves the 'ghost' values and does other 
  1185.     //  shared behavior.
  1186.     //
  1187.     static DWORD CommonDialogProc
  1188.     ( 
  1189.         IN HWND hwndDlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam,
  1190.         OUT ImpExpUserProcess** ppImpExp, OUT DWORD* pPageId,
  1191.         IN OUT ReturnValue& retVal
  1192.     );
  1193.     static void InitializePropertySheetPage( PROPSHEETPAGE* psp, DWORD idDialogTemplate, DWORD idTitle, DWORD idSubTitle,DLGPROC dlgProc, ImpExpUserProcess* lParam);
  1194.     static UINT CALLBACK PropertySheetPageProc( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
  1195.     //  some dialog procedures
  1196.     static BOOL_PTR CALLBACK Wizard97DlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  1197.     static BOOL_PTR CALLBACK TransferTypeDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  1198.     static BOOL_PTR CALLBACK InternalDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  1199.     static BOOL_PTR CALLBACK ExternalDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  1200.     static void HandleTransferTypeChange ( HWND hwndDlg, ImpExpUserProcess* m_pImpExp, UINT iSelect ) ;
  1201. public:
  1202.     static BOOL RunNewDialogProcess( HWND hParent ) ;
  1203. };
  1204. HIMAGELIST ImpExpUserDlg::m_himl = NULL ;
  1205. BOOL ImpExpUserDlg::InitImageList ( HWND hwndTree )
  1206. {
  1207.     //
  1208.     // Code to retrieve icons for open and closed folders
  1209.     // was based on code in private/samples/sampview/utility.cpp.
  1210.     //
  1211.     TCHAR       szFolder[MAX_PATH];
  1212.     SHFILEINFO  sfi;
  1213.     HIMAGELIST  himlOld ;
  1214.     DWORD       dwRet ;
  1215.     // create the image list
  1216.     m_himl = ImageList_Create ( GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLORDDB, 2, 2 ) ;
  1217.     if ( m_himl == NULL )
  1218.         return FALSE ;
  1219.     ImageList_SetBkColor( m_himl, GetSysColor(COLOR_WINDOW) ) ;
  1220.     // add the closed folder icon
  1221.     GetWindowsDirectory(szFolder, MAX_PATH);
  1222.     SHGetFileInfo( szFolder,
  1223.                    0,
  1224.                    &sfi,
  1225.                    sizeof(sfi),
  1226.                    SHGFI_ICON | SHGFI_SMALLICON);
  1227.     dwRet = ImageList_AddIcon(m_himl, sfi.hIcon);
  1228.     ASSERT ( dwRet == FOLDER_CLOSED ) ;
  1229.     // add the open folder icon
  1230.     SHGetFileInfo( szFolder,
  1231.                    0,
  1232.                    &sfi,
  1233.                    sizeof(sfi),
  1234.                    SHGFI_ICON | SHGFI_SMALLICON | SHGFI_OPENICON);
  1235.     dwRet = ImageList_AddIcon(m_himl, sfi.hIcon);
  1236.     ASSERT ( dwRet == FOLDER_OPEN ) ;
  1237.     himlOld = TreeView_SetImageList( hwndTree, m_himl, TVSIL_NORMAL );
  1238.     if ( himlOld != NULL )
  1239.     {
  1240.         BOOL fOk ;
  1241.         fOk = ImageList_Destroy ( himlOld ) ;
  1242.         ASSERT ( fOk ) ;
  1243.     }
  1244.     return TRUE ;
  1245. }
  1246. BOOL ImpExpUserDlg::DestroyImageList ( HWND hwndTree ) 
  1247. {
  1248.     HIMAGELIST himlOld ;
  1249.     himlOld = TreeView_SetImageList( hwndTree, NULL, TVSIL_NORMAL );
  1250.     if ( himlOld != NULL )
  1251.     {
  1252.         BOOL fOk ;
  1253.         fOk = ImageList_Destroy ( himlOld ) ;
  1254.         ASSERT ( fOk ) ;
  1255.     }
  1256.     return TRUE ;
  1257. }
  1258. HFONT ImpExpUserDlg::m_hfont = NULL ;
  1259. BOOL ImpExpUserDlg::InitFont ( HWND hwndStatic ) 
  1260. {
  1261.     HDC hdc = GetDC ( hwndStatic ) ;
  1262.     if ( hdc == NULL )
  1263.         return FALSE ;
  1264.     LOGFONT lf;
  1265.     lf.lfEscapement = 0;
  1266.     lf.lfOrientation = 0;
  1267.     lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  1268.     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  1269.     lf.lfQuality = DEFAULT_QUALITY;
  1270.     lf.lfPitchAndFamily = DEFAULT_PITCH;
  1271.     lf.lfItalic = 0;
  1272.     lf.lfWeight = FW_BOLD;
  1273.     lf.lfStrikeOut = 0;
  1274.     lf.lfUnderline = 0;
  1275.     lf.lfWidth = 0;
  1276.     lf.lfHeight = -MulDiv(13, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  1277.     LOGFONT lfTmp;
  1278.     HFONT   hFontOrig = (HFONT)SendMessage(hwndStatic, WM_GETFONT, (WPARAM)0, (LPARAM)0);
  1279.     if (hFontOrig && GetObject(hFontOrig, sizeof(lfTmp), &lfTmp))
  1280.     {
  1281.         lf.lfCharSet = lfTmp.lfCharSet;
  1282.         StrCpyN(lf.lfFaceName, lfTmp.lfFaceName, LF_FACESIZE);
  1283.     }
  1284.     else
  1285.     {
  1286.         lf.lfCharSet = GetTextCharset(hdc);
  1287.         StrCpyN(lf.lfFaceName, TEXT("MS Shell Dlg"), LF_FACESIZE);
  1288.     }
  1289.     m_hfont = CreateFontIndirect(&lf);
  1290.     if ( m_hfont == NULL )
  1291.         return FALSE ;
  1292.     SendMessage ( hwndStatic, WM_SETFONT, (WPARAM)m_hfont, MAKELPARAM(FALSE, 0) ) ;
  1293.     ReleaseDC ( hwndStatic,hdc ) ;
  1294.     return TRUE ;
  1295. }
  1296. BOOL ImpExpUserDlg::DestroyFont ( HWND hwndDlg )
  1297. {
  1298.     if ( m_hfont )
  1299.         DeleteObject ( m_hfont ) ;
  1300.     return TRUE ;
  1301. }
  1302. void ImpExpUserDlg::InitializePropertySheetPage
  1303. (
  1304.     PROPSHEETPAGE* psp, 
  1305.     DWORD idDialogTemplate,
  1306.     DWORD idTitle,
  1307.     DWORD idSubTitle,
  1308.     DLGPROC dlgProc,
  1309.     ImpExpUserProcess* lParam
  1310. )
  1311. {
  1312.     psp->dwSize = sizeof(PROPSHEETPAGE);
  1313.     psp->dwFlags = PSP_USECALLBACK | PSP_USETITLE;
  1314.     psp->hInstance = MLGetHinst();
  1315.     psp->pszTemplate = MAKEINTRESOURCE(idDialogTemplate);
  1316.     psp->pfnDlgProc = dlgProc;
  1317.     psp->lParam = (LPARAM)(new SheetData(idDialogTemplate,lParam));
  1318.     psp->pfnCallback = PropertySheetPageProc;
  1319.     psp->pszHeaderTitle = MAKEINTRESOURCE(idTitle);
  1320.     psp->pszHeaderSubTitle = MAKEINTRESOURCE(idSubTitle);
  1321.     psp->pszTitle = MAKEINTRESOURCE(IDS_IMPEXP_CAPTION);
  1322.     if ( idDialogTemplate == IDD_IMPEXPWELCOME ||
  1323.          idDialogTemplate == IDD_IMPEXPCOMPLETE )
  1324.     {
  1325.         psp->dwFlags |= PSP_HIDEHEADER; 
  1326.     }
  1327.     else
  1328.     {
  1329.         psp->dwFlags |= (PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE);
  1330.     }
  1331. }
  1332. UINT CALLBACK ImpExpUserDlg::PropertySheetPageProc
  1333. (
  1334.     HWND hwnd, 
  1335.     UINT uMsg, 
  1336.     LPPROPSHEETPAGE ppsp
  1337. )
  1338. {
  1339.     switch(uMsg)
  1340.     {
  1341.     case PSPCB_CREATE:
  1342.         break;
  1343.     case PSPCB_RELEASE:
  1344.         delete (SheetData*)ppsp->lParam;
  1345.         ppsp->lParam = NULL;
  1346.         break;
  1347.     default:
  1348.         break;
  1349.     }
  1350.     return TRUE ;
  1351. }
  1352. //*************************************************************
  1353. //
  1354. //  RunNewDialogProcess
  1355. //
  1356. //  Runs the Import Export Wizard.
  1357. BOOL_PTR CALLBACK TEMP(
  1358.   HWND hwndDlg,  // handle to dialog box
  1359.   UINT uMsg,     // message
  1360.   WPARAM wParam, // first message parameter
  1361.   LPARAM lParam  // second message parameter
  1362. )
  1363. {
  1364.     return (uMsg==WM_INITDIALOG);
  1365. }
  1366. BOOL ImpExpUserDlg::RunNewDialogProcess(HWND hParent)
  1367. {
  1368.     const int numPages = 9;
  1369.     ImpExpUserProcess* pImpExp = new ImpExpUserProcess();
  1370.     if( pImpExp == NULL)
  1371.         return FALSE;
  1372.         
  1373.     PROPSHEETPAGE psp[numPages];
  1374.     PROPSHEETHEADER psh;
  1375.     InitializePropertySheetPage( &psp[0], IDD_IMPEXPWELCOME,        0,                              0,                                  Wizard97DlgProc, pImpExp );
  1376.     InitializePropertySheetPage( &psp[1], IDD_IMPEXPTRANSFERTYPE,   IDS_IMPEXPTRANSFERTYPE_TITLE,   IDS_IMPEXPTRANSFERTYPE_SUBTITLE,    TransferTypeDlg, pImpExp );
  1377.     InitializePropertySheetPage( &psp[2], IDD_IMPEXPIMPFAVSRC,      IDS_IMPEXPIMPFAVSRC_TITLE,      IDS_IMPEXPIMPFAVSRC_SUBTITLE,       ExternalDlg, pImpExp );
  1378.     InitializePropertySheetPage( &psp[3], IDD_IMPEXPIMPFAVDES,      IDS_IMPEXPIMPFAVDES_TITLE,      IDS_IMPEXPIMPFAVDES_SUBTITLE,       InternalDlg, pImpExp );
  1379.     InitializePropertySheetPage( &psp[4], IDD_IMPEXPEXPFAVSRC,      IDS_IMPEXPEXPFAVSRC_TITLE,      IDS_IMPEXPEXPFAVSRC_SUBTITLE,       InternalDlg, pImpExp );
  1380.     InitializePropertySheetPage( &psp[5], IDD_IMPEXPEXPFAVDES,      IDS_IMPEXPEXPFAVDES_TITLE,      IDS_IMPEXPEXPFAVDES_SUBTITLE,       ExternalDlg, pImpExp );
  1381.     InitializePropertySheetPage( &psp[6], IDD_IMPEXPIMPCKSRC,       IDS_IMPEXPIMPCKSRC_TITLE,       IDS_IMPEXPIMPCKSRC_SUBTITLE,        ExternalDlg, pImpExp );
  1382.     InitializePropertySheetPage( &psp[7], IDD_IMPEXPEXPCKDES,       IDS_IMPEXPEXPCKDES_TITLE,       IDS_IMPEXPEXPCKDES_SUBTITLE,        ExternalDlg, pImpExp );
  1383.     InitializePropertySheetPage( &psp[8], IDD_IMPEXPCOMPLETE,       0,                              0,                                  Wizard97DlgProc, pImpExp );
  1384.     psh.dwSize = sizeof(PROPSHEETHEADER);
  1385.     psh.dwFlags = PSH_WIZARD97 | PSH_PROPSHEETPAGE | PSH_HEADER | PSH_WATERMARK ; 
  1386.     psh.hwndParent = hParent;
  1387.     psh.hInstance = MLGetHinst();
  1388.     psh.pszCaption = MAKEINTRESOURCE(IDS_IMPEXP_CAPTION);
  1389.     psh.nPages = numPages;
  1390.     psh.nStartPage = 0;
  1391.     psh.ppsp = psp;
  1392.     psh.pszbmWatermark = MAKEINTRESOURCE(IDB_IMPEXPWATERMARK);
  1393.     psh.pszbmHeader = MAKEINTRESOURCE(IDB_IMPEXPHEADER);
  1394.     int iResult = (int)PropertySheet(&psh) ;
  1395.     delete pImpExp;
  1396.     return iResult;
  1397. }
  1398. //*************************************************************
  1399. //
  1400. //  CommonDialogProc
  1401. //
  1402. //  Prepares 'ghost' member variables of the user dialog process,
  1403. //  handles ordering details of wizard pages and initializes common
  1404. //  dialog elements.
  1405. //
  1406. //  retVal passes through CommonDialogProc so that it can be set
  1407. //  if necessary.  Clients of CommonDialogProc should not need
  1408. //  to specify a new return value if CommonDialogProc has specified
  1409. //  a non-FALSE return value.
  1410. //
  1411. //  If CommonDialogProc returns FALSE dialog procedure should
  1412. //  considered 'msg' handled and return retVal immediately.
  1413. //
  1414. //  If this dialog has yet to receive WM_INITDIALOG, the 'ghost'
  1415. //  values will be zero (and invalid).
  1416. //
  1417. DWORD ImpExpUserDlg::CommonDialogProc
  1418.     IN HWND hwndDlg, 
  1419.     IN UINT msg,
  1420.     IN WPARAM wParam,
  1421.     IN LPARAM lParam,
  1422.     OUT ImpExpUserProcess** ppImpExp,
  1423.     OUT DWORD* pPageId,
  1424.     ReturnValue& retVal
  1425. )
  1426. {
  1427.     SheetData* sheetData;
  1428.     ImpExpUserProcess* m_pImpExp = NULL;
  1429.     DWORD m_idPage = 0;
  1430.     //
  1431.     // Do init-dialog stuff
  1432.     //
  1433.     if ( WM_INITDIALOG == msg )
  1434.     {
  1435.         sheetData = (SheetData*)(((PROPSHEETPAGE*)lParam)->lParam);
  1436.         SetWindowLongPtr( hwndDlg, DWLP_USER, (LONG_PTR)sheetData);
  1437.     }
  1438.     //
  1439.     // Initialize the sheetData field
  1440.     //
  1441.     sheetData = (SheetData*)GetWindowLongPtr( hwndDlg, DWLP_USER ) ;
  1442.     if ( sheetData != NULL )
  1443.     {
  1444.         m_pImpExp = *ppImpExp = sheetData->_pImpExp;
  1445.         m_idPage = *pPageId = sheetData->_idPage;
  1446.     }
  1447.     //
  1448.     // Next, we check to make sure we're on the correct page.  If not, simply
  1449.     // return -1 and the wizard will automatically advance to the next page.
  1450.     //
  1451.     if( WM_NOTIFY == msg && PSN_SETACTIVE == ((LPNMHDR)lParam)->code )
  1452.     {
  1453.         BOOL fPageValidation = TRUE ;
  1454.         switch( m_idPage )
  1455.         {
  1456.         case IDD_IMPEXPWELCOME:
  1457.         case IDD_IMPEXPTRANSFERTYPE:
  1458.         case IDD_IMPEXPCOMPLETE:                    
  1459.             break;
  1460.         case IDD_IMPEXPIMPFAVSRC:
  1461.         case IDD_IMPEXPIMPFAVDES:
  1462.             if(m_pImpExp->GetTransferType() != IMPORT || m_pImpExp->GetExternalType() != BOOKMARKS)
  1463.                 fPageValidation = FALSE;
  1464.             break;
  1465.     
  1466.         case IDD_IMPEXPEXPFAVSRC:
  1467.         case IDD_IMPEXPEXPFAVDES:
  1468.             if(m_pImpExp->GetTransferType() != EXPORT || m_pImpExp->GetExternalType() != BOOKMARKS)
  1469.                 fPageValidation = FALSE;
  1470.             break;
  1471.         case IDD_IMPEXPIMPCKSRC:
  1472.             if(m_pImpExp->GetTransferType() != IMPORT || m_pImpExp->GetExternalType() != COOKIES)
  1473.                 fPageValidation = FALSE;
  1474.             break;
  1475.         case IDD_IMPEXPEXPCKDES:
  1476.             if(m_pImpExp->GetTransferType() != EXPORT || m_pImpExp->GetExternalType() != COOKIES)
  1477.                 fPageValidation = FALSE;
  1478.             break;
  1479.         }
  1480.         SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, fPageValidation ? 0 : -1 ) ;
  1481.         retVal = TRUE ;
  1482.         
  1483.         if ( ! fPageValidation )
  1484.             return FALSE ;
  1485.     }
  1486.     //
  1487.     // Initialize fonts and image lists (if needed)
  1488.     //
  1489.     if ( WM_NOTIFY == msg )
  1490.     {
  1491.         HWND hwndTitle = GetDlgItem ( hwndDlg, IDC_IMPEXPTITLETEXT )  ;
  1492.         HWND hwndTree = GetDlgItem ( hwndDlg, IDC_IMPEXPFAVTREE )  ;
  1493.         switch ( ((LPNMHDR)lParam)->code )
  1494.         {
  1495.         case PSN_SETACTIVE:
  1496.         
  1497.             if ( hwndTitle )
  1498.                 InitFont ( hwndTitle ) ;
  1499.             if ( hwndTree )
  1500.                 InitImageList( hwndTree ) ;
  1501.     
  1502.             break ;
  1503.         case PSN_KILLACTIVE:
  1504.         case PSN_QUERYCANCEL:
  1505.             if ( hwndTitle )
  1506.                 DestroyFont ( hwndTitle ) ;
  1507.             if ( hwndTree )
  1508.                 DestroyImageList( hwndTree ) ;
  1509.             break;
  1510.         }
  1511.     
  1512.     }
  1513.     if( WM_NOTIFY == msg && PSN_SETACTIVE == ((LPNMHDR)lParam)->code )
  1514.     {
  1515.         HWND hwndParent = GetParent( hwndDlg);
  1516.         switch( m_idPage )
  1517.         {
  1518.         case IDD_IMPEXPWELCOME:
  1519.             PropSheet_SetWizButtons( hwndParent, PSWIZB_NEXT );
  1520.             break;
  1521.             
  1522.         case IDD_IMPEXPCOMPLETE:
  1523.             {
  1524.                 UINT idText ;
  1525.                 const TCHAR *szInsert = m_pImpExp->m_szFileName ;
  1526.                 TCHAR szRawString[1024] ;
  1527.                 TCHAR szRealString[1024] ;
  1528.                 //
  1529.                 // First, we need to figure out which string should 
  1530.                 // be used to describe what the wizard is going to 
  1531.                 // do (for example "Import the cookies from...")
  1532.                 //
  1533.                 if ( m_pImpExp->GetTransferType() == IMPORT )
  1534.                 {
  1535.                     if ( m_pImpExp->GetExternalType() == COOKIES )
  1536.                         idText = IDS_IMPEXP_COMPLETE_IMPCK ;
  1537.                     else
  1538.                         idText = IDS_IMPEXP_COMPLETE_IMPFV ;
  1539.                 }
  1540.                 else
  1541.                 {
  1542.                     if ( m_pImpExp->GetExternalType() == COOKIES )
  1543.                         idText = IDS_IMPEXP_COMPLETE_EXPCK ;
  1544.                     else
  1545.                         idText = IDS_IMPEXP_COMPLETE_EXPFV ;
  1546.                 }
  1547.                 LoadString(MLGetHinst(), idText, szRawString, 1024);
  1548.                 wnsprintf(szRealString, 1024, szRawString, szInsert);
  1549.                 //
  1550.                 // Set the text in the listview, and do all the other magic to make
  1551.                 // the tooltips work, etc.
  1552.                 //
  1553.                 SetListViewToString(GetDlgItem(hwndDlg,IDC_IMPEXPCOMPLETECONFIRM), szRealString);
  1554.                 //
  1555.                 // The SetListViewToString function helpfully sets the background color to
  1556.                 // gray instead of the default (white).  But we actually want it white, so 
  1557.                 // let's reset it here.
  1558.                 // 
  1559.                 ListView_SetBkColor(GetDlgItem(hwndDlg,IDC_IMPEXPCOMPLETECONFIRM), GetSysColor(COLOR_WINDOW));
  1560.                 ListView_SetTextBkColor(GetDlgItem(hwndDlg,IDC_IMPEXPCOMPLETECONFIRM), GetSysColor(COLOR_WINDOW));
  1561.                 
  1562.                 PropSheet_SetWizButtons(hwndParent, PSWIZB_BACK|PSWIZB_FINISH);
  1563.             }
  1564.             break;
  1565.             
  1566.         default:
  1567.             PropSheet_SetWizButtons( hwndParent, PSWIZB_NEXT | PSWIZB_BACK );
  1568.             break;
  1569.         }
  1570.     }
  1571.     return TRUE ;
  1572. }
  1573. //*************************************************************
  1574. //
  1575. //  Wizard97DlgProc
  1576. //
  1577. //  Dialog proc for welcome and complete pages.
  1578. //  
  1579. BOOL_PTR CALLBACK ImpExpUserDlg::Wizard97DlgProc
  1580. (
  1581.     HWND hwndDlg, 
  1582.     UINT msg, 
  1583.     WPARAM wParam, 
  1584.     LPARAM lParam
  1585. )
  1586. {
  1587.     ReturnValue retVal;
  1588.     ImpExpUserProcess* m_pImpExp = NULL;
  1589.     DWORD m_idPage = 0;
  1590.     if( !CommonDialogProc( hwndDlg, msg, wParam, lParam, 
  1591.                         &m_pImpExp, &m_idPage, retVal))
  1592.     {
  1593.         return retVal;
  1594.     }
  1595.     if( m_idPage == IDD_IMPEXPCOMPLETE 
  1596.         && msg == WM_NOTIFY
  1597.         && PSN_WIZFINISH == ((LPNMHDR)lParam)->code)
  1598.     m_pImpExp->PerformImpExpProcess(hwndDlg);
  1599.     return retVal;;
  1600. }
  1601. //*************************************************************
  1602. //
  1603. //  TransferTypeDlg
  1604. //
  1605. //  Dialog proc for dialog where user picks transfer type
  1606. //  (import vs. export), (cookies vs. bookmarks)
  1607. BOOL_PTR CALLBACK ImpExpUserDlg::TransferTypeDlg
  1608. (
  1609.     HWND hwndDlg, 
  1610.     UINT msg, 
  1611.     WPARAM wParam, 
  1612.     LPARAM lParam
  1613. )
  1614. {
  1615.     ReturnValue retVal;
  1616.     ImpExpUserProcess* m_pImpExp = NULL;
  1617.     DWORD m_idPage = 0;
  1618.     if( !CommonDialogProc( hwndDlg, msg, wParam, lParam, 
  1619.                         &m_pImpExp, &m_idPage, retVal))
  1620.     {
  1621.         return retVal;
  1622.     }
  1623.     HWND hwndDlgItem;
  1624.    
  1625.     switch( msg)
  1626.     {
  1627.     case WM_INITDIALOG:
  1628.         {
  1629.             hwndDlgItem = GetDlgItem( hwndDlg, IDC_IMPEXPACTIONLISTBOX);
  1630.             LRESULT index;
  1631.             TCHAR szBuffer[MAX_PATH];
  1632.             const DWORD cbSize = MAX_PATH;
  1633.             if( MLLoadString( IDS_IMPFAVORITES, szBuffer, cbSize))
  1634.             {
  1635.                 index = ListBox_AddString( hwndDlgItem, szBuffer);
  1636.                 ListBox_SetItemData( hwndDlgItem, index, IDS_IMPFAVORITES);
  1637.             }
  1638.             if( MLLoadString( IDS_EXPFAVORITES, szBuffer, cbSize))
  1639.             {
  1640.                 index = ListBox_AddString( hwndDlgItem, szBuffer);
  1641.                 ListBox_SetItemData( hwndDlgItem, index, IDS_EXPFAVORITES);
  1642.             }
  1643.             
  1644.             if( MLLoadString( IDS_IMPCOOKIES, szBuffer, cbSize))
  1645.             {
  1646.                 index = ListBox_AddString( hwndDlgItem, szBuffer);
  1647.                 ListBox_SetItemData( hwndDlgItem, index, IDS_IMPCOOKIES);
  1648.             }
  1649.             
  1650.             if( MLLoadString( IDS_EXPCOOKIES, szBuffer, cbSize))
  1651.             {
  1652.                 index = ListBox_AddString( hwndDlgItem, szBuffer);
  1653.                 ListBox_SetItemData( hwndDlgItem, index, IDS_EXPCOOKIES);
  1654.             }
  1655.             // Select the first list item, by default
  1656.             ListBox_SetCurSel(hwndDlgItem, 0);
  1657.             HandleTransferTypeChange(hwndDlg, m_pImpExp, IDS_IMPFAVORITES);
  1658.         }  // end of WM_INITDIALOG
  1659.         break;
  1660.         
  1661.     case WM_COMMAND:
  1662.         //  when the user selects an option, choose it and
  1663.         //and update the description box.
  1664.         hwndDlgItem = GetDlgItem(hwndDlg, IDC_IMPEXPACTIONLISTBOX);
  1665.         if(hwndDlgItem == (HWND)lParam
  1666.            && HIWORD(wParam) == LBN_SELCHANGE)
  1667.         {
  1668.             //  find out which string resource was selected.
  1669.             LRESULT index = ListBox_GetCurSel(hwndDlgItem);
  1670.             LRESULT selection = ListBox_GetItemData(hwndDlgItem, index);
  1671.             HandleTransferTypeChange ( hwndDlg, m_pImpExp, (UINT)selection ) ;
  1672.             retVal = TRUE;
  1673.         }
  1674.         break;
  1675.         
  1676.     case WM_NOTIFY:
  1677.         //
  1678.         //  Prevent advancement until user has made valid choices
  1679.         //
  1680.         if( ((LPNMHDR)lParam)->code == PSN_WIZNEXT
  1681.             &&  (m_pImpExp->GetExternalType() == INVALID_EXTERNAL
  1682.                  || m_pImpExp->GetTransferType() == INVALID_TRANSFER))
  1683.         {
  1684.             SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, -1);
  1685.             retVal = TRUE;
  1686.         }
  1687.         //
  1688.         // otherwise, set the filename to nul (so we get the default)
  1689.         // and allow default navigation behavior
  1690.         //
  1691.         m_pImpExp->m_szFileName[0] = TEXT('');
  1692.         break;
  1693.     }
  1694.     return retVal;
  1695. }
  1696. void ImpExpUserDlg::HandleTransferTypeChange ( HWND hwndDlg, ImpExpUserProcess* m_pImpExp, UINT iSelect )
  1697. {
  1698.     TCHAR szBuffer[MAX_PATH];
  1699.     const DWORD cbSize = MAX_PATH;
  1700.     //
  1701.     //  Note:  The description of each option has a resource id
  1702.     //  which is one higher than the resource id of the option name.
  1703.     //
  1704.     switch( iSelect )
  1705.     {
  1706.     case IDS_IMPFAVORITES:
  1707.         if( MLLoadString( IDS_IMPFAVORITES + 1, szBuffer, cbSize ) )
  1708.             SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC ),
  1709.                            szBuffer );
  1710.         m_pImpExp->SelectExternalType( BOOKMARKS );
  1711.         m_pImpExp->SelectTransferType( IMPORT );
  1712.         break;
  1713.         
  1714.     case IDS_EXPFAVORITES:
  1715.         if( MLLoadString( IDS_EXPFAVORITES + 1, szBuffer, cbSize ) )
  1716.             SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC ),
  1717.                            szBuffer );
  1718.         m_pImpExp->SelectExternalType( BOOKMARKS );
  1719.         m_pImpExp->SelectTransferType( EXPORT );
  1720.         break;
  1721.         
  1722.     case IDS_IMPCOOKIES:
  1723.         if( MLLoadString( IDS_IMPCOOKIES + 1, szBuffer, cbSize))
  1724.             SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC),
  1725.                            szBuffer);
  1726.         m_pImpExp->SelectExternalType( COOKIES);
  1727.         m_pImpExp->SelectTransferType( IMPORT);
  1728.         break;
  1729.     case IDS_EXPCOOKIES:
  1730.         if( MLLoadString( IDS_EXPCOOKIES + 1, szBuffer, cbSize))
  1731.             SetWindowText( GetDlgItem( hwndDlg, IDC_IMPEXPACTIONDESCSTATIC),
  1732.                            szBuffer);
  1733.         m_pImpExp->SelectExternalType( COOKIES);
  1734.         m_pImpExp->SelectTransferType( EXPORT);
  1735.         break;
  1736.     }
  1737. }
  1738. //*************************************************************
  1739. //
  1740. //  InternalDlg
  1741. //
  1742. //  Allows user to pick internal target/source from tree view.
  1743. BOOL_PTR CALLBACK ImpExpUserDlg::InternalDlg
  1744. (
  1745.     HWND hwndDlg, 
  1746.     UINT msg, 
  1747.     WPARAM wParam, 
  1748.     LPARAM lParam
  1749. )
  1750. {
  1751.     ReturnValue retVal;
  1752.     ImpExpUserProcess* m_pImpExp = NULL;
  1753.     DWORD m_idPage = 0;
  1754.     if( !CommonDialogProc( hwndDlg, msg, wParam, lParam, 
  1755.                         &m_pImpExp, &m_idPage, retVal))
  1756.     {
  1757.         return retVal;
  1758.     }
  1759.     HWND hwndDlgItem;
  1760.     switch( msg)
  1761.     {
  1762.     case WM_INITDIALOG:
  1763.         //
  1764.         // Populate the tree control
  1765.         //
  1766.         hwndDlgItem = GetDlgItem(hwndDlg, IDC_IMPEXPFAVTREE);
  1767.         if ( hwndDlgItem )
  1768.         {
  1769.             m_pImpExp->PopulateTreeViewForInternalSelection(hwndDlgItem);
  1770.             m_pImpExp->ExpandTreeViewRoot ( hwndDlgItem ) ;
  1771.         }
  1772.         else
  1773.             ASSERT(0);
  1774.         return TRUE;
  1775.     case WM_NOTIFY:
  1776.         switch( ((LPNMHDR)lParam)->code)
  1777.         {
  1778.         case PSN_WIZNEXT:
  1779.             //  Only allow user to go to next if there is a valid selection.
  1780.             if( !m_pImpExp->SelectInternalSelection(GetDlgItem(hwndDlg,IDC_IMPEXPFAVTREE)) )
  1781.             {
  1782.                 SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, -1);
  1783.                 retVal = TRUE;
  1784.             }
  1785.         }
  1786.     }
  1787.     return retVal;
  1788. }
  1789. BOOL IsValidFileOrURL(LPTSTR szFileOrURL)
  1790. {
  1791.     if (szFileOrURL == NULL)
  1792.         return FALSE;
  1793.     //
  1794.     // any URL is ok
  1795.     //
  1796.     if (PathIsURL(szFileOrURL))
  1797.         return TRUE;
  1798.     //
  1799.     // just a directory is no good, we need a filename too
  1800.     //
  1801.     if (PathIsDirectory(szFileOrURL))
  1802.         return FALSE;
  1803.     //
  1804.     // just a filename is no good, we need a directory too
  1805.     //
  1806.     if (PathIsFileSpec(szFileOrURL))
  1807.         return FALSE;
  1808.     //
  1809.     // relative paths are no good
  1810.     //
  1811.     if (PathIsRelative(szFileOrURL))
  1812.         return FALSE;
  1813.     //
  1814.     // now make sure it parses correctly
  1815.     //
  1816.     if (PathFindFileName(szFileOrURL) == szFileOrURL)
  1817.         return FALSE;
  1818.     return TRUE;
  1819. }
  1820. //*************************************************************
  1821. //
  1822. //  ExternalDlg
  1823. //
  1824. //  Allows user to pick external target/source from list box
  1825. //or manual browse.
  1826. BOOL_PTR CALLBACK ImpExpUserDlg::ExternalDlg
  1827. (
  1828.     HWND hwndDlg, 
  1829.     UINT msg, 
  1830.     WPARAM wParam, 
  1831.     LPARAM lParam
  1832. )
  1833. {
  1834.     ReturnValue retVal;
  1835.     ImpExpUserProcess* m_pImpExp = NULL;
  1836.     DWORD m_idPage = 0;
  1837.     if( !CommonDialogProc( hwndDlg, msg, wParam, lParam, 
  1838.                            &m_pImpExp, &m_idPage, retVal))
  1839.     {
  1840.         return retVal;
  1841.     }
  1842.     HWND hwndDlgItem;
  1843.     
  1844.     switch(msg)
  1845.     {
  1846.     case WM_COMMAND:
  1847.         hwndDlgItem = (HWND) lParam;
  1848.         if( HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_IMPEXPBROWSE)
  1849.         {
  1850.             OPENFILENAME ofn;
  1851.             TCHAR szFile[MAX_PATH];
  1852.             TCHAR szTitle[MAX_PATH];
  1853.             TCHAR szFilter[MAX_PATH];
  1854.             TCHAR szInitialPath[MAX_PATH];
  1855.             int i;
  1856.             ZeroMemory(&ofn, sizeof(OPENFILENAME));
  1857.             ofn.lStructSize = sizeof(OPENFILENAME);
  1858.             ofn.hwndOwner = hwndDlg;
  1859.             ofn.hInstance = MLGetHinst();
  1860.             ofn.lpstrFilter = szFilter;
  1861.             ofn.nFilterIndex = 1;
  1862.             ofn.lpstrCustomFilter = NULL;
  1863.             ofn.lpstrFile = szFile;
  1864.             ofn.nMaxFile = sizeof(szFile);
  1865.             ofn.lpstrFileTitle = NULL;
  1866.             ofn.lpstrInitialDir = szInitialPath;
  1867.             ofn.lpstrTitle = szTitle;
  1868.             ofn.lpstrDefExt = (m_pImpExp->GetExternalType()==COOKIES) ? TEXT("txt") : TEXT("htm");
  1869.             GetDlgItemText(hwndDlg, IDC_IMPEXPMANUAL, szInitialPath, ARRAYSIZE(szFile));
  1870.             szFile[0] = 0;
  1871.             if (PathIsDirectory(szInitialPath))
  1872.             {
  1873.                 ofn.lpstrInitialDir = szInitialPath;
  1874.                 szFile[0] = TEXT('');    
  1875.             }
  1876.             else
  1877.             {
  1878.                 TCHAR *pchFilePart;
  1879.                 pchFilePart = PathFindFileName(szInitialPath);
  1880.                 if (pchFilePart == szInitialPath || pchFilePart == NULL)
  1881.                 {
  1882.                     if (PathIsFileSpec(szInitialPath))
  1883.                         StrCpyN(szFile,szInitialPath,MAX_PATH);
  1884.                     else
  1885.                         szFile[0] = TEXT('');
  1886.                     ofn.lpstrInitialDir = szInitialPath;
  1887.                     SHGetSpecialFolderPath(NULL,szInitialPath,CSIDL_DESKTOP,FALSE);
  1888.                 }
  1889.                 else
  1890.                 {
  1891.                     pchFilePart[-1] = TEXT('');
  1892.                     ofn.lpstrInitialDir = szInitialPath;
  1893.                     StrCpyN(szFile,pchFilePart,MAX_PATH);
  1894.                 }
  1895.             }
  1896.             
  1897.             //
  1898.             // Work out the title and the filter strings
  1899.             //
  1900.             if (m_pImpExp->GetExternalType() == BOOKMARKS)
  1901.             {
  1902.                 MLLoadShellLangString(IDS_IMPEXP_CHOSEBOOKMARKFILE,szTitle,MAX_PATH);
  1903.                 MLLoadShellLangString(IDS_IMPEXP_BOOKMARKFILTER,szFilter,MAX_PATH);
  1904.             }
  1905.             else
  1906.             {
  1907.                 MLLoadShellLangString(IDS_IMPEXP_CHOSECOOKIEFILE,szTitle,MAX_PATH);
  1908.                 MLLoadShellLangString(IDS_IMPEXP_COOKIEFILTER,szFilter,MAX_PATH);
  1909.             }
  1910.             //
  1911.             // Search and replace '@' with nul in the filter string
  1912.             //
  1913.             for (i=0; szFilter[i]; i++)
  1914.                 if (szFilter[i]==TEXT('@'))
  1915.                     szFilter[i]=TEXT('');
  1916.             //
  1917.             // Set the flags for openfilename
  1918.             //
  1919.             ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY ;
  1920.             if (m_pImpExp->GetTransferType() == IMPORT)
  1921.                 ofn.Flags |= (OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST);
  1922.             //
  1923.             // Show the dialog
  1924.             //
  1925.             if(GetSaveFileName(&ofn))
  1926.                 if(SetWindowText(GetDlgItem(hwndDlg, IDC_IMPEXPMANUAL), ofn.lpstrFile))
  1927.                 {
  1928.                     Button_SetCheck(GetDlgItem( hwndDlg, IDC_IMPEXPRADIOFILE), BST_CHECKED);
  1929.                     Button_SetCheck(GetDlgItem( hwndDlg, IDC_IMPEXPRADIOAPP), BST_UNCHECKED);
  1930.                 }
  1931.             retVal = TRUE;
  1932.         }
  1933.         break;
  1934.     case WM_NOTIFY:
  1935.         switch( ((LPNMHDR)lParam)->code )
  1936.         {
  1937.         case PSN_SETACTIVE:
  1938.             {
  1939.                 TCHAR sBuffer[MAX_PATH];
  1940.                 DWORD cbSize = ARRAYSIZE(sBuffer);
  1941.                 hwndDlgItem = GetDlgItem( hwndDlg, IDC_IMPEXPEXTERNALCOMBO );
  1942.                 
  1943.                 //
  1944.                 // Load the "application list" into the combo box.
  1945.                 // If the list is empty, then disable the combo box, 
  1946.                 // disable the associated radio button, and select the
  1947.                 // "to/from file" option (the second radio button).
  1948.                 //
  1949.                 if( hwndDlgItem != NULL
  1950.                     && m_pImpExp->PopulateComboBoxForExternalSelection( hwndDlgItem ) )
  1951.                 {
  1952.                     EnableWindow ( GetDlgItem(hwndDlg, IDC_IMPEXPRADIOAPP), TRUE ) ;
  1953.                     EnableWindow ( hwndDlgItem, TRUE ) ;
  1954.                     Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOAPP), BST_CHECKED);
  1955.                     Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOFILE), BST_UNCHECKED);
  1956.                 }
  1957.                 else if ( hwndDlgItem != NULL)
  1958.                 {
  1959.                     EnableWindow ( GetDlgItem(hwndDlg, IDC_IMPEXPRADIOAPP), FALSE ) ;
  1960.                     EnableWindow( hwndDlgItem, FALSE ) ;
  1961.                     Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOFILE), BST_CHECKED);
  1962.                     Button_SetCheck( GetDlgItem( hwndDlg, IDC_IMPEXPRADIOAPP), BST_UNCHECKED);
  1963.                 }
  1964.                 
  1965.                 //  Put a default value in the browse option.
  1966.                 if(m_pImpExp->GetExternalManualDefault(sBuffer, &cbSize))
  1967.                     SetDlgItemText(hwndDlg, IDC_IMPEXPMANUAL, sBuffer);
  1968.                 SHAutoComplete(GetDlgItem(hwndDlg, IDC_IMPEXPMANUAL), SHACF_FILESYSTEM);
  1969.             }
  1970.             break;
  1971.         case PSN_WIZNEXT:
  1972.             
  1973.             //    If the application radio button is checked,
  1974.             //  select the selection from the application combo box.  If
  1975.             //  the manual button is checked, select the selection
  1976.             //  using the manual edit box.
  1977.             retVal = TRUE;
  1978.             
  1979.             if (Button_GetCheck(GetDlgItem(hwndDlg,IDC_IMPEXPRADIOAPP)) == BST_CHECKED)
  1980.             {
  1981.                 
  1982.                 HWND hwndComboBox = GetDlgItem(hwndDlg,IDC_IMPEXPEXTERNALCOMBO);
  1983.                 
  1984.                 if (hwndComboBox != NULL)
  1985.                 {
  1986.                     // Find out the index of the selected item
  1987.                     INT nIndex = ComboBox_GetCurSel(hwndDlg);
  1988.                     
  1989.                     if (nIndex != CB_ERR)
  1990.                     {
  1991.                         // Retrieve a pointer to the filename
  1992.                         LPTSTR pszFileName = (LPTSTR)ComboBox_GetItemData(hwndComboBox, nIndex);
  1993.                         
  1994.                         if (pszFileName != NULL)
  1995.                             StrCpyN(m_pImpExp->m_szFileName,pszFileName,MAX_PATH);
  1996.                         
  1997.                     }
  1998.                     
  1999.                 }
  2000.             }
  2001.             else if (Button_GetCheck(GetDlgItem(hwndDlg,IDC_IMPEXPRADIOFILE)) == BST_CHECKED)
  2002.             {
  2003.                 
  2004.                 // just get the text from the edit box
  2005.                 GetDlgItemText(hwndDlg,IDC_IMPEXPMANUAL,m_pImpExp->m_szFileName,MAX_PATH);
  2006.                 //
  2007.                 // Don't allow "next" if the edit control contains a bogus filename
  2008.                 //
  2009.                 if (!IsValidFileOrURL(m_pImpExp->m_szFileName))
  2010.                 {
  2011.                     
  2012.                     TCHAR szFmt[128];
  2013.                     TCHAR szMsg[INTERNET_MAX_URL_LENGTH+128];
  2014.                     MLLoadShellLangString(IDS_INVALIDURLFILE, szFmt, ARRAYSIZE(szFmt));
  2015.                     wnsprintf(szMsg, INTERNET_MAX_URL_LENGTH+40, szFmt, m_pImpExp->m_szFileName);
  2016.                     MLShellMessageBox(
  2017.                         hwndDlg, 
  2018.                         szMsg, 
  2019.                         (IMPORT == m_pImpExp->GetTransferType()) ? 
  2020.                            MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV) : 
  2021.                            MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_FAV), 
  2022.                         MB_OK);
  2023.                     
  2024.                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2025.                     return retVal;
  2026.                 }
  2027.                 //
  2028.                 // If the user doesn't type an extension, then we add ".htm"
  2029.                 // or ".txt" as appropriate.  Otherwise, we don't touch it.
  2030.                 //
  2031.                 if (*PathFindExtension(m_pImpExp->m_szFileName) == TEXT(''))
  2032.                 {
  2033.                     PathRenameExtension(
  2034.                         m_pImpExp->m_szFileName,
  2035.                         (m_pImpExp->GetExternalType()==COOKIES) ? TEXT(".txt") : TEXT(".htm"));
  2036.                 }
  2037.             }
  2038.             else
  2039.             {
  2040.                 ASSERT(0);
  2041.                 m_pImpExp->m_szFileName[0] = TEXT('');
  2042.             }
  2043.             //
  2044.             // Finally, show an overwrite or file-not-found message
  2045.             // (but supress it if importing or exporting to a web address)
  2046.             //
  2047.             if (m_pImpExp->GetExternalType() == COOKIES ||
  2048.                 !PathIsURL(m_pImpExp->m_szFileName))
  2049.             {
  2050.                 if ( EXPORT == m_pImpExp->GetTransferType() && 
  2051.                     GetFileAttributes(m_pImpExp->m_szFileName) != 0xFFFFFFFF )
  2052.                 {
  2053.                     int answer ;
  2054.                     UINT idTitle ;
  2055.                     
  2056.                     if ( m_pImpExp->GetExternalType() == COOKIES )
  2057.                         idTitle = IDS_EXPCOOKIES ;
  2058.                     else if ( m_pImpExp->GetExternalType() == BOOKMARKS )
  2059.                         idTitle = IDS_EXPFAVORITES ;
  2060.                     else
  2061.                         ASSERT(0);
  2062.                     
  2063.                     answer = WarningMessageBox(
  2064.                         hwndDlg,
  2065.                         idTitle,
  2066.                         IDS_IMPEXP_FILEEXISTS,
  2067.                         m_pImpExp->m_szFileName,
  2068.                         MB_YESNO | MB_ICONEXCLAMATION);
  2069.                     
  2070.                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (IDYES==answer)?0:-1);
  2071.                 }
  2072.                 else
  2073.                 {
  2074.                     if (IMPORT == m_pImpExp->GetTransferType())
  2075.                     {
  2076.                         // Give the user a chance to insert the floppy if it's not already in.
  2077.                         if (SUCCEEDED(SHPathPrepareForWriteWrap(hwndDlg, NULL, m_pImpExp->m_szFileName, FO_COPY, (SHPPFW_DEFAULT | SHPPFW_IGNOREFILENAME))) &&
  2078.                             (GetFileAttributes(m_pImpExp->m_szFileName) == 0xFFFFFFFF))
  2079.                         {
  2080.                             UINT idTitle ;
  2081.                     
  2082.                             if ( m_pImpExp->GetExternalType() == COOKIES )
  2083.                                 idTitle = IDS_IMPCOOKIES ;
  2084.                             else if ( m_pImpExp->GetExternalType() == BOOKMARKS )
  2085.                                 idTitle = IDS_IMPFAVORITES ;
  2086.                             else
  2087.                                 ASSERT(0);
  2088.                     
  2089.                             WarningMessageBox(
  2090.                                 hwndDlg,
  2091.                                 idTitle,
  2092.                                 IDS_IMPEXP_FILENOTFOUND,
  2093.                                 m_pImpExp->m_szFileName,
  2094.                                 MB_OK | MB_ICONEXCLAMATION);
  2095.                     
  2096.                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2097.                     
  2098.                         }
  2099.                     }
  2100.                 }
  2101.             }
  2102.             
  2103.             break; // PSN_WIZNEXT
  2104.         } // WM_NOTIFY
  2105.         break;
  2106.     
  2107.     } // switch(msg)
  2108.     return retVal;
  2109. }
  2110. BOOL WINAPI RunImportExportFavoritesWizard(HWND hDlg)
  2111. {
  2112.     ImpExpUserDlg::RunNewDialogProcess(hDlg);
  2113.     return TRUE;
  2114. }
  2115. int WarningMessageBox(HWND hwnd, UINT idTitle, UINT idMessage, LPCTSTR szFile, DWORD dwFlags)
  2116. {
  2117.     TCHAR szBuffer[1024];
  2118.     TCHAR szFormat[1024];
  2119.     //
  2120.     // load the string (must contain "%s")
  2121.     //
  2122.     MLLoadShellLangString(idMessage, szFormat, 1024);
  2123.    
  2124.     //
  2125.     // insert the filename
  2126.     //
  2127.     wnsprintf(szBuffer,1024,szFormat,szFile);
  2128.     //
  2129.     // display the messagebox
  2130.     //
  2131.     return MLShellMessageBox(
  2132.         hwnd,
  2133.         szBuffer,
  2134.         MAKEINTRESOURCE(idTitle),
  2135.         dwFlags);
  2136. }