Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions UI/file/exporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <core/mapi/mapiFile.h>
#include <core/utility/file.h>
#include <core/utility/output.h>
#include <core/utility/registry.h>
#include <core/addin/mfcmapi.h>
#include <UI/file/FileDialogEx.h>
#include <UI/Dialogs/Editors/Editor.h>
Expand All @@ -23,23 +24,41 @@ namespace file
dialog::editor::CEditor MyData(
pParentWnd, IDS_SAVEMESSAGETOFILE, IDS_SAVEMESSAGETOFILEPROMPT, CEDITOR_BUTTON_OK | CEDITOR_BUTTON_CANCEL);

UINT uidDropDown[] = {
IDS_DDTEXTFILE,
IDS_DDMSGFILEANSI,
IDS_DDMSGFILEUNICODE,
IDS_DDEMLFILE,
IDS_DDEMLFILEUSINGICONVERTERSESSION,
IDS_DDTNEFFILE};
MyData.AddPane(
viewpane::DropDownPane::Create(0, IDS_FORMATTOSAVEMESSAGE, _countof(uidDropDown), uidDropDown, true));
std::vector<UINT> uidDropDown{IDS_DDTEXTFILE, IDS_DDMSGFILEANSI, IDS_DDMSGFILEUNICODE};
if (registry::enableLegacyFeatures)
{
uidDropDown.push_back(IDS_DDEMLFILEUSINGICONVERTERSESSION);
}
uidDropDown.push_back(IDS_DDTNEFFILE);

MyData.AddPane(viewpane::DropDownPane::Create(
0, IDS_FORMATTOSAVEMESSAGE, static_cast<ULONG>(uidDropDown.size()), uidDropDown.data(), true));
if (bMultiSelect)
{
MyData.AddPane(viewpane::CheckPane::Create(1, IDS_EXPORTPROMPTLOCATION, false, false));
}

if (!MyData.DisplayDialog()) return false;

exportType = static_cast<file::exportType>(MyData.GetDropDown(0));
switch (MyData.GetDropDownValue(0))
{
case IDS_DDTEXTFILE:
exportType = exportType::text;
break;
case IDS_DDMSGFILEANSI:
exportType = exportType::msgAnsi;
break;
case IDS_DDMSGFILEUNICODE:
exportType = exportType::msgUnicode;
break;
case IDS_DDEMLFILEUSINGICONVERTERSESSION:
exportType = exportType::emlIConverter;
break;
case IDS_DDTNEFFILE:
exportType = exportType::tnef;
break;
}

bPrompt = !bMultiSelect || MyData.GetCheck(1);

switch (exportType)
Expand All @@ -55,7 +74,6 @@ namespace file
szDotExt = L".msg";
szFilter = strings::loadstring(IDS_MSGFILES);
break;
case exportType::eml:
case exportType::emlIConverter:
szExt = L"eml";
szDotExt = L".eml";
Expand Down Expand Up @@ -110,9 +128,6 @@ namespace file
case exportType::msgUnicode:
return EC_H(file::SaveToMSG(lpMessage, filename, true, pParentWnd->GetSafeHwnd(), true));
break;
case exportType::eml:
return EC_H(file::SaveToEML(lpMessage, filename));
break;
case exportType::emlIConverter:
{
auto ulConvertFlags = CCSF_SMTP;
Expand Down
5 changes: 2 additions & 3 deletions UI/file/exporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ namespace file
text = 0,
msgAnsi = 1,
msgUnicode = 2,
eml = 3,
emlIConverter = 4,
tnef = 5
emlIConverter = 3,
tnef = 4
};

class exporter
Expand Down
35 changes: 0 additions & 35 deletions core/mapi/mapiFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,41 +326,6 @@ namespace file
return hRes;
}

_Check_return_ HRESULT SaveToEML(_In_ LPMESSAGE lpMessage, _In_ const std::wstring& szFileName)
{
LPSTREAM pStrmSrc = nullptr;

if (!lpMessage || szFileName.empty()) return MAPI_E_INVALID_PARAMETER;
output::DebugPrint(output::dbgLevel::Generic, L"SaveToEML: Saving message to \"%ws\"\n", szFileName.c_str());

// Open the property of the attachment
// containing the file data
auto hRes = EC_MAPI(lpMessage->OpenProperty(
PR_INTERNET_CONTENT, // TODO: There's a modern property for this...
const_cast<LPIID>(&IID_IStream),
0,
NULL, // MAPI_MODIFY is not needed
reinterpret_cast<LPUNKNOWN*>(&pStrmSrc)));
if (FAILED(hRes))
{
if (hRes == MAPI_E_NOT_FOUND)
{
output::DebugPrint(output::dbgLevel::Generic, L"No internet content found\n");
}
}
else
{
if (pStrmSrc)
{
hRes = WC_H(WriteStreamToFile(pStrmSrc, szFileName));

pStrmSrc->Release();
}
}

return hRes;
}

