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

486 lines
12 KiB

  1. #include "pch.hxx"
  2. #include <imnact.h>
  3. #include <acctimp.h>
  4. #include <dllmain.h>
  5. #include <resource.h>
  6. #include "eudora.h"
  7. #include "demand.h"
  8. ASSERTDATA
  9. CEudoraAcctImport::CEudoraAcctImport()
  10. {
  11. m_cRef = 1;
  12. *m_szIni = 0;
  13. m_cInfo = 0;
  14. m_rgInfo = NULL;
  15. }
  16. CEudoraAcctImport::~CEudoraAcctImport()
  17. {
  18. if (m_rgInfo != NULL)
  19. MemFree(m_rgInfo);
  20. }
  21. STDMETHODIMP CEudoraAcctImport::QueryInterface(REFIID riid, LPVOID *ppv)
  22. {
  23. if (ppv == NULL)
  24. return(E_INVALIDARG);
  25. *ppv = NULL;
  26. if (IID_IUnknown == riid)
  27. *ppv = (IAccountImport *)this;
  28. else if (IID_IAccountImport == riid)
  29. *ppv = (IAccountImport *)this;
  30. else if (IID_IAccountImport2 == riid)
  31. *ppv = (IAccountImport2 *)this;
  32. else
  33. return(E_NOINTERFACE);
  34. ((LPUNKNOWN)*ppv)->AddRef();
  35. return(S_OK);
  36. }
  37. STDMETHODIMP_(ULONG) CEudoraAcctImport::AddRef()
  38. {
  39. return(++m_cRef);
  40. }
  41. STDMETHODIMP_(ULONG) CEudoraAcctImport::Release()
  42. {
  43. if (--m_cRef == 0)
  44. {
  45. delete this;
  46. return(0);
  47. }
  48. return(m_cRef);
  49. }
  50. const static char c_szRegEudora[] = "Software\\Qualcomm\\Eudora\\CommandLine";
  51. const static char c_szCmdValue[] = "Current";
  52. HRESULT STDMETHODCALLTYPE CEudoraAcctImport::AutoDetect(DWORD *pcAcct, DWORD dwFlags)
  53. {
  54. HRESULT hr;
  55. HKEY hkey;
  56. char *szCmdLine, *sz, *psz, szExpanded[MAX_PATH];
  57. DWORD type, cb;
  58. if (pcAcct == NULL)
  59. return(E_INVALIDARG);
  60. hr = S_FALSE;
  61. *pcAcct = 0;
  62. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegEudora, 0, KEY_ALL_ACCESS, &hkey))
  63. {
  64. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szCmdValue, NULL, &type, NULL, &cb) &&
  65. cb > 0 &&
  66. ((type == REG_SZ) || (type == REG_EXPAND_SZ)))
  67. {
  68. if (MemAlloc((void **)&szCmdLine, cb))
  69. {
  70. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szCmdValue, NULL, &type, (LPBYTE)szCmdLine, &cb))
  71. {
  72. sz = szCmdLine;
  73. sz = PszSkipWhiteA(sz);
  74. sz = PszScanToWhiteA(sz);
  75. sz = PszSkipWhiteA(sz);
  76. sz = PszScanToWhiteA(sz);
  77. sz = PszSkipWhiteA(sz);
  78. if (REG_EXPAND_SZ == type)
  79. {
  80. ExpandEnvironmentStrings(sz, szExpanded, ARRAYSIZE(szExpanded));
  81. psz = szExpanded;
  82. }
  83. else
  84. psz=sz;
  85. if (*psz != 0 && 0xffffffff != GetFileAttributes(psz))
  86. hr = InitAccounts(psz);
  87. }
  88. MemFree(szCmdLine);
  89. }
  90. else
  91. {
  92. hr = E_OUTOFMEMORY;
  93. }
  94. }
  95. RegCloseKey(hkey);
  96. }
  97. // TODO: if we haven't found the ini file in the reg,
  98. // let's search for it...
  99. if (hr == S_OK)
  100. *pcAcct = m_cInfo;
  101. return(hr);
  102. }
  103. HRESULT STDMETHODCALLTYPE CEudoraAcctImport::EnumerateAccounts(IEnumIMPACCOUNTS **ppEnum)
  104. {
  105. CEnumEUDORAACCTS *penum;
  106. HRESULT hr;
  107. if (ppEnum == NULL)
  108. return(E_INVALIDARG);
  109. *ppEnum = NULL;
  110. if (m_cInfo == 0)
  111. return(S_FALSE);
  112. Assert(m_rgInfo != NULL);
  113. penum = new CEnumEUDORAACCTS;
  114. if (penum == NULL)
  115. return(E_OUTOFMEMORY);
  116. hr = penum->Init(m_rgInfo, m_cInfo);
  117. if (FAILED(hr))
  118. {
  119. penum->Release();
  120. penum = NULL;
  121. }
  122. *ppEnum = penum;
  123. return(hr);
  124. }
  125. HRESULT STDMETHODCALLTYPE CEudoraAcctImport::GetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct)
  126. {
  127. if (pAcct == NULL)
  128. return(E_INVALIDARG);
  129. return(IGetSettings(dwCookie, pAcct, NULL));
  130. }
  131. HRESULT STDMETHODCALLTYPE CEudoraAcctImport::GetSettings2(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  132. {
  133. if (pAcct == NULL ||
  134. pInfo == NULL)
  135. return(E_INVALIDARG);
  136. return(IGetSettings(dwCookie, pAcct, pInfo));
  137. }
  138. const static char c_szEmpty[] = "";
  139. const static char c_szRealName[] = "RealName";
  140. const static char c_szSmtpServer[] = "SMTPServer";
  141. const static char c_szReturnAddress[] = "ReturnAddress";
  142. const static char c_szPopAccount[] = "POPAccount";
  143. const static char c_szLeaveMailOnServer[] = "LeaveMailOnServer";
  144. const static char c_szUsesIMAP[] = "UsesIMAP";
  145. const static char c_szUsesPOP[] = "UsesPOP";
  146. const static char c_sz1[] = "1";
  147. const static char c_szConnName[] = "AutoConnectionName";
  148. HRESULT CEudoraAcctImport::IGetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  149. {
  150. BOOL fSMTP, fEmail, fPop;
  151. EUDORAACCTINFO *pinfo;
  152. char sz[512], *szT;
  153. DWORD cb;
  154. HRESULT hr;
  155. Assert(pAcct != NULL);
  156. fSMTP = FALSE;
  157. fEmail = FALSE;
  158. Assert(((int) dwCookie) >= 0 && dwCookie < (DWORD_PTR)m_cInfo);
  159. pinfo = &m_rgInfo[dwCookie];
  160. Assert(pinfo->dwCookie == dwCookie);
  161. hr = pAcct->SetPropSz(AP_ACCOUNT_NAME, pinfo->szDisplay);
  162. if (FAILED(hr))
  163. return(hr);
  164. cb = GetPrivateProfileString(pinfo->szSection, c_szRealName, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  165. if (cb > 0 && !FIsEmpty(sz))
  166. {
  167. hr = pAcct->SetPropSz(AP_SMTP_DISPLAY_NAME, sz);
  168. Assert(!FAILED(hr));
  169. }
  170. cb = GetPrivateProfileString(pinfo->szSection, c_szSmtpServer, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  171. if (cb > 0 && !FIsEmpty(sz))
  172. {
  173. hr = pAcct->SetPropSz(AP_SMTP_SERVER, sz);
  174. Assert(!FAILED(hr));
  175. fSMTP = TRUE;
  176. }
  177. cb = GetPrivateProfileString(pinfo->szSection, c_szReturnAddress, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  178. if (cb > 0 && !FIsEmpty(sz))
  179. {
  180. hr = pAcct->SetPropSz(AP_SMTP_EMAIL_ADDRESS, sz);
  181. Assert(!FAILED(hr));
  182. fEmail = TRUE;
  183. }
  184. fPop = TRUE;
  185. cb = GetPrivateProfileString(pinfo->szSection, c_szUsesPOP, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  186. if (cb == 0 || 0 != lstrcmp(sz, c_sz1))
  187. {
  188. cb = GetPrivateProfileString(pinfo->szSection, c_szUsesIMAP, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  189. if (cb > 0 && 0 == lstrcmp(sz, c_sz1))
  190. fPop = FALSE;
  191. }
  192. cb = GetPrivateProfileString(pinfo->szSection, c_szPopAccount, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  193. if (cb > 0 && !FIsEmpty(sz))
  194. {
  195. if (!fEmail)
  196. {
  197. hr = pAcct->SetPropSz(AP_SMTP_EMAIL_ADDRESS, sz);
  198. Assert(!FAILED(hr));
  199. }
  200. szT = PszScanToCharA(sz, '@');
  201. if (*szT)
  202. {
  203. *szT = 0;
  204. szT++;
  205. hr = pAcct->SetPropSz(fPop ? AP_POP3_USERNAME : AP_IMAP_USERNAME, sz);
  206. Assert(!FAILED(hr));
  207. hr = pAcct->SetPropSz(fPop ? AP_POP3_SERVER : AP_IMAP_SERVER, szT);
  208. Assert(!FAILED(hr));
  209. if (!fSMTP)
  210. {
  211. hr = pAcct->SetPropSz(AP_SMTP_SERVER, szT);
  212. Assert(!FAILED(hr));
  213. }
  214. }
  215. }
  216. if (fPop)
  217. {
  218. cb = GetPrivateProfileString(pinfo->szSection, c_szLeaveMailOnServer, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  219. if (cb > 0 && 0 == lstrcmp(sz, c_sz1))
  220. {
  221. hr = pAcct->SetPropDw(AP_POP3_LEAVE_ON_SERVER, 1);
  222. Assert(!FAILED(hr));
  223. }
  224. }
  225. if (pInfo != NULL)
  226. {
  227. cb = GetPrivateProfileString(pinfo->szSection, c_szConnName, c_szEmpty, sz, ARRAYSIZE(sz), m_szIni);
  228. if (cb > 0 && !FIsEmpty(sz))
  229. {
  230. pInfo->dwConnect = CONN_USE_SETTINGS;
  231. pInfo->dwConnectType = CONNECTION_TYPE_RAS;
  232. lstrcpyn(pInfo->szConnectoid, sz, ARRAYSIZE(pInfo->szConnectoid));
  233. }
  234. else
  235. {
  236. // TODO: determine if we need to create a connectoid
  237. pInfo->dwConnect = CONN_USE_DEFAULT;
  238. }
  239. }
  240. return(S_OK);
  241. }
  242. const static char c_szPersona[] = "Personalities";
  243. const static char c_szSettings[] = "Settings";
  244. #define CALLOCINFO 8
  245. #define CALLOCSETTINGS 0x07fff
  246. HRESULT CEudoraAcctImport::InitAccounts(char *szIni)
  247. {
  248. HRESULT hr;
  249. DWORD cch, cInfoBuf;
  250. char *szBuf, *szKey, *szVal;
  251. Assert(m_cInfo == 0);
  252. Assert(m_rgInfo == NULL);
  253. if (!MemAlloc((void **)&szBuf, CALLOCSETTINGS))
  254. return(E_OUTOFMEMORY);
  255. hr = E_FAIL;
  256. cch = GetPrivateProfileSection(c_szSettings, szBuf, 0x07fff, szIni);
  257. if (cch != 0)
  258. {
  259. if (!MemAlloc((void **)&m_rgInfo, CALLOCINFO * sizeof(EUDORAACCTINFO)))
  260. {
  261. hr = E_OUTOFMEMORY;
  262. goto done;
  263. }
  264. cInfoBuf = CALLOCINFO;
  265. m_rgInfo[m_cInfo].dwCookie = m_cInfo;
  266. lstrcpy(m_rgInfo[m_cInfo].szSection, c_szSettings);
  267. LoadString(g_hInstRes, idsDefaultAccount, m_rgInfo[m_cInfo].szDisplay, ARRAYSIZE(m_rgInfo[m_cInfo].szDisplay));
  268. m_cInfo++;
  269. cch = GetPrivateProfileSection(c_szPersona, szBuf, 0x07fff, szIni);
  270. if (cch != 0)
  271. {
  272. szKey = szBuf;
  273. while (TRUE)
  274. {
  275. if (m_cInfo == cInfoBuf)
  276. {
  277. cInfoBuf += CALLOCINFO;
  278. if (!MemRealloc((void **)&m_rgInfo, cInfoBuf * sizeof(EUDORAACCTINFO)))
  279. {
  280. hr = E_OUTOFMEMORY;
  281. goto done;
  282. }
  283. }
  284. szVal = PszScanToCharA(szKey, '=');
  285. if (*szVal != 0)
  286. {
  287. szVal++;
  288. m_rgInfo[m_cInfo].dwCookie = m_cInfo;
  289. lstrcpy(m_rgInfo[m_cInfo].szSection, szVal);
  290. lstrcpy(m_rgInfo[m_cInfo].szDisplay, szVal);
  291. m_cInfo++;
  292. }
  293. szKey = szVal;
  294. while (*szKey != 0)
  295. szKey++;
  296. szKey++;
  297. if (*szKey == 0)
  298. break;
  299. }
  300. }
  301. lstrcpy(m_szIni, szIni);
  302. hr = S_OK;
  303. }
  304. done:
  305. MemFree(szBuf);
  306. return(hr);
  307. }
  308. HRESULT STDMETHODCALLTYPE CEudoraAcctImport::InitializeImport(HWND hwnd, DWORD_PTR dwCookie)
  309. {
  310. return(E_NOTIMPL);
  311. }
  312. HRESULT STDMETHODCALLTYPE CEudoraAcctImport::GetNewsGroup(INewsGroupImport *pImp, DWORD dwReserved)
  313. {
  314. return(E_NOTIMPL);
  315. }
  316. CEnumEUDORAACCTS::CEnumEUDORAACCTS()
  317. {
  318. m_cRef = 1;
  319. // m_iInfo
  320. m_cInfo = 0;
  321. m_rgInfo = NULL;
  322. }
  323. CEnumEUDORAACCTS::~CEnumEUDORAACCTS()
  324. {
  325. if (m_rgInfo != NULL)
  326. MemFree(m_rgInfo);
  327. }
  328. STDMETHODIMP CEnumEUDORAACCTS::QueryInterface(REFIID riid, LPVOID *ppv)
  329. {
  330. if (ppv == NULL)
  331. return(E_INVALIDARG);
  332. *ppv = NULL;
  333. if (IID_IUnknown == riid)
  334. *ppv = (IUnknown *)this;
  335. else if (IID_IEnumIMPACCOUNTS == riid)
  336. *ppv = (IEnumIMPACCOUNTS *)this;
  337. if (*ppv != NULL)
  338. ((LPUNKNOWN)*ppv)->AddRef();
  339. else
  340. return(E_NOINTERFACE);
  341. return(S_OK);
  342. }
  343. STDMETHODIMP_(ULONG) CEnumEUDORAACCTS::AddRef()
  344. {
  345. return(++m_cRef);
  346. }
  347. STDMETHODIMP_(ULONG) CEnumEUDORAACCTS::Release()
  348. {
  349. if (--m_cRef == 0)
  350. {
  351. delete this;
  352. return(0);
  353. }
  354. return(m_cRef);
  355. }
  356. HRESULT STDMETHODCALLTYPE CEnumEUDORAACCTS::Next(IMPACCOUNTINFO *pinfo)
  357. {
  358. if (pinfo == NULL)
  359. return(E_INVALIDARG);
  360. m_iInfo++;
  361. if ((UINT)m_iInfo >= m_cInfo)
  362. return(S_FALSE);
  363. Assert(m_rgInfo != NULL);
  364. pinfo->dwCookie = m_rgInfo[m_iInfo].dwCookie;
  365. pinfo->dwReserved = 0;
  366. lstrcpy(pinfo->szDisplay, m_rgInfo[m_iInfo].szDisplay);
  367. return(S_OK);
  368. }
  369. HRESULT STDMETHODCALLTYPE CEnumEUDORAACCTS::Reset()
  370. {
  371. m_iInfo = -1;
  372. return(S_OK);
  373. }
  374. HRESULT CEnumEUDORAACCTS::Init(EUDORAACCTINFO *pinfo, int cinfo)
  375. {
  376. DWORD cb;
  377. Assert(pinfo != NULL);
  378. Assert(cinfo > 0);
  379. cb = cinfo * sizeof(EUDORAACCTINFO);
  380. if (!MemAlloc((void **)&m_rgInfo, cb))
  381. return(E_OUTOFMEMORY);
  382. m_iInfo = -1;
  383. m_cInfo = cinfo;
  384. CopyMemory(m_rgInfo, pinfo, cb);
  385. return(S_OK);
  386. }