Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2236 lines
73 KiB

  1. //
  2. // IMPEXP.CPP - Browser Import and Export Code
  3. //
  4. // Imports and Exports Favorites in various formats
  5. //
  6. // julianj 2/16/98
  7. //
  8. //
  9. // *** IMPORT FAVORITES CODE ***
  10. //
  11. /************************************************************\
  12. FILE: impext.cpp
  13. DATE: April 1, 1996
  14. AUTHOR(S): Bryan Starbuck (bryanst)
  15. DESCRIPTION:
  16. This file contains functions that can be used to upgrade
  17. settings from the Microsoft Internet Explorer v2.0 to v3.0,
  18. and some features to import Netscape features into Internet
  19. Explorer.
  20. This file will handle the logic to convert Netscape
  21. bookmarks to Microsoft Internet Explorer favorites. This
  22. will happen by finding the location of the Netscape bookmarks
  23. file and the Microsoft Internet Explorer favorites directory
  24. from the registry. Then it will parse the bookmarks file to
  25. extract the URLs, which will finally be added to the favorites
  26. directory.
  27. USAGE:
  28. This code is designed to be called when the user may
  29. want Netscape bookmarks imported into system level Favorites
  30. usable by programs such as Internet Explorer. External
  31. users should call ImportBookmarks(). If this is done during
  32. setup, it should be done after setup specifies the Favorites
  33. registry entry and directory. If Netscape is not installed,
  34. then the ImportBookmarks() is just a big no-op.
  35. NOTE:
  36. If this file is being compiled into something other
  37. than infnist.exe, it will be necessary to include the
  38. following String Resource:
  39. #define IDS_NS_BOOKMARKS_DIR 137
  40. STRINGTABLE DISCARDABLE
  41. BEGIN
  42. ...
  43. IDS_NS_BOOKMARKS_DIR "\\Imported Bookmarks"
  44. END
  45. UPDATES: I adopted this file to allow IE4.0 having the abilities
  46. to upgrade from NetScape's setting. Two CustomActions will be added
  47. to call in functions in this file. (inateeg)
  48. 8/14/98: added functions to import or export via an URL,
  49. 8/19/98: added UI to allow user to import/export via browser's File
  50. menu/"Import and Exporting..."
  51. \************************************************************/
  52. #include "priv.h"
  53. #include "impexp.h"
  54. #include <regstr.h>
  55. #include "resource.h"
  56. #include <mluisupp.h>
  57. //
  58. // Information about the Netscape Bookmark file format that is shared between
  59. // the import and export code
  60. //
  61. #define BEGIN_DIR_TOKEN "<DT><H"
  62. #ifdef UNIX
  63. #define MID_DIR_TOKEN0 "3>"
  64. #endif
  65. #define MID_DIR_TOKEN "\">"
  66. #define END_DIR_TOKEN "</H"
  67. #define BEGIN_EXITDIR_TOKEN "</DL><p>"
  68. #define BEGIN_URL_TOKEN "<DT><A HREF=\""
  69. #define END_URL_TOKEN "\" A"
  70. #ifdef UNIX
  71. #define END_URL_TOKEN2 "\">"
  72. #endif
  73. #define BEGIN_BOOKMARK_TOKEN ">"
  74. #define END_BOOKMARK_TOKEN "</A>"
  75. #define VALIDATION_STR "<!DOCTYPE NETSCAPE-Bookmark-file-"
  76. //
  77. // Use by export code
  78. //
  79. #define COMMENT_STR "<!-- This is an automatically generated file.\r\nIt will be read and overwritten.\r\nDo Not Edit! -->"
  80. #define TITLE "<TITLE>Bookmarks</TITLE>\r\n<H1>Bookmarks</H1>"
  81. // ItemType is going to be the type of entry found in the bookmarks
  82. // file.
  83. typedef enum MYENTRYTYPE
  84. {
  85. ET_OPEN_DIR = 531, // New level in heirarchy
  86. ET_CLOSE_DIR, // Close level in heirarchy
  87. ET_BOOKMARK, // Bookmark entry.
  88. ET_NONE, // End of File
  89. ET_ERROR // Bail, we encountered an error
  90. } MyEntryType;
  91. //////////////////////////////////////////////////////////////////
  92. // Internal Functions
  93. //////////////////////////////////////////////////////////////////
  94. BOOL ImportNetscapeProxy(void); // Import Netscape Proxy Setting
  95. BOOL UpdateHomePage(void); // Upgrade IE v1.0 Home URL to v3.0
  96. BOOL ImportBookmarks(TCHAR *pszPathToFavorites, TCHAR *pszPathToBookmarks, HWND hwnd); // Import Netscape Bookmarks to IE Favorites
  97. BOOL ExportFavorites(TCHAR *pszPathToFavorites, TCHAR *pszPathToBookmarks, HWND hwnd); // Export IE Favorites to Netscape Bookmarks
  98. BOOL RegStrValueEmpty(HKEY hTheKey, char * szPath, char * szKey);
  99. BOOL GetNSProxyValue(char * szProxyValue, DWORD * pdwSize);
  100. BOOL VerifyBookmarksFile(HANDLE hFile);
  101. BOOL ConvertBookmarks(TCHAR * szFavoritesDir, HANDLE hFile);
  102. MyEntryType NextFileEntry(char ** ppStr, char ** ppToken);
  103. BOOL GetData(char ** ppData, HANDLE hFile);
  104. void RemoveInvalidFileNameChars(char * pBuf);
  105. BOOL CreateDir(char *pDirName);
  106. BOOL CloseDir(void);
  107. BOOL CreateBookmark(char *pBookmarkName);
  108. BOOL GetPathFromRegistry(LPTSTR szPath, UINT cbPath, HKEY theHKEY, LPTSTR szKey, LPTSTR szVName);
  109. BOOL GetNavBkMkDir( LPTSTR lpszDir, int isize);
  110. BOOL GetTargetFavoritesPath(LPTSTR szPath, UINT cbPath);
  111. BOOL PostFavorites(TCHAR *pszPathToBookmarks, TCHAR* pszPathToPost);
  112. void CALLBACK StatusCallback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwStatus,
  113. LPVOID lpvInfo, DWORD dwInfoLength);
  114. //////////////////////////////////////////////////////////////////
  115. // TYPES:
  116. //////////////////////////////////////////////////////////////////
  117. //typedef enum MYENTRYTYPE MyEntryType;
  118. //////////////////////////////////////////////////////////////////
  119. // Constants:
  120. //////////////////////////////////////////////////////////////////
  121. #define MAX_URL 2048
  122. #define FILE_EXT 4 // For ".url" at the end of favorite filenames
  123. #define REASONABLE_NAME_LEN 100
  124. #define ANSIStrStr(p, q) StrStrIA(p, q)
  125. #define ANSIStrChr(p, q) StrChrIA(p, q)
  126. //////////////////////////////////////////////////////////////////
  127. // GLOBALS:
  128. //////////////////////////////////////////////////////////////////
  129. #ifndef UNIX
  130. TCHAR * szNetscapeBMRegSub = TEXT("SOFTWARE\\Netscape\\Netscape Navigator\\Bookmark List");
  131. #else
  132. TCHAR * szNetscapeBMRegSub = TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\unix\\nsbookmarks");
  133. #endif
  134. TCHAR * szNetscapeBMRegKey = TEXT("File Location");
  135. TCHAR * szIEFavoritesRegSub = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
  136. TCHAR * szIEFavoritesRegKey = TEXT("Favorites");
  137. char * szInvalidFolderCharacters = "\\/:*?\"<>|";
  138. BOOL gfValidNetscapeFile = FALSE;
  139. BOOL gfValidIEDirFile = FALSE;
  140. #define _FAT_ 1
  141. #define _HPFS_ 0
  142. #define _NTFS_ 0
  143. #define _WILD_ 0
  144. #define _OFS_ 0
  145. #define _OLE_ 0
  146. #define AnsiMaxChar 128 // The array below only indicates the lower 7 bits of the byte.
  147. static UCHAR LocalLegalAnsiCharacterArray[AnsiMaxChar] = {
  148. 0, // 0x00 ^@
  149. _OLE_, // 0x01 ^A
  150. _OLE_, // 0x02 ^B
  151. _OLE_, // 0x03 ^C
  152. _OLE_, // 0x04 ^D
  153. _OLE_, // 0x05 ^E
  154. _OLE_, // 0x06 ^F
  155. _OLE_, // 0x07 ^G
  156. _OLE_, // 0x08 ^H
  157. _OLE_, // 0x09 ^I
  158. _OLE_, // 0x0A ^J
  159. _OLE_, // 0x0B ^K
  160. _OLE_, // 0x0C ^L
  161. _OLE_, // 0x0D ^M
  162. _OLE_, // 0x0E ^N
  163. _OLE_, // 0x0F ^O
  164. _OLE_, // 0x10 ^P
  165. _OLE_, // 0x11 ^Q
  166. _OLE_, // 0x12 ^R
  167. _OLE_, // 0x13 ^S
  168. _OLE_, // 0x14 ^T
  169. _OLE_, // 0x15 ^U
  170. _OLE_, // 0x16 ^V
  171. _OLE_, // 0x17 ^W
  172. _OLE_, // 0x18 ^X
  173. _OLE_, // 0x19 ^Y
  174. _OLE_, // 0x1A ^Z
  175. _OLE_, // 0x1B ESC
  176. _OLE_, // 0x1C FS
  177. _OLE_, // 0x1D GS
  178. _OLE_, // 0x1E RS
  179. _OLE_, // 0x1F US
  180. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x20 space
  181. _FAT_ | _HPFS_ | _NTFS_ | _OFS_, // 0x21 !
  182. _WILD_, // 0x22 "
  183. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x23 #
  184. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x24 $
  185. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x25 %
  186. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x26 &
  187. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x27 '
  188. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x28 (
  189. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x29 )
  190. _WILD_, // 0x2A *
  191. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2B +
  192. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2C ,
  193. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2D -
  194. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2E .
  195. 0, // 0x2F /
  196. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x30 0
  197. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x31 1
  198. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x32 2
  199. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x33 3
  200. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x34 4
  201. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x35 5
  202. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x36 6
  203. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x37 7
  204. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x38 8
  205. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x39 9
  206. _NTFS_ | _OFS_, // 0x3A :
  207. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x3B ;
  208. _WILD_, // 0x3C <
  209. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x3D =
  210. _WILD_, // 0x3E >
  211. _WILD_, // 0x3F ?
  212. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x40 @
  213. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x41 A
  214. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x42 B
  215. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x43 C
  216. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x44 D
  217. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x45 E
  218. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x46 F
  219. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x47 G
  220. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x48 H
  221. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x49 I
  222. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4A J
  223. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4B K
  224. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4C L
  225. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4D M
  226. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4E N
  227. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4F O
  228. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x50 P
  229. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x51 Q
  230. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x52 R
  231. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x53 S
  232. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x54 T
  233. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x55 U
  234. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x56 V
  235. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x57 W
  236. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x58 X
  237. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x59 Y
  238. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5A Z
  239. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5B [
  240. 0, // 0x5C backslash
  241. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5D ]
  242. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5E ^
  243. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5F _
  244. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x60 `
  245. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x61 a
  246. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x62 b
  247. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x63 c
  248. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x64 d
  249. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x65 e
  250. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x66 f
  251. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x67 g
  252. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x68 h
  253. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x69 i
  254. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6A j
  255. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6B k
  256. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6C l
  257. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6D m
  258. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6E n
  259. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6F o
  260. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x70 p
  261. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x71 q
  262. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x72 r
  263. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x73 s
  264. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x74 t
  265. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x75 u
  266. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x76 v
  267. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x77 w
  268. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x78 x
  269. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x79 y
  270. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7A z
  271. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7B {
  272. _OLE_, // 0x7C |
  273. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7D }
  274. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7E ~
  275. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7F 
  276. };
  277. // Returns the location of the favorites folder in which to import the netscape favorites
  278. BOOL GetTargetFavoritesPath(LPTSTR szPath, UINT cbPath)
  279. {
  280. if (GetPathFromRegistry(szPath, cbPath, HKEY_CURRENT_USER, szIEFavoritesRegSub, szIEFavoritesRegKey))
  281. {
  282. //MLLoadString(IDS_NS_BOOKMARKS_DIR, szSubDir, sizeof(szSubDir))
  283. //lstrcat(szPath, "\\Imported Netscape Favorites");
  284. return TRUE;
  285. }
  286. return FALSE;
  287. }
  288. ///////////////////////////////////////////////////////
  289. // Import Netscape Bookmarks to Microsoft
  290. // Internet Explorer's Favorites
  291. ///////////////////////////////////////////////////////
  292. /************************************************************\
  293. FUNCTION: ImportBookmarks
  294. PARAMETERS:
  295. HINSTANCE hInstWithStr - Location of String Resources.
  296. BOOL return - If an error occurs importing the bookmarks, FALSE is returned.
  297. DESCRIPTION:
  298. This function will see if it can find a IE Favorite's
  299. registry entry and a Netscape bookmarks registry entry. If
  300. both are found, then the conversion can happen. It will
  301. attempt to open the verify that the bookmarks file is
  302. valid and then convert the entries to favorite entries.
  303. If an error occures, ImportBookmarks() will return FALSE,
  304. otherwise it will return TRUE.
  305. \*************************************************************/
  306. BOOL ImportBookmarks(TCHAR *pszPathToFavorites, TCHAR *pszPathToBookmarks, HWND hwnd)
  307. {
  308. HANDLE hBookmarksFile = INVALID_HANDLE_VALUE;
  309. BOOL fSuccess = FALSE;
  310. // Prompt the user to insert floppy, format floppy or drive, remount mapped partition,
  311. // or any create sub directories so pszPathToBookmarks becomes valid.
  312. if (FAILED(SHPathPrepareForWriteWrap(hwnd, NULL, pszPathToBookmarks, FO_COPY, (SHPPFW_DEFAULT | SHPPFW_IGNOREFILENAME))))
  313. return FALSE;
  314. if (pszPathToFavorites==NULL || *pszPathToFavorites == TEXT('\0') ||
  315. pszPathToBookmarks==NULL || *pszPathToBookmarks == TEXT('\0'))
  316. {
  317. return FALSE;
  318. }
  319. hBookmarksFile = CreateFile(pszPathToBookmarks, GENERIC_READ, FILE_SHARE_READ, NULL,
  320. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  321. if ( hBookmarksFile != INVALID_HANDLE_VALUE )
  322. {
  323. //
  324. // Verify it's a valid Bookmarks file
  325. //
  326. if (VerifyBookmarksFile( hBookmarksFile ))
  327. {
  328. //
  329. // Do the importing...
  330. //
  331. fSuccess = ConvertBookmarks(pszPathToFavorites, hBookmarksFile);
  332. if (hwnd && !fSuccess)
  333. {
  334. MLShellMessageBox(
  335. hwnd,
  336. MAKEINTRESOURCE(IDS_IMPORTCONVERTERROR),
  337. MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV),
  338. MB_OK);
  339. }
  340. }
  341. else
  342. {
  343. if (hwnd)
  344. {
  345. MLShellMessageBox(
  346. hwnd,
  347. MAKEINTRESOURCE(IDS_NOTVALIDBOOKMARKS),
  348. MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV),
  349. MB_OK);
  350. }
  351. }
  352. CloseHandle(hBookmarksFile);
  353. }
  354. else
  355. {
  356. if (hwnd)
  357. {
  358. MLShellMessageBox(
  359. hwnd,
  360. MAKEINTRESOURCE(IDS_COULDNTOPENBOOKMARKS),
  361. MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV),
  362. MB_OK);
  363. }
  364. }
  365. return(fSuccess);
  366. }
  367. /************************************************************\
  368. FUNCTION: ConvertBookmarks
  369. PARAMETERS:
  370. char * szFavoritesDir - String containing the path to
  371. the IE Favorites directory
  372. BOOL return - If an error occurs importing the bookmarks, FALSE is returned.
  373. DESCRIPTION:
  374. This function will continue in a loop converting each
  375. entry in the bookmark file. There are three types of
  376. entries in the bookmark file, 1) a bookmark, 2) start of
  377. new level in heirarchy, 3) end of current level in heirarchy.
  378. The function NextFileEntry() will return these values until
  379. the file is empty, at which point, this function will end.
  380. NOTE:
  381. In order to prevent an infinite loop, it's assumed
  382. that NextFileEntry() will eventually return ET_NONE or ET_ERROR.
  383. \************************************************************/
  384. BOOL ConvertBookmarks(TCHAR * szFavoritesDir, HANDLE hFile)
  385. {
  386. BOOL fDone = FALSE;
  387. BOOL fSuccess = TRUE;
  388. BOOL fIsEmpty = TRUE;
  389. char * szData = NULL;
  390. char * szCurrent = NULL;
  391. char * szToken = NULL;
  392. fSuccess = GetData(&szData, hFile);
  393. if (NULL == szData)
  394. fSuccess = FALSE;
  395. szCurrent = szData;
  396. // Verify directory exists or that we can make it.
  397. if ((TRUE == fSuccess) && ( !SetCurrentDirectory(szFavoritesDir)))
  398. {
  399. // If the directory doesn't exist, make it...
  400. if ( !CreateDirectory(szFavoritesDir, NULL))
  401. fSuccess = FALSE;
  402. else
  403. if (!SetCurrentDirectory(szFavoritesDir))
  404. fSuccess = FALSE;
  405. }
  406. while ((FALSE == fDone) && (TRUE == fSuccess))
  407. {
  408. switch(NextFileEntry(&szCurrent, &szToken))
  409. {
  410. case ET_OPEN_DIR:
  411. fSuccess = CreateDir(szToken);
  412. break;
  413. case ET_CLOSE_DIR:
  414. fSuccess = CloseDir();
  415. break;
  416. case ET_BOOKMARK:
  417. fSuccess = CreateBookmark(szToken);
  418. fIsEmpty = FALSE;
  419. break;
  420. case ET_ERROR:
  421. fSuccess = FALSE;
  422. break;
  423. case ET_NONE:
  424. default:
  425. fDone = TRUE;
  426. break;
  427. }
  428. }
  429. if ( fIsEmpty )
  430. {
  431. // nothing to import, delete the dir created earlier
  432. RemoveDirectory(szFavoritesDir);
  433. }
  434. if (NULL != szData)
  435. {
  436. LocalFree(szData);
  437. szData = NULL;
  438. szCurrent = NULL; // szCurrent no longer points to valid data.
  439. szToken = NULL; // szCurrent no longer points to valid data.
  440. }
  441. return(fSuccess);
  442. }
  443. /************************************************************\
  444. FUNCTION: NextFileEntry
  445. PARAMETERS:
  446. char ** ppStr - The data to parse.
  447. char ** ppToken - The token pointer.
  448. EntryType return- See below.
  449. DESCRIPTION:
  450. This function will look for the next entry in the
  451. bookmark file to create or act on. The return value
  452. will indicate this response:
  453. ET_OPEN_DIR Create a new level in heirarchy
  454. ET_CLOSE_DIR, Close level in heirarchy
  455. ET_BOOKMARK, Create Bookmark entry.
  456. ET_NONE, End of File
  457. ET_ERROR Error encountered
  458. Errors will be detected by finding the start of a token,
  459. but in not finding other parts of the token that are needed
  460. to parse the data.
  461. \************************************************************/
  462. MyEntryType NextFileEntry(char ** ppStr, char ** ppToken)
  463. {
  464. MyEntryType returnVal = ET_NONE;
  465. char * pCurrentToken = NULL; // The current token to check if valid.
  466. char * pTheToken = NULL; // The next valid token.
  467. char * pszTemp = NULL;
  468. #ifdef UNIX
  469. char szMidDirToken[8];
  470. #endif
  471. //ASSERTSZ(NULL != ppStr, "It's an error to pass NULL for ppStr");
  472. //ASSERTSZ(NULL != *ppStr, "It's an error to pass NULL for *ppStr");
  473. //ASSERTSZ(NULL != ppToken, "It's an error to pass NULL for ppToken");
  474. if ((NULL != ppStr) && (NULL != *ppStr) && (NULL != ppToken))
  475. {
  476. // Check for begin dir token
  477. if (NULL != (pCurrentToken = ANSIStrStr(*ppStr, BEGIN_DIR_TOKEN)))
  478. {
  479. // Begin dir token found
  480. // Verify that other needed tokens exist or it's an error
  481. #ifndef UNIX
  482. if ((NULL == (pszTemp = ANSIStrStr(pCurrentToken, MID_DIR_TOKEN))) ||
  483. #else
  484. if (pCurrentToken[7] == ' ')
  485. StrCpyNA(szMidDirToken, MID_DIR_TOKEN, ARRAYSIZE(szMidDirToken));
  486. else
  487. StrCpyNA(szMidDirToken, MID_DIR_TOKEN0, ARRAYSIZE(szMidDirToken));
  488. if ((NULL == (pszTemp = ANSIStrStr(pCurrentToken, szMidDirToken))) ||
  489. #endif
  490. (NULL == ANSIStrStr(pszTemp, END_DIR_TOKEN)))
  491. {
  492. returnVal = ET_ERROR; // We can't find all the tokens needed.
  493. }
  494. else
  495. {
  496. // This function has to set *ppToken to the name of the directory to create
  497. #ifndef UNIX
  498. *ppToken = ANSIStrStr(pCurrentToken, MID_DIR_TOKEN) + sizeof(MID_DIR_TOKEN)-1;
  499. #else
  500. *ppToken = ANSIStrStr(pCurrentToken, szMidDirToken) + lstrlenA(szMidDirToken);
  501. #endif
  502. pTheToken = pCurrentToken;
  503. returnVal = ET_OPEN_DIR;
  504. }
  505. }
  506. // Check for exit dir token
  507. if ((ET_ERROR != returnVal) &&
  508. (NULL != (pCurrentToken = ANSIStrStr(*ppStr, BEGIN_EXITDIR_TOKEN))))
  509. {
  510. // Exit dir token found
  511. // See if this token comes before TheToken.
  512. if ((NULL == pTheToken) || (pCurrentToken < pTheToken))
  513. {
  514. // ppToken is not used for Exit Dir
  515. *ppToken = NULL;
  516. pTheToken = pCurrentToken;
  517. returnVal = ET_CLOSE_DIR;
  518. }
  519. }
  520. // Check for begin url token
  521. if ((ET_ERROR != returnVal) &&
  522. (NULL != (pCurrentToken = ANSIStrStr(*ppStr, BEGIN_URL_TOKEN))))
  523. {
  524. // Bookmark token found
  525. // Verify that other needed tokens exist or it's an error
  526. #ifndef UNIX
  527. if ((NULL == (pszTemp = ANSIStrStr(pCurrentToken, END_URL_TOKEN))) ||
  528. #else
  529. if (((NULL == (pszTemp = ANSIStrStr(pCurrentToken, END_URL_TOKEN))) &&
  530. (NULL == (pszTemp = ANSIStrStr(pCurrentToken, END_URL_TOKEN2)))) ||
  531. #endif
  532. (NULL == (pszTemp = ANSIStrStr(pszTemp, BEGIN_BOOKMARK_TOKEN))) ||
  533. (NULL == ANSIStrStr(pszTemp, END_BOOKMARK_TOKEN)))
  534. {
  535. returnVal = ET_ERROR; // We can't find all the tokens needed.
  536. }
  537. else
  538. {
  539. // See if this token comes before TheToken.
  540. if ((NULL == pTheToken) || (pCurrentToken < pTheToken))
  541. {
  542. // This function has to set *ppToken to the name of the bookmark
  543. *ppToken = pCurrentToken + sizeof(BEGIN_URL_TOKEN)-1;
  544. pTheToken = pCurrentToken;
  545. returnVal = ET_BOOKMARK;
  546. }
  547. }
  548. }
  549. }
  550. else
  551. returnVal = ET_ERROR; // We should never get here.
  552. if (NULL == pTheToken)
  553. returnVal = ET_NONE;
  554. else
  555. {
  556. // Next time we will start parsing where we left off.
  557. switch(returnVal)
  558. {
  559. case ET_OPEN_DIR:
  560. #ifndef UNIX
  561. *ppStr = ANSIStrStr(pTheToken, MID_DIR_TOKEN) + sizeof(MID_DIR_TOKEN);
  562. #else
  563. *ppStr = ANSIStrStr(pTheToken, szMidDirToken) + lstrlenA(szMidDirToken) + 1;
  564. #endif
  565. break;
  566. case ET_CLOSE_DIR:
  567. *ppStr = pTheToken + sizeof(BEGIN_EXITDIR_TOKEN);
  568. break;
  569. case ET_BOOKMARK:
  570. *ppStr = ANSIStrStr(pTheToken, END_BOOKMARK_TOKEN) + sizeof(END_BOOKMARK_TOKEN);
  571. break;
  572. default:
  573. break;
  574. }
  575. }
  576. return(returnVal);
  577. }
  578. /************************************************************\
  579. FUNCTION: GetPathFromRegistry
  580. PARAMETERS:
  581. LPSTR szPath - The value found in the registry. (Result of function)
  582. UINT cbPath - Size of szPath.
  583. HKEY theHKEY - The HKEY to look into (HKEY_CURRENT_USER)
  584. LPSTR szKey - Path in Registry (Software\...\Explore\Shell Folders)
  585. LPSTR szVName - Value to query (Favorites)
  586. BOOL return - TRUE if succeeded, FALSE if Error.
  587. EXAMPLE:
  588. HKEY_CURRENT_USER\Software\Microsoft\CurrentVersion\Explore\Shell Folders
  589. Favorites = "C:\WINDOWS\Favorites"
  590. DESCRIPTION:
  591. This function will look in the registry for the value
  592. to look up. The caller specifies the HKEY, subkey (szKey),
  593. value to query (szVName). The caller also sets a side memory
  594. for the result and passes a pointer to that memory in szPath
  595. with it's size in cbPath. The BOOL return value will indicate
  596. success or failure of this function.
  597. \************************************************************/
  598. BOOL GetPathFromRegistry(LPTSTR szPath, UINT cbPath, HKEY theHKEY,
  599. LPTSTR szKey, LPTSTR szVName)
  600. {
  601. DWORD dwType;
  602. DWORD dwSize;
  603. /*
  604. * Get Path to program
  605. * from the registry
  606. */
  607. dwSize = cbPath;
  608. return (ERROR_SUCCESS == SHGetValue(theHKEY, szKey, szVName, &dwType, (LPBYTE) szPath, &dwSize)
  609. && (dwType == REG_EXPAND_SZ || dwType == REG_SZ));
  610. }
  611. /************************************************************\
  612. FUNCTION: RemoveInvalidFileNameChars
  613. PARAMETERS:
  614. char * pBuf - The data to search.
  615. DESCRIPTION:
  616. This function will search pBuf until it encounters
  617. a character that is not allowed in a file name. It will
  618. then replace that character with a SPACE and continue looking
  619. for more invalid chars until they have all been removed.
  620. \************************************************************/
  621. void RemoveInvalidFileNameChars(char * pBuf)
  622. {
  623. //ASSERTSZ(NULL != pBuf, "Invalid function parameter");
  624. // Go through the array of chars, replacing offending characters with a space
  625. if (NULL != pBuf)
  626. {
  627. if (REASONABLE_NAME_LEN < strlen(pBuf))
  628. pBuf[REASONABLE_NAME_LEN] = '\0'; // String too long. Terminate it.
  629. while ('\0' != *pBuf)
  630. {
  631. // Check if the character is invalid
  632. if (!IsDBCSLeadByte(*pBuf))
  633. {
  634. if (ANSIStrChr(szInvalidFolderCharacters, *pBuf) != NULL)
  635. *pBuf = '_';
  636. }
  637. #if 0
  638. // Old code
  639. // We look in the array to see if the character is supported by FAT.
  640. // The array only includes the first 128 values, so we need to fail
  641. // on the other 128 values that have the high bit set.
  642. if (((AnsiMaxChar <= *pBuf) && (FALSE == IsDBCSLeadByte(*pBuf))) ||
  643. (0 == LocalLegalAnsiCharacterArray[*pBuf]))
  644. *pBuf = '$';
  645. #endif
  646. pBuf = CharNextA(pBuf);
  647. }
  648. }
  649. }
  650. /************************************************************\
  651. FUNCTION: CreateBookmark
  652. PARAMETERS:
  653. char * pBookmarkName- This is a pointer that contains
  654. the name of the bookmark to create.
  655. Note that it is not NULL terminated.
  656. BOOL return - Return TRUE if successful.
  657. DESCRIPTION:
  658. This function will take the data that is passed to
  659. it and extract the name of the bookmark and it's value to create.
  660. If the name is too long, it will be truncated. Then,
  661. the directory will be created. Any errors encountered
  662. will cause the function to return FALSE to indicate
  663. failure.
  664. \************************************************************/
  665. BOOL CreateBookmark(char *pBookmarkName)
  666. {
  667. BOOL fSuccess = FALSE;
  668. char szNameOfBM[REASONABLE_NAME_LEN];
  669. char szURL[MAX_URL];
  670. char * pstrEndOfStr = NULL;
  671. char * pstrBeginOfName = NULL;
  672. long lStrLen = 0;
  673. HANDLE hFile = NULL;
  674. DWORD dwSize;
  675. char szBuf[MAX_URL];
  676. //ASSERTSZ(NULL != pBookmarkName, "Bad input parameter");
  677. if (NULL != pBookmarkName)
  678. {
  679. pstrEndOfStr = ANSIStrStr(pBookmarkName, END_URL_TOKEN);
  680. #ifdef UNIX
  681. if (!pstrEndOfStr)
  682. pstrEndOfStr = ANSIStrStr(pBookmarkName, END_URL_TOKEN2);
  683. #endif
  684. if (NULL != pstrEndOfStr)
  685. {
  686. lStrLen = (int) (pstrEndOfStr-pBookmarkName);
  687. if (MAX_URL < lStrLen)
  688. lStrLen = MAX_URL-1;
  689. // Create the name of the Bookmark
  690. StrCpyNA(szURL, pBookmarkName, ARRAYSIZE(szURL));
  691. szURL[lStrLen] = '\0';
  692. // filter out file links, we won't create a bookmark to a file link
  693. // but remove the link silently and continue
  694. if (IsFileUrl(szURL))
  695. return TRUE;
  696. pstrBeginOfName = ANSIStrStr(pstrEndOfStr, BEGIN_BOOKMARK_TOKEN);
  697. if (NULL != pstrBeginOfName)
  698. {
  699. pstrBeginOfName += sizeof(BEGIN_BOOKMARK_TOKEN) - 1; // Start at beginning of Name
  700. pstrEndOfStr = ANSIStrStr(pstrBeginOfName, END_BOOKMARK_TOKEN); // Find end of name
  701. if (NULL != pstrEndOfStr)
  702. {
  703. lStrLen = (int) (pstrEndOfStr-pstrBeginOfName);
  704. if (REASONABLE_NAME_LEN-FILE_EXT < lStrLen)
  705. lStrLen = REASONABLE_NAME_LEN-FILE_EXT-1;
  706. // Generate the URL
  707. StrCpyNA(szNameOfBM, pstrBeginOfName, lStrLen+1);
  708. //szNameOfBM[lStrLen] = '\0';
  709. StrCatBuffA(szNameOfBM, ".url", ARRAYSIZE(szNameOfBM));
  710. RemoveInvalidFileNameChars(szNameOfBM);
  711. // Check to see if Favorite w/same name exists
  712. if (INVALID_HANDLE_VALUE != (hFile = CreateFileA(szNameOfBM, GENERIC_WRITE, FILE_SHARE_READ, NULL,
  713. CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL )))
  714. {
  715. WriteFile(hFile, "[InternetShortcut]\n", lstrlenA( "[InternetShortcut]\n" ), &dwSize, NULL);
  716. wnsprintfA( szBuf, ARRAYSIZE(szBuf), "URL=%s\n", szURL);
  717. WriteFile(hFile, szBuf, lstrlenA(szBuf), &dwSize, NULL );
  718. fSuccess = TRUE;
  719. }
  720. else
  721. {
  722. fSuccess = TRUE;
  723. }
  724. if (NULL != hFile)
  725. {
  726. CloseHandle( hFile );
  727. hFile = NULL;
  728. }
  729. }
  730. }
  731. }
  732. }
  733. return(fSuccess);
  734. }
  735. /************************************************************\
  736. FUNCTION: CreateDir
  737. PARAMETERS:
  738. char * pDirName - This is a pointer that contains
  739. the name of the directory to create.
  740. Note that it is not NULL terminated.
  741. BOOL return - Return TRUE if successful.
  742. DESCRIPTION:
  743. This function will take the data that is passed to
  744. it and extract the name of the directory to create.
  745. If the name is too long, it will be truncated. Then,
  746. the directory will be created. Any errors encountered
  747. will cause the function to return FALSE to indicate
  748. failure.
  749. \************************************************************/
  750. BOOL CreateDir(char *pDirName)
  751. {
  752. BOOL fSuccess = FALSE;
  753. char szNameOfDir[REASONABLE_NAME_LEN];
  754. char * pstrEndOfName = NULL;
  755. long lStrLen = 0;
  756. //ASSERTSZ(NULL != pDirName, "Bad input parameter");
  757. if (NULL != pDirName)
  758. {
  759. pstrEndOfName = ANSIStrStr(pDirName, END_DIR_TOKEN);
  760. if (NULL != pstrEndOfName)
  761. {
  762. lStrLen = (int) (pstrEndOfName-pDirName);
  763. if (REASONABLE_NAME_LEN < lStrLen)
  764. lStrLen = REASONABLE_NAME_LEN-1;
  765. StrCpyNA(szNameOfDir, pDirName, lStrLen+1);
  766. //szNameOfDir[lStrLen] = '\0';
  767. RemoveInvalidFileNameChars(szNameOfDir);
  768. if ( !SetCurrentDirectoryA(szNameOfDir) )
  769. {
  770. if ( CreateDirectoryA(szNameOfDir, NULL) )
  771. {
  772. if ( SetCurrentDirectoryA(szNameOfDir) )
  773. {
  774. fSuccess = TRUE;// It didn't exist, but now it does.
  775. }
  776. }
  777. }
  778. else
  779. fSuccess = TRUE; // It exists already.
  780. }
  781. }
  782. return(fSuccess);
  783. }
  784. /************************************************************\
  785. FUNCTION: CloseDir
  786. PARAMETERS:
  787. BOOL return - Return TRUE if successful.
  788. DESCRIPTION:
  789. This function will back out of the current directory.
  790. \************************************************************/
  791. BOOL CloseDir(void)
  792. {
  793. return( SetCurrentDirectoryA("..") );
  794. }
  795. /************************************************************\
  796. FUNCTION: VerifyBookmarksFile
  797. PARAMETERS:
  798. FILE * pFile - Pointer to Netscape Bookmarks file.
  799. BOOL return - TRUE if No Error and Valid Bookmark file
  800. DESCRIPTION:
  801. This function needs to be passed with a valid pointer
  802. that points to an open file. Upon return, the file will
  803. still be open and is guarenteed to have the file pointer
  804. point to the beginning of the file.
  805. This function will return TRUE if the file contains
  806. text that indicates it's a valid Netscape bookmarks file.
  807. \************************************************************/
  808. BOOL VerifyBookmarksFile(HANDLE hFile)
  809. {
  810. BOOL fSuccess = FALSE;
  811. char szFileHeader[sizeof(VALIDATION_STR)+1] = "";
  812. DWORD dwSize;
  813. //ASSERTSZ(NULL != pFile, "You can't pass me a NULL File Pointer");
  814. if (INVALID_HANDLE_VALUE == hFile)
  815. return(FALSE);
  816. // Reading the first part of the file. If the file isn't this long, then
  817. // it can't possibly be a Bookmarks file.
  818. if ( ReadFile( hFile, szFileHeader, sizeof(VALIDATION_STR)-1, &dwSize, NULL ) && (dwSize == sizeof(VALIDATION_STR)-1) )
  819. {
  820. #ifndef UNIX
  821. szFileHeader[sizeof(VALIDATION_STR)] = '\0'; // Terminate String.
  822. #else
  823. // The above statement doesn;t serve the purpose on UNIX.
  824. // I think we should change for NT also.
  825. // IEUNIX : NULL character after the buffer read
  826. szFileHeader[sizeof(VALIDATION_STR)-1] = '\0'; // Terminate String.
  827. #endif
  828. if (0 == StrCmpA(szFileHeader, VALIDATION_STR)) // See if header is the same as the Validation string.
  829. fSuccess = TRUE;
  830. }
  831. // Reset the point to point to the beginning of the file.
  832. dwSize = SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
  833. if ( dwSize == 0xFFFFFFFF )
  834. fSuccess = FALSE;
  835. return(fSuccess);
  836. }
  837. /************************************************************\
  838. FUNCTION: GetData
  839. PARAMETERS:
  840. char ** ppData - Where to put the data
  841. FILE * pFile - Pointer to Netscape Bookmarks file.
  842. BOOL return - Return TRUE is successful.
  843. DESCRIPTION:
  844. This function will find the size of the bookmarks file,
  845. malloc that much memory, and put the file's contents in
  846. that buffer. ppData will be invalid when the function
  847. is called and will return with malloced memory that
  848. needs to be freed by the falling function.
  849. \************************************************************/
  850. BOOL GetData(char ** ppData, HANDLE hFile)
  851. {
  852. DWORD dwlength, dwRead;
  853. BOOL fSuccess = FALSE;
  854. //ASSERTSZ(NULL != ppData, "Invalid input parameter");
  855. if (NULL != ppData)
  856. {
  857. *ppData = NULL;
  858. // Find the size of the data
  859. if ( dwlength = GetFileSize(hFile, NULL))
  860. {
  861. *ppData = (PSTR)LocalAlloc(LPTR, dwlength+1 );
  862. if (NULL != *ppData)
  863. {
  864. if ( ReadFile( hFile, *ppData, dwlength+1, &dwRead, NULL ) &&
  865. ( dwlength == dwRead ) )
  866. {
  867. fSuccess = TRUE;
  868. }
  869. (*ppData)[dwlength] = '\0';
  870. }
  871. }
  872. }
  873. return(fSuccess);
  874. }
  875. //
  876. // AddPath - added by julianj when porting from setup code to stand alone
  877. //
  878. void PASCAL AddPath(LPTSTR pszPath, LPCTSTR pszName, int cchPath )
  879. {
  880. LPTSTR pszTmp;
  881. int cchTmp;
  882. // Find end of the string
  883. cchTmp = lstrlen(pszPath);
  884. pszTmp = pszPath + cchTmp;
  885. cchTmp = cchPath - cchTmp;
  886. // If no trailing backslash then add one
  887. if ( pszTmp > pszPath && *(CharPrev( pszPath, pszTmp )) != FILENAME_SEPARATOR )
  888. {
  889. *(pszTmp++) = FILENAME_SEPARATOR;
  890. cchTmp--;
  891. }
  892. // Add new name to existing path string
  893. while ( *pszName == TEXT(' ') ) pszName++;
  894. StrCpyN( pszTmp, pszName, cchTmp );
  895. }
  896. //
  897. // GetVersionFromFile - added by julianj when porting from setup code to stand alone
  898. //
  899. BOOL GetVersionFromFile(PTSTR pszFileName, PDWORD pdwMSVer, PDWORD pdwLSVer)
  900. {
  901. DWORD dwVerInfoSize, dwHandle;
  902. LPVOID lpVerInfo;
  903. VS_FIXEDFILEINFO *pvsVSFixedFileInfo;
  904. UINT uSize;
  905. HRESULT hr = E_FAIL;
  906. *pdwMSVer = *pdwLSVer = 0;
  907. if ((dwVerInfoSize = GetFileVersionInfoSize(pszFileName, &dwHandle)))
  908. {
  909. if ((lpVerInfo = (LPVOID) LocalAlloc(LPTR, dwVerInfoSize)) != NULL)
  910. {
  911. if (GetFileVersionInfo(pszFileName, dwHandle, dwVerInfoSize, lpVerInfo))
  912. {
  913. if (VerQueryValue(lpVerInfo, TEXT("\\"), (LPVOID *) &pvsVSFixedFileInfo, &uSize))
  914. {
  915. *pdwMSVer = pvsVSFixedFileInfo->dwFileVersionMS;
  916. *pdwLSVer = pvsVSFixedFileInfo->dwFileVersionLS;
  917. hr = S_OK;
  918. }
  919. }
  920. LocalFree(lpVerInfo);
  921. lpVerInfo = NULL;
  922. }
  923. else
  924. {
  925. hr = E_OUTOFMEMORY;
  926. }
  927. }
  928. return hr;
  929. }
  930. BOOL GetNavBkMkDir( LPTSTR lpszDir, int isize)
  931. {
  932. BOOL bDirFound = FALSE;
  933. #ifndef UNIX
  934. TCHAR szDir[MAX_PATH];
  935. HKEY hKey;
  936. HKEY hKeyUser;
  937. TCHAR szUser[MAX_PATH];
  938. DWORD dwSize;
  939. StrCpyN( szUser, REGSTR_PATH_APPPATHS, ARRAYSIZE(szUser) );
  940. AddPath( szUser, TEXT("NetScape.exe"), ARRAYSIZE(szUser) );
  941. if ( GetPathFromRegistry( szDir, MAX_PATH, HKEY_LOCAL_MACHINE, szUser, TEXT("") ) &&
  942. lstrlen(szDir) )
  943. {
  944. DWORD dwMV, dwLV;
  945. if ( SUCCEEDED(GetVersionFromFile( szDir, &dwMV, &dwLV )) )
  946. {
  947. if ( dwMV < 0x00040000 )
  948. bDirFound = GetPathFromRegistry( lpszDir, isize, HKEY_CURRENT_USER,
  949. szNetscapeBMRegSub, szNetscapeBMRegKey);
  950. else
  951. {
  952. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Netscape\\Netscape Navigator\\Users"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  953. {
  954. dwSize = sizeof(szUser);
  955. if (RegQueryValueEx(hKey, TEXT("CurrentUser"), NULL, NULL, (LPBYTE)szUser, &dwSize) == ERROR_SUCCESS)
  956. {
  957. if (RegOpenKeyEx(hKey, szUser, 0, KEY_READ, &hKeyUser) == ERROR_SUCCESS)
  958. {
  959. dwSize = sizeof(szDir);
  960. if (RegQueryValueEx(hKeyUser, TEXT("DirRoot"), NULL, NULL, (LPBYTE)szDir, &dwSize) == ERROR_SUCCESS)
  961. {
  962. // Found the directory for the current user.
  963. StrCpyN( lpszDir, szDir, isize);
  964. AddPath( lpszDir, TEXT("bookmark.htm"), isize );
  965. bDirFound = TRUE;
  966. }
  967. RegCloseKey(hKeyUser);
  968. }
  969. }
  970. RegCloseKey(hKey);
  971. }
  972. }
  973. }
  974. }
  975. else
  976. #endif
  977. bDirFound = GetPathFromRegistry( lpszDir, isize, HKEY_CURRENT_USER,
  978. szNetscapeBMRegSub, szNetscapeBMRegKey);
  979. return bDirFound;
  980. }
  981. //
  982. // *** EXPORT FAVORITES CODE ***
  983. //
  984. // REVIEW REMOVE THESE
  985. #include <windows.h>
  986. //#include <stdio.h>
  987. #include <shlobj.h>
  988. #include <shlwapi.h>
  989. //
  990. // Generate HTML from favorites
  991. //
  992. #define INDENT_AMOUNT 4
  993. int Indent = 0;
  994. HANDLE g_hOutputStream = INVALID_HANDLE_VALUE;
  995. void Output(const char *format, ...)
  996. {
  997. DWORD dwSize;
  998. char buf[MAX_URL];
  999. va_list argptr;
  1000. va_start(argptr, format);
  1001. for (int i=0; i<Indent*INDENT_AMOUNT; i++)
  1002. {
  1003. WriteFile(g_hOutputStream, " ", 1, &dwSize, NULL);
  1004. }
  1005. wvnsprintfA(buf, ARRAYSIZE(buf), format, argptr);
  1006. WriteFile(g_hOutputStream, buf, lstrlenA(buf), &dwSize, NULL);
  1007. }
  1008. void OutputLn(const char *format, ...)
  1009. {
  1010. DWORD dwSize;
  1011. char buf[MAX_URL];
  1012. va_list argptr;
  1013. va_start(argptr, format);
  1014. for (int i=0; i<Indent*INDENT_AMOUNT; i++)
  1015. {
  1016. WriteFile(g_hOutputStream, " ", 1, &dwSize, NULL);
  1017. }
  1018. wvnsprintfA(buf, ARRAYSIZE(buf), format, argptr);
  1019. WriteFile(g_hOutputStream, buf, lstrlenA(buf), &dwSize, NULL);
  1020. WriteFile(g_hOutputStream, "\r\n", 2, &dwSize, NULL);
  1021. }
  1022. #define CREATION_TIME 0
  1023. #define ACCESS_TIME 1
  1024. #define MODIFY_TIME 2
  1025. //
  1026. // This nasty looking macro converts a FILETIME structure
  1027. // (100-nanosecond intervals since Jan 1st 1601) to a
  1028. // unix time_t value (seconds since Jan 1st 1970).
  1029. //
  1030. // The numbers come from knowledgebase article Q167296
  1031. //
  1032. #define FILETIME_TO_UNIXTIME(ft) (UINT)((*(LONGLONG*)&ft-116444736000000000)/10000000)
  1033. UINT GetUnixFileTime(LPTSTR pszFileName, int mode)
  1034. {
  1035. WIN32_FIND_DATA wfd;
  1036. HANDLE hFind;
  1037. hFind = FindFirstFile(pszFileName,&wfd);
  1038. if (hFind == INVALID_HANDLE_VALUE)
  1039. return 0;
  1040. FindClose(hFind);
  1041. switch (mode)
  1042. {
  1043. case CREATION_TIME:
  1044. return FILETIME_TO_UNIXTIME(wfd.ftCreationTime);
  1045. case ACCESS_TIME:
  1046. return FILETIME_TO_UNIXTIME(wfd.ftLastAccessTime);
  1047. case MODIFY_TIME:
  1048. return FILETIME_TO_UNIXTIME(wfd.ftLastWriteTime);
  1049. default:
  1050. ASSERT(0);
  1051. return 0;
  1052. }
  1053. }
  1054. void WalkTree(TCHAR * szDir)
  1055. {
  1056. WIN32_FIND_DATA findFileData;
  1057. TCHAR buf[MAX_PATH];
  1058. HANDLE hFind;
  1059. Indent++;
  1060. //
  1061. // First iterate through all directories
  1062. //
  1063. wnsprintf(buf, ARRAYSIZE(buf), TEXT("%s") TEXT(FILENAME_SEPARATOR_STR) TEXT("*"), szDir);
  1064. hFind = FindFirstFile(buf, &findFileData);
  1065. if (INVALID_HANDLE_VALUE != hFind)
  1066. {
  1067. do
  1068. {
  1069. if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  1070. {
  1071. if ((StrCmp(findFileData.cFileName, TEXT(".")) != 0 &&
  1072. StrCmp(findFileData.cFileName, TEXT("..")) != 0 &&
  1073. StrCmp(findFileData.cFileName, TEXT("History")) != 0 && // REVIEW just for JJ. Should check for system bit on folders
  1074. StrCmp(findFileData.cFileName, TEXT("Software Updates")) != 0 && // don't export software updates
  1075. StrCmp(findFileData.cFileName, TEXT("Channels")) != 0)) // don't export channels for now!
  1076. {
  1077. char thisFile[MAX_PATH];
  1078. wnsprintf(buf, ARRAYSIZE(buf), TEXT("%s") TEXT(FILENAME_SEPARATOR_STR) TEXT("%s"), szDir, findFileData.cFileName);
  1079. if (!(GetFileAttributes(buf)&FILE_ATTRIBUTE_SYSTEM))
  1080. {
  1081. SHTCharToAnsi(findFileData.cFileName, thisFile, MAX_PATH);
  1082. OutputLn("<DT><H3 FOLDED ADD_DATE=\"%u\">%s</H3>", GetUnixFileTime(buf,CREATION_TIME), thisFile);
  1083. OutputLn("<DL><p>");
  1084. WalkTree(buf);
  1085. OutputLn(BEGIN_EXITDIR_TOKEN);
  1086. }
  1087. }
  1088. else
  1089. {
  1090. ; // ignore . and ..
  1091. }
  1092. }
  1093. } while (FindNextFile(hFind, &findFileData));
  1094. FindClose(hFind);
  1095. }
  1096. //
  1097. // Next iterate through all files
  1098. //
  1099. wnsprintf(buf, ARRAYSIZE(buf), TEXT("%s") TEXT(FILENAME_SEPARATOR_STR) TEXT("*"), szDir);
  1100. hFind = FindFirstFile(buf, &findFileData);
  1101. if (INVALID_HANDLE_VALUE != hFind)
  1102. {
  1103. do
  1104. {
  1105. if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1106. {
  1107. wnsprintf(buf, ARRAYSIZE(buf), TEXT("%s") TEXT(FILENAME_SEPARATOR_STR) TEXT("%s"), szDir, findFileData.cFileName);
  1108. //
  1109. // Read the url from the .url file
  1110. //
  1111. TCHAR szUrl[MAX_PATH];
  1112. SHGetIniString(
  1113. TEXT("InternetShortcut"),
  1114. TEXT("URL"),
  1115. szUrl, // returns url
  1116. MAX_PATH,
  1117. buf); // full path to .url file
  1118. if (*szUrl != 0)
  1119. {
  1120. //
  1121. // create a copy of the filename without the extension
  1122. // note PathFindExtension returns a ptr to the NULL at
  1123. // end if '.' not found so its ok to just blast *pch with 0
  1124. //
  1125. TCHAR szFileName[MAX_PATH];
  1126. StrCpyN(szFileName, findFileData.cFileName, ARRAYSIZE(szFileName));
  1127. TCHAR *pch = PathFindExtension(szFileName);
  1128. *pch = TEXT('\0'); //
  1129. char szUrlAnsi[MAX_PATH], szFileNameAnsi[MAX_PATH];
  1130. SHTCharToAnsi(szUrl, szUrlAnsi, MAX_PATH);
  1131. SHTCharToAnsi(szFileName, szFileNameAnsi, MAX_PATH);
  1132. OutputLn("<DT><A HREF=\"%s\" ADD_DATE=\"%u\" LAST_VISIT=\"%u\" LAST_MODIFIED=\"%u\">%s</A>",
  1133. szUrlAnsi,
  1134. GetUnixFileTime(buf,CREATION_TIME),
  1135. GetUnixFileTime(buf,ACCESS_TIME),
  1136. GetUnixFileTime(buf,MODIFY_TIME),
  1137. szFileNameAnsi);
  1138. }
  1139. }
  1140. } while (FindNextFile(hFind, &findFileData));
  1141. FindClose(hFind);
  1142. }
  1143. Indent--;
  1144. }
  1145. BOOL ExportFavorites(TCHAR * pszPathToFavorites, TCHAR * pszPathToBookmarks, HWND hwnd)
  1146. {
  1147. // Prompt the user to insert floppy, format floppy or drive, remount mapped partition,
  1148. // or any create sub directories so pszPathToBookmarks becomes valid.
  1149. if (FAILED(SHPathPrepareForWriteWrap(hwnd, NULL, pszPathToBookmarks, FO_COPY, (SHPPFW_DEFAULT | SHPPFW_IGNOREFILENAME))))
  1150. return FALSE;
  1151. // Open output file REVIEW redo to use Win32 file apis
  1152. g_hOutputStream = CreateFile(
  1153. pszPathToBookmarks,
  1154. GENERIC_WRITE,
  1155. 0, // no sharing,
  1156. NULL, // no security attribs
  1157. CREATE_ALWAYS, // overwrite if present
  1158. FILE_ATTRIBUTE_NORMAL,
  1159. NULL);
  1160. if (g_hOutputStream == INVALID_HANDLE_VALUE)
  1161. return FALSE;
  1162. //
  1163. // Output bookmark file header stuff
  1164. //
  1165. Output(VALIDATION_STR);
  1166. OutputLn("1>");
  1167. OutputLn(COMMENT_STR);
  1168. OutputLn(TITLE); // REVIEW put/persist users name in Title???
  1169. //
  1170. // Do the walk
  1171. //
  1172. OutputLn("<DL><p>");
  1173. WalkTree(pszPathToFavorites);
  1174. OutputLn(BEGIN_EXITDIR_TOKEN);
  1175. //
  1176. // Close output file handle
  1177. //
  1178. CloseHandle(g_hOutputStream); // REVIEW
  1179. return TRUE;
  1180. }
  1181. //
  1182. // Import/Export User interface dialog routines
  1183. //
  1184. //
  1185. // Standalone app for importing the Netscape Favorites into IE.
  1186. //
  1187. // julianj 3/9/98
  1188. //
  1189. #ifdef _WIN32_WINNT
  1190. #undef _WIN32_WINNT
  1191. #endif
  1192. #ifdef _WIN32_WINDOWS
  1193. #undef _WIN32_WINDOWS
  1194. #endif
  1195. #ifdef WINVER
  1196. #undef WINVER
  1197. #endif
  1198. #define _WIN32_WINDOWS 0x0400
  1199. #define _WIN32_WINNT 0x0400
  1200. #define WINVER 0x0400
  1201. TCHAR g_szPathToFavorites[MAX_PATH+1];
  1202. TCHAR g_szPathToBookmarks[MAX_PATH+1];
  1203. LPITEMIDLIST g_pidlFavorites = NULL;
  1204. enum DIALOG_TYPE {FILE_OPEN_DIALOG, FILE_SAVE_DIALOG};
  1205. BOOL BrowseForBookmarks(TCHAR *pszPathToBookmarks, int cchPathToBookmarks, HWND hwnd, DIALOG_TYPE dialogType)
  1206. {
  1207. TCHAR szFile[MAX_PATH];
  1208. TCHAR szDir[MAX_PATH];
  1209. TCHAR *pszFileName = PathFindFileName(pszPathToBookmarks);
  1210. TCHAR szDialogTitle[MAX_PATH];
  1211. //
  1212. // Now copy the filename into the buffer for use with OpenFile
  1213. // and then copy szDir from path to bookmarks and truncate it at filename
  1214. // so it contains the initial working directory for the dialog
  1215. //
  1216. StrCpyN(szFile, pszFileName, ARRAYSIZE(szFile));
  1217. StrCpyN(szDir, pszPathToBookmarks, ARRAYSIZE(szDir));
  1218. szDir[pszFileName-pszPathToBookmarks] = TEXT('\0');
  1219. //
  1220. // Use common dialog code to get path to folder
  1221. //
  1222. TCHAR filter[] = TEXT("HTML File\0*.HTM\0All Files\0*.*\0");
  1223. OPENFILENAME ofn = {0};
  1224. ofn.lStructSize = sizeof(ofn);
  1225. ofn.hwndOwner = hwnd;
  1226. ofn.hInstance = HINST_THISDLL;
  1227. ofn.lpstrFilter = filter;
  1228. ofn.lpstrFile = szFile;
  1229. ofn.nMaxFile = MAX_PATH;
  1230. ofn.lpstrInitialDir = szDir;
  1231. ofn.lpstrDefExt = TEXT("htm");
  1232. if (dialogType == FILE_SAVE_DIALOG)
  1233. {
  1234. MLLoadString(IDS_EXPORTDIALOGTITLE, szDialogTitle, ARRAYSIZE(szDialogTitle));
  1235. ofn.lpstrTitle = szDialogTitle;
  1236. ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
  1237. if (GetSaveFileName(&ofn))
  1238. {
  1239. StrCpyN(pszPathToBookmarks, szFile, cchPathToBookmarks);
  1240. return TRUE;
  1241. }
  1242. }
  1243. else
  1244. {
  1245. MLLoadString(IDS_IMPORTDIALOGTITLE, szDialogTitle, ARRAYSIZE(szDialogTitle));
  1246. ofn.lpstrTitle = szDialogTitle;
  1247. ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
  1248. if (GetOpenFileName(&ofn))
  1249. {
  1250. StrCpyN(pszPathToBookmarks, szFile, cchPathToBookmarks);
  1251. return TRUE;
  1252. }
  1253. }
  1254. return FALSE;
  1255. }
  1256. HRESULT CreateILFromPath(LPCTSTR pszPath, LPITEMIDLIST* ppidl)
  1257. {
  1258. // ASSERT(pszPath);
  1259. // ASSERT(ppidl);
  1260. HRESULT hr;
  1261. IShellFolder* pIShellFolder;
  1262. hr = SHGetDesktopFolder(&pIShellFolder);
  1263. if (SUCCEEDED(hr))
  1264. {
  1265. // ASSERT(pIShellFolder);
  1266. WCHAR wszPath[MAX_PATH];
  1267. if (SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath)))
  1268. {
  1269. ULONG ucch;
  1270. hr = pIShellFolder->ParseDisplayName(NULL, NULL, wszPath, &ucch,
  1271. ppidl, NULL);
  1272. }
  1273. else
  1274. {
  1275. hr = E_FAIL;
  1276. }
  1277. pIShellFolder->Release();
  1278. }
  1279. return hr;
  1280. }
  1281. int CALLBACK BrowseForFavoritesCallBack(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
  1282. {
  1283. switch (uMsg)
  1284. {
  1285. case BFFM_INITIALIZED:
  1286. SendMessage(hwnd, BFFM_SETSELECTIONA, (WPARAM)TRUE, lpData);
  1287. break;
  1288. default:
  1289. break;
  1290. }
  1291. return 0;
  1292. }
  1293. void BrowseForFavorites(char *pszPathToFavorites, HWND hwnd)
  1294. {
  1295. //
  1296. // Use SHBrowseForFolder to get path to folder
  1297. //
  1298. char szDisplayName[MAX_PATH];
  1299. char szTitle[MAX_PATH];
  1300. MLLoadStringA(IDS_IMPORTEXPORTTITLE, szTitle, ARRAYSIZE(szTitle));
  1301. BROWSEINFOA bi = {0};
  1302. bi.hwndOwner = hwnd;
  1303. bi.pidlRoot = g_pidlFavorites;
  1304. bi.pszDisplayName = szDisplayName;
  1305. bi.lpszTitle = szTitle;
  1306. // bi.ulFlags = BIF_EDITBOX; // do we want this?
  1307. bi.ulFlags = BIF_USENEWUI;
  1308. bi.lpfn = BrowseForFavoritesCallBack;
  1309. bi.lParam = (LPARAM)pszPathToFavorites;
  1310. LPITEMIDLIST pidl = SHBrowseForFolderA(&bi);
  1311. if (pidl)
  1312. {
  1313. SHGetPathFromIDListA(pidl, pszPathToFavorites);
  1314. ILFree(pidl);
  1315. };
  1316. }
  1317. #define REG_STR_IMPEXP TEXT("Software\\Microsoft\\Internet Explorer\\Main")
  1318. #define REG_STR_PATHTOFAVORITES TEXT("FavoritesImportFolder")
  1319. #define REG_STR_PATHTOBOOKMARKS TEXT("FavoritesExportFile")
  1320. #define REG_STR_DESKTOP TEXT("Desktop")
  1321. #define REG_STR_SHELLFOLDERS TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
  1322. #ifndef UNIX
  1323. #define STR_BOOKMARK_FILE TEXT("\\bookmark.htm")
  1324. #else
  1325. #define STR_BOOKMARK_FILE TEXT("/bookmark.html")
  1326. #endif
  1327. //
  1328. // InitializePaths
  1329. //
  1330. void InitializePaths()
  1331. {
  1332. //
  1333. // Read the Netscape users bookmark file location and the
  1334. // current users favorite path from registry
  1335. //
  1336. if (!GetNavBkMkDir(g_szPathToBookmarks, MAX_PATH))
  1337. {
  1338. //
  1339. // If Nav isn't installed then use the desktop
  1340. //
  1341. GetPathFromRegistry(g_szPathToBookmarks, MAX_PATH, HKEY_CURRENT_USER,
  1342. REG_STR_SHELLFOLDERS, REG_STR_DESKTOP);
  1343. StrCatBuff(g_szPathToBookmarks, STR_BOOKMARK_FILE, ARRAYSIZE(g_szPathToBookmarks));
  1344. }
  1345. GetTargetFavoritesPath(g_szPathToFavorites, MAX_PATH);
  1346. if (FAILED(CreateILFromPath(g_szPathToFavorites, &g_pidlFavorites)))
  1347. g_pidlFavorites = NULL;
  1348. //
  1349. // Now override these values with values stored in the registry just for
  1350. // this tool, so if the user consistently wants to save their favorites
  1351. // out to a separate .HTM file its easy to do
  1352. //
  1353. HKEY hKey;
  1354. DWORD dwSize;
  1355. DWORD dwType;
  1356. if (RegOpenKeyEx(HKEY_CURRENT_USER, REG_STR_IMPEXP, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  1357. {
  1358. dwSize = MAX_PATH;
  1359. dwType = REG_SZ;
  1360. RegQueryValueEx(hKey, REG_STR_PATHTOBOOKMARKS, 0, &dwType, (LPBYTE)g_szPathToBookmarks, &dwSize);
  1361. dwSize = MAX_PATH;
  1362. dwType = REG_SZ;
  1363. RegQueryValueEx(hKey, REG_STR_PATHTOFAVORITES, 0, &dwType, (LPBYTE)g_szPathToFavorites, &dwSize);
  1364. RegCloseKey(hKey);
  1365. }
  1366. }
  1367. void PersistPaths()
  1368. {
  1369. HKEY hKey;
  1370. DWORD dwDisp;
  1371. if (RegCreateKeyEx(HKEY_CURRENT_USER, REG_STR_IMPEXP, 0, NULL, 0, KEY_WRITE, NULL, &hKey, &dwDisp) == ERROR_SUCCESS)
  1372. {
  1373. RegSetValueEx(hKey, REG_STR_PATHTOBOOKMARKS, 0, REG_SZ, (LPBYTE)g_szPathToBookmarks, (lstrlen(g_szPathToBookmarks)+1)*sizeof(TCHAR));
  1374. RegSetValueEx(hKey, REG_STR_PATHTOFAVORITES, 0, REG_SZ, (LPBYTE)g_szPathToFavorites, (lstrlen(g_szPathToFavorites)+1)*sizeof(TCHAR));
  1375. RegCloseKey(hKey);
  1376. }
  1377. }
  1378. #define REG_STR_IE_POLICIES TEXT("Software\\Policies\\Microsoft\\Internet Explorer")
  1379. #define REG_STR_IMPEXP_POLICIES TEXT("DisableImportExportFavorites")
  1380. BOOL IsImportExportDisabled(void)
  1381. {
  1382. HKEY hKey;
  1383. DWORD dwSize = sizeof(DWORD);
  1384. DWORD dwType;
  1385. DWORD value = 0;
  1386. BOOL bret = FALSE;
  1387. if (RegOpenKeyEx(HKEY_CURRENT_USER, REG_STR_IE_POLICIES, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  1388. {
  1389. if (RegQueryValueEx(hKey, REG_STR_IMPEXP_POLICIES, 0, &dwType, (PBYTE)&value, &dwSize) == ERROR_SUCCESS &&
  1390. (dwType == REG_BINARY || dwType == REG_DWORD))
  1391. bret = (value) ? TRUE : FALSE;
  1392. RegCloseKey(hKey);
  1393. }
  1394. return bret;
  1395. }
  1396. void DoImportOrExport(BOOL fImport, LPCWSTR pwszPath, LPCWSTR pwszImpExpPath, BOOL fConfirm)
  1397. {
  1398. BOOL fRemote = FALSE;
  1399. HWND hwnd = NULL;
  1400. TCHAR szImpExpPath[INTERNET_MAX_URL_LENGTH];
  1401. //
  1402. // REVIEW should this be passed in...
  1403. //
  1404. hwnd = GetActiveWindow();
  1405. // Decide if import/export is allowed here
  1406. if (IsImportExportDisabled())
  1407. {
  1408. MLShellMessageBox(
  1409. hwnd,
  1410. (fImport) ? MAKEINTRESOURCE(IDS_IMPORT_DISABLED) :
  1411. MAKEINTRESOURCE(IDS_EXPORT_DISABLED),
  1412. (fImport) ? MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV) :
  1413. MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_FAV),
  1414. MB_OK);
  1415. return;
  1416. }
  1417. InitializePaths();
  1418. //
  1419. // Overwrite path to favorites with passed in one if present
  1420. //
  1421. if (pwszPath && *pwszPath != 0)
  1422. {
  1423. SHUnicodeToTChar(pwszPath, g_szPathToFavorites, ARRAYSIZE(g_szPathToFavorites));
  1424. }
  1425. //
  1426. // Decide if we export/import to/from an URL? or a file
  1427. // (we expect pwszImpExpPath an absolute path)
  1428. // if it's not a valid URL or filename, we give error message and bail out
  1429. //
  1430. if (pwszImpExpPath && *pwszImpExpPath != 0)
  1431. {
  1432. SHUnicodeToTChar(pwszImpExpPath, szImpExpPath, ARRAYSIZE(szImpExpPath));
  1433. if (PathIsURL(pwszImpExpPath))
  1434. {
  1435. TCHAR szDialogTitle[MAX_PATH];
  1436. TCHAR szfmt[MAX_PATH], szmsg[MAX_PATH+INTERNET_MAX_URL_LENGTH];
  1437. fRemote = TRUE;
  1438. if (fImport)
  1439. {
  1440. if (fConfirm)
  1441. {
  1442. //
  1443. // Show confirmation UI when importing over internet
  1444. //
  1445. MLLoadShellLangString(IDS_CONFIRM_IMPTTL_FAV, szDialogTitle, ARRAYSIZE(szDialogTitle));
  1446. MLLoadShellLangString(IDS_CONFIRM_IMPORT, szfmt, ARRAYSIZE(szfmt));
  1447. wnsprintf(szmsg, ARRAYSIZE(szmsg), szfmt, szImpExpPath);
  1448. if (MLShellMessageBox(hwnd, szmsg, szDialogTitle,
  1449. MB_YESNO | MB_ICONQUESTION) == IDNO)
  1450. return;
  1451. }
  1452. // download imported file to cache
  1453. if ( (IsGlobalOffline() && !InternetGoOnline(g_szPathToBookmarks,hwnd,0)) ||
  1454. FAILED(URLDownloadToCacheFile(NULL, szImpExpPath, g_szPathToBookmarks, MAX_PATH, 0, NULL)))
  1455. {
  1456. MLShellMessageBox(
  1457. hwnd,
  1458. MAKEINTRESOURCE(IDS_IMPORTFAILURE_FAV),
  1459. MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV),
  1460. MB_OK);
  1461. return;
  1462. }
  1463. }
  1464. else
  1465. {
  1466. if (fConfirm)
  1467. {
  1468. //
  1469. // Show confirmation UI when exporting over internet
  1470. //
  1471. MLLoadShellLangString(IDS_CONFIRM_EXPTTL_FAV, szDialogTitle, ARRAYSIZE(szDialogTitle));
  1472. MLLoadShellLangString(IDS_CONFIRM_EXPORT, szfmt, ARRAYSIZE(szfmt));
  1473. wnsprintf(szmsg, ARRAYSIZE(szmsg), szfmt, szImpExpPath);
  1474. if (MLShellMessageBox(hwnd, szmsg, szDialogTitle,
  1475. MB_YESNO | MB_ICONQUESTION) == IDNO)
  1476. return;
  1477. }
  1478. //
  1479. // Create bookmark file name from bookmark directory with favorite name so we can export
  1480. // favorites to local file before posting to URL
  1481. //
  1482. TCHAR *pszFav = PathFindFileName(g_szPathToFavorites);
  1483. TCHAR *pszBMD = PathFindFileName(g_szPathToBookmarks);
  1484. if (pszFav && pszBMD)
  1485. {
  1486. StrCpyN(pszBMD, pszFav, ARRAYSIZE(g_szPathToFavorites) - ((int)(pszFav - g_szPathToFavorites)));
  1487. StrCatBuff(pszBMD, TEXT(".htm"), ARRAYSIZE(g_szPathToBookmarks) - ((int)(pszFav - g_szPathToBookmarks)));
  1488. }
  1489. }
  1490. }
  1491. else
  1492. {
  1493. if (fConfirm)
  1494. {
  1495. TCHAR szDialogTitle[MAX_PATH];
  1496. TCHAR szfmt[MAX_PATH], szmsg[MAX_PATH+INTERNET_MAX_URL_LENGTH];
  1497. if (fImport)
  1498. {
  1499. //
  1500. // Show confirmation UI when importing
  1501. //
  1502. MLLoadShellLangString(IDS_CONFIRM_IMPTTL_FAV, szDialogTitle, ARRAYSIZE(szDialogTitle));
  1503. MLLoadShellLangString(IDS_CONFIRM_IMPORT, szfmt, ARRAYSIZE(szfmt));
  1504. wnsprintf(szmsg, ARRAYSIZE(szmsg), szfmt, szImpExpPath);
  1505. if (MLShellMessageBox(hwnd, szmsg, szDialogTitle,
  1506. MB_YESNO | MB_ICONQUESTION) == IDNO)
  1507. return;
  1508. }
  1509. else
  1510. {
  1511. //
  1512. // Show confirmation UI when exporting.
  1513. //
  1514. MLLoadShellLangString(IDS_CONFIRM_EXPTTL_FAV, szDialogTitle, ARRAYSIZE(szDialogTitle));
  1515. MLLoadShellLangString(IDS_CONFIRM_EXPORT, szfmt, ARRAYSIZE(szfmt));
  1516. wnsprintf(szmsg, ARRAYSIZE(szmsg), szfmt, szImpExpPath);
  1517. if (MLShellMessageBox(hwnd, szmsg, szDialogTitle,
  1518. MB_YESNO | MB_ICONQUESTION) == IDNO)
  1519. return;
  1520. }
  1521. }
  1522. if (PathFindFileName(szImpExpPath) != szImpExpPath)
  1523. {
  1524. //override path to bookmarks with passed in one
  1525. StrCpyN(g_szPathToBookmarks, szImpExpPath, ARRAYSIZE(g_szPathToBookmarks));
  1526. }
  1527. else
  1528. {
  1529. MLShellMessageBox(
  1530. hwnd,
  1531. MAKEINTRESOURCE(IDS_IMPORTFAILURE_FAV),
  1532. MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV),
  1533. MB_OK);
  1534. return;
  1535. }
  1536. }
  1537. }
  1538. else
  1539. {
  1540. if (fImport)
  1541. {
  1542. //
  1543. // Do Import Favorites UI
  1544. //
  1545. if (!BrowseForBookmarks(g_szPathToBookmarks, ARRAYSIZE(g_szPathToBookmarks), hwnd, FILE_OPEN_DIALOG))
  1546. return;
  1547. }
  1548. else
  1549. {
  1550. //
  1551. // Do Export Favorites UI
  1552. //
  1553. if (!BrowseForBookmarks(g_szPathToBookmarks, ARRAYSIZE(g_szPathToBookmarks), hwnd, FILE_SAVE_DIALOG))
  1554. return;
  1555. }
  1556. }
  1557. if (fImport)
  1558. {
  1559. if (ImportBookmarks(g_szPathToFavorites, g_szPathToBookmarks, hwnd))
  1560. {
  1561. MLShellMessageBox(
  1562. hwnd,
  1563. MAKEINTRESOURCE(IDS_IMPORTSUCCESS_FAV),
  1564. MAKEINTRESOURCE(IDS_CONFIRM_IMPTTL_FAV),
  1565. MB_OK);
  1566. #ifdef UNIX
  1567. SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSH, g_szPathToFavorites, 0);
  1568. #endif
  1569. if (!fRemote)
  1570. PersistPaths();
  1571. }
  1572. else
  1573. {
  1574. ; // ImportBookmarks will report errors
  1575. }
  1576. }
  1577. else
  1578. {
  1579. if (ExportFavorites(g_szPathToFavorites, g_szPathToBookmarks, hwnd))
  1580. {
  1581. if (fRemote)
  1582. {
  1583. if ( (!IsGlobalOffline() || InternetGoOnline(g_szPathToBookmarks,hwnd,0)) &&
  1584. PostFavorites(g_szPathToBookmarks, szImpExpPath))
  1585. {
  1586. MLShellMessageBox(
  1587. hwnd,
  1588. MAKEINTRESOURCE(IDS_EXPORTSUCCESS_FAV),
  1589. MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_FAV),
  1590. MB_OK);
  1591. }
  1592. else
  1593. MLShellMessageBox(
  1594. hwnd,
  1595. MAKEINTRESOURCE(IDS_EXPORTFAILURE_FAV),
  1596. MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_FAV),
  1597. MB_OK);
  1598. //Remove temp file on local disk
  1599. DeleteFile(g_szPathToBookmarks);
  1600. }
  1601. else
  1602. {
  1603. MLShellMessageBox(
  1604. hwnd,
  1605. MAKEINTRESOURCE(IDS_EXPORTSUCCESS_FAV),
  1606. MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_FAV),
  1607. MB_OK);
  1608. PersistPaths();
  1609. }
  1610. }
  1611. else
  1612. {
  1613. MLShellMessageBox(
  1614. hwnd,
  1615. MAKEINTRESOURCE(IDS_EXPORTFAILURE_FAV),
  1616. MAKEINTRESOURCE(IDS_CONFIRM_EXPTTL_FAV),
  1617. MB_OK);
  1618. }
  1619. }
  1620. }
  1621. //
  1622. // *** POST FAVORITES HTML FILE ***
  1623. //
  1624. HINTERNET g_hInternet = 0;
  1625. HINTERNET g_hConnect = 0;
  1626. HINTERNET g_hHttpRequest = 0;
  1627. HANDLE g_hEvent = NULL;
  1628. typedef struct AsyncRes
  1629. {
  1630. DWORD_PTR Result;
  1631. DWORD_PTR Error;
  1632. } ASYNCRES;
  1633. #define STR_USERAGENT "PostFavorites"
  1634. void CloseRequest(void)
  1635. {
  1636. if (g_hHttpRequest)
  1637. InternetCloseHandle(g_hHttpRequest);
  1638. if (g_hConnect)
  1639. InternetCloseHandle(g_hConnect);
  1640. if (g_hInternet)
  1641. InternetCloseHandle(g_hInternet);
  1642. g_hInternet = g_hConnect = g_hHttpRequest = 0;
  1643. }
  1644. HRESULT InitRequest(LPSTR pszPostURL, BOOL bAsync, ASYNCRES *pasyncres)
  1645. {
  1646. char hostName[INTERNET_MAX_HOST_NAME_LENGTH+1];
  1647. char userName[INTERNET_MAX_USER_NAME_LENGTH+1];
  1648. char password[INTERNET_MAX_PASSWORD_LENGTH+1];
  1649. char urlPath[INTERNET_MAX_PATH_LENGTH+1];
  1650. URL_COMPONENTSA uc;
  1651. memset(&uc, 0, sizeof(URL_COMPONENTS));
  1652. uc.dwStructSize = sizeof(URL_COMPONENTS);
  1653. uc.lpszHostName = hostName;
  1654. uc.dwHostNameLength = sizeof(hostName);
  1655. uc.nPort = INTERNET_INVALID_PORT_NUMBER;
  1656. uc.lpszUserName = userName;
  1657. uc.dwUserNameLength = sizeof(userName);
  1658. uc.lpszPassword = password;
  1659. uc.dwPasswordLength = sizeof(password);
  1660. uc.lpszUrlPath = urlPath;
  1661. uc.dwUrlPathLength = sizeof(urlPath);
  1662. if (!InternetCrackUrlA(pszPostURL,lstrlenA(pszPostURL),ICU_DECODE, &uc))
  1663. {
  1664. return E_FAIL;
  1665. }
  1666. if (bAsync)
  1667. {
  1668. // Create an auto-reset event
  1669. g_hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  1670. if (g_hEvent == NULL)
  1671. bAsync = FALSE;
  1672. }
  1673. g_hInternet = InternetOpenA(STR_USERAGENT, // used in User-Agent: header
  1674. INTERNET_OPEN_TYPE_PRECONFIG, //INTERNET_OPEN_TYPE_DIRECT,
  1675. NULL,
  1676. NULL,
  1677. (bAsync) ? INTERNET_FLAG_ASYNC : 0
  1678. );
  1679. if ( !g_hInternet )
  1680. {
  1681. return E_FAIL;
  1682. }
  1683. if (bAsync)
  1684. {
  1685. if (INTERNET_INVALID_STATUS_CALLBACK == InternetSetStatusCallbackA(g_hInternet, StatusCallback))
  1686. return E_FAIL;
  1687. }
  1688. // Connect to host
  1689. g_hConnect = InternetConnectA(g_hInternet,
  1690. uc.lpszHostName,
  1691. uc.nPort, //INTERNET_INVALID_PORT_NUMBER,
  1692. uc.lpszUserName,
  1693. uc.lpszPassword,
  1694. INTERNET_SERVICE_HTTP,
  1695. 0, //INTERNET_FLAG_KEEP_CONNECTION,
  1696. (bAsync)? (DWORD_PTR) pasyncres : 0);
  1697. if ( !g_hConnect )
  1698. {
  1699. if (bAsync && GetLastError() == ERROR_IO_PENDING)
  1700. {
  1701. WaitForSingleObject(g_hEvent, INFINITE);
  1702. if (pasyncres->Result == 0)
  1703. return E_FAIL;
  1704. g_hConnect = (HINTERNET)pasyncres->Result;
  1705. }
  1706. else
  1707. return E_FAIL;
  1708. }
  1709. // Create request.
  1710. g_hHttpRequest = HttpOpenRequestA
  1711. (
  1712. g_hConnect,
  1713. "POST",
  1714. uc.lpszUrlPath,
  1715. HTTP_VERSIONA,
  1716. NULL, //lpszReferer
  1717. NULL, //lpszAcceptTypes
  1718. INTERNET_FLAG_RELOAD
  1719. | INTERNET_FLAG_KEEP_CONNECTION
  1720. | SECURITY_INTERNET_MASK, // ignore SSL warnings
  1721. (bAsync)? (DWORD_PTR) pasyncres : 0);
  1722. if ( !g_hHttpRequest )
  1723. {
  1724. if (bAsync && GetLastError() == ERROR_IO_PENDING)
  1725. {
  1726. WaitForSingleObject(g_hEvent, INFINITE);
  1727. if (pasyncres->Result == 0)
  1728. return E_FAIL;
  1729. g_hHttpRequest = (HINTERNET)pasyncres->Result;
  1730. }
  1731. else
  1732. return E_FAIL;
  1733. }
  1734. return S_OK;
  1735. }
  1736. const char c_szHeaders[] = "Content-Type: application/x-www-form-urlencoded\r\n";
  1737. #define c_ccHearders (ARRAYSIZE(c_szHeaders) - 1)
  1738. BOOL AddRequestHeaders
  1739. (
  1740. LPCSTR lpszHeaders,
  1741. DWORD dwHeadersLength,
  1742. DWORD dwAddFlag,
  1743. BOOL bAsync,
  1744. ASYNCRES *pasyncres
  1745. )
  1746. {
  1747. BOOL bRet = FALSE;
  1748. bRet = HttpAddRequestHeadersA(g_hHttpRequest,
  1749. lpszHeaders,
  1750. dwHeadersLength,
  1751. HTTP_ADDREQ_FLAG_ADD | dwAddFlag);
  1752. if (bAsync && !bRet && GetLastError() == ERROR_IO_PENDING)
  1753. {
  1754. WaitForSingleObject(g_hEvent, INFINITE);
  1755. bRet = (BOOL)pasyncres->Result;
  1756. }
  1757. return bRet;
  1758. }
  1759. HRESULT SendRequest
  1760. (
  1761. LPCSTR lpszHeaders,
  1762. DWORD dwHeadersLength,
  1763. LPCSTR lpszOption,
  1764. DWORD dwOptionLength,
  1765. BOOL bAsync,
  1766. ASYNCRES *pasyncres
  1767. )
  1768. {
  1769. BOOL bRet=FALSE;
  1770. bRet = AddRequestHeaders((LPCSTR)c_szHeaders, (DWORD)-1L, 0, bAsync, pasyncres);
  1771. if (lpszHeaders && *lpszHeaders) // don't bother if it's empty
  1772. {
  1773. bRet = AddRequestHeaders(
  1774. (LPCSTR)lpszHeaders,
  1775. dwHeadersLength,
  1776. HTTP_ADDREQ_FLAG_REPLACE,
  1777. bAsync,
  1778. pasyncres);
  1779. if ( !bRet )
  1780. {
  1781. return E_FAIL;
  1782. }
  1783. }
  1784. pasyncres->Result = 0;
  1785. bRet = HttpSendRequestA(g_hHttpRequest,
  1786. NULL, //HEADER_ENCTYPE,
  1787. 0, //sizeof(HEADER_ENCTYPE),
  1788. (LPVOID)lpszOption,
  1789. dwOptionLength);
  1790. if ( !bRet )
  1791. {
  1792. DWORD_PTR dwLastError = GetLastError();
  1793. if (bAsync && dwLastError == ERROR_IO_PENDING)
  1794. {
  1795. WaitForSingleObject(g_hEvent, INFINITE);
  1796. dwLastError = pasyncres->Error;
  1797. bRet = (BOOL)pasyncres->Result;
  1798. if (!bRet)
  1799. {
  1800. TraceMsg(DM_ERROR, "Async HttpSendRequest returned FALSE");
  1801. if (dwLastError != ERROR_SUCCESS)
  1802. {
  1803. TraceMsg(DM_ERROR, "Async HttpSendRequest failed: Error = %lx", dwLastError);
  1804. return E_FAIL;
  1805. }
  1806. }
  1807. }
  1808. else
  1809. {
  1810. TraceMsg(DM_ERROR, "HttpSendRequest failed: Error = %lx", dwLastError);
  1811. return E_FAIL;
  1812. }
  1813. }
  1814. //
  1815. //verify request response here
  1816. //
  1817. DWORD dwBuffLen;
  1818. TCHAR buff[10];
  1819. dwBuffLen = sizeof(buff);
  1820. bRet = HttpQueryInfo(g_hHttpRequest,
  1821. HTTP_QUERY_STATUS_CODE, //HTTP_QUERY_RAW_HEADERS,
  1822. buff,
  1823. &dwBuffLen,
  1824. NULL);
  1825. int iretcode = StrToInt(buff);
  1826. TraceMsg(DM_TRACE, "HttpQueryInfo returned %d", iretcode);
  1827. return (iretcode == HTTP_STATUS_OK) ?
  1828. S_OK : E_FAIL;
  1829. }
  1830. DWORD ReadFavoritesFile(LPCTSTR lpFile, LPSTR* lplpbuf)
  1831. {
  1832. HANDLE hFile = NULL;
  1833. DWORD cbFile = 0;
  1834. DWORD cbRead;
  1835. hFile = CreateFile(lpFile,
  1836. GENERIC_READ,
  1837. 0, //no sharing
  1838. NULL,
  1839. OPEN_EXISTING,
  1840. FILE_ATTRIBUTE_NORMAL,
  1841. NULL);
  1842. if (hFile == INVALID_HANDLE_VALUE)
  1843. return 0;
  1844. cbFile = GetFileSize(hFile, NULL);
  1845. if (cbFile == 0xFFFFFFFF)
  1846. {
  1847. CloseHandle(hFile);
  1848. return 0;
  1849. }
  1850. *lplpbuf = (LPSTR)GlobalAlloc(LPTR, (cbFile + 2) * sizeof(CHAR));
  1851. cbRead = 0;
  1852. if (!ReadFile(hFile, *lplpbuf, cbFile, &cbRead, NULL))
  1853. {
  1854. cbRead = 0;
  1855. }
  1856. ASSERT((cbRead == cbFile));
  1857. CloseHandle(hFile);
  1858. return cbRead;
  1859. }
  1860. BOOL PostFavorites(TCHAR *pszPathToBookmarks, TCHAR* pszPathToPost)
  1861. {
  1862. DWORD cbRead = 0;
  1863. LPSTR lpbuf = NULL;
  1864. BOOL bret = FALSE;
  1865. BOOL bAsync = TRUE;
  1866. CHAR szPathToPost[INTERNET_MAX_URL_LENGTH];
  1867. ASYNCRES asyncres = {0, 0};
  1868. cbRead = ReadFavoritesFile(pszPathToBookmarks, &lpbuf);
  1869. if (cbRead == 0)
  1870. {
  1871. if (lpbuf)
  1872. {
  1873. GlobalFree(lpbuf);
  1874. lpbuf = NULL;
  1875. }
  1876. return TRUE;
  1877. }
  1878. SHTCharToAnsi(pszPathToPost, szPathToPost, ARRAYSIZE(szPathToPost));
  1879. if (SUCCEEDED(InitRequest(szPathToPost, bAsync, &asyncres)))
  1880. {
  1881. bret = (SUCCEEDED(SendRequest(NULL, lstrlenA(""), lpbuf, cbRead, bAsync, &asyncres)));
  1882. }
  1883. CloseRequest();
  1884. if (lpbuf)
  1885. {
  1886. GlobalFree( lpbuf );
  1887. lpbuf = NULL;
  1888. }
  1889. return bret;
  1890. }
  1891. //
  1892. // Callback function for Asynchronous HTTP POST request
  1893. //
  1894. void CALLBACK StatusCallback(
  1895. HINTERNET hInternet,
  1896. DWORD_PTR dwContext,
  1897. DWORD dwStatus,
  1898. LPVOID lpvInfo,
  1899. DWORD dwInfoLength
  1900. )
  1901. {
  1902. switch (dwStatus)
  1903. {
  1904. case INTERNET_STATUS_REQUEST_COMPLETE:
  1905. {
  1906. ASYNCRES *pasyncres = (ASYNCRES *)dwContext;
  1907. pasyncres->Result = ((LPINTERNET_ASYNC_RESULT)lpvInfo)->dwResult;
  1908. pasyncres->Error = ((LPINTERNET_ASYNC_RESULT)lpvInfo)->dwError;
  1909. SetEvent(g_hEvent);
  1910. }
  1911. break;
  1912. default:
  1913. break;
  1914. }
  1915. }