_Check_return_ HRESULT STDAPICALLTYPE MyStgCreateStorageEx(
_In_ const std::wstring& pName,
DWORD grfMode,
Expand Down
1 change: 0 additions & 1 deletion core/mapi/mapiFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ namespace file
bool bAssoc,
bool bUnicode,
HWND hWnd);
_Check_return_ HRESULT SaveToEML(_In_ LPMESSAGE lpMessage, _In_ const std::wstring& szFileName);
_Check_return_ HRESULT CreateNewMSG(
_In_ const std::wstring& szFileName,
bool bUnicode,
Expand Down
4 changes: 2 additions & 2 deletions core/res/MFCMapi.rc2
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,7 @@ IDS_REGKEY_FORCEOUTLOOKMAPI "Force the use of Outlook's MAPI files"
IDS_REGKEY_FORCESYSTEMMAPI "Force the use of the system's MAPI files"
IDS_REGKEY_PREFER_OLMAPI32 "Prefer olmapi32.dll over other MAPI files"
IDS_REGKEY_UIDIAG "Show UI diagnostics"
IDS_REGKEY_ENABLE_LEGACY_FEATURES "Enable legacy features"

// RestrictEditor.cpp
IDS_RELOP "relop"
Expand Down Expand Up @@ -1200,10 +1201,9 @@ IDS_DDDISPLAYPROPSONLY "Only display properties from MSG file"
IDS_DDENTERFORMCLASS "Manually enter form class"
IDS_DDFOLDERFORMLIBRARY "Folder Form library"
IDS_DDORGFORMLIBRARY "Organization Forms and Application Forms libraries"
IDS_DDTEXTFILE "Text file (saves all properties of message to a text file)"
IDS_DDTEXTFILE "XML file (saves all properties of message to an XML file)"
IDS_DDMSGFILEANSI "MSG file (ANSI)"
IDS_DDMSGFILEUNICODE "MSG file (UNICODE)"
IDS_DDEMLFILE "EML file (using PR_INTERNET_CONTENT)"
IDS_DDEMLFILEUSINGICONVERTERSESSION "EML file (using IConverterSession)"
IDS_DDTNEFFILE "TNEF file (same format as winmail.dat)"
IDS_DDCOPYPROPS "IMAPIProp::CopyProps"
Expand Down
2 changes: 1 addition & 1 deletion core/res/Resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,6 @@
#define IDS_DDORGFORMLIBRARY 35246
#define IDS_DDTEXTFILE 35247
#define IDS_DDMSGFILEANSI 35248
#define IDS_DDEMLFILE 35249
#define IDS_DDTNEFFILE 35250
#define IDS_DDCOPYPROPS 35251
#define IDS_DDGETSETPROPS 35252
Expand Down Expand Up @@ -1235,3 +1234,4 @@
#define IDS_CAPABILITIES_FOLDER 35872
#define IDS_CAPABILITIES_RESTRICTION 35873
#define IDS_REGKEY_PREFER_OLMAPI32 35874
#define IDS_REGKEY_ENABLE_LEGACY_FEATURES 35875
5 changes: 4 additions & 1 deletion core/utility/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@

namespace output
{
std::wstring g_szXMLHeader = L"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
// Files are opened with the CRT "ccs=UNICODE" mode, which writes a UTF-16 LE BOM
// and encodes each character as two little-endian bytes. The declared encoding
// must match, otherwise XML parsers reject the file with an encoding mismatch.
std::wstring g_szXMLHeader = L"<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n";
std::function<void(const std::wstring& errString)> outputToDbgView;
FILE* g_fDebugFile = nullptr;

Expand Down
2 changes: 2 additions & 0 deletions core/utility/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ namespace registry
boolRegKey preferOlmapi32{L"PreferOlmapi32", true, false, IDS_REGKEY_PREFER_OLMAPI32};
boolRegKey uiDiag{L"UIDiag", false, false, IDS_REGKEY_UIDIAG};
boolRegKey displayAboutDialog{L"DisplayAboutDialog", true, false, NULL};
boolRegKey enableLegacyFeatures{L"EnableLegacyFeatures", false, false, IDS_REGKEY_ENABLE_LEGACY_FEATURES};
wstringRegKey propertyColumnOrder{L"PropertyColumnOrder", L"", false, NULL};
dwordRegKey namedPropBatchSize{L"NamedPropBatchSize", regOptionType::stringDec, 400, false, NULL};

Expand Down Expand Up @@ -101,6 +102,7 @@ namespace registry
&preferOlmapi32,
&uiDiag,
&displayAboutDialog,
&enableLegacyFeatures,
&propertyColumnOrder,
&namedPropBatchSize};

Expand Down
1 change: 1 addition & 0 deletions core/utility/registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ namespace registry
extern boolRegKey preferOlmapi32;
extern boolRegKey uiDiag;
extern boolRegKey displayAboutDialog;
extern boolRegKey enableLegacyFeatures;
extern wstringRegKey propertyColumnOrder;
extern dwordRegKey namedPropBatchSize;
} // namespace registry