986 lines
26 KiB
C++
986 lines
26 KiB
C++
#include "pch.hxx"
|
|
#include <imnact.h>
|
|
#include <acctimp.h>
|
|
#include <dllmain.h>
|
|
#include <resource.h>
|
|
#include "CommNews.h"
|
|
#include "newimp.h"
|
|
#include "ids.h"
|
|
|
|
ASSERTDATA
|
|
|
|
INT_PTR CALLBACK SelectServerDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
const static char c_szNescapeMapFile[] = "netscape-newsrc-map-file";
|
|
#define MEMCHUNK 512
|
|
|
|
CCommNewsAcctImport::CCommNewsAcctImport()
|
|
{
|
|
m_cRef = 1;
|
|
m_fIni = FALSE;
|
|
*m_szIni = 0;
|
|
m_cInfo = 0;
|
|
m_rgInfo = NULL;
|
|
m_szSubList = NULL;
|
|
m_rgServ = NULL;
|
|
m_nNumServ = 0;
|
|
}
|
|
|
|
CCommNewsAcctImport::~CCommNewsAcctImport()
|
|
{
|
|
NEWSSERVERS *pTempServ = m_rgServ;
|
|
NEWSSERVERS *pNextServ = pTempServ;
|
|
|
|
if (m_rgInfo != NULL)
|
|
MemFree(m_rgInfo);
|
|
|
|
if(m_szSubList != NULL)
|
|
MemFree(m_szSubList);
|
|
|
|
while(pTempServ)
|
|
{
|
|
pNextServ = pTempServ->pNext;
|
|
delete(pTempServ);
|
|
pTempServ = pNextServ;
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP CCommNewsAcctImport::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
if (ppv == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IID_IUnknown == riid || riid == IID_IAccountImport)
|
|
*ppv = (IAccountImport *)this;
|
|
else if (IID_IAccountImport2 == riid)
|
|
*ppv = (IAccountImport2 *)this;
|
|
else
|
|
return(E_NOINTERFACE);
|
|
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CCommNewsAcctImport::AddRef()
|
|
{
|
|
return(++m_cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CCommNewsAcctImport::Release()
|
|
{
|
|
if (--m_cRef == 0)
|
|
{
|
|
delete this;
|
|
return(0);
|
|
}
|
|
|
|
return(m_cRef);
|
|
}
|
|
|
|
const static char c_szRegNscp[] = "Software\\Netscape\\Netscape Navigator\\Users";
|
|
const static char c_szRegMail[] = "Mail";
|
|
const static char c_szRegUser[] = "User";
|
|
const static char c_szRegDirRoot[] = "DirRoot";
|
|
|
|
HRESULT STDMETHODCALLTYPE CCommNewsAcctImport::AutoDetect(DWORD *pcAcct, DWORD dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwNumSubKeys = 0;
|
|
DWORD dwIndex = 0;
|
|
HRESULT hrUser = E_FAIL;
|
|
DWORD cb = MAX_PATH;
|
|
char szUserName[MAX_PATH];
|
|
char szUserProfile[MAX_PATH];
|
|
char szUserPrefs[2][NEWSUSERCOLS], szExpanded[MAX_PATH], *psz;
|
|
HKEY hkey,
|
|
hkeyUsers;
|
|
char szPop[MAX_PATH];
|
|
DWORD dwType;
|
|
long lRetVal = 0;
|
|
|
|
|
|
Assert(m_cInfo == 0);
|
|
if (pcAcct == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
hr = S_FALSE;
|
|
*pcAcct = 0;
|
|
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegNscp, 0, KEY_ALL_ACCESS, &hkey))
|
|
{
|
|
// TODO : Fill up the m_rgInfo array with the info of all
|
|
// the users who have accounts in Communicator.
|
|
if(ERROR_SUCCESS == RegQueryInfoKey( hkey, NULL, NULL, 0, &dwNumSubKeys,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL ) && (dwNumSubKeys > 0))
|
|
{
|
|
if (!MemAlloc((void **)&m_rgInfo, dwNumSubKeys * sizeof(COMMNEWSACCTINFO)))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto done;
|
|
}
|
|
|
|
while(ERROR_SUCCESS == RegEnumKeyEx(hkey, dwIndex, szUserName, &cb, NULL, NULL, NULL, NULL))
|
|
{
|
|
if(ERROR_SUCCESS == RegOpenKeyEx(hkey, szUserName, 0, KEY_ALL_ACCESS, &hkeyUsers))
|
|
{
|
|
cb = sizeof(szUserProfile);
|
|
if(ERROR_SUCCESS == (lRetVal = RegQueryValueEx(hkeyUsers, c_szRegDirRoot, NULL, &dwType, (LPBYTE)szUserProfile, &cb )))
|
|
{
|
|
if (REG_EXPAND_SZ == dwType)
|
|
{
|
|
ExpandEnvironmentStrings(szUserProfile, szExpanded, ARRAYSIZE(szExpanded));
|
|
psz = szExpanded;
|
|
}
|
|
else
|
|
psz = szUserProfile;
|
|
|
|
//save vals into the m_rgInfo structure
|
|
hrUser = GetUserPrefs(psz, szUserPrefs, 1, NULL);
|
|
if(!FAILED(hrUser))
|
|
{
|
|
hrUser = IsValidUser(psz);
|
|
if(!FAILED(hrUser))
|
|
{
|
|
m_rgInfo[m_cInfo].dwCookie = m_cInfo;
|
|
StrCpyN(m_rgInfo[m_cInfo].szUserPath, psz, ARRAYSIZE(m_rgInfo[m_cInfo].szUserPath));
|
|
StrCpyN(m_rgInfo[m_cInfo].szDisplay, szUserName, ARRAYSIZE(m_rgInfo[m_cInfo].szDisplay));
|
|
m_cInfo++;
|
|
}
|
|
}
|
|
}
|
|
RegCloseKey(hkeyUsers);
|
|
}
|
|
dwIndex++;
|
|
if(dwIndex == dwNumSubKeys)
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
*pcAcct = m_cInfo;
|
|
}
|
|
|
|
done:
|
|
// Close the reg key now....
|
|
RegCloseKey(hkey);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
typedef struct tagSELSERVER
|
|
{
|
|
NEWSSERVERS *prgList;
|
|
DWORD *dwSelServ;
|
|
|
|
}SELSERVER;
|
|
|
|
// This function is called after we select a user profile (in case more than one is present)
|
|
// but before the 'GetSettings' finction is called. In case this profile has more than one
|
|
// servers configured, we need to display a dialog box asking the user to select a server
|
|
// account to import.
|
|
|
|
HRESULT STDMETHODCALLTYPE CCommNewsAcctImport::InitializeImport(HWND hwnd, DWORD_PTR dwCookie)
|
|
{
|
|
HRESULT hr;
|
|
SELSERVER ss;
|
|
int nRetVal = 0;
|
|
|
|
GetNumAccounts(dwCookie);
|
|
|
|
if(m_rgServ == NULL)
|
|
{
|
|
m_dwSelServ = 0;
|
|
return S_OK;
|
|
}
|
|
ss.prgList = m_rgServ;
|
|
ss.dwSelServ = &m_dwSelServ;
|
|
|
|
if(m_nNumServ > 1)
|
|
{
|
|
nRetVal = (int) DialogBoxParam(g_hInstRes, MAKEINTRESOURCE(IDD_PAGE_NEWSSERVERSELECT), hwnd, SelectServerDlgProc, (LPARAM)&ss);
|
|
if (nRetVal == IDCANCEL)
|
|
hr = E_FAIL;
|
|
else if (nRetVal == IDOK)
|
|
hr = S_OK;
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
m_dwSelServ = 0;
|
|
hr = S_OK;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
INT_PTR CALLBACK SelectServerDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hwndT;
|
|
WORD id;
|
|
DWORD iSubKey, cb;
|
|
char sz[MAX_PATH];
|
|
SELSERVER *pss;
|
|
NEWSSERVERS *pTempServ = NULL;
|
|
int index;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
Assert(lParam != NULL);
|
|
pss = (SELSERVER *)lParam;
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pss);
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_ACCTLIST);
|
|
|
|
// fill list
|
|
pTempServ = pss->prgList;
|
|
while(pTempServ != NULL)
|
|
{
|
|
if(lstrlen(pTempServ->szServerName) && lstrlen(pTempServ->szFilePath))
|
|
{
|
|
SendMessage(hwndT, LB_ADDSTRING, 0, (LPARAM)pTempServ->szServerName);
|
|
}
|
|
pTempServ = pTempServ->pNext;
|
|
}
|
|
|
|
SendMessage(hwndT, LB_SETCURSEL, 0, 0);
|
|
return(TRUE);
|
|
|
|
case WM_COMMAND:
|
|
id = LOWORD(wParam);
|
|
switch (id)
|
|
{
|
|
case IDOK:
|
|
pss = (SELSERVER *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
Assert(pss != NULL);
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_ACCTLIST);
|
|
index = (int) SendMessage(hwndT, LB_GETCURSEL, 0, 0);
|
|
Assert(index >= 0);
|
|
*(pss->dwSelServ) = (long)index;
|
|
|
|
// fall through
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hwnd, id);
|
|
return(TRUE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CCommNewsAcctImport::EnumerateAccounts(IEnumIMPACCOUNTS **ppEnum)
|
|
{
|
|
CEnumCOMMNEWSACCT *penum;
|
|
HRESULT hr;
|
|
|
|
if (ppEnum == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
*ppEnum = NULL;
|
|
|
|
if (m_cInfo == 0)
|
|
return(S_FALSE);
|
|
Assert(m_rgInfo != NULL);
|
|
|
|
penum = new CEnumCOMMNEWSACCT;
|
|
if (penum == NULL)
|
|
return(E_OUTOFMEMORY);
|
|
|
|
hr = penum->Init(m_rgInfo, m_cInfo);
|
|
if (FAILED(hr))
|
|
{
|
|
penum->Release();
|
|
penum = NULL;
|
|
}
|
|
|
|
*ppEnum = penum;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CCommNewsAcctImport::IsValidUser(char *pszFilePath)
|
|
{
|
|
char szNewsPath[MAX_PATH * 2];
|
|
HANDLE hFatFile = NULL;
|
|
DWORD dwFatFileSize = 0;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
StrCpyN(szNewsPath, pszFilePath, ARRAYSIZE(szNewsPath));
|
|
StrCatBuff(szNewsPath, "\\News\\fat", ARRAYSIZE(szNewsPath));
|
|
|
|
hFatFile = CreateFile(szNewsPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
|
|
if(INVALID_HANDLE_VALUE == hFatFile)
|
|
return hr;
|
|
|
|
dwFatFileSize = GetFileSize(hFatFile, NULL);
|
|
|
|
if(dwFatFileSize > 0)
|
|
hr = S_OK;
|
|
|
|
CloseHandle(hFatFile);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// The following two functions have been added to handle the importing of subscribed newsgroups
|
|
|
|
HRESULT CCommNewsAcctImport::GetNumAccounts(DWORD_PTR dwCookie)
|
|
{
|
|
COMMNEWSACCTINFO *pinfo;
|
|
NEWSSERVERS *pTempServ = NULL;
|
|
NEWSSERVERS *pPrevServ = NULL;
|
|
HRESULT hr = S_FALSE;
|
|
char szNewsPath[MAX_PATH * 2];
|
|
char szLineHolder[MAX_PATH * 2];
|
|
HANDLE hFatFile = NULL;
|
|
HANDLE hFatFileMap = NULL;
|
|
BYTE *pFatViewBegin = NULL,
|
|
*pFatViewCurr = NULL,
|
|
*pFatViewEnd = NULL;
|
|
char *pParse = NULL;
|
|
char *pServName = NULL;
|
|
DWORD dwFatFileSize = 0;
|
|
UINT uLine = 0;
|
|
char cPlaceHldr = 1;
|
|
int nCount = 0;
|
|
|
|
Assert(((int)dwCookie) >= 0 && dwCookie < (DWORD)m_cInfo);
|
|
pinfo = &m_rgInfo[dwCookie];
|
|
Assert(pinfo->dwCookie == dwCookie);
|
|
|
|
StrCpyN(szNewsPath, pinfo->szUserPath, ARRAYSIZE(szNewsPath));
|
|
StrCatBuff(szNewsPath, "\\News\\fat", ARRAYSIZE(szNewsPath));
|
|
|
|
hFatFile = CreateFile(szNewsPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
|
|
if(INVALID_HANDLE_VALUE == hFatFile)
|
|
return hr;
|
|
|
|
dwFatFileSize = GetFileSize(hFatFile, NULL);
|
|
|
|
hFatFileMap = CreateFileMapping(hFatFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
|
|
if(NULL == hFatFileMap)
|
|
{
|
|
CloseHandle(hFatFile);
|
|
return hr;
|
|
}
|
|
|
|
pFatViewBegin = (BYTE*)MapViewOfFile(hFatFileMap, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if(pFatViewBegin == NULL)
|
|
{
|
|
CloseHandle(hFatFileMap);
|
|
CloseHandle(hFatFile);
|
|
return hr;
|
|
}
|
|
|
|
pFatViewCurr = pFatViewBegin;
|
|
pFatViewEnd = pFatViewCurr + dwFatFileSize;
|
|
|
|
pTempServ = m_rgServ;
|
|
while(pTempServ)
|
|
{
|
|
pPrevServ = pTempServ->pNext;
|
|
ZeroMemory(pTempServ, sizeof(NEWSSERVERS));
|
|
pTempServ->pNext = pPrevServ;
|
|
pTempServ = pTempServ->pNext;
|
|
}
|
|
pTempServ = NULL;
|
|
pPrevServ = NULL;
|
|
|
|
// We will skip the first line in the "fat" file as it contains a comment.
|
|
// m_szSubList is a null separated list of
|
|
while(pFatViewCurr < pFatViewEnd)
|
|
{
|
|
uLine = 0;
|
|
while(!((pFatViewCurr[uLine] == 0x0D) && (pFatViewCurr[uLine + 1] == 0x0A)) && (pFatViewCurr + uLine < pFatViewEnd))
|
|
uLine++;
|
|
|
|
if(pFatViewCurr + uLine > pFatViewEnd)
|
|
break;
|
|
|
|
StrCpyN(szLineHolder, (char*)pFatViewCurr, uLine + 1);
|
|
pServName = szLineHolder;
|
|
pParse = szLineHolder;
|
|
|
|
if(!lstrcmp(szLineHolder, c_szNescapeMapFile))
|
|
{
|
|
pFatViewCurr += (uLine + 2);
|
|
nCount = 0;
|
|
continue;
|
|
}
|
|
|
|
while((*pServName != '-') && (*pServName != '\0'))
|
|
pServName++;
|
|
pServName++;
|
|
|
|
// Go to the first char '9' position
|
|
while((*pParse != '\0') && ((*pParse) != 9))
|
|
pParse++;
|
|
*pParse = '\0';
|
|
// pass over what was originally the first char '9' position
|
|
pParse++;
|
|
|
|
// Trim the remaining string to the second char '9' position.
|
|
while(pParse[nCount] != '\0')
|
|
{
|
|
if((int)pParse[nCount] == 9)
|
|
{
|
|
pParse[nCount] = '\0';
|
|
break;
|
|
}
|
|
nCount++;
|
|
}
|
|
|
|
if(0 == pPrevServ)
|
|
{
|
|
if(!m_rgServ)
|
|
{
|
|
m_rgServ = (NEWSSERVERS*)new NEWSSERVERS;
|
|
ZeroMemory((void*)m_rgServ, sizeof(NEWSSERVERS));
|
|
}
|
|
StrCpyN(m_rgServ->szServerName, pServName, ARRAYSIZE(m_rgServ->szServerName));
|
|
StrCpyN(m_rgServ->szFilePath, pParse, ARRAYSIZE(m_rgServ->szFilePath));
|
|
pPrevServ = m_rgServ;
|
|
}
|
|
else
|
|
{
|
|
if(!pPrevServ->pNext)
|
|
{
|
|
pPrevServ->pNext = (NEWSSERVERS*)new NEWSSERVERS;
|
|
ZeroMemory((void*)pPrevServ->pNext, sizeof(NEWSSERVERS));
|
|
}
|
|
StrCpyN(pPrevServ->pNext->szServerName, pServName, ARRAYSIZE(pPrevServ->pNext->szServerName));
|
|
StrCpyN(pPrevServ->pNext->szFilePath, pParse, ARRAYSIZE(pPrevServ->pNext->szFilePath));
|
|
pPrevServ = pPrevServ->pNext;
|
|
}
|
|
|
|
pFatViewCurr += (uLine + 2);
|
|
nCount = 0;
|
|
}
|
|
|
|
//replace the cPlaceHldr placeholder by nulls.
|
|
|
|
hr = S_OK;
|
|
|
|
pTempServ = m_rgServ;
|
|
m_nNumServ = 0;
|
|
while(pTempServ != NULL)
|
|
{
|
|
if(lstrlen(pTempServ->szServerName) && lstrlen(pTempServ->szFilePath))
|
|
{
|
|
m_nNumServ += 1;
|
|
}
|
|
pTempServ = pTempServ->pNext;
|
|
}
|
|
|
|
// Done:
|
|
CloseHandle(hFatFileMap);
|
|
CloseHandle(hFatFile);
|
|
UnmapViewOfFile(pFatViewBegin);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCommNewsAcctImport::GetNewsGroup(INewsGroupImport *pImp, DWORD dwReserved) //char *szServerName, char *szAccountName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HINSTANCE hInstance = NULL;
|
|
char *pListGroups = NULL;
|
|
NEWSSERVERS *pTempServ = NULL;
|
|
NEWSSERVERS *pPrevServ = NULL;
|
|
char szTempString[NEWSUSERCOLS];
|
|
char szFilePath[NEWSUSERCOLS];
|
|
int nReach = 0;
|
|
|
|
szFilePath[0] = '\0';
|
|
Assert(m_nNumServ > m_dwSelServ);
|
|
Assert(pImp != NULL);
|
|
|
|
pTempServ = m_rgServ;
|
|
for(DWORD nTemp1 = 0; nTemp1 < m_dwSelServ; nTemp1++)
|
|
{
|
|
pTempServ = pTempServ->pNext;
|
|
if(pTempServ == NULL)
|
|
return S_FALSE;
|
|
}
|
|
|
|
if(!FAILED(GetSubListGroups(pTempServ->szFilePath, &pListGroups)))
|
|
{
|
|
if(!SUCCEEDED(pImp->ImportSubList(pListGroups)))
|
|
hr = S_FALSE;
|
|
}
|
|
if(pListGroups != NULL)
|
|
MemFree(pListGroups);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCommNewsAcctImport::GetSubListGroups(char *pFileName, char **ppListGroups)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
HANDLE hRCHandle = NULL;
|
|
HANDLE hRCFile = NULL;
|
|
ULONG cbRCFile = 0;
|
|
BYTE *pBegin = NULL,
|
|
*pCurr = NULL,
|
|
*pEnd = NULL;
|
|
int nBalMem = MEMCHUNK;
|
|
int nLine = 0,
|
|
nCount = 0;
|
|
char cPlaceHolder = 1;
|
|
char szLineHolder[MEMCHUNK];
|
|
char *pListGroups = NULL;
|
|
|
|
Assert(lstrlen(pFileName));
|
|
Assert(ppListGroups);
|
|
*ppListGroups = NULL;
|
|
|
|
hRCHandle = CreateFile( pFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
|
|
if(hRCHandle == INVALID_HANDLE_VALUE)
|
|
return hr;
|
|
|
|
cbRCFile = GetFileSize(hRCHandle, NULL);
|
|
|
|
if(!cbRCFile) // Empty File.
|
|
goto Done;
|
|
|
|
hRCFile = CreateFileMapping(hRCHandle, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
|
|
if(hRCFile == NULL)
|
|
{
|
|
CloseHandle(hRCHandle);
|
|
return hr;
|
|
}
|
|
|
|
pBegin = (BYTE *)MapViewOfFile( hRCFile, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if(pBegin == NULL)
|
|
{
|
|
CloseHandle(hRCHandle);
|
|
CloseHandle(hRCFile);
|
|
return hr;
|
|
}
|
|
|
|
pCurr = pBegin;
|
|
pEnd = pCurr + cbRCFile;
|
|
|
|
if (!MemAlloc((void **)&pListGroups, MEMCHUNK))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Done;
|
|
}
|
|
|
|
DWORD cchSizeListGroups = MEMCHUNK;
|
|
ZeroMemory((void*)pListGroups, (cchSizeListGroups * sizeof(pListGroups[0])));
|
|
|
|
while (pCurr < pEnd)
|
|
{
|
|
nLine = 0;
|
|
while(!((pCurr[nLine] == ':') || (pCurr[nLine] == '!')) && (pCurr + nLine < pEnd))
|
|
nLine++;
|
|
|
|
if(pCurr + nLine > pEnd)
|
|
break;
|
|
|
|
if(pCurr[nLine] == '!')
|
|
goto LineEnd;
|
|
|
|
nLine++;
|
|
if(nLine < MEMCHUNK)
|
|
StrCpyN(szLineHolder, (char*)pCurr, nLine);
|
|
else
|
|
continue;
|
|
|
|
if(nLine + 2 < nBalMem)
|
|
{
|
|
StrCatBuff(pListGroups, szLineHolder, cchSizeListGroups);
|
|
StrCatBuff(pListGroups, "\1", cchSizeListGroups);
|
|
nBalMem -= (nLine + 2);
|
|
}
|
|
else
|
|
{
|
|
cchSizeListGroups += (lstrlen(pListGroups) + 1 + MEMCHUNK);
|
|
if(!MemRealloc((void **)&pListGroups, (cchSizeListGroups * sizeof(pListGroups[0]))))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Done;
|
|
}
|
|
nBalMem += MEMCHUNK;
|
|
StrCatBuff(pListGroups, szLineHolder, cchSizeListGroups);
|
|
StrCatBuff(pListGroups, "\1", cchSizeListGroups);
|
|
nBalMem -= (nLine + 2);
|
|
}
|
|
|
|
LineEnd:
|
|
while(!((pCurr[nLine] == 0x0D) && (pCurr[nLine + 1] == 0x0A)) && (pCurr + nLine < pEnd))
|
|
nLine++;
|
|
pCurr += (nLine + 2);
|
|
}
|
|
|
|
if(lstrlen(pListGroups))
|
|
{
|
|
while(pListGroups[nCount] != '\0')
|
|
{
|
|
if(pListGroups[nCount] == cPlaceHolder)
|
|
{
|
|
pListGroups[nCount] = '\0';
|
|
}
|
|
nCount++;
|
|
}
|
|
*ppListGroups = pListGroups;
|
|
hr = S_OK;
|
|
}
|
|
|
|
Done:
|
|
if(pBegin)
|
|
UnmapViewOfFile(pBegin);
|
|
if(hRCHandle != INVALID_HANDLE_VALUE)
|
|
CloseHandle(hRCHandle);
|
|
if(hRCFile)
|
|
CloseHandle(hRCFile);
|
|
|
|
return hr;
|
|
}
|
|
|
|
const static char c_szSearch[][NEWSUSERCOLS] = {"user_pref(\"network.hosts.nntp_server\"",
|
|
"user_pref(\"news.server_port\"",
|
|
"user_pref(\"mail.identity.username\"", // This is the same for NNTP also.
|
|
"user_pref(\"mail.identity.useremail\""};
|
|
const static char c_szPrefs[] = "\\prefs.js";
|
|
|
|
HRESULT CCommNewsAcctImport::GetUserPrefs(char *szUserPath, char szUserPrefs[][NEWSUSERCOLS], int nInLoop, BOOL *pbPop)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
char szTemp[MAX_PATH * 2];
|
|
char szDirpath[250];
|
|
char szLine[1000];
|
|
char szCompare[1000];
|
|
int nLine = 0;
|
|
int nFilled = 0;
|
|
int nPosition = 0;
|
|
int nLoop = nInLoop;
|
|
HANDLE hJSHandle = NULL;
|
|
HANDLE hJSFile = NULL;
|
|
ULONG cbJSFile = 0;
|
|
|
|
BYTE *pBegin = NULL,
|
|
*pCurr = NULL,
|
|
*pEnd = NULL;
|
|
|
|
Assert(nInLoop <= NEWSUSERROWS);
|
|
StrCpyN(szTemp, szUserPath, ARRAYSIZE(szTemp));
|
|
StrCatBuff(szTemp, c_szPrefs, ARRAYSIZE(szTemp));
|
|
|
|
hJSHandle = CreateFile( szTemp, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
|
|
if(hJSHandle == INVALID_HANDLE_VALUE)
|
|
return hr;
|
|
|
|
cbJSFile = GetFileSize(hJSHandle, NULL);
|
|
|
|
hJSFile = CreateFileMapping(hJSHandle, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
|
|
if(hJSFile == NULL)
|
|
{
|
|
CloseHandle(hJSHandle);
|
|
return hr;
|
|
}
|
|
|
|
pBegin = (BYTE *)MapViewOfFile( hJSFile, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if(pBegin == NULL)
|
|
{
|
|
CloseHandle(hJSHandle);
|
|
CloseHandle(hJSFile);
|
|
return hr;
|
|
}
|
|
|
|
pCurr = pBegin;
|
|
pEnd = pCurr + cbJSFile;
|
|
|
|
while (pCurr < pEnd)
|
|
{
|
|
szLine[nLine] = *pCurr; //keep storing here. will be used for comparing later.
|
|
if((pCurr[0] == 0x0D) && (pCurr[1] == 0x0A))
|
|
{
|
|
while(nLoop)
|
|
{
|
|
StrCpyN(szCompare, szLine, lstrlen(c_szSearch[nLoop - 1]) + 1);
|
|
if(lstrcmp(szCompare, c_szSearch[nLoop - 1]) == 0)
|
|
{
|
|
//Found a UserPref one of the things we are looking for"!
|
|
//Extract the stuff we want.
|
|
nPosition = lstrlen(c_szSearch[nLoop - 1]);
|
|
|
|
while (((szLine[nPosition] == '"')||(szLine[nPosition] == ' ')||(szLine[nPosition] == ',')) &&(nPosition < nLine))
|
|
nPosition++;
|
|
StrCpyN(szDirpath, &szLine[nPosition], nLine - nPosition);
|
|
|
|
//Now trim the trailing edge!!!
|
|
|
|
nPosition = lstrlen(szDirpath) - 1;
|
|
while((szDirpath[nPosition] == '"') || (szDirpath[nPosition] == ')')||(szDirpath[nPosition] == ';'))
|
|
{
|
|
szDirpath[nPosition] = '\0';
|
|
nPosition = lstrlen(szDirpath) - 1;
|
|
}
|
|
|
|
StrCpyN(szUserPrefs[nLoop - 1], szDirpath, NEWSUSERCOLS);
|
|
nFilled++;
|
|
if(nFilled == nInLoop)
|
|
break;
|
|
}
|
|
nLoop--;
|
|
}
|
|
nLoop = nInLoop;
|
|
nLine = -1; //the nLine++ that follows will make nLine zero.
|
|
pCurr++;
|
|
}
|
|
if(nFilled == nInLoop)
|
|
break;
|
|
pCurr++;
|
|
nLine++;
|
|
}
|
|
|
|
if(pBegin)
|
|
UnmapViewOfFile(pBegin);
|
|
|
|
if(hJSHandle != INVALID_HANDLE_VALUE)
|
|
CloseHandle(hJSHandle);
|
|
|
|
if(hJSFile)
|
|
CloseHandle(hJSFile);
|
|
|
|
if(nFilled == 0)
|
|
return E_FAIL;
|
|
else
|
|
{
|
|
if(nInLoop == 1) //If this function was called only to check the server enties...
|
|
{
|
|
if(lstrlen(szUserPrefs[0]))
|
|
return S_OK;
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
HRESULT CCommNewsAcctImport::GetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (pAcct == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
hr = IGetSettings(dwCookie, pAcct, NULL);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CCommNewsAcctImport::IGetSettings(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
|
|
{
|
|
NEWSSERVERS *pPrevServ = m_rgServ;
|
|
COMMNEWSACCTINFO *pinfo;
|
|
char szUserPrefs[NEWSUSERROWS][NEWSUSERCOLS];
|
|
char sz[512];
|
|
DWORD cb, type;
|
|
HRESULT hr;
|
|
BOOL bPop = TRUE;
|
|
char szNntpServ[NEWSUSERCOLS];
|
|
char szNntpPort[NEWSUSERCOLS];
|
|
szNntpPort[0] = '\0';
|
|
int nReach = 0;
|
|
DWORD dwNewsPort = 119;
|
|
|
|
Assert(pPrevServ);
|
|
Assert(m_dwSelServ < m_nNumServ);
|
|
|
|
for(DWORD nCount = 0; nCount < m_dwSelServ; nCount++)
|
|
pPrevServ = pPrevServ->pNext;
|
|
|
|
StrCpyN(szNntpServ, pPrevServ->szServerName, ARRAYSIZE(szNntpServ));
|
|
while(szNntpServ[nReach] != '\0')
|
|
{
|
|
if(szNntpServ[nReach] == ':')
|
|
{
|
|
szNntpServ[nReach] = '\0';
|
|
StrCpyN(szNntpPort, &szNntpServ[nReach+1], ARRAYSIZE(szNntpPort));
|
|
break;
|
|
}
|
|
nReach++;
|
|
}
|
|
|
|
Assert(lstrlen(szNntpServ) > 0);
|
|
|
|
ZeroMemory((void*)&szUserPrefs[0], NEWSUSERCOLS*NEWSUSERROWS*sizeof(char));
|
|
|
|
Assert(((int) dwCookie) >= 0 && dwCookie < (DWORD_PTR)m_cInfo);
|
|
pinfo = &m_rgInfo[dwCookie];
|
|
|
|
Assert(pinfo->dwCookie == dwCookie);
|
|
|
|
hr = GetUserPrefs(pinfo->szUserPath, szUserPrefs, NEWSUSERROWS, &bPop);
|
|
Assert(!FAILED(hr));
|
|
|
|
hr = pAcct->SetPropSz(AP_ACCOUNT_NAME, szNntpServ);
|
|
if (FAILED(hr))
|
|
return(hr);
|
|
|
|
hr = pAcct->SetPropSz(AP_NNTP_SERVER, szNntpServ);
|
|
Assert(!FAILED(hr));
|
|
|
|
int Len = lstrlen(szNntpPort);
|
|
if(Len)
|
|
{
|
|
// Convert the string to a dw.
|
|
DWORD dwMult = 1;
|
|
dwNewsPort = 0;
|
|
while(Len)
|
|
{
|
|
Len--;
|
|
dwNewsPort += ((int)szNntpPort[Len] - 48)*dwMult;
|
|
dwMult *= 10;
|
|
}
|
|
}
|
|
|
|
hr = pAcct->SetPropDw(AP_NNTP_PORT, dwNewsPort);
|
|
Assert(!FAILED(hr));
|
|
|
|
if(lstrlen(szUserPrefs[2]))
|
|
{
|
|
hr = pAcct->SetPropSz(AP_NNTP_DISPLAY_NAME, szUserPrefs[2]);
|
|
Assert(!FAILED(hr));
|
|
}
|
|
|
|
if(lstrlen(szUserPrefs[3]))
|
|
{
|
|
hr = pAcct->SetPropSz(AP_NNTP_EMAIL_ADDRESS, szUserPrefs[3]);
|
|
Assert(!FAILED(hr));
|
|
}
|
|
|
|
if (pInfo != NULL)
|
|
{
|
|
// TODO: can we do any better than this???
|
|
pInfo->dwConnect = CONN_USE_DEFAULT;
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP CCommNewsAcctImport::GetSettings2(DWORD_PTR dwCookie, IImnAccount *pAcct, IMPCONNINFO *pInfo)
|
|
{
|
|
if (pAcct == NULL ||
|
|
pInfo == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
return(IGetSettings(dwCookie, pAcct, pInfo));
|
|
}
|
|
|
|
CEnumCOMMNEWSACCT::CEnumCOMMNEWSACCT()
|
|
{
|
|
m_cRef = 1;
|
|
// m_iInfo
|
|
m_cInfo = 0;
|
|
m_rgInfo = NULL;
|
|
}
|
|
|
|
CEnumCOMMNEWSACCT::~CEnumCOMMNEWSACCT()
|
|
{
|
|
if (m_rgInfo != NULL)
|
|
MemFree(m_rgInfo);
|
|
}
|
|
|
|
STDMETHODIMP CEnumCOMMNEWSACCT::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
|
|
if (ppv == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IID_IUnknown == riid)
|
|
*ppv = (IUnknown *)this;
|
|
else if (IID_IEnumIMPACCOUNTS == riid)
|
|
*ppv = (IEnumIMPACCOUNTS *)this;
|
|
|
|
if (*ppv != NULL)
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
else
|
|
return(E_NOINTERFACE);
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CEnumCOMMNEWSACCT::AddRef()
|
|
{
|
|
return(++m_cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CEnumCOMMNEWSACCT::Release()
|
|
{
|
|
if (--m_cRef == 0)
|
|
{
|
|
delete this;
|
|
return(0);
|
|
}
|
|
|
|
return(m_cRef);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CEnumCOMMNEWSACCT::Next(IMPACCOUNTINFO *pinfo)
|
|
{
|
|
if (pinfo == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
m_iInfo++;
|
|
if ((UINT)m_iInfo >= m_cInfo)
|
|
return(S_FALSE);
|
|
|
|
Assert(m_rgInfo != NULL);
|
|
|
|
pinfo->dwCookie = m_rgInfo[m_iInfo].dwCookie;
|
|
pinfo->dwReserved = 0;
|
|
StrCpyN(pinfo->szDisplay, m_rgInfo[m_iInfo].szDisplay, ARRAYSIZE(pinfo->szDisplay));
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CEnumCOMMNEWSACCT::Reset()
|
|
{
|
|
m_iInfo = -1;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT CEnumCOMMNEWSACCT::Init(COMMNEWSACCTINFO *pinfo, int cinfo)
|
|
{
|
|
DWORD cb;
|
|
|
|
Assert(pinfo != NULL);
|
|
Assert(cinfo > 0);
|
|
|
|
cb = cinfo * sizeof(COMMNEWSACCTINFO);
|
|
|
|
if (!MemAlloc((void **)&m_rgInfo, cb))
|
|
return(E_OUTOFMEMORY);
|
|
|
|
m_iInfo = -1;
|
|
m_cInfo = cinfo;
|
|
CopyMemory(m_rgInfo, pinfo, cb);
|
|
|
|
return(S_OK);
|
|
}
|