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.

1179 lines
44 KiB

  1. #include "precomp.h"
  2. #include "channels.h"
  3. #define NSUBGRPS 10
  4. static DWORD s_dwMode;
  5. static void channels_InitHelper(HWND hDlg, LPCTSTR pcszAltDir, LPCTSTR pcszWorkDir, LPCTSTR pcszCustIns,
  6. WORD idList, DWORD dwPlatformId, BOOL fIgnoreOffline);
  7. static void channels_SaveHelper(HWND hwndList, LPCTSTR pcszChanDir, LPCTSTR pcszCustIns, DWORD dwMode);
  8. static int importChannels(HWND hDlg);
  9. static BOOL CALLBACK addEditChannel(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  10. static PCHANNEL findFreeChannel(HWND hwndList);
  11. void WINAPI Channels_InitA(HWND hDlg, LPCSTR pcszAltDir, LPCSTR pcszWorkDir, LPCSTR pcszCustIns,
  12. WORD idList, DWORD dwPlatformId, BOOL fIgnoreOffline)
  13. {
  14. USES_CONVERSION;
  15. channels_InitHelper(hDlg, A2CT(pcszAltDir), A2CT(pcszWorkDir), A2CT(pcszCustIns), idList,
  16. dwPlatformId, fIgnoreOffline);
  17. }
  18. void WINAPI Channels_InitW(HWND hDlg, LPCWSTR pcwszAltDir, LPCWSTR pcwszWorkDir, LPCWSTR pcwszCustIns,
  19. WORD idList, DWORD dwPlatformId, BOOL fIgnoreOffline)
  20. {
  21. USES_CONVERSION;
  22. channels_InitHelper(hDlg, W2CT(pcwszAltDir), W2CT(pcwszWorkDir), W2CT(pcwszCustIns),
  23. idList, dwPlatformId, fIgnoreOffline);
  24. }
  25. void WINAPI Channels_SaveA(HWND hwndList, LPCSTR pcszChanDir, LPCSTR pcszCustIns, DWORD dwMode /*= IEM_NEUTRAL*/)
  26. {
  27. USES_CONVERSION;
  28. channels_SaveHelper(hwndList, A2CT(pcszChanDir), A2CT(pcszCustIns), dwMode);
  29. }
  30. void WINAPI Channels_SaveW(HWND hwndList, LPCWSTR pcwszChanDir, LPCWSTR pcwszCustIns, DWORD dwMode /*= IEM_NEUTRAL*/)
  31. {
  32. USES_CONVERSION;
  33. channels_SaveHelper(hwndList, W2CT(pcwszChanDir), W2CT(pcwszCustIns), dwMode);
  34. }
  35. int WINAPI Channels_Import(HWND hDlg)
  36. {
  37. int nChannels = 0;
  38. nChannels = importChannels(hDlg);
  39. if (nChannels == 0)
  40. ErrorMessageBox(hDlg, IDS_NOCHANNELSTOIMPORT);
  41. return nChannels;
  42. }
  43. BOOL WINAPI Channels_Remove(HWND hDlg)
  44. {
  45. PCHANNEL pChan;
  46. int i;
  47. i = (INT) SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_GETCURSEL, 0, 0);
  48. pChan = (PCHANNEL)SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_GETITEMDATA, (WPARAM)i, 0);
  49. *pChan->szTitle = TEXT('\0');
  50. SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_DELETESTRING, (WPARAM)i, 0);
  51. // if add buttons have been disabled because we reached the max, then reenable them
  52. if (!IsWindowEnabled(GetDlgItem(hDlg, IDC_ADDCHANNEL)))
  53. {
  54. EnableWindow(GetDlgItem(hDlg, IDC_ADDCHANNEL), TRUE);
  55. EnableWindow(GetDlgItem(hDlg, IDC_ADDCATEGORY), TRUE);
  56. }
  57. if (SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_SETCURSEL, (WPARAM)i, 0) == LB_ERR)
  58. {
  59. if (SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_SETCURSEL, (WPARAM)(i-1), 0) == LB_ERR)
  60. {
  61. EnsureDialogFocus(hDlg, IDC_EDITCHANNEL, IDC_ADDCHANNEL);
  62. EnableWindow(GetDlgItem(hDlg, IDC_EDITCHANNEL), FALSE);
  63. EnsureDialogFocus(hDlg, IDC_REMOVECHANNEL, IDC_ADDCHANNEL);
  64. EnableWindow(GetDlgItem(hDlg, IDC_REMOVECHANNEL), FALSE);
  65. }
  66. else
  67. SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_SETTOPINDEX, (WPARAM)i, 0);
  68. }
  69. else
  70. SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_SETTOPINDEX, (WPARAM)i, 0);
  71. return TRUE;
  72. }
  73. static HRESULT xML_GetElementByIndex(IXMLElementCollection* pIXMLElementCollection, LONG nIndex,
  74. IXMLElement** ppIXMLElement)
  75. {
  76. HRESULT hr;
  77. VARIANT var1, var2;
  78. if (!pIXMLElementCollection || !ppIXMLElement)
  79. return E_FAIL;
  80. VariantInit(&var1);
  81. VariantInit(&var2);
  82. var1.vt = VT_I4;
  83. var1.lVal = nIndex;
  84. IDispatch* pIDispatch;
  85. hr = pIXMLElementCollection->item(var1, var2, &pIDispatch);
  86. if (SUCCEEDED(hr) && pIDispatch)
  87. {
  88. hr = pIDispatch->QueryInterface(IID_IXMLElement, (void**)ppIXMLElement);
  89. pIDispatch->Release();
  90. }
  91. else
  92. {
  93. *ppIXMLElement = NULL;
  94. hr = E_FAIL;
  95. }
  96. return hr;
  97. }
  98. static BOOL xML_ParseElement(IXMLElement * pIXMLElement, LPTSTR pszPath,
  99. LPCWSTR pcwszImageTypeW, LPCTSTR pcszBaseUrl)
  100. {
  101. HRESULT hr;
  102. BSTR bstrTagName;
  103. VARIANT var;
  104. WCHAR szImagePathW[MAX_PATH];
  105. TCHAR szFullUrl[INTERNET_MAX_URL_LENGTH];
  106. TCHAR szImageUrl[INTERNET_MAX_URL_LENGTH];
  107. INTERNET_CACHE_ENTRY_INFO *lpiceiInfo;
  108. DWORD dwSize = 0;
  109. USES_CONVERSION;
  110. hr = pIXMLElement->get_tagName(&bstrTagName);
  111. if (SUCCEEDED(hr) && bstrTagName)
  112. {
  113. if (StrCmpIW(bstrTagName, WSTR_LOGO) == 0)
  114. {
  115. VariantInit(&var);
  116. hr = pIXMLElement->getAttribute(WSTR_STYLE, &var);
  117. if ((SUCCEEDED(hr)) && (var.vt == VT_BSTR) && (var.bstrVal != NULL))
  118. {
  119. if ((StrCmpIW(var.bstrVal, pcwszImageTypeW) == 0) ||
  120. ((StrCmpIW(pcwszImageTypeW, WSTR_IMAGEW) == 0) &&
  121. (StrCmpIW(var.bstrVal, L"IMAGEWIDE") == 0)))
  122. {
  123. VariantClear(&var);
  124. hr = pIXMLElement->getAttribute(WSTR_HREF, &var);
  125. if ((SUCCEEDED(hr)) && (var.vt == VT_BSTR) && (var.bstrVal != NULL))
  126. {
  127. W2Tbux(var.bstrVal, szImageUrl);
  128. if (PathIsURL(szImageUrl) || ISNULL(pcszBaseUrl))
  129. StrCpy(szFullUrl, szImageUrl);
  130. else
  131. {
  132. DWORD cbSize = sizeof(szFullUrl);
  133. InternetCombineUrl(pcszBaseUrl, szImageUrl, szFullUrl, &cbSize, ICU_NO_ENCODE);
  134. }
  135. RetrieveUrlCacheEntryFile(szFullUrl, NULL, &dwSize, 0);
  136. lpiceiInfo = (INTERNET_CACHE_ENTRY_INFO *)LocalAlloc(LPTR, dwSize);
  137. if (RetrieveUrlCacheEntryFile(szFullUrl, lpiceiInfo, &dwSize, 0))
  138. {
  139. StrCpy(pszPath, lpiceiInfo->lpszLocalFileName);
  140. LocalFree(lpiceiInfo);
  141. UnlockUrlCacheEntryFile(szFullUrl, 0);
  142. return TRUE;
  143. }
  144. else
  145. {
  146. LocalFree(lpiceiInfo);
  147. hr = URLDownloadToCacheFileW(NULL, T2W(szFullUrl), szImagePathW, ARRAYSIZE(szImagePathW), 0, NULL);
  148. if (SUCCEEDED(hr))
  149. {
  150. W2Tbux(szImagePathW, pszPath);
  151. return TRUE;
  152. }
  153. }
  154. }
  155. }
  156. }
  157. }
  158. }
  159. return FALSE;
  160. }
  161. // Takes a cdf url, downloads to the cache if necessary, and parses to
  162. // find the image path in the cache(downloading again if necessary) for
  163. // either wide logo, logo or image. Returns FALSE if none specified
  164. static BOOL getCdfImage(LPCTSTR szCdfUrl, LPTSTR szPath, LPCWSTR szImageTypeW)
  165. {
  166. TCHAR szCdfUrlPath[INTERNET_MAX_URL_LENGTH];
  167. IXMLDocument* pIXMLDocument = NULL;
  168. IPersistStreamInit* pIPersistStreamInit = NULL;
  169. IStream* pIStream = NULL;
  170. IXMLElement *pRootElem = NULL;
  171. BOOL bLoad = FALSE;
  172. HRESULT hr = S_OK;
  173. INTERNET_CACHE_ENTRY_INFO *lpiceiInfo;
  174. DWORD dwSize = 0;
  175. RetrieveUrlCacheEntryFile(szCdfUrl, NULL, &dwSize, 0);
  176. lpiceiInfo = (INTERNET_CACHE_ENTRY_INFO *)LocalAlloc(LPTR, dwSize);
  177. if (RetrieveUrlCacheEntryFile(szCdfUrl, lpiceiInfo, &dwSize, 0))
  178. {
  179. StrCpy(szCdfUrlPath, lpiceiInfo->lpszLocalFileName);
  180. UnlockUrlCacheEntryFile(szCdfUrl, 0);
  181. }
  182. else
  183. {
  184. hr = URLDownloadToCacheFile(NULL, szCdfUrl, szCdfUrlPath, ARRAYSIZE(szCdfUrlPath), 0, NULL);
  185. }
  186. LocalFree(lpiceiInfo);
  187. if (!SUCCEEDED(hr))
  188. {
  189. return FALSE;
  190. }
  191. hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
  192. IID_IXMLDocument, (void**)&pIXMLDocument);
  193. // load the document
  194. if (SUCCEEDED(hr) && pIXMLDocument)
  195. {
  196. hr = pIXMLDocument->QueryInterface(IID_IPersistStreamInit,
  197. (void**)&pIPersistStreamInit);
  198. if (SUCCEEDED(hr) && pIPersistStreamInit)
  199. {
  200. hr = SHCreateStreamOnFile(szCdfUrlPath, STGM_READ, &pIStream);
  201. if (SUCCEEDED(hr) && pIStream)
  202. {
  203. hr = pIPersistStreamInit->Load(pIStream);
  204. pIStream->Release();
  205. bLoad = TRUE;
  206. }
  207. pIPersistStreamInit->Release();
  208. }
  209. }
  210. if (!bLoad)
  211. {
  212. if (pIXMLDocument)
  213. pIXMLDocument->Release();
  214. return FALSE;
  215. }
  216. // Now lets get the image
  217. hr = pIXMLDocument->get_root(&pRootElem);
  218. if (SUCCEEDED(hr) && pRootElem)
  219. {
  220. TCHAR szBaseUrl[INTERNET_MAX_URL_LENGTH];
  221. VARIANT var;
  222. IXMLElementCollection* pIXMLElementCollection;
  223. VariantInit(&var);
  224. *szBaseUrl = TEXT('\0');
  225. hr = pRootElem->getAttribute(WSTR_BASE, &var);
  226. if ((SUCCEEDED(hr)) && (var.vt == VT_BSTR) && (var.bstrVal != NULL))
  227. W2Tbux(var.bstrVal, szBaseUrl);
  228. hr = pRootElem->get_children(&pIXMLElementCollection);
  229. if (SUCCEEDED(hr) && pIXMLElementCollection)
  230. {
  231. LONG nCount;
  232. hr = pIXMLElementCollection->get_length(&nCount);
  233. if (SUCCEEDED(hr))
  234. {
  235. for (int i = 0; i < nCount; i++)
  236. {
  237. IXMLElement* pIXMLElement;
  238. hr = xML_GetElementByIndex(pIXMLElementCollection, i, &pIXMLElement);
  239. if (SUCCEEDED(hr) && pIXMLElement)
  240. {
  241. if (xML_ParseElement(pIXMLElement, szPath, szImageTypeW, szBaseUrl))
  242. {
  243. pIXMLElement->Release();
  244. hr = S_OK;
  245. break;
  246. }
  247. pIXMLElement->Release();
  248. hr = E_FAIL;
  249. }
  250. }
  251. }
  252. pIXMLElementCollection->Release();
  253. }
  254. pRootElem->Release();
  255. }
  256. pIXMLDocument->Release();
  257. if (SUCCEEDED(hr))
  258. return TRUE;
  259. else
  260. return FALSE;
  261. }
  262. // This DlgProc handles the processing for all popups on all platforms
  263. // Note that the narrow image, wide image, and icon resource id's are the
  264. // same for channels and categories.
  265. static BOOL CALLBACK addEditChannel(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  266. {
  267. TCHAR szWrk[MAX_URL];
  268. TCHAR szTitle[MAX_PATH] = TEXT(""); // buffers used for validation
  269. TCHAR szPreUrlPath[MAX_PATH] = TEXT("");
  270. TCHAR szIcon[MAX_PATH] = TEXT("");
  271. TCHAR szLogo[MAX_PATH] = TEXT("");
  272. TCHAR szWebUrl[INTERNET_MAX_URL_LENGTH] = TEXT("");
  273. PCHANNEL pSelCh;
  274. switch (uMsg)
  275. {
  276. case WM_INITDIALOG:
  277. pSelCh = (PCHANNEL)lParam;
  278. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pSelCh);
  279. if (pSelCh->fCategory)
  280. {
  281. EnableDBCSChars(hDlg, IDC_CATEGORYHTML);
  282. EnableDBCSChars(hDlg, IDE_CATEGORYTITLE);
  283. SetDlgItemText(hDlg, IDC_CATEGORYHTML, pSelCh->szWebUrl);
  284. SetDlgItemText(hDlg, IDE_CATEGORYTITLE, pSelCh->szTitle);
  285. }
  286. else
  287. {
  288. EnableDBCSChars(hDlg, IDE_CHANNELSRVURL2);
  289. EnableDBCSChars(hDlg, IDE_CHANNELTITLE2);
  290. SetDlgItemText(hDlg, IDE_CHANNELSRVURL2, pSelCh->szWebUrl);
  291. SetDlgItemText(hDlg, IDE_CHANNELTITLE2, pSelCh->szTitle);
  292. }
  293. EnableDBCSChars(hDlg, IDC_CHANNELBITMAP2);
  294. EnableDBCSChars(hDlg, IDC_CHANNELICON2);
  295. SetDlgItemText(hDlg, IDC_CHANNELBITMAP2, pSelCh->szLogo);
  296. SetDlgItemText(hDlg, IDC_CHANNELICON2, pSelCh->szIcon);
  297. if (!pSelCh->fCategory)
  298. {
  299. EnableDBCSChars(hDlg, IDC_CHANNELURL2);
  300. SetDlgItemText(hDlg, IDC_CHANNELURL2, pSelCh->szPreUrlPath);
  301. if (!HasFlag(s_dwMode, (IEM_CORP | IEM_PROFMGR)))
  302. DisableDlgItem(hDlg, IDC_CHANNELOFFL);
  303. else
  304. if (pSelCh->fOffline)
  305. CheckDlgButton(hDlg, IDC_CHANNELOFFL, BST_CHECKED);
  306. }
  307. else
  308. ASSERT(!HasFlag(s_dwMode, IEM_ADMIN));
  309. break;
  310. case WM_COMMAND:
  311. switch(HIWORD(wParam))
  312. {
  313. case BN_CLICKED:
  314. switch (LOWORD(wParam))
  315. {
  316. case IDC_BROWSECHBMP2:
  317. GetDlgItemText(hDlg, IDC_CHANNELBITMAP2, szWrk, ARRAYSIZE(szWrk));
  318. if (BrowseForFile(hDlg, szWrk, ARRAYSIZE(szWrk), GFN_PICTURE))
  319. SetDlgItemText(hDlg, IDC_CHANNELBITMAP2, szWrk);
  320. break;
  321. case IDC_BROWSECHICO2:
  322. GetDlgItemText(hDlg, IDC_CHANNELICON2, szWrk, ARRAYSIZE(szWrk));
  323. if (BrowseForFile(hDlg, szWrk, ARRAYSIZE(szWrk), GFN_ICO | GFN_PICTURE))
  324. SetDlgItemText(hDlg, IDC_CHANNELICON2, szWrk);
  325. break;
  326. case IDC_BROWSECDF2:
  327. GetDlgItemText(hDlg, IDC_CHANNELURL2, szWrk, ARRAYSIZE(szWrk));
  328. if (BrowseForFile(hDlg, szWrk, ARRAYSIZE(szWrk), GFN_CDF))
  329. SetDlgItemText(hDlg, IDC_CHANNELURL2, szWrk);
  330. break;
  331. case IDC_BROWSECATHTML:
  332. GetDlgItemText(hDlg, IDC_CATEGORYHTML, szWrk, ARRAYSIZE(szWrk));
  333. if (BrowseForFile(hDlg, szWrk, ARRAYSIZE(szWrk), GFN_LOCALHTM))
  334. SetDlgItemText(hDlg, IDC_CATEGORYHTML, szWrk);
  335. break;
  336. case IDCANCEL:
  337. EndDialog( hDlg, IDCANCEL );
  338. break;
  339. case IDOK:
  340. pSelCh = (PCHANNEL)GetWindowLongPtr(hDlg, DWLP_USER);
  341. if (pSelCh->fCategory)
  342. {
  343. GetDlgItemText( hDlg, IDE_CATEGORYTITLE, szTitle, ARRAYSIZE(szTitle) );
  344. GetDlgItemText( hDlg, IDC_CATEGORYHTML, szWebUrl, ARRAYSIZE(szWebUrl) );
  345. }
  346. else
  347. {
  348. GetDlgItemText( hDlg, IDE_CHANNELTITLE2, szTitle, ARRAYSIZE(szTitle) );
  349. GetDlgItemText( hDlg, IDE_CHANNELSRVURL2, szWebUrl, ARRAYSIZE(szWebUrl) );
  350. }
  351. GetDlgItemText( hDlg, IDC_CHANNELBITMAP2, szLogo, ARRAYSIZE(szLogo) );
  352. GetDlgItemText( hDlg, IDC_CHANNELICON2, szIcon, ARRAYSIZE(szIcon) );
  353. if (!pSelCh->fCategory) {
  354. GetDlgItemText(hDlg, IDC_CHANNELURL2, szPreUrlPath, ARRAYSIZE(szPreUrlPath));
  355. pSelCh->fOffline = IsWindowEnabled(GetDlgItem(hDlg, IDC_CHANNELOFFL)) &&
  356. (IsDlgButtonChecked(hDlg, IDC_CHANNELOFFL) == BST_CHECKED);
  357. }
  358. if (pSelCh->fCategory)
  359. {
  360. if (!CheckField(hDlg, IDE_CATEGORYTITLE, FC_NONNULL))
  361. break;
  362. }
  363. else
  364. {
  365. if (!CheckField(hDlg, IDE_CHANNELTITLE2, FC_NONNULL) ||
  366. !CheckField(hDlg, IDE_CHANNELSRVURL2, FC_NONNULL | FC_URL))
  367. break;
  368. }
  369. if (!CheckField(hDlg, IDC_CHANNELBITMAP2, FC_FILE | FC_EXISTS) ||
  370. !CheckField(hDlg, IDC_CHANNELICON2, FC_FILE | FC_EXISTS) ||
  371. (!pSelCh->fCategory && !CheckField(hDlg, IDC_CHANNELURL2, FC_FILE | FC_EXISTS)))
  372. break;
  373. // make sure they're not adding a duplicate channel/category name
  374. if ((StrCmpI(pSelCh->szTitle, szTitle) != 0) &&
  375. (ListBox_GetCount(GetDlgItem(pSelCh->hDlg, IDC_CHANNELLIST))) &&
  376. (ListBox_FindStringExact(GetDlgItem(pSelCh->hDlg, IDC_CHANNELLIST), -1,
  377. szTitle) != LB_ERR))
  378. {
  379. ErrorMessageBox(hDlg, IDS_DUPCHAN);
  380. break;
  381. }
  382. StrCpy(pSelCh->szTitle, szTitle);
  383. StrCpy(pSelCh->szWebUrl, szWebUrl);
  384. StrCpy(pSelCh->szPreUrlPath, szPreUrlPath);
  385. StrCpy(pSelCh->szIcon, szIcon);
  386. StrCpy(pSelCh->szLogo, szLogo);
  387. EndDialog( hDlg, IDOK );
  388. break;
  389. }
  390. break;
  391. }
  392. break;
  393. default:
  394. return FALSE;
  395. }
  396. return TRUE;
  397. }
  398. static PCHANNEL findFreeChannel(HWND hwndList)
  399. {
  400. int i;
  401. PCHANNEL pChan;
  402. for (i=0, pChan=(PCHANNEL)GetWindowLongPtr(hwndList, GWLP_USERDATA);
  403. (i < MAX_CHAN) && (pChan != NULL); i++, pChan++)
  404. {
  405. if (ISNULL(pChan->szTitle))
  406. {
  407. ZeroMemory(pChan, sizeof(CHANNEL));
  408. return pChan;
  409. }
  410. }
  411. return NULL;
  412. }
  413. static void convertUrlToFile(LPTSTR pszUrl)
  414. {
  415. TCHAR szFileName[MAX_PATH];
  416. LPTSTR pFile;
  417. if (ISNULL(pszUrl))
  418. return;
  419. if (StrCmpNI(pszUrl, TEXT("file:"), 5) != 0)
  420. return;
  421. else
  422. {
  423. pFile = pszUrl + 5;
  424. while ((*pFile == TEXT('/')) || (*pFile == TEXT(' ')))
  425. {
  426. pFile++;
  427. }
  428. }
  429. StrCpy(szFileName, pFile);
  430. StrCpy(pszUrl, szFileName);
  431. }
  432. static BOOL importAddChannel(HWND hDlg, LPTSTR pszDir, LPTSTR pszChan, PCHANNEL pChan, BOOL fCategory)
  433. {
  434. TCHAR szDeskIni[MAX_PATH];
  435. DWORD dwSize = sizeof(pChan->szWebUrl);
  436. HKEY hkPreload;
  437. int i;
  438. if (ListBox_FindStringExact(GetDlgItem(hDlg, IDC_CHANNELLIST), -1,
  439. pszChan) != LB_ERR)
  440. return FALSE;
  441. PathCombine(szDeskIni, pszDir, TEXT("Desktop.Ini"));
  442. if (!PathFileExists(szDeskIni))
  443. return FALSE;
  444. pChan->szWebUrl[0] = TEXT('\0');
  445. if (fCategory)
  446. {
  447. GetPrivateProfileString(SHELLCLASSINFO, URL, TEXT(""), pChan->szWebUrl, ARRAYSIZE(pChan->szWebUrl), szDeskIni );
  448. GetPrivateProfileString(SHELLCLASSINFO, LOGO, TEXT(""), pChan->szLogo, ARRAYSIZE(pChan->szLogo), szDeskIni );
  449. GetPrivateProfileString(SHELLCLASSINFO, ICONFILE, TEXT(""), pChan->szIcon, ARRAYSIZE(pChan->szIcon), szDeskIni );
  450. // szWebUrl can be empty (this is valid according to the specs)
  451. if (ISNONNULL(pChan->szWebUrl))
  452. {
  453. // szWebUrl is an 8.3 name; construct the fully qualified path
  454. StrCpy(pChan->szPreUrlPath, pChan->szWebUrl); // szPreUrlPath is used
  455. // as a temp buffer
  456. StrCpy(pChan->szWebUrl, pszDir);
  457. PathAppend(pChan->szWebUrl, pChan->szPreUrlPath);
  458. pChan->szPreUrlPath[0] = TEXT('\0');
  459. }
  460. }
  461. else
  462. {
  463. GetPrivateProfileString(CHANNEL_SECT, CDFURL, TEXT(""), pChan->szWebUrl, ARRAYSIZE(pChan->szWebUrl), szDeskIni );
  464. GetPrivateProfileString(CHANNEL_SECT, LOGO, TEXT(""), pChan->szLogo, ARRAYSIZE(pChan->szLogo), szDeskIni );
  465. GetPrivateProfileString(CHANNEL_SECT, ICON, TEXT(""), pChan->szIcon, ARRAYSIZE(pChan->szIcon), szDeskIni );
  466. if (RegOpenKeyEx(HKEY_CURRENT_USER, PRELOAD_KEY, 0, KEY_DEFAULT_ACCESS, &hkPreload) == ERROR_SUCCESS)
  467. {
  468. if (RegQueryValueEx(hkPreload, pChan->szWebUrl, NULL, NULL, (LPBYTE)pChan->szPreUrlPath, &dwSize) != ERROR_SUCCESS)
  469. pChan->szPreUrlPath[0] = TEXT('\0');
  470. else
  471. convertUrlToFile(pChan->szPreUrlPath); // strip "file://" from szPreUrlPath
  472. RegCloseKey(hkPreload);
  473. }
  474. }
  475. // categories do not need to have an .htm file according to the original channel spec
  476. if (!fCategory && ISNULL(pChan->szWebUrl))
  477. {
  478. ZeroMemory(pChan, sizeof(CHANNEL));
  479. return FALSE;
  480. }
  481. StrCpy(pChan->szTitle, pszChan);
  482. pChan->fCategory = fCategory;
  483. i = (INT) SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_ADDSTRING, 0, (LPARAM)pChan->szTitle);
  484. SendDlgItemMessage(hDlg, IDC_CHANNELLIST, LB_SETITEMDATA, (WPARAM)i, (LPARAM)pChan);
  485. if (ISNULL(pChan->szLogo))
  486. {
  487. if (!getCdfImage(pChan->szWebUrl, pChan->szLogo, WSTR_IMAGE))
  488. pChan->szLogo[0] = TEXT('\0');
  489. }
  490. convertUrlToFile(pChan->szLogo);
  491. if (ISNULL(pChan->szIcon))
  492. {
  493. if (!getCdfImage(pChan->szWebUrl, pChan->szIcon, WSTR_ICON))
  494. pChan->szIcon[0] = TEXT('\0');
  495. }
  496. convertUrlToFile(pChan->szIcon);
  497. return TRUE;
  498. }
  499. static BOOL enumChannels(HWND hDlg, LPTSTR pszDir, LPTSTR pszCat, LPINT pnChannels)
  500. {
  501. WIN32_FIND_DATA fd;
  502. TCHAR szFindPath[MAX_PATH];
  503. HANDLE hFind;
  504. BOOL fCategory = FALSE;
  505. StrCpy(szFindPath, pszDir);
  506. PathAppend(szFindPath, TEXT("*.*"));
  507. hFind = FindFirstFile(szFindPath, &fd);
  508. if (hFind == INVALID_HANDLE_VALUE)
  509. return FALSE;
  510. do
  511. {
  512. TCHAR szSubChan[MAX_PATH];
  513. // NOTE: if pszCat is empty string (""), PathAppend doesn't prefix a
  514. // backslash in szSubChan
  515. StrCpy(szSubChan, pszCat);
  516. PathAppend(szSubChan, fd.cFileName);
  517. if ((StrCmp(fd.cFileName, TEXT(".")) != 0) &&
  518. (StrCmp(fd.cFileName, TEXT("..")) != 0) &&
  519. (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  520. {
  521. TCHAR szSubDir[MAX_PATH];
  522. PathCombine(szSubDir, pszDir, fd.cFileName);
  523. fCategory = TRUE;
  524. if (!enumChannels(hDlg, szSubDir, szSubChan, pnChannels))
  525. return FALSE;
  526. }
  527. } while (FindNextFile(hFind, &fd));
  528. FindClose(hFind);
  529. if (ISNONNULL(pszCat))
  530. {
  531. PCHANNEL pChan = findFreeChannel(GetDlgItem(hDlg, IDC_CHANNELLIST));
  532. if (pChan == NULL) // MAX_CHAN reached
  533. {
  534. EnsureDialogFocus(hDlg, IDC_ADDCHANNEL, IDC_REMOVECHANNEL);
  535. EnableWindow(GetDlgItem(hDlg, IDC_ADDCHANNEL), FALSE);
  536. EnsureDialogFocus(hDlg, IDC_ADDCATEGORY, IDC_REMOVECHANNEL);
  537. EnableWindow(GetDlgItem(hDlg, IDC_ADDCATEGORY), FALSE);
  538. return FALSE;
  539. }
  540. if (importAddChannel(hDlg, pszDir, pszCat, pChan, fCategory))
  541. (*pnChannels)++;
  542. }
  543. return TRUE;
  544. }
  545. static int importChannels(HWND hDlg)
  546. {
  547. DWORD dwLength, dwType;
  548. TCHAR szChanPath[MAX_PATH];
  549. TCHAR szChannelsDir[MAX_PATH];
  550. TCHAR szTemp[MAX_PATH];
  551. HKEY hkFav;
  552. int nChannels = 0;
  553. SetCursor(LoadCursor(NULL, IDC_WAIT) );
  554. // build path to current user favorites
  555. dwLength = MAX_PATH;
  556. if (RegOpenKeyEx( HKEY_CURRENT_USER,
  557. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"),
  558. 0, KEY_DEFAULT_ACCESS, &hkFav ) != ERROR_SUCCESS)
  559. {
  560. return 0;
  561. }
  562. if (RegQueryValueEx( hkFav, TEXT("Favorites"), NULL, &dwType, (LPBYTE) szChanPath, &dwLength ) != ERROR_SUCCESS)
  563. {
  564. RegCloseKey(hkFav);
  565. return 0;
  566. }
  567. RegCloseKey(hkFav);
  568. // write info about Regular Channels
  569. LoadString( g_hInst, IDS_CHANNELSDIR, szChannelsDir, ARRAYSIZE(szChannelsDir) );
  570. PathCombine(szTemp, szChanPath, szChannelsDir);
  571. // The following scenario would arise if you don't upgrade IE5 over IE4 and
  572. // add a channel. In this case, IE5 would add the channel under the
  573. // Favorites folder itself (szChanPath contains the path to the Favorites
  574. // folder)
  575. if (!PathFileExists(szTemp))
  576. StrCpy(szTemp, szChanPath);
  577. enumChannels(hDlg, szTemp, TEXT(""), &nChannels);
  578. return nChannels;
  579. }
  580. static void channels_InitHelper(HWND hDlg, LPCTSTR pcszAltDir, LPCTSTR pcszWorkDir, LPCTSTR pcszCustIns,
  581. WORD idList, DWORD dwPlatformId, BOOL fIgnoreOffline)
  582. {
  583. TCHAR szTempBuf[16];
  584. PCHANNEL paChannels;
  585. PCHANNEL paOldChannels;
  586. int i;
  587. ASSERT(((pcszAltDir == NULL) && (pcszWorkDir == NULL)) ||
  588. ((pcszAltDir != NULL) && (pcszWorkDir != NULL)));
  589. g_dwPlatformId = dwPlatformId;
  590. SendDlgItemMessage(hDlg, idList, LB_RESETCONTENT, 0, 0);
  591. if ((paChannels = (PCHANNEL)CoTaskMemAlloc(sizeof(CHANNEL) * MAX_CHAN)) == NULL)
  592. return;
  593. ZeroMemory(paChannels, sizeof(CHANNEL) * MAX_CHAN);
  594. paOldChannels = (PCHANNEL)SetWindowLongPtr(GetDlgItem(hDlg, idList), GWLP_USERDATA, (LONG_PTR)paChannels);
  595. // delete previous allocation(mainly for profile manager)
  596. if (paOldChannels != NULL)
  597. CoTaskMemFree(paOldChannels);
  598. if (GetPrivateProfileSection(CHANNEL_ADD, szTempBuf, ARRAYSIZE(szTempBuf), pcszCustIns))
  599. {
  600. PCHANNEL pChan;
  601. TCHAR szChTitleParm[16],
  602. szChUrlParm[16],
  603. szChPreUrlParm[32],
  604. szChIconParm[32],
  605. szChBmpParm[32],
  606. szChOfflineParm[16];
  607. int j;
  608. if (StrCmpI(szTempBuf, TEXT("No Channels")) == 0)
  609. return;
  610. for (i = 0, pChan = paChannels; i < MAX_CHAN; i++, pChan++)
  611. {
  612. wnsprintf(szChUrlParm, ARRAYSIZE(szChUrlParm), TEXT("%s%u"), CDFURL, i);
  613. wnsprintf(szChTitleParm, ARRAYSIZE(szChTitleParm), TEXT("%s%u"), CHTITLE, i);
  614. if (GetPrivateProfileString(CHANNEL_ADD, szChTitleParm, TEXT(""), pChan->szTitle, ARRAYSIZE(pChan->szTitle), pcszCustIns) == 0)
  615. break;
  616. GetPrivateProfileString(CHANNEL_ADD, szChUrlParm, TEXT(""), pChan->szWebUrl, ARRAYSIZE(pChan->szWebUrl), pcszCustIns);
  617. wnsprintf(szChPreUrlParm, ARRAYSIZE(szChPreUrlParm), TEXT("%s%u"), CHPREURLPATH, i);
  618. wnsprintf(szChIconParm, ARRAYSIZE(szChIconParm), TEXT("%s%u"), CHICON, i);
  619. wnsprintf(szChBmpParm, ARRAYSIZE(szChBmpParm), TEXT("%s%u"), CHBMP, i);
  620. GetPrivateProfileString(CHANNEL_ADD, szChPreUrlParm, TEXT(""), pChan->szPreUrlPath, ARRAYSIZE(pChan->szPreUrlPath), pcszCustIns);
  621. GetPrivateProfileString(CHANNEL_ADD, szChIconParm,TEXT(""), pChan->szIcon, ARRAYSIZE(pChan->szIcon), pcszCustIns);
  622. GetPrivateProfileString(CHANNEL_ADD, szChBmpParm, TEXT(""), pChan->szLogo, ARRAYSIZE(pChan->szLogo), pcszCustIns);
  623. pChan->fOffline = FALSE;
  624. if (!fIgnoreOffline) {
  625. wnsprintf(szChOfflineParm, ARRAYSIZE(szChOfflineParm), TEXT("%s%u"), IK_CHL_OFFLINE, i);
  626. pChan->fOffline = (BOOL)GetPrivateProfileInt(IS_CHANNEL_ADD, szChOfflineParm, (int)FALSE, pcszCustIns);
  627. }
  628. // delete the files from an alternative dir (desktop dir in profmgr, ieaklite dir
  629. // in wizard), making sure to copy them to the work dir first
  630. if (pcszAltDir != NULL)
  631. {
  632. MoveFileToWorkDir(PathFindFileName(pChan->szPreUrlPath), pcszAltDir, pcszWorkDir, TRUE);
  633. MoveFileToWorkDir(PathFindFileName(pChan->szIcon), pcszAltDir, pcszWorkDir);
  634. MoveFileToWorkDir(PathFindFileName(pChan->szLogo), pcszAltDir, pcszWorkDir);
  635. }
  636. j = (int)SendDlgItemMessage( hDlg, idList, LB_ADDSTRING, 0, (LPARAM) pChan->szTitle);
  637. SendDlgItemMessage(hDlg, idList, LB_SETITEMDATA, (WPARAM)j, (LPARAM)pChan);
  638. }
  639. for (i = 0; i < MAX_CHAN; i++, pChan++)
  640. {
  641. wnsprintf(szChTitleParm, ARRAYSIZE(szChTitleParm), TEXT("%s%u"), CATTITLE, i);
  642. if (GetPrivateProfileString(CHANNEL_ADD, szChTitleParm, TEXT(""), pChan->szTitle, ARRAYSIZE(pChan->szTitle), pcszCustIns) == 0)
  643. break;
  644. pChan->fCategory = TRUE;
  645. wnsprintf(szChUrlParm, ARRAYSIZE(szChUrlParm), TEXT("%s%u"), CATHTML, i);
  646. wnsprintf(szChIconParm, ARRAYSIZE(szChIconParm), TEXT("%s%u"), CATICON, i);
  647. wnsprintf(szChBmpParm, ARRAYSIZE(szChBmpParm), TEXT("%s%u"), CATBMP, i);
  648. GetPrivateProfileString(CHANNEL_ADD, szChUrlParm, TEXT(""), pChan->szWebUrl, ARRAYSIZE(pChan->szWebUrl), pcszCustIns);
  649. GetPrivateProfileString(CHANNEL_ADD, szChIconParm, TEXT(""), pChan->szIcon, ARRAYSIZE(pChan->szIcon), pcszCustIns);
  650. GetPrivateProfileString(CHANNEL_ADD, szChBmpParm, TEXT(""), pChan->szLogo, ARRAYSIZE(pChan->szLogo), pcszCustIns);
  651. pChan->fOffline = FALSE;
  652. // delete the files from the desktop dir
  653. if (pcszAltDir != NULL)
  654. {
  655. MoveFileToWorkDir(PathFindFileName(pChan->szWebUrl), pcszAltDir, pcszWorkDir, TRUE);
  656. MoveFileToWorkDir(PathFindFileName(pChan->szIcon), pcszAltDir, pcszWorkDir, TRUE);
  657. MoveFileToWorkDir(PathFindFileName(pChan->szLogo), pcszAltDir, pcszWorkDir, TRUE);
  658. }
  659. j = (int)SendDlgItemMessage( hDlg, idList, LB_ADDSTRING, 0, (LPARAM) pChan->szTitle);
  660. SendDlgItemMessage(hDlg, idList, LB_SETITEMDATA, (WPARAM)j, (LPARAM)pChan);
  661. }
  662. }
  663. SendDlgItemMessage(hDlg, idList, LB_SETCURSEL, (WPARAM)-1, 0);
  664. }
  665. static void writeIE4Info(HANDLE hInf, int index, PCHANNEL pChan)
  666. {
  667. static const TCHAR c_szInfTitle[] = TEXT("HKCU,\"%s\",\"Title\",,\"%s\"\r\n");
  668. static const TCHAR c_szInfURL_File[] = TEXT("HKCU,\"%s\",\"URL\",,\"%s%%10%%\\web\\%s\"\r\n");
  669. static const TCHAR c_szInfURL_HTTP[] = TEXT("HKCU,\"%s\",\"URL\",,\"%s\"\r\n");
  670. static const TCHAR c_szInfPreloadUrl[] = TEXT("HKCU,\"%s\",\"PreloadURL\",,\"%s%%10%%\\web\\%s\"\r\n");
  671. static const TCHAR c_szInfLogo_File[] = TEXT("HKCU,\"%s\",\"Logo\",,\"%s%%10%%\\web\\%s\"\r\n");
  672. static const TCHAR c_szInfLogo_HTTP[] = TEXT("HKCU,\"%s\",\"Logo\",,\"%s\"\r\n");
  673. static const TCHAR c_szInfIcon_File[] = TEXT("HKCU,\"%s\",\"Icon\",,\"%s%%10%%\\web\\%s\"\r\n");
  674. static const TCHAR c_szInfIcon_HTTP[] = TEXT("HKCU,\"%s\",\"Icon\",,\"%s\"\r\n");
  675. static const TCHAR c_szInfCategory[] = TEXT("HKCU,\"%s\",\"Category\",65537,1\r\n");
  676. TCHAR szKey[MAX_PATH];
  677. TCHAR szInfLine[MAX_PATH];
  678. TCHAR szFileUrlPrefix[ARRAYSIZE(FILEPREFIX)] = TEXT("");
  679. DWORD dwSize;
  680. wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("%%ChannelKey%%\\ieakChl%u"), index);
  681. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfTitle, szKey, pChan->szTitle);
  682. WriteStringToFile(hInf, szInfLine, dwSize);
  683. if (pChan->fCategory)
  684. {
  685. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfCategory, szKey);
  686. WriteStringToFile(hInf, szInfLine, dwSize);
  687. }
  688. else
  689. StrCpy(szFileUrlPrefix, FILEPREFIX);
  690. // BUGBUG: (pritobla) For a category, szWebUrl can be empty; we should take care of this case
  691. if (PathIsFileOrFileURL(pChan->szWebUrl))
  692. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfURL_File, szKey, szFileUrlPrefix, PathFindFileName(pChan->szWebUrl));
  693. else
  694. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfURL_HTTP, szKey, pChan->szWebUrl);
  695. WriteStringToFile(hInf, szInfLine, dwSize);
  696. if (ISNONNULL(pChan->szPreUrlPath))
  697. {
  698. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfPreloadUrl, szKey, szFileUrlPrefix, PathFindFileName(pChan->szPreUrlPath));
  699. WriteStringToFile(hInf, szInfLine, dwSize);
  700. }
  701. if (ISNONNULL(pChan->szLogo))
  702. {
  703. if (PathIsFileOrFileURL(pChan->szLogo))
  704. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfLogo_File, szKey, szFileUrlPrefix, PathFindFileName(pChan->szLogo));
  705. else
  706. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfLogo_HTTP, szKey, pChan->szLogo);
  707. WriteStringToFile(hInf, szInfLine, dwSize);
  708. }
  709. if (ISNONNULL(pChan->szIcon))
  710. {
  711. if (PathIsFileOrFileURL(pChan->szIcon))
  712. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfIcon_File, szKey, szFileUrlPrefix, PathFindFileName(pChan->szIcon));
  713. else
  714. dwSize = wnsprintf(szInfLine, ARRAYSIZE(szInfLine), c_szInfIcon_HTTP, szKey, pChan->szIcon);
  715. WriteStringToFile(hInf, szInfLine, dwSize);
  716. }
  717. }
  718. // The ie4chnls.inf is not made as a template inf file because in the GPE context the
  719. // template inf's will not be available.
  720. static TCHAR szIE4Buf[] = TEXT("[Version]\r\n\
  721. Signature=\"$CHICAGO$\"\r\n\
  722. AdvancedINF=2.5\r\n\r\n\
  723. [DefaultInstall]\r\n\
  724. RequiredEngine=Setupapi,\"Couldn't find Setupapi.dll\"\r\n\
  725. Delreg=IeakChan.DelReg\r\n\
  726. Addreg=IeakChan.AddReg\r\n\
  727. RegisterOCXs=IeakChan.Register\r\n\
  728. DoShellRefresh=1\r\n\r\n\
  729. [IeakChan.Register]\r\n\
  730. %11%\\webcheck.dll,IN,Policy\r\n\r\n\
  731. [IeakChan.DelReg]\r\n\
  732. HKCU,\"Software\\Policies\\Microsoft\\Internet Explorer\\Infodelivery\\CompletedModifications\",\"ChannelDefault\",,,\r\n\r\n\
  733. [Strings]\r\n\
  734. DiskName=\"Channel Files\"\r\n\
  735. ChannelKey=\"Software\\Policies\\Microsoft\\Internet Explorer\\Infodelivery\\Modifications\\ChannelDefault\\AddChannels\"\r\n\
  736. SubKey=\"Software\\Policies\\Microsoft\\Internet Explorer\\Infodelivery\\Modifications\\ChannelDefault\\AddSubscriptions\"\r\n\
  737. CleanKey=\"Software\\Policies\\Microsoft\\Internet Explorer\\Infodelivery\\Modifications\\ChannelDefault\\RemoveAllChannels\"\r\n\r\n\0");
  738. static void channels_SaveHelper(HWND hwndList, LPCTSTR pcszChanDir, LPCTSTR pcszCustIns, DWORD dwMode)
  739. {
  740. PCHANNEL pChan;
  741. PCHANNEL paChannel;
  742. TCHAR szIE4ChnlsInf[MAX_PATH],
  743. szChTitleParm[32],
  744. szChUrlParm[32],
  745. szChPreUrlParm[32],
  746. szChBmpParm[32],
  747. szChIconParm[32],
  748. szChPreUrlNameParm[32],
  749. szChBmpNameParm[32],
  750. szChOfflineParm[16],
  751. szChIconNameParm[32],
  752. szTempPath[MAX_PATH];
  753. LPTSTR pWrk;
  754. HANDLE hInf = NULL;
  755. DWORD dwSize;
  756. int i, j, k;
  757. BOOL fChan = FALSE;
  758. GUID guid;
  759. TCHAR szChlSizeLine[MAX_PATH],
  760. szOemSizeLine[MAX_PATH];
  761. TCHAR szChlSize[5];
  762. TCHAR szOemSize[5];
  763. BYTE bData;
  764. LPTSTR pszBuf;
  765. HKEY hk;
  766. // create a temp path to copy all files to temporarily
  767. GetTempPath(countof(szTempPath), szTempPath);
  768. if (CoCreateGuid(&guid) == NOERROR)
  769. {
  770. TCHAR szGUID[128];
  771. CoStringFromGUID(guid, szGUID, countof(szGUID));
  772. PathAppend(szTempPath, szGUID);
  773. }
  774. else
  775. PathAppend(szTempPath, TEXT("IEAKCHAN"));
  776. PathCreatePath(szTempPath);
  777. WritePrivateProfileString(CHANNEL_ADD, NULL, NULL, pcszCustIns);
  778. WritePrivateProfileString(NULL, NULL, NULL, pcszCustIns);
  779. PathCombine(szIE4ChnlsInf, szTempPath, TEXT("ie4chnls.inf"));
  780. //----- Prepare Channel Size and OEM Size -----
  781. StrCpy(szChlSize, TEXT("0x0B"));
  782. StrCpy(szOemSize, TEXT("0x00"));
  783. if (RegOpenKeyEx(HKEY_CURRENT_USER, DESKTOPKEY, 0, KEY_DEFAULT_ACCESS, &hk) == ERROR_SUCCESS) {
  784. dwSize = sizeof(bData);
  785. if (RegQueryValueEx(hk, CHANNELSIZE, NULL, NULL, &bData, &dwSize) == ERROR_SUCCESS) {
  786. szChlSize[2] = TEXT('\0');
  787. AppendCommaHex(szChlSize, bData, 0);
  788. }
  789. dwSize = sizeof(bData);
  790. if (RegQueryValueEx(hk, OEMSIZE, NULL, NULL, &bData, &dwSize) == ERROR_SUCCESS) {
  791. szOemSize[2] = TEXT('\0');
  792. AppendCommaHex(szOemSize, bData, 0);
  793. }
  794. RegCloseKey(hk);
  795. }
  796. wnsprintf(szChlSizeLine, ARRAYSIZE(szChlSizeLine), REG_KEY_CHAN_SIZE, szChlSize);
  797. wnsprintf(szOemSizeLine, ARRAYSIZE(szOemSizeLine), REG_KEY_OEM_SIZE, szOemSize);
  798. //----- Write the standard goo ---
  799. pszBuf = (LPTSTR)LocalAlloc(LPTR, INF_BUF_SIZE*sizeof(TCHAR));
  800. if (pszBuf == NULL)
  801. return;
  802. dwSize = wnsprintf(pszBuf, INF_BUF_SIZE, TEXT("\r\n[%s]\r\n%s\r\n%s\r\n\r\n"), IEAKCHANADDREG, szChlSizeLine, szOemSizeLine);
  803. hInf = CreateFile(szIE4ChnlsInf, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
  804. if (hInf == INVALID_HANDLE_VALUE) {
  805. LocalFree(pszBuf);
  806. return;
  807. }
  808. SetFilePointer(hInf, 0, NULL, FILE_BEGIN);
  809. WriteStringToFile(hInf, szIE4Buf, ARRAYSIZE(szIE4Buf));
  810. SetFilePointer(hInf, 0, NULL, FILE_END);
  811. WriteStringToFile(hInf, pszBuf, dwSize);
  812. LocalFree(pszBuf);
  813. paChannel = (PCHANNEL)GetWindowLongPtr(hwndList, GWLP_USERDATA);
  814. for (i = 0, j = 0, k = 0, pChan = paChannel; (i < MAX_CHAN) && (pChan != NULL); i++, pChan++)
  815. {
  816. if (ISNULL(pChan->szTitle))
  817. continue;
  818. if (!pChan->fCategory)
  819. {
  820. fChan = TRUE;
  821. wnsprintf(szChTitleParm, ARRAYSIZE(szChTitleParm), TEXT("%s%u"), CHTITLE, j);
  822. wnsprintf(szChUrlParm, ARRAYSIZE(szChUrlParm), TEXT("%s%u"), CDFURL, j);
  823. WritePrivateProfileString(CHANNEL_ADD, szChTitleParm, pChan->szTitle, pcszCustIns);
  824. WritePrivateProfileString(CHANNEL_ADD, szChUrlParm, pChan->szWebUrl, pcszCustIns);
  825. writeIE4Info(hInf, i, pChan);
  826. wnsprintf(szChPreUrlParm, ARRAYSIZE(szChPreUrlParm), TEXT("%s%u"), CHPREURLPATH, j);
  827. wnsprintf(szChIconParm, ARRAYSIZE(szChIconParm), TEXT("%s%u"), CHICON, j);
  828. wnsprintf(szChBmpParm, ARRAYSIZE(szChBmpParm), TEXT("%s%u"), CHBMP, j);
  829. wnsprintf(szChPreUrlNameParm, ARRAYSIZE(szChPreUrlNameParm), TEXT("%s%u"), CHPREURLNAME, j);
  830. wnsprintf(szChIconNameParm, ARRAYSIZE(szChIconNameParm), TEXT("%s%u"), CHICONNAME, j);
  831. wnsprintf(szChBmpNameParm, ARRAYSIZE(szChBmpNameParm), TEXT("%s%u"), CHBMPNAME, j);
  832. wnsprintf(szChOfflineParm, ARRAYSIZE(szChOfflineParm), TEXT("%s%u"), IK_CHL_OFFLINE, j);
  833. WritePrivateProfileString(CHANNEL_ADD, szChPreUrlParm, pChan->szPreUrlPath, pcszCustIns);
  834. pWrk = StrRChr(pChan->szPreUrlPath, NULL, TEXT('\\'));
  835. if (pWrk != NULL)
  836. {
  837. pWrk++;
  838. WritePrivateProfileString( CHANNEL_ADD, szChPreUrlNameParm, pWrk, pcszCustIns );
  839. if (PathFileExists(pChan->szPreUrlPath))
  840. {
  841. CopyFileToDir(pChan->szPreUrlPath, szTempPath);
  842. CopyHtmlImgs(pChan->szPreUrlPath, szTempPath, NULL, NULL);
  843. }
  844. else
  845. {
  846. TCHAR szFile[MAX_PATH];
  847. PathCombine(szFile, pcszChanDir, PathFindFileName(pChan->szPreUrlPath));
  848. CopyFileToDir(szFile, szTempPath);
  849. CopyHtmlImgs(szFile, szTempPath, NULL, NULL);
  850. }
  851. }
  852. WritePrivateProfileString(CHANNEL_ADD, szChIconParm, pChan->szIcon, pcszCustIns);
  853. pWrk = StrRChr(pChan->szIcon, NULL, TEXT('\\'));
  854. if (pWrk != NULL)
  855. {
  856. pWrk++;
  857. WritePrivateProfileString( CHANNEL_ADD, szChIconNameParm, pWrk, pcszCustIns );
  858. if (PathFileExists(pChan->szIcon))
  859. CopyFileToDir(pChan->szIcon, szTempPath);
  860. else
  861. {
  862. TCHAR szFile[MAX_PATH];
  863. PathCombine(szFile, pcszChanDir, PathFindFileName(pChan->szIcon));
  864. CopyFileToDir(szFile, szTempPath);
  865. }
  866. }
  867. WritePrivateProfileString(CHANNEL_ADD, szChBmpParm, pChan->szLogo, pcszCustIns);
  868. pWrk = StrRChr(pChan->szLogo, NULL, TEXT('\\'));
  869. if (pWrk)
  870. {
  871. pWrk++;
  872. WritePrivateProfileString( CHANNEL_ADD, szChBmpNameParm, pWrk, pcszCustIns );
  873. if (PathFileExists(pChan->szLogo))
  874. CopyFileToDir(pChan->szLogo, szTempPath);
  875. else
  876. {
  877. TCHAR szFile[MAX_PATH];
  878. PathCombine(szFile, pcszChanDir, PathFindFileName(pChan->szLogo));
  879. CopyFileToDir(szFile, szTempPath);
  880. }
  881. }
  882. if (pChan->fOffline)
  883. // NOTE: (andrewgu) no need to write NULL on FALSE as the whole section was
  884. // wiped out up above.
  885. WritePrivateProfileString(IS_CHANNEL_ADD, szChOfflineParm, TEXT("1"), pcszCustIns);
  886. j++;
  887. }
  888. else
  889. {
  890. fChan = TRUE;
  891. wnsprintf(szChTitleParm, ARRAYSIZE(szChTitleParm), TEXT("%s%u"), CATTITLE, k);
  892. WritePrivateProfileString(CHANNEL_ADD, szChTitleParm, pChan->szTitle, pcszCustIns);
  893. writeIE4Info(hInf, i, pChan);
  894. wnsprintf(szChPreUrlParm, ARRAYSIZE(szChPreUrlParm), TEXT("%s%u"), CATHTML, k);
  895. wnsprintf(szChIconParm, ARRAYSIZE(szChIconParm), TEXT("%s%u"), CATICON, k);
  896. wnsprintf(szChBmpParm, ARRAYSIZE(szChBmpParm), TEXT("%s%u"), CATBMP, k);
  897. wnsprintf(szChPreUrlNameParm, ARRAYSIZE(szChPreUrlNameParm), TEXT("%s%u"), CATHTMLNAME, k);
  898. wnsprintf(szChIconNameParm, ARRAYSIZE(szChIconNameParm), TEXT("%s%u"), CATICONNAME, k);
  899. wnsprintf(szChBmpNameParm, ARRAYSIZE(szChBmpNameParm), TEXT("%s%u"), CATBMPNAME, k);
  900. WritePrivateProfileString(CHANNEL_ADD, szChPreUrlParm, pChan->szWebUrl, pcszCustIns);
  901. pWrk = StrRChr(pChan->szWebUrl, NULL, TEXT('\\'));
  902. if (pWrk != NULL) // make sure we're not copying over the file as hidden/system
  903. {
  904. DWORD dwFileAttrib;
  905. dwFileAttrib = GetFileAttributes(pChan->szWebUrl);
  906. SetFileAttributes(pChan->szWebUrl, FILE_ATTRIBUTE_NORMAL);
  907. pWrk++;
  908. WritePrivateProfileString( CHANNEL_ADD, szChPreUrlNameParm, pWrk, pcszCustIns );
  909. if (PathFileExists(pChan->szWebUrl))
  910. CopyFileToDir(pChan->szWebUrl, szTempPath);
  911. else
  912. {
  913. TCHAR szFile[MAX_PATH];
  914. PathCombine(szFile, pcszChanDir, PathFindFileName(pChan->szWebUrl));
  915. CopyFileToDir(szFile, szTempPath);
  916. }
  917. SetFileAttributes(pChan->szWebUrl, dwFileAttrib);
  918. }
  919. WritePrivateProfileString(CHANNEL_ADD, szChIconParm, pChan->szIcon, pcszCustIns);
  920. pWrk = StrRChr(pChan->szIcon, NULL, TEXT('\\'));
  921. if (pWrk != NULL)
  922. {
  923. pWrk++;
  924. WritePrivateProfileString( CHANNEL_ADD, szChIconNameParm, pWrk, pcszCustIns );
  925. if (PathFileExists(pChan->szIcon))
  926. CopyFileToDir(pChan->szIcon, szTempPath);
  927. else
  928. {
  929. TCHAR szFile[MAX_PATH];
  930. PathCombine(szFile, pcszChanDir, PathFindFileName(pChan->szIcon));
  931. CopyFileToDir(szFile, szTempPath);
  932. }
  933. }
  934. WritePrivateProfileString(CHANNEL_ADD, szChBmpParm, pChan->szLogo, pcszCustIns);
  935. pWrk = StrRChr(pChan->szLogo, NULL, TEXT('\\'));
  936. if (pWrk != NULL)
  937. {
  938. pWrk++;
  939. WritePrivateProfileString( CHANNEL_ADD, szChBmpNameParm, pWrk, pcszCustIns );
  940. if (PathFileExists(pChan->szLogo))
  941. CopyFileToDir(pChan->szLogo, szTempPath);
  942. else
  943. {
  944. TCHAR szFile[MAX_PATH];
  945. PathCombine(szFile, pcszChanDir, PathFindFileName(pChan->szLogo));
  946. CopyFileToDir(szFile, szTempPath);
  947. }
  948. }
  949. k++;
  950. }
  951. }
  952. PathRemovePath(pcszChanDir);
  953. if (!fChan)
  954. WritePrivateProfileSection(CHANNEL_ADD, TEXT("No Channels\0"), pcszCustIns);
  955. else
  956. {
  957. // copy over all the files from the temp dir back to the working dir
  958. PathCreatePath(pcszChanDir);
  959. CopyFileToDir(szTempPath, pcszChanDir);
  960. }
  961. WritePrivateProfileString(NULL, NULL, NULL, pcszCustIns);
  962. CloseHandle(hInf);
  963. if (fChan)
  964. {
  965. TCHAR szBuf[MAX_PATH];
  966. wnsprintf(szBuf, ARRAYSIZE(szBuf), TEXT("*,ie4chnls.inf,%s"), DEFAULT_INSTALL);
  967. WritePrivateProfileString(EXTREGINF, TEXT("channels"), szBuf, pcszCustIns);
  968. }
  969. else
  970. {
  971. WritePrivateProfileString(EXTREGINF, TEXT("channels"), NULL, pcszCustIns);
  972. DeleteFile(szIE4ChnlsInf);
  973. }
  974. PathRemovePath(szTempPath);
  975. // do not free for profile manager since we might still be on the page due to file save
  976. if (!HasFlag(dwMode, IEM_PROFMGR) && (paChannel != NULL))
  977. {
  978. CoTaskMemFree(paChannel);
  979. SetWindowLong(hwndList, GWLP_USERDATA, NULL);
  980. }
  981. }