Leaked source code of windows server 2003
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.

992 lines
38 KiB

  1. /************************************************************\
  2. FILE: convert.c
  3. DATE: April 1, 1996
  4. AUTHOR(S): Bryan Starbuck (bryanst)
  5. DESCRIPTION:
  6. This file contains functions that can be used to upgrade
  7. settings from the Microsoft Internet Explorer v2.0 to v3.0,
  8. and some features to import Netscape features into Internet
  9. Explorer.
  10. This file will handle the logic to convert Netscape
  11. bookmarks to Microsoft Internet Explorer favorites. This
  12. will happen by finding the location of the Netscape bookmarks
  13. file and the Microsoft Internet Explorer favorites directory
  14. from the registry. Then it will parse the bookmarks file to
  15. extract the URLs, which will finally be added to the favorites
  16. directory.
  17. USAGE:
  18. This code is designed to be called when the user may
  19. want Netscape bookmarks imported into system level Favorites
  20. usable by programs such as Internet Explorer. External
  21. users should call ImportBookmarks(). If this is done during
  22. setup, it should be done after setup specifies the Favorites
  23. registry entry and directory. If Netscape is not installed,
  24. then the ImportBookmarks() is just a big no-op.
  25. NOTE:
  26. If this file is being compiled into something other
  27. than infnist.exe, it will be necessary to include the
  28. following String Resource:
  29. #define IDS_NS_BOOKMARKS_DIR 137
  30. STRINGTABLE DISCARDABLE
  31. BEGIN
  32. ...
  33. IDS_NS_BOOKMARKS_DIR "\\Imported Bookmarks"
  34. END
  35. UPDATES: I adopted this file to allow IE4.0 having the abilities
  36. to upgrade from NetScape's setting. Two CustomActions will be added
  37. to call in functions in this file. (inateeg)
  38. \************************************************************/
  39. #include "priv.h"
  40. #include "advpub.h"
  41. #include "sdsutils.h"
  42. #include "utils.h"
  43. #include "convert.h"
  44. #include <regstr.h>
  45. //////////////////////////////////////////////////////////////////
  46. // TYPES:
  47. //////////////////////////////////////////////////////////////////
  48. //typedef enum MYENTRYTYPE MyEntryType;
  49. extern HINSTANCE g_hinst;
  50. //////////////////////////////////////////////////////////////////
  51. // Constants:
  52. //////////////////////////////////////////////////////////////////
  53. #define MAX_URL 2048
  54. #define FILE_EXT 4 // For ".url" at the end of favorite filenames
  55. #define REASONABLE_NAME_LEN 100
  56. #define BEGIN_DIR_TOKEN "<DT><H"
  57. #define MID_DIR_TOKEN "\">"
  58. #define END_DIR_TOKEN "</H"
  59. #define BEGIN_EXITDIR_TOKEN "</DL><p>"
  60. #define BEGIN_URL_TOKEN "<DT><A HREF=\""
  61. #define END_URL_TOKEN "\" A"
  62. #define BEGIN_BOOKMARK_TOKEN ">"
  63. #define END_BOOKMARK_TOKEN "</A>"
  64. #define VALIDATION_STR "<!DOCTYPE NETSCAPE-Bookmark-file-"
  65. //////////////////////////////////////////////////////////////////
  66. // GLOBALS:
  67. //////////////////////////////////////////////////////////////////
  68. char * szNetscapeBMRegSub = "SOFTWARE\\Netscape\\Netscape Navigator\\Bookmark List";
  69. char * szNetscapeBMRegKey = "File Location";
  70. char * szIEFavoritesRegSub = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
  71. char * szIEFavoritesRegKey = "Favorites";
  72. char * szInvalidFolderCharacters = "\\/:*?\"<>|";
  73. BOOL gfValidNetscapeFile = FALSE;
  74. BOOL gfValidIEDirFile = FALSE;
  75. #define _FAT_ 1
  76. #define _HPFS_ 0
  77. #define _NTFS_ 0
  78. #define _WILD_ 0
  79. #define _OFS_ 0
  80. #define _OLE_ 0
  81. #define AnsiMaxChar 128 // The array below only indicates the lower 7 bits of the byte.
  82. static UCHAR LocalLegalAnsiCharacterArray[AnsiMaxChar] = {
  83. 0, // 0x00 ^@
  84. _OLE_, // 0x01 ^A
  85. _OLE_, // 0x02 ^B
  86. _OLE_, // 0x03 ^C
  87. _OLE_, // 0x04 ^D
  88. _OLE_, // 0x05 ^E
  89. _OLE_, // 0x06 ^F
  90. _OLE_, // 0x07 ^G
  91. _OLE_, // 0x08 ^H
  92. _OLE_, // 0x09 ^I
  93. _OLE_, // 0x0A ^J
  94. _OLE_, // 0x0B ^K
  95. _OLE_, // 0x0C ^L
  96. _OLE_, // 0x0D ^M
  97. _OLE_, // 0x0E ^N
  98. _OLE_, // 0x0F ^O
  99. _OLE_, // 0x10 ^P
  100. _OLE_, // 0x11 ^Q
  101. _OLE_, // 0x12 ^R
  102. _OLE_, // 0x13 ^S
  103. _OLE_, // 0x14 ^T
  104. _OLE_, // 0x15 ^U
  105. _OLE_, // 0x16 ^V
  106. _OLE_, // 0x17 ^W
  107. _OLE_, // 0x18 ^X
  108. _OLE_, // 0x19 ^Y
  109. _OLE_, // 0x1A ^Z
  110. _OLE_, // 0x1B ESC
  111. _OLE_, // 0x1C FS
  112. _OLE_, // 0x1D GS
  113. _OLE_, // 0x1E RS
  114. _OLE_, // 0x1F US
  115. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x20 space
  116. _FAT_ | _HPFS_ | _NTFS_ | _OFS_, // 0x21 !
  117. _WILD_, // 0x22 "
  118. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x23 #
  119. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x24 $
  120. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x25 %
  121. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x26 &
  122. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x27 '
  123. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x28 (
  124. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x29 )
  125. _WILD_, // 0x2A *
  126. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2B +
  127. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2C ,
  128. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2D -
  129. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2E .
  130. 0, // 0x2F /
  131. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x30 0
  132. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x31 1
  133. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x32 2
  134. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x33 3
  135. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x34 4
  136. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x35 5
  137. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x36 6
  138. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x37 7
  139. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x38 8
  140. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x39 9
  141. _NTFS_ | _OFS_, // 0x3A :
  142. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x3B ;
  143. _WILD_, // 0x3C <
  144. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x3D =
  145. _WILD_, // 0x3E >
  146. _WILD_, // 0x3F ?
  147. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x40 @
  148. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x41 A
  149. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x42 B
  150. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x43 C
  151. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x44 D
  152. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x45 E
  153. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x46 F
  154. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x47 G
  155. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x48 H
  156. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x49 I
  157. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4A J
  158. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4B K
  159. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4C L
  160. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4D M
  161. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4E N
  162. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4F O
  163. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x50 P
  164. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x51 Q
  165. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x52 R
  166. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x53 S
  167. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x54 T
  168. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x55 U
  169. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x56 V
  170. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x57 W
  171. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x58 X
  172. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x59 Y
  173. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5A Z
  174. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5B [
  175. 0, // 0x5C backslash
  176. _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5D ]
  177. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5E ^
  178. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5F _
  179. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x60 `
  180. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x61 a
  181. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x62 b
  182. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x63 c
  183. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x64 d
  184. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x65 e
  185. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x66 f
  186. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x67 g
  187. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x68 h
  188. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x69 i
  189. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6A j
  190. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6B k
  191. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6C l
  192. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6D m
  193. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6E n
  194. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6F o
  195. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x70 p
  196. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x71 q
  197. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x72 r
  198. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x73 s
  199. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x74 t
  200. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x75 u
  201. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x76 v
  202. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x77 w
  203. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x78 x
  204. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x79 y
  205. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7A z
  206. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7B {
  207. _OLE_, // 0x7C |
  208. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7D }
  209. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7E ~
  210. _FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7F 
  211. };
  212. ///////////////////////////////////////////////////////
  213. // Import Netscape Bookmarks to Microsoft
  214. // Internet Explorer's Favorites
  215. ///////////////////////////////////////////////////////
  216. /************************************************************\
  217. FUNCTION: ImportBookmarks
  218. PARAMETERS:
  219. HINSTANCE hInstWithStr - Location of String Resources.
  220. BOOL return - If an error occurs importing the bookmarks, FALSE is returned.
  221. DESCRIPTION:
  222. This function will see if it can find a IE Favorite's
  223. registry entry and a Netscape bookmarks registry entry. If
  224. both are found, then the conversion can happen. It will
  225. attempt to open the verify that the bookmarks file is
  226. valid and then convert the entries to favorite entries.
  227. If an error occures, ImportBookmarks() will return FALSE,
  228. otherwise it will return TRUE.
  229. \*************************************************************/
  230. BOOL ImportBookmarks(HINSTANCE hInstWithStr)
  231. {
  232. char szFavoritesDir[MAX_PATH];
  233. char szBookmarksDir[MAX_PATH];
  234. HANDLE hBookmarksFile = INVALID_HANDLE_VALUE;
  235. BOOL fSuccess = FALSE;
  236. // Initialize Variables
  237. szFavoritesDir[0] = '\0';
  238. szBookmarksDir[0] = '\0';
  239. // Get Bookmarks Dir
  240. if (TRUE == GetNavBkMkDir( szBookmarksDir, sizeof(szBookmarksDir) ) )
  241. {
  242. if ((NULL != szBookmarksDir) && (szBookmarksDir[0] != '\0'))
  243. {
  244. hBookmarksFile = CreateFile(szBookmarksDir, GENERIC_READ, FILE_SHARE_READ, NULL,
  245. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  246. if ( hBookmarksFile != INVALID_HANDLE_VALUE )
  247. {
  248. // Get Favorites Dir
  249. if (TRUE == GetPathFromRegistry(szFavoritesDir, MAX_PATH, HKEY_CURRENT_USER,
  250. szIEFavoritesRegSub, szIEFavoritesRegKey))
  251. {
  252. if ((NULL != szFavoritesDir) && (szFavoritesDir[0] != '\0'))
  253. {
  254. // Verify it's a valid Bookmarks file
  255. if (TRUE == VerifyBookmarksFile( hBookmarksFile ))
  256. {
  257. // Do the importing...
  258. fSuccess = ConvertBookmarks(szFavoritesDir, hBookmarksFile, hInstWithStr);
  259. }
  260. }
  261. }
  262. }
  263. }
  264. }
  265. if (INVALID_HANDLE_VALUE != hBookmarksFile)
  266. {
  267. CloseHandle(hBookmarksFile);
  268. }
  269. return(fSuccess);
  270. }
  271. /************************************************************\
  272. FUNCTION: ConvertBookmarks
  273. PARAMETERS:
  274. char * szFavoritesDir - String containing the path to
  275. the IE Favorites directory
  276. BOOL return - If an error occurs importing the bookmarks, FALSE is returned.
  277. DESCRIPTION:
  278. This function will continue in a loop converting each
  279. entry in the bookmark file. There are three types of
  280. entries in the bookmark file, 1) a bookmark, 2) start of
  281. new level in heirarchy, 3) end of current level in heirarchy.
  282. The function NextFileEntry() will return these values until
  283. the file is empty, at which point, this function will end.
  284. NOTE:
  285. In order to prevent an infinite loop, it's assumed
  286. that NextFileEntry() will eventually return ET_NONE or ET_ERROR.
  287. \************************************************************/
  288. BOOL ConvertBookmarks(char * szFavoritesDir, HANDLE hFile, HINSTANCE hInstWithStr)
  289. {
  290. BOOL fDone = FALSE;
  291. BOOL fSuccess = TRUE;
  292. BOOL fIsEmpty = TRUE;
  293. char * szData = NULL;
  294. char * szCurrent = NULL;
  295. char * szToken = NULL;
  296. char szSubDir[MAX_PATH];
  297. fSuccess = GetData(&szData, hFile);
  298. if (NULL == szData)
  299. fSuccess = FALSE;
  300. szCurrent = szData;
  301. // Verify directory exists or that we can make it.
  302. if ((TRUE == fSuccess) && ( !SetCurrentDirectory(szFavoritesDir)))
  303. {
  304. // If the directory doesn't exist, make it...
  305. if ( !CreateDirectory(szFavoritesDir, NULL))
  306. fSuccess = FALSE;
  307. else
  308. if (!SetCurrentDirectory(szFavoritesDir))
  309. fSuccess = FALSE;
  310. }
  311. // We don't want to install Other Popular Browser's bookmarks on our top level of our
  312. // favorites, so we create a sub director to put them in.
  313. if (0 != LoadString(hInstWithStr, IDS_NS_BOOKMARKS_DIR, szSubDir, sizeof(szSubDir)))
  314. {
  315. lstrcat(szFavoritesDir, szSubDir);
  316. if ((TRUE == fSuccess) && (!SetCurrentDirectory(szFavoritesDir)))
  317. {
  318. // If the directory doesn't exist, make it...
  319. if (!CreateDirectory(szFavoritesDir, NULL))
  320. fSuccess = FALSE;
  321. else
  322. if (!SetCurrentDirectory(szFavoritesDir))
  323. fSuccess = FALSE;
  324. }
  325. }
  326. else
  327. fSuccess = FALSE;
  328. while ((FALSE == fDone) && (TRUE == fSuccess))
  329. {
  330. switch(NextFileEntry(&szCurrent, &szToken))
  331. {
  332. case ET_OPEN_DIR:
  333. fSuccess = CreateDir(szToken);
  334. break;
  335. case ET_CLOSE_DIR:
  336. fSuccess = CloseDir();
  337. break;
  338. case ET_BOOKMARK:
  339. fSuccess = CreateBookmark(szToken);
  340. fIsEmpty = FALSE;
  341. break;
  342. case ET_ERROR:
  343. fSuccess = FALSE;
  344. break;
  345. case ET_NONE:
  346. default:
  347. fDone = TRUE;
  348. break;
  349. }
  350. }
  351. if ( fIsEmpty )
  352. {
  353. // nothing to import, delete the dir created earlier
  354. DelNode(szFavoritesDir, 0);
  355. }
  356. if (NULL != szData)
  357. {
  358. LocalFree(szData);
  359. szData = NULL;
  360. szCurrent = NULL; // szCurrent no longer points to valid data.
  361. szToken = NULL; // szCurrent no longer points to valid data.
  362. }
  363. return(fSuccess);
  364. }
  365. /************************************************************\
  366. FUNCTION: NextFileEntry
  367. PARAMETERS:
  368. char ** ppStr - The data to parse.
  369. char ** ppToken - The token pointer.
  370. EntryType return- See below.
  371. DESCRIPTION:
  372. This function will look for the next entry in the
  373. bookmark file to create or act on. The return value
  374. will indicate this response:
  375. ET_OPEN_DIR Create a new level in heirarchy
  376. ET_CLOSE_DIR, Close level in heirarchy
  377. ET_BOOKMARK, Create Bookmark entry.
  378. ET_NONE, End of File
  379. ET_ERROR Error encountered
  380. Errors will be detected by finding the start of a token,
  381. but in not finding other parts of the token that are needed
  382. to parse the data.
  383. \************************************************************/
  384. MyEntryType NextFileEntry(char ** ppStr, char ** ppToken)
  385. {
  386. MyEntryType returnVal = ET_NONE;
  387. char * pCurrentToken = NULL; // The current token to check if valid.
  388. char * pTheToken = NULL; // The next valid token.
  389. char * pszTemp = NULL;
  390. //ASSERTSZ(NULL != ppStr, "It's an error to pass NULL for ppStr");
  391. //ASSERTSZ(NULL != *ppStr, "It's an error to pass NULL for *ppStr");
  392. //ASSERTSZ(NULL != ppToken, "It's an error to pass NULL for ppToken");
  393. if ((NULL != ppStr) && (NULL != *ppStr) && (NULL != ppToken))
  394. {
  395. // Check for begin dir token
  396. if (NULL != (pCurrentToken = ANSIStrStr(*ppStr, BEGIN_DIR_TOKEN)))
  397. {
  398. // Begin dir token found
  399. // Verify that other needed tokens exist or it's an error
  400. if ((NULL == (pszTemp = ANSIStrStr(pCurrentToken, MID_DIR_TOKEN))) ||
  401. (NULL == ANSIStrStr(pszTemp, END_DIR_TOKEN)))
  402. {
  403. returnVal = ET_ERROR; // We can't find all the tokens needed.
  404. }
  405. else
  406. {
  407. // This function has to set *ppToken to the name of the directory to create
  408. *ppToken = ANSIStrStr(pCurrentToken, MID_DIR_TOKEN) + sizeof(MID_DIR_TOKEN)-1;
  409. pTheToken = pCurrentToken;
  410. returnVal = ET_OPEN_DIR;
  411. }
  412. }
  413. // Check for exit dir token
  414. if ((ET_ERROR != returnVal) &&
  415. (NULL != (pCurrentToken = ANSIStrStr(*ppStr, BEGIN_EXITDIR_TOKEN))))
  416. {
  417. // Exit dir token found
  418. // See if this token comes before TheToken.
  419. if ((NULL == pTheToken) || (pCurrentToken < pTheToken))
  420. {
  421. // ppToken is not used for Exit Dir
  422. *ppToken = NULL;
  423. pTheToken = pCurrentToken;
  424. returnVal = ET_CLOSE_DIR;
  425. }
  426. }
  427. // Check for begin dir token
  428. if ((ET_ERROR != returnVal) &&
  429. (NULL != (pCurrentToken = ANSIStrStr(*ppStr, BEGIN_URL_TOKEN))))
  430. {
  431. // Bookmark token found
  432. // Verify that other needed tokens exist or it's an error
  433. if ((NULL == (pszTemp = ANSIStrStr(pCurrentToken, END_URL_TOKEN))) ||
  434. (NULL == (pszTemp = ANSIStrStr(pszTemp, BEGIN_BOOKMARK_TOKEN))) ||
  435. (NULL == ANSIStrStr(pszTemp, END_BOOKMARK_TOKEN)))
  436. {
  437. returnVal = ET_ERROR; // We can't find all the tokens needed.
  438. }
  439. else
  440. {
  441. // See if this token comes before TheToken.
  442. if ((NULL == pTheToken) || (pCurrentToken < pTheToken))
  443. {
  444. // This function has to set *ppToken to the name of the bookmark
  445. *ppToken = pCurrentToken + sizeof(BEGIN_URL_TOKEN)-1;
  446. pTheToken = pCurrentToken;
  447. returnVal = ET_BOOKMARK;
  448. }
  449. }
  450. }
  451. }
  452. else
  453. returnVal = ET_ERROR; // We should never get here.
  454. if (NULL == pTheToken)
  455. returnVal = ET_NONE;
  456. else
  457. {
  458. // Next time we will start parsing where we left off.
  459. switch(returnVal)
  460. {
  461. case ET_OPEN_DIR:
  462. *ppStr = ANSIStrStr(pTheToken, MID_DIR_TOKEN) + sizeof(MID_DIR_TOKEN);
  463. break;
  464. case ET_CLOSE_DIR:
  465. *ppStr = pTheToken + sizeof(BEGIN_EXITDIR_TOKEN);
  466. break;
  467. case ET_BOOKMARK:
  468. *ppStr = ANSIStrStr(pTheToken, END_BOOKMARK_TOKEN) + sizeof(END_BOOKMARK_TOKEN);
  469. break;
  470. default:
  471. break;
  472. }
  473. }
  474. return(returnVal);
  475. }
  476. /************************************************************\
  477. FUNCTION: GetPathFromRegistry
  478. PARAMETERS:
  479. LPSTR szPath - The value found in the registry. (Result of function)
  480. UINT cbPath - Size of szPath.
  481. HKEY theHKEY - The HKEY to look into (HKEY_CURRENT_USER)
  482. LPSTR szKey - Path in Registry (Software\...\Explore\Shell Folders)
  483. LPSTR szVName - Value to query (Favorites)
  484. BOOL return - TRUE if succeeded, FALSE if Error.
  485. EXAMPLE:
  486. HKEY_CURRENT_USER\Software\Microsoft\CurrentVersion\Explore\Shell Folders
  487. Favorites = "C:\WINDOWS\Favorites"
  488. DESCRIPTION:
  489. This function will look in the registry for the value
  490. to look up. The caller specifies the HKEY, subkey (szKey),
  491. value to query (szVName). The caller also sets a side memory
  492. for the result and passes a pointer to that memory in szPath
  493. with it's size in cbPath. The BOOL return value will indicate
  494. success or failure of this function.
  495. \************************************************************/
  496. BOOL GetPathFromRegistry(LPSTR szPath, UINT cbPath, HKEY theHKEY,
  497. LPSTR szKey, LPSTR szVName)
  498. {
  499. HKEY hkPath = NULL;
  500. DWORD dwType;
  501. DWORD dwSize;
  502. /*
  503. * Get Path to program
  504. * from the registry
  505. */
  506. if (ERROR_SUCCESS != RegOpenKeyEx(theHKEY, szKey, 0, KEY_READ, &hkPath))
  507. {
  508. return(FALSE);
  509. }
  510. dwSize = cbPath;
  511. if (ERROR_SUCCESS != RegQueryValueEx(hkPath, szVName, NULL, &dwType, (LPBYTE) szPath, &dwSize))
  512. {
  513. RegCloseKey(hkPath);
  514. hkPath = NULL;
  515. return(FALSE);
  516. }
  517. RegCloseKey(hkPath);
  518. hkPath = NULL;
  519. /*
  520. * If we got nothing or it wasn't a string then
  521. * we bail out
  522. */
  523. if ((dwSize == 0) || (dwType != REG_SZ))
  524. return(FALSE);
  525. return(TRUE);
  526. }
  527. /************************************************************\
  528. FUNCTION: RemoveInvalidFileNameChars
  529. PARAMETERS:
  530. char * pBuf - The data to search.
  531. DESCRIPTION:
  532. This function will search pBuf until it encounters
  533. a character that is not allowed in a file name. It will
  534. then replace that character with a SPACE and continue looking
  535. for more invalid chars until they have all been removed.
  536. \************************************************************/
  537. void RemoveInvalidFileNameChars(char * pBuf)
  538. {
  539. //ASSERTSZ(NULL != pBuf, "Invalid function parameter");
  540. // Go through the array of chars, replacing offending characters with a space
  541. if (NULL != pBuf)
  542. {
  543. if (REASONABLE_NAME_LEN < strlen(pBuf))
  544. pBuf[REASONABLE_NAME_LEN] = '\0'; // String too long. Terminate it.
  545. while ('\0' != *pBuf)
  546. {
  547. // Check if the character is invalid
  548. if (!IsDBCSLeadByte(*pBuf))
  549. {
  550. if (ANSIStrChr(szInvalidFolderCharacters, *pBuf) != NULL)
  551. *pBuf = '_';
  552. }
  553. #if 0
  554. // Old code
  555. // We look in the array to see if the character is supported by FAT.
  556. // The array only includes the first 128 values, so we need to fail
  557. // on the other 128 values that have the high bit set.
  558. if (((AnsiMaxChar <= *pBuf) && (FALSE == IsDBCSLeadByte(*pBuf))) ||
  559. (0 == LocalLegalAnsiCharacterArray[*pBuf]))
  560. *pBuf = '$';
  561. #endif
  562. pBuf = CharNext(pBuf);
  563. }
  564. }
  565. }
  566. /************************************************************\
  567. FUNCTION: CreateBookmark
  568. PARAMETERS:
  569. char * pBookmarkName- This is a pointer that contains
  570. the name of the bookmark to create.
  571. Note that it is not NULL terminated.
  572. BOOL return - Return TRUE if successful.
  573. DESCRIPTION:
  574. This function will take the data that is passed to
  575. it and extract the name of the bookmark and it's value to create.
  576. If the name is too long, it will be truncated. Then,
  577. the directory will be created. Any errors encountered
  578. will cause the function to return FALSE to indicate
  579. failure.
  580. \************************************************************/
  581. BOOL CreateBookmark(char *pBookmarkName)
  582. {
  583. BOOL fSuccess = FALSE;
  584. char szNameOfBM[REASONABLE_NAME_LEN];
  585. char szURL[MAX_URL];
  586. char * pstrEndOfStr = NULL;
  587. char * pstrBeginOfName = NULL;
  588. long lStrLen = 0;
  589. HANDLE hFile = NULL;
  590. DWORD dwSize;
  591. char szBuf[MAX_URL];
  592. //ASSERTSZ(NULL != pBookmarkName, "Bad input parameter");
  593. if (NULL != pBookmarkName)
  594. {
  595. pstrEndOfStr = ANSIStrStr(pBookmarkName, END_URL_TOKEN);
  596. if (NULL != pstrEndOfStr)
  597. {
  598. lStrLen = (long)(pstrEndOfStr-pBookmarkName);
  599. if (MAX_URL < lStrLen)
  600. lStrLen = MAX_URL-1;
  601. // Create the name of the Bookmark
  602. lstrcpyn(szURL, pBookmarkName, MAX_URL);
  603. szURL[lStrLen] = '\0';
  604. pstrBeginOfName = ANSIStrStr(pstrEndOfStr, BEGIN_BOOKMARK_TOKEN);
  605. if (NULL != pstrBeginOfName)
  606. {
  607. pstrBeginOfName += sizeof(BEGIN_BOOKMARK_TOKEN) - 1; // Start at beginning of Name
  608. pstrEndOfStr = ANSIStrStr(pstrBeginOfName, END_BOOKMARK_TOKEN); // Find end of name
  609. if (NULL != pstrEndOfStr)
  610. {
  611. lStrLen = (long)(pstrEndOfStr-pstrBeginOfName);
  612. if (REASONABLE_NAME_LEN-FILE_EXT < lStrLen)
  613. lStrLen = REASONABLE_NAME_LEN-FILE_EXT-1;
  614. // Generate the URL
  615. lstrcpyn(szNameOfBM, pstrBeginOfName, lStrLen+1);
  616. //szNameOfBM[lStrLen] = '\0';
  617. lstrcat(szNameOfBM, ".url");
  618. RemoveInvalidFileNameChars(szNameOfBM);
  619. // Check to see if Favorite w/same name exists
  620. if (INVALID_HANDLE_VALUE != (hFile = CreateFile(szNameOfBM, GENERIC_WRITE, FILE_SHARE_READ, NULL,
  621. CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL )))
  622. {
  623. WriteFile(hFile, "[InternetShortcut]\n", lstrlen( "[InternetShortcut]\n" ), &dwSize, NULL);
  624. wsprintf( szBuf, "URL=%s\n", szURL);
  625. WriteFile(hFile, szBuf, lstrlen(szBuf), &dwSize, NULL );
  626. fSuccess = TRUE;
  627. }
  628. else
  629. {
  630. fSuccess = TRUE;
  631. }
  632. if (NULL != hFile)
  633. {
  634. CloseHandle( hFile );
  635. hFile = NULL;
  636. }
  637. }
  638. }
  639. }
  640. }
  641. return(fSuccess);
  642. }
  643. /************************************************************\
  644. FUNCTION: CreateDir
  645. PARAMETERS:
  646. char * pDirName - This is a pointer that contains
  647. the name of the directory to create.
  648. Note that it is not NULL terminated.
  649. BOOL return - Return TRUE if successful.
  650. DESCRIPTION:
  651. This function will take the data that is passed to
  652. it and extract the name of the directory to create.
  653. If the name is too long, it will be truncated. Then,
  654. the directory will be created. Any errors encountered
  655. will cause the function to return FALSE to indicate
  656. failure.
  657. \************************************************************/
  658. BOOL CreateDir(char *pDirName)
  659. {
  660. BOOL fSuccess = FALSE;
  661. char szNameOfDir[REASONABLE_NAME_LEN];
  662. char * pstrEndOfName = NULL;
  663. long lStrLen = 0;
  664. //ASSERTSZ(NULL != pDirName, "Bad input parameter");
  665. if (NULL != pDirName)
  666. {
  667. pstrEndOfName = ANSIStrStr(pDirName, END_DIR_TOKEN);
  668. if (NULL != pstrEndOfName)
  669. {
  670. lStrLen = (long)(pstrEndOfName-pDirName);
  671. if (REASONABLE_NAME_LEN < lStrLen)
  672. lStrLen = REASONABLE_NAME_LEN-1;
  673. lstrcpyn(szNameOfDir, pDirName, lStrLen+1);
  674. //szNameOfDir[lStrLen] = '\0';
  675. RemoveInvalidFileNameChars(szNameOfDir);
  676. // BUGBUG : Try to CD into existing dir first
  677. if ( !SetCurrentDirectory(szNameOfDir) )
  678. {
  679. if ( CreateDirectory(szNameOfDir, NULL) )
  680. {
  681. if ( SetCurrentDirectory(szNameOfDir) )
  682. {
  683. fSuccess = TRUE;// It didn't exist, but now it does.
  684. }
  685. }
  686. }
  687. else
  688. fSuccess = TRUE; // It exists already.
  689. }
  690. }
  691. return(fSuccess);
  692. }
  693. /************************************************************\
  694. FUNCTION: CloseDir
  695. PARAMETERS:
  696. BOOL return - Return TRUE if successful.
  697. DESCRIPTION:
  698. This function will back out of the current directory.
  699. \************************************************************/
  700. BOOL CloseDir(void)
  701. {
  702. return( SetCurrentDirectory("..") );
  703. }
  704. /************************************************************\
  705. FUNCTION: VerifyBookmarksFile
  706. PARAMETERS:
  707. FILE * pFile - Pointer to Netscape Bookmarks file.
  708. BOOL return - TRUE if No Error and Valid Bookmark file
  709. DESCRIPTION:
  710. This function needs to be passed with a valid pointer
  711. that points to an open file. Upon return, the file will
  712. still be open and is guarenteed to have the file pointer
  713. point to the beginning of the file.
  714. This function will return TRUE if the file contains
  715. text that indicates it's a valid Netscape bookmarks file.
  716. \************************************************************/
  717. BOOL VerifyBookmarksFile(HANDLE hFile)
  718. {
  719. BOOL fSuccess = FALSE;
  720. char szFileHeader[sizeof(VALIDATION_STR)+1] = "";
  721. DWORD dwSize;
  722. //ASSERTSZ(NULL != pFile, "You can't pass me a NULL File Pointer");
  723. if (INVALID_HANDLE_VALUE == hFile)
  724. return(FALSE);
  725. // Reading the first part of the file. If the file isn't this long, then
  726. // it can't possibly be a Bookmarks file.
  727. if ( ReadFile( hFile, szFileHeader, sizeof(VALIDATION_STR)-1, &dwSize, NULL ) && (dwSize == sizeof(VALIDATION_STR)-1) )
  728. {
  729. szFileHeader[sizeof(VALIDATION_STR)] = '\0'; // Terminate String.
  730. if (0 == lstrcmp(szFileHeader, VALIDATION_STR)) // See if header is the same as the Validation string.
  731. fSuccess = TRUE;
  732. }
  733. // Reset the point to point to the beginning of the file.
  734. dwSize = SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
  735. if ( dwSize == 0xFFFFFFFF )
  736. fSuccess = FALSE;
  737. return(fSuccess);
  738. }
  739. /************************************************************\
  740. FUNCTION: GetData
  741. PARAMETERS:
  742. char ** ppData - Where to put the data
  743. FILE * pFile - Pointer to Netscape Bookmarks file.
  744. BOOL return - Return TRUE is successful.
  745. DESCRIPTION:
  746. This function will find the size of the bookmarks file,
  747. malloc that much memory, and put the file's contents in
  748. that buffer. ppData will be invalid when the function
  749. is called and will return with malloced memory that
  750. needs to be freed by the falling function.
  751. \************************************************************/
  752. BOOL GetData(char ** ppData, HANDLE hFile)
  753. {
  754. DWORD dwlength, dwRead;
  755. BOOL fSuccess = FALSE;
  756. //ASSERTSZ(NULL != ppData, "Invalid input parameter");
  757. if (NULL != ppData)
  758. {
  759. *ppData = NULL;
  760. // Find the size of the data
  761. if ( dwlength = GetFileSize(hFile, NULL))
  762. {
  763. *ppData = (PSTR)LocalAlloc(LPTR, dwlength+1 );
  764. if (NULL != *ppData)
  765. {
  766. if ( ReadFile( hFile, *ppData, dwlength+1, &dwRead, NULL ) &&
  767. ( dwlength == dwRead ) )
  768. {
  769. fSuccess = TRUE;
  770. }
  771. (*ppData)[dwlength] = '\0';
  772. }
  773. }
  774. }
  775. return(fSuccess);
  776. }
  777. BOOL GetNavBkMkDir( LPSTR lpszDir, int isize )
  778. {
  779. char szDir[MAX_PATH];
  780. HKEY hKey;
  781. HKEY hKeyUser;
  782. char szUser[MAX_PATH];
  783. DWORD dwSize;
  784. BOOL bDirFound = FALSE;
  785. lstrcpy( szUser, REGSTR_PATH_APPPATHS );
  786. AddPath( szUser, "NetScape.exe" );
  787. if ( GetPathFromRegistry( szDir, MAX_PATH, HKEY_LOCAL_MACHINE, szUser, "" ) &&
  788. lstrlen(szDir) )
  789. {
  790. DWORD dwMV, dwLV;
  791. if ( SUCCEEDED(GetVersionFromFile( szDir, &dwMV, &dwLV, TRUE)) )
  792. {
  793. if ( dwMV < 0x00040000 )
  794. {
  795. bDirFound = GetPathFromRegistry( lpszDir, isize, HKEY_CURRENT_USER,
  796. szNetscapeBMRegSub, szNetscapeBMRegKey);
  797. }
  798. else
  799. {
  800. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Netscape\\Netscape Navigator\\Users", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  801. {
  802. dwSize = sizeof(szUser);
  803. if (RegQueryValueEx(hKey, "CurrentUser", NULL, NULL, (LPBYTE)szUser, &dwSize) == ERROR_SUCCESS)
  804. {
  805. if (RegOpenKeyEx(hKey, szUser, 0, KEY_READ, &hKeyUser) == ERROR_SUCCESS)
  806. {
  807. dwSize = sizeof(szDir);
  808. if (RegQueryValueEx(hKeyUser, "DirRoot", NULL, NULL, (LPBYTE)szDir, &dwSize) == ERROR_SUCCESS)
  809. {
  810. // Found the directory for the current user.
  811. lstrcpy( lpszDir, szDir);
  812. AddPath( lpszDir, "bookmark.htm" );
  813. bDirFound = TRUE;
  814. }
  815. RegCloseKey(hKeyUser);
  816. }
  817. }
  818. RegCloseKey(hKey);
  819. }
  820. if (!bDirFound)
  821. {
  822. szUser[0] = '\0';
  823. // NAV 4.5 is not writing the above keys. there is a different way of finding the user dir.
  824. if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Netscape\\Netscape Navigator\\biff", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
  825. {
  826. dwSize = sizeof(szUser);
  827. if (RegQueryValueEx(hKey, "CurrentUser", NULL, NULL, (LPBYTE)szUser, &dwSize) == ERROR_SUCCESS)
  828. {
  829. // Have the current user name. Now get the root folder where the user folder are.
  830. if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Netscape\\Netscape Navigator\\Main", 0, KEY_QUERY_VALUE, &hKeyUser) == ERROR_SUCCESS)
  831. {
  832. dwSize = sizeof(szDir);
  833. if (RegQueryValueEx(hKeyUser, "Install Directory", NULL, NULL, (LPBYTE)szDir, &dwSize) == ERROR_SUCCESS)
  834. {
  835. // Got the install folder.
  836. // Need to the the parent folder and then append users\%s , %s gets replaced with
  837. // the CurrentUser name.
  838. if (GetParentDir(szDir))
  839. {
  840. AddPath(szDir, "Users");
  841. AddPath(szDir, szUser);
  842. AddPath(szDir, "bookmark.htm" );
  843. bDirFound = TRUE;
  844. lstrcpy(lpszDir, szDir);
  845. }
  846. }
  847. RegCloseKey(hKeyUser);
  848. }
  849. }
  850. RegCloseKey(hKey);
  851. }
  852. }
  853. }
  854. }
  855. }
  856. else
  857. bDirFound = GetPathFromRegistry( lpszDir, isize, HKEY_CURRENT_USER,
  858. szNetscapeBMRegSub, szNetscapeBMRegKey);
  859. return bDirFound;
  860. }