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.

592 lines
16 KiB

  1. #include "pch.hxx"
  2. #include <imnact.h>
  3. #include <acctimp.h>
  4. #include <dllmain.h>
  5. #include <resource.h>
  6. #include <nexpress.h>
  7. #include "newimp.h"
  8. #include <shlwapi.h>
  9. #include "strconst.h"
  10. ASSERTDATA
  11. #define MEMCHUNK 512
  12. CNExpressAcctImport::CNExpressAcctImport()
  13. {
  14. m_cRef = 1;
  15. m_fIni = FALSE;
  16. *m_szIni = 0;
  17. m_cInfo = 0;
  18. m_rgInfo = NULL;
  19. }
  20. CNExpressAcctImport::~CNExpressAcctImport()
  21. {
  22. if (m_rgInfo != NULL)
  23. MemFree(m_rgInfo);
  24. }
  25. STDMETHODIMP CNExpressAcctImport::QueryInterface(REFIID riid, LPVOID *ppv)
  26. {
  27. if (ppv == NULL)
  28. return(E_INVALIDARG);
  29. *ppv = NULL;
  30. if ((IID_IUnknown == riid) || (IID_IAccountImport == riid))
  31. *ppv = (IAccountImport *)this;
  32. else if (IID_IAccountImport2 == riid)
  33. *ppv = (IAccountImport2 *)this;
  34. else
  35. return(E_NOINTERFACE);
  36. ((LPUNKNOWN)*ppv)->AddRef();
  37. return(S_OK);
  38. }
  39. STDMETHODIMP_(ULONG) CNExpressAcctImport::AddRef()
  40. {
  41. return(++m_cRef);
  42. }
  43. STDMETHODIMP_(ULONG) CNExpressAcctImport::Release()
  44. {
  45. if (--m_cRef == 0)
  46. {
  47. delete this;
  48. return(0);
  49. }
  50. return(m_cRef);
  51. }
  52. const static char c_szConfig[] = "Config";
  53. const static char c_szAuth[] = "Auth";
  54. const static char c_szNxNNTPServer[] = "NNTPServer";
  55. const static char c_szFullname[] = "Fullname";
  56. const static char c_szOrganization[] = "Organization";
  57. const static char c_szEmail[] = "Email";
  58. const static char c_szNxUsername[] = "Username";
  59. const static char c_szNNTPPort[] = "NNTPPort";
  60. const static char c_szHomeDir[] = "HomeDir";
  61. const static char c_szNewsrc[] = "NewsRC";
  62. const static char c_szNxIni[] = "\\nx.ini";
  63. const static char c_szNx[] = "nx";
  64. const static char c_szRegServicesDef[] = "Software\\NewsXpress\\Services\\Default";
  65. const static char c_szRegAuth[] = "Software\\NewsXpress\\Services\\Default\\Authorization";
  66. const static char c_szRegNxUser[] = "Software\\NewsXpress\\User";
  67. const static char c_szRegNxRoot[] = "Software\\NewsXpress";
  68. const static char c_szRegNNTPServer[] = "NNTP Server";
  69. const static char c_szRegNNTPPort[] = "NNTP Port";
  70. const static char c_szRegHomeDir[] = "Home Dir";
  71. HRESULT STDMETHODCALLTYPE CNExpressAcctImport::AutoDetect(DWORD *pcAcct, DWORD dwFlags)
  72. {
  73. HKEY hkey;
  74. DWORD type, cb, dw;
  75. char szNewsServer[MAX_PATH], szWinPath[MAX_PATH];
  76. Assert(m_cInfo == 0);
  77. if (pcAcct == NULL)
  78. return(E_INVALIDARG);
  79. *pcAcct = 0;
  80. cb = sizeof(szNewsServer);
  81. if (ERROR_SUCCESS == SHGetValue(HKEY_CURRENT_USER, c_szRegServicesDef, c_szRegNNTPServer, &type, (LPBYTE)szNewsServer, &cb))
  82. {
  83. if (!MemAlloc((void **)&m_rgInfo, sizeof(NXACCTINFO)))
  84. return(E_OUTOFMEMORY);
  85. m_rgInfo->dwCookie = 0;
  86. *m_rgInfo->szUserPath = 0;
  87. StrCpyN(m_rgInfo->szDisplay, szNewsServer, ARRAYSIZE(m_rgInfo->szDisplay));
  88. m_cInfo = 1;
  89. }
  90. else
  91. {
  92. if (0 == GetEnvironmentVariable(c_szNx, szWinPath, ARRAYSIZE(szWinPath)))
  93. {
  94. if (0 == GetWindowsDirectory(szWinPath, ARRAYSIZE(szWinPath)))
  95. return(S_OK);
  96. StrCatBuff(szWinPath, c_szNxIni, ARRAYSIZE(szWinPath));
  97. }
  98. dw = GetFileAttributes(szWinPath);
  99. if (dw != -1 && dw != FILE_ATTRIBUTE_DIRECTORY)
  100. {
  101. if (GetPrivateProfileString(c_szConfig, c_szNxNNTPServer, c_szEmpty, szNewsServer, ARRAYSIZE(szNewsServer), szWinPath))
  102. {
  103. if (!MemAlloc((void **)&m_rgInfo, sizeof(NXACCTINFO)))
  104. return(E_OUTOFMEMORY);
  105. m_rgInfo->dwCookie = 0;
  106. StrCpyN(m_rgInfo->szUserPath, szWinPath, ARRAYSIZE(m_rgInfo->szUserPath));
  107. StrCpyN(m_rgInfo->szDisplay, szNewsServer, ARRAYSIZE(m_rgInfo->szDisplay));
  108. m_cInfo = 1;
  109. }
  110. }
  111. }
  112. *pcAcct = m_cInfo;
  113. return(S_OK);
  114. }
  115. HRESULT STDMETHODCALLTYPE CNExpressAcctImport::InitializeImport(HWND hwnd, DWORD_PTR dwCookie)
  116. {
  117. Assert(dwCookie == 0);
  118. return S_OK;
  119. }
  120. HRESULT STDMETHODCALLTYPE CNExpressAcctImport::EnumerateAccounts(IEnumIMPACCOUNTS **ppEnum)
  121. {
  122. CEnumNXACCT *penum;
  123. HRESULT hr;
  124. if (ppEnum == NULL)
  125. return(E_INVALIDARG);
  126. *ppEnum = NULL;
  127. if (m_cInfo == 0)
  128. return(S_FALSE);
  129. Assert(m_rgInfo != NULL);
  130. penum = new CEnumNXACCT;
  131. if (penum == NULL)
  132. return(E_OUTOFMEMORY);
  133. hr = penum->Init(m_rgInfo, m_cInfo);
  134. if (FAILED(hr))
  135. {
  136. penum->Release();
  137. penum = NULL;
  138. }
  139. *ppEnum = penum;
  140. return(hr);
  141. }
  142. HRESULT STDMETHODCALLTYPE CNExpressAcctImport::GetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct)
  143. {
  144. HRESULT hr;
  145. if (pAcct == NULL)
  146. return(E_INVALIDARG);
  147. hr = IGetSettings(dwCookie, pAcct, NULL);
  148. return(hr);
  149. }
  150. HRESULT CNExpressAcctImport::IGetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  151. {
  152. HRESULT hr;
  153. HKEY hkey;
  154. UINT port;
  155. NXACCTINFO *pinfo;
  156. char sz[512];
  157. DWORD cb, type;
  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. if (*pinfo->szUserPath != 0)
  165. {
  166. // ini file
  167. if (GetPrivateProfileString(c_szConfig, c_szNxNNTPServer, c_szEmpty, sz, ARRAYSIZE(sz), pinfo->szUserPath))
  168. {
  169. hr = pAcct->SetPropSz(AP_NNTP_SERVER, sz);
  170. Assert(!FAILED(hr));
  171. }
  172. port = GetPrivateProfileInt(c_szConfig, c_szNNTPPort, 0, pinfo->szUserPath);
  173. if (port != 0)
  174. {
  175. hr = pAcct->SetPropDw(AP_NNTP_PORT, port);
  176. Assert(!FAILED(hr));
  177. }
  178. if (GetPrivateProfileString(c_szConfig, c_szFullname, c_szEmpty, sz, ARRAYSIZE(sz), pinfo->szUserPath))
  179. {
  180. hr = pAcct->SetPropSz(AP_NNTP_DISPLAY_NAME, sz);
  181. Assert(!FAILED(hr));
  182. }
  183. if (GetPrivateProfileString(c_szConfig, c_szEmail, c_szEmpty, sz, ARRAYSIZE(sz), pinfo->szUserPath))
  184. {
  185. hr = pAcct->SetPropSz(AP_NNTP_EMAIL_ADDRESS, sz);
  186. Assert(!FAILED(hr));
  187. }
  188. if (GetPrivateProfileString(c_szConfig, c_szOrganization, c_szEmpty, sz, ARRAYSIZE(sz), pinfo->szUserPath))
  189. {
  190. hr = pAcct->SetPropSz(AP_NNTP_ORG_NAME, sz);
  191. Assert(!FAILED(hr));
  192. }
  193. if (GetPrivateProfileString(c_szAuth, c_szNxUsername, c_szEmpty, sz, ARRAYSIZE(sz), pinfo->szUserPath))
  194. {
  195. hr = pAcct->SetPropSz(AP_NNTP_USERNAME, sz);
  196. Assert(!FAILED(hr));
  197. }
  198. }
  199. else
  200. {
  201. // registry
  202. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegServicesDef, 0, KEY_READ, &hkey))
  203. {
  204. cb = sizeof(sz);
  205. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szRegNNTPServer, NULL, &type, (LPBYTE)sz, &cb))
  206. {
  207. hr = pAcct->SetPropSz(AP_NNTP_SERVER, sz);
  208. Assert(!FAILED(hr));
  209. }
  210. cb = sizeof(port);
  211. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szRegNNTPPort, NULL, &type, (LPBYTE)&port, &cb) && port != 0)
  212. {
  213. hr = pAcct->SetPropDw(AP_NNTP_PORT, port);
  214. Assert(!FAILED(hr));
  215. }
  216. RegCloseKey(hkey);
  217. }
  218. cb = sizeof(sz);
  219. if (ERROR_SUCCESS == SHGetValue(HKEY_CURRENT_USER, c_szRegAuth, c_szNxUsername, &type, (LPBYTE)sz, &cb) && cb > 1)
  220. {
  221. hr = pAcct->SetPropSz(AP_NNTP_USERNAME, sz);
  222. Assert(!FAILED(hr));
  223. }
  224. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegNxUser, 0, KEY_READ, &hkey))
  225. {
  226. cb = sizeof(sz);
  227. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szEmail, NULL, &type, (LPBYTE)sz, &cb))
  228. {
  229. hr = pAcct->SetPropSz(AP_NNTP_EMAIL_ADDRESS, sz);
  230. Assert(!FAILED(hr));
  231. }
  232. cb = sizeof(sz);
  233. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szFullname, NULL, &type, (LPBYTE)sz, &cb))
  234. {
  235. hr = pAcct->SetPropSz(AP_NNTP_DISPLAY_NAME, sz);
  236. Assert(!FAILED(hr));
  237. }
  238. cb = sizeof(sz);
  239. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szOrganization, NULL, &type, (LPBYTE)sz, &cb))
  240. {
  241. hr = pAcct->SetPropSz(AP_NNTP_ORG_NAME, sz);
  242. Assert(!FAILED(hr));
  243. }
  244. RegCloseKey(hkey);
  245. }
  246. }
  247. if (pInfo != NULL)
  248. {
  249. // TODO: can we do any better than this???
  250. pInfo->dwConnect = CONN_USE_DEFAULT;
  251. }
  252. return(S_OK);
  253. }
  254. HRESULT CNExpressAcctImport::GetNewsGroup(INewsGroupImport *pImp, DWORD dwReserved)
  255. {
  256. BOOL fRet;
  257. DWORD cb, type;
  258. char szHomeDir[MAX_PATH], szRCFile[MAX_PATH];
  259. HRESULT hr = S_OK;
  260. char *pListGroups = NULL;
  261. Assert(pImp != NULL);
  262. *szHomeDir = 0;
  263. fRet = FALSE;
  264. if (*m_rgInfo->szUserPath != 0)
  265. {
  266. if (GetPrivateProfileString(c_szConfig, c_szHomeDir, c_szEmpty, szHomeDir, MAX_PATH, m_rgInfo->szUserPath) &&
  267. GetPrivateProfileString(c_szConfig, c_szNewsrc, c_szEmpty, szRCFile, MAX_PATH, m_rgInfo->szUserPath))
  268. {
  269. fRet = TRUE;
  270. }
  271. }
  272. else
  273. {
  274. cb = sizeof(szHomeDir);
  275. if (ERROR_SUCCESS == SHGetValue(HKEY_CURRENT_USER, c_szRegNxRoot, c_szRegHomeDir, &type, (LPBYTE)szHomeDir, &cb) && cb > 1)
  276. {
  277. cb = sizeof(szRCFile);
  278. if (ERROR_SUCCESS == SHGetValue(HKEY_CURRENT_USER, c_szRegServicesDef, c_szNewsrc, &type, (LPBYTE)szRCFile, &cb) && cb > 1)
  279. {
  280. fRet = TRUE;
  281. }
  282. }
  283. }
  284. if (fRet)
  285. {
  286. PathAppend(szHomeDir, szRCFile);
  287. if (SUCCEEDED(hr = GetSubListGroups(szHomeDir, &pListGroups)))
  288. {
  289. hr = pImp->ImportSubList(pListGroups);
  290. MemFree(pListGroups);
  291. }
  292. }
  293. return hr;
  294. }
  295. HRESULT CNExpressAcctImport::GetSubListGroups(char *szHomeDir, char **ppListGroups)
  296. {
  297. HRESULT hr = E_FAIL;
  298. HANDLE hRCHandle = NULL;
  299. HANDLE hRCFile = NULL;
  300. ULONG cbRCFile = 0;
  301. BYTE *pBegin = NULL,
  302. *pCurr = NULL,
  303. *pEnd = NULL;
  304. int nBalMem = MEMCHUNK;
  305. int nLine = 0,
  306. nCount = 0;
  307. char cPlaceHolder = 1;
  308. char szLineHolder[MEMCHUNK];
  309. char *pListGroups = NULL;
  310. Assert(szHomeDir);
  311. Assert(ppListGroups);
  312. *ppListGroups = NULL;
  313. hRCHandle = CreateFile( szHomeDir, GENERIC_READ, FILE_SHARE_READ, NULL,
  314. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  315. if(hRCHandle == INVALID_HANDLE_VALUE)
  316. return hr;
  317. cbRCFile = GetFileSize(hRCHandle, NULL);
  318. if(!cbRCFile) // Empty File.
  319. goto Done;
  320. hRCFile = CreateFileMapping(hRCHandle, NULL, PAGE_READONLY, 0, 0, NULL);
  321. if(hRCFile == NULL)
  322. {
  323. CloseHandle(hRCHandle);
  324. return hr;
  325. }
  326. pBegin = (BYTE *)MapViewOfFile( hRCFile, FILE_MAP_READ, 0, 0, 0);
  327. if(pBegin == NULL)
  328. {
  329. CloseHandle(hRCHandle);
  330. CloseHandle(hRCFile);
  331. return hr;
  332. }
  333. pCurr = pBegin;
  334. pEnd = pCurr + cbRCFile;
  335. if (!MemAlloc((void **)&pListGroups, MEMCHUNK))
  336. {
  337. hr = E_OUTOFMEMORY;
  338. goto Done;
  339. }
  340. DWORD cchSizeListGroups = MEMCHUNK;
  341. ZeroMemory((void*)pListGroups, (cchSizeListGroups * sizeof(pListGroups[0])));
  342. while (pCurr < pEnd)
  343. {
  344. nLine = 0;
  345. while(!((pCurr[nLine] == ':') || (pCurr[nLine] == '!')) && (pCurr + nLine < pEnd))
  346. nLine++;
  347. if(pCurr + nLine > pEnd)
  348. break;
  349. if(pCurr[nLine] == '!')
  350. goto LineEnd;
  351. nLine++;
  352. if(nLine < MEMCHUNK)
  353. StrCpyN(szLineHolder, (char*)pCurr, nLine);
  354. else
  355. continue;
  356. if(nLine + 2 < nBalMem)
  357. {
  358. StrCatBuff(pListGroups, szLineHolder, cchSizeListGroups);
  359. StrCatBuff(pListGroups, "\1", cchSizeListGroups);
  360. nBalMem -= (nLine + 2);
  361. }
  362. else
  363. {
  364. cchSizeListGroups += (lstrlen(pListGroups) + 1 + MEMCHUNK);
  365. if(!MemRealloc((void **)&pListGroups, (cchSizeListGroups * sizeof(pListGroups[0]))))
  366. {
  367. hr = E_OUTOFMEMORY;
  368. goto Done;
  369. }
  370. nBalMem += MEMCHUNK;
  371. StrCatBuff(pListGroups, szLineHolder, cchSizeListGroups);
  372. StrCatBuff(pListGroups, "\1", cchSizeListGroups);
  373. nBalMem -= (nLine + 2);
  374. }
  375. LineEnd:
  376. while(!((pCurr[nLine] == 0x0D) && (pCurr[nLine + 1] == 0x0A)) && (pCurr + nLine < pEnd))
  377. nLine++;
  378. pCurr += (nLine + 2);
  379. }
  380. if(lstrlen(pListGroups))
  381. {
  382. while(pListGroups[nCount] != '\0')
  383. {
  384. if(pListGroups[nCount] == cPlaceHolder)
  385. {
  386. pListGroups[nCount] = '\0';
  387. }
  388. nCount++;
  389. }
  390. *ppListGroups = pListGroups;
  391. hr = S_OK;
  392. }
  393. Done:
  394. if(hRCHandle != INVALID_HANDLE_VALUE)
  395. CloseHandle(hRCHandle);
  396. if(pBegin)
  397. UnmapViewOfFile(pBegin);
  398. if(hRCFile)
  399. CloseHandle(hRCFile);
  400. return hr;
  401. }
  402. STDMETHODIMP CNExpressAcctImport::GetSettings2(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  403. {
  404. if (pAcct == NULL ||
  405. pInfo == NULL)
  406. return(E_INVALIDARG);
  407. return(IGetSettings(dwCookie, pAcct, pInfo));
  408. }
  409. CEnumNXACCT::CEnumNXACCT()
  410. {
  411. m_cRef = 1;
  412. // m_iInfo
  413. m_cInfo = 0;
  414. m_rgInfo = NULL;
  415. }
  416. CEnumNXACCT::~CEnumNXACCT()
  417. {
  418. if (m_rgInfo != NULL)
  419. MemFree(m_rgInfo);
  420. }
  421. STDMETHODIMP CEnumNXACCT::QueryInterface(REFIID riid, LPVOID *ppv)
  422. {
  423. if (ppv == NULL)
  424. return(E_INVALIDARG);
  425. *ppv = NULL;
  426. if (IID_IUnknown == riid)
  427. *ppv = (IUnknown *)this;
  428. else if (IID_IEnumIMPACCOUNTS == riid)
  429. *ppv = (IEnumIMPACCOUNTS *)this;
  430. if (*ppv != NULL)
  431. ((LPUNKNOWN)*ppv)->AddRef();
  432. else
  433. return(E_NOINTERFACE);
  434. return(S_OK);
  435. }
  436. STDMETHODIMP_(ULONG) CEnumNXACCT::AddRef()
  437. {
  438. return(++m_cRef);
  439. }
  440. STDMETHODIMP_(ULONG) CEnumNXACCT::Release()
  441. {
  442. if (--m_cRef == 0)
  443. {
  444. delete this;
  445. return(0);
  446. }
  447. return(m_cRef);
  448. }
  449. HRESULT STDMETHODCALLTYPE CEnumNXACCT::Next(IMPACCOUNTINFO *pinfo)
  450. {
  451. if (pinfo == NULL)
  452. return(E_INVALIDARG);
  453. m_iInfo++;
  454. if ((UINT)m_iInfo >= m_cInfo)
  455. return(S_FALSE);
  456. Assert(m_rgInfo != NULL);
  457. pinfo->dwCookie = m_rgInfo[m_iInfo].dwCookie;
  458. pinfo->dwReserved = 0;
  459. StrCpyN(pinfo->szDisplay, m_rgInfo[m_iInfo].szDisplay, ARRAYSIZE(pinfo->szDisplay));
  460. return(S_OK);
  461. }
  462. HRESULT STDMETHODCALLTYPE CEnumNXACCT::Reset()
  463. {
  464. m_iInfo = -1;
  465. return(S_OK);
  466. }
  467. HRESULT CEnumNXACCT::Init(NXACCTINFO *pinfo, int cinfo)
  468. {
  469. DWORD cb;
  470. Assert(pinfo != NULL);
  471. Assert(cinfo > 0);
  472. cb = cinfo * sizeof(NXACCTINFO);
  473. if (!MemAlloc((void **)&m_rgInfo, cb))
  474. return(E_OUTOFMEMORY);
  475. m_iInfo = -1;
  476. m_cInfo = cinfo;
  477. CopyMemory(m_rgInfo, pinfo, cb);
  478. return(S_OK);
  479. }