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.
749 lines
20 KiB
749 lines
20 KiB
#include "pch.hxx"
|
|
#include "impapi.h"
|
|
#include "comconv.h"
|
|
#include <newimp.h>
|
|
#include <eudrimp.h>
|
|
#include "commimp.h"
|
|
#include <mapi.h>
|
|
#include <mapix.h>
|
|
#include <import.h>
|
|
#include <dllmain.h>
|
|
|
|
ASSERTDATA
|
|
|
|
HRESULT FindSnm(EUDORANODE *pParent, EUDORANODE **pplist, TCHAR *npath);
|
|
INT_PTR CALLBACK SelectCommUserDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
HRESULT GetCommunicatorDirectory(char *szUser, char *szDir, int cch);
|
|
|
|
const static char c_szSnmExt[] = "\\*.snm";
|
|
const static char c_szSnmHeader[] = "# Netscape folder cache"; //used for avoiding processing Netscape 3.0 SNM files
|
|
const static char c_szDrafts[] = "Drafts";
|
|
const static char c_szUnsent[] = "Unsent Messages";
|
|
const static char c_szSent[] = "Sent";
|
|
|
|
CCommunicatorImport::CCommunicatorImport()
|
|
{
|
|
DllAddRef();
|
|
|
|
m_cRef = 1;
|
|
m_plist = NULL;
|
|
*m_szUser = 0;
|
|
}
|
|
|
|
CCommunicatorImport::~CCommunicatorImport()
|
|
{
|
|
if (m_plist != NULL)
|
|
EudoraFreeFolderList(m_plist);
|
|
|
|
DllRelease();
|
|
}
|
|
|
|
ULONG CCommunicatorImport::AddRef()
|
|
{
|
|
m_cRef++;
|
|
|
|
return(m_cRef);
|
|
}
|
|
|
|
ULONG CCommunicatorImport::Release()
|
|
{
|
|
ULONG cRef;
|
|
|
|
cRef = --m_cRef;
|
|
if (cRef == 0)
|
|
delete this;
|
|
|
|
return(cRef);
|
|
}
|
|
|
|
HRESULT CCommunicatorImport::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (ppv == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IID_IMailImport == riid)
|
|
*ppv = (IMailImport *)this;
|
|
else if (IID_IUnknown == riid)
|
|
*ppv = (IUnknown *)this;
|
|
else
|
|
hr = E_NOINTERFACE;
|
|
|
|
if (*ppv != NULL)
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
|
|
return(hr);
|
|
}
|
|
|
|
typedef struct tagSELCOMMINFO
|
|
{
|
|
char szUser[MAX_PATH];
|
|
HKEY hkey;
|
|
} SELCOMMINFO;
|
|
|
|
const static char c_szRegNscp[] = "Software\\Netscape\\Netscape Navigator\\Users";
|
|
|
|
HRESULT CCommunicatorImport::InitializeImport(HWND hwnd)
|
|
{
|
|
DWORD cUsers;
|
|
int iRet;
|
|
HKEY hkey;
|
|
HRESULT hr;
|
|
SELCOMMINFO si;
|
|
|
|
hr = S_OK;
|
|
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegNscp, 0, KEY_ALL_ACCESS, &hkey))
|
|
{
|
|
if (ERROR_SUCCESS == RegQueryInfoKey(hkey, NULL, NULL, 0, &cUsers, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
|
|
{
|
|
if (cUsers > 1)
|
|
{
|
|
si.hkey = hkey;
|
|
|
|
iRet = (int) DialogBoxParam(g_hInstImp, MAKEINTRESOURCE(iddSelectCommUser), hwnd, SelectCommUserDlgProc, (LPARAM)&si);
|
|
if (iRet == IDCANCEL)
|
|
hr = S_FALSE;
|
|
else if (iRet == IDOK)
|
|
StrCpyN(m_szUser, si.szUser, ARRAYSIZE(m_szUser));
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
INT_PTR CALLBACK SelectCommUserDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hwndT;
|
|
WORD id;
|
|
DWORD iSubKey, cb;
|
|
char sz[MAX_PATH];
|
|
SELCOMMINFO *psi;
|
|
int index;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
Assert(lParam != NULL);
|
|
psi = (SELCOMMINFO *)lParam;
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)psi);
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_USERLIST);
|
|
|
|
// fill list
|
|
iSubKey = 0;
|
|
cb = sizeof(sz);
|
|
while (ERROR_SUCCESS == RegEnumKeyEx(psi->hkey, iSubKey, sz, &cb, NULL, NULL, NULL, NULL))
|
|
{
|
|
SendMessage(hwndT, LB_ADDSTRING, 0, (LPARAM)sz);
|
|
iSubKey++;
|
|
cb = sizeof(sz);
|
|
}
|
|
|
|
SendMessage(hwndT, LB_SETCURSEL, 0, 0);
|
|
return(TRUE);
|
|
|
|
case WM_COMMAND:
|
|
id = LOWORD(wParam);
|
|
switch (id)
|
|
{
|
|
case IDOK:
|
|
psi = (SELCOMMINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
Assert(psi != NULL);
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_USERLIST);
|
|
index = (int) SendMessage(hwndT, LB_GETCURSEL, 0, 0);
|
|
Assert(index >= 0);
|
|
if (SendMessage(hwndT, LB_GETTEXTLEN, (WPARAM)index, 0) < ARRAYSIZE(psi->szUser))
|
|
SendMessage(hwndT, LB_GETTEXT, (WPARAM)index, (LPARAM)psi->szUser);
|
|
|
|
// fall through
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hwnd, id);
|
|
return(TRUE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
const static char c_szCommunicatorKey[] = "SOFTWARE\\Netscape\\Netscape Navigator\\Users";
|
|
const static char c_szCurrentUser[] = "CurrentUser";
|
|
const static char c_szDirRoot[] = "DirRoot";
|
|
const static char c_szMailDir[] = "\\Mail";
|
|
|
|
HRESULT GetCommunicatorDirectory(char *szUser, char *szDir, int cch)
|
|
{
|
|
char sz[MAX_PATH], szTemp[MAX_PATH], szExpanded[MAX_PATH], *psz;
|
|
HKEY hkResult, hkResult1;
|
|
LONG lRes;
|
|
DWORD cb, dwType;
|
|
HRESULT hr;
|
|
|
|
hr = E_FAIL;
|
|
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szCommunicatorKey, 0, KEY_QUERY_VALUE, &hkResult))
|
|
{
|
|
if (szUser == NULL)
|
|
{
|
|
cb = sizeof(sz);
|
|
lRes = RegQueryValueEx(hkResult, c_szCurrentUser, NULL, NULL, (LPBYTE)sz, &cb);
|
|
szUser = sz;
|
|
}
|
|
else
|
|
{
|
|
Assert(*szUser != 0);
|
|
lRes = ERROR_SUCCESS;
|
|
}
|
|
|
|
if (lRes == ERROR_SUCCESS)
|
|
{
|
|
cb = sizeof(szTemp);
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hkResult, szUser, 0, KEY_QUERY_VALUE, &hkResult1))
|
|
{
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hkResult1, c_szDirRoot, NULL, &dwType, (LPBYTE)szTemp, &cb))
|
|
{
|
|
if (REG_EXPAND_SZ == dwType)
|
|
{
|
|
ZeroMemory(szExpanded, ARRAYSIZE(szExpanded));
|
|
ExpandEnvironmentStrings(szTemp, szExpanded, ARRAYSIZE(szExpanded));
|
|
psz = szExpanded;
|
|
}
|
|
else
|
|
psz = szTemp;
|
|
|
|
if (!GetStorePath(psz, szDir, cch))
|
|
{
|
|
StrCpyN(szDir, psz, cch);
|
|
StrCatBuff(szDir, c_szMailDir, cch);
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
RegCloseKey(hkResult1);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkResult);
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CCommunicatorImport::GetDirectory(char *szDir, UINT cch)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Assert(szDir != NULL);
|
|
|
|
hr = GetCommunicatorDirectory(*m_szUser != 0 ? m_szUser : NULL, szDir, cch);
|
|
if (FAILED(hr))
|
|
*szDir = 0;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT CCommunicatorImport::SetDirectory(char *szDir)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Assert(szDir != NULL);
|
|
|
|
if (!ValidStoreDirectory(szDir, NETSCAPE))
|
|
return(S_FALSE);
|
|
|
|
if (m_plist != NULL)
|
|
{
|
|
EudoraFreeFolderList(m_plist);
|
|
m_plist = NULL;
|
|
}
|
|
|
|
hr = FindSnm(NULL, &m_plist, szDir);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CCommunicatorImport::EnumerateFolders(DWORD_PTR dwCookie, IEnumFOLDERS **ppEnum)
|
|
{
|
|
CCommunicatorEnumFOLDERS *pEnum;
|
|
EUDORANODE *pnode;
|
|
|
|
Assert(ppEnum != NULL);
|
|
*ppEnum = NULL;
|
|
|
|
if (dwCookie == COOKIE_ROOT)
|
|
pnode = m_plist;
|
|
else
|
|
pnode = ((EUDORANODE *)dwCookie)->pchild;
|
|
|
|
if (pnode == NULL)
|
|
return(S_FALSE);
|
|
|
|
pEnum = new CCommunicatorEnumFOLDERS(pnode);
|
|
if (pEnum == NULL)
|
|
return(E_OUTOFMEMORY);
|
|
|
|
*ppEnum = pEnum;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP CCommunicatorImport::ImportFolder(DWORD_PTR dwCookie, IFolderImport *pImport)
|
|
{
|
|
char szHdr[64];
|
|
EUDORANODE *pnode;
|
|
HRESULT hr = E_FAIL;
|
|
TCHAR cMsgFile[MAX_PATH];
|
|
BYTE *pSnm, *pMsg, *pEnd, *pEndMsg, *pT, *pNextMsg, *pLast;
|
|
ULONG i, lMsgs, lTotalMsgs, lNumNulls, cbMsg, cbSnm, cExtra, uOffset, uMsgSize, cMsgImp;
|
|
ULONG lRoof = 32;
|
|
ULONG Offset = 0;
|
|
int nNumLevels = 1;
|
|
HANDLE mapSnm, mapMsg, hSnm, hMsg;
|
|
|
|
Assert(pImport != NULL);
|
|
|
|
pnode = (EUDORANODE *)dwCookie;
|
|
Assert(pnode != NULL);
|
|
|
|
if (pnode->iFileType == SNM_DRAFT)
|
|
m_bDraft = TRUE;
|
|
else
|
|
m_bDraft = FALSE;
|
|
|
|
Assert((pnode->iFileType == SNM_FILE ) || (pnode->iFileType == SNM_DRAFT));
|
|
|
|
hr = E_FAIL;
|
|
pSnm = NULL;
|
|
mapSnm = NULL;
|
|
pMsg = NULL;
|
|
mapMsg = NULL;
|
|
|
|
StrCpyN(cMsgFile, pnode->szFile, ARRAYSIZE(cMsgFile));
|
|
cMsgFile[(lstrlen(cMsgFile)) - 4] = 0;
|
|
|
|
hMsg = CreateFile(cMsgFile, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
if (hMsg == INVALID_HANDLE_VALUE)
|
|
return(hrFolderOpenFail);
|
|
|
|
cbMsg = GetFileSize(hMsg, NULL);
|
|
if (cbMsg == 0)
|
|
{
|
|
CloseHandle(hMsg);
|
|
return(S_OK);
|
|
}
|
|
|
|
hSnm = CreateFile(pnode->szFile, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
if (hSnm == INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(hMsg);
|
|
return(hrFolderOpenFail);
|
|
}
|
|
|
|
cbSnm = GetFileSize(hSnm, NULL);
|
|
if (cbSnm < 2560)
|
|
{
|
|
// the .snm file header is 2560 bytes in size, so anything less
|
|
// than this is bogus or doesn't have messages anyway, so no point
|
|
// in continuing
|
|
goto DoneImport;
|
|
}
|
|
|
|
mapSnm = CreateFileMapping(hSnm, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
if (mapSnm == NULL)
|
|
goto DoneImport;
|
|
|
|
pSnm = (BYTE *)MapViewOfFile(mapSnm, FILE_MAP_READ, 0, 0, 0);
|
|
if (pSnm == NULL)
|
|
goto DoneImport;
|
|
|
|
pEnd = pSnm + cbSnm;
|
|
|
|
// Do something else to verify the genuineness of the SNM file (like
|
|
// comparing the two separately stored values of "total # of messages").
|
|
|
|
// 1) Confirm that this is not a NS 3.0 SNM file.
|
|
|
|
CopyMemory(szHdr, pSnm, ARRAYSIZE(c_szSnmHeader) - 1);
|
|
szHdr[ARRAYSIZE(c_szSnmHeader) - 1] = 0;
|
|
if (0 == lstrcmp(szHdr, c_szSnmHeader))
|
|
{
|
|
// this is a Version 3.0 SNM file
|
|
goto DoneImport;
|
|
}
|
|
|
|
// 2) Do someting else!!! We need to verify as much as possible or we'll
|
|
// end up hanging.
|
|
|
|
mapMsg = CreateFileMapping(hMsg, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
if (mapMsg == NULL)
|
|
goto DoneImport;
|
|
|
|
pMsg = (BYTE *)MapViewOfFile(mapMsg, FILE_MAP_READ, 0, 0, 0);
|
|
if (pMsg == NULL)
|
|
goto DoneImport;
|
|
|
|
pEndMsg = pMsg + cbMsg;
|
|
|
|
// Get the total number of messages in the SNM file
|
|
lTotalMsgs = GetOffset(pSnm, cbSnm, 400, 0); //408 - 8 as we add 8 in GetOffset
|
|
|
|
cMsgImp = 0;
|
|
pLast = pMsg;
|
|
|
|
pImport->SetMessageCount(lTotalMsgs);
|
|
|
|
if (lTotalMsgs > 0)
|
|
{
|
|
Offset = (ULONG)GetPrimaryOffset(pSnm, cbSnm);
|
|
// Find the number of 'Levels'
|
|
if(Offset < cbSnm)
|
|
{
|
|
while(lRoof < lTotalMsgs)
|
|
{
|
|
lRoof *= 32;
|
|
nNumLevels++;
|
|
}
|
|
hr = ProcessBlocks(pSnm, cbSnm, pMsg, cbMsg, nNumLevels, Offset, pImport);
|
|
}
|
|
}
|
|
|
|
DoneImport:
|
|
if (pSnm != NULL)
|
|
UnmapViewOfFile(pSnm);
|
|
if (mapSnm != NULL)
|
|
CloseHandle(mapSnm);
|
|
if (pMsg != NULL)
|
|
UnmapViewOfFile(pMsg);
|
|
if (mapMsg != NULL)
|
|
CloseHandle(mapMsg);
|
|
|
|
CloseHandle(hSnm);
|
|
CloseHandle(hMsg);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CCommunicatorImport::ProcessBlocks(BYTE* pSnm, ULONG cbSnm,
|
|
BYTE* pMsg, ULONG cbMsg,
|
|
int nLayer, ULONG Offset,
|
|
IFolderImport *pImport)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HRESULT hr1 = E_FAIL;
|
|
Assert(Offset + 7 < cbSnm);
|
|
int nNumLoops = (int)pSnm[Offset + 7];
|
|
ULONG NewOffset = 0;
|
|
|
|
for(int nElement = 0; nElement < nNumLoops; nElement++)
|
|
{
|
|
if(hr != hrUserCancel)
|
|
{
|
|
if(nLayer == 1)
|
|
{
|
|
NewOffset = GetOffset(pSnm, cbSnm, Offset, 2*nElement);
|
|
// We use 2*nElement above to access elements 8 bytes apart.
|
|
hr1 = ProcessMessages(pSnm,cbSnm, pMsg, cbMsg, NewOffset, pImport);
|
|
if(FAILED(hr1))
|
|
hr = E_FAIL;
|
|
if(hr1 == hrUserCancel)
|
|
return hr1;
|
|
}
|
|
else
|
|
{
|
|
NewOffset = GetOffset(pSnm, cbSnm, Offset, nElement);
|
|
hr = ProcessBlocks(pSnm, cbSnm, pMsg, cbMsg, nLayer - 1, NewOffset, pImport);
|
|
}
|
|
}
|
|
else
|
|
return(hrUserCancel);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
ULONG CCommunicatorImport::GetPrimaryOffset(BYTE* pSnm, ULONG cbSnm)
|
|
{
|
|
return GetOffset(pSnm, cbSnm, 416, 0); //424 - 8 as we add 8 in GetOffset
|
|
}
|
|
|
|
ULONG CCommunicatorImport::GetOffset(BYTE* pSnm, ULONG cbSnm, ULONG Offset, int nElement)
|
|
{
|
|
Assert (3 + Offset + (4*(nElement + 2)) < cbSnm); // One common check point!!!
|
|
ULONG result = 0;
|
|
|
|
result = (ULONG)pSnm[0 + Offset + (4*(nElement + 2))]*16777216 +
|
|
(ULONG)pSnm[1 + Offset + (4*(nElement + 2))]*65536 +
|
|
(ULONG)pSnm[2 + Offset + (4*(nElement + 2))]*256 +
|
|
(ULONG)pSnm[3 + Offset + (4*(nElement + 2))];
|
|
return result;
|
|
}
|
|
|
|
HRESULT CCommunicatorImport::ProcessMessages(BYTE* pSnm, ULONG cbSnm,
|
|
BYTE* pMsg, ULONG cbMsg,
|
|
ULONG NewOffset,
|
|
IFolderImport* pImport)
|
|
{
|
|
ULONG lMsgOffset = 0;
|
|
ULONG uMsgSize = 0;
|
|
HRESULT hr = E_FAIL;
|
|
LPSTREAM lpstm = NULL;
|
|
int nPriority = 1;
|
|
DWORD dwFlags = 0;
|
|
|
|
nPriority = (int)*(pSnm + NewOffset + 47);
|
|
|
|
switch(nPriority)
|
|
{
|
|
case 1:
|
|
case 4:
|
|
dwFlags |= MSG_PRI_NORMAL;
|
|
break;
|
|
|
|
case 2:
|
|
case 3:
|
|
dwFlags |= MSG_PRI_LOW;
|
|
break;
|
|
|
|
case 5:
|
|
case 6:
|
|
dwFlags |= MSG_PRI_HIGH;
|
|
break;
|
|
|
|
default:
|
|
dwFlags |= MSG_PRI_NORMAL;
|
|
break;
|
|
}
|
|
|
|
lMsgOffset = GetOffset(pSnm, cbSnm, NewOffset + 18, 0); //26 - 8 as we add 8 in GetOffset
|
|
uMsgSize = GetOffset(pSnm, cbSnm, NewOffset + 40, 0); //48 - 8 as we add 8 in GetOffset
|
|
|
|
Assert(lMsgOffset + uMsgSize <= cbMsg);
|
|
Assert(pImport != NULL);
|
|
|
|
hr = HrByteToStream(&lpstm, pMsg + lMsgOffset, uMsgSize);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
Assert(lpstm != NULL);
|
|
// 0x01 == read
|
|
if (((pSnm + NewOffset) != NULL) && (0 == ((pSnm + NewOffset)[45] & 0x01)))
|
|
dwFlags |= MSG_STATE_UNREAD;
|
|
if(m_bDraft)
|
|
dwFlags |= MSG_STATE_UNSENT;
|
|
|
|
hr = pImport->ImportMessage(MSG_TYPE_MAIL, dwFlags, lpstm, NULL, 0);
|
|
lpstm->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
CCommunicatorEnumFOLDERS::CCommunicatorEnumFOLDERS(EUDORANODE *plist)
|
|
{
|
|
Assert(plist != NULL);
|
|
|
|
m_cRef = 1;
|
|
m_plist = plist;
|
|
m_pnext = plist;
|
|
}
|
|
|
|
CCommunicatorEnumFOLDERS::~CCommunicatorEnumFOLDERS()
|
|
{
|
|
|
|
}
|
|
|
|
ULONG CCommunicatorEnumFOLDERS::AddRef()
|
|
{
|
|
m_cRef++;
|
|
|
|
return(m_cRef);
|
|
}
|
|
|
|
ULONG CCommunicatorEnumFOLDERS::Release()
|
|
{
|
|
ULONG cRef;
|
|
|
|
cRef = --m_cRef;
|
|
if (cRef == 0)
|
|
delete this;
|
|
|
|
return(cRef);
|
|
}
|
|
|
|
HRESULT CCommunicatorEnumFOLDERS::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (ppv == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IID_IEnumFOLDERS == riid)
|
|
*ppv = (IEnumFOLDERS *)this;
|
|
else if (IID_IUnknown == riid)
|
|
*ppv = (IUnknown *)this;
|
|
else
|
|
hr = E_NOINTERFACE;
|
|
|
|
if (*ppv != NULL)
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CCommunicatorEnumFOLDERS::Next(IMPORTFOLDER *pfldr)
|
|
{
|
|
Assert(pfldr != NULL);
|
|
|
|
if (m_pnext == NULL)
|
|
return(S_FALSE);
|
|
|
|
ZeroMemory(pfldr, sizeof(IMPORTFOLDER));
|
|
pfldr->dwCookie = (DWORD_PTR)m_pnext;
|
|
|
|
// To map Netscape's "Sent" folder to OE's "Sent Items" - Bug 2688.
|
|
if (m_pnext->type != FOLDER_TYPE_SENT)
|
|
StrCpyN(pfldr->szName, m_pnext->szName, ARRAYSIZE(pfldr->szName));
|
|
else
|
|
StrCpyN(pfldr->szName, "Sent Items", ARRAYSIZE(pfldr->szName));
|
|
|
|
pfldr->type = m_pnext->type;
|
|
pfldr->fSubFolders = (m_pnext->pchild != NULL);
|
|
|
|
m_pnext = m_pnext->pnext;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT CCommunicatorEnumFOLDERS::Reset()
|
|
{
|
|
m_pnext = m_plist;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
/*******************************************************************
|
|
* FUNCTION NAME:FindSnm
|
|
*
|
|
* PURPOSE:To Get the Snm files in a folder
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
* IN:parent EUDORANODE ,previously processed EUDORANODE
|
|
*
|
|
* OUT: Pointer to the first node in the tree
|
|
*
|
|
* RETURNS: TRUE or FALSE
|
|
*******************************************************************/
|
|
|
|
HRESULT FindSnm(EUDORANODE *pparent, EUDORANODE **pplist,TCHAR *npath)
|
|
{
|
|
HRESULT hr;
|
|
HANDLE h1, h2;
|
|
TCHAR path[MAX_PATH], path1[MAX_PATH], szInbox[CCHMAX_STRINGRES], szTrash[CCHMAX_STRINGRES];
|
|
TCHAR szNewPath[MAX_PATH];
|
|
WIN32_FIND_DATA FindFileData;
|
|
WIN32_FIND_DATA SbdFileData;
|
|
EUDORANODE *newp, *newp1, *last = NULL, *plist = NULL;
|
|
|
|
Assert(pplist != NULL);
|
|
Assert(npath != NULL);
|
|
|
|
*pplist = NULL;
|
|
|
|
StrCpyN(path, npath, ARRAYSIZE(path));
|
|
StrCatBuff(path, c_szSnmExt, ARRAYSIZE(path));
|
|
|
|
h1 = FindFirstFile(path, &FindFileData);
|
|
if (h1 == INVALID_HANDLE_VALUE)
|
|
return(S_OK);
|
|
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
LoadString(g_hInstImp, idsInbox, szInbox, ARRAYSIZE(szInbox));
|
|
LoadString(g_hInstImp, idsTrash, szTrash, ARRAYSIZE(szTrash));
|
|
|
|
do
|
|
{
|
|
if (!MemAlloc((void **)&newp, sizeof(EUDORANODE)))
|
|
goto err;
|
|
ZeroMemory(newp, sizeof(EUDORANODE));
|
|
|
|
if (plist == NULL)
|
|
{
|
|
Assert(last == NULL);
|
|
plist = newp;
|
|
}
|
|
else
|
|
{
|
|
last->pnext = newp;
|
|
}
|
|
last = newp;
|
|
|
|
StrCpyN(newp->szName, FindFileData.cFileName, ARRAYSIZE(newp->szName));
|
|
|
|
wnsprintf(newp->szFile, ARRAYSIZE(newp->szFile), "%s\\%s", npath, newp->szName);
|
|
|
|
newp->szName[(lstrlen(newp->szName)) - 4] = 0;
|
|
|
|
if (0 == lstrcmpi(newp->szName, szInbox))
|
|
newp->type = FOLDER_TYPE_INBOX;
|
|
else if (0 == lstrcmpi(newp->szName, szTrash))
|
|
newp->type = FOLDER_TYPE_DELETED;
|
|
else if(0 == lstrcmpi(newp->szName, c_szSent)) //c_szSent need not be localised as per my investigation - v-sramas.
|
|
newp->type = FOLDER_TYPE_SENT;
|
|
|
|
newp->pparent = pparent;
|
|
newp->depth = (pparent == NULL ? 0 : (pparent->depth + 1));
|
|
|
|
// This following will be used later to set the flag of
|
|
// a message so that it is editable (MSG_STATE_UNSENT).
|
|
if ((0 == lstrcmpi(newp->szName, c_szDrafts)) ||(0 == lstrcmpi(newp->szName, c_szUnsent)))
|
|
newp->iFileType = SNM_DRAFT;
|
|
else
|
|
newp->iFileType = SNM_FILE;
|
|
|
|
// Search for a corresponding .SBD folder - file now.
|
|
|
|
wnsprintf(path1, ARRAYSIZE(path1), "%s", newp->szFile);
|
|
path1[(lstrlen(path1)) - 3] = 0;
|
|
StrCatBuff(path1, "sbd", ARRAYSIZE(path1));
|
|
|
|
h2 = FindFirstFile(path1, &SbdFileData);
|
|
|
|
if (h2 != INVALID_HANDLE_VALUE)
|
|
{
|
|
//Recurse here
|
|
wnsprintf(szNewPath, ARRAYSIZE(szNewPath), "%s\\%s", npath, SbdFileData.cFileName);
|
|
FindSnm(newp, &newp->pchild, szNewPath);
|
|
}
|
|
}
|
|
while (FindNextFile(h1, &FindFileData));
|
|
|
|
hr = S_OK;
|
|
|
|
err:
|
|
FindClose(h1);
|
|
|
|
if (FAILED(hr) && plist != NULL)
|
|
{
|
|
EudoraFreeFolderList(plist);
|
|
plist = NULL;
|
|
}
|
|
|
|
*pplist = plist;
|
|
|
|
return(hr);
|
|
}
|