/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsOEScanBoxes.h"
#include "nsMsgUtils.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIImportService.h"
#include "nsIFile.h"
#include "nsIImportMailboxDescriptor.h"
#include "nsOERegUtil.h"
#include "nsOE5File.h"
#include "nsNetUtil.h"
#include "OEDebugLog.h"
#include "nsIInputStream.h"
#include "nsISeekableStream.h"
#include "plstr.h"
#include <windows.h>
#include "nsIWindowsRegKey.h"
#ifdef MOZILLA_INTERNAL_API
#include "nsNativeCharsetUtils.h"
#else
#include "nsMsgI18N.h"
#define NS_CopyNativeToUnicode(source, dest) \
nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), source, dest)
#define NS_CopyUnicodeToNative(source, dest) \
nsMsgI18NConvertFromUnicode(nsMsgI18NFileSystemCharset(), source, dest)
#endif
/*
.nch file format???
offset 20 - long = offset to first record
*/
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
nsOEScanBoxes::nsOEScanBoxes()
{
m_pFirst = nullptr;
}
nsOEScanBoxes::~nsOEScanBoxes()
{
int i, max;
MailboxEntry *pEntry;
for (i = 0, max = m_entryArray.Length(); i < max; i++) {
pEntry = m_entryArray.ElementAt(i);
delete pEntry;
}
// Now free the unprocessed child entries (ie, those without parents for some reason).
for (i = 0, max = m_pendingChildArray.Length(); i < max; i++)
{
pEntry = m_pendingChildArray.ElementAt(i);
if (!pEntry->processed)
delete pEntry;
}
}
/*
3.x & 4.x registry
Software/Microsoft/Outlook Express/
5.0 registry
Identies - value of "Default User ID" is {GUID}
Identities/{GUID}/Software/Microsoft/Outlook Express/5.0/
*/
bool nsOEScanBoxes::Find50Mail(nsIFile *pWhere)
{
nsAutoString userId;
nsresult rv = nsOERegUtil::GetDefaultUserId(userId);
NS_ENSURE_SUCCESS(rv, false);
nsAutoString path(NS_LITERAL_STRING("Identities\\"));
path.Append(userId);
path.AppendLiteral("\\Software\\Microsoft\\Outlook Express\\5.0");
nsCOMPtr<nsIWindowsRegKey> key =
do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
path,
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
NS_ENSURE_SUCCESS(rv, false);
nsAutoString storeRoot;
key->ReadStringValue(NS_LITERAL_STRING("Store Root"), storeRoot);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIFile> localWhere = do_QueryInterface(pWhere);
localWhere->InitWithPath(storeRoot);
nsAutoCString nativeStoreRoot;
NS_CopyUnicodeToNative(storeRoot, nativeStoreRoot);
IMPORT_LOG1("Setting native path: %s\n", nativeStoreRoot.get());
bool isDir = false;
rv = localWhere->IsDirectory(&isDir);
return isDir;
}
bool nsOEScanBoxes::FindMail(nsIFile *pWhere)
{
if (Find50Mail(pWhere))
return true;
nsresult rv;
nsCOMPtr<nsIWindowsRegKey> key =
do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_LITERAL_STRING("Software\\Microsoft\\Outlook Express"),
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
NS_ENSURE_SUCCESS(rv, false);
nsAutoString storeRoot;
key->ReadStringValue(NS_LITERAL_STRING("Store Root"), storeRoot);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIFile> localWhere = do_QueryInterface(pWhere);
localWhere->InitWithPath(storeRoot);
localWhere->AppendNative(NS_LITERAL_CSTRING("Mail"));
bool isDir = false;
localWhere->IsDirectory(&isDir);
return isDir;
}
bool nsOEScanBoxes::GetMailboxes(nsIFile *pWhere, nsIArray **pArray)
{
nsCString path;
pWhere->GetNativePath(path);
if (!path.IsEmpty()) {
IMPORT_LOG1("Looking for mail in: %s\n", path.get());
}
else {
pWhere->GetNativeLeafName(path);
if (!path.IsEmpty())
IMPORT_LOG1("Looking for mail in: %s\n", path.get());
else
IMPORT_LOG0("Unable to get info about where to look for mail\n");
}
nsCOMPtr <nsIFile> location;
pWhere->Clone(getter_AddRefs(location));
// 1. Look for 5.0 folders.dbx
// 2. Look for 3.x & 4.x folders.nch
// 3. Look for 5.0 *.dbx mailboxes
// 4. Look for 3.x & 4.x *.mbx mailboxes
bool result;
location->AppendNative(NS_LITERAL_CSTRING("folders.dbx"));
if (Find50MailBoxes(location)) {
result = GetMailboxList(pWhere, pArray);
}
else {
// 2. Look for 4.x mailboxes
pWhere->Clone(getter_AddRefs(location));
location->AppendNative(NS_LITERAL_CSTRING("folders.nch"));
if (FindMailBoxes(location)) {
result = GetMailboxList(pWhere, pArray);
}
else {
// 3 & 4, look for the specific mailbox files.
pWhere->Clone(getter_AddRefs(location));
ScanMailboxDir(location);
result = GetMailboxList(pWhere, pArray);
}
}
return result;
}
void nsOEScanBoxes::Reset(void)
{
int max = m_entryArray.Length();
for (int i = 0; i < max; i++) {
MailboxEntry *pEntry = m_entryArray.ElementAt(i);
delete pEntry;
}
m_entryArray.Clear();
m_pFirst = nullptr;
}
bool nsOEScanBoxes::FindMailBoxes(nsIFile* descFile)
{
Reset();
nsresult rv;
bool isFile = false;
rv = descFile->IsFile(&isFile);
if (NS_FAILED(rv) || !isFile)
return false;
nsCOMPtr <nsIInputStream> descInputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(descInputStream), descFile);
NS_ENSURE_SUCCESS(rv, false);
IMPORT_LOG0("Reading the folders.nch file\n");
uint32_t curRec;
if (!ReadLong(descInputStream, curRec, 20)) {
return false;
}
// Now for each record
bool done = false;
uint32_t equal;
uint32_t size;
uint32_t previous;
uint32_t next;
MailboxEntry * pEntry;
bool failed;
while (!done) {
if (!ReadLong(descInputStream, equal, curRec)) return false;
if (curRec != equal) {
IMPORT_LOG1("Record start invalid: %ld\n", curRec);
break;
}
if (!ReadLong(descInputStream, size, curRec + 4)) return false;
if (!ReadLong(descInputStream, previous, curRec + 8)) return false;
if (!ReadLong(descInputStream, next, curRec + 12)) return false;
failed = false;
pEntry = new MailboxEntry;
if (!ReadLong(descInputStream, pEntry->index, curRec + 16)) failed = true;
if (!ReadString(descInputStream, pEntry->mailName, curRec + 20)) failed = true;
if (!ReadString(descInputStream, pEntry->fileName, curRec + 279)) failed = true;
if (!ReadLong(descInputStream, pEntry->parent, curRec + 539)) failed = true;
if (!ReadLong(descInputStream, pEntry->child, curRec + 543)) failed = true;
if (!ReadLong(descInputStream, pEntry->sibling, curRec + 547)) failed = true;
if (!ReadLong(descInputStream, pEntry->type, curRec + 551)) failed = true;
if (failed) {
delete pEntry;
return false;
}
#ifdef _TRACE_MAILBOX_ENTRIES
IMPORT_LOG0("------------\n");
IMPORT_LOG2(" Offset: %lx, index: %ld\n", curRec, pEntry->index);
IMPORT_LOG2(" previous: %lx, next: %lx\n", previous, next);
IMPORT_LOG2(" Name: %S, File: %s\n", (char16_t *) pEntry->mailName, (const char *) pEntry->fileName);
IMPORT_LOG3(" Parent: %ld, Child: %ld, Sibling: %ld\n", pEntry->parent, pEntry->child, pEntry->sibling);
#endif
if (!StringEndsWith(pEntry->fileName, NS_LITERAL_CSTRING(".mbx")))
pEntry->fileName.Append(".mbx");
m_entryArray.AppendElement(pEntry);
curRec = next;
if (!next)
done = true;
}
MailboxEntry *pZero = GetIndexEntry(0);
if (pZero)
m_pFirst = GetIndexEntry(pZero->child);
IMPORT_LOG1("Read the folders.nch file, found %ld mailboxes\n", (long) m_entryArray.Length());
return true;
}
bool nsOEScanBoxes::Find50MailBoxes(nsIFile* descFile)
{
Reset();
nsresult rv;
bool isFile = false;
rv = descFile->IsFile(&isFile);
if (NS_FAILED(rv) || !isFile)
return false;
nsCOMPtr <nsIInputStream> descInputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(descInputStream), descFile);
NS_ENSURE_SUCCESS(rv, false);
IMPORT_LOG0("Reading the folders.dbx file\n");
uint32_t *pIndex;
uint32_t indexSize = 0;
if (!nsOE5File::ReadIndex(descInputStream, &pIndex, &indexSize)) {
IMPORT_LOG0("*** NOT USING FOLDERS.DBX!!!\n");
return false;
}
uint32_t marker;
uint32_t size;
char *pBytes;
uint32_t cntRead;
int32_t recordId;
int32_t strOffset;
uint8_t tag;
uint32_t data;
int32_t dataOffset;
uint32_t id;
uint32_t parent;
uint32_t numMessages;
char * pFileName;
char * pDataSource;
MailboxEntry * pEntry;
MailboxEntry * pLastEntry = nullptr;
uint32_t localStoreId = 0;
for (uint32_t i = 0; i < indexSize; i++) {
if (!ReadLong(descInputStream, marker, pIndex[i])) continue;
if (marker != pIndex[i]) continue;
if (!ReadLong(descInputStream, size, pIndex[i] + 4)) continue;
size += 4;
pBytes = new char[size];
rv = descInputStream->Read(pBytes, size, &cntRead);
if (NS_FAILED(rv) || ((uint32_t)cntRead != size)) {
delete [] pBytes;
continue;
}
recordId = pBytes[2];
strOffset = (recordId * 4) + 4;
if (recordId == 4)
strOffset += 4;
id = 0;
parent = 0;
numMessages = 0;
pFileName = nullptr;
pDataSource = nullptr;
dataOffset = 4;
while (dataOffset < strOffset) {
tag = (uint8_t) pBytes[dataOffset];
data = 0; // make sure all bytes are 0 before copying 3 bytes over.
memcpy(&data, &(pBytes[dataOffset + 1]), 3);
switch(tag) {
case 0x80: // id record
id = data;
break;
case 0x81: // parent id
parent = data;
break;
case 0x87: // number of messages in this mailbox
numMessages = data;
break;
case 0x03: // file name for this mailbox
if (((uint32_t)strOffset + data) < size)
pFileName = (char *)(pBytes + strOffset + data);
break;
case 0x05: // data source for this record (this is not a mailbox!)
if (((uint32_t)strOffset + data) < size)
pDataSource = (char *) (pBytes + strOffset + data);
break;
}
dataOffset += 4;
}
// now build an entry if necessary!
if (pDataSource) {
if (!PL_strcasecmp(pDataSource, "LocalStore"))
{
localStoreId = id;
// See if we have any child folders that need to be added/processed for this top level parent.
ProcessPendingChildEntries(localStoreId, localStoreId, m_pendingChildArray);
// Clean up the pending list.
RemoveProcessedChildEntries();
}
}
else if (id && localStoreId && parent) {
// veryify that this mailbox is in the local store
data = parent;
while (data && (data != localStoreId)) {
pEntry = GetIndexEntry(data);
if (pEntry)
data = pEntry->parent;
else
data = 0;
}
if (data == localStoreId) {
// Create an entry for this bugger
pEntry = NewMailboxEntry(id, parent, (const char *) (pBytes + strOffset), pFileName);
if (pEntry)
{
AddChildEntry(pEntry, localStoreId);
pEntry->processed = true;
// See if we have any child folders that need to be added/processed.
ProcessPendingChildEntries(id, localStoreId, m_pendingChildArray);
// Clean up the pending list.
RemoveProcessedChildEntries();
}
}
else
{
// Put this folder into child array and process it when its parent shows up.
pEntry = NewMailboxEntry(id, parent, (const char *) (pBytes + strOffset), pFileName);
if (pEntry)
m_pendingChildArray.AppendElement(pEntry);
}
}
else if (pFileName)
{
// Put this folder into child array and process it when its parent shows up.
// For some reason, it's likely that child folders come before their parents.
pEntry = NewMailboxEntry(id, parent, (const char *) (pBytes + strOffset), pFileName);
if (pEntry)
m_pendingChildArray.AppendElement(pEntry);
}
delete [] pBytes;
}
delete [] pIndex;
return m_entryArray.Length();
}
nsOEScanBoxes::MailboxEntry *nsOEScanBoxes::NewMailboxEntry(uint32_t id, uint32_t parent, const char *prettyName, char *pFileName)
{
MailboxEntry *pEntry = new MailboxEntry();
if (!pEntry)
return nullptr;
pEntry->index = id;
pEntry->parent = parent;
pEntry->child = 0;
pEntry->type = 0;
pEntry->sibling = -1;
pEntry->processed = false;
NS_CopyNativeToUnicode(nsDependentCString(prettyName), pEntry->mailName);
if (pFileName)
pEntry->fileName = pFileName;
return pEntry;
}
void nsOEScanBoxes::ProcessPendingChildEntries(uint32_t parent, uint32_t rootIndex, nsTArray<MailboxEntry*> &childArray)
{
int32_t i, max;
MailboxEntry *pEntry;
for (i = 0, max = childArray.Length(); i < max; i++)
{
pEntry = childArray.ElementAt(i);
if ((!pEntry->processed) && (pEntry->parent == parent))
{
AddChildEntry(pEntry, rootIndex);
pEntry->processed = true; // indicate it's been processed.
// See if there are unprocessed child folders for this child in the
// array as well (ie, both child and grand-child are on the list).
ProcessPendingChildEntries(pEntry->index, rootIndex, childArray);
}
}
}
void nsOEScanBoxes::RemoveProcessedChildEntries()
{
// Remove already processed entries from the pending list. Note that these entries are also
// on 'm_entryArray' list so we don't want to deallocate the space for the entries now.
MailboxEntry * pEntry;
int32_t i;
for (i = m_pendingChildArray.Length()-1; i >= 0; i--)
{
pEntry = m_pendingChildArray.ElementAt(i);
if (pEntry->processed)
m_pendingChildArray.RemoveElementAt(i);
}
}
void nsOEScanBoxes::AddChildEntry(MailboxEntry *pEntry, uint32_t rootIndex)
{
if (!m_pFirst) {
if (pEntry->parent == rootIndex) {
m_pFirst = pEntry;
m_entryArray.AppendElement(pEntry);
}
else {
delete pEntry;
}
return;
}
MailboxEntry * pParent = nullptr;
MailboxEntry * pSibling = nullptr;
if (pEntry->parent == rootIndex) {
pSibling = m_pFirst;
}
else {
pParent = GetIndexEntry(pEntry->parent);
}
if (!pParent && !pSibling) {
delete pEntry;
return;
}
if (pParent && (pParent->child == 0)) {
pParent->child = pEntry->index;
m_entryArray.AppendElement(pEntry);
return;
}
if (!pSibling)
pSibling = GetIndexEntry(pParent->child);
while (pSibling && (pSibling->sibling != -1)) {
pSibling = GetIndexEntry(pSibling->sibling);
}
if (!pSibling) {
delete pEntry;
return;
}
pSibling->sibling = pEntry->index;
m_entryArray.AppendElement(pEntry);
}
bool nsOEScanBoxes::Scan50MailboxDir(nsIFile * srcDir)
{
Reset();
MailboxEntry *pEntry;
int32_t index = 1;
char *pLeaf;
bool hasMore;
nsCOMPtr<nsISimpleEnumerator> directoryEnumerator;
nsresult rv = srcDir->GetDirectoryEntries(getter_AddRefs(directoryEnumerator));
NS_ENSURE_SUCCESS(rv, false);
directoryEnumerator->HasMoreElements(&hasMore);
bool isFile;
nsCOMPtr<nsIFile> entry;
nsCString fName;
while (hasMore && NS_SUCCEEDED(rv))
{
nsCOMPtr<nsISupports> aSupport;
rv = directoryEnumerator->GetNext(getter_AddRefs(aSupport));
nsCOMPtr<nsIFile> entry(do_QueryInterface(aSupport, &rv));
directoryEnumerator->HasMoreElements(&hasMore);
isFile = false;
rv = entry->IsFile(&isFile);
if (NS_SUCCEEDED(rv) && isFile) {
pLeaf = nullptr;
rv = entry->GetNativeLeafName(fName);
if (NS_SUCCEEDED(rv) &&
(StringEndsWith(fName, NS_LITERAL_CSTRING(".dbx")))) {
// This is a *.dbx file in the mail directory
if (nsOE5File::IsLocalMailFile(entry)) {
pEntry = new MailboxEntry;
pEntry->index = index;
index++;
pEntry->parent = 0;
pEntry->child = 0;
pEntry->sibling = index;
pEntry->type = -1;
fName.SetLength(fName.Length() - 4);
pEntry->fileName = fName.get();
NS_CopyNativeToUnicode(fName, pEntry->mailName);
m_entryArray.AppendElement(pEntry);
}
}
}
}
if (m_entryArray.Length() > 0) {
pEntry = m_entryArray.ElementAt(m_entryArray.Length() - 1);
pEntry->sibling = -1;
return true;
}
return false;
}
void nsOEScanBoxes::ScanMailboxDir(nsIFile * srcDir)
{
if (Scan50MailboxDir(srcDir))
return;
Reset();
MailboxEntry * pEntry;
int32_t index = 1;
nsAutoCString pLeaf;
uint32_t sLen;
bool hasMore;
nsCOMPtr<nsISimpleEnumerator> directoryEnumerator;
nsresult rv = srcDir->GetDirectoryEntries(getter_AddRefs(directoryEnumerator));
NS_ENSURE_SUCCESS_VOID(rv);
directoryEnumerator->HasMoreElements(&hasMore);
bool isFile;
nsCOMPtr<nsIFile> entry;
nsCString fName;
nsCString ext;
nsCString name;
while (hasMore && NS_SUCCEEDED(rv))
{
nsCOMPtr<nsISupports> aSupport;
rv = directoryEnumerator->GetNext(getter_AddRefs(aSupport));
nsCOMPtr<nsIFile> entry(do_QueryInterface(aSupport, &rv));
directoryEnumerator->HasMoreElements(&hasMore);
isFile = false;
rv = entry->IsFile(&isFile);
if (NS_SUCCEEDED(rv) && isFile)
{
rv = entry->GetNativeLeafName(pLeaf);
if (NS_SUCCEEDED(rv) && !pLeaf.IsEmpty() &&
((sLen = pLeaf.Length()) > 4) &&
(!PL_strcasecmp(pLeaf.get() + sLen - 3, "mbx")))
{
// This is a *.mbx file in the mail directory
pEntry = new MailboxEntry;
pEntry->index = index;
index++;
pEntry->parent = 0;
pEntry->child = 0;
pEntry->sibling = index;
pEntry->type = -1;
pEntry->fileName = pLeaf;
pLeaf.SetLength(sLen - 4);
NS_CopyNativeToUnicode(pLeaf, pEntry->mailName);
m_entryArray.AppendElement(pEntry);
}
}
}
if (m_entryArray.Length() > 0) {
pEntry = m_entryArray.ElementAt(m_entryArray.Length() - 1);
pEntry->sibling = -1;
}
}
uint32_t nsOEScanBoxes::CountMailboxes(MailboxEntry *pBox)
{
if (pBox == nullptr) {
if (m_pFirst != nullptr)
pBox = m_pFirst;
else {
if (m_entryArray.Length() > 0)
pBox = m_entryArray.ElementAt(0);
}
}
uint32_t count = 0;
MailboxEntry * pChild;
while (pBox) {
count++;
if (pBox->child) {
pChild = GetIndexEntry(pBox->child);
if (pChild != nullptr)
count += CountMailboxes(pChild);
}
if (pBox->sibling != -1) {
pBox = GetIndexEntry(pBox->sibling);
}
else
pBox = nullptr;
}
return count;
}
bool nsOEScanBoxes::GetMailboxList(nsIFile * root, nsIArray **pArray)
{
nsresult rv;
nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
if (NS_FAILED(rv)) {
IMPORT_LOG0("FAILED to allocate the nsIArray\n");
return false;
}
BuildMailboxList(nullptr, root, 1, array);
array.forget(pArray);
return true;
}
void nsOEScanBoxes::BuildMailboxList(MailboxEntry *pBox, nsIFile * root, int32_t depth, nsIMutableArray *pArray)
{
if (pBox == nullptr) {
if (m_pFirst != nullptr) {
pBox = m_pFirst;
IMPORT_LOG0("Assigning start of mailbox list to m_pFirst\n");
}
else {
if (m_entryArray.Length() > 0) {
pBox = m_entryArray.ElementAt(0);
IMPORT_LOG0("Assigning start of mailbox list to entry at index 0\n");
}
}
if (pBox == nullptr) {
IMPORT_LOG0("ERROR ASSIGNING STARTING MAILBOX\n");
}
}
nsresult rv;
nsCOMPtr<nsIFile> file;
MailboxEntry *pChild;
nsIImportMailboxDescriptor *pID;
nsISupports *pInterface;
int64_t size;
nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS_VOID(rv);
while (pBox) {
rv = impSvc->CreateNewMailboxDescriptor(&pID);
if (NS_SUCCEEDED(rv)) {
pID->SetDepth(depth);
pID->SetIdentifier(pBox->index);
pID->SetDisplayName((char16_t *)pBox->mailName.get());
if (!pBox->fileName.IsEmpty()) {
pID->GetFile(getter_AddRefs(file));
file->InitWithFile(root);
file->AppendNative(pBox->fileName);
size = 0;
file->GetFileSize(&size);
pID->SetSize(size);
}
rv = pID->QueryInterface(kISupportsIID, (void **) &pInterface);
pArray->AppendElement(pInterface, false);
pInterface->Release();
pID->Release();
}
if (pBox->child) {
pChild = GetIndexEntry(pBox->child);
if (pChild != nullptr)
BuildMailboxList(pChild, root, depth + 1, pArray);
}
if (pBox->sibling != -1) {
pBox = GetIndexEntry(pBox->sibling);
}
else
pBox = nullptr;
}
}
nsOEScanBoxes::MailboxEntry * nsOEScanBoxes::GetIndexEntry(uint32_t index)
{
int32_t max = m_entryArray.Length();
for (int32_t i = 0; i < max; i++) {
MailboxEntry *pEntry = m_entryArray.ElementAt(i);
if (pEntry->index == index)
return pEntry;
}
return nullptr;
}
// -------------------------------------------------------
// File utility routines
// -------------------------------------------------------
bool nsOEScanBoxes::ReadLong(nsIInputStream * stream, int32_t& val, uint32_t offset)
{
nsresult rv;
nsCOMPtr <nsISeekableStream> seekStream = do_QueryInterface(stream, &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
NS_ENSURE_SUCCESS(rv, false);
uint32_t cntRead;
char * pReadTo = (char *)&val;
rv = stream->Read(pReadTo, sizeof(val), &cntRead);
return NS_SUCCEEDED(rv) && cntRead == sizeof(val);
}
bool nsOEScanBoxes::ReadLong(nsIInputStream * stream, uint32_t& val, uint32_t offset)
{
nsresult rv;
nsCOMPtr <nsISeekableStream> seekStream = do_QueryInterface(stream, &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
NS_ENSURE_SUCCESS(rv, false);
uint32_t cntRead;
char * pReadTo = (char *)&val;
rv = stream->Read(pReadTo, sizeof(val), &cntRead);
if (NS_FAILED(rv) || (cntRead != sizeof(val)))
return false;
return true;
}
// It appears as though the strings for file name and mailbox
// name are at least 254 chars - verified - they are probably 255
// but why bother going that far! If a file name is that long then
// the heck with it.
#define kOutlookExpressStringLength 252
bool nsOEScanBoxes::ReadString(nsIInputStream * stream, nsString& str, uint32_t offset)
{
nsresult rv;
nsCOMPtr<nsISeekableStream> seekStream = do_QueryInterface(stream, &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
NS_ENSURE_SUCCESS(rv, false);
uint32_t cntRead;
char buffer[kOutlookExpressStringLength];
char *pReadTo = buffer;
rv = stream->Read(pReadTo, kOutlookExpressStringLength, &cntRead);
if (NS_FAILED(rv) || (cntRead != kOutlookExpressStringLength))
return false;
buffer[kOutlookExpressStringLength - 1] = 0;
str.AssignASCII(buffer);
return true;
}
bool nsOEScanBoxes::ReadString(nsIInputStream * stream, nsCString& str, uint32_t offset)
{
nsresult rv;
nsCOMPtr<nsISeekableStream> seekStream = do_QueryInterface(stream, &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
NS_ENSURE_SUCCESS(rv, false);
uint32_t cntRead;
char buffer[kOutlookExpressStringLength];
char *pReadTo = buffer;
rv = stream->Read(pReadTo, kOutlookExpressStringLength, &cntRead);
if (NS_FAILED(rv) || (cntRead != kOutlookExpressStringLength))
return false;
buffer[kOutlookExpressStringLength - 1] = 0;
str = buffer;
return true;
}