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.

480 lines
13 KiB

  1. #include "pch.hxx"
  2. #include <imnact.h>
  3. #include <acctimp.h>
  4. #include <dllmain.h>
  5. #include <resource.h>
  6. #include <AgntNews.h> // Forte Agent
  7. #include "newimp.h"
  8. ASSERTDATA
  9. #define MEMCHUNK 512
  10. CAgentAcctImport::CAgentAcctImport()
  11. {
  12. m_cRef = 1;
  13. m_fIni = FALSE;
  14. *m_szIni = 0;
  15. m_cInfo = 0;
  16. m_rgInfo = NULL;
  17. }
  18. CAgentAcctImport::~CAgentAcctImport()
  19. {
  20. if (m_rgInfo != NULL)
  21. MemFree(m_rgInfo);
  22. }
  23. STDMETHODIMP CAgentAcctImport::QueryInterface(REFIID riid, LPVOID *ppv)
  24. {
  25. if (ppv == NULL)
  26. return(E_INVALIDARG);
  27. *ppv = NULL;
  28. if ((IID_IUnknown == riid) || (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) CAgentAcctImport::AddRef()
  38. {
  39. return(++m_cRef);
  40. }
  41. STDMETHODIMP_(ULONG) CAgentAcctImport::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_szRegAgnt[] = "Software\\Forte\\Agent\\Paths";
  51. const static char c_szDefPath[] = "c:\\Agent\\Data\\Agent.ini";
  52. const static char c_szRegIni[] = "IniFile";
  53. const static char c_szRegUninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Forte Agent";
  54. const static char c_szRegString[] = "UninstallString";
  55. HRESULT STDMETHODCALLTYPE CAgentAcctImport::AutoDetect(DWORD *pcAcct, DWORD dwFlags)
  56. {
  57. HRESULT hr = S_OK;
  58. DWORD cb = MAX_PATH, dwType;
  59. char szUserName[MAX_PATH];
  60. char szUserIniPath[MAX_PATH];
  61. char szExpanded[MAX_PATH];
  62. char szNewsServer[MAX_PATH];
  63. char szIniPath[] = "Data\\Agent.ini";
  64. char *psz;
  65. int nCount = 0;
  66. HKEY hkey;
  67. Assert(m_cInfo == 0);
  68. if (pcAcct == NULL)
  69. return(E_INVALIDARG);
  70. *pcAcct = 0;
  71. // FIRST CHECK FOR FORTE AGENT
  72. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegAgnt, 0, KEY_ALL_ACCESS, &hkey))
  73. {
  74. cb = sizeof(szUserIniPath);
  75. if(ERROR_SUCCESS == RegQueryValueEx(hkey, c_szRegIni, NULL, &dwType, (LPBYTE)szUserIniPath, &cb ))
  76. {
  77. if (REG_EXPAND_SZ == dwType)
  78. {
  79. DWORD nReturn = ExpandEnvironmentStrings(szUserIniPath, szExpanded, ARRAYSIZE(szExpanded));
  80. if (nReturn && nReturn <= ARRAYSIZE(szExpanded))
  81. psz = szExpanded;
  82. else
  83. psz = szUserIniPath;
  84. }
  85. else
  86. psz = szUserIniPath;
  87. GetPrivateProfileString("Profile", "FullName", "Default User", szUserName, MAX_PATH, psz);
  88. if(GetPrivateProfileString("Servers", "NewsServer", "", szNewsServer, MAX_PATH, psz))
  89. {
  90. if (!MemAlloc((void **)&m_rgInfo, 1*sizeof(AGNTNEWSACCTINFO)))
  91. {
  92. hr = E_OUTOFMEMORY;
  93. goto done;
  94. }
  95. m_rgInfo[m_cInfo].dwCookie = m_cInfo;
  96. StrCpyN(m_rgInfo[m_cInfo].szUserPath, psz, ARRAYSIZE(m_rgInfo[m_cInfo].szUserPath));
  97. StrCpyN(m_rgInfo[m_cInfo].szDisplay, szUserName, ARRAYSIZE(m_rgInfo[m_cInfo].szDisplay));
  98. m_cInfo++;
  99. }
  100. }
  101. }
  102. // IF FORTE AGENT IS NOT FOUND, CHECK FOR FREE AGENT.
  103. // CHECK THE DEFAULT PATH "C:\AGENT\DATA " FOR THE "AGENT.INI" FILE
  104. else if(GetPrivateProfileString("Servers", "NewsServer", "", szNewsServer, MAX_PATH, c_szDefPath))
  105. {
  106. if (!MemAlloc((void **)&m_rgInfo, 1*sizeof(AGNTNEWSACCTINFO)))
  107. {
  108. hr = E_OUTOFMEMORY;
  109. goto done;
  110. }
  111. GetPrivateProfileString("Profile", "FullName", "Default User", szUserName, MAX_PATH, c_szDefPath);
  112. m_rgInfo[m_cInfo].dwCookie = m_cInfo;
  113. StrCpyN(m_rgInfo[m_cInfo].szUserPath, c_szDefPath, ARRAYSIZE(m_rgInfo[m_cInfo].szUserPath));
  114. StrCpyN(m_rgInfo[m_cInfo].szDisplay, szUserName, ARRAYSIZE(m_rgInfo[m_cInfo].szDisplay));
  115. m_cInfo++;
  116. }
  117. // ELSE THE WORKAROUND FOR GETTING THE FREE AGENT INSTALL PATH i.e. RETRIEVE THE (UN)INSTALLATION PATH FOR (FREE?)-AGENT FROM THE REGISTRY.
  118. else
  119. {
  120. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegUninstall, 0, KEY_ALL_ACCESS, &hkey))
  121. {
  122. cb = sizeof(szUserIniPath);
  123. if(ERROR_SUCCESS == RegQueryValueEx(hkey, c_szRegString, NULL, &dwType, (LPBYTE)szUserIniPath, &cb ))
  124. {
  125. // $$$Review: [NAB] Seems like this would break if there were a space in the the dir name!
  126. while(szUserIniPath[nCount] != ' ')
  127. nCount++;
  128. // Come back now.
  129. while(szUserIniPath[nCount] != '\\')
  130. nCount--;
  131. nCount++;
  132. szUserIniPath[nCount] = '\0';
  133. StrCatBuff(szUserIniPath, szIniPath, ARRAYSIZE(szUserIniPath));
  134. if (REG_EXPAND_SZ == dwType)
  135. {
  136. ExpandEnvironmentStrings(szUserIniPath, szExpanded, ARRAYSIZE(szExpanded));
  137. psz = szExpanded;
  138. }
  139. else
  140. psz = szUserIniPath;
  141. GetPrivateProfileString("Profile", "FullName", "Default User", szUserName, MAX_PATH, psz);
  142. if(GetPrivateProfileString("Servers", "NewsServer", "", szNewsServer, MAX_PATH, psz))
  143. {
  144. if (!MemAlloc((void **)&m_rgInfo, 1*sizeof(AGNTNEWSACCTINFO)))
  145. {
  146. hr = E_OUTOFMEMORY;
  147. goto done;
  148. }
  149. m_rgInfo[m_cInfo].dwCookie = m_cInfo;
  150. StrCpyN(m_rgInfo[m_cInfo].szUserPath, psz, ARRAYSIZE(m_rgInfo[m_cInfo].szUserPath));
  151. StrCpyN(m_rgInfo[m_cInfo].szDisplay, szUserName, ARRAYSIZE(m_rgInfo[m_cInfo].szDisplay));
  152. m_cInfo++;
  153. }
  154. }
  155. }
  156. }
  157. if (hr == S_OK)
  158. {
  159. *pcAcct = m_cInfo;
  160. }
  161. done:
  162. RegCloseKey(hkey);
  163. return(hr);
  164. }
  165. HRESULT STDMETHODCALLTYPE CAgentAcctImport::InitializeImport(HWND hwnd, DWORD_PTR dwCookie)
  166. {
  167. return S_OK;
  168. }
  169. HRESULT STDMETHODCALLTYPE CAgentAcctImport::EnumerateAccounts(IEnumIMPACCOUNTS **ppEnum)
  170. {
  171. CEnumAGNTACCT *penum;
  172. HRESULT hr;
  173. if (ppEnum == NULL)
  174. return(E_INVALIDARG);
  175. *ppEnum = NULL;
  176. if (m_cInfo == 0)
  177. return(S_FALSE);
  178. Assert(m_rgInfo != NULL);
  179. penum = new CEnumAGNTACCT;
  180. if (penum == NULL)
  181. return(E_OUTOFMEMORY);
  182. hr = penum->Init(m_rgInfo, m_cInfo);
  183. if (FAILED(hr))
  184. {
  185. penum->Release();
  186. penum = NULL;
  187. }
  188. *ppEnum = penum;
  189. return(hr);
  190. }
  191. HRESULT STDMETHODCALLTYPE CAgentAcctImport::GetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct)
  192. {
  193. HRESULT hr;
  194. if (pAcct == NULL)
  195. return(E_INVALIDARG);
  196. hr = IGetSettings(dwCookie, pAcct, NULL);
  197. return(hr);
  198. }
  199. HRESULT CAgentAcctImport::IGetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  200. {
  201. HRESULT hr;
  202. AGNTNEWSACCTINFO *pinfo;
  203. char szUserPrefs[AGNTSUSERROWS][AGNTSUSERCOLS];
  204. char sz[512];
  205. DWORD cb, type;
  206. DWORD dwNewsPort = 119;
  207. ZeroMemory((void*)&szUserPrefs[0], AGNTSUSERCOLS*AGNTSUSERROWS*sizeof(char));
  208. Assert(((int) dwCookie) >= 0 && dwCookie < (DWORD_PTR)m_cInfo);
  209. pinfo = &m_rgInfo[dwCookie];
  210. Assert(pinfo->dwCookie == dwCookie);
  211. hr = GetUserPrefs(pinfo->szUserPath, szUserPrefs);
  212. Assert(0 < lstrlen(szUserPrefs[0]));
  213. hr = pAcct->SetPropSz(AP_ACCOUNT_NAME, szUserPrefs[0]);
  214. if (FAILED(hr))
  215. return(hr);
  216. hr = pAcct->SetPropSz(AP_NNTP_SERVER, szUserPrefs[0]);
  217. Assert(!FAILED(hr));
  218. if(lstrcmp(szUserPrefs[1], "119"))
  219. {
  220. int Len = lstrlen(szUserPrefs[1]);
  221. if(Len)
  222. {
  223. // Convert the string to a dw.
  224. DWORD dwMult = 1;
  225. dwNewsPort = 0;
  226. while(Len)
  227. {
  228. Len--;
  229. dwNewsPort += ((int)szUserPrefs[1][Len] - 48)*dwMult;
  230. dwMult *= 10;
  231. }
  232. }
  233. }
  234. hr = pAcct->SetPropDw(AP_NNTP_PORT, dwNewsPort);
  235. Assert(!FAILED(hr));
  236. if(lstrlen(szUserPrefs[2]))
  237. {
  238. hr = pAcct->SetPropSz(AP_NNTP_DISPLAY_NAME, szUserPrefs[2]);
  239. Assert(!FAILED(hr));
  240. }
  241. if(lstrlen(szUserPrefs[3]))
  242. {
  243. hr = pAcct->SetPropSz(AP_NNTP_EMAIL_ADDRESS, szUserPrefs[3]);
  244. Assert(!FAILED(hr));
  245. }
  246. if (pInfo != NULL)
  247. {
  248. // TODO: can we do any better than this???
  249. pInfo->dwConnect = CONN_USE_DEFAULT;
  250. }
  251. return(S_OK);
  252. }
  253. HRESULT CAgentAcctImport::GetUserPrefs(char *szUserPath, char szUserPrefs[][AGNTSUSERCOLS])
  254. {
  255. HRESULT hr = E_FAIL;
  256. DWORD dwResult = 0;
  257. if(!GetPrivateProfileString("Servers", "NewsServer", "News", szUserPrefs[0], AGNTSUSERCOLS, szUserPath))
  258. hr = S_FALSE;
  259. if(!GetPrivateProfileString("Servers", "NNTPPort", "119", szUserPrefs[1], AGNTSUSERCOLS, szUserPath))
  260. hr = S_FALSE;
  261. if(!GetPrivateProfileString("Profile", "FullName", "Default User", szUserPrefs[2], AGNTSUSERCOLS, szUserPath))
  262. hr = S_FALSE;
  263. if(!GetPrivateProfileString("Profile", "EMailAddress", "", szUserPrefs[3], AGNTSUSERCOLS, szUserPath))
  264. hr = S_FALSE;
  265. return hr;
  266. }
  267. HRESULT CAgentAcctImport::GetNewsGroup(INewsGroupImport *pImp, DWORD dwReserved)
  268. {
  269. // We can ignore the first parameter as we have only one server.
  270. HRESULT hr = S_OK;
  271. char *pListGroups = NULL;
  272. char szFilePath[AGNTSUSERCOLS];
  273. int nCounter;
  274. Assert(pImp != NULL);
  275. StrCpyNA(szFilePath, m_rgInfo[0].szUserPath, ARRAYSIZE(szFilePath));
  276. nCounter = lstrlen(szFilePath);
  277. if (nCounter)
  278. {
  279. while (nCounter)
  280. {
  281. if (szFilePath[nCounter] == '\\')
  282. {
  283. szFilePath[nCounter] = '\0';
  284. break;
  285. }
  286. nCounter--;
  287. }
  288. }
  289. else
  290. {
  291. return S_FALSE;
  292. }
  293. if (!FAILED(GetSubListGroups(szFilePath, &pListGroups)))
  294. {
  295. if (!SUCCEEDED(pImp->ImportSubList(pListGroups)))
  296. hr = S_FALSE;
  297. }
  298. if (pListGroups != NULL)
  299. MemFree(pListGroups);
  300. return hr;
  301. }
  302. const static char c_szGroupFile[] = "Groups.dat";
  303. const static char c_szBakupFile[] = "Grpdat.bak";
  304. HRESULT CAgentAcctImport::GetSubListGroups(char *szHomeDir, char **ppListGroups)
  305. {
  306. return(E_FAIL);
  307. }
  308. STDMETHODIMP CAgentAcctImport::GetSettings2(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
  309. {
  310. if (pAcct == NULL ||
  311. pInfo == NULL)
  312. return(E_INVALIDARG);
  313. return(IGetSettings(dwCookie, pAcct, pInfo));
  314. }
  315. CEnumAGNTACCT::CEnumAGNTACCT()
  316. {
  317. m_cRef = 1;
  318. // m_iInfo
  319. m_cInfo = 0;
  320. m_rgInfo = NULL;
  321. }
  322. CEnumAGNTACCT::~CEnumAGNTACCT()
  323. {
  324. if (m_rgInfo != NULL)
  325. MemFree(m_rgInfo);
  326. }
  327. STDMETHODIMP CEnumAGNTACCT::QueryInterface(REFIID riid, LPVOID *ppv)
  328. {
  329. if (ppv == NULL)
  330. return(E_INVALIDARG);
  331. *ppv = NULL;
  332. if (IID_IUnknown == riid)
  333. *ppv = (IUnknown *)this;
  334. else if (IID_IEnumIMPACCOUNTS == riid)
  335. *ppv = (IEnumIMPACCOUNTS *)this;
  336. if (*ppv != NULL)
  337. ((LPUNKNOWN)*ppv)->AddRef();
  338. else
  339. return(E_NOINTERFACE);
  340. return(S_OK);
  341. }
  342. STDMETHODIMP_(ULONG) CEnumAGNTACCT::AddRef()
  343. {
  344. return(++m_cRef);
  345. }
  346. STDMETHODIMP_(ULONG) CEnumAGNTACCT::Release()
  347. {
  348. if (--m_cRef == 0)
  349. {
  350. delete this;
  351. return(0);
  352. }
  353. return(m_cRef);
  354. }
  355. HRESULT STDMETHODCALLTYPE CEnumAGNTACCT::Next(IMPACCOUNTINFO *pinfo)
  356. {
  357. if (pinfo == NULL)
  358. return(E_INVALIDARG);
  359. m_iInfo++;
  360. if ((UINT)m_iInfo >= m_cInfo)
  361. return(S_FALSE);
  362. Assert(m_rgInfo != NULL);
  363. pinfo->dwCookie = m_rgInfo[m_iInfo].dwCookie;
  364. pinfo->dwReserved = 0;
  365. StrCpyNA(pinfo->szDisplay, m_rgInfo[m_iInfo].szDisplay, ARRAYSIZE(pinfo->szDisplay));
  366. return(S_OK);
  367. }
  368. HRESULT STDMETHODCALLTYPE CEnumAGNTACCT::Reset()
  369. {
  370. m_iInfo = -1;
  371. return(S_OK);
  372. }
  373. HRESULT CEnumAGNTACCT::Init(AGNTNEWSACCTINFO *pinfo, int cinfo)
  374. {
  375. DWORD cb;
  376. Assert(pinfo != NULL);
  377. Assert(cinfo > 0);
  378. cb = cinfo * sizeof(AGNTNEWSACCTINFO);
  379. if (!MemAlloc((void **)&m_rgInfo, cb))
  380. return(E_OUTOFMEMORY);
  381. m_iInfo = -1;
  382. m_cInfo = cinfo;
  383. CopyMemory(m_rgInfo, pinfo, cb);
  384. return(S_OK);
  385. }