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.

985 lines
27 KiB

  1. #include "pch.hxx"
  2. #include <imnact.h>
  3. #include <acctimp.h>
  4. #include <dllmain.h>
  5. #include <resource.h>
  6. #include "CommNews.h"
  7. #include "newimp.h"
  8. #include "ids.h"
  9. ASSERTDATA
  10. INT_PTR CALLBACK SelectServerDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  11. const static char c_szNescapeMapFile[] = "netscape-newsrc-map-file";
  12. #define MEMCHUNK 512
  13. CCommNewsAcctImport::CCommNewsAcctImport()
  14. {
  15. m_cRef = 1;
  16. m_fIni = FALSE;
  17. *m_szIni = 0;
  18. m_cInfo = 0;
  19. m_rgInfo = NULL;
  20. m_szSubList = NULL;
  21. m_rgServ = NULL;
  22. m_nNumServ = 0;
  23. }
  24. CCommNewsAcctImport::~CCommNewsAcctImport()
  25. {
  26. NEWSSERVERS *pTempServ = m_rgServ;
  27. NEWSSERVERS *pNextServ = pTempServ;
  28. if (m_rgInfo != NULL)
  29. MemFree(m_rgInfo);
  30. if(m_szSubList != NULL)
  31. MemFree(m_szSubList);
  32. while(pTempServ)
  33. {
  34. pNextServ = pTempServ->pNext;
  35. delete(pTempServ);
  36. pTempServ = pNextServ;
  37. }
  38. }
  39. STDMETHODIMP CCommNewsAcctImport::QueryInterface(REFIID riid, LPVOID *ppv)
  40. {
  41. if (ppv == NULL)
  42. return(E_INVALIDARG);
  43. *ppv = NULL;
  44. if (IID_IUnknown == riid || riid == IID_IAccountImport)
  45. *ppv = (IAccountImport *)this;
  46. else if (IID_IAccountImport2 == riid)
  47. *ppv = (IAccountImport2 *)this;
  48. else
  49. return(E_NOINTERFACE);
  50. ((LPUNKNOWN)*ppv)->AddRef();
  51. return(S_OK);
  52. }
  53. STDMETHODIMP_(ULONG) CCommNewsAcctImport::AddRef()
  54. {
  55. return(++m_cRef);
  56. }
  57. STDMETHODIMP_(ULONG) CCommNewsAcctImport::Release()
  58. {
  59. if (--m_cRef == 0)
  60. {
  61. delete this;
  62. return(0);
  63. }
  64. return(m_cRef);
  65. }
  66. const static char c_szRegNscp[] = "Software\\Netscape\\Netscape Navigator\\Users";
  67. const static char c_szRegMail[] = "Mail";
  68. const static char c_szRegUser[] = "User";
  69. const static char c_szRegDirRoot[] = "DirRoot";
  70. HRESULT STDMETHODCALLTYPE CCommNewsAcctImport::AutoDetect(DWORD *pcAcct, DWORD dwFlags)
  71. {
  72. HRESULT hr;
  73. DWORD dwNumSubKeys = 0;
  74. DWORD dwIndex = 0;
  75. HRESULT hrUser = E_FAIL;
  76. DWORD cb = MAX_PATH;
  77. char szUserName[MAX_PATH];
  78. char szUserProfile[MAX_PATH];
  79. char szUserPrefs[2][NEWSUSERCOLS], szExpanded[MAX_PATH], *psz;
  80. HKEY hkey,
  81. hkeyUsers;
  82. char szPop[MAX_PATH];
  83. DWORD dwType;
  84. long lRetVal = 0;
  85. Assert(m_cInfo == 0);
  86. if (pcAcct == NULL)
  87. return(E_INVALIDARG);
  88. hr = S_FALSE;
  89. *pcAcct = 0;
  90. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegNscp, 0, KEY_ALL_ACCESS, &hkey))
  91. {
  92. // TODO : Fill up the m_rgInfo array with the info of all
  93. // the users who have accounts in Communicator.
  94. if(ERROR_SUCCESS == RegQueryInfoKey( hkey, NULL, NULL, 0, &dwNumSubKeys,
  95. NULL, NULL, NULL, NULL, NULL, NULL, NULL ) && (dwNumSubKeys > 0))
  96. {
  97. if (!MemAlloc((void **)&m_rgInfo, dwNumSubKeys * sizeof(COMMNEWSACCTINFO)))
  98. {
  99. hr = E_OUTOFMEMORY;
  100. goto done;
  101. }
  102. while(ERROR_SUCCESS == RegEnumKeyEx(hkey, dwIndex, szUserName, &cb, NULL, NULL, NULL, NULL))
  103. {
  104. if(ERROR_SUCCESS == RegOpenKeyEx(hkey, szUserName, 0, KEY_ALL_ACCESS, &hkeyUsers))
  105. {
  106. cb = sizeof(szUserProfile);
  107. if(ERROR_SUCCESS == (lRetVal = RegQueryValueEx(hkeyUsers, c_szRegDirRoot, NULL, &dwType, (LPBYTE)szUserProfile, &cb )))
  108. {
  109. if (REG_EXPAND_SZ == dwType)
  110. {
  111. ExpandEnvironmentStrings(szUserProfile, szExpanded, ARRAYSIZE(szExpanded));
  112. psz = szExpanded;
  113. }
  114. else
  115. psz = szUserProfile;
  116. //save vals into the m_rgInfo structure
  117. hrUser = GetUserPrefs(psz, szUserPrefs, 1, NULL);
  118. if(!FAILED(hrUser))
  119. {
  120. hrUser = IsValidUser(psz);
  121. if(!FAILED(hrUser))
  122. {
  123. m_rgInfo[m_cInfo].dwCookie = m_cInfo;
  124. StrCpyN(m_rgInfo[m_cInfo].szUserPath, psz, ARRAYSIZE(m_rgInfo[m_cInfo].szUserPath));
  125. StrCpyN(m_rgInfo[m_cInfo].szDisplay, szUserName, ARRAYSIZE(m_rgInfo[m_cInfo].szDisplay));
  126. m_cInfo++;
  127. }
  128. }
  129. }
  130. RegCloseKey(hkeyUsers);
  131. }
  132. dwIndex++;
  133. if(dwIndex == dwNumSubKeys)
  134. hr = S_OK;
  135. }
  136. }
  137. }
  138. if (hr == S_OK)
  139. {
  140. *pcAcct = m_cInfo;
  141. }
  142. done:
  143. // Close the reg key now....
  144. RegCloseKey(hkey);
  145. return(hr);
  146. }
  147. typedef struct tagSELSERVER
  148. {
  149. NEWSSERVERS *prgList;
  150. DWORD *dwSelServ;
  151. }SELSERVER;
  152. // This function is called after we select a user profile (in case more than one is present)
  153. // but before the 'GetSettings' finction is called. In case this profile has more than one
  154. // servers configured, we need to display a dialog box asking the user to select a server
  155. // account to import.
  156. HRESULT STDMETHODCALLTYPE CCommNewsAcctImport::InitializeImport(HWND hwnd, DWORD_PTR dwCookie)
  157. {
  158. HRESULT hr;
  159. SELSERVER ss;
  160. int nRetVal = 0;
  161. GetNumAccounts(dwCookie);
  162. if(m_rgServ == NULL)
  163. {
  164. m_dwSelServ = 0;
  165. return S_OK;
  166. }
  167. ss.prgList = m_rgServ;
  168. ss.dwSelServ = &m_dwSelServ;
  169. if(m_nNumServ > 1)
  170. {
  171. nRetVal = (int) DialogBoxParam(g_hInstRes, MAKEINTRESOURCE(IDD_PAGE_NEWSSERVERSELECT), hwnd, SelectServerDlgProc, (LPARAM)&ss);
  172. if (nRetVal == IDCANCEL)
  173. hr = E_FAIL;
  174. else if (nRetVal == IDOK)
  175. hr = S_OK;
  176. else
  177. hr = E_FAIL;
  178. }
  179. else
  180. {
  181. m_dwSelServ = 0;
  182. hr = S_OK;
  183. }
  184. return hr;
  185. }
  186. INT_PTR CALLBACK SelectServerDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  187. {
  188. HWND hwndT;
  189. WORD id;
  190. DWORD iSubKey, cb;
  191. char sz[MAX_PATH];
  192. SELSERVER *pss;
  193. NEWSSERVERS *pTempServ = NULL;
  194. int index;
  195. switch (msg)
  196. {
  197. case WM_INITDIALOG:
  198. Assert(lParam != NULL);
  199. pss = (SELSERVER *)lParam;
  200. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pss);
  201. hwndT = GetDlgItem(hwnd, IDC_ACCTLIST);
  202. // fill list
  203. pTempServ = pss->prgList;
  204. while(pTempServ != NULL)
  205. {
  206. if(lstrlen(pTempServ->szServerName) && lstrlen(pTempServ->szFilePath))
  207. {
  208. SendMessage(hwndT, LB_ADDSTRING, 0, (LPARAM)pTempServ->szServerName);
  209. }
  210. pTempServ = pTempServ->pNext;
  211. }
  212. SendMessage(hwndT, LB_SETCURSEL, 0, 0);
  213. return(TRUE);
  214. case WM_COMMAND:
  215. id = LOWORD(wParam);
  216. switch (id)
  217. {
  218. case IDOK:
  219. pss = (SELSERVER *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  220. Assert(pss != NULL);
  221. hwndT = GetDlgItem(hwnd, IDC_ACCTLIST);
  222. index = (int) SendMessage(hwndT, LB_GETCURSEL, 0, 0);
  223. Assert(index >= 0);
  224. *(pss->dwSelServ) = (long)index;
  225. // fall through
  226. case IDCANCEL:
  227. EndDialog(hwnd, id);
  228. return(TRUE);
  229. }
  230. break;
  231. }
  232. return(FALSE);
  233. }
  234. HRESULT STDMETHODCALLTYPE CCommNewsAcctImport::EnumerateAccounts(IEnumIMPACCOUNTS **ppEnum)
  235. {
  236. CEnumCOMMNEWSACCT *penum;
  237. HRESULT hr;
  238. if (ppEnum == NULL)
  239. return(E_INVALIDARG);
  240. *ppEnum = NULL;
  241. if (m_cInfo == 0)
  242. return(S_FALSE);
  243. Assert(m_rgInfo != NULL);
  244. penum = new CEnumCOMMNEWSACCT;
  245. if (penum == NULL)
  246. return(E_OUTOFMEMORY);
  247. hr = penum->Init(m_rgInfo, m_cInfo);
  248. if (FAILED(hr))
  249. {
  250. penum->Release();
  251. penum = NULL;
  252. }
  253. *ppEnum = penum;
  254. return(hr);
  255. }
  256. HRESULT CCommNewsAcctImport::IsValidUser(char *pszFilePath)
  257. {
  258. char szNewsPath[MAX_PATH * 2];
  259. HANDLE hFatFile = NULL;
  260. DWORD dwFatFileSize = 0;
  261. HRESULT hr = E_FAIL;
  262. StrCpyN(szNewsPath, pszFilePath, ARRAYSIZE(szNewsPath));
  263. StrCatBuff(szNewsPath, "\\News\\fat", ARRAYSIZE(szNewsPath));
  264. hFatFile = CreateFile(szNewsPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  265. if(INVALID_HANDLE_VALUE == hFatFile)
  266. return hr;
  267. dwFatFileSize = GetFileSize(hFatFile, NULL);
  268. if(dwFatFileSize > 0)
  269. hr = S_OK;
  270. CloseHandle(hFatFile);
  271. return hr;
  272. }
  273. // The following two functions have been added to handle the importing of subscribed newsgroups
  274. HRESULT CCommNewsAcctImport::GetNumAccounts(DWORD_PTR dwCookie)
  275. {
  276. COMMNEWSACCTINFO *pinfo;
  277. NEWSSERVERS *pTempServ = NULL;
  278. NEWSSERVERS *pPrevServ = NULL;
  279. HRESULT hr = S_FALSE;
  280. char szNewsPath[MAX_PATH * 2];
  281. char szLineHolder[MAX_PATH * 2];
  282. HANDLE hFatFile = NULL;
  283. HANDLE hFatFileMap = NULL;
  284. BYTE *pFatViewBegin = NULL,
  285. *pFatViewCurr = NULL,
  286. *pFatViewEnd = NULL;
  287. char *pParse = NULL;
  288. char *pServName = NULL;
  289. DWORD dwFatFileSize = 0;
  290. UINT uLine = 0;
  291. char cPlaceHldr = 1;
  292. int nCount = 0;
  293. Assert(((int)dwCookie) >= 0 && dwCookie < (DWORD)m_cInfo);
  294. pinfo = &m_rgInfo[dwCookie];
  295. Assert(pinfo->dwCookie == dwCookie);
  296. StrCpyN(szNewsPath, pinfo->szUserPath, ARRAYSIZE(szNewsPath));
  297. StrCatBuff(szNewsPath, "\\News\\fat", ARRAYSIZE(szNewsPath));
  298. hFatFile = CreateFile(szNewsPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  299. if(INVALID_HANDLE_VALUE == hFatFile)
  300. return hr;
  301. dwFatFileSize = GetFileSize(hFatFile, NULL);
  302. hFatFileMap = CreateFileMapping(hFatFile, NULL, PAGE_READONLY, 0, 0, NULL);
  303. if(NULL == hFatFileMap)
  304. {
  305. CloseHandle(hFatFile);
  306. return hr;
  307. }
  308. pFatViewBegin = (BYTE*)MapViewOfFile(hFatFileMap, FILE_MAP_READ, 0, 0, 0);
  309. if(pFatViewBegin == NULL)
  310. {
  311. CloseHandle(hFatFileMap);
  312. CloseHandle(hFatFile);
  313. return hr;
  314. }
  315. pFatViewCurr = pFatViewBegin;
  316. pFatViewEnd = pFatViewCurr + dwFatFileSize;
  317. pTempServ = m_rgServ;
  318. while(pTempServ)
  319. {
  320. pPrevServ = pTempServ->pNext;
  321. ZeroMemory(pTempServ, sizeof(NEWSSERVERS));
  322. pTempServ->pNext = pPrevServ;
  323. pTempServ = pTempServ->pNext;
  324. }
  325. pTempServ = NULL;
  326. pPrevServ = NULL;
  327. // We will skip the first line in the "fat" file as it contains a comment.
  328. // m_szSubList is a null separated list of
  329. while(pFatViewCurr < pFatViewEnd)
  330. {
  331. uLine = 0;
  332. while(!((pFatViewCurr[uLine] == 0x0D) && (pFatViewCurr[uLine + 1] == 0x0A)) && (pFatViewCurr + uLine < pFatViewEnd))
  333. uLine++;
  334. if(pFatViewCurr + uLine > pFatViewEnd)
  335. break;
  336. StrCpyN(szLineHolder, (char*)pFatViewCurr, uLine + 1);
  337. pServName = szLineHolder;
  338. pParse = szLineHolder;
  339. if(!lstrcmp(szLineHolder, c_szNescapeMapFile))
  340. {
  341. pFatViewCurr += (uLine + 2);
  342. nCount = 0;
  343. continue;
  344. }
  345. while((*pServName != '-') && (*pServName != '\0'))
  346. pServName++;
  347. pServName++;
  348. // Go to the first char '9' position
  349. while((*pParse != '\0') && ((*pParse) != 9))
  350. pParse++;
  351. *pParse = '\0';
  352. // pass over what was originally the first char '9' position
  353. pParse++;
  354. // Trim the remaining string to the second char '9' position.
  355. while(pParse[nCount] != '\0')
  356. {
  357. if((int)pParse[nCount] == 9)
  358. {
  359. pParse[nCount] = '\0';
  360. break;
  361. }
  362. nCount++;
  363. }
  364. if(0 == pPrevServ)
  365. {
  366. if(!m_rgServ)
  367. {
  368. m_rgServ = (NEWSSERVERS*)new NEWSSERVERS;
  369. ZeroMemory((void*)m_rgServ, sizeof(NEWSSERVERS));
  370. }
  371. StrCpyN(m_rgServ->szServerName, pServName, ARRAYSIZE(m_rgServ->szServerName));
  372. StrCpyN(m_rgServ->szFilePath, pParse, ARRAYSIZE(m_rgServ->szFilePath));
  373. pPrevServ = m_rgServ;
  374. }
  375. else
  376. {
  377. if(!pPrevServ->pNext)
  378. {
  379. pPrevServ->pNext = (NEWSSERVERS*)new NEWSSERVERS;
  380. ZeroMemory((void*)pPrevServ->pNext, sizeof(NEWSSERVERS));
  381. }
  382. StrCpyN(pPrevServ->pNext->szServerName, pServName, ARRAYSIZE(pPrevServ->pNext->szServerName));
  383. StrCpyN(pPrevServ->pNext->szFilePath, pParse, ARRAYSIZE(pPrevServ->pNext->szFilePath));
  384. pPrevServ = pPrevServ->pNext;
  385. }
  386. pFatViewCurr += (uLine + 2);
  387. nCount = 0;
  388. }
  389. //replace the cPlaceHldr placeholder by nulls.
  390. hr = S_OK;
  391. pTempServ = m_rgServ;
  392. m_nNumServ = 0;
  393. while(pTempServ != NULL)
  394. {
  395. if(lstrlen(pTempServ->szServerName) && lstrlen(pTempServ->szFilePath))
  396. {
  397. m_nNumServ += 1;
  398. }
  399. pTempServ = pTempServ->pNext;
  400. }
  401. // Done:
  402. CloseHandle(hFatFileMap);
  403. CloseHandle(hFatFile);
  404. UnmapViewOfFile(pFatViewBegin);
  405. return hr;
  406. }
  407. HRESULT CCommNewsAcctImport::GetNewsGroup(INewsGroupImport *pImp, DWORD dwReserved) //char *szServerName, char *szAccountName)
  408. {
  409. HRESULT hr = S_OK;
  410. HINSTANCE hInstance = NULL;
  411. char *pListGroups = NULL;
  412. NEWSSERVERS *pTempServ = NULL;
  413. NEWSSERVERS *pPrevServ = NULL;
  414. char szTempString[NEWSUSERCOLS];
  415. char szFilePath[NEWSUSERCOLS];
  416. int nReach = 0;
  417. szFilePath[0] = '\0';
  418. Assert(m_nNumServ > m_dwSelServ);
  419. Assert(pImp != NULL);
  420. pTempServ = m_rgServ;
  421. for(DWORD nTemp1 = 0; nTemp1 < m_dwSelServ; nTemp1++)
  422. {
  423. pTempServ = pTempServ->pNext;
  424. if(pTempServ == NULL)
  425. return S_FALSE;
  426. }
  427. if(!FAILED(GetSubListGroups(pTempServ->szFilePath, &pListGroups)))
  428. {
  429. if(!SUCCEEDED(pImp->ImportSubList(pListGroups)))
  430. hr = S_FALSE;
  431. }
  432. if(pListGroups != NULL)
  433. MemFree(pListGroups);
  434. return hr;
  435. }
  436. HRESULT CCommNewsAcctImport::GetSubListGroups(char *pFileName, char **ppListGroups)
  437. {
  438. HRESULT hr = E_FAIL;
  439. HANDLE hRCHandle = NULL;
  440. HANDLE hRCFile = NULL;
  441. ULONG cbRCFile = 0;
  442. BYTE *pBegin = NULL,
  443. *pCurr = NULL,
  444. *pEnd = NULL;
  445. int nBalMem = MEMCHUNK;
  446. int nLine = 0,
  447. nCount = 0;
  448. char cPlaceHolder = 1;
  449. char szLineHolder[MEMCHUNK];
  450. char *pListGroups = NULL;
  451. Assert(lstrlen(pFileName));
  452. Assert(ppListGroups);
  453. *ppListGroups = NULL;
  454. hRCHandle = CreateFile( pFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  455. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  456. if(hRCHandle == INVALID_HANDLE_VALUE)
  457. return hr;
  458. cbRCFile = GetFileSize(hRCHandle, NULL);
  459. if(!cbRCFile) // Empty File.
  460. goto Done;
  461. hRCFile = CreateFileMapping(hRCHandle, NULL, PAGE_READONLY, 0, 0, NULL);
  462. if(hRCFile == NULL)
  463. {
  464. CloseHandle(hRCHandle);
  465. return hr;
  466. }
  467. pBegin = (BYTE *)MapViewOfFile( hRCFile, FILE_MAP_READ, 0, 0, 0);
  468. if(pBegin == NULL)
  469. {
  470. CloseHandle(hRCHandle);
  471. CloseHandle(hRCFile);
  472. return hr;
  473. }
  474. pCurr = pBegin;
  475. pEnd = pCurr + cbRCFile;
  476. if (!MemAlloc((void **)&pListGroups, MEMCHUNK))
  477. {
  478. hr = E_OUTOFMEMORY;
  479. goto Done;
  480. }
  481. DWORD cchSizeListGroups = MEMCHUNK;
  482. ZeroMemory((void*)pListGroups, (cchSizeListGroups * sizeof(pListGroups[0])));
  483. while (pCurr < pEnd)
  484. {
  485. nLine = 0;
  486. while(!((pCurr[nLine] == ':') || (pCurr[nLine] == '!')) && (pCurr + nLine < pEnd))
  487. nLine++;
  488. if(pCurr + nLine > pEnd)
  489. break;
  490. if(pCurr[nLine] == '!')
  491. goto LineEnd;
  492. nLine++;
  493. if(nLine < MEMCHUNK)
  494. StrCpyN(szLineHolder, (char*)pCurr, nLine);
  495. else
  496. continue;
  497. if(nLine + 2 < nBalMem)
  498. {
  499. StrCatBuff(pListGroups, szLineHolder, cchSizeListGroups);
  500. StrCatBuff(pListGroups, "\1", cchSizeListGroups);
  501. nBalMem -= (nLine + 2);
  502. }
  503. else
  504. {
  505. cchSizeListGroups += (lstrlen(pListGroups) + 1 + MEMCHUNK);
  506. if(!MemRealloc((void **)&pListGroups, (cchSizeListGroups * sizeof(pListGroups[0]))))
  507. {
  508. hr = E_OUTOFMEMORY;
  509. goto Done;
  510. }
  511. nBalMem += MEMCHUNK;
  512. StrCatBuff(pListGroups, szLineHolder, cchSizeListGroups);
  513. StrCatBuff(pListGroups, "\1", cchSizeListGroups);
  514. nBalMem -= (nLine + 2);
  515. }
  516. LineEnd:
  517. while(!((pCurr[nLine] == 0x0D) && (pCurr[nLine + 1] == 0x0A)) && (pCurr + nLine < pEnd))
  518. nLine++;
  519. pCurr += (nLine + 2);
  520. }
  521. if(lstrlen(pListGroups))
  522. {
  523. while(pListGroups[nCount] != '\0')
  524. {
  525. if(pListGroups[nCount] == cPlaceHolder)
  526. {
  527. pListGroups[nCount] = '\0';
  528. }
  529. nCount++;
  530. }
  531. *ppListGroups = pListGroups;
  532. hr = S_OK;
  533. }
  534. Done:
  535. if(pBegin)
  536. UnmapViewOfFile(pBegin);
  537. if(hRCHandle != INVALID_HANDLE_VALUE)
  538. CloseHandle(hRCHandle);
  539. if(hRCFile)
  540. CloseHandle(hRCFile);
  541. return hr;
  542. }
  543. const static char c_szSearch[][NEWSUSERCOLS] = {"user_pref(\"network.hosts.nntp_server\"",
  544. "user_pref(\"news.server_port\"",
  545. "user_pref(\"mail.identity.username\"", // This is the same for NNTP also.
  546. "user_pref(\"mail.identity.useremail\""};
  547. const static char c_szPrefs[] = "\\prefs.js";
  548. HRESULT CCommNewsAcctImport::GetUserPrefs(char *szUserPath, char szUserPrefs[][NEWSUSERCOLS], int nInLoop, BOOL *pbPop)
  549. {
  550. HRESULT hr = E_FAIL;
  551. char szTemp[MAX_PATH * 2];
  552. char szDirpath[250];
  553. char szLine[1000];
  554. char szCompare[1000];
  555. int nLine = 0;
  556. int nFilled = 0;
  557. int nPosition = 0;
  558. int nLoop = nInLoop;
  559. HANDLE hJSHandle = NULL;
  560. HANDLE hJSFile = NULL;
  561. ULONG cbJSFile = 0;
  562. BYTE *pBegin = NULL,
  563. *pCurr = NULL,
  564. *pEnd = NULL;
  565. Assert(nInLoop <= NEWSUSERROWS);
  566. StrCpyN(szTemp, szUserPath, ARRAYSIZE(szTemp));
  567. StrCatBuff(szTemp, c_szPrefs, ARRAYSIZE(szTemp));
  568. hJSHandle = CreateFile( szTemp, GENERIC_READ, FILE_SHARE_READ, NULL,
  569. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  570. if(hJSHandle == INVALID_HANDLE_VALUE)
  571. return hr;
  572. cbJSFile = GetFileSize(hJSHandle, NULL);
  573. hJSFile = CreateFileMapping(hJSHandle, NULL, PAGE_READONLY, 0, 0, NULL);
  574. if(hJSFile == NULL)
  575. {
  576. CloseHandle(hJSHandle);
  577. return hr;
  578. }
  579. pBegin = (BYTE *)MapViewOfFile( hJSFile, FILE_MAP_READ, 0, 0, 0);
  580. if(pBegin == NULL)
  581. {
  582. CloseHandle(hJSHandle);
  583. CloseHandle(hJSFile);
  584. return hr;
  585. }
  586. pCurr = pBegin;
  587. pEnd = pCurr + cbJSFile;
  588. while (pCurr < pEnd)
  589. {
  590. szLine[nLine] = *pCurr; //keep storing here. will be used for comparing later.
  591. if((pCurr[0] == 0x0D) && (pCurr[1] == 0x0A))
  592. {
  593. while(nLoop)
  594. {
  595. StrCpyN(szCompare, szLine, lstrlen(c_szSearch[nLoop - 1]) + 1);
  596. if(lstrcmp(szCompare, c_szSearch[nLoop - 1]) == 0)
  597. {
  598. //Found a UserPref one of the things we are looking for"!
  599. //Extract the stuff we want.
  600. nPosition = lstrlen(c_szSearch[nLoop - 1]);
  601. while (((szLine[nPosition] == '"')||(szLine[nPosition] == ' ')||(szLine[nPosition] == ',')) &&(nPosition < nLine))
  602. nPosition++;
  603. StrCpyN(szDirpath, &szLine[nPosition], nLine - nPosition);
  604. //Now trim the trailing edge!!!
  605. nPosition = lstrlen(szDirpath) - 1;
  606. while((szDirpath[nPosition] == '"') || (szDirpath[nPosition] == ')')||(szDirpath[nPosition] == ';'))
  607. {
  608. szDirpath[nPosition] = '\0';
  609. nPosition = lstrlen(szDirpath) - 1;
  610. }
  611. StrCpyN(szUserPrefs[nLoop - 1], szDirpath, NEWSUSERCOLS);
  612. nFilled++;
  613. if(nFilled == nInLoop)
  614. break;
  615. }
  616. nLoop--;
  617. }
  618. nLoop = nInLoop;
  619. nLine = -1; //the nLine++ that follows will make nLine zero.
  620. pCurr++;
  621. }
  622. if(nFilled == nInLoop)
  623. break;
  624. pCurr++;
  625. nLine++;
  626. }
  627. if(pBegin)
  628. UnmapViewOfFile(pBegin);
  629. if(hJSHandle != INVALID_HANDLE_VALUE)
  630. CloseHandle(hJSHandle);
  631. if(hJSFile)
  632. CloseHandle(hJSFile);
  633. if(nFilled == 0)
  634. return E_FAIL;
  635. else
  636. {
  637. if(nInLoop == 1) //If this function was called only to check the server enties...
  638. {
  639. if(lstrlen(szUserPrefs[0]))
  640. return S_OK;
  641. else
  642. return E_FAIL;
  643. }
  644. return S_OK;
  645. }
  646. }
  647. HRESULT CCommNewsAcctImport::GetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct)
  648. {
  649. HRESULT hr;
  650. if (pAcct == NULL)
  651. return(E_INVALIDARG);
  652. hr = IGetSettings(dwCookie, pAcct, NULL);
  653. return(hr);
  654. }
  655. HRESULT CCommNewsAcctImport::IGetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  656. {
  657. NEWSSERVERS *pPrevServ = m_rgServ;
  658. COMMNEWSACCTINFO *pinfo;
  659. char szUserPrefs[NEWSUSERROWS][NEWSUSERCOLS];
  660. char sz[512];
  661. DWORD cb, type;
  662. HRESULT hr;
  663. BOOL bPop = TRUE;
  664. char szNntpServ[NEWSUSERCOLS];
  665. char szNntpPort[NEWSUSERCOLS];
  666. szNntpPort[0] = '\0';
  667. int nReach = 0;
  668. DWORD dwNewsPort = 119;
  669. Assert(pPrevServ);
  670. Assert(m_dwSelServ < m_nNumServ);
  671. for(DWORD nCount = 0; nCount < m_dwSelServ; nCount++)
  672. pPrevServ = pPrevServ->pNext;
  673. StrCpyN(szNntpServ, pPrevServ->szServerName, ARRAYSIZE(szNntpServ));
  674. while(szNntpServ[nReach] != '\0')
  675. {
  676. if(szNntpServ[nReach] == ':')
  677. {
  678. szNntpServ[nReach] = '\0';
  679. StrCpyN(szNntpPort, &szNntpServ[nReach+1], ARRAYSIZE(szNntpPort));
  680. break;
  681. }
  682. nReach++;
  683. }
  684. Assert(lstrlen(szNntpServ) > 0);
  685. ZeroMemory((void*)&szUserPrefs[0], NEWSUSERCOLS*NEWSUSERROWS*sizeof(char));
  686. Assert(((int) dwCookie) >= 0 && dwCookie < (DWORD_PTR)m_cInfo);
  687. pinfo = &m_rgInfo[dwCookie];
  688. Assert(pinfo->dwCookie == dwCookie);
  689. hr = GetUserPrefs(pinfo->szUserPath, szUserPrefs, NEWSUSERROWS, &bPop);
  690. Assert(!FAILED(hr));
  691. hr = pAcct->SetPropSz(AP_ACCOUNT_NAME, szNntpServ);
  692. if (FAILED(hr))
  693. return(hr);
  694. hr = pAcct->SetPropSz(AP_NNTP_SERVER, szNntpServ);
  695. Assert(!FAILED(hr));
  696. int Len = lstrlen(szNntpPort);
  697. if(Len)
  698. {
  699. // Convert the string to a dw.
  700. DWORD dwMult = 1;
  701. dwNewsPort = 0;
  702. while(Len)
  703. {
  704. Len--;
  705. dwNewsPort += ((int)szNntpPort[Len] - 48)*dwMult;
  706. dwMult *= 10;
  707. }
  708. }
  709. hr = pAcct->SetPropDw(AP_NNTP_PORT, dwNewsPort);
  710. Assert(!FAILED(hr));
  711. if(lstrlen(szUserPrefs[2]))
  712. {
  713. hr = pAcct->SetPropSz(AP_NNTP_DISPLAY_NAME, szUserPrefs[2]);
  714. Assert(!FAILED(hr));
  715. }
  716. if(lstrlen(szUserPrefs[3]))
  717. {
  718. hr = pAcct->SetPropSz(AP_NNTP_EMAIL_ADDRESS, szUserPrefs[3]);
  719. Assert(!FAILED(hr));
  720. }
  721. if (pInfo != NULL)
  722. {
  723. // TODO: can we do any better than this???
  724. pInfo->dwConnect = CONN_USE_DEFAULT;
  725. }
  726. return(S_OK);
  727. }
  728. STDMETHODIMP CCommNewsAcctImport::GetSettings2(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  729. {
  730. if (pAcct == NULL ||
  731. pInfo == NULL)
  732. return(E_INVALIDARG);
  733. return(IGetSettings(dwCookie, pAcct, pInfo));
  734. }
  735. CEnumCOMMNEWSACCT::CEnumCOMMNEWSACCT()
  736. {
  737. m_cRef = 1;
  738. // m_iInfo
  739. m_cInfo = 0;
  740. m_rgInfo = NULL;
  741. }
  742. CEnumCOMMNEWSACCT::~CEnumCOMMNEWSACCT()
  743. {
  744. if (m_rgInfo != NULL)
  745. MemFree(m_rgInfo);
  746. }
  747. STDMETHODIMP CEnumCOMMNEWSACCT::QueryInterface(REFIID riid, LPVOID *ppv)
  748. {
  749. if (ppv == NULL)
  750. return(E_INVALIDARG);
  751. *ppv = NULL;
  752. if (IID_IUnknown == riid)
  753. *ppv = (IUnknown *)this;
  754. else if (IID_IEnumIMPACCOUNTS == riid)
  755. *ppv = (IEnumIMPACCOUNTS *)this;
  756. if (*ppv != NULL)
  757. ((LPUNKNOWN)*ppv)->AddRef();
  758. else
  759. return(E_NOINTERFACE);
  760. return(S_OK);
  761. }
  762. STDMETHODIMP_(ULONG) CEnumCOMMNEWSACCT::AddRef()
  763. {
  764. return(++m_cRef);
  765. }
  766. STDMETHODIMP_(ULONG) CEnumCOMMNEWSACCT::Release()
  767. {
  768. if (--m_cRef == 0)
  769. {
  770. delete this;
  771. return(0);
  772. }
  773. return(m_cRef);
  774. }
  775. HRESULT STDMETHODCALLTYPE CEnumCOMMNEWSACCT::Next(IMPACCOUNTINFO *pinfo)
  776. {
  777. if (pinfo == NULL)
  778. return(E_INVALIDARG);
  779. m_iInfo++;
  780. if ((UINT)m_iInfo >= m_cInfo)
  781. return(S_FALSE);
  782. Assert(m_rgInfo != NULL);
  783. pinfo->dwCookie = m_rgInfo[m_iInfo].dwCookie;
  784. pinfo->dwReserved = 0;
  785. StrCpyN(pinfo->szDisplay, m_rgInfo[m_iInfo].szDisplay, ARRAYSIZE(pinfo->szDisplay));
  786. return(S_OK);
  787. }
  788. HRESULT STDMETHODCALLTYPE CEnumCOMMNEWSACCT::Reset()
  789. {
  790. m_iInfo = -1;
  791. return(S_OK);
  792. }
  793. HRESULT CEnumCOMMNEWSACCT::Init(COMMNEWSACCTINFO *pinfo, int cinfo)
  794. {
  795. DWORD cb;
  796. Assert(pinfo != NULL);
  797. Assert(cinfo > 0);
  798. cb = cinfo * sizeof(COMMNEWSACCTINFO);
  799. if (!MemAlloc((void **)&m_rgInfo, cb))
  800. return(E_OUTOFMEMORY);
  801. m_iInfo = -1;
  802. m_cInfo = cinfo;
  803. CopyMemory(m_rgInfo, pinfo, cb);
  804. return(S_OK);
  805. }