#include "pch.hxx" #include #include #include #include #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); }