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.

523 lines
14 KiB

  1. #include "pch.hxx"
  2. #include <imnact.h>
  3. #include <acctimp.h>
  4. #include <dllmain.h>
  5. #include <resource.h>
  6. #include "CommAct.h"
  7. ASSERTDATA
  8. CCommAcctImport::CCommAcctImport()
  9. {
  10. m_cRef = 1;
  11. m_fIni = FALSE;
  12. *m_szIni = 0;
  13. m_cInfo = 0;
  14. m_rgInfo = NULL;
  15. }
  16. CCommAcctImport::~CCommAcctImport()
  17. {
  18. if (m_rgInfo != NULL)
  19. MemFree(m_rgInfo);
  20. }
  21. STDMETHODIMP CCommAcctImport::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. ((LPUNKNOWN)*ppv)->AddRef();
  33. return(S_OK);
  34. }
  35. STDMETHODIMP_(ULONG) CCommAcctImport::AddRef()
  36. {
  37. return(++m_cRef);
  38. }
  39. STDMETHODIMP_(ULONG) CCommAcctImport::Release()
  40. {
  41. if (--m_cRef == 0)
  42. {
  43. delete this;
  44. return(0);
  45. }
  46. return(m_cRef);
  47. }
  48. const static char c_szRegNscp[] = "Software\\Netscape\\Netscape Navigator\\Users";
  49. const static char c_szRegMail[] = "Mail";
  50. const static char c_szRegUser[] = "User";
  51. const static char c_szRegDirRoot[] = "DirRoot";
  52. const static char c_szEmpty[] = "";
  53. const static char c_szIni[] = "ini";
  54. const static char c_szNetscape[] = "Netscape";
  55. const static char c_szPopServer[] = "POP_Server";
  56. const static char c_szSmtpServer[] = "SMTP_Server";
  57. const static char c_szPopName[] = "POP Name";
  58. const static char c_szUserName[] = "User_Name";
  59. const static char c_szUserAddr[] = "User_Addr";
  60. HRESULT STDMETHODCALLTYPE CCommAcctImport::AutoDetect(DWORD *pcAcct, DWORD dwFlags)
  61. {
  62. HRESULT hr;
  63. DWORD dwNumSubKeys = 0;
  64. DWORD dwIndex = 0;
  65. HRESULT hrUser = E_FAIL;
  66. DWORD cb = MAX_PATH;
  67. char szUserName[MAX_PATH];
  68. char szUserProfile[MAX_PATH];
  69. char szUserPrefs[2][USERCOLS];
  70. HKEY hkey,
  71. hkeyUsers;
  72. char szPop[MAX_PATH], *psz, szExpanded[MAX_PATH];
  73. DWORD dwType;
  74. long lRetVal = 0;
  75. Assert(m_cInfo == 0);
  76. if (pcAcct == NULL)
  77. return(E_INVALIDARG);
  78. hr = S_FALSE;
  79. *pcAcct = 0;
  80. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegNscp, 0, KEY_ALL_ACCESS, &hkey))
  81. {
  82. // TODO : Fill up the m_rgInfo array with the info of all
  83. // the users who have accounts in Communicator.
  84. if(ERROR_SUCCESS == RegQueryInfoKey( hkey, NULL, NULL, 0, &dwNumSubKeys,
  85. NULL, NULL, NULL, NULL, NULL, NULL, NULL ) && (dwNumSubKeys > 0))
  86. {
  87. if (!MemAlloc((void **)&m_rgInfo, dwNumSubKeys * sizeof(COMMACCTINFO)))
  88. {
  89. hr = E_OUTOFMEMORY;
  90. goto done;
  91. }
  92. while(ERROR_SUCCESS == RegEnumKeyEx(hkey, dwIndex, szUserName, &cb, NULL, NULL, NULL, NULL))
  93. {
  94. if(ERROR_SUCCESS == RegOpenKeyEx(hkey, szUserName, 0, KEY_ALL_ACCESS, &hkeyUsers))
  95. {
  96. cb = sizeof(szUserProfile);
  97. if(ERROR_SUCCESS == (lRetVal = RegQueryValueEx(hkeyUsers, c_szRegDirRoot, NULL, &dwType, (LPBYTE)szUserProfile, &cb )))
  98. {
  99. if (REG_EXPAND_SZ == dwType)
  100. {
  101. ExpandEnvironmentStrings(szUserProfile, szExpanded, ARRAYSIZE(szExpanded));
  102. psz = szExpanded;
  103. }
  104. else
  105. psz = szUserProfile;
  106. //save vals into the m_rgInfo structure
  107. hrUser = GetUserPrefs(psz, szUserPrefs, 2, NULL);
  108. if(!FAILED(hrUser))
  109. {
  110. m_rgInfo[m_cInfo].dwCookie = m_cInfo;
  111. StrCpyNA(m_rgInfo[m_cInfo].szUserPath, psz, ARRAYSIZE(m_rgInfo[m_cInfo].szUserPath));
  112. StrCpyNA(m_rgInfo[m_cInfo].szDisplay, szUserName, ARRAYSIZE(m_rgInfo[m_cInfo].szDisplay));
  113. m_cInfo++;
  114. }
  115. }
  116. RegCloseKey(hkeyUsers);
  117. }
  118. dwIndex++;
  119. if(dwIndex == dwNumSubKeys)
  120. hr = S_OK;
  121. }
  122. }
  123. }
  124. if (hr == S_OK)
  125. {
  126. *pcAcct = m_cInfo;
  127. }
  128. done:
  129. // Close the reg key now....
  130. RegCloseKey(hkey);
  131. return(hr);
  132. }
  133. HRESULT STDMETHODCALLTYPE CCommAcctImport::EnumerateAccounts(IEnumIMPACCOUNTS **ppEnum)
  134. {
  135. CEnumCOMMACCTS *penum;
  136. HRESULT hr;
  137. if (ppEnum == NULL)
  138. return(E_INVALIDARG);
  139. *ppEnum = NULL;
  140. if (m_cInfo == 0)
  141. return(S_FALSE);
  142. Assert(m_rgInfo != NULL);
  143. penum = new CEnumCOMMACCTS;
  144. if (penum == NULL)
  145. return(E_OUTOFMEMORY);
  146. hr = penum->Init(m_rgInfo, m_cInfo);
  147. if (FAILED(hr))
  148. {
  149. penum->Release();
  150. penum = NULL;
  151. }
  152. *ppEnum = penum;
  153. return(hr);
  154. }
  155. HRESULT STDMETHODCALLTYPE CCommAcctImport::GetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct)
  156. {
  157. if (pAcct == NULL)
  158. return(E_INVALIDARG);
  159. return(IGetSettings(dwCookie, pAcct, NULL));
  160. }
  161. HRESULT STDMETHODCALLTYPE CCommAcctImport::GetSettings2(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  162. {
  163. if (pAcct == NULL ||
  164. pInfo == NULL)
  165. return(E_INVALIDARG);
  166. return(IGetSettings(dwCookie, pAcct, pInfo));
  167. }
  168. HRESULT STDMETHODCALLTYPE CCommAcctImport::IGetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  169. {
  170. HKEY hkey, hkeyT;
  171. COMMACCTINFO *pinfo;
  172. char szUserPrefs[USERROWS][USERCOLS];
  173. char sz[512];
  174. DWORD cb, type;
  175. HRESULT hr;
  176. BOOL bPop = TRUE;
  177. ZeroMemory(szUserPrefs, USERCOLS*USERROWS*sizeof(char));
  178. Assert(((int)dwCookie) >= 0 && dwCookie < (DWORD_PTR)m_cInfo);
  179. pinfo = &m_rgInfo[dwCookie];
  180. Assert(pinfo->dwCookie == dwCookie);
  181. hr = pAcct->SetPropSz(AP_ACCOUNT_NAME, pinfo->szDisplay);
  182. if (FAILED(hr))
  183. return(hr);
  184. hr = GetUserPrefs(pinfo->szUserPath, szUserPrefs, USERROWS, &bPop);
  185. Assert(!FAILED(hr));
  186. if(lstrlen(szUserPrefs[0]))
  187. {
  188. hr = pAcct->SetPropSz(AP_SMTP_SERVER, szUserPrefs[0]);
  189. Assert(!FAILED(hr));
  190. }
  191. if(lstrlen(szUserPrefs[1]))
  192. {
  193. hr = pAcct->SetPropSz(bPop ? AP_POP3_SERVER : AP_IMAP_SERVER, szUserPrefs[1]);
  194. Assert(!FAILED(hr));
  195. }
  196. if(lstrlen(szUserPrefs[3]))
  197. {
  198. hr = pAcct->SetPropSz(bPop ? AP_POP3_USERNAME : AP_IMAP_USERNAME, szUserPrefs[3]);
  199. Assert(!FAILED(hr));
  200. }
  201. if(lstrlen(szUserPrefs[4]))
  202. {
  203. hr = pAcct->SetPropSz(AP_SMTP_DISPLAY_NAME, szUserPrefs[4]);
  204. Assert(!FAILED(hr));
  205. }
  206. if(lstrlen(szUserPrefs[5]))
  207. {
  208. hr = pAcct->SetPropSz(AP_SMTP_EMAIL_ADDRESS, szUserPrefs[5]);
  209. Assert(!FAILED(hr));
  210. }
  211. if(!lstrcmp(szUserPrefs[6], "true"))
  212. {
  213. hr = pAcct->SetPropDw(AP_POP3_LEAVE_ON_SERVER, 1);
  214. Assert(!FAILED(hr));
  215. }
  216. if(lstrlen(szUserPrefs[7]))
  217. {
  218. hr = pAcct->SetPropSz(AP_SMTP_REPLY_EMAIL_ADDRESS, szUserPrefs[7]);
  219. Assert(!FAILED(hr));
  220. }
  221. if (pInfo != NULL)
  222. {
  223. // TODO: can we do any better than this???
  224. pInfo->dwConnect = CONN_USE_DEFAULT;
  225. }
  226. return(S_OK);
  227. }
  228. HRESULT STDMETHODCALLTYPE CCommAcctImport::InitializeImport(HWND hwnd, DWORD_PTR dwCookie)
  229. {
  230. return(E_NOTIMPL);
  231. }
  232. HRESULT STDMETHODCALLTYPE CCommAcctImport::GetNewsGroup(INewsGroupImport *pImp, DWORD dwReserved)
  233. {
  234. return(E_NOTIMPL);
  235. }
  236. const static char c_szSearch[USERROWS][USERCOLS] = {"user_pref(\"network.hosts.smtp_server\"",
  237. "user_pref(\"network.hosts.pop_server\"",
  238. "user_pref(\"mail.server_type\"",
  239. "user_pref(\"mail.pop_name\"",
  240. "user_pref(\"mail.identity.username\"",
  241. "user_pref(\"mail.identity.useremail\"",
  242. "user_pref(\"mail.leave_on_server\"",
  243. "user_pref(\"mail.identity.reply_to\""};
  244. const static char c_szPrefs[] = "\\prefs.js";
  245. HRESULT CCommAcctImport::GetUserPrefs(char *szUserPath, char szUserPrefs[][USERCOLS], int nInLoop, BOOL *pbPop)
  246. {
  247. HRESULT hr = E_FAIL;
  248. char szTemp[MAX_PATH * 2];
  249. char szDirpath[250];
  250. char szLine[1000];
  251. char szCompare[1000];
  252. int nLine = 0;
  253. int nFilled = 0;
  254. int nPosition = 0;
  255. int nLoop = nInLoop;
  256. HANDLE hJSHandle = NULL;
  257. HANDLE hJSFile = NULL;
  258. ULONG cbJSFile = 0;
  259. BYTE *pBegin = NULL,
  260. *pCurr = NULL,
  261. *pEnd = NULL;
  262. Assert(nInLoop <= USERROWS);
  263. StrCpyN(szTemp, szUserPath, ARRAYSIZE(szTemp));
  264. StrCatBuff(szTemp, c_szPrefs, ARRAYSIZE(szTemp));
  265. hJSHandle = CreateFile( szTemp, GENERIC_READ, FILE_SHARE_READ, NULL,
  266. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  267. if(hJSHandle == INVALID_HANDLE_VALUE)
  268. return hr;
  269. cbJSFile = GetFileSize(hJSHandle, NULL);
  270. hJSFile = CreateFileMapping(hJSHandle, NULL, PAGE_READONLY, 0, 0, NULL);
  271. if(hJSFile == NULL)
  272. {
  273. CloseHandle(hJSHandle);
  274. return hr;
  275. }
  276. pBegin = (BYTE *)MapViewOfFile( hJSFile, FILE_MAP_READ, 0, 0, 0);
  277. if(pBegin == NULL)
  278. {
  279. CloseHandle(hJSHandle);
  280. CloseHandle(hJSFile);
  281. return hr;
  282. }
  283. pCurr = pBegin;
  284. pEnd = pCurr + cbJSFile;
  285. while (pCurr < pEnd)
  286. {
  287. szLine[nLine] = *pCurr; //keep storing here. will be used for comparing later.
  288. if((pCurr[0] == 0x0D) && (pCurr[1] == 0x0A))
  289. {
  290. while(nLoop)
  291. {
  292. StrCpyN(szCompare, szLine, lstrlen(c_szSearch[nLoop - 1]) + 1);
  293. if(lstrcmp(szCompare, c_szSearch[nLoop - 1]) == 0)
  294. {
  295. //Found a UserPref one of the things we are looking for"!
  296. //Extract the stuff we want.
  297. nPosition = lstrlen(c_szSearch[nLoop - 1]);
  298. while (((szLine[nPosition] == '"')||(szLine[nPosition] == ' ')||(szLine[nPosition] == ',')) &&(nPosition < nLine))
  299. nPosition++;
  300. StrCpyN(szDirpath, &szLine[nPosition], nLine - nPosition);
  301. //Now trim the trailing edge!!!
  302. nPosition = lstrlen(szDirpath) - 1;
  303. while((szDirpath[nPosition] == '"') || (szDirpath[nPosition] == ')')||(szDirpath[nPosition] == ';'))
  304. {
  305. szDirpath[nPosition] = '\0';
  306. nPosition = lstrlen(szDirpath) - 1;
  307. }
  308. StrCpyN(szUserPrefs[nLoop - 1], szDirpath, USERCOLS);
  309. nFilled++;
  310. if(nFilled == nInLoop)
  311. break;
  312. }
  313. nLoop--;
  314. }
  315. nLoop = nInLoop;
  316. nLine = -1; //the nLine++ that follows will make nLine zero.
  317. pCurr++;
  318. }
  319. if(nFilled == nInLoop)
  320. break;
  321. pCurr++;
  322. nLine++;
  323. }
  324. if(hJSHandle != INVALID_HANDLE_VALUE)
  325. CloseHandle(hJSHandle);
  326. if(pBegin)
  327. UnmapViewOfFile(pBegin);
  328. if(hJSFile)
  329. CloseHandle(hJSFile);
  330. if(nFilled == 0)
  331. return E_FAIL;
  332. else
  333. {
  334. if(nInLoop == 2) //If this function was called only to check the server enties...
  335. {
  336. if(lstrlen(szUserPrefs[1]))
  337. return S_OK;
  338. else
  339. return E_FAIL;
  340. }
  341. else
  342. {
  343. if(lstrlen(szUserPrefs[2]))
  344. {
  345. if(lstrcmp(szUserPrefs[2], "1"))
  346. *pbPop = TRUE;
  347. else
  348. *pbPop = FALSE;
  349. }
  350. else
  351. *pbPop = TRUE;
  352. return S_OK;
  353. }
  354. }
  355. }
  356. CEnumCOMMACCTS::CEnumCOMMACCTS()
  357. {
  358. m_cRef = 1;
  359. // m_iInfo
  360. m_cInfo = 0;
  361. m_rgInfo = NULL;
  362. }
  363. CEnumCOMMACCTS::~CEnumCOMMACCTS()
  364. {
  365. if (m_rgInfo != NULL)
  366. MemFree(m_rgInfo);
  367. }
  368. STDMETHODIMP CEnumCOMMACCTS::QueryInterface(REFIID riid, LPVOID *ppv)
  369. {
  370. if (ppv == NULL)
  371. return(E_INVALIDARG);
  372. *ppv = NULL;
  373. if (IID_IUnknown == riid)
  374. *ppv = (IUnknown *)this;
  375. else if (IID_IEnumIMPACCOUNTS == riid)
  376. *ppv = (IEnumIMPACCOUNTS *)this;
  377. if (*ppv != NULL)
  378. ((LPUNKNOWN)*ppv)->AddRef();
  379. else
  380. return(E_NOINTERFACE);
  381. return(S_OK);
  382. }
  383. STDMETHODIMP_(ULONG) CEnumCOMMACCTS::AddRef()
  384. {
  385. return(++m_cRef);
  386. }
  387. STDMETHODIMP_(ULONG) CEnumCOMMACCTS::Release()
  388. {
  389. if (--m_cRef == 0)
  390. {
  391. delete this;
  392. return(0);
  393. }
  394. return(m_cRef);
  395. }
  396. HRESULT STDMETHODCALLTYPE CEnumCOMMACCTS::Next(IMPACCOUNTINFO *pinfo)
  397. {
  398. if (pinfo == NULL)
  399. return(E_INVALIDARG);
  400. m_iInfo++;
  401. if ((UINT)m_iInfo >= m_cInfo)
  402. return(S_FALSE);
  403. Assert(m_rgInfo != NULL);
  404. pinfo->dwCookie = m_rgInfo[m_iInfo].dwCookie;
  405. pinfo->dwReserved = 0;
  406. StrCpyN(pinfo->szDisplay, m_rgInfo[m_iInfo].szDisplay, ARRAYSIZE(pinfo->szDisplay));
  407. return(S_OK);
  408. }
  409. HRESULT STDMETHODCALLTYPE CEnumCOMMACCTS::Reset()
  410. {
  411. m_iInfo = -1;
  412. return(S_OK);
  413. }
  414. HRESULT CEnumCOMMACCTS::Init(COMMACCTINFO *pinfo, int cinfo)
  415. {
  416. DWORD cb;
  417. Assert(pinfo != NULL);
  418. Assert(cinfo > 0);
  419. cb = cinfo * sizeof(COMMACCTINFO);
  420. if (!MemAlloc((void **)&m_rgInfo, cb))
  421. return(E_OUTOFMEMORY);
  422. m_iInfo = -1;
  423. m_cInfo = cinfo;
  424. CopyMemory(m_rgInfo, pinfo, cb);
  425. return(S_OK);
  426. }